From 7cd664bd6d7ced4323d28d5a58f13f982fdfb9f5 Mon Sep 17 00:00:00 2001 From: Melisa Guevara Date: Thu, 10 Apr 2025 18:06:21 -0300 Subject: [PATCH 1/5] WIP: svm version of get fill deadline buffer --- src/arch/svm/SpokeUtils.ts | 63 +++++++++++++++++++++++++++++++++++--- src/arch/svm/utils.ts | 2 +- test/SpokeUtils.ts | 17 ++++++++++ 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/src/arch/svm/SpokeUtils.ts b/src/arch/svm/SpokeUtils.ts index 8eb4bee31..84917fc9f 100644 --- a/src/arch/svm/SpokeUtils.ts +++ b/src/arch/svm/SpokeUtils.ts @@ -1,6 +1,20 @@ -import { Rpc, SolanaRpcApi } from "@solana/kit"; +import { + Rpc, + SolanaRpcApi, + Address, + getProgramDerivedAddress, + address, + getStructDecoder, + getBooleanCodec, + getU32Codec, + getU64Codec, + getAddressCodec, + getAddressDecoder, +} from "@solana/kit"; + import { Deposit, FillStatus, FillWithBlock, RelayData } from "../../interfaces"; import { BigNumber, isUnsafeDepositId } from "../../utils"; +import { snakeToCamel } from "../../svm/utils/events"; type Provider = Rpc; @@ -52,12 +66,16 @@ export async function getTimestampForBlock(provider: Provider, blockNumber: numb * @param endBlock end block * @returns maximum of fill deadline buffer at start and end block */ -export function getMaxFillDeadlineInRange( - _spokePool: unknown, +export async function getMaxFillDeadlineInRange( + _spokePool: { provider: Provider }, _startBlock: number, _endBlock: number -): Promise { - throw new Error("getMaxFillDeadlineInRange: not implemented"); +): Promise { + const programId = "JAZWcGrpSWNPTBj8QtJ9UyQqhJCDhG9GJkDeMf5NQBiq"; // TODO: read this from the spokePool + const statePda = await getStatePda(programId); + const state = await queryStateFromStatePda(statePda, _spokePool.provider); + + return state.fillDeadlineBuffer; } /** @@ -176,3 +194,38 @@ export function findFillEvent( ): Promise { throw new Error("fillStatusArray: not implemented"); } + +export async function queryStateFromStatePda(statePda: Address, provider: Provider) { + const pdaAccountInfo = await provider.getAccountInfo(statePda, { encoding: "base64" }).send(); + if (!pdaAccountInfo.value?.data) { + throw new Error("State account data not found"); + } + const stateDecoder = getStructDecoder([ + ["paused_deposits", getBooleanCodec()], + ["paused_fills", getBooleanCodec()], + ["owner", getAddressDecoder()], + ["seed", getU64Codec()], + ["number_of_deposits", getU32Codec()], + ["chain_id", getU64Codec()], + ["current_time", getU32Codec()], + ["remote_domain", getU32Codec()], + ["cross_domain_admin", getAddressCodec()], + ["root_bundle_id", getU32Codec()], + ["deposit_quote_time_buffer", getU32Codec()], + ["fill_deadline_buffer", getU32Codec()], + ]); + const stateData = pdaAccountInfo.value.data[0]; + const stateDataBytes = Buffer.from(stateData, "base64"); + const discriminatorBytesSize = 8; + const decodedState = stateDecoder.decode(Uint8Array.from(stateDataBytes), discriminatorBytesSize); + return Object.fromEntries(Object.entries(decodedState).map(([key, value]) => [snakeToCamel(key), value])); +} + +// TODO: Should accept seed +export async function getStatePda(programId: string): Promise
{ + const [statePda] = await getProgramDerivedAddress({ + programAddress: address(programId), + seeds: ["state", new Uint8Array(8)], // This only works if second seed is zero, make it dynamic + }); + return statePda; +} diff --git a/src/arch/svm/utils.ts b/src/arch/svm/utils.ts index 5b1c18f7c..18a604839 100644 --- a/src/arch/svm/utils.ts +++ b/src/arch/svm/utils.ts @@ -53,7 +53,7 @@ export function decodeEvent(idl: Idl, rawEvent: string): { data: EventData; name /** * Converts a snake_case string to camelCase. */ -function snakeToCamel(s: string): string { +export function snakeToCamel(s: string): string { return s.replace(/(_\w)/g, (match) => match[1].toUpperCase()); } diff --git a/test/SpokeUtils.ts b/test/SpokeUtils.ts index bbab28cda..cea46c359 100644 --- a/test/SpokeUtils.ts +++ b/test/SpokeUtils.ts @@ -2,6 +2,8 @@ import { utils as ethersUtils } from "ethers"; import { UNDEFINED_MESSAGE_HASH, ZERO_BYTES } from "../src/constants"; import { getMessageHash, getRelayEventKey, keccak256, randomAddress, toBN, validateFillForDeposit } from "../src/utils"; import { expect } from "./utils"; +import { CachedSolanaRpcFactory } from "../src/providers"; +import { getMaxFillDeadlineInRange } from "../src/arch/svm/SpokeUtils"; const random = () => Math.round(Math.random() * 1e8); const randomBytes = () => `0x${ethersUtils.randomBytes(48).join("").slice(0, 64)}`; @@ -26,6 +28,21 @@ describe("SpokeUtils", function () { exclusivityDeadline: random(), }; + it.only("getMaxFillDeadlineInRange returns the correct fill deadline", async function () { + const rpcFactory = new CachedSolanaRpcFactory( + "sdk-test", + undefined, + 10, + 0, + undefined, + "https://api.mainnet-beta.solana.com", + 34268394551451 + ); + const provider = rpcFactory.createRpcClient(); + const fillDeadline = await getMaxFillDeadlineInRange({ provider }, 0, 100); + console.log(fillDeadline); + }); + it("getRelayEventKey correctly concatenates an event key", function () { const eventKey = getRelayEventKey(sampleData); const expectedKey = From 9cf29183cb164d3343934925f8d8a63ccca0306f Mon Sep 17 00:00:00 2001 From: Melisa Guevara Date: Mon, 14 Apr 2025 16:27:24 -0300 Subject: [PATCH 2/5] feat: svm get fill deadline buffer --- src/arch/svm/SpokeUtils.ts | 76 +++++-------------- src/arch/svm/utils.ts | 2 +- .../SpokePoolClient/SVMSpokePoolClient.ts | 18 +++-- test/SpokeUtils.ts | 17 ----- 4 files changed, 31 insertions(+), 82 deletions(-) diff --git a/src/arch/svm/SpokeUtils.ts b/src/arch/svm/SpokeUtils.ts index 84917fc9f..60133011f 100644 --- a/src/arch/svm/SpokeUtils.ts +++ b/src/arch/svm/SpokeUtils.ts @@ -1,20 +1,8 @@ -import { - Rpc, - SolanaRpcApi, - Address, - getProgramDerivedAddress, - address, - getStructDecoder, - getBooleanCodec, - getU32Codec, - getU64Codec, - getAddressCodec, - getAddressDecoder, -} from "@solana/kit"; +import { Rpc, SolanaRpcApi, Address, getProgramDerivedAddress, address, getU64Encoder } from "@solana/kit"; import { Deposit, FillStatus, FillWithBlock, RelayData } from "../../interfaces"; import { BigNumber, isUnsafeDepositId } from "../../utils"; -import { snakeToCamel } from "../../svm/utils/events"; +import { fetchState } from "@across-protocol/contracts/dist/src/svm/clients/SvmSpoke"; type Provider = Rpc; @@ -60,22 +48,15 @@ export async function getTimestampForBlock(provider: Provider, blockNumber: numb } /** - * Return maximum of fill deadline buffer at start and end of block range. - * @param spokePool SpokePool contract instance - * @param startBlock start block - * @param endBlock end block - * @returns maximum of fill deadline buffer at start and end block + * Returns the current fill deadline buffer. + * @param provider SVM Provider instance + * @param programId Program ID from which State account is derived. + * @returns fill deadline buffer */ -export async function getMaxFillDeadlineInRange( - _spokePool: { provider: Provider }, - _startBlock: number, - _endBlock: number -): Promise { - const programId = "JAZWcGrpSWNPTBj8QtJ9UyQqhJCDhG9GJkDeMf5NQBiq"; // TODO: read this from the spokePool +export async function getFillDeadline(provider: Provider, programId: string): Promise { const statePda = await getStatePda(programId); - const state = await queryStateFromStatePda(statePda, _spokePool.provider); - - return state.fillDeadlineBuffer; + const state = await fetchState(provider, statePda); + return state.data.fillDeadlineBuffer; } /** @@ -195,37 +176,18 @@ export function findFillEvent( throw new Error("fillStatusArray: not implemented"); } -export async function queryStateFromStatePda(statePda: Address, provider: Provider) { - const pdaAccountInfo = await provider.getAccountInfo(statePda, { encoding: "base64" }).send(); - if (!pdaAccountInfo.value?.data) { - throw new Error("State account data not found"); - } - const stateDecoder = getStructDecoder([ - ["paused_deposits", getBooleanCodec()], - ["paused_fills", getBooleanCodec()], - ["owner", getAddressDecoder()], - ["seed", getU64Codec()], - ["number_of_deposits", getU32Codec()], - ["chain_id", getU64Codec()], - ["current_time", getU32Codec()], - ["remote_domain", getU32Codec()], - ["cross_domain_admin", getAddressCodec()], - ["root_bundle_id", getU32Codec()], - ["deposit_quote_time_buffer", getU32Codec()], - ["fill_deadline_buffer", getU32Codec()], - ]); - const stateData = pdaAccountInfo.value.data[0]; - const stateDataBytes = Buffer.from(stateData, "base64"); - const discriminatorBytesSize = 8; - const decodedState = stateDecoder.decode(Uint8Array.from(stateDataBytes), discriminatorBytesSize); - return Object.fromEntries(Object.entries(decodedState).map(([key, value]) => [snakeToCamel(key), value])); -} - -// TODO: Should accept seed -export async function getStatePda(programId: string): Promise
{ +/** + * Returns the PDA for the State account. + * @param programId The SpokePool program ID. + * @param extraSeed An optional extra seed. Defaults to 0. + * @returns The PDA for the State account. + */ +export async function getStatePda(programId: string, extraSeed = 0): Promise
{ + const seedEncoder = getU64Encoder(); + const encodedExtraSeed = seedEncoder.encode(extraSeed); const [statePda] = await getProgramDerivedAddress({ programAddress: address(programId), - seeds: ["state", new Uint8Array(8)], // This only works if second seed is zero, make it dynamic + seeds: ["state", encodedExtraSeed], }); return statePda; } diff --git a/src/arch/svm/utils.ts b/src/arch/svm/utils.ts index 18a604839..5b1c18f7c 100644 --- a/src/arch/svm/utils.ts +++ b/src/arch/svm/utils.ts @@ -53,7 +53,7 @@ export function decodeEvent(idl: Idl, rawEvent: string): { data: EventData; name /** * Converts a snake_case string to camelCase. */ -export function snakeToCamel(s: string): string { +function snakeToCamel(s: string): string { return s.replace(/(_\w)/g, (match) => match[1].toUpperCase()); } diff --git a/src/clients/SpokePoolClient/SVMSpokePoolClient.ts b/src/clients/SpokePoolClient/SVMSpokePoolClient.ts index 6e2dfd62b..2293ad164 100644 --- a/src/clients/SpokePoolClient/SVMSpokePoolClient.ts +++ b/src/clients/SpokePoolClient/SVMSpokePoolClient.ts @@ -1,7 +1,8 @@ import winston from "winston"; import { Rpc, SolanaRpcApiFromTransport, RpcTransport } from "@solana/kit"; + import { BigNumber, DepositSearchResult, EventSearchConfig, MakeOptional } from "../../utils"; -import { SvmSpokeEventsClient, SVMEventNames } from "../../arch/svm"; +import { SvmSpokeEventsClient, SVMEventNames, getFillDeadline, getTimestampForBlock } from "../../arch/svm"; import { HubPoolClient } from "../HubPoolClient"; import { knownEventNames, SpokePoolClient, SpokePoolUpdate } from "./SpokePoolClient"; import { RelayData, FillStatus } from "../../interfaces"; @@ -19,6 +20,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { chainId: number, deploymentSlot: bigint, // Using slot instead of block number for SVM eventSearchConfig: MakeOptional, + protected programId: string, protected svmEventsClient: SvmSpokeEventsClient, protected rpc: Rpc> ) { @@ -35,6 +37,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { chainId: number, deploymentSlot: bigint, eventSearchConfig: MakeOptional = { fromBlock: 0, maxBlockLookBack: 0 }, // Provide default + programId: string, rpc: Rpc> ): Promise { const svmEventsClient = await SvmSpokeEventsClient.create(rpc); @@ -44,6 +47,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { chainId, deploymentSlot, eventSearchConfig, + programId, svmEventsClient, rpc ); @@ -150,18 +154,18 @@ export class SvmSpokePoolClient extends SpokePoolClient { } /** - * Retrieves the maximum fill deadline buffer. - * TODO: Implement SVM equivalent, perhaps reading from a config account. + * Retrieves the fill deadline buffer fetched from the State PDA. + * @note This function assumes that fill deadline buffer is a constant value in svm environments. */ - public getMaxFillDeadlineInRange(_startSlot: number, _endSlot: number): Promise { - throw new Error("getMaxFillDeadlineInRange not implemented for SVM"); + public override getMaxFillDeadlineInRange(_startSlot: number, _endSlot: number): Promise { + return getFillDeadline(this.rpc, this.programId); } /** * Retrieves the timestamp for a given SVM slot number. */ - public getTimestampForBlock(_blockNumber: number): Promise { - throw new Error("getTimestampForBlock not implemented for SVM"); + public override getTimestampForBlock(blockNumber: number): Promise { + return getTimestampForBlock(this.rpc, blockNumber); } /** diff --git a/test/SpokeUtils.ts b/test/SpokeUtils.ts index cea46c359..bbab28cda 100644 --- a/test/SpokeUtils.ts +++ b/test/SpokeUtils.ts @@ -2,8 +2,6 @@ import { utils as ethersUtils } from "ethers"; import { UNDEFINED_MESSAGE_HASH, ZERO_BYTES } from "../src/constants"; import { getMessageHash, getRelayEventKey, keccak256, randomAddress, toBN, validateFillForDeposit } from "../src/utils"; import { expect } from "./utils"; -import { CachedSolanaRpcFactory } from "../src/providers"; -import { getMaxFillDeadlineInRange } from "../src/arch/svm/SpokeUtils"; const random = () => Math.round(Math.random() * 1e8); const randomBytes = () => `0x${ethersUtils.randomBytes(48).join("").slice(0, 64)}`; @@ -28,21 +26,6 @@ describe("SpokeUtils", function () { exclusivityDeadline: random(), }; - it.only("getMaxFillDeadlineInRange returns the correct fill deadline", async function () { - const rpcFactory = new CachedSolanaRpcFactory( - "sdk-test", - undefined, - 10, - 0, - undefined, - "https://api.mainnet-beta.solana.com", - 34268394551451 - ); - const provider = rpcFactory.createRpcClient(); - const fillDeadline = await getMaxFillDeadlineInRange({ provider }, 0, 100); - console.log(fillDeadline); - }); - it("getRelayEventKey correctly concatenates an event key", function () { const eventKey = getRelayEventKey(sampleData); const expectedKey = From fe2b2259fca16a0c8e244e4d6e1bab3439bc28e7 Mon Sep 17 00:00:00 2001 From: Melisa Guevara Date: Tue, 15 Apr 2025 12:05:15 -0300 Subject: [PATCH 3/5] set state pda as a client property --- src/arch/svm/SpokeUtils.ts | 23 +++---------------- src/arch/svm/utils.ts | 19 ++++++++++++++- .../SpokePoolClient/SVMSpokePoolClient.ts | 16 ++++++++++--- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/arch/svm/SpokeUtils.ts b/src/arch/svm/SpokeUtils.ts index 60133011f..2b6923185 100644 --- a/src/arch/svm/SpokeUtils.ts +++ b/src/arch/svm/SpokeUtils.ts @@ -1,4 +1,4 @@ -import { Rpc, SolanaRpcApi, Address, getProgramDerivedAddress, address, getU64Encoder } from "@solana/kit"; +import { Rpc, SolanaRpcApi, Address } from "@solana/kit"; import { Deposit, FillStatus, FillWithBlock, RelayData } from "../../interfaces"; import { BigNumber, isUnsafeDepositId } from "../../utils"; @@ -50,11 +50,10 @@ export async function getTimestampForBlock(provider: Provider, blockNumber: numb /** * Returns the current fill deadline buffer. * @param provider SVM Provider instance - * @param programId Program ID from which State account is derived. + * @param statePda Spoke Pool's State PDA * @returns fill deadline buffer */ -export async function getFillDeadline(provider: Provider, programId: string): Promise { - const statePda = await getStatePda(programId); +export async function getFillDeadline(provider: Provider, statePda: Address): Promise { const state = await fetchState(provider, statePda); return state.data.fillDeadlineBuffer; } @@ -175,19 +174,3 @@ export function findFillEvent( ): Promise { throw new Error("fillStatusArray: not implemented"); } - -/** - * Returns the PDA for the State account. - * @param programId The SpokePool program ID. - * @param extraSeed An optional extra seed. Defaults to 0. - * @returns The PDA for the State account. - */ -export async function getStatePda(programId: string, extraSeed = 0): Promise
{ - const seedEncoder = getU64Encoder(); - const encodedExtraSeed = seedEncoder.encode(extraSeed); - const [statePda] = await getProgramDerivedAddress({ - programAddress: address(programId), - seeds: ["state", encodedExtraSeed], - }); - return statePda; -} diff --git a/src/arch/svm/utils.ts b/src/arch/svm/utils.ts index 5b1c18f7c..e628ddab9 100644 --- a/src/arch/svm/utils.ts +++ b/src/arch/svm/utils.ts @@ -1,5 +1,6 @@ import { BN, BorshEventCoder, Idl } from "@coral-xyz/anchor"; -import web3, { address, RpcTransport } from "@solana/kit"; +import web3, { address, getProgramDerivedAddress, getU64Encoder, Address, RpcTransport } from "@solana/kit"; + import { EventName, EventData, SVMEventNames } from "./types"; /** @@ -64,3 +65,19 @@ export function getEventName(rawName: string): EventName { if (Object.values(SVMEventNames).some((name) => rawName.includes(name))) return rawName as EventName; throw new Error(`Unknown event name: ${rawName}`); } + +/** + * Returns the PDA for the State account. + * @param programId The SpokePool program ID. + * @param extraSeed An optional extra seed. Defaults to 0. + * @returns The PDA for the State account. + */ +export async function getStatePda(programId: string, extraSeed = 0): Promise
{ + const seedEncoder = getU64Encoder(); + const encodedExtraSeed = seedEncoder.encode(extraSeed); + const [statePda] = await getProgramDerivedAddress({ + programAddress: address(programId), + seeds: ["state", encodedExtraSeed], + }); + return statePda; +} diff --git a/src/clients/SpokePoolClient/SVMSpokePoolClient.ts b/src/clients/SpokePoolClient/SVMSpokePoolClient.ts index 2293ad164..ed6e183b8 100644 --- a/src/clients/SpokePoolClient/SVMSpokePoolClient.ts +++ b/src/clients/SpokePoolClient/SVMSpokePoolClient.ts @@ -1,11 +1,18 @@ import winston from "winston"; -import { Rpc, SolanaRpcApiFromTransport, RpcTransport } from "@solana/kit"; +import { Address, Rpc, SolanaRpcApiFromTransport, RpcTransport } from "@solana/kit"; import { BigNumber, DepositSearchResult, EventSearchConfig, MakeOptional } from "../../utils"; -import { SvmSpokeEventsClient, SVMEventNames, getFillDeadline, getTimestampForBlock } from "../../arch/svm"; +import { + SvmSpokeEventsClient, + SVMEventNames, + getFillDeadline, + getTimestampForBlock, + getStatePda, +} from "../../arch/svm"; import { HubPoolClient } from "../HubPoolClient"; import { knownEventNames, SpokePoolClient, SpokePoolUpdate } from "./SpokePoolClient"; import { RelayData, FillStatus } from "../../interfaces"; + /** * SvmSpokePoolClient is a client for the SVM SpokePool program. It extends the base SpokePoolClient * and implements the abstract methods required for interacting with an SVM Spoke Pool. @@ -21,6 +28,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { deploymentSlot: bigint, // Using slot instead of block number for SVM eventSearchConfig: MakeOptional, protected programId: string, + protected statePda: Address, protected svmEventsClient: SvmSpokeEventsClient, protected rpc: Rpc> ) { @@ -40,6 +48,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { programId: string, rpc: Rpc> ): Promise { + const statePda = await getStatePda(programId); const svmEventsClient = await SvmSpokeEventsClient.create(rpc); return new SvmSpokePoolClient( logger, @@ -48,6 +57,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { deploymentSlot, eventSearchConfig, programId, + statePda, svmEventsClient, rpc ); @@ -158,7 +168,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { * @note This function assumes that fill deadline buffer is a constant value in svm environments. */ public override getMaxFillDeadlineInRange(_startSlot: number, _endSlot: number): Promise { - return getFillDeadline(this.rpc, this.programId); + return getFillDeadline(this.rpc, this.statePda); } /** From d7e3dd696d67a778dd5866525be71f0fdf406fdc Mon Sep 17 00:00:00 2001 From: Melisa Guevara Date: Wed, 16 Apr 2025 13:42:10 -0300 Subject: [PATCH 4/5] fix programId type --- src/arch/svm/eventsClient.ts | 4 ++++ src/arch/svm/utils.ts | 4 ++-- src/clients/SpokePoolClient/SVMSpokePoolClient.ts | 6 +++--- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/arch/svm/eventsClient.ts b/src/arch/svm/eventsClient.ts index 1be71c10f..42d51ece8 100644 --- a/src/arch/svm/eventsClient.ts +++ b/src/arch/svm/eventsClient.ts @@ -209,4 +209,8 @@ export class SvmSpokeEventsClient { return events; } + + public getSvmSpokeAddress(): Address { + return this.svmSpokeAddress; + } } diff --git a/src/arch/svm/utils.ts b/src/arch/svm/utils.ts index e628ddab9..939b421ec 100644 --- a/src/arch/svm/utils.ts +++ b/src/arch/svm/utils.ts @@ -72,11 +72,11 @@ export function getEventName(rawName: string): EventName { * @param extraSeed An optional extra seed. Defaults to 0. * @returns The PDA for the State account. */ -export async function getStatePda(programId: string, extraSeed = 0): Promise
{ +export async function getStatePda(programId: Address, extraSeed = 0): Promise
{ const seedEncoder = getU64Encoder(); const encodedExtraSeed = seedEncoder.encode(extraSeed); const [statePda] = await getProgramDerivedAddress({ - programAddress: address(programId), + programAddress: programId, seeds: ["state", encodedExtraSeed], }); return statePda; diff --git a/src/clients/SpokePoolClient/SVMSpokePoolClient.ts b/src/clients/SpokePoolClient/SVMSpokePoolClient.ts index ed6e183b8..b97a6ce4c 100644 --- a/src/clients/SpokePoolClient/SVMSpokePoolClient.ts +++ b/src/clients/SpokePoolClient/SVMSpokePoolClient.ts @@ -27,7 +27,7 @@ export class SvmSpokePoolClient extends SpokePoolClient { chainId: number, deploymentSlot: bigint, // Using slot instead of block number for SVM eventSearchConfig: MakeOptional, - protected programId: string, + protected programId: Address, protected statePda: Address, protected svmEventsClient: SvmSpokeEventsClient, protected rpc: Rpc> @@ -45,11 +45,11 @@ export class SvmSpokePoolClient extends SpokePoolClient { chainId: number, deploymentSlot: bigint, eventSearchConfig: MakeOptional = { fromBlock: 0, maxBlockLookBack: 0 }, // Provide default - programId: string, rpc: Rpc> ): Promise { - const statePda = await getStatePda(programId); const svmEventsClient = await SvmSpokeEventsClient.create(rpc); + const programId = svmEventsClient.getSvmSpokeAddress(); + const statePda = await getStatePda(programId); return new SvmSpokePoolClient( logger, hubPoolClient, From d37346b126d901ce19ff89ac47bfcb49d98e8766 Mon Sep 17 00:00:00 2001 From: Melisa Guevara Date: Mon, 21 Apr 2025 19:55:03 -0300 Subject: [PATCH 5/5] remove extra seed param for getting state pda --- src/arch/svm/utils.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/arch/svm/utils.ts b/src/arch/svm/utils.ts index 939b421ec..65fbbc44d 100644 --- a/src/arch/svm/utils.ts +++ b/src/arch/svm/utils.ts @@ -69,15 +69,14 @@ export function getEventName(rawName: string): EventName { /** * Returns the PDA for the State account. * @param programId The SpokePool program ID. - * @param extraSeed An optional extra seed. Defaults to 0. * @returns The PDA for the State account. */ -export async function getStatePda(programId: Address, extraSeed = 0): Promise
{ - const seedEncoder = getU64Encoder(); - const encodedExtraSeed = seedEncoder.encode(extraSeed); +export async function getStatePda(programId: Address): Promise
{ + const intEncoder = getU64Encoder(); + const seed = intEncoder.encode(0); const [statePda] = await getProgramDerivedAddress({ programAddress: programId, - seeds: ["state", encodedExtraSeed], + seeds: ["state", seed], }); return statePda; }