UNPKG

@wuwei-labs/srsly

Version:
103 lines 3.86 kB
/** * @purpose Contract account utilities for SRSLY * * Fetches contract state data from the SRSLY program. */ import { getBase64Encoder } from '@solana/kit'; import { fetchContractState, CONTRACT_STATE_DISCRIMINATOR, getContractStateDecoder, } from '../generated/codama/accounts'; import { SRSLY_PROGRAM_ADDRESS } from '../generated/codama/programs/srsly'; import { getRpcUrl } from '../utils/config'; import { createRpc } from '../utils/rpc'; /** * Fetch contract state from the SRSLY program * * @param contractAddress - Contract account address * @param rpcUrl - Optional RPC endpoint URL. If not provided, uses RPC from global config * @returns Contract state with fleet, gameId, ownerProfile, etc. * @throws Error if contract account not found or fetch fails * * @example * ```typescript * // Uses RPC URL from global config * const contract = await fetchContract('ContractAddress...'); * console.log(contract.data.fleet, contract.data.gameId); * * // Uses specific RPC URL * const contract2 = await fetchContract( * 'ContractAddress...', * 'https://api.devnet.solana.com' * ); * console.log('Rate:', contract2.data.rate); * ``` */ export async function fetchContract(contractAddress, rpcUrl) { try { // Get RPC URL from config or use provided const resolvedRpcUrl = rpcUrl || getRpcUrl(); const rpc = createRpc(resolvedRpcUrl); // Use Codama-generated fetch function const account = await fetchContractState(rpc, contractAddress); return account; } catch (error) { throw new Error(`Failed to fetch contract state at ${contractAddress}: ${error.message}`); } } /** * Fetch all contract state accounts from the SRSLY program * * Uses getProgramAccounts with a discriminator filter to find all ContractState accounts. * * @param rpcUrl - Optional RPC endpoint URL. If not provided, uses RPC from global config * @returns Array of contract states with their addresses * * @example * ```typescript * const contracts = await fetchAllContracts(); * console.log(`Found ${contracts.length} contracts`); * contracts.forEach(c => console.log(c.address, c.data.fleet)); * ``` */ export async function fetchAllContracts(rpcUrl) { try { const resolvedRpcUrl = rpcUrl || getRpcUrl(); const rpc = createRpc(resolvedRpcUrl); // Convert discriminator to base64 string for memcmp filter (browser-compatible) const discriminatorBase64 = btoa(String.fromCharCode(...CONTRACT_STATE_DISCRIMINATOR)); // getProgramAccounts uses branded string types — cast through any const response = await rpc .getProgramAccounts(SRSLY_PROGRAM_ADDRESS, { encoding: 'base64', filters: [ { memcmp: { offset: 0n, bytes: discriminatorBase64, encoding: 'base64', }, }, ], }) .send(); const base64Encoder = getBase64Encoder(); const decoder = getContractStateDecoder(); // @solana/kit returns the array directly, not wrapped in { value } const accounts = Array.isArray(response) ? response : response.value; const results = []; for (const account of accounts) { try { const bytes = base64Encoder.encode(account.account.data[0]); const decoded = decoder.decode(bytes); results.push({ data: decoded, address: account.pubkey }); } catch { // Skip accounts that fail to decode } } return results; } catch (error) { throw new Error(`Failed to fetch all contract states: ${error.message}`); } } //# sourceMappingURL=contract.js.map