5
5
"encoding/json"
6
6
"errors"
7
7
"fmt"
8
+ "github.com/aptos-labs/aptos-go-sdk/crypto"
8
9
"io"
9
10
"log/slog"
10
11
"net/http"
@@ -16,7 +17,6 @@ import (
16
17
17
18
"github.com/aptos-labs/aptos-go-sdk/api"
18
19
"github.com/aptos-labs/aptos-go-sdk/bcs"
19
- "github.com/aptos-labs/aptos-go-sdk/crypto"
20
20
)
21
21
22
22
const (
@@ -676,18 +676,8 @@ type EstimateMaxGasAmount bool
676
676
type EstimatePrioritizedGasUnitPrice bool
677
677
678
678
// SimulateTransaction simulates a transaction
679
- //
680
- // TODO: This needs to support RawTransactionWithData
681
- // TODO: Support multikey simulation
682
679
func (rc * NodeClient ) SimulateTransaction (rawTxn * RawTransaction , sender TransactionSigner , options ... any ) (data []* api.UserTransaction , err error ) {
683
680
// build authenticator for simulation
684
- derivationScheme := sender .PubKey ().Scheme ()
685
- switch derivationScheme {
686
- case crypto .MultiEd25519Scheme :
687
- case crypto .MultiKeyScheme :
688
- // todo: add support for multikey simulation on the node
689
- return nil , fmt .Errorf ("currently unsupported sender derivation scheme %v" , derivationScheme )
690
- }
691
681
auth := sender .SimulationAuthenticator ()
692
682
693
683
// generate signed transaction for simulation (with zero signature)
@@ -696,6 +686,63 @@ func (rc *NodeClient) SimulateTransaction(rawTxn *RawTransaction, sender Transac
696
686
return nil , err
697
687
}
698
688
689
+ return rc .simulateTransactionInner (signedTxn , options ... )
690
+ }
691
+
692
+ // SimulateTransactionMultiAgent simulates a transaction as fee payer or multi agent
693
+ func (rc * NodeClient ) SimulateTransactionMultiAgent (rawTxn * RawTransactionWithData , sender TransactionSigner , options ... any ) (data []* api.UserTransaction , err error ) {
694
+ expirationSeconds := DefaultExpirationSeconds
695
+
696
+ var feePayer * AccountAddress
697
+ var additionalSigners []AccountAddress
698
+
699
+ for opti , option := range options {
700
+ switch ovalue := option .(type ) {
701
+ case ExpirationSeconds :
702
+ expirationSeconds = int64 (ovalue )
703
+ if expirationSeconds < 0 {
704
+ err = errors .New ("ExpirationSeconds cannot be less than 0" )
705
+ return nil , err
706
+ }
707
+ case FeePayer :
708
+ feePayer = ovalue
709
+ case AdditionalSigners :
710
+ additionalSigners = ovalue
711
+ default :
712
+ err = fmt .Errorf ("APTTransferTransaction arg [%d] unknown option type %T" , opti + 4 , option )
713
+ return nil , err
714
+ }
715
+ }
716
+
717
+ var signedTxn * SignedTransaction
718
+ var ok bool
719
+ if feePayer != nil {
720
+ senderAuth := sender .SimulationAuthenticator ()
721
+ feePayerAuth := crypto .NoAccountAuthenticator ()
722
+ additionalSignersAuth := make ([]crypto.AccountAuthenticator , len (additionalSigners ))
723
+ for i := range additionalSigners {
724
+ additionalSignersAuth [i ] = * crypto .NoAccountAuthenticator ()
725
+ }
726
+ signedTxn , ok = rawTxn .ToFeePayerSignedTransaction (senderAuth , feePayerAuth , additionalSignersAuth )
727
+ if ! ok {
728
+ return nil , fmt .Errorf ("failed to convert fee payer signer to signed transaction" )
729
+ }
730
+ } else {
731
+ senderAuth := sender .SimulationAuthenticator ()
732
+ additionalSignersAuth := make ([]crypto.AccountAuthenticator , len (additionalSigners ))
733
+ for i := range additionalSigners {
734
+ additionalSignersAuth [i ] = * crypto .NoAccountAuthenticator ()
735
+ }
736
+ signedTxn , ok = rawTxn .ToMultiAgentSignedTransaction (senderAuth , additionalSignersAuth )
737
+ if ! ok {
738
+ return nil , fmt .Errorf ("failed to convert multi agent signer to signed transaction" )
739
+ }
740
+ }
741
+
742
+ return rc .simulateTransactionInner (signedTxn , options ... )
743
+ }
744
+
745
+ func (rc * NodeClient ) simulateTransactionInner (signedTxn * SignedTransaction , options ... any ) (data []* api.UserTransaction , err error ) {
699
746
sblob , err := bcs .Serialize (signedTxn )
700
747
if err != nil {
701
748
return
@@ -705,7 +752,7 @@ func (rc *NodeClient) SimulateTransaction(rawTxn *RawTransaction, sender Transac
705
752
706
753
// parse simulate tx options
707
754
params := url.Values {}
708
- for i , arg := range options {
755
+ for _ , arg := range options {
709
756
switch value := arg .(type ) {
710
757
case EstimateGasUnitPrice :
711
758
params .Set ("estimate_gas_unit_price" , strconv .FormatBool (bool (value )))
@@ -714,8 +761,7 @@ func (rc *NodeClient) SimulateTransaction(rawTxn *RawTransaction, sender Transac
714
761
case EstimatePrioritizedGasUnitPrice :
715
762
params .Set ("estimate_prioritized_gas_unit_price" , strconv .FormatBool (bool (value )))
716
763
default :
717
- err = fmt .Errorf ("SimulateTransaction arg %d bad type %T" , i + 1 , arg )
718
- return
764
+ // Silently ignore unknown arguments, as there are multiple intakes
719
765
}
720
766
}
721
767
if len (params ) != 0 {
0 commit comments