explorer-api: populate per-block Addresses from verbose getblock tx outputs
This commit is contained in:
@@ -64,6 +64,42 @@ async function rpc(method, params = []) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- Block address enrichment -------------------------------------------------
|
||||
// Attach the distinct addresses appearing in a block's transaction outputs.
|
||||
// Triangles has a transparent ledger (addressindex/txindex enabled), so these
|
||||
// are public. Privacy in Triangles is network-level (Tor) + encrypted SMSG
|
||||
// messaging, not shielded transactions, so surfacing per-block addresses is fine.
|
||||
async function attachAddresses(block) {
|
||||
if (!block || !Array.isArray(block.tx)) return block;
|
||||
const addrSet = new Set();
|
||||
for (const entry of block.tx.slice(0, 50)) {
|
||||
// getblock(verbose) gives full tx objects here; fall back to a lookup if
|
||||
// we only got a txid string.
|
||||
let tx = entry;
|
||||
if (typeof entry === 'string') {
|
||||
try { tx = await rpc('getrawtransaction', [entry, 1]); }
|
||||
catch (e) { continue; }
|
||||
}
|
||||
for (const vout of ((tx && tx.vout) || [])) {
|
||||
const addrs = vout.scriptPubKey && vout.scriptPubKey.addresses;
|
||||
if (Array.isArray(addrs)) addrs.forEach((a) => addrSet.add(a));
|
||||
}
|
||||
}
|
||||
block.addresses = Array.from(addrSet);
|
||||
return block;
|
||||
}
|
||||
|
||||
// getblock + address enrichment, cached by hash (blocks are immutable).
|
||||
async function getEnrichedBlock(hash) {
|
||||
const key = 'eblock:' + hash;
|
||||
const cached = getCached(key);
|
||||
if (cached) return cached;
|
||||
const block = await rpc('getblock', [hash, true]);
|
||||
await attachAddresses(block);
|
||||
setCache(key, block);
|
||||
return block;
|
||||
}
|
||||
|
||||
// REST endpoint: /rest/chaininfo (with cache for expensive gettxoutsetinfo)
|
||||
app.get('/rest/chaininfo', async (req, res) => {
|
||||
try {
|
||||
@@ -101,7 +137,7 @@ app.get('/rest/chaininfo', async (req, res) => {
|
||||
// REST endpoint: /rest/block/:hash
|
||||
app.get('/rest/block/:hash', async (req, res) => {
|
||||
try {
|
||||
const block = await rpc('getblock', [req.params.hash, true]); // true = verbose with tx data
|
||||
const block = await getEnrichedBlock(req.params.hash);
|
||||
res.json(block);
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: 'Block not found' });
|
||||
@@ -112,7 +148,7 @@ app.get('/rest/block/:hash', async (req, res) => {
|
||||
app.get('/rest/blockbyheight/:height', async (req, res) => {
|
||||
try {
|
||||
const hash = await rpc('getblockhash', [parseInt(req.params.height)]);
|
||||
const block = await rpc('getblock', [hash, true]); // true = verbose
|
||||
const block = await getEnrichedBlock(hash);
|
||||
res.json(block);
|
||||
} catch (error) {
|
||||
res.status(404).json({ error: 'Block not found' });
|
||||
|
||||
Reference in New Issue
Block a user