Skip to content

Commit

Permalink
feat: options builder
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Goulding <[email protected]>
  • Loading branch information
ryandgoulding committed Dec 12, 2023
1 parent 1185ca7 commit 8334e95
Show file tree
Hide file tree
Showing 12 changed files with 2,248 additions and 75 deletions.
21 changes: 21 additions & 0 deletions packages/omnicounter-utils-evm/src/omnicounter/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pMemoize from 'p-memoize'
import { OmniCounterApp } from '@/omnicounter/sdk'
import { createEndpointFactory } from '@layerzerolabs/protocol-utils-evm'
import { EndpointFactory } from '@layerzerolabs/protocol-utils'
import { OAppFactory } from '@layerzerolabs/ua-utils'
import { OmniContractFactory } from '@layerzerolabs/utils-evm'

/**
* Syntactic sugar that creates an instance of EVM `OmniCounterApp` SDK
* based on an `OmniPoint` with help of an `OmniContractFactory`
* and an (optional) `EndpointFactory`
*
* @param {OmniContractFactory} contractFactory
* @param {EndpointFactory} [endpointFactory]
* @returns {EndpointFactory<Endpoint>}
*/
export const createOmniCounterAppFactory = (
contractFactory: OmniContractFactory,
endpointFactory: EndpointFactory = createEndpointFactory(contractFactory)
): OAppFactory<OmniCounterApp> =>
pMemoize(async (point) => new OmniCounterApp(await contractFactory(point), endpointFactory))
1 change: 1 addition & 0 deletions packages/omnicounter-utils-evm/src/omnicounter/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './factory'
export * from './sdk'
9 changes: 9 additions & 0 deletions packages/omnicounter-utils-evm/src/omnicounter/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { IOmniCounterApp } from '@layerzerolabs/omnicounter-utils'
import { EndpointFactory } from '@layerzerolabs/protocol-utils'
import { OApp } from '@layerzerolabs/ua-utils-evm'
import { OmniTransaction } from '@layerzerolabs/utils'
import { OmniContract } from '@layerzerolabs/utils-evm'

export class OmniCounterApp extends OApp implements IOmniCounterApp {
public constructor(
public override contract: OmniContract,
protected override endpointFactory: EndpointFactory
) {
super(contract, endpointFactory)
}

public async increment(eid: number, type: number, options: string): Promise<OmniTransaction> {
const data = this.contract.contract.interface.encodeFunctionData('increment', [eid, type, options])
return super.createTransaction(data)
Expand Down
8 changes: 8 additions & 0 deletions packages/ua-utils-evm-hardhat-test/contracts/OmniCounter.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.22;

import { OmniCounter as OmniCounterImpl } from "@layerzerolabs/lz-evm-oapp-v2/contracts/oapp/examples/OmniCounter.sol";

contract OmniCounterOApp is OmniCounterImpl {
constructor(address _endpoint, address _owner) OmniCounterImpl(_endpoint, _owner) {}
}
38 changes: 22 additions & 16 deletions packages/ua-utils-evm-hardhat-test/deploy/001_bootstrap.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,32 @@
import { type DeployFunction } from 'hardhat-deploy/types'
import assert from 'assert'
import { TransactionReceipt, TransactionResponse } from '@ethersproject/providers'
import { formatEid } from '@layerzerolabs/utils'
import { wrapEIP1193Provider } from '@layerzerolabs/utils-evm-hardhat'
import env from 'hardhat'
import { Contract } from 'ethers'
import { TransactionReceipt, TransactionResponse } from '@ethersproject/providers'
import assert from 'assert'
import { Contract, ethers } from 'ethers'
import { HardhatRuntimeEnvironment } from 'hardhat/types'

const DEFAULT_NATIVE_DECIMALS_RATE = '18' //ethers.utils.parseUnits('1', 18).toString()
const DEFAULT_NATIVE_DECIMALS_RATE = ethers.utils.parseUnits('1', 18).toString()

/**
* This deploy function will deploy and configure LayerZero endpoint
* This `deploy` function will deploy and configure LayerZero EndpointV2. This includes:
* - EndpointV2
* - SendUln302
* - ReceiveUln302
* - PriceFeed
* - Executor
* - ExecutorFeeLib
* - DVN
* - DVNFeeLib
*
* @param env `HardhatRuntimeEnvironment`
* @param {HardhatRuntimeEnvironment} env
*/
const deploy: DeployFunction = async ({ getUnnamedAccounts, deployments, network }) => {
const deploy: DeployFunction = async ({ getUnnamedAccounts, deployments, network }: HardhatRuntimeEnvironment) => {
assert(network.config.eid != null, `Missing endpoint ID for network ${network.name}`)

const [deployer] = await getUnnamedAccounts()
assert(deployer, 'Missing deployer')
const signer = wrapEIP1193Provider(network.provider).getSigner()

await deployments.delete('EndpointV2')
const endpointV2Deployment = await deployments.deploy('EndpointV2', {
Expand Down Expand Up @@ -95,13 +104,12 @@ const deploy: DeployFunction = async ({ getUnnamedAccounts, deployments, network
},
})

const signer = wrapEIP1193Provider(env.network.provider).getSigner()
const executorContract = new Contract(executor.address, executor.abi).connect(signer)
const setExecFeeLibResp: TransactionResponse = await executorContract.setWorkerFeeLib?.(executorFeeLib.address, {
from: await signer.getAddress(),
})
const setExecFeeLibReceipt: TransactionReceipt = await setExecFeeLibResp.wait()
const setExecFeeLibResp: TransactionResponse = await executorContract.setWorkerFeeLib(executorFeeLib.address)
const setExecFeeLibReceipt: TransactionReceipt = await setExecFeeLibResp.wait(1)
assert(setExecFeeLibReceipt?.status === 1)
const executorWorkerFeeLib = await executorContract.workerFeeLib?.()
console.dir({ executorWorkerFeeLib }, { depth: null })

await deployments.delete('DVN')
const dvn = await deployments.deploy('DVN', {
Expand All @@ -123,9 +131,7 @@ const deploy: DeployFunction = async ({ getUnnamedAccounts, deployments, network
})

const dvnContract = new Contract(dvn.address, dvn.abi).connect(signer)
const setDvnFeeLibResp: TransactionResponse = await dvnContract.setWorkerFeeLib?.(dvnFeeLib.address, {
from: await signer.getAddress(),
})
const setDvnFeeLibResp: TransactionResponse = await dvnContract.setWorkerFeeLib?.(dvnFeeLib.address)
const setDvnFeeLibReceipt: TransactionReceipt = await setDvnFeeLibResp.wait()
assert(setDvnFeeLibReceipt?.status === 1)

Expand Down
32 changes: 32 additions & 0 deletions packages/ua-utils-evm-hardhat-test/deploy/003_omnicounteroapp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { formatEid } from '@layerzerolabs/utils'
import { type DeployFunction } from 'hardhat-deploy/types'
import assert from 'assert'

/**
* This deploy function will deploy and configure LayerZero OmniCounter
*
* @param env `HardhatRuntimeEnvironment`
*/
const deploy: DeployFunction = async ({ getUnnamedAccounts, deployments, network }) => {
assert(network.config.eid != null, `Missing endpoint ID for network ${network.name}`)

const [deployer] = await getUnnamedAccounts()
assert(deployer, 'Missing deployer')

await deployments.delete('OmniCounterOApp')
const endpointV2 = await deployments.get('EndpointV2')
const omniCounterDeployment = await deployments.deploy('OmniCounterOApp', {
from: deployer,
args: [endpointV2.address, deployer],
})

console.table({
Network: `${network.name} (endpoint ${formatEid(network.config.eid)})`,
OmniCounterOApp: omniCounterDeployment.address,
})
}

deploy.tags = ['OApp', 'OmniCounterOApp']
deploy.dependencies = ['Bootstrap']

export default deploy
2 changes: 1 addition & 1 deletion packages/ua-utils-evm-hardhat-test/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testTimeout: 15000,
testTimeout: 60000,
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
Expand Down
3 changes: 3 additions & 0 deletions packages/ua-utils-evm-hardhat-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"@layerzerolabs/lz-evm-sdk-v1": "~1.5.72",
"@layerzerolabs/lz-evm-sdk-v2": "~1.5.72",
"@layerzerolabs/lz-utility-v2": "~1.5.72",
"@layerzerolabs/omnicounter-utils": "~0.0.1",
"@layerzerolabs/omnicounter-utils-evm": "~0.0.1",
"@layerzerolabs/protocol-utils": "~0.0.1",
"@layerzerolabs/protocol-utils-evm": "~0.0.1",
"@layerzerolabs/toolbox-hardhat": "~0.0.1",
Expand All @@ -45,6 +47,7 @@
"hardhat": "^2.19.2",
"hardhat-deploy": "^0.11.43",
"jest": "^29.7.0",
"solidity-bytes-utils": "^0.8.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
Expand Down
10 changes: 10 additions & 0 deletions packages/ua-utils-evm-hardhat-test/test/__utils__/omnicounter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { EndpointId } from '@layerzerolabs/lz-definitions'
import { createNetworkEnvironmentFactory } from '@layerzerolabs/utils-evm-hardhat'
import deploy from '../../deploy/003_omnicounteroapp'

export const deployOmniCounter = async () => {
const environmentFactory = createNetworkEnvironmentFactory()

await deploy(await environmentFactory(EndpointId.ETHEREUM_MAINNET))
await deploy(await environmentFactory(EndpointId.AVALANCHE_MAINNET))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'hardhat'
import { TransactionReceipt } from '@ethersproject/providers'
import { EndpointId, MainnetEndpointId } from '@layerzerolabs/lz-definitions'
import { Options } from '@layerzerolabs/lz-utility-v2'
import { createOmniCounterAppFactory } from '@layerzerolabs/omnicounter-utils-evm'
import { configureOApp } from '@layerzerolabs/ua-utils'
import { OmniTransaction } from '@layerzerolabs/utils'
import { omniContractToPoint } from '@layerzerolabs/utils-evm'
import {
createConnectedContractFactory,
createSignerFactory,
OmniGraphBuilderHardhat,
OmniGraphHardhat,
} from '@layerzerolabs/utils-evm-hardhat'
import { setupDefaultEndpoint } from '../__utils__/endpoint'
import { deployOmniCounter } from '../__utils__/omnicounter'

describe('oapp/options', () => {
const ethContract = { eid: EndpointId.ETHEREUM_MAINNET, contractName: 'OmniCounterOApp' }
const avaxContract = { eid: EndpointId.AVALANCHE_MAINNET, contractName: 'OmniCounterOApp' }

const config: OmniGraphHardhat = {
contracts: [
{
contract: ethContract,
},
{
contract: avaxContract,
},
],
connections: [
{
from: ethContract,
to: avaxContract,
},
{
from: avaxContract,
to: ethContract,
},
],
}

beforeEach(async () => {
await setupDefaultEndpoint()
await deployOmniCounter()
})

it('lzReceive option', async () => {
const contractFactory = createConnectedContractFactory()
const builder = await OmniGraphBuilderHardhat.fromConfig(config)
const sdkFactory = createOmniCounterAppFactory(contractFactory)
const signerFactory = createSignerFactory()

const ethPoint = omniContractToPoint(await contractFactory(ethContract))
const ethSdk = await sdkFactory(ethPoint)
const ethSigner = await signerFactory(ethContract.eid)

const avaxPoint = omniContractToPoint(await contractFactory(avaxContract))
const avaxSdk = await sdkFactory(avaxPoint)
const avaxSigner = await signerFactory(avaxContract.eid)

const transactions = await configureOApp(builder.graph, sdkFactory)
for (const transaction of transactions) {
const signer = transaction.point.eid === MainnetEndpointId.ETHEREUM_MAINNET ? ethSigner : avaxSigner
const txResponse = await signer.signAndSend(transaction)
const txReceipt: TransactionReceipt = await txResponse.wait()
expect(txReceipt.status).toBe(1)
}

expect(await ethSdk.hasPeer(avaxPoint.eid, avaxPoint.address)).toBe(true)
expect(await avaxSdk.hasPeer(ethPoint.eid, ethPoint.address)).toBe(true)

const options = Options.newOptions().addExecutorLzReceiveOption(200000)
console.dir(
{
options: options.toHex(),
},
{ depth: null }
)
const incrementTx: OmniTransaction = {
...(await ethSdk.increment(avaxPoint.eid, 1, options.toHex())),
gasLimit: 2000000,
value: '1000000000000000000',
}
const incrementTxResponse = await ethSigner.signAndSend(incrementTx)
const incrementTxReceipt: TransactionReceipt = await incrementTxResponse.wait()
expect(incrementTxReceipt.status).toEqual(1)
})
})
2 changes: 1 addition & 1 deletion packages/ua-utils-evm/src/oapp/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { OmniSDK } from '@layerzerolabs/utils-evm'
export class OApp extends OmniSDK implements IOApp {
constructor(
contract: OmniContract,
private readonly endpointFactory: EndpointFactory
protected readonly endpointFactory: EndpointFactory
) {
super(contract)
}
Expand Down
Loading

0 comments on commit 8334e95

Please sign in to comment.