Architecture
Zecpass is three small pieces on top of two rails that already exist. Everything Zecpass wrote can be read in an afternoon; everything it depends on has its own audits and its own liquidity.
The road
Zcash (shielded) NEAR Intents Arbitrum One
┌────────────────┐ deshield ┌──────────────────┐ settle ┌──────────────────┐
│ user's wallet │ ───────────▶ │ one-time deposit │ ──────────▶ │ relayer address │
│ (Zodl) │ │ address (t1…) │ ETH │ 0x5C9A…951F │
└────────────────┘ └──────────────────┘ └────────┬─────────┘
│ Relay, 1 block
▼
Robinhood Chain (4663) ┌──────────────────┐
┌──────────────────┐ sweep ┌──────────────────┐ buy │ user's pass │
│ beneficiary 0x… │ ◀───────── │ Zecpass hub │ ◀────────── │ CREATE2 contract │
│ holds $ZECPASS │ tokens │ fee 0.5 % → trsy │ ETH │ passOf(benef.) │
└──────────────────┘ └────────┬─────────┘ └──────────────────┘
│ market.buy
▼
┌──────────────────┐
│ Pons V2 curve or │
│ Uniswap V4 pool │
└──────────────────┘
Rail one: NEAR Intents (ZEC in)
NEAR Intents is an intent settlement network: a user deposits an asset at an address the network generates, market makers compete to fill the intent, and the winner pays the destination asset on the destination chain. Zecpass uses its 1Click API.
- The order asks for
ZEC (nep141:zec.omft.near)in andETH on Arbitrum One (nep141:arb.omft.near)out, exact input, 1 percent slippage tolerance, recipient = the relayer's address on Arbitrum One, refund = the user's transparent Zcash address. - The response is a fresh transparent Zcash deposit address and a signed quote with a deadline.
- 1Click polls Zcash, runs the fill and reports
SUCCESSwith the Arbitrum transaction hash and the exact amount paid. - Measured on 2026-09-20: 0.1 ZEC to 0.0569 ETH, estimated settlement 454 seconds.
Why Arbitrum One and not Robinhood Chain directly: NEAR Intents lists ETH on Robinhood Chain (nep141:hood.omft.near) as an asset, but no solver quotes it yet. The relayer probes that route every ten minutes. The day a quote comes back, new orders are created with the pass address as the NEAR Intents recipient and the Arbitrum and Relay legs disappear. Nothing else changes. That route is called the direct rail on the stats page.
Rail two: Relay (Arbitrum One to Robinhood Chain)
Relay is a cross-chain relaying service with its own solvers and its own capital on both sides. The relayer asks for a quote with recipient set to the user's pass on Robinhood Chain, receives one transaction to sign on Arbitrum One, sends it, and Relay pays the pass on Robinhood Chain in about one block.
- Measured on 2026-09-20: 0.01 ETH in, 0.009985 ETH out, 0.15 percent impact, one second.
- Relay's status endpoint is polled until it reports success; the Robinhood Chain transaction hash is recorded on the order.
The relayer
A single small machine on Fly.io running one Node process. It does four things and stores one JSON file.
- Creates orders: validates the request, computes the pass address, asks 1Click for a quote and a deposit address, persists the order.
- Watches settlements: every twenty seconds it polls 1Click for every open order and advances the state.
- Moves the ETH: on settlement it either delivers from the hub vault at once (instant mode) or sends the Relay transaction toward the pass (bridge mode).
- Triggers sweeps: once ETH sits in a pass it calls
sweepon the hub. Sweeps are permissionless: anyone could, the relayer simply does.
The relayer key is the only Zecpass key that holds user value, and only on Arbitrum One, for the seconds between rails. See Security for the bound on that exposure.
The hub
One contract on Robinhood Chain, Zecpass, with a vault, a fee, two rails and a set of passes.
- Passes.
passOf(beneficiary)is a CREATE2 address derived from the beneficiary alone. It exists as a plain address before anybody sends ETH to it, which is what lets Relay (or, later, NEAR Intents directly) pay it without knowing anything about Zecpass. The firstsweepdeploys the tinyPasscontract at that address; from then on it has code, areceive, and one function only the hub can call. - Sweep (rail two): anyone calls
sweep(beneficiary, minTokensOut). The hub pulls the pass's ETH, takes the fee, buys $ZECPASS through the market adapter and transfers the tokens to the beneficiary. - Deliver (rail one): the relayer calls
deliver(orderId, beneficiary, amountWei, minTokensOut)and the hub does the same buy from its own vault. Each order id can be delivered once, each delivery is capped, and the sum per UTC day is capped. This is the instant path. - Withdraw: the beneficiary, and nobody else, can call
withdraw(beneficiary)to receive the raw ETH sitting in their pass. It works while paused and before the token is set. It is the guarantee that a pass is never a trap. - Market adapter.
PonsMarketknows the two lives of a Pons token: the bonding curve, then the Uniswap V4 pool with the Pons hook. The hub callsmarket.buyand does not care which.
Contract details, events and invariants are in Contract.
The two delivery modes
| Instant mode | Bridge mode | |
|---|---|---|
| Trigger | vault balance covers the order and the caps allow it | otherwise |
| Delivery | deliver from the vault, right after NEAR Intents settles |
Relay to the pass, then sweep |
| User wait after settlement | one block | two blocks and a Relay hop, a few seconds |
| Where the Arbitrum ETH goes | Relay to the hub, to refill the vault | Relay to the pass |
| Trust | the relayer is trusted to only deliver against real settlements; caps bound the damage | the pass is the user's; the relayer only pays gas |
The vault is funded by the treasury from the token's creator fees and the hub fee. An empty vault is not a failure, it is bridge mode.
Order state machine
created → awaiting_deposit → deposit_seen → settling → settled_arb ─┬─(instant)─▶ delivering → delivered
│ │ └─(bridge)──▶ bridging → bridged → delivering → delivered
└─▶ expired └─▶ refunded | failed
Every transition is appended to the order's event list with a timestamp and a note, so an order is its own audit trail. The Relayer page lists the exact conditions for each edge.
What runs where
| Component | Runtime | State |
|---|---|---|
web/ |
Vercel, Next.js | none; reads chain and relayer on request |
relayer/ |
Fly.io, Node 22 | orders.json on a volume |
contracts/ |
Robinhood Chain | hub storage, passes |
| $ZECPASS | Pons V2 | curve, then Uniswap V4 |