Explorer redesing tuning
This commit is contained in:
parent
9919f1a685
commit
dca00bf770
19
api/types.go
19
api/types.go
@ -5,7 +5,6 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/trezor/blockbook/bchain"
|
"github.com/trezor/blockbook/bchain"
|
||||||
@ -190,14 +189,17 @@ func (a Tokens) Less(i, j int) bool {
|
|||||||
} else if ti.BaseValue > tj.BaseValue {
|
} else if ti.BaseValue > tj.BaseValue {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
c := strings.Compare(ti.Name, tj.Name)
|
if ti.Name == "" {
|
||||||
if c == 1 {
|
if tj.Name != "" {
|
||||||
return false
|
return false
|
||||||
} else if c == -1 {
|
}
|
||||||
return true
|
} else {
|
||||||
|
if tj.Name == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return ti.Name < tj.Name
|
||||||
}
|
}
|
||||||
c = strings.Compare(ti.Contract, tj.Contract)
|
return ti.Contract < tj.Contract
|
||||||
return c == -1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TokenTransfer contains info about a token transfer done in a transaction
|
// TokenTransfer contains info about a token transfer done in a transaction
|
||||||
@ -329,6 +331,7 @@ type Address struct {
|
|||||||
Nonce string `json:"nonce,omitempty"`
|
Nonce string `json:"nonce,omitempty"`
|
||||||
UsedTokens int `json:"usedTokens,omitempty"`
|
UsedTokens int `json:"usedTokens,omitempty"`
|
||||||
Tokens Tokens `json:"tokens,omitempty"`
|
Tokens Tokens `json:"tokens,omitempty"`
|
||||||
|
FiatValue float64 `json:"fiatValue,omitempty"`
|
||||||
TokensBaseValue float64 `json:"tokensBaseValue,omitempty"`
|
TokensBaseValue float64 `json:"tokensBaseValue,omitempty"`
|
||||||
TokensFiatValue float64 `json:"tokensFiatValue,omitempty"`
|
TokensFiatValue float64 `json:"tokensFiatValue,omitempty"`
|
||||||
TotalBaseValue float64 `json:"totalBaseValue,omitempty"`
|
TotalBaseValue float64 `json:"totalBaseValue,omitempty"`
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"math/big"
|
"math/big"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -219,3 +220,104 @@ func TestAmount_Compare(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTokens_Sort(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
unsorted Tokens
|
||||||
|
sorted Tokens
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "one",
|
||||||
|
unsorted: Tokens{
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
Contract: "0x1",
|
||||||
|
BaseValue: 12.34,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sorted: Tokens{
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
Contract: "0x1",
|
||||||
|
BaseValue: 12.34,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "mix",
|
||||||
|
unsorted: Tokens{
|
||||||
|
{
|
||||||
|
Name: "",
|
||||||
|
Contract: "0x6",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "",
|
||||||
|
Contract: "0x5",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "b",
|
||||||
|
Contract: "0x2",
|
||||||
|
BaseValue: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "d",
|
||||||
|
Contract: "0x4",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
Contract: "0x1",
|
||||||
|
BaseValue: 12.34,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "c",
|
||||||
|
Contract: "0x3",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
sorted: Tokens{
|
||||||
|
{
|
||||||
|
Name: "a",
|
||||||
|
Contract: "0x1",
|
||||||
|
BaseValue: 12.34,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "b",
|
||||||
|
Contract: "0x2",
|
||||||
|
BaseValue: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "c",
|
||||||
|
Contract: "0x3",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "d",
|
||||||
|
Contract: "0x4",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "",
|
||||||
|
Contract: "0x5",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "",
|
||||||
|
Contract: "0x6",
|
||||||
|
BaseValue: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
sort.Sort(tt.unsorted)
|
||||||
|
if !reflect.DeepEqual(tt.unsorted, tt.sorted) {
|
||||||
|
t.Errorf("Tokens Sort got %v, want %v", tt.unsorted, tt.sorted)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1256,22 +1256,26 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option Acco
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var secondaryRate, totalFiatValue float64
|
|
||||||
ticker := w.is.GetCurrentTicker("", "")
|
|
||||||
totalBaseValue, err := strconv.ParseFloat((*Amount)(&ba.BalanceSat).DecimalString(w.chainParser.AmountDecimals()), 64)
|
|
||||||
if ticker != nil && err == nil {
|
|
||||||
r, found := ticker.Rates[secondaryCoin]
|
|
||||||
if found {
|
|
||||||
secondaryRate = float64(r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if w.chainType == bchain.ChainBitcoinType {
|
if w.chainType == bchain.ChainBitcoinType {
|
||||||
totalReceived = ba.ReceivedSat()
|
totalReceived = ba.ReceivedSat()
|
||||||
totalSent = &ba.SentSat
|
totalSent = &ba.SentSat
|
||||||
} else {
|
|
||||||
totalBaseValue += ed.tokensBaseValue
|
|
||||||
}
|
}
|
||||||
totalFiatValue = secondaryRate * totalBaseValue
|
var secondaryRate, totalFiatValue, totalBaseValue, fiatValue float64
|
||||||
|
if secondaryCoin != "" {
|
||||||
|
ticker := w.is.GetCurrentTicker("", "")
|
||||||
|
balance, err := strconv.ParseFloat((*Amount)(&ba.BalanceSat).DecimalString(w.chainParser.AmountDecimals()), 64)
|
||||||
|
if ticker != nil && err == nil {
|
||||||
|
r, found := ticker.Rates[secondaryCoin]
|
||||||
|
if found {
|
||||||
|
secondaryRate = float64(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fiatValue = secondaryRate * balance
|
||||||
|
if w.chainType == bchain.ChainEthereumType {
|
||||||
|
totalBaseValue += balance + ed.tokensBaseValue
|
||||||
|
totalFiatValue = secondaryRate * totalBaseValue
|
||||||
|
}
|
||||||
|
}
|
||||||
r := &Address{
|
r := &Address{
|
||||||
Paging: pg,
|
Paging: pg,
|
||||||
AddrStr: address,
|
AddrStr: address,
|
||||||
@ -1286,6 +1290,7 @@ func (w *Worker) GetAddress(address string, page int, txsOnPage int, option Acco
|
|||||||
Transactions: txs,
|
Transactions: txs,
|
||||||
Txids: txids,
|
Txids: txids,
|
||||||
Tokens: ed.tokens,
|
Tokens: ed.tokens,
|
||||||
|
FiatValue: fiatValue,
|
||||||
TokensBaseValue: ed.tokensBaseValue,
|
TokensBaseValue: ed.tokensBaseValue,
|
||||||
TokensFiatValue: ed.tokensFiatValue,
|
TokensFiatValue: ed.tokensFiatValue,
|
||||||
TotalBaseValue: totalBaseValue,
|
TotalBaseValue: totalBaseValue,
|
||||||
|
|||||||
18
api/xpub.go
18
api/xpub.go
@ -4,6 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -387,7 +388,7 @@ func (w *Worker) getXpubData(xd *bchain.XpubDescriptor, page int, txsOnPage int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetXpubAddress computes address value and gets transactions for given address
|
// GetXpubAddress computes address value and gets transactions for given address
|
||||||
func (w *Worker) GetXpubAddress(xpub string, page int, txsOnPage int, option AccountDetails, filter *AddressFilter, gap int) (*Address, error) {
|
func (w *Worker) GetXpubAddress(xpub string, page int, txsOnPage int, option AccountDetails, filter *AddressFilter, gap int, secondaryCoin string) (*Address, error) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
page--
|
page--
|
||||||
if page < 0 {
|
if page < 0 {
|
||||||
@ -567,6 +568,20 @@ func (w *Worker) GetXpubAddress(xpub string, page int, txsOnPage int, option Acc
|
|||||||
setIsOwnAddresses(txs, xpubAddresses)
|
setIsOwnAddresses(txs, xpubAddresses)
|
||||||
var totalReceived big.Int
|
var totalReceived big.Int
|
||||||
totalReceived.Add(&data.balanceSat, &data.sentSat)
|
totalReceived.Add(&data.balanceSat, &data.sentSat)
|
||||||
|
|
||||||
|
var fiatValue float64
|
||||||
|
if secondaryCoin != "" {
|
||||||
|
ticker := w.is.GetCurrentTicker("", "")
|
||||||
|
balance, err := strconv.ParseFloat((*Amount)(&data.balanceSat).DecimalString(w.chainParser.AmountDecimals()), 64)
|
||||||
|
if ticker != nil && err == nil {
|
||||||
|
r, found := ticker.Rates[secondaryCoin]
|
||||||
|
if found {
|
||||||
|
secondaryRate := float64(r)
|
||||||
|
fiatValue = secondaryRate * balance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addr := Address{
|
addr := Address{
|
||||||
Paging: pg,
|
Paging: pg,
|
||||||
AddrStr: xpub,
|
AddrStr: xpub,
|
||||||
@ -580,6 +595,7 @@ func (w *Worker) GetXpubAddress(xpub string, page int, txsOnPage int, option Acc
|
|||||||
Txids: txids,
|
Txids: txids,
|
||||||
UsedTokens: usedTokens,
|
UsedTokens: usedTokens,
|
||||||
Tokens: tokens,
|
Tokens: tokens,
|
||||||
|
FiatValue: fiatValue,
|
||||||
XPubAddresses: xpubAddresses,
|
XPubAddresses: xpubAddresses,
|
||||||
AddressAliases: w.getAddressAliases(addresses),
|
AddressAliases: w.getAddressAliases(addresses),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -592,7 +592,7 @@ func (b *EthereumRPC) getCreationContractInfo(contract string, height uint32) *b
|
|||||||
|
|
||||||
func (b *EthereumRPC) processCallTrace(call *rpcCallTrace, d *bchain.EthereumInternalData, contracts []bchain.ContractInfo, blockHeight uint32) []bchain.ContractInfo {
|
func (b *EthereumRPC) processCallTrace(call *rpcCallTrace, d *bchain.EthereumInternalData, contracts []bchain.ContractInfo, blockHeight uint32) []bchain.ContractInfo {
|
||||||
value, err := hexutil.DecodeBig(call.Value)
|
value, err := hexutil.DecodeBig(call.Value)
|
||||||
if call.Type == "CREATE" {
|
if call.Type == "CREATE" || call.Type == "CREATE2" {
|
||||||
d.Transfers = append(d.Transfers, bchain.EthereumInternalTransfer{
|
d.Transfers = append(d.Transfers, bchain.EthereumInternalTransfer{
|
||||||
Type: bchain.CREATE,
|
Type: bchain.CREATE,
|
||||||
Value: *value,
|
Value: *value,
|
||||||
@ -600,7 +600,6 @@ func (b *EthereumRPC) processCallTrace(call *rpcCallTrace, d *bchain.EthereumInt
|
|||||||
To: call.To, // new contract address
|
To: call.To, // new contract address
|
||||||
})
|
})
|
||||||
contracts = append(contracts, *b.getCreationContractInfo(call.To, blockHeight))
|
contracts = append(contracts, *b.getCreationContractInfo(call.To, blockHeight))
|
||||||
|
|
||||||
} else if call.Type == "SELFDESTRUCT" {
|
} else if call.Type == "SELFDESTRUCT" {
|
||||||
d.Transfers = append(d.Transfers, bchain.EthereumInternalTransfer{
|
d.Transfers = append(d.Transfers, bchain.EthereumInternalTransfer{
|
||||||
Type: bchain.SELFDESTRUCT,
|
Type: bchain.SELFDESTRUCT,
|
||||||
|
|||||||
@ -850,8 +850,12 @@ func (s *PublicServer) summaryValuesSpan(baseValue float64, secondaryValue float
|
|||||||
rv.WriteString(")</span>")
|
rv.WriteString(")</span>")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if td.SecondaryCoin != "" {
|
if baseValue > 0 {
|
||||||
rv.WriteString("-")
|
appendAmountSpan(&rv, "", strconv.FormatFloat(baseValue, 'f', 6, 64), td.CoinShortcut, "")
|
||||||
|
} else {
|
||||||
|
if td.SecondaryCoin != "" {
|
||||||
|
rv.WriteString("-")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return template.HTML(rv.String())
|
return template.HTML(rv.String())
|
||||||
@ -1184,16 +1188,16 @@ func (s *PublicServer) explorerXpub(w http.ResponseWriter, r *http.Request) (tpl
|
|||||||
return errorTpl, nil, api.NewAPIError("Missing xpub", true)
|
return errorTpl, nil, api.NewAPIError("Missing xpub", true)
|
||||||
}
|
}
|
||||||
s.metrics.ExplorerViews.With(common.Labels{"action": "xpub"}).Inc()
|
s.metrics.ExplorerViews.With(common.Labels{"action": "xpub"}).Inc()
|
||||||
page, _, _, filter, filterParam, gap := s.getAddressQueryParams(r, api.AccountDetailsTxHistoryLight, txsOnPage)
|
|
||||||
// do not allow txsOnPage and details to be changed by query params
|
// do not allow txsOnPage and details to be changed by query params
|
||||||
address, err := s.api.GetXpubAddress(xpub, page, txsOnPage, api.AccountDetailsTxHistoryLight, filter, gap)
|
page, _, _, filter, filterParam, gap := s.getAddressQueryParams(r, api.AccountDetailsTxHistoryLight, txsOnPage)
|
||||||
|
data := s.newTemplateData(r)
|
||||||
|
address, err := s.api.GetXpubAddress(xpub, page, txsOnPage, api.AccountDetailsTxHistoryLight, filter, gap, strings.ToLower(data.SecondaryCoin))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == api.ErrUnsupportedXpub {
|
if err == api.ErrUnsupportedXpub {
|
||||||
err = api.NewAPIError("XPUB functionality is not supported", true)
|
err = api.NewAPIError("XPUB functionality is not supported", true)
|
||||||
}
|
}
|
||||||
return errorTpl, nil, err
|
return errorTpl, nil, err
|
||||||
}
|
}
|
||||||
data := s.newTemplateData(r)
|
|
||||||
data.AddrStr = address.AddrStr
|
data.AddrStr = address.AddrStr
|
||||||
data.Address = address
|
data.Address = address
|
||||||
data.Page = address.Page
|
data.Page = address.Page
|
||||||
@ -1267,7 +1271,7 @@ func (s *PublicServer) explorerSearch(w http.ResponseWriter, r *http.Request) (t
|
|||||||
var err error
|
var err error
|
||||||
s.metrics.ExplorerViews.With(common.Labels{"action": "search"}).Inc()
|
s.metrics.ExplorerViews.With(common.Labels{"action": "search"}).Inc()
|
||||||
if len(q) > 0 {
|
if len(q) > 0 {
|
||||||
address, err = s.api.GetXpubAddress(q, 0, 1, api.AccountDetailsBasic, &api.AddressFilter{Vout: api.AddressFilterVoutOff}, 0)
|
address, err = s.api.GetXpubAddress(q, 0, 1, api.AccountDetailsBasic, &api.AddressFilter{Vout: api.AddressFilterVoutOff}, 0, "")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
http.Redirect(w, r, joinURL("/xpub/", url.QueryEscape(address.AddrStr)), http.StatusFound)
|
http.Redirect(w, r, joinURL("/xpub/", url.QueryEscape(address.AddrStr)), http.StatusFound)
|
||||||
return noTpl, nil, nil
|
return noTpl, nil, nil
|
||||||
@ -1501,7 +1505,8 @@ func (s *PublicServer) apiXpub(r *http.Request, apiVersion int) (interface{}, er
|
|||||||
var err error
|
var err error
|
||||||
s.metrics.ExplorerViews.With(common.Labels{"action": "api-xpub"}).Inc()
|
s.metrics.ExplorerViews.With(common.Labels{"action": "api-xpub"}).Inc()
|
||||||
page, pageSize, details, filter, _, gap := s.getAddressQueryParams(r, api.AccountDetailsTxidHistory, txsInAPI)
|
page, pageSize, details, filter, _, gap := s.getAddressQueryParams(r, api.AccountDetailsTxidHistory, txsInAPI)
|
||||||
address, err = s.api.GetXpubAddress(xpub, page, pageSize, details, filter, gap)
|
secondaryCoin := strings.ToLower(r.URL.Query().Get("secondary"))
|
||||||
|
address, err = s.api.GetXpubAddress(xpub, page, pageSize, details, filter, gap, secondaryCoin)
|
||||||
if err == nil && apiVersion == apiV1 {
|
if err == nil && apiVersion == apiV1 {
|
||||||
return s.api.AddressToV1(address), nil
|
return s.api.AddressToV1(address), nil
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -538,7 +538,7 @@ func (s *WebsocketServer) getAccountInfo(req *accountInfoReq) (res *api.Address,
|
|||||||
if req.PageSize == 0 {
|
if req.PageSize == 0 {
|
||||||
req.PageSize = txsOnPage
|
req.PageSize = txsOnPage
|
||||||
}
|
}
|
||||||
a, err := s.api.GetXpubAddress(req.Descriptor, req.Page, req.PageSize, opt, &filter, req.Gap)
|
a, err := s.api.GetXpubAddress(req.Descriptor, req.Page, req.PageSize, opt, &filter, req.Gap, strings.ToLower(req.SecondaryCurrency))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return s.api.GetAddress(req.Descriptor, req.Page, req.PageSize, opt, &filter, strings.ToLower(req.SecondaryCurrency))
|
return s.api.GetAddress(req.Descriptor, req.Page, req.PageSize, opt, &filter, strings.ToLower(req.SecondaryCurrency))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@ body {
|
|||||||
body {
|
body {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background: linear-gradient(to bottom, #f6f6f6 300px, #e5e5e5 0), #e5e5e5;
|
background: linear-gradient(to bottom, #f6f6f6 360px, #e5e5e5 0), #e5e5e5;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -588,6 +588,16 @@ span.btn-paging:hover {
|
|||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
body {
|
body {
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
|
background: linear-gradient(to bottom, #f6f6f6 500px, #e5e5e5 0), #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding-left: 2px;
|
||||||
|
padding-right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-body {
|
||||||
|
padding: var(--bs-accordion-body-padding-y) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.octicon {
|
.octicon {
|
||||||
@ -595,6 +605,10 @@ span.btn-paging:hover {
|
|||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.unconfirmed {
|
||||||
|
padding: 0.1rem 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
.btn {
|
.btn {
|
||||||
--bs-btn-font-size: 0.8rem;
|
--bs-btn-font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,19 @@
|
|||||||
{{define "specific"}}{{$addr := .Address}}{{$data := .}}
|
{{define "specific"}}{{$addr := .Address}}{{$data := .}}
|
||||||
<div class="row">
|
<div class="row g-0 ms-2 ms-lg-0">
|
||||||
<div class="col-md-10 order-2 order-md-1">
|
<div class="col-md-10 order-2 order-md-1">
|
||||||
<h1>{{if $addr.ContractInfo}}Contract {{$addr.ContractInfo.Name}}{{if $addr.ContractInfo.Symbol}} ({{$addr.ContractInfo.Symbol}}){{end}}{{else}}Address {{addressAlias $addr.AddrStr $data}}{{end}}</h1>
|
<h1>{{if $addr.ContractInfo}}Contract {{$addr.ContractInfo.Name}}{{if $addr.ContractInfo.Symbol}} ({{$addr.ContractInfo.Symbol}}){{end}}{{else}}Address {{addressAlias $addr.AddrStr $data}}{{end}}</h1>
|
||||||
<h5 class="col-12 d-flex h-data pb-2"><span class="ellipsis copyable">{{$addr.AddrStr}}</span></h5>
|
<h5 class="col-12 d-flex h-data pb-2"><span class="ellipsis copyable">{{$addr.AddrStr}}</span></h5>
|
||||||
<h4>
|
<h4 class="row">
|
||||||
{{formattedAmountSpan $addr.BalanceSat 0 $data.CoinShortcut $data "copyable"}}
|
<div class="col-lg-6">{{formattedAmountSpan $addr.BalanceSat 0 $data.CoinShortcut $data "copyable"}}</div>
|
||||||
{{if $addr.TotalFiatValue}}<span class="ps-5"{{if eq .ChainType 1}} tt="Address value including tokens"{{end}}>{{summaryValuesSpan $addr.TotalBaseValue $addr.TotalFiatValue $data}}</span>{{end}}
|
{{if $addr.FiatValue}}<div class="col-lg-6">{{summaryValuesSpan 0 $addr.FiatValue $data}}</div>{{end}}
|
||||||
</h4>
|
</h4>
|
||||||
|
{{if gt $addr.TotalFiatValue $addr.FiatValue}}
|
||||||
|
<div class="row g-0 small text-muted">Including Tokens</div>
|
||||||
|
<h4 class="row">
|
||||||
|
<div class="col-lg-6">{{summaryValuesSpan $addr.TotalBaseValue 0 $data}}</div>
|
||||||
|
<div class="col-lg-6">{{summaryValuesSpan 0 $addr.TotalFiatValue $data}}</div>
|
||||||
|
</h4>
|
||||||
|
{{end}}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 order-1 order-md-2 d-flex justify-content-center justify-content-md-end mb-3 mb-md-0">
|
<div class="col-md-2 order-1 order-md-2 d-flex justify-content-center justify-content-md-end mb-3 mb-md-0">
|
||||||
<div id="qrcode"></div>
|
<div id="qrcode"></div>
|
||||||
@ -121,7 +128,7 @@
|
|||||||
<th style="width: 25%;">Contract</th>
|
<th style="width: 25%;">Contract</th>
|
||||||
<th style="width: 30%;">Quantity</th>
|
<th style="width: 30%;">Quantity</th>
|
||||||
<th style="width: 35%;">Value</th>
|
<th style="width: 35%;">Value</th>
|
||||||
<th class="text-end" style="width: 10%;">Transfers</th>
|
<th class="text-end" style="width: 10%;"><span class="d-none d-md-block">Transfers</span><span class="d-block d-md-none">#</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
{{range $t := $addr.Tokens}}
|
{{range $t := $addr.Tokens}}
|
||||||
{{if eq $t.Type "ERC20"}}
|
{{if eq $t.Type "ERC20"}}
|
||||||
@ -157,7 +164,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th style="width: 25%;">Contract</th>
|
<th style="width: 25%;">Contract</th>
|
||||||
<th style="width: 65%;">Tokens</th>
|
<th style="width: 65%;">Tokens</th>
|
||||||
<th class="text-end" style="width: 10%;">Transfers</th>
|
<th class="text-end" style="width: 10%;"><span class="d-none d-md-block">Transfers</span><span class="d-block d-md-none">#</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
{{range $t := $addr.Tokens}}
|
{{range $t := $addr.Tokens}}
|
||||||
{{if eq $t.Type "ERC721"}}
|
{{if eq $t.Type "ERC721"}}
|
||||||
@ -194,7 +201,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th style="width: 25%;">Contract</th>
|
<th style="width: 25%;">Contract</th>
|
||||||
<th style="width: 65%;">Tokens</th>
|
<th style="width: 65%;">Tokens</th>
|
||||||
<th class="text-end" style="width: 10%;">Transfers</th>
|
<th class="text-end" style="width: 10%;"><span class="d-none d-md-block">Transfers</span><span class="d-block d-md-none">#</span></th>
|
||||||
</tr>
|
</tr>
|
||||||
{{range $t := $addr.Tokens}}
|
{{range $t := $addr.Tokens}}
|
||||||
{{if eq $t.Type "ERC1155"}}
|
{{if eq $t.Type "ERC1155"}}
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
<a class="nav-link" href="/sendtx">Send Transaction</a>
|
<a class="nav-link" href="/sendtx">Send Transaction</a>
|
||||||
</span>
|
</span>
|
||||||
<span class="navbar-nav ml-md-auto d-lg-flex d-none">
|
<span class="navbar-nav ml-md-auto d-lg-flex d-none">
|
||||||
<a class="nav-link" href="http://trezor.io/compare" target="_blank" rel="noopener noreferrer">Don't have a Trezor? Get one!</a>
|
<a class="nav-link" href="https://trezor.io/compare" target="_blank" rel="noopener noreferrer">Don't have a Trezor? Get one!</a>
|
||||||
</span>
|
</span>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -48,7 +48,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Transactions in Mempool</td>
|
<td>Transactions in Mempool</td>
|
||||||
<td>{{if .InternalExplorer}}<a href="/mempool">{{$bb.MempoolSize}}</a>{{else}}{{formatInt $bb.MempoolSize}}{{end}}</td>
|
<td>{{if .InternalExplorer}}<a href="/mempool">{{formatInt $bb.MempoolSize}}</a>{{else}}{{formatInt $bb.MempoolSize}}{{end}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{if $bb.HasFiatRates}}
|
{{if $bb.HasFiatRates}}
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@ -111,8 +111,8 @@
|
|||||||
<div id="inputDataBody" class="accordion-collapse collapse" aria-labelledby="inputDataHeading" data-bs-parent="#inputData">
|
<div id="inputDataBody" class="accordion-collapse collapse" aria-labelledby="inputDataHeading" data-bs-parent="#inputData">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12"><span class="copyable" style="overflow-wrap: break-word;">{{$tx.EthereumSpecific.Data}}</span></div>
|
<div class="col-12 mx-1 mx-md-0"><span class="copyable" style="overflow-wrap: break-word;">{{$tx.EthereumSpecific.Data}}</span></div>
|
||||||
<div class="col-12 pt-2"><span class="copyable">{{$tx.EthereumSpecific.ParsedData.Function}}</span></div>
|
<div class="col-12 mx-1 mx-md-0 pt-2"><span class="copyable">{{$tx.EthereumSpecific.ParsedData.Function}}</span></div>
|
||||||
{{if $tx.EthereumSpecific.ParsedData.Params}}
|
{{if $tx.EthereumSpecific.ParsedData.Params}}
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<table class="table data-table mt-2 mb-0">
|
<table class="table data-table mt-2 mb-0">
|
||||||
|
|||||||
@ -3,7 +3,10 @@
|
|||||||
<div class="col-md-10 order-2 order-md-1">
|
<div class="col-md-10 order-2 order-md-1">
|
||||||
<h1>XPUB</h1>
|
<h1>XPUB</h1>
|
||||||
<h5 class="col-12 d-flex h-data pb-2"><span class="ellipsis copyable">{{$addr.AddrStr}}</span></h5>
|
<h5 class="col-12 d-flex h-data pb-2"><span class="ellipsis copyable">{{$addr.AddrStr}}</span></h5>
|
||||||
<h4>{{amountSpan $addr.BalanceSat $data "copyable"}}</h4>
|
<h4 class="row">
|
||||||
|
<div class="col-lg-6">{{formattedAmountSpan $addr.BalanceSat 0 $data.CoinShortcut $data "copyable"}}</div>
|
||||||
|
{{if $addr.FiatValue}}<div class="col-lg-6">{{summaryValuesSpan 0 $addr.FiatValue $data}}</div>{{end}}
|
||||||
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 order-1 order-md-2 d-flex justify-content-center justify-content-md-end mb-3 mb-md-0">
|
<div class="col-md-2 order-1 order-md-2 d-flex justify-content-center justify-content-md-end mb-3 mb-md-0">
|
||||||
<div id="qrcode"></div>
|
<div id="qrcode"></div>
|
||||||
@ -60,7 +63,7 @@
|
|||||||
<td>{{amountSpan $t.BalanceSat $data "copyable"}}</td>
|
<td>{{amountSpan $t.BalanceSat $data "copyable"}}</td>
|
||||||
<td>{{formatInt $t.Transfers}}</td>
|
<td>{{formatInt $t.Transfers}}</td>
|
||||||
<td>{{$t.Path}}</td>
|
<td>{{$t.Path}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
{{else}}
|
{{else}}
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user