Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
janjakubnanista committed Nov 28, 2023
1 parent 7b85494 commit 7ae2991
Show file tree
Hide file tree
Showing 25 changed files with 397 additions and 47 deletions.
8 changes: 7 additions & 1 deletion packages/ua-utils-evm-hardhat-test/contracts/DefaultOApp.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.19;

contract DefaultOApp {}
contract DefaultOApp {
mapping(uint256 => address) public peers;

function setPeer(uint256 eid, address peer) external {
peers[eid] = peer;
}
}
57 changes: 50 additions & 7 deletions packages/ua-utils-evm-hardhat-test/test/builder.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { expect } from 'chai'
import hre from 'hardhat'
import { describe } from 'mocha'
import { eidAndDeploymentToPoint, OmniGraphBuilderHardhat } from '@layerzerolabs/ua-utils-evm-hardhat'
import {
eidAndContractToPoint,
eidAndDeploymentToPoint,
OmniGraphBuilderHardhat,
} from '@layerzerolabs/ua-utils-evm-hardhat'
import { getNetworkRuntimeEnvironment } from '@layerzerolabs/utils-evm-hardhat'
import { arePointsEqual, OmniPoint } from '@layerzerolabs/ua-utils'
import assert from 'assert'
Expand All @@ -23,7 +27,35 @@ describe('builder', () => {
vengaboysDeployment
)

const builder = await OmniGraphBuilderHardhat.fromDeployedContract(hre, 'DefaultOApp')
const builder = await OmniGraphBuilderHardhat.fromDeployedContract(
hre,
'DefaultOApp',
async (contract, builder, eid) => {
builder.addNodes({ point: eidAndContractToPoint(eid, contract), config: undefined })

const [peerBritney, peerVengaboys] = await Promise.all([
contract.peers(britneyEnv.network.config.endpointId),
contract.peers(vengaboysEnv.network.config.endpointId),
])

builder.addEdges(
{
vector: {
from: eidAndContractToPoint(eid, contract),
to: { eid: britneyEnv.network.config.endpointId!, address: peerBritney },
},
config: undefined,
},
{
vector: {
from: eidAndContractToPoint(eid, contract),
to: { eid: vengaboysEnv.network.config.endpointId!, address: peerVengaboys },
},
config: undefined,
}
)
}
)

expect(builder.graph).to.eql({
contracts: [
Expand All @@ -36,7 +68,6 @@ describe('builder', () => {
config: undefined,
},
],
connections: [],
})
})

Expand All @@ -60,7 +91,13 @@ describe('builder', () => {
)

// First we create a builder using the redeployed contracts
const oldBuilder = await OmniGraphBuilderHardhat.fromDeployedContract(hre, 'DefaultOApp')
const oldBuilder = await OmniGraphBuilderHardhat.fromDeployedContract(
hre,
'DefaultOApp',
(contract, builder, eid) => {
builder.addNodes({ point: { eid, address: contract.address }, config: {} })
}
)

// Now we redeploy one of the contracts
const [_, deployer] = await britneyEnv.getUnnamedAccounts()
Expand All @@ -79,18 +116,24 @@ describe('builder', () => {
// As a sanity check, we make sure the deployment has actually changed
expect(arePointsEqual(newBritneyPoint, oldBritneyPoint)).to.be.false

const builder = await OmniGraphBuilderHardhat.fromDeployedContract(hre, 'DefaultOApp')
const builder = await OmniGraphBuilderHardhat.fromDeployedContract(
hre,
'DefaultOApp',
(contract, builder, eid) => {
builder.addNodes({ point: { eid, address: contract.address }, config: {} })
}
)

expect(oldBuilder.graph).not.to.eql(builder.graph)
expect(builder.graph).to.eql({
contracts: [
{
point: oldVengaboysPoint,
config: undefined,
config: {},
},
{
point: newBritneyPoint,
config: undefined,
config: {},
},
],
connections: [],
Expand Down
2 changes: 2 additions & 0 deletions packages/ua-utils-evm-hardhat/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"lint": "npx eslint '**/*.{js,ts,json}'"
},
"devDependencies": {
"@ethersproject/contracts": "^5.7.0",
"@gnosis.pm/safe-core-sdk": "^2.0.0",
"@gnosis.pm/safe-core-sdk-types": "^1.0.0",
"@gnosis.pm/safe-ethers-lib": "^1.0.0",
Expand All @@ -55,6 +56,7 @@
"zod": "^3.22.4"
},
"peerDependencies": {
"@ethersproject/contracts": "^5.7.0",
"@gnosis.pm/safe-core-sdk": "^2.0.0",
"@gnosis.pm/safe-core-sdk-types": "^1.0.0",
"@gnosis.pm/safe-ethers-lib": "^1.0.0",
Expand Down
64 changes: 46 additions & 18 deletions packages/ua-utils-evm-hardhat/src/omnigraph/builder.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,59 @@
import 'hardhat-deploy/dist/src/type-extensions'
import type { HardhatRuntimeEnvironment } from 'hardhat/types'
import type { Deployment } from 'hardhat-deploy/types'
import { OmniGraphBuilder } from '@layerzerolabs/ua-utils'
import { createNetworkLogger, getNetworkRuntimeEnvironment } from '@layerzerolabs/utils-evm-hardhat'
import { contractNameToPoint } from './coordinates'
import { createNetworkEnvironmentFactory, createProviderFactory } from '@layerzerolabs/utils-evm-hardhat'
import { Contract } from '@ethersproject/contracts'
import { EndpointId } from '@layerzerolabs/lz-definitions'
import { contractNameToDeployments } from './coordinates'

export class OmniGraphBuilderHardhat<TNodeConfig, TEdgeConfig> extends OmniGraphBuilder<TNodeConfig, TEdgeConfig> {
static async fromDeployedContract(
static async fromDeployedContract<TNodeConfig, TEdgeConfig>(
hre: HardhatRuntimeEnvironment,
contractName: string
): Promise<OmniGraphBuilder<undefined, undefined>> {
const builder = new OmniGraphBuilder<undefined, undefined>()
contractName: string,
onInstance: (
contract: Contract,
builder: OmniGraphBuilderHardhat<TNodeConfig, TEdgeConfig>,
eid: EndpointId,
env: HardhatRuntimeEnvironment
) => void | Promise<void>
): Promise<OmniGraphBuilderHardhat<TNodeConfig, TEdgeConfig>> {
const builder = new OmniGraphBuilderHardhat<TNodeConfig, TEdgeConfig>()
const deployments = await contractNameToDeployments(hre, contractName)
const providerFactory = createProviderFactory(hre)
const networkEnvironmentFactory = createNetworkEnvironmentFactory(hre)

for (const networkName of Object.keys(hre.config.networks)) {
const logger = createNetworkLogger(networkName)
const env = await getNetworkRuntimeEnvironment(networkName)
const point = await contractNameToPoint(env, contractName)
for (const [eid, deployment] of deployments) {
const env = await networkEnvironmentFactory(eid)
const provider = await providerFactory(eid)
const contract = new Contract(deployment.address, deployment.abi, provider)

if (point == null) {
logger.warn(`Could not find contract '${contractName}'`)
logger.warn(``)
logger.warn(`- Make sure the contract has been deployed`)
logger.warn(`- Make sure to include the endpointId in your hardhat networks config`)
await onInstance(contract, builder, eid, env)
}

return builder
}

static async fromDeployments<TNodeConfig, TEdgeConfig>(
hre: HardhatRuntimeEnvironment,
deployments: Map<EndpointId, Deployment>,
onInstance: (
contract: Contract,
builder: OmniGraphBuilderHardhat<TNodeConfig, TEdgeConfig>,
eid: EndpointId,
env: HardhatRuntimeEnvironment
) => void | Promise<void>
): Promise<OmniGraphBuilderHardhat<TNodeConfig, TEdgeConfig>> {
const builder = new OmniGraphBuilderHardhat<TNodeConfig, TEdgeConfig>()
const providerFactory = createProviderFactory(hre)
const networkEnvironmentFactory = createNetworkEnvironmentFactory(hre)

continue
}
for (const [eid, deployment] of deployments) {
const env = await networkEnvironmentFactory(eid)
const provider = await providerFactory(eid)
const contract = new Contract(deployment.address, deployment.abi, provider)

builder.addNodes({ point, config: undefined })
await onInstance(contract, builder, eid, env)
}

return builder
Expand Down
36 changes: 24 additions & 12 deletions packages/ua-utils-evm-hardhat/src/omnigraph/coordinates.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
import 'hardhat-deploy/dist/src/type-extensions'
import '@layerzerolabs/utils-evm-hardhat/type-extensions'
import type { Contract } from '@ethersproject/contracts'
import type { EndpointId } from '@layerzerolabs/lz-definitions'
import type { OmniPoint } from '@layerzerolabs/ua-utils'
import type { Deployment } from 'hardhat-deploy/types'
import { HardhatRuntimeEnvironment } from 'hardhat/types'
import { assertHardhatDeploy } from '@/internal/assertions'
import { getNetworkNamesByEid, getNetworkRuntimeEnvironment } from '@layerzerolabs/utils-evm-hardhat'

export const contractNameToPoint = async (
export const eidAndDeploymentToPoint = (eid: EndpointId, { address }: Deployment): OmniPoint => ({
eid,
address,
})

export const eidAndContractToPoint = (eid: EndpointId, { address }: Contract): OmniPoint => ({
eid,
address,
})

export const contractNameToDeployments = async (
hre: HardhatRuntimeEnvironment,
contractName: string
): Promise<OmniPoint | undefined> => {
): Promise<Map<EndpointId, Deployment>> => {
assertHardhatDeploy(hre)

const eid = hre.network.config.endpointId
if (eid == null) return undefined
const deploymentsByEid: Map<EndpointId, Deployment> = new Map()
const networkNamesByEid = getNetworkNamesByEid(hre)

const deployment = await hre.deployments.getOrNull(contractName)
if (deployment == null) return undefined
for (const [eid, networkName] of networkNamesByEid) {
const env = await getNetworkRuntimeEnvironment(networkName)
const deployment = await env.deployments.getOrNull(contractName)
if (deployment == null) continue

return eidAndDeploymentToPoint(eid, deployment)
}
deploymentsByEid.set(eid, deployment)
}

export const eidAndDeploymentToPoint = (eid: EndpointId, { address }: Deployment): OmniPoint => ({
eid,
address,
})
return deploymentsByEid
}
3 changes: 3 additions & 0 deletions packages/ua-utils-evm/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.turbo
dist
node_modules
3 changes: 3 additions & 0 deletions packages/ua-utils-evm/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../.eslintrc.json"
}
23 changes: 23 additions & 0 deletions packages/ua-utils-evm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<p align="center">
<a href="https://layerzero.network">
<img alt="LayerZero" style="max-width: 500px" src="https://d3a2dpnnrypp5h.cloudfront.net/bridge-app/lz.png"/>
</a>
</p>

<h1 align="center">@layerzerolabs/ua-utils-evm</h1>

<!-- The badges section -->
<p align="center">
<!-- Shields.io NPM published package version -->
<a href="https://www.npmjs.com/package/@layerzerolabs/ua-utils-evm"><img alt="NPM Version" src="https://img.shields.io/npm/v/@layerzerolabs/ua-utils-evm"/></a>
<!-- Shields.io NPM downloads -->
<a href="https://www.npmjs.com/package/@layerzerolabs/ua-utils-evm"><img alt="Downloads" src="https://img.shields.io/npm/dm/@layerzerolabs/ua-utils-evm"/></a>
<!-- Shields.io license badge -->
<a href="https://www.npmjs.com/package/@layerzerolabs/ua-utils-evm"><img alt="NPM License" src="https://img.shields.io/npm/l/@layerzerolabs/ua-utils-evm"/></a>
</p>

## Installation

```sh
$ npm install @layerzerolabs/ua-utils-evm
```
8 changes: 8 additions & 0 deletions packages/ua-utils-evm/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};
55 changes: 55 additions & 0 deletions packages/ua-utils-evm/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
{
"name": "@layerzerolabs/ua-utils-evm",
"version": "0.1.0",
"private": true,
"description": "Utilities for working with LayerZero contracts",
"repository": {
"type": "git",
"url": "git+https://github.com/LayerZero-Labs/lz-utils.git",
"directory": "packages/ua-utils-evm"
},
"license": "MIT",
"exports": {
".": {
"types": "./dist/index.d.ts",
"require": "./dist/index.js",
"import": "./dist/index.mjs"
}
},
"main": "dist/index.js",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"files": [
"dist/"
],
"scripts": {
"prebuild": "tsc -noEmit",
"build": "npx tsup",
"clean": "rm -rf dist",
"lint": "npx eslint '**/*.{js,ts,json}'",
"test": "jest"
},
"devDependencies": {
"@ethersproject/constants": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@layerzerolabs/lz-definitions": "~1.5.62",
"@layerzerolabs/test-utils": "~0.0.1",
"@layerzerolabs/ua-utils": "~0.1.0",
"@layerzerolabs/utils-evm": "~0.0.1",
"@types/jest": "^29.5.10",
"fast-check": "^3.14.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"tslib": "~2.6.2",
"tsup": "^7.2.0",
"typescript": "^5.2.2",
"zod": "^3.22.4"
},
"peerDependencies": {
"@layerzerolabs/lz-definitions": "~1.5.62",
"@layerzerolabs/ua-utils": "~0.0.1",
"@layerzerolabs/utils-evm": "~0.0.1",
"zod": "^3.22.4"
}
}
20 changes: 20 additions & 0 deletions packages/ua-utils-evm/src/oapp/sdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Address, OAppSdk, OmniTransaction } from '@layerzerolabs/ua-utils'
import { omniContractToPoint, OmniContract, ignoreZero } from '@layerzerolabs/utils-evm'
import { EndpointId } from '@layerzerolabs/lz-definitions'

export class OAppEvmSdk implements OAppSdk {
constructor(public readonly contract: OmniContract) {}

async peers(eid: EndpointId): Promise<string | undefined> {
return ignoreZero(await this.contract.contract.peers(eid))
}

async setPeer(eid: EndpointId, address: Address): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('setPeer', [eid, address])

return {
point: omniContractToPoint(this.contract),
data,
}
}
}
11 changes: 11 additions & 0 deletions packages/ua-utils-evm/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"exclude": ["dist", "node_modules"],
"include": ["src", "test"],
"compilerOptions": {
"types": ["node", "jest"],
"paths": {
"@/*": ["./src/*"]
}
}
}
Loading

0 comments on commit 7ae2991

Please sign in to comment.