Docs menu

CIPHR docs, for developers

Keeper

The signing route (api/mint-auth.js) checks a buy and signs an authorisation for it, using the shared library api/_snag-mint-lib.js. CIPHR does not run a keeper. Its collection only accepts a mint from the buyer named in the authorisation, because the buyer's own wallet has to attach the seal, so the buyer's own wallet is the one that calls the route, then submits the mint itself.

Status

What the route does, in order

POST { "txHash": "0x..." } to api/mint-auth.js. It refuses at the first failure, in this order, each with its own status code:

StepStatusMessage
Method and JSON shape405 / 400POST only / Send a JSON object
txHash shape400txHash must be 0x and 64 hex characters
Config present503minting not connected
Per-IP budget503 / 429busy, try again shortly / too many authorisations from this address, wait a few minutes
Receipt reachable502chain not reachable
Transaction exists404transaction not found
Transaction succeeded400that transaction failed
Two confirmations409buy is too new, try again in a moment
Collection readable, not paused, right chain502 / 503collection not readable / minting is paused / wrong chain
A qualifying pool-to-buyer transfer400buy under the minimum / no buy from the pool in that transaction
Not already used409that buy already has its piece
Domain and digest match the contract502collection domain mismatch
Success200buyer, buyRef, amountIn, deadline, signature, collection

Nothing is cleaned up on the caller's behalf. A malformed field is refused, never guessed at.

Rate limits

Six authorisations per client per ten minutes, counted by the first of x-vercel-forwarded-for, x-forwarded-for or x-real-ip. The store is bounded: expired windows are dropped first, and when every slot is held by a live caller a new caller is told the service is busy rather than evicting someone else's window.

The signer key is the trust root

Limit

Anyone holding SIGNER_KEY can authorise a mint for any address. That is the honest shape of this design: the chain proves the buy, but a server attests to it. The contract can rotate the signer (setSigner) and can be paused, and the owner is a two-step transfer that cannot be renounced, so a leaked key is recoverable. It is still a key, and it should live nowhere but the Vercel environment.

Why there is no funded keeper

On the base platform a keeper watches the pool, asks the route for an authorisation on the buyer's behalf, and submits the mint itself, so the buyer never pays gas. CIPHR requires the buyer wallet to submit mintForBuy with an enclave-signed seal. The buyer pays network gas. A keeper cannot substitute for the buyer or bypass the enrolled enclave key.

Resealing and revealing, later

Both are calls the holder makes directly on the collection, whenever they choose, again from their own wallet and at their own gas cost.

The buy signing route proves eligibility. Sealing, resealing and revealing also require the Phala CVM service, holder authentication and an enrolled enclave signature. A standalone wallet signature cannot replace the enclave proof. Production deployment and attestation remain unverified.