Docs menu

YONDER docs, for developers

Keeper

YONDER has a signing route (api/mint-auth.js) but no funded keeper submitting mints on a buyer's behalf. The route reads a buy from the chain and signs an authorisation naming the buyer; it never touches the stealth address, the ephemeral key or the view tag, because those never leave the buyer's own browser. The buyer's own wallet has to be the one that calls mintForBuy, since the contract requires the sender and the authorised buyer to be the same address, so the buyer pays the gas.

Status

Limit

The generic family keeper script, scripts/snag-keeper.mjs, is present in this fork's file tree as shared infrastructure, but it cannot submit a YONDER mint. It would need to send the transaction from its own funded wallet, and the contract rejects any mintForBuy call whose sender is not the authorised buyer. There is no relayer for YONDER; "Get my pieces" on the buyer's own wallet is the only path to a mint.

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 signature only ever names the buyer, the buy reference, the amount and a deadline; it says nothing about the stealth address, the ephemeral key or the view tag the buyer supplies at submission time, so a leaked signer key cannot redirect where anyone's piece lands. 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 keeper for YONDER

A generic mint-relayer needs its own wallet to submit the mint, funded and separate from the buyer's. YONDER's contract will not accept that: mintForBuy reverts unless msg.sender is the same address the authorisation names as buyer. A relayer would have to impersonate the buyer's wallet to submit for them, which it cannot do. So for this fork, the only path from an authorisation to a minted piece is the buyer's own wallet, opened on Get my pieces, calling the contract directly and paying its own gas.

Failure modes and recovery