github.com/gagliardetto/solana-go@v1.11.0/rpc/simulateTransaction.go (about) 1 // Copyright 2021 github.com/gagliardetto 2 // This file has been modified by github.com/gagliardetto 3 // 4 // Copyright 2020 dfuse Platform Inc. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 package rpc 18 19 import ( 20 "context" 21 "encoding/base64" 22 "fmt" 23 24 "github.com/gagliardetto/solana-go" 25 ) 26 27 type SimulateTransactionResponse struct { 28 RPCContext 29 Value *SimulateTransactionResult `json:"value"` 30 } 31 32 type SimulateTransactionResult struct { 33 // Error if transaction failed, null if transaction succeeded. 34 Err interface{} `json:"err,omitempty"` 35 36 // Array of log messages the transaction instructions output during execution, 37 // null if simulation failed before the transaction was able to execute 38 // (for example due to an invalid blockhash or signature verification failure) 39 Logs []string `json:"logs,omitempty"` 40 41 // Array of accounts with the same length as the accounts.addresses array in the request. 42 Accounts []*Account `json:"accounts"` 43 44 // The number of compute budget units consumed during the processing of this transaction. 45 UnitsConsumed *uint64 `json:"unitsConsumed,omitempty"` 46 } 47 48 // SimulateTransaction simulates sending a transaction. 49 func (cl *Client) SimulateTransaction( 50 ctx context.Context, 51 transaction *solana.Transaction, 52 ) (out *SimulateTransactionResponse, err error) { 53 return cl.SimulateTransactionWithOpts( 54 ctx, 55 transaction, 56 nil, 57 ) 58 } 59 60 type SimulateTransactionOpts struct { 61 // If true the transaction signatures will be verified 62 // (default: false, conflicts with ReplaceRecentBlockhash) 63 SigVerify bool 64 65 // Commitment level to simulate the transaction at. 66 // (default: "finalized"). 67 Commitment CommitmentType 68 69 // If true the transaction recent blockhash will be replaced with the most recent blockhash. 70 // (default: false, conflicts with SigVerify) 71 ReplaceRecentBlockhash bool 72 73 Accounts *SimulateTransactionAccountsOpts 74 } 75 76 type SimulateTransactionAccountsOpts struct { 77 // (optional) Encoding for returned Account data, 78 // either "base64" (default), "base64+zstd" or "jsonParsed". 79 // - "jsonParsed" encoding attempts to use program-specific state parsers 80 // to return more human-readable and explicit account state data. 81 // If "jsonParsed" is requested but a parser cannot be found, 82 // the field falls back to binary encoding, detectable when 83 // the data field is type <string>. 84 Encoding solana.EncodingType 85 86 // An array of accounts to return. 87 Addresses []solana.PublicKey 88 } 89 90 // SimulateTransaction simulates sending a transaction. 91 func (cl *Client) SimulateTransactionWithOpts( 92 ctx context.Context, 93 transaction *solana.Transaction, 94 opts *SimulateTransactionOpts, 95 ) (out *SimulateTransactionResponse, err error) { 96 txData, err := transaction.MarshalBinary() 97 if err != nil { 98 return nil, fmt.Errorf("send transaction: encode transaction: %w", err) 99 } 100 return cl.SimulateRawTransactionWithOpts(ctx, txData, opts) 101 } 102 103 func (cl *Client) SimulateRawTransactionWithOpts( 104 ctx context.Context, 105 txData []byte, 106 opts *SimulateTransactionOpts, 107 ) (out *SimulateTransactionResponse, err error) { 108 obj := M{ 109 "encoding": "base64", 110 } 111 if opts != nil { 112 if opts.SigVerify { 113 obj["sigVerify"] = opts.SigVerify 114 } 115 if opts.Commitment != "" { 116 obj["commitment"] = opts.Commitment 117 } 118 if opts.ReplaceRecentBlockhash { 119 obj["replaceRecentBlockhash"] = opts.ReplaceRecentBlockhash 120 } 121 if opts.Accounts != nil { 122 obj["accounts"] = M{ 123 "encoding": opts.Accounts.Encoding, 124 "addresses": opts.Accounts.Addresses, 125 } 126 } 127 } 128 129 b64Data := base64.StdEncoding.EncodeToString(txData) 130 params := []interface{}{ 131 b64Data, 132 obj, 133 } 134 135 err = cl.rpcClient.CallForInto(ctx, &out, "simulateTransaction", params) 136 return 137 }