From 2ee33135bf6bf8dd4363878464e3f5100bb82b70 Mon Sep 17 00:00:00 2001 From: sinco <38270935+zxk0029@users.noreply.github.com> Date: Fri, 21 Feb 2025 20:58:29 +0800 Subject: [PATCH] refactor: Improve OKLink API error handling and URL crafting - Enhance error handling in OKLink account balance methods - Add null/empty data checks in GetAccountBalance - Modify CraftOkLinkURL to handle URL path construction more robustly - Update API call method to use consistent ChainExplorerName - Improve error reporting for token balance requests --- examples/account_test.go | 2 +- examples/mock.go | 14 ++++++------- explorer/base/client.go | 8 +++++++- explorer/oklink/account.go | 42 +++++++++++++++++++++++--------------- explorer/oklink/token.go | 4 ++-- 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/examples/account_test.go b/examples/account_test.go index 9542fdd..7112e07 100644 --- a/examples/account_test.go +++ b/examples/account_test.go @@ -12,7 +12,7 @@ func TestGetAccountBalance(t *testing.T) { if err != nil { fmt.Println("new mock client fail", "err", err) } - accountItem := []string{"0xD79053a14BC465d9C1434d4A4fAbdeA7b6a2A94b"} + accountItem := []string{"0x2Fc617E933a52713247CE25730f6695920B3befe"} symbol := []string{"ETH"} contractAddress := []string{"0x00"} protocolType := []string{""} diff --git a/examples/mock.go b/examples/mock.go index 811ca87..afd3435 100644 --- a/examples/mock.go +++ b/examples/mock.go @@ -9,18 +9,18 @@ import ( ) var ( - //EtherscanBaseUrl = "https://api.etherscan.io/api?" - //EtherscanApiKey = "HZEZGEPJJDA633N421AYW9NE8JFNZZC7JT" - //EtherscanTimeout = time.Second * 20 + EtherscanBaseUrl = "https://api.etherscan.io/api?" + EtherscanApiKey = "HZEZGEPJJDA633N421AYW9NE8JFNZZC7JT" + EtherscanTimeout = time.Second * 20 OklinkBaseUrl = "https://www.oklink.com" OklinkApiKey = "5181d535-b68f-41cf-bbc6-25905e46b6a6" OkTimeout = time.Second * 20 - // test success - EtherscanBaseUrl = "https://api-holesky.etherscan.io/api?" - EtherscanApiKey = "HZEZGEPJJDA633N421AYW9NE8JFNZZC7JT" - EtherscanTimeout = time.Second * 20 + //// test success + //EtherscanBaseUrl = "https://api-holesky.etherscan.io/api?" + //EtherscanApiKey = "HZEZGEPJJDA633N421AYW9NE8JFNZZC7JT" + //EtherscanTimeout = time.Second * 20 ) func NewMockClient() (*oklink.ChainExplorerAdaptor, *etherscan.ChainExplorerAdaptor, error) { diff --git a/explorer/base/client.go b/explorer/base/client.go index f32ab4e..5b2cbd7 100644 --- a/explorer/base/client.go +++ b/explorer/base/client.go @@ -210,7 +210,13 @@ func (bc *BaseClient) CraftEtherScanURL(module, action string, param map[string] } func (bc *BaseClient) CraftOkLinkURL(apiUrl string) (URL string) { - URL = bc.baseURL + apiUrl + // 确保 baseURL 末尾没有斜杠 + baseURL := strings.TrimRight(bc.baseURL, "/") + // 确保 apiUrl 开头有斜杠 + if !strings.HasPrefix(apiUrl, "/") { + apiUrl = "/" + apiUrl + } + URL = baseURL + apiUrl fmt.Println("CraftEtherScanURL", URL) return } diff --git a/explorer/oklink/account.go b/explorer/oklink/account.go index 59d2a06..214deb0 100644 --- a/explorer/oklink/account.go +++ b/explorer/oklink/account.go @@ -14,45 +14,55 @@ import ( // GET /api/v5/explorer/address/address-summary?chainShortName=eth&address=0x85c6627c4ed773cb7c32644b041f58a058b00d30 func (cea *ChainExplorerAdaptor) GetAccountBalance(request *account.AccountBalanceRequest) (*account.AccountBalanceResponse, error) { - var abrps *account.AccountBalanceResponse if request.ContractAddress[0] == "0x00" { apiUrl := fmt.Sprintf("api/v5/explorer/address/address-summary?chainShortName=%s&address=%s", request.ChainShortName, request.Account[0]) var responseData []AddressSummaryData - err := cea.baseClient.Call("oklink", "", "", apiUrl, nil, &responseData) + err := cea.baseClient.Call(ChainExplorerName, "", "", apiUrl, nil, &responseData) if err != nil { fmt.Println("error is:", err) - return nil, err + return &account.AccountBalanceResponse{}, nil + } + + // 检查是否有数据返回 + if len(responseData) == 0 { + fmt.Println("no data returned") + return &account.AccountBalanceResponse{}, nil } + balance, _ := new(big.Int).SetString(responseData[0].Balance, 10) - abrps = &account.AccountBalanceResponse{ + return &account.AccountBalanceResponse{ Account: responseData[0].Address, Balance: (*common.BigInt)(balance), BalanceStr: responseData[0].Balance, Symbol: responseData[0].BalanceSymbol, ContractAddress: responseData[0].CreateContractAddress, TokenId: "0x00", - } + }, nil } else { - apiUrl := fmt.Sprintf("api/v5/explorer/address/token-balance?chainShortName=%s&address=%s&tokenContractAddress=%s&protocolType=%s&limit=%d", request.ChainShortName, request.Account[0], request.ContractAddress[0], request.ProtocolType[0], request.Limit[0]) - fmt.Println(apiUrl) + apiUrl := fmt.Sprintf("api/v5/explorer/address/token-balance?chainShortName=%s&address=%s&tokenContractAddress=%s&protocolType=%s&limit=%s", request.ChainShortName, request.Account[0], request.ContractAddress[0], request.ProtocolType[0], request.Limit[0]) + var responseData []AddressTokenBalanceData - err := cea.baseClient.Call("oklink", "", "", apiUrl, nil, &responseData) + err := cea.baseClient.Call(ChainExplorerName, "", "", apiUrl, nil, &responseData) if err != nil { - return nil, err + return &account.AccountBalanceResponse{}, nil + } + + // 检查是否有数据返回 + if len(responseData) == 0 || len(responseData[0].TokenList) == 0 { + return &account.AccountBalanceResponse{}, fmt.Errorf("no token data found for address %s and contract %s", + request.Account[0], request.ContractAddress[0]) } - fmt.Println(responseData) - fmt.Println(responseData[0].TokenList) + balance, _ := new(big.Int).SetString(responseData[0].TokenList[0].HoldingAmount, 10) - abrps = &account.AccountBalanceResponse{ + return &account.AccountBalanceResponse{ Account: request.Account[0], Balance: (*common.BigInt)(balance), BalanceStr: responseData[0].TokenList[0].HoldingAmount, Symbol: responseData[0].TokenList[0].Symbol, ContractAddress: responseData[0].TokenList[0].TokenContractAddress, TokenId: responseData[0].TokenList[0].TokenId, - } + }, nil } - return abrps, nil } func (cea *ChainExplorerAdaptor) GetMultiAccountBalance(request *account.AccountBalanceRequest) ([]*account.AccountBalanceResponse, error) { @@ -65,7 +75,7 @@ func (cea *ChainExplorerAdaptor) GetMultiAccountBalance(request *account.Account if request.ContractAddress[0] == "0x00" { apiUrl := fmt.Sprintf("api/v5/explorer/address/balance-multi?chainShortName=%s&address=%s", request.ChainShortName, result) var responseData []AddressBalanceMultiData - err := cea.baseClient.Call("oklink", "", "", apiUrl, nil, &responseData) + err := cea.baseClient.Call(ChainExplorerName, "", "", apiUrl, nil, &responseData) if err != nil { return nil, err } @@ -87,7 +97,7 @@ func (cea *ChainExplorerAdaptor) GetMultiAccountBalance(request *account.Account apiUrl := fmt.Sprintf("api/v5/explorer/address/token-balance-multi?chainShortName=%s&address=%s&protocolType=%s&page=%s&limit=%s", request.ChainShortName, result, request.ProtocolType[0], request.Page[0], request.Limit[0]) fmt.Println("apiUrlapiUrl===", apiUrl) var responseData []AddressTokenBalanceMultiData - err := cea.baseClient.Call("oklink", "", "", apiUrl, nil, &responseData) + err := cea.baseClient.Call(ChainExplorerName, "", "", apiUrl, nil, &responseData) if err != nil { return nil, err } diff --git a/explorer/oklink/token.go b/explorer/oklink/token.go index c7c0fba..1e9c22c 100644 --- a/explorer/oklink/token.go +++ b/explorer/oklink/token.go @@ -14,7 +14,7 @@ func (cea *ChainExplorerAdaptor) GetTokenList(request *token.TokenRequest) ([]to apiUrl := fmt.Sprintf("api/v5/explorer/inscription/token-list?chainShortName=%s&protocolType=%s&tokenInscriptionId=%s&symbol=%s&projectId=%s&page=%s&limit=%s", request.ChainShortName, _protocolType, request.TokenInscriptionId, request.Symbol, request.ProjectId, request.Page, request.Limit) var responseData []TokenListData - err := cea.baseClient.Call("oklink", "", "", apiUrl, nil, &responseData) + err := cea.baseClient.Call(ChainExplorerName, "", "", apiUrl, nil, &responseData) if err != nil { return nil, err } @@ -32,7 +32,7 @@ func (cea *ChainExplorerAdaptor) GetTokenList(request *token.TokenRequest) ([]to apiUrl := fmt.Sprintf("api/v5/explorer/token/token-list?chainShortName=%s&protocolType=%s&tokenContractAddress=%s&page=%s&limit=%s", request.ChainShortName, _protocolType, request.ContractAddress, request.Page, request.Limit) var responseData []TokenListData - err := cea.baseClient.Call("oklink", "", "", apiUrl, nil, &responseData) + err := cea.baseClient.Call(ChainExplorerName, "", "", apiUrl, nil, &responseData) if err != nil { return nil, err }