diff --git a/rpc/simulateTransaction.go b/rpc/simulateTransaction.go index 572e0818d..290651c87 100644 --- a/rpc/simulateTransaction.go +++ b/rpc/simulateTransaction.go @@ -41,6 +41,9 @@ type SimulateTransactionResult struct { // Array of accounts with the same length as the accounts.addresses array in the request. Accounts []*Account `json:"accounts"` + // Array of parsed inner instructions + InnerInstructions []SimulatedInnerInstructions `json:"innerInstructions"` + // The number of compute budget units consumed during the processing of this transaction. UnitsConsumed *uint64 `json:"unitsConsumed,omitempty"` } @@ -70,6 +73,10 @@ type SimulateTransactionOpts struct { // (default: false, conflicts with SigVerify) ReplaceRecentBlockhash bool + // If true the response will include inner instructions. + // These inner instructions will be jsonParsed where possible, otherwise json. + InnerInstructions bool + Accounts *SimulateTransactionAccountsOpts } @@ -118,6 +125,9 @@ func (cl *Client) SimulateRawTransactionWithOpts( if opts.ReplaceRecentBlockhash { obj["replaceRecentBlockhash"] = opts.ReplaceRecentBlockhash } + if opts.InnerInstructions { + obj["innerInstructions"] = opts.InnerInstructions + } if opts.Accounts != nil { obj["accounts"] = M{ "encoding": opts.Accounts.Encoding, diff --git a/rpc/types.go b/rpc/types.go index 2bb942998..a9ff4610c 100644 --- a/rpc/types.go +++ b/rpc/types.go @@ -237,6 +237,50 @@ type InnerInstruction struct { Instructions []CompiledInstruction `json:"instructions"` } +// The parsed data of inner instructions returned by RPC when simulating transaction +type SimulatedInnerInstructions struct { + // TODO: == int64 ??? + // Index of the transaction instruction from which the inner instruction(s) originated + Index uint16 `json:"index"` + + // Ordered list of inner program instructions that were invoked during a single transaction instruction. + Instructions []SimulatedParsedInstruction `json:"instructions"` +} + +// The parsed inner instruction returned by RPC when simulating transaction +type SimulatedParsedInstruction struct { + Parsed InstructionParsedData `json:"parsed"` + Accounts []solana.PublicKey `json:"accounts"` + ProgramId solana.PublicKey `json:"programId"` + Data solana.Base58 `json:"data"` + StackHeight uint16 `json:"stackHeight"` +} + +type InstructionParsedData struct { + Info InstructionInfoFields `json:"info"` + Type InstructionActionType `json:"type"` +} + +type InstructionInfoFields struct { + Authority *solana.PublicKey `json:"authority,omitempty"` + Destination *solana.PublicKey `json:"destination,omitempty"` + Source *solana.PublicKey `json:"source,omitempty"` + Account *solana.PublicKey `json:"account,omitempty"` + Mint *solana.PublicKey `json:"mint,omitempty"` + Owner *solana.PublicKey `json:"owner,omitempty"` + NewAccount *solana.PublicKey `json:"newAccount,omitempty"` + + // Token transfer + TokenAmount *UiTokenAmount `json:"tokenAmount,omitempty"` + + // Create account + Lamports *uint64 `json:"lamports,omitempty"` + Space *uint64 `json:"space,omitempty"` + + // Extension types + ExtensionTypes *[]string `json:"extensionTypes,omitempty"` +} + type CompiledInstruction struct { // Index into the message.accountKeys array indicating the program account that executes this instruction. // NOTE: it is actually a uint8, but using a uint16 because uint8 is treated as a byte everywhere, @@ -476,6 +520,18 @@ const ( CommitmentProcessed CommitmentType = "processed" ) +// action type for parsed simulated inner instruction +type InstructionActionType string + +const ( + CreateAccount InstructionActionType = "createAccount" + Transfer InstructionActionType = "transfer" + TransferChecked InstructionActionType = "transferChecked" + GetAccountDataSize InstructionActionType = "getAccountDataSize" + InitializeImmutableOwner InstructionActionType = "initializeImmutableOwner" + InitializeAccount3 InstructionActionType = "initializeAccount3" +) + type ParsedTransaction struct { Signatures []solana.Signature `json:"signatures"` Message ParsedMessage `json:"message"` @@ -535,7 +591,7 @@ type ParsedInstruction struct { Parsed *InstructionInfoEnvelope `json:"parsed,omitempty"` Data solana.Base58 `json:"data,omitempty"` Accounts []solana.PublicKey `json:"accounts,omitempty"` - StackHeight int64 `json:"stackHeight"` + StackHeight uint16 `json:"stackHeight"` } type InstructionInfoEnvelope struct {