import type { Address } from '@solana/addresses'; import type { Base58EncodedBytes, Base58EncodedDataResponse, Base64EncodedDataResponse, Blockhash } from '@solana/rpc-types'; import type { CompiledTransactionMessage, CompiledTransactionMessageWithLifetime, TransactionVersion } from '@solana/transaction-messages'; import type { Transaction } from '@solana/transactions'; import type { LoadedAddresses } from './loaded-addresses'; /** * The subset of a wire-format transaction response (`encoding: 'base58'` or * `'base64'`) that {@link decodeTransactionFromRpcResponse} reads: the * base-encoded wire-transaction tuple, plus the optional `meta` (carrying * `loadedAddresses`) and `version`. * * Only these fields are modeled — not the full RPC response envelope — so any * response carrying a compatible wire-transaction tuple satisfies it * structurally, regardless of which method produced it (`getTransaction`, * `getTransactionsForAddress`, or a future one). */ type DecodableWireTransactionResponse = Readonly<{ meta?: unknown; transaction: Base58EncodedDataResponse | Base64EncodedDataResponse; version?: TransactionVersion; }>; /** * The subset of an `encoding: 'json'` transaction response that * {@link decodeTransactionFromRpcResponse} reads. Only the message fields the * decoder actually consumes are modeled, so any response carrying a compatible * `transaction.message` satisfies it structurally, regardless of which method * produced it. */ type DecodableJsonTransactionResponse = Readonly<{ meta?: unknown; transaction: Readonly<{ message: Readonly<{ accountKeys: readonly Address[]; addressTableLookups?: readonly Readonly<{ accountKey: Address; readonlyIndexes: readonly number[]; writableIndexes: readonly number[]; }>[] | null; header: Readonly<{ numReadonlySignedAccounts: number; numReadonlyUnsignedAccounts: number; numRequiredSignatures: number; }>; instructions: readonly Readonly<{ accounts: readonly number[]; data: Base58EncodedBytes; programIdIndex: number; }>[]; recentBlockhash: Blockhash; }>; }>; version?: TransactionVersion; }>; /** * The result of decoding a confirmed-transaction RPC response: the * {@link CompiledTransactionMessage} (always with a `lifetimeToken` carrying * the recent blockhash), the loaded ALT addresses pulled from `meta` (if * any), and — for `'base64'` and `'base58'` responses — the wire-format * {@link Transaction}. * * `transaction` is omitted for `encoding: 'json'` responses: the server * has already decompiled the wire format, so there are no message bytes * to round-trip. If you need a re-encodable {@link Transaction}, fetch * the response with `encoding: 'base64'`. * * @example * ```ts * const { compiledMessage, loadedAddresses, transaction } = * decodeTransactionFromRpcResponse(rpcResponse); * ``` */ export type DecodedRpcTransaction = Readonly<{ compiledMessage: CompiledTransactionMessage & CompiledTransactionMessageWithLifetime; loadedAddresses: LoadedAddresses; transaction?: Transaction; }>; /** * Decodes a confirmed-transaction RPC response (any of `encoding: 'base64'`, * `'base58'`, or `'json'`) into a {@link CompiledTransactionMessage} plus, * for `'base64'` and `'base58'`, a re-encodable {@link Transaction}. The * JSON path does not produce a `Transaction`: the server has already * decompiled the wire format, so there are no message bytes to carry. * * Because it reads only the `transaction` / `meta` / `version` envelope — * not a method-specific response shape — it accepts results from any method * that returns confirmed transactions in these encodings: `getTransaction`, * `getTransactionsForAddress`, and `getBlock` (the latter two with * `transactionDetails: 'full'`). The array-returning methods just need a map: * * ```ts * const { data } = await rpc.getTransactionsForAddress(address, { * encoding: 'base64', * maxSupportedTransactionVersion: 0, * transactionDetails: 'full', * }).send(); * const decoded = data.map(tx => decodeTransactionFromRpcResponse(tx)); * * const block = await rpc.getBlock(slot, { * encoding: 'base64', * maxSupportedTransactionVersion: 0, * transactionDetails: 'full', * }).send(); * const decodedBlockTxs = block?.transactions.map(tx => decodeTransactionFromRpcResponse(tx)) ?? []; * ``` * * `'jsonParsed'` is **not** supported — its instructions arrive * pre-parsed by the server and lack raw bytes, so they cannot be * round-tripped through the auto-generated `parseXInstruction` clients. * Passing a `'jsonParsed'` response throws * {@link SOLANA_ERROR__TRANSACTION_INTROSPECTION__CANNOT_DECODE_JSON_PARSED_TRANSACTION}; * any other unrecognized input throws * {@link SOLANA_ERROR__TRANSACTION_INTROSPECTION__UNRECOGNIZED_GET_TRANSACTION_RESPONSE}. * * A response carrying a transaction version this package cannot decode * throws {@link SOLANA_ERROR__TRANSACTION__VERSION_NUMBER_NOT_SUPPORTED} — * raised by the JSON path for an unrecognized `version`, and by the wire * decoders for malformed binary input. * * Use this together with {@link getInstructionsFromCompiledTransactionMessage} * (or {@link walkInstructions}) to inspect a confirmed transaction's * instructions in a form the auto-generated `@solana-program/*` clients * can `parse` directly. * * Prefer `encoding: 'base64'` when bandwidth allows — it is the most * compact, the wire bytes round-trip cleanly through the kit codecs, and * the return type statically guarantees a re-encodable `transaction`. * * @example * ```ts * const rpcResponse = await rpc.getTransaction(signature(txid), { * commitment: 'confirmed', * encoding: 'base64', * maxSupportedTransactionVersion: 0, * }).send(); * if (!rpcResponse) throw new Error('not found'); * * const { compiledMessage, loadedAddresses } = decodeTransactionFromRpcResponse(rpcResponse); * const instructions = getInstructionsFromCompiledTransactionMessage(compiledMessage, loadedAddresses); * ``` */ export declare function decodeTransactionFromRpcResponse(rpcTx: DecodableWireTransactionResponse): DecodedRpcTransaction & { transaction: Transaction; }; export declare function decodeTransactionFromRpcResponse(rpcTx: DecodableJsonTransactionResponse): DecodedRpcTransaction & { transaction?: never; }; export {}; //# sourceMappingURL=decode-rpc-transaction.d.ts.map