You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
407 lines
16 KiB
407 lines
16 KiB
extends layout
|
|
|
|
block headContent
|
|
title Address #{address}
|
|
|
|
block content
|
|
if (result && result.validateaddress)
|
|
if (!result.validateaddress.isvalid)
|
|
h1(class="h3 text-danger") Invalid Address
|
|
br
|
|
small(class="text-monospace") #{address}
|
|
else
|
|
h1.h3 Address
|
|
br
|
|
small(class="text-monospace") #{address}
|
|
|
|
hr
|
|
|
|
if (payoutAddressForMiner)
|
|
div(class="alert alert-primary shadow-sm", style="padding-bottom: 0;")
|
|
div(class="float-left", style="width: 50px; height: 50px; font-size: 18px;")
|
|
i(class="fas fa-certificate fa-2x", style="margin-top: 10px;")
|
|
|
|
h4(class="alert-heading h6 font-weight-bold") #{coinConfig.name} Fun
|
|
|
|
p
|
|
span This looks like a miner payout address for
|
|
span(class="font-weight-bold") #{payoutAddressForMiner.name}
|
|
if (coinConfig.miningPoolsConfigUrls.length > 1)
|
|
span (see the configurations:
|
|
each item, index in coinConfig.miningPoolsConfigUrls
|
|
if (index > 0)
|
|
span ,
|
|
a(href=item) config ##{index + 1}
|
|
span )
|
|
else
|
|
span (see the configuration
|
|
a(href=coinConfig.miningPoolsConfigUrls[0]) here
|
|
span )
|
|
|
|
else if (global.specialAddresses[address] && global.specialAddresses[address].type == "fun")
|
|
div(class="alert alert-primary shadow-sm", style="padding-bottom: 0;")
|
|
div(class="float-left", style="width: 50px; height: 50px; font-size: 18px;")
|
|
i(class="fas fa-certificate fa-2x", style="margin-top: 10px;")
|
|
|
|
h4(class="alert-heading h6 font-weight-bold") #{coinConfig.name} Fun
|
|
|
|
// special address info
|
|
- var saInfo = global.specialAddresses[address].addressInfo;
|
|
if (saInfo.alertBodyHtml)
|
|
p
|
|
span !{saInfo.alertBodyHtml}
|
|
|
|
if (saInfo.referenceUrl && saInfo.referenceUrl.trim().length > 0 && saInfo.alertBodyHtml.indexOf(saInfo.referenceUrl) == -1)
|
|
span
|
|
a(href=saInfo.referenceUrl) Read more
|
|
|
|
else
|
|
p
|
|
span #{saInfo.summary}
|
|
|
|
if (saInfo.referenceUrl && saInfo.referenceUrl.trim().length > 0)
|
|
span
|
|
a(href=saInfo.referenceUrl) Read more
|
|
|
|
|
|
if (false)
|
|
pre
|
|
code.json.bg-light #{JSON.stringify(addressObj, null, 4)}
|
|
|
|
ul.nav.nav-tabs.mb-3
|
|
li.nav-item
|
|
a.nav-link.active(data-toggle="tab", href="#tab-details", role="tab") Details
|
|
li.nav-item
|
|
a.nav-link(data-toggle="tab", href="#tab-json", role="tab") JSON
|
|
|
|
|
|
div.tab-content
|
|
div(id="tab-details", class="tab-pane active", role="tabpanel")
|
|
|
|
if (false && config.electrumXServers && config.electrumXServers.length > 0)
|
|
if (session.hideElectrumTrustWarnings != "true")
|
|
div(class="alert alert-primary alert-dismissible clearfix shadow-sm", role="alert")
|
|
span this explorer is database-free, it doesn't natively support address balances and transaction histories. In order to provide this functionality, address balances and transaction history can be requested from a configurable set of ElectrumX servers. If multiple ElectrumX servers are configured, the results are cross-referenced and conflicts noted. For the transaction history displayed below, only the transaction identifiers from ElectrumX are used; the transaction details are requested via RPC from this app's primary node, as usual.
|
|
|
|
a(href="/changeSetting?name=hideElectrumTrustWarnings&value=true", class="close", aria-label="Close", style="text-decoration: none;")
|
|
span(aria-hidden="true") ×
|
|
|
|
div.card.shadow-sm.mb-3
|
|
div.card-body
|
|
h3.h6 Summary
|
|
if (config.addressApi)
|
|
small.text-muted.border-dotted.ml-2(title=`Some details for this address were queried from ${config.addressApi}` data-toggle="tooltip") Trust Note
|
|
hr
|
|
|
|
div.row
|
|
div.col-md-6
|
|
|
|
if (addressObj.hash)
|
|
div.row
|
|
div.summary-split-table-label Hash 160
|
|
div.summary-split-table-content.text-monospace #{addressObj.hash.toString("hex")}
|
|
|
|
if (result.validateaddress.scriptPubKey)
|
|
div.row
|
|
div.summary-split-table-label Script Public Key
|
|
div.summary-split-table-content.text-monospace #{result.validateaddress.scriptPubKey}
|
|
|
|
if (addressObj.hasOwnProperty("version"))
|
|
div.row
|
|
div.summary-split-table-label Version
|
|
div.summary-split-table-content.text-monospace #{addressObj.version}
|
|
|
|
if (result.validateaddress.hasOwnProperty("witness_version"))
|
|
div.row
|
|
div.summary-split-table-label Witness Version
|
|
div.summary-split-table-content.text-monospace #{result.validateaddress.witness_version}
|
|
|
|
if (result.validateaddress.witness_program)
|
|
div.row
|
|
div.summary-split-table-label Witness Program
|
|
div.summary-split-table-content.text-monospace #{result.validateaddress.witness_program}
|
|
|
|
if (firstSeenTransaction && firstSeenTransaction.confirmations > 0)
|
|
div.row
|
|
div.summary-split-table-label First Seen
|
|
div.summary-split-table-content.text-monospace
|
|
if (getblockchaininfo)
|
|
span Block ##{(getblockchaininfo.blocks - firstSeenTransaction.confirmations).toLocaleString()}
|
|
else
|
|
a(href=("/block/" + firstSeenTransaction.blockhash)) #{firstSeenTransaction.blockhash}
|
|
|
|
br
|
|
|
|
span #{moment.utc(new Date(firstSeenTransaction.time * 1000)).format("Y-MM-DD HH:mm:ss")} utc
|
|
- var timeAgoTime = firstSeenTransaction.time;
|
|
include includes/time-ago.pug
|
|
|
|
if (false)
|
|
pre
|
|
code.json.bg-light #{JSON.stringify(firstSeenTransaction)}
|
|
|
|
if (balance)
|
|
if (balance.conflictedResults)
|
|
div.row
|
|
div.summary-split-table-label Balance
|
|
div.summary-split-table-content.text-monospace
|
|
span(class="text-warning") Conflicted ElectrumX Results
|
|
|
|
each item in balance.conflictedResults
|
|
- var currencyValue = item.confirmed / coinConfig.baseCurrencyUnit.multiplier;
|
|
include includes/value-display.pug
|
|
|
|
|
|
else
|
|
div.row
|
|
div.summary-split-table-label Balance
|
|
div.summary-split-table-content.text-monospace
|
|
- var currencyValue = balance.result.confirmed / coinConfig.baseCurrencyUnit.multiplier;
|
|
include includes/value-display.pug
|
|
|
|
if (balance.unconfirmed)
|
|
div.row
|
|
div.summary-split-table-label Unconfirmed
|
|
div.summary-split-table-content.text-monospace
|
|
- var currencyValue = balance.unconfirmed / coinConfig.baseCurrencyUnit.multiplier;
|
|
include includes/value-display.pug
|
|
|
|
if (addressDetails && addressDetails.balanceSat)
|
|
div.row
|
|
div.summary-split-table-label Balance
|
|
div.summary-split-table-content.text-monospace
|
|
- var currencyValue = new Decimal(addressDetails.balanceSat).dividedBy(coinConfig.baseCurrencyUnit.multiplier);
|
|
include includes/value-display.pug
|
|
|
|
if (addressDetails && addressDetails.txCount)
|
|
div.row
|
|
div.summary-split-table-label Transactions
|
|
div.summary-split-table-content.text-monospace #{addressDetails.txCount.toLocaleString()}
|
|
|
|
div.row
|
|
div.summary-split-table-label QR Code
|
|
div.summary-split-table-content.text-monospace
|
|
img(src=addressQrCodeUrl, alt=address, style="border: solid 1px #ccc;")
|
|
|
|
div.col-md-6
|
|
if (electrumScripthash)
|
|
div.row
|
|
div.summary-split-table-label Scripthash
|
|
div.summary-split-table-content.text-monospace #{electrumScripthash}
|
|
|
|
- var x = result.validateaddress;
|
|
- var flagNames = ["Is Valid?", "Is Script?", "Is Witness?", "Is Mine?", "Is Watch-Only?"];
|
|
- var flags = [x.isvalid, x.isscript, x.iswitness, x.ismine, x.iswatchonly];
|
|
|
|
each flagName, index in flagNames
|
|
div.row
|
|
div.summary-split-table-label #{flagName}
|
|
div.summary-split-table-content.text-monospace
|
|
if (flags[index])
|
|
i(class="fas fa-check text-success")
|
|
else
|
|
i(class="fas fa-times text-warning")
|
|
|
|
if (false)
|
|
div(class="card mb-3 shadow-sm")
|
|
div.card-header
|
|
span(class="h6") Flags
|
|
div.card-body
|
|
div(class="table-responsive")
|
|
table(class="table text-center")
|
|
thead
|
|
tr
|
|
th Is Valid?
|
|
th Is Script?
|
|
th Is Witness?
|
|
th Is Mine?
|
|
th Is Watch-Only?
|
|
tbody
|
|
tr
|
|
- var x = result.validateaddress;
|
|
- var flags = [x.isvalid, x.isscript, x.iswitness, x.ismine, x.iswatchonly];
|
|
|
|
each flag in flags
|
|
td
|
|
if (flag)
|
|
i(class="fas fa-check text-success")
|
|
else
|
|
i(class="fas fa-times text-warning")
|
|
|
|
div.card.shadow-sm.mb-3
|
|
div.card-body
|
|
div.clearfix
|
|
div.float-left
|
|
h3.h6.mb-0
|
|
if (addressDetails && addressDetails.txCount)
|
|
if (addressDetails.txCount == 1)
|
|
span 1 Transaction
|
|
else
|
|
span #{addressDetails.txCount.toLocaleString()} Transactions
|
|
else
|
|
span Transactions
|
|
|
|
if (config.addressApi)
|
|
if (config.addressApi == "electrumx")
|
|
small.text-muted.border-dotted.ml-2(title=`The list of transaction IDs for this address was queried from ElectrumX (using the configured server(s))` data-toggle="tooltip") Trust Note
|
|
else
|
|
small.text-muted.border-dotted.ml-2(title=`The list of transaction IDs for this address was queried from ${config.addressApi}` data-toggle="tooltip") Trust Note
|
|
|
|
if (!crawlerBot && txids && txids.length > 1 && addressApiSupport.sortDesc && addressApiSupport.sortAsc)
|
|
div(class="float-right")
|
|
a(href="#", class="pull-right dropdown-toggle", data-toggle="dropdown", aria-haspopup="true", aria-expanded="false")
|
|
if (sort == "desc")
|
|
span Newest First
|
|
else
|
|
span Oldest First
|
|
|
|
div(class="dropdown-menu dropdown-menu-right")
|
|
a(href=("/address/" + address), class="dropdown-item")
|
|
if (sort == "desc")
|
|
i(class="fa fa-check")
|
|
span Newest First
|
|
a(href=("/address/" + address + "?sort=asc"), class="dropdown-item")
|
|
if (sort != "desc")
|
|
i(class="fa fa-check")
|
|
span Oldest First
|
|
|
|
else if (txids && txids.length > 1 && addressApiSupport.sortDesc && !addressApiSupport.sortAsc)
|
|
div.float-right
|
|
span.text-muted Newest First
|
|
|
|
hr
|
|
|
|
if (conflictedTxidResults)
|
|
div(class="alert alert-warning", style="padding-bottom: 0;")
|
|
div(class="float-left", style="width: 55px; height: 50px; font-size: 18px;")
|
|
i(class="fas fa-exclamation-triangle fa-2x", style="margin-top: 10px;")
|
|
h4(class="alert-heading h6 font-weight-bold") Trust Warning
|
|
p
|
|
span The transaction history for this address was requested from mulitple ElectrumX servers and the results did not match. The results below were obtained only from
|
|
span(class="font-weight-bold") #{electrumHistory.server}
|
|
|
|
|
|
if (true)
|
|
if (addressApiError && addressApiError.error && addressApiError.error.code && addressApiError.error.code == -32600)
|
|
span Failed to retrieve transaction history from ElectrumX. See
|
|
a(href="https://github.com/janoside/btc-rpc-explorer/issues/67") Issue #67
|
|
span for more information.
|
|
|
|
|
|
else if (addressApiError && addressApiError.userText)
|
|
div.text-danger Error: #{addressApiError.userText}
|
|
|
|
else if (addressDetailsErrors && addressDetailsErrors.length > 0)
|
|
each err in addressDetailsErrors
|
|
if (err.e && err.e.error && err.e.error.message == "history too large")
|
|
span Failed to retrieve transaction history from ElectrumX. See
|
|
a(href="https://github.com/janoside/btc-rpc-explorer/issues/67") Issue #67
|
|
span for more information.
|
|
|
|
else if (err == "No address API configured")
|
|
span No address API is configured. See
|
|
a(href="https://github.com/janoside/btc-rpc-explorer/blob/master/.env-sample") the example configuration file
|
|
span for help setting up an address API if desired.
|
|
|
|
else if (transactions.length == 0)
|
|
span No transactions found
|
|
|
|
each tx, txIndex in transactions
|
|
//pre
|
|
// code.json.bg-light #{JSON.stringify(tx, null, 4)}
|
|
div.card.shadow-sm(class=((txIndex < (transactions.length - 1) || txids.length > limit) ? "mb-3" : ""))
|
|
div.card-header.text-monospace.clearfix
|
|
div.float-left.mr-0
|
|
if (sort == "desc")
|
|
span ##{(addressDetails.txCount - offset - txIndex).toLocaleString()}
|
|
else
|
|
span ##{(offset + txIndex + 1).toLocaleString()}
|
|
span –
|
|
|
|
div.row
|
|
div.col-md-8
|
|
if (tx && tx.txid)
|
|
a(href=("/tx/" + tx.txid)) #{tx.txid}
|
|
|
|
if (global.specialTransactions && global.specialTransactions[tx.txid])
|
|
span
|
|
a(data-toggle="tooltip", title=(coinConfig.name + " Fun! See transaction for details"))
|
|
i.fas.fa-certificate.text-primary
|
|
|
|
br
|
|
|
|
if (addrGainsByTx[tx.txid])
|
|
- var currencyValue = addrGainsByTx[tx.txid];
|
|
span(class="text-success") +
|
|
include includes/value-display.pug
|
|
|
|
if (addrLossesByTx[tx.txid])
|
|
span /
|
|
|
|
if (addrLossesByTx[tx.txid])
|
|
- var currencyValue = addrLossesByTx[tx.txid];
|
|
span(class="text-danger") -
|
|
include includes/value-display.pug
|
|
|
|
div.col-md-4
|
|
div.text-md-right
|
|
if (tx.time)
|
|
- var timestampHuman = tx.time;
|
|
include includes/timestamp-human.pug
|
|
|
|
br
|
|
|
|
- var timeAgoTime = tx.time;
|
|
small.text-muted (
|
|
include includes/time-ago-text.pug
|
|
span ago)
|
|
|
|
else
|
|
span.text-danger Unconfirmed
|
|
|
|
div.card-body
|
|
if (true)
|
|
- var txInputs = txInputsByTransaction[tx.txid];
|
|
- var blockHeight = blockHeightsByTxid[tx.txid];
|
|
- var txIOHighlightAddress = address;
|
|
|
|
include includes/transaction-io-details.pug
|
|
|
|
else
|
|
p Since this explorer is database-free, it doesn't natively support address transaction history. However, you can configure it to communicate with one or more ElectrumX servers to build and display this data. In doing so, you should be aware that you'll be trusting those ElectrumX servers. If you configure multiple servers the results obtained from each will be cross-referenced against the others. Communicating with ElectrumX servers will also impact your privacy since the servers will know what addresses you're interested in. If these tradeoffs are acceptable, you can see a list of public ElectrumX servers here:
|
|
a(href="https://uasf.saltylemon.org/electrum") https://uasf.saltylemon.org/electrum
|
|
|
|
if (false)
|
|
pre
|
|
code.json.bg-light #{JSON.stringify(transactions, null, 4)}
|
|
|
|
if (!crawlerBot && addressDetails && addressDetails.txCount > limit)
|
|
- var txCount = addressDetails.txCount;
|
|
- var pageNumber = offset / limit + 1;
|
|
- var pageCount = Math.floor(txCount / limit);
|
|
- if (pageCount * limit < txCount) {
|
|
- pageCount++;
|
|
- }
|
|
- var paginationUrlFunction = function(x) {
|
|
- return paginationBaseUrl + "&limit=" + limit + "&offset=" + ((x - 1) * limit);
|
|
- }
|
|
|
|
hr.mt-3
|
|
|
|
include includes/pagination.pug
|
|
|
|
|
|
|
|
|
|
div(id="tab-json", class="tab-pane", role="tabpanel")
|
|
div.highlight
|
|
h4 validateaddress
|
|
pre
|
|
code.json.bg-light(data-lang="json") #{JSON.stringify(result.validateaddress, null, 4)}
|
|
|
|
if (addressDetails)
|
|
h4 addressDetails
|
|
pre
|
|
code.json.bg-light #{JSON.stringify(addressDetails, null, 4)}
|
|
|
|
|
|
|