Resumen
@solana/transaction-introspection convierte una respuesta RPC de
getTransaction en una lista de instrucciones con direcciones reales.
Resuelve índices de cuentas (incluidas las direcciones de tablas de búsqueda),
decodifica instrucciones CPI internas y recorre el árbol de instrucciones
completo en el orden del explorador.
¿Buscas cómo un programa inspecciona instrucciones hermanas en cadena en tiempo de ejecución? Eso es el sysvar de instrucciones - consulta Introspección de Instrucciones. Esta página trata sobre la decodificación de una transacción fuera de cadena a partir de una respuesta RPC.
Una respuesta de getTransaction no te entrega
una lista de instrucciones lista para usar. Las cuentas se almacenan como
índices numéricos, las
transacciones versionadas
dividen esas cuentas en claves estáticas más direcciones cargadas desde
Tablas de Búsqueda de Direcciones,
y las instrucciones internas de Cross Program Invocation (CPIs) llegan como
blobs codificados en los metadatos de la transacción.
@solana/transaction-introspection realiza esta resolución por ti. Decodifica
la transacción en formato de red, mapea cada índice de cuenta de vuelta a su
Address, normaliza las instrucciones internas y devuelve las instrucciones en
el mismo orden externo-luego-interno que muestra un explorador de bloques. Las
instrucciones devueltas se conectan directamente a los helpers
parseXInstruction de los clientes generados por codama (p. ej.,
@solana-program/* ).
npm install @solana/transaction-introspection @solana/kit @solana/instructions @solana-program/token
Decodificar la respuesta
Obtén la transacción con una codificación en formato de red y pasa la respuesta
a decodeTransactionFromRpcResponse.
import { createSolanaRpc, signature } from "@solana/kit";import { decodeTransactionFromRpcResponse } from "@solana/transaction-introspection";const rpc = createSolanaRpc("https://api.mainnet-beta.solana.com");const txid ="3jUKrQp1UGq5ih6FTDUUt2kkqUfoG2o4kY5T1DoVHK2tXXDLdxJSXzuJGY4JPoRivgbi45U2bc7LZfMa6C4R3szX";const rpcTx = await rpc.getTransaction(signature(txid), {commitment: "confirmed",encoding: "base64",maxSupportedTransactionVersion: 0}).send();if (!rpcTx) throw new Error(`Transaction ${txid} not found`);const { compiledMessage, loadedAddresses } =decodeTransactionFromRpcResponse(rpcTx);
Los fragmentos restantes reutilizan rpcTx, compiledMessage y
loadedAddresses de este paso.
Realiza la solicitud con codificación base64, base58 o json.
decodeTransactionFromRpcResponse rechaza las respuestas jsonParsed: esa
codificación le pide al nodo RPC que analice las instrucciones en el servidor,
por lo que no queda nada que decodificar en el cliente.
Recorrer las instrucciones
walkInstructions devuelve cada instrucción — externas e internas — como un
array en el orden que muestra un explorador de bloques: cada instrucción externa
seguida inmediatamente por las instrucciones internas que generaron sus CPIs.
Cada instrucción incluye un campo trace que describe su posición en la
jerarquía de llamadas.
import { walkInstructions } from "@solana/transaction-introspection";for (const ix of walkInstructions({compiledMessage,loadedAddresses,meta: rpcTx.meta})) {const location =ix.trace.kind === "outer"? `outer[${ix.trace.index}]`: `inner[${ix.trace.outerIndex}/${ix.trace.innerIndex}]`;console.log(location, ix.programAddress, ix.accounts?.length ?? 0);}
El trace es una unión discriminada: { kind: "outer", index } para una
instrucción de nivel superior, o
{ kind: "inner", outerIndex, innerIndex, stackHeight? } para una instrucción
CPI anidada bajo una instrucción externa.
meta es opcional — pasa rpcTx.meta directamente aunque pueda ser null. Sin
metadatos, walkInstructions devuelve únicamente las instrucciones externas.
Parsear con un cliente de programa
Cada instrucción de walkInstructions es un ResolvedInstruction, por lo que
funciona directamente con los predicados de @solana/instructions y los helpers
identifyXInstruction / parseXInstruction generados por los clientes
@solana-program/* — sin paso de conversión.
Este ejemplo audita cada instrucción SyncNative de Token Program en una
transacción, tanto si se ejecutó en el nivel superior como dentro de un CPI.
import {isInstructionForProgram,isInstructionWithAccounts,isInstructionWithData} from "@solana/instructions";import { walkInstructions } from "@solana/transaction-introspection";import {identifyTokenInstruction,parseSyncNativeInstruction,TOKEN_PROGRAM_ADDRESS,TokenInstruction} from "@solana-program/token";for (const ix of walkInstructions({compiledMessage,loadedAddresses,meta: rpcTx.meta})) {if (!isInstructionForProgram(ix, TOKEN_PROGRAM_ADDRESS)) continue;if (!isInstructionWithData(ix) || !isInstructionWithAccounts(ix)) continue;if (identifyTokenInstruction(ix) !== TokenInstruction.SyncNative) continue;const parsed = parseSyncNativeInstruction(ix);console.log(ix.trace, parsed);}
Helpers de nivel inferior
walkInstructions cubre la mayoría de los casos, pero el paquete también expone
los componentes sobre los que se construye:
getInstructionsFromCompiledTransactionMessage(compiledMessage, loadedAddresses?)devuelve únicamente las instrucciones externas, con cuentas resueltas y datos decodificados.getInnerInstructionsFromMeta(meta, accountMetas)decodifica las instrucciones CPI internas a partir de los metadatos de la transacción.getAccountMetasFromCompiledTransactionMessage(compiledMessage, loadedAddresses?)devuelve la lista completa de cuentas en el orden de la transacción — la entrada que el helper anterior necesita para resolver los índices de cuentas de las instrucciones internas.
import {getAccountMetasFromCompiledTransactionMessage,getInnerInstructionsFromMeta,getInstructionsFromCompiledTransactionMessage} from "@solana/transaction-introspection";const outer = getInstructionsFromCompiledTransactionMessage(compiledMessage,loadedAddresses);const accountMetas = getAccountMetasFromCompiledTransactionMessage(compiledMessage,loadedAddresses);if (!rpcTx.meta) throw new Error("Transaction metadata missing");const inner = getInnerInstructionsFromMeta(rpcTx.meta, accountMetas);
¿Usas Rust?
No existe un equivalente en Rust de este paquete. Para obtener instrucciones
parseadas desde Rust, solicita UiTransactionEncoding::JsonParsed desde
getTransaction y deja que el nodo RPC
resuelva las cuentas y las instrucciones internas por ti.
Ver también
- Estructura de la Transacción - la anatomía de la respuesta que este paquete decodifica
- Transacciones Versionadas - cómo las Tablas de Búsqueda de Direcciones dividen las cuentas en grupos estáticos y cargados
getTransaction- el método RPC que devuelve la transacción
Is this page helpful?