|
1 |
| -import { Rpc, SolanaRpcApi } from "@solana/kit"; |
| 1 | +import { |
| 2 | + Rpc, |
| 3 | + SolanaRpcApi, |
| 4 | + Address, |
| 5 | + getProgramDerivedAddress, |
| 6 | + address, |
| 7 | + getStructDecoder, |
| 8 | + getBooleanCodec, |
| 9 | + getU32Codec, |
| 10 | + getU64Codec, |
| 11 | + getAddressCodec, |
| 12 | + getAddressDecoder, |
| 13 | +} from "@solana/kit"; |
| 14 | + |
2 | 15 | import { Deposit, FillStatus, FillWithBlock, RelayData } from "../../interfaces";
|
3 | 16 | import { BigNumber, isUnsafeDepositId } from "../../utils";
|
| 17 | +import { snakeToCamel } from "../../svm/utils/events"; |
4 | 18 |
|
5 | 19 | type Provider = Rpc<SolanaRpcApi>;
|
6 | 20 |
|
@@ -52,12 +66,16 @@ export async function getTimestampForBlock(provider: Provider, blockNumber: numb
|
52 | 66 | * @param endBlock end block
|
53 | 67 | * @returns maximum of fill deadline buffer at start and end block
|
54 | 68 | */
|
55 |
| -export function getMaxFillDeadlineInRange( |
56 |
| - _spokePool: unknown, |
| 69 | +export async function getMaxFillDeadlineInRange( |
| 70 | + _spokePool: { provider: Provider }, |
57 | 71 | _startBlock: number,
|
58 | 72 | _endBlock: number
|
59 |
| -): Promise<number> { |
60 |
| - throw new Error("getMaxFillDeadlineInRange: not implemented"); |
| 73 | +): Promise<any> { |
| 74 | + const programId = "JAZWcGrpSWNPTBj8QtJ9UyQqhJCDhG9GJkDeMf5NQBiq"; // TODO: read this from the spokePool |
| 75 | + const statePda = await getStatePda(programId); |
| 76 | + const state = await queryStateFromStatePda(statePda, _spokePool.provider); |
| 77 | + |
| 78 | + return state.fillDeadlineBuffer; |
61 | 79 | }
|
62 | 80 |
|
63 | 81 | /**
|
@@ -176,3 +194,38 @@ export function findFillEvent(
|
176 | 194 | ): Promise<FillWithBlock | undefined> {
|
177 | 195 | throw new Error("fillStatusArray: not implemented");
|
178 | 196 | }
|
| 197 | + |
| 198 | +export async function queryStateFromStatePda(statePda: Address, provider: Provider) { |
| 199 | + const pdaAccountInfo = await provider.getAccountInfo(statePda, { encoding: "base64" }).send(); |
| 200 | + if (!pdaAccountInfo.value?.data) { |
| 201 | + throw new Error("State account data not found"); |
| 202 | + } |
| 203 | + const stateDecoder = getStructDecoder([ |
| 204 | + ["paused_deposits", getBooleanCodec()], |
| 205 | + ["paused_fills", getBooleanCodec()], |
| 206 | + ["owner", getAddressDecoder()], |
| 207 | + ["seed", getU64Codec()], |
| 208 | + ["number_of_deposits", getU32Codec()], |
| 209 | + ["chain_id", getU64Codec()], |
| 210 | + ["current_time", getU32Codec()], |
| 211 | + ["remote_domain", getU32Codec()], |
| 212 | + ["cross_domain_admin", getAddressCodec()], |
| 213 | + ["root_bundle_id", getU32Codec()], |
| 214 | + ["deposit_quote_time_buffer", getU32Codec()], |
| 215 | + ["fill_deadline_buffer", getU32Codec()], |
| 216 | + ]); |
| 217 | + const stateData = pdaAccountInfo.value.data[0]; |
| 218 | + const stateDataBytes = Buffer.from(stateData, "base64"); |
| 219 | + const discriminatorBytesSize = 8; |
| 220 | + const decodedState = stateDecoder.decode(Uint8Array.from(stateDataBytes), discriminatorBytesSize); |
| 221 | + return Object.fromEntries(Object.entries(decodedState).map(([key, value]) => [snakeToCamel(key), value])); |
| 222 | +} |
| 223 | + |
| 224 | +// TODO: Should accept seed |
| 225 | +export async function getStatePda(programId: string): Promise<Address> { |
| 226 | + const [statePda] = await getProgramDerivedAddress({ |
| 227 | + programAddress: address(programId), |
| 228 | + seeds: ["state", new Uint8Array(8)], // This only works if second seed is zero, make it dynamic |
| 229 | + }); |
| 230 | + return statePda; |
| 231 | +} |
0 commit comments