From ec67a3e0ae06bb6b71d4f8758cf8afed49538947 Mon Sep 17 00:00:00 2001 From: Chenyang Date: Fri, 18 Apr 2025 21:57:34 +0800 Subject: [PATCH] Init transaction struct --- models/sui_types/object.go | 6 + transaction/command.go | 43 ++++++ transaction/transaction.go | 172 ++++++++++++++++++++++ transaction/transaction_data.go | 253 ++++++++++++++++++++++++++++++++ 4 files changed, 474 insertions(+) create mode 100644 transaction/command.go create mode 100644 transaction/transaction.go create mode 100644 transaction/transaction_data.go diff --git a/models/sui_types/object.go b/models/sui_types/object.go index bd18688..6fd2145 100644 --- a/models/sui_types/object.go +++ b/models/sui_types/object.go @@ -6,6 +6,12 @@ type SuiObjectRef struct { Version uint64 `json:"version"` } +type SuiSharedObject struct { + ObjectId string `json:"objectId"` + InitialSharedVersion uint64 `json:"initialSharedVersion"` + Mutable bool `json:"mutable"` +} + type Owner struct { AddressOwner string `json:"addressOwner,omitempty"` ObjectOwner string `json:"objectOwner,omitempty"` diff --git a/transaction/command.go b/transaction/command.go new file mode 100644 index 0000000..0f29bbc --- /dev/null +++ b/transaction/command.go @@ -0,0 +1,43 @@ +package transaction + +func moveCall(input ProgrammableMoveCall) Command { + return MoveCall{ + Value: input, + } +} + +func transferObjects(input TransferObjectsValue) Command { + return TransferObjects{ + Value: input, + } +} + +func splitCoins(input SplitCoinsValue) Command { + return SplitCoins{ + Value: input, + } +} + +func mergeCoins(input MergeCoinsValue) Command { + return MergeCoins{ + Value: input, + } +} + +func publish(input PublishValue) Command { + return Publish{ + Value: input, + } +} + +func makeMoveVec(input MakeMoveVecValue) Command { + return MakeMoveVec{ + Value: input, + } +} + +func upgrade(input UpgradeValue) Command { + return Upgrade{ + Value: input, + } +} diff --git a/transaction/transaction.go b/transaction/transaction.go new file mode 100644 index 0000000..5f9e75e --- /dev/null +++ b/transaction/transaction.go @@ -0,0 +1,172 @@ +package transaction + +import ( + "math" + + "github.com/block-vision/sui-go-sdk/models" + "github.com/block-vision/sui-go-sdk/models/sui_types" +) + +type Transaction struct { + Data TransactionData +} + +func NewTransaction() *Transaction { + data := TransactionData{} + + return &Transaction{ + Data: data, + } +} + +func (tx *Transaction) SetSender(sender models.SuiAddress) *Transaction { + tx.Data.Sender = &sender + return tx +} + +func (tx *Transaction) SetSenderIfNotSet(sender models.SuiAddress) *Transaction { + if tx.Data.Sender == nil { + tx.Data.Sender = &sender + } + return tx +} + +func (tx *Transaction) SetExpiration(expiration TransactionExpiration) *Transaction { + tx.Data.Expiration = expiration + return tx +} + +func (tx *Transaction) SetGasPayment(payment []sui_types.SuiObjectRef) *Transaction { + tx.Data.GasData.Payment = payment + return tx +} + +func (tx *Transaction) SetGasOwner(owner models.SuiAddress) *Transaction { + tx.Data.GasData.Owner = &owner + return tx +} + +func (tx *Transaction) SetGasPrice(price uint64) *Transaction { + tx.Data.GasData.Price = &price + return tx +} + +func (tx *Transaction) SetGasBudget(budget uint64) *Transaction { + tx.Data.GasData.Budget = &budget + return tx +} + +func (tx *Transaction) SetGasBudgetIfNotSet(budget uint64) *Transaction { + if tx.Data.GasData.Budget == nil { + tx.Data.GasData.Budget = &budget + } + return tx +} + +func (tx *Transaction) Gas() Argument { + return GasCoin{ + Value: true, + } +} + +func (tx *Transaction) Add(command Command) Argument { + tx.Data.Commands = append(tx.Data.Commands, command) + index := uint16(len(tx.Data.Commands) - 1) + return createTransactionResult(index, nil) +} + +func (tx *Transaction) SplitCoins(coin Argument, amount []Argument) Argument { + cmd := splitCoins(SplitCoinsValue{ + Coin: coin, + Amount: amount, + }) + tx.Data.Commands = append(tx.Data.Commands, cmd) + index := uint16(len(tx.Data.Commands) - 1) + return createTransactionResult(index, nil) +} + +func (tx *Transaction) MergeCoins(destination Argument, sources []Argument) Argument { + return tx.Add(mergeCoins(MergeCoinsValue{ + Destination: destination, + Sources: sources, + })) +} + +func (tx *Transaction) Publish(modules []string, dependencies []string) Argument { + return tx.Add(publish(PublishValue{ + Modules: modules, + Dependencies: dependencies, + })) +} + +func (tx *Transaction) Upgrade( + modules []string, + dependencies []string, + packageId string, + ticket Argument, +) Argument { + return tx.Add(upgrade(UpgradeValue{ + Modules: modules, + Dependencies: dependencies, + Package: packageId, + Ticket: ticket, + })) +} + +func (tx *Transaction) MoveCall( + packageId string, + module string, + function string, + typeArguments []string, + arguments []Argument, +) Argument { + return tx.Add(moveCall(ProgrammableMoveCall{ + Package: packageId, + Module: module, + Function: function, + TypeArguments: typeArguments, + Arguments: arguments, + })) +} + +func (tx *Transaction) transferObjects(objects []Argument, address Argument) Argument { + return tx.Add(transferObjects(TransferObjectsValue{ + Objects: objects, + Address: address, + })) +} + +func (tx *Transaction) makeMoveVec(typeValue *string, elements []Argument) Argument { + return tx.Add(makeMoveVec(MakeMoveVecValue{ + Type: typeValue, + Elements: elements, + })) +} + +func (tx *Transaction) Object(obj string) Argument { + // TODO + return InputObject{ + Value: obj, + } +} + +func (tx *Transaction) Pure(input string) Argument { + // TODO + return InputPure{ + Value: []byte{}, + } +} + +func createTransactionResult(index uint16, length *uint16) Argument { + // TODO: Support multiple results + if length == nil { + length = math.MaxInt + } + + return NestedResult{ + Value: NestedResultValue{ + Index: index, + ResultIndex: 0, + }, + } +} diff --git a/transaction/transaction_data.go b/transaction/transaction_data.go new file mode 100644 index 0000000..29ac83a --- /dev/null +++ b/transaction/transaction_data.go @@ -0,0 +1,253 @@ +package transaction + +import ( + "github.com/block-vision/sui-go-sdk/models" + "github.com/block-vision/sui-go-sdk/models/sui_types" +) + +// TransactionData https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L1625 +type TransactionData struct { + Sender *models.SuiAddress + Expiration TransactionExpiration + GasData GasData + Inputs []CallArg + Commands []Command +} + +// GasData https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L1600 +type GasData struct { + Payment []sui_types.SuiObjectRef + Owner *models.SuiAddress + Price *uint64 + Budget *uint64 +} + +// TransactionExpiration https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L1608 +type TransactionExpiration struct { + Epoch *uint64 +} + +// ProgrammableTransaction https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L702 +type ProgrammableTransaction struct { + Inputs []CallArg + Commands []Command +} + +// CallArg https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L80 +// - Pure +// - Object +type CallArg interface { + callArgKind() string +} + +type Pure struct { + Value []byte +} + +func (p Pure) callArgKind() string { + return "Pure" +} + +type Object struct { + Value ObjectArg +} + +func (o Object) callArgKind() string { + return "Object" +} + +// ObjectArg +// - ImmOrOwnedObject +// - SharedObject +// - Receiving +type ObjectArg interface { + objectArgKind() string +} + +type ImmOrOwnedObject struct { + Value sui_types.SuiObjectRef +} + +func (i ImmOrOwnedObject) objectArgKind() string { + return "ImmOrOwnedObject" +} + +type SharedObject struct { + Value sui_types.SuiSharedObject +} + +func (s SharedObject) objectArgKind() string { + return "SharedObject" +} + +type Receiving struct { + Value sui_types.SuiObjectRef +} + +func (r Receiving) objectArgKind() string { + return "Receiving" +} + +// Command https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L712 +// - MoveCall +// - TransferObjects +// - SplitCoins +// - MergeCoins +// - Publish +// - MakeMoveVec +// - Upgrade +type Command interface { + commandKind() string +} + +type MoveCall struct { + Value ProgrammableMoveCall +} + +func (m MoveCall) commandKind() string { + return "MoveCall" +} + +type TransferObjects struct { + Value TransferObjectsValue +} + +func (t TransferObjects) commandKind() string { + return "TransferObjects" +} + +type SplitCoins struct { + Value SplitCoinsValue +} + +func (s SplitCoins) commandKind() string { + return "SplitCoins" +} + +type MergeCoins struct { + Value MergeCoinsValue +} + +func (m MergeCoins) commandKind() string { + return "MergeCoins" +} + +type Publish struct { + Value PublishValue +} + +func (p Publish) commandKind() string { + return "Publish" +} + +type MakeMoveVec struct { + Value MakeMoveVecValue +} + +func (m MakeMoveVec) commandKind() string { + return "MakeMoveVec" +} + +type Upgrade struct { + Value UpgradeValue +} + +func (u Upgrade) commandKind() string { + return "Upgrade" +} + +// ProgrammableMoveCall https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L762 +type ProgrammableMoveCall struct { + Package string + Module string + Function string + TypeArguments []string + Arguments []Argument +} + +type TransferObjectsValue struct { + Objects []Argument + Address Argument +} + +type SplitCoinsValue struct { + Coin Argument + Amount []Argument +} + +type MergeCoinsValue struct { + Destination Argument + Sources []Argument +} + +type PublishValue struct { + Modules []string + Dependencies []string +} + +type MakeMoveVecValue struct { + Type *string + Elements []Argument +} + +type UpgradeValue struct { + Modules []string + Dependencies []string + Package string + Ticket Argument +} + +// Argument https://github.com/MystenLabs/sui/blob/fb27c6c7166f5e4279d5fd1b2ebc5580ca0e81b2/crates/sui-types/src/transaction.rs#L745 +// - GasCoin +// - InputPure +// - InputObject +// - Result +// - NestedResult +type Argument interface { + argumentKind() string +} + +type GasCoin struct { + Value bool +} + +func (g GasCoin) argumentKind() string { + return "GasCoin" +} + +type InputPure struct { + Value []byte +} + +func (i InputPure) argumentKind() string { + return "Pure" +} + +type InputObject struct { + Value string +} + +func (i InputObject) argumentKind() string { + return "Object" +} + +type Result struct { + Value uint16 +} + +func (r Result) argumentKind() string { + return "Result" +} + +type NestedResult struct { + Value NestedResultValue +} + +func (n NestedResult) argumentKind() string { + return "NestedResult" +} + +type NestedResultValue struct { + Index uint16 + ResultIndex uint16 +}