diff --git a/gmsui/README.md b/gmsui/README.md new file mode 100644 index 0000000..660c2ce --- /dev/null +++ b/gmsui/README.md @@ -0,0 +1 @@ +Sui SDK has migrated to https://github.com/W3Tools/gosui diff --git a/gmsui/b64/b64.go b/gmsui/b64/b64.go deleted file mode 100644 index c4a793d..0000000 --- a/gmsui/b64/b64.go +++ /dev/null @@ -1,11 +0,0 @@ -package b64 - -import "encoding/base64" - -func FromBase64(base64String string) ([]byte, error) { - return base64.StdEncoding.DecodeString(base64String) -} - -func ToBase64(bs []byte) string { - return base64.StdEncoding.EncodeToString(bs) -} diff --git a/gmsui/b64/b64_test.go b/gmsui/b64/b64_test.go deleted file mode 100644 index 82d407c..0000000 --- a/gmsui/b64/b64_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package b64_test - -import ( - "testing" - - "github.com/W3Tools/go-modules/gmsui/b64" -) - -func TestFromBase64(t *testing.T) { - tests := []struct { - name string - base64String string - expectedBytes []byte - expectError bool - }{ - { - name: "Valid base64 string", - base64String: "SGVsbG8sIFdvcmxkIQ==", // "Hello, World!" - expectedBytes: []byte("Hello, World!"), - expectError: false, - }, - { - name: "Invalid base64 string", - base64String: "InvalidBase64", - expectedBytes: nil, - expectError: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result, err := b64.FromBase64(tt.base64String) - if (err != nil) != tt.expectError { - t.Errorf("expected error: %v, got: %v", tt.expectError, err) - } - if !tt.expectError && string(result) != string(tt.expectedBytes) { - t.Errorf("expected %v, but got %v", tt.expectedBytes, result) - } - }) - } -} - -func TestToBase64(t *testing.T) { - tests := []struct { - name string - inputBytes []byte - expectedBase64 string - }{ - { - name: "Encode string to base64", - inputBytes: []byte("Hello, World!"), - expectedBase64: "SGVsbG8sIFdvcmxkIQ==", - }, - { - name: "Encode empty string to base64", - inputBytes: []byte(""), - expectedBase64: "", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := b64.ToBase64(tt.inputBytes) - if result != tt.expectedBase64 { - t.Errorf("expected %v, but got %v", tt.expectedBase64, result) - } - }) - } -} diff --git a/gmsui/client/chain.go b/gmsui/client/chain.go deleted file mode 100644 index da13c8e..0000000 --- a/gmsui/client/chain.go +++ /dev/null @@ -1 +0,0 @@ -package client diff --git a/gmsui/client/client.go b/gmsui/client/client.go deleted file mode 100644 index c9dbf8f..0000000 --- a/gmsui/client/client.go +++ /dev/null @@ -1,653 +0,0 @@ -package client - -import ( - "context" - "fmt" - "math/big" - "net/http" - "net/url" - "time" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/W3Tools/go-modules/gmsui/types" - "github.com/W3Tools/go-modules/gmsui/utils" -) - -type SuiClientOptions struct { - URL string -} - -type SuiClient struct { - ctx context.Context - rpc string - requestId int - httpClient *http.Client -} - -type SuiTransportRequestOptions struct { - Method string `json:"method"` - Params []any `json:"params"` -} - -func NewSuiClient(ctx context.Context, rpc string) (*SuiClient, error) { - _, err := url.ParseRequestURI(rpc) - if err != nil { - return nil, err - } - - httpClient := &http.Client{ - Transport: &http.Transport{ - MaxIdleConns: 5, - IdleConnTimeout: 30 * time.Second, - }, - Timeout: 30 * time.Second, - } - - return &SuiClient{ctx: ctx, rpc: rpc, requestId: 1, httpClient: httpClient}, nil -} - -func (client *SuiClient) Context() context.Context { - return client.ctx -} - -func (client *SuiClient) RPC() string { - return client.rpc -} - -// Invoke any RPC method -func (client *SuiClient) Call(method string, params []any, response any) error { - return client.request(SuiTransportRequestOptions{Method: method, Params: params}, &response) -} - -func (client *SuiClient) GetRpcApiVersion() (string, error) { - var response struct { - Info struct { - Version string `json:"version"` - } `json:"info"` - } - err := client.request(SuiTransportRequestOptions{Method: "rpc.discover", Params: []any{}}, &response) - if err != nil { - return "", err - } - - return response.Info.Version, nil -} - -// Get all Coin<`coin_type`> objects owned by an address. -func (client *SuiClient) GetCoins(input types.GetCoinsParams) (response *types.PaginatedCoins, err error) { - if input.Owner == "" || !utils.IsValidSuiAddress(utils.NormalizeSuiAddress(input.Owner)) { - return nil, fmt.Errorf("invalid sui address") - } - - if input.CoinType != nil || *input.CoinType != "" { - input.CoinType = gm.NewStringPtr(utils.NormalizeSuiCoinType(*input.CoinType)) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getCoins", - Params: []any{utils.NormalizeSuiAddress(input.Owner), input.CoinType, input.Cursor, input.Limit}, - }, - &response, - ) -} - -// Get all Coin objects owned by an address. -func (client *SuiClient) GetAllCoins(input types.GetAllCoinsParams) (response *types.PaginatedCoins, err error) { - if input.Owner == "" || !utils.IsValidSuiAddress(utils.NormalizeSuiAddress(input.Owner)) { - return nil, fmt.Errorf("invalid sui address") - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getAllCoins", - Params: []any{utils.NormalizeSuiAddress(input.Owner), input.Cursor, input.Limit}, - }, - &response, - ) -} - -// Get the total coin balance for one coin type, owned by the address owner. -func (client *SuiClient) GetBalance(input types.GetBalanceParams) (response *types.Balance, err error) { - if input.Owner == "" || !utils.IsValidSuiAddress(utils.NormalizeSuiAddress(input.Owner)) { - return nil, fmt.Errorf("invalid sui address") - } - - if input.CoinType != nil || *input.CoinType != "" { - input.CoinType = gm.NewStringPtr(utils.NormalizeSuiCoinType(*input.CoinType)) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getBalance", - Params: []any{utils.NormalizeSuiAddress(input.Owner), input.CoinType}, - }, - &response, - ) -} - -// Get the total coin balance for all coin types, owned by the address owner. -func (client *SuiClient) GetAllBalances(input types.GetAllBalancesParams) (response []*types.Balance, err error) { - if input.Owner == "" || !utils.IsValidSuiAddress(utils.NormalizeSuiAddress(input.Owner)) { - return nil, fmt.Errorf("invalid sui address") - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getAllBalances", - Params: []any{utils.NormalizeSuiAddress(input.Owner)}, - }, - &response, - ) -} - -// Fetch CoinMetadata for a given coin type -func (client *SuiClient) GetCoinMetadata(input types.GetCoinMetadataParams) (response *types.CoinMetadata, err error) { - if input.CoinType != "" { - input.CoinType = utils.NormalizeSuiCoinType(input.CoinType) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getCoinMetadata", - Params: []any{input.CoinType}, - }, - &response, - ) -} - -// Fetch total supply for a coin -func (client *SuiClient) GetTotalSupply(input types.GetTotalSupplyParams) (response *types.CoinSupply, err error) { - if input.CoinType != "" { - input.CoinType = utils.NormalizeSuiCoinType(input.CoinType) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getTotalSupply", - Params: []any{input.CoinType}, - }, - &response, - ) -} - -// Get details about an object -func (client *SuiClient) GetObject(input types.GetObjectParams) (response *types.SuiObjectResponse, err error) { - if input.ID == "" || !utils.IsValidSuiObjectId(utils.NormalizeSuiObjectId(input.ID)) { - return nil, fmt.Errorf("invalid sui object id") - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getObject", - Params: []any{utils.NormalizeSuiObjectId(input.ID), input.Options}, - }, - &response, - ) -} - -// Batch get details about a list of objects. If any of the object ids are duplicates the call will fail -func (client *SuiClient) MultiGetObjects(input types.MultiGetObjectsParams) (response []*types.SuiObjectResponse, err error) { - _, err = gm.Map(input.IDs, func(v string) (any, error) { - if v == "" || !utils.IsValidSuiObjectId(utils.NormalizeSuiObjectId(v)) { - return nil, fmt.Errorf("invalid sui object id %s", v) - } - return nil, nil - }) - if err != nil { - return nil, err - } - - var ids []string - for _, id := range input.IDs { - ids = gm.UniqueAppend(ids, id) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_multiGetObjects", - Params: []any{ids, input.Options}, - }, - &response, - ) -} - -// Get all objects owned by an address -func (client *SuiClient) GetOwnedObjects(input types.GetOwnedObjectsParams) (response *types.PaginatedObjectsResponse, err error) { - if input.Owner == "" || !utils.IsValidSuiAddress(utils.NormalizeSuiAddress(input.Owner)) { - return nil, fmt.Errorf("invalid sui address") - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getOwnedObjects", - Params: []any{ - utils.NormalizeSuiAddress(input.Owner), - types.SuiObjectResponseQuery{ - Filter: input.SuiObjectResponseQuery.Filter, - Options: input.SuiObjectResponseQuery.Options, - }, - input.Cursor, - input.Limit, - }, - }, - &response, - ) -} - -// Return the object information for a specified version -func (client *SuiClient) TryGetPastObject(input types.TryGetPastObjectParams) (response *types.ObjectReadWrapper, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_tryGetPastObject", - Params: []any{utils.NormalizeSuiObjectId(input.ID), input.Version, input.Options}, - }, - &response, - ) -} - -// Return the list of dynamic field objects owned by an object -func (client *SuiClient) GetDynamicFields(input types.GetDynamicFieldsParams) (response *types.DynamicFieldPage, err error) { - if input.ParentId == "" || !utils.IsValidSuiObjectId(utils.NormalizeSuiObjectId(input.ParentId)) { - return nil, fmt.Errorf("invalid sui object id") - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getDynamicFields", - Params: []any{utils.NormalizeSuiObjectId(input.ParentId), input.Cursor, input.Limit}, - }, - &response, - ) -} - -// Return the dynamic field object information for a specified object -func (client *SuiClient) GetDynamicFieldObject(input types.GetDynamicFieldObjectParams) (response *types.SuiObjectResponse, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getDynamicFieldObject", - Params: []any{input.ParentId, input.Name}, - }, - &response, - ) -} - -func (client *SuiClient) GetTransactionBlock(input types.GetTransactionBlockParams) (response *types.SuiTransactionBlockResponse, err error) { - if !utils.IsValidTransactionDigest(input.Digest) { - return nil, fmt.Errorf("invalid transaction digest") - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getTransactionBlock", - Params: []any{input.Digest, input.Options}, - }, - &response, - ) -} - -func (client *SuiClient) MultiGetTransactionBlocks(input types.MultiGetTransactionBlocksParams) (response []*types.SuiTransactionBlockResponse, err error) { - _, err = gm.Map(input.Digests, func(v string) (any, error) { - if v == "" || !utils.IsValidTransactionDigest(v) { - return nil, fmt.Errorf("invalid transaction digest %s", v) - } - return nil, nil - }) - if err != nil { - return nil, err - } - - var ids []string - for _, id := range input.Digests { - ids = gm.UniqueAppend(ids, id) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_multiGetTransactionBlocks", - Params: []any{ids, input.Options}, - }, - &response, - ) -} - -// Get transaction blocks for a given query criteria -func (client *SuiClient) QueryTransactionBlocks(input types.QueryTransactionBlocksParams) (response *types.PaginatedTransactionResponse, err error) { - var order bool = true - if input.Order != nil { - order = (input.Order == &types.Descending) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_queryTransactionBlocks", - Params: []any{ - input.SuiTransactionBlockResponseQuery, - input.Cursor, - input.Limit, - &order, - }, - }, - &response, - ) -} - -// Get total number of transactions -func (client *SuiClient) GetTotalTransactionBlocks() (response *big.Int, err error) { - var response_ string - err = client.request( - SuiTransportRequestOptions{ - Method: "sui_getTotalTransactionBlocks", - Params: []any{}, - }, - &response_, - ) - if err != nil { - return nil, err - } - - response, ok := new(big.Int).SetString(response_, 10) - if !ok { - return nil, fmt.Errorf("got invalid string number %s", response_) - } - - return response, nil -} - -func (client *SuiClient) SubscribeTransaction(input types.SubscribeTransactionParams) (response any, err error) { - return nil, fmt.Errorf("unimplemented") -} - -// Get events for a given query criteria -func (client *SuiClient) QueryEvents(input types.QueryEventsParams) (response *types.PaginatedEvents, err error) { - var order bool = true - if input.Order != nil { - order = (input.Order == &types.Descending) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_queryEvents", - Params: []any{input.Query, input.Cursor, input.Limit, order}, - }, - &response, - ) -} - -// Subscribe to get notifications whenever an event matching the filter occurs -func (client *SuiClient) SubscribeEvent(input types.SubscribeEventParams) (response any, err error) { - return nil, fmt.Errorf("unimplemented") -} - -func (client *SuiClient) GetProtocolConfig(input types.GetProtocolConfigParams) (response *types.ProtocolConfig, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getProtocolConfig", - Params: []any{input.Version}, - }, - &response, - ) -} - -// Get the sequence number of the latest checkpoint that has been executed -func (client *SuiClient) GetLatestCheckpointSequenceNumber() (response string, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getLatestCheckpointSequenceNumber", - Params: []any{}, - }, - &response, - ) -} - -// Returns information about a given checkpoint -func (client *SuiClient) GetCheckpoint(input types.GetCheckpointParams) (response *types.Checkpoint, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getCheckpoint", - Params: []any{input.ID}, - }, - &response, - ) -} - -// Returns historical checkpoints paginated -func (client *SuiClient) GetCheckpoints(input types.GetCheckpointsParams) (response *types.CheckpointPage, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getCheckpoints", - Params: []any{input.Cursor, input.Limit, input.DescendingOrder}, - }, - &response, - ) -} - -// Getting the reference gas price for the network -func (client *SuiClient) GetReferenceGasPrice() (response *big.Int, err error) { - var response_ string - err = client.request( - SuiTransportRequestOptions{ - Method: "suix_getReferenceGasPrice", - Params: []any{}, - }, - &response_, - ) - if err != nil { - return nil, err - } - - response, ok := new(big.Int).SetString(response_, 10) - if !ok { - return nil, fmt.Errorf("got invalid string number %s", response_) - } - - return response, nil -} - -// Return the latest system state content. -func (client *SuiClient) GetLatestSuiSystemState() (response *types.SuiSystemStateSummary, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getLatestSuiSystemState", - Params: []any{}, - }, - &response, - ) -} - -// Return the committee information for the asked epoch -func (client *SuiClient) GetCommitteeInfo(input types.GetCommitteeInfoParams) (response *types.CommitteeInfo, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getCommitteeInfo", - Params: []any{input.Epoch}, - }, - &response, - ) -} - -// Return the Validators APYs -func (client *SuiClient) GetValidatorsApy() (response *types.ValidatorsApy, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getValidatorsApy", - Params: []any{}, - }, - &response, - ) -} - -func (client *SuiClient) GetChainIdentifier() (response string, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getChainIdentifier", - Params: []any{}, - }, - &response, - ) -} - -// Return the delegated stakes for an address -func (client *SuiClient) GetStakes(input types.GetStakesParams) (response []*types.DelegatedStake, err error) { - if input.Owner == "" || !utils.IsValidSuiObjectId(utils.NormalizeSuiObjectId(input.Owner)) { - return nil, fmt.Errorf("invalid sui address") - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getStakes", - Params: []any{utils.NormalizeSuiObjectId(input.Owner)}, - }, - &response, - ) -} - -// Return the delegated stakes queried by id. -func (client *SuiClient) GetStakesByIds(input types.GetStakesByIdsParams) (response []*types.DelegatedStake, err error) { - _, err = gm.Map(input.StakedSuiIds, func(v string) (any, error) { - if v == "" || !utils.IsValidSuiObjectId(utils.NormalizeSuiObjectId(v)) { - return nil, fmt.Errorf("invalid sui object id %s", v) - } - return nil, nil - }) - if err != nil { - return nil, err - } - - var ids []string - for _, id := range input.StakedSuiIds { - ids = gm.UniqueAppend(ids, id) - } - - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_getStakesByIds", - Params: []any{ids}, - }, - &response, - ) -} - -func (client *SuiClient) ResolveNameServiceNames(input types.ResolveNameServiceNamesParams) (response *types.ResolvedNameServiceNames, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_resolveNameServiceNames", - Params: []any{input.Address, input.Cursor, input.Limit}, - }, - &response, - ) -} - -func (client *SuiClient) ResolveNameServiceAddress(input types.ResolveNameServiceAddressParams) (response string, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "suix_resolveNameServiceAddress", - Params: []any{input.Name}, - }, - &response, - ) -} - -// Get Move function argument types like read, write and full access -func (client *SuiClient) GetMoveFunctionArgTypes(input types.GetMoveFunctionArgTypesParams) (response []types.SuiMoveFunctionArgTypeWrapper, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getMoveFunctionArgTypes", - Params: []any{utils.NormalizeSuiObjectId(input.Package), input.Module, input.Function}, - }, - &response, - ) -} - -// Get a map from module name to structured representations of Move modules -func (client *SuiClient) GetNormalizedMoveModulesByPackage(input types.GetNormalizedMoveModulesByPackageParams) (response *types.SuiMoveNormalizedModules, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getNormalizedMoveModulesByPackage", - Params: []any{utils.NormalizeSuiObjectId(input.Package)}, - }, - &response, - ) -} - -// Get a structured representation of Move module -func (client *SuiClient) GetNormalizedMoveModule(input types.GetNormalizedMoveModuleParams) (response *types.SuiMoveNormalizedModule, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getNormalizedMoveModule", - Params: []any{utils.NormalizeSuiObjectId(input.Package), input.Module}, - }, - &response, - ) -} - -// Get a structured representation of Move function -func (client *SuiClient) GetNormalizedMoveFunction(input types.GetNormalizedMoveFunctionParams) (response *types.SuiMoveNormalizedFunction, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getNormalizedMoveFunction", - Params: []any{utils.NormalizeSuiObjectId(input.Package), input.Module, input.Function}, - }, - &response, - ) -} - -// Get a structured representation of Move struct -func (client *SuiClient) GetNormalizedMoveStruct(input types.GetNormalizedMoveStructParams) (response *types.SuiMoveNormalizedStruct, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_getNormalizedMoveStruct", - Params: []any{utils.NormalizeSuiObjectId(input.Package), input.Module, input.Struct}, - }, - &response, - ) -} - -// Dry run a transaction block and return the result. -func (client *SuiClient) DryRunTransactionBlock(input types.DryRunTransactionBlockParams) (response *types.DryRunTransactionBlockResponse, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_dryRunTransactionBlock", - Params: []any{b64.ToBase64(input.TransactionBlock)}, - }, - &response, - ) -} - -// Runs the transaction block in dev-inspect mode. -// Which allows for nearly any transaction (or Move call) with any arguments. -// Detailed results are provided, including both the transaction effects and any return values. -func (client *SuiClient) DevInspectTransactionBlock(input types.DevInspectTransactionBlockParams) (response *types.DevInspectResults, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_devInspectTransactionBlock", - Params: []any{input.Sender, input.TransactionBlock, input.GasPrice, input.Epoch}, - }, - &response, - ) -} - -func (client *SuiClient) ExecuteTransactionBlock(input types.ExecuteTransactionBlockParams) (response *types.SuiTransactionBlockResponse, err error) { - return response, client.request( - SuiTransportRequestOptions{ - Method: "sui_executeTransactionBlock", - Params: []any{b64.ToBase64(input.TransactionBlock), input.Signature, input.Options, input.RequestType}, - }, - &response, - ) -} - -func (client *SuiClient) SignAndExecuteTransactionBlock(input types.SignAndExecuteTransactionBlockParams) (response *types.SuiTransactionBlockResponse, err error) { - signatureData, err := input.Signer.SignTransactionBlock(input.TransactionBlock) - if err != nil { - return nil, err - } - - return client.ExecuteTransactionBlock(types.ExecuteTransactionBlockParams{ - TransactionBlock: input.TransactionBlock, - Signature: []string{signatureData.Signature}, - Options: input.Options, - RequestType: input.RequestType, - }) -} diff --git a/gmsui/client/client_test.go b/gmsui/client/client_test.go deleted file mode 100644 index ca2717b..0000000 --- a/gmsui/client/client_test.go +++ /dev/null @@ -1,7 +0,0 @@ -package client_test - -import ( - "testing" -) - -func TestSuiClient(t *testing.T) {} diff --git a/gmsui/client/http-transport.go b/gmsui/client/http-transport.go deleted file mode 100644 index 5f05052..0000000 --- a/gmsui/client/http-transport.go +++ /dev/null @@ -1,97 +0,0 @@ -package client - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "reflect" -) - -func (client *SuiClient) request(input SuiTransportRequestOptions, output interface{}) error { - reflectValue := reflect.ValueOf(output) - if output != nil && reflectValue.Kind() != reflect.Pointer { - return fmt.Errorf("output not a pointer or nil pointer") - } - - message, err := client.newRequestMessage(input.Method, input.Params) - if err != nil { - return err - } - - jsb, err := json.Marshal(message) - if err != nil { - return err - } - - httpRequest, err := http.NewRequestWithContext(client.ctx, http.MethodPost, client.rpc, bytes.NewReader(jsb)) - if err != nil { - return err - } - httpRequest.ContentLength = int64(len(jsb)) - httpRequest.Header.Set("Content-Type", "application/json") - - response, err := client.httpClient.Do(httpRequest) - if err != nil { - return err - } - defer response.Body.Close() - - if response.StatusCode < 200 || response.StatusCode >= 300 { - return fmt.Errorf("unexpected status code: %v, status: %v", response.StatusCode, response.Status) - } - - body, err := io.ReadAll(response.Body) - if err != nil { - return err - } - - var v jsonrpcResponse - err = json.Unmarshal(body, &v) - if err != nil { - return err - } - - if v.Error != nil { - return fmt.Errorf("unexpected code: %d, message: %v", v.Error.Code, string(v.Error.Message)) - } - - return json.Unmarshal(v.Result, &output) -} - -type jsonrpcRequest struct { - Jsonrpc string `json:"jsonrpc,omitempty"` - ID json.RawMessage `json:"id,omitempty"` - Method string `json:"method,omitempty"` - Params json.RawMessage `json:"params,omitempty"` -} - -func (client *SuiClient) newRequestMessage(method string, params []any) (*jsonrpcRequest, error) { - id, err := json.Marshal(client.requestId) - if err != nil { - return nil, err - } - - requestMessage := &jsonrpcRequest{Jsonrpc: "2.0", ID: id, Method: method} - if !reflect.ValueOf(params).IsNil() { - requestMessage.Params, err = json.Marshal(params) - if err != nil { - return nil, err - } - } - - return requestMessage, nil -} - -type jsonrpcResponse struct { - Jsonrpc string `json:"jsonrpc,omitempty"` - ID json.RawMessage `json:"id,omitempty"` - Result json.RawMessage `json:"result"` - Error *jsonrpcError `json:"error,omitempty"` -} - -type jsonrpcError struct { - Code int64 `json:"code,omitempty"` - Message json.RawMessage `json:"message,omitempty"` -} diff --git a/gmsui/client/network.go b/gmsui/client/network.go deleted file mode 100644 index 2e800e6..0000000 --- a/gmsui/client/network.go +++ /dev/null @@ -1,16 +0,0 @@ -package client - -func GetFullNodeURL(network string) string { - switch network { - case "mainnet": - return "https://fullnode.mainnet.sui.io:443" - case "testnet": - return "https://fullnode.testnet.sui.io:443" - case "devnet": - return "https://fullnode.devnet.sui.io:443" - case "localnet": - return "http://127.0.0.1:9000" - default: - return "https://fullnode.devnet.sui.io:443" - } -} diff --git a/gmsui/client/network_test.go b/gmsui/client/network_test.go deleted file mode 100644 index 7995928..0000000 --- a/gmsui/client/network_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package client_test - -import ( - "testing" - - "github.com/W3Tools/go-modules/gmsui/client" -) - -func TestGetFullNodeURL(t *testing.T) { - tests := []struct { - network string - want string - }{ - {"mainnet", "https://fullnode.mainnet.sui.io:443"}, - {"testnet", "https://fullnode.testnet.sui.io:443"}, - {"devnet", "https://fullnode.devnet.sui.io:443"}, - {"localnet", "http://127.0.0.1:9000"}, - {"unknown", "https://fullnode.devnet.sui.io:443"}, - } - - for _, tt := range tests { - t.Run(tt.network, func(t *testing.T) { - got := client.GetFullNodeURL(tt.network) - if got != tt.want { - t.Errorf("GetFullNodeURL(%q) = %v; want %v", tt.network, got, tt.want) - } - }) - } -} diff --git a/gmsui/client_call.go b/gmsui/client_call.go deleted file mode 100644 index 1ccf708..0000000 --- a/gmsui/client_call.go +++ /dev/null @@ -1,168 +0,0 @@ -package gmsui - -import ( - "encoding/json" - "fmt" - "strconv" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/client" - "github.com/W3Tools/go-modules/gmsui/types" -) - -func GetObjectAndUnmarshal[T any](client *client.SuiClient, id string) (raw *types.SuiObjectResponse, value *T, err error) { - raw, err = client.GetObject(types.GetObjectParams{ - ID: id, - Options: &types.SuiObjectDataOptions{ - ShowType: true, - ShowContent: true, - ShowBcs: true, - ShowOwner: true, - ShowPreviousTransaction: true, - ShowStorageRebate: true, - ShowDisplay: true, - }, - }) - if err != nil { - return nil, nil, err - } - - switch t := raw.Data.Content.SuiParsedData.(type) { - case types.SuiParsedPackageData: - return nil, nil, fmt.Errorf("unimplemented %s, expected an object id, not package id", t.DataType) - case types.SuiParsedMoveObjectData: - jsb, err := t.Fields.MarshalJSON() - if err != nil { - return nil, nil, err - } - - value = new(T) - err = json.Unmarshal(jsb, &value) - if err != nil { - return nil, nil, err - } - return raw, value, err - default: - return nil, nil, fmt.Errorf("unknown data type, expected an object id, value: %v", t) - } -} - -func GetObjectsAndUnmarshal[T any](client *client.SuiClient, ids []string) (raw []*types.SuiObjectResponse, values []*T, err error) { - raw, err = client.MultiGetObjects(types.MultiGetObjectsParams{ - IDs: ids, - Options: &types.SuiObjectDataOptions{ - ShowType: true, - ShowContent: true, - ShowBcs: true, - ShowOwner: true, - ShowPreviousTransaction: true, - ShowStorageRebate: true, - ShowDisplay: true, - }, - }) - if err != nil { - return nil, nil, err - } - - for _, data := range raw { - switch t := data.Data.Content.SuiParsedData.(type) { - case types.SuiParsedPackageData: - return nil, nil, fmt.Errorf("unimplemented %s, %s expected an object id, not package id", t.DataType, data.Data.ObjectId) - case types.SuiParsedMoveObjectData: - jsb, err := t.Fields.MarshalJSON() - if err != nil { - return nil, nil, err - } - - var value = new(T) - err = json.Unmarshal(jsb, &value) - if err != nil { - return nil, nil, err - } - values = append(values, value) - default: - return nil, nil, fmt.Errorf("unknown data type, %s expected an object id, value: %v", data.Data.ObjectId, t) - } - } - return -} - -func GetDynamicFieldObjectAndUnmarshal[T any, NameType any](client *client.SuiClient, parentId string, name types.DynamicFieldName) (raw *types.SuiObjectResponse, value *SuiMoveDynamicField[T, NameType], err error) { - raw, err = client.GetDynamicFieldObject(types.GetDynamicFieldObjectParams{ - ParentId: parentId, - Name: name, - }) - if err != nil { - return nil, nil, err - } - - object, ok := raw.Data.Content.SuiParsedData.(types.SuiParsedMoveObjectData) - if !ok { - return nil, nil, fmt.Errorf("unknown data type, expected an object id, value: %v", raw.Data.Content.SuiParsedData) - } - - jsb, err := object.Fields.MarshalJSON() - if err != nil { - return nil, nil, err - } - - data := new(SuiMoveDynamicField[T, NameType]) - err = json.Unmarshal(jsb, &data) - if err != nil { - return nil, nil, err - } - - return raw, data, nil -} - -// Instance Get All Sui Coins -func GetAllCoins(client *client.SuiClient, owner string, coinType string) (data []types.CoinStruct, err error) { - firstPage, err := client.GetCoins(types.GetCoinsParams{Owner: owner, CoinType: &coinType, Limit: gm.NewNumberPtr(1)}) - if err != nil { - return - } - data = append(data, firstPage.Data...) - - nextCursor := firstPage.NextCursor - hasNext := firstPage.HasNextPage - for hasNext { - nextPage, err := client.GetCoins(types.GetCoinsParams{Owner: owner, CoinType: &coinType, Limit: gm.NewNumberPtr(1), Cursor: nextCursor}) - if err != nil { - break - } - - nextCursor = nextPage.NextCursor - hasNext = nextPage.HasNextPage - data = append(data, nextPage.Data...) - } - return -} - -func GetMaxCoinObject(client *client.SuiClient, owner, coinType string) (*types.CoinStruct, error) { - coins, err := GetAllCoins(client, owner, coinType) - if err != nil { - return nil, err - } - - if len(coins) == 0 { - return nil, fmt.Errorf("address: [%s], coins not found, type: %s", owner, coinType) - } - - max := coins[0] - for _, coin := range coins { - balance, err := strconv.ParseUint(coin.Balance, 10, 64) - if err != nil { - return nil, err - } - - maxBalance, err := strconv.ParseUint(max.Balance, 10, 64) - if err != nil { - return nil, err - } - - if balance > maxBalance { - max = coin - } - } - return &max, nil -} diff --git a/gmsui/client_call_test.go b/gmsui/client_call_test.go deleted file mode 100644 index 6795f6b..0000000 --- a/gmsui/client_call_test.go +++ /dev/null @@ -1,84 +0,0 @@ -package gmsui_test - -import ( - "testing" - - "github.com/W3Tools/go-modules/gmsui" -) - -type TestClock struct { - Id gmsui.SuiMoveId `json:"id"` - TimestampMs string `json:"timestamp_ms"` -} - -// Does not actually run the test, but the test is valid -func TestClientCall_GetObjectAndUnmarshal(t *testing.T) { - // suiClient, err := client.NewSuiClient(context.Background(), client.GetFullNodeURL("mainnet")) - // if err != nil { - // t.Fatalf("failed to new sui client, msg: %v", err) - // } - - // _, clockObject, err := gmsui.GetObjectAndUnmarshal[TestClock](suiClient, "0x6") - // if err != nil { - // t.Fatalf("failed to get object and unmarshal, msg: %v", err) - // } - - // if reflect.DeepEqual(clockObject.Id.Id, "") { - // t.Errorf("expected id not none, but got %s", clockObject.Id.Id) - // } - - // if reflect.DeepEqual(clockObject.TimestampMs, "") { - // t.Errorf("expected timestamp not none, but got %s", clockObject.TimestampMs) - // } - - // _, packageObject, err := gmsui.GetObjectAndUnmarshal[TestClock](suiClient, "0x2") - // if err == nil { - // t.Fatalf("unable to get 0x2 package, expected package but got unknown") - // } - - // jsb, _ := json.Marshal(packageObject) - // fmt.Printf("package content: %v\n", string(jsb)) -} - -// Does not actually run the test, but the test is valid -func TestClientCall_GetObjectsAndUnmarshal(t *testing.T) { - // suiClient, err := client.NewSuiClient(context.Background(), client.GetFullNodeURL("mainnet")) - // if err != nil { - // t.Fatalf("failed to new sui client, msg: %v", err) - // } - - // _, clockObjects, err := gmsui.GetObjectsAndUnmarshal[TestClock](suiClient, []string{"0x6", "0x6"}) - // if err != nil { - // t.Fatalf("failed to get objects and unmarshal, msg: %v", err) - // } - - // for _, obj := range clockObjects { - // if reflect.DeepEqual(obj.Id.Id, "") { - // t.Errorf("expected id not none, but got %s", obj.Id.Id) - // } - - // if reflect.DeepEqual(obj.TimestampMs, "") { - // t.Errorf("expected timestamp not none, but got %s", obj.TimestampMs) - // } - // } -} - -// Does not actually run the test, but the test is valid -func TestClientCall_GetDynamicFieldObjectAndUnmarshal(t *testing.T) { -} - -// Does not actually run the test, but the test is valid -func TestClientCall_GetAllCoins(t *testing.T) { - // suiClient, err := client.NewSuiClient(context.Background(), client.GetFullNodeURL("mainnet")) - // if err != nil { - // t.Fatalf("failed to new sui client, msg: %v", err) - // } - - // coins, err := gmsui.GetAllCoins(suiClient, "0x2", "0x2::sui::SUI") - // if err != nil { - // t.Fatalf("failed to get all coins, msg: %v", err) - // } - - // jsb, _ := json.Marshal(coins) - // fmt.Printf("coinst: %v\n", string(jsb)) -} diff --git a/gmsui/constants.go b/gmsui/constants.go deleted file mode 100644 index db77225..0000000 --- a/gmsui/constants.go +++ /dev/null @@ -1,9 +0,0 @@ -package gmsui - -var ( - SuiGasCoinType string = "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI" - - SuiZeroAddress string = "0x0000000000000000000000000000000000000000000000000000000000000000" - SuiClockObjectId string = "0x0000000000000000000000000000000000000000000000000000000000000006" - SuiPackageId string = "0x0000000000000000000000000000000000000000000000000000000000000002" -) diff --git a/gmsui/cryptography/constants.go b/gmsui/cryptography/constants.go deleted file mode 100644 index f04bade..0000000 --- a/gmsui/cryptography/constants.go +++ /dev/null @@ -1,7 +0,0 @@ -package cryptography - -const ( - Ed25519PublicKeySize = 32 - Secp256k1PublicKeySize = 33 - Secp256r1PublicKeySize = 33 -) diff --git a/gmsui/cryptography/derivation.go b/gmsui/cryptography/derivation.go deleted file mode 100644 index a4e2285..0000000 --- a/gmsui/cryptography/derivation.go +++ /dev/null @@ -1,106 +0,0 @@ -package cryptography - -import ( - "crypto/hmac" - "crypto/sha512" - "encoding/hex" - "fmt" - "regexp" - "strconv" - "strings" -) - -var pathRegex = regexp.MustCompile(`^m(\/[0-9]+')+$`) - -const ( - Ed25519CURVE = "ed25519 seed" - HardenedOffset = 0x80000000 -) - -type Key struct { - Key []byte - ChainCode []byte -} - -func ReplaceDerive(val string) string { - return strings.Replace(val, "'", "", -1) -} - -func IsValidPath(path string) bool { - if !pathRegex.MatchString(path) { - return false - } - segments := strings.Split(path, "/")[1:] - for _, seg := range segments { - seg = ReplaceDerive(seg) - if _, err := strconv.Atoi(seg); err != nil { - return false - } - } - return true -} - -func GetMasterKeyFromSeed(seed string) (*Key, error) { - bs, err := hex.DecodeString(seed) - if err != nil { - return nil, err - } - - h := hmac.New(sha512.New, []byte(Ed25519CURVE)) - _, err = h.Write(bs) - if err != nil { - return nil, err - } - - sum := h.Sum(nil) - return &Key{Key: sum[:32], ChainCode: sum[32:]}, nil -} - -func CKDPriv(parent *Key, index uint32) (*Key, error) { - indexBuffer := make([]byte, 4) - indexBuffer[0] = byte(index >> 24) - indexBuffer[1] = byte(index >> 16) - indexBuffer[2] = byte(index >> 8) - indexBuffer[3] = byte(index) - - data := make([]byte, 1+len(parent.Key)+len(indexBuffer)) - data[0] = 0 - copy(data[1:], parent.Key) - copy(data[1+len(parent.Key):], indexBuffer) - - h := hmac.New(sha512.New, parent.ChainCode) - _, err := h.Write(data) - if err != nil { - return nil, err - } - - sum := h.Sum(nil) - return &Key{Key: sum[:32], ChainCode: sum[32:]}, nil -} - -func DerivePath(path string, seed string) (*Key, error) { - if !IsValidPath(path) { - return nil, fmt.Errorf("invalid derivation path") - } - - key, err := GetMasterKeyFromSeed(seed) - if err != nil { - return nil, err - } - - segments := strings.Split(path, "/")[1:] - for _, seg := range segments { - seg = ReplaceDerive(seg) - index, err := strconv.Atoi(seg) - if err != nil { - return nil, fmt.Errorf("invalid segment %s in path %s", seg, path) - } - - key, err = CKDPriv(key, uint32(index)+HardenedOffset) - if err != nil { - return nil, err - } - } - - return key, nil -} diff --git a/gmsui/cryptography/intent.go b/gmsui/cryptography/intent.go deleted file mode 100644 index 19eb8ac..0000000 --- a/gmsui/cryptography/intent.go +++ /dev/null @@ -1,41 +0,0 @@ -package cryptography - -import ( - "bytes" -) - -type AppId = uint8 - -const ( - Sui AppId = iota -) - -type IntentVersion = uint8 - -const ( - V0 IntentVersion = iota -) - -type IntentScope = uint8 - -const ( - TransactionData IntentScope = iota - TransactionEffects - CheckpointSummary - PersonalMessage -) - -type Intent = []uint8 - -func IntentWithScope(scope IntentScope) Intent { - return []uint8{scope, V0, Sui} -} - -func MessageWithIntent(scope IntentScope, message []byte) []byte { - intent := IntentWithScope(scope) - intentMessage := new(bytes.Buffer) - intentMessage.Write(intent) - intentMessage.Write(message) - - return intentMessage.Bytes() -} diff --git a/gmsui/cryptography/intent_test.go b/gmsui/cryptography/intent_test.go deleted file mode 100644 index 1d5b6e8..0000000 --- a/gmsui/cryptography/intent_test.go +++ /dev/null @@ -1,83 +0,0 @@ -package cryptography_test - -import ( - "bytes" - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" -) - -func TestIntentWithScope(t *testing.T) { - tests := []struct { - name string - scope cryptography.IntentScope - expected cryptography.Intent - }{ - { - name: "TransactionData scope", - scope: cryptography.TransactionData, - expected: cryptography.Intent{cryptography.TransactionData, cryptography.V0, cryptography.Sui}, - }, - { - name: "TransactionEffects scope", - scope: cryptography.TransactionEffects, - expected: cryptography.Intent{cryptography.TransactionEffects, cryptography.V0, cryptography.Sui}, - }, - { - name: "CheckpointSummary scope", - scope: cryptography.CheckpointSummary, - expected: cryptography.Intent{cryptography.CheckpointSummary, cryptography.V0, cryptography.Sui}, - }, - { - name: "PersonalMessage scope", - scope: cryptography.PersonalMessage, - expected: cryptography.Intent{cryptography.PersonalMessage, cryptography.V0, cryptography.Sui}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := cryptography.IntentWithScope(tt.scope) - if !bytes.Equal(result, tt.expected) { - t.Errorf("expected %v, but got %v", tt.expected, result) - } - }) - } -} - -func TestMessageWithIntent(t *testing.T) { - tests := []struct { - name string - scope cryptography.IntentScope - message []byte - expected []byte - }{ - { - name: "TransactionData with message", - scope: cryptography.TransactionData, - message: []byte("test message"), - expected: append(cryptography.IntentWithScope(cryptography.TransactionData), []byte("test message")...), - }, - { - name: "TransactionEffects with message", - scope: cryptography.TransactionEffects, - message: []byte("another message"), - expected: append(cryptography.IntentWithScope(cryptography.TransactionEffects), []byte("another message")...), - }, - { - name: "Empty message", - scope: cryptography.PersonalMessage, - message: []byte(""), - expected: cryptography.IntentWithScope(cryptography.PersonalMessage), - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - result := cryptography.MessageWithIntent(tt.scope, tt.message) - if !bytes.Equal(result, tt.expected) { - t.Errorf("expected %v, but got %v", tt.expected, result) - } - }) - } -} diff --git a/gmsui/cryptography/keypair.go b/gmsui/cryptography/keypair.go deleted file mode 100644 index 4f3c245..0000000 --- a/gmsui/cryptography/keypair.go +++ /dev/null @@ -1,157 +0,0 @@ -package cryptography - -import ( - "fmt" - - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/btcsuite/btcd/btcutil/bech32" - "github.com/fardream/go-bcs/bcs" - "golang.org/x/crypto/blake2b" -) - -const ( - PrivateKeySize = 32 - SuiPrivateKeyPrefix = "suiprivkey" -) - -type ParsedKeypair struct { - Scheme SignatureScheme - SecretKey []byte -} - -type SignatureWithBytes struct { - Bytes string - Signature SerializedSignature -} - -type Signer interface { - Sign(bs []byte) ([]byte, error) - SignWithIntent(bs []byte, intent IntentScope) (*SignatureWithBytes, error) - SignTransactionBlock(bs []byte) (*SignatureWithBytes, error) - SignPersonalMessage(bs []byte) (*SignatureWithBytes, error) - ToSuiAddress() string - SignData(data []byte) ([]byte, error) - GetKeyScheme() SignatureScheme - GetPublicKey() (PublicKey, error) -} - -type Keypair interface { - Signer - GetSecretKey() (string, error) -} - -type BaseSigner struct { - self Signer -} - -/** - * Sign messages with a specific intent. By combining the message bytes with the intent before hashing and signing, - * it ensures that a signed message is tied to a specific purpose and domain separator is provided - */ -func (signer *BaseSigner) SignWithIntent(bs []byte, intent IntentScope) (*SignatureWithBytes, error) { - intentMessage := MessageWithIntent(intent, bs) - digest := blake2b.Sum256(intentMessage) - - publicKey, err := signer.self.GetPublicKey() - if err != nil { - return nil, err - } - - sign, err := signer.self.Sign(digest[:]) - if err != nil { - return nil, err - } - - signature, err := ToSerializedSignature(SerializeSignatureInput{ - SignatureScheme: signer.self.GetKeyScheme(), - Signature: sign, - PublicKey: publicKey, - }) - if err != nil { - return nil, err - } - - return &SignatureWithBytes{Bytes: b64.ToBase64(bs), Signature: signature}, nil -} - -/** - * Signs provided transaction block by calling `signWithIntent()` with a `TransactionData` provided as intent scope - */ -func (signer *BaseSigner) SignTransactionBlock(bs []byte) (*SignatureWithBytes, error) { - return signer.SignWithIntent(bs, TransactionData) -} - -/** - * Signs provided personal message by calling `signWithIntent()` with a `PersonalMessage` provided as intent scope - */ -func (signer *BaseSigner) SignPersonalMessage(bs []byte) (*SignatureWithBytes, error) { - msg, err := bcs.Marshal(bs) - if err != nil { - return nil, err - } - - return signer.SignWithIntent(msg, PersonalMessage) -} - -func (signer *BaseSigner) ToSuiAddress() string { - publicKey, _ := signer.self.GetPublicKey() - return publicKey.ToSuiAddress() -} - -// abstract -// func (signer *BaseSigner) Sign(bs []byte) []byte { return nil } -// func (signer *BaseSigner) SignData(data []byte) []byte { return nil } -// func (signer *BaseSigner) GetKeyScheme() SignatureScheme { return "" } -// func (signer *BaseSigner) GetPublicKey() PublicKey { return nil } - -type BaseKeypair struct { - BaseSigner -} - -func (base *BaseKeypair) SetSelf(signer Signer) { - base.self = signer -} - -/** - * This returns an ParsedKeypair object based by validating the - * 33-byte Bech32 encoded string starting with `suiprivkey`, and - * parse out the signature scheme and the private key in bytes. - */ -func DecodeSuiPrivateKey(value string) (*ParsedKeypair, error) { - prefix, words, err := bech32.Decode(value) - if err != nil { - return nil, err - } - if prefix != SuiPrivateKeyPrefix { - return nil, fmt.Errorf("invalid private key prefix") - } - extendedSecretKey, err := bech32.ConvertBits(words, 5, 8, false) - if err != nil { - return nil, err - } - secretKey := extendedSecretKey[1:] - signatureScheme := SignatureFlagToScheme[extendedSecretKey[0]] - return &ParsedKeypair{Scheme: signatureScheme, SecretKey: secretKey}, nil -} - -/** - * This returns a Bech32 encoded string starting with `suiprivkey`, - * encoding 33-byte `flag || bytes` for the given the 32-byte private - * key and its signature scheme. - */ -func EncodeSuiPrivateKey(bytes []byte, scheme string) (string, error) { - if len(bytes) != PrivateKeySize { - return "", fmt.Errorf("invalid bytes length") - } - flag := SignatureSchemeToFlag[scheme] - privKeyBytes := append([]byte{flag}, bytes...) - words, err := bech32.ConvertBits(privKeyBytes, 8, 5, true) - if err != nil { - return "", err - } - encoded, err := bech32.Encode(SuiPrivateKeyPrefix, words) - if err != nil { - return "", err - } - return encoded, nil -} diff --git a/gmsui/cryptography/keypair_test.go b/gmsui/cryptography/keypair_test.go deleted file mode 100644 index 6d400a3..0000000 --- a/gmsui/cryptography/keypair_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package cryptography_test - -import ( - "bytes" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" -) - -func TestEncodeAndDecodeSuiPrivateKey(t *testing.T) { - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - t.Fatalf("failed to generate private key, msg: %v", err) - } - - privateKeyBytes := privateKey.D.Bytes() - if len(privateKeyBytes) != cryptography.PrivateKeySize { - t.Fatalf("expect private key size to be %d, got %d", privateKeyBytes, len(privateKeyBytes)) - } - - scheme := "ED25519" - encoded, err := cryptography.EncodeSuiPrivateKey(privateKeyBytes, scheme) - if err != nil { - t.Fatalf("failed to encode private key, msg: %v", err) - } - - decoded, err := cryptography.DecodeSuiPrivateKey(encoded) - if err != nil { - t.Fatalf("failed to decode sui private key, msg: %v", err) - } - - if decoded.Scheme != scheme { - t.Fatalf("expected scheme %s, got %s", scheme, decoded.Scheme) - } - - if !bytes.Equal(decoded.SecretKey, privateKeyBytes) { - t.Fatalf("decode private key does not match original") - } -} diff --git a/gmsui/cryptography/mnemonics.go b/gmsui/cryptography/mnemonics.go deleted file mode 100644 index 5e6cb3b..0000000 --- a/gmsui/cryptography/mnemonics.go +++ /dev/null @@ -1,54 +0,0 @@ -package cryptography - -import ( - "encoding/hex" - "fmt" - "regexp" - - "github.com/tyler-smith/go-bip39" -) - -// Parse and validate a path that is compliant to SLIP-0010 in form m/44'/784'/{account_index}'/{change_index}'/{address_index}'. -// e.g. `m/44'/784'/0'/0'/0'` -func IsValidHardenedPath(path string) bool { - matched, _ := regexp.MatchString("^m\\/44'\\/784'\\/[0-9]+'\\/[0-9]+'\\/[0-9]+'+$", path) - return matched -} - -// Parse and validate a path that is compliant to BIP-32 in form m/54'/784'/{account_index}'/{change_index}/{address_index} -// for Secp256k1 and m/74'/784'/{account_index}'/{change_index}/{address_index} for Secp256r1. -// Note that the purpose for Secp256k1 is registered as 54, to differentiate from Ed25519 with purpose 44. -// e.g. `m/54'/784'/0'/0/0` -func IsValidBIP32Path(path string) bool { - matched, _ := regexp.MatchString("^m\\/(54|74)'\\/784'\\/[0-9]+'\\/[0-9]+\\/[0-9]+$", path) - return matched -} - -// Uses KDF to derive 64 bytes of key data from mnemonic with empty password. -// mnemonics 12 words string split by spaces. -func MnemonicToSeed(mnemonics string) ([]byte, error) { - if !bip39.IsMnemonicValid(mnemonics) { - return nil, fmt.Errorf("invalid mnemonic") - } - - return bip39.NewSeed(mnemonics, ""), nil -} - -// Derive the seed in hex format from a 12-word mnemonic string. -// mnemonics 12 words string split by spaces. -func MnemonicToSeedHex(mnemonics string) (string, error) { - seed, err := MnemonicToSeed(mnemonics) - if err != nil { - return "", err - } - return hex.EncodeToString(seed), nil -} - -func GenerateMnemonic() (string, error) { - entropy, err := bip39.NewEntropy(128) - if err != nil { - return "", err - } - - return bip39.NewMnemonic(entropy) -} diff --git a/gmsui/cryptography/mnemonics_test.go b/gmsui/cryptography/mnemonics_test.go deleted file mode 100644 index af8050f..0000000 --- a/gmsui/cryptography/mnemonics_test.go +++ /dev/null @@ -1,133 +0,0 @@ -package cryptography_test - -import ( - "encoding/hex" - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/tyler-smith/go-bip39" -) - -func TestIsValidHardenedPath(t *testing.T) { - paths := []struct { - input string - expected bool - }{ - {"m/44'/784'/0'/0'/0'", true}, - {"m/44'/784'/123'/456'/789'", true}, - - {"m/44'/784'/0'/0/0'", false}, - {"m/54'/784'/0'/0'/0'", false}, - {"m/44'/784'/0'/0'/", false}, - {"m/44/784'/0'/0'/0'", false}, - {"m/44'/785'/0'/0'/0'", false}, - {"m/44'/784'/0'/0'/0", false}, // Missing single quote at the end - {"m/44'/784'/0'/0'/0'/", false}, // Extra slash at the end - {"m/44'/784'/a'/b'/c'", false}, // Non-numeric indexes - {"m/44'/784'/0'/0'/0'/extra", false}, // Extra characters at the end - } - - for _, path := range paths { - result := cryptography.IsValidHardenedPath(path.input) - if result != path.expected { - t.Errorf("IsValidHardenedPath(%s) returned %t, expected %t", path.input, result, path.expected) - } - } -} - -func TestIsValidBIP32Path(t *testing.T) { - paths := []struct { - input string - expected bool - }{ - {"m/54'/784'/0'/0/0", true}, - {"m/74'/784'/123'/456/789", true}, - {"m/54'/784'/0'/0'/0'", false}, - {"m/44'/784'/0'/0/0", false}, - {"m/54'/784'/0'/0/", false}, - {"m/54/784'/0'/0/0", false}, - - {"m/54'/784'/0'/0/0'", false}, // Extra single quote at the end - {"m/54'/784'/0'/0/0/", false}, // Extra slash at the end - {"m/54'/784'/a'/b/c", false}, // Non-numeric indexes - {"m/54'/784'/0'/0/0/extra", false}, // Extra characters at the end - {"m/74'/784'/0'/0/0", true}, // Secp256r1 path - } - - for _, path := range paths { - result := cryptography.IsValidBIP32Path(path.input) - if result != path.expected { - t.Errorf("IsValidBIP32Path(%s) returned %t, expected %t", path.input, result, path.expected) - } - } -} - -func TestMnemonicToSeed(t *testing.T) { - entropy, err := bip39.NewEntropy(128) - if err != nil { - t.Fatalf("failed to new entropy, msg: %v", err) - } - - validMnemonic, err := bip39.NewMnemonic(entropy) - if err != nil { - t.Fatalf("failed to generate mnemonic: %v", err) - } - - seed, err := cryptography.MnemonicToSeed(validMnemonic) - if err != nil { - t.Errorf("expected mnemonic to be valid, got error: %v", err) - } - if len(seed) == 0 { - t.Errorf("expected non-empty seed for valid mnemonic") - } - - invalidMnemonic := "invalid mnemonic phrase that does not conform to BIP39" - _, err = cryptography.MnemonicToSeed(invalidMnemonic) - if err == nil { - t.Fatalf("mnemonic unable to seed, msg: %v", err) - } -} - -func TestMnemonicToSeedHex(t *testing.T) { - entropy, err := bip39.NewEntropy(128) - if err != nil { - t.Fatalf("failed to new entropy, msg: %v", err) - } - - mnemonic, err := bip39.NewMnemonic(entropy) - if err != nil { - t.Fatalf("GenerateMnemonic returned error: %v", err) - } - - expectedSeed, err := cryptography.MnemonicToSeed(mnemonic) - if err != nil { - t.Fatalf("MnemonicToSeed returned error for valid mnemonic: %v", err) - } - - expectedHex := hex.EncodeToString(expectedSeed) - - hexSeed, err := cryptography.MnemonicToSeedHex(mnemonic) - if err != nil { - t.Errorf("MnemonicToSeedHex returned error for valid mnemonic: %v", err) - } - if hexSeed != expectedHex { - t.Errorf("MnemonicToSeedHex returned %s, expected %s", hexSeed, expectedHex) - } - - invalidMnemonic := "invalid mnemonic" - _, err = cryptography.MnemonicToSeedHex(invalidMnemonic) - if err == nil { - t.Errorf("MnemonicToSeedHex did not return error for invalid mnemonic: %s", invalidMnemonic) - } -} - -func TestGenerateMnemonic(t *testing.T) { - mnemonic, err := cryptography.GenerateMnemonic() - if err != nil { - t.Errorf("GenerateMnemonic returned error: %v", err) - } - - if !bip39.IsMnemonicValid(mnemonic) { - t.Errorf("GenerateMnemonic generated an invalid mnemonic: %s", mnemonic) - } -} diff --git a/gmsui/cryptography/publickey.go b/gmsui/cryptography/publickey.go deleted file mode 100644 index bb87a2b..0000000 --- a/gmsui/cryptography/publickey.go +++ /dev/null @@ -1,106 +0,0 @@ -package cryptography - -import ( - "bytes" - "encoding/hex" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/W3Tools/go-modules/gmsui/utils" - "github.com/fardream/go-bcs/bcs" - "golang.org/x/crypto/blake2b" -) - -type PublicKey interface { - Equals(publicKey PublicKey) bool - ToBase64() string - ToSuiPublicKey() string - VerifyWithIntent(bs []byte, signature SerializedSignature, intent IntentScope) (bool, error) - VerifyPersonalMessage(message []byte, signature SerializedSignature) (bool, error) - VerifyTransactionBlock(transactionBlock []byte, signature SerializedSignature) (bool, error) - ToSuiBytes() []byte - ToSuiAddress() string - ToRawBytes() []byte - Flag() uint8 - Verify(message []byte, signature SerializedSignature) (bool, error) -} - -type BasePublicKey struct { - self PublicKey -} - -// Checks if two public keys are equal -func (base *BasePublicKey) Equals(publicKey PublicKey) bool { - return gm.BytesEqual(base.self.ToRawBytes(), publicKey.ToRawBytes()) -} - -// Return the base-64 representation of the public key -func (base *BasePublicKey) ToBase64() string { - return b64.ToBase64(base.self.ToRawBytes()) -} - -/* - * Return the Sui representation of the public key encoded in - * base-64. A Sui public key is formed by the concatenation - * of the scheme flag with the raw bytes of the public key - */ -func (base *BasePublicKey) ToSuiPublicKey() string { - suiBytes := base.ToSuiBytes() - return b64.ToBase64(suiBytes) -} - -func (base *BasePublicKey) VerifyWithIntent(bs []byte, signature SerializedSignature, intent IntentScope) (bool, error) { - intentMessage := MessageWithIntent(intent, bs) - digest := blake2b.Sum256(intentMessage) - return base.self.Verify(digest[:], signature) -} - -// Verifies that the signature is valid for for the provided PersonalMessage -func (base *BasePublicKey) VerifyPersonalMessage(message []byte, signature SerializedSignature) (bool, error) { - msg, err := bcs.Marshal(message) - if err != nil { - return false, err - } - return base.VerifyWithIntent(msg, signature, PersonalMessage) -} - -// Verifies that the signature is valid for for the provided TransactionBlock -func (base *BasePublicKey) VerifyTransactionBlock(transactionBlock []byte, signature SerializedSignature) (bool, error) { - return base.VerifyWithIntent(transactionBlock, signature, TransactionData) -} - -/** - * Returns the bytes representation of the public key - * prefixed with the signature scheme flag - */ -func (base *BasePublicKey) ToSuiBytes() []byte { - rawBytes := base.self.ToRawBytes() - suiBytes := new(bytes.Buffer) - suiBytes.Write([]byte{base.self.Flag()}) - suiBytes.Write(rawBytes) - - return suiBytes.Bytes() -} - -// Return the Sui address associated with this Ed25519 public key -func (base *BasePublicKey) ToSuiAddress() string { - digest := blake2b.Sum256(base.ToSuiBytes()) - return utils.NormalizeSuiAddress(hex.EncodeToString(digest[:])[:utils.SuiAddressLength*2]) -} - -// abstract: Return the byte array representation of the public key -// func (base *BasePublicKey) ToRawBytes() []byte - -// abstract: Return signature scheme flag of the public key -// func (base *BasePublicKey) Flag() uint8 - -// // abstract: Verifies that the signature is valid for for the provided message -// -// func (base *BasePublicKey) Verify(message []byte, signature SerializedSignature) (bool, error) { -// return false, nil -// } - -// To ensure thread memory safety, this method needs to be removed. This matter is temporarily added to the todo list -func (base *BasePublicKey) SetSelf(pubkey PublicKey) { - base.self = pubkey -} diff --git a/gmsui/cryptography/signature.go b/gmsui/cryptography/signature.go deleted file mode 100644 index ed1aa61..0000000 --- a/gmsui/cryptography/signature.go +++ /dev/null @@ -1,92 +0,0 @@ -package cryptography - -import ( - "bytes" - "fmt" - - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/fardream/go-bcs/bcs" -) - -/** - * Pair of signature and corresponding public key - */ -type SerializeSignatureInput struct { - SignatureScheme SignatureScheme - Signature []byte - PublicKey PublicKey -} - -type SerializedSignature = string - -/** - * Takes in a signature, its associated signing scheme and a public key, then serializes this data - */ -func ToSerializedSignature(input SerializeSignatureInput) (string, error) { - if input.PublicKey == nil { - return "", fmt.Errorf("publicKey is required") - } - - pubKeyBytes := input.PublicKey.ToRawBytes() - serializedSignature := new(bytes.Buffer) - serializedSignature.Write([]byte{SignatureSchemeToFlag[input.SignatureScheme]}) - serializedSignature.Write(input.Signature) - serializedSignature.Write(pubKeyBytes) - return b64.ToBase64(serializedSignature.Bytes()), nil -} - -/** - * Decodes a serialized signature into its constituent components: the signature scheme, the actual signature, and the public key - */ -func ParseSerializedSignature(serializedSignature SerializedSignature) (*SerializedSignatureParsedData, error) { - bs, err := b64.FromBase64(serializedSignature) - if err != nil { - return nil, err - } - - signatureScheme := SignatureFlagToScheme[bs[0]] - - switch signatureScheme { - case Ed25519Scheme, Secp256k1Scheme, Secp256r1Scheme: - size := SignatureSchemeToSize[signatureScheme] - signature := bs[1 : len(bs)-size] - publicKey := bs[1+len(signature):] - - data := &SerializedSignatureParsedData{ - SerializedSignature: serializedSignature, - SignatureScheme: signatureScheme, - Signature: signature, - PubKey: publicKey, - Bytes: bs, - } - - return data, nil - case MultiSigScheme: - multisig := new(MultiSigStruct) - _, err := bcs.Unmarshal(bs[1:], &multisig) - if err != nil { - return nil, err - } - - data := &SerializedSignatureParsedData{ - SerializedSignature: serializedSignature, - SignatureScheme: signatureScheme, - Multisig: multisig, - Bytes: bs, - } - return data, nil - case ZkLoginScheme: - return nil, fmt.Errorf("unimplemented %v", ZkLoginScheme) - default: - return nil, fmt.Errorf("unsupported signature scheme") - } -} - -type SerializedSignatureParsedData struct { - SerializedSignature SerializedSignature `json:"serializedSignature"` - SignatureScheme string `json:"signatureScheme"` - Signature []byte `json:"signature,omitempty"` - PubKey []byte `json:"pubKey,omitempty"` - Bytes []byte `json:"bytes"` - Multisig *MultiSigStruct `json:"multisig,omitempty"` -} diff --git a/gmsui/cryptography/signature_scheme.go b/gmsui/cryptography/signature_scheme.go deleted file mode 100644 index 5ebf696..0000000 --- a/gmsui/cryptography/signature_scheme.go +++ /dev/null @@ -1,34 +0,0 @@ -package cryptography - -type SignatureScheme = string -type SignatureFlag = uint8 - -var ( - Ed25519Scheme SignatureScheme = "ED25519" - Secp256k1Scheme SignatureScheme = "Secp256k1" - Secp256r1Scheme SignatureScheme = "Secp256r1" - MultiSigScheme SignatureScheme = "MultiSig" - ZkLoginScheme SignatureScheme = "ZkLogin" -) - -var SignatureSchemeToFlag = map[SignatureScheme]SignatureFlag{ - Ed25519Scheme: 0x00, - Secp256k1Scheme: 0x01, - Secp256r1Scheme: 0x02, - MultiSigScheme: 0x03, - ZkLoginScheme: 0x05, -} - -var SignatureSchemeToSize = map[SignatureScheme]int{ - Ed25519Scheme: 32, - Secp256k1Scheme: 33, - Secp256r1Scheme: 33, -} - -var SignatureFlagToScheme = map[SignatureFlag]SignatureScheme{ - 0x00: Ed25519Scheme, - 0x01: Secp256k1Scheme, - 0x02: Secp256r1Scheme, - 0x03: MultiSigScheme, - 0x05: ZkLoginScheme, -} diff --git a/gmsui/cryptography/signature_scheme_test.go b/gmsui/cryptography/signature_scheme_test.go deleted file mode 100644 index 38ded93..0000000 --- a/gmsui/cryptography/signature_scheme_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package cryptography_test - -import ( - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" -) - -func TestSignatureSchemeToFlag(t *testing.T) { - tests := []struct { - name string - scheme cryptography.SignatureScheme - expectedFlag cryptography.SignatureFlag - expectingFail bool - }{ - {"Ed25519", cryptography.Ed25519Scheme, 0x00, false}, - {"Secp256k1", cryptography.Secp256k1Scheme, 0x01, false}, - {"Secp256r1", cryptography.Secp256r1Scheme, 0x02, false}, - {"MultiSig", cryptography.MultiSigScheme, 0x03, false}, - {"ZkLogin", cryptography.ZkLoginScheme, 0x05, false}, - {"UnknownScheme", "UnknownScheme", 0x00, true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - flag, exists := cryptography.SignatureSchemeToFlag[tt.scheme] - if tt.expectingFail { - if exists { - t.Errorf("expected failure, but got flag %v", flag) - } - } else { - if !exists || flag != tt.expectedFlag { - t.Errorf("expected flag %v, but got %v", tt.expectedFlag, flag) - } - } - }) - } -} - -func TestSignatureSchemeToSize(t *testing.T) { - tests := []struct { - name string - scheme cryptography.SignatureScheme - expectedSize int - expectingFail bool - }{ - {"Ed25519", cryptography.Ed25519Scheme, 32, false}, - {"Secp256k1", cryptography.Secp256k1Scheme, 33, false}, - {"Secp256r1", cryptography.Secp256r1Scheme, 33, false}, - {"UnknownScheme", "UnknownScheme", 0, true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - size, exists := cryptography.SignatureSchemeToSize[tt.scheme] - if tt.expectingFail { - if exists { - t.Errorf("expected failure, but got size %v", size) - } - } else { - if !exists || size != tt.expectedSize { - t.Errorf("expected size %v, but got %v", tt.expectedSize, size) - } - } - }) - } -} - -func TestSignatureFlagToScheme(t *testing.T) { - tests := []struct { - name string - flag cryptography.SignatureFlag - expectedScheme cryptography.SignatureScheme - expectingFail bool - }{ - {"Ed25519", 0x00, cryptography.Ed25519Scheme, false}, - {"Secp256k1", 0x01, cryptography.Secp256k1Scheme, false}, - {"Secp256r1", 0x02, cryptography.Secp256r1Scheme, false}, - {"MultiSig", 0x03, cryptography.MultiSigScheme, false}, - {"ZkLogin", 0x05, cryptography.ZkLoginScheme, false}, - {"UnknownFlag", 0x04, "", true}, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - scheme, exists := cryptography.SignatureFlagToScheme[tt.flag] - if tt.expectingFail { - if exists { - t.Errorf("expected failure, but got scheme %v", scheme) - } - } else { - if !exists || scheme != tt.expectedScheme { - t.Errorf("expected scheme %v, but got %v", tt.expectedScheme, scheme) - } - } - }) - } -} diff --git a/gmsui/cryptography/types.go b/gmsui/cryptography/types.go deleted file mode 100644 index eb024b3..0000000 --- a/gmsui/cryptography/types.go +++ /dev/null @@ -1,107 +0,0 @@ -package cryptography - -import ( - "fmt" - "io" - - "github.com/fardream/go-bcs/bcs" -) - -type CompressedSignature struct { - Signature [65]byte `json:"signature"` -} - -type PubKeyEnumWeightPair struct { - PubKey []byte `json:"pubKey"` - Weight uint8 `json:"weight"` -} - -type MultiSigPublicKeyStruct struct { - PubKeyMap []*PubKeyEnumWeightPair `json:"pubKeymap"` - Threshold uint16 `json:"threshold"` -} - -type MultiSigStruct struct { - Sigs []CompressedSignature `json:"sigs"` - Bitmap uint16 `json:"bitmap"` - MultisigPubKey MultiSigPublicKeyStruct `json:"multisigPubKey"` -} - -type MultiSigPublicKeyPair struct { - Weight uint8 `json:"weight"` - PublicKey PublicKey `json:"publicKey"` -} - -var ( - _ bcs.Marshaler = (*PubKeyEnumWeightPair)(nil) - _ bcs.Unmarshaler = (*PubKeyEnumWeightPair)(nil) -) - -func (p PubKeyEnumWeightPair) MarshalBCS() ([]byte, error) { - switch len(p.PubKey) { - case 33: - data := struct { - PubKey [33]byte `json:"pubKey"` - Weight uint8 `json:"weight"` - }{PubKey: [33]byte(p.PubKey[:]), Weight: p.Weight} - return bcs.Marshal(data) - case 34: - data := struct { - PubKey [34]byte `json:"pubKey"` - Weight uint8 `json:"weight"` - }{PubKey: [34]byte(p.PubKey[:]), Weight: p.Weight} - return bcs.Marshal(data) - default: - return nil, fmt.Errorf("pubKey length must be either 33 or 34 bytes") - - } -} - -func (p *PubKeyEnumWeightPair) UnmarshalBCS(r io.Reader) (int, error) { - pubkeyType, n, err := ReadByte(r) - if err != nil { - return n, err - } - - pubkeySize := 0 - switch pubkeyType { - case SignatureSchemeToFlag[Ed25519Scheme]: - pubkeySize = Ed25519PublicKeySize - case SignatureSchemeToFlag[Secp256k1Scheme]: - pubkeySize = Secp256k1PublicKeySize - case SignatureSchemeToFlag[Secp256r1Scheme]: - pubkeySize = Secp256r1PublicKeySize - } - - pubkey := make([]byte, pubkeySize) - read, err := r.Read(pubkey) - n += read - if err != nil { - return n, err - } - - weight, read, err := ReadByte(r) - n += read - if err != nil { - return n, err - } - - p.PubKey = append([]byte{pubkeyType}, pubkey...) - p.Weight = weight - - return n, nil -} - -func ReadByte(r io.Reader) (byte, int, error) { - b := [1]byte{} - n, err := r.Read(b[:]) - if err != nil { - return 0, n, err - } - - if n == 0 { - return 0, n, io.ErrUnexpectedEOF - } - - return b[0], n, nil -} diff --git a/gmsui/event.go b/gmsui/event.go deleted file mode 100644 index b4d2ff4..0000000 --- a/gmsui/event.go +++ /dev/null @@ -1,38 +0,0 @@ -package gmsui - -import ( - "encoding/json" - "fmt" - - "github.com/W3Tools/go-modules/gmsui/types" -) - -// Define the type as MoveModule/MoveEventModule. Events emitted, defined on the specified Move module. -// Reference: https://docs.sui.io/guides/developer/sui-101/using-events#filtering-event-queries -type MoveEventModuleConfig struct { - Package string `toml:"Package,omitempty"` - Module string `toml:"Module,omitempty"` -} - -func (ec *MoveEventModuleConfig) Join() string { - return fmt.Sprintf("%s::%s", ec.Package, ec.Module) -} - -func (ec *MoveEventModuleConfig) JoinEventName(name string) string { - return fmt.Sprintf("%s::%s::%s", ec.Package, ec.Module, name) -} - -// Parsing custom event json -// Reference: https://docs.sui.io/guides/developer/sui-101/using-events#move-event-structure -func ParseEvent[T any](event types.SuiEvent) (*T, error) { - jsonBytes, err := json.Marshal(event.ParsedJson) - if err != nil { - return nil, err - } - - parsedJson := new(T) - if err := json.Unmarshal(jsonBytes, &parsedJson); err != nil { - return nil, err - } - return parsedJson, nil -} diff --git a/gmsui/keypairs/ed25519/ed25519_test.go b/gmsui/keypairs/ed25519/ed25519_test.go deleted file mode 100644 index e12dc8a..0000000 --- a/gmsui/keypairs/ed25519/ed25519_test.go +++ /dev/null @@ -1,185 +0,0 @@ -package ed25519_test - -import ( - "crypto/ed25519" - "crypto/rand" - "reflect" - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - ed25519_keypair "github.com/W3Tools/go-modules/gmsui/keypairs/ed25519" - "github.com/tyler-smith/go-bip39" -) - -func TestGenerateAndVerifyEd25519Keypair(t *testing.T) { - keypair, err := ed25519_keypair.GenerateEd25519Keypair() - if err != nil { - t.Fatalf("unable to generate Ed25519 keypair, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), cryptography.Ed25519PublicKeySize) { - t.Errorf("expected public key size to be %d, but got %d", ed25519.PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), ed25519.PrivateKeySize) { - t.Errorf("expected private key size to be %d, but got %d", ed25519.PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Ed25519Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Ed25519Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := ed25519_keypair.NewEd25519PublicKey(keypair.PublicKey()) - if err != nil { - t.Fatalf("unable to create Ed25519 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Ed25519Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Ed25519Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Ed25519Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialized signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) - - t.Run("SignPersonalMessage", func(t *testing.T) { - signature, err := keypair.SignPersonalMessage(message) - if err != nil { - t.Fatalf("unable to sign personal message, msg: %v", err) - } - - valid, err := publicKey.VerifyPersonalMessage(message, signature.Signature) - if err != nil { - t.Fatalf("unable to verify personal message, msg: %v", err) - } - - if !valid { - t.Errorf("signature verification failed") - } - }) -} - -func TestFromSecretKeyAndVerify(t *testing.T) { - seed := make([]byte, ed25519.SeedSize) - _, err := rand.Read(seed) - if err != nil { - t.Fatalf("error generating random secret key: %v", err) - } - - keypair, err := ed25519_keypair.FromSecretKey(seed, false) - if err != nil { - t.Fatalf("unable to create Ed25519 keypair from seed, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), ed25519.PublicKeySize) { - t.Errorf("expected public key size to be %d, but got %d", ed25519.PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), ed25519.PrivateKeySize) { - t.Errorf("expected private key size to be %d, but got %d", ed25519.PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Ed25519Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Ed25519Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := ed25519_keypair.NewEd25519PublicKey(keypair.PublicKey()) - if err != nil { - t.Fatalf("unable to create Ed25519 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Ed25519Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Ed25519Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Ed25519Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialized signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) -} - -func TestDeriveKeypairFromMnemonic(t *testing.T) { - entropy, err := bip39.NewEntropy(128) - if err != nil { - t.Fatalf("failed to new entropy, msg: %v", err) - } - - mnemonic, err := bip39.NewMnemonic(entropy) - if err != nil { - t.Fatalf("unable to generate mnemonic, msg: %v", err) - } - - keypair, err := ed25519_keypair.DeriveKeypair(mnemonic, ed25519_keypair.DefaultEd25519DerivationPath) - if err != nil { - t.Fatalf("unable to derive keypair, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), ed25519.PublicKeySize) { - t.Errorf("expected public key size to be %d, but got %d", ed25519.PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), ed25519.PrivateKeySize) { - t.Errorf("expected private key size to be %d, but got %d", ed25519.PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Ed25519Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Ed25519Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := ed25519_keypair.NewEd25519PublicKey(keypair.PublicKey()) - if err != nil { - t.Fatalf("unable to create Ed25519 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Ed25519Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Ed25519Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Ed25519Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialized signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) -} diff --git a/gmsui/keypairs/ed25519/keypair.go b/gmsui/keypairs/ed25519/keypair.go deleted file mode 100644 index e11e563..0000000 --- a/gmsui/keypairs/ed25519/keypair.go +++ /dev/null @@ -1,147 +0,0 @@ -package ed25519 - -import ( - "crypto/ed25519" - "crypto/rand" - "errors" - "fmt" - - "github.com/W3Tools/go-modules/gmsui/cryptography" -) - -var ( - _ cryptography.Keypair = (*Ed25519Keypair)(nil) -) - -const DefaultEd25519DerivationPath = "m/44'/784'/0'/0'/0'" - -// Ed25519 Keypair data. The publickey is the 32-byte public key and the secretkey is 64-byte -// Where the first 32 bytes is the secret key and the last 32 bytes is the public key. -type Ed25519KeypairData struct { - PublicKey []byte - SecretKey []byte -} - -// An Ed25519 Keypair used for signing transactions. -type Ed25519Keypair struct { - keypair *Ed25519KeypairData - cryptography.BaseKeypair -} - -// Create or generate a new Ed25519 keypair instance. -func NewEd25519Keypair(keypair *Ed25519KeypairData) (*Ed25519Keypair, error) { - if keypair == nil { - publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader) - if err != nil { - return nil, err - } - keypair = &Ed25519KeypairData{PublicKey: publicKey, SecretKey: privateKey} - } - - kp := &Ed25519Keypair{keypair: keypair} - kp.SetSelf(kp) - return kp, nil -} - -// Get the key scheme of the keypair ED25519 -func (k *Ed25519Keypair) GetKeyScheme() cryptography.SignatureScheme { - return cryptography.Ed25519Scheme -} - -// The public key for this Ed25519 keypair -func (k *Ed25519Keypair) GetPublicKey() (cryptography.PublicKey, error) { - return NewEd25519PublicKey(k.keypair.PublicKey) -} - -// The Bech32 secret key string for this Ed25519 keypair -func (k *Ed25519Keypair) GetSecretKey() (string, error) { - return cryptography.EncodeSuiPrivateKey(k.keypair.SecretKey[:cryptography.PrivateKeySize], k.GetKeyScheme()) -} - -func (k *Ed25519Keypair) Sign(data []byte) ([]byte, error) { - return k.SignData(data) -} - -// Return the signature for the provided data using Ed25519. -func (k *Ed25519Keypair) SignData(data []byte) ([]byte, error) { - return ed25519.Sign(k.keypair.SecretKey, data), nil -} - -// Generate a new random Ed25519 keypair -func GenerateEd25519Keypair() (*Ed25519Keypair, error) { - return NewEd25519Keypair(nil) -} - -// Create a Ed25519 keypair from a raw secret key byte array, also known as seed. -// This is NOT the private scalar which is result of hashing and bit clamping of the raw secret key. -func FromSecretKey(secretKey []byte, skipValidation bool) (*Ed25519Keypair, error) { - secretKeyLength := len(secretKey) - if secretKeyLength != cryptography.PrivateKeySize { - return nil, fmt.Errorf("wrong secretKey size. expected %d bytes, got %d", cryptography.PrivateKeySize, secretKeyLength) - } - - privateKey := ed25519.NewKeyFromSeed(secretKey) - publicKey := privateKey.Public().(ed25519.PublicKey) - - if !skipValidation { - signData := []byte("sui validation") - signature := ed25519.Sign(privateKey, signData) - if !ed25519.Verify(publicKey, signData, signature) { - return nil, errors.New("provided secretKey is invalid") - } - } - - return NewEd25519Keypair(&Ed25519KeypairData{PublicKey: publicKey, SecretKey: privateKey}) -} - -// Derive Ed25519 keypair from mnemonics and path -// The mnemonics must be normalized and validated against the english wordlist. -// If path is none, it will default to m/44'/784'/0'/0'/0' -// Otherwise the path must be compliant to SLIP-0010 in form m/44'/784'/{account_index}'/{change_index}'/{address_index}'. -func DeriveKeypair(mnemonics, path string) (*Ed25519Keypair, error) { - if path == "" { - path = DefaultEd25519DerivationPath - } - if !cryptography.IsValidHardenedPath(path) { - return nil, fmt.Errorf("invalid derivation path") - } - - seedHex, err := cryptography.MnemonicToSeedHex(mnemonics) - if err != nil { - return nil, err - } - - key, err := cryptography.DerivePath(path, seedHex) - if err != nil { - return nil, err - } - - return FromSecretKey(key.Key, false) -} - -// Derive Ed25519 keypair from mnemonicSeed and path. -// If path is none, it will default to m/44'/784'/0'/0'/0' -// Otherwise the path must be compliant to SLIP-0010 in form m/44'/784'/{account_index}'/{change_index}'/{address_index}'. -func DeriveKeypairFromSeed(seedHex, path string) (*Ed25519Keypair, error) { - if path == "" { - path = DefaultEd25519DerivationPath - } - - if !cryptography.IsValidHardenedPath(path) { - return nil, fmt.Errorf("invalid derivation path") - } - - key, err := cryptography.DerivePath(path, seedHex) - if err != nil { - return nil, err - } - return FromSecretKey(key.Key, false) -} - -func (kp *Ed25519Keypair) PublicKey() []byte { - return kp.keypair.PublicKey -} - -func (kp *Ed25519Keypair) SecretKey() []byte { - return kp.keypair.SecretKey -} diff --git a/gmsui/keypairs/ed25519/publickey.go b/gmsui/keypairs/ed25519/publickey.go deleted file mode 100644 index 2763432..0000000 --- a/gmsui/keypairs/ed25519/publickey.go +++ /dev/null @@ -1,66 +0,0 @@ -package ed25519 - -import ( - "crypto/ed25519" - "fmt" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/W3Tools/go-modules/gmsui/cryptography" -) - -var ( - _ cryptography.PublicKey = (*Ed25519PublicKey)(nil) -) - -type Ed25519PublicKey struct { - data []byte - cryptography.BasePublicKey -} - -func NewEd25519PublicKey[T string | []byte](value T) (publicKey *Ed25519PublicKey, err error) { - publicKey = new(Ed25519PublicKey) - switch v := any(value).(type) { - case string: - publicKey.data, err = b64.FromBase64(v) - if err != nil { - return nil, err - } - case []byte: - publicKey.data = v - } - - if len(publicKey.data) != cryptography.Ed25519PublicKeySize { - return nil, fmt.Errorf("invalid public key input. expected %v bytes, got %v", cryptography.Ed25519PublicKeySize, len(publicKey.data)) - } - publicKey.SetSelf(publicKey) - return -} - -// Return the byte array representation of the Ed25519 public key -func (key *Ed25519PublicKey) ToRawBytes() []byte { - return key.data -} - -// Return the Sui address associated with this Ed25519 public key -func (key *Ed25519PublicKey) Flag() uint8 { - return cryptography.SignatureSchemeToFlag[cryptography.Ed25519Scheme] -} - -// Verifies that the signature is valid for for the provided message -func (key *Ed25519PublicKey) Verify(message []byte, signature cryptography.SerializedSignature) (bool, error) { - parsed, err := cryptography.ParseSerializedSignature(signature) - if err != nil { - return false, err - } - - if parsed.SignatureScheme != cryptography.Ed25519Scheme { - return false, fmt.Errorf("invalid signature scheme") - } - - if !gm.BytesEqual(key.ToRawBytes(), parsed.PubKey) { - return false, fmt.Errorf("signature does not match public key") - } - - return ed25519.Verify(parsed.PubKey, message, parsed.Signature), nil -} diff --git a/gmsui/keypairs/ed25519/publickey_test.go b/gmsui/keypairs/ed25519/publickey_test.go deleted file mode 100644 index 7d68cc1..0000000 --- a/gmsui/keypairs/ed25519/publickey_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package ed25519_test - -import ( - "reflect" - "testing" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/cryptography" - ed25519_keypair "github.com/W3Tools/go-modules/gmsui/keypairs/ed25519" - "github.com/fardream/go-bcs/bcs" -) - -func TestEd25519PublicKey(t *testing.T) { - tests := []struct { - suiAddress string - rawBytes []byte - publicKey string - suiBytes []byte - suiPublicKey string - flag uint8 - message string - signature string - }{ - { - // m/44'/784'/0'/0'/0' - suiAddress: "0x5058cfdd208cf43ad09e95e064d16fec9033cddf424756b980bc2f645969ea5e", - rawBytes: []byte{254, 160, 35, 2, 213, 131, 174, 249, 17, 21, 83, 205, 86, 152, 194, 117, 175, 219, 42, 205, 48, 253, 187, 139, 108, 120, 141, 198, 49, 161, 180, 124}, - publicKey: "/qAjAtWDrvkRFVPNVpjCda/bKs0w/buLbHiNxjGhtHw=", - suiBytes: []byte{0, 254, 160, 35, 2, 213, 131, 174, 249, 17, 21, 83, 205, 86, 152, 194, 117, 175, 219, 42, 205, 48, 253, 187, 139, 108, 120, 141, 198, 49, 161, 180, 124}, - suiPublicKey: "AP6gIwLVg675ERVTzVaYwnWv2yrNMP27i2x4jcYxobR8", - flag: 0, - message: "hello", - signature: "AAX5Ny4lOGQuwCk6xomSNtuiFjmQNYf7FXxeKLJ7IX9vhQCWvDCO734lGCSJArZGGPXxanWzQunvHYkp6KbR6QL+oCMC1YOu+REVU81WmMJ1r9sqzTD9u4tseI3GMaG0fA==", - }, - { - // m/44'/784'/0'/0'/1' - suiAddress: "0xef65e3e07a2c4bc4370d7865ccdbbd9ae85962b6602525ef9cc68581203dc8a6", - rawBytes: []byte{117, 128, 142, 161, 104, 165, 131, 152, 47, 60, 74, 181, 173, 188, 9, 85, 36, 138, 213, 90, 57, 208, 249, 90, 80, 208, 100, 16, 96, 231, 208, 219}, - publicKey: "dYCOoWilg5gvPEq1rbwJVSSK1Vo50PlaUNBkEGDn0Ns=", - suiBytes: []byte{0, 117, 128, 142, 161, 104, 165, 131, 152, 47, 60, 74, 181, 173, 188, 9, 85, 36, 138, 213, 90, 57, 208, 249, 90, 80, 208, 100, 16, 96, 231, 208, 219}, - suiPublicKey: "AHWAjqFopYOYLzxKta28CVUkitVaOdD5WlDQZBBg59Db", - flag: 0, - message: "hello", - signature: "AOu/hsEv/4RqO9tezlmmn19net4x/cEqhpyETr3ZGA0I5uxagSQzPTw1oFdXH2EPcMZG44wX9gBeuZOKPPNmkQp1gI6haKWDmC88SrWtvAlVJIrVWjnQ+VpQ0GQQYOfQ2w==", - }, - { - // m/44'/784'/0'/0'/2' - suiAddress: "0xf7e1dfc2e9d82325dd5a6b67f683c6dceeb6f6fac7f78139614d5e80d9853b7f", - rawBytes: []byte{255, 141, 156, 70, 154, 124, 81, 87, 198, 68, 54, 241, 125, 144, 73, 233, 124, 253, 196, 64, 151, 221, 39, 157, 121, 56, 92, 238, 64, 163, 109, 57}, - publicKey: "/42cRpp8UVfGRDbxfZBJ6Xz9xECX3SedeThc7kCjbTk=", - suiBytes: []byte{0, 255, 141, 156, 70, 154, 124, 81, 87, 198, 68, 54, 241, 125, 144, 73, 233, 124, 253, 196, 64, 151, 221, 39, 157, 121, 56, 92, 238, 64, 163, 109, 57}, - suiPublicKey: "AP+NnEaafFFXxkQ28X2QSel8/cRAl90nnXk4XO5Ao205", - flag: 0, - message: "hello", - signature: "AJ0FNCly92/2jxEWnkp9hNKVR7vkdMqxCsXPZ3FlU5yvUPa57od6+1TmLH8LqTK1sNOe3caLh/q9VPv1Jz47FwL/jZxGmnxRV8ZENvF9kEnpfP3EQJfdJ515OFzuQKNtOQ==", - }, - } - - for _, tt := range tests { - t.Run(tt.suiAddress, func(t *testing.T) { - publicKey, err := ed25519_keypair.NewEd25519PublicKey(tt.publicKey) - if err != nil { - t.Fatalf("Unable to NewEd25519PublicKey, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.ToSuiAddress(), tt.suiAddress) { - t.Errorf("sui address expected %v, but got %v", tt.suiAddress, publicKey.ToSuiAddress()) - } - - if !gm.BytesEqual(publicKey.ToRawBytes(), tt.rawBytes) { - t.Errorf("raw bytes expected %v, but got %v", tt.rawBytes, publicKey.ToRawBytes()) - } - - if !gm.BytesEqual(publicKey.ToSuiBytes(), tt.suiBytes) { - t.Errorf("sui bytes expected %v, but got %v", tt.suiBytes, publicKey.ToSuiBytes()) - } - - if !reflect.DeepEqual(publicKey.ToBase64(), tt.publicKey) { - t.Errorf("public key expected %v, but got %v", tt.suiPublicKey, publicKey.ToBase64()) - } - - if !reflect.DeepEqual(publicKey.ToSuiPublicKey(), tt.suiPublicKey) { - t.Errorf("sui public key expected %v, but got %v", tt.suiPublicKey, publicKey.ToBase64()) - } - - if !reflect.DeepEqual(publicKey.Flag(), tt.flag) { - t.Errorf("flag expected %v, but got %v", tt.flag, publicKey.Flag()) - } - - pass, err := publicKey.VerifyPersonalMessage([]byte(tt.message), tt.signature) - if err != nil { - t.Fatalf("unable to verify personal message, msg: %v", err) - } - if !pass { - t.Errorf("verify personal message unpass") - } - - bcsMessage, err := bcs.Marshal([]byte(tt.message)) - if err != nil { - t.Fatalf("unable to marshal bcs, msg: %v", err) - } - pass, err = publicKey.VerifyWithIntent(bcsMessage, tt.signature, cryptography.PersonalMessage) - if err != nil { - t.Fatalf("unable to verify with intent, msg: %v", err) - } - if !pass { - t.Errorf("verify with intent unpass") - } - }) - } -} diff --git a/gmsui/keypairs/secp256k1/k.go b/gmsui/keypairs/secp256k1/k.go deleted file mode 100644 index effb2f9..0000000 --- a/gmsui/keypairs/secp256k1/k.go +++ /dev/null @@ -1,103 +0,0 @@ -package secp256k1 - -import ( - "crypto/hmac" - "crypto/sha256" - "fmt" - "math/big" - - "github.com/btcsuite/btcd/btcec/v2" -) - -// DeterministicSign generates deterministic ECDSA signature using RFC 6979 for secp256k1 curve -func deterministicSign(priv *btcec.PrivateKey, hash []byte) (*big.Int, *big.Int, error) { - curve := btcec.S256() - k := deterministicK(priv, hash) - r, s, err := signWithK(priv, hash, k) - if err != nil { - return nil, nil, err - } - - // Ensure s is in the lower half of the order - halfOrder := new(big.Int).Rsh(curve.Params().N, 1) - if s.Cmp(halfOrder) > 0 { - s.Sub(curve.Params().N, s) - } - - return r, s, nil -} - -// RFC 6979 deterministic K generation for secp256k1 -func deterministicK(priv *btcec.PrivateKey, hash []byte) *big.Int { - curve := btcec.S256() - q := curve.Params().N - - v := make([]byte, 32) - k := make([]byte, 32) - for i := range v { - v[i] = 0x01 - } - - hm := hmac.New(sha256.New, k) - hm.Write(v) - hm.Write([]byte{0x00}) - hm.Write(priv.ToECDSA().D.Bytes()) - hm.Write(hash) - k = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - hm.Write([]byte{0x01}) - hm.Write(priv.ToECDSA().D.Bytes()) - hm.Write(hash) - k = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - - for { - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - kInt := new(big.Int).SetBytes(v) - if kInt.Sign() > 0 && kInt.Cmp(q) < 0 { - return kInt - } - hm = hmac.New(sha256.New, k) - hm.Write(v) - hm.Write([]byte{0x00}) - k = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - } -} - -func signWithK(priv *btcec.PrivateKey, hash []byte, k *big.Int) (*big.Int, *big.Int, error) { - curve := btcec.S256() - n := curve.Params().N - - kInv := new(big.Int).ModInverse(k, n) - r, _ := curve.ScalarBaseMult(k.Bytes()) - r.Mod(r, n) - if r.Sign() == 0 { - return nil, nil, fmt.Errorf("calculated R is zero") - } - - e := new(big.Int).SetBytes(hash) - s := new(big.Int).Mul(priv.ToECDSA().D, r) - s.Add(s, e) - s.Mul(s, kInv) - s.Mod(s, n) - if s.Sign() == 0 { - return nil, nil, fmt.Errorf("calculated S is zero") - } - - return r, s, nil -} diff --git a/gmsui/keypairs/secp256k1/keypair.go b/gmsui/keypairs/secp256k1/keypair.go deleted file mode 100644 index fc8cdd9..0000000 --- a/gmsui/keypairs/secp256k1/keypair.go +++ /dev/null @@ -1,209 +0,0 @@ -package secp256k1 - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/sha256" - "errors" - "fmt" - "math/big" - "strings" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/btcsuite/btcd/btcec/v2" - "github.com/btcsuite/btcd/btcutil/hdkeychain" - "github.com/btcsuite/btcd/chaincfg" - "golang.org/x/crypto/blake2b" -) - -var ( - _ cryptography.Keypair = (*Secp256k1Keypair)(nil) -) - -const DefaultSecp256k1DerivationPath = "m/54'/784'/0'/0/0" - -// Secp256k1 Keypair data -type Secp256k1KeypairData struct { - PublicKey []byte - SecretKey []byte -} - -// An Secp256k1 Keypair used for signing transactions. -type Secp256k1Keypair struct { - keypair *Secp256k1KeypairData - cryptography.BaseKeypair -} - -// Create or generate random keypair instance. -func NewSecp256k1Keypair(keypair *Secp256k1KeypairData) (*Secp256k1Keypair, error) { - if keypair == nil { - privateKey, err := btcec.NewPrivateKey() - if err != nil { - return nil, err - } - publicKey := privateKey.PubKey() - keypair = &Secp256k1KeypairData{PublicKey: publicKey.SerializeCompressed(), SecretKey: privateKey.Serialize()} - } - - kp := &Secp256k1Keypair{keypair: keypair} - kp.SetSelf(kp) - return kp, nil -} - -// Get the key scheme of the keypair Secp256k1 -func (k *Secp256k1Keypair) GetKeyScheme() cryptography.SignatureScheme { - return cryptography.Secp256k1Scheme -} - -// The public key for this keypair -func (k *Secp256k1Keypair) GetPublicKey() (cryptography.PublicKey, error) { - return NewSecp256k1PublicKey(k.keypair.PublicKey) -} - -// The Bech32 secret key string for this Secp256k1 keypair -func (k *Secp256k1Keypair) GetSecretKey() (string, error) { - return cryptography.EncodeSuiPrivateKey(k.keypair.SecretKey, k.GetKeyScheme()) -} - -func (k *Secp256k1Keypair) Sign(data []byte) ([]byte, error) { - return k.SignData(data) -} - -// Return the signature for the provided data. -func (k *Secp256k1Keypair) SignData(data []byte) ([]byte, error) { - hexMessage := sha256.Sum256(data) - - privKey, _ := btcec.PrivKeyFromBytes(k.keypair.SecretKey) - - r, s, err := deterministicSign(privKey, hexMessage[:]) - if err != nil { - return nil, err - } - - return append(r.Bytes(), s.Bytes()...), nil -} - -// Generate a new random keypair -func GenerateSecp256k1Keypair() (*Secp256k1Keypair, error) { - return NewSecp256k1Keypair(nil) -} - -// Create a keypair from a raw secret key byte array. -// This method should only be used to recreate a keypair from a previously generated secret key. -// Generating keypairs from a random seed should be done with the {@link Keypair.fromSeed} method. -func FromSecretKey(secretKey []byte, skipValidation bool) (*Secp256k1Keypair, error) { - privKey, _ := btcec.PrivKeyFromBytes(secretKey) - pubKey := privKey.PubKey().SerializeCompressed() - - if !skipValidation { - signData := []byte("sui validation") - hash := blake2b.Sum256(signData) - - r, s, err := ecdsa.Sign(rand.Reader, privKey.ToECDSA(), hash[:]) - if err != nil { - return nil, fmt.Errorf("failed to sign message hash: %v", err) - } - if !ecdsa.Verify(privKey.PubKey().ToECDSA(), hash[:], r, s) { - return nil, errors.New("provided secretKey is invalid") - } - } - - return NewSecp256k1Keypair(&Secp256k1KeypairData{PublicKey: pubKey, SecretKey: secretKey}) -} - -// Generate a keypair from a 32 byte seed. -func FromSeed(seed []byte) (*Secp256k1Keypair, error) { - privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, fmt.Errorf("failed to generate private key: %v", err) - } - - privKey.D = new(big.Int).SetBytes(seed) - pubKey := append(privKey.PublicKey.X.Bytes(), privKey.PublicKey.Y.Bytes()...) - - return NewSecp256k1Keypair(&Secp256k1KeypairData{PublicKey: pubKey, SecretKey: privKey.D.Bytes()}) -} - -// Derive Secp256k1 keypair from mnemonics and path. The mnemonics must be normalized and validated against the english wordlist. -// If path is none, it will default to m/54'/784'/0'/0/0 -// Otherwise the path must be compliant to BIP-32 in form m/54'/784'/{account_index}'/{change_index}/{address_index}. -func DeriveKeypair(mnemonics string, path string) (*Secp256k1Keypair, error) { - if path == "" { - path = DefaultSecp256k1DerivationPath - } - - if !cryptography.IsValidBIP32Path(path) { - return nil, fmt.Errorf("invalid derivation path") - } - seed, err := cryptography.MnemonicToSeed(mnemonics) - if err != nil { - return nil, err - } - - // Derive master key from seed - master, err := hdkeychain.NewMaster(seed, &chaincfg.Params{}) - if err != nil { - return nil, fmt.Errorf("failed to derive master key: %v", err) - } - - // Derive child key using the specified path - child, err := deriveChildKey(master, path) - if err != nil { - return nil, fmt.Errorf("failed to derive child key: %v", err) - } - - privKey, err := child.ECPrivKey() - if err != nil { - return nil, fmt.Errorf("failed to get private key: %v", err) - } - - return FromSecretKey(privKey.Serialize(), false) -} - -func deriveChildKey(masterKey *hdkeychain.ExtendedKey, path string) (*hdkeychain.ExtendedKey, error) { - // Parse BIP32 path - segments := strings.Split(path, "/")[1:] - key := masterKey - for _, part := range segments { - var index uint32 - var err error - if part[len(part)-1] == '\'' { - index, err = parseHardenedIndex(part[:len(part)-1]) - } else { - index, err = parseIndex(part) - } - if err != nil { - return nil, err - } - key, err = key.Derive(index) - if err != nil { - return nil, err - } - } - return key, nil -} - -// Helper function to parse a normal index -func parseIndex(part string) (uint32, error) { - var index uint32 - _, err := fmt.Sscanf(part, "%d", &index) - return index, err -} - -// Helper function to parse a hardened index -func parseHardenedIndex(part string) (uint32, error) { - index, err := parseIndex(part) - if err != nil { - return 0, err - } - return index + hdkeychain.HardenedKeyStart, nil -} - -func (kp *Secp256k1Keypair) PublicKey() []byte { - return kp.keypair.PublicKey -} - -func (kp *Secp256k1Keypair) SecretKey() []byte { - return kp.keypair.SecretKey -} diff --git a/gmsui/keypairs/secp256k1/publickey.go b/gmsui/keypairs/secp256k1/publickey.go deleted file mode 100644 index 7cb8c92..0000000 --- a/gmsui/keypairs/secp256k1/publickey.go +++ /dev/null @@ -1,88 +0,0 @@ -package secp256k1 - -import ( - "bytes" - "crypto/ecdsa" - "crypto/sha256" - "fmt" - "math/big" - - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/btcsuite/btcd/btcec/v2" -) - -var ( - _ cryptography.PublicKey = (*Secp256k1PublicKey)(nil) -) - -// A Secp256k1 public key -type Secp256k1PublicKey struct { - data []byte - cryptography.BasePublicKey -} - -// Create a new Secp256k1PublicKey object -func NewSecp256k1PublicKey[T string | []byte](value T) (publicKey *Secp256k1PublicKey, err error) { - publicKey = new(Secp256k1PublicKey) - switch v := any(value).(type) { - case string: - publicKey.data, err = b64.FromBase64(v) - if err != nil { - return nil, err - } - case []byte: - publicKey.data = v - } - if len(publicKey.data) != cryptography.Secp256k1PublicKeySize { - return nil, fmt.Errorf("invalid public key input, expected %d bytes, got %d", cryptography.Secp256k1PublicKeySize, len(publicKey.data)) - } - publicKey.SetSelf(publicKey) - return -} - -// Checks if two Secp256k1 public keys are equal -func (k *Secp256k1PublicKey) Equals(publicKey cryptography.PublicKey) bool { - return k.BasePublicKey.Equals(publicKey) -} - -// Return the byte array representation of the Secp256k1 public key -func (k *Secp256k1PublicKey) ToRawBytes() []byte { - return k.data -} - -// Return the Sui address associated with this Secp256k1 public key -func (k *Secp256k1PublicKey) Flag() uint8 { - return cryptography.SignatureSchemeToFlag[cryptography.Secp256k1Scheme] -} - -// Verifies that the signature is valid for for the provided message -func (k *Secp256k1PublicKey) Verify(message []byte, signature cryptography.SerializedSignature) (bool, error) { - parsed, err := cryptography.ParseSerializedSignature(signature) - if err != nil { - return false, err - } - - if parsed.SignatureScheme != cryptography.Secp256k1Scheme { - return false, fmt.Errorf("invalid signature scheme") - } - - if !bytes.Equal(k.ToRawBytes(), parsed.PubKey) { - return false, fmt.Errorf("signature does not match public key") - } - - // Parse the signature into r and s components - r := new(big.Int).SetBytes(parsed.Signature[:32]) - s := new(big.Int).SetBytes(parsed.Signature[32:]) - - pubKey, err := btcec.ParsePubKey(k.ToRawBytes()) - if err != nil { - return false, err - } - - // Verify the signature - hash := sha256.Sum256(message) - verified := ecdsa.Verify(pubKey.ToECDSA(), hash[:], r, s) - - return verified, nil -} diff --git a/gmsui/keypairs/secp256k1/secp256k1_test.go b/gmsui/keypairs/secp256k1/secp256k1_test.go deleted file mode 100644 index 7772788..0000000 --- a/gmsui/keypairs/secp256k1/secp256k1_test.go +++ /dev/null @@ -1,184 +0,0 @@ -package secp256k1_test - -import ( - "crypto/rand" - "reflect" - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/W3Tools/go-modules/gmsui/keypairs/secp256k1" - "github.com/tyler-smith/go-bip39" -) - -func TestGenerateAndVerifySecp256k1Keypair(t *testing.T) { - keypair, err := secp256k1.GenerateSecp256k1Keypair() - if err != nil { - t.Fatalf("unable to generate Secp256k1 keypair, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), cryptography.Secp256k1PublicKeySize) { - t.Errorf("expected public key size to be %d, but got %d", cryptography.Secp256k1PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), 32) { - t.Errorf("expected private key size to be %d, but got %d", 32, len(keypair.SecretKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Secp256k1Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Secp256k1Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("unable to get Secp256k1 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Secp256k1Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Secp256k1Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Secp256k1Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialize signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) - - t.Run("SignPersonalMessage", func(t *testing.T) { - signature, err := keypair.SignPersonalMessage(message) - if err != nil { - t.Fatalf("unable to sign personal message, msg: %v", err) - } - - valid, err := publicKey.VerifyPersonalMessage(message, signature.Signature) - if err != nil { - t.Fatalf("unable to verify personal message, msg: %v", err) - } - - if !valid { - t.Errorf("signature verification failed") - } - }) -} - -func TestFromSecretKeyAndVerifySecp256k1(t *testing.T) { - secretKey := make([]byte, 32) - _, err := rand.Read(secretKey) - if err != nil { - t.Fatalf("error generating random secret key: %v", err) - } - - keypair, err := secp256k1.FromSecretKey(secretKey, false) - if err != nil { - t.Fatalf("unable to create Secp256k1 keypair from secret key, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), 33) { - t.Errorf("expected public key size to be %d, but got %d", 33, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), 32) { - t.Errorf("expected private key size to be %d, but got %d", 32, len(keypair.SecretKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Secp256k1Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Secp256k1Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("unable to get Secp256k1 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Secp256k1Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Secp256k1Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Secp256k1Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialize signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) -} - -func TestDeriveSecp256k1KeypairFromMnemonic(t *testing.T) { - entropy, err := bip39.NewEntropy(128) - if err != nil { - t.Fatalf("failed to new entropy, msg: %v", err) - } - - mnemonic, err := bip39.NewMnemonic(entropy) - if err != nil { - t.Fatalf("unable to generate mnemonic, msg: %v", err) - } - - keypair, err := secp256k1.DeriveKeypair(mnemonic, secp256k1.DefaultSecp256k1DerivationPath) - if err != nil { - t.Fatalf("unable to derive Secp256k1 keypair, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), 33) { - t.Errorf("expected public key size to be %d, but got %d", 33, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), 32) { - t.Errorf("expected private key size to be %d, but got %d", 32, len(keypair.SecretKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Secp256k1Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Secp256k1Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("unable to get Secp256k1 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Secp256k1Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Secp256k1Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Secp256k1Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialize signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) -} diff --git a/gmsui/keypairs/secp256r1/k.go b/gmsui/keypairs/secp256r1/k.go deleted file mode 100644 index ea64225..0000000 --- a/gmsui/keypairs/secp256r1/k.go +++ /dev/null @@ -1,103 +0,0 @@ -package secp256r1 - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/hmac" - "crypto/sha256" - "fmt" - "math/big" -) - -// DeterministicSign generates deterministic ECDSA signature using RFC 6979 for secp256r1 curve -func deterministicSign(priv *ecdsa.PrivateKey, hash []byte) (*big.Int, *big.Int, error) { - curve := elliptic.P256() - k := deterministicK(priv.D, hash) - r, s, err := signWithK(priv, hash, k) - if err != nil { - return nil, nil, err - } - - // Ensure s is in the lower half of the order - halfOrder := new(big.Int).Rsh(curve.Params().N, 1) - if s.Cmp(halfOrder) > 0 { - s.Sub(curve.Params().N, s) - } - - return r, s, nil -} - -// RFC 6979 deterministic K generation -func deterministicK(priv *big.Int, hash []byte) *big.Int { - curve := elliptic.P256() - q := curve.Params().N - - v := make([]byte, 32) - k := make([]byte, 32) - for i := range v { - v[i] = 0x01 - } - - hm := hmac.New(sha256.New, k) - hm.Write(v) - hm.Write([]byte{0x00}) - hm.Write(priv.Bytes()) - hm.Write(hash) - k = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - hm.Write([]byte{0x01}) - hm.Write(priv.Bytes()) - hm.Write(hash) - k = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - - for { - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - kInt := new(big.Int).SetBytes(v) - if kInt.Sign() > 0 && kInt.Cmp(q) < 0 { - return kInt - } - hm = hmac.New(sha256.New, k) - hm.Write(v) - hm.Write([]byte{0x00}) - k = hm.Sum(nil) - - hm = hmac.New(sha256.New, k) - hm.Write(v) - v = hm.Sum(nil) - } -} - -func signWithK(priv *ecdsa.PrivateKey, hash []byte, k *big.Int) (*big.Int, *big.Int, error) { - curve := priv.Curve - n := curve.Params().N - - kInv := new(big.Int).ModInverse(k, n) - r, _ := curve.ScalarBaseMult(k.Bytes()) - r.Mod(r, n) - if r.Sign() == 0 { - return nil, nil, fmt.Errorf("calculated R is zero") - } - - e := new(big.Int).SetBytes(hash) - s := new(big.Int).Mul(priv.D, r) - s.Add(s, e) - s.Mul(s, kInv) - s.Mod(s, n) - if s.Sign() == 0 { - return nil, nil, fmt.Errorf("calculated S is zero") - } - - return r, s, nil -} diff --git a/gmsui/keypairs/secp256r1/keypair.go b/gmsui/keypairs/secp256r1/keypair.go deleted file mode 100644 index 90169e1..0000000 --- a/gmsui/keypairs/secp256r1/keypair.go +++ /dev/null @@ -1,193 +0,0 @@ -package secp256r1 - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/rand" - "crypto/sha256" - "errors" - "fmt" - "math/big" - "strconv" - "strings" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/tyler-smith/go-bip32" - "golang.org/x/crypto/blake2b" -) - -var ( - _ cryptography.Keypair = (*Secp256r1Keypair)(nil) -) - -const DefaultSecp256r1DerivationPath = "m/74'/784'/0'/0/0" - -// Secp256r1 Keypair data -type Secp256r1KeypairData struct { - PublicKey []byte - SecretKey []byte -} - -// An Secp256r1 Keypair used for signing transactions. -type Secp256r1Keypair struct { - keypair *Secp256r1KeypairData - cryptography.BaseKeypair -} - -// Create or generate random keypair instance. -func NewSecp256r1Keypair(keypair *Secp256r1KeypairData) (*Secp256r1Keypair, error) { - if keypair == nil { - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) - if err != nil { - return nil, err - } - publicKey := elliptic.MarshalCompressed(elliptic.P256(), privateKey.PublicKey.X, privateKey.PublicKey.Y) - keypair = &Secp256r1KeypairData{PublicKey: publicKey, SecretKey: privateKey.D.Bytes()} - } - - kp := &Secp256r1Keypair{keypair: keypair} - kp.SetSelf(kp) - return kp, nil -} - -// Get the key scheme of the keypair Secp256r1 -func (k *Secp256r1Keypair) GetKeyScheme() cryptography.SignatureScheme { - return cryptography.Secp256r1Scheme -} - -// The public key for this keypair -func (k *Secp256r1Keypair) GetPublicKey() (cryptography.PublicKey, error) { - return NewSecp256r1PublicKey(k.keypair.PublicKey) -} - -// The Bech32 secret key string for this Secp256r1 keypair -func (k *Secp256r1Keypair) GetSecretKey() (string, error) { - return cryptography.EncodeSuiPrivateKey(k.keypair.SecretKey, k.GetKeyScheme()) -} - -func (k *Secp256r1Keypair) Sign(data []byte) ([]byte, error) { - return k.SignData(data) -} - -// Return the signature for the provided data. -func (k *Secp256r1Keypair) SignData(data []byte) ([]byte, error) { - hexMessage := sha256.Sum256(data) - - privKey := new(ecdsa.PrivateKey) - privKey.PublicKey.Curve = elliptic.P256() - privKey.D = new(big.Int).SetBytes(k.keypair.SecretKey) - privKey.PublicKey.X, privKey.PublicKey.Y = privKey.PublicKey.Curve.ScalarBaseMult(privKey.D.Bytes()) - r, s, err := deterministicSign(privKey, hexMessage[:]) - if err != nil { - return nil, err - } - - return append(r.Bytes(), s.Bytes()...), nil -} - -// Generate a new random keypair -func GenerateSecp256r1Keypair() (*Secp256r1Keypair, error) { - return NewSecp256r1Keypair(nil) -} - -// Create a keypair from a raw secret key byte array. -// This method should only be used to recreate a keypair from a previously generated secret key. -// Generating keypairs from a random seed should be done with the {@link Keypair.fromSeed} method. -func FromSecretKey(secretKey []byte, skipValidation bool) (*Secp256r1Keypair, error) { - privateKey := new(ecdsa.PrivateKey) - privateKey.PublicKey.Curve = elliptic.P256() - privateKey.D = new(big.Int).SetBytes(secretKey) - privateKey.PublicKey.X, privateKey.PublicKey.Y = privateKey.PublicKey.Curve.ScalarBaseMult(privateKey.D.Bytes()) - publicKey := elliptic.MarshalCompressed(privateKey.PublicKey.Curve, privateKey.PublicKey.X, privateKey.PublicKey.Y) - - if !skipValidation { - signData := []byte("sui validation") - hash := blake2b.Sum256(signData) - r, s, err := ecdsa.Sign(rand.Reader, privateKey, hash[:]) - if err != nil { - return nil, err - } - - if !ecdsa.Verify(&privateKey.PublicKey, hash[:], r, s) { - return nil, errors.New("provided secretKey is invalid") - } - } - return NewSecp256r1Keypair(&Secp256r1KeypairData{PublicKey: publicKey, SecretKey: secretKey}) -} - -// Generate a keypair from a 32 byte seed. -func FromSeed(seed []byte) (*Secp256r1Keypair, error) { - privateKey, err := ecdsa.GenerateKey(elliptic.P256(), strings.NewReader(string(seed))) - if err != nil { - return nil, err - } - publicKey := elliptic.MarshalCompressed(privateKey.PublicKey.Curve, privateKey.PublicKey.X, privateKey.PublicKey.Y) - secretKey := privateKey.D.Bytes() - - return NewSecp256r1Keypair(&Secp256r1KeypairData{PublicKey: publicKey, SecretKey: secretKey}) -} - -// Derive Secp256r1 keypair from mnemonics and path. The mnemonics must be normalized and validated against the english wordlist. -// If path is none, it will default to m/74'/784'/0'/0/0 -// Otherwise the path must be compliant to BIP-32 in form m/74'/784'/{account_index}'/{change_index}/{address_index}. -func DeriveKeypair(mnemonics string, path string) (*Secp256r1Keypair, error) { - if path == "" { - path = DefaultSecp256r1DerivationPath - } - - if !cryptography.IsValidBIP32Path(path) { - return nil, fmt.Errorf("invalid derivation path") - } - seed, err := cryptography.MnemonicToSeed(mnemonics) - if err != nil { - return nil, err - } - - masterKey, err := bip32.NewMasterKey(seed) - if err != nil { - return nil, err - } - - key, err := deriveChildKeyFromPath(masterKey, path) - if err != nil { - return nil, err - } - return FromSecretKey(key.Key, false) -} - -func deriveChildKeyFromPath(masterKey *bip32.Key, path string) (*bip32.Key, error) { - segments := strings.Split(path, "/")[1:] - key := masterKey - - for _, segment := range segments { - if strings.HasSuffix(segment, "'") { - index, err := strconv.Atoi(strings.TrimSuffix(segment, "'")) - if err != nil { - return nil, err - } - key, err = key.NewChildKey(bip32.FirstHardenedChild + uint32(index)) - if err != nil { - return nil, err - } - } else { - index, err := strconv.Atoi(segment) - if err != nil { - return nil, err - } - key, err = key.NewChildKey(uint32(index)) - if err != nil { - return nil, err - } - } - } - - return key, nil -} - -func (kp *Secp256r1Keypair) PublicKey() []byte { - return kp.keypair.PublicKey -} - -func (kp *Secp256r1Keypair) SecretKey() []byte { - return kp.keypair.SecretKey -} diff --git a/gmsui/keypairs/secp256r1/publickey.go b/gmsui/keypairs/secp256r1/publickey.go deleted file mode 100644 index 485f55d..0000000 --- a/gmsui/keypairs/secp256r1/publickey.go +++ /dev/null @@ -1,91 +0,0 @@ -package secp256r1 - -import ( - "crypto/ecdsa" - "crypto/elliptic" - "crypto/sha256" - "errors" - "fmt" - "math/big" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/W3Tools/go-modules/gmsui/cryptography" -) - -var ( - _ cryptography.PublicKey = (*Secp256r1PublicKey)(nil) -) - -// A Secp256r1 public key -type Secp256r1PublicKey struct { - data []byte - cryptography.BasePublicKey -} - -// Create a new Secp256r1PublicKey object -func NewSecp256r1PublicKey[T string | []byte](value T) (publicKey *Secp256r1PublicKey, err error) { - publicKey = new(Secp256r1PublicKey) - switch v := any(value).(type) { - case string: - publicKey.data, err = b64.FromBase64(v) - if err != nil { - return nil, err - } - case []byte: - publicKey.data = v - } - if len(publicKey.data) != cryptography.Secp256r1PublicKeySize { - return nil, fmt.Errorf("invalid public key input, expected %d bytes, got %d", cryptography.Secp256r1PublicKeySize, len(publicKey.data)) - } - publicKey.SetSelf(publicKey) - return -} - -// Checks if two Secp256r1 public keys are equal -func (k *Secp256r1PublicKey) Equals(publicKey cryptography.PublicKey) bool { - return k.BasePublicKey.Equals(publicKey) -} - -// Return the byte array representation of the Secp256r1 public key -func (k *Secp256r1PublicKey) ToRawBytes() []byte { - return k.data -} - -// Return the Sui address associated with this Secp256r1 public key -func (k *Secp256r1PublicKey) Flag() uint8 { - return cryptography.SignatureSchemeToFlag[cryptography.Secp256r1Scheme] -} - -// Verifies that the signature is valid for for the provided message -func (k *Secp256r1PublicKey) Verify(message []byte, signature cryptography.SerializedSignature) (bool, error) { - parsed, err := cryptography.ParseSerializedSignature(signature) - if err != nil { - return false, err - } - - if parsed.SignatureScheme != cryptography.Secp256r1Scheme { - return false, fmt.Errorf("invalid signature scheme") - } - - if !gm.BytesEqual(k.ToRawBytes(), parsed.PubKey) { - return false, fmt.Errorf("signature does not match public key") - } - - x, y := elliptic.UnmarshalCompressed(elliptic.P256(), k.ToRawBytes()) - if x == nil || y == nil { - return false, errors.New("error unmarshaling public key") - } - - curve := elliptic.P256() - pubKey := ecdsa.PublicKey{Curve: curve, X: x, Y: y} - - // Parse the signature into r and s components - r := new(big.Int).SetBytes(parsed.Signature[:32]) - s := new(big.Int).SetBytes(parsed.Signature[32:]) - - // Verify the signature - hash := sha256.Sum256(message) - valid := ecdsa.Verify(&pubKey, hash[:], r, s) - return valid, nil -} diff --git a/gmsui/keypairs/secp256r1/secp256r1_test.go b/gmsui/keypairs/secp256r1/secp256r1_test.go deleted file mode 100644 index 71115d6..0000000 --- a/gmsui/keypairs/secp256r1/secp256r1_test.go +++ /dev/null @@ -1,184 +0,0 @@ -package secp256r1_test - -import ( - "crypto/rand" - "reflect" - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/W3Tools/go-modules/gmsui/keypairs/secp256r1" - "github.com/tyler-smith/go-bip39" -) - -func TestGenerateAndVerifySecp256r1Keypair(t *testing.T) { - keypair, err := secp256r1.GenerateSecp256r1Keypair() - if err != nil { - t.Fatalf("unable to generate Secp256r1 keypair, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), cryptography.Secp256r1PublicKeySize) { - t.Errorf("expected public key size to be %d, but got %d", cryptography.Secp256r1PublicKeySize, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), 32) { - t.Errorf("expected private key size to be %d, but got %d", 32, len(keypair.SecretKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Secp256r1Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Secp256r1Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("unable to get Secp256r1 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Secp256r1Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Secp256r1Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Secp256r1Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialize signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) - - t.Run("SignPersonalMessage", func(t *testing.T) { - signature, err := keypair.SignPersonalMessage(message) - if err != nil { - t.Fatalf("unable to sign personal message, msg: %v", err) - } - - valid, err := publicKey.VerifyPersonalMessage(message, signature.Signature) - if err != nil { - t.Fatalf("unable to verify personal message, msg: %v", err) - } - - if !valid { - t.Errorf("signature verification failed") - } - }) -} - -func TestFromSecretKeyAndVerifySecp256r1(t *testing.T) { - secretKey := make([]byte, 32) - _, err := rand.Read(secretKey) - if err != nil { - t.Fatalf("error generating random secret key: %v", err) - } - - keypair, err := secp256r1.FromSecretKey(secretKey, false) - if err != nil { - t.Fatalf("unable to create Secp256r1 keypair from secret key, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), 33) { - t.Errorf("expected public key size to be %d, but got %d", 33, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), 32) { - t.Errorf("expected private key size to be %d, but got %d", 32, len(keypair.SecretKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Secp256r1Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Secp256r1Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("unable to get Secp256r1 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Secp256r1Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Secp256r1Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Secp256r1Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialize signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) -} - -func TestDeriveSecp256r1KeypairFromMnemonic(t *testing.T) { - entropy, err := bip39.NewEntropy(128) - if err != nil { - t.Fatalf("failed to new entropy, msg: %v", err) - } - - mnemonic, err := bip39.NewMnemonic(entropy) - if err != nil { - t.Fatalf("unable to generate mnemonic, msg: %v", err) - } - - keypair, err := secp256r1.DeriveKeypair(mnemonic, secp256r1.DefaultSecp256r1DerivationPath) - if err != nil { - t.Fatalf("unable to derive Secp256r1 keypair, msg: %v", err) - } - - if !reflect.DeepEqual(len(keypair.PublicKey()), 33) { - t.Errorf("expected public key size to be %d, but got %d", 33, len(keypair.PublicKey())) - } - - if !reflect.DeepEqual(len(keypair.SecretKey()), 32) { - t.Errorf("expected private key size to be %d, but got %d", 32, len(keypair.SecretKey())) - } - - if !reflect.DeepEqual(keypair.GetKeyScheme(), cryptography.Secp256r1Scheme) { - t.Errorf("expected key scheme %v, but got %v", cryptography.Secp256r1Scheme, keypair.GetKeyScheme()) - } - - publicKey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("unable to get Secp256r1 public key, msg: %v", err) - } - - if !reflect.DeepEqual(publicKey.Flag(), cryptography.SignatureSchemeToFlag[cryptography.Secp256r1Scheme]) { - t.Errorf("expected public key flag %v, but got %v", cryptography.SignatureSchemeToFlag[cryptography.Secp256r1Scheme], publicKey.Flag()) - } - - message := []byte("Hello, Go Modules!") - - t.Run("SignMessage", func(t *testing.T) { - signature, _ := keypair.SignData(message) - - serializedSignature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{SignatureScheme: cryptography.Secp256r1Scheme, PublicKey: publicKey, Signature: signature}) - if err != nil { - t.Fatalf("unable to serialize signature, msg: %v", err) - } - - valid, err := publicKey.Verify(message, serializedSignature) - if err != nil { - t.Fatalf("unable to verify signature, msg: %v", err) - } - if !valid { - t.Errorf("signature verification failed") - } - }) -} diff --git a/gmsui/move_types.go b/gmsui/move_types.go deleted file mode 100644 index 11939b9..0000000 --- a/gmsui/move_types.go +++ /dev/null @@ -1,35 +0,0 @@ -package gmsui - -type SuiMoveId struct { - Id string `json:"id"` -} - -type SuiMoveTable struct { - Fields SuiMoveTableFields `json:"fields"` - Type string `json:"type"` -} - -type SuiMoveTableFields struct { - Id SuiMoveId `json:"id"` - Size string `json:"size"` -} - -type SuiMoveString struct { - Type string `json:"type"` - Fields SuiMoveStringFields `json:"fields"` -} - -type SuiMoveStringFields struct { - Name string `json:"name"` -} - -type SuiMoveDynamicField[TypeFields any, TypeName any] struct { - Id SuiMoveId `json:"id"` - Name TypeName `json:"name"` - Value SuiMoveDynamicFieldValue[TypeFields] `json:"value"` -} - -type SuiMoveDynamicFieldValue[TypeFields any] struct { - Fields TypeFields `json:"fields"` - Type string `json:"type"` -} diff --git a/gmsui/multisig/multisig_test.go b/gmsui/multisig/multisig_test.go deleted file mode 100644 index 75a94a1..0000000 --- a/gmsui/multisig/multisig_test.go +++ /dev/null @@ -1,167 +0,0 @@ -package multisig_test - -import ( - "fmt" - "strings" - "testing" - - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/W3Tools/go-modules/gmsui/keypairs/ed25519" - "github.com/W3Tools/go-modules/gmsui/multisig" -) - -var ( - keypair0 *ed25519.Ed25519PublicKey - keypair1 *ed25519.Ed25519PublicKey - keypair2 *ed25519.Ed25519PublicKey - keypair3 *ed25519.Ed25519PublicKey - multisigPublicKey *multisig.MultiSigPublicKey -) - -func init() { - var err error - keypair0, err = ed25519.NewEd25519PublicKey("RIIlNygk0BhV4AyP1Ntwa9jeiz9MULhjODIEvWSJ0gk=") - if err != nil { - panic(fmt.Sprintf("new ed25519 public key err, msg: %v", err)) - } - fmt.Printf(`keypair0 -> address: %v - flag: %v - toRawBytes: %v - toBase64: %v - toSuiBytes: %v - toSuiPublicKey: %v`, - keypair0.ToSuiAddress(), keypair0.Flag(), keypair0.ToRawBytes(), keypair0.ToBase64(), keypair0.ToSuiBytes(), keypair0.ToSuiPublicKey()) - fmt.Println("") - - keypair1, err = ed25519.NewEd25519PublicKey("H8gKV7gmH1T7YmAfwp5FNPWas0K0AFY2OBQ+0uOY57E=") - if err != nil { - panic(fmt.Sprintf("new ed25519 public key err, msg: %v", err)) - } - fmt.Printf(`keypair1 -> address: %v - flag: %v - toRawBytes: %v - toBase64: %v - toSuiBytes: %v - toSuiPublicKey: %v`, - keypair1.ToSuiAddress(), keypair1.Flag(), keypair1.ToRawBytes(), keypair1.ToBase64(), keypair1.ToSuiBytes(), keypair1.ToSuiPublicKey()) - fmt.Println("") - - keypair2, err = ed25519.NewEd25519PublicKey("hGxdp+5Molt7N1VRSvp5eExYViexZzISsYW51okg+7w=") - if err != nil { - panic(fmt.Sprintf("new ed25519 public key err, msg: %v", err)) - } - fmt.Printf(`keypair2 -> address: %v - flag: %v - toRawBytes: %v - toBase64: %v - toSuiBytes: %v - toSuiPublicKey: %v`, - keypair2.ToSuiAddress(), keypair2.Flag(), keypair2.ToRawBytes(), keypair2.ToBase64(), keypair2.ToSuiBytes(), keypair2.ToSuiPublicKey()) - fmt.Println("") - - keypair3, err = ed25519.NewEd25519PublicKey("bkIKm0xtKG3cPNZsFnIy+HDmBp8kLQspBu1rWqbmRbE=") - if err != nil { - panic(fmt.Sprintf("new ed25519 public key err, msg: %v", err)) - } - fmt.Printf(`keypair3 -> address: %v - flag: %v - toRawBytes: %v - toBase64: %v - toSuiBytes: %v - toSuiPublicKey: %v`, - keypair3.ToSuiAddress(), keypair3.Flag(), keypair3.ToRawBytes(), keypair3.ToBase64(), keypair3.ToSuiBytes(), keypair3.ToSuiPublicKey()) - fmt.Println("") - - multisigPublicKey, err = new(multisig.MultiSigPublicKey).FromPublicKeys( - []multisig.PublicKeyWeightPair{ - { - PublicKey: keypair0, - Weight: 1, - }, - { - PublicKey: keypair1, - Weight: 1, - }, - { - PublicKey: keypair2, - Weight: 1, - }, - { - PublicKey: keypair3, - Weight: 1, - }, - }, - 3, - ) - if err != nil { - panic(fmt.Sprintf("new multisig public key from public keys error, msg: %v", err)) - } - - fmt.Printf(`multisig -> address: %v - flag: %v - threshold: %v - base64: %v - raw bytes: %v - sui bytes: %v - sui public key: %v`, - multisigPublicKey.ToSuiAddress(), multisigPublicKey.Flag(), multisigPublicKey.GetThreshold(), multisigPublicKey.ToBase64(), multisigPublicKey.ToRawBytes(), multisigPublicKey.ToSuiBytes(), multisigPublicKey.ToSuiPublicKey()) - fmt.Println("") - fmt.Printf("%s\n", strings.Repeat("-", 150)) -} - -func TestCombinePartialSignatures(t *testing.T) { - signature0 := "AJe72Zj/9Ooyv8mHpZjzKXEF6NLbeQKr/pfWDPfCi7yofyY6s0WRb/z+/VqEfg/GhRpmI7dHEARGjXBOxGBTSghEgiU3KCTQGFXgDI/U23Br2N6LP0xQuGM4MgS9ZInSCQ==" - signature2 := "AKdszUyALLWYUz7XK9Hm6FYJ0d3quIZ39wSx1GUUCCI4HNuNbTer+3v0gf6+dFaWs+6JySl87OJbZjYVmJaqWAuEbF2n7kyiW3s3VVFK+nl4TFhWJ7FnMhKxhbnWiSD7vA==" - signature3 := "AN/ugnW8oV1qLZptKuGx7G+yH2bhtTeK7OPe1wj0SHvYp74T/3ccWhaA0+Qzy0k5eC1EeRkndGgjGp7XA0LZrQxuQgqbTG0obdw81mwWcjL4cOYGnyQtCykG7WtapuZFsQ==" - - data, err := multisigPublicKey.CombinePartialSignatures([]cryptography.SerializedSignature{signature0, signature3, signature2}) - if err != nil { - t.Fatalf("combine partial signature err, msg: %v", err) - } - fmt.Printf("combinePartialSignatures: %v\n", data) - - txb := "AAABACAsFID88X4wXT/z/MbNiECsiW73FJO3HyyKXhySS1OBZgIEAdwCoRzrCwYAAAAKAQAIAggMAxQVBCkCBSsVB0BdCJ0BQArdAQgM5QFJDa4CAgADAQgBCwEMAAAIAAECBAADAQIAAAUAAQAACgIBAAEGAAMAAgkFAQEIAwQBBwgCAAIHCAADAQgBAQgAAQkAAQMHQ291bnRlcglUeENvbnRleHQDVUlEBWhlbGxvAmlkBGluaXQDbmV3Bm51bWJlcgZvYmplY3QMc2hhcmVfb2JqZWN0BXRvdWNoCHRyYW5zZmVyCnR4X2NvbnRleHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAICBAgBBwMAAAAAAQYLABECBgAAAAAAAAAAEgA4AAIBAQAABhEKAQwCCwEGAAAAAAAAAAAhBAgGAQAAAAAAAAAMAgoAEAAUCwIWCwAPABUCAAEAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQIAAAEAACwUgPzxfjBdP/P8xs2IQKyJbvcUk7cfLIpeHJJLU4FmAbLXqgfMag7gldu5IkqvV+goaqyaVbeXAVPw2SgCGVoVUJ42DwAAAAAg2JaDc2hq9u0qw503zPRRv39t6ksRcSwKKV8Bom3GtwIsFID88X4wXT/z/MbNiECsiW73FJO3HyyKXhySS1OBZu4CAAAAAAAAgJaYAAAAAAAA" - b64txb, err := b64.FromBase64(txb) - if err != nil { - t.Fatalf("from base64 err, msg: %v", err) - } - - pass, err := multisigPublicKey.VerifyTransactionBlock(b64txb, data) - if err != nil { - t.Fatalf("verify transaction block err, msg: %v", err) - } - fmt.Printf("pass: %v\n", pass) -} - -func TestVerifyPersonalMessage(t *testing.T) { - message := []byte("hello world") - - signature1 := "AH89ba1KO7KoMQfjGJOkxKaI80GseFWQ/GKTF7pV0hc4LpAnHZ0lfCQWavvTL5v6DaIzTBYlpD9V7kFesCr80whEgiU3KCTQGFXgDI/U23Br2N6LP0xQuGM4MgS9ZInSCQ==" - data, err := multisigPublicKey.CombinePartialSignatures([]cryptography.SerializedSignature{signature1}) - if err != nil { - t.Fatalf("combine partial signature err, msg: %v", err) - } - fmt.Printf("combine partial signatures: %v\n", data) - - pass, err := multisigPublicKey.VerifyPersonalMessage(message, data) - if err != nil { - t.Fatalf("verify personal message err, msg: %v", err) - } - fmt.Printf("pass: %v\n", pass) -} - -func TestVerifyTransactionBlock(t *testing.T) { - signature := "AH89ba1KO7KoMQfjGJOkxKaI80GseFWQ/GKTF7pV0hc4LpAnHZ0lfCQWavvTL5v6DaIzTBYlpD9V7kFesCr80whEgiU3KCTQGFXgDI/U23Br2N6LP0xQuGM4MgS9ZInSCQ==" - txb := "AAABACAsFID88X4wXT/z/MbNiECsiW73FJO3HyyKXhySS1OBZgIEAdwCoRzrCwYAAAAKAQAIAggMAxQVBCkCBSsVB0BdCJ0BQArdAQgM5QFJDa4CAgADAQgBCwEMAAAIAAECBAADAQIAAAUAAQAACgIBAAEGAAMAAgkFAQEIAwQBBwgCAAIHCAADAQgBAQgAAQkAAQMHQ291bnRlcglUeENvbnRleHQDVUlEBWhlbGxvAmlkBGluaXQDbmV3Bm51bWJlcgZvYmplY3QMc2hhcmVfb2JqZWN0BXRvdWNoCHRyYW5zZmVyCnR4X2NvbnRleHQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAICBAgBBwMAAAAAAQYLABECBgAAAAAAAAAAEgA4AAIBAQAABhEKAQwCCwEGAAAAAAAAAAAhBAgGAQAAAAAAAAAMAgoAEAAUCwIWCwAPABUCAAEAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQIAAAEAACwUgPzxfjBdP/P8xs2IQKyJbvcUk7cfLIpeHJJLU4FmAbLXqgfMag7gldu5IkqvV+goaqyaVbeXAVPw2SgCGVoVUJ42DwAAAAAg2JaDc2hq9u0qw503zPRRv39t6ksRcSwKKV8Bom3GtwIsFID88X4wXT/z/MbNiECsiW73FJO3HyyKXhySS1OBZu4CAAAAAAAAgJaYAAAAAAAA" - - b64txb, err := b64.FromBase64(txb) - if err != nil { - t.Fatalf("from base64 err, msg: %v", err) - } - pass, err := keypair0.VerifyTransactionBlock(b64txb, signature) - if err != nil { - t.Fatalf("verify transaction block err, msg: %v", err) - } - fmt.Printf("pass: %v\n", pass) -} diff --git a/gmsui/multisig/publickey.go b/gmsui/multisig/publickey.go deleted file mode 100644 index 651cd48..0000000 --- a/gmsui/multisig/publickey.go +++ /dev/null @@ -1,366 +0,0 @@ -package multisig - -import ( - "bytes" - "encoding/hex" - "fmt" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/b64" - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/W3Tools/go-modules/gmsui/utils" - "github.com/W3Tools/go-modules/gmsui/verify" - "github.com/fardream/go-bcs/bcs" - "golang.org/x/crypto/blake2b" -) - -const ( - MaxSignerInMultisig = 10 - MinSignerInMultisig = 1 -) - -var ( - _ cryptography.PublicKey = (*MultiSigPublicKey)(nil) -) - -type StringPubKeyEnumWeightPair struct { - PubKey string `json:"pubKey"` - Weight uint8 `json:"weight"` -} - -type ParsedPartialMultiSigSignature struct { - SignatureScheme cryptography.SignatureScheme - Signature []byte - PublicKey cryptography.PublicKey - Weight uint8 -} - -type MultiSigPublicKey struct { - rawBytes []byte - multisigPublicKey cryptography.MultiSigPublicKeyStruct - publicKeys []cryptography.MultiSigPublicKeyPair - cryptography.BasePublicKey -} - -type PublicKeyWeightPair struct { - PublicKey cryptography.PublicKey - Weight uint8 -} - -func NewMultiSigPublicKey[T string | []byte | cryptography.MultiSigPublicKeyStruct](value T) (multisig *MultiSigPublicKey, err error) { - multisig = new(MultiSigPublicKey) - switch v := any(value).(type) { - case string: - rawBytes, err := b64.FromBase64(v) - if err != nil { - return nil, err - } - multisig.rawBytes = rawBytes - - multisigPublicKeyStruct := new(cryptography.MultiSigPublicKeyStruct) - _, err = bcs.Unmarshal(multisig.rawBytes, &multisigPublicKeyStruct) - if err != nil { - return nil, err - } - multisig.multisigPublicKey = *multisigPublicKeyStruct - case []byte: - multisig.rawBytes = v - - multisigPublicKeyStruct := new(cryptography.MultiSigPublicKeyStruct) - _, err = bcs.Unmarshal(multisig.rawBytes, &multisigPublicKeyStruct) - if err != nil { - return nil, err - } - multisig.multisigPublicKey = *multisigPublicKeyStruct - case cryptography.MultiSigPublicKeyStruct: - multisig.multisigPublicKey = v - - rawBytes, err := bcs.Marshal(multisig.multisigPublicKey) - if err != nil { - return nil, err - } - multisig.rawBytes = rawBytes - } - if multisig.multisigPublicKey.Threshold < 1 { - return nil, fmt.Errorf("invalid threshold") - } - - seenPublicKeys := make(map[string]bool) - multisig.publicKeys, err = gm.Map(multisig.multisigPublicKey.PubKeyMap, func(v *cryptography.PubKeyEnumWeightPair) (cryptography.MultiSigPublicKeyPair, error) { - publicKeyString := string(v.PubKey[:]) - if ok := seenPublicKeys[publicKeyString]; ok { - return cryptography.MultiSigPublicKeyPair{}, fmt.Errorf("multisig does not support duplicate public keys") - } - seenPublicKeys[publicKeyString] = true - - if v.Weight < 1 { - return cryptography.MultiSigPublicKeyPair{}, fmt.Errorf("invalid weight") - } - - pubKey, err := verify.PublicKeyFromRawBytes(cryptography.SignatureFlagToScheme[v.PubKey[0]], v.PubKey[1:]) - if err != nil { - return cryptography.MultiSigPublicKeyPair{}, err - } - return cryptography.MultiSigPublicKeyPair{PublicKey: pubKey, Weight: v.Weight}, nil - }) - if err != nil { - return nil, err - } - - var totalWeight uint16 = 0 - gm.Map(multisig.publicKeys, func(v cryptography.MultiSigPublicKeyPair) (any, error) { - totalWeight = totalWeight + uint16(v.Weight) - return nil, nil - }) - - if multisig.multisigPublicKey.Threshold > totalWeight { - return nil, fmt.Errorf("unreachable threshold") - } - - if len(multisig.publicKeys) > MaxSignerInMultisig { - return nil, fmt.Errorf("max number of signers in a multisig is %d", MaxSignerInMultisig) - } - - if len(multisig.publicKeys) < MinSignerInMultisig { - return nil, fmt.Errorf("min number of signers in a multisig is %d", MinSignerInMultisig) - } - - multisig.SetSelf(multisig) - return -} - -func (multisig *MultiSigPublicKey) FromPublicKeys(publicKeys []PublicKeyWeightPair, threshold uint16) (*MultiSigPublicKey, error) { - pubKeyMap, err := gm.Map(publicKeys, func(v PublicKeyWeightPair) (*cryptography.PubKeyEnumWeightPair, error) { - return &cryptography.PubKeyEnumWeightPair{PubKey: v.PublicKey.ToSuiBytes(), Weight: v.Weight}, nil - }) - if err != nil { - return nil, err - } - - return NewMultiSigPublicKey(cryptography.MultiSigPublicKeyStruct{PubKeyMap: pubKeyMap, Threshold: threshold}) -} - -// Checks if two MultiSig public keys are equal -func (key *MultiSigPublicKey) Equals(publicKey cryptography.PublicKey) bool { - return key.BasePublicKey.Equals(publicKey) -} - -// Return the Sui address associated with this MultiSig public key -func (multisig *MultiSigPublicKey) ToSuiAddress() string { - tmp := new(bytes.Buffer) - tmp.WriteByte(cryptography.SignatureSchemeToFlag[cryptography.MultiSigScheme]) - - threshold, _ := bcs.Marshal(multisig.multisigPublicKey.Threshold) - tmp.Write(threshold) - - for _, publicKey := range multisig.publicKeys { - tmp.Write(publicKey.PublicKey.ToSuiBytes()) - tmp.WriteByte(publicKey.Weight) - } - - sum256 := blake2b.Sum256(tmp.Bytes()) - return utils.NormalizeShortSuiAddress(hex.EncodeToString(sum256[:])[:64]) -} - -// Return the byte array representation of the MultiSig public key -func (multisig *MultiSigPublicKey) ToRawBytes() []byte { - return multisig.rawBytes -} - -func (multisig *MultiSigPublicKey) GetPublicKeys() []cryptography.MultiSigPublicKeyPair { - return multisig.publicKeys -} - -func (multisig *MultiSigPublicKey) GetThreshold() uint16 { - return multisig.multisigPublicKey.Threshold -} - -// Return the Sui address associated with this MultiSig public key -func (multisig *MultiSigPublicKey) Flag() uint8 { - return cryptography.SignatureSchemeToFlag[cryptography.MultiSigScheme] -} - -// Verifies that the signature is valid for for the provided message -func (multisig *MultiSigPublicKey) Verify(message []byte, multisigSignature cryptography.SerializedSignature) (bool, error) { - parsed, err := cryptography.ParseSerializedSignature(multisigSignature) - if err != nil { - return false, err - } - - if parsed.SignatureScheme != cryptography.MultiSigScheme { - return false, err - } - - thisMultisig := parsed.Multisig - - bs1, err := bcs.Marshal(multisig.multisigPublicKey) - if err != nil { - return false, err - } - bs2, err := bcs.Marshal(thisMultisig.MultisigPubKey) - if err != nil { - return false, err - } - - if !bytes.Equal(bs1, bs2) { - return false, err - } - - var signatureWeight uint16 = 0 - partialParsedData, err := ParsePartialSignatures(thisMultisig) - if err != nil { - return false, err - } - - for _, data := range partialParsedData { - signature, err := cryptography.ToSerializedSignature(cryptography.SerializeSignatureInput{ - SignatureScheme: cryptography.SignatureFlagToScheme[data.PublicKey.Flag()], - Signature: data.Signature, - PublicKey: data.PublicKey, - }) - if err != nil { - return false, err - } - - pass, err := data.PublicKey.Verify(message, signature) - if err != nil { - return false, err - } - if !pass { - return false, nil - } - - signatureWeight += uint16(data.Weight) - } - return (signatureWeight >= multisig.multisigPublicKey.Threshold), nil -} - -func (multisig *MultiSigPublicKey) CombinePartialSignatures(signatures []cryptography.SerializedSignature) (cryptography.SerializedSignature, error) { - if len(signatures) > MaxSignerInMultisig { - return "", fmt.Errorf("max number of signatures in a multisig is %d", MaxSignerInMultisig) - } - - var bitmap uint16 = 0 - compressedSignatures := make([]cryptography.CompressedSignature, len(signatures)) - for i := 0; i < len(signatures); i++ { - parsed, err := cryptography.ParseSerializedSignature(signatures[i]) - if err != nil { - return "", err - } - - if parsed.SignatureScheme == cryptography.MultiSigScheme { - return "", fmt.Errorf("multisig is not supported inside MultiSig") - } - if parsed.SignatureScheme == cryptography.ZkLoginScheme { - return "", fmt.Errorf("unimplemented %v", parsed.SignatureScheme) - } - - tmp := new(bytes.Buffer) - tmp.Write([]byte{cryptography.SignatureSchemeToFlag[parsed.SignatureScheme]}) - tmp.Write(parsed.Signature) - compressedSignatures[i] = cryptography.CompressedSignature{Signature: [65]byte(tmp.Bytes())} - - var publicKeyIndex *int - for j := 0; j < len(multisig.publicKeys); j++ { - if bytes.Equal(parsed.PubKey, multisig.publicKeys[j].PublicKey.ToRawBytes()) { - if bitmap&(1< 0 { - return "", fmt.Errorf("received multiple signatures from the same public key") - } - publicKeyIndex = &j - break - } - } - - if publicKeyIndex == nil { - return "", fmt.Errorf("received signature from unknown public key") - } - bitmap |= 1 << *publicKeyIndex - } - - m := cryptography.MultiSigStruct{ - Sigs: compressedSignatures, - Bitmap: bitmap, - MultisigPubKey: multisig.multisigPublicKey, - } - - bs, err := bcs.Marshal(&m) - if err != nil { - return "", err - } - - tmp := new(bytes.Buffer) - tmp.Write([]byte{cryptography.SignatureSchemeToFlag[cryptography.MultiSigScheme]}) - tmp.Write(bs) - - return b64.ToBase64(tmp.Bytes()), nil -} - -// Parse multisig structure into an array of individual signatures: signature scheme, the actual individual signature, public key and its weight. -func ParsePartialSignatures(multisig *cryptography.MultiSigStruct) ([]ParsedPartialMultiSigSignature, error) { - res := make([]ParsedPartialMultiSigSignature, len(multisig.Sigs)) - - for i := 0; i < len(multisig.Sigs); i++ { - signatureScheme := cryptography.SignatureFlagToScheme[multisig.Sigs[i].Signature[0]] - signature := multisig.Sigs[i].Signature[1:] - - bitmapIndices, err := AsIndices(multisig.Bitmap) - if err != nil { - return nil, err - } - pkIndex := bitmapIndices[i] - pair := multisig.MultisigPubKey.PubKeyMap[pkIndex] - pkBytes := pair.PubKey[1:] - - if signatureScheme == cryptography.MultiSigScheme { - return nil, fmt.Errorf("multisig is not supported inside MultiSig") - } - - publicKey, err := verify.PublicKeyFromRawBytes(signatureScheme, pkBytes) - if err != nil { - return nil, err - } - - res[i] = ParsedPartialMultiSigSignature{ - SignatureScheme: signatureScheme, - Signature: signature, - PublicKey: publicKey, - Weight: pair.Weight, - } - - } - return res, nil -} - -func AsIndices(bitmap uint16) ([]byte, error) { - if bitmap > 1024 { - return nil, fmt.Errorf("invalid bitmap") - } - - res := []byte{} - for i := 0; i < 10; i++ { - if (bitmap & (1 << i)) != 0 { - res = append(res, byte(i)) - } - } - return res, nil -} - -func PublicKeyFromSuiBytes[T string | []byte](publicKey T) (pk cryptography.PublicKey, err error) { - var bs []byte - switch v := any(publicKey).(type) { - case string: - bs, err = b64.FromBase64(v) - if err != nil { - return nil, err - } - case []byte: - bs = v - } - - signatureScheme := cryptography.SignatureFlagToScheme[bs[0]] - - if signatureScheme == cryptography.ZkLoginScheme { - return nil, fmt.Errorf("zkLogin publicKey is not supported") - } - return verify.PublicKeyFromRawBytes(signatureScheme, bs[1:]) -} diff --git a/gmsui/tests/account_test.go b/gmsui/tests/account_test.go deleted file mode 100644 index d241195..0000000 --- a/gmsui/tests/account_test.go +++ /dev/null @@ -1,739 +0,0 @@ -package tests - -import ( - "bytes" - "reflect" - "testing" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/W3Tools/go-modules/gmsui/keypairs/ed25519" - "github.com/W3Tools/go-modules/gmsui/keypairs/secp256k1" - "github.com/W3Tools/go-modules/gmsui/keypairs/secp256r1" - "github.com/W3Tools/go-modules/gmsui/multisig" -) - -const mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" -const message = "Hello Go Modules!" - -func TestEd25519(t *testing.T) { - testDatas := []struct { - path string - expected struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - } - }{ - { - path: "m/44'/784'/0'/0'/0'", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "ED25519", - getSecretKey: "suiprivkey1qzyxnjc8z79lvlsg6lz2hh69fp7m7duunfzjlnkzsd59f062855mqacydfr", - toSuiAddress: "0x5e93a736d04fbb25737aa40bee40171ef79f65fae833749e3c089fe7cc2161f1", - publicKeyToRawBytes: []byte{144, 11, 77, 129, 238, 206, 163, 223, 47, 116, 177, 66, 0, 196, 244, 207, 63, 73, 175, 172, 167, 166, 52, 255, 210, 207, 111, 248, 43, 218, 236, 242}, - publicKeyToSuiBytes: []byte{0, 144, 11, 77, 129, 238, 206, 163, 223, 47, 116, 177, 66, 0, 196, 244, 207, 63, 73, 175, 172, 167, 166, 52, 255, 210, 207, 111, 248, 43, 218, 236, 242}, - publicKeyToBase64: "kAtNge7Oo98vdLFCAMT0zz9Jr6ynpjT/0s9v+Cva7PI=", - publicKeyToSuiPublicKey: "AJALTYHuzqPfL3SxQgDE9M8/Sa+sp6Y0/9LPb/gr2uzy", - publicKeyToSuiAddress: "0x5e93a736d04fbb25737aa40bee40171ef79f65fae833749e3c089fe7cc2161f1", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AGtXLcPTNs1EukLef73WVQ+Q0P+9uyrbu/g4u3X4H/uCgbhk3G6Dg46xO9Bs5C78wcmqE9p1sZO0UWsg0l5UrwGQC02B7s6j3y90sUIAxPTPP0mvrKemNP/Sz2/4K9rs8g==", - }, - }, - { - path: "m/44'/784'/0'/0'/1'", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "ED25519", - getSecretKey: "suiprivkey1qpqk4vck5utyfttht7yphs4xc5flc7ymvzts36vh077f27d9lj942dj2rlk", - toSuiAddress: "0xf7c7a39996ac7f1c307b96c96d65cce0855dcc7ccd021c453964f2f62f98e71f", - publicKeyToRawBytes: []byte{72, 13, 240, 13, 190, 79, 51, 38, 217, 189, 169, 144, 121, 149, 79, 166, 157, 83, 121, 195, 78, 102, 210, 173, 163, 102, 215, 119, 167, 200, 112, 93}, - publicKeyToSuiBytes: []byte{0, 72, 13, 240, 13, 190, 79, 51, 38, 217, 189, 169, 144, 121, 149, 79, 166, 157, 83, 121, 195, 78, 102, 210, 173, 163, 102, 215, 119, 167, 200, 112, 93}, - publicKeyToBase64: "SA3wDb5PMybZvamQeZVPpp1TecNOZtKto2bXd6fIcF0=", - publicKeyToSuiPublicKey: "AEgN8A2+TzMm2b2pkHmVT6adU3nDTmbSraNm13enyHBd", - publicKeyToSuiAddress: "0xf7c7a39996ac7f1c307b96c96d65cce0855dcc7ccd021c453964f2f62f98e71f", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AOwzsOUKlYyE9140S59Gw/giW6AWRTGDH2qhCxoBXa13cBlLyUP2y+4mh2MTGZbl8jdE4dxQmB+fez9UqIFXdAFIDfANvk8zJtm9qZB5lU+mnVN5w05m0q2jZtd3p8hwXQ==", - }, - }, - { - path: "m/44'/784'/0'/0'/100'", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "ED25519", - getSecretKey: "suiprivkey1qrf7g3kgaa0e9qrdk5hkgn9hgu8ns35eqynxrmv39dltsf07ksrny7hmmm7", - toSuiAddress: "0x09bc557f22f2a7d19dbbb2e0862164e8f119d1a085356458e25679d2ece2fbe7", - publicKeyToRawBytes: []byte{181, 33, 229, 132, 252, 227, 116, 97, 174, 182, 8, 43, 122, 79, 119, 187, 164, 229, 102, 2, 163, 232, 176, 67, 77, 126, 236, 43, 254, 24, 159, 92}, - publicKeyToSuiBytes: []byte{0, 181, 33, 229, 132, 252, 227, 116, 97, 174, 182, 8, 43, 122, 79, 119, 187, 164, 229, 102, 2, 163, 232, 176, 67, 77, 126, 236, 43, 254, 24, 159, 92}, - publicKeyToBase64: "tSHlhPzjdGGutggrek93u6TlZgKj6LBDTX7sK/4Yn1w=", - publicKeyToSuiPublicKey: "ALUh5YT843RhrrYIK3pPd7uk5WYCo+iwQ01+7Cv+GJ9c", - publicKeyToSuiAddress: "0x09bc557f22f2a7d19dbbb2e0862164e8f119d1a085356458e25679d2ece2fbe7", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AGpkrflwgasF/JEju0E+alpK0lIYw7a3JQj1HCM121PsF8W6yRcowdSQo+z7cwnQ7dhZrmDRvvAI30EICYI2PQm1IeWE/ON0Ya62CCt6T3e7pOVmAqPosENNfuwr/hifXA==", - }, - }, - } - for _, test := range testDatas { - t.Run(test.path, func(t *testing.T) { - // For keypair - keypair, err := ed25519.DeriveKeypair(mnemonic, test.path) - if err != nil { - t.Fatalf("failed to derive ed25519 keypair, msg: %v", err) - } - - getKeyScheme := keypair.GetKeyScheme() - if !reflect.DeepEqual(getKeyScheme, test.expected.getKeyScheme) { - t.Errorf("unable to get key scheme, expected %s, but got %s", test.expected.getKeyScheme, getKeyScheme) - } - - getSecretKey, err := keypair.GetSecretKey() - if err != nil { - t.Fatalf("failed to get secret key, msg: %v", err) - } - if !reflect.DeepEqual(getSecretKey, test.expected.getSecretKey) { - t.Errorf("unable to get secret key, expected %v, but got %v", test.expected.getSecretKey, getSecretKey) - } - - if !reflect.DeepEqual(keypair.ToSuiAddress(), test.expected.toSuiAddress) { - t.Errorf("unable to sui address, expected %v, but got %v", test.expected.toSuiAddress, keypair.ToSuiAddress()) - } - - // For public key - pubkey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("failed to get public key, msg: %v", err) - } - if !bytes.Equal(pubkey.ToRawBytes(), test.expected.publicKeyToRawBytes) { - t.Errorf("unable to get public key to raw bytes, expected %v, but got %v", test.expected.publicKeyToRawBytes, pubkey.ToRawBytes()) - } - - if !bytes.Equal(pubkey.ToSuiBytes(), test.expected.publicKeyToSuiBytes) { - t.Errorf("unable to get public key to sui bytes, expected %v, but got %v", test.expected.publicKeyToSuiBytes, pubkey.ToSuiBytes()) - } - - if !reflect.DeepEqual(pubkey.ToBase64(), test.expected.publicKeyToBase64) { - t.Errorf("unable to get public key to base64, expected %v, but got %v", test.expected.publicKeyToBase64, pubkey.ToBase64()) - } - - if !reflect.DeepEqual(pubkey.ToSuiPublicKey(), test.expected.publicKeyToSuiPublicKey) { - t.Errorf("unable to get public key to sui public key, expected %v, but got %v", test.expected.publicKeyToSuiPublicKey, pubkey.ToSuiPublicKey()) - } - - if !reflect.DeepEqual(pubkey.ToSuiAddress(), test.expected.publicKeyToSuiAddress) { - t.Errorf("unable to get public key to sui address, expected %v, but got %v", test.expected.publicKeyToSuiAddress, pubkey.ToSuiAddress()) - } - - // For signature - data, err := keypair.SignPersonalMessage([]byte(message)) - if err != nil { - t.Fatalf("keypair failed to sign personal message, msg: %v", err) - } - - if !reflect.DeepEqual(data.Bytes, test.expected.message) { - t.Errorf("unable to sign personal message, bytes expected %s, but got %v", test.expected.message, data.Bytes) - } - - if !reflect.DeepEqual(data.Signature, test.expected.signature) { - t.Errorf("unable to sign personal message, signature expected %s, but got %v", test.expected.signature, data.Signature) - } - - pass, err := pubkey.VerifyPersonalMessage([]byte(message), data.Signature) - if err != nil { - t.Fatalf("public key failed to verify personal message, msg: %v", err) - } - if !pass { - t.Errorf("unable to verify personal message, expected %v, but got %v", true, pass) - } - }) - } -} - -func TestSecp256k1(t *testing.T) { - testDatas := []struct { - path string - expected struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - } - }{ - { - path: "m/54'/784'/0'/0/0", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "Secp256k1", - getSecretKey: "suiprivkey1qy82eu8yuzp4dykhe5d8cth23sw05yxnqqzpf5ce0rnmdjn905rgge6hyhd", - toSuiAddress: "0xc61a7f1161020a717f852dca2e9bfc1ffe235145406dfbdccc16e6907c1f5403", - publicKeyToRawBytes: []byte{2, 98, 61, 134, 15, 70, 204, 233, 17, 125, 63, 26, 195, 130, 183, 156, 89, 146, 138, 0, 74, 25, 134, 86, 26, 153, 223, 42, 133, 22, 124, 245, 133}, - publicKeyToSuiBytes: []byte{1, 2, 98, 61, 134, 15, 70, 204, 233, 17, 125, 63, 26, 195, 130, 183, 156, 89, 146, 138, 0, 74, 25, 134, 86, 26, 153, 223, 42, 133, 22, 124, 245, 133}, - publicKeyToBase64: "AmI9hg9GzOkRfT8aw4K3nFmSigBKGYZWGpnfKoUWfPWF", - publicKeyToSuiPublicKey: "AQJiPYYPRszpEX0/GsOCt5xZkooAShmGVhqZ3yqFFnz1hQ==", - publicKeyToSuiAddress: "0xc61a7f1161020a717f852dca2e9bfc1ffe235145406dfbdccc16e6907c1f5403", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AbtKlpY/Bsmo9huj2TiGdD92phTWxx3ABn4t/McFV7iGQFwzhvj8loW95rvoXplGC5XvrERwLk9XPYNpS9K758sCYj2GD0bM6RF9PxrDgrecWZKKAEoZhlYamd8qhRZ89YU=", - }, - }, - { - path: "m/54'/784'/0'/0/1", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "Secp256k1", - getSecretKey: "suiprivkey1qy7nhapqvq4jw3y9a2nr0sr8ug5awejjgs0d9zeq39hzh9afxr2u757dqhd", - toSuiAddress: "0x03de9efda2d82b61535b6f8448ea1ef55f914994f4b27f4628f918a054e55ba4", - publicKeyToRawBytes: []byte{2, 56, 161, 184, 104, 161, 161, 222, 177, 157, 85, 123, 132, 0, 169, 250, 46, 20, 141, 54, 137, 124, 85, 2, 113, 226, 87, 216, 253, 178, 5, 141, 81}, - publicKeyToSuiBytes: []byte{1, 2, 56, 161, 184, 104, 161, 161, 222, 177, 157, 85, 123, 132, 0, 169, 250, 46, 20, 141, 54, 137, 124, 85, 2, 113, 226, 87, 216, 253, 178, 5, 141, 81}, - publicKeyToBase64: "AjihuGihod6xnVV7hACp+i4UjTaJfFUCceJX2P2yBY1R", - publicKeyToSuiPublicKey: "AQI4obhooaHesZ1Ve4QAqfouFI02iXxVAnHiV9j9sgWNUQ==", - publicKeyToSuiAddress: "0x03de9efda2d82b61535b6f8448ea1ef55f914994f4b27f4628f918a054e55ba4", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AUnwfiejszYSZ/2vP8+YrkcsP18tmNbV6Crqg1yV9YjDTvhBhVRTkupJvblaESJXgyWWBKEnZY4avNMJ/ZgwtTsCOKG4aKGh3rGdVXuEAKn6LhSNNol8VQJx4lfY/bIFjVE=", - }, - }, - { - path: "m/54'/784'/0'/0/100", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "Secp256k1", - getSecretKey: "suiprivkey1q9kmy20jqv70xh3arz7zq6e8xxcqncakde2zf4axc43a2wpw9f59cf0gjvh", - toSuiAddress: "0x968c9a3409ec574e66fa2275a41b349d33f286c1f3f9dab05cfe1dc0385ce56e", - publicKeyToRawBytes: []byte{2, 41, 208, 210, 198, 3, 116, 32, 177, 207, 164, 84, 229, 197, 122, 6, 197, 83, 107, 42, 185, 24, 176, 145, 21, 149, 60, 32, 175, 172, 196, 114, 33}, - publicKeyToSuiBytes: []byte{1, 2, 41, 208, 210, 198, 3, 116, 32, 177, 207, 164, 84, 229, 197, 122, 6, 197, 83, 107, 42, 185, 24, 176, 145, 21, 149, 60, 32, 175, 172, 196, 114, 33}, - publicKeyToBase64: "AinQ0sYDdCCxz6RU5cV6BsVTayq5GLCRFZU8IK+sxHIh", - publicKeyToSuiPublicKey: "AQIp0NLGA3Qgsc+kVOXFegbFU2squRiwkRWVPCCvrMRyIQ==", - publicKeyToSuiAddress: "0x968c9a3409ec574e66fa2275a41b349d33f286c1f3f9dab05cfe1dc0385ce56e", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "ASZEpic8S267G1WS6Tu/0eNdeCsyjOTmD6DVImGP19w2dij/Px6FKrL4tGHtQlUJbf/zVCJvJVYD0QEtR9d24LICKdDSxgN0ILHPpFTlxXoGxVNrKrkYsJEVlTwgr6zEciE=", - }, - }, - } - for _, test := range testDatas { - t.Run(test.path, func(t *testing.T) { - // For keypair - keypair, err := secp256k1.DeriveKeypair(mnemonic, test.path) - if err != nil { - t.Fatalf("failed to derive secp256k1 keypair, msg: %v", err) - } - - getKeyScheme := keypair.GetKeyScheme() - if !reflect.DeepEqual(getKeyScheme, test.expected.getKeyScheme) { - t.Errorf("unable to get key scheme, expected %s, but got %s", test.expected.getKeyScheme, getKeyScheme) - } - - getSecretKey, err := keypair.GetSecretKey() - if err != nil { - t.Fatalf("failed to get secret key, msg: %v", err) - } - if !reflect.DeepEqual(getSecretKey, test.expected.getSecretKey) { - t.Errorf("unable to get secret key, expected %v, but got %v", test.expected.getSecretKey, getSecretKey) - } - - if !reflect.DeepEqual(keypair.ToSuiAddress(), test.expected.toSuiAddress) { - t.Errorf("unable to sui address, expected %v, but got %v", test.expected.toSuiAddress, keypair.ToSuiAddress()) - } - - // For public key - pubkey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("failed to get public key, msg: %v", err) - } - if !bytes.Equal(pubkey.ToRawBytes(), test.expected.publicKeyToRawBytes) { - t.Errorf("unable to get public key to raw bytes, expected %v, but got %v", test.expected.publicKeyToRawBytes, pubkey.ToRawBytes()) - } - - if !bytes.Equal(pubkey.ToSuiBytes(), test.expected.publicKeyToSuiBytes) { - t.Errorf("unable to get public key to sui bytes, expected %v, but got %v", test.expected.publicKeyToSuiBytes, pubkey.ToSuiBytes()) - } - - if !reflect.DeepEqual(pubkey.ToBase64(), test.expected.publicKeyToBase64) { - t.Errorf("unable to get public key to base64, expected %v, but got %v", test.expected.publicKeyToBase64, pubkey.ToBase64()) - } - - if !reflect.DeepEqual(pubkey.ToSuiPublicKey(), test.expected.publicKeyToSuiPublicKey) { - t.Errorf("unable to get public key to sui public key, expected %v, but got %v", test.expected.publicKeyToSuiPublicKey, pubkey.ToSuiPublicKey()) - } - - if !reflect.DeepEqual(pubkey.ToSuiAddress(), test.expected.publicKeyToSuiAddress) { - t.Errorf("unable to get public key to sui address, expected %v, but got %v", test.expected.publicKeyToSuiAddress, pubkey.ToSuiAddress()) - } - - // For signature - data, err := keypair.SignPersonalMessage([]byte(message)) - if err != nil { - t.Fatalf("keypair failed to sign personal message, msg: %v", err) - } - - if !reflect.DeepEqual(data.Bytes, test.expected.message) { - t.Errorf("unable to sign personal message, bytes expected %s, but got %v", test.expected.message, data.Bytes) - } - - if !reflect.DeepEqual(data.Signature, test.expected.signature) { - t.Errorf("unable to sign personal message, signature expected %s, but got %v", test.expected.signature, data.Signature) - } - - pass, err := pubkey.VerifyPersonalMessage([]byte(message), data.Signature) - if err != nil { - t.Fatalf("public key failed to verify personal message, msg: %v", err) - } - if !pass { - t.Errorf("unable to verify personal message, expected %v, but got %v", true, pass) - } - }) - } -} - -func TestSecp256r1(t *testing.T) { - testDatas := []struct { - path string - expected struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - } - }{ - { - path: "m/74'/784'/0'/0/0", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "Secp256r1", - getSecretKey: "suiprivkey1qfy8w9uvgleu04l6um3u6dagtsdgy8mysx8rr4qlyjn9ummcg34dzjn2gkr", - toSuiAddress: "0x0c0f9f53f2ad697e18279dfadefdd070c8e99416309d3ce614086c0860db6bb4", - publicKeyToRawBytes: []byte{3, 64, 25, 188, 168, 168, 120, 69, 138, 99, 229, 191, 83, 243, 8, 85, 227, 16, 112, 247, 181, 124, 249, 220, 242, 101, 201, 139, 219, 23, 187, 23, 196}, - publicKeyToSuiBytes: []byte{2, 3, 64, 25, 188, 168, 168, 120, 69, 138, 99, 229, 191, 83, 243, 8, 85, 227, 16, 112, 247, 181, 124, 249, 220, 242, 101, 201, 139, 219, 23, 187, 23, 196}, - publicKeyToBase64: "A0AZvKioeEWKY+W/U/MIVeMQcPe1fPnc8mXJi9sXuxfE", - publicKeyToSuiPublicKey: "AgNAGbyoqHhFimPlv1PzCFXjEHD3tXz53PJlyYvbF7sXxA==", - publicKeyToSuiAddress: "0x0c0f9f53f2ad697e18279dfadefdd070c8e99416309d3ce614086c0860db6bb4", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AkgYRN9hEX5LgSlT+r/M/15e9UKJmGxFeUc+q4ozTgXzCUOkBXHdVGrqKrTm4M50wp/pAgNnnASSJVRnGSmjA14DQBm8qKh4RYpj5b9T8whV4xBw97V8+dzyZcmL2xe7F8Q=", - }, - }, - { - path: "m/74'/784'/0'/0/1", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "Secp256r1", - getSecretKey: "suiprivkey1qt2yx236gj92a304eh49xzfmmypvaqeu9vvcjnaz09eyaumg0466vw83env", - toSuiAddress: "0xd4b4dcbc801c2d465b3f7a44cb1acad9702c14f790302625fef20b0811dc636a", - publicKeyToRawBytes: []byte{2, 124, 18, 113, 171, 75, 241, 31, 57, 238, 45, 0, 213, 64, 91, 78, 8, 205, 136, 84, 150, 206, 253, 112, 171, 155, 195, 138, 172, 188, 252, 40, 20}, - publicKeyToSuiBytes: []byte{2, 2, 124, 18, 113, 171, 75, 241, 31, 57, 238, 45, 0, 213, 64, 91, 78, 8, 205, 136, 84, 150, 206, 253, 112, 171, 155, 195, 138, 172, 188, 252, 40, 20}, - publicKeyToBase64: "AnwScatL8R857i0A1UBbTgjNiFSWzv1wq5vDiqy8/CgU", - publicKeyToSuiPublicKey: "AgJ8EnGrS/EfOe4tANVAW04IzYhUls79cKubw4qsvPwoFA==", - publicKeyToSuiAddress: "0xd4b4dcbc801c2d465b3f7a44cb1acad9702c14f790302625fef20b0811dc636a", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AkJXhYmR3t2UnTgeDJYyOBPaScS0+Aoip9ehG4DEy6BoBPMJIGUUyI4SHoPi4KSjaMCEDWIk1WUI/Ot7Q6nBCdgCfBJxq0vxHznuLQDVQFtOCM2IVJbO/XCrm8OKrLz8KBQ=", - }, - }, - { - path: "m/74'/784'/0'/0/100", - expected: struct { - getKeyScheme string - getSecretKey string - toSuiAddress string - publicKeyToRawBytes []byte - publicKeyToSuiBytes []byte - publicKeyToBase64 string - publicKeyToSuiPublicKey string - publicKeyToSuiAddress string - message string - signature string - }{ - getKeyScheme: "Secp256r1", - getSecretKey: "suiprivkey1qgw0mmwmjrnv0p5k4pz280pycp6kqf2el00xhtg7hm8dp9d8hjs2cw27tma", - toSuiAddress: "0xa4872fd99dc16d9374adee9759653be974b770bf437a47e7db7f3fc3edabfe37", - publicKeyToRawBytes: []byte{2, 172, 241, 252, 174, 88, 35, 149, 136, 100, 96, 254, 24, 99, 230, 135, 48, 246, 182, 211, 11, 245, 6, 98, 2, 29, 9, 75, 69, 59, 164, 117, 186}, - publicKeyToSuiBytes: []byte{2, 2, 172, 241, 252, 174, 88, 35, 149, 136, 100, 96, 254, 24, 99, 230, 135, 48, 246, 182, 211, 11, 245, 6, 98, 2, 29, 9, 75, 69, 59, 164, 117, 186}, - publicKeyToBase64: "Aqzx/K5YI5WIZGD+GGPmhzD2ttML9QZiAh0JS0U7pHW6", - publicKeyToSuiPublicKey: "AgKs8fyuWCOViGRg/hhj5ocw9rbTC/UGYgIdCUtFO6R1ug==", - publicKeyToSuiAddress: "0xa4872fd99dc16d9374adee9759653be974b770bf437a47e7db7f3fc3edabfe37", - - message: "EUhlbGxvIEdvIE1vZHVsZXMh", - signature: "AnTTdvH53Oe3bwoocWFhFymLBFCch2BuGVIbPFr7THvGVcwH2mvFL9fx+kLHb43gAkbJVhaR/rqa6pVgz4Aa1ZQCrPH8rlgjlYhkYP4YY+aHMPa20wv1BmICHQlLRTukdbo=", - }, - }, - } - for _, test := range testDatas { - t.Run(test.path, func(t *testing.T) { - // For keypair - keypair, err := secp256r1.DeriveKeypair(mnemonic, test.path) - if err != nil { - t.Fatalf("failed to derive secp256r1 keypair, msg: %v", err) - } - - getKeyScheme := keypair.GetKeyScheme() - if !reflect.DeepEqual(getKeyScheme, test.expected.getKeyScheme) { - t.Errorf("unable to get key scheme, expected %s, but got %s", test.expected.getKeyScheme, getKeyScheme) - } - - getSecretKey, err := keypair.GetSecretKey() - if err != nil { - t.Fatalf("failed to get secret key, msg: %v", err) - } - if !reflect.DeepEqual(getSecretKey, test.expected.getSecretKey) { - t.Errorf("unable to get secret key, expected %v, but got %v", test.expected.getSecretKey, getSecretKey) - } - - if !reflect.DeepEqual(keypair.ToSuiAddress(), test.expected.toSuiAddress) { - t.Errorf("unable to sui address, expected %v, but got %v", test.expected.toSuiAddress, keypair.ToSuiAddress()) - } - - // For public key - pubkey, err := keypair.GetPublicKey() - if err != nil { - t.Fatalf("failed to get public key, msg: %v", err) - } - if !bytes.Equal(pubkey.ToRawBytes(), test.expected.publicKeyToRawBytes) { - t.Errorf("unable to get public key to raw bytes, expected %v, but got %v", test.expected.publicKeyToRawBytes, pubkey.ToRawBytes()) - } - - if !bytes.Equal(pubkey.ToSuiBytes(), test.expected.publicKeyToSuiBytes) { - t.Errorf("unable to get public key to sui bytes, expected %v, but got %v", test.expected.publicKeyToSuiBytes, pubkey.ToSuiBytes()) - } - - if !reflect.DeepEqual(pubkey.ToBase64(), test.expected.publicKeyToBase64) { - t.Errorf("unable to get public key to base64, expected %v, but got %v", test.expected.publicKeyToBase64, pubkey.ToBase64()) - } - - if !reflect.DeepEqual(pubkey.ToSuiPublicKey(), test.expected.publicKeyToSuiPublicKey) { - t.Errorf("unable to get public key to sui public key, expected %v, but got %v", test.expected.publicKeyToSuiPublicKey, pubkey.ToSuiPublicKey()) - } - - if !reflect.DeepEqual(pubkey.ToSuiAddress(), test.expected.publicKeyToSuiAddress) { - t.Errorf("unable to get public key to sui address, expected %v, but got %v", test.expected.publicKeyToSuiAddress, pubkey.ToSuiAddress()) - } - - // For signature - data, err := keypair.SignPersonalMessage([]byte(message)) - if err != nil { - t.Fatalf("keypair failed to sign personal message, msg: %v", err) - } - - if !reflect.DeepEqual(data.Bytes, test.expected.message) { - t.Errorf("unable to sign personal message, bytes expected %s, but got %v", test.expected.message, data.Bytes) - } - - if !reflect.DeepEqual(data.Signature, test.expected.signature) { - t.Errorf("unable to sign personal message, signature expected %s, but got %v", test.expected.signature, data.Signature) - } - - pass, err := pubkey.VerifyPersonalMessage([]byte(message), data.Signature) - if err != nil { - t.Fatalf("public key failed to verify personal message, msg: %v", err) - } - if !pass { - t.Errorf("unable to verify personal message, expected %v, but got %v", true, pass) - } - }) - } -} - -func TestMultisig(t *testing.T) { - testDatas := []struct { - ed25519Path string - ed25519Weight uint8 - secp256k1Path string - secp256k1Weight uint8 - secp256r1Path string - secp256r1Weight uint8 - message string - threshold uint16 - expected struct { - flag uint8 - threshold uint16 - toBase64 string - toRawBytes []byte - toSuiPublicKey string - toSuiBytes []byte - toSuiAddress string - ed25519Signature string - secp256k1Signature string - secp256r1Signature string - combineSignature string - } - }{ - { - ed25519Path: "m/44'/784'/0'/0'/100'", - ed25519Weight: 2, - secp256k1Path: "m/54'/784'/0'/0/100", - secp256k1Weight: 2, - secp256r1Path: "m/74'/784'/0'/0/100", - secp256r1Weight: 2, - message: "Hello Sui MultiSig!", - threshold: 3, - expected: struct { - flag uint8 - threshold uint16 - toBase64 string - toRawBytes []byte - toSuiPublicKey string - toSuiBytes []byte - toSuiAddress string - ed25519Signature string - secp256k1Signature string - secp256r1Signature string - combineSignature string - }{ - flag: 3, - threshold: 3, - toBase64: "AwC1IeWE/ON0Ya62CCt6T3e7pOVmAqPosENNfuwr/hifXAIBAinQ0sYDdCCxz6RU5cV6BsVTayq5GLCRFZU8IK+sxHIhAgICrPH8rlgjlYhkYP4YY+aHMPa20wv1BmICHQlLRTukdboCAwA=", - toRawBytes: []byte{3, 0, 181, 33, 229, 132, 252, 227, 116, 97, 174, 182, 8, 43, 122, 79, 119, 187, 164, 229, 102, 2, 163, 232, 176, 67, 77, 126, 236, 43, 254, 24, 159, 92, 2, 1, 2, 41, 208, 210, 198, 3, 116, 32, 177, 207, 164, 84, 229, 197, 122, 6, 197, 83, 107, 42, 185, 24, 176, 145, 21, 149, 60, 32, 175, 172, 196, 114, 33, 2, 2, 2, 172, 241, 252, 174, 88, 35, 149, 136, 100, 96, 254, 24, 99, 230, 135, 48, 246, 182, 211, 11, 245, 6, 98, 2, 29, 9, 75, 69, 59, 164, 117, 186, 2, 3, 0}, - toSuiPublicKey: "AwMAtSHlhPzjdGGutggrek93u6TlZgKj6LBDTX7sK/4Yn1wCAQIp0NLGA3Qgsc+kVOXFegbFU2squRiwkRWVPCCvrMRyIQICAqzx/K5YI5WIZGD+GGPmhzD2ttML9QZiAh0JS0U7pHW6AgMA", - toSuiBytes: []byte{3, 3, 0, 181, 33, 229, 132, 252, 227, 116, 97, 174, 182, 8, 43, 122, 79, 119, 187, 164, 229, 102, 2, 163, 232, 176, 67, 77, 126, 236, 43, 254, 24, 159, 92, 2, 1, 2, 41, 208, 210, 198, 3, 116, 32, 177, 207, 164, 84, 229, 197, 122, 6, 197, 83, 107, 42, 185, 24, 176, 145, 21, 149, 60, 32, 175, 172, 196, 114, 33, 2, 2, 2, 172, 241, 252, 174, 88, 35, 149, 136, 100, 96, 254, 24, 99, 230, 135, 48, 246, 182, 211, 11, 245, 6, 98, 2, 29, 9, 75, 69, 59, 164, 117, 186, 2, 3, 0}, - toSuiAddress: "0xfb061fbd2807b3b6f74cc8f238141ee8e72623a1cd35b9cd6f6bce40be9caccb", - ed25519Signature: "AIgT8hGxxolm+7DH2GYa0F8GH29su6hUXKESLTLO58O7FbE32o98EVHmfMGhBEDL3i2crqZg6EZoLM1yAPst/Qy1IeWE/ON0Ya62CCt6T3e7pOVmAqPosENNfuwr/hifXA==", - secp256k1Signature: "AUCEfb7JJL6T3U2ELhxYGxRE/ys1lnVg9SBOT5dYNIapaE58rOnch+nLlPoSaAqNL0Gnn+wvYvGsO5mGG/u++pgCKdDSxgN0ILHPpFTlxXoGxVNrKrkYsJEVlTwgr6zEciE=", - secp256r1Signature: "Ak3cCty+GNPSMkwKEb4UwxJv8KAxO/4sXGWGIT6K/NsnASzh/LgJFDturYbfs7eJUmY1QrdQCsx4JS7sL6UCF64CrPH8rlgjlYhkYP4YY+aHMPa20wv1BmICHQlLRTukdbo=", - combineSignature: "AwMAiBPyEbHGiWb7sMfYZhrQXwYfb2y7qFRcoRItMs7nw7sVsTfaj3wRUeZ8waEEQMveLZyupmDoRmgszXIA+y39DAFAhH2+ySS+k91NhC4cWBsURP8rNZZ1YPUgTk+XWDSGqWhOfKzp3Ifpy5T6EmgKjS9Bp5/sL2LxrDuZhhv7vvqYAk3cCty+GNPSMkwKEb4UwxJv8KAxO/4sXGWGIT6K/NsnASzh/LgJFDturYbfs7eJUmY1QrdQCsx4JS7sL6UCF64HAAMAtSHlhPzjdGGutggrek93u6TlZgKj6LBDTX7sK/4Yn1wCAQIp0NLGA3Qgsc+kVOXFegbFU2squRiwkRWVPCCvrMRyIQICAqzx/K5YI5WIZGD+GGPmhzD2ttML9QZiAh0JS0U7pHW6AgMA", - }, - }, - { - ed25519Path: "m/44'/784'/0'/0'/0'", - ed25519Weight: 1, - secp256k1Path: "m/54'/784'/0'/0/0", - secp256k1Weight: 1, - secp256r1Path: "m/74'/784'/0'/0/0", - secp256r1Weight: 1, - message: "Hello Sui MultiSig!", - threshold: 2, - expected: struct { - flag uint8 - threshold uint16 - toBase64 string - toRawBytes []byte - toSuiPublicKey string - toSuiBytes []byte - toSuiAddress string - ed25519Signature string - secp256k1Signature string - secp256r1Signature string - combineSignature string - }{ - flag: 3, - threshold: 2, - toBase64: "AwCQC02B7s6j3y90sUIAxPTPP0mvrKemNP/Sz2/4K9rs8gEBAmI9hg9GzOkRfT8aw4K3nFmSigBKGYZWGpnfKoUWfPWFAQIDQBm8qKh4RYpj5b9T8whV4xBw97V8+dzyZcmL2xe7F8QBAgA=", - toRawBytes: []byte{3, 0, 144, 11, 77, 129, 238, 206, 163, 223, 47, 116, 177, 66, 0, 196, 244, 207, 63, 73, 175, 172, 167, 166, 52, 255, 210, 207, 111, 248, 43, 218, 236, 242, 1, 1, 2, 98, 61, 134, 15, 70, 204, 233, 17, 125, 63, 26, 195, 130, 183, 156, 89, 146, 138, 0, 74, 25, 134, 86, 26, 153, 223, 42, 133, 22, 124, 245, 133, 1, 2, 3, 64, 25, 188, 168, 168, 120, 69, 138, 99, 229, 191, 83, 243, 8, 85, 227, 16, 112, 247, 181, 124, 249, 220, 242, 101, 201, 139, 219, 23, 187, 23, 196, 1, 2, 0}, - toSuiPublicKey: "AwMAkAtNge7Oo98vdLFCAMT0zz9Jr6ynpjT/0s9v+Cva7PIBAQJiPYYPRszpEX0/GsOCt5xZkooAShmGVhqZ3yqFFnz1hQECA0AZvKioeEWKY+W/U/MIVeMQcPe1fPnc8mXJi9sXuxfEAQIA", - toSuiBytes: []byte{3, 3, 0, 144, 11, 77, 129, 238, 206, 163, 223, 47, 116, 177, 66, 0, 196, 244, 207, 63, 73, 175, 172, 167, 166, 52, 255, 210, 207, 111, 248, 43, 218, 236, 242, 1, 1, 2, 98, 61, 134, 15, 70, 204, 233, 17, 125, 63, 26, 195, 130, 183, 156, 89, 146, 138, 0, 74, 25, 134, 86, 26, 153, 223, 42, 133, 22, 124, 245, 133, 1, 2, 3, 64, 25, 188, 168, 168, 120, 69, 138, 99, 229, 191, 83, 243, 8, 85, 227, 16, 112, 247, 181, 124, 249, 220, 242, 101, 201, 139, 219, 23, 187, 23, 196, 1, 2, 0}, - toSuiAddress: "0x357ef6da9a57094cb90b1d6c40a5f0a5c533e48ed69d02f66e292ceff2f80cd9", - ed25519Signature: "AIzXgqJN8Rwqt22Ap2pwkx9+ucchpDeAsCiAOZaOZZqbgqaEybaIXjys7L4mojDMo+3pWlSeLpV6WJN1yO7tVQyQC02B7s6j3y90sUIAxPTPP0mvrKemNP/Sz2/4K9rs8g==", - secp256k1Signature: "AdDfYvAb/NGpRNcvnItMof1rY2rE8c8QPcpdebS3FmrRNGePO+AasY1Eklhe50P0KzVvLHK4PGgzyb2PpJDOQYoCYj2GD0bM6RF9PxrDgrecWZKKAEoZhlYamd8qhRZ89YU=", - secp256r1Signature: "AohHLG9bUkjYFyXxIiYY7JprgAnerwiPYX1HA8Byqug3aaTMcqeWNYJu/s5Z2e0256oZprIttsZ36YBpc381sa4DQBm8qKh4RYpj5b9T8whV4xBw97V8+dzyZcmL2xe7F8Q=", - combineSignature: "AwMAjNeCok3xHCq3bYCnanCTH365xyGkN4CwKIA5lo5lmpuCpoTJtohePKzsviaiMMyj7elaVJ4ulXpYk3XI7u1VDAHQ32LwG/zRqUTXL5yLTKH9a2NqxPHPED3KXXm0txZq0TRnjzvgGrGNRJJYXudD9Cs1byxyuDxoM8m9j6SQzkGKAohHLG9bUkjYFyXxIiYY7JprgAnerwiPYX1HA8Byqug3aaTMcqeWNYJu/s5Z2e0256oZprIttsZ36YBpc381sa4HAAMAkAtNge7Oo98vdLFCAMT0zz9Jr6ynpjT/0s9v+Cva7PIBAQJiPYYPRszpEX0/GsOCt5xZkooAShmGVhqZ3yqFFnz1hQECA0AZvKioeEWKY+W/U/MIVeMQcPe1fPnc8mXJi9sXuxfEAQIA", - }, - }, - } - - for _, test := range testDatas { - t.Run(test.expected.toSuiAddress, func(t *testing.T) { - ed25519Keypair, err := ed25519.DeriveKeypair(mnemonic, test.ed25519Path) - if err != nil { - t.Fatalf("failed to derive ed25519 keypair, msg: %v", err) - } - - secp256k1Keypair, err := secp256k1.DeriveKeypair(mnemonic, test.secp256k1Path) - if err != nil { - t.Fatalf("failed to derive secp256k1 keypair, msg: %v", err) - } - - secp256r1Keypair, err := secp256r1.DeriveKeypair(mnemonic, test.secp256r1Path) - if err != nil { - t.Fatalf("failed to derive secp256r1 keypair, msg: %v", err) - } - - ed25519PublicKey, err := ed25519Keypair.GetPublicKey() - if err != nil { - t.Fatalf("failed to get ed25519 public key, msg: %v", err) - } - - secp256k1PublicKey, err := secp256k1Keypair.GetPublicKey() - if err != nil { - t.Fatalf("failed to get secp256k1 public key, msg: %v", err) - } - - secp256r1PublicKey, err := secp256r1Keypair.GetPublicKey() - if err != nil { - t.Fatalf("failed to get secp256r1 public key, msg: %v", err) - } - - multisigPubKey, err := new(multisig.MultiSigPublicKey).FromPublicKeys([]multisig.PublicKeyWeightPair{ - {PublicKey: ed25519PublicKey, Weight: test.ed25519Weight}, - {PublicKey: secp256k1PublicKey, Weight: test.secp256k1Weight}, - {PublicKey: secp256r1PublicKey, Weight: test.secp256r1Weight}, - }, test.threshold) - if err != nil { - t.Fatalf("failed to new multisig public key, msg: %v", err) - } - - if !reflect.DeepEqual(test.expected.flag, multisigPubKey.Flag()) { - t.Errorf("expected flag %v, but got %v", test.expected.flag, multisigPubKey.Flag()) - } - if !reflect.DeepEqual(test.expected.threshold, multisigPubKey.GetThreshold()) { - t.Errorf("expected threshold %v, but got %v", test.expected.threshold, multisigPubKey.GetThreshold()) - } - if !reflect.DeepEqual(test.expected.toBase64, multisigPubKey.ToBase64()) { - t.Errorf("expected base64 %v, but got %v", test.expected.toBase64, multisigPubKey.ToBase64()) - } - if !reflect.DeepEqual(test.expected.toSuiPublicKey, multisigPubKey.ToSuiPublicKey()) { - t.Errorf("expected sui public key %v, but got %v", test.expected.toSuiPublicKey, multisigPubKey.ToSuiPublicKey()) - } - if !reflect.DeepEqual(test.expected.toSuiAddress, multisigPubKey.ToSuiAddress()) { - t.Errorf("expected sui address %v, but got %v", test.expected.toSuiAddress, multisigPubKey.ToSuiAddress()) - } - if !bytes.Equal(test.expected.toRawBytes, multisigPubKey.ToRawBytes()) { - t.Errorf("expected raw bytes %v, but got %v", test.expected.toRawBytes, multisigPubKey.ToRawBytes()) - } - if !bytes.Equal(test.expected.toSuiBytes, multisigPubKey.ToSuiBytes()) { - t.Errorf("expected raw sui bytes %v, but got %v", test.expected.toSuiBytes, multisigPubKey.ToSuiBytes()) - } - - m, err := multisig.NewMultiSigPublicKey(multisigPubKey.ToRawBytes()) - if err != nil { - t.Fatalf("failed to new multisig public key, msg: %v", err) - } - - if !bytes.Equal(m.ToRawBytes(), multisigPubKey.ToRawBytes()) { - t.Errorf("expected raw bytes %v, but got %v", multisigPubKey.ToRawBytes(), m.ToRawBytes()) - } - - signatureData1, err := ed25519Keypair.SignPersonalMessage([]byte(test.message)) - if err != nil { - t.Fatalf("failed to sign ed25519 personal message, msg: %v", err) - } - if !reflect.DeepEqual(signatureData1.Signature, test.expected.ed25519Signature) { - t.Errorf("expected ed25519 signature %v, but got %v", test.expected.ed25519Signature, signatureData1.Signature) - } - - signatureData2, err := secp256k1Keypair.SignPersonalMessage([]byte(test.message)) - if err != nil { - t.Fatalf("failed to sign secp256k1 personal message, msg: %v", err) - } - if !reflect.DeepEqual(signatureData2.Signature, test.expected.secp256k1Signature) { - t.Errorf("expected secp256k1 signature %v, but got %v", test.expected.secp256k1Signature, signatureData2.Signature) - } - - signatureData3, err := secp256r1Keypair.SignPersonalMessage([]byte(test.message)) - if err != nil { - t.Fatalf("failed to sign secp256r1 personal message, msg: %v", err) - } - if !reflect.DeepEqual(signatureData3.Signature, test.expected.secp256r1Signature) { - t.Errorf("expected secp256r1 signature %v, but got %v", test.expected.secp256r1Signature, signatureData3.Signature) - } - - signature, err := multisigPubKey.CombinePartialSignatures([]cryptography.SerializedSignature{signatureData1.Signature, signatureData2.Signature, signatureData3.Signature}) - if err != nil { - t.Fatalf("failed to combine partial signatures, msg: %v", err) - } - if !reflect.DeepEqual(signature, test.expected.combineSignature) { - t.Errorf("expected signature %v, but got %v", test.expected.combineSignature, signature) - } - }) - - } -} diff --git a/gmsui/transactions/internal.go b/gmsui/transactions/internal.go deleted file mode 100644 index 37854bd..0000000 --- a/gmsui/transactions/internal.go +++ /dev/null @@ -1,441 +0,0 @@ -package transactions - -import ( - "fmt" - "reflect" - "strconv" - "strings" - - gm "github.com/W3Tools/go-modules" - "github.com/W3Tools/go-modules/gmsui/types" - "github.com/W3Tools/go-modules/gmsui/utils" - "github.com/W3Tools/go-sui-sdk/v2/lib" - "github.com/W3Tools/go-sui-sdk/v2/move_types" - "github.com/W3Tools/go-sui-sdk/v2/sui_types" -) - -// Create Transaction Result With NormalizedMoveFunction Return Count -func (txb *Transaction) createTransactionResult(count int) []*sui_types.Argument { - nestedResult1 := uint16(len(txb.builder.Commands) - 1) - returnArguments := make([]*sui_types.Argument, count) - for i := 0; i < count; i++ { - returnArguments[i] = &sui_types.Argument{ - NestedResult: &struct { - Result1 uint16 - Result2 uint16 - }{ - Result1: nestedResult1, - Result2: uint16(i), - }, - } - } - - return returnArguments -} - -func setGasPrice(txb *Transaction) error { - if txb.GasConfig.Price == 0 { - referenceGasPrice, err := txb.client.GetReferenceGasPrice() - if err != nil { - return fmt.Errorf("failed to get reference gas price, err: %v", err) - } - - txb.GasConfig.Price = referenceGasPrice.Uint64() + 1 - } - - return nil -} - -func setGasBudget(txb *Transaction) error { - if txb.GasConfig.Budget == 0 { - tx := *txb - - dryRunResult, err := tx.DryRunTransactionBlock() - if err != nil { - return fmt.Errorf("failed to dry run transaction block, err: %v", err) - } - - if dryRunResult.Effects.Status.Status != "success" { - return fmt.Errorf("dry run failed, could not automatically determine a budget: %v", dryRunResult.Effects.Status.Error) - } - - safeOverhead := utils.GAS_SAFE_OVERHEAD * tx.GasConfig.Price - - computationCost, err := strconv.ParseUint(dryRunResult.Effects.GasUsed.ComputationCost, 10, 64) - if err != nil { - return fmt.Errorf("failed to parse computation cost, err: %v", err) - } - baseComputationCostWithOverhead := computationCost + safeOverhead - - storageCost, err := strconv.ParseUint(dryRunResult.Effects.GasUsed.StorageCost, 10, 64) - if err != nil { - return fmt.Errorf("failed to parse storage cost, err: %v", err) - } - storageRebate, err := strconv.ParseUint(dryRunResult.Effects.GasUsed.StorageRebate, 10, 64) - if err != nil { - return fmt.Errorf("failed to parse storage rebate, err: %v", err) - } - - cost := baseComputationCostWithOverhead + storageCost - if storageRebate > cost { - txb.GasConfig.Budget = baseComputationCostWithOverhead - } else { - gasBudget := baseComputationCostWithOverhead + storageCost - storageRebate - if gasBudget > baseComputationCostWithOverhead { - txb.GasConfig.Budget = gasBudget - } else { - txb.GasConfig.Budget = baseComputationCostWithOverhead - } - } - } - - return nil -} - -func setGasPayment(txb *Transaction) error { - if len(txb.GasConfig.Payment) == 0 { - owner := txb.GasConfig.Owner - if owner == "" { - owner = txb.Sender.String() - } - coins, err := txb.client.GetCoins(types.GetCoinsParams{Owner: owner, CoinType: gm.NewStringPtr(utils.SUI_TYPE_ARG)}) - if err != nil { - return fmt.Errorf("failed to get coins, err: %v", err) - } - - paymentCoins := make([]*sui_types.ObjectRef, 0) - for _, coin := range coins.Data { - objectRef, err := coinStructToObjectRef(coin) - if err != nil { - return fmt.Errorf("failed to create object reference, err: %v", err) - } - - paymentCoins = append(paymentCoins, objectRef) - } - - if len(paymentCoins) == 0 { - return fmt.Errorf("no valid gas coins found for the transaction") - } - - txb.GasConfig.Payment = paymentCoins - } - - return nil -} - -// Check if the param is tx_context.TxContext -func isTxContext(param types.SuiMoveNormalizedType) bool { - structType := extractStructTag(param) - if structType == nil { - return false - } - - return structType.Struct.Address == "0x2" && structType.Struct.Module == "tx_context" && structType.Struct.Name == "TxContext" -} - -// Extract NormalizedMoveFunction Type -func extractStructTag(normalizedType types.SuiMoveNormalizedType) *types.SuiMoveNormalizedType_Struct { - _struct, ok := normalizedType.(types.SuiMoveNormalizedType_Struct) - if ok { - return &_struct - } - - ref := extractReference(normalizedType) - mutRef := extractMutableReference(normalizedType) - - if ref != nil { - return extractStructTag(ref) - } - - if mutRef != nil { - return extractStructTag(mutRef) - } - - return nil -} - -func extractReference(normalizedType types.SuiMoveNormalizedType) types.SuiMoveNormalizedType { - reference, ok := normalizedType.(types.SuiMoveNormalizedType_Reference) - if ok { - return reference.Reference.SuiMoveNormalizedType - } - return nil -} - -func extractMutableReference(normalizedType types.SuiMoveNormalizedType) types.SuiMoveNormalizedType { - mutableReference, ok := normalizedType.(types.SuiMoveNormalizedType_MutableReference) - if ok { - return mutableReference.MutableReference.SuiMoveNormalizedType - } - return nil -} - -// Resolve Parameter - -// Allowed types are sui_types.Argument, string -> object id, *TransactionInputGasCoin -func (txb *Transaction) resolveSplitCoinsCoin(coin any) (*UnresolvedParameter, error) { - unresolvedParameter := NewUnresolvedParameter(1) - - reflectValue := reflect.ValueOf(coin) - switch reflectValue.Type() { - case reflect.TypeOf((*sui_types.Argument)(nil)): // nest result - unresolvedParameter.Arguments[0] = &UnresolvedArgument{Argument: reflectValue.Interface().(*sui_types.Argument)} - case reflect.TypeOf((*TransactionInputGasCoin)(nil)): // gas coin - unresolvedParameter.Arguments[0] = &UnresolvedArgument{Argument: &sui_types.Argument{GasCoin: &lib.EmptyEnum{}}} - case reflect.TypeOf(""): // object id - unresolvedParameter.Objects[0] = UnresolvedObject{Mutable: false, ObjectId: reflectValue.String()} - default: - return nil, fmt.Errorf("input coin should one of address(string), sui_types.Argument or *TransactionInputGasCoin, got %v", reflectValue.Type().String()) - } - - return unresolvedParameter, nil -} - -// Allowed types are uint, uint8, uint16, uint32, uint64, sui_types.Argument -func (txb *Transaction) resolveSplitCoinsAmounts(amounts []any) (*UnresolvedParameter, error) { - unresolvedParameter := NewUnresolvedParameter(len(amounts)) - - for idx, amount := range amounts { - reflectValue := reflect.ValueOf(amount) - switch reflectValue.Type() { - case reflect.TypeOf((*sui_types.Argument)(nil)): // nest result - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Argument: reflectValue.Interface().(*sui_types.Argument)} - case reflect.TypeOf(uint(0)), reflect.TypeOf(uint8(0)), reflect.TypeOf(uint16(0)), reflect.TypeOf(uint32(0)), reflect.TypeOf(uint64(0)): - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Pure: amount} - default: - return nil, fmt.Errorf("input amount should be uint or sui_types.Argument at index %d, got %v", idx, reflectValue.Type().String()) - } - } - - return unresolvedParameter, nil -} - -// Parse TransferObjects Params - -// Allowed types are sui_types.Argument, string -> object id -func (txb *Transaction) resolveTransferObjectsObjects(objects []any) (*UnresolvedParameter, error) { - unresolvedParameter := NewUnresolvedParameter(len(objects)) - - for idx, object := range objects { - reflectValue := reflect.ValueOf(object) - switch reflectValue.Type() { - case reflect.TypeOf((*sui_types.Argument)(nil)): // nest result - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Argument: reflectValue.Interface().(*sui_types.Argument)} - case reflect.TypeOf((*TransactionInputGasCoin)(nil)): // gas coin - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Argument: &sui_types.Argument{GasCoin: &lib.EmptyEnum{}}} - case reflect.TypeOf(""): // object id - unresolvedParameter.Objects[idx] = UnresolvedObject{Mutable: false, ObjectId: reflectValue.String()} - default: - return nil, fmt.Errorf("input object should one of address(string), sui_types.Argument or *TransactionInputGasCoin at index %d, got %v", idx, reflectValue.Type().String()) - } - } - - return unresolvedParameter, nil -} - -// Allowed types are sui_types.Argument, string -> address -func (txb *Transaction) resolveTransferObjectsAddress(address any) (*UnresolvedParameter, error) { - unresolvedParameter := NewUnresolvedParameter(1) - - reflectValue := reflect.ValueOf(address) - switch reflectValue.Type() { - case reflect.TypeOf((*sui_types.Argument)(nil)): // nest result - unresolvedParameter.Arguments[0] = &UnresolvedArgument{Argument: reflectValue.Interface().(*sui_types.Argument)} - case reflect.TypeOf(""): // address - suiAddress, err := sui_types.NewAddressFromHex(reflectValue.String()) - if err != nil { - return nil, fmt.Errorf("input address must conform to the address(string), got %v", reflectValue.String()) - } - - unresolvedParameter.Arguments[0] = &UnresolvedArgument{Pure: suiAddress} - default: - return nil, fmt.Errorf("input address should be address(string) or sui_types.Argument, got %v", reflectValue.Type().String()) - } - - return unresolvedParameter, nil -} - -// Parse MergeCoins Params - -// Allowed types are sui_types.Argument, string -> object id -func (txb *Transaction) resolveMergeCoinsDestination(destination any) (*UnresolvedParameter, error) { - unresolvedParameter := NewUnresolvedParameter(1) - - reflectValue := reflect.ValueOf(destination) - switch reflectValue.Type() { - case reflect.TypeOf((*sui_types.Argument)(nil)): // nest result - unresolvedParameter.Arguments[0] = &UnresolvedArgument{Argument: reflectValue.Interface().(*sui_types.Argument)} - case reflect.TypeOf(""): // address - unresolvedParameter.Objects[0] = UnresolvedObject{Mutable: false, ObjectId: reflectValue.String()} - default: - return nil, fmt.Errorf("input destination should be address(string) or sui_types.Argument, got %v", reflectValue.Type().String()) - } - - return unresolvedParameter, nil -} - -// Allowed types are sui_types.Argument, string -> object id -func (txb *Transaction) resolveMergeCoinsSources(sources []any) (*UnresolvedParameter, error) { - unresolvedParameter := NewUnresolvedParameter(len(sources)) - - for idx, source := range sources { - reflectValue := reflect.ValueOf(source) - switch reflectValue.Type() { - case reflect.TypeOf((*sui_types.Argument)(nil)): // nest result - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Argument: reflectValue.Interface().(*sui_types.Argument)} - case reflect.TypeOf(""): // object id - unresolvedParameter.Objects[idx] = UnresolvedObject{Mutable: false, ObjectId: reflectValue.String()} - default: - return nil, fmt.Errorf("input source should be address(string) or sui_types.Argument at index %d, got %v", idx, reflectValue.Type().String()) - } - } - - return unresolvedParameter, nil -} - -// Resolve Function -func (txb *Transaction) resolveMoveFunction(pkg, mod, fn string, arguments []interface{}, typeArguments []string) (inputArguments []sui_types.Argument, inputTypeArguments []move_types.TypeTag, returnsCount int, err error) { - normalized, err := txb.client.GetNormalizedMoveFunction(types.GetNormalizedMoveFunctionParams{Package: pkg, Module: mod, Function: fn}) - if err != nil { - return nil, nil, 0, fmt.Errorf("can not call jsonrpc to get normalized move function in command %d: %v", len(txb.builder.Commands), err) - } - - if len(normalized.Parameters) > 0 && isTxContext(normalized.Parameters[len(normalized.Parameters)-1].SuiMoveNormalizedType) { - normalized.Parameters = normalized.Parameters[:len(arguments)] - } - - if len(arguments) != len(normalized.Parameters) || len(typeArguments) != len(normalized.TypeParameters) { - return nil, nil, 0, fmt.Errorf("incorrect number of arguments or type arguments in command %d, required arguments: %d, type arguments: %d", len(txb.builder.Commands), len(normalized.Parameters), len(normalized.TypeParameters)) - } - - inputTypeArguments, err = txb.resolveFunctionTypeArguments(typeArguments) - if err != nil { - return nil, nil, 0, fmt.Errorf("can not resolve function type arguments in command %d: %v", len(txb.builder.Commands), err) - } - - unresolvedParameter, err := txb.resolveFunctionArguments(arguments, normalized.Parameters) - if err != nil { - return nil, nil, 0, fmt.Errorf("can not resolve function arguments in command %d: %v", len(txb.builder.Commands), err) - } - - inputArguments, err = unresolvedParameter.resolveAndPArseToArguments(txb.client, txb) - if err != nil { - return nil, nil, 0, fmt.Errorf("can not parse unresolved parameter to arguments in command %d: %v", len(txb.builder.Commands), err) - } - return inputArguments, inputTypeArguments, len(normalized.Return), nil -} - -func (txb *Transaction) resolveFunctionArguments(inputArguments []interface{}, requiredArguments []*types.SuiMoveNormalizedTypeWrapper) (*UnresolvedParameter, error) { - unresolvedParameter := NewUnresolvedParameter(len(requiredArguments)) - for idx, parameter := range requiredArguments { - reflecetInput := reflect.ValueOf(inputArguments[idx]) - if reflecetInput.Type() == reflect.TypeOf((*sui_types.Argument)(nil)) { - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Argument: reflecetInput.Interface().(*sui_types.Argument)} - continue - } - - reflectParameter := reflect.ValueOf(parameter.SuiMoveNormalizedType) - - switch reflectParameter.Type() { - case reflect.TypeOf(types.SuiMoveNormalizedType_Vector{}): - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Pure: inputArguments[idx]} - case reflect.TypeOf(types.SuiMoveNormalizedType_String("")): - // Here we are only supporting pure types - switch reflectParameter.String() { - case "Bool", "U8", "U16", "U32", "U64", "U128", "U256": - if reflecetInput.Kind() == reflect.String { - return nil, fmt.Errorf("input parameter must be bool or unsigned integer at index %d, got %v", idx, reflecetInput.Type()) - } - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Pure: inputArguments[idx]} - case "Address": - address, err := sui_types.NewAddressFromHex(utils.NormalizeSuiAddress(inputArguments[idx].(string))) - if err != nil { - return nil, fmt.Errorf("input parameter must conform to the address(string) at index %d, got %v", idx, inputArguments[idx]) - } - unresolvedParameter.Arguments[idx] = &UnresolvedArgument{Pure: address} - default: - return nil, fmt.Errorf("function string parameter [%v] is not supported at index %d", reflectParameter.String(), idx) - } - default: - if reflecetInput.Type().Kind() != reflect.String { - return nil, fmt.Errorf("input parameter must be address(string) at index %d, got %v", idx, reflecetInput.Type()) - } - switch reflectParameter.Type() { - case reflect.TypeOf(types.SuiMoveNormalizedType_Reference{}): - unresolvedParameter.Objects[idx] = UnresolvedObject{Mutable: false, ObjectId: inputArguments[idx].(string)} - case reflect.TypeOf(types.SuiMoveNormalizedType_MutableReference{}): - unresolvedParameter.Objects[idx] = UnresolvedObject{Mutable: true, ObjectId: inputArguments[idx].(string)} - case reflect.TypeOf(types.SuiMoveNormalizedType_Struct{}): - unresolvedParameter.Objects[idx] = UnresolvedObject{Mutable: false, ObjectId: inputArguments[idx].(string)} - default: - return nil, fmt.Errorf("function parameter [%v] is not supported at index %d", reflectParameter.Type(), idx) - } - } - } - return unresolvedParameter, nil -} - -func (txb *Transaction) resolveFunctionTypeArguments(typeArguments []string) (inputTypeArguments []move_types.TypeTag, err error) { - inputTypeArguments = []move_types.TypeTag{} - - for idx, arg := range typeArguments { - entry := strings.Split(arg, "::") - if len(entry) != 3 { - return nil, fmt.Errorf("input type arguments at index %d must be in the format 'address::module::name', got [%v]", idx, arg) - } - - object, err := sui_types.NewObjectIdFromHex(entry[0]) - if err != nil { - return nil, fmt.Errorf("input type arguments at index %d must be in the format 'address::module::name', got [%v]: %v", idx, entry[0], err) - } - - typeTag := move_types.TypeTag{ - Struct: &move_types.StructTag{ - Address: *object, - Module: move_types.Identifier(entry[1]), - Name: move_types.Identifier(entry[2]), - }, - } - inputTypeArguments = append(inputTypeArguments, typeTag) - } - return -} - -// Convert ObjectResponse to ObjectArg -func objectResponseToObjectArg(data *types.SuiObjectResponse, mutable bool) (*sui_types.ObjectArg, error) { - if data == nil || data.Data == nil { - return nil, fmt.Errorf("invalid object response") - } - - objectArg := new(sui_types.ObjectArg) - - id, err := sui_types.NewObjectIdFromHex(data.Data.ObjectId) - if err != nil { - return nil, fmt.Errorf("object id [%s] must be sui address: %v", data.Data.ObjectId, err) - } - - owner := data.Data.Owner.ObjectOwner - switch owner := owner.(type) { - case types.ObjectOwner_Shared: - // Shared object: just set the initial shared version - objectArg.SharedObject = &struct { - Id move_types.AccountAddress - InitialSharedVersion uint64 - Mutable bool - }{ - Id: *id, - InitialSharedVersion: owner.Shared.InitialSharedVersion, - Mutable: mutable, - } - default: - // Other object: set the version and digest - objectRef, err := ObjectStringRef{ObjectId: data.Data.ObjectId, Version: data.Data.Version, Digest: data.Data.Digest}.ToObjectRef() - if err != nil { - return nil, fmt.Errorf("can not convert object ref: %v", err) - } - - objectArg.ImmOrOwnedObject = objectRef - } - - return objectArg, nil -} diff --git a/gmsui/transactions/object_ref.go b/gmsui/transactions/object_ref.go deleted file mode 100644 index d17ce48..0000000 --- a/gmsui/transactions/object_ref.go +++ /dev/null @@ -1,36 +0,0 @@ -package transactions - -import ( - "fmt" - "strconv" - - "github.com/W3Tools/go-modules/gmsui/types" - "github.com/W3Tools/go-sui-sdk/v2/sui_types" -) - -type ObjectStringRef struct { - ObjectId string `json:"objectId"` - Version string `json:"version"` - Digest string `json:"digest"` -} - -func (ref ObjectStringRef) ToObjectRef() (*sui_types.ObjectRef, error) { - objectId, err := sui_types.NewObjectIdFromHex(ref.ObjectId) - if err != nil { - return nil, fmt.Errorf("can not create object id from hex [%s]: %v", ref.ObjectId, err) - } - digest, err := sui_types.NewDigest(ref.Digest) - if err != nil { - return nil, fmt.Errorf("can not create digest [%s]: %v", ref.Digest, err) - } - version, err := strconv.ParseUint(ref.Version, 10, 64) - if err != nil { - return nil, fmt.Errorf("can not parse version [%s] to uint64: %v", ref.Version, err) - } - - return &sui_types.ObjectRef{ObjectId: *objectId, Version: version, Digest: *digest}, nil -} - -func coinStructToObjectRef(coin types.CoinStruct) (*sui_types.ObjectRef, error) { - return ObjectStringRef{ObjectId: coin.CoinObjectId, Version: coin.Version, Digest: coin.Digest}.ToObjectRef() -} diff --git a/gmsui/transactions/parameter.go b/gmsui/transactions/parameter.go deleted file mode 100644 index 4cde2a4..0000000 --- a/gmsui/transactions/parameter.go +++ /dev/null @@ -1,123 +0,0 @@ -package transactions - -import ( - "fmt" - - "github.com/W3Tools/go-modules/gmsui/client" - "github.com/W3Tools/go-modules/gmsui/types" - "github.com/W3Tools/go-modules/gmsui/utils" - "github.com/W3Tools/go-sui-sdk/v2/sui_types" -) - -type UnresolvedParameter struct { - Arguments UnresolvedArguments `json:"argument"` - Objects map[int]UnresolvedObject `json:"object"` // map key is index of argument -} - -type UnresolvedArgument struct { - Pure any - Object *sui_types.ObjectArg - Argument *sui_types.Argument -} -type UnresolvedArguments []*UnresolvedArgument - -type UnresolvedObject struct { - ObjectId string - Mutable bool -} - -func NewUnresolvedParameter(count int) *UnresolvedParameter { - return &UnresolvedParameter{ - Arguments: make(UnresolvedArguments, count), - Objects: make(map[int]UnresolvedObject), - } -} - -func (up *UnresolvedParameter) merge(dest *UnresolvedParameter) { - if dest == nil { - return - } - - count := len(up.Arguments) - - up.Arguments = append(up.Arguments, dest.Arguments...) - for idx, obj := range dest.Objects { - up.Objects[idx+count] = obj - } -} - -func (up *UnresolvedParameter) resolveAndPArseToArguments(suiClient *client.SuiClient, txb *Transaction) ([]sui_types.Argument, error) { - err := up.resolveObjects(suiClient) - if err != nil { - return nil, fmt.Errorf("can not resolve objects: %v", err) - } - - return up.toArguments(txb) -} - -func (up *UnresolvedParameter) resolveObjects(suiClient *client.SuiClient) error { - if len(up.Objects) > 0 { - var ids []string - for _, resolve := range up.Objects { - ids = append(ids, resolve.ObjectId) - } - - var objects []*types.SuiObjectResponse - objects, err := suiClient.MultiGetObjects(types.MultiGetObjectsParams{IDs: ids, Options: &types.SuiObjectDataOptions{ShowOwner: true}}) - if err != nil { - return fmt.Errorf("can not call jsonrpc to multi get objects: %v", err) - } - - objectMap := utils.SliceToMap(objects, func(v *types.SuiObjectResponse) string { - if v.Data != nil { - return v.Data.ObjectId - } - return "" - }) - - for idx, resolveObject := range up.Objects { - if idx >= len(up.Arguments) { - return fmt.Errorf("can not resolve object at index %d, out of range", idx) - } - - object := objectMap[utils.NormalizeSuiObjectId(resolveObject.ObjectId)] - if object == nil { - return fmt.Errorf("can not fetch object with id [%s] at index %d", resolveObject.ObjectId, idx) - } - - objectArg, err := objectResponseToObjectArg(object, resolveObject.Mutable) - if err != nil { - return fmt.Errorf("can not convert object response to object arg at index %d: %v", idx, err) - } - - up.Arguments[idx] = &UnresolvedArgument{Object: objectArg} - } - } - - return nil -} - -func (up *UnresolvedParameter) toArguments(txb *Transaction) ([]sui_types.Argument, error) { - arguments := make([]sui_types.Argument, len(up.Arguments)) - for idx, input := range up.Arguments { - if input.Pure != nil { - value, err := txb.builder.Pure(input.Pure) - if err != nil { - return nil, fmt.Errorf("can not create pure argument at index %d: %v", idx, err) - } - arguments[idx] = value - } else if input.Object != nil { - value, err := txb.builder.Obj(*input.Object) - if err != nil { - return nil, fmt.Errorf("can not create object argument at index %d: %v", idx, err) - } - arguments[idx] = value - } else if input.Argument != nil { - arguments[idx] = *input.Argument - } else { - return nil, fmt.Errorf("invalid input argument at index: %v, pure: %v, object: %v, argument: %v", idx, input.Pure, input.Object, input.Argument) - } - } - - return arguments, nil -} diff --git a/gmsui/transactions/transaction.go b/gmsui/transactions/transaction.go deleted file mode 100644 index 77ccbe9..0000000 --- a/gmsui/transactions/transaction.go +++ /dev/null @@ -1,305 +0,0 @@ -package transactions - -import ( - "context" - "fmt" - "strings" - - "github.com/W3Tools/go-modules/gmsui/client" - "github.com/W3Tools/go-modules/gmsui/types" - "github.com/W3Tools/go-modules/gmsui/utils" - "github.com/W3Tools/go-sui-sdk/v2/move_types" - "github.com/W3Tools/go-sui-sdk/v2/sui_types" - "github.com/fardream/go-bcs/bcs" -) - -type Transaction struct { - client *client.SuiClient - builder *sui_types.ProgrammableTransactionBuilder - ctx context.Context - - Sender *sui_types.SuiAddress `json:"sender"` - GasConfig *GasData `json:"gasConfig"` -} - -type GasData struct { - Budget uint64 `json:"budget"` - Price uint64 `json:"price"` - Owner string `json:"owner"` - Payment []*sui_types.ObjectRef `json:"payment"` -} - -func NewTransaction(client *client.SuiClient) *Transaction { - return &Transaction{ - client: client, - builder: sui_types.NewProgrammableTransactionBuilder(), - ctx: client.Context(), - - GasConfig: new(GasData), - } -} - -func (txb *Transaction) TransactionBuilder() *sui_types.ProgrammableTransactionBuilder { - return txb.builder -} - -func (txb *Transaction) Client() *client.SuiClient { - return txb.client -} - -func (txb *Transaction) Context() context.Context { - return txb.ctx -} - -type TransactionInputGasCoin struct { - GasCoin bool `json:"gasCoin"` -} - -func (txb *Transaction) Gas() *TransactionInputGasCoin { - return &TransactionInputGasCoin{GasCoin: true} -} - -// Split coins into multiple parts -func (txb *Transaction) SplitCoins(coin interface{}, amounts []interface{}) (returnArguments []*sui_types.Argument, err error) { - if len(amounts) == 0 { - return nil, nil - } - - unresolvedParameter, err := txb.resolveSplitCoinsCoin(coin) - if err != nil { - return nil, fmt.Errorf("can not resolve coin in command %d: %v", len(txb.builder.Commands), err) - } - - amountArguments, err := txb.resolveSplitCoinsAmounts(amounts) - if err != nil { - return nil, fmt.Errorf("can not resolve amounts in command %d: %v", len(txb.builder.Commands), err) - } - - unresolvedParameter.merge(amountArguments) - arguments, err := unresolvedParameter.resolveAndPArseToArguments(txb.client, txb) - if err != nil { - return nil, fmt.Errorf("can not resolve and parse to arguments in command %d, err: %v", len(txb.builder.Commands), err) - } - - txb.builder.Command( - sui_types.Command{ - SplitCoins: &struct { - Argument sui_types.Argument - Arguments []sui_types.Argument - }{ - Argument: arguments[0], - Arguments: arguments[1:], - }, - }, - ) - - return txb.createTransactionResult(len(amounts)), nil -} - -// Transfer objects to address -func (txb *Transaction) TransferObjects(objects []interface{}, address interface{}) error { - if len(objects) == 0 { - return nil - } - - unresolvedParameter, err := txb.resolveTransferObjectsObjects(objects) - if err != nil { - return fmt.Errorf("can not resolve objects in command %d: %v", len(txb.builder.Commands), err) - } - - unresolvedAddressArgument, err := txb.resolveTransferObjectsAddress(address) - if err != nil { - return fmt.Errorf("can not resolve address in command %d: %v", len(txb.builder.Commands), err) - } - - unresolvedParameter.merge(unresolvedAddressArgument) - arguments, err := unresolvedParameter.resolveAndPArseToArguments(txb.client, txb) - if err != nil { - return fmt.Errorf("can not resolve and parse to arguments in command %d, err: %v", len(txb.builder.Commands), err) - } - - txb.builder.Command( - sui_types.Command{ - TransferObjects: &struct { - Arguments []sui_types.Argument - Argument sui_types.Argument - }{ - Arguments: arguments[:len(arguments)-1], - Argument: arguments[len(arguments)-1], - }, - }, - ) - - return nil -} - -// Merge Coins into one -func (txb *Transaction) MergeCoins(destination interface{}, sources []interface{}) (err error) { - if len(sources) == 0 { - return nil - } - - unresolvedParameter, err := txb.resolveMergeCoinsDestination(destination) - if err != nil { - return fmt.Errorf("failed to resolve destination in command %d, err: %v", len(txb.builder.Commands), err) - } - - unresolvedSourceParameter, err := txb.resolveMergeCoinsSources(sources) - if err != nil { - return fmt.Errorf("failed to resolve sources in command %d, err: %v", len(txb.builder.Commands), err) - } - - unresolvedParameter.merge(unresolvedSourceParameter) - arguments, err := unresolvedParameter.resolveAndPArseToArguments(txb.client, txb) - if err != nil { - return fmt.Errorf("can not resolve and parse to arguments in command %d, err: %v", len(txb.builder.Commands), err) - } - - txb.builder.Command( - sui_types.Command{ - MergeCoins: &struct { - Argument sui_types.Argument - Arguments []sui_types.Argument - }{ - Argument: arguments[0], - Arguments: arguments[1:], - }, - }, - ) - - return nil -} - -func (txb *Transaction) MoveCall(target string, arguments []interface{}, typeArguments []string) (returnArguments []*sui_types.Argument, err error) { - entry := strings.Split(target, "::") - if len(entry) != 3 { - return nil, fmt.Errorf("invalid target [%s]", target) - } - var pkg, mod, fn = utils.NormalizeSuiObjectId(entry[0]), entry[1], entry[2] - - inputArguments, inputTypeArguments, returnsCount, err := txb.resolveMoveFunction(pkg, mod, fn, arguments, typeArguments) - if err != nil { - return nil, fmt.Errorf("failed to parse function arguments, err: %v", err) - } - - packageId, err := sui_types.NewAddressFromHex(pkg) - if err != nil { - return nil, fmt.Errorf("invalid package address [%v]", err) - } - - txb.builder.Command( - sui_types.Command{ - MoveCall: &sui_types.ProgrammableMoveCall{ - Package: *packageId, - Module: move_types.Identifier(mod), - Function: move_types.Identifier(fn), - Arguments: inputArguments, - TypeArguments: inputTypeArguments, - }, - }, - ) - - return txb.createTransactionResult(returnsCount), nil -} - -func (txb *Transaction) Build(sender string) (*sui_types.TransactionData, []byte, error) { - txb.SetSenderIfNotSet(sender) - - if err := setGasPrice(txb); err != nil { - return nil, nil, fmt.Errorf("can not set gas price when building transaction: %v", err) - } - if err := setGasBudget(txb); err != nil { - return nil, nil, fmt.Errorf("can not set gas budget when building transaction: %v", err) - } - if err := setGasPayment(txb); err != nil { - return nil, nil, fmt.Errorf("can not set gas payment when building transaction: %v", err) - } - - tx := sui_types.NewProgrammable( - *txb.Sender, - txb.GasConfig.Payment, - txb.builder.Finish(), - txb.GasConfig.Budget, - txb.GasConfig.Price, - ) - bs, err := bcs.Marshal(tx) - if err != nil { - return nil, nil, fmt.Errorf("can not marshal transaction: %v", err) - } - return &tx, bs, err -} - -func (txb *Transaction) DryRunTransactionBlock() (*types.DryRunTransactionBlockResponse, error) { - if txb.Sender == nil { - return nil, fmt.Errorf("missing transaction sender") - } - - if err := setGasPrice(txb); err != nil { - return nil, fmt.Errorf("failed to set gas price, err: %v", err) - } - - tx := sui_types.NewProgrammable( - *txb.Sender, - nil, - txb.builder.Finish(), - utils.MAX_GAS, - txb.GasConfig.Price, - ) - bs, err := bcs.Marshal(tx) - if err != nil { - return nil, fmt.Errorf("can not marshal transaction, err: %v", err) - } - - return txb.client.DryRunTransactionBlock(types.DryRunTransactionBlockParams{TransactionBlock: bs}) -} - -func (txb *Transaction) DevInspectTransactionBlock() (*types.DevInspectResults, error) { - if txb.Sender == nil { - return nil, fmt.Errorf("missing transaction sender") - } - - bs, err := bcs.Marshal(txb.builder.Finish()) - if err != nil { - return nil, fmt.Errorf("can not marshal transaction: %v", err) - } - - txBytes := append([]byte{0}, bs...) - return txb.client.DevInspectTransactionBlock(types.DevInspectTransactionBlockParams{Sender: txb.Sender.String(), TransactionBlock: txBytes}) -} - -func (txb *Transaction) SetSender(sender string) { - address, err := sui_types.NewAddressFromHex(sender) - if err != nil { - panic(fmt.Errorf("failed to create address from hex [%s], err: %v", sender, err)) - } - - txb.Sender = address -} - -func (txb *Transaction) SetSenderIfNotSet(sender string) { - if txb.Sender == nil { - txb.SetSender(sender) - } -} - -func (txb *Transaction) SetGasPrice(price uint64) { - txb.GasConfig.Price = price -} - -func (txb *Transaction) SetGasBudget(budget uint64) { - txb.GasConfig.Budget = budget -} - -func (txb *Transaction) SetGasBudgetIfNotSet(budget uint64) { - if txb.GasConfig.Budget == 0 { - txb.GasConfig.Budget = budget - } -} - -func (txb *Transaction) SetGasOwner(owner string) { - txb.GasConfig.Owner = owner -} - -func (txb *Transaction) SetGasPayment(payments []*sui_types.ObjectRef) { - txb.GasConfig.Payment = payments -} diff --git a/gmsui/types/filter.go b/gmsui/types/filter.go deleted file mode 100644 index 8d410ee..0000000 --- a/gmsui/types/filter.go +++ /dev/null @@ -1,43 +0,0 @@ -package types - -type TransactionFilter struct { - Checkpoint *string `json:"Checkpoint,omitempty"` - MoveFunction *TransactionFilter_MoveFunction `json:"MoveFunction,omitempty"` - InputObject *string `json:"InputObject,omitempty"` - ChangedObject *string `json:"ChangedObject,omitempty"` - FromAddress *string `json:"FromAddress,omitempty"` - ToAddress *string `json:"ToAddress,omitempty"` - FromAndToAddress *TransactionFilter_FromAndToAddress `json:"FromAndToAddress,omitempty"` - FromOrToAddress *TransactionFilter_FromOrToAddress `json:"FromOrToAddress,omitempty"` - TransactionKind *string `json:"TransactionKind,omitempty"` - TransactionKindIn []*string `json:"TransactionKindIn,omitempty"` -} - -type SuiObjectDataFilter struct { - *SuiObjectDataFilter_MatchAll - *SuiObjectDataFilter_MatchAny - *SuiObjectDataFilter_MatchNone - *SuiObjectDataFilter_Package - *SuiObjectDataFilter_MoveModule - *SuiObjectDataFilter_StructType - *SuiObjectDataFilter_AddressOwner - *SuiObjectDataFilter_ObjectOwner - *SuiObjectDataFilter_ObjectId - *SuiObjectDataFilter_ObjectIds - *SuiObjectDataFilter_Version -} - -type SuiEventFilter struct { - Sender *string `json:"Sender,omitempty"` - Transaction *string `json:"Transaction,omitempty"` - Package *string `json:"Package,omitempty"` - MoveModule *SuiEventFilter_MoveModule `json:"MoveModule,omitempty"` - MoveEventType *string `json:"MoveEventType,omitempty"` - MoveEventModule *SuiEventFilter_MoveEventModule `json:"MoveEventModule,omitempty"` - MoveEventField *SuiEventFilter_MoveEventField `json:"MoveEventField,omitempty"` - TimeRange *SuiEventFilter_TimeRange `json:"TimeRange,omitempty"` - All *SuiEventFilters `json:"All,omitempty"` - Any *SuiEventFilters `json:"Any,omitempty"` - And *SuiEventFilters `json:"And,omitempty"` - Or *SuiEventFilters `json:"Or,omitempty"` -} diff --git a/gmsui/types/input_object_kind.go b/gmsui/types/input_object_kind.go deleted file mode 100644 index 13b2248..0000000 --- a/gmsui/types/input_object_kind.go +++ /dev/null @@ -1,87 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type InputObjectKind interface { - isInputObjectKind() -} - -type InputObjectKindMovePackage struct { - MovePackage string `json:"MovePackage"` -} - -type InputObjectKindImmOrOwnedMoveObject struct { - ImmOrOwnedMoveObject SuiObjectRef `json:"ImmOrOwnedMoveObject"` -} - -type InputObjectKindSharedMoveObject struct { - SharedMoveObject KindSharedMoveObject `json:"SharedMoveObject"` -} - -type KindSharedMoveObject struct { - ID string `json:"id"` - InitialSharedVersion string `json:"initial_shared_version"` - Mutable bool `json:"mutable,omitempty"` -} - -func (InputObjectKindMovePackage) isInputObjectKind() {} -func (InputObjectKindImmOrOwnedMoveObject) isInputObjectKind() {} -func (InputObjectKindSharedMoveObject) isInputObjectKind() {} - -type InputObjectKindWrapper struct { - InputObjectKind -} - -func (w *InputObjectKindWrapper) UnmarshalJSON(data []byte) error { - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - switch { - case obj["MovePackage"] != nil: - var s InputObjectKindMovePackage - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.InputObjectKind = s - case obj["ImmOrOwnedMoveObject"] != nil: - var s InputObjectKindImmOrOwnedMoveObject - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.InputObjectKind = s - case obj["SharedMoveObject"] != nil: - var s InputObjectKindSharedMoveObject - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.InputObjectKind = s - default: - return errors.New("unknown InputObjectKind type") - } - - return nil -} - -func (w *InputObjectKindWrapper) MarshalJSON() ([]byte, error) { - switch t := w.InputObjectKind.(type) { - case InputObjectKindMovePackage: - return json.Marshal(InputObjectKindMovePackage{ - MovePackage: t.MovePackage, - }) - case InputObjectKindImmOrOwnedMoveObject: - return json.Marshal(InputObjectKindImmOrOwnedMoveObject{ - ImmOrOwnedMoveObject: t.ImmOrOwnedMoveObject, - }) - case InputObjectKindSharedMoveObject: - return json.Marshal(InputObjectKindSharedMoveObject{ - SharedMoveObject: t.SharedMoveObject, - }) - default: - return nil, errors.New("unknown InputObjectKind type") - } -} diff --git a/gmsui/types/move_struct.go b/gmsui/types/move_struct.go deleted file mode 100644 index 5fcc07c..0000000 --- a/gmsui/types/move_struct.go +++ /dev/null @@ -1,215 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type MoveStruct interface { - isMoveStruct() - isMoveValue() -} - -type MoveStruct_MoveValue []MoveValueWrapper - -type MoveStruct_FieldsType struct { - Type string `json:"type"` - Fields map[string]MoveValueWrapper `json:"fields"` -} - -type MoveStruct_Map map[string]MoveValueWrapper - -func (MoveStruct_MoveValue) isMoveStruct() {} -func (MoveStruct_FieldsType) isMoveStruct() {} -func (MoveStruct_Map) isMoveStruct() {} - -func (MoveStruct_MoveValue) isMoveValue() {} -func (MoveStruct_FieldsType) isMoveValue() {} -func (MoveStruct_Map) isMoveValue() {} - -type MoveStructWrapper struct { - MoveStruct -} - -func (w *MoveStructWrapper) UnmarshalJSON(data []byte) error { - var mvs MoveStruct_MoveValue - if err := json.Unmarshal(data, &mvs); err == nil { - w.MoveStruct = mvs - return nil - } - - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - if _, ok := obj["fields"]; ok { - var ms MoveStruct_FieldsType - if err := json.Unmarshal(data, &ms); err != nil { - return err - } - w.MoveStruct = ms - return nil - } else { - var ms MoveStruct_Map - if err := json.Unmarshal(data, &ms); err != nil { - return err - } - w.MoveStruct = ms - return nil - } -} - -func (w MoveStructWrapper) MarshalJSON() ([]byte, error) { - switch v := w.MoveStruct.(type) { - case MoveStruct_MoveValue: - return json.Marshal([]MoveValueWrapper(v)) - case MoveStruct_FieldsType: - return json.Marshal(MoveStruct_FieldsType{Fields: v.Fields, Type: v.Type}) - case MoveStruct_Map: - return json.Marshal(v) - default: - return nil, errors.New("unknown MoveStruct type") - } -} - -// ---------- Move Value ----------- -type MoveValue interface { - isMoveValue() -} - -type MoveNumberValue uint64 -type MoveBooleanValue bool -type MoveStringValue string -type MoveValue_MoveValues []MoveValueWrapper -type MoveIdValue struct { - Id string `json:"id"` -} -type MoveStructValue MoveStruct - -func (MoveNumberValue) isMoveValue() {} -func (MoveBooleanValue) isMoveValue() {} -func (MoveStringValue) isMoveValue() {} -func (MoveValue_MoveValues) isMoveValue() {} -func (MoveIdValue) isMoveValue() {} - -type MoveValueWrapper struct { - MoveValue -} - -func (w *MoveValueWrapper) UnmarshalJSON(data []byte) error { - var num uint64 - if err := json.Unmarshal(data, &num); err == nil { - w.MoveValue = MoveNumberValue(num) - return nil - } - var bol bool - if err := json.Unmarshal(data, &bol); err == nil { - w.MoveValue = MoveBooleanValue(bol) - return nil - } - - var str string - if err := json.Unmarshal(data, &str); err == nil { - w.MoveValue = MoveStringValue(str) - return nil - } - - var mvs []MoveValueWrapper - if err := json.Unmarshal(data, &mvs); err == nil { - w.MoveValue = MoveValue_MoveValues(mvs) - return nil - } - - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - if _, ok := obj["id"]; ok { - var mid MoveIdValue - if err := json.Unmarshal(data, &mid); err == nil { - w.MoveValue = mid - return nil - } - } else { - var ms MoveStructWrapper - if err := json.Unmarshal(data, &ms); err == nil { - w.MoveValue = MoveStructValue(ms) - return nil - } - } - - return errors.New("unknown MoveValue type") -} - -func (w MoveValueWrapper) MarshalJSON() ([]byte, error) { - switch v := w.MoveValue.(type) { - case MoveNumberValue: - return json.Marshal(uint64(v)) - case MoveBooleanValue: - return json.Marshal(bool(v)) - case MoveStringValue: - return json.Marshal(string(v)) - case MoveIdValue: - return json.Marshal(MoveIdValue{Id: v.Id}) - case MoveStructValue: - return json.Marshal(MoveStruct(v)) - case MoveValue_MoveValues: - return json.Marshal(v) - default: - return nil, errors.New("unknown MoveValue type") - } -} - -// ------------------SuiMoveFunctionArgType------------------ -type SuiMoveFunctionArgType interface { - isSuiMoveFunctionArgType() -} - -type SuiMoveFunctionArgStringType string -type SuiMoveFunctionArgObjectType struct { - Object ObjectValueKind `json:"Object"` -} - -func (SuiMoveFunctionArgStringType) isSuiMoveFunctionArgType() {} -func (SuiMoveFunctionArgObjectType) isSuiMoveFunctionArgType() {} - -type SuiMoveFunctionArgTypeWrapper struct { - SuiMoveFunctionArgType -} - -func (w *SuiMoveFunctionArgTypeWrapper) UnmarshalJSON(data []byte) error { - var str string - if err := json.Unmarshal(data, &str); err == nil { - w.SuiMoveFunctionArgType = SuiMoveFunctionArgStringType(str) - return nil - } - - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - if _, ok := obj["Object"]; ok { - var at SuiMoveFunctionArgObjectType - if err := json.Unmarshal(data, &at); err != nil { - return err - } - - w.SuiMoveFunctionArgType = at - return nil - } - - return errors.New("unknown SuiMoveFunctionArgType type") -} - -func (w SuiMoveFunctionArgTypeWrapper) MarshalJSON() ([]byte, error) { - switch v := w.SuiMoveFunctionArgType.(type) { - case SuiMoveFunctionArgStringType: - return json.Marshal(string(v)) - case SuiMoveFunctionArgObjectType: - return json.Marshal(SuiMoveFunctionArgObjectType{Object: v.Object}) - default: - return nil, errors.New("unknown SuiMoveFunctionArgType type") - } -} diff --git a/gmsui/types/object_owner.go b/gmsui/types/object_owner.go deleted file mode 100644 index 7791082..0000000 --- a/gmsui/types/object_owner.go +++ /dev/null @@ -1,96 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type ObjectOwner interface { - isObjectOwner() -} - -type ObjectOwner_AddressOwner struct { - AddressOwner string `json:"AddressOwner"` -} - -type ObjectOwner_ObjectOwner struct { - ObjectOwner string `json:"ObjectOwner"` -} - -type ObjectOwner_Shared struct { - Shared ObjectOwner_SharedData `json:"Shared"` -} - -type ObjectOwner_SharedData struct { - InitialSharedVersion uint64 `json:"initial_shared_version"` -} - -type ObjectOwner_Immutable string - -func (ObjectOwner_AddressOwner) isObjectOwner() {} -func (ObjectOwner_ObjectOwner) isObjectOwner() {} -func (ObjectOwner_Shared) isObjectOwner() {} -func (ObjectOwner_Immutable) isObjectOwner() {} - -type ObjectOwnerWrapper struct { - ObjectOwner -} - -// UnmarshalJSON custom unmarshaller for ObjectOwnerWrapper -func (w *ObjectOwnerWrapper) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err == nil { - w.ObjectOwner = ObjectOwner_Immutable(s) - return nil - } - - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - if addressOwner, ok := obj["AddressOwner"]; ok { - var o ObjectOwner_AddressOwner - if err := json.Unmarshal(addressOwner, &o.AddressOwner); err != nil { - return err - } - w.ObjectOwner = o - return nil - } - - if objectOwner, ok := obj["ObjectOwner"]; ok { - var o ObjectOwner_ObjectOwner - if err := json.Unmarshal(objectOwner, &o.ObjectOwner); err != nil { - return err - } - w.ObjectOwner = o - return nil - } - - if shared, ok := obj["Shared"]; ok { - var o ObjectOwner_Shared - if err := json.Unmarshal(shared, &o.Shared); err != nil { - return err - } - - w.ObjectOwner = o - return nil - } - - return errors.New("unknown ObjectOwner type") -} - -func (w ObjectOwnerWrapper) MarshalJSON() ([]byte, error) { - switch o := w.ObjectOwner.(type) { - case ObjectOwner_AddressOwner: - return json.Marshal(ObjectOwner_AddressOwner{AddressOwner: o.AddressOwner}) - case ObjectOwner_ObjectOwner: - return json.Marshal(ObjectOwner_ObjectOwner{ObjectOwner: o.ObjectOwner}) - case ObjectOwner_Shared: - return json.Marshal(ObjectOwner_Shared{Shared: o.Shared}) - case ObjectOwner_Immutable: - return json.Marshal(string(o)) - default: - return nil, errors.New("unknown ObjectOwner type") - } -} diff --git a/gmsui/types/object_read.go b/gmsui/types/object_read.go deleted file mode 100644 index 068516c..0000000 --- a/gmsui/types/object_read.go +++ /dev/null @@ -1,116 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type ObjectRead interface { - isObjectRead() -} - -type ObjectReadVersionFound struct { - Details SuiObjectData `json:"detail"` - Status string `json:"status"` -} - -type ObjectReadObjectNotExists struct { - Details string `json:"detail"` - Status string `json:"status"` -} - -type ObjectReadObjectDeleted struct { - Details SuiObjectRef `json:"detail"` - Status string `json:"status"` -} - -type ObjectReadVersionNotFound struct { - Details [2]string `json:"detail"` - Status string `json:"status"` -} - -type ObjectReadVersionTooHigh struct { - Details VersionTooHighDetails `json:"detail"` - Status string `json:"status"` -} - -type VersionTooHighDetails struct { - AskedVersion string `json:"asked_version"` - LatestVersion string `json:"latest_version"` - ObjectID string `json:"object_id"` -} - -func (ObjectReadVersionFound) isObjectRead() {} -func (ObjectReadObjectNotExists) isObjectRead() {} -func (ObjectReadObjectDeleted) isObjectRead() {} -func (ObjectReadVersionNotFound) isObjectRead() {} -func (ObjectReadVersionTooHigh) isObjectRead() {} - -type ObjectReadWrapper struct { - ObjectRead -} - -func (w *ObjectReadWrapper) UnmarshalJSON(data []byte) error { - type Status struct { - Status string `json:"status"` - } - - var status Status - if err := json.Unmarshal(data, &status); err != nil { - return err - } - - switch status.Status { - case "VersionFound": - var or ObjectReadVersionFound - if err := json.Unmarshal(data, &or); err != nil { - return err - } - w.ObjectRead = or - case "ObjectNotExists": - var or ObjectReadObjectNotExists - if err := json.Unmarshal(data, &or); err != nil { - return err - } - w.ObjectRead = or - case "ObjectDeleted": - var or ObjectReadObjectDeleted - if err := json.Unmarshal(data, &or); err != nil { - return err - } - w.ObjectRead = or - case "VersionNotFound": - var or ObjectReadVersionNotFound - if err := json.Unmarshal(data, &or); err != nil { - return err - } - w.ObjectRead = or - case "VersionTooHigh": - var or ObjectReadVersionTooHigh - if err := json.Unmarshal(data, &or); err != nil { - return err - } - w.ObjectRead = or - default: - return errors.New("unknown ObjectRead type") - } - - return nil -} - -func (w ObjectReadWrapper) MarshalJSON() ([]byte, error) { - switch obj := w.ObjectRead.(type) { - case ObjectReadVersionFound: - return json.Marshal(ObjectReadVersionFound{Details: obj.Details, Status: obj.Status}) - case ObjectReadObjectNotExists: - return json.Marshal(ObjectReadObjectNotExists{Details: obj.Details, Status: obj.Status}) - case ObjectReadObjectDeleted: - return json.Marshal(ObjectReadObjectDeleted{Details: obj.Details, Status: obj.Status}) - case ObjectReadVersionNotFound: - return json.Marshal(ObjectReadVersionNotFound{Details: obj.Details, Status: obj.Status}) - case ObjectReadVersionTooHigh: - return json.Marshal(ObjectReadVersionTooHigh{Details: obj.Details, Status: obj.Status}) - default: - return nil, errors.New("unknown ObjectRead type") - } -} diff --git a/gmsui/types/object_response_error.go b/gmsui/types/object_response_error.go deleted file mode 100644 index 4f599c5..0000000 --- a/gmsui/types/object_response_error.go +++ /dev/null @@ -1,119 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type ObjectResponseError interface { - isObjectResponseError() -} - -type ObjectResponseNotExistsError struct { - Code string `json:"code"` - ObjectId string `json:"object_id"` -} - -type ObjectResponseDynamicFieldNotFoundError struct { - Code string `json:"code"` - ParentObjectId string `json:"parent_object_id"` -} - -type ObjectResponseDeletedError struct { - Code string `json:"code"` - Digest string `json:"digest"` - ObjectId string `json:"object_id"` - Version uint64 `json:"version"` -} - -type ObjectResponseUnknownError struct { - Code string `json:"code"` -} - -type ObjectResponseDisplayErrorError struct { - Code string `json:"code"` - Error string `json:"error"` -} - -func (ObjectResponseNotExistsError) isObjectResponseError() {} -func (ObjectResponseDynamicFieldNotFoundError) isObjectResponseError() {} -func (ObjectResponseDeletedError) isObjectResponseError() {} -func (ObjectResponseUnknownError) isObjectResponseError() {} -func (ObjectResponseDisplayErrorError) isObjectResponseError() {} - -type ObjectResponseErrorWrapper struct { - ObjectResponseError -} - -func (w *ObjectResponseErrorWrapper) UnmarshalJSON(data []byte) error { - type ErrorCode struct { - Code string `json:"code"` - } - - var errorCode ErrorCode - if err := json.Unmarshal(data, &errorCode); err != nil { - return err - } - - switch errorCode.Code { - case "notExists": - var e ObjectResponseNotExistsError - if err := json.Unmarshal(data, &e); err != nil { - return err - } - - w.ObjectResponseError = e - return nil - case "deleted": - var e ObjectResponseDeletedError - if err := json.Unmarshal(data, &e); err != nil { - return err - } - - w.ObjectResponseError = e - return nil - case "dynamicFieldNotFound": - var e ObjectResponseDynamicFieldNotFoundError - if err := json.Unmarshal(data, &e); err != nil { - return err - } - - w.ObjectResponseError = e - return nil - case "unknown": - var e ObjectResponseUnknownError - if err := json.Unmarshal(data, &e); err != nil { - return err - } - - w.ObjectResponseError = e - return nil - case "displayError": - var e ObjectResponseDisplayErrorError - if err := json.Unmarshal(data, &e); err != nil { - return err - } - - w.ObjectResponseError = e - return nil - default: - return errors.New("unknown ObjectResponseError type") - } -} - -func (w *ObjectResponseErrorWrapper) MarshalJSON() ([]byte, error) { - switch e := w.ObjectResponseError.(type) { - case ObjectResponseNotExistsError: - return json.Marshal(ObjectResponseNotExistsError{Code: e.Code, ObjectId: e.ObjectId}) - case ObjectResponseDynamicFieldNotFoundError: - return json.Marshal(ObjectResponseDynamicFieldNotFoundError{Code: e.Code, ParentObjectId: e.ParentObjectId}) - case ObjectResponseDeletedError: - return json.Marshal(ObjectResponseDeletedError{Code: e.Code, Digest: e.Digest, ObjectId: e.ObjectId, Version: e.Version}) - case ObjectResponseUnknownError: - return json.Marshal(ObjectResponseUnknownError{Code: e.Code}) - case ObjectResponseDisplayErrorError: - return json.Marshal(ObjectResponseDisplayErrorError{Code: e.Code, Error: e.Error}) - default: - return nil, errors.New("unknown ObjectResponseError type") - } -} diff --git a/gmsui/types/params.go b/gmsui/types/params.go deleted file mode 100644 index 969b709..0000000 --- a/gmsui/types/params.go +++ /dev/null @@ -1,280 +0,0 @@ -package types - -import "github.com/W3Tools/go-modules/gmsui/cryptography" - -type GetCoinsParams struct { - Owner string `json:"owner"` - CoinType *string `json:"coinType,omitempty"` - Cursor *string `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` -} - -type GetAllCoinsParams struct { - Owner string `json:"owner"` - Cursor *string `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` -} - -type GetBalanceParams struct { - Owner string `json:"owner"` - CoinType *string `json:"coinType,omitempty"` -} - -type GetAllBalancesParams struct { - Owner string `json:"owner"` -} - -type GetCoinMetadataParams struct { - CoinType string `json:"coinType"` -} - -type GetTotalSupplyParams struct { - CoinType string `json:"coinType"` -} - -type GetObjectParams struct { - ID string `json:"id"` - Options *SuiObjectDataOptions `json:"options,omitempty"` -} - -type MultiGetObjectsParams struct { - IDs []string `json:"ids"` - Options *SuiObjectDataOptions `json:"options,omitempty"` -} - -type GetOwnedObjectsParams struct { - Owner string `json:"owner"` - Cursor *string `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` - SuiObjectResponseQuery SuiObjectResponseQuery `json:",inline"` -} - -type TryGetPastObjectParams struct { - ID string `json:"id"` - Version int `json:"version"` - Options *SuiObjectDataOptions `json:"options,omitempty"` -} - -type GetDynamicFieldsParams struct { - ParentId string `json:"parentId"` - Cursor *string `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` -} - -type GetDynamicFieldObjectParams struct { - ParentId string `json:"parentId"` - Name DynamicFieldName `json:"name"` -} - -type GetTransactionBlockParams struct { - Digest string `json:"digest"` - Options *SuiTransactionBlockResponseOptions `json:"options,omitempty"` -} - -type MultiGetTransactionBlocksParams struct { - Digests []string `json:"digests"` - Options *SuiTransactionBlockResponseOptions `json:"options,omitempty"` -} - -type QueryTransactionBlocksParams struct { - Cursor *string `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` - Order *QueryTransactionBlocksParams_Order `json:"order,omitempty"` - SuiTransactionBlockResponseQuery SuiTransactionBlockResponseQuery `json:",inline"` -} - -type QueryEventsParams struct { - Query SuiEventFilter `json:"query"` - Cursor *EventId `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` - Order *QueryTransactionBlocksParams_Order `json:"order,omitempty"` -} - -type GetProtocolConfigParams struct { - Version *string `json:"version,omitempty"` -} - -type GetCheckpointParams struct { - ID CheckpointId `json:"id"` -} - -type GetCheckpointsParams struct { - Cursor *string `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` - DescendingOrder bool `json:"descendingOrder"` -} - -type GetCommitteeInfoParams struct { - Epoch *string `json:"epoch,omitempty"` -} - -type SubscribeEventParams struct { - Filter SuiEventFilter `json:"filter"` -} - -type SubscribeTransactionParams struct { - Filter TransactionFilter `json:"filter"` -} - -type GetStakesParams struct { - Owner string `json:"owner"` -} - -type GetStakesByIdsParams struct { - StakedSuiIds []string `json:"stakedSuiIds"` -} - -type ResolveNameServiceNamesParams struct { - Address string `json:"address"` - Cursor *string `json:"cursor,omitempty"` - Limit *int `json:"limit,omitempty"` -} - -type GetMoveFunctionArgTypesParams struct { - Package string `json:"package"` - Module string `json:"module"` - Function string `json:"function"` -} - -type GetNormalizedMoveModulesByPackageParams struct { - Package string `json:"package"` -} - -type GetNormalizedMoveModuleParams struct { - Package string `json:"package"` - Module string `json:"module"` -} - -type GetNormalizedMoveFunctionParams struct { - Package string `json:"package"` - Module string `json:"module"` - Function string `json:"function"` -} - -type GetNormalizedMoveStructParams struct { - Package string `json:"package"` - Module string `json:"module"` - Struct string `json:"struct"` -} - -type ResolveNameServiceAddressParams struct { - Name string `json:"name"` -} - -type DryRunTransactionBlockParams struct { - TransactionBlock []byte `json:"transactionBlock"` -} - -type DevInspectTransactionBlockParams struct { - Sender string `json:"sender"` - TransactionBlock interface{} `json:"transactionBlock"` - GasPrice *uint64 `json:"gasPrice,omitempty"` - Epoch *string `json:"epoch,omitempty"` -} - -type ExecuteTransactionBlockParams struct { - TransactionBlock []byte `json:"transactionBlock"` - Signature []string `json:"signature"` - Options *SuiTransactionBlockResponseOptions `json:"options,omitempty"` - RequestType *ExecuteTransactionRequestType `json:"requestType,omitempty"` -} - -type SignAndExecuteTransactionBlockParams struct { - TransactionBlock []byte `json:"transactionBlock"` - Signer cryptography.Signer `json:"signer"` - Options *SuiTransactionBlockResponseOptions `json:"options,omitempty"` - RequestType *ExecuteTransactionRequestType `json:"requestType,omitempty"` -} - -type SuiObjectDataFilter_MatchAll struct { - MatchAll []SuiObjectDataFilter `json:"MatchAll"` -} - -type SuiObjectDataFilter_MatchAny struct { - MatchAny []SuiObjectDataFilter `json:"MatchAny"` -} - -type SuiObjectDataFilter_MatchNone struct { - MatchNone []SuiObjectDataFilter `json:"MatchNone"` -} - -type SuiObjectDataFilter_Package struct { - Package string `json:"Package"` -} - -type SuiObjectDataFilter_MoveModule struct { - MoveModule SuiObjectDataFilter_MoveModule_Struct `json:"MoveModule"` -} - -type SuiObjectDataFilter_MoveModule_Struct struct { - Module string `json:"module"` - Package string `json:"package"` -} - -type SuiObjectDataFilter_StructType struct { - StructType string `json:"StructType"` -} - -type SuiObjectDataFilter_AddressOwner struct { - AddressOwner string `json:"AddressOwner"` -} - -type SuiObjectDataFilter_ObjectOwner struct { - ObjectOwner string `json:"ObjectOwner"` -} - -type SuiObjectDataFilter_ObjectId struct { - ObjectId string `json:"ObjectId"` -} - -type SuiObjectDataFilter_ObjectIds struct { - ObjectIds []string `json:"ObjectIds"` -} - -type SuiObjectDataFilter_Version struct { - Version string `json:"Version"` -} - -type QueryTransactionBlocksParams_Order string - -var ( - Ascending QueryTransactionBlocksParams_Order = "ascending" - Descending QueryTransactionBlocksParams_Order = "descending" -) - -type TransactionFilter_MoveFunction struct { - Function *string `json:"function,omitempty"` - Module *string `json:"module,omitempty"` - Package string `json:"package"` -} - -type TransactionFilter_FromAndToAddress struct { - From string `json:"from"` - To string `json:"to"` -} - -type TransactionFilter_FromOrToAddress struct { - Addr string `json:"addr"` -} - -type SuiEventFilter_MoveModule struct { - Module string `json:"module"` - Package string `json:"package"` -} - -type SuiEventFilter_MoveEventModule struct { - Module string `json:"module"` - Package string `json:"package"` -} - -type SuiEventFilter_MoveEventField struct { - Path string `json:"path"` - Value interface{} `json:"value"` -} - -type SuiEventFilter_TimeRange struct { - EndTime string `json:"endTime"` - StartTime string `json:"startTime"` -} - -type SuiEventFilters []SuiEventFilter diff --git a/gmsui/types/parsed_data.go b/gmsui/types/parsed_data.go deleted file mode 100644 index 434c43a..0000000 --- a/gmsui/types/parsed_data.go +++ /dev/null @@ -1,70 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type SuiParsedData interface { - isSuiParsedData() -} - -type SuiParsedMoveObjectData struct { - DataType string `json:"dataType"` - Type string `json:"type"` - HasPublicTransfer bool `json:"hasPublicTransfer"` - Fields MoveStructWrapper `json:"fields"` -} - -type SuiParsedPackageData struct { - DataType string `json:"dataType"` - Disassembled *map[string]interface{} `json:"disassembled,omitempty"` -} - -func (SuiParsedMoveObjectData) isSuiParsedData() {} -func (SuiParsedPackageData) isSuiParsedData() {} - -type SuiParsedDataWrapper struct { - SuiParsedData -} - -func (w *SuiParsedDataWrapper) UnmarshalJSON(data []byte) error { - type DataType struct { - DataType string `json:"dataType"` - } - - var dataType DataType - if err := json.Unmarshal(data, &dataType); err != nil { - return err - } - - switch dataType.DataType { - case "moveObject": - var p SuiParsedMoveObjectData - if err := json.Unmarshal(data, &p); err != nil { - return err - } - w.SuiParsedData = p - return nil - case "package": - var p SuiParsedPackageData - if err := json.Unmarshal(data, &p); err != nil { - return err - } - w.SuiParsedData = p - return nil - default: - return errors.New("unknown SuiParsedData type") - } -} - -func (w *SuiParsedDataWrapper) MarshalJSON() ([]byte, error) { - switch data := w.SuiParsedData.(type) { - case SuiParsedMoveObjectData: - return json.Marshal(SuiParsedMoveObjectData{DataType: data.DataType, Type: data.Type, HasPublicTransfer: data.HasPublicTransfer, Fields: data.Fields}) - case SuiParsedPackageData: - return json.Marshal(SuiParsedPackageData{DataType: data.DataType, Disassembled: data.Disassembled}) - default: - return nil, errors.New("unknown SuiParsedData type") - } -} diff --git a/gmsui/types/protocol_config_value.go b/gmsui/types/protocol_config_value.go deleted file mode 100644 index 72aeabc..0000000 --- a/gmsui/types/protocol_config_value.go +++ /dev/null @@ -1,21 +0,0 @@ -package types - -type ProtocolConfigValue interface { - isProtocolConfigValue() -} - -type ProtocolConfigValue_u32 struct { - U32 string `json:"u32"` -} - -type ProtocolConfigValue_u64 struct { - U64 string `json:"u64"` -} - -type ProtocolConfigValue_f64 struct { - F64 string `json:"f64"` -} - -func (ProtocolConfigValue_u32) isProtocolConfigValue() {} -func (ProtocolConfigValue_u64) isProtocolConfigValue() {} -func (ProtocolConfigValue_f64) isProtocolConfigValue() {} diff --git a/gmsui/types/raw_data.go b/gmsui/types/raw_data.go deleted file mode 100644 index 6257f94..0000000 --- a/gmsui/types/raw_data.go +++ /dev/null @@ -1,87 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type RawData interface { - isRawData() -} - -type RawDataMoveObject struct { - DataType string `json:"dataType"` - Type string `json:"type"` - HasPublicTransfer bool `json:"hasPublicTransfer"` - Version uint64 `json:"version"` - BcsBytes string `json:"bcsBytes"` -} - -type RawDataPackage struct { - DataType string `json:"dataType"` - ID string `json:"id"` - Version uint64 `json:"version"` - ModuleMap map[string]string `json:"moduleMap"` - TypeOriginTable []TypeOrigin `json:"typeOriginTable"` - LinkageTable map[string]UpgradeInfo `json:"linkageTable"` -} - -func (RawDataMoveObject) isRawData() {} -func (RawDataPackage) isRawData() {} - -type RawDataWrapper struct { - RawData -} - -func (w *RawDataWrapper) UnmarshalJSON(data []byte) error { - type DataType struct { - DataType string `json:"dataType"` - } - var dataType DataType - if err := json.Unmarshal(data, &dataType); err != nil { - return err - } - - switch dataType.DataType { - case "moveObject": - var rd RawDataMoveObject - if err := json.Unmarshal(data, &rd); err != nil { - return err - } - w.RawData = rd - case "package": - var rd RawDataPackage - if err := json.Unmarshal(data, &rd); err != nil { - return err - } - w.RawData = rd - default: - return errors.New("unknown RawData type") - } - - return nil -} - -func (w *RawDataWrapper) MarshalJSON() ([]byte, error) { - switch rd := w.RawData.(type) { - case RawDataMoveObject: - return json.Marshal(RawDataMoveObject{ - BcsBytes: rd.BcsBytes, - DataType: rd.DataType, - HasPublicTransfer: rd.HasPublicTransfer, - Type: rd.Type, - Version: rd.Version, - }) - case RawDataPackage: - return json.Marshal(RawDataPackage{ - DataType: rd.DataType, - ID: rd.ID, - LinkageTable: rd.LinkageTable, - ModuleMap: rd.ModuleMap, - TypeOriginTable: rd.TypeOriginTable, - Version: rd.Version, - }) - default: - return nil, errors.New("unknown RawData type") - } -} diff --git a/gmsui/types/signature_type.go b/gmsui/types/signature_type.go deleted file mode 100644 index 4aef625..0000000 --- a/gmsui/types/signature_type.go +++ /dev/null @@ -1,157 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type Signature interface { - isSignature() -} - -type SignatureEd25519 struct { - Ed25519SuiSignature string `json:"Ed25519SuiSignature"` -} - -type SignatureSecp256k1 struct { - Secp256k1SuiSignature string `json:"Secp256k1SuiSignature"` -} - -type SignatureSecp256r1 struct { - Secp256r1SuiSignature string `json:"Secp256r1SuiSignature"` -} - -func (SignatureEd25519) isSignature() {} -func (SignatureSecp256k1) isSignature() {} -func (SignatureSecp256r1) isSignature() {} - -type SignatureWrapper struct { - Signature -} - -func (w *SignatureWrapper) UnmarshalJSON(data []byte) error { - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - switch { - case obj["Ed25519SuiSignature"] != nil: - var s SignatureEd25519 - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.Signature = s - case obj["Secp256k1SuiSignature"] != nil: - var s SignatureSecp256k1 - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.Signature = s - case obj["Secp256r1SuiSignature"] != nil: - var s SignatureSecp256r1 - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.Signature = s - default: - return errors.New("unknown Signature type") - } - - return nil -} - -func (w *SignatureWrapper) MarshalJSON() ([]byte, error) { - switch s := w.Signature.(type) { - case SignatureEd25519: - return json.Marshal(SignatureEd25519{ - Ed25519SuiSignature: s.Ed25519SuiSignature, - }) - case SignatureSecp256k1: - return json.Marshal(SignatureSecp256k1{ - Secp256k1SuiSignature: s.Secp256k1SuiSignature, - }) - case SignatureSecp256r1: - return json.Marshal(SignatureSecp256r1{ - Secp256r1SuiSignature: s.Secp256r1SuiSignature, - }) - default: - return nil, errors.New("unknown Signature type") - } -} - -// --------------CompressedSignature-------------- -type CompressedSignature interface { - isCompressedSignature() -} - -type CompressedSignatureEd25519 struct { - Ed25519 string `json:"Ed25519"` -} - -type CompressedSignatureSecp256k1 struct { - Secp256k1 string `json:"Secp256k1"` -} - -type CompressedSignatureSecp256r1 struct { - Secp256r1 string `json:"Secp256r1"` -} - -func (CompressedSignatureEd25519) isCompressedSignature() {} -func (CompressedSignatureSecp256k1) isCompressedSignature() {} -func (CompressedSignatureSecp256r1) isCompressedSignature() {} - -type CompressedSignatureWrapper struct { - CompressedSignature -} - -func (w *CompressedSignatureWrapper) UnmarshalJSON(data []byte) error { - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - switch { - case obj["Ed25519"] != nil: - var s CompressedSignatureEd25519 - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.CompressedSignature = s - case obj["Secp256k1"] != nil: - var s CompressedSignatureSecp256k1 - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.CompressedSignature = s - case obj["Secp256r1"] != nil: - var s CompressedSignatureSecp256r1 - if err := json.Unmarshal(data, &s); err != nil { - return err - } - w.CompressedSignature = s - default: - return errors.New("unknown CompressedSignature type") - } - - return nil -} - -func (w *CompressedSignatureWrapper) MarshalJSON() ([]byte, error) { - switch s := w.CompressedSignature.(type) { - case CompressedSignatureEd25519: - return json.Marshal(CompressedSignatureEd25519{ - Ed25519: s.Ed25519, - }) - case CompressedSignatureSecp256k1: - return json.Marshal(CompressedSignatureSecp256k1{ - Secp256k1: s.Secp256k1, - }) - case CompressedSignatureSecp256r1: - return json.Marshal(CompressedSignatureSecp256r1{ - Secp256r1: s.Secp256r1, - }) - default: - return nil, errors.New("unknown CompressedSignature type") - } -} diff --git a/gmsui/types/stake_object.go b/gmsui/types/stake_object.go deleted file mode 100644 index 79701d5..0000000 --- a/gmsui/types/stake_object.go +++ /dev/null @@ -1,110 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type StakeObject interface { - isStakeObject() -} - -type StakeObjectPending struct { - Principal string `json:"principal"` - StakeActiveEpoch string `json:"stakeActiveEpoch"` - StakeRequestEpoch string `json:"stakeRequestEpoch"` - StakedSuiId string `json:"stakedSuiId"` - Status string `json:"status"` -} - -type StakeObjectActive struct { - Principal string `json:"principal"` - StakeActiveEpoch string `json:"stakeActiveEpoch"` - StakeRequestEpoch string `json:"stakeRequestEpoch"` - StakedSuiId string `json:"stakedSuiId"` - EstimatedReward string `json:"estimatedReward"` - Status string `json:"status"` -} - -type StakeObjectUnstaked struct { - Principal string `json:"principal"` - StakeActiveEpoch string `json:"stakeActiveEpoch"` - StakeRequestEpoch string `json:"stakeRequestEpoch"` - StakedSuiId string `json:"stakedSuiId"` - Status string `json:"status"` -} - -func (StakeObjectPending) isStakeObject() {} -func (StakeObjectActive) isStakeObject() {} -func (StakeObjectUnstaked) isStakeObject() {} - -type StakeObjectWrapper struct { - StakeObject -} - -func (w *StakeObjectWrapper) UnmarshalJSON(data []byte) error { - type Status struct { - Status string `json:"status"` - } - var status Status - if err := json.Unmarshal(data, &status); err != nil { - return err - } - - switch status.Status { - case "Pending": - var so StakeObjectPending - if err := json.Unmarshal(data, &so); err != nil { - return err - } - w.StakeObject = so - case "Active": - var so StakeObjectActive - if err := json.Unmarshal(data, &so); err != nil { - return err - } - w.StakeObject = so - case "Unstaked": - var so StakeObjectUnstaked - if err := json.Unmarshal(data, &so); err != nil { - return err - } - w.StakeObject = so - default: - return errors.New("unknown StakeObject type") - } - - return nil -} - -func (w *StakeObjectWrapper) MarshalJSON() ([]byte, error) { - switch obj := w.StakeObject.(type) { - case StakeObjectPending: - return json.Marshal(StakeObjectPending{ - Status: obj.Status, - Principal: obj.Principal, - StakeActiveEpoch: obj.StakeActiveEpoch, - StakeRequestEpoch: obj.StakeRequestEpoch, - StakedSuiId: obj.StakedSuiId, - }) - case StakeObjectActive: - return json.Marshal(StakeObjectActive{ - Status: obj.Status, - Principal: obj.Principal, - StakeActiveEpoch: obj.StakeActiveEpoch, - StakeRequestEpoch: obj.StakeRequestEpoch, - StakedSuiId: obj.StakedSuiId, - EstimatedReward: obj.EstimatedReward, - }) - case StakeObjectUnstaked: - return json.Marshal(StakeObjectUnstaked{ - Status: obj.Status, - Principal: obj.Principal, - StakeActiveEpoch: obj.StakeActiveEpoch, - StakeRequestEpoch: obj.StakeRequestEpoch, - StakedSuiId: obj.StakedSuiId, - }) - default: - return nil, errors.New("unknown StakeObject type") - } -} diff --git a/gmsui/types/sui_call_arg.go b/gmsui/types/sui_call_arg.go deleted file mode 100644 index e6fe47b..0000000 --- a/gmsui/types/sui_call_arg.go +++ /dev/null @@ -1,111 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type SuiCallArg interface { - isSuiCallArg() -} - -type SuiCallArgImmOrOwnedObject struct { - Type string `json:"type"` - Digest string `json:"digest"` - ObjectId string `json:"objectId"` - ObjectType string `json:"objectType"` - Version string `json:"version"` -} - -type SuiCallArgSharedObject struct { - Type string `json:"type"` - ObjectType string `json:"objectType"` - ObjectId string `json:"objectId"` - InitialSharedVersion string `json:"initialSharedVersion"` - Mutable bool `json:"mutable"` -} - -type SuiCallArgReceiving struct { - Type string `json:"type"` - Digest string `json:"digest"` - ObjectId string `json:"objectId"` - ObjectType string `json:"objectType"` - Version string `json:"version"` -} - -type SuiCallArgPure struct { - Type string `json:"type"` - ValueType *string `json:"valueType,omitempty"` - Value interface{} `json:"value"` -} - -func (SuiCallArgImmOrOwnedObject) isSuiCallArg() {} -func (SuiCallArgSharedObject) isSuiCallArg() {} -func (SuiCallArgReceiving) isSuiCallArg() {} -func (SuiCallArgPure) isSuiCallArg() {} - -type SuiCallArgWrapper struct { - SuiCallArg -} - -func (w *SuiCallArgWrapper) UnmarshalJSON(data []byte) error { - type Type struct { - Type string `json:"type"` - ObjectType string `json:"objectType"` - } - var argType Type - if err := json.Unmarshal(data, &argType); err != nil { - return err - } - - switch argType.Type { - case "object": - switch argType.ObjectType { - case "immOrOwnedObject": - var a SuiCallArgImmOrOwnedObject - if err := json.Unmarshal(data, &a); err != nil { - return err - } - w.SuiCallArg = a - case "sharedObject": - var a SuiCallArgSharedObject - if err := json.Unmarshal(data, &a); err != nil { - return err - } - w.SuiCallArg = a - case "receiving": - var a SuiCallArgReceiving - if err := json.Unmarshal(data, &a); err != nil { - return err - } - w.SuiCallArg = a - default: - return errors.New("unknown SuiCallArg object type") - } - case "pure": - var a SuiCallArgPure - if err := json.Unmarshal(data, &a); err != nil { - return err - } - w.SuiCallArg = a - default: - return errors.New("unknown SuiCallArg type") - } - - return nil -} - -func (w *SuiCallArgWrapper) MarshalJSON() ([]byte, error) { - switch arg := w.SuiCallArg.(type) { - case SuiCallArgImmOrOwnedObject: - return json.Marshal(arg) - case SuiCallArgSharedObject: - return json.Marshal(arg) - case SuiCallArgReceiving: - return json.Marshal(arg) - case SuiCallArgPure: - return json.Marshal(arg) - default: - return nil, errors.New("unknown SuiCallArg type") - } -} diff --git a/gmsui/types/sui_move_normalized_type.go b/gmsui/types/sui_move_normalized_type.go deleted file mode 100644 index bf12d68..0000000 --- a/gmsui/types/sui_move_normalized_type.go +++ /dev/null @@ -1,129 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type SuiMoveNormalizedType interface { - isSuiMoveNormalizedType() -} - -type SuiMoveNormalizedType_String string - -type SuiMoveNormalizedType_Struct struct { - Struct SuiMoveNormalizedTypeStruct `json:"Struct"` -} - -type SuiMoveNormalizedTypeStruct struct { - Address string `json:"address"` - Module string `json:"module"` - Name string `json:"name"` - TypeArguments []SuiMoveNormalizedTypeWrapper `json:"typeArguments"` -} - -type SuiMoveNormalizedType_Vector struct { - Vector SuiMoveNormalizedTypeWrapper `json:"Vector"` -} - -type SuiMoveNormalizedType_TypeParameter struct { - TypeParameter uint64 `json:"TypeParameter"` -} - -type SuiMoveNormalizedType_Reference struct { - Reference SuiMoveNormalizedTypeWrapper `json:"Reference"` -} - -type SuiMoveNormalizedType_MutableReference struct { - MutableReference SuiMoveNormalizedTypeWrapper `json:"MutableReference"` -} - -func (SuiMoveNormalizedType_String) isSuiMoveNormalizedType() {} -func (SuiMoveNormalizedType_Struct) isSuiMoveNormalizedType() {} -func (SuiMoveNormalizedType_Vector) isSuiMoveNormalizedType() {} -func (SuiMoveNormalizedType_TypeParameter) isSuiMoveNormalizedType() {} -func (SuiMoveNormalizedType_Reference) isSuiMoveNormalizedType() {} -func (SuiMoveNormalizedType_MutableReference) isSuiMoveNormalizedType() {} - -type SuiMoveNormalizedTypeWrapper struct { - SuiMoveNormalizedType -} - -func (w *SuiMoveNormalizedTypeWrapper) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err == nil { - w.SuiMoveNormalizedType = SuiMoveNormalizedType_String(s) - return nil - } - - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - if _struct, ok := obj["Struct"]; ok { - var s SuiMoveNormalizedType_Struct - if err := json.Unmarshal(_struct, &s.Struct); err != nil { - return err - } - w.SuiMoveNormalizedType = s - return nil - } - - if vector, ok := obj["Vector"]; ok { - var s SuiMoveNormalizedType_Vector - if err := json.Unmarshal(vector, &s.Vector); err != nil { - return err - } - w.SuiMoveNormalizedType = s - return nil - } - - if typeParameter, ok := obj["TypeParameter"]; ok { - var s SuiMoveNormalizedType_TypeParameter - if err := json.Unmarshal(typeParameter, &s.TypeParameter); err != nil { - return err - } - w.SuiMoveNormalizedType = s - return nil - } - - if reference, ok := obj["Reference"]; ok { - var s SuiMoveNormalizedType_Reference - if err := json.Unmarshal(reference, &s.Reference); err != nil { - return err - } - w.SuiMoveNormalizedType = s - return nil - } - - if mutableReference, ok := obj["MutableReference"]; ok { - var s SuiMoveNormalizedType_MutableReference - if err := json.Unmarshal(mutableReference, &s.MutableReference); err != nil { - return err - } - w.SuiMoveNormalizedType = s - return nil - } - - return errors.New("unknown SuiMoveNormalizedType type") -} - -func (w SuiMoveNormalizedTypeWrapper) MarshalJSON() ([]byte, error) { - switch t := w.SuiMoveNormalizedType.(type) { - case SuiMoveNormalizedType_String: - return json.Marshal(string(t)) - case SuiMoveNormalizedType_Struct: - return json.Marshal(SuiMoveNormalizedType_Struct{Struct: t.Struct}) - case SuiMoveNormalizedType_Vector: - return json.Marshal(SuiMoveNormalizedType_Vector{Vector: t.Vector}) - case SuiMoveNormalizedType_TypeParameter: - return json.Marshal(SuiMoveNormalizedType_TypeParameter{TypeParameter: t.TypeParameter}) - case SuiMoveNormalizedType_Reference: - return json.Marshal(SuiMoveNormalizedType_Reference{Reference: t.Reference}) - case SuiMoveNormalizedType_MutableReference: - return json.Marshal(SuiMoveNormalizedType_MutableReference{MutableReference: t.MutableReference}) - default: - return nil, errors.New("unknown SuiMoveNormalizedType") - } -} diff --git a/gmsui/types/sui_object_change.go b/gmsui/types/sui_object_change.go deleted file mode 100644 index 73f0e96..0000000 --- a/gmsui/types/sui_object_change.go +++ /dev/null @@ -1,148 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -type SuiObjectChange interface { - isSuiObjectChange() -} - -type SuiObjectChangePublished struct { - Type string `json:"type"` - PackageId string `json:"packageId"` - Version string `json:"version"` - Digest string `json:"digest"` - Modules []string `json:"modules"` -} - -type SuiObjectChangeTransferred struct { - Type string `json:"type"` - Sender string `json:"sender"` - Recipient *ObjectOwnerWrapper `json:"recipient,omitempty"` - ObjectType string `json:"objectType"` - ObjectId string `json:"objectId"` - Version string `json:"version"` - Digest string `json:"digest"` -} - -type SuiObjectChangeMutated struct { - Type string `json:"type"` - Sender string `json:"sender"` - Owner *ObjectOwnerWrapper `json:"owner"` - ObjectType string `json:"objectType"` - ObjectId string `json:"objectId"` - Version string `json:"version"` - PreviousVersion string `json:"previousVersion"` - Digest string `json:"digest"` -} - -type SuiObjectChangeDeleted struct { - Type string `json:"type"` - Sender string `json:"sender"` - ObjectType string `json:"objectType"` - ObjectId string `json:"objectId"` - Version string `json:"version"` -} - -type SuiObjectChangeWrapped struct { - Type string `json:"type"` - Sender string `json:"sender"` - ObjectType string `json:"objectType"` - ObjectId string `json:"objectId"` - Version string `json:"version"` -} - -type SuiObjectChangeCreated struct { - Type string `json:"type"` - Sender string `json:"sender"` - Owner *ObjectOwnerWrapper `json:"owner,omitempty"` - ObjectType string `json:"objectType"` - ObjectId string `json:"objectId"` - Version string `json:"version"` - Digest string `json:"digest"` -} - -func (SuiObjectChangePublished) isSuiObjectChange() {} -func (SuiObjectChangeTransferred) isSuiObjectChange() {} -func (SuiObjectChangeMutated) isSuiObjectChange() {} -func (SuiObjectChangeDeleted) isSuiObjectChange() {} -func (SuiObjectChangeWrapped) isSuiObjectChange() {} -func (SuiObjectChangeCreated) isSuiObjectChange() {} - -type SuiObjectChangeWrapper struct { - SuiObjectChange -} - -func (w *SuiObjectChangeWrapper) UnmarshalJSON(data []byte) error { - type Type struct { - Type string `json:"type"` - } - - var changeType Type - if err := json.Unmarshal(data, &changeType); err != nil { - return err - } - - switch changeType.Type { - case "published": - var c SuiObjectChangePublished - if err := json.Unmarshal(data, &c); err != nil { - return err - } - w.SuiObjectChange = c - case "transferred": - var c SuiObjectChangeTransferred - if err := json.Unmarshal(data, &c); err != nil { - return err - } - w.SuiObjectChange = c - case "mutated": - var c SuiObjectChangeMutated - if err := json.Unmarshal(data, &c); err != nil { - return err - } - w.SuiObjectChange = c - case "deleted": - var c SuiObjectChangeDeleted - if err := json.Unmarshal(data, &c); err != nil { - return err - } - w.SuiObjectChange = c - case "wrapped": - var c SuiObjectChangeWrapped - if err := json.Unmarshal(data, &c); err != nil { - return err - } - w.SuiObjectChange = c - case "created": - var c SuiObjectChangeCreated - if err := json.Unmarshal(data, &c); err != nil { - return err - } - w.SuiObjectChange = c - default: - return errors.New("unknown SuiObjectChange type") - } - return nil -} - -func (w SuiObjectChangeWrapper) MarshalJSON() ([]byte, error) { - switch change := w.SuiObjectChange.(type) { - case SuiObjectChangePublished: - return json.Marshal(change) - case SuiObjectChangeTransferred: - return json.Marshal(change) - case SuiObjectChangeMutated: - return json.Marshal(change) - case SuiObjectChangeDeleted: - return json.Marshal(change) - case SuiObjectChangeWrapped: - return json.Marshal(change) - case SuiObjectChangeCreated: - return json.Marshal(change) - default: - return nil, errors.New("unknown SuiObjectChange type") - } -} diff --git a/gmsui/types/transaction_kind.go b/gmsui/types/transaction_kind.go deleted file mode 100644 index 3fe916c..0000000 --- a/gmsui/types/transaction_kind.go +++ /dev/null @@ -1,543 +0,0 @@ -package types - -import ( - "encoding/json" - "errors" -) - -// -----------SuiTransactionBlockKind----------- -type SuiTransactionBlockKind interface { - isSuiTransactionBlockKind() -} - -type SuiTransactionBlockKindChangeEpoch struct { - ComputationCharge string `json:"computation_charge"` - Epoch string `json:"epoch"` - EpochStartTimestampMs string `json:"epoch_start_timestamp_ms"` - Kind string `json:"kind"` - StorageCharge string `json:"storage_charge"` - StorageRebate string `json:"storage_rebate"` -} - -type SuiTransactionBlockKindGenesis struct { - Kind string `json:"kind"` - Objects []string `json:"objects"` -} - -type SuiTransactionBlockKindConsensusCommitPrologue struct { - CommitTimestampMs string `json:"commit_timestamp_ms"` - Epoch string `json:"epoch"` - Kind string `json:"kind"` - Round string `json:"round"` -} - -type SuiTransactionBlockKindConsensusCommitPrologueV3 struct { - Kind string `json:"kind"` - Epoch string `json:"epoch"` - Round string `json:"round"` - SubDagIndex interface{} `json:"sub_dag_index"` - CommitTimestampMs string `json:"commit_timestamp_ms"` - ConsensusCommitDigest string `json:"consensus_commit_digest"` - ConsensusDeterminedVersionAssignments ConsensusDeterminedVersionAssignments `json:"consensus_determined_version_assignments"` -} - -type ConsensusDeterminedVersionAssignments struct { - CancelledTransactions []interface{} `json:"CancelledTransactions"` -} - -type SuiTransactionBlockKindProgrammableTransaction struct { - Kind string `json:"kind"` - Inputs []SuiCallArgWrapper `json:"inputs"` - Transactions []SuiTransactionWrapper `json:"transactions"` -} - -type SuiTransactionBlockKindAuthenticatorStateUpdate struct { - Epoch string `json:"epoch"` - Kind string `json:"kind"` - NewActiveJwks []SuiActiveJwk `json:"new_active_jwks"` - Round string `json:"round"` -} - -type SuiTransactionBlockKindEndOfEpochTransaction struct { - Kind string `json:"kind"` - Transactions []SuiEndOfEpochTransactionKindWrapper `json:"Transactions"` -} - -func (SuiTransactionBlockKindChangeEpoch) isSuiTransactionBlockKind() {} -func (SuiTransactionBlockKindGenesis) isSuiTransactionBlockKind() {} -func (SuiTransactionBlockKindConsensusCommitPrologue) isSuiTransactionBlockKind() {} -func (SuiTransactionBlockKindConsensusCommitPrologueV3) isSuiTransactionBlockKind() {} -func (SuiTransactionBlockKindProgrammableTransaction) isSuiTransactionBlockKind() {} -func (SuiTransactionBlockKindAuthenticatorStateUpdate) isSuiTransactionBlockKind() {} -func (SuiTransactionBlockKindEndOfEpochTransaction) isSuiTransactionBlockKind() {} - -type SuiTransactionBlockKindWrapper struct { - SuiTransactionBlockKind -} - -func (w *SuiTransactionBlockKindWrapper) UnmarshalJSON(data []byte) error { - type Kind struct { - Kind string `json:"kind"` - } - - var kind Kind - if err := json.Unmarshal(data, &kind); err != nil { - return err - } - - switch kind.Kind { - case "ChangeEpoch": - var k SuiTransactionBlockKindChangeEpoch - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiTransactionBlockKind = k - case "Genesis": - var k SuiTransactionBlockKindGenesis - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiTransactionBlockKind = k - case "ConsensusCommitPrologue": - var k SuiTransactionBlockKindConsensusCommitPrologue - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiTransactionBlockKind = k - case "ConsensusCommitPrologueV3": - var k SuiTransactionBlockKindConsensusCommitPrologueV3 - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiTransactionBlockKind = k - case "ProgrammableTransaction": - var k SuiTransactionBlockKindProgrammableTransaction - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiTransactionBlockKind = k - case "AuthenticatorStateUpdate": - var k SuiTransactionBlockKindAuthenticatorStateUpdate - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiTransactionBlockKind = k - case "EndOfEpochTransaction": - var k SuiTransactionBlockKindEndOfEpochTransaction - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiTransactionBlockKind = k - default: - return errors.New("unknown SuiTransactionBlockKind type") - } - - return nil -} - -func (w SuiTransactionBlockKindWrapper) MarshalJSON() ([]byte, error) { - switch t := w.SuiTransactionBlockKind.(type) { - case SuiTransactionBlockKindChangeEpoch: - return json.Marshal(SuiTransactionBlockKindChangeEpoch{ - Kind: t.Kind, - ComputationCharge: t.ComputationCharge, - Epoch: t.Epoch, - EpochStartTimestampMs: t.EpochStartTimestampMs, - StorageCharge: t.StorageCharge, - StorageRebate: t.StorageRebate, - }) - case SuiTransactionBlockKindGenesis: - return json.Marshal(SuiTransactionBlockKindGenesis{ - Kind: t.Kind, - Objects: t.Objects, - }) - case SuiTransactionBlockKindConsensusCommitPrologue: - return json.Marshal(SuiTransactionBlockKindConsensusCommitPrologue{ - Kind: t.Kind, - Epoch: t.Epoch, - CommitTimestampMs: t.CommitTimestampMs, - Round: t.Round, - }) - case SuiTransactionBlockKindConsensusCommitPrologueV3: - return json.Marshal(SuiTransactionBlockKindConsensusCommitPrologueV3{ - Kind: t.Kind, - Epoch: t.Epoch, - Round: t.Round, - SubDagIndex: t.SubDagIndex, - CommitTimestampMs: t.CommitTimestampMs, - ConsensusCommitDigest: t.ConsensusCommitDigest, - ConsensusDeterminedVersionAssignments: t.ConsensusDeterminedVersionAssignments, - }) - case SuiTransactionBlockKindProgrammableTransaction: - return json.Marshal(SuiTransactionBlockKindProgrammableTransaction{ - Kind: t.Kind, - Inputs: t.Inputs, - Transactions: t.Transactions, - }) - case SuiTransactionBlockKindAuthenticatorStateUpdate: - return json.Marshal(SuiTransactionBlockKindAuthenticatorStateUpdate{ - Kind: t.Kind, - Epoch: t.Epoch, - NewActiveJwks: t.NewActiveJwks, - Round: t.Round, - }) - case SuiTransactionBlockKindEndOfEpochTransaction: - return json.Marshal(SuiTransactionBlockKindEndOfEpochTransaction{ - Kind: t.Kind, - Transactions: t.Transactions, - }) - default: - return nil, errors.New("unknown SuiTransactionBlockKind type") - } -} - -// -----------Sui Transaction----------- -type SuiTransaction interface { - isSuiTransaction() -} - -type SuiTransactionMoveCall struct { - MoveCall MoveCallSuiTransaction `json:"MoveCall"` -} - -type SuiTransactionTransferObjects struct { - TransferObjects [2]SuiTransactionArgumentWrapper `json:"TransferObjects"` -} - -type SuiTransactionSplitCoins struct { - SplitCoins [2]SuiTransactionArgumentWrapper `json:"SplitCoins"` -} - -type SuiTransactionMergeCoins struct { - MergeCoins [2]SuiTransactionArgumentWrapper `json:"MergeCoins"` -} - -type SuiTransactionPublish struct { - Publish []string `json:"Publish"` -} - -type SuiTransactionUpgrade struct { - Upgrade [3]SuiTransactionArgumentWrapper `json:"Upgrade"` -} - -type SuiTransactionMakeMoveVec struct { - MakeMoveVec [2]*SuiTransactionArgumentWrapper `json:"MakeMoveVec"` -} - -func (SuiTransactionMoveCall) isSuiTransaction() {} -func (SuiTransactionTransferObjects) isSuiTransaction() {} -func (SuiTransactionSplitCoins) isSuiTransaction() {} -func (SuiTransactionMergeCoins) isSuiTransaction() {} -func (SuiTransactionPublish) isSuiTransaction() {} -func (SuiTransactionUpgrade) isSuiTransaction() {} -func (SuiTransactionMakeMoveVec) isSuiTransaction() {} - -type SuiTransactionWrapper struct { - SuiTransaction -} - -func (w *SuiTransactionWrapper) UnmarshalJSON(data []byte) error { - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - if _, ok := obj["MoveCall"]; ok { - var t SuiTransactionMoveCall - if err := json.Unmarshal(data, &t); err != nil { - return err - } - w.SuiTransaction = t - return nil - } - - if _, ok := obj["TransferObjects"]; ok { - var t SuiTransactionTransferObjects - if err := json.Unmarshal(data, &t); err != nil { - return err - } - w.SuiTransaction = t - return nil - } - - if _, ok := obj["SplitCoins"]; ok { - var t SuiTransactionSplitCoins - if err := json.Unmarshal(data, &t); err != nil { - return err - } - w.SuiTransaction = t - return nil - } - - if _, ok := obj["MergeCoins"]; ok { - var t SuiTransactionMergeCoins - if err := json.Unmarshal(data, &t); err != nil { - return err - } - w.SuiTransaction = t - return nil - } - - if _, ok := obj["Publish"]; ok { - var t SuiTransactionPublish - if err := json.Unmarshal(data, &t); err != nil { - return err - } - w.SuiTransaction = t - return nil - } - - if _, ok := obj["Upgrade"]; ok { - var t SuiTransactionUpgrade - if err := json.Unmarshal(data, &t); err != nil { - return err - } - w.SuiTransaction = t - return nil - } - - if _, ok := obj["MakeMoveVec"]; ok { - var t SuiTransactionMakeMoveVec - if err := json.Unmarshal(data, &t); err != nil { - return err - } - w.SuiTransaction = t - return nil - } - - return errors.New("unknown SuiTransaction type") -} - -func (w *SuiTransactionWrapper) MarshalJSON() ([]byte, error) { - switch t := w.SuiTransaction.(type) { - case SuiTransactionMoveCall: - return json.Marshal(t) - case SuiTransactionTransferObjects: - return json.Marshal(t) - case SuiTransactionSplitCoins: - return json.Marshal(t) - case SuiTransactionMergeCoins: - return json.Marshal(t) - case SuiTransactionPublish: - return json.Marshal(t) - case SuiTransactionUpgrade: - return json.Marshal(t) - case SuiTransactionMakeMoveVec: - return json.Marshal(t) - default: - return nil, errors.New("unknown SuiTransaction type") - } -} - -// -----------SuiEndOfEpochTransactionKind----------- -type SuiEndOfEpochTransactionKind interface { - isSuiEndOfEpochTransactionKind() -} -type SuiEndOfEpochTransactionKindAuthenticatorStateCreate string - -type SuiEndOfEpochTransactionKindChangeEpoch struct { - ChangeEpoch SuiChangeEpoch `json:"ChangeEpoch"` -} - -type SuiEndOfEpochTransactionKindAuthenticatorStateExpire struct { - AuthenticatorStateExpire SuiAuthenticatorStateExpire `json:"AuthenticatorStateExpire"` -} - -func (SuiEndOfEpochTransactionKindAuthenticatorStateCreate) isSuiEndOfEpochTransactionKind() {} -func (SuiEndOfEpochTransactionKindChangeEpoch) isSuiEndOfEpochTransactionKind() {} -func (SuiEndOfEpochTransactionKindAuthenticatorStateExpire) isSuiEndOfEpochTransactionKind() {} - -type SuiEndOfEpochTransactionKindWrapper struct { - SuiEndOfEpochTransactionKind -} - -func (w *SuiEndOfEpochTransactionKindWrapper) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err == nil { - w.SuiEndOfEpochTransactionKind = SuiEndOfEpochTransactionKindAuthenticatorStateCreate(s) - return nil - } - - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - switch { - case obj["ChangeEpoch"] != nil: - var k SuiEndOfEpochTransactionKindChangeEpoch - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiEndOfEpochTransactionKind = k - case obj["AuthenticatorStateExpire"] != nil: - var k SuiEndOfEpochTransactionKindAuthenticatorStateExpire - if err := json.Unmarshal(data, &k); err != nil { - return err - } - w.SuiEndOfEpochTransactionKind = k - default: - return errors.New("unknown SuiEndOfEpochTransactionKind type") - } - return nil -} - -func (w *SuiEndOfEpochTransactionKindWrapper) MarshalJSON() ([]byte, error) { - switch t := w.SuiEndOfEpochTransactionKind.(type) { - case SuiEndOfEpochTransactionKindAuthenticatorStateCreate: - return json.Marshal(string(t)) - case SuiEndOfEpochTransactionKindChangeEpoch: - return json.Marshal(SuiEndOfEpochTransactionKindChangeEpoch{ChangeEpoch: t.ChangeEpoch}) - case SuiEndOfEpochTransactionKindAuthenticatorStateExpire: - return json.Marshal(SuiEndOfEpochTransactionKindAuthenticatorStateExpire{AuthenticatorStateExpire: t.AuthenticatorStateExpire}) - default: - return nil, errors.New("unknown SuiEndOfEpochTransactionKind type") - } -} - -// -----------SuiArgument----------- -type SuiArgument interface { - isSuiArgument() -} - -type SuiArgumentGasCoin string - -type SuiArgumentInput struct { - Input uint64 `json:"Input"` -} - -type SuiArgumentResult struct { - Result uint64 `json:"Result"` -} - -type SuiArgumentNestedResult struct { - NestedResult [2]uint64 `json:"NestedResult"` -} - -func (SuiArgumentGasCoin) isSuiArgument() {} -func (SuiArgumentInput) isSuiArgument() {} -func (SuiArgumentResult) isSuiArgument() {} -func (SuiArgumentNestedResult) isSuiArgument() {} - -type SuiArgumentWrapper struct { - SuiArgument -} - -func (w *SuiArgumentWrapper) UnmarshalJSON(data []byte) error { - var s string - if err := json.Unmarshal(data, &s); err == nil { - w.SuiArgument = SuiArgumentGasCoin(s) - return nil - } - - var obj map[string]json.RawMessage - if err := json.Unmarshal(data, &obj); err != nil { - return err - } - - if _, ok := obj["Input"]; ok { - var sa SuiArgumentInput - if err := json.Unmarshal(data, &sa); err != nil { - return err - } - w.SuiArgument = sa - return nil - } - - if _, ok := obj["Result"]; ok { - var sa SuiArgumentResult - if err := json.Unmarshal(data, &sa); err != nil { - return err - } - w.SuiArgument = sa - return nil - } - - if _, ok := obj["NestedResult"]; ok { - var sa SuiArgumentNestedResult - if err := json.Unmarshal(data, &sa); err != nil { - return err - } - w.SuiArgument = sa - return nil - } - - return errors.New("unknown SuiArgument type") -} - -func (w SuiArgumentWrapper) MarshalJSON() ([]byte, error) { - switch arg := w.SuiArgument.(type) { - case SuiArgumentGasCoin: - return json.Marshal(SuiArgumentGasCoin(arg)) - case SuiArgumentInput: - return json.Marshal(SuiArgumentInput{Input: arg.Input}) - case SuiArgumentResult: - return json.Marshal(SuiArgumentResult{Result: arg.Result}) - case SuiArgumentNestedResult: - return json.Marshal(SuiArgumentNestedResult{NestedResult: arg.NestedResult}) - default: - return nil, errors.New("unknown SuiArgument type") - } -} - -// -----------SuiTransactionArgument----------- -type SuiTransactionArgument interface { - isSuiTransactionArgument() -} - -type SuiTransactionArgumentOne SuiArgumentWrapper -type SuiTransactionArgumentArray []SuiArgumentWrapper -type SuiTransactionArgumentString string -type SuiTransactionArgumentStringArray []string - -func (SuiTransactionArgumentOne) isSuiTransactionArgument() {} -func (SuiTransactionArgumentArray) isSuiTransactionArgument() {} -func (SuiTransactionArgumentString) isSuiTransactionArgument() {} -func (SuiTransactionArgumentStringArray) isSuiTransactionArgument() {} - -type SuiTransactionArgumentWrapper struct { - SuiTransactionArgument -} - -func (w *SuiTransactionArgumentWrapper) UnmarshalJSON(data []byte) error { - var one SuiArgumentWrapper - if err := json.Unmarshal(data, &one); err == nil { - w.SuiTransactionArgument = SuiTransactionArgumentOne(one) - return nil - } - - var array []SuiArgumentWrapper - if err := json.Unmarshal(data, &array); err == nil { - w.SuiTransactionArgument = SuiTransactionArgumentArray(array) - return nil - } - - var s string - if err := json.Unmarshal(data, &s); err == nil { - w.SuiTransactionArgument = SuiTransactionArgumentString(s) - return nil - } - - var sa []string - if err := json.Unmarshal(data, &sa); err == nil { - w.SuiTransactionArgument = SuiTransactionArgumentStringArray(sa) - return nil - } - - return errors.New("unknown SuiTransactionArgument type") -} - -func (w SuiTransactionArgumentWrapper) MarshalJSON() ([]byte, error) { - switch arg := w.SuiTransactionArgument.(type) { - case SuiTransactionArgumentOne: - return json.Marshal(SuiArgumentWrapper(arg)) - case SuiTransactionArgumentArray: - return json.Marshal([]SuiArgumentWrapper(arg)) - case SuiTransactionArgumentString: - return json.Marshal(SuiTransactionArgumentString(arg)) - case SuiTransactionArgumentStringArray: - return json.Marshal(SuiTransactionArgumentStringArray(arg)) - default: - return nil, errors.New("unknown SuiTransactionArgument type") - } -} diff --git a/gmsui/types/types.go b/gmsui/types/types.go deleted file mode 100644 index 449dd04..0000000 --- a/gmsui/types/types.go +++ /dev/null @@ -1,653 +0,0 @@ -package types - -type Balance struct { - CoinObjectCount int `json:"coinObjectCount"` - CoinType string `json:"coinType"` - LockedBalance map[string]string `json:"lockedBalance"` - TotalBalance string `json:"totalBalance"` -} - -type BalanceChange struct { - Owner ObjectOwnerWrapper `json:"owner"` - CoinType string `json:"coinType"` - Amount string `json:"amount"` -} - -type Checkpoint struct { - Epoch string `json:"epoch"` - SequenceNumber string `json:"sequenceNumber"` - Digest string `json:"digest"` - NetworkTotalTransactions string `json:"networkTotalTransactions"` - PreviousDigest string `json:"previousDigest,omitempty"` - EpochRollingGasCostSummary GasCostSummary `json:"epochRollingGasCostSummary"` - TimestampMs string `json:"timestampMs"` - EndOfEpochData *EndOfEpochData `json:"endOfEpochData,omitempty"` - Transactions []string `json:"transactions"` - CheckpointCommitments []CheckpointCommitment `json:"checkpointCommitments"` - ValidatorSignature string `json:"validatorSignature"` -} - -type GasCostSummary struct { - ComputationCost string `json:"computationCost"` - StorageCost string `json:"storageCost"` - StorageRebate string `json:"storageRebate"` - NonRefundableStorageFee string `json:"nonRefundableStorageFee"` -} - -type EndOfEpochData struct { - EpochCommitments []CheckpointCommitment `json:"epochCommitments"` - NextEpochCommittee [][2]string `json:"nextEpochCommittee"` - NextEpochProtocolVersion string `json:"nextEpochProtocolVersion"` -} - -type CheckpointCommitment struct { - ECMHLiveObjectSetDigest ECMHLiveObjectSetDigest `json:"ecmhLiveObjectSetDigest"` -} - -type ECMHLiveObjectSetDigest struct { - Digest []int `json:"digest"` // TODO: bytes? -} - -type CheckpointId string - -type Claim struct { - IndexMod4 uint64 `json:"indexMod4"` - Value string `json:"value"` -} - -type CoinStruct struct { - Balance string `json:"balance"` - CoinObjectId string `json:"coinObjectId"` - CoinType string `json:"coinType"` - Digest string `json:"digest"` - PreviousTransaction string `json:"previousTransaction"` - Version string `json:"version"` -} - -type CommitteeInfo struct { - Epoch string `json:"epoch"` - Validators [][2]string `json:"validators"` -} - -type DelegatedStake struct { - ValidatorAddress string `json:"validatorAddress"` - StakingPool string `json:"stakingPool"` - Stakes []StakeObjectWrapper `json:"stakes"` -} - -type DevInspectResults struct { - Effects TransactionEffects `json:"effects"` - Error string `json:"error,omitempty"` - Events []SuiEvent `json:"events"` - Results []SuiExecutionResult `json:"results,omitempty"` -} - -type TransactionEffects struct { - MessageVersion string `json:"messageVersion"` - Status ExecutionStatus `json:"status"` - ExecutedEpoch string `json:"executedEpoch"` - GasUsed GasCostSummary `json:"gasUsed"` - ModifiedAtVersions []TransactionBlockEffectsModifiedAtVersions `json:"modifiedAtVersions,omitempty"` - SharedObjects []SuiObjectRef `json:"sharedObjects,omitempty"` - TransactionDigest string `json:"transactionDigest"` - Created []OwnedObjectRef `json:"created,omitempty"` - Mutated []OwnedObjectRef `json:"mutated,omitempty"` - Deleted []SuiObjectRef `json:"deleted,omitempty"` - GasObject OwnedObjectRef `json:"gasObject"` - EventsDigest *string `json:"eventsDigest,omitempty"` - Dependencies []string `json:"dependencies,omitempty"` - Unwrapped []OwnedObjectRef `json:"unwrapped,omitempty"` - UnwrappedThenDeleted []SuiObjectRef `json:"unwrappedThenDeleted,omitempty"` - Wrapped []SuiObjectRef `json:"wrapped,omitempty"` -} - -type ExecutionStatus struct { - Status string `json:"status"` - Error string `json:"error,omitempty"` -} - -type TransactionBlockEffectsModifiedAtVersions struct { - ObjectId string `json:"objectId"` - SequenceNumber string `json:"sequenceNumber"` -} - -type SuiObjectRef struct { - ObjectId string `json:"objectId"` - Version uint64 `json:"version"` - Digest string `json:"digest"` -} - -type OwnedObjectRef struct { - Owner ObjectOwnerWrapper `json:"owner"` - Reference SuiObjectRef `json:"reference"` -} - -type SuiEvent struct { - Id EventId `json:"id"` - PackageId string `json:"packageId"` - TransactionModule string `json:"transactionModule"` - Sender string `json:"sender"` - Type string `json:"type"` - ParsedJson interface{} `json:"parsedJson"` - Bcs string `json:"bcs"` - TimestampMs string `json:"timestampMs,omitempty"` -} - -type EventId struct { - TxDigest string `json:"txDigest"` - EventSeq string `json:"eventSeq"` -} - -type SuiExecutionResult struct { - MutableReferenceOutputs [][3]interface{} `json:"mutableReferenceOutputs,omitempty"` // TODO: [SuiArgument, bytes, string][] - ReturnValues [][2]interface{} `json:"returnValues,omitempty"` // TODO: interface -> [bytes, string][] -} - -type DisplayFieldsResponse struct { - Data map[string]*string `json:"data"` - Error *ObjectResponseErrorWrapper `json:"error"` -} - -type DryRunTransactionBlockResponse struct { - Effects TransactionEffects `json:"effects"` - Events []SuiEvent `json:"events"` - ObjectChanges []SuiObjectChangeWrapper `json:"objectChanges"` - BalanceChanges []BalanceChange `json:"balanceChanges"` - Input TransactionBlockData `json:"input"` -} - -type TransactionBlockData struct { - MessageVersion string `json:"messageVersion"` - Transaction SuiTransactionBlockKindWrapper `json:"transaction"` - Sender string `json:"sender"` - GasData SuiGasData `json:"gasData"` -} - -type SuiGasData struct { - Payment []SuiObjectRef `json:"payment"` - Owner string `json:"owner"` - Price string `json:"price"` - Budget string `json:"budget"` -} - -type DynamicFieldInfo struct { - Name DynamicFieldName `json:"name"` - BcsName string `json:"bcsName"` - Type DynamicFieldType `json:"type"` - ObjectType string `json:"objectType"` - ObjectId string `json:"objectId"` - Version int64 `json:"version"` - Digest string `json:"digest"` -} - -type DynamicFieldName struct { - Type string `json:"type"` - Value interface{} `json:"value"` -} - -type DynamicFieldType string - -var ( - DynamicField DynamicFieldType = "DynamicField" - DynamicObject DynamicFieldType = "DynamicObject" -) - -type ExecuteTransactionRequestType string - -var ( - WaitForEffectsCert ExecuteTransactionRequestType = "WaitForEffectsCert" - WaitForLocalExecution ExecuteTransactionRequestType = "WaitForLocalExecution" -) - -type SuiObjectData struct { - ObjectId string `json:"objectId"` - Version string `json:"version"` - Digest string `json:"digest"` - Type *string `json:"type,omitempty"` - Owner *ObjectOwnerWrapper `json:"owner,omitempty"` - PreviousTransaction *string `json:"previousTransaction,omitempty"` - StorageRebate *string `json:"storageRebate,omitempty"` - Display *DisplayFieldsResponse `json:"display,omitempty"` - Content *SuiParsedDataWrapper `json:"content,omitempty"` - Bcs *RawDataWrapper `json:"bcs,omitempty"` -} - -type SuiObjectDataOptions struct { - ShowBcs bool `json:"showBcs,omitempty"` - ShowContent bool `json:"showContent,omitempty"` - ShowDisplay bool `json:"showDisplay,omitempty"` - ShowOwner bool `json:"showOwner,omitempty"` - ShowPreviousTransaction bool `json:"showPreviousTransaction,omitempty"` - ShowStorageRebate bool `json:"showStorageRebate,omitempty"` - ShowType bool `json:"showType,omitempty"` -} - -type SuiObjectResponseQuery struct { - Filter *SuiObjectDataFilter `json:"filter,omitempty"` - Options *SuiObjectDataOptions `json:"options,omitempty"` -} - -type PaginatedCoins struct { - Data []CoinStruct `json:"data"` - HasNextPage bool `json:"hasNextPage"` - NextCursor *string `json:"nextCursor,omitempty"` -} - -type PaginatedDynamicFieldInfos struct { - Data []DynamicFieldInfo `json:"data"` - NextCursor *string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type PaginatedEvents struct { - Data []SuiEvent `json:"data"` - NextCursor *EventId `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type PaginatedStrings struct { - Data []string `json:"data"` - NextCursor *string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type PaginatedObjectsResponse struct { - Data []SuiObjectResponse `json:"data"` - NextCursor *string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type SuiObjectResponse struct { - Data *SuiObjectData `json:"data,omitempty"` - Error *ObjectResponseErrorWrapper `json:"error,omitempty"` -} - -type PaginatedTransactionResponse struct { - Data []SuiTransactionBlockResponse `json:"data"` - NextCursor *string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type SuiTransactionBlockResponse struct { - Digest string `json:"digest"` - Transaction *SuiTransactionBlock `json:"transaction,omitempty"` - RawTransaction string `json:"rawTransaction,omitempty"` - Effects *TransactionEffects `json:"effects,omitempty"` - Events []*SuiEvent `json:"events,omitempty"` - ObjectChanges []*SuiObjectChangeWrapper `json:"objectChanges,omitempty"` - BalanceChanges []*BalanceChange `json:"balanceChanges,omitempty"` - TimestampMs *string `json:"timestampMs,omitempty"` - Checkpoint *string `json:"checkpoint,omitempty"` - ConfirmedLocalExecution *bool `json:"confirmedLocalExecution,omitempty"` - Errors []string `json:"errors,omitempty"` -} - -type SuiTransactionBlock struct { - Data TransactionBlockData `json:"data"` - TxSignatures []string `json:"txSignatures"` -} - -type ProtocolConfig struct { - MinSupportedProtocolVersion string `json:"minSupportedProtocolVersion"` - MaxSupportedProtocolVersion string `json:"maxSupportedProtocolVersion"` - ProtocolVersion string `json:"protocolVersion"` - FeatureFlags map[string]bool `json:"featureFlags"` - Attributes map[string]ProtocolConfigValue `json:"attributes"` -} - -type SuiActiveJwk struct { - Epoch string `json:"epoch"` - Jwk SuiJWK `json:"jwk"` - JwkID SuiJwkID `json:"jwk_id"` -} - -type SuiJWK struct { - Alg string `json:"alg"` - E string `json:"e"` - Kty string `json:"kty"` - N string `json:"n"` -} - -type SuiJwkID struct { - Iss string `json:"iss"` - Kid string `json:"kid"` -} - -type SuiAuthenticatorStateExpire struct { - MinEpoch string `json:"min_epoch"` -} - -type SuiChangeEpoch struct { - ComputationCharge string `json:"computation_charge"` - Epoch string `json:"epoch"` - EpochStartTimestampMs string `json:"epoch_start_timestamp_ms"` - StorageCharge string `json:"storage_charge"` - StorageRebate string `json:"storage_rebate"` -} - -type CoinMetadata struct { - Decimals uint8 `json:"decimals"` - Description string `json:"description"` - IconUrl string `json:"iconUrl,omitempty"` - ID string `json:"id,omitempty"` - Name string `json:"name"` - Symbol string `json:"symbol"` -} - -type SuiMoveAbilitySet struct { - Abilities []SuiMoveAbility `json:"abilities"` -} - -type SuiMoveAbility string - -var ( - Copy SuiMoveAbility = "Copy" - Drop SuiMoveAbility = "Drop" - Store SuiMoveAbility = "Store" - Key SuiMoveAbility = "Key" -) - -type SuiMoveModuleId struct { - Address string `json:"address"` - Name string `json:"name"` -} - -type SuiMoveNormalizedField struct { - Name string `json:"name"` - Type SuiMoveNormalizedTypeWrapper `json:"type"` -} - -type SuiMoveNormalizedFunction struct { - Visibility SuiMoveVisibility `json:"visibility"` - IsEntry bool `json:"isEntry"` - TypeParameters []SuiMoveAbilitySet `json:"typeParameters"` - Parameters []*SuiMoveNormalizedTypeWrapper `json:"parameters"` - Return []*SuiMoveNormalizedTypeWrapper `json:"return"` -} - -type SuiMoveVisibility string - -var ( - Private SuiMoveVisibility = "Private" - Public SuiMoveVisibility = "Public" - Friend SuiMoveVisibility = "Friend" -) - -type SuiMoveNormalizedModule struct { - FileFormatVersion int `json:"fileFormatVersion"` - Address string `json:"address"` - Name string `json:"name"` - Friends []SuiMoveModuleId `json:"friends"` - Structs map[string]SuiMoveNormalizedStruct `json:"structs"` - ExposedFunctions map[string]SuiMoveNormalizedFunction `json:"exposedFunctions"` -} - -type SuiMoveNormalizedStruct struct { - Abilities SuiMoveAbilitySet `json:"abilities"` - TypeParameters []SuiMoveStructTypeParameter `json:"typeParameters"` - Fields []SuiMoveNormalizedField `json:"fields"` -} - -type SuiMoveStructTypeParameter struct { - Constraints SuiMoveAbilitySet `json:"constraints"` - IsPhantom bool `json:"isPhantom"` -} - -type MoveCallSuiTransaction struct { - Package string `json:"package"` - Module string `json:"module"` - Function string `json:"function"` - TypeArguments []*string `json:"type_arguments,omitempty"` - Arguments []SuiArgumentWrapper `json:"arguments"` -} - -type SuiSystemStateSummary struct { - Epoch string `json:"epoch"` - ProtocolVersion string `json:"protocolVersion"` - SystemStateVersion string `json:"systemStateVersion"` - StorageFundTotalObjectStorageRebates string `json:"storageFundTotalObjectStorageRebates"` - StorageFundNonRefundableBalance string `json:"storageFundNonRefundableBalance"` - ReferenceGasPrice string `json:"referenceGasPrice"` - SafeMode bool `json:"safeMode"` - SafeModeStorageRewards string `json:"safeModeStorageRewards"` - SafeModeComputationRewards string `json:"safeModeComputationRewards"` - SafeModeStorageRebates string `json:"safeModeStorageRebates"` - SafeModeNonRefundableStorageFee string `json:"safeModeNonRefundableStorageFee"` - EpochStartTimestampMs string `json:"epochStartTimestampMs"` - EpochDurationMs string `json:"epochDurationMs"` - StakeSubsidyStartEpoch string `json:"stakeSubsidyStartEpoch"` - MaxValidatorCount string `json:"maxValidatorCount"` - MinValidatorJoiningStake string `json:"minValidatorJoiningStake"` - ValidatorLowStakeThreshold string `json:"validatorLowStakeThreshold"` - ValidatorVeryLowStakeThreshold string `json:"validatorVeryLowStakeThreshold"` - ValidatorLowStakeGracePeriod string `json:"validatorLowStakeGracePeriod"` - StakeSubsidyBalance string `json:"stakeSubsidyBalance"` - StakeSubsidyDistributionCounter string `json:"stakeSubsidyDistributionCounter"` - StakeSubsidyCurrentDistributionAmount string `json:"stakeSubsidyCurrentDistributionAmount"` - StakeSubsidyPeriodLength string `json:"stakeSubsidyPeriodLength"` - StakeSubsidyDecreaseRate int `json:"stakeSubsidyDecreaseRate"` - TotalStake string `json:"totalStake"` - ActiveValidators []SuiValidatorSummary `json:"activeValidators"` - PendingActiveValidatorsId string `json:"pendingActiveValidatorsId"` - PendingActiveValidatorsSize string `json:"pendingActiveValidatorsSize"` - PendingRemovals []string `json:"pendingRemovals"` - StakingPoolMappingsId string `json:"stakingPoolMappingsId"` - StakingPoolMappingsSize string `json:"stakingPoolMappingsSize"` - InactivePoolsId string `json:"inactivePoolsId"` - InactivePoolsSize string `json:"inactivePoolsSize"` - ValidatorCandidatesId string `json:"validatorCandidatesId"` - ValidatorCandidatesSize string `json:"validatorCandidatesSize"` - AtRiskValidators [][2]string `json:"atRiskValidators"` - ValidatorReportRecords [][2]interface{} `json:"validatorReportRecords"` -} - -type SuiValidatorSummary struct { - SuiAddress string `json:"suiAddress"` - ProtocolPubkeyBytes string `json:"protocolPubkeyBytes"` - NetworkPubkeyBytes string `json:"networkPubkeyBytes"` - WorkerPubkeyBytes string `json:"workerPubkeyBytes"` - ProofOfPossessionBytes string `json:"proofOfPossessionBytes"` - Name string `json:"name"` - Description string `json:"description"` - ImageUrl string `json:"imageUrl"` - ProjectUrl string `json:"projectUrl"` - NetAddress string `json:"netAddress"` - P2pAddress string `json:"p2pAddress"` - PrimaryAddress string `json:"primaryAddress"` - WorkerAddress string `json:"workerAddress"` - NextEpochProtocolPubkeyBytes *string `json:"nextEpochProtocolPubkeyBytes"` - NextEpochProofOfPossession *string `json:"nextEpochProofOfPossession"` - NextEpochNetworkPubkeyBytes *string `json:"nextEpochNetworkPubkeyBytes"` - NextEpochWorkerPubkeyBytes *string `json:"nextEpochWorkerPubkeyBytes"` - NextEpochNetAddress *string `json:"nextEpochNetAddress"` - NextEpochP2pAddress *string `json:"nextEpochP2pAddress"` - NextEpochPrimaryAddress *string `json:"nextEpochPrimaryAddress"` - NextEpochWorkerAddress *string `json:"nextEpochWorkerAddress"` - VotingPower string `json:"votingPower"` - OperationCapId string `json:"operationCapId"` - GasPrice string `json:"gasPrice"` - CommissionRate string `json:"commissionRate"` - NextEpochStake string `json:"nextEpochStake"` - NextEpochGasPrice string `json:"nextEpochGasPrice"` - NextEpochCommissionRate string `json:"nextEpochCommissionRate"` - StakingPoolId string `json:"stakingPoolId"` - StakingPoolActivationEpoch *string `json:"stakingPoolActivationEpoch"` - StakingPoolDeactivationEpoch *string `json:"stakingPoolDeactivationEpoch"` - StakingPoolSuiBalance string `json:"stakingPoolSuiBalance"` - RewardsPool string `json:"rewardsPool"` - PoolTokenBalance string `json:"poolTokenBalance"` - PendingStake string `json:"pendingStake"` - PendingTotalSuiWithdraw string `json:"pendingTotalSuiWithdraw"` - PendingPoolTokenWithdraw string `json:"pendingPoolTokenWithdraw"` - ExchangeRatesId string `json:"exchangeRatesId"` - ExchangeRatesSize string `json:"exchangeRatesSize"` -} - -type SuiTransactionBlockBuilderMode string - -const ( - Commit SuiTransactionBlockBuilderMode = "Commit" - DevInspect SuiTransactionBlockBuilderMode = "DevInspect" -) - -type CoinSupply struct { - Value string `json:"value"` -} - -type TransactionBlockBytes struct { - Gas []SuiObjectRef `json:"gas"` - InputObjects []InputObjectKindWrapper `json:"inputObjects"` - TxBytes string `json:"txBytes"` -} - -type SuiTransactionBlockResponseOptions struct { - ShowInput bool `json:"showInput,omitempty"` - ShowEffects bool `json:"showEffects,omitempty"` - ShowEvents bool `json:"showEvents,omitempty"` - ShowObjectChanges bool `json:"showObjectChanges,omitempty"` - ShowBalanceChanges bool `json:"showBalanceChanges,omitempty"` - ShowRawInput bool `json:"showRawInput,omitempty"` -} - -type SuiTransactionBlockResponseQuery struct { - Filter *TransactionFilter `json:"filter,omitempty"` - Options *SuiTransactionBlockResponseOptions `json:"options,omitempty"` -} - -type TypeOrigin struct { - ModuleName string `json:"module_name"` - DataTypeName string `json:"datatype_name"` - Package string `json:"package"` -} - -type UpgradeInfo struct { - UpgradedId string `json:"upgraded_id"` - UpgradedVersion int64 `json:"upgraded_version"` -} - -type ValidatorApy struct { - Address string `json:"address"` - APY float64 `json:"apy"` -} - -type ValidatorsApy struct { - APYs []ValidatorApy `json:"apys"` - Epoch string `json:"epoch"` -} - -type ZkLoginAuthenticator struct { - Inputs ZkLoginInputs `json:"inputs"` - MaxEpoch string `json:"maxEpoch"` - UserSignature SignatureWrapper `json:"userSignature"` -} - -type ZkLoginInputs struct { - AddressSeed string `json:"addressSeed"` - HeaderBase64 string `json:"headerBase64"` - IssBase64Details Claim `json:"issBase64Details"` - ProofPoints ZkLoginProof `json:"proofPoints"` -} - -type ZkLoginProof struct { - A []string `json:"a"` - B [][]string `json:"b"` - C []string `json:"c"` -} - -type PaginatedCheckpoints struct { - Data []Checkpoint `json:"data"` - HasNextPage bool `json:"hasNextPage"` - NextCursor *string `json:"nextCursor,omitempty"` -} - -type ObjectValueKind string - -const ( - ByImmutableReference ObjectValueKind = "ByImmutableReference" - ByMutableReference ObjectValueKind = "ByMutableReference" - ByValue ObjectValueKind = "ByValue" -) - -type ResolvedNameServiceNames struct { - Data []string `json:"data"` - NextCursor *string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type EpochInfo struct { - Epoch string `json:"epoch"` - Validators []SuiValidatorSummary `json:"validators"` - EpochTotalTransactions string `json:"epochTotalTransactions"` - FirstCheckpointId string `json:"firstCheckpointId"` - EpochStartTimestamp string `json:"epochStartTimestamp"` - EndOfEpochInfo *EndOfEpochInfo `json:"endOfEpochInfo"` - ReferenceGasPrice *uint64 `json:"referenceGasPrice"` -} - -type EndOfEpochInfo struct { - LastCheckpointId string `json:"lastCheckpointId"` - EpochEndTimestamp string `json:"epochEndTimestamp"` - ProtocolVersion string `json:"protocolVersion"` - ReferenceGasPrice string `json:"referenceGasPrice"` - TotalStake string `json:"totalStake"` - StorageFundReinvestment string `json:"storageFundReinvestment"` - StorageCharge string `json:"storageCharge"` - StorageRebate string `json:"storageRebate"` - StorageFundBalance string `json:"storageFundBalance"` - StakeSubsidyAmount string `json:"stakeSubsidyAmount"` - TotalGasFees string `json:"totalGasFees"` - TotalStakeRewardsDistributed string `json:"totalStakeRewardsDistributed"` - LeftoverStorageFundInflow string `json:"leftoverStorageFundInflow"` -} - -type EpochPage struct { - Data []EpochInfo `json:"data"` - NextCursor string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type DynamicFieldPage struct { - Data []DynamicFieldInfo `json:"data"` - NextCursor *string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type CheckpointPage struct { - Data []Checkpoint `json:"data"` - NextCursor *string `json:"nextCursor,omitempty"` - HasNextPage bool `json:"hasNextPage"` -} - -type SuiMoveNormalizedModules map[string]SuiMoveNormalizedModule - -type ProgrammableTransaction struct { - Transactions []SuiTransactionWrapper `json:"transactions"` - Inputs []SuiCallArgWrapper `json:"inputs"` -} - -type GetPastObjectRequest struct { - ObjectID string `json:"objectId"` - Version string `json:"version"` -} - -type LoadedChildObject struct { - ObjectID string `json:"objectId"` - SequenceNumber string `json:"sequenceNumber"` -} - -type LoadedChildObjectsResponse struct { - LoadedChildObjects []LoadedChildObject `json:"loadedChildObjects"` -} - -type MoveCallParams struct { - Arguments []interface{} `json:"arguments"` - Function string `json:"function"` - Module string `json:"module"` - PackageObjectId string `json:"packageObjectId"` - TypeArguments []string `json:"typeArguments,omitempty"` -} - -type TransferObjectParams struct { - ObjectID string `json:"objectId"` - Recipient string `json:"recipient"` -} diff --git a/gmsui/utils.go b/gmsui/utils.go deleted file mode 100644 index 953af93..0000000 --- a/gmsui/utils.go +++ /dev/null @@ -1,71 +0,0 @@ -package gmsui - -import ( - "crypto/ed25519" - "encoding/base64" - "encoding/hex" - "encoding/json" - "fmt" - - "github.com/ethereum/go-ethereum/common/hexutil" - "golang.org/x/crypto/blake2b" -) - -// Utils -func B64ToSuiPrivateKey(b64 string) (string, error) { - b64Decode, err := base64.StdEncoding.DecodeString(b64) - if err != nil { - return "", err - } - - hexPriKey := hexutil.Encode(b64Decode) - if len(hexPriKey) != 68 { - return "", fmt.Errorf("unknown base64. %s", b64) - } - return fmt.Sprintf("0x%s", hexPriKey[4:]), nil -} - -func SuiPrivateKeyToB64(pk string) (string, error) { - if len(pk) != 66 { - return "", fmt.Errorf("unknown private key. %s", pk) - } - - pk = fmt.Sprintf("00%s", pk[2:]) - byteKey, err := hex.DecodeString(pk) - if err != nil { - return "", fmt.Errorf("private key decode err %v", err) - } - - return base64.StdEncoding.EncodeToString(byteKey), nil -} - -func B64PublicKeyToSuiAddress(b64 string) (string, error) { - b64Decode, err := base64.StdEncoding.DecodeString(b64) - if err != nil { - return "", fmt.Errorf("unknown base64. %s", b64) - } - addrBytes := blake2b.Sum256(b64Decode) - return fmt.Sprintf("0x%s", hex.EncodeToString(addrBytes[:])[:64]), nil -} - -func Ed25519PublicKeyToB64PublicKey(ed25519PubKey ed25519.PublicKey) string { - newPubkey := []byte{0} - newPubkey = append(newPubkey, ed25519PubKey...) - return base64.StdEncoding.EncodeToString(newPubkey) -} - -func ParseDevInspectReturnValue(v [2]interface{}) ([]byte, error) { - // v[0] --> bcs data - // v[1] --> data type - jsb, err := json.Marshal(v[0]) - if err != nil { - return nil, err - } - - var bs []byte - err = json.Unmarshal(jsb, &bs) - if err != nil { - return nil, err - } - return bs, nil -} diff --git a/gmsui/utils/constants.go b/gmsui/utils/constants.go deleted file mode 100644 index 6bb743b..0000000 --- a/gmsui/utils/constants.go +++ /dev/null @@ -1,17 +0,0 @@ -package utils - -import "fmt" - -var ( - SUI_DECIMALS = 9 - MIST_PER_SUI = 1000000000 - GAS_SAFE_OVERHEAD uint64 = 1000 - MAX_GAS uint64 = 50000000000 - MOVE_STDLIB_ADDRESS = NormalizeSuiObjectId("0x1") - SUI_FRAMEWORK_ADDRESS = NormalizeSuiObjectId("0x2") - SUI_SYSTEM_ADDRESS = NormalizeSuiObjectId("0x3") - SUI_CLOCK_OBJECT_ID = NormalizeSuiObjectId("0x6") - SUI_SYSTEM_MODULE_NAME = "sui_system" - SUI_TYPE_ARG = fmt.Sprintf("%s::sui::SUI", SUI_FRAMEWORK_ADDRESS) - SUI_SYSTEM_STATE_OBJECT_ID = NormalizeSuiObjectId("0x5") -) diff --git a/gmsui/utils/slice2map.go b/gmsui/utils/slice2map.go deleted file mode 100644 index 751a401..0000000 --- a/gmsui/utils/slice2map.go +++ /dev/null @@ -1,9 +0,0 @@ -package utils - -func SliceToMap[T any, V comparable](src []T, key func(T) V) map[V]T { - var result = make(map[V]T) - for _, v := range src { - result[key(v)] = v - } - return result -} diff --git a/gmsui/utils/sui_types.go b/gmsui/utils/sui_types.go deleted file mode 100644 index e294014..0000000 --- a/gmsui/utils/sui_types.go +++ /dev/null @@ -1,110 +0,0 @@ -package utils - -import ( - "fmt" - "regexp" - "strings" -) - -const ( - SuiAddressLength = 32 - TxDigestLength = 32 -) - -// Returns whether the tx digest is valid based on the serialization format -func IsValidTransactionDigest(v string) bool { - return false -} - -func IsValidSuiAddress(v string) bool { - return IsHex(v) && GetHexByteLength(v) == SuiAddressLength -} - -func IsValidSuiObjectId(v string) bool { - return IsValidSuiAddress(v) -} - -/** - * Perform the following operations: - * 1. Make the address lower case - * 2. Prepend `0x` if the string does not start with `0x`. - * 3. Add more zeros if the length of the address(excluding `0x`) is less than `SUI_ADDRESS_LENGTH` - * - * WARNING: if the address value itself starts with `0x`, e.g., `0x0x`, the default behavior - * is to treat the first `0x` not as part of the address. The default behavior can be overridden by - * setting `forceAdd0x` to true - * - */ -// 0x1 -> 0x0000000000000000000000000000000000000000000000000000000000000001 -func NormalizeSuiAddress(v string) string { - address := strings.ToLower(v) - address = strings.TrimPrefix(address, "0x") - - if len(address) > SuiAddressLength*2 { - return "0x" + address - } - - return fmt.Sprintf("0x%s", strings.Repeat("0", SuiAddressLength*2-len(address))+address) -} - -// 0x1 -> 0x0000000000000000000000000000000000000000000000000000000000000001 -func NormalizeSuiObjectId(v string) string { - return NormalizeSuiAddress(v) -} - -// 0x2::sui::SUI -> 0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI -func NormalizeSuiCoinType(v string) string { - splits := strings.Split(v, "::") - if len(splits) != 3 { - return v - } - - return fmt.Sprintf("%s::%s::%s", NormalizeSuiAddress(splits[0]), splits[1], splits[2]) -} - -// 0x0000000000000000000000000000000000000000000000000000000000000001 -> 0x1 -func NormalizeShortSuiAddress(v string) string { - address := NormalizeSuiAddress(v) - - address = strings.TrimPrefix(address, "0x") - address = strings.TrimLeft(address, "0") - - if address == "" { - return "0x0" - } - - return "0x" + address -} - -// 0x0000000000000000000000000000000000000000000000000000000000000001 -> 0x1 -func NormalizeShortSuiObjectId(v string) string { - return NormalizeShortSuiAddress(v) -} - -// 0x2::sui::SUI -> 0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI -func NormalizeShortSuiCoinType(v string) string { - splits := strings.Split(v, "::") - if len(splits) != 3 { - return v - } - - return fmt.Sprintf("%s::%s::%s", NormalizeShortSuiAddress(splits[0]), splits[1], splits[2]) -} - -func IsHex(v string) bool { - re := regexp.MustCompile(`^(0x|0X)?[a-fA-F0-9]+$`) - - if !re.MatchString(v) { - return false - } - - return len(v)%2 == 0 -} - -func GetHexByteLength(v string) int { - if strings.HasPrefix(v, "0x") || strings.HasPrefix(v, "0X") { - v = v[2:] - } - - return len(v) / 2 -} diff --git a/gmsui/utils/sui_types_test.go b/gmsui/utils/sui_types_test.go deleted file mode 100644 index f2fadd5..0000000 --- a/gmsui/utils/sui_types_test.go +++ /dev/null @@ -1,161 +0,0 @@ -package utils_test - -import ( - "reflect" - "testing" - - "github.com/W3Tools/go-modules/gmsui/utils" -) - -func TestNormalizeSuiAddress(t *testing.T) { - tests := []struct { - str string - expected string - }{ - { - str: "", - expected: "0x0000000000000000000000000000000000000000000000000000000000000000", - }, - { - str: "a", - expected: "0x000000000000000000000000000000000000000000000000000000000000000a", - }, - { - str: "123", - expected: "0x0000000000000000000000000000000000000000000000000000000000000123", - }, - { - str: "0xa123", - expected: "0x000000000000000000000000000000000000000000000000000000000000a123", - }, - { - str: "0x6", - expected: "0x0000000000000000000000000000000000000000000000000000000000000006", - }, - { - str: "0x06", - expected: "0x0000000000000000000000000000000000000000000000000000000000000006", - }, - } - - for _, tt := range tests { - t.Run(tt.str, func(t *testing.T) { - normalizedAddress := utils.NormalizeSuiAddress(tt.str) - if !reflect.DeepEqual(normalizedAddress, tt.expected) { - t.Errorf("normalize sui address expected %s, but got %v", tt.expected, normalizedAddress) - } - - normalizedObject := utils.NormalizeSuiObjectId(tt.str) - if !reflect.DeepEqual(normalizedObject, tt.expected) { - t.Errorf("normalize sui object expected %s, but got %v", tt.expected, normalizedObject) - } - }) - } -} -func TestNormalizeShortSuiAddress(t *testing.T) { - tests := []struct { - str string - expected string - }{ - { - str: "0x0000000000000000000000000000000000000000000000000000000000000000", - expected: "0x0", - }, - { - str: "0x000000000000000000000000000000000000000000000000000000000000000a", - expected: "0xa", - }, - { - str: "0x0000000000000000000000000000000000000000000000000000000000000123", - expected: "0x123", - }, - { - str: "0x000000000000000000000000000000000000000000000000000000000000a123", - expected: "0xa123", - }, - { - str: "0x0000000000000000000000000000000000000000000000000000000000000006", - expected: "0x6", - }, - { - str: "0x0000000000000000000000000000000000000000000000000000000000000006", - expected: "0x6", - }, - { - str: "0x06", - expected: "0x6", - }, - } - - for _, tt := range tests { - t.Run(tt.str, func(t *testing.T) { - normalizedShortSuiAddress := utils.NormalizeShortSuiAddress(tt.str) - if !reflect.DeepEqual(normalizedShortSuiAddress, tt.expected) { - t.Errorf("normalize short sui address expected %s, but got %s", tt.expected, normalizedShortSuiAddress) - } - - normalizedShortSuiObjectId := utils.NormalizeShortSuiObjectId(tt.str) - if !reflect.DeepEqual(normalizedShortSuiObjectId, tt.expected) { - t.Errorf("normalize short sui object id expected %s, but got %s", tt.expected, normalizedShortSuiObjectId) - } - }) - } -} - -func TestNormalizeSuiCoinType(t *testing.T) { - tests := []struct { - str string - expected string - }{ - { - str: "0x2::sui::SUI", - expected: "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI", - }, - { - str: "0x02::sui::SUI", - expected: "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI", - }, - { - str: "0x01", - expected: "0x01", - }, - } - - for _, tt := range tests { - t.Run(tt.str, func(t *testing.T) { - normalizedShortSuiAddress := utils.NormalizeSuiCoinType(tt.str) - if !reflect.DeepEqual(normalizedShortSuiAddress, tt.expected) { - t.Errorf("normalize short sui address expected %s, but got %s", tt.expected, normalizedShortSuiAddress) - } - }) - } -} - -func TestNormalizeShortSuiCoinType(t *testing.T) { - tests := []struct { - str string - expected string - }{ - { - str: "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI", - expected: "0x2::sui::SUI", - }, - { - str: "0x02::sui::SUI", - expected: "0x2::sui::SUI", - }, - { - str: "0x01", - expected: "0x01", - }, - } - - for _, tt := range tests { - t.Run(tt.str, func(t *testing.T) { - normalizedShortSuiAddress := utils.NormalizeShortSuiCoinType(tt.str) - if !reflect.DeepEqual(normalizedShortSuiAddress, tt.expected) { - t.Errorf("normalize short sui address expected %s, but got %s", tt.expected, normalizedShortSuiAddress) - } - }) - } -} diff --git a/gmsui/utils/unsigned_integer.go b/gmsui/utils/unsigned_integer.go deleted file mode 100644 index cb8b01b..0000000 --- a/gmsui/utils/unsigned_integer.go +++ /dev/null @@ -1,18 +0,0 @@ -package utils - -func UnsignedIntegerToUint64(v any) uint64 { - switch v := v.(type) { - case uint64: - return v - case uint32: - return uint64(v) - case uint16: - return uint64(v) - case uint8: - return uint64(v) - case uint: - return uint64(v) - default: - return 0 - } -} diff --git a/gmsui/verify/verify.go b/gmsui/verify/verify.go deleted file mode 100644 index 2050199..0000000 --- a/gmsui/verify/verify.go +++ /dev/null @@ -1,27 +0,0 @@ -package verify - -import ( - "fmt" - - "github.com/W3Tools/go-modules/gmsui/cryptography" - "github.com/W3Tools/go-modules/gmsui/keypairs/ed25519" - "github.com/W3Tools/go-modules/gmsui/keypairs/secp256k1" - "github.com/W3Tools/go-modules/gmsui/keypairs/secp256r1" -) - -func PublicKeyFromRawBytes(signatureScheme cryptography.SignatureScheme, bs []byte) (cryptography.PublicKey, error) { - switch signatureScheme { - case cryptography.Ed25519Scheme: - return ed25519.NewEd25519PublicKey(bs) - case cryptography.Secp256k1Scheme: - return secp256k1.NewSecp256k1PublicKey(bs) - case cryptography.Secp256r1Scheme: - return secp256r1.NewSecp256r1PublicKey(bs) - case cryptography.MultiSigScheme: - return nil, fmt.Errorf("unimplemented %v", signatureScheme) - case cryptography.ZkLoginScheme: - return nil, fmt.Errorf("unimplemented %v", signatureScheme) - default: - return nil, fmt.Errorf("unsupported signature scheme %v", signatureScheme) - } -} diff --git a/go.mod b/go.mod index 28bdfbc..d3ec3b1 100644 --- a/go.mod +++ b/go.mod @@ -4,15 +4,9 @@ go 1.22.1 require ( github.com/DeanThompson/ginpprof v0.0.0-20201112072838-007b1e56b2e1 - github.com/W3Tools/go-sui-sdk/v2 v2.1.5 github.com/aws/aws-lambda-go v1.46.0 github.com/aws/aws-sdk-go v1.50.31 - github.com/btcsuite/btcd v0.23.0 - github.com/btcsuite/btcd/btcec/v2 v2.3.2 - github.com/btcsuite/btcd/btcutil v1.1.3 - github.com/ethereum/go-ethereum v1.13.15 github.com/everFinance/goar v1.6.3 - github.com/fardream/go-bcs v0.5.0 github.com/gin-gonic/gin v1.9.1 github.com/go-playground/validator/v10 v10.14.0 github.com/go-redis/redis/v8 v8.11.5 @@ -20,9 +14,6 @@ require ( github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible github.com/google/uuid v1.5.0 - github.com/tyler-smith/go-bip32 v1.0.0 - github.com/tyler-smith/go-bip39 v1.1.0 - golang.org/x/crypto v0.21.0 gorm.io/driver/mysql v1.5.2 gorm.io/gorm v1.25.5 ) @@ -30,11 +21,9 @@ require ( replace github.com/fardream/go-bcs => github.com/W3Tools/go-bcs v0.0.3 require ( - github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect - github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect - github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect - github.com/btcsuite/btcutil v1.0.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcutil v1.1.3 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect @@ -45,6 +34,7 @@ require ( github.com/denisenkom/go-mssqldb v0.10.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/ethereum/go-ethereum v1.13.15 // indirect github.com/everFinance/arseeding v1.2.5 // indirect github.com/everFinance/ethrpc v1.0.4 // indirect github.com/everFinance/goether v1.1.9 // indirect @@ -71,7 +61,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-sqlite3 v1.14.8 // indirect - github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect @@ -87,6 +76,7 @@ require ( github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect golang.org/x/arch v0.3.0 // indirect + golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/net v0.22.0 // indirect golang.org/x/sync v0.5.0 // indirect diff --git a/go.sum b/go.sum index 86ae606..76bf01e 100644 --- a/go.sum +++ b/go.sum @@ -5,10 +5,6 @@ github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/DeanThompson/ginpprof v0.0.0-20201112072838-007b1e56b2e1 h1:IIOiH2YkFyyHCImuX7YWlHpc7wHZTQVxZwADs5jfggQ= github.com/DeanThompson/ginpprof v0.0.0-20201112072838-007b1e56b2e1/go.mod h1:kMi/fSDAgvjo9TYfYwYeQ2vkyj+VTR/tB6u/Tjh39t0= -github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= -github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= -github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= -github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= @@ -18,10 +14,6 @@ github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9 github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/W3Tools/go-bcs v0.0.3 h1:FbTcnM+RmKm2sp2FQ0t/kNgznK8oOOdJh0q34iv+4Gs= -github.com/W3Tools/go-bcs v0.0.3/go.mod h1:UsoxhIoe2GsVexX0s5NDLIChxeb/JUbjw7IWzzgF3Xk= -github.com/W3Tools/go-sui-sdk/v2 v2.1.5 h1:5Nl72eQw9g3NhVXBFq9L7JmlFvnLTS6lpcqEdh1e4Cs= -github.com/W3Tools/go-sui-sdk/v2 v2.1.5/go.mod h1:i7nxpuXV7KjX2D1Jh/lnbZD9tAi0YWK2e+MEt9I2DDU= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -65,8 +57,6 @@ github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOF github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= -github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= -github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= @@ -88,8 +78,6 @@ github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhD github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= -github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= @@ -445,8 +433,6 @@ github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceT github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4= -github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= @@ -582,7 +568,6 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -620,10 +605,6 @@ github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9f github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= -github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= -github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= @@ -649,7 +630,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -661,7 +641,6 @@ golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -856,8 +835,6 @@ honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= -launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=