# Pay the winner of a Three.js game with Nano (XNO)

For an AI coding tool, or a developer. Source: https://nano133.com/build/three

The package `@nano133/three` (npm, MIT) does these steps: `npm install @nano133/three` (its Firestore store uses
`firebase-admin`, an optional peer). The code below shows the same pattern by hand. The page's demo, "Coin Run", checks each run on the
server for real. A run of all 10 coins can make one claim at the site's faucet: the faucet's gift for a new
wallet, with the faucet's own rules and limits. It is the same claim that the faucet page gives with no game,
and a win adds no Nano to it. That is not a send from a game's prize wallet, which is what this spec
describes; nano133.com has no prize wallet.

## What you build

When a player wins a round, the game's server sends a small prize to the player's Nano address. Nano takes no
fee from a payment, so a prize of a fraction of a cent arrives whole.

## The four steps

1. **The game ends.** The browser sends the round's id and the player's inputs to the game's server.
2. **The server checks the round.** It runs the same rule file on the inputs of a round that it started
   itself (and, in a game with chance, with the seed it made itself). The server decides the win. The
   browser's word is never enough.
3. **The server sends the prize** from the game's wallet, inside its limits, exactly once.
4. **The player's wallet shows it.** A Nano payment is confirmed, usually in under a second.

## Rules to follow

1. **One pure rule file.** No three.js, no clock, no `Math.random()`: `(inputs) -> result`, or
   `(seed, inputs) -> result` for a game with chance. The browser
   draws with it, the server checks with it. Give it a version, and replay a round with the version it
   started with.
2. **The server starts the round** and keeps its start time. A round cannot end sooner than its own length:
   refuse it, or let the game send it again later, when it comes too soon. In a game with chance **the server
   makes the seed** and keeps it with the round: a page that chose its own seed could choose an easy one.
3. **Inputs, not a score.** The game sends what the player did. The rule file must refuse inputs that no
   player could make (in the example: jumps that are not whole step numbers in rising order).
4. **A replay proves the result, not the player.** A script can play well. So the prize is small, and limits
   bound the loss: a prize limit for each player and each day, a total for the day, and a rate limit on the
   routes. Decide what a win is worth with that in mind.
5. **The key stays on the server**, in a secret manager. Never in the game's code, never printed, logged or
   committed. Keep only a small balance in the prize wallet.
6. **Pay once.** Close the round in one database transaction. Save the signed send on the round before you
   publish it; on a retry, publish the saved block again and never sign a second one.
7. **Who is paid.** Use an address your server already trusts for this player (for example from
   "Sign in with Nano": https://nano133.com/build/sign-in-with-nano). Do not take a payee from the request
   that ends the round.
8. **An empty wallet or a full limit** is a normal answer: the player won and gets no prize. Say so in the
   game.
9. **Check your law first.** A prize of money for a game can fall under rules on prize promotions or
   gambling where you or your players live. This page is not legal advice.
10. **Test with no real money first.**

## The example game: "Coin Run"

A little runner runs by itself along a fixed course of 26 seconds; the player's one input is a jump; there are
10 coins and 6 low blocks; all 10 coins is a win. Time is counted in steps of 1/60 second. The input is the
list of the step numbers at which a jump started. The course is fixed, so the game has no seed: a script that
knows the course can send a perfect list, which is why rule 4 matters. The files, in full, are on the page:

- `run.js`: the rule (`start`, `step`, `play`, the course as data).
- `game.js` (three.js) or `Game.jsx` (react-three-fiber): the picture and the recording of the jumps.
- `server.js`: a run starts, a run ends (replay, the least time, one use, limits), the send.

## Related

- Nano Checkout (take a payment, for example 1 cent to play): https://nano133.com/build/nano-checkout
- Late Payment Return: https://nano133.com/build/late-payment-return
- Sign in with Nano: https://nano133.com/build/sign-in-with-nano
- Nano for AI (an MCP server, a public node): https://nano133.com/ai
