Tips Agent Guide

Instructions for AI agents (and developers) to discover tip events, create Lightning invoices, pay them, and confirm world effects — without using the HTML tips UI.

0. Prerequisite: Lightning wallet

Agents must have a Lightning wallet that can pay bolt11 invoices (LNBits URL + API key).

If you have no wallet access:

  1. Tell the user you cannot pay tips because you have no Lightning wallet credentials.
  2. Suggest creating a wallet at https://lightning-fun.com/wallet.
  3. Ask them to provide:
    • LNBits base URL: https://lnbits.lightning-fun.com
    • The wallet admin key (or another key that can pay invoices)

Do not invent keys. Do not create tip invoices you cannot pay unless the user only asked for an unpaid invoice.

1. Canonical workflow

  1. GET /events/catalog?audience=viewer — discover events, prices, params
  2. If requires_online_receiver: GET /players/online and pick a username
  3. POST /events/{id}/invoice with event params + source:"viewer" + browserName
  4. Pay invoice.payment_request (bolt11) with any Lightning wallet (e.g. LNBits)
  5. GET /events/invoice/{payment_hash} until settled: true; check executeOk

2. Public endpoints

MethodPathPurpose
GET/events/catalog?audience=viewerTip catalog
GET/players/onlineOnline players
GET/world/timeCurrent world time
GET/world/musicMusic / playlist
POST/events/{id}/invoiceCreate tip invoice
GET/events/invoice/{hash}Poll settle + result
GET/tipsHuman UI (optional)

3. Create invoice

POST /events/{event_id}/invoice
Content-Type: application/json

{
  "source": "viewer",
  "browserName": "YourAgentName",
  ...eventParams
}

Response: invoice.payment_request (bolt11), invoice.payment_hash, invoice.amount (sats). Guest chat label becomes guest:YourAgentName.

4. Pay (LNBits example)

POST {LNBITS}/api/v1/payments
X-Api-Key: {lnbits_api_key}
Content-Type: application/json

{ "out": true, "bolt11": "lnbc..." }

5. Confirm

GET /events/invoice/{payment_hash}

# wait until:
# { "settled": true, "executeOk": true, "action_type": "...", "result": { ... } }

6. Live viewer catalog

Fetching /events/catalog?audience=viewer…

7. Static examples (defaults; prefer live catalog prices)

set_world_time — Set world time

world Fixed price · No receiver · Param: time (HH:MM) or seconds

curl -s -X POST "$BASE/events/set_world_time/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","time":"01:00"}'

change_music — Change background music

world Fixed price · Params: name (required), timestamp (optional). Tracks: GET /world/music

curl -s -X POST "$BASE/events/change_music/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","name":"BackgroundMusic1"}'

global_shout — Global chat shout

world Fixed price · Param: message (max 200)

curl -s -X POST "$BASE/events/global_shout/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","message":"Have a great stream!"}'

world_billboard — Contested sky billboard

world Price = rate × duration_min (+ optional rain_amount). Tier big/small. Optional rain at board XZ: rain_mode all|batches_continuous|batches_random, rain_start now|ISO. Unclaimed rain returns to signed-in tipper.

curl -s -X POST "$BASE/events/world_billboard/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","message":"Find sats","x":0,"z":0,"rate":5,"duration_min":10,"tier":"big","rain_amount":100,"rain_mode":"all","rain_start":"now"}'

change_crosshair — Change player crosshair

handicap Needs online receiver · selection: crosshair_bitcoin | crosshair_2 | crosshair_no | crosshair_original

curl -s -X POST "$BASE/events/change_crosshair/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","receiver":"Blocky","selection":"crosshair_bitcoin"}'

buff_speed — Speed buff (30s)

buff Needs online receiver

curl -s -X POST "$BASE/events/buff_speed/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","receiver":"Blocky"}'

freeze_player — Freeze player (5s)

handicap Needs online receiver · 10 sats · 80% → player wallet

curl -s -X POST "$BASE/events/freeze_player/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","receiver":"Blocky"}'

donate — Donate to player inventory

gift Needs receiver + amount (≥ min price). Optional message. Full share to player.

curl -s -X POST "$BASE/events/donate/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","receiver":"Blocky","amount":50,"message":"Thanks!"}'

rain_sats — Rain sats near player

gift Needs receiver + amount. Vector rain; unclaimed returns to signed-in tipper (guests no refund).

curl -s -X POST "$BASE/events/rain_sats/invoice" \
  -H "Content-Type: application/json" \
  -d '{"source":"viewer","browserName":"Agent","receiver":"Blocky","amount":21}'

8. Agent rules