Docs menu

LOCKET docs, for developers

Keeper

The signing route (api/mint-auth.js) shares one library, api/_snag-mint-lib.js, with the same authorisation code a keeper would use elsewhere in the family. For LOCKET, that authorisation is only half the job. The route answers a wallet that asks for its own piece over HTTP, proving the buy happened; it never mints anything by itself. LOCKET has no funded keeper submitting mints on a buyer's behalf, because the contract only accepts the credited buyer as the transaction's sender, and only that buyer's own wallet can produce the sealed commitment and ciphertext a mint now carries. Finishing the mint, and later requesting a holder check, is the holder's own action, from their own connected wallet, paying their own gas.

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 and the keeper's own shell.

Finishing your own mint

There is no node scripts/snag-keeper.mjs run for LOCKET the way a plain buy-and-relay collection in this family would use one. Once the signing route answers, the holder's own wallet does the rest: build the encrypted commitment and ciphertext client-side after direct Lit identity discovery, then call mintForBuy directly, attaching the server's authorisation alongside that seal. The buyer's wallet pays the gas for that call, the same as any other on-chain action they take.

Opening later requires Lit TEE execution and a fresh read from pinned Robinhood Chain RPC. The Lit action sends an encrypted response to the holder browser. This is unverified live and stays disabled.

Failure modes and recovery