From 23f94127be8de9c74379147c4efa070cd651ddc3 Mon Sep 17 00:00:00 2001 From: Fornax <23104993+0xfornax@users.noreply.github.com> Date: Wed, 26 Aug 2026 18:30:53 -0300 Subject: [PATCH 1/2] Add callAPI generic call --- rocketpool/api/service/gas.go | 5 +- shared/services/rocketpool/api.go | 38 +- shared/services/rocketpool/auction.go | 140 +-- shared/services/rocketpool/client.go | 14 +- shared/services/rocketpool/gas.go | 17 +- shared/services/rocketpool/megapool.go | 475 +---------- shared/services/rocketpool/minipool.go | 311 +------ shared/services/rocketpool/network.go | 117 +-- shared/services/rocketpool/node.go | 1089 +++--------------------- shared/services/rocketpool/odao.go | 662 ++------------ shared/services/rocketpool/pdao.go | 669 ++------------- shared/services/rocketpool/queue.go | 78 +- shared/services/rocketpool/security.go | 242 +----- shared/services/rocketpool/service.go | 43 +- shared/services/rocketpool/upgrades.go | 42 +- shared/services/rocketpool/wallet.go | 191 +---- shared/types/api/api.go | 5 + shared/types/api/auction.go | 32 +- shared/types/api/debug.go | 3 +- shared/types/api/megapool.go | 50 +- shared/types/api/minipool.go | 136 +-- shared/types/api/network.go | 27 +- shared/types/api/node.go | 319 +++---- shared/types/api/odao.go | 135 +-- shared/types/api/pdao.go | 158 ++-- shared/types/api/queue.go | 18 +- shared/types/api/security.go | 78 +- shared/types/api/service.go | 17 +- shared/types/api/upgrades.go | 12 +- shared/types/api/wallet.go | 43 +- 30 files changed, 773 insertions(+), 4393 deletions(-) diff --git a/rocketpool/api/service/gas.go b/rocketpool/api/service/gas.go index 8d3328c1e..af3c0201f 100644 --- a/rocketpool/api/service/gas.go +++ b/rocketpool/api/service/gas.go @@ -26,9 +26,8 @@ func getGasPriceFromLatestBlock(c *cli.Command) (*api.GasPriceFromLatestBlockRes } return &api.GasPriceFromLatestBlockResponse{ - Status: "success", - GasPrice: gasPrice.BaseFee, - Error: "", + APIResponse: api.APIResponse{Status: "success"}, + GasPrice: gasPrice.BaseFee, }, nil } diff --git a/shared/services/rocketpool/api.go b/shared/services/rocketpool/api.go index 5eddcf8a5..9520afa75 100644 --- a/shared/services/rocketpool/api.go +++ b/shared/services/rocketpool/api.go @@ -11,18 +11,38 @@ import ( "github.com/rocket-pool/smartnode/shared/types/api" ) -// Wait for a transaction — no timeout; blocks until the tx is included or the caller cancels. -func (c *Client) WaitForTransaction(txHash common.Hash) (api.APIResponse, error) { - responseBytes, err := c.callHTTPAPICtx(context.Background(), "GET", "/api/wait", url.Values{"txHash": {txHash.Hex()}}) +type apiResult interface { + APIError() string +} + +// callAPI unmarshals a JSON API reply into T and turns a non-empty Error field into a Go error +func (c *Client) callAPI[T apiResult](method, path string, params url.Values, errPrefix string) (T, error) { + body, err := c.callHTTPAPI(method, path, params) + return decodeAPI[T](body, err, errPrefix) +} + +// callAPICtx is callAPI with an explicit context (custom timeouts, or none). +func (c *Client) callAPICtx[T apiResult](ctx context.Context, method, path string, params url.Values, errPrefix string) (T, error) { + body, err := c.callHTTPAPICtx(ctx, method, path, params) + return decodeAPI[T](body, err, errPrefix) +} + +func decodeAPI[T apiResult](body []byte, err error, errPrefix string) (T, error) { + var zero T if err != nil { - return api.APIResponse{}, fmt.Errorf("Error waiting for tx: %w", err) + return zero, fmt.Errorf("%s: %w", errPrefix, err) } - var response api.APIResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.APIResponse{}, fmt.Errorf("Error decoding wait response: %w", err) + var response T + if err := json.Unmarshal(body, &response); err != nil { + return zero, fmt.Errorf("%s: could not decode response: %w", errPrefix, err) } - if response.Error != "" { - return api.APIResponse{}, fmt.Errorf("Error waiting for tx: %s", response.Error) + if apiErr := response.APIError(); apiErr != "" { + return response, fmt.Errorf("%s: %s", errPrefix, apiErr) } return response, nil } + +// Wait for a transaction — no timeout; blocks until the tx is included or the caller cancels. +func (c *Client) WaitForTransaction(txHash common.Hash) (api.APIResponse, error) { + return c.callAPICtx[api.APIResponse](context.Background(), "GET", "/api/wait", url.Values{"txHash": {txHash.Hex()}}, "Error waiting for tx") +} diff --git a/shared/services/rocketpool/auction.go b/shared/services/rocketpool/auction.go index 23547252f..8884d4ade 100644 --- a/shared/services/rocketpool/auction.go +++ b/shared/services/rocketpool/auction.go @@ -5,23 +5,14 @@ import ( "math/big" "net/url" - "github.com/goccy/go-json" - "github.com/rocket-pool/smartnode/shared/types/api" ) // Get RPL auction status func (c *Client) AuctionStatus() (api.AuctionStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/auction/status", nil) + response, err := c.callAPI[api.AuctionStatusResponse]("GET", "/api/auction/status", nil, "Could not get auction status") if err != nil { - return api.AuctionStatusResponse{}, fmt.Errorf("Could not get auction status: %w", err) - } - var response api.AuctionStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.AuctionStatusResponse{}, fmt.Errorf("Could not decode auction stats response: %w", err) - } - if response.Error != "" { - return api.AuctionStatusResponse{}, fmt.Errorf("Could not get auction status: %s", response.Error) + return response, err } if response.TotalRPLBalance == nil { response.TotalRPLBalance = big.NewInt(0) @@ -37,16 +28,9 @@ func (c *Client) AuctionStatus() (api.AuctionStatusResponse, error) { // Get RPL lots for auction func (c *Client) AuctionLots() (api.AuctionLotsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/auction/lots", nil) + response, err := c.callAPI[api.AuctionLotsResponse]("GET", "/api/auction/lots", nil, "Could not get auction lots") if err != nil { - return api.AuctionLotsResponse{}, fmt.Errorf("Could not get auction lots: %w", err) - } - var response api.AuctionLotsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.AuctionLotsResponse{}, fmt.Errorf("Could not decode auction lots response: %w", err) - } - if response.Error != "" { - return api.AuctionLotsResponse{}, fmt.Errorf("Could not get auction lots: %s", response.Error) + return response, err } for i := 0; i < len(response.Lots); i++ { details := &response.Lots[i].Details @@ -86,142 +70,54 @@ func (c *Client) AuctionLots() (api.AuctionLotsResponse, error) { // Check whether the node can create a new lot func (c *Client) CanCreateLot() (api.CanCreateLotResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/auction/can-create-lot", nil) - if err != nil { - return api.CanCreateLotResponse{}, fmt.Errorf("Could not get can create lot status: %w", err) - } - var response api.CanCreateLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanCreateLotResponse{}, fmt.Errorf("Could not decode can create lot response: %w", err) - } - if response.Error != "" { - return api.CanCreateLotResponse{}, fmt.Errorf("Could not get can create lot status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanCreateLotResponse]("GET", "/api/auction/can-create-lot", nil, "Could not get can create lot status") } // Create a new lot func (c *Client) CreateLot() (api.CreateLotResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/auction/create-lot", nil) - if err != nil { - return api.CreateLotResponse{}, fmt.Errorf("Could not create lot: %w", err) - } - var response api.CreateLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CreateLotResponse{}, fmt.Errorf("Could not decode create lot response: %w", err) - } - if response.Error != "" { - return api.CreateLotResponse{}, fmt.Errorf("Could not create lot: %s", response.Error) - } - return response, nil + return c.callAPI[api.CreateLotResponse]("POST", "/api/auction/create-lot", nil, "Could not create lot") } // Check whether the node can bid on a lot func (c *Client) CanBidOnLot(lotIndex uint64, amountWei *big.Int) (api.CanBidOnLotResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/auction/can-bid-lot", url.Values{ + return c.callAPI[api.CanBidOnLotResponse]("GET", "/api/auction/can-bid-lot", url.Values{ "lotIndex": {fmt.Sprintf("%d", lotIndex)}, "amountWei": {amountWei.String()}, - }) - if err != nil { - return api.CanBidOnLotResponse{}, fmt.Errorf("Could not get can bid on lot status: %w", err) - } - var response api.CanBidOnLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanBidOnLotResponse{}, fmt.Errorf("Could not decode can bid on lot response: %w", err) - } - if response.Error != "" { - return api.CanBidOnLotResponse{}, fmt.Errorf("Could not get can bid on lot status: %s", response.Error) - } - return response, nil + }, "Could not get can bid on lot status") } // Bid on a lot func (c *Client) BidOnLot(lotIndex uint64, amountWei *big.Int) (api.BidOnLotResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/auction/bid-lot", url.Values{ + return c.callAPI[api.BidOnLotResponse]("POST", "/api/auction/bid-lot", url.Values{ "lotIndex": {fmt.Sprintf("%d", lotIndex)}, "amountWei": {amountWei.String()}, - }) - if err != nil { - return api.BidOnLotResponse{}, fmt.Errorf("Could not bid on lot: %w", err) - } - var response api.BidOnLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.BidOnLotResponse{}, fmt.Errorf("Could not decode bid on lot response: %w", err) - } - if response.Error != "" { - return api.BidOnLotResponse{}, fmt.Errorf("Could not bid on lot: %s", response.Error) - } - return response, nil + }, "Could not bid on lot") } // Check whether the node can claim RPL from a lot func (c *Client) CanClaimFromLot(lotIndex uint64) (api.CanClaimFromLotResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/auction/can-claim-lot", url.Values{ + return c.callAPI[api.CanClaimFromLotResponse]("GET", "/api/auction/can-claim-lot", url.Values{ "lotIndex": {fmt.Sprintf("%d", lotIndex)}, - }) - if err != nil { - return api.CanClaimFromLotResponse{}, fmt.Errorf("Could not get can claim RPL from lot status: %w", err) - } - var response api.CanClaimFromLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanClaimFromLotResponse{}, fmt.Errorf("Could not decode can claim RPL from lot response: %w", err) - } - if response.Error != "" { - return api.CanClaimFromLotResponse{}, fmt.Errorf("Could not get can claim RPL from lot status: %s", response.Error) - } - return response, nil + }, "Could not get can claim RPL from lot status") } // Claim RPL from a lot func (c *Client) ClaimFromLot(lotIndex uint64) (api.ClaimFromLotResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/auction/claim-lot", url.Values{ + return c.callAPI[api.ClaimFromLotResponse]("POST", "/api/auction/claim-lot", url.Values{ "lotIndex": {fmt.Sprintf("%d", lotIndex)}, - }) - if err != nil { - return api.ClaimFromLotResponse{}, fmt.Errorf("Could not claim RPL from lot: %w", err) - } - var response api.ClaimFromLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ClaimFromLotResponse{}, fmt.Errorf("Could not decode claim RPL from lot response: %w", err) - } - if response.Error != "" { - return api.ClaimFromLotResponse{}, fmt.Errorf("Could not claim RPL from lot: %s", response.Error) - } - return response, nil + }, "Could not claim RPL from lot") } // Check whether the node can recover unclaimed RPL from a lot func (c *Client) CanRecoverUnclaimedRPLFromLot(lotIndex uint64) (api.CanRecoverRPLFromLotResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/auction/can-recover-lot", url.Values{ + return c.callAPI[api.CanRecoverRPLFromLotResponse]("GET", "/api/auction/can-recover-lot", url.Values{ "lotIndex": {fmt.Sprintf("%d", lotIndex)}, - }) - if err != nil { - return api.CanRecoverRPLFromLotResponse{}, fmt.Errorf("Could not get can recover unclaimed RPL from lot status: %w", err) - } - var response api.CanRecoverRPLFromLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanRecoverRPLFromLotResponse{}, fmt.Errorf("Could not decode can recover unclaimed RPL from lot response: %w", err) - } - if response.Error != "" { - return api.CanRecoverRPLFromLotResponse{}, fmt.Errorf("Could not get can recover unclaimed RPL from lot status: %s", response.Error) - } - return response, nil + }, "Could not get can recover unclaimed RPL from lot status") } // Recover unclaimed RPL from a lot (returning it to the auction contract) func (c *Client) RecoverUnclaimedRPLFromLot(lotIndex uint64) (api.RecoverRPLFromLotResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/auction/recover-lot", url.Values{ + return c.callAPI[api.RecoverRPLFromLotResponse]("POST", "/api/auction/recover-lot", url.Values{ "lotIndex": {fmt.Sprintf("%d", lotIndex)}, - }) - if err != nil { - return api.RecoverRPLFromLotResponse{}, fmt.Errorf("Could not recover unclaimed RPL from lot: %w", err) - } - var response api.RecoverRPLFromLotResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RecoverRPLFromLotResponse{}, fmt.Errorf("Could not decode recover unclaimed RPL from lot response: %w", err) - } - if response.Error != "" { - return api.RecoverRPLFromLotResponse{}, fmt.Errorf("Could not recover unclaimed RPL from lot: %s", response.Error) - } - return response, nil + }, "Could not recover unclaimed RPL from lot") } diff --git a/shared/services/rocketpool/client.go b/shared/services/rocketpool/client.go index 1afcdedf2..6a13a06fc 100644 --- a/shared/services/rocketpool/client.go +++ b/shared/services/rocketpool/client.go @@ -559,21 +559,13 @@ func (c *Client) PrintServiceCompose(composeFiles []string) error { // Get the Rocket Pool service version func (c *Client) GetServiceVersion() (string, error) { type versionResponse struct { - Status string `json:"status"` - Error string `json:"error"` + api.APIResponse Version string `json:"version"` } - responseBytes, err := c.callHTTPAPI("GET", "/api/version", nil) + response, err := c.callAPI[versionResponse]("GET", "/api/version", nil, "Could not get Rocket Pool service version") if err != nil { - return "", fmt.Errorf("Could not get Rocket Pool service version: %w", err) - } - var response versionResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return "", fmt.Errorf("Could not decode Rocket Pool service version response: %w", err) - } - if response.Error != "" { - return "", fmt.Errorf("Could not get Rocket Pool service version: %s", response.Error) + return "", err } version, err := semver.Make(response.Version) diff --git a/shared/services/rocketpool/gas.go b/shared/services/rocketpool/gas.go index 1d1855153..aa3b5a86d 100644 --- a/shared/services/rocketpool/gas.go +++ b/shared/services/rocketpool/gas.go @@ -1,10 +1,6 @@ package rocketpool import ( - "fmt" - - "github.com/goccy/go-json" - "github.com/rocket-pool/smartnode/rocketpool-cli/cli/color" "github.com/rocket-pool/smartnode/shared/types/api" ) @@ -18,16 +14,5 @@ func (c *Client) PrintMultiTxWarning() { // Get the gas price from the latest block func (c *Client) GetGasPriceFromLatestBlock() (api.GasPriceFromLatestBlockResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/service/get-gas-price-from-latest-block", nil) - if err != nil { - return api.GasPriceFromLatestBlockResponse{}, fmt.Errorf("Could not get gas price from latest block: %w", err) - } - var response api.GasPriceFromLatestBlockResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GasPriceFromLatestBlockResponse{}, fmt.Errorf("Could not decode gas price from latest block response: %w", err) - } - if response.Error != "" { - return api.GasPriceFromLatestBlockResponse{}, fmt.Errorf("Could not get gas price from latest block: %s", response.Error) - } - return response, nil + return c.callAPI[api.GasPriceFromLatestBlockResponse]("GET", "/api/service/get-gas-price-from-latest-block", nil, "Could not get gas price from latest block") } diff --git a/shared/services/rocketpool/megapool.go b/shared/services/rocketpool/megapool.go index fb4745ae5..98af2bd41 100644 --- a/shared/services/rocketpool/megapool.go +++ b/shared/services/rocketpool/megapool.go @@ -7,7 +7,6 @@ import ( "strconv" "github.com/ethereum/go-ethereum/common" - "github.com/goccy/go-json" "github.com/rocket-pool/smartnode/shared/types/api" ) @@ -18,424 +17,138 @@ func (c *Client) MegapoolStatus(finalizedState bool) (api.MegapoolStatusResponse if finalizedState { finalizedStr = "true" } - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/status", url.Values{"finalizedState": {finalizedStr}}) - if err != nil { - return api.MegapoolStatusResponse{}, fmt.Errorf("Could not get megapool status: %w", err) - } - var response api.MegapoolStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolStatusResponse{}, fmt.Errorf("Could not decode megapool status response: %w", err) - } - if response.Error != "" { - return api.MegapoolStatusResponse{}, fmt.Errorf("Could not get megapool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolStatusResponse]("GET", "/api/megapool/status", url.Values{"finalizedState": {finalizedStr}}, "Could not get megapool status") } // Get a map of the node's validators and beacon balances func (c *Client) GetValidatorMapAndBalances() (api.MegapoolValidatorMapAndRewardsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/validator-map-and-balances", nil) - if err != nil { - return api.MegapoolValidatorMapAndRewardsResponse{}, fmt.Errorf("Could not get megapool validator-map-and-balances: %w", err) - } - var response api.MegapoolValidatorMapAndRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolValidatorMapAndRewardsResponse{}, fmt.Errorf("Could not decode megapool validator-map-and-balances response: %w", err) - } - if response.Error != "" { - return api.MegapoolValidatorMapAndRewardsResponse{}, fmt.Errorf("Could not get megapool validator-map-and-balances: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolValidatorMapAndRewardsResponse]("GET", "/api/megapool/validator-map-and-balances", nil, "Could not get megapool validator-map-and-balances") } // Check whether the node can claim a megapool refund func (c *Client) CanClaimMegapoolRefund() (api.CanClaimRefundResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-claim-refund", nil) - if err != nil { - return api.CanClaimRefundResponse{}, fmt.Errorf("Could not get can claim refund status: %w", err) - } - var response api.CanClaimRefundResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanClaimRefundResponse{}, fmt.Errorf("Could not decode can claim refund response: %w", err) - } - if response.Error != "" { - return api.CanClaimRefundResponse{}, fmt.Errorf("Could not get can claim refund status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanClaimRefundResponse]("GET", "/api/megapool/can-claim-refund", nil, "Could not get can claim refund status") } // Claim megapool refund func (c *Client) ClaimMegapoolRefund() (api.ClaimRefundResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/claim-refund", nil) - if err != nil { - return api.ClaimRefundResponse{}, fmt.Errorf("Could not claim refund: %w", err) - } - var response api.ClaimRefundResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ClaimRefundResponse{}, fmt.Errorf("Could not decode claim refund response: %w", err) - } - if response.Error != "" { - return api.ClaimRefundResponse{}, fmt.Errorf("Could not get claim refund status: %s", response.Error) - } - return response, nil + return c.callAPI[api.ClaimRefundResponse]("POST", "/api/megapool/claim-refund", nil, "Could not claim refund") } // Check whether the node can repay megapool debt func (c *Client) CanRepayDebt(amountWei *big.Int) (api.CanRepayDebtResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-repay-debt", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanRepayDebtResponse{}, fmt.Errorf("Could not get can repay debt status: %w", err) - } - var response api.CanRepayDebtResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanRepayDebtResponse{}, fmt.Errorf("Could not decode can repay debt response: %w", err) - } - if response.Error != "" { - return api.CanRepayDebtResponse{}, fmt.Errorf("Could not get can repay debt status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanRepayDebtResponse]("GET", "/api/megapool/can-repay-debt", url.Values{"amountWei": {amountWei.String()}}, "Could not get can repay debt status") } // Repay megapool debt func (c *Client) RepayDebt(amountWei *big.Int) (api.RepayDebtResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/repay-debt", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.RepayDebtResponse{}, fmt.Errorf("Could not repay megapool debt: %w", err) - } - var response api.RepayDebtResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RepayDebtResponse{}, fmt.Errorf("Could not decode repay debt response: %w", err) - } - if response.Error != "" { - return api.RepayDebtResponse{}, fmt.Errorf("Could not repay megapool debt: %s", response.Error) - } - return response, nil + return c.callAPI[api.RepayDebtResponse]("POST", "/api/megapool/repay-debt", url.Values{"amountWei": {amountWei.String()}}, "Could not repay megapool debt") } // Check whether the node can reduce the megapool bond func (c *Client) CanReduceBond(amountWei *big.Int) (api.CanReduceBondResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-reduce-bond", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanReduceBondResponse{}, fmt.Errorf("Could not get can reduce bond status: %w", err) - } - var response api.CanReduceBondResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanReduceBondResponse{}, fmt.Errorf("Could not decode can reduce bond response: %w", err) - } - if response.Error != "" { - return api.CanReduceBondResponse{}, fmt.Errorf("Could not get can reduce bond status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanReduceBondResponse]("GET", "/api/megapool/can-reduce-bond", url.Values{"amountWei": {amountWei.String()}}, "Could not get can reduce bond status") } // Reduce megapool bond func (c *Client) ReduceBond(amountWei *big.Int) (api.ReduceBondResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/reduce-bond", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.ReduceBondResponse{}, fmt.Errorf("Could not reduce bond: %w", err) - } - var response api.ReduceBondResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ReduceBondResponse{}, fmt.Errorf("Could not decode reduce bond response: %w", err) - } - if response.Error != "" { - return api.ReduceBondResponse{}, fmt.Errorf("Could not reduce bond: %s", response.Error) - } - return response, nil + return c.callAPI[api.ReduceBondResponse]("POST", "/api/megapool/reduce-bond", url.Values{"amountWei": {amountWei.String()}}, "Could not reduce bond") } // Check whether the node can stake a megapool validator func (c *Client) CanStake(validatorId uint64) (api.CanStakeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-stake", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.CanStakeResponse{}, fmt.Errorf("Could not get can stake status: %w", err) - } - var response api.CanStakeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanStakeResponse{}, fmt.Errorf("Could not decode can stake response: %w", err) - } - if response.Error != "" { - return api.CanStakeResponse{}, fmt.Errorf("Could not get can stake status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanStakeResponse]("GET", "/api/megapool/can-stake", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not get can stake status") } // Stake a megapool validator func (c *Client) Stake(validatorId uint64) (api.StakeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/stake", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.StakeResponse{}, fmt.Errorf("Could not stake megapool validator: %w", err) - } - var response api.StakeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.StakeResponse{}, fmt.Errorf("Could not decode stake response: %w", err) - } - if response.Error != "" { - return api.StakeResponse{}, fmt.Errorf("Could not stake megapool validator: %s", response.Error) - } - return response, nil + return c.callAPI[api.StakeResponse]("POST", "/api/megapool/stake", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not stake megapool validator") } // Check whether a megapool validator can be dissolved func (c *Client) CanDissolveValidator(validatorId uint64) (api.CanDissolveValidatorResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-dissolve-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.CanDissolveValidatorResponse{}, fmt.Errorf("Could not get can dissolve validator status: %w", err) - } - var response api.CanDissolveValidatorResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanDissolveValidatorResponse{}, fmt.Errorf("Could not decode can dissolve-validator response: %w", err) - } - if response.Error != "" { - return api.CanDissolveValidatorResponse{}, fmt.Errorf("Could not get can dissolve status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanDissolveValidatorResponse]("GET", "/api/megapool/can-dissolve-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not get can dissolve validator status") } // Dissolve a megapool validator func (c *Client) DissolveValidator(validatorId uint64) (api.DissolveValidatorResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/dissolve-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.DissolveValidatorResponse{}, fmt.Errorf("Could not dissolve megapool validator: %w", err) - } - var response api.DissolveValidatorResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DissolveValidatorResponse{}, fmt.Errorf("Could not decode dissolve response: %w", err) - } - if response.Error != "" { - return api.DissolveValidatorResponse{}, fmt.Errorf("Could not dissolve megapool validator: %s", response.Error) - } - return response, nil + return c.callAPI[api.DissolveValidatorResponse]("POST", "/api/megapool/dissolve-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not dissolve megapool validator") } // Check whether a megapool validator can be dissolved with proof func (c *Client) CanDissolveWithProof(validatorId uint64) (api.CanDissolveWithProofResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-dissolve-with-proof", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.CanDissolveWithProofResponse{}, fmt.Errorf("Could not get can dissolve-with-proof status: %w", err) - } - var response api.CanDissolveWithProofResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanDissolveWithProofResponse{}, fmt.Errorf("Could not decode can dissolve-with-proof response: %w", err) - } - if response.Error != "" { - return api.CanDissolveWithProofResponse{}, fmt.Errorf("Could not get can dissolve-with-proof status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanDissolveWithProofResponse]("GET", "/api/megapool/can-dissolve-with-proof", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not get can dissolve-with-proof status") } // Dissolve a megapool validator with proof func (c *Client) DissolveWithProof(validatorId uint64) (api.DissolveWithProofResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/dissolve-with-proof", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.DissolveWithProofResponse{}, fmt.Errorf("Could not dissolve megapool validator with proof: %w", err) - } - var response api.DissolveWithProofResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DissolveWithProofResponse{}, fmt.Errorf("Could not decode dissolve-with-proof response: %w", err) - } - if response.Error != "" { - return api.DissolveWithProofResponse{}, fmt.Errorf("Could not dissolve megapool validator with proof: %s", response.Error) - } - return response, nil + return c.callAPI[api.DissolveWithProofResponse]("POST", "/api/megapool/dissolve-with-proof", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not dissolve megapool validator with proof") } // Check whether a megapool validator can be exited func (c *Client) CanExitValidator(validatorId uint64) (api.CanExitValidatorResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-exit-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.CanExitValidatorResponse{}, fmt.Errorf("Could not get can exit validator status: %w", err) - } - var response api.CanExitValidatorResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanExitValidatorResponse{}, fmt.Errorf("Could not decode can exit-validator response: %w", err) - } - if response.Error != "" { - return api.CanExitValidatorResponse{}, fmt.Errorf("Could not get can exit status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanExitValidatorResponse]("GET", "/api/megapool/can-exit-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not get can exit validator status") } // Exit a megapool validator func (c *Client) ExitValidator(validatorId uint64) (api.ExitValidatorResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/exit-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.ExitValidatorResponse{}, fmt.Errorf("Could not exit megapool validator: %w", err) - } - var response api.ExitValidatorResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ExitValidatorResponse{}, fmt.Errorf("Could not decode exit response: %w", err) - } - if response.Error != "" { - return api.ExitValidatorResponse{}, fmt.Errorf("Could not exit megapool validator: %s", response.Error) - } - return response, nil + return c.callAPI[api.ExitValidatorResponse]("POST", "/api/megapool/exit-validator", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not exit megapool validator") } // Check whether the node can notify validator exit func (c *Client) CanNotifyValidatorExit(validatorId uint64) (api.CanNotifyValidatorExitResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-notify-validator-exit", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.CanNotifyValidatorExitResponse{}, fmt.Errorf("Could not get can notify validator exit status: %w", err) - } - var response api.CanNotifyValidatorExitResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNotifyValidatorExitResponse{}, fmt.Errorf("Could not decode can notify validator exit response: %w", err) - } - if response.Error != "" { - return api.CanNotifyValidatorExitResponse{}, fmt.Errorf("Could not get can notify validator exit status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNotifyValidatorExitResponse]("GET", "/api/megapool/can-notify-validator-exit", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not get can notify validator exit status") } // Notify the megapool that a validator has exited func (c *Client) NotifyValidatorExit(validatorId uint64) (api.NotifyValidatorExitResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/notify-validator-exit", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}) - if err != nil { - return api.NotifyValidatorExitResponse{}, fmt.Errorf("Could not notify validator exit: %w", err) - } - var response api.NotifyValidatorExitResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NotifyValidatorExitResponse{}, fmt.Errorf("Could not decode notify validator exit response: %w", err) - } - if response.Error != "" { - return api.NotifyValidatorExitResponse{}, fmt.Errorf("Could not notify validator exit: %s", response.Error) - } - return response, nil + return c.callAPI[api.NotifyValidatorExitResponse]("POST", "/api/megapool/notify-validator-exit", url.Values{"validatorId": {fmt.Sprintf("%d", validatorId)}}, "Could not notify validator exit") } // Check whether the node can notify final balance func (c *Client) CanNotifyFinalBalance(validatorId uint64, slot uint64) (api.CanNotifyFinalBalanceResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-notify-final-balance", url.Values{ + return c.callAPI[api.CanNotifyFinalBalanceResponse]("GET", "/api/megapool/can-notify-final-balance", url.Values{ "validatorId": {fmt.Sprintf("%d", validatorId)}, "slot": {fmt.Sprintf("%d", slot)}, - }) - if err != nil { - return api.CanNotifyFinalBalanceResponse{}, fmt.Errorf("Could not get can notify final balance status: %w", err) - } - var response api.CanNotifyFinalBalanceResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNotifyFinalBalanceResponse{}, fmt.Errorf("Could not decode can notify final balance response: %w", err) - } - if response.Error != "" { - return api.CanNotifyFinalBalanceResponse{}, fmt.Errorf("Could not get can notify final balance status: %s", response.Error) - } - return response, nil + }, "Could not get can notify final balance status") } // Notify the megapool of a validator's final balance func (c *Client) NotifyFinalBalance(validatorId uint64, slot uint64) (api.NotifyFinalBalanceResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/notify-final-balance", url.Values{ + return c.callAPI[api.NotifyFinalBalanceResponse]("POST", "/api/megapool/notify-final-balance", url.Values{ "validatorId": {fmt.Sprintf("%d", validatorId)}, "slot": {fmt.Sprintf("%d", slot)}, - }) - if err != nil { - return api.NotifyFinalBalanceResponse{}, fmt.Errorf("Could not notify final balance: %w", err) - } - var response api.NotifyFinalBalanceResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NotifyFinalBalanceResponse{}, fmt.Errorf("Could not decode notify final balance response: %w", err) - } - if response.Error != "" { - return api.NotifyFinalBalanceResponse{}, fmt.Errorf("Could not notify final balance: %s", response.Error) - } - return response, nil + }, "Could not notify final balance") } // Check whether the node can exit the validator queue func (c *Client) CanExitQueue(validatorIndex uint32) (api.CanExitQueueResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-exit-queue", url.Values{"validatorIndex": {fmt.Sprintf("%d", validatorIndex)}}) - if err != nil { - return api.CanExitQueueResponse{}, fmt.Errorf("Could not get can exit queue status: %w", err) - } - var response api.CanExitQueueResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanExitQueueResponse{}, fmt.Errorf("Could not decode can exit queue response: %w", err) - } - if response.Error != "" { - return api.CanExitQueueResponse{}, fmt.Errorf("Could not get can exit queue status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanExitQueueResponse]("GET", "/api/megapool/can-exit-queue", url.Values{"validatorIndex": {fmt.Sprintf("%d", validatorIndex)}}, "Could not get can exit queue status") } // Exit the validator queue func (c *Client) ExitQueue(validatorIndex uint32) (api.ExitQueueResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/exit-queue", url.Values{"validatorIndex": {fmt.Sprintf("%d", validatorIndex)}}) - if err != nil { - return api.ExitQueueResponse{}, fmt.Errorf("Could not exit queue: %w", err) - } - var response api.ExitQueueResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ExitQueueResponse{}, fmt.Errorf("Could not decode exit queue response: %w", err) - } - if response.Error != "" { - return api.ExitQueueResponse{}, fmt.Errorf("Could not exit queue: %s", response.Error) - } - return response, nil + return c.callAPI[api.ExitQueueResponse]("POST", "/api/megapool/exit-queue", url.Values{"validatorIndex": {fmt.Sprintf("%d", validatorIndex)}}, "Could not exit queue") } // Get the gas info for a megapool delegate upgrade func (c *Client) CanDelegateUpgradeMegapool(address common.Address) (api.MegapoolCanDelegateUpgradeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-delegate-upgrade", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.MegapoolCanDelegateUpgradeResponse{}, fmt.Errorf("Could not get can delegate upgrade megapool status: %w", err) - } - var response api.MegapoolCanDelegateUpgradeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolCanDelegateUpgradeResponse{}, fmt.Errorf("Could not decode can delegate upgrade megapool response: %w", err) - } - if response.Error != "" { - return api.MegapoolCanDelegateUpgradeResponse{}, fmt.Errorf("Could not get can delegate upgrade megapool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolCanDelegateUpgradeResponse]("GET", "/api/megapool/can-delegate-upgrade", url.Values{"address": {address.Hex()}}, "Could not get can delegate upgrade megapool status") } // Upgrade the megapool delegate func (c *Client) DelegateUpgradeMegapool(address common.Address) (api.MegapoolDelegateUpgradeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/delegate-upgrade", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.MegapoolDelegateUpgradeResponse{}, fmt.Errorf("Could not upgrade megapool delegate: %w", err) - } - var response api.MegapoolDelegateUpgradeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolDelegateUpgradeResponse{}, fmt.Errorf("Could not decode megapool delegate upgrade response: %w", err) - } - if response.Error != "" { - return api.MegapoolDelegateUpgradeResponse{}, fmt.Errorf("Could not upgrade megapool delegate: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolDelegateUpgradeResponse]("POST", "/api/megapool/delegate-upgrade", url.Values{"address": {address.Hex()}}, "Could not upgrade megapool delegate") } // Get the megapool's use-latest-delegate setting func (c *Client) GetUseLatestDelegate(address common.Address) (api.MegapoolGetUseLatestDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/get-use-latest-delegate", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.MegapoolGetUseLatestDelegateResponse{}, fmt.Errorf("Could not get use latest delegate for megapool: %w", err) - } - var response api.MegapoolGetUseLatestDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolGetUseLatestDelegateResponse{}, fmt.Errorf("Could not decode get use latest delegate for megapool response: %w", err) - } - if response.Error != "" { - return api.MegapoolGetUseLatestDelegateResponse{}, fmt.Errorf("Could not get use latest delegate for megapool: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolGetUseLatestDelegateResponse]("GET", "/api/megapool/get-use-latest-delegate", url.Values{"address": {address.Hex()}}, "Could not get use latest delegate for megapool") } // Check whether a megapool can have its use-latest-delegate setting changed func (c *Client) CanSetUseLatestDelegateMegapool(address common.Address, useLatest bool) (api.MegapoolCanSetUseLatestDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-set-use-latest-delegate", url.Values{"address": {address.Hex()}, "setLatest": {strconv.FormatBool(useLatest)}}) - if err != nil { - return api.MegapoolCanSetUseLatestDelegateResponse{}, fmt.Errorf("Could not get can set use latest delegate for megapool status: %w", err) - } - var response api.MegapoolCanSetUseLatestDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolCanSetUseLatestDelegateResponse{}, fmt.Errorf("Could not decode can set use latest delegate for megapool response: %w", err) - } - if response.Error != "" { - return api.MegapoolCanSetUseLatestDelegateResponse{}, fmt.Errorf("Could not get can set use latest delegate for megapool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolCanSetUseLatestDelegateResponse]("GET", "/api/megapool/can-set-use-latest-delegate", url.Values{"address": {address.Hex()}, "setLatest": {strconv.FormatBool(useLatest)}}, "Could not get can set use latest delegate for megapool status") } // Change a megapool's use-latest-delegate setting @@ -444,165 +157,55 @@ func (c *Client) SetUseLatestDelegateMegapool(address common.Address, setting bo if setting { settingStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/set-use-latest-delegate", url.Values{ + return c.callAPI[api.MegapoolSetUseLatestDelegateResponse]("POST", "/api/megapool/set-use-latest-delegate", url.Values{ "address": {address.Hex()}, "setting": {settingStr}, - }) - if err != nil { - return api.MegapoolSetUseLatestDelegateResponse{}, fmt.Errorf("Could not set use latest delegate for megapool: %w", err) - } - var response api.MegapoolSetUseLatestDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolSetUseLatestDelegateResponse{}, fmt.Errorf("Could not decode set use latest delegate for megapool response: %w", err) - } - if response.Error != "" { - return api.MegapoolSetUseLatestDelegateResponse{}, fmt.Errorf("Could not set use latest delegate for megapool: %s", response.Error) - } - return response, nil + }, "Could not set use latest delegate for megapool") } // Get the megapool's delegate address func (c *Client) GetDelegate() (api.MegapoolGetDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/get-delegate", nil) - if err != nil { - return api.MegapoolGetDelegateResponse{}, fmt.Errorf("Could get delegate for megapool: %w", err) - } - var response api.MegapoolGetDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolGetDelegateResponse{}, fmt.Errorf("Could not decode get delegate for megapool response: %w", err) - } - if response.Error != "" { - return api.MegapoolGetDelegateResponse{}, fmt.Errorf("Could not get delegate for megapool: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolGetDelegateResponse]("GET", "/api/megapool/get-delegate", nil, "Could get delegate for megapool") } // Get the megapool's effective delegate address func (c *Client) GetEffectiveDelegate(address common.Address) (api.MegapoolGetEffectiveDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/get-effective-delegate", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.MegapoolGetEffectiveDelegateResponse{}, fmt.Errorf("Could get effective delegate for megapool: %w", err) - } - var response api.MegapoolGetEffectiveDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolGetEffectiveDelegateResponse{}, fmt.Errorf("Could not decode get effective delegate for megapool response: %w", err) - } - if response.Error != "" { - return api.MegapoolGetEffectiveDelegateResponse{}, fmt.Errorf("Could not get effective delegate for megapool: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolGetEffectiveDelegateResponse]("GET", "/api/megapool/get-effective-delegate", url.Values{"address": {address.Hex()}}, "Could get effective delegate for megapool") } // Calculate the megapool pending rewards func (c *Client) CalculatePendingRewards() (api.MegapoolRewardSplitResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/pending-rewards", nil) - if err != nil { - return api.MegapoolRewardSplitResponse{}, fmt.Errorf("Could not get pending rewards: %w", err) - } - var response api.MegapoolRewardSplitResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolRewardSplitResponse{}, fmt.Errorf("Could not decode pending rewards response: %w", err) - } - if response.Error != "" { - return api.MegapoolRewardSplitResponse{}, fmt.Errorf("Could not get pending rewards: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolRewardSplitResponse]("GET", "/api/megapool/pending-rewards", nil, "Could not get pending rewards") } // Calculate rewards split given an arbitrary amount func (c *Client) CalculateRewards(amountWei *big.Int) (api.MegapoolRewardSplitResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/calculate-rewards", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.MegapoolRewardSplitResponse{}, fmt.Errorf("Could not calculate rewards: %w", err) - } - var response api.MegapoolRewardSplitResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MegapoolRewardSplitResponse{}, fmt.Errorf("Could not decode calculate rewards response: %w", err) - } - if response.Error != "" { - return api.MegapoolRewardSplitResponse{}, fmt.Errorf("Could not get calculate rewards: %s", response.Error) - } - return response, nil + return c.callAPI[api.MegapoolRewardSplitResponse]("GET", "/api/megapool/calculate-rewards", url.Values{"amountWei": {amountWei.String()}}, "Could not calculate rewards") } // Check if the node can distribute megapool rewards func (c *Client) CanDistributeMegapool() (api.CanDistributeMegapoolResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/can-distribute", nil) - if err != nil { - return api.CanDistributeMegapoolResponse{}, fmt.Errorf("Could not get can-distribute-megapool response: %w", err) - } - var response api.CanDistributeMegapoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanDistributeMegapoolResponse{}, fmt.Errorf("Could not decode can-distribute-megapool response: %w", err) - } - if response.Error != "" { - return api.CanDistributeMegapoolResponse{}, fmt.Errorf("Could not get can-distribute-megapool response: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanDistributeMegapoolResponse]("GET", "/api/megapool/can-distribute", nil, "Could not get can-distribute-megapool response") } // Distribute megapool rewards func (c *Client) DistributeMegapool() (api.DistributeMegapoolResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/megapool/distribute", nil) - if err != nil { - return api.DistributeMegapoolResponse{}, fmt.Errorf("Could not get distribute-megapool response: %w", err) - } - var response api.DistributeMegapoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DistributeMegapoolResponse{}, fmt.Errorf("Could not decode distribute-megapool response: %w", err) - } - if response.Error != "" { - return api.DistributeMegapoolResponse{}, fmt.Errorf("Could not get distribute-megapool response: %s", response.Error) - } - return response, nil + return c.callAPI[api.DistributeMegapoolResponse]("POST", "/api/megapool/distribute", nil, "Could not get distribute-megapool response") } // Get the validator withdrawals processed in the latest beacon block (with execution payload) func (c *Client) GetLatestBlockWithdrawals() (api.LatestBlockWithdrawalsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/latest-block-withdrawals", nil) - if err != nil { - return api.LatestBlockWithdrawalsResponse{}, fmt.Errorf("Could not get latest block withdrawals: %w", err) - } - var response api.LatestBlockWithdrawalsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.LatestBlockWithdrawalsResponse{}, fmt.Errorf("Could not decode latest block withdrawals response: %w", err) - } - if response.Error != "" { - return api.LatestBlockWithdrawalsResponse{}, fmt.Errorf("Could not get latest block withdrawals: %s", response.Error) - } - return response, nil + return c.callAPI[api.LatestBlockWithdrawalsResponse]("GET", "/api/megapool/latest-block-withdrawals", nil, "Could not get latest block withdrawals") } // Get an estimate of the beacon chain withdrawal-sweep cycle time func (c *Client) GetBeaconWithdrawalQueueEstimate() (api.BeaconWithdrawalQueueEstimateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/beacon-withdrawal-queue-estimate", nil) - if err != nil { - return api.BeaconWithdrawalQueueEstimateResponse{}, fmt.Errorf("Could not get beacon withdrawal queue estimate: %w", err) - } - var response api.BeaconWithdrawalQueueEstimateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.BeaconWithdrawalQueueEstimateResponse{}, fmt.Errorf("Could not decode beacon withdrawal queue estimate response: %w", err) - } - if response.Error != "" { - return api.BeaconWithdrawalQueueEstimateResponse{}, fmt.Errorf("Could not get beacon withdrawal queue estimate: %s", response.Error) - } - return response, nil + return c.callAPI[api.BeaconWithdrawalQueueEstimateResponse]("GET", "/api/megapool/beacon-withdrawal-queue-estimate", nil, "Could not get beacon withdrawal queue estimate") } // Get the bond amount required for the megapool's next validator func (c *Client) GetNewValidatorBondRequirement() (api.GetNewValidatorBondRequirementResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/megapool/get-new-validator-bond-requirement", nil) - if err != nil { - return api.GetNewValidatorBondRequirementResponse{}, fmt.Errorf("Could not get new validator bond requirement: %w", err) - } - var response api.GetNewValidatorBondRequirementResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetNewValidatorBondRequirementResponse{}, fmt.Errorf("Could not decode new validator bond requirement response: %w", err) - } - if response.Error != "" { - return api.GetNewValidatorBondRequirementResponse{}, fmt.Errorf("Could not get new validator bond requirement: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetNewValidatorBondRequirementResponse]("GET", "/api/megapool/get-new-validator-bond-requirement", nil, "Could not get new validator bond requirement") } // DissolveWithProof and CanDissolveWithProof client methods added above. diff --git a/shared/services/rocketpool/minipool.go b/shared/services/rocketpool/minipool.go index aa2d44a7b..9c3434b1a 100644 --- a/shared/services/rocketpool/minipool.go +++ b/shared/services/rocketpool/minipool.go @@ -1,29 +1,20 @@ package rocketpool import ( - "fmt" "math/big" "net/url" "strconv" "github.com/ethereum/go-ethereum/common" - "github.com/goccy/go-json" "github.com/rocket-pool/smartnode/shared/types/api" ) // Get minipool status func (c *Client) MinipoolStatus() (api.MinipoolStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/status", nil) + response, err := c.callAPI[api.MinipoolStatusResponse]("GET", "/api/minipool/status", nil, "Could not get minipool status") if err != nil { - return api.MinipoolStatusResponse{}, fmt.Errorf("Could not get minipool status: %w", err) - } - var response api.MinipoolStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MinipoolStatusResponse{}, fmt.Errorf("Could not decode minipool status response: %w", err) - } - if response.Error != "" { - return api.MinipoolStatusResponse{}, fmt.Errorf("Could not get minipool status: %s", response.Error) + return response, err } for i := 0; i < len(response.Minipools); i++ { mp := &response.Minipools[i] @@ -60,354 +51,123 @@ func (c *Client) MinipoolStatus() (api.MinipoolStatusResponse, error) { // Check whether a minipool is eligible for a refund func (c *Client) CanRefundMinipool(address common.Address) (api.CanRefundMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/can-refund", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.CanRefundMinipoolResponse{}, fmt.Errorf("Could not get can refund minipool status: %w", err) - } - var response api.CanRefundMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanRefundMinipoolResponse{}, fmt.Errorf("Could not decode can refund minipool response: %w", err) - } - if response.Error != "" { - return api.CanRefundMinipoolResponse{}, fmt.Errorf("Could not get can refund minipool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanRefundMinipoolResponse]("GET", "/api/minipool/can-refund", url.Values{"address": {address.Hex()}}, "Could not get can refund minipool status") } // Refund ETH from a minipool func (c *Client) RefundMinipool(address common.Address) (api.RefundMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/refund", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.RefundMinipoolResponse{}, fmt.Errorf("Could not refund minipool: %w", err) - } - var response api.RefundMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RefundMinipoolResponse{}, fmt.Errorf("Could not decode refund minipool response: %w", err) - } - if response.Error != "" { - return api.RefundMinipoolResponse{}, fmt.Errorf("Could not refund minipool: %s", response.Error) - } - return response, nil + return c.callAPI[api.RefundMinipoolResponse]("POST", "/api/minipool/refund", url.Values{"address": {address.Hex()}}, "Could not refund minipool") } // Check whether a minipool is eligible for staking func (c *Client) CanStakeMinipool(address common.Address) (api.CanStakeMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/can-stake", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.CanStakeMinipoolResponse{}, fmt.Errorf("Could not get can stake minipool status: %w", err) - } - var response api.CanStakeMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanStakeMinipoolResponse{}, fmt.Errorf("Could not decode can stake minipool response: %w", err) - } - if response.Error != "" { - return api.CanStakeMinipoolResponse{}, fmt.Errorf("Could not get can stake minipool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanStakeMinipoolResponse]("GET", "/api/minipool/can-stake", url.Values{"address": {address.Hex()}}, "Could not get can stake minipool status") } // Stake a minipool func (c *Client) StakeMinipool(address common.Address) (api.StakeMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/stake", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.StakeMinipoolResponse{}, fmt.Errorf("Could not stake minipool: %w", err) - } - var response api.StakeMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.StakeMinipoolResponse{}, fmt.Errorf("Could not decode stake minipool response: %w", err) - } - if response.Error != "" { - return api.StakeMinipoolResponse{}, fmt.Errorf("Could not stake minipool: %s", response.Error) - } - return response, nil + return c.callAPI[api.StakeMinipoolResponse]("POST", "/api/minipool/stake", url.Values{"address": {address.Hex()}}, "Could not stake minipool") } // Check whether a minipool can be dissolved func (c *Client) CanDissolveMinipool(address common.Address) (api.CanDissolveMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/can-dissolve", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.CanDissolveMinipoolResponse{}, fmt.Errorf("Could not get can dissolve minipool status: %w", err) - } - var response api.CanDissolveMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanDissolveMinipoolResponse{}, fmt.Errorf("Could not decode can dissolve minipool response: %w", err) - } - if response.Error != "" { - return api.CanDissolveMinipoolResponse{}, fmt.Errorf("Could not get can dissolve minipool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanDissolveMinipoolResponse]("GET", "/api/minipool/can-dissolve", url.Values{"address": {address.Hex()}}, "Could not get can dissolve minipool status") } // Dissolve a minipool func (c *Client) DissolveMinipool(address common.Address) (api.DissolveMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/dissolve", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.DissolveMinipoolResponse{}, fmt.Errorf("Could not dissolve minipool: %w", err) - } - var response api.DissolveMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DissolveMinipoolResponse{}, fmt.Errorf("Could not decode dissolve minipool response: %w", err) - } - if response.Error != "" { - return api.DissolveMinipoolResponse{}, fmt.Errorf("Could not dissolve minipool: %s", response.Error) - } - return response, nil + return c.callAPI[api.DissolveMinipoolResponse]("POST", "/api/minipool/dissolve", url.Values{"address": {address.Hex()}}, "Could not dissolve minipool") } // Check whether a minipool can be exited func (c *Client) CanExitMinipool(address common.Address) (api.CanExitMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/can-exit", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.CanExitMinipoolResponse{}, fmt.Errorf("Could not get can exit minipool status: %w", err) - } - var response api.CanExitMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanExitMinipoolResponse{}, fmt.Errorf("Could not decode can exit minipool response: %w", err) - } - if response.Error != "" { - return api.CanExitMinipoolResponse{}, fmt.Errorf("Could not get can exit minipool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanExitMinipoolResponse]("GET", "/api/minipool/can-exit", url.Values{"address": {address.Hex()}}, "Could not get can exit minipool status") } // Exit a minipool func (c *Client) ExitMinipool(address common.Address) (api.ExitMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/exit", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.ExitMinipoolResponse{}, fmt.Errorf("Could not exit minipool: %w", err) - } - var response api.ExitMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ExitMinipoolResponse{}, fmt.Errorf("Could not decode exit minipool response: %w", err) - } - if response.Error != "" { - return api.ExitMinipoolResponse{}, fmt.Errorf("Could not exit minipool: %s", response.Error) - } - return response, nil + return c.callAPI[api.ExitMinipoolResponse]("POST", "/api/minipool/exit", url.Values{"address": {address.Hex()}}, "Could not exit minipool") } // Check all of the node's minipools for closure eligibility, and return the details of the closeable ones func (c *Client) GetMinipoolCloseDetailsForNode() (api.GetMinipoolCloseDetailsForNodeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/get-minipool-close-details-for-node", nil) - if err != nil { - return api.GetMinipoolCloseDetailsForNodeResponse{}, fmt.Errorf("Could not get get-minipool-close-details-for-node status: %w", err) - } - var response api.GetMinipoolCloseDetailsForNodeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetMinipoolCloseDetailsForNodeResponse{}, fmt.Errorf("Could not decode get-minipool-close-details-for-node response: %w", err) - } - if response.Error != "" { - return api.GetMinipoolCloseDetailsForNodeResponse{}, fmt.Errorf("Could not get get-minipool-close-details-for-node status: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetMinipoolCloseDetailsForNodeResponse]("GET", "/api/minipool/get-minipool-close-details-for-node", nil, "Could not get get-minipool-close-details-for-node status") } // Close a minipool func (c *Client) CloseMinipool(address common.Address, bundle bool) (api.CloseMinipoolResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/close", url.Values{ + return c.callAPI[api.CloseMinipoolResponse]("POST", "/api/minipool/close", url.Values{ "address": {address.Hex()}, "bundle": {strconv.FormatBool(bundle)}, - }) - if err != nil { - return api.CloseMinipoolResponse{}, fmt.Errorf("Could not close minipool: %w", err) - } - var response api.CloseMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CloseMinipoolResponse{}, fmt.Errorf("Could not decode close minipool response: %w", err) - } - if response.Error != "" { - return api.CloseMinipoolResponse{}, fmt.Errorf("Could not close minipool: %s", response.Error) - } - return response, nil + }, "Could not close minipool") } // Check whether a minipool can have its delegate upgraded func (c *Client) CanDelegateUpgradeMinipool(address common.Address) (api.CanDelegateUpgradeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/can-delegate-upgrade", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.CanDelegateUpgradeResponse{}, fmt.Errorf("Could not get can delegate upgrade minipool status: %w", err) - } - var response api.CanDelegateUpgradeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanDelegateUpgradeResponse{}, fmt.Errorf("Could not decode can delegate upgrade minipool response: %w", err) - } - if response.Error != "" { - return api.CanDelegateUpgradeResponse{}, fmt.Errorf("Could not get can delegate upgrade minipool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanDelegateUpgradeResponse]("GET", "/api/minipool/can-delegate-upgrade", url.Values{"address": {address.Hex()}}, "Could not get can delegate upgrade minipool status") } // Upgrade a minipool delegate func (c *Client) DelegateUpgradeMinipool(address common.Address) (api.DelegateUpgradeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/delegate-upgrade", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.DelegateUpgradeResponse{}, fmt.Errorf("Could not upgrade delegate for minipool: %w", err) - } - var response api.DelegateUpgradeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DelegateUpgradeResponse{}, fmt.Errorf("Could not decode upgrade delegate minipool response: %w", err) - } - if response.Error != "" { - return api.DelegateUpgradeResponse{}, fmt.Errorf("Could not upgrade delegate for minipool: %s", response.Error) - } - return response, nil + return c.callAPI[api.DelegateUpgradeResponse]("POST", "/api/minipool/delegate-upgrade", url.Values{"address": {address.Hex()}}, "Could not upgrade delegate for minipool") } // Check whether a minipool can have its auto-upgrade setting changed func (c *Client) CanSetUseLatestDelegateMinipool(address common.Address, setLatest bool) (api.CanSetUseLatestDelegateResponse, error) { // pass setLatest as well - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/can-set-use-latest-delegate", url.Values{"address": {address.Hex()}, "setLatest": {strconv.FormatBool(setLatest)}}) - if err != nil { - return api.CanSetUseLatestDelegateResponse{}, fmt.Errorf("Could not get can set use latest delegate for minipool status: %w", err) - } - var response api.CanSetUseLatestDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetUseLatestDelegateResponse{}, fmt.Errorf("Could not decode can set use latest delegate for minipool response: %w", err) - } - if response.Error != "" { - return api.CanSetUseLatestDelegateResponse{}, fmt.Errorf("Could not get can set use latest delegate for minipool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanSetUseLatestDelegateResponse]("GET", "/api/minipool/can-set-use-latest-delegate", url.Values{"address": {address.Hex()}, "setLatest": {strconv.FormatBool(setLatest)}}, "Could not get can set use latest delegate for minipool status") } // Change a minipool's auto-upgrade setting func (c *Client) SetUseLatestDelegateMinipool(address common.Address) (api.SetUseLatestDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/set-use-latest-delegate", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.SetUseLatestDelegateResponse{}, fmt.Errorf("Could not set use latest delegate for minipool: %w", err) - } - var response api.SetUseLatestDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetUseLatestDelegateResponse{}, fmt.Errorf("Could not decode set use latest delegate for minipool response: %w", err) - } - if response.Error != "" { - return api.SetUseLatestDelegateResponse{}, fmt.Errorf("Could not set use latest delegate for minipool: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetUseLatestDelegateResponse]("POST", "/api/minipool/set-use-latest-delegate", url.Values{"address": {address.Hex()}}, "Could not set use latest delegate for minipool") } // Get the artifacts necessary for vanity address searching func (c *Client) GetVanityArtifacts(depositAmount *big.Int, nodeAddress string) (api.GetVanityArtifactsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/get-vanity-artifacts", url.Values{ + return c.callAPI[api.GetVanityArtifactsResponse]("GET", "/api/minipool/get-vanity-artifacts", url.Values{ "depositAmount": {depositAmount.String()}, "nodeAddress": {nodeAddress}, - }) - if err != nil { - return api.GetVanityArtifactsResponse{}, fmt.Errorf("Could not get vanity artifacts: %w", err) - } - var response api.GetVanityArtifactsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetVanityArtifactsResponse{}, fmt.Errorf("Could not decode get vanity artifacts response: %w", err) - } - if response.Error != "" { - return api.GetVanityArtifactsResponse{}, fmt.Errorf("Could not get vanity artifacts: %s", response.Error) - } - return response, nil + }, "Could not get vanity artifacts") } // Get the balance distribution details for all of the node's minipools func (c *Client) GetDistributeBalanceDetails() (api.GetDistributeBalanceDetailsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/get-distribute-balance-details", nil) - if err != nil { - return api.GetDistributeBalanceDetailsResponse{}, fmt.Errorf("Could not get distribute balance details: %w", err) - } - var response api.GetDistributeBalanceDetailsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetDistributeBalanceDetailsResponse{}, fmt.Errorf("Could not decode get distribute balance details response: %w", err) - } - if response.Error != "" { - return api.GetDistributeBalanceDetailsResponse{}, fmt.Errorf("Could not get distribute balance details: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetDistributeBalanceDetailsResponse]("GET", "/api/minipool/get-distribute-balance-details", nil, "Could not get distribute balance details") } // Distribute a minipool's ETH balance func (c *Client) DistributeBalance(address common.Address) (api.DistributeBalanceResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/distribute-balance", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.DistributeBalanceResponse{}, fmt.Errorf("Could not get distribute balance status: %w", err) - } - var response api.DistributeBalanceResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DistributeBalanceResponse{}, fmt.Errorf("Could not decode distribute balance response: %w", err) - } - if response.Error != "" { - return api.DistributeBalanceResponse{}, fmt.Errorf("Could not get distribute balance status: %s", response.Error) - } - return response, nil + return c.callAPI[api.DistributeBalanceResponse]("POST", "/api/minipool/distribute-balance", url.Values{"address": {address.Hex()}}, "Could not get distribute balance status") } // Import a validator private key for a vacant minipool func (c *Client) ImportKey(address common.Address, mnemonic string) (api.ChangeWithdrawalCredentialsResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/import-key", url.Values{ + return c.callAPI[api.ChangeWithdrawalCredentialsResponse]("POST", "/api/minipool/import-key", url.Values{ "address": {address.Hex()}, "mnemonic": {mnemonic}, - }) - if err != nil { - return api.ChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not import validator key: %w", err) - } - var response api.ChangeWithdrawalCredentialsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not decode import-key response: %w", err) - } - if response.Error != "" { - return api.ChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not import validator key: %s", response.Error) - } - return response, nil + }, "Could not import validator key") } // Check whether a solo validator's withdrawal creds can be migrated to a minipool address func (c *Client) CanChangeWithdrawalCredentials(address common.Address, mnemonic string) (api.CanChangeWithdrawalCredentialsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/can-change-withdrawal-creds", url.Values{ + return c.callAPI[api.CanChangeWithdrawalCredentialsResponse]("GET", "/api/minipool/can-change-withdrawal-creds", url.Values{ "address": {address.Hex()}, "mnemonic": {mnemonic}, - }) - if err != nil { - return api.CanChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not get can-change-withdrawal-creds status: %w", err) - } - var response api.CanChangeWithdrawalCredentialsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not decode can-change-withdrawal-creds response: %w", err) - } - if response.Error != "" { - return api.CanChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not get can-change-withdrawal-creds status: %s", response.Error) - } - return response, nil + }, "Could not get can-change-withdrawal-creds status") } // Migrate a solo validator's withdrawal creds to a minipool address func (c *Client) ChangeWithdrawalCredentials(address common.Address, mnemonic string) (api.ChangeWithdrawalCredentialsResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/change-withdrawal-creds", url.Values{ + return c.callAPI[api.ChangeWithdrawalCredentialsResponse]("POST", "/api/minipool/change-withdrawal-creds", url.Values{ "address": {address.Hex()}, "mnemonic": {mnemonic}, - }) - if err != nil { - return api.ChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not change withdrawal creds: %w", err) - } - var response api.ChangeWithdrawalCredentialsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not decode change-withdrawal-creds response: %w", err) - } - if response.Error != "" { - return api.ChangeWithdrawalCredentialsResponse{}, fmt.Errorf("Could not change withdrawal creds: %s", response.Error) - } - return response, nil + }, "Could not change withdrawal creds") } // Check all of the node's minipools for rescue eligibility, and return the details of the rescuable ones func (c *Client) GetMinipoolRescueDissolvedDetailsForNode() (api.GetMinipoolRescueDissolvedDetailsForNodeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/minipool/get-rescue-dissolved-details-for-node", nil) - if err != nil { - return api.GetMinipoolRescueDissolvedDetailsForNodeResponse{}, fmt.Errorf("Could not get get-minipool-rescue-dissolved-details-for-node status: %w", err) - } - var response api.GetMinipoolRescueDissolvedDetailsForNodeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetMinipoolRescueDissolvedDetailsForNodeResponse{}, fmt.Errorf("Could not decode get-minipool-rescue-dissolved-details-for-node response: %w", err) - } - if response.Error != "" { - return api.GetMinipoolRescueDissolvedDetailsForNodeResponse{}, fmt.Errorf("Could not get get-minipool-rescue-dissolved-details-for-node status: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetMinipoolRescueDissolvedDetailsForNodeResponse]("GET", "/api/minipool/get-rescue-dissolved-details-for-node", nil, "Could not get get-minipool-rescue-dissolved-details-for-node status") } // Rescue a dissolved minipool by depositing ETH for it to the Beacon deposit contract @@ -416,20 +176,9 @@ func (c *Client) RescueDissolvedMinipool(address common.Address, amount *big.Int if submit { submitStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/minipool/rescue-dissolved", url.Values{ + return c.callAPI[api.RescueDissolvedMinipoolResponse]("POST", "/api/minipool/rescue-dissolved", url.Values{ "address": {address.Hex()}, "amount": {amount.String()}, "submit": {submitStr}, - }) - if err != nil { - return api.RescueDissolvedMinipoolResponse{}, fmt.Errorf("Could not rescue dissolved minipool: %w", err) - } - var response api.RescueDissolvedMinipoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RescueDissolvedMinipoolResponse{}, fmt.Errorf("Could not decode rescue dissolved minipool response: %w", err) - } - if response.Error != "" { - return api.RescueDissolvedMinipoolResponse{}, fmt.Errorf("Could not rescue dissolved minipool: %s", response.Error) - } - return response, nil + }, "Could not rescue dissolved minipool") } diff --git a/shared/services/rocketpool/network.go b/shared/services/rocketpool/network.go index 72b246842..aa079d407 100644 --- a/shared/services/rocketpool/network.go +++ b/shared/services/rocketpool/network.go @@ -5,39 +5,19 @@ import ( "math/big" "net/url" - "github.com/goccy/go-json" - "github.com/rocket-pool/smartnode/shared/types/api" ) // Get network node fee func (c *Client) NodeFee() (api.NodeFeeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/network/node-fee", nil) - if err != nil { - return api.NodeFeeResponse{}, fmt.Errorf("Could not get network node fee: %w", err) - } - var response api.NodeFeeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeFeeResponse{}, fmt.Errorf("Could not decode network node fee response: %w", err) - } - if response.Error != "" { - return api.NodeFeeResponse{}, fmt.Errorf("Could not get network node fee: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeFeeResponse]("GET", "/api/network/node-fee", nil, "Could not get network node fee") } // Get network RPL price func (c *Client) RplPrice() (api.RplPriceResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/network/rpl-price", nil) + response, err := c.callAPI[api.RplPriceResponse]("GET", "/api/network/rpl-price", nil, "Could not get network RPL price") if err != nil { - return api.RplPriceResponse{}, fmt.Errorf("Could not get network RPL price: %w", err) - } - var response api.RplPriceResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RplPriceResponse{}, fmt.Errorf("Could not decode network RPL price response: %w", err) - } - if response.Error != "" { - return api.RplPriceResponse{}, fmt.Errorf("Could not get network RPL price: %s", response.Error) + return response, err } if response.RplPrice == nil { response.RplPrice = big.NewInt(0) @@ -47,112 +27,35 @@ func (c *Client) RplPrice() (api.RplPriceResponse, error) { // Get network stats func (c *Client) NetworkStats() (api.NetworkStatsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/network/stats", nil) - if err != nil { - return api.NetworkStatsResponse{}, fmt.Errorf("Could not get network stats: %w", err) - } - var response api.NetworkStatsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NetworkStatsResponse{}, fmt.Errorf("Could not decode network stats response: %w", err) - } - if response.Error != "" { - return api.NetworkStatsResponse{}, fmt.Errorf("Could not get network stats: %s", response.Error) - } - return response, nil + return c.callAPI[api.NetworkStatsResponse]("GET", "/api/network/stats", nil, "Could not get network stats") } // Get the timezone map func (c *Client) TimezoneMap() (api.NetworkTimezonesResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/network/timezone-map", nil) - if err != nil { - return api.NetworkTimezonesResponse{}, fmt.Errorf("Could not get network timezone map: %w", err) - } - var response api.NetworkTimezonesResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NetworkTimezonesResponse{}, fmt.Errorf("Could not decode network timezone map response: %w", err) - } - if response.Error != "" { - return api.NetworkTimezonesResponse{}, fmt.Errorf("Could not get network timezone map: %s", response.Error) - } - return response, nil + return c.callAPI[api.NetworkTimezonesResponse]("GET", "/api/network/timezone-map", nil, "Could not get network timezone map") } // Check if the rewards tree for the provided interval can be generated func (c *Client) CanGenerateRewardsTree(index uint64) (api.CanNetworkGenerateRewardsTreeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/network/can-generate-rewards-tree", url.Values{"index": {fmt.Sprintf("%d", index)}}) - if err != nil { - return api.CanNetworkGenerateRewardsTreeResponse{}, fmt.Errorf("Could not check rewards tree generation status: %w", err) - } - var response api.CanNetworkGenerateRewardsTreeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNetworkGenerateRewardsTreeResponse{}, fmt.Errorf("Could not decode rewards tree generation status response: %w", err) - } - if response.Error != "" { - return api.CanNetworkGenerateRewardsTreeResponse{}, fmt.Errorf("Could not check rewards tree generation status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNetworkGenerateRewardsTreeResponse]("GET", "/api/network/can-generate-rewards-tree", url.Values{"index": {fmt.Sprintf("%d", index)}}, "Could not check rewards tree generation status") } // Set a request marker for the watchtower to generate the rewards tree for the given interval func (c *Client) GenerateRewardsTree(index uint64) (api.NetworkGenerateRewardsTreeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/network/generate-rewards-tree", url.Values{"index": {fmt.Sprintf("%d", index)}}) - if err != nil { - return api.NetworkGenerateRewardsTreeResponse{}, fmt.Errorf("Could not initialize rewards tree generation: %w", err) - } - var response api.NetworkGenerateRewardsTreeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NetworkGenerateRewardsTreeResponse{}, fmt.Errorf("Could not decode rewards tree generation response: %w", err) - } - if response.Error != "" { - return api.NetworkGenerateRewardsTreeResponse{}, fmt.Errorf("Could not initialize rewards tree generation: %s", response.Error) - } - return response, nil + return c.callAPI[api.NetworkGenerateRewardsTreeResponse]("POST", "/api/network/generate-rewards-tree", url.Values{"index": {fmt.Sprintf("%d", index)}}, "Could not initialize rewards tree generation") } // GetActiveDAOProposals fetches information about active DAO proposals func (c *Client) GetActiveDAOProposals() (api.NetworkDAOProposalsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/network/dao-proposals", nil) - if err != nil { - return api.NetworkDAOProposalsResponse{}, fmt.Errorf("could not request active DAO proposals: %w", err) - } - var response api.NetworkDAOProposalsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NetworkDAOProposalsResponse{}, fmt.Errorf("could not decode dao proposals response: %w", err) - } - if response.Error != "" { - return api.NetworkDAOProposalsResponse{}, fmt.Errorf("error after requesting dao proposals: %s", response.Error) - } - return response, nil + return c.callAPI[api.NetworkDAOProposalsResponse]("GET", "/api/network/dao-proposals", nil, "could not request active DAO proposals") } // Download a rewards info file from IPFS for the given interval func (c *Client) DownloadRewardsFile(interval uint64) (api.DownloadRewardsFileResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/network/download-rewards-file", url.Values{"interval": {fmt.Sprintf("%d", interval)}}) - if err != nil { - return api.DownloadRewardsFileResponse{}, fmt.Errorf("could not download rewards file: %w", err) - } - var response api.DownloadRewardsFileResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DownloadRewardsFileResponse{}, fmt.Errorf("could not decode download-rewards-file response: %w", err) - } - if response.Error != "" { - return api.DownloadRewardsFileResponse{}, fmt.Errorf("error after downloading rewards file: %s", response.Error) - } - return response, nil + return c.callAPI[api.DownloadRewardsFileResponse]("POST", "/api/network/download-rewards-file", url.Values{"interval": {fmt.Sprintf("%d", interval)}}, "could not download rewards file") } // Get the address of the latest minipool delegate contract func (c *Client) GetLatestDelegate() (api.GetLatestDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/network/latest-delegate", nil) - if err != nil { - return api.GetLatestDelegateResponse{}, fmt.Errorf("could not get latest delegate: %w", err) - } - var response api.GetLatestDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetLatestDelegateResponse{}, fmt.Errorf("could not decode get-latest-delegate response: %w", err) - } - if response.Error != "" { - return api.GetLatestDelegateResponse{}, fmt.Errorf("could not get latest delegate: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetLatestDelegateResponse]("GET", "/api/network/latest-delegate", nil, "could not get latest delegate") } diff --git a/shared/services/rocketpool/node.go b/shared/services/rocketpool/node.go index ec699e5ff..d66bc2d8f 100644 --- a/shared/services/rocketpool/node.go +++ b/shared/services/rocketpool/node.go @@ -3,7 +3,6 @@ package rocketpool import ( "context" "encoding/hex" - "fmt" "math/big" "net/url" "strconv" @@ -11,7 +10,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/goccy/go-json" "github.com/rocket-pool/smartnode/shared/types/api" ) @@ -24,16 +22,9 @@ func zeroIfNil(in **big.Int) { // Get node status func (c *Client) NodeStatus() (api.NodeStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/status", nil) + response, err := c.callAPI[api.NodeStatusResponse]("GET", "/api/node/status", nil, "Could not get node status") if err != nil { - return api.NodeStatusResponse{}, fmt.Errorf("Could not get node status: %w", err) - } - var response api.NodeStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeStatusResponse{}, fmt.Errorf("Could not decode node status response: %w", err) - } - if response.Error != "" { - return api.NodeStatusResponse{}, fmt.Errorf("Could not get node status: %s", response.Error) + return response, err } zeroIfNil(&response.TotalRplStake) zeroIfNil(&response.RplStakeMegapool) @@ -68,711 +59,249 @@ func (c *Client) NodeStatus() (api.NodeStatusResponse, error) { func (c *Client) NodeAlerts() (api.NodeAlertsResponse, error) { ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() - responseBytes, err := c.callHTTPAPICtx(ctx, "GET", "/api/node/alerts", nil) - if err != nil { - return api.NodeAlertsResponse{}, fmt.Errorf("could not get node alerts: %w", err) - } - var response api.NodeAlertsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeAlertsResponse{}, fmt.Errorf("could not decode node alerts response: %w", err) - } - if response.Error != "" { - return api.NodeAlertsResponse{}, fmt.Errorf("could not get node alerts: %s", response.Error) - } - return response, nil + return c.callAPICtx[api.NodeAlertsResponse](ctx, "GET", "/api/node/alerts", nil, "could not get node alerts") } // Check whether the node can be registered func (c *Client) CanRegisterNode(timezoneLocation string) (api.CanRegisterNodeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-register", url.Values{"timezoneLocation": {timezoneLocation}}) - if err != nil { - return api.CanRegisterNodeResponse{}, fmt.Errorf("Could not get can register node status: %w", err) - } - var response api.CanRegisterNodeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanRegisterNodeResponse{}, fmt.Errorf("Could not decode can register node response: %w", err) - } - if response.Error != "" { - return api.CanRegisterNodeResponse{}, fmt.Errorf("Could not get can register node status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanRegisterNodeResponse]("GET", "/api/node/can-register", url.Values{"timezoneLocation": {timezoneLocation}}, "Could not get can register node status") } // Register the node func (c *Client) RegisterNode(timezoneLocation string) (api.RegisterNodeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/register", url.Values{"timezoneLocation": {timezoneLocation}}) - if err != nil { - return api.RegisterNodeResponse{}, fmt.Errorf("Could not register node: %w", err) - } - var response api.RegisterNodeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RegisterNodeResponse{}, fmt.Errorf("Could not decode register node response: %w", err) - } - if response.Error != "" { - return api.RegisterNodeResponse{}, fmt.Errorf("Could not register node: %s", response.Error) - } - return response, nil + return c.callAPI[api.RegisterNodeResponse]("POST", "/api/node/register", url.Values{"timezoneLocation": {timezoneLocation}}, "Could not register node") } // Checks if the node's primary withdrawal address can be set func (c *Client) CanSetNodePrimaryWithdrawalAddress(withdrawalAddress common.Address, confirm bool) (api.CanSetNodePrimaryWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-set-primary-withdrawal-address", url.Values{ + return c.callAPI[api.CanSetNodePrimaryWithdrawalAddressResponse]("GET", "/api/node/can-set-primary-withdrawal-address", url.Values{ "address": {withdrawalAddress.Hex()}, "confirm": {strconv.FormatBool(confirm)}, - }) - if err != nil { - return api.CanSetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not get can set node primary withdrawal address: %w", err) - } - var response api.CanSetNodePrimaryWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not decode can set node primary withdrawal address response: %w", err) - } - if response.Error != "" { - return api.CanSetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not get can set node primary withdrawal address: %s", response.Error) - } - return response, nil + }, "Could not get can set node primary withdrawal address") } // Set the node's primary withdrawal address func (c *Client) SetNodePrimaryWithdrawalAddress(withdrawalAddress common.Address, confirm bool) (api.SetNodePrimaryWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/set-primary-withdrawal-address", url.Values{ + return c.callAPI[api.SetNodePrimaryWithdrawalAddressResponse]("POST", "/api/node/set-primary-withdrawal-address", url.Values{ "address": {withdrawalAddress.Hex()}, "confirm": {strconv.FormatBool(confirm)}, - }) - if err != nil { - return api.SetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not set node primary withdrawal address: %w", err) - } - var response api.SetNodePrimaryWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not decode set node primary withdrawal address response: %w", err) - } - if response.Error != "" { - return api.SetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not set node primary withdrawal address: %s", response.Error) - } - return response, nil + }, "Could not set node primary withdrawal address") } // Checks if the node's primary withdrawal address can be confirmed func (c *Client) CanConfirmNodePrimaryWithdrawalAddress() (api.CanSetNodePrimaryWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-confirm-primary-withdrawal-address", nil) - if err != nil { - return api.CanSetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not get can confirm node primary withdrawal address: %w", err) - } - var response api.CanSetNodePrimaryWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not decode can confirm node primary withdrawal address response: %w", err) - } - if response.Error != "" { - return api.CanSetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not get can confirm node primary withdrawal address: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanSetNodePrimaryWithdrawalAddressResponse]("GET", "/api/node/can-confirm-primary-withdrawal-address", nil, "Could not get can confirm node primary withdrawal address") } // Confirm the node's primary withdrawal address func (c *Client) ConfirmNodePrimaryWithdrawalAddress() (api.SetNodePrimaryWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/confirm-primary-withdrawal-address", nil) - if err != nil { - return api.SetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not confirm node primary withdrawal address: %w", err) - } - var response api.SetNodePrimaryWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not decode confirm node primary withdrawal address response: %w", err) - } - if response.Error != "" { - return api.SetNodePrimaryWithdrawalAddressResponse{}, fmt.Errorf("Could not confirm node primary withdrawal address: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetNodePrimaryWithdrawalAddressResponse]("POST", "/api/node/confirm-primary-withdrawal-address", nil, "Could not confirm node primary withdrawal address") } // Checks if the node's RPL withdrawal address can be set func (c *Client) CanSetNodeRPLWithdrawalAddress(withdrawalAddress common.Address, confirm bool) (api.CanSetNodeRPLWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-set-rpl-withdrawal-address", url.Values{ + return c.callAPI[api.CanSetNodeRPLWithdrawalAddressResponse]("GET", "/api/node/can-set-rpl-withdrawal-address", url.Values{ "address": {withdrawalAddress.Hex()}, "confirm": {strconv.FormatBool(confirm)}, - }) - if err != nil { - return api.CanSetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not get can set node RPL withdrawal address: %w", err) - } - var response api.CanSetNodeRPLWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not decode can set node RPL withdrawal address response: %w", err) - } - if response.Error != "" { - return api.CanSetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not get can set node RPL withdrawal address: %s", response.Error) - } - return response, nil + }, "Could not get can set node RPL withdrawal address") } // Set the node's RPL withdrawal address func (c *Client) SetNodeRPLWithdrawalAddress(withdrawalAddress common.Address, confirm bool) (api.SetNodeRPLWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/set-rpl-withdrawal-address", url.Values{ + return c.callAPI[api.SetNodeRPLWithdrawalAddressResponse]("POST", "/api/node/set-rpl-withdrawal-address", url.Values{ "address": {withdrawalAddress.Hex()}, "confirm": {strconv.FormatBool(confirm)}, - }) - if err != nil { - return api.SetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not set node RPL withdrawal address: %w", err) - } - var response api.SetNodeRPLWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not decode set node RPL withdrawal address response: %w", err) - } - if response.Error != "" { - return api.SetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not set node RPL withdrawal address: %s", response.Error) - } - return response, nil + }, "Could not set node RPL withdrawal address") } // Checks if the node's RPL withdrawal address can be confirmed func (c *Client) CanConfirmNodeRPLWithdrawalAddress() (api.CanSetNodeRPLWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-confirm-rpl-withdrawal-address", nil) - if err != nil { - return api.CanSetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not get can confirm node RPL withdrawal address: %w", err) - } - var response api.CanSetNodeRPLWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not decode can confirm node RPL withdrawal address response: %w", err) - } - if response.Error != "" { - return api.CanSetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not get can confirm node RPL withdrawal address: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanSetNodeRPLWithdrawalAddressResponse]("GET", "/api/node/can-confirm-rpl-withdrawal-address", nil, "Could not get can confirm node RPL withdrawal address") } // Confirm the node's RPL withdrawal address func (c *Client) ConfirmNodeRPLWithdrawalAddress() (api.SetNodeRPLWithdrawalAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/confirm-rpl-withdrawal-address", nil) - if err != nil { - return api.SetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not confirm node RPL withdrawal address: %w", err) - } - var response api.SetNodeRPLWithdrawalAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not decode confirm node RPL withdrawal address response: %w", err) - } - if response.Error != "" { - return api.SetNodeRPLWithdrawalAddressResponse{}, fmt.Errorf("Could not confirm node RPL withdrawal address: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetNodeRPLWithdrawalAddressResponse]("POST", "/api/node/confirm-rpl-withdrawal-address", nil, "Could not confirm node RPL withdrawal address") } // Checks if the node's timezone location can be set func (c *Client) CanSetNodeTimezone(timezoneLocation string) (api.CanSetNodeTimezoneResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-set-timezone", url.Values{"timezoneLocation": {timezoneLocation}}) - if err != nil { - return api.CanSetNodeTimezoneResponse{}, fmt.Errorf("Could not get can set node timezone: %w", err) - } - var response api.CanSetNodeTimezoneResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetNodeTimezoneResponse{}, fmt.Errorf("Could not decode can set node timezone response: %w", err) - } - if response.Error != "" { - return api.CanSetNodeTimezoneResponse{}, fmt.Errorf("Could not get can set node timezone: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanSetNodeTimezoneResponse]("GET", "/api/node/can-set-timezone", url.Values{"timezoneLocation": {timezoneLocation}}, "Could not get can set node timezone") } // Set the node's timezone location func (c *Client) SetNodeTimezone(timezoneLocation string) (api.SetNodeTimezoneResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/set-timezone", url.Values{"timezoneLocation": {timezoneLocation}}) - if err != nil { - return api.SetNodeTimezoneResponse{}, fmt.Errorf("Could not set node timezone: %w", err) - } - var response api.SetNodeTimezoneResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetNodeTimezoneResponse{}, fmt.Errorf("Could not decode set node timezone response: %w", err) - } - if response.Error != "" { - return api.SetNodeTimezoneResponse{}, fmt.Errorf("Could not set node timezone: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetNodeTimezoneResponse]("POST", "/api/node/set-timezone", url.Values{"timezoneLocation": {timezoneLocation}}, "Could not set node timezone") } // Check whether the node can swap RPL tokens func (c *Client) CanNodeSwapRpl(amountWei *big.Int) (api.CanNodeSwapRplResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-swap-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanNodeSwapRplResponse{}, fmt.Errorf("Could not get can node swap RPL status: %w", err) - } - var response api.CanNodeSwapRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeSwapRplResponse{}, fmt.Errorf("Could not decode can node swap RPL response: %w", err) - } - if response.Error != "" { - return api.CanNodeSwapRplResponse{}, fmt.Errorf("Could not get can node swap RPL status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeSwapRplResponse]("GET", "/api/node/can-swap-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not get can node swap RPL status") } // Get the gas estimate for approving legacy RPL interaction func (c *Client) NodeSwapRplApprovalGas(amountWei *big.Int) (api.NodeSwapRplApproveGasResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-swap-rpl-approval-gas", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeSwapRplApproveGasResponse{}, fmt.Errorf("Could not get old RPL approval gas: %w", err) - } - var response api.NodeSwapRplApproveGasResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSwapRplApproveGasResponse{}, fmt.Errorf("Could not decode node swap RPL approve gas response: %w", err) - } - if response.Error != "" { - return api.NodeSwapRplApproveGasResponse{}, fmt.Errorf("Could not get old RPL approval gas: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeSwapRplApproveGasResponse]("GET", "/api/node/get-swap-rpl-approval-gas", url.Values{"amountWei": {amountWei.String()}}, "Could not get old RPL approval gas") } // Approves old RPL for a token swap func (c *Client) NodeSwapRplApprove(amountWei *big.Int) (api.NodeSwapRplApproveResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/swap-rpl-approve-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeSwapRplApproveResponse{}, fmt.Errorf("Could not approve old RPL: %w", err) - } - var response api.NodeSwapRplApproveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSwapRplApproveResponse{}, fmt.Errorf("Could not decode node swap RPL approve response: %w", err) - } - if response.Error != "" { - return api.NodeSwapRplApproveResponse{}, fmt.Errorf("Could not approve old RPL tokens for swapping: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeSwapRplApproveResponse]("POST", "/api/node/swap-rpl-approve-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not approve old RPL") } // Swap node's old RPL tokens for new RPL tokens, waiting for the approval to be included in a block first func (c *Client) NodeWaitAndSwapRpl(amountWei *big.Int, approvalTxHash common.Hash) (api.NodeSwapRplSwapResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/wait-and-swap-rpl", url.Values{ + return c.callAPI[api.NodeSwapRplSwapResponse]("POST", "/api/node/wait-and-swap-rpl", url.Values{ "amountWei": {amountWei.String()}, "approvalTxHash": {approvalTxHash.Hex()}, - }) - if err != nil { - return api.NodeSwapRplSwapResponse{}, fmt.Errorf("Could not swap node's RPL tokens: %w", err) - } - var response api.NodeSwapRplSwapResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSwapRplSwapResponse{}, fmt.Errorf("Could not decode node swap RPL tokens response: %w", err) - } - if response.Error != "" { - return api.NodeSwapRplSwapResponse{}, fmt.Errorf("Could not swap node's RPL tokens: %s", response.Error) - } - return response, nil + }, "Could not swap node's RPL tokens") } // Swap node's old RPL tokens for new RPL tokens func (c *Client) NodeSwapRpl(amountWei *big.Int) (api.NodeSwapRplSwapResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/swap-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeSwapRplSwapResponse{}, fmt.Errorf("Could not swap node's RPL tokens: %w", err) - } - var response api.NodeSwapRplSwapResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSwapRplSwapResponse{}, fmt.Errorf("Could not decode node swap RPL tokens response: %w", err) - } - if response.Error != "" { - return api.NodeSwapRplSwapResponse{}, fmt.Errorf("Could not swap node's RPL tokens: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeSwapRplSwapResponse]("POST", "/api/node/swap-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not swap node's RPL tokens") } // Get a node's legacy RPL allowance for swapping on the new RPL contract func (c *Client) GetNodeSwapRplAllowance() (api.NodeSwapRplAllowanceResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/swap-rpl-allowance", nil) - if err != nil { - return api.NodeSwapRplAllowanceResponse{}, fmt.Errorf("Could not get node swap RPL allowance: %w", err) - } - var response api.NodeSwapRplAllowanceResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSwapRplAllowanceResponse{}, fmt.Errorf("Could not decode node swap RPL allowance response: %w", err) - } - if response.Error != "" { - return api.NodeSwapRplAllowanceResponse{}, fmt.Errorf("Could not get node swap RPL allowance: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeSwapRplAllowanceResponse]("GET", "/api/node/swap-rpl-allowance", nil, "Could not get node swap RPL allowance") } // Check whether the node can stake RPL func (c *Client) CanNodeStakeRpl(amountWei *big.Int) (api.CanNodeStakeRplResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-stake-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanNodeStakeRplResponse{}, fmt.Errorf("Could not get can node stake RPL status: %w", err) - } - var response api.CanNodeStakeRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeStakeRplResponse{}, fmt.Errorf("Could not decode can node stake RPL response: %w", err) - } - if response.Error != "" { - return api.CanNodeStakeRplResponse{}, fmt.Errorf("Could not get can node stake RPL status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeStakeRplResponse]("GET", "/api/node/can-stake-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not get can node stake RPL status") } // Get the gas estimate for approving new RPL interaction func (c *Client) NodeStakeRplApprovalGas(amountWei *big.Int) (api.NodeStakeRplApproveGasResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-stake-rpl-approval-gas", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeStakeRplApproveGasResponse{}, fmt.Errorf("Could not get new RPL approval gas: %w", err) - } - var response api.NodeStakeRplApproveGasResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeStakeRplApproveGasResponse{}, fmt.Errorf("Could not decode node stake RPL approve gas response: %w", err) - } - if response.Error != "" { - return api.NodeStakeRplApproveGasResponse{}, fmt.Errorf("Could not get new RPL approval gas: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeStakeRplApproveGasResponse]("GET", "/api/node/get-stake-rpl-approval-gas", url.Values{"amountWei": {amountWei.String()}}, "Could not get new RPL approval gas") } // Approve RPL for staking against the node func (c *Client) NodeStakeRplApprove(amountWei *big.Int) (api.NodeStakeRplApproveResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/stake-rpl-approve-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeStakeRplApproveResponse{}, fmt.Errorf("Could not approve RPL for staking: %w", err) - } - var response api.NodeStakeRplApproveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeStakeRplApproveResponse{}, fmt.Errorf("Could not decode stake node RPL approve response: %w", err) - } - if response.Error != "" { - return api.NodeStakeRplApproveResponse{}, fmt.Errorf("Could not approve RPL for staking: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeStakeRplApproveResponse]("POST", "/api/node/stake-rpl-approve-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not approve RPL for staking") } // Stake RPL against the node waiting for approvalTxHash to be included in a block first func (c *Client) NodeWaitAndStakeRpl(amountWei *big.Int, approvalTxHash common.Hash) (api.NodeStakeRplStakeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/wait-and-stake-rpl", url.Values{ + return c.callAPI[api.NodeStakeRplStakeResponse]("POST", "/api/node/wait-and-stake-rpl", url.Values{ "amountWei": {amountWei.String()}, "approvalTxHash": {approvalTxHash.Hex()}, - }) - if err != nil { - return api.NodeStakeRplStakeResponse{}, fmt.Errorf("Could not stake node RPL: %w", err) - } - var response api.NodeStakeRplStakeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeStakeRplStakeResponse{}, fmt.Errorf("Could not decode stake node RPL response: %w", err) - } - if response.Error != "" { - return api.NodeStakeRplStakeResponse{}, fmt.Errorf("Could not stake node RPL: %s", response.Error) - } - return response, nil + }, "Could not stake node RPL") } // Stake RPL against the node func (c *Client) NodeStakeRpl(amountWei *big.Int) (api.NodeStakeRplStakeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/stake-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeStakeRplStakeResponse{}, fmt.Errorf("Could not stake node RPL: %w", err) - } - var response api.NodeStakeRplStakeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeStakeRplStakeResponse{}, fmt.Errorf("Could not decode stake node RPL response: %w", err) - } - if response.Error != "" { - return api.NodeStakeRplStakeResponse{}, fmt.Errorf("Could not stake node RPL: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeStakeRplStakeResponse]("POST", "/api/node/stake-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not stake node RPL") } // Get a node's RPL allowance for the staking contract func (c *Client) GetNodeStakeRplAllowance() (api.NodeStakeRplAllowanceResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/stake-rpl-allowance", nil) - if err != nil { - return api.NodeStakeRplAllowanceResponse{}, fmt.Errorf("Could not get node stake RPL allowance: %w", err) - } - var response api.NodeStakeRplAllowanceResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeStakeRplAllowanceResponse{}, fmt.Errorf("Could not decode node stake RPL allowance response: %w", err) - } - if response.Error != "" { - return api.NodeStakeRplAllowanceResponse{}, fmt.Errorf("Could not get node stake RPL allowance: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeStakeRplAllowanceResponse]("GET", "/api/node/stake-rpl-allowance", nil, "Could not get node stake RPL allowance") } // Checks if the node operator can set RPL locking allowed func (c *Client) CanSetRPLLockingAllowed(allowed bool) (api.CanSetRplLockingAllowedResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-set-rpl-locking-allowed", url.Values{"allowed": {strconv.FormatBool(allowed)}}) - if err != nil { - return api.CanSetRplLockingAllowedResponse{}, fmt.Errorf("Could not get can set RPL locking allowed: %w", err) - } - var response api.CanSetRplLockingAllowedResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetRplLockingAllowedResponse{}, fmt.Errorf("Could not decode can set RPL locking allowed: %w", err) - } - if response.Error != "" { - return api.CanSetRplLockingAllowedResponse{}, fmt.Errorf("Could not set RPL locking allowed: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanSetRplLockingAllowedResponse]("GET", "/api/node/can-set-rpl-locking-allowed", url.Values{"allowed": {strconv.FormatBool(allowed)}}, "Could not get can set RPL locking allowed") } // Sets the allow state for the node to lock RPL func (c *Client) SetRPLLockingAllowed(allowed bool) (api.SetRplLockingAllowedResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/set-rpl-locking-allowed", url.Values{"allowed": {strconv.FormatBool(allowed)}}) - if err != nil { - return api.SetRplLockingAllowedResponse{}, fmt.Errorf("Could not set RPL locking allowed: %w", err) - } - var response api.SetRplLockingAllowedResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetRplLockingAllowedResponse{}, fmt.Errorf("Could not decode set RPL locking allowed response: %w", err) - } - if response.Error != "" { - return api.SetRplLockingAllowedResponse{}, fmt.Errorf("Could not set RPL locking allowed: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetRplLockingAllowedResponse]("POST", "/api/node/set-rpl-locking-allowed", url.Values{"allowed": {strconv.FormatBool(allowed)}}, "Could not set RPL locking allowed") } // Checks if the node operator can set RPL stake for allowed func (c *Client) CanSetStakeRPLForAllowed(caller common.Address, allowed bool) (api.CanSetStakeRplForAllowedResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-set-stake-rpl-for-allowed", url.Values{ + return c.callAPI[api.CanSetStakeRplForAllowedResponse]("GET", "/api/node/can-set-stake-rpl-for-allowed", url.Values{ "caller": {caller.Hex()}, "allowed": {strconv.FormatBool(allowed)}, - }) - if err != nil { - return api.CanSetStakeRplForAllowedResponse{}, fmt.Errorf("Could not get can set stake RPL for allowed: %w", err) - } - var response api.CanSetStakeRplForAllowedResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetStakeRplForAllowedResponse{}, fmt.Errorf("Could not decode can set stake RPL for allowed: %w", err) - } - if response.Error != "" { - return api.CanSetStakeRplForAllowedResponse{}, fmt.Errorf("Could not set stake RPL for allowed: %s", response.Error) - } - return response, nil + }, "Could not get can set stake RPL for allowed") } // Sets the allow state of another address staking on behalf of the node func (c *Client) SetStakeRPLForAllowed(caller common.Address, allowed bool) (api.SetStakeRplForAllowedResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/set-stake-rpl-for-allowed", url.Values{ + return c.callAPI[api.SetStakeRplForAllowedResponse]("POST", "/api/node/set-stake-rpl-for-allowed", url.Values{ "caller": {caller.Hex()}, "allowed": {strconv.FormatBool(allowed)}, - }) - if err != nil { - return api.SetStakeRplForAllowedResponse{}, fmt.Errorf("Could not set stake RPL for allowed: %w", err) - } - var response api.SetStakeRplForAllowedResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetStakeRplForAllowedResponse{}, fmt.Errorf("Could not decode set stake RPL for allowed response: %w", err) - } - if response.Error != "" { - return api.SetStakeRplForAllowedResponse{}, fmt.Errorf("Could not set stake RPL for allowed: %s", response.Error) - } - return response, nil + }, "Could not set stake RPL for allowed") } // Check whether the node can withdraw RPL func (c *Client) CanNodeWithdrawRpl() (api.CanNodeWithdrawRplResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-withdraw-rpl", nil) - if err != nil { - return api.CanNodeWithdrawRplResponse{}, fmt.Errorf("Could not get can node withdraw RPL status: %w", err) - } - var response api.CanNodeWithdrawRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeWithdrawRplResponse{}, fmt.Errorf("Could not decode can node withdraw RPL response: %w", err) - } - if response.Error != "" { - return api.CanNodeWithdrawRplResponse{}, fmt.Errorf("Could not get can node withdraw RPL status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeWithdrawRplResponse]("GET", "/api/node/can-withdraw-rpl", nil, "Could not get can node withdraw RPL status") } // Withdraw RPL staked against the node func (c *Client) NodeWithdrawRpl() (api.NodeWithdrawRplResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/withdraw-rpl", nil) - if err != nil { - return api.NodeWithdrawRplResponse{}, fmt.Errorf("Could not withdraw node RPL: %w", err) - } - var response api.NodeWithdrawRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeWithdrawRplResponse{}, fmt.Errorf("Could not decode withdraw node RPL response: %w", err) - } - if response.Error != "" { - return api.NodeWithdrawRplResponse{}, fmt.Errorf("Could not withdraw node RPL: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeWithdrawRplResponse]("POST", "/api/node/withdraw-rpl", nil, "Could not withdraw node RPL") } // Check whether the node can unstake legacy RPL func (c *Client) CanNodeUnstakeLegacyRpl(amountWei *big.Int) (api.CanNodeUnstakeLegacyRplResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-unstake-legacy-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanNodeUnstakeLegacyRplResponse{}, fmt.Errorf("Could not get can node unstake legacy RPL status: %w", err) - } - var response api.CanNodeUnstakeLegacyRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeUnstakeLegacyRplResponse{}, fmt.Errorf("Could not decode can node unstake legacy RPL response: %w", err) - } - if response.Error != "" { - return api.CanNodeUnstakeLegacyRplResponse{}, fmt.Errorf("Could not get can node unstake legacy RPL status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeUnstakeLegacyRplResponse]("GET", "/api/node/can-unstake-legacy-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not get can node unstake legacy RPL status") } // Unstake legacy RPL staked against the node func (c *Client) NodeUnstakeLegacyRpl(amountWei *big.Int) (api.NodeUnstakeLegacyRplResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/unstake-legacy-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeUnstakeLegacyRplResponse{}, fmt.Errorf("Could not unstake node legacy RPL: %w", err) - } - var response api.NodeUnstakeLegacyRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeUnstakeLegacyRplResponse{}, fmt.Errorf("Could not decode unstake node legacy RPL response: %w", err) - } - if response.Error != "" { - return api.NodeUnstakeLegacyRplResponse{}, fmt.Errorf("Could not unstake node legacy RPL: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeUnstakeLegacyRplResponse]("POST", "/api/node/unstake-legacy-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not unstake node legacy RPL") } // Check whether the node can withdraw RPL // Used if saturn is not deployed (v1.3.1) func (c *Client) CanNodeWithdrawRplV1_3_1(amountWei *big.Int) (api.CanNodeWithdrawRplv1_3_1Response, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-withdraw-rpl-v131", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanNodeWithdrawRplv1_3_1Response{}, fmt.Errorf("Could not get can node withdraw RPL status: %w", err) - } - var response api.CanNodeWithdrawRplv1_3_1Response - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeWithdrawRplv1_3_1Response{}, fmt.Errorf("Could not decode can node withdraw RPL response: %w", err) - } - if response.Error != "" { - return api.CanNodeWithdrawRplv1_3_1Response{}, fmt.Errorf("Could not get can node withdraw RPL status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeWithdrawRplv1_3_1Response]("GET", "/api/node/can-withdraw-rpl-v131", url.Values{"amountWei": {amountWei.String()}}, "Could not get can node withdraw RPL status") } // Withdraw RPL staked against the node // Used if saturn is not deployed (v1.3.1) func (c *Client) NodeWithdrawRplV1_3_1(amountWei *big.Int) (api.NodeWithdrawRplResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/withdraw-rpl-v131", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeWithdrawRplResponse{}, fmt.Errorf("Could not withdraw node RPL: %w", err) - } - var response api.NodeWithdrawRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeWithdrawRplResponse{}, fmt.Errorf("Could not decode withdraw node RPL response: %w", err) - } - if response.Error != "" { - return api.NodeWithdrawRplResponse{}, fmt.Errorf("Could not withdraw node RPL: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeWithdrawRplResponse]("POST", "/api/node/withdraw-rpl-v131", url.Values{"amountWei": {amountWei.String()}}, "Could not withdraw node RPL") } // Check whether the node can unstake RPL func (c *Client) CanNodeUnstakeRpl(amountWei *big.Int) (api.CanNodeUnstakeRplResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-unstake-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanNodeUnstakeRplResponse{}, fmt.Errorf("Could not get can node unstake RPL status: %w", err) - } - var response api.CanNodeUnstakeRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeUnstakeRplResponse{}, fmt.Errorf("Could not decode can node unstake RPL response: %w", err) - } - if response.Error != "" { - return api.CanNodeUnstakeRplResponse{}, fmt.Errorf("Could not get can node unstake RPL status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeUnstakeRplResponse]("GET", "/api/node/can-unstake-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not get can node unstake RPL status") } // Unstake RPL staked against the node func (c *Client) NodeUnstakeRpl(amountWei *big.Int) (api.NodeUnstakeRplResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/unstake-rpl", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeUnstakeRplResponse{}, fmt.Errorf("Could not unstake node RPL: %w", err) - } - var response api.NodeUnstakeRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeUnstakeRplResponse{}, fmt.Errorf("Could not decode unstake node RPL response: %w", err) - } - if response.Error != "" { - return api.NodeUnstakeRplResponse{}, fmt.Errorf("Could not unstake node RPL: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeUnstakeRplResponse]("POST", "/api/node/unstake-rpl", url.Values{"amountWei": {amountWei.String()}}, "Could not unstake node RPL") } // Check whether we can withdraw ETH staked on behalf of the node func (c *Client) CanNodeWithdrawEth(amountWei *big.Int) (api.CanNodeWithdrawEthResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-withdraw-eth", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanNodeWithdrawEthResponse{}, fmt.Errorf("Could not get can node withdraw ETH status: %w", err) - } - var response api.CanNodeWithdrawEthResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeWithdrawEthResponse{}, fmt.Errorf("Could not decode can node withdraw ETH response: %w", err) - } - if response.Error != "" { - return api.CanNodeWithdrawEthResponse{}, fmt.Errorf("Could not get can node withdraw ETH status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeWithdrawEthResponse]("GET", "/api/node/can-withdraw-eth", url.Values{"amountWei": {amountWei.String()}}, "Could not get can node withdraw ETH status") } // Withdraw ETH staked on behalf of the node func (c *Client) NodeWithdrawEth(amountWei *big.Int) (api.NodeWithdrawEthResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/withdraw-eth", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeWithdrawEthResponse{}, fmt.Errorf("Could not withdraw node ETH: %w", err) - } - var response api.NodeWithdrawEthResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeWithdrawEthResponse{}, fmt.Errorf("Could not decode withdraw node ETH response: %w", err) - } - if response.Error != "" { - return api.NodeWithdrawEthResponse{}, fmt.Errorf("Could not withdraw node ETH: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeWithdrawEthResponse]("POST", "/api/node/withdraw-eth", url.Values{"amountWei": {amountWei.String()}}, "Could not withdraw node ETH") } // Check whether we can withdraw credit from the node func (c *Client) CanNodeWithdrawCredit(amountWei *big.Int) (api.CanNodeWithdrawCreditResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-withdraw-credit", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.CanNodeWithdrawCreditResponse{}, fmt.Errorf("Could not get can node withdraw credit status: %w", err) - } - var response api.CanNodeWithdrawCreditResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeWithdrawCreditResponse{}, fmt.Errorf("Could not decode can node withdraw credit response: %w", err) - } - if response.Error != "" { - return api.CanNodeWithdrawCreditResponse{}, fmt.Errorf("Could not get can node withdraw credit status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeWithdrawCreditResponse]("GET", "/api/node/can-withdraw-credit", url.Values{"amountWei": {amountWei.String()}}, "Could not get can node withdraw credit status") } // Withdraw credit from the node as rETH func (c *Client) NodeWithdrawCredit(amountWei *big.Int) (api.NodeWithdrawCreditResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/withdraw-credit", url.Values{"amountWei": {amountWei.String()}}) - if err != nil { - return api.NodeWithdrawCreditResponse{}, fmt.Errorf("Could not withdraw credit: %w", err) - } - var response api.NodeWithdrawCreditResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeWithdrawCreditResponse{}, fmt.Errorf("Could not decode withdraw credit response: %w", err) - } - if response.Error != "" { - return api.NodeWithdrawCreditResponse{}, fmt.Errorf("Could not withdraw credit: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeWithdrawCreditResponse]("POST", "/api/node/withdraw-credit", url.Values{"amountWei": {amountWei.String()}}, "Could not withdraw credit") } // Check whether the node can make multiple deposits func (c *Client) CanNodeDeposits(count uint64, amountWei *big.Int, minFee float64, salt *big.Int, expressTickets uint64) (api.CanNodeDepositsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-deposit", url.Values{ + return c.callAPI[api.CanNodeDepositsResponse]("GET", "/api/node/can-deposit", url.Values{ "count": {strconv.FormatUint(count, 10)}, "amountWei": {amountWei.String()}, "minFee": {strconv.FormatFloat(minFee, 'f', -1, 64)}, "salt": {salt.String()}, "expressTickets": {strconv.FormatUint(expressTickets, 10)}, - }) - if err != nil { - return api.CanNodeDepositsResponse{}, fmt.Errorf("Could not get can node deposits status: %w", err) - } - var response api.CanNodeDepositsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeDepositsResponse{}, fmt.Errorf("Could not decode can node deposits response: %w", err) - } - if response.Error != "" { - return api.CanNodeDepositsResponse{}, fmt.Errorf("Could not get can node deposits status: %s", response.Error) - } - return response, nil + }, "Could not get can node deposits status") } // Make multiple node deposits func (c *Client) NodeDeposits(count uint64, amountWei *big.Int, minFee float64, salt *big.Int, useCreditBalance bool, expressTickets uint64, submit bool) (api.NodeDepositsResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/deposit", url.Values{ + return c.callAPI[api.NodeDepositsResponse]("POST", "/api/node/deposit", url.Values{ "count": {strconv.FormatUint(count, 10)}, "amountWei": {amountWei.String()}, "minFee": {strconv.FormatFloat(minFee, 'f', -1, 64)}, @@ -780,292 +309,105 @@ func (c *Client) NodeDeposits(count uint64, amountWei *big.Int, minFee float64, "expressTickets": {strconv.FormatUint(expressTickets, 10)}, "useCreditBalance": {strconv.FormatBool(useCreditBalance)}, "submit": {strconv.FormatBool(submit)}, - }) - if err != nil { - return api.NodeDepositsResponse{}, fmt.Errorf("Could not make node deposits: %w", err) - } - var response api.NodeDepositsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeDepositsResponse{}, fmt.Errorf("Could not decode node deposits response: %w", err) - } - if response.Error != "" { - return api.NodeDepositsResponse{}, fmt.Errorf("Could not make node deposits: %s", response.Error) - } - return response, nil + }, "Could not make node deposits") } // Check whether the node can send tokens func (c *Client) CanNodeSend(amountRaw float64, token string, toAddress common.Address) (api.CanNodeSendResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-send", url.Values{ + return c.callAPI[api.CanNodeSendResponse]("GET", "/api/node/can-send", url.Values{ "amountRaw": {strconv.FormatFloat(amountRaw, 'f', 10, 64)}, "token": {token}, "to": {toAddress.Hex()}, - }) - if err != nil { - return api.CanNodeSendResponse{}, fmt.Errorf("Could not get can node send status: %w", err) - } - var response api.CanNodeSendResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeSendResponse{}, fmt.Errorf("Could not decode can node send response: %w", err) - } - if response.Error != "" { - return api.CanNodeSendResponse{}, fmt.Errorf("Could not get can node send status: %s", response.Error) - } - return response, nil + }, "Could not get can node send status") } // Send tokens from the node to an address func (c *Client) NodeSend(amountRaw float64, token string, toAddress common.Address) (api.NodeSendResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/send", url.Values{ + return c.callAPI[api.NodeSendResponse]("POST", "/api/node/send", url.Values{ "amountRaw": {strconv.FormatFloat(amountRaw, 'f', 10, 64)}, "token": {token}, "to": {toAddress.Hex()}, - }) - if err != nil { - return api.NodeSendResponse{}, fmt.Errorf("Could not send tokens from node: %w", err) - } - var response api.NodeSendResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSendResponse{}, fmt.Errorf("Could not decode node send response: %w", err) - } - if response.Error != "" { - return api.NodeSendResponse{}, fmt.Errorf("Could not send tokens from node: %s", response.Error) - } - return response, nil + }, "Could not send tokens from node") } // Send all tokens of the given type from the node to an address. // Uses the exact on-chain *big.Int balance to avoid float64 rounding errors. func (c *Client) NodeSendAll(token string, toAddress common.Address) (api.NodeSendResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/send-all", url.Values{ + return c.callAPI[api.NodeSendResponse]("POST", "/api/node/send-all", url.Values{ "token": {token}, "to": {toAddress.Hex()}, - }) - if err != nil { - return api.NodeSendResponse{}, fmt.Errorf("Could not send tokens from node: %w", err) - } - var response api.NodeSendResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSendResponse{}, fmt.Errorf("Could not decode node send-all response: %w", err) - } - if response.Error != "" { - return api.NodeSendResponse{}, fmt.Errorf("Could not send tokens from node: %s", response.Error) - } - return response, nil + }, "Could not send tokens from node") } // Check whether the node can burn tokens func (c *Client) CanNodeBurn(amountWei *big.Int, token string) (api.CanNodeBurnResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-burn", url.Values{ + return c.callAPI[api.CanNodeBurnResponse]("GET", "/api/node/can-burn", url.Values{ "amountWei": {amountWei.String()}, "token": {token}, - }) - if err != nil { - return api.CanNodeBurnResponse{}, fmt.Errorf("Could not get can node burn status: %w", err) - } - var response api.CanNodeBurnResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeBurnResponse{}, fmt.Errorf("Could not decode can node burn response: %w", err) - } - if response.Error != "" { - return api.CanNodeBurnResponse{}, fmt.Errorf("Could not get can node burn status: %s", response.Error) - } - return response, nil + }, "Could not get can node burn status") } // Burn tokens owned by the node for ETH func (c *Client) NodeBurn(amountWei *big.Int, token string) (api.NodeBurnResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/burn", url.Values{ + return c.callAPI[api.NodeBurnResponse]("POST", "/api/node/burn", url.Values{ "amountWei": {amountWei.String()}, "token": {token}, - }) - if err != nil { - return api.NodeBurnResponse{}, fmt.Errorf("Could not burn tokens owned by node: %w", err) - } - var response api.NodeBurnResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeBurnResponse{}, fmt.Errorf("Could not decode node burn response: %w", err) - } - if response.Error != "" { - return api.NodeBurnResponse{}, fmt.Errorf("Could not burn tokens owned by node: %s", response.Error) - } - return response, nil + }, "Could not burn tokens owned by node") } // Get node sync progress func (c *Client) NodeSync() (api.NodeSyncProgressResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/sync", nil) - if err != nil { - return api.NodeSyncProgressResponse{}, fmt.Errorf("Could not get node sync: %w", err) - } - var response api.NodeSyncProgressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSyncProgressResponse{}, fmt.Errorf("Could not decode node sync response: %w", err) - } - if response.Error != "" { - return api.NodeSyncProgressResponse{}, fmt.Errorf("Could not get node sync: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeSyncProgressResponse]("GET", "/api/node/sync", nil, "Could not get node sync") } // Check whether the node has RPL rewards available to claim func (c *Client) CanNodeClaimRpl() (api.CanNodeClaimRplResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-claim-rpl-rewards", nil) - if err != nil { - return api.CanNodeClaimRplResponse{}, fmt.Errorf("Could not get can node claim rpl rewards status: %w", err) - } - var response api.CanNodeClaimRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeClaimRplResponse{}, fmt.Errorf("Could not decode can node claim rpl rewards response: %w", err) - } - if response.Error != "" { - return api.CanNodeClaimRplResponse{}, fmt.Errorf("Could not get can node claim rpl rewards status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeClaimRplResponse]("GET", "/api/node/can-claim-rpl-rewards", nil, "Could not get can node claim rpl rewards status") } // Claim available RPL rewards func (c *Client) NodeClaimRpl() (api.NodeClaimRplResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/claim-rpl-rewards", nil) - if err != nil { - return api.NodeClaimRplResponse{}, fmt.Errorf("Could not claim rpl rewards: %w", err) - } - var response api.NodeClaimRplResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeClaimRplResponse{}, fmt.Errorf("Could not decode node claim rpl rewards response: %w", err) - } - if response.Error != "" { - return api.NodeClaimRplResponse{}, fmt.Errorf("Could not claim rpl rewards: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeClaimRplResponse]("POST", "/api/node/claim-rpl-rewards", nil, "Could not claim rpl rewards") } // Get node RPL rewards status func (c *Client) NodeRewards() (api.NodeRewardsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/rewards", nil) - if err != nil { - return api.NodeRewardsResponse{}, fmt.Errorf("Could not get node rewards: %w", err) - } - var response api.NodeRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeRewardsResponse{}, fmt.Errorf("Could not decode node rewards response: %w", err) - } - if response.Error != "" { - return api.NodeRewardsResponse{}, fmt.Errorf("Could not get node rewards: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeRewardsResponse]("GET", "/api/node/rewards", nil, "Could not get node rewards") } // Get the deposit contract info for Rocket Pool and the Beacon Client func (c *Client) DepositContractInfo() (api.DepositContractInfoResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/deposit-contract-info", nil) - if err != nil { - return api.DepositContractInfoResponse{}, fmt.Errorf("Could not get deposit contract info: %w", err) - } - var response api.DepositContractInfoResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.DepositContractInfoResponse{}, fmt.Errorf("Could not decode deposit contract info response: %w", err) - } - if response.Error != "" { - return api.DepositContractInfoResponse{}, fmt.Errorf("Could not get deposit contract info: %s", response.Error) - } - return response, nil + return c.callAPI[api.DepositContractInfoResponse]("GET", "/api/node/deposit-contract-info", nil, "Could not get deposit contract info") } // Get the initialization status of the fee distributor contract func (c *Client) IsFeeDistributorInitialized() (api.NodeIsFeeDistributorInitializedResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/is-fee-distributor-initialized", nil) - if err != nil { - return api.NodeIsFeeDistributorInitializedResponse{}, fmt.Errorf("Could not get fee distributor initialization status: %w", err) - } - var response api.NodeIsFeeDistributorInitializedResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeIsFeeDistributorInitializedResponse{}, fmt.Errorf("Could not decode fee distributor initialization status response: %w", err) - } - if response.Error != "" { - return api.NodeIsFeeDistributorInitializedResponse{}, fmt.Errorf("Could not get fee distributor initialization status: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeIsFeeDistributorInitializedResponse]("GET", "/api/node/is-fee-distributor-initialized", nil, "Could not get fee distributor initialization status") } // Get the gas cost for initializing the fee distributor contract func (c *Client) GetInitializeFeeDistributorGas() (api.NodeInitializeFeeDistributorGasResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-initialize-fee-distributor-gas", nil) - if err != nil { - return api.NodeInitializeFeeDistributorGasResponse{}, fmt.Errorf("Could not get initialize fee distributor gas: %w", err) - } - var response api.NodeInitializeFeeDistributorGasResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeInitializeFeeDistributorGasResponse{}, fmt.Errorf("Could not decode initialize fee distributor gas response: %w", err) - } - if response.Error != "" { - return api.NodeInitializeFeeDistributorGasResponse{}, fmt.Errorf("Could not get initialize fee distributor gas: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeInitializeFeeDistributorGasResponse]("GET", "/api/node/get-initialize-fee-distributor-gas", nil, "Could not get initialize fee distributor gas") } // Initialize the fee distributor contract func (c *Client) InitializeFeeDistributor() (api.NodeInitializeFeeDistributorResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/initialize-fee-distributor", nil) - if err != nil { - return api.NodeInitializeFeeDistributorResponse{}, fmt.Errorf("Could not initialize fee distributor: %w", err) - } - var response api.NodeInitializeFeeDistributorResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeInitializeFeeDistributorResponse{}, fmt.Errorf("Could not decode initialize fee distributor response: %w", err) - } - if response.Error != "" { - return api.NodeInitializeFeeDistributorResponse{}, fmt.Errorf("Could not initialize fee distributor: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeInitializeFeeDistributorResponse]("POST", "/api/node/initialize-fee-distributor", nil, "Could not initialize fee distributor") } // Check if distributing ETH from the node's fee distributor is possible func (c *Client) CanDistribute() (api.NodeCanDistributeResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-distribute", nil) - if err != nil { - return api.NodeCanDistributeResponse{}, fmt.Errorf("Could not get can distribute: %w", err) - } - var response api.NodeCanDistributeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeCanDistributeResponse{}, fmt.Errorf("Could not decode can distribute response: %w", err) - } - if response.Error != "" { - return api.NodeCanDistributeResponse{}, fmt.Errorf("Could not get can distribute: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeCanDistributeResponse]("GET", "/api/node/can-distribute", nil, "Could not get can distribute") } // Distribute ETH from the node's fee distributor func (c *Client) Distribute() (api.NodeDistributeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/distribute", nil) - if err != nil { - return api.NodeDistributeResponse{}, fmt.Errorf("Could not distribute ETH: %w", err) - } - var response api.NodeDistributeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeDistributeResponse{}, fmt.Errorf("Could not decode distribute response: %w", err) - } - if response.Error != "" { - return api.NodeDistributeResponse{}, fmt.Errorf("Could not distribute ETH: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeDistributeResponse]("POST", "/api/node/distribute", nil, "Could not distribute ETH") } // Get info about your eligible rewards periods, including balances and Merkle proofs func (c *Client) GetRewardsInfo() (api.NodeGetRewardsInfoResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-rewards-info", nil) - if err != nil { - return api.NodeGetRewardsInfoResponse{}, fmt.Errorf("Could not get rewards info: %w", err) - } - var response api.NodeGetRewardsInfoResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeGetRewardsInfoResponse{}, fmt.Errorf("Could not decode get rewards info response: %w", err) - } - if response.Error != "" { - return api.NodeGetRewardsInfoResponse{}, fmt.Errorf("Could not get rewards info: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeGetRewardsInfoResponse]("GET", "/api/node/get-rewards-info", nil, "Could not get rewards info") } // Check if the rewards for the given intervals can be claimed @@ -1074,18 +416,7 @@ func (c *Client) CanNodeClaimRewards(indices []uint64) (api.CanNodeClaimRewardsR for i, idx := range indices { indexStrings[i] = strconv.FormatUint(idx, 10) } - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-claim-rewards", url.Values{"indices": {strings.Join(indexStrings, ",")}}) - if err != nil { - return api.CanNodeClaimRewardsResponse{}, fmt.Errorf("Could not check if can claim rewards: %w", err) - } - var response api.CanNodeClaimRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeClaimRewardsResponse{}, fmt.Errorf("Could not decode can claim rewards response: %w", err) - } - if response.Error != "" { - return api.CanNodeClaimRewardsResponse{}, fmt.Errorf("Could not check if can claim rewards: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanNodeClaimRewardsResponse]("GET", "/api/node/can-claim-rewards", url.Values{"indices": {strings.Join(indexStrings, ",")}}, "Could not check if can claim rewards") } // Claim rewards for the given reward intervals @@ -1094,18 +425,7 @@ func (c *Client) NodeClaimRewards(indices []uint64) (api.NodeClaimRewardsRespons for i, idx := range indices { indexStrings[i] = strconv.FormatUint(idx, 10) } - responseBytes, err := c.callHTTPAPI("POST", "/api/node/claim-rewards", url.Values{"indices": {strings.Join(indexStrings, ",")}}) - if err != nil { - return api.NodeClaimRewardsResponse{}, fmt.Errorf("Could not claim rewards: %w", err) - } - var response api.NodeClaimRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeClaimRewardsResponse{}, fmt.Errorf("Could not decode claim rewards response: %w", err) - } - if response.Error != "" { - return api.NodeClaimRewardsResponse{}, fmt.Errorf("Could not claim rewards: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeClaimRewardsResponse]("POST", "/api/node/claim-rewards", url.Values{"indices": {strings.Join(indexStrings, ",")}}, "Could not claim rewards") } // Check if the rewards for the given intervals can be claimed, and RPL restaked automatically @@ -1114,21 +434,10 @@ func (c *Client) CanNodeClaimAndStakeRewards(indices []uint64, stakeAmountWei *b for i, idx := range indices { indexStrings[i] = strconv.FormatUint(idx, 10) } - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-claim-and-stake-rewards", url.Values{ + return c.callAPI[api.CanNodeClaimAndStakeRewardsResponse]("GET", "/api/node/can-claim-and-stake-rewards", url.Values{ "indices": {strings.Join(indexStrings, ",")}, "stakeAmount": {stakeAmountWei.String()}, - }) - if err != nil { - return api.CanNodeClaimAndStakeRewardsResponse{}, fmt.Errorf("Could not check if can claim and stake rewards: %w", err) - } - var response api.CanNodeClaimAndStakeRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeClaimAndStakeRewardsResponse{}, fmt.Errorf("Could not decode can claim and stake rewards response: %w", err) - } - if response.Error != "" { - return api.CanNodeClaimAndStakeRewardsResponse{}, fmt.Errorf("Could not check if can claim and stake rewards: %s", response.Error) - } - return response, nil + }, "Could not check if can claim and stake rewards") } // Claim rewards for the given reward intervals and restake RPL automatically @@ -1137,291 +446,95 @@ func (c *Client) NodeClaimAndStakeRewards(indices []uint64, stakeAmountWei *big. for i, idx := range indices { indexStrings[i] = strconv.FormatUint(idx, 10) } - responseBytes, err := c.callHTTPAPI("POST", "/api/node/claim-and-stake-rewards", url.Values{ + return c.callAPI[api.NodeClaimAndStakeRewardsResponse]("POST", "/api/node/claim-and-stake-rewards", url.Values{ "indices": {strings.Join(indexStrings, ",")}, "stakeAmount": {stakeAmountWei.String()}, - }) - if err != nil { - return api.NodeClaimAndStakeRewardsResponse{}, fmt.Errorf("Could not claim and stake rewards: %w", err) - } - var response api.NodeClaimAndStakeRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeClaimAndStakeRewardsResponse{}, fmt.Errorf("Could not decode claim and stake rewards response: %w", err) - } - if response.Error != "" { - return api.NodeClaimAndStakeRewardsResponse{}, fmt.Errorf("Could not claim and stake rewards: %s", response.Error) - } - return response, nil + }, "Could not claim and stake rewards") } // Check whether or not the node is opted into the Smoothing Pool func (c *Client) NodeGetSmoothingPoolRegistrationStatus() (api.GetSmoothingPoolRegistrationStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-smoothing-pool-registration-status", nil) - if err != nil { - return api.GetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not get smoothing pool registration status: %w", err) - } - var response api.GetSmoothingPoolRegistrationStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not decode smoothing pool registration status response: %w", err) - } - if response.Error != "" { - return api.GetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not get smoothing pool registration status: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetSmoothingPoolRegistrationStatusResponse]("GET", "/api/node/get-smoothing-pool-registration-status", nil, "Could not get smoothing pool registration status") } // Check if the node's Smoothing Pool status can be changed func (c *Client) CanNodeSetSmoothingPoolStatus(status bool) (api.CanSetSmoothingPoolRegistrationStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-set-smoothing-pool-status", url.Values{"status": {strconv.FormatBool(status)}}) - if err != nil { - return api.CanSetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not get can-set-smoothing-pool-status: %w", err) - } - var response api.CanSetSmoothingPoolRegistrationStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanSetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not decode can-set-smoothing-pool-status response: %w", err) - } - if response.Error != "" { - return api.CanSetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not get can-set-smoothing-pool-status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanSetSmoothingPoolRegistrationStatusResponse]("GET", "/api/node/can-set-smoothing-pool-status", url.Values{"status": {strconv.FormatBool(status)}}, "Could not get can-set-smoothing-pool-status") } // Sets the node's Smoothing Pool opt-in status func (c *Client) NodeSetSmoothingPoolStatus(status bool) (api.SetSmoothingPoolRegistrationStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/set-smoothing-pool-status", url.Values{"status": {strconv.FormatBool(status)}}) - if err != nil { - return api.SetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not set smoothing pool status: %w", err) - } - var response api.SetSmoothingPoolRegistrationStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not decode set-smoothing-pool-status response: %w", err) - } - if response.Error != "" { - return api.SetSmoothingPoolRegistrationStatusResponse{}, fmt.Errorf("Could not set smoothing pool status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetSmoothingPoolRegistrationStatusResponse]("POST", "/api/node/set-smoothing-pool-status", url.Values{"status": {strconv.FormatBool(status)}}, "Could not set smoothing pool status") } func (c *Client) ResolveEnsName(name string) (api.ResolveEnsNameResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/resolve-ens-name", url.Values{"name": {name}}) - if err != nil { - return api.ResolveEnsNameResponse{}, fmt.Errorf("Could not resolve ENS name: %w", err) - } - var response api.ResolveEnsNameResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ResolveEnsNameResponse{}, fmt.Errorf("Could not decode resolve-ens-name: %w", err) - } - if response.Error != "" { - return api.ResolveEnsNameResponse{}, fmt.Errorf("Could not resolve ENS name: %s", response.Error) - } - return response, nil + return c.callAPI[api.ResolveEnsNameResponse]("GET", "/api/node/resolve-ens-name", url.Values{"name": {name}}, "Could not resolve ENS name") } func (c *Client) ReverseResolveEnsName(name string) (api.ResolveEnsNameResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/reverse-resolve-ens-name", url.Values{"address": {name}}) - if err != nil { - return api.ResolveEnsNameResponse{}, fmt.Errorf("Could not reverse resolve ENS name: %w", err) - } - var response api.ResolveEnsNameResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ResolveEnsNameResponse{}, fmt.Errorf("Could not decode reverse-resolve-ens-name: %w", err) - } - if response.Error != "" { - return api.ResolveEnsNameResponse{}, fmt.Errorf("Could not reverse resolve ENS name: %s", response.Error) - } - return response, nil + return c.callAPI[api.ResolveEnsNameResponse]("GET", "/api/node/reverse-resolve-ens-name", url.Values{"address": {name}}, "Could not reverse resolve ENS name") } // Use the node private key to sign an arbitrary message func (c *Client) SignMessage(message string) (api.NodeSignResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/sign-message", url.Values{"message": {message}}) - if err != nil { - return api.NodeSignResponse{}, fmt.Errorf("Could not sign message: %w", err) - } - - var response api.NodeSignResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSignResponse{}, fmt.Errorf("Could not decode node sign response: %w", err) - } - if response.Error != "" { - return api.NodeSignResponse{}, fmt.Errorf("Could not sign message: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeSignResponse]("POST", "/api/node/sign-message", url.Values{"message": {message}}, "Could not sign message") } // Get the node's collateral info, including pending bond reductions func (c *Client) CheckCollateral() (api.CheckCollateralResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/check-collateral", nil) - if err != nil { - return api.CheckCollateralResponse{}, fmt.Errorf("Could not get check-collateral status: %w", err) - } - var response api.CheckCollateralResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CheckCollateralResponse{}, fmt.Errorf("Could not decode check-collateral response: %w", err) - } - if response.Error != "" { - return api.CheckCollateralResponse{}, fmt.Errorf("Could not get check-collateral status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CheckCollateralResponse]("GET", "/api/node/check-collateral", nil, "Could not get check-collateral status") } // Get the ETH balance of the node address func (c *Client) GetEthBalance() (api.NodeEthBalanceResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-eth-balance", nil) - if err != nil { - return api.NodeEthBalanceResponse{}, fmt.Errorf("Could not get get-eth-balance status: %w", err) - } - var response api.NodeEthBalanceResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeEthBalanceResponse{}, fmt.Errorf("Could not decode get-eth-balance response: %w", err) - } - if response.Error != "" { - return api.NodeEthBalanceResponse{}, fmt.Errorf("Could not get get-eth-balance status: %s", response.Error) - } - return response, nil + return c.callAPI[api.NodeEthBalanceResponse]("GET", "/api/node/get-eth-balance", nil, "Could not get get-eth-balance status") } // Estimates the gas for sending a zero-value message with a payload func (c *Client) CanSendMessage(address common.Address, message []byte) (api.CanNodeSendMessageResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-send-message", url.Values{ + return c.callAPI[api.CanNodeSendMessageResponse]("GET", "/api/node/can-send-message", url.Values{ "address": {address.Hex()}, "message": {hex.EncodeToString(message)}, - }) - if err != nil { - return api.CanNodeSendMessageResponse{}, fmt.Errorf("Could not get can-send-message response: %w", err) - } - var response api.CanNodeSendMessageResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanNodeSendMessageResponse{}, fmt.Errorf("Could not decode can-send-message response: %w", err) - } - if response.Error != "" { - return api.CanNodeSendMessageResponse{}, fmt.Errorf("Could not get can-send-message response: %s", response.Error) - } - return response, nil + }, "Could not get can-send-message response") } // Sends a zero-value message with a payload func (c *Client) SendMessage(address common.Address, message []byte) (api.NodeSendMessageResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/send-message", url.Values{ + return c.callAPI[api.NodeSendMessageResponse]("POST", "/api/node/send-message", url.Values{ "address": {address.Hex()}, "message": {hex.EncodeToString(message)}, - }) - if err != nil { - return api.NodeSendMessageResponse{}, fmt.Errorf("Could not get send-message response: %w", err) - } - var response api.NodeSendMessageResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.NodeSendMessageResponse{}, fmt.Errorf("Could not decode send-message response: %w", err) - } - if response.Error != "" { - return api.NodeSendMessageResponse{}, fmt.Errorf("Could not get send-message response: %s", response.Error) - } - return response, nil + }, "Could not get send-message response") } // Get the number of express tickets available for the node func (c *Client) GetExpressTicketCount() (api.GetExpressTicketCountResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-express-ticket-count", nil) - if err != nil { - return api.GetExpressTicketCountResponse{}, fmt.Errorf("Could not get express ticket count: %w", err) - } - var response api.GetExpressTicketCountResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetExpressTicketCountResponse{}, fmt.Errorf("Could not decode express ticket count response: %w", err) - } - if response.Error != "" { - return api.GetExpressTicketCountResponse{}, fmt.Errorf("Could not get express ticket count: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetExpressTicketCountResponse]("GET", "/api/node/get-express-ticket-count", nil, "Could not get express ticket count") } // Check if the node's express tickets have been provisioned func (c *Client) GetExpressTicketsProvisioned() (api.GetExpressTicketsProvisionedResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-express-tickets-provisioned", nil) - if err != nil { - return api.GetExpressTicketsProvisionedResponse{}, fmt.Errorf("Could not get express tickets provisioned: %w", err) - } - var response api.GetExpressTicketsProvisionedResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetExpressTicketsProvisionedResponse{}, fmt.Errorf("Could not decode express ticket count response: %w", err) - } - if response.Error != "" { - return api.GetExpressTicketsProvisionedResponse{}, fmt.Errorf("Could not get express ticket count: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetExpressTicketsProvisionedResponse]("GET", "/api/node/get-express-tickets-provisioned", nil, "Could not get express tickets provisioned") } func (c *Client) CanProvisionExpressTickets() (api.CanProvisionExpressTicketsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-provision-express-tickets", nil) - if err != nil { - return api.CanProvisionExpressTicketsResponse{}, fmt.Errorf("Could not get can-provision-express-tickets response: %w", err) - } - var response api.CanProvisionExpressTicketsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProvisionExpressTicketsResponse{}, fmt.Errorf("Could not decode can-provision-express-tickets response: %w", err) - } - if response.Error != "" { - return api.CanProvisionExpressTicketsResponse{}, fmt.Errorf("Could not get can-provision-express-tickets response: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProvisionExpressTicketsResponse]("GET", "/api/node/can-provision-express-tickets", nil, "Could not get can-provision-express-tickets response") } func (c *Client) ProvisionExpressTickets() (api.ProvisionExpressTicketsResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/provision-express-tickets", nil) - if err != nil { - return api.ProvisionExpressTicketsResponse{}, fmt.Errorf("Could not get provision-express-tickets response: %w", err) - } - var response api.ProvisionExpressTicketsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProvisionExpressTicketsResponse{}, fmt.Errorf("Could not decode provision-express-tickets response: %w", err) - } - if response.Error != "" { - return api.ProvisionExpressTicketsResponse{}, fmt.Errorf("Could not get provision-express-tickets response: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProvisionExpressTicketsResponse]("POST", "/api/node/provision-express-tickets", nil, "Could not get provision-express-tickets response") } // Check whether the node can claim unclaimed rewards func (c *Client) CanClaimUnclaimedRewards(nodeAddress common.Address) (api.CanClaimUnclaimedRewardsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/can-claim-unclaimed-rewards", url.Values{"nodeAddress": {nodeAddress.Hex()}}) - if err != nil { - return api.CanClaimUnclaimedRewardsResponse{}, fmt.Errorf("Could not get can-claim-unclaimed-rewards response: %w", err) - } - var response api.CanClaimUnclaimedRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanClaimUnclaimedRewardsResponse{}, fmt.Errorf("Could not decode can-claim-unclaimed-rewards response: %w", err) - } - if response.Error != "" { - return api.CanClaimUnclaimedRewardsResponse{}, fmt.Errorf("Could not get can-claim-unclaimed-rewards response: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanClaimUnclaimedRewardsResponse]("GET", "/api/node/can-claim-unclaimed-rewards", url.Values{"nodeAddress": {nodeAddress.Hex()}}, "Could not get can-claim-unclaimed-rewards response") } // Send unclaimed rewards to a node operator's withdrawal address func (c *Client) ClaimUnclaimedRewards(nodeAddress common.Address) (api.ClaimUnclaimedRewardsResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/node/claim-unclaimed-rewards", url.Values{"nodeAddress": {nodeAddress.Hex()}}) - if err != nil { - return api.ClaimUnclaimedRewardsResponse{}, fmt.Errorf("Could not get claim-unclaimed-rewards response: %w", err) - } - var response api.ClaimUnclaimedRewardsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ClaimUnclaimedRewardsResponse{}, fmt.Errorf("Could not decode claim-unclaimed-rewards response: %w", err) - } - if response.Error != "" { - return api.ClaimUnclaimedRewardsResponse{}, fmt.Errorf("Could not get claim-unclaimed-rewards response: %s", response.Error) - } - return response, nil + return c.callAPI[api.ClaimUnclaimedRewardsResponse]("POST", "/api/node/claim-unclaimed-rewards", url.Values{"nodeAddress": {nodeAddress.Hex()}}, "Could not get claim-unclaimed-rewards response") } // Get the bond requirement for a number of validators func (c *Client) GetBondRequirement(numValidators uint64) (api.GetBondRequirementResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/node/get-bond-requirement", url.Values{"numValidators": {strconv.FormatUint(numValidators, 10)}}) - if err != nil { - return api.GetBondRequirementResponse{}, fmt.Errorf("Could not get get-bond-requirement response: %w", err) - } - var response api.GetBondRequirementResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetBondRequirementResponse{}, fmt.Errorf("Could not decode get-bond-requirement response: %w", err) - } - return response, nil + return c.callAPI[api.GetBondRequirementResponse]("GET", "/api/node/get-bond-requirement", url.Values{"numValidators": {strconv.FormatUint(numValidators, 10)}}, "Could not get get-bond-requirement response") } diff --git a/shared/services/rocketpool/odao.go b/shared/services/rocketpool/odao.go index 937d6c74f..b61ffc7f3 100644 --- a/shared/services/rocketpool/odao.go +++ b/shared/services/rocketpool/odao.go @@ -1,45 +1,25 @@ package rocketpool import ( - "fmt" "math/big" "net/url" "strconv" "github.com/ethereum/go-ethereum/common" - "github.com/goccy/go-json" "github.com/rocket-pool/smartnode/shared/types/api" ) // Get oracle DAO status func (c *Client) TNDAOStatus() (api.TNDAOStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/status", nil) - if err != nil { - return api.TNDAOStatusResponse{}, fmt.Errorf("Could not get oracle DAO status: %w", err) - } - var response api.TNDAOStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.TNDAOStatusResponse{}, fmt.Errorf("Could not decode oracle DAO stats response: %w", err) - } - if response.Error != "" { - return api.TNDAOStatusResponse{}, fmt.Errorf("Could not get oracle DAO status: %s", response.Error) - } - return response, nil + return c.callAPI[api.TNDAOStatusResponse]("GET", "/api/odao/status", nil, "Could not get oracle DAO status") } // Get oracle DAO members func (c *Client) TNDAOMembers() (api.TNDAOMembersResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/members", nil) + response, err := c.callAPI[api.TNDAOMembersResponse]("GET", "/api/odao/members", nil, "Could not get oracle DAO members") if err != nil { - return api.TNDAOMembersResponse{}, fmt.Errorf("Could not get oracle DAO members: %w", err) - } - var response api.TNDAOMembersResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.TNDAOMembersResponse{}, fmt.Errorf("Could not decode oracle DAO members response: %w", err) - } - if response.Error != "" { - return api.TNDAOMembersResponse{}, fmt.Errorf("Could not get oracle DAO members: %s", response.Error) + return response, err } for i := 0; i < len(response.Members); i++ { member := &response.Members[i] @@ -52,192 +32,71 @@ func (c *Client) TNDAOMembers() (api.TNDAOMembersResponse, error) { // Get oracle DAO proposals func (c *Client) TNDAOProposals() (api.TNDAOProposalsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/proposals", nil) - if err != nil { - return api.TNDAOProposalsResponse{}, fmt.Errorf("Could not get oracle DAO proposals: %w", err) - } - var response api.TNDAOProposalsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.TNDAOProposalsResponse{}, fmt.Errorf("Could not decode oracle DAO proposals response: %w", err) - } - if response.Error != "" { - return api.TNDAOProposalsResponse{}, fmt.Errorf("Could not get oracle DAO proposals: %s", response.Error) - } - return response, nil + return c.callAPI[api.TNDAOProposalsResponse]("GET", "/api/odao/proposals", nil, "Could not get oracle DAO proposals") } // Get a single oracle DAO proposal func (c *Client) TNDAOProposal(id uint64) (api.TNDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/proposal-details", url.Values{"id": {strconv.FormatUint(id, 10)}}) - if err != nil { - return api.TNDAOProposalResponse{}, fmt.Errorf("Could not get oracle DAO proposal: %w", err) - } - var response api.TNDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.TNDAOProposalResponse{}, fmt.Errorf("Could not decode oracle DAO proposal response: %w", err) - } - if response.Error != "" { - return api.TNDAOProposalResponse{}, fmt.Errorf("Could not get oracle DAO proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.TNDAOProposalResponse]("GET", "/api/odao/proposal-details", url.Values{"id": {strconv.FormatUint(id, 10)}}, "Could not get oracle DAO proposal") } // Check whether the node can propose inviting a new member func (c *Client) CanProposeInviteToTNDAO(memberAddress common.Address, memberId, memberUrl string) (api.CanProposeTNDAOInviteResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-invite", url.Values{ + return c.callAPI[api.CanProposeTNDAOInviteResponse]("GET", "/api/odao/can-propose-invite", url.Values{ "address": {memberAddress.Hex()}, "memberId": {memberId}, "memberUrl": {memberUrl}, - }) - if err != nil { - return api.CanProposeTNDAOInviteResponse{}, fmt.Errorf("Could not get can propose oracle DAO invite status: %w", err) - } - var response api.CanProposeTNDAOInviteResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOInviteResponse{}, fmt.Errorf("Could not decode can propose oracle DAO invite response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOInviteResponse{}, fmt.Errorf("Could not get can propose oracle DAO invite status: %s", response.Error) - } - return response, nil + }, "Could not get can propose oracle DAO invite status") } // Propose inviting a new member func (c *Client) ProposeInviteToTNDAO(memberAddress common.Address, memberId, memberUrl string) (api.ProposeTNDAOInviteResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-invite", url.Values{ + return c.callAPI[api.ProposeTNDAOInviteResponse]("POST", "/api/odao/propose-invite", url.Values{ "address": {memberAddress.Hex()}, "memberId": {memberId}, "memberUrl": {memberUrl}, - }) - if err != nil { - return api.ProposeTNDAOInviteResponse{}, fmt.Errorf("Could not propose oracle DAO invite: %w", err) - } - var response api.ProposeTNDAOInviteResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOInviteResponse{}, fmt.Errorf("Could not decode propose oracle DAO invite response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOInviteResponse{}, fmt.Errorf("Could not propose oracle DAO invite: %s", response.Error) - } - return response, nil + }, "Could not propose oracle DAO invite") } // Check whether the node can propose leaving the oracle DAO func (c *Client) CanProposeLeaveTNDAO() (api.CanProposeTNDAOLeaveResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-leave", nil) - if err != nil { - return api.CanProposeTNDAOLeaveResponse{}, fmt.Errorf("Could not get can propose leaving oracle DAO status: %w", err) - } - var response api.CanProposeTNDAOLeaveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOLeaveResponse{}, fmt.Errorf("Could not decode can propose leaving oracle DAO response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOLeaveResponse{}, fmt.Errorf("Could not get can propose leaving oracle DAO status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOLeaveResponse]("GET", "/api/odao/can-propose-leave", nil, "Could not get can propose leaving oracle DAO status") } // Propose leaving the oracle DAO func (c *Client) ProposeLeaveTNDAO() (api.ProposeTNDAOLeaveResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-leave", nil) - if err != nil { - return api.ProposeTNDAOLeaveResponse{}, fmt.Errorf("Could not propose leaving oracle DAO: %w", err) - } - var response api.ProposeTNDAOLeaveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOLeaveResponse{}, fmt.Errorf("Could not decode propose leaving oracle DAO response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOLeaveResponse{}, fmt.Errorf("Could not propose leaving oracle DAO: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOLeaveResponse]("POST", "/api/odao/propose-leave", nil, "Could not propose leaving oracle DAO") } // Check whether the node can propose kicking a member func (c *Client) CanProposeKickFromTNDAO(memberAddress common.Address, fineAmountWei *big.Int) (api.CanProposeTNDAOKickResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-kick", url.Values{ + return c.callAPI[api.CanProposeTNDAOKickResponse]("GET", "/api/odao/can-propose-kick", url.Values{ "address": {memberAddress.Hex()}, "fineAmountWei": {fineAmountWei.String()}, - }) - if err != nil { - return api.CanProposeTNDAOKickResponse{}, fmt.Errorf("Could not get can propose kicking oracle DAO member status: %w", err) - } - var response api.CanProposeTNDAOKickResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOKickResponse{}, fmt.Errorf("Could not decode can propose kicking oracle DAO member response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOKickResponse{}, fmt.Errorf("Could not get can propose kicking oracle DAO member status: %s", response.Error) - } - return response, nil + }, "Could not get can propose kicking oracle DAO member status") } // Propose kicking a member func (c *Client) ProposeKickFromTNDAO(memberAddress common.Address, fineAmountWei *big.Int) (api.ProposeTNDAOKickResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-kick", url.Values{ + return c.callAPI[api.ProposeTNDAOKickResponse]("POST", "/api/odao/propose-kick", url.Values{ "address": {memberAddress.Hex()}, "fineAmountWei": {fineAmountWei.String()}, - }) - if err != nil { - return api.ProposeTNDAOKickResponse{}, fmt.Errorf("Could not propose kicking oracle DAO member: %w", err) - } - var response api.ProposeTNDAOKickResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOKickResponse{}, fmt.Errorf("Could not decode propose kicking oracle DAO member response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOKickResponse{}, fmt.Errorf("Could not propose kicking oracle DAO member: %s", response.Error) - } - return response, nil + }, "Could not propose kicking oracle DAO member") } // Check whether the node can cancel a proposal func (c *Client) CanCancelTNDAOProposal(proposalId uint64) (api.CanCancelTNDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-cancel-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}) - if err != nil { - return api.CanCancelTNDAOProposalResponse{}, fmt.Errorf("Could not get can cancel oracle DAO proposal status: %w", err) - } - var response api.CanCancelTNDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanCancelTNDAOProposalResponse{}, fmt.Errorf("Could not decode can cancel oracle DAO proposal response: %w", err) - } - if response.Error != "" { - return api.CanCancelTNDAOProposalResponse{}, fmt.Errorf("Could not get can cancel oracle DAO proposal status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanCancelTNDAOProposalResponse]("GET", "/api/odao/can-cancel-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}, "Could not get can cancel oracle DAO proposal status") } // Cancel a proposal made by the node func (c *Client) CancelTNDAOProposal(proposalId uint64) (api.CancelTNDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/cancel-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}) - if err != nil { - return api.CancelTNDAOProposalResponse{}, fmt.Errorf("Could not cancel oracle DAO proposal: %w", err) - } - var response api.CancelTNDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CancelTNDAOProposalResponse{}, fmt.Errorf("Could not decode cancel oracle DAO proposal response: %w", err) - } - if response.Error != "" { - return api.CancelTNDAOProposalResponse{}, fmt.Errorf("Could not cancel oracle DAO proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.CancelTNDAOProposalResponse]("POST", "/api/odao/cancel-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}, "Could not cancel oracle DAO proposal") } // Check whether the node can vote on a proposal func (c *Client) CanVoteOnTNDAOProposal(proposalId uint64) (api.CanVoteOnTNDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-vote-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}) - if err != nil { - return api.CanVoteOnTNDAOProposalResponse{}, fmt.Errorf("Could not get can vote on oracle DAO proposal status: %w", err) - } - var response api.CanVoteOnTNDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanVoteOnTNDAOProposalResponse{}, fmt.Errorf("Could not decode can vote on oracle DAO proposal response: %w", err) - } - if response.Error != "" { - return api.CanVoteOnTNDAOProposalResponse{}, fmt.Errorf("Could not get can vote on oracle DAO proposal status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanVoteOnTNDAOProposalResponse]("GET", "/api/odao/can-vote-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}, "Could not get can vote on oracle DAO proposal status") } // Vote on a proposal @@ -246,268 +105,81 @@ func (c *Client) VoteOnTNDAOProposal(proposalId uint64, support bool) (api.VoteO if support { supportStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/vote-proposal", url.Values{ + return c.callAPI[api.VoteOnTNDAOProposalResponse]("POST", "/api/odao/vote-proposal", url.Values{ "id": {strconv.FormatUint(proposalId, 10)}, "support": {supportStr}, - }) - if err != nil { - return api.VoteOnTNDAOProposalResponse{}, fmt.Errorf("Could not vote on oracle DAO proposal: %w", err) - } - var response api.VoteOnTNDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.VoteOnTNDAOProposalResponse{}, fmt.Errorf("Could not decode vote on oracle DAO proposal response: %w", err) - } - if response.Error != "" { - return api.VoteOnTNDAOProposalResponse{}, fmt.Errorf("Could not vote on oracle DAO proposal: %s", response.Error) - } - return response, nil + }, "Could not vote on oracle DAO proposal") } // Check whether the node can execute a proposal func (c *Client) CanExecuteTNDAOProposal(proposalId uint64) (api.CanExecuteTNDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-execute-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}) - if err != nil { - return api.CanExecuteTNDAOProposalResponse{}, fmt.Errorf("Could not get can execute oracle DAO proposal status: %w", err) - } - var response api.CanExecuteTNDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanExecuteTNDAOProposalResponse{}, fmt.Errorf("Could not decode can execute oracle DAO proposal response: %w", err) - } - if response.Error != "" { - return api.CanExecuteTNDAOProposalResponse{}, fmt.Errorf("Could not get can execute oracle DAO proposal status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanExecuteTNDAOProposalResponse]("GET", "/api/odao/can-execute-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}, "Could not get can execute oracle DAO proposal status") } // Execute a proposal func (c *Client) ExecuteTNDAOProposal(proposalId uint64) (api.ExecuteTNDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/execute-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}) - if err != nil { - return api.ExecuteTNDAOProposalResponse{}, fmt.Errorf("Could not execute oracle DAO proposal: %w", err) - } - var response api.ExecuteTNDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ExecuteTNDAOProposalResponse{}, fmt.Errorf("Could not decode execute oracle DAO proposal response: %w", err) - } - if response.Error != "" { - return api.ExecuteTNDAOProposalResponse{}, fmt.Errorf("Could not execute oracle DAO proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.ExecuteTNDAOProposalResponse]("POST", "/api/odao/execute-proposal", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}, "Could not execute oracle DAO proposal") } // Check whether the node can join the oracle DAO func (c *Client) CanJoinTNDAO() (api.CanJoinTNDAOResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-join", nil) - if err != nil { - return api.CanJoinTNDAOResponse{}, fmt.Errorf("Could not get can join oracle DAO status: %w", err) - } - var response api.CanJoinTNDAOResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanJoinTNDAOResponse{}, fmt.Errorf("Could not decode can join oracle DAO response: %w", err) - } - if response.Error != "" { - return api.CanJoinTNDAOResponse{}, fmt.Errorf("Could not get can join oracle DAO status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanJoinTNDAOResponse]("GET", "/api/odao/can-join", nil, "Could not get can join oracle DAO status") } // Approve RPL for joining the oracle DAO func (c *Client) ApproveRPLToJoinTNDAO() (api.JoinTNDAOApproveResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/join-approve-rpl", nil) - if err != nil { - return api.JoinTNDAOApproveResponse{}, fmt.Errorf("Could not approve RPL for joining oracle DAO: %w", err) - } - var response api.JoinTNDAOApproveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.JoinTNDAOApproveResponse{}, fmt.Errorf("Could not decode approve RPL for joining oracle DAO response: %w", err) - } - if response.Error != "" { - return api.JoinTNDAOApproveResponse{}, fmt.Errorf("Could not approve RPL for joining oracle DAO: %s", response.Error) - } - return response, nil + return c.callAPI[api.JoinTNDAOApproveResponse]("POST", "/api/odao/join-approve-rpl", nil, "Could not approve RPL for joining oracle DAO") } // Join the oracle DAO (requires an executed invite proposal) func (c *Client) JoinTNDAO(approvalTxHash common.Hash) (api.JoinTNDAOJoinResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/join", url.Values{"approvalTxHash": {approvalTxHash.String()}}) - if err != nil { - return api.JoinTNDAOJoinResponse{}, fmt.Errorf("Could not join oracle DAO: %w", err) - } - var response api.JoinTNDAOJoinResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.JoinTNDAOJoinResponse{}, fmt.Errorf("Could not decode join oracle DAO response: %w", err) - } - if response.Error != "" { - return api.JoinTNDAOJoinResponse{}, fmt.Errorf("Could not join oracle DAO: %s", response.Error) - } - return response, nil + return c.callAPI[api.JoinTNDAOJoinResponse]("POST", "/api/odao/join", url.Values{"approvalTxHash": {approvalTxHash.String()}}, "Could not join oracle DAO") } // Check whether the node can leave the oracle DAO func (c *Client) CanLeaveTNDAO() (api.CanLeaveTNDAOResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-leave", nil) - if err != nil { - return api.CanLeaveTNDAOResponse{}, fmt.Errorf("Could not get can leave oracle DAO status: %w", err) - } - var response api.CanLeaveTNDAOResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanLeaveTNDAOResponse{}, fmt.Errorf("Could not decode can leave oracle DAO response: %w", err) - } - if response.Error != "" { - return api.CanLeaveTNDAOResponse{}, fmt.Errorf("Could not get can leave oracle DAO status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanLeaveTNDAOResponse]("GET", "/api/odao/can-leave", nil, "Could not get can leave oracle DAO status") } // Leave the oracle DAO (requires an executed leave proposal) func (c *Client) LeaveTNDAO(bondRefundAddress common.Address) (api.LeaveTNDAOResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/leave", url.Values{"bondRefundAddress": {bondRefundAddress.Hex()}}) - if err != nil { - return api.LeaveTNDAOResponse{}, fmt.Errorf("Could not leave oracle DAO: %w", err) - } - var response api.LeaveTNDAOResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.LeaveTNDAOResponse{}, fmt.Errorf("Could not decode leave oracle DAO response: %w", err) - } - if response.Error != "" { - return api.LeaveTNDAOResponse{}, fmt.Errorf("Could not leave oracle DAO: %s", response.Error) - } - return response, nil + return c.callAPI[api.LeaveTNDAOResponse]("POST", "/api/odao/leave", url.Values{"bondRefundAddress": {bondRefundAddress.Hex()}}, "Could not leave oracle DAO") } func (c *Client) CanProposeTNDAOSettingMembersQuorum(quorum float64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-members-quorum", url.Values{"quorum": {strconv.FormatFloat(quorum, 'f', -1, 64)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting members.quorum: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting members.quorum response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting members.quorum: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-members-quorum", url.Values{"quorum": {strconv.FormatFloat(quorum, 'f', -1, 64)}}, "Could not get can propose setting members.quorum") } func (c *Client) CanProposeTNDAOSettingMembersRplBond(bondAmountWei *big.Int) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-members-rplbond", url.Values{"bondAmountWei": {bondAmountWei.String()}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting members.rplbond: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting members.rplbond response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting members.rplbond: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-members-rplbond", url.Values{"bondAmountWei": {bondAmountWei.String()}}, "Could not get can propose setting members.rplbond") } func (c *Client) CanProposeTNDAOSettingProposalCooldown(proposalCooldownTimespan uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-proposal-cooldown", url.Values{"value": {strconv.FormatUint(proposalCooldownTimespan, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.cooldown.time: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting proposal.cooldown.time response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.cooldown.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-proposal-cooldown", url.Values{"value": {strconv.FormatUint(proposalCooldownTimespan, 10)}}, "Could not get can propose setting proposal.cooldown.time") } func (c *Client) CanProposeTNDAOSettingProposalVoteTimespan(proposalVoteTimespan uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-proposal-vote-timespan", url.Values{"value": {strconv.FormatUint(proposalVoteTimespan, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.vote.time: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting proposal.vote.time response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.vote.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-proposal-vote-timespan", url.Values{"value": {strconv.FormatUint(proposalVoteTimespan, 10)}}, "Could not get can propose setting proposal.vote.time") } func (c *Client) CanProposeTNDAOSettingProposalVoteDelayTimespan(proposalDelayTimespan uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-proposal-vote-delay-timespan", url.Values{"value": {strconv.FormatUint(proposalDelayTimespan, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.vote.delay.time: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting proposal.vote.delay.time response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.vote.delay.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-proposal-vote-delay-timespan", url.Values{"value": {strconv.FormatUint(proposalDelayTimespan, 10)}}, "Could not get can propose setting proposal.vote.delay.time") } func (c *Client) CanProposeTNDAOSettingProposalExecuteTimespan(proposalExecuteTimespan uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-proposal-execute-timespan", url.Values{"value": {strconv.FormatUint(proposalExecuteTimespan, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.execute.time: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting proposal.execute.time response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.execute.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-proposal-execute-timespan", url.Values{"value": {strconv.FormatUint(proposalExecuteTimespan, 10)}}, "Could not get can propose setting proposal.execute.time") } func (c *Client) CanProposeTNDAOSettingProposalActionTimespan(proposalActionTimespan uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-proposal-action-timespan", url.Values{"value": {strconv.FormatUint(proposalActionTimespan, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.action.time: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting proposal.action.time response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting proposal.action.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-proposal-action-timespan", url.Values{"value": {strconv.FormatUint(proposalActionTimespan, 10)}}, "Could not get can propose setting proposal.action.time") } func (c *Client) CanProposeTNDAOSettingScrubPeriod(scrubPeriod uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.scrub.period: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting minipool.scrub.period response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.scrub.period: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}, "Could not get can propose setting minipool.scrub.period") } func (c *Client) CanProposeTNDAOSettingPromotionScrubPeriod(scrubPeriod uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-promotion-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.promotion.scrub.period: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting minipool.promotion.scrub.period response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.promotion.scrub.period: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-promotion-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}, "Could not get can propose setting minipool.promotion.scrub.period") } func (c *Client) CanProposeTNDAOSettingScrubPenaltyEnabled(enabled bool) (api.CanProposeTNDAOSettingResponse, error) { @@ -515,184 +187,52 @@ func (c *Client) CanProposeTNDAOSettingScrubPenaltyEnabled(enabled bool) (api.Ca if enabled { enabledStr = "true" } - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-scrub-penalty-enabled", url.Values{"enabled": {enabledStr}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.scrub.penalty.enabled: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting minipool.scrub.penalty.enabled response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.scrub.penalty.enabled: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-scrub-penalty-enabled", url.Values{"enabled": {enabledStr}}, "Could not get can propose setting minipool.scrub.penalty.enabled") } func (c *Client) CanProposeTNDAOSettingBondReductionWindowStart(windowStart uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-bond-reduction-window-start", url.Values{"value": {strconv.FormatUint(windowStart, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.bond.reduction.window.start: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting minipool.bond.reduction.window.start response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.bond.reduction.window.start: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-bond-reduction-window-start", url.Values{"value": {strconv.FormatUint(windowStart, 10)}}, "Could not get can propose setting minipool.bond.reduction.window.start") } func (c *Client) CanProposeTNDAOSettingBondReductionWindowLength(windowLength uint64) (api.CanProposeTNDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-propose-bond-reduction-window-length", url.Values{"value": {strconv.FormatUint(windowLength, 10)}}) - if err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.bond.reduction.window.length: %w", err) - } - var response api.CanProposeTNDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not decode can propose setting minipool.bond.reduction.window.length response: %w", err) - } - if response.Error != "" { - return api.CanProposeTNDAOSettingResponse{}, fmt.Errorf("Could not get can propose setting minipool.bond.reduction.window.length: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProposeTNDAOSettingResponse]("GET", "/api/odao/can-propose-bond-reduction-window-length", url.Values{"value": {strconv.FormatUint(windowLength, 10)}}, "Could not get can propose setting minipool.bond.reduction.window.length") } // Propose a setting update func (c *Client) ProposeTNDAOSettingMembersQuorum(quorum float64) (api.ProposeTNDAOSettingMembersQuorumResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-members-quorum", url.Values{"quorum": {strconv.FormatFloat(quorum, 'f', -1, 64)}}) - if err != nil { - return api.ProposeTNDAOSettingMembersQuorumResponse{}, fmt.Errorf("Could not propose oracle DAO setting members.quorum: %w", err) - } - var response api.ProposeTNDAOSettingMembersQuorumResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingMembersQuorumResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting members.quorum response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingMembersQuorumResponse{}, fmt.Errorf("Could not propose oracle DAO setting members.quorum: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingMembersQuorumResponse]("POST", "/api/odao/propose-members-quorum", url.Values{"quorum": {strconv.FormatFloat(quorum, 'f', -1, 64)}}, "Could not propose oracle DAO setting members.quorum") } func (c *Client) ProposeTNDAOSettingMembersRplBond(bondAmountWei *big.Int) (api.ProposeTNDAOSettingMembersRplBondResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-members-rplbond", url.Values{"bondAmountWei": {bondAmountWei.String()}}) - if err != nil { - return api.ProposeTNDAOSettingMembersRplBondResponse{}, fmt.Errorf("Could not propose oracle DAO setting members.rplbond: %w", err) - } - var response api.ProposeTNDAOSettingMembersRplBondResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingMembersRplBondResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting members.rplbond response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingMembersRplBondResponse{}, fmt.Errorf("Could not propose oracle DAO setting members.rplbond: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingMembersRplBondResponse]("POST", "/api/odao/propose-members-rplbond", url.Values{"bondAmountWei": {bondAmountWei.String()}}, "Could not propose oracle DAO setting members.rplbond") } func (c *Client) ProposeTNDAOSettingProposalCooldown(proposalCooldownTimespan uint64) (api.ProposeTNDAOSettingProposalCooldownResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-proposal-cooldown", url.Values{"value": {strconv.FormatUint(proposalCooldownTimespan, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingProposalCooldownResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.cooldown.time: %w", err) - } - var response api.ProposeTNDAOSettingProposalCooldownResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingProposalCooldownResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting proposal.cooldown.time response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingProposalCooldownResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.cooldown.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingProposalCooldownResponse]("POST", "/api/odao/propose-proposal-cooldown", url.Values{"value": {strconv.FormatUint(proposalCooldownTimespan, 10)}}, "Could not propose oracle DAO setting proposal.cooldown.time") } func (c *Client) ProposeTNDAOSettingProposalVoteTimespan(proposalVoteTimespan uint64) (api.ProposeTNDAOSettingProposalVoteTimespanResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-proposal-vote-timespan", url.Values{"value": {strconv.FormatUint(proposalVoteTimespan, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingProposalVoteTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.vote.time: %w", err) - } - var response api.ProposeTNDAOSettingProposalVoteTimespanResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingProposalVoteTimespanResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting proposal.vote.time response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingProposalVoteTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.vote.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingProposalVoteTimespanResponse]("POST", "/api/odao/propose-proposal-vote-timespan", url.Values{"value": {strconv.FormatUint(proposalVoteTimespan, 10)}}, "Could not propose oracle DAO setting proposal.vote.time") } func (c *Client) ProposeTNDAOSettingProposalVoteDelayTimespan(proposalDelayTimespan uint64) (api.ProposeTNDAOSettingProposalVoteDelayTimespanResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-proposal-vote-delay-timespan", url.Values{"value": {strconv.FormatUint(proposalDelayTimespan, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingProposalVoteDelayTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.vote.delay.time: %w", err) - } - var response api.ProposeTNDAOSettingProposalVoteDelayTimespanResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingProposalVoteDelayTimespanResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting proposal.vote.delay.time response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingProposalVoteDelayTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.vote.delay.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingProposalVoteDelayTimespanResponse]("POST", "/api/odao/propose-proposal-vote-delay-timespan", url.Values{"value": {strconv.FormatUint(proposalDelayTimespan, 10)}}, "Could not propose oracle DAO setting proposal.vote.delay.time") } func (c *Client) ProposeTNDAOSettingProposalExecuteTimespan(proposalExecuteTimespan uint64) (api.ProposeTNDAOSettingProposalExecuteTimespanResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-proposal-execute-timespan", url.Values{"value": {strconv.FormatUint(proposalExecuteTimespan, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingProposalExecuteTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.execute.time: %w", err) - } - var response api.ProposeTNDAOSettingProposalExecuteTimespanResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingProposalExecuteTimespanResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting proposal.execute.time response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingProposalExecuteTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.execute.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingProposalExecuteTimespanResponse]("POST", "/api/odao/propose-proposal-execute-timespan", url.Values{"value": {strconv.FormatUint(proposalExecuteTimespan, 10)}}, "Could not propose oracle DAO setting proposal.execute.time") } func (c *Client) ProposeTNDAOSettingProposalActionTimespan(proposalActionTimespan uint64) (api.ProposeTNDAOSettingProposalActionTimespanResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-proposal-action-timespan", url.Values{"value": {strconv.FormatUint(proposalActionTimespan, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingProposalActionTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.action.time: %w", err) - } - var response api.ProposeTNDAOSettingProposalActionTimespanResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingProposalActionTimespanResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting proposal.action.time response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingProposalActionTimespanResponse{}, fmt.Errorf("Could not propose oracle DAO setting proposal.action.time: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingProposalActionTimespanResponse]("POST", "/api/odao/propose-proposal-action-timespan", url.Values{"value": {strconv.FormatUint(proposalActionTimespan, 10)}}, "Could not propose oracle DAO setting proposal.action.time") } func (c *Client) ProposeTNDAOSettingScrubPeriod(scrubPeriod uint64) (api.ProposeTNDAOSettingScrubPeriodResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingScrubPeriodResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.scrub.period: %w", err) - } - var response api.ProposeTNDAOSettingScrubPeriodResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingScrubPeriodResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting minipool.scrub.period response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingScrubPeriodResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.scrub.period: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingScrubPeriodResponse]("POST", "/api/odao/propose-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}, "Could not propose oracle DAO setting minipool.scrub.period") } func (c *Client) ProposeTNDAOSettingPromotionScrubPeriod(scrubPeriod uint64) (api.ProposeTNDAOSettingPromotionScrubPeriodResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-promotion-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingPromotionScrubPeriodResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.promotion.scrub.period: %w", err) - } - var response api.ProposeTNDAOSettingPromotionScrubPeriodResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingPromotionScrubPeriodResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting minipool.promotion.scrub.period response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingPromotionScrubPeriodResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.promotion.scrub.period: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingPromotionScrubPeriodResponse]("POST", "/api/odao/propose-promotion-scrub-period", url.Values{"value": {strconv.FormatUint(scrubPeriod, 10)}}, "Could not propose oracle DAO setting minipool.promotion.scrub.period") } func (c *Client) ProposeTNDAOSettingScrubPenaltyEnabled(enabled bool) (api.ProposeTNDAOSettingScrubPenaltyEnabledResponse, error) { @@ -700,62 +240,22 @@ func (c *Client) ProposeTNDAOSettingScrubPenaltyEnabled(enabled bool) (api.Propo if enabled { enabledStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-scrub-penalty-enabled", url.Values{"enabled": {enabledStr}}) - if err != nil { - return api.ProposeTNDAOSettingScrubPenaltyEnabledResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.scrub.penalty.enabled: %w", err) - } - var response api.ProposeTNDAOSettingScrubPenaltyEnabledResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingScrubPenaltyEnabledResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting minipool.scrub.penalty.enabled response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingScrubPenaltyEnabledResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.scrub.penalty.enabled: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingScrubPenaltyEnabledResponse]("POST", "/api/odao/propose-scrub-penalty-enabled", url.Values{"enabled": {enabledStr}}, "Could not propose oracle DAO setting minipool.scrub.penalty.enabled") } func (c *Client) ProposeTNDAOSettingBondReductionWindowStart(windowStart uint64) (api.ProposeTNDAOSettingBondReductionWindowStartResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-bond-reduction-window-start", url.Values{"value": {strconv.FormatUint(windowStart, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingBondReductionWindowStartResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.bond.reduction.window.start: %w", err) - } - var response api.ProposeTNDAOSettingBondReductionWindowStartResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingBondReductionWindowStartResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting minipool.bond.reduction.window.start response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingBondReductionWindowStartResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.bond.reduction.window.start: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingBondReductionWindowStartResponse]("POST", "/api/odao/propose-bond-reduction-window-start", url.Values{"value": {strconv.FormatUint(windowStart, 10)}}, "Could not propose oracle DAO setting minipool.bond.reduction.window.start") } func (c *Client) ProposeTNDAOSettingBondReductionWindowLength(windowLength uint64) (api.ProposeTNDAOSettingBondReductionWindowLengthResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/propose-bond-reduction-window-length", url.Values{"value": {strconv.FormatUint(windowLength, 10)}}) - if err != nil { - return api.ProposeTNDAOSettingBondReductionWindowLengthResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.bond.reduction.window.length: %w", err) - } - var response api.ProposeTNDAOSettingBondReductionWindowLengthResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposeTNDAOSettingBondReductionWindowLengthResponse{}, fmt.Errorf("Could not decode propose oracle DAO setting minipool.bond.reduction.window.length response: %w", err) - } - if response.Error != "" { - return api.ProposeTNDAOSettingBondReductionWindowLengthResponse{}, fmt.Errorf("Could not propose oracle DAO setting minipool.bond.reduction.window.length: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProposeTNDAOSettingBondReductionWindowLengthResponse]("POST", "/api/odao/propose-bond-reduction-window-length", url.Values{"value": {strconv.FormatUint(windowLength, 10)}}, "Could not propose oracle DAO setting minipool.bond.reduction.window.length") } // Get the member settings func (c *Client) GetTNDAOMemberSettings() (api.GetTNDAOMemberSettingsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/get-member-settings", nil) + response, err := c.callAPI[api.GetTNDAOMemberSettingsResponse]("GET", "/api/odao/get-member-settings", nil, "Could not get oracle DAO member settings") if err != nil { - return api.GetTNDAOMemberSettingsResponse{}, fmt.Errorf("Could not get oracle DAO member settings: %w", err) - } - var response api.GetTNDAOMemberSettingsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetTNDAOMemberSettingsResponse{}, fmt.Errorf("Could not decode oracle DAO member settings response: %w", err) - } - if response.Error != "" { - return api.GetTNDAOMemberSettingsResponse{}, fmt.Errorf("Could not get oracle DAO member settings: %s", response.Error) + return response, err } if response.RPLBond == nil { response.RPLBond = big.NewInt(0) @@ -768,72 +268,28 @@ func (c *Client) GetTNDAOMemberSettings() (api.GetTNDAOMemberSettingsResponse, e // Get the proposal settings func (c *Client) GetTNDAOProposalSettings() (api.GetTNDAOProposalSettingsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/get-proposal-settings", nil) - if err != nil { - return api.GetTNDAOProposalSettingsResponse{}, fmt.Errorf("Could not get oracle DAO proposal settings: %w", err) - } - var response api.GetTNDAOProposalSettingsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetTNDAOProposalSettingsResponse{}, fmt.Errorf("Could not decode oracle DAO proposal settings response: %w", err) - } - if response.Error != "" { - return api.GetTNDAOProposalSettingsResponse{}, fmt.Errorf("Could not get oracle DAO proposal settings: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetTNDAOProposalSettingsResponse]("GET", "/api/odao/get-proposal-settings", nil, "Could not get oracle DAO proposal settings") } // Get the minipool settings func (c *Client) GetTNDAOMinipoolSettings() (api.GetTNDAOMinipoolSettingsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/get-minipool-settings", nil) - if err != nil { - return api.GetTNDAOMinipoolSettingsResponse{}, fmt.Errorf("Could not get oracle DAO minipool settings: %w", err) - } - var response api.GetTNDAOMinipoolSettingsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetTNDAOMinipoolSettingsResponse{}, fmt.Errorf("Could not decode oracle DAO minipool settings response: %w", err) - } - if response.Error != "" { - return api.GetTNDAOMinipoolSettingsResponse{}, fmt.Errorf("Could not get oracle DAO minipool settings: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetTNDAOMinipoolSettingsResponse]("GET", "/api/odao/get-minipool-settings", nil, "Could not get oracle DAO minipool settings") } // Check whether the node can penalise a megapool func (c *Client) CanPenaliseMegapool(megapoolAddress common.Address, block *big.Int, amountWei *big.Int) (api.CanPenaliseMegapoolResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/odao/can-penalise-megapool", url.Values{ + return c.callAPI[api.CanPenaliseMegapoolResponse]("GET", "/api/odao/can-penalise-megapool", url.Values{ "megapoolAddress": {megapoolAddress.Hex()}, "block": {block.String()}, "amountWei": {amountWei.String()}, - }) - if err != nil { - return api.CanPenaliseMegapoolResponse{}, fmt.Errorf("Could not get can penalise megapool status: %w", err) - } - var response api.CanPenaliseMegapoolResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanPenaliseMegapoolResponse{}, fmt.Errorf("Could not decode can penalise megapool response: %w", err) - } - if response.Error != "" { - return api.CanPenaliseMegapoolResponse{}, fmt.Errorf("Could not get can penalise megapool status: %s", response.Error) - } - return response, nil + }, "Could not get can penalise megapool status") } // Penalise a megapool func (c *Client) PenaliseMegapool(megapoolAddress common.Address, block *big.Int, amountWei *big.Int) (api.RepayDebtResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/odao/penalise-megapool", url.Values{ + return c.callAPI[api.RepayDebtResponse]("POST", "/api/odao/penalise-megapool", url.Values{ "megapoolAddress": {megapoolAddress.Hex()}, "block": {block.String()}, "amountWei": {amountWei.String()}, - }) - if err != nil { - return api.RepayDebtResponse{}, fmt.Errorf("Could not penalise megapool: %w", err) - } - var response api.RepayDebtResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RepayDebtResponse{}, fmt.Errorf("Could not decode penalise megapool response: %w", err) - } - if response.Error != "" { - return api.RepayDebtResponse{}, fmt.Errorf("Could not penalise megapool: %s", response.Error) - } - return response, nil + }, "Could not penalise megapool") } diff --git a/shared/services/rocketpool/pdao.go b/shared/services/rocketpool/pdao.go index 1c6eb517e..656c7d079 100644 --- a/shared/services/rocketpool/pdao.go +++ b/shared/services/rocketpool/pdao.go @@ -31,178 +31,68 @@ func getVoteDirectionString(direction types.VoteDirection) string { // Get protocol DAO proposals func (c *Client) PDAOProposals() (api.PDAOProposalsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/proposals", nil) - if err != nil { - return api.PDAOProposalsResponse{}, fmt.Errorf("Could not get protocol DAO proposals: %w", err) - } - var response api.PDAOProposalsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposalsResponse{}, fmt.Errorf("Could not decode protocol DAO proposals response: %w", err) - } - if response.Error != "" { - return api.PDAOProposalsResponse{}, fmt.Errorf("Could not get protocol DAO proposals: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOProposalsResponse]("GET", "/api/pdao/proposals", nil, "Could not get protocol DAO proposals") } // Get protocol DAO proposal details func (c *Client) PDAOProposalDetails(proposalID uint64) (api.PDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/proposal-details", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}) - if err != nil { - return api.PDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO proposal: %w", err) - } - var response api.PDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposalResponse{}, fmt.Errorf("Could not decode protocol DAO proposal response: %w", err) - } - if response.Error != "" { - return api.PDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOProposalResponse]("GET", "/api/pdao/proposal-details", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}, "Could not get protocol DAO proposal") } // Check whether the node can vote on a proposal func (c *Client) PDAOCanVoteProposal(proposalID uint64, voteDirection types.VoteDirection) (api.CanVoteOnPDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-vote-proposal", url.Values{ + return c.callAPI[api.CanVoteOnPDAOProposalResponse]("GET", "/api/pdao/can-vote-proposal", url.Values{ "id": {strconv.FormatUint(proposalID, 10)}, "voteDirection": {getVoteDirectionString(voteDirection)}, - }) - if err != nil { - return api.CanVoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-vote-proposal: %w", err) - } - var response api.CanVoteOnPDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanVoteOnPDAOProposalResponse{}, fmt.Errorf("Could not decode protocol DAO can-vote-proposal response: %w", err) - } - if response.Error != "" { - return api.CanVoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-vote-proposal: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-vote-proposal") } // Vote on a proposal func (c *Client) PDAOVoteProposal(proposalID uint64, voteDirection types.VoteDirection) (api.VoteOnPDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/vote-proposal", url.Values{ + return c.callAPI[api.VoteOnPDAOProposalResponse]("POST", "/api/pdao/vote-proposal", url.Values{ "id": {strconv.FormatUint(proposalID, 10)}, "voteDirection": {getVoteDirectionString(voteDirection)}, - }) - if err != nil { - return api.VoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO vote-proposal: %w", err) - } - var response api.VoteOnPDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.VoteOnPDAOProposalResponse{}, fmt.Errorf("Could not decode protocol DAO vote-proposal response: %w", err) - } - if response.Error != "" { - return api.VoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO vote-proposal: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO vote-proposal") } // Check whether the node can override the delegate's vote on a proposal func (c *Client) PDAOCanOverrideVote(proposalID uint64, voteDirection types.VoteDirection) (api.CanVoteOnPDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-override-vote", url.Values{ + return c.callAPI[api.CanVoteOnPDAOProposalResponse]("GET", "/api/pdao/can-override-vote", url.Values{ "id": {strconv.FormatUint(proposalID, 10)}, "voteDirection": {getVoteDirectionString(voteDirection)}, - }) - if err != nil { - return api.CanVoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-override-vote: %w", err) - } - var response api.CanVoteOnPDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanVoteOnPDAOProposalResponse{}, fmt.Errorf("Could not decode protocol DAO can-override-vote response: %w", err) - } - if response.Error != "" { - return api.CanVoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-override-vote: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-override-vote") } // Override the delegate's vote on a proposal func (c *Client) PDAOOverrideVote(proposalID uint64, voteDirection types.VoteDirection) (api.VoteOnPDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/override-vote", url.Values{ + return c.callAPI[api.VoteOnPDAOProposalResponse]("POST", "/api/pdao/override-vote", url.Values{ "id": {strconv.FormatUint(proposalID, 10)}, "voteDirection": {getVoteDirectionString(voteDirection)}, - }) - if err != nil { - return api.VoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO override-vote: %w", err) - } - var response api.VoteOnPDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.VoteOnPDAOProposalResponse{}, fmt.Errorf("Could not decode protocol DAO override-vote response: %w", err) - } - if response.Error != "" { - return api.VoteOnPDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO override-vote: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO override-vote") } // Check whether the node can execute a proposal func (c *Client) PDAOCanExecuteProposal(proposalID uint64) (api.CanExecutePDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-execute-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}) - if err != nil { - return api.CanExecutePDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-execute-proposal: %w", err) - } - var response api.CanExecutePDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanExecutePDAOProposalResponse{}, fmt.Errorf("Could not decode protocol DAO can-execute-proposal response: %w", err) - } - if response.Error != "" { - return api.CanExecutePDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-execute-proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanExecutePDAOProposalResponse]("GET", "/api/pdao/can-execute-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}, "Could not get protocol DAO can-execute-proposal") } // Execute a proposal func (c *Client) PDAOExecuteProposal(proposalID uint64) (api.ExecutePDAOProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/execute-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}) - if err != nil { - return api.ExecutePDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO execute-proposal: %w", err) - } - var response api.ExecutePDAOProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ExecutePDAOProposalResponse{}, fmt.Errorf("Could not decode protocol DAO execute-proposal response: %w", err) - } - if response.Error != "" { - return api.ExecutePDAOProposalResponse{}, fmt.Errorf("Could not get protocol DAO execute-proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.ExecutePDAOProposalResponse]("POST", "/api/pdao/execute-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}, "Could not get protocol DAO execute-proposal") } // Get protocol DAO settings func (c *Client) PDAOGetSettings() (api.GetPDAOSettingsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/get-settings", nil) - if err != nil { - return api.GetPDAOSettingsResponse{}, fmt.Errorf("Could not get protocol DAO get-settings: %w", err) - } - var response api.GetPDAOSettingsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetPDAOSettingsResponse{}, fmt.Errorf("Could not decode protocol DAO get-settings response: %w", err) - } - if response.Error != "" { - return api.GetPDAOSettingsResponse{}, fmt.Errorf("Could not get protocol DAO get-settings: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetPDAOSettingsResponse]("GET", "/api/pdao/get-settings", nil, "Could not get protocol DAO get-settings") } // Check whether the node can propose updating a PDAO setting func (c *Client) PDAOCanProposeSetting(contract string, setting string, value string) (api.CanProposePDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-setting", url.Values{ + return c.callAPI[api.CanProposePDAOSettingResponse]("GET", "/api/pdao/can-propose-setting", url.Values{ "contract": {contract}, "setting": {setting}, "value": {value}, - }) - if err != nil { - return api.CanProposePDAOSettingResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-setting: %w", err) - } - var response api.CanProposePDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposePDAOSettingResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-setting response: %w", err) - } - if response.Error != "" { - return api.CanProposePDAOSettingResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-setting: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-setting") } // Check whether the node can propose updating multiple PDAO settings @@ -211,21 +101,10 @@ func (c *Client) PDAOCanProposeSettingMulti(settings []api.PDAOBatchSetting, cus if err != nil { return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not encode multi-setting proposal: %w", err) } - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/can-propose-setting-multi", url.Values{ + return c.callAPI[api.CanProposePDAOSettingMultiResponse]("POST", "/api/pdao/can-propose-setting-multi", url.Values{ "settings": {string(settingsJSON)}, "customMessage": {customMessage}, - }) - if err != nil { - return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-setting-multi: %w", err) - } - var response api.CanProposePDAOSettingMultiResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-setting-multi response: %w", err) - } - if response.Error != "" { - return api.CanProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-setting-multi: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-setting-multi") } // Propose updating multiple PDAO settings @@ -234,148 +113,71 @@ func (c *Client) PDAOProposeSettingMulti(settings []api.PDAOBatchSetting, custom if err != nil { return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not encode multi-setting proposal: %w", err) } - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-setting-multi", url.Values{ + return c.callAPI[api.ProposePDAOSettingMultiResponse]("POST", "/api/pdao/propose-setting-multi", url.Values{ "settings": {string(settingsJSON)}, "customMessage": {customMessage}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO propose-setting-multi: %w", err) - } - var response api.ProposePDAOSettingMultiResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not decode protocol DAO propose-setting-multi response: %w", err) - } - if response.Error != "" { - return api.ProposePDAOSettingMultiResponse{}, fmt.Errorf("Could not get protocol DAO propose-setting-multi: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-setting-multi") } // Propose updating a PDAO setting func (c *Client) PDAOProposeSetting(contract string, setting string, value string, blockNumber uint32) (api.ProposePDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-setting", url.Values{ + return c.callAPI[api.ProposePDAOSettingResponse]("POST", "/api/pdao/propose-setting", url.Values{ "contract": {contract}, "setting": {setting}, "value": {value}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.ProposePDAOSettingResponse{}, fmt.Errorf("Could not get protocol DAO propose-setting: %w", err) - } - var response api.ProposePDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposePDAOSettingResponse{}, fmt.Errorf("Could not decode protocol DAO propose-setting response: %w", err) - } - if response.Error != "" { - return api.ProposePDAOSettingResponse{}, fmt.Errorf("Could not get protocol DAO propose-setting: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-setting") } // Get the allocation percentages of RPL rewards func (c *Client) PDAOGetRewardsPercentages() (api.PDAOGetRewardsPercentagesResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/get-rewards-percentages", nil) - if err != nil { - return api.PDAOGetRewardsPercentagesResponse{}, fmt.Errorf("Could not get protocol DAO get-rewards-percentages: %w", err) - } - var response api.PDAOGetRewardsPercentagesResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOGetRewardsPercentagesResponse{}, fmt.Errorf("Could not decode protocol DAO get-rewards-percentages response: %w", err) - } - if response.Error != "" { - return api.PDAOGetRewardsPercentagesResponse{}, fmt.Errorf("Could not get protocol DAO get-rewards-percentages: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOGetRewardsPercentagesResponse]("GET", "/api/pdao/get-rewards-percentages", nil, "Could not get protocol DAO get-rewards-percentages") } // Check whether the node can propose new RPL rewards allocation percentages func (c *Client) PDAOCanProposeRewardsPercentages(node *big.Int, odao *big.Int, pdao *big.Int) (api.PDAOCanProposeRewardsPercentagesResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-rewards-percentages", url.Values{ + return c.callAPI[api.PDAOCanProposeRewardsPercentagesResponse]("GET", "/api/pdao/can-propose-rewards-percentages", url.Values{ "node": {node.String()}, "odao": {odao.String()}, "pdao": {pdao.String()}, - }) - if err != nil { - return api.PDAOCanProposeRewardsPercentagesResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-rewards-percentages: %w", err) - } - var response api.PDAOCanProposeRewardsPercentagesResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeRewardsPercentagesResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-rewards-percentages response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeRewardsPercentagesResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-rewards-percentages: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-rewards-percentages") } // Propose new RPL rewards allocation percentages func (c *Client) PDAOProposeRewardsPercentages(node *big.Int, odao *big.Int, pdao *big.Int, blockNumber uint32) (api.ProposePDAOSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-rewards-percentages", url.Values{ + return c.callAPI[api.ProposePDAOSettingResponse]("POST", "/api/pdao/propose-rewards-percentages", url.Values{ "node": {node.String()}, "odao": {odao.String()}, "pdao": {pdao.String()}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.ProposePDAOSettingResponse{}, fmt.Errorf("Could not get protocol DAO propose-rewards-percentages: %w", err) - } - var response api.ProposePDAOSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProposePDAOSettingResponse{}, fmt.Errorf("Could not decode protocol DAO propose-rewards-percentages response: %w", err) - } - if response.Error != "" { - return api.ProposePDAOSettingResponse{}, fmt.Errorf("Could not get protocol DAO propose-rewards-percentages: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-rewards-percentages") } // Check whether the node can propose a one-time spend of the Protocol DAO's treasury func (c *Client) PDAOCanProposeOneTimeSpend(invoiceID string, recipient common.Address, amount *big.Int, customMessage string) (api.PDAOCanProposeOneTimeSpendResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-one-time-spend", url.Values{ + return c.callAPI[api.PDAOCanProposeOneTimeSpendResponse]("GET", "/api/pdao/can-propose-one-time-spend", url.Values{ "invoiceId": {invoiceID}, "recipient": {recipient.Hex()}, "amount": {amount.String()}, "customMessage": {customMessage}, - }) - if err != nil { - return api.PDAOCanProposeOneTimeSpendResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-one-time-spend: %w", err) - } - var response api.PDAOCanProposeOneTimeSpendResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeOneTimeSpendResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-one-time-spend response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeOneTimeSpendResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-one-time-spend: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-one-time-spend") } // Propose a one-time spend of the Protocol DAO's treasury func (c *Client) PDAOProposeOneTimeSpend(invoiceID string, recipient common.Address, amount *big.Int, blockNumber uint32, customMessage string) (api.PDAOProposeOneTimeSpendResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-one-time-spend", url.Values{ + return c.callAPI[api.PDAOProposeOneTimeSpendResponse]("POST", "/api/pdao/propose-one-time-spend", url.Values{ "invoiceId": {invoiceID}, "recipient": {recipient.Hex()}, "amount": {amount.String()}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, "customMessage": {customMessage}, - }) - if err != nil { - return api.PDAOProposeOneTimeSpendResponse{}, fmt.Errorf("Could not get protocol DAO propose-one-time-spend: %w", err) - } - var response api.PDAOProposeOneTimeSpendResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeOneTimeSpendResponse{}, fmt.Errorf("Could not decode protocol DAO propose-one-time-spend response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeOneTimeSpendResponse{}, fmt.Errorf("Could not get protocol DAO propose-one-time-spend: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-one-time-spend") } // Check whether the node can propose a recurring spend of the Protocol DAO's treasury func (c *Client) PDAOCanProposeRecurringSpend(contractName string, recipient common.Address, amountPerPeriod *big.Int, periodLength time.Duration, startTime time.Time, numberOfPeriods uint64, customMessage string) (api.PDAOCanProposeRecurringSpendResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-recurring-spend", url.Values{ + return c.callAPI[api.PDAOCanProposeRecurringSpendResponse]("GET", "/api/pdao/can-propose-recurring-spend", url.Values{ "contractName": {contractName}, "recipient": {recipient.Hex()}, "amountPerPeriod": {amountPerPeriod.String()}, @@ -383,23 +185,12 @@ func (c *Client) PDAOCanProposeRecurringSpend(contractName string, recipient com "startTime": {strconv.FormatInt(startTime.Unix(), 10)}, "numberOfPeriods": {strconv.FormatUint(numberOfPeriods, 10)}, "customMessage": {customMessage}, - }) - if err != nil { - return api.PDAOCanProposeRecurringSpendResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-recurring-spend: %w", err) - } - var response api.PDAOCanProposeRecurringSpendResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeRecurringSpendResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-recurring-spend response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeRecurringSpendResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-recurring-spend: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-recurring-spend") } // Propose a recurring spend of the Protocol DAO's treasury func (c *Client) PDAOProposeRecurringSpend(contractName string, recipient common.Address, amountPerPeriod *big.Int, periodLength time.Duration, startTime time.Time, numberOfPeriods uint64, blockNumber uint32, customMessage string) (api.PDAOProposeRecurringSpendResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-recurring-spend", url.Values{ + return c.callAPI[api.PDAOProposeRecurringSpendResponse]("POST", "/api/pdao/propose-recurring-spend", url.Values{ "contractName": {contractName}, "recipient": {recipient.Hex()}, "amountPerPeriod": {amountPerPeriod.String()}, @@ -408,46 +199,24 @@ func (c *Client) PDAOProposeRecurringSpend(contractName string, recipient common "numberOfPeriods": {strconv.FormatUint(numberOfPeriods, 10)}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, "customMessage": {customMessage}, - }) - if err != nil { - return api.PDAOProposeRecurringSpendResponse{}, fmt.Errorf("Could not get protocol DAO propose-recurring-spend: %w", err) - } - var response api.PDAOProposeRecurringSpendResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeRecurringSpendResponse{}, fmt.Errorf("Could not decode protocol DAO propose-recurring-spend response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeRecurringSpendResponse{}, fmt.Errorf("Could not get protocol DAO propose-recurring-spend: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-recurring-spend") } // Check whether the node can propose an update to an existing recurring spend plan func (c *Client) PDAOCanProposeRecurringSpendUpdate(contractName string, recipient common.Address, amountPerPeriod *big.Int, periodLength time.Duration, numberOfPeriods uint64, customMessage string) (api.PDAOCanProposeRecurringSpendUpdateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-recurring-spend-update", url.Values{ + return c.callAPI[api.PDAOCanProposeRecurringSpendUpdateResponse]("GET", "/api/pdao/can-propose-recurring-spend-update", url.Values{ "contractName": {contractName}, "recipient": {recipient.Hex()}, "amountPerPeriod": {amountPerPeriod.String()}, "periodLength": {periodLength.String()}, "numberOfPeriods": {strconv.FormatUint(numberOfPeriods, 10)}, "customMessage": {customMessage}, - }) - if err != nil { - return api.PDAOCanProposeRecurringSpendUpdateResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-recurring-spend-update: %w", err) - } - var response api.PDAOCanProposeRecurringSpendUpdateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeRecurringSpendUpdateResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-recurring-spend-update response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeRecurringSpendUpdateResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-recurring-spend-update: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-recurring-spend-update") } // Propose an update to an existing recurring spend plan func (c *Client) PDAOProposeRecurringSpendUpdate(contractName string, recipient common.Address, amountPerPeriod *big.Int, periodLength time.Duration, numberOfPeriods uint64, blockNumber uint32, customMessage string) (api.PDAOProposeRecurringSpendUpdateResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-recurring-spend-update", url.Values{ + return c.callAPI[api.PDAOProposeRecurringSpendUpdateResponse]("POST", "/api/pdao/propose-recurring-spend-update", url.Values{ "contractName": {contractName}, "recipient": {recipient.Hex()}, "amountPerPeriod": {amountPerPeriod.String()}, @@ -455,92 +224,37 @@ func (c *Client) PDAOProposeRecurringSpendUpdate(contractName string, recipient "numberOfPeriods": {strconv.FormatUint(numberOfPeriods, 10)}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, "customMessage": {customMessage}, - }) - if err != nil { - return api.PDAOProposeRecurringSpendUpdateResponse{}, fmt.Errorf("Could not get protocol DAO propose-recurring-spend-update: %w", err) - } - var response api.PDAOProposeRecurringSpendUpdateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeRecurringSpendUpdateResponse{}, fmt.Errorf("Could not decode protocol DAO propose-recurring-spend-update response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeRecurringSpendUpdateResponse{}, fmt.Errorf("Could not get protocol DAO propose-recurring-spend-update: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-recurring-spend-update") } // Check whether the node can invite someone to the security council func (c *Client) PDAOCanProposeInviteToSecurityCouncil(id string, address common.Address) (api.PDAOCanProposeInviteToSecurityCouncilResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-invite-to-security-council", url.Values{ + return c.callAPI[api.PDAOCanProposeInviteToSecurityCouncilResponse]("GET", "/api/pdao/can-propose-invite-to-security-council", url.Values{ "id": {id}, "address": {address.Hex()}, - }) - if err != nil { - return api.PDAOCanProposeInviteToSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-invite-to-security-council: %w", err) - } - var response api.PDAOCanProposeInviteToSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeInviteToSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-invite-to-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeInviteToSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-invite-to-security-council: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-invite-to-security-council") } // Propose inviting someone to the security council func (c *Client) PDAOProposeInviteToSecurityCouncil(id string, address common.Address, blockNumber uint32) (api.PDAOProposeInviteToSecurityCouncilResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-invite-to-security-council", url.Values{ + return c.callAPI[api.PDAOProposeInviteToSecurityCouncilResponse]("POST", "/api/pdao/propose-invite-to-security-council", url.Values{ "id": {id}, "address": {address.Hex()}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.PDAOProposeInviteToSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-invite-to-security-council: %w", err) - } - var response api.PDAOProposeInviteToSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeInviteToSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO propose-invite-to-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeInviteToSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-invite-to-security-council: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-invite-to-security-council") } // Check whether the node can kick someone from the security council func (c *Client) PDAOCanProposeKickFromSecurityCouncil(address common.Address) (api.PDAOCanProposeKickFromSecurityCouncilResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-kick-from-security-council", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.PDAOCanProposeKickFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-kick-from-security-council: %w", err) - } - var response api.PDAOCanProposeKickFromSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeKickFromSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-kick-from-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeKickFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-kick-from-security-council: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOCanProposeKickFromSecurityCouncilResponse]("GET", "/api/pdao/can-propose-kick-from-security-council", url.Values{"address": {address.Hex()}}, "Could not get protocol DAO can-propose-kick-from-security-council") } // Propose kicking someone from the security council func (c *Client) PDAOProposeKickFromSecurityCouncil(address common.Address, blockNumber uint32) (api.PDAOProposeKickFromSecurityCouncilResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-kick-from-security-council", url.Values{ + return c.callAPI[api.PDAOProposeKickFromSecurityCouncilResponse]("POST", "/api/pdao/propose-kick-from-security-council", url.Values{ "address": {address.Hex()}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.PDAOProposeKickFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-kick-from-security-council: %w", err) - } - var response api.PDAOProposeKickFromSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeKickFromSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO propose-kick-from-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeKickFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-kick-from-security-council: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-kick-from-security-council") } // Check whether the node can kick multiple members from the security council @@ -549,18 +263,7 @@ func (c *Client) PDAOCanProposeKickMultiFromSecurityCouncil(addresses []common.A for i, address := range addresses { addressStrings[i] = address.Hex() } - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-kick-multi-from-security-council", url.Values{"addresses": {strings.Join(addressStrings, ",")}}) - if err != nil { - return api.PDAOCanProposeKickMultiFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-kick-multi-from-security-council: %w", err) - } - var response api.PDAOCanProposeKickMultiFromSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeKickMultiFromSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-kick-multi-from-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeKickMultiFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-kick-multi-from-security-council: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOCanProposeKickMultiFromSecurityCouncilResponse]("GET", "/api/pdao/can-propose-kick-multi-from-security-council", url.Values{"addresses": {strings.Join(addressStrings, ",")}}, "Could not get protocol DAO can-propose-kick-multi-from-security-council") } // Propose kicking multiple members from the security council @@ -569,78 +272,34 @@ func (c *Client) PDAOProposeKickMultiFromSecurityCouncil(addresses []common.Addr for i, address := range addresses { addressStrings[i] = address.Hex() } - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-kick-multi-from-security-council", url.Values{ + return c.callAPI[api.PDAOProposeKickMultiFromSecurityCouncilResponse]("POST", "/api/pdao/propose-kick-multi-from-security-council", url.Values{ "addresses": {strings.Join(addressStrings, ",")}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.PDAOProposeKickMultiFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-kick-multi-from-security-council: %w", err) - } - var response api.PDAOProposeKickMultiFromSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeKickMultiFromSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO propose-kick-multi-from-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeKickMultiFromSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-kick-multi-from-security-council: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-kick-multi-from-security-council") } // Check whether the node can propose replacing someone on the security council func (c *Client) PDAOCanProposeReplaceMemberOfSecurityCouncil(existingAddress common.Address, newID string, newAddress common.Address) (api.PDAOCanProposeReplaceMemberOfSecurityCouncilResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-replace-member-of-security-council", url.Values{ + return c.callAPI[api.PDAOCanProposeReplaceMemberOfSecurityCouncilResponse]("GET", "/api/pdao/can-propose-replace-member-of-security-council", url.Values{ "existingAddress": {existingAddress.Hex()}, "newId": {newID}, "newAddress": {newAddress.Hex()}, - }) - if err != nil { - return api.PDAOCanProposeReplaceMemberOfSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-replace-member-of-security-council: %w", err) - } - var response api.PDAOCanProposeReplaceMemberOfSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanProposeReplaceMemberOfSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-replace-member-of-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOCanProposeReplaceMemberOfSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-replace-member-of-security-council: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-propose-replace-member-of-security-council") } // Propose replacing someone on the security council func (c *Client) PDAOProposeReplaceMemberOfSecurityCouncil(existingAddress common.Address, newID string, newAddress common.Address, blockNumber uint32) (api.PDAOProposeReplaceMemberOfSecurityCouncilResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-replace-member-of-security-council", url.Values{ + return c.callAPI[api.PDAOProposeReplaceMemberOfSecurityCouncilResponse]("POST", "/api/pdao/propose-replace-member-of-security-council", url.Values{ "existingAddress": {existingAddress.Hex()}, "newId": {newID}, "newAddress": {newAddress.Hex()}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.PDAOProposeReplaceMemberOfSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-replace-member-of-security-council: %w", err) - } - var response api.PDAOProposeReplaceMemberOfSecurityCouncilResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeReplaceMemberOfSecurityCouncilResponse{}, fmt.Errorf("Could not decode protocol DAO propose-replace-member-of-security-council response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeReplaceMemberOfSecurityCouncilResponse{}, fmt.Errorf("Could not get protocol DAO propose-replace-member-of-security-council: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-replace-member-of-security-council") } // Get the list of proposals with claimable / rewardable bonds func (c *Client) PDAOGetClaimableBonds() (api.PDAOGetClaimableBondsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/get-claimable-bonds", nil) - if err != nil { - return api.PDAOGetClaimableBondsResponse{}, fmt.Errorf("Could not get protocol DAO get-claimable-bonds: %w", err) - } - var response api.PDAOGetClaimableBondsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOGetClaimableBondsResponse{}, fmt.Errorf("Could not decode protocol DAO get-claimable-bonds response: %w", err) - } - if response.Error != "" { - return api.PDAOGetClaimableBondsResponse{}, fmt.Errorf("Could not get protocol DAO get-claimable-bonds: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOGetClaimableBondsResponse]("GET", "/api/pdao/get-claimable-bonds", nil, "Could not get protocol DAO get-claimable-bonds") } // Check whether the node can claim / unlock bonds from a proposal @@ -649,21 +308,10 @@ func (c *Client) PDAOCanClaimBonds(proposalID uint64, indices []uint64) (api.PDA for i, index := range indices { indicesStrings[i] = strconv.FormatUint(index, 10) } - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-claim-bonds", url.Values{ + return c.callAPI[api.PDAOCanClaimBondsResponse]("GET", "/api/pdao/can-claim-bonds", url.Values{ "proposalId": {strconv.FormatUint(proposalID, 10)}, "indices": {strings.Join(indicesStrings, ",")}, - }) - if err != nil { - return api.PDAOCanClaimBondsResponse{}, fmt.Errorf("Could not get protocol DAO can-claim-bonds: %w", err) - } - var response api.PDAOCanClaimBondsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanClaimBondsResponse{}, fmt.Errorf("Could not decode protocol DAO can-claim-bonds response: %w", err) - } - if response.Error != "" { - return api.PDAOCanClaimBondsResponse{}, fmt.Errorf("Could not get protocol DAO can-claim-bonds: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-claim-bonds") } // Claim / unlock bonds from a proposal @@ -676,259 +324,94 @@ func (c *Client) PDAOClaimBonds(isProposer bool, proposalID uint64, indices []ui if isProposer { isProposerStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/claim-bonds", url.Values{ + return c.callAPI[api.PDAOClaimBondsResponse]("POST", "/api/pdao/claim-bonds", url.Values{ "isProposer": {isProposerStr}, "proposalId": {strconv.FormatUint(proposalID, 10)}, "indices": {strings.Join(indicesStrings, ",")}, - }) - if err != nil { - return api.PDAOClaimBondsResponse{}, fmt.Errorf("Could not get protocol DAO claim-bonds: %w", err) - } - var response api.PDAOClaimBondsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOClaimBondsResponse{}, fmt.Errorf("Could not decode protocol DAO claim-bonds response: %w", err) - } - if response.Error != "" { - return api.PDAOClaimBondsResponse{}, fmt.Errorf("Could not get protocol DAO claim-bonds: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO claim-bonds") } // Check whether the node can defeat a proposal func (c *Client) PDAOCanDefeatProposal(proposalID uint64, index uint64) (api.PDAOCanDefeatProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-defeat-proposal", url.Values{ + return c.callAPI[api.PDAOCanDefeatProposalResponse]("GET", "/api/pdao/can-defeat-proposal", url.Values{ "id": {strconv.FormatUint(proposalID, 10)}, "index": {strconv.FormatUint(index, 10)}, - }) - if err != nil { - return api.PDAOCanDefeatProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-defeat-proposal: %w", err) - } - var response api.PDAOCanDefeatProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanDefeatProposalResponse{}, fmt.Errorf("Could not decode protocol DAO can-defeat-proposal response: %w", err) - } - if response.Error != "" { - return api.PDAOCanDefeatProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-defeat-proposal: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO can-defeat-proposal") } // Defeat a proposal func (c *Client) PDAODefeatProposal(proposalID uint64, index uint64) (api.PDAODefeatProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/defeat-proposal", url.Values{ + return c.callAPI[api.PDAODefeatProposalResponse]("POST", "/api/pdao/defeat-proposal", url.Values{ "id": {strconv.FormatUint(proposalID, 10)}, "index": {strconv.FormatUint(index, 10)}, - }) - if err != nil { - return api.PDAODefeatProposalResponse{}, fmt.Errorf("Could not get protocol DAO defeat-proposal: %w", err) - } - var response api.PDAODefeatProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAODefeatProposalResponse{}, fmt.Errorf("Could not decode protocol DAO defeat-proposal response: %w", err) - } - if response.Error != "" { - return api.PDAODefeatProposalResponse{}, fmt.Errorf("Could not get protocol DAO defeat-proposal: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO defeat-proposal") } // Check whether the node can finalize a proposal func (c *Client) PDAOCanFinalizeProposal(proposalID uint64) (api.PDAOCanFinalizeProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-finalize-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}) - if err != nil { - return api.PDAOCanFinalizeProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-finalize-proposal: %w", err) - } - var response api.PDAOCanFinalizeProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanFinalizeProposalResponse{}, fmt.Errorf("Could not decode protocol DAO can-finalize-proposal response: %w", err) - } - if response.Error != "" { - return api.PDAOCanFinalizeProposalResponse{}, fmt.Errorf("Could not get protocol DAO can-finalize-proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOCanFinalizeProposalResponse]("GET", "/api/pdao/can-finalize-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}, "Could not get protocol DAO can-finalize-proposal") } // Finalize a proposal func (c *Client) PDAOFinalizeProposal(proposalID uint64) (api.PDAOFinalizeProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/finalize-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}) - if err != nil { - return api.PDAOFinalizeProposalResponse{}, fmt.Errorf("Could not get protocol DAO finalize-proposal: %w", err) - } - var response api.PDAOFinalizeProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOFinalizeProposalResponse{}, fmt.Errorf("Could not decode protocol DAO finalize-proposal response: %w", err) - } - if response.Error != "" { - return api.PDAOFinalizeProposalResponse{}, fmt.Errorf("Could not get protocol DAO finalize-proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOFinalizeProposalResponse]("POST", "/api/pdao/finalize-proposal", url.Values{"id": {strconv.FormatUint(proposalID, 10)}}, "Could not get protocol DAO finalize-proposal") } // EstimateSetVotingDelegateGas estimates the gas required to set an on-chain voting delegate func (c *Client) EstimateSetVotingDelegateGas(address common.Address) (api.PDAOCanSetVotingDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/estimate-set-voting-delegate-gas", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.PDAOCanSetVotingDelegateResponse{}, fmt.Errorf("could not call estimate-set-voting-delegate-gas: %w", err) - } - var response api.PDAOCanSetVotingDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanSetVotingDelegateResponse{}, fmt.Errorf("could not decode estimate-set-voting-delegate-gas response: %w", err) - } - if response.Error != "" { - return api.PDAOCanSetVotingDelegateResponse{}, fmt.Errorf("error after requesting estimate-set-voting-delegate-gas: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOCanSetVotingDelegateResponse]("GET", "/api/pdao/estimate-set-voting-delegate-gas", url.Values{"address": {address.Hex()}}, "could not call estimate-set-voting-delegate-gas") } // SetVotingDelegate sets an on-chain voting delegate for the node func (c *Client) SetVotingDelegate(address common.Address) (api.PDAOSetVotingDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/set-voting-delegate", url.Values{"address": {address.Hex()}}) - if err != nil { - return api.PDAOSetVotingDelegateResponse{}, fmt.Errorf("could not call set-voting-delegate: %w", err) - } - var response api.PDAOSetVotingDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOSetVotingDelegateResponse{}, fmt.Errorf("could not decode set-voting-delegate response: %w", err) - } - if response.Error != "" { - return api.PDAOSetVotingDelegateResponse{}, fmt.Errorf("error after requesting set-voting-delegate: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOSetVotingDelegateResponse]("POST", "/api/pdao/set-voting-delegate", url.Values{"address": {address.Hex()}}, "could not call set-voting-delegate") } // GetCurrentVotingDelegate gets the node current on-chain voting delegate func (c *Client) GetCurrentVotingDelegate() (api.PDAOCurrentVotingDelegateResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/get-current-voting-delegate", nil) - if err != nil { - return api.PDAOCurrentVotingDelegateResponse{}, fmt.Errorf("could not request get-current-voting-delegate: %w", err) - } - var response api.PDAOCurrentVotingDelegateResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCurrentVotingDelegateResponse{}, fmt.Errorf("could not decode get-current-voting-delegate: %w", err) - } - if response.Error != "" { - return api.PDAOCurrentVotingDelegateResponse{}, fmt.Errorf("error after requesting get-current-voting-delegate: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOCurrentVotingDelegateResponse]("GET", "/api/pdao/get-current-voting-delegate", nil, "could not request get-current-voting-delegate") } // CanSetSignallingAddress fetches gas info and if a node can set the signalling address func (c *Client) CanSetSignallingAddress(signallingAddress common.Address, signature string) (api.PDAOCanSetSignallingAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-set-signalling-address", url.Values{ + return c.callAPI[api.PDAOCanSetSignallingAddressResponse]("GET", "/api/pdao/can-set-signalling-address", url.Values{ "address": {signallingAddress.Hex()}, "signature": {signature}, - }) - if err != nil { - return api.PDAOCanSetSignallingAddressResponse{}, fmt.Errorf("could not call can-set-signalling-address: %w", err) - } - var response api.PDAOCanSetSignallingAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanSetSignallingAddressResponse{}, fmt.Errorf("could not decode can-set-signalling-address response: %w", err) - } - if response.Error != "" { - return api.PDAOCanSetSignallingAddressResponse{}, fmt.Errorf("error after requesting can-set-signalling-address: %s", response.Error) - } - return response, nil + }, "could not call can-set-signalling-address") } // SetSignallingAddress sets the node's signalling address func (c *Client) SetSignallingAddress(signallingAddress common.Address, signature string) (api.PDAOSetSignallingAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/set-signalling-address", url.Values{ + return c.callAPI[api.PDAOSetSignallingAddressResponse]("POST", "/api/pdao/set-signalling-address", url.Values{ "address": {signallingAddress.Hex()}, "signature": {signature}, - }) - if err != nil { - return api.PDAOSetSignallingAddressResponse{}, fmt.Errorf("could not call set-signalling-address: %w", err) - } - var response api.PDAOSetSignallingAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOSetSignallingAddressResponse{}, fmt.Errorf("could not decode set-signalling-address response: %w", err) - } - if response.Error != "" { - return api.PDAOSetSignallingAddressResponse{}, fmt.Errorf("error after requesting set-signalling-address: %s", response.Error) - } - return response, nil + }, "could not call set-signalling-address") } // CanClearSignallingAddress fetches gas info and if a node can clear a signalling address func (c *Client) CanClearSignallingAddress() (api.PDAOCanClearSignallingAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-clear-signalling-address", nil) - if err != nil { - return api.PDAOCanClearSignallingAddressResponse{}, fmt.Errorf("could not call can-clear-signalling-address: %w", err) - } - var response api.PDAOCanClearSignallingAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOCanClearSignallingAddressResponse{}, fmt.Errorf("could not decode can-clear-signalling-address response: %w", err) - } - if response.Error != "" { - return api.PDAOCanClearSignallingAddressResponse{}, fmt.Errorf("error after requesting can-clear-signalling-address: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOCanClearSignallingAddressResponse]("GET", "/api/pdao/can-clear-signalling-address", nil, "could not call can-clear-signalling-address") } // ClearSignallingAddress clears the node's signalling address func (c *Client) ClearSignallingAddress() (api.PDAOSetSignallingAddressResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/clear-signalling-address", nil) - if err != nil { - return api.PDAOSetSignallingAddressResponse{}, fmt.Errorf("could not call clear-signalling-address: %w", err) - } - var response api.PDAOSetSignallingAddressResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOSetSignallingAddressResponse{}, fmt.Errorf("could not decode clear-signalling-address response: %w", err) - } - if response.Error != "" { - return api.PDAOSetSignallingAddressResponse{}, fmt.Errorf("error after requesting clear-signalling-address: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOSetSignallingAddressResponse]("POST", "/api/pdao/clear-signalling-address", nil, "could not call clear-signalling-address") } // Check whether the node can propose a list of addresses that can update commission share parameters func (c *Client) PDAOCanProposeAllowListedControllers(addressList string) (api.PDAOACanProposeAllowListedControllersResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/can-propose-allow-listed-controllers", url.Values{"addressList": {addressList}}) - if err != nil { - return api.PDAOACanProposeAllowListedControllersResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-allow-listed-controllers: %w", err) - } - var response api.PDAOACanProposeAllowListedControllersResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOACanProposeAllowListedControllersResponse{}, fmt.Errorf("Could not decode protocol DAO can-propose-allow-listed-controllers response: %w", err) - } - if response.Error != "" { - return api.PDAOACanProposeAllowListedControllersResponse{}, fmt.Errorf("Could not get protocol DAO can-propose-allow-listed-controllers: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOACanProposeAllowListedControllersResponse]("GET", "/api/pdao/can-propose-allow-listed-controllers", url.Values{"addressList": {addressList}}, "Could not get protocol DAO can-propose-allow-listed-controllers") } // Propose a list of addresses that can update commission share parameters func (c *Client) PDAOProposeAllowListedControllers(addressList string, blockNumber uint32) (api.PDAOProposeAllowListedControllersResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/pdao/propose-allow-listed-controllers", url.Values{ + return c.callAPI[api.PDAOProposeAllowListedControllersResponse]("POST", "/api/pdao/propose-allow-listed-controllers", url.Values{ "addressList": {addressList}, "blockNumber": {strconv.FormatUint(uint64(blockNumber), 10)}, - }) - if err != nil { - return api.PDAOProposeAllowListedControllersResponse{}, fmt.Errorf("Could not get protocol DAO propose-allow-listed-controllers: %w", err) - } - var response api.PDAOProposeAllowListedControllersResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOProposeAllowListedControllersResponse{}, fmt.Errorf("Could not decode protocol DAO propose-allow-listed-controllers response: %w", err) - } - if response.Error != "" { - return api.PDAOProposeAllowListedControllersResponse{}, fmt.Errorf("Could not get protocol DAO propose-allow-listed-controllers: %s", response.Error) - } - return response, nil + }, "Could not get protocol DAO propose-allow-listed-controllers") } // Get PDAO Status func (c *Client) PDAOStatus() (api.PDAOStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/pdao/status", nil) - if err != nil { - return api.PDAOStatusResponse{}, fmt.Errorf("could not call get pdao status: %w", err) - } - var response api.PDAOStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.PDAOStatusResponse{}, fmt.Errorf("could not decode get-voting-power: %w", err) - } - if response.Error != "" { - return api.PDAOStatusResponse{}, fmt.Errorf("error after requesting get-voting-power: %s", response.Error) - } - return response, nil + return c.callAPI[api.PDAOStatusResponse]("GET", "/api/pdao/status", nil, "could not call get pdao status") } diff --git a/shared/services/rocketpool/queue.go b/shared/services/rocketpool/queue.go index 0e4592a20..73592b645 100644 --- a/shared/services/rocketpool/queue.go +++ b/shared/services/rocketpool/queue.go @@ -5,23 +5,14 @@ import ( "math/big" "net/url" - "github.com/goccy/go-json" - "github.com/rocket-pool/smartnode/shared/types/api" ) // Get queue status func (c *Client) QueueStatus() (api.QueueStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/queue/status", nil) + response, err := c.callAPI[api.QueueStatusResponse]("GET", "/api/queue/status", nil, "Could not get queue status") if err != nil { - return api.QueueStatusResponse{}, fmt.Errorf("Could not get queue status: %w", err) - } - var response api.QueueStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.QueueStatusResponse{}, fmt.Errorf("Could not decode queue status response: %w", err) - } - if response.Error != "" { - return api.QueueStatusResponse{}, fmt.Errorf("Could not get queue status: %s", response.Error) + return response, err } if response.DepositPoolBalance == nil { response.DepositPoolBalance = big.NewInt(0) @@ -34,79 +25,24 @@ func (c *Client) QueueStatus() (api.QueueStatusResponse, error) { // Check whether the queue can be processed func (c *Client) CanProcessQueue(m uint32) (api.CanProcessQueueResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/queue/can-process", url.Values{"max": {fmt.Sprintf("%d", m)}}) - if err != nil { - return api.CanProcessQueueResponse{}, fmt.Errorf("Could not get can process queue status: %w", err) - } - var response api.CanProcessQueueResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanProcessQueueResponse{}, fmt.Errorf("Could not decode can process queue response: %w", err) - } - if response.Error != "" { - return api.CanProcessQueueResponse{}, fmt.Errorf("Could not get can process queue status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanProcessQueueResponse]("GET", "/api/queue/can-process", url.Values{"max": {fmt.Sprintf("%d", m)}}, "Could not get can process queue status") } // Process the queue func (c *Client) ProcessQueue(m uint32) (api.ProcessQueueResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/queue/process", url.Values{"max": {fmt.Sprintf("%d", m)}}) - if err != nil { - return api.ProcessQueueResponse{}, fmt.Errorf("Could not process queue: %w", err) - } - var response api.ProcessQueueResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ProcessQueueResponse{}, fmt.Errorf("Could not decode process queue response: %w", err) - } - if response.Error != "" { - return api.ProcessQueueResponse{}, fmt.Errorf("Could not process queue: %s", response.Error) - } - return response, nil + return c.callAPI[api.ProcessQueueResponse]("POST", "/api/queue/process", url.Values{"max": {fmt.Sprintf("%d", m)}}, "Could not process queue") } // Check whether deposits can be assigned func (c *Client) CanAssignDeposits(m uint32) (api.CanAssignDepositsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/queue/can-assign-deposits", url.Values{"max": {fmt.Sprintf("%d", m)}}) - if err != nil { - return api.CanAssignDepositsResponse{}, fmt.Errorf("Could not get can assign deposits status: %w", err) - } - var response api.CanAssignDepositsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanAssignDepositsResponse{}, fmt.Errorf("Could not decode can assign deposits response: %w", err) - } - if response.Error != "" { - return api.CanAssignDepositsResponse{}, fmt.Errorf("Could not get can assign deposits status: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanAssignDepositsResponse]("GET", "/api/queue/can-assign-deposits", url.Values{"max": {fmt.Sprintf("%d", m)}}, "Could not get can assign deposits status") } // Assign deposits to queued validators func (c *Client) AssignDeposits(m uint32) (api.AssignDepositsResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/queue/assign-deposits", url.Values{"max": {fmt.Sprintf("%d", m)}}) - if err != nil { - return api.AssignDepositsResponse{}, fmt.Errorf("Could not assign deposits: %w", err) - } - var response api.AssignDepositsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.AssignDepositsResponse{}, fmt.Errorf("Could not decode assign deposits response: %w", err) - } - if response.Error != "" { - return api.AssignDepositsResponse{}, fmt.Errorf("Could not assign deposits: %s", response.Error) - } - return response, nil + return c.callAPI[api.AssignDepositsResponse]("POST", "/api/queue/assign-deposits", url.Values{"max": {fmt.Sprintf("%d", m)}}, "Could not assign deposits") } func (c *Client) GetQueueDetails() (api.GetQueueDetailsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/queue/get-queue-details", nil) - if err != nil { - return api.GetQueueDetailsResponse{}, fmt.Errorf("Could not get total queue length: %w", err) - } - var response api.GetQueueDetailsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.GetQueueDetailsResponse{}, fmt.Errorf("Could not decode get total queue length response: %w", err) - } - if response.Error != "" { - return api.GetQueueDetailsResponse{}, fmt.Errorf("Could not get total queue length: %s", response.Error) - } - return response, nil + return c.callAPI[api.GetQueueDetailsResponse]("GET", "/api/queue/get-queue-details", nil, "Could not get total queue length") } diff --git a/shared/services/rocketpool/security.go b/shared/services/rocketpool/security.go index 45bc9c2c8..e17622a3d 100644 --- a/shared/services/rocketpool/security.go +++ b/shared/services/rocketpool/security.go @@ -4,153 +4,52 @@ import ( "fmt" "net/url" - "github.com/goccy/go-json" - "github.com/rocket-pool/smartnode/shared/types/api" ) // Get security council status func (c *Client) SecurityStatus() (api.SecurityStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/status", nil) - if err != nil { - return api.SecurityStatusResponse{}, fmt.Errorf("Could not get security council status: %w", err) - } - var response api.SecurityStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityStatusResponse{}, fmt.Errorf("Could not decode security council stats response: %w", err) - } - if response.Error != "" { - return api.SecurityStatusResponse{}, fmt.Errorf("Could not get security council status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityStatusResponse]("GET", "/api/security/status", nil, "Could not get security council status") } // Get the security council members func (c *Client) SecurityMembers() (api.SecurityMembersResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/members", nil) - if err != nil { - return api.SecurityMembersResponse{}, fmt.Errorf("Could not get security council members: %w", err) - } - var response api.SecurityMembersResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityMembersResponse{}, fmt.Errorf("Could not decode security council members response: %w", err) - } - if response.Error != "" { - return api.SecurityMembersResponse{}, fmt.Errorf("Could not get security council members: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityMembersResponse]("GET", "/api/security/members", nil, "Could not get security council members") } // Get the security council proposals func (c *Client) SecurityProposals() (api.SecurityProposalsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/proposals", nil) - if err != nil { - return api.SecurityProposalsResponse{}, fmt.Errorf("Could not get security council proposals: %w", err) - } - var response api.SecurityProposalsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityProposalsResponse{}, fmt.Errorf("Could not decode security council proposals response: %w", err) - } - if response.Error != "" { - return api.SecurityProposalsResponse{}, fmt.Errorf("Could not get security council proposals: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityProposalsResponse]("GET", "/api/security/proposals", nil, "Could not get security council proposals") } // Get details of a proposal func (c *Client) SecurityProposal(id uint64) (api.SecurityProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/proposal-details", url.Values{"id": {fmt.Sprintf("%d", id)}}) - if err != nil { - return api.SecurityProposalResponse{}, fmt.Errorf("Could not get security council proposal: %w", err) - } - var response api.SecurityProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityProposalResponse{}, fmt.Errorf("Could not decode security council proposal response: %w", err) - } - if response.Error != "" { - return api.SecurityProposalResponse{}, fmt.Errorf("Could not get security council proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityProposalResponse]("GET", "/api/security/proposal-details", url.Values{"id": {fmt.Sprintf("%d", id)}}, "Could not get security council proposal") } // Check whether the node can propose to leave the security council func (c *Client) SecurityProposeLeave() (api.SecurityProposeLeaveResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/security/propose-leave", nil) - if err != nil { - return api.SecurityProposeLeaveResponse{}, fmt.Errorf("Could not get security-propose-leave status: %w", err) - } - var response api.SecurityProposeLeaveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityProposeLeaveResponse{}, fmt.Errorf("Could not decode security-propose-leave response: %w", err) - } - if response.Error != "" { - return api.SecurityProposeLeaveResponse{}, fmt.Errorf("Could not get security-propose-leave status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityProposeLeaveResponse]("POST", "/api/security/propose-leave", nil, "Could not get security-propose-leave status") } // Check whether the node can propose leaving the security council func (c *Client) SecurityCanProposeLeave() (api.SecurityCanProposeLeaveResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/can-propose-leave", nil) - if err != nil { - return api.SecurityCanProposeLeaveResponse{}, fmt.Errorf("Could not get security-can-propose-leave status: %w", err) - } - var response api.SecurityCanProposeLeaveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCanProposeLeaveResponse{}, fmt.Errorf("Could not decode security-can-propose-leave response: %w", err) - } - if response.Error != "" { - return api.SecurityCanProposeLeaveResponse{}, fmt.Errorf("Could not get security-can-propose-leave status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityCanProposeLeaveResponse]("GET", "/api/security/can-propose-leave", nil, "Could not get security-can-propose-leave status") } // Check whether the node can cancel a proposal func (c *Client) SecurityCanCancelProposal(proposalId uint64) (api.SecurityCanCancelProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/can-cancel-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}) - if err != nil { - return api.SecurityCanCancelProposalResponse{}, fmt.Errorf("Could not get security-can-cancel-proposal status: %w", err) - } - var response api.SecurityCanCancelProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCanCancelProposalResponse{}, fmt.Errorf("Could not decode security-can-cancel-proposal response: %w", err) - } - if response.Error != "" { - return api.SecurityCanCancelProposalResponse{}, fmt.Errorf("Could not get security-can-cancel-proposal status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityCanCancelProposalResponse]("GET", "/api/security/can-cancel-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}, "Could not get security-can-cancel-proposal status") } // Cancel a proposal made by the node func (c *Client) SecurityCancelProposal(proposalId uint64) (api.SecurityCancelProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/security/cancel-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}) - if err != nil { - return api.SecurityCancelProposalResponse{}, fmt.Errorf("Could not cancel security council proposal: %w", err) - } - var response api.SecurityCancelProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCancelProposalResponse{}, fmt.Errorf("Could not decode cancel security council proposal response: %w", err) - } - if response.Error != "" { - return api.SecurityCancelProposalResponse{}, fmt.Errorf("Could not cancel security council proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityCancelProposalResponse]("POST", "/api/security/cancel-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}, "Could not cancel security council proposal") } // Check whether the node can vote on a proposal func (c *Client) SecurityCanVoteOnProposal(proposalId uint64) (api.SecurityCanVoteOnProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/can-vote-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}) - if err != nil { - return api.SecurityCanVoteOnProposalResponse{}, fmt.Errorf("Could not get security-can-vote-on-proposal status: %w", err) - } - var response api.SecurityCanVoteOnProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCanVoteOnProposalResponse{}, fmt.Errorf("Could not decode security-can-vote-on-proposal response: %w", err) - } - if response.Error != "" { - return api.SecurityCanVoteOnProposalResponse{}, fmt.Errorf("Could not get security-can-vote-on-proposal status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityCanVoteOnProposalResponse]("GET", "/api/security/can-vote-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}, "Could not get security-can-vote-on-proposal status") } // Vote on a proposal @@ -159,155 +58,56 @@ func (c *Client) SecurityVoteOnProposal(proposalId uint64, support bool) (api.Se if support { supportStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/security/vote-proposal", url.Values{ + return c.callAPI[api.SecurityVoteOnProposalResponse]("POST", "/api/security/vote-proposal", url.Values{ "id": {fmt.Sprintf("%d", proposalId)}, "support": {supportStr}, - }) - if err != nil { - return api.SecurityVoteOnProposalResponse{}, fmt.Errorf("Could not vote on security council proposal: %w", err) - } - var response api.SecurityVoteOnProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityVoteOnProposalResponse{}, fmt.Errorf("Could not decode vote on security council proposal response: %w", err) - } - if response.Error != "" { - return api.SecurityVoteOnProposalResponse{}, fmt.Errorf("Could not vote on security council proposal: %s", response.Error) - } - return response, nil + }, "Could not vote on security council proposal") } // Check whether the node can execute a proposal func (c *Client) SecurityCanExecuteProposal(proposalId uint64) (api.SecurityCanExecuteProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/can-execute-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}) - if err != nil { - return api.SecurityCanExecuteProposalResponse{}, fmt.Errorf("Could not get security-can-execute-proposal status: %w", err) - } - var response api.SecurityCanExecuteProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCanExecuteProposalResponse{}, fmt.Errorf("Could not decode security-can-execute-proposal response: %w", err) - } - if response.Error != "" { - return api.SecurityCanExecuteProposalResponse{}, fmt.Errorf("Could not get security-can-execute-proposal status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityCanExecuteProposalResponse]("GET", "/api/security/can-execute-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}, "Could not get security-can-execute-proposal status") } // Execute a proposal func (c *Client) SecurityExecuteProposal(proposalId uint64) (api.SecurityExecuteProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/security/execute-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}) - if err != nil { - return api.SecurityExecuteProposalResponse{}, fmt.Errorf("Could not execute security council proposal: %w", err) - } - var response api.SecurityExecuteProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityExecuteProposalResponse{}, fmt.Errorf("Could not decode execute security council proposal response: %w", err) - } - if response.Error != "" { - return api.SecurityExecuteProposalResponse{}, fmt.Errorf("Could not execute security council proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityExecuteProposalResponse]("POST", "/api/security/execute-proposal", url.Values{"id": {fmt.Sprintf("%d", proposalId)}}, "Could not execute security council proposal") } // Check whether the node can join the security council func (c *Client) SecurityCanJoin() (api.SecurityCanJoinResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/can-join", nil) - if err != nil { - return api.SecurityCanJoinResponse{}, fmt.Errorf("Could not get security-can-join status: %w", err) - } - var response api.SecurityCanJoinResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCanJoinResponse{}, fmt.Errorf("Could not decode security-can-join response: %w", err) - } - if response.Error != "" { - return api.SecurityCanJoinResponse{}, fmt.Errorf("Could not get security-can-join status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityCanJoinResponse]("GET", "/api/security/can-join", nil, "Could not get security-can-join status") } // Join the security council (requires an executed invite proposal) func (c *Client) SecurityJoin() (api.SecurityJoinResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/security/join", nil) - if err != nil { - return api.SecurityJoinResponse{}, fmt.Errorf("Could not join security council: %w", err) - } - var response api.SecurityJoinResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityJoinResponse{}, fmt.Errorf("Could not decode join security council response: %w", err) - } - if response.Error != "" { - return api.SecurityJoinResponse{}, fmt.Errorf("Could not join security council: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityJoinResponse]("POST", "/api/security/join", nil, "Could not join security council") } // Check whether the node can leave the security council func (c *Client) SecurityCanLeave() (api.SecurityCanLeaveResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/can-leave", nil) - if err != nil { - return api.SecurityCanLeaveResponse{}, fmt.Errorf("Could not get security-can-leave status: %w", err) - } - var response api.SecurityCanLeaveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCanLeaveResponse{}, fmt.Errorf("Could not decode security-can-leave response: %w", err) - } - if response.Error != "" { - return api.SecurityCanLeaveResponse{}, fmt.Errorf("Could not get security-can-leave status: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityCanLeaveResponse]("GET", "/api/security/can-leave", nil, "Could not get security-can-leave status") } // Leave the security council (requires an executed leave proposal) func (c *Client) SecurityLeave() (api.SecurityLeaveResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/security/leave", nil) - if err != nil { - return api.SecurityLeaveResponse{}, fmt.Errorf("Could not leave security council: %w", err) - } - var response api.SecurityLeaveResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityLeaveResponse{}, fmt.Errorf("Could not decode leave security council response: %w", err) - } - if response.Error != "" { - return api.SecurityLeaveResponse{}, fmt.Errorf("Could not leave security council: %s", response.Error) - } - return response, nil + return c.callAPI[api.SecurityLeaveResponse]("POST", "/api/security/leave", nil, "Could not leave security council") } // Check whether the node can propose updating a PDAO setting func (c *Client) SecurityCanProposeSetting(contract string, setting string, value string) (api.SecurityCanProposeSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/security/can-propose-setting", url.Values{ + return c.callAPI[api.SecurityCanProposeSettingResponse]("GET", "/api/security/can-propose-setting", url.Values{ "contractName": {contract}, "settingName": {setting}, "value": {value}, - }) - if err != nil { - return api.SecurityCanProposeSettingResponse{}, fmt.Errorf("Could not get security-can-propose-setting: %w", err) - } - var response api.SecurityCanProposeSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityCanProposeSettingResponse{}, fmt.Errorf("Could not decode security-can-propose-setting response: %w", err) - } - if response.Error != "" { - return api.SecurityCanProposeSettingResponse{}, fmt.Errorf("Could not get security-can-propose-setting: %s", response.Error) - } - return response, nil + }, "Could not get security-can-propose-setting") } // Propose updating a PDAO setting func (c *Client) SecurityProposeSetting(contract string, setting string, value string) (api.SecurityProposeSettingResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/security/propose-setting", url.Values{ + return c.callAPI[api.SecurityProposeSettingResponse]("POST", "/api/security/propose-setting", url.Values{ "contractName": {contract}, "settingName": {setting}, "value": {value}, - }) - if err != nil { - return api.SecurityProposeSettingResponse{}, fmt.Errorf("Could not propose security council setting: %w", err) - } - var response api.SecurityProposeSettingResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SecurityProposeSettingResponse{}, fmt.Errorf("Could not decode propose security council setting response: %w", err) - } - if response.Error != "" { - return api.SecurityProposeSettingResponse{}, fmt.Errorf("Could not propose security council setting: %s", response.Error) - } - return response, nil + }, "Could not propose security council setting") } diff --git a/shared/services/rocketpool/service.go b/shared/services/rocketpool/service.go index 1adc4c182..6d3f0f3d0 100644 --- a/shared/services/rocketpool/service.go +++ b/shared/services/rocketpool/service.go @@ -1,58 +1,21 @@ package rocketpool import ( - "fmt" - - "github.com/goccy/go-json" - "github.com/rocket-pool/smartnode/shared/types/api" ) // Deletes the data folder including the wallet file, password file, and all validator keys. // Don't use this unless you have a very good reason to do it (such as switching from a Testnet to Mainnet). func (c *Client) TerminateDataFolder() (api.TerminateDataFolderResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/service/terminate-data-folder", nil) - if err != nil { - return api.TerminateDataFolderResponse{}, fmt.Errorf("Could not delete data folder: %w", err) - } - var response api.TerminateDataFolderResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.TerminateDataFolderResponse{}, fmt.Errorf("Could not decode terminate-data-folder response: %w", err) - } - if response.Error != "" { - return api.TerminateDataFolderResponse{}, fmt.Errorf("Could not delete data folder: %s", response.Error) - } - return response, nil + return c.callAPI[api.TerminateDataFolderResponse]("POST", "/api/service/terminate-data-folder", nil, "Could not delete data folder") } // Gets the status of the configured Execution and Beacon clients func (c *Client) GetClientStatus() (api.ClientStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/service/get-client-status", nil) - if err != nil { - return api.ClientStatusResponse{}, fmt.Errorf("Could not get client status: %w", err) - } - var response api.ClientStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ClientStatusResponse{}, fmt.Errorf("Could not decode client status response: %w", err) - } - if response.Error != "" { - return api.ClientStatusResponse{}, fmt.Errorf("Could not get client status: %s", response.Error) - } - return response, nil + return c.callAPI[api.ClientStatusResponse]("GET", "/api/service/get-client-status", nil, "Could not get client status") } // Restarts the Validator client func (c *Client) RestartVc() (api.RestartVcResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/service/restart-vc", nil) - if err != nil { - return api.RestartVcResponse{}, fmt.Errorf("Could not get restart-vc status: %w", err) - } - var response api.RestartVcResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RestartVcResponse{}, fmt.Errorf("Could not decode restart-vc response: %w", err) - } - if response.Error != "" { - return api.RestartVcResponse{}, fmt.Errorf("Could not get restart-vc status: %s", response.Error) - } - return response, nil + return c.callAPI[api.RestartVcResponse]("POST", "/api/service/restart-vc", nil, "Could not get restart-vc status") } diff --git a/shared/services/rocketpool/upgrades.go b/shared/services/rocketpool/upgrades.go index b4ab7c53d..2298bb794 100644 --- a/shared/services/rocketpool/upgrades.go +++ b/shared/services/rocketpool/upgrades.go @@ -1,59 +1,23 @@ package rocketpool import ( - "fmt" "net/url" "strconv" - "github.com/goccy/go-json" - "github.com/rocket-pool/smartnode/shared/types/api" ) // Get upgrade proposals func (c *Client) TNDAOUpgradeProposals() (api.TNDAOGetUpgradeProposalsResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/upgrade/get-upgrade-proposals", nil) - if err != nil { - return api.TNDAOGetUpgradeProposalsResponse{}, fmt.Errorf("Could not get upgrade proposals: %w", err) - } - var response api.TNDAOGetUpgradeProposalsResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.TNDAOGetUpgradeProposalsResponse{}, fmt.Errorf("Could not decode upgrade proposals response: %w", err) - } - if response.Error != "" { - return api.TNDAOGetUpgradeProposalsResponse{}, fmt.Errorf("Could not get upgrade proposals: %s", response.Error) - } - return response, nil + return c.callAPI[api.TNDAOGetUpgradeProposalsResponse]("GET", "/api/upgrade/get-upgrade-proposals", nil, "Could not get upgrade proposals") } // Check whether the node can execute a proposal func (c *Client) CanExecuteUpgradeProposal(proposalId uint64) (api.CanExecuteUpgradeProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/upgrade/can-execute-upgrade", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}) - if err != nil { - return api.CanExecuteUpgradeProposalResponse{}, fmt.Errorf("Could not check whether the node can execute upgrade proposal: %w", err) - } - var response api.CanExecuteUpgradeProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.CanExecuteUpgradeProposalResponse{}, fmt.Errorf("Could not decode can execute upgrade proposal response: %w", err) - } - if response.Error != "" { - return api.CanExecuteUpgradeProposalResponse{}, fmt.Errorf("Could not check whether the node can execute upgrade proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.CanExecuteUpgradeProposalResponse]("GET", "/api/upgrade/can-execute-upgrade", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}, "Could not check whether the node can execute upgrade proposal") } // Execute a proposal func (c *Client) ExecuteUpgradeProposal(proposalId uint64) (api.ExecuteUpgradeProposalResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/upgrade/execute-upgrade", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}) - if err != nil { - return api.ExecuteUpgradeProposalResponse{}, fmt.Errorf("Could not execute upgrade proposal: %w", err) - } - var response api.ExecuteUpgradeProposalResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ExecuteUpgradeProposalResponse{}, fmt.Errorf("Could not decode execute upgrade proposal response: %w", err) - } - if response.Error != "" { - return api.ExecuteUpgradeProposalResponse{}, fmt.Errorf("Could not execute upgrade proposal: %s", response.Error) - } - return response, nil + return c.callAPI[api.ExecuteUpgradeProposalResponse]("POST", "/api/upgrade/execute-upgrade", url.Values{"id": {strconv.FormatUint(proposalId, 10)}}, "Could not execute upgrade proposal") } diff --git a/shared/services/rocketpool/wallet.go b/shared/services/rocketpool/wallet.go index d3f58974c..f3367294d 100644 --- a/shared/services/rocketpool/wallet.go +++ b/shared/services/rocketpool/wallet.go @@ -7,57 +7,23 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/goccy/go-json" "github.com/rocket-pool/smartnode/shared/types/api" ) // Get wallet status func (c *Client) WalletStatus() (api.WalletStatusResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/wallet/status", nil) - if err != nil { - return api.WalletStatusResponse{}, fmt.Errorf("Could not get wallet status: %w", err) - } - var response api.WalletStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.WalletStatusResponse{}, fmt.Errorf("Could not decode wallet status response: %w", err) - } - if response.Error != "" { - return api.WalletStatusResponse{}, fmt.Errorf("Could not get wallet status: %s", response.Error) - } - return response, nil + return c.callAPI[api.WalletStatusResponse]("GET", "/api/wallet/status", nil, "Could not get wallet status") } // Set wallet password func (c *Client) SetPassword(password string) (api.SetPasswordResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/set-password", url.Values{"password": {password}}) - if err != nil { - return api.SetPasswordResponse{}, fmt.Errorf("Could not set wallet password: %w", err) - } - var response api.SetPasswordResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetPasswordResponse{}, fmt.Errorf("Could not decode set wallet password response: %w", err) - } - if response.Error != "" { - return api.SetPasswordResponse{}, fmt.Errorf("Could not set wallet password: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetPasswordResponse]("POST", "/api/wallet/set-password", url.Values{"password": {password}}, "Could not set wallet password") } // Initialize wallet func (c *Client) InitWallet(derivationPath string) (api.InitWalletResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/init", url.Values{"derivationPath": {derivationPath}}) - if err != nil { - return api.InitWalletResponse{}, fmt.Errorf("Could not initialize wallet: %w", err) - } - var response api.InitWalletResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.InitWalletResponse{}, fmt.Errorf("Could not decode initialize wallet response: %w", err) - } - if response.Error != "" { - return api.InitWalletResponse{}, fmt.Errorf("Could not initialize wallet: %s", response.Error) - } - return response, nil + return c.callAPI[api.InitWalletResponse]("POST", "/api/wallet/init", url.Values{"derivationPath": {derivationPath}}, "Could not initialize wallet") } // Recover wallet @@ -66,23 +32,12 @@ func (c *Client) RecoverWallet(mnemonic string, skipValidatorKeyRecovery bool, d if skipValidatorKeyRecovery { skipStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/recover", url.Values{ + return c.callAPI[api.RecoverWalletResponse]("POST", "/api/wallet/recover", url.Values{ "mnemonic": {mnemonic}, "skipValidatorKeyRecovery": {skipStr}, "derivationPath": {derivationPath}, "walletIndex": {fmt.Sprintf("%d", walletIndex)}, - }) - if err != nil { - return api.RecoverWalletResponse{}, fmt.Errorf("Could not recover wallet: %w", err) - } - var response api.RecoverWalletResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RecoverWalletResponse{}, fmt.Errorf("Could not decode recover wallet response: %w", err) - } - if response.Error != "" { - return api.RecoverWalletResponse{}, fmt.Errorf("Could not recover wallet: %s", response.Error) - } - return response, nil + }, "Could not recover wallet") } // Search and recover wallet @@ -91,22 +46,11 @@ func (c *Client) SearchAndRecoverWallet(mnemonic string, address common.Address, if skipValidatorKeyRecovery { skipStr = "true" } - responseBytes, err := c.callHTTPAPICtx(context.Background(), "POST", "/api/wallet/search-and-recover", url.Values{ + return c.callAPICtx[api.SearchAndRecoverWalletResponse](context.Background(), "POST", "/api/wallet/search-and-recover", url.Values{ "mnemonic": {mnemonic}, "address": {address.Hex()}, "skipValidatorKeyRecovery": {skipStr}, - }) - if err != nil { - return api.SearchAndRecoverWalletResponse{}, fmt.Errorf("Could not search and recover wallet: %w", err) - } - var response api.SearchAndRecoverWalletResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SearchAndRecoverWalletResponse{}, fmt.Errorf("Could not decode search-and-recover wallet response: %w", err) - } - if response.Error != "" { - return api.SearchAndRecoverWalletResponse{}, fmt.Errorf("Could not search and recover wallet: %s", response.Error) - } - return response, nil + }, "Could not search and recover wallet") } // Recover wallet (test, no save) @@ -115,23 +59,12 @@ func (c *Client) TestRecoverWallet(mnemonic string, skipValidatorKeyRecovery boo if skipValidatorKeyRecovery { skipStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/test-recover", url.Values{ + return c.callAPI[api.RecoverWalletResponse]("POST", "/api/wallet/test-recover", url.Values{ "mnemonic": {mnemonic}, "skipValidatorKeyRecovery": {skipStr}, "derivationPath": {derivationPath}, "walletIndex": {fmt.Sprintf("%d", walletIndex)}, - }) - if err != nil { - return api.RecoverWalletResponse{}, fmt.Errorf("Could not test recover wallet: %w", err) - } - var response api.RecoverWalletResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RecoverWalletResponse{}, fmt.Errorf("Could not decode test recover wallet response: %w", err) - } - if response.Error != "" { - return api.RecoverWalletResponse{}, fmt.Errorf("Could not test recover wallet: %s", response.Error) - } - return response, nil + }, "Could not test recover wallet") } // Search and recover wallet (test, no save) @@ -140,105 +73,39 @@ func (c *Client) TestSearchAndRecoverWallet(mnemonic string, address common.Addr if skipValidatorKeyRecovery { skipStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/test-search-and-recover", url.Values{ + return c.callAPI[api.SearchAndRecoverWalletResponse]("POST", "/api/wallet/test-search-and-recover", url.Values{ "mnemonic": {mnemonic}, "address": {address.Hex()}, "skipValidatorKeyRecovery": {skipStr}, - }) - if err != nil { - return api.SearchAndRecoverWalletResponse{}, fmt.Errorf("Could not test search and recover wallet: %w", err) - } - var response api.SearchAndRecoverWalletResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SearchAndRecoverWalletResponse{}, fmt.Errorf("Could not decode test-search-and-recover wallet response: %w", err) - } - if response.Error != "" { - return api.SearchAndRecoverWalletResponse{}, fmt.Errorf("Could not test search and recover wallet: %s", response.Error) - } - return response, nil + }, "Could not test search and recover wallet") } // Rebuild wallet func (c *Client) RebuildWallet() (api.RebuildWalletResponse, error) { // removed timeout as large nodes were exceeding it - responseBytes, err := c.callHTTPAPICtx(context.Background(), "POST", "/api/wallet/rebuild", nil) - if err != nil { - return api.RebuildWalletResponse{}, fmt.Errorf("Could not rebuild wallet: %w", err) - } - var response api.RebuildWalletResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.RebuildWalletResponse{}, fmt.Errorf("Could not decode rebuild wallet response: %w", err) - } - if response.Error != "" { - return api.RebuildWalletResponse{}, fmt.Errorf("Could not rebuild wallet: %s", response.Error) - } - return response, nil + return c.callAPICtx[api.RebuildWalletResponse](context.Background(), "POST", "/api/wallet/rebuild", nil, "Could not rebuild wallet") } // Get the status of any validator key recovery currently running func (c *Client) GetKeyRecoveryStatus() (api.KeyRecoveryStatusResponse, error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - responseBytes, err := c.callHTTPAPICtx(ctx, "GET", "/api/wallet/recovery-status", nil) - if err != nil { - return api.KeyRecoveryStatusResponse{}, fmt.Errorf("Could not get key recovery status: %w", err) - } - var response api.KeyRecoveryStatusResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.KeyRecoveryStatusResponse{}, fmt.Errorf("Could not decode key recovery status response: %w", err) - } - if response.Error != "" { - return api.KeyRecoveryStatusResponse{}, fmt.Errorf("Could not get key recovery status: %s", response.Error) - } - return response, nil + return c.callAPICtx[api.KeyRecoveryStatusResponse](ctx, "GET", "/api/wallet/recovery-status", nil, "Could not get key recovery status") } // Estimate the gas required to set an ENS reverse record to a name func (c *Client) EstimateGasSetEnsName(name string) (api.SetEnsNameResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/wallet/estimate-gas-set-ens-name", url.Values{"name": {name}}) - if err != nil { - return api.SetEnsNameResponse{}, fmt.Errorf("Could not get estimate-gas-set-ens-name response: %w", err) - } - var response api.SetEnsNameResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetEnsNameResponse{}, fmt.Errorf("Could not decode estimate-gas-set-ens-name response: %w", err) - } - if response.Error != "" { - return api.SetEnsNameResponse{}, fmt.Errorf("Could not get estimate-gas-set-ens-name response: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetEnsNameResponse]("GET", "/api/wallet/estimate-gas-set-ens-name", url.Values{"name": {name}}, "Could not get estimate-gas-set-ens-name response") } // Set an ENS reverse record to a name func (c *Client) SetEnsName(name string) (api.SetEnsNameResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/set-ens-name", url.Values{"name": {name}}) - if err != nil { - return api.SetEnsNameResponse{}, fmt.Errorf("Could not update ENS record: %w", err) - } - var response api.SetEnsNameResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.SetEnsNameResponse{}, fmt.Errorf("Could not decode set-ens-name response: %w", err) - } - if response.Error != "" { - return api.SetEnsNameResponse{}, fmt.Errorf("Could not update ENS record: %s", response.Error) - } - return response, nil + return c.callAPI[api.SetEnsNameResponse]("POST", "/api/wallet/set-ens-name", url.Values{"name": {name}}, "Could not update ENS record") } // Export wallet func (c *Client) ExportWallet() (api.ExportWalletResponse, error) { - responseBytes, err := c.callHTTPAPI("GET", "/api/wallet/export", nil) - if err != nil { - return api.ExportWalletResponse{}, fmt.Errorf("Could not export wallet: %w", err) - } - var response api.ExportWalletResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.ExportWalletResponse{}, fmt.Errorf("Could not decode export wallet response: %w", err) - } - if response.Error != "" { - return api.ExportWalletResponse{}, fmt.Errorf("Could not export wallet: %s", response.Error) - } - return response, nil + return c.callAPI[api.ExportWalletResponse]("GET", "/api/wallet/export", nil, "Could not export wallet") } // Set the node address to an arbitrary address @@ -247,32 +114,10 @@ func (c *Client) Masquerade(address common.Address, observe bool) (api.Masquerad if observe { observeStr = "true" } - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/masquerade", url.Values{"address": {address.Hex()}, "observe": {observeStr}}) - if err != nil { - return api.MasqueradeResponse{}, fmt.Errorf("Could not masquerade wallet: %w", err) - } - var response api.MasqueradeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.MasqueradeResponse{}, fmt.Errorf("Could not decode masquerade wallet response: %w", err) - } - if response.Error != "" { - return api.MasqueradeResponse{}, fmt.Errorf("Could not masquerade wallet: %s", response.Error) - } - return response, nil + return c.callAPI[api.MasqueradeResponse]("POST", "/api/wallet/masquerade", url.Values{"address": {address.Hex()}, "observe": {observeStr}}, "Could not masquerade wallet") } // Delete the address file, ending a masquerade func (c *Client) EndMasquerade() (api.EndMasqueradeResponse, error) { - responseBytes, err := c.callHTTPAPI("POST", "/api/wallet/end-masquerade", nil) - if err != nil { - return api.EndMasqueradeResponse{}, fmt.Errorf("Could not end masquerade: %w", err) - } - var response api.EndMasqueradeResponse - if err := json.Unmarshal(responseBytes, &response); err != nil { - return api.EndMasqueradeResponse{}, fmt.Errorf("Could not decode end masquerade response: %w", err) - } - if response.Error != "" { - return api.EndMasqueradeResponse{}, fmt.Errorf("Could not end masquerade: %s", response.Error) - } - return response, nil + return c.callAPI[api.EndMasqueradeResponse]("POST", "/api/wallet/end-masquerade", nil, "Could not end masquerade") } diff --git a/shared/types/api/api.go b/shared/types/api/api.go index 897901daf..4ce170ba1 100644 --- a/shared/types/api/api.go +++ b/shared/types/api/api.go @@ -1,6 +1,11 @@ package api +// APIResponse is the common envelope for Smart Node HTTP API replies. +// Concrete response types embed it so JSON field names stay `status` and `error`. type APIResponse struct { Status string `json:"status"` Error string `json:"error"` } + +// APIError returns the API error string, or empty if the call succeeded. +func (r APIResponse) APIError() string { return r.Error } diff --git a/shared/types/api/auction.go b/shared/types/api/auction.go index 4bdb61790..d903ae653 100644 --- a/shared/types/api/auction.go +++ b/shared/types/api/auction.go @@ -10,8 +10,7 @@ import ( ) type AuctionStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TotalRPLBalance *big.Int `json:"totalRPLBalance"` AllottedRPLBalance *big.Int `json:"allottedRPLBalance"` RemainingRPLBalance *big.Int `json:"remainingRPLBalance"` @@ -24,9 +23,8 @@ type AuctionStatusResponse struct { } type AuctionLotsResponse struct { - Status string `json:"status"` - Error string `json:"error"` - Lots []LotDetails `json:"lots"` + APIResponse + Lots []LotDetails `json:"lots"` } type LotDetails struct { Details auction.LotDetails `json:"details"` @@ -36,23 +34,20 @@ type LotDetails struct { } type CanCreateLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanCreate bool `json:"canCreate"` InsufficientBalance bool `json:"insufficientBalance"` CreateLotDisabled bool `json:"createLotDisabled"` GasLimits gaslimit.Limits `json:"gasLimits"` } type CreateLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse LotId uint64 `json:"lotId"` TxHash common.Hash `json:"txHash"` } type CanBidOnLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanBid bool `json:"canBid"` DoesNotExist bool `json:"doesNotExist"` BiddingEnded bool `json:"biddingEnded"` @@ -61,14 +56,12 @@ type CanBidOnLotResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type BidOnLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanClaimFromLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanClaim bool `json:"canClaim"` DoesNotExist bool `json:"doesNotExist"` NoBidFromAddress bool `json:"noBidFromAddress"` @@ -76,14 +69,12 @@ type CanClaimFromLotResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type ClaimFromLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanRecoverRPLFromLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanRecover bool `json:"canRecover"` DoesNotExist bool `json:"doesNotExist"` BiddingNotEnded bool `json:"biddingNotEnded"` @@ -92,7 +83,6 @@ type CanRecoverRPLFromLotResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type RecoverRPLFromLotResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } diff --git a/shared/types/api/debug.go b/shared/types/api/debug.go index a38621b9d..3c5e0b2f9 100644 --- a/shared/types/api/debug.go +++ b/shared/types/api/debug.go @@ -1,8 +1,7 @@ package api type RewardsEventResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Found bool `json:"found"` Index string `json:"index"` ExecutionBlock string `json:"executionBlock"` diff --git a/shared/types/api/megapool.go b/shared/types/api/megapool.go index a15a4fad4..aff5ae461 100644 --- a/shared/types/api/megapool.go +++ b/shared/types/api/megapool.go @@ -15,8 +15,7 @@ import ( ) type MegapoolStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Megapool MegapoolDetails `json:"megapoolDetails"` LatestDelegate common.Address `json:"latestDelegate"` BeaconHead beacon.BeaconHead `json:"beaconHead"` @@ -82,8 +81,7 @@ type MegapoolValidatorDetails struct { } type MegapoolValidatorMapAndRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse MegapoolValidatorMap map[string][]MegapoolValidatorDetails `json:"megapoolValidatorMap"` TotalBeaconBalance *big.Int `json:"totalBeaconBalance"` NodeShareOfCLBalance *big.Int `json:"nodeShareOfCLBalance"` @@ -91,8 +89,7 @@ type MegapoolValidatorMapAndRewardsResponse struct { } type MegapoolRewardSplitResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse RewardSplit megapool.RewardSplit `json:"rewardSplit"` RefundValue *big.Int `json:"refundValue"` } @@ -105,49 +102,41 @@ type QueueDetails struct { } type MegapoolCanDelegateUpgradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type MegapoolDelegateUpgradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type MegapoolGetDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } type MegapoolCanSetUseLatestDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` MatchesCurrentSetting bool `json:"matchesCurrentSetting"` } type MegapoolSetUseLatestDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type MegapoolGetUseLatestDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` - Setting bool `json:"setting"` + APIResponse + Setting bool `json:"setting"` } type MegapoolGetEffectiveDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } type CanDistributeMegapoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse MegapoolAddress common.Address `json:"megapoolAddress"` MegapoolNotDeployed bool `json:"megapoolNotDeployed"` LastDistributionTime uint64 `json:"lastDistributionTime"` @@ -159,8 +148,7 @@ type CanDistributeMegapoolResponse struct { } type DistributeMegapoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } @@ -172,28 +160,24 @@ type ValidatorWithdrawableEpochProof struct { Witnesses [][32]byte } type GetNewValidatorBondRequirementResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse NewValidatorBondRequirement *big.Int `json:"newValidatorBondRequirement"` } type GetNodeMegapoolEthBondedResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse EthBonded *big.Int `json:"ethBonded"` } type LatestBlockWithdrawalsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Slot uint64 `json:"slot"` BlockNumber uint64 `json:"blockNumber"` Withdrawals []beacon.WithdrawalInfo `json:"withdrawals"` } type BeaconWithdrawalQueueEstimateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ExitQueueGwei uint64 `json:"exitQueueGwei"` ChurnPerEpochGwei uint64 `json:"churnPerEpochGwei"` SecondsPerEpoch uint64 `json:"secondsPerEpoch"` diff --git a/shared/types/api/minipool.go b/shared/types/api/minipool.go index 0fbf96859..c6ccbcde2 100644 --- a/shared/types/api/minipool.go +++ b/shared/types/api/minipool.go @@ -14,8 +14,7 @@ import ( ) type MinipoolStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Minipools []MinipoolDetails `json:"minipools"` LatestDelegate common.Address `json:"latestDelegate"` } @@ -64,80 +63,67 @@ type MinipoolBalanceDistributionDetails struct { } type CanRefundMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanRefund bool `json:"canRefund"` InsufficientRefundBalance bool `json:"insufficientRefundBalance"` GasLimits gaslimit.Limits `json:"gasLimits"` } type RefundMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanDissolveMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanDissolve bool `json:"canDissolve"` InvalidStatus bool `json:"invalidStatus"` GasLimits gaslimit.Limits `json:"gasLimits"` } type DissolveMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanExitMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` - CanExit bool `json:"canExit"` - InvalidStatus bool `json:"invalidStatus"` + APIResponse + CanExit bool `json:"canExit"` + InvalidStatus bool `json:"invalidStatus"` } type ExitMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type CanChangeWithdrawalCredentialsResponse struct { - Status string `json:"status"` - Error string `json:"error"` - CanChange bool `json:"canChange"` + APIResponse + CanChange bool `json:"canChange"` } type ChangeWithdrawalCredentialsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type ImportKeyResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type CanProcessWithdrawalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanWithdraw bool `json:"canWithdraw"` InvalidStatus bool `json:"invalidStatus"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProcessWithdrawalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanProcessWithdrawalAndFinaliseResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanWithdraw bool `json:"canWithdraw"` InvalidStatus bool `json:"invalidStatus"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProcessWithdrawalAndFinaliseResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } @@ -157,26 +143,22 @@ type MinipoolCloseDetails struct { } type GetMinipoolCloseDetailsForNodeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ExpressTicketsProvisioned bool `json:"expressTicketsProvisioned"` IsFeeDistributorInitialized bool `json:"isFeeDistributorInitialized"` Details []MinipoolCloseDetails `json:"details"` } type CloseMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type GetDistributeBalanceDetailsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Details []MinipoolBalanceDistributionDetails `json:"details"` } type CanDistributeBalanceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse MinipoolVersion uint8 `json:"minipoolVersion"` MinipoolStatus types.MinipoolStatus `json:"minipoolStatus"` Balance *big.Int `json:"balance"` @@ -184,109 +166,91 @@ type CanDistributeBalanceResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type EstimateDistributeBalanceGasResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type DistributeBalanceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanFinaliseMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type FinaliseMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanDelegateUpgradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse LatestDelegateAddress common.Address `json:"latestDelegateAddress"` GasLimits gaslimit.Limits `json:"gasLimits"` } type DelegateUpgradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanSetUseLatestDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type SetUseLatestDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanStakeMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanStake bool `json:"canStake"` GasLimits gaslimit.Limits `json:"gasLimits"` } type StakeMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanPromoteMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPromote bool `json:"canPromote"` GasLimits gaslimit.Limits `json:"gasLimits"` } type PromoteMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type GetUseLatestDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` - Setting bool `json:"setting"` + APIResponse + Setting bool `json:"setting"` } type GetDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } type GetPreviousDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } type GetEffectiveDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } type GetVanityArtifactsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse NodeAddress common.Address `json:"nodeAddress"` MinipoolFactoryAddress common.Address `json:"minipoolFactoryAddress"` InitHash common.Hash `json:"initHash"` } type CanBeginReduceBondAmountResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BondReductionDisabled bool `json:"bondReductionDisabled"` MinipoolVersionTooLow bool `json:"minipoolVersionTooLow"` Balance uint64 `json:"balance"` @@ -298,21 +262,18 @@ type CanBeginReduceBondAmountResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type BeginReduceBondAmountResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanReduceBondAmountResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse MinipoolVersion uint8 `json:"minipoolVersion"` CanReduce bool `json:"canReduce"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ReduceBondAmountResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } @@ -328,18 +289,15 @@ type MinipoolRescueDissolvedDetails struct { } type GetMinipoolRescueDissolvedDetailsForNodeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Details []MinipoolRescueDissolvedDetails `json:"details"` } type RescueDissolvedMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type GetBondReductionEnabledResponse struct { - Status string `json:"status"` - Error string `json:"error"` - BondReductionEnabled bool `json:"bondReductionEnabled"` + APIResponse + BondReductionEnabled bool `json:"bondReductionEnabled"` } diff --git a/shared/types/api/network.go b/shared/types/api/network.go index bec33ddab..c2fec42dd 100644 --- a/shared/types/api/network.go +++ b/shared/types/api/network.go @@ -7,8 +7,7 @@ import ( ) type NodeFeeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse NodeFee float64 `json:"nodeFee"` MinNodeFee float64 `json:"minNodeFee"` TargetNodeFee float64 `json:"targetNodeFee"` @@ -16,15 +15,13 @@ type NodeFeeResponse struct { } type RplPriceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse RplPrice *big.Int `json:"rplPrice"` RplPriceBlock uint64 `json:"rplPriceBlock"` } type NetworkStatsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TotalValueLocked float64 `json:"totalValueLocked"` DepositPoolBalance float64 `json:"depositPoolBalance"` MinipoolCapacity float64 `json:"minipoolCapacity"` @@ -58,23 +55,20 @@ type NetworkStatsResponse struct { } type NetworkTimezonesResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TimezoneCounts map[string]uint64 `json:"timezoneCounts"` TimezoneTotal uint64 `json:"timezoneTotal"` NodeTotal uint64 `json:"nodeTotal"` } type CanNetworkGenerateRewardsTreeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CurrentIndex uint64 `json:"currentIndex"` TreeFileExists bool `json:"treeFileExists"` } type NetworkGenerateRewardsTreeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type SnapshotResponseStruct struct { @@ -84,8 +78,7 @@ type SnapshotResponseStruct struct { } type NetworkDAOProposalsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse AccountAddress common.Address `json:"accountAddress"` AccountAddressFormatted string `json:"accountAddressFormatted"` TotalDelegatedVp *big.Int `json:"totalDelegateVp"` @@ -115,12 +108,10 @@ func (s *SnapshotResponseStruct) VoteCount() uint { } type DownloadRewardsFileResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type GetLatestDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } diff --git a/shared/types/api/node.go b/shared/types/api/node.go index dbc536ca1..218accdd0 100644 --- a/shared/types/api/node.go +++ b/shared/types/api/node.go @@ -16,8 +16,7 @@ import ( ) type NodeStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Warning string `json:"warning"` AccountAddress common.Address `json:"accountAddress"` AccountAddressFormatted string `json:"accountAddressFormatted"` @@ -161,59 +160,50 @@ func (n NodeAlert) ColorString() string { } type CanRegisterNodeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanRegister bool `json:"canRegister"` AlreadyRegistered bool `json:"alreadyRegistered"` RegistrationDisabled bool `json:"registrationDisabled"` GasLimits gaslimit.Limits `json:"gasLimits"` } type RegisterNodeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanProvisionExpressTicketsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanProvision bool `json:"canProvision"` AlreadyProvisioned bool `json:"alreadyProvisioned"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProvisionExpressTicketsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanSetNodePrimaryWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanSet bool `json:"canSet"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SetNodePrimaryWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanConfirmNodePrimaryWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanConfirm bool `json:"canConfirm"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ConfirmNodePrimaryWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanSetNodeRPLWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanSet bool `json:"canSet"` PrimaryAddressDiffers bool `json:"primaryAddressDiffers"` RPLAddressDiffers bool `json:"rplAddressDiffers"` @@ -221,169 +211,141 @@ type CanSetNodeRPLWithdrawalAddressResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type SetNodeRPLWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanConfirmNodeRPLWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanConfirm bool `json:"canConfirm"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ConfirmNodeRPLWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type GetNodePrimaryWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } type GetNodePendingPrimaryWithdrawalAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` } type CanSetNodeTimezoneResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanSet bool `json:"canSet"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SetNodeTimezoneResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeSwapRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanSwap bool `json:"canSwap"` InsufficientBalance bool `json:"insufficientBalance"` GasLimits gaslimit.Limits `json:"GasLimits"` } type NodeSwapRplApproveGasResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeSwapRplApproveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ApproveTxHash common.Hash `json:"approveTxHash"` } type NodeSwapRplSwapResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse SwapTxHash common.Hash `json:"swapTxHash"` } type NodeSwapRplAllowanceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Allowance *big.Int `json:"allowance"` } type CanNodeStakeRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanStake bool `json:"canStake"` InsufficientBalance bool `json:"insufficientBalance"` InConsensus bool `json:"inConsensus"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeStakeRplApproveGasResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeStakeRplApproveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ApproveTxHash common.Hash `json:"approveTxHash"` } type NodeStakeRplStakeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse StakeTxHash common.Hash `json:"stakeTxHash"` } type NodeStakeRplAllowanceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Allowance *big.Int `json:"allowance"` } type CanSetRplLockingAllowedResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanSet bool `json:"canSet"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SetRplLockingAllowedResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse SetTxHash common.Hash `json:"setTxHash"` } type CanSetStakeRplForAllowedResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanSet bool `json:"canSet"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SetStakeRplForAllowedResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse SetTxHash common.Hash `json:"setTxHash"` } type CanNodeWithdrawEthResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanWithdraw bool `json:"canWithdraw"` InsufficientBalance bool `json:"insufficientBalance"` HasDifferentWithdrawalAddress bool `json:"hasDifferentWithdrawalAddress"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeWithdrawEthResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeWithdrawCreditResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanWithdraw bool `json:"canWithdraw"` InsufficientBalance bool `json:"insufficientBalance"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeWithdrawCreditResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeUnstakeRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanUnstake bool `json:"canUnstake"` InsufficientBalance bool `json:"insufficientBalance"` HasDifferentRPLWithdrawalAddress bool `json:"hasDifferentRPLWithdrawalAddress"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeUnstakeRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeUnstakeLegacyRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanUnstake bool `json:"canUnstake"` InsufficientBalance bool `json:"insufficientBalance"` HasDifferentRPLWithdrawalAddress bool `json:"hasDifferentRPLWithdrawalAddress"` @@ -391,19 +353,16 @@ type CanNodeUnstakeLegacyRplResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeUnstakeLegacyRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type NodeWithdrawRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeWithdrawRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanWithdraw bool `json:"canWithdraw"` InsufficientBalance bool `json:"insufficientBalance"` UnstakingPeriodActive bool `json:"unstakingPeriodActive"` @@ -411,8 +370,7 @@ type CanNodeWithdrawRplResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type CanNodeWithdrawRplv1_3_1Response struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanWithdraw bool `json:"canWithdraw"` InsufficientBalance bool `json:"insufficientBalance"` BelowMaxRPLStake bool `json:"belowMaxRPLStake"` @@ -423,8 +381,7 @@ type CanNodeWithdrawRplv1_3_1Response struct { } type CanNodeDepositsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanDeposit bool `json:"canDeposit"` CreditBalance *big.Int `json:"creditBalance"` UsableCreditBalance *big.Int `json:"usableCreditBalance"` @@ -444,16 +401,14 @@ type CanNodeDepositsResponse struct { } type NodeDepositsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` ValidatorPubkeys []rptypes.ValidatorPubkey `json:"validatorPubkeys"` ScrubPeriod time.Duration `json:"scrubPeriod"` } type CanCreateVacantMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanDeposit bool `json:"canDeposit"` InsufficientRplStake bool `json:"insufficientRplStake"` InvalidAmount bool `json:"invalidAmount"` @@ -462,8 +417,7 @@ type CanCreateVacantMinipoolResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type CreateVacantMinipoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` MinipoolAddress common.Address `json:"minipoolAddress"` ScrubPeriod time.Duration `json:"scrubPeriod"` @@ -471,8 +425,7 @@ type CreateVacantMinipoolResponse struct { } type CanNodeSendResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Balance float64 `json:"balance"` TokenName string `json:"name"` TokenSymbol string `json:"symbol"` @@ -481,58 +434,49 @@ type CanNodeSendResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeSendResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeSendMessageResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeSendMessageResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeBurnResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanBurn bool `json:"canBurn"` InsufficientBalance bool `json:"insufficientBalance"` InsufficientCollateral bool `json:"insufficientCollateral"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeBurnResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type NodeSyncProgressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse EcStatus ClientManagerStatus `json:"ecStatus"` BcStatus ClientManagerStatus `json:"bcStatus"` } type CanNodeClaimRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse RplAmount *big.Int `json:"rplAmount"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeClaimRplResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type NodeRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse NodeRegistrationTime time.Time `json:"nodeRegistrationTime"` RewardsInterval time.Duration `json:"rewardsInterval"` LastCheckpoint time.Time `json:"lastCheckpoint"` @@ -554,8 +498,7 @@ type NodeRewardsResponse struct { } type DepositContractInfoResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse RPDepositContract common.Address `json:"rpDepositContract"` RPNetwork uint64 `json:"rpNetwork"` BeaconDepositContract common.Address `json:"beaconDepositContract"` @@ -564,43 +507,36 @@ type DepositContractInfoResponse struct { } type NodeSignResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse SignedData string `json:"signedData"` } type NodeIsFeeDistributorInitializedResponse struct { - Status string `json:"status"` - Error string `json:"error"` - IsInitialized bool `json:"isInitialized"` + APIResponse + IsInitialized bool `json:"isInitialized"` } type NodeInitializeFeeDistributorGasResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Distributor common.Address `json:"distributor"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeInitializeFeeDistributorResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type NodeCanDistributeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Balance *big.Int `json:"balance"` NodeShare float64 `json:"nodeShare"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeDistributeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type NodeGetRewardsInfoResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Registered bool `json:"registered"` ClaimedIntervals []uint64 `json:"claimedIntervals"` UnclaimedIntervals []rewards.IntervalInfo `json:"unclaimedIntervals"` @@ -617,46 +553,38 @@ type NodeGetRewardsInfoResponse struct { } type CanNodeClaimRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeClaimRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNodeClaimAndStakeRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type NodeClaimAndStakeRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type GetSmoothingPoolRegistrationStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse NodeRegistered bool `json:"nodeRegistered"` TimeLeftUntilChangeable time.Duration `json:"timeLeftUntilChangeable"` } type CanSetSmoothingPoolRegistrationStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type SetSmoothingPoolRegistrationStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type ResolveEnsNameResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` EnsName string `json:"ensName"` } @@ -676,9 +604,8 @@ type SnapshotProposal struct { Link string `json:"link"` } type SnapshotResponse struct { - Status string `json:"status"` - Error string `json:"error"` - Data struct { + APIResponse + Data struct { Proposals []SnapshotProposal `json:"proposals"` } } @@ -698,21 +625,18 @@ type SnapshotProposalVote struct { } `json:"proposal"` } type SnapshotVotedProposals struct { - Status string `json:"status"` - Error string `json:"error"` - Data struct { + APIResponse + Data struct { Votes []SnapshotProposalVote `json:"votes"` } `json:"data"` } type SmoothingRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse EthBalance *big.Int `json:"eth_balance"` } type CheckCollateralResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse EthBorrowed *big.Int `json:"ethBorrowed"` EthBorrowedLimit *big.Int `json:"ethBorrowedLimit"` PendingBorrowAmount *big.Int `json:"pendingBorrowAmount"` @@ -720,117 +644,99 @@ type CheckCollateralResponse struct { } type NodeEthBalanceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Balance *big.Int `json:"balance"` } type NodeAlertsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Alerts []NodeAlert `json:"alerts"` } type GetExpressTicketCountResponse struct { - Status string `json:"status"` - Error string `json:"error"` - Count uint64 `json:"count"` + APIResponse + Count uint64 `json:"count"` } type GetBondRequirementResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BondRequirement *big.Int `json:"bondRequirement"` } type GetExpressTicketsProvisionedResponse struct { - Status string `json:"status"` - Error string `json:"error"` - Provisioned bool `json:"provisioned"` + APIResponse + Provisioned bool `json:"provisioned"` } type CanClaimRefundResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanClaim bool `json:"canClaim"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ClaimRefundResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanReduceBondResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanReduceBond bool `json:"canReduceBond"` NotEnoughBond bool `json:"notEnoughBond"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ReduceBondResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanRepayDebtResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanRepay bool `json:"canRepay"` NotEnoughDebt bool `json:"notEnoughDebt"` NotEnoughBalance bool `json:"notEnoughBalance"` GasLimits gaslimit.Limits `json:"gasLimits"` } type RepayDebtResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanDissolveValidatorResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanDissolve bool `json:"canDissolve"` NotInPrestake bool `json:"notInPrestake"` GasLimits gaslimit.Limits `json:"gasLimits"` } type DissolveValidatorResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanDissolveWithProofResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanDissolve bool `json:"canDissolve"` NotInPrestake bool `json:"notInPrestake"` ValidCredentials bool `json:"validCredentials"` GasLimits gaslimit.Limits `json:"gasLimits"` } type DissolveWithProofResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanExitValidatorResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExit bool `json:"canExit"` InvalidStatus bool `json:"invalidStatus"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ExitValidatorResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNotifyValidatorExitResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExit bool `json:"canExit"` InvalidStatus bool `json:"invalidStatus"` AlreadyExiting bool `json:"alreadyExiting"` @@ -839,59 +745,50 @@ type CanNotifyValidatorExitResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type NotifyValidatorExitResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanNotifyFinalBalanceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExit bool `json:"canExit"` InvalidStatus bool `json:"invalidStatus"` GasLimits gaslimit.Limits `json:"gasLimits"` } type NotifyFinalBalanceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanStakeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanStake bool `json:"canStake"` IndexNotFound bool `json:"indexNotFound"` GasLimits gaslimit.Limits `json:"gasLimits"` } type StakeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanExitQueueResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExit bool `json:"canExit"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ExitQueueResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanClaimUnclaimedRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanClaim bool `json:"canClaim"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ClaimUnclaimedRewardsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } diff --git a/shared/types/api/odao.go b/shared/types/api/odao.go index ba554f0e2..031f25295 100644 --- a/shared/types/api/odao.go +++ b/shared/types/api/odao.go @@ -11,8 +11,7 @@ import ( ) type TNDAOStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse IsMember bool `json:"isMember"` CanJoin bool `json:"canJoin"` CanLeave bool `json:"canLeave"` @@ -31,86 +30,74 @@ type TNDAOStatusResponse struct { } type TNDAOMembersResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Members []tn.MemberDetails `json:"members"` } type TNDAOProposalsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Proposals []dao.ProposalDetails `json:"proposals"` } type TNDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Proposal dao.ProposalDetails `json:"proposal"` } type CanProposeTNDAOInviteResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` ProposalCooldownActive bool `json:"proposalCooldownActive"` MemberAlreadyExists bool `json:"memberAlreadyExists"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProposeTNDAOInviteResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type CanProposeTNDAOLeaveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` ProposalCooldownActive bool `json:"proposalCooldownActive"` InsufficientMembers bool `json:"insufficientMembers"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProposeTNDAOLeaveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type CanProposeTNDAOReplaceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` ProposalCooldownActive bool `json:"proposalCooldownActive"` MemberAlreadyExists bool `json:"memberAlreadyExists"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProposeTNDAOReplaceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type CanProposeTNDAOKickResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` ProposalCooldownActive bool `json:"proposalCooldownActive"` InsufficientRplBond bool `json:"insufficientRplBond"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProposeTNDAOKickResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type CanCancelTNDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanCancel bool `json:"canCancel"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` @@ -118,14 +105,12 @@ type CanCancelTNDAOProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type CancelTNDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanVoteOnTNDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanVote bool `json:"canVote"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` @@ -134,28 +119,24 @@ type CanVoteOnTNDAOProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type VoteOnTNDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanExecuteTNDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExecute bool `json:"canExecute"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ExecuteTNDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanExecuteTNDAOUpgradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExecute bool `json:"canExecute"` InvalidTrustedNode bool `json:"invalidTrustedNode"` DoesNotExist bool `json:"doesNotExist"` @@ -163,14 +144,12 @@ type CanExecuteTNDAOUpgradeResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type ExecuteTNDAOUpgradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanJoinTNDAOResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanJoin bool `json:"canJoin"` ProposalExpired bool `json:"proposalExpired"` AlreadyMember bool `json:"alreadyMember"` @@ -178,127 +157,107 @@ type CanJoinTNDAOResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type JoinTNDAOApproveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ApproveTxHash common.Hash `json:"approveTxHash"` } type JoinTNDAOJoinResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse JoinTxHash common.Hash `json:"joinTxHash"` } type CanLeaveTNDAOResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanLeave bool `json:"canLeave"` ProposalExpired bool `json:"proposalExpired"` InsufficientMembers bool `json:"insufficientMembers"` GasLimits gaslimit.Limits `json:"gasLimits"` } type LeaveTNDAOResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanReplaceTNDAOPositionResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanReplace bool `json:"canReplace"` ProposalExpired bool `json:"proposalExpired"` MemberAlreadyExists bool `json:"memberAlreadyExists"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ReplaceTNDAOPositionResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanProposeTNDAOSettingResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` ProposalCooldownActive bool `json:"proposalCooldownActive"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ProposeTNDAOSettingMembersQuorumResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingMembersRplBondResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingProposalCooldownResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingProposalVoteTimespanResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingProposalVoteDelayTimespanResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingProposalExecuteTimespanResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingProposalActionTimespanResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingScrubPeriodResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingPromotionScrubPeriodResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingScrubPenaltyEnabledResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingBondReductionWindowStartResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type ProposeTNDAOSettingBondReductionWindowLengthResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type GetTNDAOMemberSettingsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Quorum float64 `json:"quorum"` RPLBond *big.Int `json:"rplBond"` ChallengeCooldown uint64 `json:"challengeCooldown"` @@ -306,8 +265,7 @@ type GetTNDAOMemberSettingsResponse struct { ChallengeCost *big.Int `json:"challengeCost"` } type GetTNDAOProposalSettingsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Cooldown uint64 `json:"cooldown"` VoteTime uint64 `json:"voteTime"` VoteDelayTime uint64 `json:"voteDelayTime"` @@ -315,8 +273,7 @@ type GetTNDAOProposalSettingsResponse struct { ActionTime uint64 `json:"actionTime"` } type GetTNDAOMinipoolSettingsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ScrubPeriod uint64 `json:"scrubPeriod"` PromotionScrubPeriod uint64 `json:"promotionScrubPeriod"` ScrubPenaltyEnabled bool `json:"scrubPenaltyEnabled"` @@ -325,13 +282,11 @@ type GetTNDAOMinipoolSettingsResponse struct { } type CanPenaliseMegapoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPenalise bool `json:"canPenalise"` GasLimits gaslimit.Limits `json:"gasLimits"` } type PenaliseMegapoolResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } diff --git a/shared/types/api/pdao.go b/shared/types/api/pdao.go index 98f010f6a..075418eeb 100644 --- a/shared/types/api/pdao.go +++ b/shared/types/api/pdao.go @@ -18,20 +18,17 @@ type PDAOProposalWithNodeVoteDirection struct { } type PDAOProposalsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Proposals []PDAOProposalWithNodeVoteDirection `json:"proposals"` } type PDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Proposal PDAOProposalWithNodeVoteDirection `json:"proposal"` } type CanCancelPDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanCancel bool `json:"canCancel"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` @@ -39,14 +36,12 @@ type CanCancelPDAOProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type CancelPDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanVoteOnPDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanVote bool `json:"canVote"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` @@ -56,28 +51,24 @@ type CanVoteOnPDAOProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type VoteOnPDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type CanExecutePDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExecute bool `json:"canExecute"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` GasLimits gaslimit.Limits `json:"gasLimits"` } type ExecutePDAOProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type GetPDAOSettingsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Auction struct { IsCreateLotEnabled bool `json:"isCreateLotEnabled"` IsBidOnLotEnabled bool `json:"isBidOnLotEnabled"` @@ -191,8 +182,7 @@ type GetPDAOSettingsResponse struct { } type CanProposePDAOSettingResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` InsufficientRpl bool `json:"proposalCooldownActive"` StakedRpl *big.Int `json:"stakedRpl"` @@ -203,8 +193,7 @@ type CanProposePDAOSettingResponse struct { IsRplLockingDisallowed bool `json:"isRplLockingDisallowed"` } type ProposePDAOSettingResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } @@ -217,8 +206,7 @@ type PDAOBatchSetting struct { } type CanProposePDAOSettingMultiResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` InsufficientRpl bool `json:"proposalCooldownActive"` StakedRpl *big.Int `json:"stakedRpl"` @@ -230,23 +218,20 @@ type CanProposePDAOSettingMultiResponse struct { } type ProposePDAOSettingMultiResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOGetRewardsPercentagesResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Node *big.Int `json:"node"` OracleDao *big.Int `json:"odao"` ProtocolDao *big.Int `json:"pdao"` } type PDAOCanProposeRewardsPercentagesResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` CanPropose bool `json:"canPropose"` @@ -254,30 +239,26 @@ type PDAOCanProposeRewardsPercentagesResponse struct { } type PDAOProposeRewardsPercentagesResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOCanProposeOneTimeSpendResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` CanPropose bool `json:"canPropose"` IsRplLockingDisallowed bool `json:"isRplLockingDisallowed"` } type PDAOProposeOneTimeSpendResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOCanProposeRecurringSpendResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` CanPropose bool `json:"canPropose"` @@ -285,15 +266,13 @@ type PDAOCanProposeRecurringSpendResponse struct { } type PDAOProposeRecurringSpendResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOCanProposeRecurringSpendUpdateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` CanPropose bool `json:"canPropose"` @@ -301,15 +280,13 @@ type PDAOCanProposeRecurringSpendUpdateResponse struct { } type PDAOProposeRecurringSpendUpdateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOCanProposeInviteToSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` MemberAlreadyExists bool `json:"memberAlreadyExists"` BlockNumber uint32 `json:"blockNumber"` @@ -317,43 +294,37 @@ type PDAOCanProposeInviteToSecurityCouncilResponse struct { IsRplLockingDisallowed bool `json:"isRplLockingDisallowed"` } type PDAOProposeInviteToSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOCanProposeKickFromSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` CanPropose bool `json:"canPropose"` IsRplLockingDisallowed bool `json:"isRplLockingDisallowed"` } type PDAOProposeKickFromSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOCanProposeKickMultiFromSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` } type PDAOProposeKickMultiFromSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type PDAOCanProposeReplaceMemberOfSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` CanPropose bool `json:"canPropose"` @@ -361,8 +332,7 @@ type PDAOCanProposeReplaceMemberOfSecurityCouncilResponse struct { } type PDAOProposeReplaceMemberOfSecurityCouncilResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } @@ -377,14 +347,12 @@ type BondClaimResult struct { } type PDAOGetClaimableBondsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ClaimableBonds []BondClaimResult `json:"claimableBonds"` } type PDAOCanClaimBondsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse IsProposer bool `json:"isProposer"` CanClaim bool `json:"canClaim"` DoesNotExist bool `json:"doesNotExist"` @@ -392,14 +360,12 @@ type PDAOCanClaimBondsResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type PDAOClaimBondsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOCanDefeatProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanDefeat bool `json:"canDefeat"` DoesNotExist bool `json:"doesNotExist"` AlreadyDefeated bool `json:"alreadyDefeated"` @@ -408,14 +374,12 @@ type PDAOCanDefeatProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type PDAODefeatProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOCanFinalizeProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanFinalize bool `json:"canFinalize"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` @@ -423,65 +387,55 @@ type PDAOCanFinalizeProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type PDAOFinalizeProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOCanSetVotingDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` } type PDAOSetVotingDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOCurrentVotingDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse AccountAddress common.Address `json:"accountAddress"` VotingDelegate common.Address `json:"votingDelegate"` } type PDAOCanInitializeVotingWithDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse VotingInitialized bool `json:"votingInitialized"` GasLimits gaslimit.Limits `json:"gasLimits"` } type PDAOInitializeVotingWithDelegateResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOCanInitializeVotingResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse VotingInitialized bool `json:"votingInitialized"` GasLimits gaslimit.Limits `json:"gasLimits"` } type PDAOInitializeVotingResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOIsVotingInitializedResponse struct { - Status string `json:"status"` - Error string `json:"error"` - VotingInitialized bool `json:"votingInitialized"` + APIResponse + VotingInitialized bool `json:"votingInitialized"` } type PDAOStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse VotingPower *big.Int `json:"votingPower"` OnchainVotingDelegate common.Address `json:"onchainVotingDelegate"` OnchainVotingDelegateFormatted string `json:"onchainVotingDelegateFormatted"` @@ -500,43 +454,37 @@ type PDAOStatusResponse struct { } type PDAOCanSetSignallingAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` NodeToSigner common.Address `json:"nodeToSigner"` } type PDAOSetSignallingAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOCanClearSignallingAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasLimits gaslimit.Limits `json:"gasLimits"` VotingInitialized bool `json:"votingInitialized"` NodeToSigner common.Address `json:"nodeToSigner"` } type PDAOClearSignallingAddressResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type PDAOACanProposeAllowListedControllersResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse BlockNumber uint32 `json:"blockNumber"` GasLimits gaslimit.Limits `json:"gasLimits"` CanPropose bool `json:"canPropose"` IsRplLockingDisallowed bool `json:"isRplLockingDisallowed"` } type PDAOProposeAllowListedControllersResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } diff --git a/shared/types/api/queue.go b/shared/types/api/queue.go index 084a9e411..88f95ae55 100644 --- a/shared/types/api/queue.go +++ b/shared/types/api/queue.go @@ -8,16 +8,14 @@ import ( ) type QueueStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse DepositPoolBalance *big.Int `json:"depositPoolBalance"` MinipoolQueueLength uint64 `json:"minipoolQueueLength"` MinipoolQueueCapacity *big.Int `json:"minipoolQueueCapacity"` } type CanProcessQueueResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanProcess bool `json:"canProcess"` AssignDepositsDisabled bool `json:"assignDepositsDisabled"` NoMinipoolsAvailable bool `json:"noMinipoolsAvailable"` @@ -25,14 +23,12 @@ type CanProcessQueueResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type ProcessQueueResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type GetQueueDetailsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TotalLength uint32 `json:"totalLength"` ExpressLength uint32 `json:"expressLength"` StandardLength uint32 `json:"standardLength"` @@ -41,15 +37,13 @@ type GetQueueDetailsResponse struct { } type CanAssignDepositsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanAssign bool `json:"canAssign"` AssignDepositsDisabled bool `json:"assignDepositsDisabled"` GasLimits gaslimit.Limits `json:"gasLimits"` } type AssignDepositsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } diff --git a/shared/types/api/security.go b/shared/types/api/security.go index 545d45aee..ca442b327 100644 --- a/shared/types/api/security.go +++ b/shared/types/api/security.go @@ -9,8 +9,7 @@ import ( ) type SecurityStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse IsMember bool `json:"isMember"` CanJoin bool `json:"canJoin"` CanLeave bool `json:"canLeave"` @@ -28,107 +27,91 @@ type SecurityStatusResponse struct { } type SecurityMembersResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Members []security.SecurityDAOMemberDetails `json:"members"` } type SecurityProposalsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Proposals []dao.ProposalDetails `json:"proposals"` } type SecurityProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Proposal dao.ProposalDetails `json:"proposal"` } type SecurityCanProposeInviteResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` MemberAlreadyExists bool `json:"memberAlreadyExists"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityProposeInviteResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type SecurityCanProposeLeaveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` MemberDoesntExist bool `json:"memberDoesntExist"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityProposeLeaveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type SecurityCanProposeKickResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityProposeKickResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type SecurityCanProposeKickMultiResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityProposeKickMultiResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type SecurityCanProposeSettingResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityProposeSettingResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type SecurityCanProposeReplaceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanPropose bool `json:"canPropose"` OldMemberDoesntExist bool `json:"oldMemberDoesntExist"` NewMemberAlreadyExists bool `json:"newMemberAlreadyExists"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityProposeReplaceResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ProposalId uint64 `json:"proposalId"` TxHash common.Hash `json:"txHash"` } type SecurityCanCancelProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanCancel bool `json:"canCancel"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` @@ -136,14 +119,12 @@ type SecurityCanCancelProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityCancelProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type SecurityCanVoteOnProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanVote bool `json:"canVote"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` @@ -152,48 +133,41 @@ type SecurityCanVoteOnProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityVoteOnProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type SecurityCanExecuteProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExecute bool `json:"canExecute"` DoesNotExist bool `json:"doesNotExist"` InvalidState bool `json:"invalidState"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityExecuteProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type SecurityCanJoinResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanJoin bool `json:"canJoin"` ProposalExpired bool `json:"proposalExpired"` AlreadyMember bool `json:"alreadyMember"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityJoinResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } type SecurityCanLeaveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanLeave bool `json:"canLeave"` ProposalExpired bool `json:"proposalExpired"` GasLimits gaslimit.Limits `json:"gasLimits"` } type SecurityLeaveResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } diff --git a/shared/types/api/service.go b/shared/types/api/service.go index ede8bbe46..bb0f55097 100644 --- a/shared/types/api/service.go +++ b/shared/types/api/service.go @@ -7,19 +7,16 @@ import ( ) type GasPriceFromLatestBlockResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse GasPrice *big.Int `json:"gasPrice"` } type TerminateDataFolderResponse struct { - Status string `json:"status"` - Error string `json:"error"` - FolderExisted bool `json:"folderExisted"` + APIResponse + FolderExisted bool `json:"folderExisted"` } type CreateFeeRecipientFileResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Distributor common.Address `json:"distributor"` } @@ -40,13 +37,11 @@ type ClientManagerStatus struct { } type ClientStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse EcManagerStatus ClientManagerStatus `json:"ecManagerStatus"` BcManagerStatus ClientManagerStatus `json:"bcManagerStatus"` } type RestartVcResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } diff --git a/shared/types/api/upgrades.go b/shared/types/api/upgrades.go index 3f1b34222..b11ec3bb8 100644 --- a/shared/types/api/upgrades.go +++ b/shared/types/api/upgrades.go @@ -8,22 +8,19 @@ import ( ) type TNDAOUpgradeStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse UpgradeProposalCount uint64 `json:"upgradeProposalCount"` UpgradeProposalState string `json:"upgradeProposalState"` UpgradeProposalEndTime uint64 `json:"upgradeProposalEndTime"` } type TNDAOGetUpgradeProposalsResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Proposals []upgrades.UpgradeProposalDetails `json:"proposals"` } type CanExecuteUpgradeProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CanExecute bool `json:"canExecute"` DoesNotExist bool `json:"doesNotExist"` InvalidTrustedNode bool `json:"invalidTrustedNode"` @@ -31,7 +28,6 @@ type CanExecuteUpgradeProposalResponse struct { GasLimits gaslimit.Limits `json:"gasLimits"` } type ExecuteUpgradeProposalResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse TxHash common.Hash `json:"txHash"` } diff --git a/shared/types/api/wallet.go b/shared/types/api/wallet.go index 583cfd734..579b2347a 100644 --- a/shared/types/api/wallet.go +++ b/shared/types/api/wallet.go @@ -21,10 +21,9 @@ type ValidatorKeystore struct { } type WalletStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` - PasswordSet bool `json:"passwordSet"` - WalletInitialized bool `json:"walletInitialized"` + APIResponse + PasswordSet bool `json:"passwordSet"` + WalletInitialized bool `json:"walletInitialized"` // When masquerading, AccountAddress represents the masqueraded address. // When using a normal wallet, AccountAddress represents the address derived from the wallet stored on disk AccountAddress common.Address `json:"accountAddress"` @@ -35,27 +34,23 @@ type WalletStatusResponse struct { } type SetPasswordResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type InitWalletResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Mnemonic string `json:"mnemonic"` AccountAddress common.Address `json:"accountAddress"` } type RecoverWalletResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse AccountAddress common.Address `json:"accountAddress"` ValidatorKeys []types.ValidatorPubkey `json:"validatorKeys"` } type SearchAndRecoverWalletResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse FoundWallet bool `json:"foundWallet"` AccountAddress common.Address `json:"accountAddress"` DerivationPath string `json:"derivationPath"` @@ -64,8 +59,7 @@ type SearchAndRecoverWalletResponse struct { } type RebuildWalletResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse ValidatorKeys []types.ValidatorPubkey `json:"validatorKeys"` } @@ -81,22 +75,19 @@ type KeyRecoveryStatus struct { } type KeyRecoveryStatusResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Recovery KeyRecoveryStatus `json:"recovery"` } type ExportWalletResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Password string `json:"password"` Wallet string `json:"wallet"` AccountPrivateKey string `json:"accountPrivateKey"` } type SetEnsNameResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse Address common.Address `json:"address"` EnsName string `json:"ensName"` TxHash common.Hash `json:"txHash"` @@ -104,23 +95,19 @@ type SetEnsNameResponse struct { } type TestMnemonicResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse CurrentAddress common.Address `json:"currentAddress"` RecoveredAddress common.Address `json:"recoveredAddress"` } type PurgeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type MasqueradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } type EndMasqueradeResponse struct { - Status string `json:"status"` - Error string `json:"error"` + APIResponse } From 9a9b1c7d547eec83114fbb6373adcdfd45d31d1e Mon Sep 17 00:00:00 2001 From: Fornax <23104993+0xfornax@users.noreply.github.com> Date: Wed, 26 Aug 2026 19:20:57 -0300 Subject: [PATCH 2/2] Add loadAutoTxGas --- rocketpool/node/auto-tx-gas.go | 53 +++++++++++++++++++ rocketpool/node/auto-tx-gas_test.go | 52 ++++++++++++++++++ rocketpool/node/defend-challenge-exit.go | 28 ++-------- rocketpool/node/defend-pdao-props.go | 28 ++-------- rocketpool/node/distribute-minipools.go | 45 ++++------------ rocketpool/node/notify-final-balance.go | 28 ++-------- rocketpool/node/notify-validator-exit.go | 28 ++-------- .../node/prestake-megapool-validator.go | 29 ++-------- rocketpool/node/provision-express-tickets.go | 31 ++--------- rocketpool/node/set-latest-delegate.go | 28 ++-------- rocketpool/node/stake-megapool-validator.go | 28 ++-------- rocketpool/node/verify-pdao-props.go | 28 ++-------- 12 files changed, 153 insertions(+), 253 deletions(-) create mode 100644 rocketpool/node/auto-tx-gas.go create mode 100644 rocketpool/node/auto-tx-gas_test.go diff --git a/rocketpool/node/auto-tx-gas.go b/rocketpool/node/auto-tx-gas.go new file mode 100644 index 000000000..7fe9ec480 --- /dev/null +++ b/rocketpool/node/auto-tx-gas.go @@ -0,0 +1,53 @@ +package node + +import ( + "math/big" + + log "github.com/rocket-pool/smartnode/shared/logger" + "github.com/rocket-pool/smartnode/shared/math" + "github.com/rocket-pool/smartnode/shared/services/config" + rpgas "github.com/rocket-pool/smartnode/shared/services/gas" +) + +// autoTxGas is the node-task view of the Smartnode auto-tx gas settings. +type autoTxGas struct { + thresholdGwei float64 + maxFee *big.Int + maxPriorityFee *big.Int +} + +// loadAutoTxGas reads the auto-tx gas threshold, manual max fee, and priority +// fee from cfg. A missing or zero priority fee is replaced with the default +// and logged as a warning. A zero max fee is returned as a nil *big.Int so +// callers can fall back to oracle pricing. +func loadAutoTxGas(cfg *config.RocketPoolConfig, logger *log.ColorLogger) autoTxGas { + thresholdGwei := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) + + maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) + var maxFee *big.Int + if maxFeeGwei != 0 { + maxFee = math.GweiToWei(maxFeeGwei) + } + + priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) + var maxPriorityFee *big.Int + if priorityFeeGwei == 0 { + logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) + maxPriorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) + } else { + maxPriorityFee = math.GweiToWei(priorityFeeGwei) + } + + maxFeeGweiLog := 0.0 + if maxFee != nil { + maxFeeGweiLog = math.WeiToGwei(maxFee) + } + logger.Printlnf("Loaded auto-tx gas: threshold=%.4f gwei, maxFee=%.4f gwei (0=oracle), priorityFee=%.4f gwei", + thresholdGwei, maxFeeGweiLog, math.WeiToGwei(maxPriorityFee)) + + return autoTxGas{ + thresholdGwei: thresholdGwei, + maxFee: maxFee, + maxPriorityFee: maxPriorityFee, + } +} diff --git a/rocketpool/node/auto-tx-gas_test.go b/rocketpool/node/auto-tx-gas_test.go new file mode 100644 index 000000000..2b7ab548e --- /dev/null +++ b/rocketpool/node/auto-tx-gas_test.go @@ -0,0 +1,52 @@ +package node + +import ( + "testing" + + log "github.com/rocket-pool/smartnode/shared/logger" + "github.com/rocket-pool/smartnode/shared/math" + "github.com/rocket-pool/smartnode/shared/services/config" + rpgas "github.com/rocket-pool/smartnode/shared/services/gas" +) + +func TestLoadAutoTxGas(t *testing.T) { + cfg := &config.RocketPoolConfig{Smartnode: &config.SmartnodeConfig{}} + cfg.Smartnode.AutoTxGasThreshold.ID = "autoTx" + cfg.Smartnode.AutoTxGasThreshold.Value = 12.5 + cfg.Smartnode.ManualMaxFee.ID = "maxFee" + cfg.Smartnode.ManualMaxFee.Value = 30.0 + cfg.Smartnode.PriorityFee.ID = "prio" + cfg.Smartnode.PriorityFee.Value = 1.5 + + logger := log.NewColorLogger(0) + gas := loadAutoTxGas(cfg, &logger) + if gas.thresholdGwei != 12.5 { + t.Fatalf("threshold = %v, want 12.5", gas.thresholdGwei) + } + if gas.maxFee.Cmp(math.GweiToWei(30)) != 0 { + t.Fatalf("maxFee = %s, want 30 gwei", gas.maxFee) + } + if gas.maxPriorityFee.Cmp(math.GweiToWei(1.5)) != 0 { + t.Fatalf("maxPriorityFee = %s, want 1.5 gwei", gas.maxPriorityFee) + } +} + +func TestLoadAutoTxGasDefaults(t *testing.T) { + cfg := &config.RocketPoolConfig{Smartnode: &config.SmartnodeConfig{}} + cfg.Smartnode.AutoTxGasThreshold.Value = 0.0 + cfg.Smartnode.ManualMaxFee.Value = 0.0 + cfg.Smartnode.PriorityFee.Value = 0.0 + + logger := log.NewColorLogger(0) + gas := loadAutoTxGas(cfg, &logger) + if gas.thresholdGwei != 0 { + t.Fatalf("threshold = %v, want 0", gas.thresholdGwei) + } + if gas.maxFee != nil { + t.Fatalf("maxFee = %s, want nil", gas.maxFee) + } + wantPrio := math.GweiToWei(rpgas.DefaultPriorityFeeGwei) + if gas.maxPriorityFee.Cmp(wantPrio) != 0 { + t.Fatalf("maxPriorityFee = %s, want default %s", gas.maxPriorityFee, wantPrio) + } +} diff --git a/rocketpool/node/defend-challenge-exit.go b/rocketpool/node/defend-challenge-exit.go index 3a306e136..548553b35 100644 --- a/rocketpool/node/defend-challenge-exit.go +++ b/rocketpool/node/defend-challenge-exit.go @@ -15,7 +15,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/types" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/beacon" "github.com/rocket-pool/smartnode/shared/services/config" @@ -64,26 +63,7 @@ func newDefendChallengeExit(c *cli.Command, logger log.ColorLogger) (*defendChal return nil, err } - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested max fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } + gas := loadAutoTxGas(cfg, &logger) // Return task return &defendChallengeExit{ @@ -94,9 +74,9 @@ func newDefendChallengeExit(c *cli.Command, logger log.ColorLogger) (*defendChal rp: rp, bc: bc, d: d, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, }, nil diff --git a/rocketpool/node/defend-pdao-props.go b/rocketpool/node/defend-pdao-props.go index fab39d5a4..13ffc60a7 100644 --- a/rocketpool/node/defend-pdao-props.go +++ b/rocketpool/node/defend-pdao-props.go @@ -15,7 +15,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/transactions" "github.com/rocket-pool/smartnode/bindings/types" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/beacon" "github.com/rocket-pool/smartnode/shared/services/config" @@ -68,26 +67,7 @@ func newDefendPdaoProps(c *cli.Command, logger log.ColorLogger) (*defendPdaoProp return nil, err } - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested priority fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } + gas := loadAutoTxGas(cfg, &logger) // Get the event interval size intervalSize := big.NewInt(int64(cfg.Geth.EventLogInterval)) @@ -112,9 +92,9 @@ func newDefendPdaoProps(c *cli.Command, logger log.ColorLogger) (*defendPdaoProp w: w, rp: rp, bc: bc, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, nodeAddress: account.Address, propMgr: propMgr, diff --git a/rocketpool/node/distribute-minipools.go b/rocketpool/node/distribute-minipools.go index 2f16467ed..650f76d96 100644 --- a/rocketpool/node/distribute-minipools.go +++ b/rocketpool/node/distribute-minipools.go @@ -69,41 +69,18 @@ func newDistributeMinipools(c *cli.Command, logger log.ColorLogger) (*distribute return nil, err } - // Check if auto-distributing is disabled - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) + gas := loadAutoTxGas(cfg, &logger) distributeThreshold := cfg.Smartnode.DistributeThreshold.Value.(float64) disabled := false - if gasThreshold == 0 { + if gas.thresholdGwei == 0 { logger.Println("Automatic tx gas threshold is 0, disabling auto-distribute.") disabled = true - } else { - // Safety clamp - if distributeThreshold >= 8 { - logger.Printlnf("WARNING: Auto-distribute threshold is more than 8 ETH (%.6f ETH), reducing to 7.5 ETH for safety", distributeThreshold) - distributeThreshold = 7.5 - } else if distributeThreshold == 0 { - logger.Println("Auto-distribute threshold is 0, disabling auto-distribute.") - disabled = true - } - } - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested max fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) + } else if distributeThreshold >= 8 { + logger.Printlnf("WARNING: Auto-distribute threshold is more than 8 ETH (%.6f ETH), reducing to 7.5 ETH for safety", distributeThreshold) + distributeThreshold = 7.5 + } else if distributeThreshold == 0 { + logger.Println("Auto-distribute threshold is 0, disabling auto-distribute.") + disabled = true } // Return task @@ -115,12 +92,12 @@ func newDistributeMinipools(c *cli.Command, logger log.ColorLogger) (*distribute rp: rp, bc: bc, d: d, - gasThreshold: gasThreshold, + gasThreshold: gas.thresholdGwei, distributeThreshold: math.EthToWei(distributeThreshold), disabled: disabled, eight: math.EthToWei(8), - maxFee: maxFee, - maxPriorityFee: priorityFee, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, }, nil diff --git a/rocketpool/node/notify-final-balance.go b/rocketpool/node/notify-final-balance.go index 641fe2a9c..68977e84e 100644 --- a/rocketpool/node/notify-final-balance.go +++ b/rocketpool/node/notify-final-balance.go @@ -14,7 +14,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/transactions" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/beacon" "github.com/rocket-pool/smartnode/shared/services/config" @@ -63,26 +62,7 @@ func newNotifyFinalBalance(c *cli.Command, logger log.ColorLogger) (*notifyFinal return nil, err } - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested max fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } + gas := loadAutoTxGas(cfg, &logger) // Return task return ¬ifyFinalBalance{ @@ -93,9 +73,9 @@ func newNotifyFinalBalance(c *cli.Command, logger log.ColorLogger) (*notifyFinal rp: rp, bc: bc, d: d, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, }, nil diff --git a/rocketpool/node/notify-validator-exit.go b/rocketpool/node/notify-validator-exit.go index c16a3bdbc..f5f6f0bb2 100644 --- a/rocketpool/node/notify-validator-exit.go +++ b/rocketpool/node/notify-validator-exit.go @@ -15,7 +15,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/types" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/beacon" "github.com/rocket-pool/smartnode/shared/services/config" @@ -67,26 +66,7 @@ func newNotifyValidatorExit(c *cli.Command, logger log.ColorLogger) (*notifyVali return nil, err } - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested max fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } + gas := loadAutoTxGas(cfg, &logger) // Return task return ¬ifyValidatorExit{ @@ -97,9 +77,9 @@ func newNotifyValidatorExit(c *cli.Command, logger log.ColorLogger) (*notifyVali rp: rp, bc: bc, d: d, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, }, nil diff --git a/rocketpool/node/prestake-megapool-validator.go b/rocketpool/node/prestake-megapool-validator.go index 952640139..1ce0a8335 100644 --- a/rocketpool/node/prestake-megapool-validator.go +++ b/rocketpool/node/prestake-megapool-validator.go @@ -16,7 +16,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/transactions" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/config" rpgas "github.com/rocket-pool/smartnode/shared/services/gas" @@ -60,27 +59,7 @@ func newPrestakeMegapoolValidator(c *cli.Command, logger log.ColorLogger) (*pres return nil, err } - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested max fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } - + gas := loadAutoTxGas(cfg, &logger) autoAssignmentDelay := cfg.Smartnode.AutoAssignmentDelay.Value.(uint16) // Return task @@ -91,9 +70,9 @@ func newPrestakeMegapoolValidator(c *cli.Command, logger log.ColorLogger) (*pres w: w, rp: rp, d: d, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, autoAssignmentDelay: autoAssignmentDelay, }, nil diff --git a/rocketpool/node/provision-express-tickets.go b/rocketpool/node/provision-express-tickets.go index d14975b24..d6bc9f08d 100644 --- a/rocketpool/node/provision-express-tickets.go +++ b/rocketpool/node/provision-express-tickets.go @@ -12,7 +12,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/transactions" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/config" rpgas "github.com/rocket-pool/smartnode/shared/services/gas" @@ -56,33 +55,13 @@ func newProvisionExpressTickets(c *cli.Command, logger log.ColorLogger) (*provis return nil, err } - // Check if automatic transactions are disabled - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) + gas := loadAutoTxGas(cfg, &logger) disabled := false - if gasThreshold == 0 { + if gas.thresholdGwei == 0 { logger.Println("Automatic tx gas threshold is 0, disabling auto-provision.") disabled = true } - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested priority fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } - // Return task return &provisionExpress{ c: c, @@ -91,10 +70,10 @@ func newProvisionExpressTickets(c *cli.Command, logger log.ColorLogger) (*provis w: w, rp: rp, d: d, - gasThreshold: gasThreshold, + gasThreshold: gas.thresholdGwei, disabled: disabled, - maxFee: maxFee, - maxPriorityFee: priorityFee, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, }, nil diff --git a/rocketpool/node/set-latest-delegate.go b/rocketpool/node/set-latest-delegate.go index d02abc5b4..4b430164c 100644 --- a/rocketpool/node/set-latest-delegate.go +++ b/rocketpool/node/set-latest-delegate.go @@ -14,7 +14,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/rocketpool" "github.com/rocket-pool/smartnode/bindings/transactions" rpstate "github.com/rocket-pool/smartnode/bindings/utils/state" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services/alerting" log "github.com/rocket-pool/smartnode/shared/logger" @@ -67,26 +66,7 @@ func newSetUseLatestDelegate(c *cli.Command, logger log.ColorLogger) (*setUseLat return nil, err } - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested max fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } - - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) + gas := loadAutoTxGas(cfg, &logger) startTime := time.Now() @@ -99,9 +79,9 @@ func newSetUseLatestDelegate(c *cli.Command, logger log.ColorLogger) (*setUseLat rp: rp, bc: bc, d: d, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, startTime: startTime, }, nil diff --git a/rocketpool/node/stake-megapool-validator.go b/rocketpool/node/stake-megapool-validator.go index 1866b5b56..694b5d4b1 100644 --- a/rocketpool/node/stake-megapool-validator.go +++ b/rocketpool/node/stake-megapool-validator.go @@ -15,7 +15,6 @@ import ( "github.com/rocket-pool/smartnode/rocketpool/validator" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/beacon" "github.com/rocket-pool/smartnode/shared/services/config" @@ -65,26 +64,7 @@ func newStakeMegapoolValidator(c *cli.Command, logger log.ColorLogger) (*stakeMe return nil, err } - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested max fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } + gas := loadAutoTxGas(cfg, &logger) // Return task return &stakeMegapoolValidator{ @@ -95,9 +75,9 @@ func newStakeMegapoolValidator(c *cli.Command, logger log.ColorLogger) (*stakeMe rp: rp, bc: bc, d: d, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, }, nil diff --git a/rocketpool/node/verify-pdao-props.go b/rocketpool/node/verify-pdao-props.go index 3f4f2a821..b07577d5b 100644 --- a/rocketpool/node/verify-pdao-props.go +++ b/rocketpool/node/verify-pdao-props.go @@ -15,7 +15,6 @@ import ( "github.com/rocket-pool/smartnode/bindings/transactions" "github.com/rocket-pool/smartnode/bindings/types" log "github.com/rocket-pool/smartnode/shared/logger" - "github.com/rocket-pool/smartnode/shared/math" "github.com/rocket-pool/smartnode/shared/services" "github.com/rocket-pool/smartnode/shared/services/beacon" "github.com/rocket-pool/smartnode/shared/services/config" @@ -102,26 +101,7 @@ func newVerifyPdaoProps(c *cli.Command, logger log.ColorLogger) (*verifyPdaoProp return nil, err } - gasThreshold := cfg.Smartnode.AutoTxGasThreshold.Value.(float64) - - // Get the user-requested max fee - maxFeeGwei := cfg.Smartnode.ManualMaxFee.Value.(float64) - var maxFee *big.Int - if maxFeeGwei == 0 { - maxFee = nil - } else { - maxFee = math.GweiToWei(maxFeeGwei) - } - - // Get the user-requested priority fee - priorityFeeGwei := cfg.Smartnode.PriorityFee.Value.(float64) - var priorityFee *big.Int - if priorityFeeGwei == 0 { - logger.Printlnf("WARNING: priority fee was missing or 0, setting a default of %.2f.", rpgas.DefaultPriorityFeeGwei) - priorityFee = math.GweiToWei(rpgas.DefaultPriorityFeeGwei) - } else { - priorityFee = math.GweiToWei(priorityFeeGwei) - } + gas := loadAutoTxGas(cfg, &logger) // Get the event interval size intervalSize := big.NewInt(int64(cfg.Geth.EventLogInterval)) @@ -146,9 +126,9 @@ func newVerifyPdaoProps(c *cli.Command, logger log.ColorLogger) (*verifyPdaoProp w: w, rp: rp, bc: bc, - gasThreshold: gasThreshold, - maxFee: maxFee, - maxPriorityFee: priorityFee, + gasThreshold: gas.thresholdGwei, + maxFee: gas.maxFee, + maxPriorityFee: gas.maxPriorityFee, gasLimit: 0, nodeAddress: account.Address, propMgr: propMgr,