diff --git a/api/types.go b/api/types.go index 796573b9..a701f8e3 100644 --- a/api/types.go +++ b/api/types.go @@ -14,10 +14,10 @@ import ( type GetAddressOption int const ( - // ExistOnly - only that address is indexed - ExistOnly GetAddressOption = iota - // BalancesOnly - only balances - BalancesOnly + // Basic - only that address is indexed and some basic info + Basic GetAddressOption = iota + // Balance - only balances + Balance // TxidHistory - balances and txids, subject to paging TxidHistory // TxHistory - balances and full tx data, subject to paging @@ -90,7 +90,9 @@ type Erc20Token struct { Txs int `json:"txs"` Name string `json:"name"` Symbol string `json:"symbol"` - Balance string `json:"balance"` + Decimal int `json:"decimal"` + Balance string `json:"balance,omitempty"` + BalanceSat string `json:"balanceSat,omitempty"` ContractIndex string `json:"-"` } @@ -123,7 +125,7 @@ type Tx struct { ValueInSat big.Int `json:"-"` Fees string `json:"fees"` FeesSat big.Int `json:"-"` - Hex string `json:"hex"` + Hex string `json:"hex,omitempty"` CoinSpecificData interface{} `json:"-"` CoinSpecificJSON json.RawMessage `json:"-"` Erc20Transfers []Erc20Transfer `json:"erc20transfers,omitempty"` @@ -132,9 +134,9 @@ type Tx struct { // Paging contains information about paging for address, blocks and block type Paging struct { - Page int `json:"page"` - TotalPages int `json:"totalPages"` - ItemsOnPage int `json:"itemsOnPage"` + Page int `json:"page,omitempty"` + TotalPages int `json:"totalPages,omitempty"` + ItemsOnPage int `json:"itemsOnPage,omitempty"` } // AddressFilterNone disables filtering of transactions @@ -158,6 +160,7 @@ type Address struct { TxApperances int `json:"txApperances"` Transactions []*Tx `json:"txs,omitempty"` Txids []string `json:"transactions,omitempty"` + Nonce string `json:"nonce,omitempty"` Erc20Contract *bchain.Erc20Contract `json:"erc20contract,omitempty"` Erc20Tokens []Erc20Token `json:"erc20tokens,omitempty"` Filter string `json:"-"` diff --git a/api/worker.go b/api/worker.go index b1036986..85f79738 100644 --- a/api/worker.go +++ b/api/worker.go @@ -448,7 +448,7 @@ func (w *Worker) getEthereumTypeAddressBalances(addrDesc bchain.AddressDescripto Txs: uint32(ca.EthTxs), } // do not read balances etc in case of ExistOnly option - if option != ExistOnly { + if option != Basic { var b *big.Int b, err = w.chain.EthereumTypeGetBalance(addrDesc) if err != nil { @@ -526,7 +526,7 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option GetA } } // if only check that the address exist, return if we have the address - if option == ExistOnly && ba != nil { + if option == Basic && ba != nil { return &Address{AddrStr: address}, nil } // convert the address to the format defined by the parser @@ -554,7 +554,7 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option GetA } txm = UniqueTxidsInReverse(txm) // check if the address exist - if len(txc)+len(txm) == 0 || option == ExistOnly { + if len(txc)+len(txm) == 0 || option == Basic { return &Address{ AddrStr: address, Balance: w.chainParser.AmountToDecimalString(&ba.BalanceSat), diff --git a/server/public.go b/server/public.go index ea580fbf..b4f83e8c 100644 --- a/server/public.go +++ b/server/public.go @@ -554,7 +554,7 @@ func (s *PublicServer) explorerSearch(w http.ResponseWriter, r *http.Request) (t http.Redirect(w, r, joinURL("/tx/", tx.Txid), 302) return noTpl, nil, nil } - address, err = s.api.GetAddress(q, 0, 1, api.ExistOnly, api.AddressFilterNone) + address, err = s.api.GetAddress(q, 0, 1, api.Basic, api.AddressFilterNone) if err == nil { http.Redirect(w, r, joinURL("/address/", address.AddrStr), 302) return noTpl, nil, nil diff --git a/server/socketio.go b/server/socketio.go index 131f31e1..bca903a8 100644 --- a/server/socketio.go +++ b/server/socketio.go @@ -103,6 +103,13 @@ var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (inter } return }, + "getAccountInfo": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) { + req, err := unmarshalGetAccountInfoRequest(params) + if err == nil { + rv, err = s.getAccountInfo(req) + } + return + }, "getBlockHeader": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) { height, hash, err := unmarshalGetBlockHeader(params) if err == nil { @@ -207,6 +214,22 @@ func unmarshalGetAddressRequest(params []byte) (addr []string, opts addrOpts, er return } +type accountInfoReq struct { + Descriptor string `json:"descriptor"` + Details string `json:"details"` + PageSize int `json:"pageSize"` + Page int `json:"page"` +} + +func unmarshalGetAccountInfoRequest(params []byte) (*accountInfoReq, error) { + var r accountInfoReq + err := json.Unmarshal(params, &r) + if err != nil { + return nil, err + } + return &r, nil +} + type resultAddressTxids struct { Result []string `json:"result"` } @@ -661,6 +684,24 @@ func (s *SocketIoServer) getMempoolEntry(txid string) (res resultGetMempoolEntry return } +func (s *SocketIoServer) getAccountInfo(req *accountInfoReq) (res *api.Address, err error) { + if s.chainParser.GetChainType() == bchain.ChainEthereumType { + var opt api.GetAddressOption + switch req.Details { + case "balance": + opt = api.Balance + case "txids": + opt = api.TxidHistory + case "txs": + opt = api.TxHistory + default: + opt = api.Basic + } + return s.api.GetAddress(req.Descriptor, req.Page, req.PageSize, opt, api.AddressFilterNone) + } + return nil, errors.New("Not implemented") +} + // onSubscribe expects two event subscriptions based on the req parameter (including the doublequotes): // "bitcoind/hashblock" // "bitcoind/addresstxid",["2MzTmvPJLZaLzD9XdN3jMtQA5NexC3rAPww","2NAZRJKr63tSdcTxTN3WaE9ZNDyXy6PgGuv"] diff --git a/static/templates/address.html b/static/templates/address.html index f4e2600b..f06b0869 100644 --- a/static/templates/address.html +++ b/static/templates/address.html @@ -92,7 +92,7 @@

Transactions

- diff --git a/static/test.html b/static/test.html index b12ebc4d..1047c3c0 100644 --- a/static/test.html +++ b/static/test.html @@ -51,6 +51,26 @@ return socket.send({ method, params }, f); } + function getAccountInfo() { + const descriptor = document.getElementById('getAccountInfoDescriptor').value.trim(); + const selectDetails = document.getElementById('getAccountInfoDetails'); + const details = selectDetails.options[selectDetails.selectedIndex].value; + const page = parseInt(document.getElementById("getAccountInfoPage").value); + const pageSize = 10; + const method = 'getAccountInfo'; + const params = { + descriptor, + details, + page, + pageSize, + }; + socket.send({ method, params}, function (result) { + console.log('getAccountInfo sent successfully'); + console.log(result); + document.getElementById('getAccountInfoResult').innerText = JSON.stringify(result).replace(/,/g, ", "); + }); + } + function getAddressHistory() { var addresses = document.getElementById('getAddressHistoryAddresses').value.split(","); addresses = addresses.map(s => s.trim()); @@ -264,6 +284,28 @@
+
+
+ +
+
+
+ + + +
+
+
+
+
+
+
+