import { address, type Account, type Address, type Rpc } from '@solana/kit' import { type GetProgramAccountsApi } from '@solana/rpc-api' import { type GetAccountInfoApi } from '@solana/rpc-api' import type { Base64EncodedBytes, Lamports } from '@solana/rpc-types' import { decodeSolistingStateOrderAccount, fetchSolistingStateOrderAccount, getSolistingStateOrderAccountDiscriminatorBytes, type SolistingStateOrderAccount, } from './generated/solisting/src/generated/index' import { deriveEscrowId } from './pda' const PROGRAM_ADDRESS = address('9uF64swnFqo34oFJtv8Qx9JDyXXJz73eDFF4cKRBfQBZ') export type OrderAccountWithPda = Account type GpaRpc = Rpc type GetRpc = Rpc // OrderAccount byte layout (Sol-currency variant, the only one currently implemented): // 0: discriminator (8) // 8: listing (32) // 40: buyer (32) // 72: seller (32) // 104: resolver Option = 1 byte tag + 32 bytes = 33 bytes // 137: paymentCurrency — Sol variant = 1 byte tag + 0 data = 1 byte total // 138: amount (8) // 146: escrowAccount (32) const LISTING_OFFSET = 8n const BUYER_OFFSET = 40n // escrowAccount offset is only valid for Sol-currency orders. // SPL orders (currently rejected by the program with SplNotImplemented) would sit at offset 179. const ESCROW_ACCOUNT_OFFSET = 146n type RawGpaResult = Array<{ pubkey: Address account: { executable: boolean lamports: bigint owner: Address space: bigint data: [string, 'base64'] } }> const DISC_BASE64 = Buffer.from( getSolistingStateOrderAccountDiscriminatorBytes(), ).toString('base64') as Base64EncodedBytes async function gpa( rpc: GpaRpc, addressFilter: { offset: bigint; addr: Address }, ): Promise { const results = await rpc .getProgramAccounts(PROGRAM_ADDRESS, { encoding: 'base64', filters: [ { memcmp: { offset: 0n, bytes: DISC_BASE64, encoding: 'base64' } }, { memcmp: { offset: addressFilter.offset, bytes: addressFilter.addr as never, encoding: 'base58' } }, ], }) .send() return (results as RawGpaResult).map((r) => { const data = new Uint8Array(Buffer.from(r.account.data[0], 'base64')) return decodeSolistingStateOrderAccount({ address: r.pubkey, data, executable: r.account.executable, lamports: r.account.lamports as unknown as Lamports, programAddress: r.account.owner, space: r.account.space, exists: true, }) as OrderAccountWithPda }) } export function fetchOrdersForListing(rpc: GpaRpc, listingPk: Address): Promise { return gpa(rpc, { offset: LISTING_OFFSET, addr: listingPk }) } export function fetchOrdersByBuyer(rpc: GpaRpc, buyer: Address): Promise { return gpa(rpc, { offset: BUYER_OFFSET, addr: buyer }) } export async function fetchOrderByEscrow(rpc: GpaRpc, escrowPda: Address): Promise { const results = await gpa(rpc, { offset: ESCROW_ACCOUNT_OFFSET, addr: escrowPda }) return results[0] ?? null } export async function fetchOrder(rpc: GetRpc, addr: Address): Promise { return fetchSolistingStateOrderAccount(rpc, addr).catch(() => null) } export { deriveEscrowId }