11package alchemy
22
33import (
4+ "encoding/json"
45 "fmt"
6+ "math/big"
57 "time"
68
79 "github.com/ethereum/go-ethereum/common"
@@ -14,6 +16,35 @@ import (
1416const getAssetTransfersMethod = "alchemy_getAssetTransfers"
1517const MaxAssetTransfersCount = 1000
1618
19+ // AlchemyBigInt wraps VarHexBigInt to handle Alchemy API inconsistency
20+ // it sometimes returns plain decimal numbers instead of hexadecimal
21+ type AlchemyBigInt struct {
22+ * bigint.VarHexBigInt
23+ }
24+
25+ func (a * AlchemyBigInt ) UnmarshalJSON (data []byte ) error {
26+ var str string
27+ if err := json .Unmarshal (data , & str ); err != nil {
28+ return err
29+ }
30+
31+ // alchemy sometimes returns plain numbers like "0" or "1" without "0x" prefix
32+ // so we need to take this into account
33+ if len (str ) >= 2 && str [0 :2 ] == "0x" {
34+ // hex string case
35+ a .VarHexBigInt = & bigint.VarHexBigInt {}
36+ return a .VarHexBigInt .UnmarshalJSON (data )
37+ } else {
38+ // plain decimal number
39+ val := new (big.Int )
40+ if _ , ok := val .SetString (str , 10 ); ! ok {
41+ return fmt .Errorf ("invalid decimal number: %s" , str )
42+ }
43+ a .VarHexBigInt = & bigint.VarHexBigInt {Int : val }
44+ return nil
45+ }
46+ }
47+
1748type TransferCategory string
1849
1950const (
@@ -58,7 +89,7 @@ type Transfer struct {
5889 ToAddress * common.Address `json:"to,omitempty"`
5990 Value float64 `json:"value,omitempty"`
6091 Erc1155Metadata []Erc1155Metadata `json:"erc1155Metadata,omitempty"`
61- TokenID * bigint. VarHexBigInt `json:"tokenId"`
92+ TokenID * AlchemyBigInt `json:"tokenId"`
6293 Asset string `json:"asset"`
6394 UniqueID string `json:"uniqueId"`
6495 Hash common.Hash `json:"hash"`
@@ -79,7 +110,7 @@ func (t Transfer) IsIncoming(accountAddress common.Address) bool {
79110}
80111
81112type Erc1155Metadata struct {
82- TokenID * bigint. VarHexBigInt `json:"tokenId"`
113+ TokenID * AlchemyBigInt `json:"tokenId"`
83114 Value * bigint.VarHexBigInt `json:"value"`
84115}
85116
0 commit comments