diff --git a/examples/ptb/main.go b/examples/ptb/main.go index d12003d..5d794db 100644 --- a/examples/ptb/main.go +++ b/examples/ptb/main.go @@ -26,6 +26,7 @@ func main() { fmt.Println(signerAccount.Address) simpleTransaction(ctx, client, signerAccount) + // moveCallTransaction(ctx, client, signerAccount) // TODO: sponsored transaction not work now // sponsoredTransaction(ctx, client, signerAccount) } @@ -94,6 +95,88 @@ func simpleTransaction(ctx context.Context, suiClient *sui.Client, signer *signe fmt.Println(resp.Digest, resp.Effects, resp.Results) } +func moveCallTransaction(ctx context.Context, suiClient *sui.Client, signer *signer.Signer) { + gasCoinObjectId := "" + + gasCoinObj, err := suiClient.SuiGetObject(ctx, models.SuiGetObjectRequest{ + ObjectId: gasCoinObjectId, + Options: models.SuiObjectDataOptions{ + ShowContent: true, + ShowDisplay: true, + ShowType: true, + ShowBcs: true, + ShowOwner: true, + ShowPreviousTransaction: true, + ShowStorageRebate: true, + }, + }) + if err != nil { + panic(err) + } + version, err := strconv.ParseUint(gasCoinObj.Data.Version, 10, 64) + if err != nil { + panic(err) + } + gasCoin, err := transaction.NewSuiObjectRef( + models.SuiAddress(gasCoinObjectId), + version, + models.ObjectDigest(gasCoinObj.Data.Digest), + ) + if err != nil { + panic(err) + } + + tx := transaction.NewTransaction() + + tx.SetSuiClient(suiClient). + SetSigner(signer). + SetSender(models.SuiAddress(signer.Address)). + SetGasPrice(1000). + SetGasBudget(50000000). + SetGasPayment([]transaction.SuiObjectRef{*gasCoin}). + SetGasOwner(models.SuiAddress(signer.Address)) + + addressBytes, err := transaction.ConvertSuiAddressStringToBytes("0x0000000000000000000000000000000000000000000000000000000000000002") + if err != nil { + panic(err) + } + + tx.MoveCall( + "0xeffc8ae61f439bb34c9b905ff8f29ec56873dcedf81c7123ff2f1f67c45ec302", + "utils", + "check_coin_threshold", + []transaction.TypeTag{ + { + Struct: &transaction.StructTag{ + Address: *addressBytes, + Module: "sui", + Name: "SUI", + }, + }, + }, + []transaction.Argument{ + tx.Gas(), + tx.Pure(uint64(1000000000 * 0.01)), + }, + ) + + resp, err := tx.Execute( + ctx, + models.SuiTransactionBlockOptions{ + ShowInput: true, + ShowRawInput: true, + ShowEffects: true, + ShowEvents: true, + }, + "WaitForLocalExecution", + ) + if err != nil { + panic(err) + } + + fmt.Println(resp.Digest, resp.Effects, resp.Results) +} + func sponsoredTransaction(ctx context.Context, suiClient *sui.Client, rawSigner *signer.Signer) { sponsoredSigner, err := signer.NewSignertWithMnemonic("") if err != nil { diff --git a/transaction/command.go b/transaction/command.go index 5080771..7d5130b 100644 --- a/transaction/command.go +++ b/transaction/command.go @@ -1,45 +1,43 @@ package transaction -import "github.com/samber/lo" - func moveCall(input ProgrammableMoveCall) Command { return Command{ - MoveCall: lo.ToPtr(input), + MoveCall: &input, } } func transferObjects(input TransferObjects) Command { return Command{ - TransferObjects: lo.ToPtr(input), + TransferObjects: &input, } } func splitCoins(input SplitCoins) Command { return Command{ - SplitCoins: lo.ToPtr(input), + SplitCoins: &input, } } func mergeCoins(input MergeCoins) Command { return Command{ - MergeCoins: lo.ToPtr(input), + MergeCoins: &input, } } func publish(input Publish) Command { return Command{ - Publish: lo.ToPtr(input), + Publish: &input, } } func makeMoveVec(input MakeMoveVec) Command { return Command{ - MakeMoveVec: lo.ToPtr(input), + MakeMoveVec: &input, } } func upgrade(input Upgrade) Command { return Command{ - Upgrade: lo.ToPtr(input), + Upgrade: &input, } } diff --git a/transaction/transaction.go b/transaction/transaction.go index 2c0d942..3b49fce 100644 --- a/transaction/transaction.go +++ b/transaction/transaction.go @@ -207,7 +207,7 @@ func (tx *Transaction) MoveCall( packageId models.SuiAddress, module string, function string, - typeArguments []string, + typeArguments []TypeTag, arguments []Argument, ) Argument { packageIdBytes, err := ConvertSuiAddressStringToBytes(packageId) @@ -219,7 +219,7 @@ func (tx *Transaction) MoveCall( Package: *packageIdBytes, Module: module, Function: function, - TypeArguments: typeArguments, + TypeArguments: convertTypeTagsToTypeTagPtrs(typeArguments), Arguments: convertArgumentsToArgumentPtrs(arguments), })) } @@ -471,10 +471,22 @@ func createTransactionResult(index uint16, length *uint16) Argument { } func convertArgumentsToArgumentPtrs(args []Argument) []*Argument { + fmt.Println(len(args)) argPtrs := make([]*Argument, len(args)) for i, arg := range args { - argPtrs[i] = &arg + v := arg + argPtrs[i] = &v } return argPtrs } + +func convertTypeTagsToTypeTagPtrs(tags []TypeTag) []*TypeTag { + tagPtrs := make([]*TypeTag, len(tags)) + for i, tag := range tags { + v := tag + tagPtrs[i] = &v + } + + return tagPtrs +} diff --git a/transaction/transaction_data.go b/transaction/transaction_data.go index ccf0b3a..a6fa2a5 100644 --- a/transaction/transaction_data.go +++ b/transaction/transaction_data.go @@ -120,9 +120,9 @@ type ProgrammableTransaction struct { // - ConsensusCommitPrologue type TransactionKind struct { ProgrammableTransaction *ProgrammableTransaction - ChangeEpoch struct{} - Genesis struct{} - ConsensusCommitPrologue struct{} + ChangeEpoch any + Genesis any + ConsensusCommitPrologue any } func (*TransactionKind) IsBcsEnum() {} @@ -204,7 +204,7 @@ type ProgrammableMoveCall struct { Package models.SuiAddressBytes Module string Function string - TypeArguments []string + TypeArguments []*TypeTag Arguments []*Argument } @@ -270,3 +270,28 @@ type SharedObjectRef struct { InitialSharedVersion uint64 Mutable bool } + +type StructTag struct { + Address models.SuiAddressBytes + Module string + Name string + TypeParams []*TypeTag +} + +// TypeTag https://github.com/MystenLabs/sui/blob/ece197ed5c414eb274f99afc52704664af8d0c38/external-crates/move/crates/move-core-types/src/language_storage.rs#L33 +// Do not reorder the fields, it will break the bcs encoding +type TypeTag struct { + Bool *bool + U8 *bool + U128 *bool + U256 *bool + Address *bool + Signer *bool + Vector *TypeTag + Struct *StructTag + U16 *bool + U32 *bool + U64 *bool +} + +func (*TypeTag) IsBcsEnum() {} diff --git a/transaction/transaction_test.go b/transaction/transaction_test.go index 8835fbf..72a26eb 100644 --- a/transaction/transaction_test.go +++ b/transaction/transaction_test.go @@ -59,6 +59,39 @@ func TestNewTransaction(t *testing.T) { onlyTransactionKind: false, expectBcsBase64: "AAACAAgA4fUFAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkCAgABAQAAAQECAAABAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYgIAAAAAAAAAIAABAgMEBQYHCAkAAQIDBAUGBwgJAAECAwQFBgcICQECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYFAAAAAAAAAGQAAAAAAAAAAA==", }, + { + name: "tx move call", + fun: func() *Transaction { + tx := setupTransaction() + + addressBytes, err := ConvertSuiAddressStringToBytes("0x0000000000000000000000000000000000000000000000000000000000000002") + if err != nil { + panic(err) + } + + tx.MoveCall( + "0xeffc8ae61f439bb34c9b905ff8f29ec56873dcedf81c7123ff2f1f67c45ec302", + "utils", + "check_coin_threshold", + []TypeTag{ + { + Struct: &StructTag{ + Address: *addressBytes, + Module: "sui", + Name: "SUI", + }, + }, + }, + []Argument{ + tx.Gas(), + tx.Pure(uint64(1000000000 * 0.1)), + }, + ) + return tx + }, + onlyTransactionKind: false, + expectBcsBase64: "AAABAAgA4fUFAAAAAAEA7/yK5h9Dm7NMm5Bf+PKexWhz3O34HHEj/y8fZ8RewwIFdXRpbHMUY2hlY2tfY29pbl90aHJlc2hvbGQBBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACA3N1aQNTVUkAAgABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgFhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYmNhYgIAAAAAAAAAIAABAgMEBQYHCAkAAQIDBAUGBwgJAAECAwQFBgcICQECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYFAAAAAAAAAGQAAAAAAAAAAA==", + }, } for _, c := range cases {