Repository navigation
feat: add Zcash to the explorer (adapter, pages, routes) #398
Description
Summary
Add Zcash as a first-class network in the explorer UI — adapter, pages, routes and search — mirroring how Bitcoin is wired up.
Motivation
Completes the Zcash rollout. Depends on #396 (ships ZcashClient) and #397 (network entries + type: "zcash").
Proposed Solution
Bitcoin is the closest existing template, since Zcash is a Bitcoin fork with a UTXO model plus shielded pools.
1. Types — src/types/index.ts: widen NetworkType from "evm" | "bitcoin" | "solana" to include "zcash".
2. Adapter — src/services/adapters/ZcashAdapter/ZcashAdapter.ts, modelled on BitcoinAdapter. Add a createZcashAdapter(networkId: string, client: ZcashClient) branch to adaptersFactory.ts alongside createBitcoinAdapter.
3. Pages — src/components/pages/zcash/, mirroring pages/bitcoin/: network dashboard, blocks list + detail, transactions list + detail, address, mempool. Register lazy exports in LazyComponents.tsx.
4. Routes — App.tsx, following the btc / tbtc pattern and keeping them before the :networkId catch-all:
zec, zec/blocks, zec/block/:filter, zec/txs, zec/tx/:filter,
zec/address/:address, zec/mempool, zec/mempool/:filter
plus the tzec testnet equivalents.
5. Supporting modules — src/config/zcashConstants.ts, src/utils/zcashFormatters.ts / zcashUtils.ts, src/hooks/useZcashDashboard.ts, and Zcash branches in useSearch.ts, useNetworkDashboard.ts, NavbarLogo.tsx, NetworkBlockIndicator.tsx, DataService.ts, AIPromptTemplates.ts, settings/index.tsx, plus locales/*/tooltips.json for all five languages.
What Zcash needs that Bitcoin does not
These are the parts where copying BitcoinAdapter verbatim will be wrong:
hash_or_heightis a string.getBlock,getBlockHeaderandzGetTreestatetake a block hash or a height as a decimal string —getBlock("3444000", 1), not a number. Easy to get wrong when porting Bitcoin call sites.getRawTransactionverbosity is numeric (0= hex,1= object), not a boolean as in Bitcoin.- Address-index methods take an object bag:
getAddressBalance({ addresses: ["t1..."] }). - Zcash-only response fields to surface in the UI:
nonceis a 32-byte hex string (not a number),solutionholds the Equihash solution, blocks carryfinalsaplingroot/finalorchardroot(the latter only on post-NU5 blocks, so treat it as optional) andtrees(Sapling/Orchard note-commitment tree sizes). - Shielded transaction bundles: transactions may carry
vShieldedSpend,vShieldedOutput, anorchardbundle,valueBalance, andvjoinsplitfor Sprout-era transactions. A transaction can legitimately have emptyvin/voutwhile moving value entirely within a shielded pool — the transaction view must not render those as "empty". - Address types: transparent (
t1…/t3…), Sapling (zs…), and unified (u1…). Search and address routing need to distinguish them;zListUnifiedReceiversdecomposes a unified address into its receivers. - Value pools on the dashboard:
getBlockchainInforeturns per-pool balances (transparent,sprout,sapling,orchard,lockbox,ironwood) pluschainSupply— good material for the network dashboard, and genuinely Zcash-specific.
Constraints worth knowing before starting
- No WebSocket. Zebra's RPC server is built
.http_only(), so there are no subscriptions. Live block updates must poll, as Bitcoin already does. - Hosted RPC cannot serve the shielded features. The only free endpoints (Tatum) whitelist their method set: every
z_*andgetaddress*call returns-32601, with or without an API key — I verified this against a real key, so it is a fixed whitelist rather than a paid tier. That means address balance/history pages and any shielded-pool view require a self-hostedzebrad. See feat: add Zcash to explorer-metadata #397. - Suggested sequencing: ship blocks / transactions / mempool / block dashboard against the hosted endpoints first, and gate the address and shielded views behind the self-hosted node.
Acceptance Criteria
-
NetworkTypeincludes"zcash" -
ZcashAdapterimplemented and registered inadaptersFactory.ts -
pages/zcash/renders network, blocks, block, txs, tx and mempool views -
zec/tzecroutes registered before the:networkIdcatch-all - Search resolves Zcash block hashes, heights, txids and transparent addresses
- Shielded transactions render correctly, including ones with empty
vin/vout - Tooltip locales added for all five languages
- Address and shielded views degrade gracefully when the RPC rejects the method
Activity
snattydev commentedon Sep 14, 2026
In progress — explorer-side Zcash work for this issue is underway.
Scope so far:
ZcashAdapter+zec/tzecroutes, pages, search, dashboard, mempool, and tooltips (mirroring Bitcoin, with Zcash-specific RPC/UI)@openscan/network-connectorsfrom GitHubmain(PR Display source code from sourcify and hardhard ignition #26 /ZcashClient); npm1.7.0still does not export the client-32601rather than showing a fake 0 ZEC balanceStill open: PR, connectors npm bump when published, and metadata #397 (
rpcs/zec/*.json) when1.3.0-alpha.0is on npm.Please hold off duplicating this unless coordinating — a PR will be linked here when it is up.
snattydev commentedon Sep 14, 2026
Update — I should have checked the open PRs before commenting.
@MatiasOS already has a stacked series for this issue:
1.8(covers feat: adopt Zcash support from @openscan/network-connectors #396;ZcashClientis on npm now)#397 / explorer-metadata#17 is also merged.
Please ignore the earlier “in progress” note. I will not open a competing PR for adapter/dashboard/blocks. Happy to review that stack, or pick up later slices (tx / address / mempool / search) after #408 if useful.