ZecpassGet a pass

API

There are two HTTP surfaces: the site's /api/* routes, which the browser uses, and the relayer's endpoints, which the site forwards to. Anyone can call either.

Site routes

The site proxies the relayer so that the browser talks to one origin. When NEXT_PUBLIC_RELAYER_URL is unset, the quote and rails routes fall back to calling NEAR Intents and Relay directly (dry), and the order routes answer 503 with a clear message.

GET /api/quote?amountZec=0.1

{
  "zecIn": "0.1",
  "ethOnArb": "0.056926831576983610",
  "ethOnArbWei": "56926831576983610",
  "ethOnHood": "0.056838",
  "ethOnHoodWei": "56838000000000000",
  "feeBps": 50,
  "ethToCurve": "0.056554",
  "usdIn": "149.64",
  "usdOut": "150.30",
  "timeEstimateSeconds": 454,
  "relaySeconds": 1,
  "source": "direct",
  "at": "2026-09-21T10:00:00.000Z"
}

source is relayer when the relayer answered and direct when the site asked the rails itself. Amounts are strings; do arithmetic on the Wei fields.

GET /api/rails

{
  "direct": { "available": false, "checkedAt": "…", "note": "no solver quotes ZEC to Robinhood Chain right now" },
  "relay":  { "available": true,  "checkedAt": "…", "note": "Arbitrum One to Robinhood Chain, about one block" },
  "source": "direct"
}

The relayer's version adds vault, token, hub, relayerArb and relayerHood.

POST /api/orders

Body {"amountZec":"0.1","beneficiary":"0x…","refundTo":"t1…"}. Returns the relayer's order object, or 400 with {error} on validation, or 503 when no relayer is connected.

GET /api/orders/:id and POST /api/orders/:id

Read an order; or post {"txHash":"…"} to forward the Zcash transaction id.

Relayer endpoints

Documented on the Relayer page. Same shapes as above, plus GET /stats and GET /health.

Upstream: NEAR Intents 1Click

Base https://1click.chaindefuser.com. What Zecpass sends:

POST /v0/quote
{
  "dry": false,
  "swapType": "EXACT_INPUT",
  "slippageTolerance": 100,
  "originAsset": "nep141:zec.omft.near",
  "depositType": "ORIGIN_CHAIN",
  "destinationAsset": "nep141:arb.omft.near",
  "amount": "10000000",
  "refundTo": "t1…",
  "refundType": "ORIGIN_CHAIN",
  "recipient": "0x5C9A100eC739Bd7d80F1502e97Be9f549986951F",
  "recipientType": "DESTINATION_CHAIN",
  "deadline": "2026-09-21T10:20:00.000Z"
}

Then GET /v0/status?depositAddress=… until SUCCESS, REFUNDED or FAILED. Optional POST /v0/deposit/submit {txHash, depositAddress}.

Without a partner key 1Click adds 25 bps to the swap. With one (ONECLICK_JWT), the partner schedule applies and any appFees are split with 1Click. Zecpass does not set appFees in version one.

Upstream: Relay

POST https://api.relay.link/quote
{
  "user": "0x5C9A…951F",
  "recipient": "<pass or hub on Robinhood Chain>",
  "originChainId": 42161,
  "destinationChainId": 4663,
  "originCurrency": "0x0000000000000000000000000000000000000000",
  "destinationCurrency": "0x0000000000000000000000000000000000000000",
  "amount": "<wei>",
  "tradeType": "EXACT_INPUT"
}

The answer carries one transaction (steps[0].items[0].data) to send on Arbitrum One and a requestId to poll at GET /intents/status?requestId=….

Reading the chain yourself

The hub's ABI is in web/src/lib/abi.ts. Useful reads: passOf(address), token(), feeBps(), paused(), totalOrders(), totalEthIn(), totalFees(), totalTokensOut(). Logs: Delivered, Swept, Withdrawn. RPC https://rpc.mainnet.chain.robinhood.com, chain id 4663.