Skip to content

Commit

Permalink
Merge branch 'goulding/krak/aptops-v2-examples' of https://github.com…
Browse files Browse the repository at this point in the history
…/LayerZero-Labs/devtools into goulding/krak/aptops-v2-examples
  • Loading branch information
AlexanderLiteplo committed Jan 12, 2025
2 parents d6a7963 + 47bbb2d commit e1ead74
Show file tree
Hide file tree
Showing 20 changed files with 1,073 additions and 1,586 deletions.
5 changes: 5 additions & 0 deletions examples/oft-move/hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ const config: HardhatUserConfig = {
url: process.env.RPC_URL_ETHEREUM_TESTNET || 'https://sepolia.infura.io/v3/',
accounts,
},
'solana-devnet': {
eid: EndpointId.SOLANA_V2_TESTNET.valueOf(),
url: process.env.RPC_URL_SOLANA_TESTNET || 'https://api.devnet.solana.com',
accounts,
},
hardhat: {
// Need this for testing because TestHelperOz5.sol is exceeding the compiled contract size limit
allowUnlimitedContractSize: true,
Expand Down
68 changes: 67 additions & 1 deletion examples/oft-move/move.layerzero.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ const ethContract: OmniPointHardhat = {
contractName: 'MyOFT',
}

const solanaContract: OmniPointHardhat = {
eid: EndpointId.SOLANA_V2_TESTNET,
contractName: 'MyOFT',
}

const config: OAppOmniGraphHardhat = {
contracts: [
{
Expand Down Expand Up @@ -155,7 +160,68 @@ const config: OAppOmniGraphHardhat = {
},
receiveLibraryTimeoutConfig: {
lib: '0x188d4bbCeD671A7aA2b5055937F79510A32e9683',
expiry: BigInt(500),
expiry: BigInt(67323472),
},
sendConfig: {
executorConfig: {
maxMessageSize: 65536,
executor: '0x31894b190a8bAbd9A067Ce59fde0BfCFD2B18470',
},
ulnConfig: {
confirmations: BigInt(5),
requiredDVNs: [
'0x0eE552262f7B562eFcED6DD4A7e2878AB897d405',
'0x6f99eA3Fc9206E2779249E15512D7248dAb0B52e',
],
optionalDVNs: [
'0x2dDf08e397541721acD82E5b8a1D0775454a180B',
'0x6F978ee5bfd7b1A8085A3eA9e54eB76e668E195a',
],
optionalDVNThreshold: 1,
},
},
receiveConfig: {
ulnConfig: {
confirmations: BigInt(5),
requiredDVNs: [
'0x0eE552262f7B562eFcED6DD4A7e2878AB897d405',
'0x6f99eA3Fc9206E2779249E15512D7248dAb0B52e',
],
optionalDVNs: [
'0x2dDf08e397541721acD82E5b8a1D0775454a180B',
'0x6F978ee5bfd7b1A8085A3eA9e54eB76e668E195a',
],
optionalDVNThreshold: 1,
},
},
},
},
{
from: bscContract,
to: solanaContract,
config: {
enforcedOptions: [
{
msgType: 1,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 200000, // gas limit in wei for EndpointV2.lzReceive
value: 0, // msg.value in wei for EndpointV2.lzReceive
},
{
msgType: 2,
optionType: ExecutorOptionType.LZ_RECEIVE,
gas: 200000, // gas limit in wei for EndpointV2.lzCompose
value: 0, // msg.value in wei for EndpointV2.lzCompose
},
],
sendLibrary: '0x55f16c442907e86D764AFdc2a07C2de3BdAc8BB7',
receiveLibraryConfig: {
receiveLibrary: '0x188d4bbCeD671A7aA2b5055937F79510A32e9683',
gracePeriod: BigInt(0),
},
receiveLibraryTimeoutConfig: {
lib: '0x188d4bbCeD671A7aA2b5055937F79510A32e9683',
expiry: BigInt(67323472),
},
sendConfig: {
executorConfig: {
Expand Down
6 changes: 4 additions & 2 deletions packages/devtools-move/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,24 @@
},
"dependencies": {
"@types/chai": "^4.3.11",
"@types/jest": "^29.5.12",
"chai": "^4.4.1",
"jest": "^29.7.0",
"ts-jest": "^29.2.5"
},
"devDependencies": {
"@aptos-labs/ts-sdk": "^1.33.1",
"@layerzerolabs/devtools-extensible-cli": "^0.0.1",
"@layerzerolabs/lz-definitions": "^3.0.21",
"@layerzerolabs/lz-definitions": "^3.0.40",
"@layerzerolabs/lz-evm-sdk-v2": "^3.0.27",
"@layerzerolabs/lz-serdes": "^3.0.19",
"@layerzerolabs/lz-v2-utilities": "^3.0.12",
"@layerzerolabs/toolbox-hardhat": "~0.6.3",
"@types/argparse": "^2.0.17",
"@types/jest": "^29.5.12",
"@types/node": "~18.18.14",
"argparse": "^2.0.1",
"base-x": "^5.0.0",
"bs58": "^6.0.0",
"depcheck": "^1.4.7",
"dotenv": "^16.4.7",
"ethers": "^5.7.2",
Expand Down
10 changes: 5 additions & 5 deletions packages/devtools-move/tasks/evm/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ export type eid = string
export type EidTxMap = Record<eid, [PopulatedTransaction]>
export type address = string

export type NonEvmOAppMetadata = {
address: address
type WireOntoOapp = {
eid: eid
rpc: string
address: address
}

export type ContractMetadata = {
Expand All @@ -33,6 +32,7 @@ export type ContractMetadata = {
oapp: ethers.Contract
epv2: ethers.Contract
}
wireOntoOapps: WireOntoOapp[]
provider: ethers.providers.JsonRpcProvider
configAccount: OAppNodeConfig
configOapp: OAppEdgeConfig | undefined
Expand All @@ -48,8 +48,8 @@ export type AccountData = {
//[TxTypes][eid] = PopulatedTransaction
export type TxEidMapping = Record<TxTypes, EidTxMap>

//[number][address] = ContractMetadata
export type ContractMetadataMapping = Record<eid, ContractMetadata>
//[fromEid as number] = ContractMetadata
export type OmniContractMetadataMapping = Record<eid, ContractMetadata>

export type enforcedOptionParam = {
eid: eid
Expand Down
101 changes: 52 additions & 49 deletions packages/devtools-move/tasks/evm/wire-evm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import { Contract, ethers } from 'ethers'

import { getDeploymentAddressAndAbi } from '@layerzerolabs/lz-evm-sdk-v2'

import { getEidFromMoveNetwork, getLzNetworkStage, parseYaml } from '../move/utils/aptosNetworkParser'
import { getMoveVMOftAddress } from '../move/utils/utils'
import { createEidToNetworkMapping, getConfigConnections, getHHAccountConfig } from '../shared/utils'
import { createEidToNetworkMapping, getConfigConnectionsFromChainType, getHHAccountConfig } from '../shared/utils'

import AnvilForkNode from './utils/anvilForkNode'
import { createSetDelegateTransactions } from './wire/setDelegate'
Expand All @@ -18,11 +16,12 @@ import { createSetSendConfigTransactions } from './wire/setSendConfig'
import { createSetSendLibraryTransactions } from './wire/setSendLibrary'
import { executeTransactions } from './wire/transactionExecutor'

import type { ContractMetadataMapping, NonEvmOAppMetadata, TxEidMapping } from './utils/types'
import type { OmniContractMetadataMapping, TxEidMapping } from './utils/types'
import path from 'path'
import dotenv from 'dotenv'
import { getNetworkForChainId } from '@layerzerolabs/lz-definitions'
import { OAppOmniGraphHardhat } from '@layerzerolabs/toolbox-hardhat'
import { getNetworkForChainId, ChainType } from '@layerzerolabs/lz-definitions'
import { OAppEdgeConfig, OmniEdgeHardhat } from '@layerzerolabs/toolbox-hardhat'
import { createSetReceiveLibraryTimeoutTransactions } from './wire/setReceiveLibraryTimeout'

/**
* @description Handles wiring of EVM contracts with the Aptos OApp
Expand All @@ -43,12 +42,8 @@ async function wireEvm(args: any) {
process.exit(1)
}

const { network } = await parseYaml()
const EID_APTOS = getEidFromMoveNetwork('aptos', network)
const globalConfigPath = path.resolve(path.join(args.rootDir, args.oapp_config))
// @todo grow connectionsToWire by taking in non-evm connections instead of only APTOS.
const connectionsToWire = await getConfigConnections('to', EID_APTOS, globalConfigPath)

const connectionsToWire = await getConfigConnectionsFromChainType('from', ChainType.EVM, globalConfigPath)
const accountConfigs = await getHHAccountConfig(globalConfigPath)
const networks = await createEidToNetworkMapping('networkName')
const rpcUrls = await createEidToNetworkMapping('url')
Expand All @@ -66,34 +61,29 @@ async function wireEvm(args: any) {
}

// Indexed by the eid it contains information about the contract, provider, and configuration of the account and oapp.
const contractMetaData: ContractMetadataMapping = {}

// @todo Use this as a primary key for NonEvmOAppWiring in the following code
const lzNetworkStage = getLzNetworkStage(network)
const APTOS_OAPP_ADDRESS = getMoveVMOftAddress(lzNetworkStage)

const nonEvmOapp: NonEvmOAppMetadata = {
address: APTOS_OAPP_ADDRESS,
eid: EID_APTOS.toString(),
rpc: rpcUrls[EID_APTOS],
}
const omniContracts: OmniContractMetadataMapping = {}

logPathwayHeader(connectionsToWire)
/*
* Looping through the connections we build out the contractMetaData and TxTypeEidMapping by reading from the deployment files.
* contractMetaData contains ethers Contract objects for the OApp and EndpointV2 contracts.
* Looping through the connections we build out the omniContracts and TxTypeEidMapping by reading from the deployment files.
* omniContracts contains ethers Contract objects for the OApp and EndpointV2 contracts.
*/
for (const conn of connectionsToWire) {
logPathwayHeader(conn)

const fromEid = conn.from.eid
const toEid = conn.to.eid
const fromNetwork = networks[fromEid]
const toNetwork = networks[toEid]
const configOapp = conn?.config

const provider = new ethers.providers.JsonRpcProvider(rpcUrls[fromEid])
const signer = new ethers.Wallet(privateKey, provider)

const OAppDeploymentPath = path.resolve(`deployments/${fromNetwork}/${conn.from.contractName}.json`)
const OAppDeploymentData = JSON.parse(fs.readFileSync(OAppDeploymentPath, 'utf8'))

const WireOAppDeploymentPath = path.resolve(`deployments/${toNetwork}/${conn.to.contractName}.json`)
const WireOAppDeploymentData = JSON.parse(fs.readFileSync(WireOAppDeploymentPath, 'utf8'))

const EndpointV2DeploymentData = getDeploymentAddressAndAbi(fromNetwork, 'EndpointV2')

const { address: oappAddress, abi: oappAbi } = OAppDeploymentData
Expand All @@ -102,7 +92,11 @@ async function wireEvm(args: any) {
const OAppContract = new Contract(oappAddress, oappAbi, signer)
const EPV2Contract = new Contract(epv2Address, epv2Abi, signer)

contractMetaData[fromEid] = {
const currWireOntoOapps = omniContracts[fromEid]?.wireOntoOapps ?? []
const wireOntoOapp = { eid: toEid.toString(), address: WireOAppDeploymentData.address }
currWireOntoOapps.push(wireOntoOapp)

omniContracts[fromEid] = {
address: {
oapp: oappAddress,
epv2: epv2Address,
Expand All @@ -111,54 +105,63 @@ async function wireEvm(args: any) {
oapp: OAppContract,
epv2: EPV2Contract,
},
wireOntoOapps: currWireOntoOapps,
provider: provider,
configAccount: accountConfigs[fromEid],
configOapp: configOapp,
}
}

TxTypeEidMapping.setPeer = await createSetPeerTransactions(contractMetaData, nonEvmOapp)
TxTypeEidMapping.setDelegate = await createSetDelegateTransactions(contractMetaData, nonEvmOapp)
TxTypeEidMapping.setEnforcedOptions = await createSetEnforcedOptionsTransactions(contractMetaData, nonEvmOapp)
TxTypeEidMapping.setSendLibrary = await createSetSendLibraryTransactions(contractMetaData, nonEvmOapp)
TxTypeEidMapping.setReceiveLibrary = await createSetReceiveLibraryTransactions(contractMetaData, nonEvmOapp)
TxTypeEidMapping.sendConfig = await createSetSendConfigTransactions(contractMetaData, nonEvmOapp)
TxTypeEidMapping.receiveConfig = await createSetReceiveConfigTransactions(contractMetaData, nonEvmOapp)

// TxTypeEidMapping.setReceiveLibraryTimeout = await createSetReceiveLibraryTimeoutTransactions(
// contractMetaData,
// nonEvmOapp
// )
TxTypeEidMapping.setPeer = await createSetPeerTransactions(omniContracts)
TxTypeEidMapping.setDelegate = await createSetDelegateTransactions(omniContracts)
TxTypeEidMapping.setEnforcedOptions = await createSetEnforcedOptionsTransactions(omniContracts)
TxTypeEidMapping.setSendLibrary = await createSetSendLibraryTransactions(omniContracts)
TxTypeEidMapping.setReceiveLibrary = await createSetReceiveLibraryTransactions(omniContracts)
TxTypeEidMapping.sendConfig = await createSetSendConfigTransactions(omniContracts)
TxTypeEidMapping.receiveConfig = await createSetReceiveConfigTransactions(omniContracts)
TxTypeEidMapping.setReceiveLibraryTimeout = await createSetReceiveLibraryTimeoutTransactions(omniContracts)

// @todo Clean this up or move to utils
const rpcUrlSelfMap: { [eid: string]: string } = {}
for (const [eid, eidData] of Object.entries(contractMetaData)) {
for (const [eid, eidData] of Object.entries(omniContracts)) {
rpcUrlSelfMap[eid] = eidData.provider.connection.url
}

const anvilForkNode = new AnvilForkNode(rpcUrlSelfMap, 8545)

try {
const forkRpcMap = await anvilForkNode.startNodes()
await executeTransactions(contractMetaData, TxTypeEidMapping, forkRpcMap, 'dry-run', privateKey)
await executeTransactions(contractMetaData, TxTypeEidMapping, rpcUrlSelfMap, 'broadcast', privateKey)
await executeTransactions(omniContracts, TxTypeEidMapping, forkRpcMap, 'dry-run', privateKey)
await executeTransactions(omniContracts, TxTypeEidMapping, rpcUrlSelfMap, 'broadcast', privateKey)
} catch (error) {
anvilForkNode.killNodes()
throw new Error(`Failed to wire EVM contracts: ${error}`)
}
anvilForkNode.killNodes()
}

function logPathwayHeader(connection: OAppOmniGraphHardhat['connections'][number]) {
const fromNetwork = getNetworkForChainId(connection.from.eid)
const toNetwork = getNetworkForChainId(connection.to.eid)
function logPathwayHeader(connections: OmniEdgeHardhat<OAppEdgeConfig | undefined>[]) {
const pathwayStrings = []
let largestPathwayString = 0
console.log('Found wire connection for pathways:')
for (const [_fromEid, eidData] of Object.entries(connections)) {
const fromNetwork = getNetworkForChainId(Number(eidData.from.eid))
const toNetwork = getNetworkForChainId(Number(eidData.to.eid))

const pathwayString = `🔄 Building wire transactions for pathway: ${fromNetwork.chainName}-${fromNetwork.env}${toNetwork.chainName}-${toNetwork.env} 🔄`
const borderLine = '━'.repeat(pathwayString.length)
const pathwayString = `${fromNetwork.chainName}-${fromNetwork.env}${toNetwork.chainName}-${toNetwork.env}`

pathwayStrings.push(pathwayString)
if (pathwayString.length > largestPathwayString) {
largestPathwayString = pathwayString.length
}
}
const borderLine = '━'.repeat(largestPathwayString + 5)
console.log(borderLine)
console.log(pathwayString)
console.log(`${borderLine}\n`)
for (const [index, pathwayString] of pathwayStrings.entries()) {
console.log(`${(index + 1).toString().padStart(2, ' ')}: ${pathwayString}`)
}
console.log(`${borderLine}`)
console.log('🔄 Building wire transactions for all the above pathways.\n')
}

export { wireEvm }
21 changes: 9 additions & 12 deletions packages/devtools-move/tasks/evm/wire/setDelegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,36 @@ import { diffPrinter } from '../../shared/utils'

import { createDiffMessage, printAlreadySet, printNotSet } from '../../shared/messageBuilder'

import type { ContractMetadataMapping, EidTxMap, NonEvmOAppMetadata } from '../utils/types'
import type { OmniContractMetadataMapping, EidTxMap } from '../utils/types'

/**
* @notice Sets delegate for a contract.
* @dev Fetches the current delegate from EndpointV2
* @dev Sets the new delegate on the OApp
* @returns EidTxMap
*/
export async function createSetDelegateTransactions(
eidDataMapping: ContractMetadataMapping,
_nonEvmOapp: NonEvmOAppMetadata
): Promise<EidTxMap> {
export async function createSetDelegateTransactions(eidDataMapping: OmniContractMetadataMapping): Promise<EidTxMap> {
const txTypePool: EidTxMap = {}

for (const [eid, { address, contract, configAccount }] of Object.entries(eidDataMapping)) {
const currDelegate = await getDelegate(contract.epv2, address.oapp)

if (!configAccount?.delegate) {
printNotSet('delegate', Number(eid), Number(_nonEvmOapp.eid))
printNotSet('delegate', Number(eid), Number(eid))
continue
}

const newD = utils.getAddress(configAccount.delegate)
const newDelegate = utils.getAddress(configAccount.delegate)

if (currDelegate === newD) {
printAlreadySet('delegate', Number(eid), Number(_nonEvmOapp.eid))
if (currDelegate === newDelegate) {
printAlreadySet('delegate', Number(eid), Number(eid))
continue
}

const diffMessage = createDiffMessage('delegate', Number(eid), Number(_nonEvmOapp.eid))
diffPrinter(diffMessage, { delegate: currDelegate }, { delegate: newD })
const diffMessage = createDiffMessage('delegate', Number(eid), Number(eid))
diffPrinter(diffMessage, { delegate: currDelegate }, { delegate: newDelegate })

const tx = await contract.oapp.populateTransaction.setDelegate(newD)
const tx = await contract.oapp.populateTransaction.setDelegate(newDelegate)

txTypePool[eid] = txTypePool[eid] ?? []
txTypePool[eid].push(tx)
Expand Down
Loading

0 comments on commit e1ead74

Please sign in to comment.