Skip to content

API and GraphQL

zeko-proof-api is both a Mina compatibility façade and the Ethereum proof operator. The sequencer points its L1 and archive GraphQL URIs at this service; users continue to send ordinary L2 transactions to the sequencer itself.

Mina GraphQL subset

The gateway implements only operations used by src/app/zeko/sequencer/gql_client/gql_client.ml:

OperationBacking data
accountComplete virtual Mina account JSON seeded at genesis and updated after confirmed settlements.
pooledZkappCommandsPending settlement commands persisted by the gateway.
pooledUserCommandsPending signed commands, when present.
actionsExact proof-emitted outer actions indexed from confirmed Ethereum receipts.
networkStateCanonical/finalized Ethereum heights used by the Actions indexer.
eventsEmpty list; the current sequencer path does not require event data.
genesisConstantsConfigured genesis timestamp and account-creation fee.
runtimeConfigConfigured fork slot.
bestChainCanonical Ethereum block numbers and hashes in Mina-shaped fields.
sendZkappQueues an EthereumSettlementInput exported by the OCaml committer.

Operations outside this subset return a GraphQL error. This is not a general Mina node proxy.

The separate POST /archive/graphql route exposes the two read-only operations needed by the Actions indexer and browser SDK: networkState and block-ranged actions. It derives them from the canonical Zeko archive PostgreSQL pool, including action-state boundaries, transaction hashes, and account-update IDs. It is an archive adapter, not a second source of L2 state.

Settlement mutation authentication

The current OCaml client cannot attach a custom HTTP header, so sendZkapp carries gatewayToken as a GraphQL variable. The sequencer reads it from ZEKO_ETHEREUM_GATEWAY_TOKEN. Read queries remain unauthenticated.

The mutation is idempotent by the exported Mina transaction hash. Reusing a hash for different proof input is rejected. The command remains visible in the pending pool until the Ethereum transaction reaches consensus finality. New commands must also use the configured outer account and the fee payer's current virtual nonce. This prevents failed proof attempts from creating nonce gaps that could not be derived when replaying accepted settlements.

REST API

Operator routes

These routes require x-api-key: <PROOF_API_KEY>:

Method and pathPurpose
POST /v1/settlementsQueue a settlement proof bundle. Alias: /v1/proofs/settlement.
POST /v1/bridge/deposits/proveQueue the next canonical finalized deposit batch.
POST /v1/proofs/bridgeLow-level bridge fixture endpoint; not the production deposit entry point.
POST /v1/proofs/withdrawLegacy withdrawal fixture endpoint.
GET /v1/proofsList jobs, optionally filtered by kind/status.
GET /v1/proofs/:idInspect input digest, public values, costs, request and transaction state.
GET /v1/proofs/:id/quoteRead live auction parameters without creating a proof request.
POST /v1/proofs/:id/approveApprove one exact preflight digest with PGU and price caps.
POST /v1/proofs/:id/cancelReject a job only before a network request exists.

Public bridge routes

Method and pathPurpose
GET /v1/bridge/configChain, contract, decimal, finality-mode, and withdrawal-delay discovery for browser clients.
GET /v1/bridge/deposits?zekoRecipient=0x...&after=N&limit=NRecover a wallet's deposits after a page reload.
GET /v1/bridge/deposits/:nonceImmutable action/registry identity, deposit finality, proof, synchronization, and next user action.
GET /v1/bridge/withdrawal-requests?recipient=0x...&after=NDiscover withdrawal requests as soon as their canonical inner actions reach the archive, before settlement.
GET /v1/bridge/withdrawals?recipient=0x...&after=NDiscover indexed native claims.
GET /v1/bridge/withdrawals/:sequence/:offsetReturn one fixed-depth Merkle proof and live delay/cursor status.
GET /v1/bridge/token-withdrawals/:sequence/:offsetReturn registry identity, one fixed-depth ERC-20 Merkle proof, and live delay/cursor status.
GET /healthDatabase and Ethereum connectivity.

Deposit and ERC-20 withdrawal responses expose encodingVersion, registryIndex, and recordCommitment. Native deposits use version 0, legacy one-token actions use version 1, and both have null registry fields. Universal registry actions use version 2 and carry the exact index and canonical Mina Poseidon record commitment persisted from their accepted events.

Public explorer routes

The read-only explorer surface is served under /v1/explorer. It joins the Zeko archive through a separate read-only PostgreSQL pool with gateway and canonical Ethereum indexer state.

Method and pathPurpose
GET /v1/explorer/summaryL2, settlement, bridge, and source-health summary.
GET /v1/explorer/search?q=…Exact search across indexed record types.
GET /v1/explorer/blocks[/:height-or-hash]Archive blocks and their single user/zkApp transaction.
GET /v1/explorer/transactions[/:hash]Commands, status, and zkApp account updates.
GET /v1/explorer/accounts/:publicKeyLatest canonical observed account state and history.
GET /v1/explorer/settlements[/:id-or-sequence]Public proof progress merged with accepted Ethereum events.
GET /v1/explorer/deposits[/:nonce]Native deposit and synchronization status.
GET /v1/explorer/withdrawals[/:sequence/:offset]Withdrawal inclusion, delay, cursor, and claim status.

List cursors are opaque and limits are bounded to 100. Large numeric values are decimal strings. Public settlement objects do not expose proof inputs, approval data, request IDs, operator errors, or costs. See the L2 and settlement explorer for UI and deployment details.

Exposure policy

Bind the gateway and sequencer to a private address. Put a TLS reverse proxy in front of them and apply route-specific policy:

  • /graphql serves Mina-compatible account/archive reads to the sequencer and bridge clients; settlement submission still requires gatewayToken.
  • /archive/graphql serves the read-only Mina archive subset backed by the recoverable Zeko archive database.
  • proof job, quote, approval, and cancellation routes require both network restriction and API-key authentication.
  • bridge config, deposit/withdrawal discovery, and read-only GraphQL operations may be public and rate limited.
  • /v1/explorer/* may be public and rate limited; it does not make proof operator routes public.
  • PostgreSQL, RabbitMQ, DA RPC, and signer RPC must not be publicly reachable.

Do not expose the gateway directly to the Internet merely because it has an API key. Its GraphQL handler uses a deliberately narrow operation recognizer, not a full public GraphQL security layer.

API_CORS_ALLOWED_ORIGINS controls browser origins. Use an exact comma-separated allowlist in a deployment; * is intended only for isolated development.

Browser status model

Deposit responses expose both a stable status and nextAction. The status progression is confirminglockedproofQueued/provingbridgeProvensynchronized; approval mode inserts awaitingProofApproval. A terminal proof error is proofFailed. Browser code should display the server status and resume by nonce instead of keeping its own authoritative state machine.

Withdrawal amounts are decimal strings, not JSON numbers. This preserves the full Solidity/Mina uint64 range in JavaScript.

Virtual Mina state

VIRTUAL_MINA_ACCOUNTS_PATH seeds complete account objects for at least the outer account and sequencer fee payer. VIRTUAL_MINA_OUTER_PUBLIC_KEY tells the indexer where to publish bridge-produced actions.

Confirmed settlements update zkappState, the five-element action state, fee-payer nonce, actions, block view, and pending pool atomically with a stored pre-state snapshot. That snapshot makes live reorg rollback deterministic.

The snapshot and proof job are not the only recovery source. A fresh gateway indexes finalized bridge-transition and settlement events, decodes the exact accepted public values from Ethereum transaction calldata, and replays the outer account and action sequence in block/log order. For withdrawal proofs it joins the Ethereum-accepted root with canonical inner-action preimages from the Zeko archive and accepts the reconstruction only when the full Merkle root matches. See recovery and rebuild.

Experimental Zeko settlement and native bridge glue for Ethereum.