diff --git a/governance/pyth_staking_sdk/src/pyth-staking-client.ts b/governance/pyth_staking_sdk/src/pyth-staking-client.ts index cd4317918..55380f513 100644 --- a/governance/pyth_staking_sdk/src/pyth-staking-client.ts +++ b/governance/pyth_staking_sdk/src/pyth-staking-client.ts @@ -49,6 +49,7 @@ import { type VoterWeightAction, type VestingSchedule, } from "./types"; +import { bigintMax } from "./utils/bigint"; import { convertBigIntToBN, convertBNToBigInt } from "./utils/bn"; import { epochToDate, getCurrentEpoch } from "./utils/clock"; import { extractPublisherData } from "./utils/pool"; @@ -680,12 +681,32 @@ export class PythStakingClient { stakeAccountPositions, ); const allPublishers = extractPublisherData(poolData); - const publishers = allPublishers.filter(({ pubkey }) => - stakeAccountPositionsData.data.positions.some( - ({ targetWithParameters }) => - targetWithParameters.integrityPool?.publisher.equals(pubkey), - ), - ); + const publishers = allPublishers + .map((publisher) => { + const positionsWithPublisher = + stakeAccountPositionsData.data.positions.filter( + ({ targetWithParameters }) => + targetWithParameters.integrityPool?.publisher.equals( + publisher.pubkey, + ), + ); + + let lowestEpoch; + for (const position of positionsWithPublisher) { + if ( + lowestEpoch === undefined || + position.activationEpoch < lowestEpoch + ) { + lowestEpoch = position.activationEpoch; + } + } + + return { + ...publisher, + lowestEpoch, + }; + }) + .filter(({ lowestEpoch }) => lowestEpoch !== undefined); const delegationRecords = await Promise.all( publishers.map(({ pubkey }) => @@ -693,6 +714,20 @@ export class PythStakingClient { ), ); + let lowestEpoch: bigint | undefined; + for (const [index, publisher] of publishers.entries()) { + const maximum = bigintMax( + publisher.lowestEpoch, + delegationRecords[index]?.lastEpoch, + ); + if ( + lowestEpoch === undefined || + (maximum !== undefined && maximum < lowestEpoch) + ) { + lowestEpoch = maximum; + } + } + const currentEpoch = await getCurrentEpoch(this.connection); // Filter out delegationRecord that are up to date @@ -738,7 +773,7 @@ export class PythStakingClient { return { advanceDelegationRecordInstructions, mergePositionsInstruction, - publishers, + lowestEpoch, }; } @@ -776,26 +811,12 @@ export class PythStakingClient { totalRewards += BigInt("0x" + buffer.toString("hex")); } - const delegationRecords = await Promise.all( - instructions.publishers.map(({ pubkey }) => - this.getDelegationRecord(stakeAccountPositions, pubkey), - ), - ); - - let lowestEpoch: bigint | undefined; - for (const record of delegationRecords) { - if ( - record !== null && - (lowestEpoch === undefined || record.lastEpoch < lowestEpoch) - ) { - lowestEpoch = record.lastEpoch; - } - } - return { totalRewards, expiry: - lowestEpoch === undefined ? undefined : epochToDate(lowestEpoch + 52n), + instructions.lowestEpoch === undefined + ? undefined + : epochToDate(instructions.lowestEpoch + 53n), }; } diff --git a/governance/pyth_staking_sdk/src/utils/bigint.ts b/governance/pyth_staking_sdk/src/utils/bigint.ts new file mode 100644 index 000000000..bc44ae691 --- /dev/null +++ b/governance/pyth_staking_sdk/src/utils/bigint.ts @@ -0,0 +1,9 @@ +export const bigintMax = (a: bigint | undefined, b: bigint | undefined) => { + if (a === undefined) { + return b; + } + if (b === undefined) { + return a; + } + return a > b ? a : b; +};