Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🧹 Decoupling UA SDKs from hardhat deploy #869

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .changeset/unlucky-cameras-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@layerzerolabs/omnicounter-devtools-evm": major
"@layerzerolabs/ua-devtools-evm-hardhat": major
"@layerzerolabs/ua-devtools-evm": major
"@layerzerolabs/devtools-evm": major
"@layerzerolabs/ua-devtools-evm-hardhat-v1-test": patch
"@layerzerolabs/ua-devtools-evm-hardhat-test": patch
"@layerzerolabs/protocol-devtools-evm": patch
"@layerzerolabs/devtools-cli-test": patch
"@layerzerolabs/oft-solana-example": patch
---

Decouple UA SDKs from `hardhat-deploy`

The UA (`OApp`, `Ownable`, `LzApp`, `ERC20`) SDKs now accept a `Provider` and an `ABI` instead of an ethers `Contract` instance. Any code that uses these constructors directly needs to be updated.
4 changes: 2 additions & 2 deletions examples/oft-solana/tasks/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
firstFactory,
formatEid,
} from '@layerzerolabs/devtools'
import { createConnectedContractFactory } from '@layerzerolabs/devtools-evm-hardhat'
import { createProviderFactory } from '@layerzerolabs/devtools-evm-hardhat'
import { OmniSignerSolana, createConnectionFactory, createRpcUrlFactory } from '@layerzerolabs/devtools-solana'
import { ChainType, EndpointId, endpointIdToChainType } from '@layerzerolabs/lz-definitions'
import { IOApp } from '@layerzerolabs/ua-devtools'
Expand All @@ -34,7 +34,7 @@ export const createSdkFactory = (
//
// We do this by using the firstFactory helper function that is provided by the devtools package.
// This function will try to execute the factories one by one and return the first one that succeeds.
const evmSdkfactory = createOAppFactory(createConnectedContractFactory())
const evmSdkfactory = createOAppFactory(createProviderFactory())
const solanaSdkFactory = createOFTFactory(
// The first parameter to createOFTFactory is a user account factory
//
Expand Down
2 changes: 1 addition & 1 deletion packages/devtools-cli/src/commands/oapp/wire/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export const wire = new Command('wire')

// If we are in dry run mode, we'll just print the transactions and exit
if (dryRun) {
printRecords(transactions.map(formatOmniTransaction))
return printRecords(transactions.map(formatOmniTransaction))
}
}
)
21 changes: 11 additions & 10 deletions packages/devtools-evm/src/omnigraph/sdk.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import type { OmniPoint, OmniTransaction } from '@layerzerolabs/devtools'
import { formatOmniPoint, type OmniPoint, type OmniTransaction } from '@layerzerolabs/devtools'
import type { IOmniSDK, OmniContract } from './types'
import { omniContractToPoint } from './coordinates'
import { createContractErrorParser } from '@/errors/parser'
import type { OmniContractErrorParser, OmniContractErrorParserFactory } from '@/errors/types'
import type { ContractError } from '@/errors/errors'
import { Logger, createModuleLogger } from '@layerzerolabs/io-devtools'
import { formatOmniContract } from './format'
import { JsonFragment } from '@ethersproject/abi'
import { Provider } from '@/provider'
import { Contract } from '@ethersproject/contracts'

/**
* Base class for all EVM SDKs, providing some common functionality
Expand Down Expand Up @@ -43,21 +44,21 @@ export abstract class OmniSDK implements IOmniSDK {
}

constructor(
public readonly contract: OmniContract,
protected readonly logger: Logger = createModuleLogger(
`EVM SDK ${new.target.name} @ ${formatOmniContract(contract)}`
)
public readonly provider: Provider,
public readonly point: OmniPoint,
public readonly abi: JsonFragment[],
protected readonly logger: Logger = createModuleLogger(`EVM SDK ${new.target.name} @ ${formatOmniPoint(point)}`)
) {}

/**
* Human radable label for this SDK
*/
get label(): string {
return formatOmniContract(this.contract)
return formatOmniPoint(this.point)
}

get point(): OmniPoint {
return omniContractToPoint(this.contract)
get contract(): OmniContract {
return { eid: this.point.eid, contract: new Contract(this.point.address, this.abi).connect(this.provider) }
}

protected createTransaction(data: string): OmniTransaction {
Expand Down
2 changes: 2 additions & 0 deletions packages/devtools-evm/src/omnigraph/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { JsonFragment } from '@ethersproject/abi'
import type { Contract } from '@ethersproject/contracts'
import type { Factory, IOmniSDK as IOmniSDKAbstract, OmniPoint, WithEid } from '@layerzerolabs/devtools'

Expand All @@ -11,5 +12,6 @@ export type OmniContractFactory<TOmniPoint = OmniPoint> = Factory<[TOmniPoint],
* Base interface for all EVM SDKs, adding the EVM specific attributes
*/
export interface IOmniSDK extends IOmniSDKAbstract {
abi: JsonFragment[]
contract: OmniContract
}
84 changes: 84 additions & 0 deletions packages/devtools/src/flows/wire.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { Configurator, OmniGraph, OmniSDKFactory } from '@/omnigraph/types'
import { formatOmniTransaction, OmniTransaction, SignAndSend } from '@/transactions'
import { createLogger, printBoolean, printJson, type Logger } from '@layerzerolabs/io-devtools'
import { printRecords } from '@layerzerolabs/io-devtools/swag'

export interface WireFlowOptions {
assert?: boolean
dryRun?: boolean
logger?: Logger
configPath: string
loadConfig: (path: string) => Promise<OmniGraph>
configure: Configurator
signAndSend: SignAndSend
createSdk: OmniSDKFactory
}

export const wireFlow = async ({
assert,
dryRun,
logger = createLogger(),
configPath,
loadConfig,
configure,
createSdk,
}: WireFlowOptions) => {
// And since this command is not complete yet, we'll warn the user
logger.warn(
`This command is just a placeholder. Please use @layerzerolabs/toolbox-hardhat package for the time being.`
)

if (assert) {
logger.info(`Running in assertion mode`)
} else if (dryRun) {
logger.info(`Running in dry run mode`)
}

let graph: OmniGraph

// Now it's time to load the config file
try {
logger.info(`Loading config file from ${configPath}`)

graph = await loadConfig(configPath)

logger.info(`${printBoolean(true)} Successfully loaded config file from ${configPath}`)
logger.debug(`Loaded config file from ${configPath}:\n\n${printJson(graph)}`)
} catch (error) {
logger.error(`Failed to load config from ${configPath}:\n\n${error}`)

process.exit(1)
}

let transactions: OmniTransaction[]

try {
logger.info(`Checking configuration`)

transactions = await configure(graph, createSdk)
} catch (error) {
logger.error(`Failed to check OApp configuration:\n\n${error}`)

process.exit(1)
}

// If there are no transactions that need to be executed, we'll just exit
if (transactions.length === 0) {
return logger.info(`The OApp is wired, no action is necessary`), undefined
} else if (assert) {
// If we are in assertion mode, we'll print out the transactions and exit with code 1
// if there is anything left to configure
logger.error(`The OApp is not fully wired, following transactions are necessary:`)

// Print the outstanding transactions
printRecords(transactions.map(formatOmniTransaction))

// Exit with non-zero error code
process.exit(1)
}

// If we are in dry run mode, we'll just print the transactions and exit
if (dryRun) {
printRecords(transactions.map(formatOmniTransaction))
}
}
14 changes: 7 additions & 7 deletions packages/omnicounter-devtools-evm/src/omnicounter/factory.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import pMemoize from 'p-memoize'
import { OmniCounter } from '@/omnicounter/sdk'
import { OAppFactory } from '@layerzerolabs/ua-devtools'
import { OmniContractFactory } from '@layerzerolabs/devtools-evm'
import { ProviderFactory } from '@layerzerolabs/devtools-evm'

/**
* Syntactic sugar that creates an instance of EVM `OmniCounter` SDK based on an `OmniPoint` with help of an
* `OmniContractFactory` and an (optional) `EndpointV2Factory`
* Syntactic sugar that creates an instance of EVM `OmniCounter` SDK based on an `OmniPoint` with help of a
* `ProviderFactory`
*
* @param {OmniContractFactory} contractFactory
* @returns {EndpointV2Factory<Endpoint>}
* @param {ProviderFactory} providerFactory
* @returns {OAppFactory<OmniCounter>}
*/
export const createOmniCounterFactory = (contractFactory: OmniContractFactory): OAppFactory<OmniCounter> =>
pMemoize(async (point) => new OmniCounter(await contractFactory(point)))
export const createOmniCounterFactory = (providerFactory: ProviderFactory): OAppFactory<OmniCounter> =>
pMemoize(async (point) => new OmniCounter(await providerFactory(point.eid), point))
3 changes: 1 addition & 2 deletions packages/protocol-devtools-evm/src/dvn/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { OmniSDK, type Provider } from '@layerzerolabs/devtools-evm'
import { printJson } from '@layerzerolabs/io-devtools'
import { DVNDstConfigSchema } from './schema'
import { abi } from '@layerzerolabs/lz-evm-sdk-v2/artifacts/contracts/uln/dvn/DVN.sol/DVN.json'
import { Contract } from '@ethersproject/contracts'

export class DVN extends OmniSDK implements IDVN {
constructor(provider: Provider, point: OmniPoint) {
super({ eid: point.eid, contract: new Contract(point.address, abi).connect(provider) })
super(provider, point, abi)
}

async getDstConfig(eid: EndpointId): Promise<DVNDstConfig> {
Expand Down
3 changes: 1 addition & 2 deletions packages/protocol-devtools-evm/src/endpointv2/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { Uln302SetExecutorConfig } from '@layerzerolabs/protocol-devtools'
import { printJson } from '@layerzerolabs/io-devtools'
import { ReceiveLibrarySchema } from './schema'
import { abi } from '@layerzerolabs/lz-evm-sdk-v2/artifacts/contracts/EndpointV2.sol/EndpointV2.json'
import { Contract } from '@ethersproject/contracts'

const CONFIG_TYPE_EXECUTOR = 1
const CONFIG_TYPE_ULN = 2
Expand All @@ -40,7 +39,7 @@ const CONFIG_TYPE_ULN = 2
*/
export class EndpointV2 extends OmniSDK implements IEndpointV2 {
constructor(provider: Provider, point: OmniPoint) {
super({ eid: point.eid, contract: new Contract(point.address, abi).connect(provider) })
super(provider, point, abi)
}

@AsyncRetriable()
Expand Down
3 changes: 1 addition & 2 deletions packages/protocol-devtools-evm/src/executor/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { OmniSDK, type Provider } from '@layerzerolabs/devtools-evm'
import { printJson } from '@layerzerolabs/io-devtools'
import { ExecutorDstConfigSchema } from './schema'
import { abi } from '@layerzerolabs/lz-evm-sdk-v2/artifacts/contracts/Executor.sol/Executor.json'
import { Contract } from '@ethersproject/contracts'

export class Executor extends OmniSDK implements IExecutor {
constructor(provider: Provider, point: OmniPoint) {
super({ eid: point.eid, contract: new Contract(point.address, abi).connect(provider) })
super(provider, point, abi)
}

async getDstConfig(eid: EndpointId): Promise<ExecutorDstConfig> {
Expand Down
3 changes: 1 addition & 2 deletions packages/protocol-devtools-evm/src/priceFeed/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import { OmniSDK, type Provider } from '@layerzerolabs/devtools-evm'
import { printJson } from '@layerzerolabs/io-devtools'
import { PriceDataSchema } from './schema'
import { abi } from '@layerzerolabs/lz-evm-sdk-v2/artifacts/contracts/PriceFeed.sol/PriceFeed.json'
import { Contract } from '@ethersproject/contracts'

export class PriceFeed extends OmniSDK implements IPriceFeed {
constructor(provider: Provider, point: OmniPoint) {
super({ eid: point.eid, contract: new Contract(point.address, abi).connect(provider) })
super(provider, point, abi)
}

async getPrice(eid: EndpointId): Promise<PriceData> {
Expand Down
3 changes: 1 addition & 2 deletions packages/protocol-devtools-evm/src/uln302/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,13 @@ import assert from 'assert'
import { printBoolean, printJson } from '@layerzerolabs/io-devtools'
import { isZero, AsyncRetriable } from '@layerzerolabs/devtools'
import { OmniSDK, Provider, addChecksum, makeZeroAddress } from '@layerzerolabs/devtools-evm'
import { Contract } from '@ethersproject/contracts'
// Although this SDK is not specific to SendUln302, it uses the SendUln302 ABI
// because it contains all the necessary method fragments
import { abi } from '@layerzerolabs/lz-evm-sdk-v2/artifacts/contracts/uln/uln302/SendUln302.sol/SendUln302.json'

export class Uln302 extends OmniSDK implements IUln302 {
constructor(provider: Provider, point: OmniPoint) {
super({ eid: point.eid, contract: new Contract(point.address, abi).connect(provider) })
super(provider, point, abi)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { printCrossTable, printRecord, setDefaultLogLevel } from '@layerzerolabs
import { SUBTASK_LZ_OAPP_CONFIG_LOAD, TASK_LZ_OAPP_ENFORCED_OPTS_GET } from '@/constants/tasks'
import { printLogo } from '@layerzerolabs/io-devtools/swag'
import { EncodedOption, OAppOmniGraph } from '@layerzerolabs/ua-devtools'
import { createConnectedContractFactory, types } from '@layerzerolabs/devtools-evm-hardhat'
import { createProviderFactory, types } from '@layerzerolabs/devtools-evm-hardhat'
import { createOAppFactory } from '@layerzerolabs/ua-devtools-evm'
import { checkOAppEnforcedOptions } from '@layerzerolabs/ua-devtools'
import { getNetworkNameForEid } from '@layerzerolabs/devtools-evm-hardhat'
Expand Down Expand Up @@ -39,8 +39,7 @@ const action: ActionType<TaskArgs> = async ({ oappConfig: oappConfigPath, logLev
}))

// At this point we are ready read data from the OApp
const contractFactory = createConnectedContractFactory()
const oAppFactory = createOAppFactory(contractFactory)
const oAppFactory = createOAppFactory(createProviderFactory())

try {
const enforcedOptions = await checkOAppEnforcedOptions(graph, oAppFactory)
Expand Down
5 changes: 2 additions & 3 deletions packages/ua-devtools-evm-hardhat/src/tasks/oapp/peers.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { createLogger, printBoolean, printCrossTable, setDefaultLogLevel } from
import { SUBTASK_LZ_OAPP_CONFIG_LOAD, TASK_LZ_OAPP_PEERS_GET } from '@/constants/tasks'
import { printLogo } from '@layerzerolabs/io-devtools/swag'
import { OAppOmniGraph } from '@layerzerolabs/ua-devtools'
import { createConnectedContractFactory, types } from '@layerzerolabs/devtools-evm-hardhat'
import { createProviderFactory, types } from '@layerzerolabs/devtools-evm-hardhat'
import { createOAppFactory } from '@layerzerolabs/ua-devtools-evm'
import { checkOAppPeers } from '@layerzerolabs/ua-devtools'
import { getNetworkNameForEid } from '@layerzerolabs/devtools-evm-hardhat'
Expand Down Expand Up @@ -43,8 +43,7 @@ const action: ActionType<TaskArgs> = async ({ oappConfig: oappConfigPath, logLev

// At this point we are ready read data from the OApp
logger.verbose(`Reading peers from OApps`)
const contractFactory = createConnectedContractFactory()
const oAppFactory = createOAppFactory(contractFactory)
const oAppFactory = createOAppFactory(createProviderFactory())

try {
const peers = await checkOAppPeers(graph, oAppFactory)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SUBTASK_LZ_OAPP_WIRE_CONFIGURE } from '@/constants'
import { OmniGraphBuilder, OmniTransaction } from '@layerzerolabs/devtools'
import { createConnectedContractFactory, types } from '@layerzerolabs/devtools-evm-hardhat'
import { createProviderFactory, types } from '@layerzerolabs/devtools-evm-hardhat'
import { createModuleLogger, printJson } from '@layerzerolabs/io-devtools'
import { IOApp, OAppOmniGraph, configureOApp } from '@layerzerolabs/ua-devtools'
import { createOAppFactory } from '@layerzerolabs/ua-devtools-evm'
Expand All @@ -11,7 +11,7 @@ import type { SubtaskConfigureTaskArgs } from './types'
const action: ActionType<SubtaskConfigureTaskArgs<OAppOmniGraph, IOApp>> = async ({
graph,
configurator = configureOApp,
sdkFactory = createOAppFactory(createConnectedContractFactory()),
sdkFactory = createOAppFactory(createProviderFactory()),
}): Promise<OmniTransaction[]> => {
const logger = createModuleLogger(SUBTASK_LZ_OAPP_WIRE_CONFIGURE)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { OwnableOmniGraph } from '@layerzerolabs/ua-devtools'
import {
types,
SUBTASK_LZ_SIGN_AND_SEND,
createConnectedContractFactory,
createSignerFactory,
createGnosisSignerFactory,
formatOmniTransaction,
createProviderFactory,
} from '@layerzerolabs/devtools-evm-hardhat'
import { printLogo, printRecords } from '@layerzerolabs/io-devtools/swag'
import { type SignAndSendResult } from '@layerzerolabs/devtools'
Expand Down Expand Up @@ -58,7 +58,7 @@ const action: ActionType<TaskArgs> = async (
// At this point we are ready to create the list of transactions
logger.verbose(`Creating a list of ownership transferring transactions`)

const createSdk = createOwnableFactory(createOAppFactory(createConnectedContractFactory()))
const createSdk = createOwnableFactory(createOAppFactory(createProviderFactory()))
const transactions = await configureOwnable(graph, createSdk)

// Flood users with debug output
Expand Down
9 changes: 9 additions & 0 deletions packages/ua-devtools-evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,20 @@
"p-memoize": "~4.0.4"
},
"devDependencies": {
"@ethersproject/abi": "~5.7.0",
"@ethersproject/address": "~5.7.0",
"@ethersproject/bignumber": "^5.7.0",
"@ethersproject/constants": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"@layerzerolabs/devtools": "~0.3.24",
"@layerzerolabs/devtools-evm": "~0.4.1",
"@layerzerolabs/io-devtools": "~0.1.12",
"@layerzerolabs/lz-definitions": "^2.3.34",
"@layerzerolabs/lz-evm-sdk-v1": "^2.3.24",
"@layerzerolabs/lz-evm-sdk-v2": "^2.3.24",
"@layerzerolabs/lz-v2-utilities": "^2.3.34",
"@layerzerolabs/oapp-evm": "~0.0.2",
"@layerzerolabs/protocol-devtools": "~0.4.2",
"@layerzerolabs/protocol-devtools-evm": "~1.1.0",
"@layerzerolabs/test-devtools": "~0.2.8",
Expand All @@ -59,13 +64,17 @@
"zod": "^3.22.4"
},
"peerDependencies": {
"@ethersproject/abi": "^5.7.0",
"@ethersproject/constants": "^5.7.0",
"@ethersproject/contracts": "^5.7.0",
"@layerzerolabs/devtools": "~0.3.24",
"@layerzerolabs/devtools-evm": "~0.4.1",
"@layerzerolabs/io-devtools": "~0.1.12",
"@layerzerolabs/lz-definitions": "^2.3.3",
"@layerzerolabs/lz-evm-sdk-v1": "^2.3.24",
"@layerzerolabs/lz-evm-sdk-v2": "^2.3.24",
"@layerzerolabs/lz-v2-utilities": "^2.3.3",
"@layerzerolabs/oapp-evm": "^0.0.2",
"@layerzerolabs/protocol-devtools": "~0.4.2",
"@layerzerolabs/protocol-devtools-evm": "~1.1.0",
"@layerzerolabs/ua-devtools": "~1.0.3",
Expand Down
Loading
Loading