The NEAR pages from #44 and #47 link a bridge mint back to its Quantus transaction, but the link lands on the block, because there is nothing finer to land on:
There is no extrinsic route. The site has pages for blocks, accounts, call kinds, event kinds, runtimes and nodes, but none for a single extrinsic. The block page lists its extrinsics without anchors, so a link cannot even land on the right row.
Most extrinsics have no hash. A transaction is addressed by its hash, and chain_extrinsic.hash has been written only since migration 0018 (2026-10-06), plus the bridge-deposit backfill in bridgescan::hashes. Measured 2026-10-07: 2,541 of 284,221 indexed mainnet extrinsics have one. A page keyed by hash would resolve recent transactions and bridge deposits and nothing older.
The NEAR side already links here exactly: the bridge writes the depositor's Quantus tx hash into the mint. The missing half is the Quantus page to receive that link, and a link from there back to the mint.
What, in order
Anchors on the block page. Each extrinsic row gets an id (#x<index>), so /quantus/block/<h>#x<i> lands on it. Small, and worth having whatever else happens.
Hash backfill. A resumable job reads each block body from our own node (chain_getBlock on bob, about 181k blocks), hashes every extrinsic (Blake2-256 of the encoded bytes, length prefix included: the rule bridge::extrinsic_hash already pins), and fills chain_extrinsic.hash. It keeps its own cursor, the same shape as event_scan, because the process restarts several times a day and anything that walks history has to be resumable. Each block is one call to a node we run, and no public endpoint is involved. Progress is logged as hashed against remaining, so a stall is visible.
A page at /quantus/tx/<hash>, plus GET /v1/chains/{chain}/tx/{hash}, resolved through chain_extrinsic.hash to height and index. It shows what the block page already decodes, for that one extrinsic:
signer, call and decoded arguments, and signature scheme and size (never the signature itself);
every event it emitted, its result (ExtrinsicSuccess or ExtrinsicFailed with the error), and its fee (TransactionFeePaid);
its block, time and position, with a link to the anchored row;
bridge context: for a transfer into a bridge deposit address, the NEAR mint that names this hash (from bridge_mint), linked to its NEAR transaction page; for a custody payout matched to a withdrawal, the withdrawal, labelled inferred as on the bridge page.
Links switch over. The NEAR transaction page, the account page and the bridge tables link to /quantus/tx/<hash>. They fall back to the anchored block row while the backfill has not reached a transaction.
Not in scope
Hashes for chains other than mainnet are the same job pointed at a different node; this issue is about making the route exist.
## Why
The NEAR pages from #44 and #47 link a bridge mint back to its Quantus transaction, but the link lands on the **block**, because there is nothing finer to land on:
- **There is no extrinsic route.** The site has pages for blocks, accounts, call kinds, event kinds, runtimes and nodes, but none for a single extrinsic. The block page lists its extrinsics without anchors, so a link cannot even land on the right row.
- **Most extrinsics have no hash.** A transaction is addressed by its hash, and `chain_extrinsic.hash` has been written only since migration 0018 (2026-10-06), plus the bridge-deposit backfill in `bridgescan::hashes`. Measured 2026-10-07: **2,541 of 284,221** indexed mainnet extrinsics have one. A page keyed by hash would resolve recent transactions and bridge deposits and nothing older.
The NEAR side already links here exactly: the bridge writes the depositor's Quantus tx hash into the mint. The missing half is the Quantus page to receive that link, and a link from there back to the mint.
## What, in order
1. **Anchors on the block page.** Each extrinsic row gets an id (`#x<index>`), so `/quantus/block/<h>#x<i>` lands on it. Small, and worth having whatever else happens.
2. **Hash backfill.** A resumable job reads each block body from our own node (`chain_getBlock` on bob, about 181k blocks), hashes every extrinsic (Blake2-256 of the encoded bytes, length prefix included: the rule `bridge::extrinsic_hash` already pins), and fills `chain_extrinsic.hash`. It keeps its own cursor, the same shape as `event_scan`, because the process restarts several times a day and anything that walks history has to be resumable. Each block is one call to a node we run, and no public endpoint is involved. Progress is logged as hashed against remaining, so a stall is visible.
3. **A page at `/quantus/tx/<hash>`**, plus `GET /v1/chains/{chain}/tx/{hash}`, resolved through `chain_extrinsic.hash` to height and index. It shows what the block page already decodes, for that one extrinsic:
- signer, call and decoded arguments, and signature scheme and size (never the signature itself);
- every event it emitted, its result (`ExtrinsicSuccess` or `ExtrinsicFailed` with the error), and its fee (`TransactionFeePaid`);
- its block, time and position, with a link to the anchored row;
- **bridge context:** for a transfer into a bridge deposit address, the NEAR mint that names this hash (from `bridge_mint`), linked to its NEAR transaction page; for a custody payout matched to a withdrawal, the withdrawal, labelled inferred as on the bridge page.
4. **Links switch over.** The NEAR transaction page, the account page and the bridge tables link to `/quantus/tx/<hash>`. They fall back to the anchored block row while the backfill has not reached a transaction.
## Not in scope
Hashes for chains other than mainnet are the same job pointed at a different node; this issue is about making the route exist.
Related: #44, #47.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why
The NEAR pages from #44 and #47 link a bridge mint back to its Quantus transaction, but the link lands on the block, because there is nothing finer to land on:
chain_extrinsic.hashhas been written only since migration 0018 (2026-10-06), plus the bridge-deposit backfill inbridgescan::hashes. Measured 2026-10-07: 2,541 of 284,221 indexed mainnet extrinsics have one. A page keyed by hash would resolve recent transactions and bridge deposits and nothing older.The NEAR side already links here exactly: the bridge writes the depositor's Quantus tx hash into the mint. The missing half is the Quantus page to receive that link, and a link from there back to the mint.
What, in order
#x<index>), so/quantus/block/<h>#x<i>lands on it. Small, and worth having whatever else happens.chain_getBlockon bob, about 181k blocks), hashes every extrinsic (Blake2-256 of the encoded bytes, length prefix included: the rulebridge::extrinsic_hashalready pins), and fillschain_extrinsic.hash. It keeps its own cursor, the same shape asevent_scan, because the process restarts several times a day and anything that walks history has to be resumable. Each block is one call to a node we run, and no public endpoint is involved. Progress is logged as hashed against remaining, so a stall is visible./quantus/tx/<hash>, plusGET /v1/chains/{chain}/tx/{hash}, resolved throughchain_extrinsic.hashto height and index. It shows what the block page already decodes, for that one extrinsic:ExtrinsicSuccessorExtrinsicFailedwith the error), and its fee (TransactionFeePaid);bridge_mint), linked to its NEAR transaction page; for a custody payout matched to a withdrawal, the withdrawal, labelled inferred as on the bridge page./quantus/tx/<hash>. They fall back to the anchored block row while the backfill has not reached a transaction.Not in scope
Hashes for chains other than mainnet are the same job pointed at a different node; this issue is about making the route exist.
Related: #44, #47.