diff --git a/api/types.go b/api/types.go index 6cea9243..86a48a03 100644 --- a/api/types.go +++ b/api/types.go @@ -233,7 +233,9 @@ type Address struct { TotalTokens int `json:"totalTokens,omitempty"` Tokens []Token `json:"tokens,omitempty"` Erc20Contract *bchain.Erc20Contract `json:"erc20contract,omitempty"` - Filter string `json:"-"` + // helpers for explorer + Filter string `json:"-"` + XPubAddresses map[string]struct{} `json:"-"` } // AddressUtxo holds information about address and its transactions diff --git a/api/xpub.go b/api/xpub.go index 141b8381..5a456003 100644 --- a/api/xpub.go +++ b/api/xpub.go @@ -235,6 +235,10 @@ func (w *Worker) GetAddressForXpub(xpub string, page int, txsOnPage int, option } // gap is increased one as there must be gap of empty addresses before the derivation is stopped gap++ + page-- + if page < 0 { + page = 0 + } var processedHash string cachedXpubsMux.Lock() data, found := cachedXpubs[xpub] @@ -305,7 +309,7 @@ func (w *Worker) GetAddressForXpub(xpub string, page int, txsOnPage int, option if option >= TxidHistory { txc := make(xpubTxids, 0, 32) var addTxids func(ad *xpubAddress) - if filter.FromHeight != 0 || filter.ToHeight != 0 || filter.Vout != AddressFilterVoutOff { + if filter.FromHeight == 0 && filter.ToHeight == 0 && filter.Vout == AddressFilterVoutOff { addTxids = func(ad *xpubAddress) { txc = append(txc, ad.txids...) } @@ -372,13 +376,21 @@ func (w *Worker) GetAddressForXpub(xpub string, page int, txsOnPage int, option } } totalTokens := 0 + xpubAddresses := make(map[string]struct{}) tokens := make([]Token, 0, 4) for i := range data.addresses { ad := &data.addresses[i] if ad.balance != nil { totalTokens++ if filter.AllTokens || !IsZeroBigInt(&ad.balance.BalanceSat) { - tokens = append(tokens, w.tokenFromXpubAddress(ad, 0, i)) + t := w.tokenFromXpubAddress(ad, 0, i) + tokens = append(tokens, t) + xpubAddresses[t.Name] = struct{}{} + } else { + a, _, _ := w.chainParser.GetAddressesFromAddrDesc(ad.addrDesc) + if len(a) > 0 { + xpubAddresses[a[0]] = struct{}{} + } } } } @@ -387,7 +399,14 @@ func (w *Worker) GetAddressForXpub(xpub string, page int, txsOnPage int, option if ad.balance != nil { totalTokens++ if filter.AllTokens || !IsZeroBigInt(&ad.balance.BalanceSat) { - tokens = append(tokens, w.tokenFromXpubAddress(ad, 1, i)) + t := w.tokenFromXpubAddress(ad, 1, i) + tokens = append(tokens, t) + xpubAddresses[t.Name] = struct{}{} + } else { + a, _, _ := w.chainParser.GetAddressesFromAddrDesc(ad.addrDesc) + if len(a) > 0 { + xpubAddresses[a[0]] = struct{}{} + } } } } @@ -402,10 +421,11 @@ func (w *Worker) GetAddressForXpub(xpub string, page int, txsOnPage int, option Txs: int(data.txs), // UnconfirmedBalanceSat: (*Amount)(&uBalSat), // UnconfirmedTxs: len(txm), - Transactions: txs, - Txids: txids, - TotalTokens: totalTokens, - Tokens: tokens, + Transactions: txs, + Txids: txids, + TotalTokens: totalTokens, + Tokens: tokens, + XPubAddresses: xpubAddresses, } glog.Info("GetAddressForXpub ", xpub[:16], ", ", len(data.addresses)+len(data.changeAddresses), " derived addresses, ", data.txs, " total txs finished in ", time.Since(start)) return &addr, nil diff --git a/server/public.go b/server/public.go index d40567c3..ecad94d0 100644 --- a/server/public.go +++ b/server/public.go @@ -415,7 +415,7 @@ func (s *PublicServer) parseTemplates() []*template.Template { "formatAmount": s.formatAmount, "formatAmountWithDecimals": formatAmountWithDecimals, "setTxToTemplateData": setTxToTemplateData, - "stringInSlice": stringInSlice, + "isOwnAddress": isOwnAddress, } var createTemplate func(filenames ...string) *template.Template if s.debug { @@ -504,6 +504,23 @@ func setTxToTemplateData(td *TemplateData, tx *api.Tx) *TemplateData { return td } +// returns true if addresses are "own", +// i.e. either the address of the address detail or belonging to the xpub +func isOwnAddress(td *TemplateData, addresses []string) bool { + if len(addresses) == 1 { + a := addresses[0] + if a == td.AddrStr { + return true + } + if td.Address != nil && td.Address.XPubAddresses != nil { + if _, found := td.Address.XPubAddresses[a]; found { + return true + } + } + } + return false +} + func (s *PublicServer) explorerTx(w http.ResponseWriter, r *http.Request) (tpl, *TemplateData, error) { var tx *api.Tx var err error diff --git a/server/public_test.go b/server/public_test.go index 525a7248..a6feca10 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -151,7 +151,7 @@ func httpTests_BitcoinType(t *testing.T, ts *httptest.Server) { `td class="data">0 FAKE`, `mzVznVsCHkVHX9UN8WPFASWUUHtxnNn4Jj`, `13.60030331 FAKE`, - `