Skip to content

feat: add Zcash to the explorer (adapter, pages, routes) #398

Open

Description

@MatiasOS

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_height is a string. getBlock, getBlockHeader and zGetTreestate take 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.
  • getRawTransaction verbosity 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: nonce is a 32-byte hex string (not a number), solution holds the Equihash solution, blocks carry finalsaplingroot / finalorchardroot (the latter only on post-NU5 blocks, so treat it as optional) and trees (Sapling/Orchard note-commitment tree sizes).
  • Shielded transaction bundles: transactions may carry vShieldedSpend, vShieldedOutput, an orchard bundle, valueBalance, and vjoinsplit for Sprout-era transactions. A transaction can legitimately have empty vin/vout while 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; zListUnifiedReceivers decomposes a unified address into its receivers.
  • Value pools on the dashboard: getBlockchainInfo returns per-pool balances (transparent, sprout, sapling, orchard, lockbox, ironwood) plus chainSupply — 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_* and getaddress* 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-hosted zebrad. 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

  • NetworkType includes "zcash"
  • ZcashAdapter implemented and registered in adaptersFactory.ts
  • pages/zcash/ renders network, blocks, block, txs, tx and mempool views
  • zec / tzec routes registered before the :networkId catch-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

  1. snattydev commented on Sep 14, 2026

    @snattydev

    In progress — explorer-side Zcash work for this issue is underway.

    Scope so far:

    • ZcashAdapter + zec/tzec routes, pages, search, dashboard, mempool, and tooltips (mirroring Bitcoin, with Zcash-specific RPC/UI)
    • @openscan/network-connectors from GitHub main (PR Display source code from sourcify and hardhard ignition #26 / ZcashClient); npm 1.7.0 still does not export the client
    • Hosted Tatum RPCs via builtin defaults; address/shielded views degrade on JSON-RPC -32601 rather than showing a fake 0 ZEC balance
    • No Playwright e2e against Tatum (5 req/min); no ZEC USD price in this issue

    Still open: PR, connectors npm bump when published, and metadata #397 (rpcs/zec/*.json) when 1.3.0-alpha.0 is on npm.

    Please hold off duplicating this unless coordinating — a PR will be linked here when it is up.

  2. snattydev commented on Sep 14, 2026

    @snattydev

    Update — I should have checked the open PRs before commenting.

    @MatiasOS already has a stacked series for this issue:

    #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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions