diff --git a/.changeset/yellow-swans-own.md b/.changeset/yellow-swans-own.md new file mode 100644 index 000000000..fcee76526 --- /dev/null +++ b/.changeset/yellow-swans-own.md @@ -0,0 +1,7 @@ +--- +"@layerzerolabs/ua-devtools-solana": patch +"@layerzerolabs/ua-devtools-evm": patch +"@layerzerolabs/ua-devtools": patch +--- + +Remove recently introduced getEndpointConfigAddress method on IOApp diff --git a/packages/ua-devtools-evm/src/oapp/sdk.ts b/packages/ua-devtools-evm/src/oapp/sdk.ts index 0aebeca07..e649042ed 100644 --- a/packages/ua-devtools-evm/src/oapp/sdk.ts +++ b/packages/ua-devtools-evm/src/oapp/sdk.ts @@ -25,15 +25,6 @@ export class OApp extends Ownable implements IOApp { super(contract) } - /** - * For EVM OApps, the config is stored under the OApp's address - * - * @returns {OmniAddress} - */ - getEndpointConfigAddress(): OmniAddress { - return this.contract.contract.address - } - @AsyncRetriable() async getEndpointSDK(): Promise { this.logger.debug(`Getting EndpointV2 SDK`) diff --git a/packages/ua-devtools-solana/src/oft/sdk.ts b/packages/ua-devtools-solana/src/oft/sdk.ts index 88fd21a72..de42a1e44 100644 --- a/packages/ua-devtools-solana/src/oft/sdk.ts +++ b/packages/ua-devtools-solana/src/oft/sdk.ts @@ -1,5 +1,5 @@ import type { IOApp, OAppEnforcedOptionParam } from '@layerzerolabs/ua-devtools' -import { OftTools, OFT_SEED, EndpointProgram } from '@layerzerolabs/lz-solana-sdk-v2' +import { OftTools, EndpointProgram, OftProgram } from '@layerzerolabs/lz-solana-sdk-v2' import { type OmniAddress, type OmniTransaction, @@ -28,21 +28,12 @@ export class OFT extends OmniSDK implements IOApp { connection: Connection, point: OmniPoint, userAccount: PublicKey, - public readonly mintAccount: PublicKey, + public readonly programId: PublicKey = OftProgram.OFT_DEFAULT_PROGRAM_ID, logger?: Logger ) { super(connection, point, userAccount, logger) } - /** - * For Solana OFTs, the endpoint config is stored under the config account - * - * @returns {OmniAddress} - */ - getEndpointConfigAddress(): OmniAddress { - return this.configAccount.toBase58() - } - getOwner(): Promise { throw new Error('Method not implemented.') } @@ -55,10 +46,6 @@ export class OFT extends OmniSDK implements IOApp { throw new Error('Method not implemented.') } - get configAccount(): PublicKey { - return PublicKey.findProgramAddressSync([Buffer.from(OFT_SEED), this.mintAccount.toBuffer()], this.publicKey)[0] - } - @AsyncRetriable() async getEndpointSDK(): Promise { this.logger.debug(`Getting EndpointV2 SDK`) @@ -76,7 +63,7 @@ export class OFT extends OmniSDK implements IOApp { this.logger.debug(`Getting peer for ${eidLabel}`) try { - const peer = await OftTools.getPeerAddress(this.connection, this.configAccount, eid, this.publicKey) + const peer = await OftTools.getPeerAddress(this.connection, this.publicKey, eid, this.programId) // We run the hex string we got through a normalization/denormalization process // that will ensure that zero addresses will get stripped @@ -110,7 +97,7 @@ export class OFT extends OmniSDK implements IOApp { this.logger.debug(`Setting peer for eid ${eid} (${eidLabel}) to address ${peerAsBytes32}`) const transaction = new Transaction().add( - await OftTools.createSetPeerIx(this.userAccount, this.configAccount, eid, normalizedPeer, this.publicKey) + await OftTools.createSetPeerIx(this.userAccount, this.publicKey, eid, normalizedPeer, this.programId) ) return { @@ -148,7 +135,7 @@ export class OFT extends OmniSDK implements IOApp { this.logger.verbose(`Getting enforced options for ${eidLabel} and message type ${msgType}`) try { - const options = await OftTools.getEnforcedOptions(this.connection, this.configAccount, eid, this.publicKey) + const options = await OftTools.getEnforcedOptions(this.connection, this.publicKey, eid, this.programId) const optionsForMsgType = msgType === MSG_TYPE_SEND ? options.send : options.sendAndCall return toHex(optionsForMsgType) @@ -176,11 +163,11 @@ export class OFT extends OmniSDK implements IOApp { const instruction = await OftTools.createSetEnforcedOptionsIx( this.userAccount, // your admin address - this.configAccount, // your OFT Config + this.publicKey, // your OFT Config eid, // destination endpoint id for the options to apply to sendOption, sendAndCallOption, - this.publicKey + this.programId ) transaction.add(instruction) diff --git a/packages/ua-devtools-solana/test/oft/sdk.test.ts b/packages/ua-devtools-solana/test/oft/sdk.test.ts index d2563533f..82a3921d1 100644 --- a/packages/ua-devtools-solana/test/oft/sdk.test.ts +++ b/packages/ua-devtools-solana/test/oft/sdk.test.ts @@ -26,9 +26,9 @@ describe('oft/sdk', () => { // // We need to run our own Solana node with the OFT account cloned // so that we can isolate these tests - const point = { eid: EndpointId.SOLANA_V2_MAINNET, address: 'Ag28jYmND83RnwcSFq2vwWxThSya55etjWJwubd8tRXs' } + const programId = new PublicKey('Ag28jYmND83RnwcSFq2vwWxThSya55etjWJwubd8tRXs') + const point = { eid: EndpointId.SOLANA_V2_MAINNET, address: '8aFeCEhGLwbWHWiiezLAKanfD5Cn3BW3nP6PZ54K9LYC' } const account = new PublicKey('6tzUZqC33igPgP7YyDnUxQg6eupMmZGRGKdVAksgRzvk') - const mintAccount = new PublicKey('Bq9wBU8fqFnUDkrWqLFXGRc7BvRMPjUkCM2SrJf6dBMv') afterEach(() => { createSetEnforcedOptionsIxMock.mockClear() @@ -39,7 +39,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) expect(await sdk.getPeer(EndpointId.ETHEREUM_V2_TESTNET)).toBeUndefined() }) @@ -48,7 +48,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const peer = await sdk.getPeer(EndpointId.ETHEREUM_V2_MAINNET) expect(peer).toEqual(expect.any(String)) @@ -67,7 +67,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const omniTransaction = await sdk.setPeer(EndpointId.ETHEREUM_V2_MAINNET, makeBytes32()) expect(omniTransaction).toEqual({ @@ -83,7 +83,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const omniTransaction = await sdk.setPeer(EndpointId.APTOS_MAINNET, makeBytes32()) expect(omniTransaction).toEqual({ @@ -99,7 +99,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const omniTransaction = await sdk.setPeer(EndpointId.SOLANA_V2_MAINNET, point.address) expect(omniTransaction).toEqual({ @@ -116,7 +116,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) await expect(sdk.getEnforcedOptions(EndpointId.ETHEREUM_V2_TESTNET, 3)).rejects.toMatchSnapshot() }) @@ -125,7 +125,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) expect(await sdk.getEnforcedOptions(EndpointId.ETHEREUM_V2_TESTNET, 1)).toBe('0x') }) @@ -134,7 +134,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const sendOptionsHex = await sdk.getEnforcedOptions(EndpointId.ETHEREUM_V2_MAINNET, 1) expect(sendOptionsHex).toEqual(expect.any(String)) @@ -155,7 +155,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) await expect( sdk.setEnforcedOptions([ @@ -171,7 +171,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const enforcedOptions = [ { @@ -192,7 +192,7 @@ describe('oft/sdk', () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const enforcedOptions = [ // We'll set two options for ethereum @@ -229,31 +229,31 @@ describe('oft/sdk', () => { // Ethereum should have both msgType options set expect(createSetEnforcedOptionsIxMock).toHaveBeenCalledWith( sdk.userAccount, - sdk.configAccount, + sdk.publicKey, EndpointId.ETHEREUM_V2_TESTNET, Options.newOptions().addExecutorOrderedExecutionOption().toBytes(), Options.newOptions().addExecutorLzReceiveOption(1, 1).toBytes(), - sdk.publicKey + programId ) // Base should have one option set expect(createSetEnforcedOptionsIxMock).toHaveBeenCalledWith( sdk.userAccount, - sdk.configAccount, + sdk.publicKey, EndpointId.BASE_V2_MAINNET, Options.newOptions().addExecutorLzReceiveOption(4, 1).toBytes(), Options.newOptions().toBytes(), - sdk.publicKey + programId ) // Avalanche should use the latter option and ignore the first one expect(createSetEnforcedOptionsIxMock).toHaveBeenCalledWith( sdk.userAccount, - sdk.configAccount, + sdk.publicKey, EndpointId.AVALANCHE_V2_MAINNET, Options.newOptions().toBytes(), Options.newOptions().addExecutorLzReceiveOption(3, 1).toBytes(), - sdk.publicKey + programId ) }) }) @@ -262,14 +262,14 @@ describe('oft/sdk', () => { it('should return an SDK with the correct eid and address', async () => { const connectionFactory = createConnectionFactory(defaultRpcUrlFactory) const connection = await connectionFactory(EndpointId.SOLANA_V2_MAINNET) - const sdk = new OFT(connection, point, account, mintAccount) + const sdk = new OFT(connection, point, account, programId) const endpointSdk = await sdk.getEndpointSDK() expect(endpointSdk.point).toEqual({ eid: sdk.point.eid, address: EndpointProgram.PROGRAM_ID.toBase58() }) // Run a random function on the SDK to check whether it works expect( - await endpointSdk.isDefaultSendLibrary(sdk.configAccount.toBase58(), EndpointId.ETHEREUM_V2_MAINNET) + await endpointSdk.isDefaultSendLibrary(sdk.publicKey.toBase58(), EndpointId.ETHEREUM_V2_MAINNET) ).toBeFalsy() }) }) diff --git a/packages/ua-devtools/src/oapp/config.ts b/packages/ua-devtools/src/oapp/config.ts index 6547f9068..6dfdc8af8 100644 --- a/packages/ua-devtools/src/oapp/config.ts +++ b/packages/ua-devtools/src/oapp/config.ts @@ -9,10 +9,9 @@ import { createConfigureMultiple, createConfigureNodes, createConfigureEdges, - type OmniPoint, } from '@layerzerolabs/devtools' -import type { IOApp, OAppConfigurator, OAppEnforcedOption, OAppEnforcedOptionParam, OAppFactory } from './types' -import { createModuleLogger, createWithAsyncLogger, type Logger, printBoolean } from '@layerzerolabs/io-devtools' +import type { OAppConfigurator, OAppEnforcedOption, OAppEnforcedOptionParam, OAppFactory } from './types' +import { createModuleLogger, createWithAsyncLogger, printBoolean } from '@layerzerolabs/io-devtools' import type { SetConfigParam } from '@layerzerolabs/protocol-devtools' import assert from 'assert' import { ExecutorOptionType, Options } from '@layerzerolabs/lz-v2-utilities' @@ -103,10 +102,9 @@ export const configureSendLibraries: OAppConfigurator = withOAppLogger( return [] } - const configAddress = await getEndpointConfigAddressPolyfill(sdk, from, logger) const endpointSdk = await sdk.getEndpointSDK() - const isDefaultLibrary = await endpointSdk.isDefaultSendLibrary(configAddress, to.eid) - const currentSendLibrary = await endpointSdk.getSendLibrary(configAddress, to.eid) + const isDefaultLibrary = await endpointSdk.isDefaultSendLibrary(from.address, to.eid) + const currentSendLibrary = await endpointSdk.getSendLibrary(from.address, to.eid) if (!isDefaultLibrary && currentSendLibrary === config.sendLibrary) { logger.verbose( @@ -116,7 +114,7 @@ export const configureSendLibraries: OAppConfigurator = withOAppLogger( } logger.verbose(`Setting sendLibrary ${config.sendLibrary} for ${formatOmniVector({ from, to })}`) - return [await endpointSdk.setSendLibrary(configAddress, to.eid, config.sendLibrary)] + return [await endpointSdk.setSendLibrary(from.address, to.eid, config.sendLibrary)] }, { onStart: (logger, [{ vector }]) => @@ -145,10 +143,9 @@ export const configureReceiveLibraries: OAppConfigurator = withOAppLogger( return [] } - const configAddress = await getEndpointConfigAddressPolyfill(sdk, from, logger) const endpointSdk = await sdk.getEndpointSDK() const [currentReceiveLibrary, isDefaultLibrary] = await endpointSdk.getReceiveLibrary( - configAddress, + from.address, to.eid ) @@ -165,7 +162,7 @@ export const configureReceiveLibraries: OAppConfigurator = withOAppLogger( return [ await endpointSdk.setReceiveLibrary( - configAddress, + from.address, to.eid, config.receiveLibraryConfig.receiveLibrary, config.receiveLibraryConfig.gracePeriod @@ -203,9 +200,8 @@ export const configureReceiveLibraryTimeouts: OAppConfigurator = withOAppLogger( const { receiveLibraryTimeoutConfig } = config - const configAddress = await getEndpointConfigAddressPolyfill(sdk, from, logger) const endpointSdk = await sdk.getEndpointSDK() - const timeout = await endpointSdk.getReceiveLibraryTimeout(configAddress, to.eid) + const timeout = await endpointSdk.getReceiveLibraryTimeout(from.address, to.eid) if (isDeepEqual(timeout, receiveLibraryTimeoutConfig)) { logger.verbose( @@ -220,7 +216,7 @@ export const configureReceiveLibraryTimeouts: OAppConfigurator = withOAppLogger( return [ await endpointSdk.setReceiveLibraryTimeout( - configAddress, + from.address, to.eid, receiveLibraryTimeoutConfig.lib, receiveLibraryTimeoutConfig.expiry @@ -262,10 +258,8 @@ export const configureSendConfig: OAppConfigurator = withOAppLogger( } const oappSdk = await createSdk(from) - const configAddress = await getEndpointConfigAddressPolyfill(oappSdk, from, logger) - const configPoint: OmniPoint = { ...from, address: configAddress } const endpointSdk = await oappSdk.getEndpointSDK() - const currentSendLibrary = config.sendLibrary ?? (await endpointSdk.getSendLibrary(configAddress, to.eid)) + const currentSendLibrary = config.sendLibrary ?? (await endpointSdk.getSendLibrary(from.address, to.eid)) assert( currentSendLibrary !== undefined, 'sendLibrary has not been set in your config and no default value exists' @@ -277,7 +271,7 @@ export const configureSendConfig: OAppConfigurator = withOAppLogger( // We need to ask not for the final config formed of the default config and the app config, // we only need to check the app config const hasExecutorConfig = await endpointSdk.hasAppExecutorConfig( - configAddress, + from.address, currentSendLibrary, to.eid, config.sendConfig.executorConfig @@ -294,17 +288,15 @@ export const configureSendConfig: OAppConfigurator = withOAppLogger( ) // Updates map with nw configs for that OApp and Send Library - const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(configPoint, () => new Map()) + const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()) const existingSetConfigs = setConfigsByLibrary.get(currentSendLibrary) ?? [] setConfigsByEndpointAndLibrary.set( - configPoint, + from, setConfigsByLibrary.set(currentSendLibrary, [...existingSetConfigs, ...newSetConfigs]) ) const updatedConfigList = - setConfigsByEndpointAndLibrary - .getOrElse(configPoint, () => new Map()) - .get(currentSendLibrary) ?? [] + setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()).get(currentSendLibrary) ?? [] const updatedConfigListCsv = updatedConfigList .map( (setConfigParam) => @@ -323,7 +315,7 @@ export const configureSendConfig: OAppConfigurator = withOAppLogger( // We need to ask not for the final config formed of the default config and the app config, // we only need to check the app config const hasUlnConfig = await endpointSdk.hasAppUlnConfig( - configAddress, + from.address, currentSendLibrary, to.eid, config.sendConfig.ulnConfig @@ -339,17 +331,15 @@ export const configureSendConfig: OAppConfigurator = withOAppLogger( ]) // Updates map with new configs for that OApp and Send Library - const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(configPoint, () => new Map()) + const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()) const existingSetConfigs = setConfigsByLibrary.get(currentSendLibrary) ?? [] setConfigsByEndpointAndLibrary.set( - configPoint, + from, setConfigsByLibrary.set(currentSendLibrary, [...existingSetConfigs, ...newSetConfigs]) ) const updatedConfigList = - setConfigsByEndpointAndLibrary - .getOrElse(configPoint, () => new Map()) - .get(currentSendLibrary) ?? [] + setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()).get(currentSendLibrary) ?? [] const updatedConfigListCsv = updatedConfigList .map( (setConfigParam) => @@ -388,12 +378,10 @@ export const configureReceiveConfig: OAppConfigurator = withOAppLogger( } const oappSdk = await createSdk(from) - const configAddress = await getEndpointConfigAddressPolyfill(oappSdk, from, logger) - const configPoint: OmniPoint = { ...from, address: configAddress } const endpointSdk = await oappSdk.getEndpointSDK() const [currentReceiveLibrary] = config?.receiveLibraryConfig?.receiveLibrary ? [config.receiveLibraryConfig?.receiveLibrary, false] - : await endpointSdk.getReceiveLibrary(configAddress, to.eid) + : await endpointSdk.getReceiveLibrary(from.address, to.eid) assert( currentReceiveLibrary !== undefined, 'receiveLibrary has not been set in your config and no default value exists' @@ -404,7 +392,7 @@ export const configureReceiveConfig: OAppConfigurator = withOAppLogger( // We need to ask not for the final config formed of the default config and the app config, // we only need to check the app config const hasUlnConfig = await endpointSdk.hasAppUlnConfig( - configAddress, + from.address, currentReceiveLibrary, to.eid, config.receiveConfig.ulnConfig @@ -420,16 +408,15 @@ export const configureReceiveConfig: OAppConfigurator = withOAppLogger( ]) // Updates map with new configs for that OApp and Receive Library - const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(configPoint, () => new Map()) + const setConfigsByLibrary = setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()) const existingSetConfigs = setConfigsByLibrary.get(currentReceiveLibrary) ?? [] setConfigsByEndpointAndLibrary.set( - configPoint, + from, setConfigsByLibrary.set(currentReceiveLibrary, [...existingSetConfigs, ...newSetConfigs]) ) const updatedConfigList = - setConfigsByEndpointAndLibrary.getOrElse(configPoint, () => new Map()).get(currentReceiveLibrary) ?? - [] + setConfigsByEndpointAndLibrary.getOrElse(from, () => new Map()).get(currentReceiveLibrary) ?? [] const updatedConfigListCsv = updatedConfigList .map( (setConfigParam) => @@ -640,14 +627,3 @@ export const configureOApp: OAppConfigurator = withOAppLogger( onError: (logger, args, error) => logger.error(`Failed to check OApp configuration: ${error}`), } ) - -const getEndpointConfigAddressPolyfill = async (sdk: IOApp, point: OmniPoint, logger: Logger) => { - return typeof sdk.getEndpointConfigAddress === 'function' - ? // The new devtools versions have the getEndpointConfigAddress method - await sdk.getEndpointConfigAddress() - : // The old versions don't have it, so we fallback to using the OApp address and warn the user - (logger.warn( - `Your SDK does not support getEndpointConfigAddress method. Please update @layerzerolabs packages to their newest versions` - ), - point.address) -} diff --git a/packages/ua-devtools/src/oapp/types.ts b/packages/ua-devtools/src/oapp/types.ts index bbbb3b7a6..7ab3c1fb7 100644 --- a/packages/ua-devtools/src/oapp/types.ts +++ b/packages/ua-devtools/src/oapp/types.ts @@ -16,14 +16,6 @@ import { ExecutorOptionType } from '@layerzerolabs/lz-v2-utilities' import type { IOwnable, OwnableNodeConfig } from '@/ownable/types' export interface IOApp extends IOmniSDK, IOwnable { - /** - * For non-EVM networks the address of the contract might not correspond to the address - * under which the config is stored on the Endpoint - * - * An example of this is Solana for which the config is stored under a different account - * derviced from the program ID and the mint account - */ - getEndpointConfigAddress(): OmniAddress | Promise getEndpointSDK(): Promise getPeer(eid: EndpointId): Promise hasPeer(eid: EndpointId, address: OmniAddress | null | undefined): Promise