From 5651a4baa66191d32f15d836a616b7b3a8bb75f9 Mon Sep 17 00:00:00 2001 From: Joey Kraut Date: Thu, 19 Dec 2024 11:50:51 -0800 Subject: [PATCH] .github: Add workflows and fix lints --- .github/workflows/lint.yml | 38 +++++++++ .github/workflows/test.yml | 27 +++++++ .golangci.yml | 35 ++++----- client/api_types/api_external_match.go | 19 ++--- client/api_types/api_order_book.go | 4 +- client/api_types/api_wallet.go | 37 ++++++--- client/api_types/api_wallet_test.go | 5 +- client/api_types/conversion.go | 4 +- client/api_types/conversion_test.go | 5 +- client/api_types/request_response_types.go | 77 ++++++++++--------- client/external_match_client/client.go | 8 +- client/http.go | 8 +- client/renegade_client/balance_operations.go | 9 ++- client/renegade_client/client.go | 11 ++- client/renegade_client/order_operations.go | 13 ++-- client/renegade_client/permit2.go | 12 +-- client/renegade_client/tasks.go | 40 +++++----- client/renegade_client/wallet_operations.go | 16 ++-- crypto/poseidon2.go | 9 ++- crypto/poseidon2_constants.go | 8 +- crypto/poseidon2_test.go | 10 +-- examples/01_external_match/main.go | 1 + examples/02_external_quote_validation/main.go | 21 ++--- .../03_external_match_with_receiver/main.go | 1 + examples/04_modify_quoted_order/main.go | 1 + wallet/balance.go | 1 + wallet/fixed_point.go | 4 +- wallet/fixed_point_test.go | 2 +- wallet/helpers.go | 1 + wallet/keychain.go | 11 ++- wallet/keychain_derivation.go | 26 +++---- wallet/keychain_test.go | 2 +- wallet/order.go | 33 +++++--- wallet/scalar_serialization.go | 11 ++- wallet/scalar_serialization_test.go | 2 +- wallet/wallet.go | 28 +++---- wallet/wallet_test.go | 2 +- 37 files changed, 332 insertions(+), 210 deletions(-) create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..f539742 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,38 @@ +name: Lint + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + lint: + name: Lint and Format + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.21' + cache: true + + - name: Install dependencies + run: go mod download + + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: latest + args: --timeout=5m + + - name: Check formatting + run: | + if [ "$(gofmt -l . | wc -l)" -gt 0 ]; then + echo "The following files are not formatted correctly:" + gofmt -l . + exit 1 + fi \ No newline at end of file diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..9c403d7 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,27 @@ +name: Test + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + test: + name: Run Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.21' + cache: true + + - name: Install dependencies + run: go mod download + + - name: Run tests + run: go test -v ./... \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 17580ef..ddeb51c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,34 +1,25 @@ linters: enable: - gofmt - - golint - govet - - errcheck - - staticcheck - gosimple + - staticcheck + - errcheck - ineffassign - - unused + - typecheck - misspell - - lll + - goimports + - revive + - gosec + +linters-settings: + govet: + shadow: true + goimports: + local-prefixes: github.com/renegade-fi/golang-sdk run: deadline: 5m - tests: true - skip-dirs: - - vendor issues: - exclude-rules: - - path: _test\.go - linters: - - errcheck - -linters-settings: - govet: - check-shadowing: true - golint: - min-confidence: 0.8 - gofmt: - simplify: true - lll: - line-length: 120 + exclude-use-default: false diff --git a/client/api_types/api_external_match.go b/client/api_types/api_external_match.go index 9a81694..0e003c8 100644 --- a/client/api_types/api_external_match.go +++ b/client/api_types/api_external_match.go @@ -1,4 +1,5 @@ -package api_types +// Package api_types provides API data structures for the Renegade SDK +package api_types //nolint:revive import ( "errors" @@ -7,7 +8,7 @@ import ( // ApiExternalOrder is an order from outside of the darkpool, generated by a client // requesting an external match -type ApiExternalOrder struct { +type ApiExternalOrder struct { //nolint:revive // The mint (erc20 address) of the base asset // As a hex string BaseMint string `json:"base_mint"` @@ -26,7 +27,7 @@ type ApiExternalOrder struct { } // ApiExternalOrderBuilder helps construct ApiExternalOrder with validation -type ApiExternalOrderBuilder struct { +type ApiExternalOrderBuilder struct { //nolint:revive order ApiExternalOrder } @@ -98,13 +99,13 @@ func (b *ApiExternalOrderBuilder) Build() (*ApiExternalOrder, error) { } // ApiExternalAssetTransfer represents a single transfer between the external client and darkpool -type ApiExternalAssetTransfer struct { +type ApiExternalAssetTransfer struct { //nolint:revive Mint string `json:"mint"` Amount Amount `json:"amount"` } // ApiExternalQuote is a quote from the relayer for an external order -type ApiExternalQuote struct { +type ApiExternalQuote struct { //nolint:revive Order ApiExternalOrder `json:"order"` MatchResult ApiExternalMatchResult `json:"match_result"` Fees ApiFee `json:"fees"` @@ -117,13 +118,13 @@ type ApiExternalQuote struct { // ApiSignedQuote is a quote from the relayer, signed with the relayer's admin API key // This allows a client to submit an authorized quote to the relayer and receive back an // assembled settlement transaction at the quoted price -type ApiSignedQuote struct { +type ApiSignedQuote struct { //nolint:revive Quote ApiExternalQuote `json:"quote"` Signature string `json:"signature"` } // ApiExternalMatchBundle contains a match and a transaction that the client can submit on-chain -type ApiExternalMatchBundle struct { +type ApiExternalMatchBundle struct { //nolint:revive MatchResult ApiExternalMatchResult `json:"match_result"` Fees ApiFee `json:"fees"` Receive ApiExternalAssetTransfer `json:"receive"` @@ -132,7 +133,7 @@ type ApiExternalMatchBundle struct { } // ApiExternalMatchResult is the result of a request to generate an external match -type ApiExternalMatchResult struct { +type ApiExternalMatchResult struct { //nolint:revive QuoteMint string `json:"quote_mint"` BaseMint string `json:"base_mint"` QuoteAmount Amount `json:"quote_amount"` @@ -141,7 +142,7 @@ type ApiExternalMatchResult struct { } // ApiSettlementTransaction is an EVM transaction parameterization for settling an external match -type ApiSettlementTransaction struct { +type ApiSettlementTransaction struct { //nolint:revive Type string `json:"type"` To string `json:"to"` Data string `json:"data"` diff --git a/client/api_types/api_order_book.go b/client/api_types/api_order_book.go index 8233f27..42e329d 100644 --- a/client/api_types/api_order_book.go +++ b/client/api_types/api_order_book.go @@ -1,7 +1,7 @@ -package api_types +package api_types //nolint:revive // ApiToken is a token available on the exchange -type ApiToken struct { +type ApiToken struct { //nolint:revive // The mint (erc20 address) of the token Address string `json:"address"` // The symbol of the token diff --git a/client/api_types/api_wallet.go b/client/api_types/api_wallet.go index d93219a..ce658fc 100644 --- a/client/api_types/api_wallet.go +++ b/client/api_types/api_wallet.go @@ -1,4 +1,5 @@ -package api_types +// Package api_types provides API data structures for the Renegade SDK +package api_types //nolint:revive import ( "crypto/ecdsa" @@ -14,25 +15,31 @@ import ( // The number of u32 limbs in the serialized form of a secret share const secretShareLimbCount = 8 // 256 bits +// Amount is a big.Int marshalled and unmarshalled as a rust-compatible string type Amount big.Int +// NewAmount creates a new Amount from an int64 func NewAmount(i int64) Amount { return Amount(*big.NewInt(i)) } +// IsZero returns true if the amount is zero func (a *Amount) IsZero() bool { return (*big.Int)(a).Sign() == 0 } +// String returns the string representation of the amount func (a *Amount) String() string { return (*big.Int)(a).String() } +// MarshalJSON marshals the amount to a JSON string func (a Amount) MarshalJSON() ([]byte, error) { s := a.String() return []byte(s), nil } +// SetString sets the amount from a string func (a *Amount) SetString(s string, base int) error { i, ok := new(big.Int).SetString(s, base) if !ok { @@ -42,31 +49,37 @@ func (a *Amount) SetString(s string, base int) error { return nil } +// UnmarshalJSON unmarshals the amount from a JSON string func (a *Amount) UnmarshalJSON(b []byte) error { s := string(b) return a.SetString(s, 10) } +// Add adds two amounts func (a Amount) Add(b Amount) Amount { sum := new(big.Int).Add((*big.Int)(&a), (*big.Int)(&b)) return Amount(*sum) } +// Sub subtracts two amounts func (a Amount) Sub(b Amount) Amount { diff := new(big.Int).Sub((*big.Int)(&a), (*big.Int)(&b)) return Amount(*diff) } +// Mul multiplies two amounts func (a Amount) Mul(b Amount) Amount { prod := new(big.Int).Mul((*big.Int)(&a), (*big.Int)(&b)) return Amount(*prod) } +// Div divides two amounts func (a Amount) Div(b Amount) Amount { quot := new(big.Int).Div((*big.Int)(&a), (*big.Int)(&b)) return Amount(*quot) } +// Cmp compares two amounts func (a Amount) Cmp(b Amount) int { return (*big.Int)(&a).Cmp((*big.Int)(&b)) } @@ -101,9 +114,9 @@ func orderSideToScalar(side string) (wallet.Scalar, error) { } // ApiOrder is an order in a Renegade wallet -type ApiOrder struct { +type ApiOrder struct { //nolint:revive // The id of the order - Id uuid.UUID `json:"id"` + Id uuid.UUID `json:"id"` //nolint:revive // The mint (erc20 address) of the base asset // As a hex string BaseMint string `json:"base_mint"` @@ -162,7 +175,7 @@ func (a *ApiOrder) ToOrder(o *wallet.Order) error { } // ApiBalance is a balance in a Renegade wallet -type ApiBalance struct { +type ApiBalance struct { //nolint:revive // The mint (erc20 address) of the asset Mint string `json:"mint"` // The amount of the asset @@ -201,17 +214,18 @@ func (a *ApiBalance) ToBalance(b *wallet.Balance) error { // ApiFee is a fee in the Renegade system, due on a match, balance, etc // Contains both a relayer fee and a protocol fee -type ApiFee struct { +type ApiFee struct { //nolint:revive RelayerFee Amount `json:"relayer_fee"` ProtocolFee Amount `json:"protocol_fee"` } +// Total returns the total fee func (f *ApiFee) Total() Amount { return f.RelayerFee.Add(f.ProtocolFee) } // ApiPublicKeychain is a public keychain in the Renegade system -type ApiPublicKeychain struct { +type ApiPublicKeychain struct { //nolint:revive // The public root key of the wallet // As a hex string PkRoot string `json:"pk_root"` @@ -220,6 +234,7 @@ type ApiPublicKeychain struct { PkMatch string `json:"pk_match"` } +// FromPublicKeychain converts a wallet.PublicKeychain to an ApiPublicKeychain func (a *ApiPublicKeychain) FromPublicKeychain(pk *wallet.PublicKeychain) error { a.PkRoot = pk.PkRoot.ToHexString() a.PkMatch = pk.PkMatch.ToHexString() @@ -227,6 +242,7 @@ func (a *ApiPublicKeychain) FromPublicKeychain(pk *wallet.PublicKeychain) error return nil } +// ToPublicKeychain converts an ApiPublicKeychain to a wallet.PublicKeychain func (a *ApiPublicKeychain) ToPublicKeychain() (*wallet.PublicKeychain, error) { pkRoot, err := new(wallet.PublicSigningKey).FromHexString(a.PkRoot) if err != nil { @@ -244,7 +260,7 @@ func (a *ApiPublicKeychain) ToPublicKeychain() (*wallet.PublicKeychain, error) { } // ApiPrivateKeychain represents a private keychain for the API wallet -type ApiPrivateKeychain struct { +type ApiPrivateKeychain struct { //nolint:revive // The private root key of the wallet // As a hex string, optional SkRoot *string `json:"sk_root,omitempty"` @@ -302,7 +318,7 @@ func (a *ApiPrivateKeychain) ToPrivateKeychain() (*wallet.PrivateKeychain, error } // ApiKeychain represents a keychain API type that maintains all keys as hex strings -type ApiKeychain struct { +type ApiKeychain struct { //nolint:revive // The public keychain PublicKeys ApiPublicKeychain `json:"public_keys"` // The private keychain @@ -346,9 +362,9 @@ func (a *ApiKeychain) ToKeychain() (*wallet.Keychain, error) { } // ApiWallet is a wallet in the Renegade system -type ApiWallet struct { +type ApiWallet struct { //nolint: revive // Identifier - Id uuid.UUID `json:"id"` + Id uuid.UUID `json:"id"` //nolint: revive // The orders maintained by this wallet Orders []ApiOrder `json:"orders"` // The balances maintained by the wallet to cover orders @@ -370,6 +386,7 @@ type ApiWallet struct { Blinder [secretShareLimbCount]uint32 `json:"blinder"` } +// FromWallet converts a wallet.Wallet to an ApiWallet func (a *ApiWallet) FromWallet(w *wallet.Wallet) (*ApiWallet, error) { a.Id = w.Id diff --git a/client/api_types/api_wallet_test.go b/client/api_types/api_wallet_test.go index c2dd0d4..97bb3c2 100644 --- a/client/api_types/api_wallet_test.go +++ b/client/api_types/api_wallet_test.go @@ -1,4 +1,4 @@ -package api_types +package api_types //nolint:revive import ( "crypto/ecdsa" @@ -6,8 +6,9 @@ import ( "testing" "github.com/ethereum/go-ethereum/crypto/secp256k1" - "github.com/renegade-fi/golang-sdk/wallet" "github.com/stretchr/testify/assert" + + "github.com/renegade-fi/golang-sdk/wallet" ) func TestApiWalletConversion(t *testing.T) { diff --git a/client/api_types/conversion.go b/client/api_types/conversion.go index a000c09..94466ca 100644 --- a/client/api_types/conversion.go +++ b/client/api_types/conversion.go @@ -1,4 +1,4 @@ -package api_types +package api_types //nolint:revive import ( "math/big" @@ -12,7 +12,7 @@ func ScalarToUintLimbs(s wallet.Scalar) ScalarLimbs { limbs := [secretShareLimbCount]uint32{} for i := 0; i < secretShareLimbCount; i++ { if bigint.BitLen() > 0 { - limbs[i] = uint32(bigint.Uint64()) + limbs[i] = uint32(bigint.Uint64()) //nolint:gosec bigint.Rsh(bigint, 32) } else { break diff --git a/client/api_types/conversion_test.go b/client/api_types/conversion_test.go index d01aecc..d9a1eed 100644 --- a/client/api_types/conversion_test.go +++ b/client/api_types/conversion_test.go @@ -1,11 +1,12 @@ -package api_types +package api_types //nolint:revive import ( "testing" "github.com/consensys/gnark-crypto/ecc/bn254/fr" - "github.com/renegade-fi/golang-sdk/wallet" "github.com/stretchr/testify/assert" + + "github.com/renegade-fi/golang-sdk/wallet" ) func TestScalarUintLimbConversion(t *testing.T) { diff --git a/client/api_types/request_response_types.go b/client/api_types/request_response_types.go index 3d30dd4..201d772 100644 --- a/client/api_types/request_response_types.go +++ b/client/api_types/request_response_types.go @@ -1,4 +1,4 @@ -package api_types +package api_types //nolint:revive import ( "fmt" @@ -6,8 +6,10 @@ import ( "github.com/google/uuid" ) +//nolint:revive const ( // --- Orderbook Endpoints --- // + // GetSupportedTokensPath is the path for the GetSupportedTokens action GetSupportedTokensPath = "/v0/supported-tokens" // --- Wallet Endpoints --- // @@ -17,7 +19,7 @@ const ( // in its queue have been processed BackOfQueueWalletPath = "/v0/wallet/%s/back-of-queue" // LookupWalletPath is the path for the LookupWallet action - LookupWalletPath = "/v0/wallet/lookup" + LookupWalletPath = "/v0/wallet/lookup" //nolint:gosec // RefreshWalletPath is the path for the RefreshWallet action RefreshWalletPath = "/v0/wallet/%s/refresh" // CreateWalletPath is the path for the CreateWallet action @@ -46,6 +48,7 @@ const ( AssembleExternalQuotePath = "/v0/matching-engine/assemble-external-match" ) +// ScalarLimbs is an array of uint32 limbs type ScalarLimbs [secretShareLimbCount]uint32 // WalletUpdateAuthorization encapsulates the client generated authorization for wallet updates @@ -58,53 +61,53 @@ type WalletUpdateAuthorization struct { } // BuildGetWalletPath builds the path for the GetWallet action -func BuildGetWalletPath(walletId uuid.UUID) string { - return fmt.Sprintf(GetWalletPath, walletId) +func BuildGetWalletPath(walletID uuid.UUID) string { + return fmt.Sprintf(GetWalletPath, walletID) } // BuildBackOfQueueWalletPath builds the path for the BackOfQueueWallet action -func BuildBackOfQueueWalletPath(walletId uuid.UUID) string { - return fmt.Sprintf(BackOfQueueWalletPath, walletId) +func BuildBackOfQueueWalletPath(walletID uuid.UUID) string { + return fmt.Sprintf(BackOfQueueWalletPath, walletID) } // BuildRefreshWalletPath builds the path for the RefreshWallet action -func BuildRefreshWalletPath(walletId uuid.UUID) string { - return fmt.Sprintf(RefreshWalletPath, walletId) +func BuildRefreshWalletPath(walletID uuid.UUID) string { + return fmt.Sprintf(RefreshWalletPath, walletID) } // BuildCreateOrderPath builds the path for the CreateOrder action -func BuildCreateOrderPath(walletId uuid.UUID) string { - return fmt.Sprintf(CreateOrderPath, walletId) +func BuildCreateOrderPath(walletID uuid.UUID) string { + return fmt.Sprintf(CreateOrderPath, walletID) } // BuildCancelOrderPath builds the path for the CancelOrder action -func BuildCancelOrderPath(walletId uuid.UUID, orderId uuid.UUID) string { - return fmt.Sprintf(CancelOrderPath, walletId, orderId) +func BuildCancelOrderPath(walletID uuid.UUID, orderID uuid.UUID) string { + return fmt.Sprintf(CancelOrderPath, walletID, orderID) } // BuildDepositPath builds the path for the Deposit action -func BuildDepositPath(walletId uuid.UUID) string { - return fmt.Sprintf(DepositPath, walletId) +func BuildDepositPath(walletID uuid.UUID) string { + return fmt.Sprintf(DepositPath, walletID) } // BuildWithdrawPath builds the path for the Withdraw action -func BuildWithdrawPath(walletId uuid.UUID, mint string) string { - return fmt.Sprintf(WithdrawPath, walletId, mint) +func BuildWithdrawPath(walletID uuid.UUID, mint string) string { + return fmt.Sprintf(WithdrawPath, walletID, mint) } // BuildPayFeesPath builds the path for the PayFees action -func BuildPayFeesPath(walletId uuid.UUID) string { - return fmt.Sprintf(PayFeesPath, walletId) +func BuildPayFeesPath(walletID uuid.UUID) string { + return fmt.Sprintf(PayFeesPath, walletID) } // BuildTaskStatusPath builds the path for the TaskStatus action -func BuildTaskStatusPath(taskId uuid.UUID) string { - return fmt.Sprintf(TaskStatusPath, taskId) +func BuildTaskStatusPath(taskID uuid.UUID) string { + return fmt.Sprintf(TaskStatusPath, taskID) } // BuildTaskHistoryPath builds the path for the TaskHistory action -func BuildTaskHistoryPath(walletId uuid.UUID) string { - return fmt.Sprintf(TaskHistoryPath, walletId) +func BuildTaskHistoryPath(walletID uuid.UUID) string { + return fmt.Sprintf(TaskHistoryPath, walletID) } // ----------------------- @@ -127,7 +130,7 @@ type GetWalletResponse struct { // LookupWalletRequest is the request body for the LookupWallet action type LookupWalletRequest struct { - WalletId uuid.UUID `json:"wallet_id"` + WalletId uuid.UUID `json:"wallet_id"` //nolint:revive BlinderSeed ScalarLimbs `json:"blinder_seed"` ShareSeed ScalarLimbs `json:"secret_share_seed"` PrivateKeychain ApiPrivateKeychain `json:"private_keychain"` @@ -135,13 +138,13 @@ type LookupWalletRequest struct { // LookupWalletResponse is the response body for a LookupWallet request type LookupWalletResponse struct { - WalletId uuid.UUID `json:"wallet_id"` - TaskId uuid.UUID `json:"task_id"` + WalletId uuid.UUID `json:"wallet_id"` //nolint:revive + TaskId uuid.UUID `json:"task_id"` //nolint:revive } // RefreshWalletResponse is the response body for a RefreshWallet request type RefreshWalletResponse struct { - TaskId uuid.UUID `json:"task_id"` + TaskId uuid.UUID `json:"task_id"` //nolint:revive } // CreateWalletRequest is the request body for the CreateWallet action @@ -152,8 +155,8 @@ type CreateWalletRequest struct { // CreateWalletResponse is the response body for the CreateWallet action type CreateWalletResponse struct { - TaskId uuid.UUID `json:"task_id"` - WalletId uuid.UUID `json:"wallet_id"` + TaskId uuid.UUID `json:"task_id"` //nolint:revive + WalletId uuid.UUID `json:"wallet_id"` //nolint:revive } // CreateOrderRequest is the request body for the CreateOrder action @@ -165,9 +168,9 @@ type CreateOrderRequest struct { // CreateOrderResponse is the response body for the CreateOrder action type CreateOrderResponse struct { // Id is the ID of the order that was created - Id uuid.UUID `json:"id"` + Id uuid.UUID `json:"id"` //nolint:revive // TaskId is the ID of the task that was created to update the wallet - TaskId uuid.UUID `json:"task_id"` + TaskId uuid.UUID `json:"task_id"` //nolint:revive } // CancelOrderRequest is the request body for the CancelOrder action @@ -178,7 +181,7 @@ type CancelOrderRequest struct { // CancelOrderResponse is the response body for the CancelOrder action type CancelOrderResponse struct { // TaskId is the ID of the task that was created to update the wallet - TaskId uuid.UUID `json:"task_id"` + TaskId uuid.UUID `json:"task_id"` //nolint:revive // Order is the order that was canceled Order ApiOrder `json:"order"` } @@ -206,7 +209,7 @@ type DepositRequest struct { // DepositResponse is the response body for the Deposit action type DepositResponse struct { // TaskId is the ID of the task that was created to update the wallet - TaskId uuid.UUID `json:"task_id"` + TaskId uuid.UUID `json:"task_id"` //nolint:revive } // WithdrawRequest is the request body for the Withdraw action @@ -225,18 +228,18 @@ type WithdrawRequest struct { // WithdrawResponse is the response body for the Withdraw action type WithdrawResponse struct { // TaskId is the ID of the task that was created to update the wallet - TaskId uuid.UUID `json:"task_id"` + TaskId uuid.UUID `json:"task_id"` //nolint:revive } // PayFeesResponse is the response body for the PayFees action type PayFeesResponse struct { // TaskIds are the IDs of the tasks that were created to pay the fees - TaskIds []uuid.UUID `json:"task_ids"` + TaskIds []uuid.UUID `json:"task_ids"` //nolint:revive } // ApiTaskStatus is the status of a running task // ApiTaskStatus represents the status of a task -type ApiTaskStatus struct { +type ApiTaskStatus struct { //nolint:revive // ID is the identifier of the task ID uuid.UUID `json:"id"` // Description is the description of the task @@ -254,9 +257,9 @@ type TaskResponse struct { } // ApiHistoricalTask represents a historical task -type ApiHistoricalTask struct { +type ApiHistoricalTask struct { //nolint:revive // ID is the identifier of the task - Id uuid.UUID `json:"id"` + Id uuid.UUID `json:"id"` //nolint:revive // State is the current state of the task State string `json:"state"` // CreatedAt is the timestamp when the task was created diff --git a/client/external_match_client/client.go b/client/external_match_client/client.go index 231ef0b..0f19fb0 100644 --- a/client/external_match_client/client.go +++ b/client/external_match_client/client.go @@ -1,4 +1,4 @@ -package external_match_client +package external_match_client //nolint:revive import ( "encoding/json" @@ -7,17 +7,19 @@ import ( "net/http" geth_common "github.com/ethereum/go-ethereum/common" + "github.com/renegade-fi/golang-sdk/client" "github.com/renegade-fi/golang-sdk/client/api_types" "github.com/renegade-fi/golang-sdk/wallet" ) +//nolint:revive const ( testnetBaseUrl = "https://testnet.auth-server.renegade.fi:3000" testnetRelayerBaseUrl = "https://testnet.cluster0.renegade.fi:3000" mainnetBaseUrl = "https://mainnet.auth-server.renegade.fi:3000" mainnetRelayerBaseUrl = "https://mainnet.cluster0.renegade.fi:3000" - apiKeyHeader = "X-Renegade-Api-Key" + apiKeyHeader = "X-Renegade-Api-Key" //nolint:gosec ) // ExternalMatchBundle is the application level analog to the ApiExternalMatchBundle @@ -94,7 +96,7 @@ func NewAssembleExternalMatchOptions() *AssembleExternalMatchOptions { type ExternalMatchClient struct { apiKey string httpClient *client.HttpClient - relayerHttpClient *client.HttpClient + relayerHttpClient *client.HttpClient //nolint:revive } // NewTestnetExternalMatchClient creates a new ExternalMatchClient for the testnet diff --git a/client/http.go b/client/http.go index dcfe5e3..591dc9c 100644 --- a/client/http.go +++ b/client/http.go @@ -1,3 +1,4 @@ +// Package client provides a client for the renegade API package client import ( @@ -28,14 +29,14 @@ const ( ) // HttpClient represents an HTTP client with a base URL and auth key -type HttpClient struct { +type HttpClient struct { //nolint:revive baseURL string httpClient *http.Client authKey *wallet.HmacKey } // NewHttpClient creates a new HttpClient with the given base URL and auth key -func NewHttpClient(baseURL string, authKey *wallet.HmacKey) *HttpClient { +func NewHttpClient(baseURL string, authKey *wallet.HmacKey) *HttpClient { //nolint:revive return &HttpClient{ baseURL: baseURL, httpClient: &http.Client{}, @@ -175,6 +176,7 @@ func (c *HttpClient) doRequestWithStatus( if err != nil { return 0, nil, fmt.Errorf("failed to send request: %w", err) } + //nolint:errcheck defer resp.Body.Close() // Read and check the response @@ -200,7 +202,7 @@ func (c *HttpClient) addAuth(req *http.Request, bodyBytes []byte) { // Compute the expiration time expiration := time.Now().Add(signatureExpiration * time.Second).UnixMilli() expirationBytes := make([]byte, 8) - binary.LittleEndian.PutUint64(expirationBytes, uint64(expiration)) + binary.LittleEndian.PutUint64(expirationBytes, uint64(expiration)) //nolint:gosec req.Header.Set(expirationHeader, strconv.FormatInt(expiration, 10)) // Create the hmac diff --git a/client/renegade_client/balance_operations.go b/client/renegade_client/balance_operations.go index c661b7a..db59744 100644 --- a/client/renegade_client/balance_operations.go +++ b/client/renegade_client/balance_operations.go @@ -1,3 +1,4 @@ +// Package client provides a client for the renegade API package client import ( @@ -53,8 +54,8 @@ func (c *RenegadeClient) deposit( req.WalletUpdateAuthorization = *auth // Post the deposit to the relayer - walletId := c.walletSecrets.Id - path := api_types.BuildDepositPath(walletId) + walletID := c.walletSecrets.Id + path := api_types.BuildDepositPath(walletID) resp := api_types.DepositResponse{} err = c.httpClient.PostWithAuth(path, req, &resp) @@ -258,8 +259,8 @@ func (c *RenegadeClient) generatePermit2Signature( ) (*PermitWitnessTransferFrom, []byte, error) { // Construct the EIP712 domain permit2Address := common.HexToAddress(c.chainConfig.Permit2Address) - chainId := big.NewInt(int64(c.chainConfig.ChainID)) - domain := ConstructEIP712Domain(chainId, permit2Address) + chainID := big.NewInt(int64(c.chainConfig.ChainID)) //nolint:gosec + domain := ConstructEIP712Domain(chainID, permit2Address) // Create the TokenPermissions struct tokenPermissions := abis.ISignatureTransferTokenPermissions{ diff --git a/client/renegade_client/client.go b/client/renegade_client/client.go index 2fb754b..7636f44 100644 --- a/client/renegade_client/client.go +++ b/client/renegade_client/client.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/ethclient" "github.com/google/uuid" + "github.com/renegade-fi/golang-sdk/client" "github.com/renegade-fi/golang-sdk/client/api_types" "github.com/renegade-fi/golang-sdk/wallet" @@ -23,10 +24,11 @@ type ChainConfig struct { // DarkpoolAddress is the address of the Darkpool contract DarkpoolAddress string // EthereumRpcUrl is the URL of the Ethereum RPC - EthereumRpcUrl string + EthereumRpcUrl string //nolint:revive } var ( + // ArbitrumOneConfig is the configuration for the Arbitrum One chain ArbitrumOneConfig = ChainConfig{ ChainID: 42161, Permit2Address: "0x000000000022D473030F116dDEE9F6B43aC78BA3", @@ -34,6 +36,7 @@ var ( EthereumRpcUrl: "https://arb1.arbitrum.io/rpc", } + // ArbitrumSepoliaConfig is the configuration for the Arbitrum Sepolia chain ArbitrumSepoliaConfig = ChainConfig{ ChainID: 421614, Permit2Address: "0x9458198bcc289c42e460cb8ca143e5854f734442", @@ -295,7 +298,7 @@ func (c *RenegadeClient) PlaceOrder(order *wallet.Order) (*wallet.Wallet, error) // Returns: // - *api_types.CancelOrderResponse: Contains the task ID and the canceled order if successful. // - error: An error if the order cancellation fails, nil otherwise. -func (c *RenegadeClient) CancelOrder(orderId uuid.UUID) (*wallet.Wallet, error) { +func (c *RenegadeClient) CancelOrder(orderId uuid.UUID) (*wallet.Wallet, error) { //nolint:revive if err := c.cancelOrder(orderId, true /* blocking */); err != nil { return nil, err } @@ -326,7 +329,7 @@ func getWalletUpdateAuth(wallet *wallet.Wallet) (*api_types.WalletUpdateAuthoriz } // createRpcClient creates a new RPC client -func (c *RenegadeClient) createRpcClient() (*ethclient.Client, error) { +func (c *RenegadeClient) createRpcClient() (*ethclient.Client, error) { //nolint:revive return ethclient.Dial(c.chainConfig.EthereumRpcUrl) } @@ -334,7 +337,7 @@ func (c *RenegadeClient) createRpcClient() (*ethclient.Client, error) { func (c *RenegadeClient) createTransactor( ethPrivateKey *ecdsa.PrivateKey, ) (*bind.TransactOpts, error) { - chainID := big.NewInt(int64(c.chainConfig.ChainID)) + chainID := big.NewInt(int64(c.chainConfig.ChainID)) //nolint:gosec auth, err := bind.NewKeyedTransactorWithChainID(ethPrivateKey, chainID) if err != nil { return nil, fmt.Errorf("failed to create transactor: %w", err) diff --git a/client/renegade_client/order_operations.go b/client/renegade_client/order_operations.go index 5102462..22d20d2 100644 --- a/client/renegade_client/order_operations.go +++ b/client/renegade_client/order_operations.go @@ -2,6 +2,7 @@ package client import ( "github.com/google/uuid" + "github.com/renegade-fi/golang-sdk/client/api_types" "github.com/renegade-fi/golang-sdk/wallet" ) @@ -41,8 +42,8 @@ func (c *RenegadeClient) placeOrder(order *wallet.Order, blocking bool) error { WalletUpdateAuthorization: *auth, } - walletId := c.walletSecrets.Id - path := api_types.BuildCreateOrderPath(walletId) + walletID := c.walletSecrets.Id + path := api_types.BuildCreateOrderPath(walletID) resp := api_types.CreateOrderResponse{} err = c.httpClient.PostWithAuth(path, req, &resp) @@ -61,7 +62,7 @@ func (c *RenegadeClient) placeOrder(order *wallet.Order, blocking bool) error { } // cancelOrder cancels an order via the Renegade API -func (c *RenegadeClient) cancelOrder(orderId uuid.UUID, blocking bool) error { +func (c *RenegadeClient) cancelOrder(orderID uuid.UUID, blocking bool) error { // Get the back of the queue wallet backOfQueueWallet, err := c.GetBackOfQueueWallet() if err != nil { @@ -69,7 +70,7 @@ func (c *RenegadeClient) cancelOrder(orderId uuid.UUID, blocking bool) error { } // Cancel the order - err = backOfQueueWallet.CancelOrder(orderId) + err = backOfQueueWallet.CancelOrder(orderID) if err != nil { return err } @@ -85,8 +86,8 @@ func (c *RenegadeClient) cancelOrder(orderId uuid.UUID, blocking bool) error { } // Post the order to the relayer - walletId := c.walletSecrets.Id - path := api_types.BuildCancelOrderPath(walletId, orderId) + walletID := c.walletSecrets.Id + path := api_types.BuildCancelOrderPath(walletID, orderID) req := api_types.CancelOrderRequest{ WalletUpdateAuthorization: *auth, } diff --git a/client/renegade_client/permit2.go b/client/renegade_client/permit2.go index 7fcaa67..863c348 100644 --- a/client/renegade_client/permit2.go +++ b/client/renegade_client/permit2.go @@ -9,6 +9,7 @@ import ( "github.com/renegade-fi/golang-sdk/abis" ) +// PermitWitnessTransferFrom is the permit for the deposit type PermitWitnessTransferFrom struct { Permitted abis.ISignatureTransferTokenPermissions Spender common.Address @@ -23,19 +24,20 @@ type DepositWitness struct { PkRoot [4]*big.Int } -const PERMIT2_EIP712_DOMAIN_NAME = "Permit2" +const permit2EIP712DomainName = "Permit2" +// EIP712Domain is the domain for the permit type EIP712Domain struct { Name string - ChainId *big.Int + ChainId *big.Int //nolint:revive VerifyingContract common.Address } // ConstructEIP712Domain constructs an EIP712Domain -func ConstructEIP712Domain(chainId *big.Int, verifyingContract common.Address) EIP712Domain { +func ConstructEIP712Domain(chainID *big.Int, verifyingContract common.Address) EIP712Domain { return EIP712Domain{ - Name: PERMIT2_EIP712_DOMAIN_NAME, - ChainId: chainId, + Name: permit2EIP712DomainName, + ChainId: chainID, VerifyingContract: verifyingContract, } } diff --git a/client/renegade_client/tasks.go b/client/renegade_client/tasks.go index 3f15523..de93cce 100644 --- a/client/renegade_client/tasks.go +++ b/client/renegade_client/tasks.go @@ -7,6 +7,7 @@ import ( "time" "github.com/google/uuid" + "github.com/renegade-fi/golang-sdk/client/api_types" ) @@ -19,8 +20,8 @@ const ( // getTaskHistory gets the task history for a given wallet func (c *RenegadeClient) getTaskHistory() ([]api_types.ApiHistoricalTask, error) { - walletId := c.walletSecrets.Id - path := api_types.BuildTaskHistoryPath(walletId) + walletID := c.walletSecrets.Id + path := api_types.BuildTaskHistoryPath(walletID) resp := api_types.TaskHistoryResponse{} err := c.httpClient.GetWithAuth(path, nil /* body */, &resp) if err != nil { @@ -31,7 +32,7 @@ func (c *RenegadeClient) getTaskHistory() ([]api_types.ApiHistoricalTask, error) } // getTask gets a task by id -func (c *RenegadeClient) getTaskStatusFromHistory(taskId uuid.UUID) (string, error) { +func (c *RenegadeClient) getTaskStatusFromHistory(taskID uuid.UUID) (string, error) { tasks, err := c.getTaskHistory() if err != nil { return "", err @@ -39,7 +40,7 @@ func (c *RenegadeClient) getTaskStatusFromHistory(taskId uuid.UUID) (string, err // Find the task for _, task := range tasks { - if task.Id == taskId { + if task.Id == taskID { return task.State, nil } } @@ -48,14 +49,14 @@ func (c *RenegadeClient) getTaskStatusFromHistory(taskId uuid.UUID) (string, err } // getTaskStatusDirect gets the status of a task directly from the task endpoint -func (c *RenegadeClient) getTaskStatusDirect(taskId uuid.UUID) (string, error) { - path := api_types.BuildTaskStatusPath(taskId) +func (c *RenegadeClient) getTaskStatusDirect(taskID uuid.UUID) (string, error) { + path := api_types.BuildTaskStatusPath(taskID) resp := api_types.TaskResponse{} err := c.httpClient.GetWithAuth(path, nil /* body */, &resp) // If the task is no longer registered, check task history if err != nil && strings.Contains(err.Error(), "task not found") { - return c.getTaskStatusFromHistory(taskId) + return c.getTaskStatusFromHistory(taskID) } if err != nil { @@ -66,20 +67,19 @@ func (c *RenegadeClient) getTaskStatusDirect(taskId uuid.UUID) (string, error) { } // getTaskStatus gets the status of a task by looking up the task in the task history -func (c *RenegadeClient) getTaskStatus(taskId uuid.UUID, direct bool) (string, error) { +func (c *RenegadeClient) getTaskStatus(taskID uuid.UUID, direct bool) (string, error) { if direct { - return c.getTaskStatusDirect(taskId) - } else { - return c.getTaskStatusFromHistory(taskId) + return c.getTaskStatusDirect(taskID) } + return c.getTaskStatusFromHistory(taskID) } // waitForTaskGeneric waits for a task to complete or until the timeout is reached -func (c *RenegadeClient) waitForTaskGeneric(taskId uuid.UUID, direct bool) error { - log.Printf("waiting for task %s to complete", taskId) +func (c *RenegadeClient) waitForTaskGeneric(taskID uuid.UUID, direct bool) error { + log.Printf("waiting for task %s to complete", taskID) deadline := time.Now().Add(taskTimeout) for time.Now().Before(deadline) { - state, err := c.getTaskStatus(taskId, direct) + state, err := c.getTaskStatus(taskID, direct) if err != nil { return err } @@ -87,10 +87,10 @@ func (c *RenegadeClient) waitForTaskGeneric(taskId uuid.UUID, direct bool) error // Check for completion or failure state = strings.ToLower(state) if state == taskCompletedStatus { - log.Printf("task %s completed", taskId) + log.Printf("task %s completed", taskID) return nil } else if state == taskFailedStatus { - log.Printf("task %s failed", taskId) + log.Printf("task %s failed", taskID) return fmt.Errorf("task failed") } @@ -101,11 +101,11 @@ func (c *RenegadeClient) waitForTaskGeneric(taskId uuid.UUID, direct bool) error } // waitForTask waits for a task to complete or until the timeout is reached -func (c *RenegadeClient) waitForTask(taskId uuid.UUID) error { - return c.waitForTaskGeneric(taskId, false /* direct */) +func (c *RenegadeClient) waitForTask(taskID uuid.UUID) error { + return c.waitForTaskGeneric(taskID, false /* direct */) } // waitForTaskWithDirect waits for a task to complete or until the timeout is reached -func (c *RenegadeClient) waitForTaskDirect(taskId uuid.UUID) error { - return c.waitForTaskGeneric(taskId, true /* direct */) +func (c *RenegadeClient) waitForTaskDirect(taskID uuid.UUID) error { + return c.waitForTaskGeneric(taskID, true /* direct */) } diff --git a/client/renegade_client/wallet_operations.go b/client/renegade_client/wallet_operations.go index e3faf2f..74569d5 100644 --- a/client/renegade_client/wallet_operations.go +++ b/client/renegade_client/wallet_operations.go @@ -7,8 +7,8 @@ import ( // getWallet retrieves a wallet from the relayer func (c *RenegadeClient) getWallet() (*wallet.Wallet, error) { - walletId := c.walletSecrets.Id - path := api_types.BuildGetWalletPath(walletId) + walletID := c.walletSecrets.Id + path := api_types.BuildGetWalletPath(walletID) resp := api_types.GetWalletResponse{} err := c.httpClient.GetWithAuth(path, nil /* body */, &resp) @@ -27,8 +27,8 @@ func (c *RenegadeClient) getWallet() (*wallet.Wallet, error) { // getBackOfQueueWallet retrieves the wallet at the back of the processing queue from the relayer func (c *RenegadeClient) getBackOfQueueWallet() (*wallet.Wallet, error) { - walletId := c.walletSecrets.Id - path := api_types.BuildBackOfQueueWalletPath(walletId) + walletID := c.walletSecrets.Id + path := api_types.BuildBackOfQueueWalletPath(walletID) resp := api_types.GetWalletResponse{} err := c.httpClient.GetWithAuth(path, nil /* body */, &resp) @@ -63,7 +63,7 @@ func (c *RenegadeClient) getBackOfQueueWallet() (*wallet.Wallet, error) { // share seed, and private keychain (excluding the root key). It then sends a POST // request to the relayer and returns the response. func (c *RenegadeClient) lookupWallet(blocking bool) error { - walletId := c.walletSecrets.Id + walletID := c.walletSecrets.Id path := api_types.LookupWalletPath // Build the request @@ -77,7 +77,7 @@ func (c *RenegadeClient) lookupWallet(blocking bool) error { blinderSeed := api_types.ScalarToUintLimbs(c.walletSecrets.BlinderSeed) shareSeed := api_types.ScalarToUintLimbs(c.walletSecrets.ShareSeed) request := api_types.LookupWalletRequest{ - WalletId: walletId, + WalletId: walletID, BlinderSeed: blinderSeed, ShareSeed: shareSeed, PrivateKeychain: *keys, @@ -117,8 +117,8 @@ func (c *RenegadeClient) lookupWallet(blocking bool) error { // to the relayer. If successful, it returns the response containing the task ID for tracking // the refresh operation. func (c *RenegadeClient) refreshWallet(blocking bool) error { - walletId := c.walletSecrets.Id - path := api_types.BuildRefreshWalletPath(walletId) + walletID := c.walletSecrets.Id + path := api_types.BuildRefreshWalletPath(walletID) resp := api_types.RefreshWalletResponse{} err := c.httpClient.PostWithAuth(path, nil, &resp) diff --git a/crypto/poseidon2.go b/crypto/poseidon2.go index ed461f7..fc0f3d7 100644 --- a/crypto/poseidon2.go +++ b/crypto/poseidon2.go @@ -1,3 +1,4 @@ +// Package crypto provides cryptographic primitives for the Renegade SDK package crypto import ( @@ -25,7 +26,7 @@ func (p *PoseidonCSPRNG) Next() fr.Element { return hashRes } -// Return the next n scalars in the CSPRNG +// NextN returns the next n scalars in the CSPRNG func (p *PoseidonCSPRNG) NextN(n int) []fr.Element { result := make([]fr.Element, n) for i := 0; i < n; i++ { @@ -57,7 +58,7 @@ func NewPoseidon2Sponge() *Poseidon2Sponge { // Hash hashes the given input and returns a single-squeeze func (p *Poseidon2Sponge) Hash(seq []fr.Element) fr.Element { - //nolint:errcheck + //nolint:errcheck,gosec p.AbsorbBatch(seq) return p.Squeeze() } @@ -138,7 +139,7 @@ func (p *Poseidon2Sponge) externalRound(roundNumber int) { // externalAddRC adds a round constant to the state in an external round func (p *Poseidon2Sponge) externalAddRC(roundNumber int) { - rc := FULL_ROUND_CONSTANTS[roundNumber] + rc := fullRoundConstants[roundNumber] for i := range p.state { p.state[i].Add(&p.state[i], &rc[i]) } @@ -172,7 +173,7 @@ func (p *Poseidon2Sponge) internalRound(roundNumber int) { // internalAddRC adds a round constant to the first state element in an internal round func (p *Poseidon2Sponge) internalAddRC(roundNumber int) { - rc := PARTIAL_ROUND_CONSTANTS[roundNumber] + rc := partialRoundConstants[roundNumber] p.state[0].Add(&p.state[0], &rc) } diff --git a/crypto/poseidon2_constants.go b/crypto/poseidon2_constants.go index e41d4e9..47e3751 100644 --- a/crypto/poseidon2_constants.go +++ b/crypto/poseidon2_constants.go @@ -7,10 +7,10 @@ import ( // Poseidon2Sponge is a sponge const ( // R_F is the number of full rounds in the Poseidon permutation - R_F = 8 + R_F = 8 //nolint:revive // R_P is the number of partial rounds in the Poseidon permutation - R_P = 56 + R_P = 56 //nolint:revive // WIDTH is the width of the Poseidon permutation's code WIDTH = 3 @@ -27,7 +27,7 @@ const ( // FULL_ROUND_CONSTANTS are the round constants used in the full rounds of the Poseidon permutation // In Montgomery form -var FULL_ROUND_CONSTANTS = [R_F][WIDTH]fr.Element{ +var fullRoundConstants = [R_F][WIDTH]fr.Element{ { {15502152792957798476, 2953781152519934815, 789263285804927433, 3266336410389770144}, {6170676942082823556, 15509510193735291493, 7415284283107350036, 292284789622600672}, @@ -72,7 +72,7 @@ var FULL_ROUND_CONSTANTS = [R_F][WIDTH]fr.Element{ // PARTIAL_ROUND_CONSTANTS are the round constants used in the partial rounds // of the Poseidon permutation in Montgomery form -var PARTIAL_ROUND_CONSTANTS = [R_P]fr.Element{ +var partialRoundConstants = [R_P]fr.Element{ {7073706554792388047, 15115725580624899978, 3679228461395092567, 1155120523926954320}, {9209151483111776538, 17577545623568481397, 13585757825660930829, 3472890281115441576}, {5142214011637547477, 6729742127441928110, 7928974164783286805, 2757086277530341826}, diff --git a/crypto/poseidon2_test.go b/crypto/poseidon2_test.go index ae75a6e..f3221db 100644 --- a/crypto/poseidon2_test.go +++ b/crypto/poseidon2_test.go @@ -8,7 +8,7 @@ import ( ) // LARGE_TEST_VECTOR is a large random vector for testing purposes -var LARGE_TEST_VECTOR = []string{ +var largeTestVector = []string{ "19230904647065636396038552256938968853322683750200788848331370785095198876878", "15911637536990531499916323601087363308229536839479434470684150236988586364318", "19564613450635237900605484014415855639638711726565938233242326595431025719394", @@ -114,7 +114,7 @@ var LARGE_TEST_VECTOR = []string{ // LARGE_TEST_VECTOR_HASH is the expected hash output for LARGE_TEST_VECTOR // //nolint:lll -var LARGE_TEST_VECTOR_HASH = "7043431630205359021101812166882265280337929418769865370612041462630759989210" +var largeTestVectorHash = "7043431630205359021101812166882265280337929418769865370612041462630759989210" func feltFromString(s string) fr.Element { var felt fr.Element @@ -211,8 +211,8 @@ func TestPoseidon2Sponge_ErrorHandling(t *testing.T) { func TestPoseidon2Sponge_LargeVector(t *testing.T) { // Convert the test vector to a slice of `fr.Element` - input := make([]fr.Element, len(LARGE_TEST_VECTOR)) - for i, s := range LARGE_TEST_VECTOR { + input := make([]fr.Element, len(largeTestVector)) + for i, s := range largeTestVector { input[i] = feltFromString(s) } @@ -221,7 +221,7 @@ func TestPoseidon2Sponge_LargeVector(t *testing.T) { result := sponge.Hash(input) assert.Equal(t, - LARGE_TEST_VECTOR_HASH, + largeTestVectorHash, result.String(), "Hash result for large test vector mismatch", ) diff --git a/examples/01_external_match/main.go b/examples/01_external_match/main.go index 4e5ed6c..37f5653 100644 --- a/examples/01_external_match/main.go +++ b/examples/01_external_match/main.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/renegade-fi/golang-sdk/client/api_types" external_match_client "github.com/renegade-fi/golang-sdk/client/external_match_client" "github.com/renegade-fi/golang-sdk/wallet" diff --git a/examples/02_external_quote_validation/main.go b/examples/02_external_quote_validation/main.go index 2e3ba59..749d842 100644 --- a/examples/02_external_quote_validation/main.go +++ b/examples/02_external_quote_validation/main.go @@ -1,3 +1,5 @@ +// Package main is an example of how to use the Renegade SDK to get an external +// quote, validate it, and submit it to the sequencer. package main import ( @@ -10,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/renegade-fi/golang-sdk/client/api_types" external_match_client "github.com/renegade-fi/golang-sdk/client/external_match_client" "github.com/renegade-fi/golang-sdk/wallet" @@ -19,7 +22,7 @@ const ( quoteMint = "0xdf8d259c04020562717557f2b5a3cf28e92707d1" // USDC baseMint = "0xc3414a7ef14aaaa9c4522dfc00a4e66e74e9c25a" // WETH darkpoolAddress = "0x9af58f1ff20ab22e819e40b57ffd784d115a9ef5" - chainId = 421614 // Testnet + chainID = 421614 // Testnet ) func main() { @@ -97,7 +100,7 @@ func getQuoteAndSubmit(order *api_types.ApiExternalOrder, client *external_match return err } - fmt.Println("Bundle submitted successfully!\n") + fmt.Println("Bundle submitted successfully!") return nil } @@ -147,7 +150,7 @@ func submitBundle(bundle external_match_client.ExternalMatchBundle) error { } ethTx := types.NewTx(&types.DynamicFeeTx{ - ChainID: big.NewInt(chainId), // Sepolia chain ID + ChainID: big.NewInt(chainID), // Sepolia chain ID Nonce: nonce, GasTipCap: gasPrice, // Use suggested gas price as tip cap GasFeeCap: new(big.Int).Mul(gasPrice, big.NewInt(2)), // Fee cap at 2x gas price @@ -158,7 +161,7 @@ func submitBundle(bundle external_match_client.ExternalMatchBundle) error { }) // Sign and send transaction - signer := types.LatestSignerForChainID(big.NewInt(chainId)) + signer := types.LatestSignerForChainID(big.NewInt(chainID)) signedTx, err := types.SignTx(ethTx, signer, privateKey) if err != nil { panic(err) @@ -177,16 +180,16 @@ func submitBundle(bundle external_match_client.ExternalMatchBundle) error { // | Helpers | // ----------- -func getRpcUrl() string { - rpcUrl := os.Getenv("RPC_URL") - if rpcUrl == "" { +func getRpcURL() string { //nolint:revive + rpcURL := os.Getenv("RPC_URL") + if rpcURL == "" { panic("RPC_URL environment variable not set") } - return rpcUrl + return rpcURL } func getEthClient() (*ethclient.Client, error) { - return ethclient.Dial(getRpcUrl()) + return ethclient.Dial(getRpcURL()) } func getPrivateKey() (*ecdsa.PrivateKey, error) { diff --git a/examples/03_external_match_with_receiver/main.go b/examples/03_external_match_with_receiver/main.go index 1789fd9..8da8b48 100644 --- a/examples/03_external_match_with_receiver/main.go +++ b/examples/03_external_match_with_receiver/main.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/renegade-fi/golang-sdk/client/api_types" external_match_client "github.com/renegade-fi/golang-sdk/client/external_match_client" "github.com/renegade-fi/golang-sdk/wallet" diff --git a/examples/04_modify_quoted_order/main.go b/examples/04_modify_quoted_order/main.go index 8b46664..f3b187d 100644 --- a/examples/04_modify_quoted_order/main.go +++ b/examples/04_modify_quoted_order/main.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" + "github.com/renegade-fi/golang-sdk/client/api_types" external_match_client "github.com/renegade-fi/golang-sdk/client/external_match_client" "github.com/renegade-fi/golang-sdk/wallet" diff --git a/wallet/balance.go b/wallet/balance.go index a09b899..36b7e58 100644 --- a/wallet/balance.go +++ b/wallet/balance.go @@ -1,3 +1,4 @@ +// Package wallet provides a wallet for the Renegade system package wallet import ( diff --git a/wallet/fixed_point.go b/wallet/fixed_point.go index d8eed78..32ba71a 100644 --- a/wallet/fixed_point.go +++ b/wallet/fixed_point.go @@ -28,7 +28,7 @@ func NewFixedPoint(repr Scalar) FixedPoint { return FixedPoint{Repr: repr} } -// FromFloat creates a new fixed point number from a float +// FixedPointFromFloat creates a new fixed point number from a float func FixedPointFromFloat(f float64) FixedPoint { bigF := big.NewFloat(f) // Shift left by precisionBits @@ -59,7 +59,7 @@ func (fp FixedPoint) ToFloat() float64 { return f } -// ToDecimalString converts a fixed point number to the base10 string representation of its `repr` +// ToReprDecimalString converts a fixed point number to the base10 string representation of its `repr` func (fp FixedPoint) ToReprDecimalString() string { reprBigint := fp.Repr.ToBigInt() diff --git a/wallet/fixed_point_test.go b/wallet/fixed_point_test.go index 96497c2..5053ab1 100644 --- a/wallet/fixed_point_test.go +++ b/wallet/fixed_point_test.go @@ -13,7 +13,7 @@ const precisionTolerance = 1e-10 // TestFixedPoint tests the fixed point implementation func TestFixedPoint(t *testing.T) { // Generate a random float64 between 0 and 1000 - originalFloat := rand.Float64() * 1000 + originalFloat := rand.Float64() * 1000 //nolint:gosec // Convert to and from FixedPoint fixedPoint := FixedPointFromFloat(originalFloat) diff --git a/wallet/helpers.go b/wallet/helpers.go index 8cc5112..3d95a7e 100644 --- a/wallet/helpers.go +++ b/wallet/helpers.go @@ -2,6 +2,7 @@ package wallet import ( "github.com/consensys/gnark-crypto/ecc/bn254/fr" + renegade_crypto "github.com/renegade-fi/golang-sdk/crypto" ) diff --git a/wallet/keychain.go b/wallet/keychain.go index 28aa45d..ae5018d 100644 --- a/wallet/keychain.go +++ b/wallet/keychain.go @@ -90,6 +90,7 @@ func scalarLimbsToBigInt(limbs []Scalar) *big.Int { return b } +// ToScalars converts the public key to a slice of scalars func (pk *PublicSigningKey) ToScalars() ([]Scalar, error) { xScalars := bigintToScalarLimbs(*pk.X) yScalars := bigintToScalarLimbs(*pk.Y) @@ -108,6 +109,7 @@ func (pk *PublicSigningKey) ToScalars() ([]Scalar, error) { return []Scalar{xScalars[0], xScalars[1], yScalars[0], yScalars[1]}, nil } +// FromScalars converts a slice of scalars to a public key func (pk *PublicSigningKey) FromScalars(scalars *ScalarIterator) error { xScalars := make([]Scalar, 2) yScalars := make([]Scalar, 2) @@ -134,6 +136,7 @@ func (pk *PublicSigningKey) FromScalars(scalars *ScalarIterator) error { return nil } +// NumScalars returns the number of scalars in the public key func (pk *PublicSigningKey) NumScalars() int { return 4 } @@ -159,13 +162,16 @@ func (pk *PublicSigningKey) FromHexString(hexString string) (PublicSigningKey, e return *pk, nil } +// PrivateSigningKey is a private key over the secp256k1 curve type PrivateSigningKey ecdsa.PrivateKey +// ToScalars converts the private key to a slice of scalars func (pk *PrivateSigningKey) ToScalars() ([]Scalar, error) { limbs := bigintToScalarLimbs(*pk.D) return limbs, nil } +// FromScalars converts a slice of scalars to a private key func (pk *PrivateSigningKey) FromScalars(scalars *ScalarIterator) error { d, err := scalars.Next() if err != nil { @@ -175,6 +181,7 @@ func (pk *PrivateSigningKey) FromScalars(scalars *ScalarIterator) error { return nil } +// NumScalars returns the number of scalars in the private key func (pk *PrivateSigningKey) NumScalars() int { return 2 } @@ -244,9 +251,9 @@ func (pk *FeeEncryptionKey) FromBytes(bytes []byte) error { var yBytes [fr.Bytes]byte copy(xBytes[:], bytes[:fr.Bytes]) copy(yBytes[:], bytes[fr.Bytes:]) - //nolint:errcheck + //nolint:errcheck,gosec pk.X.FromLittleEndianBytes(xBytes) - //nolint:errcheck + //nolint:errcheck,gosec pk.Y.FromLittleEndianBytes(yBytes) return nil } diff --git a/wallet/keychain_derivation.go b/wallet/keychain_derivation.go index 1e4e4d8..a749656 100644 --- a/wallet/keychain_derivation.go +++ b/wallet/keychain_derivation.go @@ -34,16 +34,16 @@ const ( shareSeedMessage = "share seed" // walletIdMessage is the message used to derive the wallet ID - walletIdMessage = "wallet id" + walletIDMessage = "wallet id" // walletIdNumBytes is the number of bytes in the wallet ID - walletIdNumBytes = 16 + walletIDNumBytes = 16 ) // DeriveKeychain derives the keychain from the private key -func DeriveKeychain(pkey *ecdsa.PrivateKey, chainId uint64) (*Keychain, error) { +func DeriveKeychain(pkey *ecdsa.PrivateKey, chainID uint64) (*Keychain, error) { // Create the derivation key - derivationKey, err := createDerivationKey(pkey, chainId) + derivationKey, err := createDerivationKey(pkey, chainID) if err != nil { return nil, err } @@ -71,13 +71,13 @@ func DeriveKeychain(pkey *ecdsa.PrivateKey, chainId uint64) (*Keychain, error) { } // DeriveWalletSeeds derives the blinder and secret share seeds from the derivation key -func DeriveWalletSeeds(privateKey *ecdsa.PrivateKey, chainId uint64) ( +func DeriveWalletSeeds(privateKey *ecdsa.PrivateKey, chainID uint64) ( blinderSeed, shareSeed Scalar, err error, ) { // Create the derivation key - derivationKey, err := createDerivationKey(privateKey, chainId) + derivationKey, err := createDerivationKey(privateKey, chainID) if err != nil { return Scalar{}, Scalar{}, err } @@ -96,26 +96,26 @@ func DeriveWalletSeeds(privateKey *ecdsa.PrivateKey, chainId uint64) ( } // DeriveWalletID derives the wallet ID from the private key -func DeriveWalletID(privateKey *ecdsa.PrivateKey, chainId uint64) (uuid.UUID, error) { +func DeriveWalletID(privateKey *ecdsa.PrivateKey, chainID uint64) (uuid.UUID, error) { // Create the derivation key - derivationKey, err := createDerivationKey(privateKey, chainId) + derivationKey, err := createDerivationKey(privateKey, chainID) if err != nil { return uuid.Nil, err } // Derive the wallet ID - walletIdBytes, err := getExtendedSigBytes([]byte(walletIdMessage), derivationKey) + walletIDBytes, err := getExtendedSigBytes([]byte(walletIDMessage), derivationKey) if err != nil { return uuid.Nil, err } // Convert the bytes to a UUID - walletId, err := uuid.FromBytes(walletIdBytes[:walletIdNumBytes]) + walletID, err := uuid.FromBytes(walletIDBytes[:walletIDNumBytes]) if err != nil { return uuid.Nil, fmt.Errorf("failed to create UUID from bytes: %v", err) } - return walletId, nil + return walletID, nil } @@ -142,8 +142,8 @@ func createKeychain(skRoot *ecdsa.PrivateKey, skMatch Scalar, symmetricKey HmacK } // createDerivationKey creates a new private key from the signature -func createDerivationKey(pkey *ecdsa.PrivateKey, chainId uint64) (*ecdsa.PrivateKey, error) { - message := []byte(fmt.Sprintf("%s%d", derivationKeyMessage, chainId)) +func createDerivationKey(pkey *ecdsa.PrivateKey, chainID uint64) (*ecdsa.PrivateKey, error) { + message := []byte(fmt.Sprintf("%s%d", derivationKeyMessage, chainID)) keyBytes, err := getExtendedSigBytes(message, pkey) if err != nil { return nil, err diff --git a/wallet/keychain_test.go b/wallet/keychain_test.go index 6912f86..551a7c4 100644 --- a/wallet/keychain_test.go +++ b/wallet/keychain_test.go @@ -9,7 +9,7 @@ import ( func TestScalarLimbsToBigInt(t *testing.T) { // Sample a random big.Int limit := new(big.Int).Lsh(big.NewInt(1), 256) - r := rand.New(rand.NewSource(0)) + r := rand.New(rand.NewSource(0)) //nolint:gosec randomBigInt := new(big.Int).Rand(r, limit) // Convert to scalar limbs and back diff --git a/wallet/order.go b/wallet/order.go index 9d0a8f3..1659331 100644 --- a/wallet/order.go +++ b/wallet/order.go @@ -12,12 +12,19 @@ import ( type OrderSide int const ( + // Buy is the buy side of an order Buy OrderSide = iota + // Sell is the sell side of an order Sell ) -const OrderSide_BUY = 0 -const OrderSide_SELL = 1 +// OrderSide_BUY is a buy side order +const OrderSide_BUY = 0 //nolint:revive + +// OrderSide_SELL is a sell side order +const OrderSide_SELL = 1 //nolint:revive + +// FromScalars converts a slice of scalars to an OrderSide func (s *OrderSide) FromScalars(scalars *ScalarIterator) error { scalar, err := scalars.Next() if err != nil { @@ -29,15 +36,17 @@ func (s *OrderSide) FromScalars(scalars *ScalarIterator) error { return fmt.Errorf("invalid OrderSide value: %v", scalar) } - *s = OrderSide(elt.Uint64()) + *s = OrderSide(elt.Uint64()) //nolint:gosec return nil } +// ToScalars converts an OrderSide to a slice of scalars func (s *OrderSide) ToScalars() ([]Scalar, error) { - elt := fr.NewElement(uint64(*s)) + elt := fr.NewElement(uint64(*s)) //nolint:gosec return []Scalar{Scalar(elt)}, nil } +// NumScalars returns the number of scalars in the OrderSide func (s *OrderSide) NumScalars() int { return 1 } @@ -45,7 +54,7 @@ func (s *OrderSide) NumScalars() int { // Order is an order in the Renegade system type Order struct { // ID is the id of the order - Id uuid.UUID `scalar_serialize:"skip"` + Id uuid.UUID `scalar_serialize:"skip"` //nolint:revive // QuoteMint is the erc20 address of the quote asset QuoteMint Scalar // BaseMint is the erc20 address of the base asset @@ -70,7 +79,7 @@ func NewOrderBuilder() *OrderBuilder { } // WithId sets the Id -func (ob *OrderBuilder) WithId(id uuid.UUID) *OrderBuilder { +func (ob *OrderBuilder) WithId(id uuid.UUID) *OrderBuilder { //nolint:revive ob.order.Id = id return ob } @@ -137,7 +146,7 @@ func (ob *OrderBuilder) Build() Order { return ob.order } -// Update NewEmptyOrder to use the builder +// NewEmptyOrder creates a new empty order func NewEmptyOrder() Order { id := uuid.New() return Order{ @@ -150,7 +159,7 @@ func NewEmptyOrder() Order { } } -// Add a new function to create an order with some default values +// NewOrder creates a new order func NewOrder( quoteMint Scalar, baseMint Scalar, @@ -212,9 +221,9 @@ func (w *Wallet) findReplaceableOrder() int { } // CancelOrder cancels an order by ID -func (w *Wallet) CancelOrder(orderId uuid.UUID) error { +func (w *Wallet) CancelOrder(orderID uuid.UUID) error { // Find the order to cancel - idx := w.findOrder(orderId) + idx := w.findOrder(orderID) if idx == -1 { return fmt.Errorf("order not found") } @@ -225,9 +234,9 @@ func (w *Wallet) CancelOrder(orderId uuid.UUID) error { } // findOrder finds the index of an order with the given ID, or -1 if no order has the given ID -func (w *Wallet) findOrder(orderId uuid.UUID) int { +func (w *Wallet) findOrder(orderID uuid.UUID) int { for i, order := range w.Orders { - if order.Id == orderId { + if order.Id == orderID { return i } } diff --git a/wallet/scalar_serialization.go b/wallet/scalar_serialization.go index e31fbac..35da912 100644 --- a/wallet/scalar_serialization.go +++ b/wallet/scalar_serialization.go @@ -20,6 +20,7 @@ type ScalarSerialize interface { NumScalars() int } +// FromScalars converts a `ScalarIterator` to func (s *Scalar) FromScalars(scalars *ScalarIterator) error { scalar, err := scalars.Next() if err != nil { @@ -29,16 +30,20 @@ func (s *Scalar) FromScalars(scalars *ScalarIterator) error { return nil } +// ToScalars converts a `Scalar` to a slice fo `Scalar`s func (s *Scalar) ToScalars() ([]Scalar, error) { return []Scalar{*s}, nil } +// NumScalars returns the number of `Scalar`s in the `Scalar` func (s *Scalar) NumScalars() int { return 1 } +// Uint64 is a type that can be serialized to a slice of `Scalar`s type Uint64 uint64 +// FromScalars converts a `ScalarIterator` to a `Uint64` func (s *Uint64) FromScalars(scalars *ScalarIterator) error { scalar, err := scalars.Next() if err != nil { @@ -50,11 +55,13 @@ func (s *Uint64) FromScalars(scalars *ScalarIterator) error { return nil } +// ToScalars converts a `Uint64` to a slice of `Scalar`s func (s *Uint64) ToScalars() ([]Scalar, error) { elt := fr.NewElement(uint64(*s)) return []Scalar{Scalar(elt)}, nil } +// NumScalars returns the number of `Scalar`s in the `Uint64` func (s *Uint64) NumScalars() int { return 1 } @@ -152,12 +159,12 @@ func (s *ScalarIterator) Next() (Scalar, error) { return scalar, nil } -// Remaining returns the remaining scalars in the iterator +// NumRemaining returns the remaining scalars in the iterator func (s *ScalarIterator) NumRemaining() int { return len(s.scalars) - s.index } -// FromScalarsReflection is a helper function to deserialize a struct from a +// FromScalarsRecursive is a helper function to deserialize a struct from a // slice of scalars using reflection func FromScalarsRecursive(s interface{}, scalars *ScalarIterator) error { // If the type implements ScalarSerialize, use the specialized method diff --git a/wallet/scalar_serialization_test.go b/wallet/scalar_serialization_test.go index 778cd98..2496c86 100644 --- a/wallet/scalar_serialization_test.go +++ b/wallet/scalar_serialization_test.go @@ -22,7 +22,7 @@ type TestStruct struct { func randomScalar() Scalar { elt := fr.Element{} // nolint: errcheck - elt.SetRandom() + elt.SetRandom() //nolint:gosec return Scalar(elt) } diff --git a/wallet/wallet.go b/wallet/wallet.go index cc35390..dfe3668 100644 --- a/wallet/wallet.go +++ b/wallet/wallet.go @@ -16,9 +16,9 @@ import ( const ( // numScalarsWalletShare is the number of scalars in a wallet share numScalarsWalletShare = 70 - // maxBalances is the maximum number of balances in a wallet + // MaxBalances is the maximum number of balances in a wallet MaxBalances = 10 - // maxOrders is the maximum number of orders in a wallet + // MaxOrders is the maximum number of orders in a wallet MaxOrders = 4 ) @@ -123,7 +123,7 @@ func (s *Scalar) FromLittleEndianBytes(bytes [fr.Bytes]byte) (*Scalar, error) { return s, nil } -// HexString returns the hex string representation of the scalar +// ToHexString returns the hex string representation of the scalar func (s *Scalar) ToHexString() string { bytes := s.ToBigInt().Bytes() return hex.EncodeToString(bytes[:]) @@ -158,9 +158,9 @@ func (s *Scalar) FromBigInt(i *big.Int) Scalar { } // WalletSecrets contains the information about a wallet necessary to recover it -type WalletSecrets struct { +type WalletSecrets struct { //nolint:revive // Id is the UUID of the wallet - Id uuid.UUID + Id uuid.UUID //nolint:revive // Address is the Ethereum address of the wallet Address string // Keychain is the keychain used to manage the wallet @@ -172,10 +172,10 @@ type WalletSecrets struct { } // DeriveWalletSecrets derives the wallet secrets from the given Ethereum private key -func DeriveWalletSecrets(ethKey *ecdsa.PrivateKey, chainId uint64) (*WalletSecrets, error) { +func DeriveWalletSecrets(ethKey *ecdsa.PrivateKey, chainId uint64) (*WalletSecrets, error) { //nolint:revive address := crypto.PubkeyToAddress(ethKey.PublicKey).Hex() - walletId, err := DeriveWalletID(ethKey, chainId) + walletId, err := DeriveWalletID(ethKey, chainId) //nolint:revive if err != nil { return nil, err } @@ -201,7 +201,7 @@ func DeriveWalletSecrets(ethKey *ecdsa.PrivateKey, chainId uint64) (*WalletSecre // WalletShare represents a secret share of a wallet, containing only the // elements of a wallet that are stored on-chain -type WalletShare struct { +type WalletShare struct { //nolint:revive // Balances are the balances of the wallet Balances [MaxBalances]Balance // Orders are the orders of the wallet @@ -237,7 +237,7 @@ func EmptyWalletShare(publicKeys PublicKeychain) (WalletShare, error) { return share, nil } -// SplitIntoShares splits a wallet share into two shares using the given private +// SplitPublicPrivate splits a wallet share into two shares using the given private // shares and blinder func (ws *WalletShare) SplitPublicPrivate( privateShares []Scalar, @@ -314,7 +314,7 @@ func CombineShares( // Wallet is a wallet in the Renegade system type Wallet struct { - Id uuid.UUID + Id uuid.UUID //nolint:revive Orders []Order Balances []Balance Keychain *Keychain @@ -326,8 +326,8 @@ type Wallet struct { } // NewEmptyWallet creates a new empty wallet -func NewEmptyWallet(privateKey *ecdsa.PrivateKey, chainId uint64) (*Wallet, error) { - secrets, err := DeriveWalletSecrets(privateKey, chainId) +func NewEmptyWallet(privateKey *ecdsa.PrivateKey, chainID uint64) (*Wallet, error) { + secrets, err := DeriveWalletSecrets(privateKey, chainID) if err != nil { return nil, err } @@ -337,7 +337,7 @@ func NewEmptyWallet(privateKey *ecdsa.PrivateKey, chainId uint64) (*Wallet, erro // NewEmptyWalletFromSecrets creates a new wallet from the given wallet secrets func NewEmptyWalletFromSecrets(secrets *WalletSecrets) (*Wallet, error) { - walletId := secrets.Id + walletID := secrets.Id keychain := secrets.Keychain // Setup a wallet with empty shares @@ -359,7 +359,7 @@ func NewEmptyWalletFromSecrets(secrets *WalletSecrets) (*Wallet, error) { publicShare.Blinder = blinder.Sub(blinderPrivateShare) return &Wallet{ - Id: walletId, + Id: walletID, Orders: make([]Order, 0), Balances: make([]Balance, 0), Keychain: keychain, diff --git a/wallet/wallet_test.go b/wallet/wallet_test.go index 3613b3c..4924556 100644 --- a/wallet/wallet_test.go +++ b/wallet/wallet_test.go @@ -46,7 +46,7 @@ func TestScalarToFromLittleEndianBytes(t *testing.T) { // Convert to little-endian bytes and back littleEndianBytes := randomScalar.LittleEndianBytes() var newScalar Scalar - newScalar.FromLittleEndianBytes(littleEndianBytes) + newScalar.FromLittleEndianBytes(littleEndianBytes) //nolint:errcheck,gosec // Compare the original and new scalar assert.Equal(t, randomScalar, newScalar, "Scalar -> LittleEndianBytes -> Scalar conversion failed")