YONDER docs, for developers
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.
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.
POST { "txHash": "0x..." } to api/mint-auth.js. It refuses at the first failure, in this order, each with its own status code:
| Step | Status | Message |
|---|---|---|
| Method and JSON shape | 405 / 400 | POST only / Send a JSON object |
| txHash shape | 400 | txHash must be 0x and 64 hex characters |
| Config present | 503 | minting not connected |
| Per-IP budget | 503 / 429 | busy, try again shortly / too many authorisations from this address, wait a few minutes |
| Receipt reachable | 502 | chain not reachable |
| Transaction exists | 404 | transaction not found |
| Transaction succeeded | 400 | that transaction failed |
| Two confirmations | 409 | buy is too new, try again in a moment |
| Collection readable, not paused, right chain | 502 / 503 | collection not readable / minting is paused / wrong chain |
| A qualifying pool-to-buyer transfer | 400 | buy under the minimum / no buy from the pool in that transaction |
| Not already used | 409 | that buy already has its piece |
| Domain and digest match the contract | 502 | collection domain mismatch |
| Success | 200 | buyer, buyRef, amountIn, deadline, signature, collection |
Nothing is cleaned up on the caller's behalf. A malformed field is refused, never guessed at.
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.
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.
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.