Skip to content

Instantly share code, notes, and snippets.

@melvincarvalho
Last active October 4, 2026 12:55
Show Gist options
  • Select an option

  • Save melvincarvalho/d51e456e8303f1ebfd092ac4dfac8638 to your computer and use it in GitHub Desktop.

Select an option

Save melvincarvalho/d51e456e8303f1ebfd092ac4dfac8638 to your computer and use it in GitHub Desktop.
Poker for sats, on Nostr keys, with no rake — what it is, what it is not, how to play, how to run your own table

Poker for sats, on Nostr keys, with no rake

Play: https://librepoker.org/sats/#ledger=a8ccb724eb2a17671502766fb3fbd319c3e588f659f15fffff7265413a7b5947&bot=d0284b87bbdac4d86520668bfb56d9cdfea4e5c387a934eb4ab016037c5cc201

Heads-up limit hold'em against a bot, for sats, where every hand settles the moment it ends and nobody takes a cut. Test coins only for now (txbt4, the BLAKE2b testnet4): worth nothing, which is the point while the rails are new.

What it is

flowchart LR
  subgraph you["Your browser"]
    K[Nostr key = your account]
    P[The table page]
  end
  subgraph relays["Nostr relays"]
    L[(Ledger · kind 30333<br/>signed by the operator)]
    R[(Requests · kind 3700<br/>join · transfer · withdraw)]
  end
  subgraph op["The operator (anyone can run one)"]
    O[Operator key]
    D[Deposit addresses<br/>one per account, derived<br/>from operator key + your did]
  end
  C[(txbt4 chain)]
  P -- reads --> L
  P -- signs & publishes --> R
  R -- applied every minute --> O
  O -- republishes --> L
  C -- deposits seen, credited --> O
  O -- withdrawals paid --> C
  K -. signs .-> P
  D --- C
Loading

Three small things, each of which you could run yourself:

  1. Your account is a Nostr key. Sign in with a NIP-07 extension or a key the page makes for you. Your did:nostr:<pubkey> is the account; there is no signup.
  2. The money is a Web Ledger run by a teller. An operator publishes a small signed JSON document (a Nostr event, kind 30333) listing every account's balance. Each account has its own deposit address, derived from the operator's key and your did, so the page shows you yours without asking anyone. Pay it from any wallet; the operator credits it after one confirmation.
  3. A hand is a signed transfer. When a hand ends, the loser signs a Nostr event (kind 3700: "transfer N sats to <winner>") and publishes it. The operator applies it and republishes the ledger. That's the whole settlement: a signature, no fee, no block, no rake. Your page applies it locally the instant it's signed, so the next hand deals at once.
sequenceDiagram
  participant You
  participant Page as Table page
  participant Relays
  participant Op as Operator (every minute)
  You->>Page: play the hand
  Page->>Page: hand ends: loser owes winner N sats
  Page->>Page: loser's key signs "transfer N to winner" (kind 3700)
  Page->>Page: applied to the local copy at once · next hand deals
  Page--)Relays: publish (retried until a relay has it)
  Relays->>Op: the transfer
  Op->>Op: apply, republish the ledger (kind 30333)
  Relays->>Page: newest ledger · the hand is checked off
Loading

Withdrawals are the same shape: you sign "withdraw N to <address>", the operator pays it from the deposits in one real transaction, and the ledger shows the debit. The operator for this table pays automatically, within a minute, up to 100,000 sats a go.

What it is not

  • Not trustless. The operator holds the deposits and writes the ledger. What's provable is that it can't invent a hand you didn't sign, and that the book must equal deposits minus payouts; what's trusted is that it pays out. Same trust as a poker club's cashier, with a public ledger.
  • Not private. Anyone with the operator's key and the ledger hash can compute every deposit address.
  • Not real money yet. txbt4 sats. Mainnet or Lightning on the same rails is a decision, not a technical gap.
  • This demo table's bot key is in the link. The bot is an account like any other, and the page needs its key to sign the bot's losses, so it travels in the URL fragment. Anyone with the link could play the bot's money or withdraw it. That's fine for a demo and will move to a house-run bot before it's anything else.

How to play

Open the link, press bank, make a key (or use your extension), copy your deposit address, send it some txbt4 from Reef (a node and wallet in a tab; the page links straight into its Send form) and press Join. When the block lands you're credited and can sit. Stakes 1/2 to 100/200, buy-in 100 big blinds. The bank panel lists your withdrawals with their state until they're paid.

Run your own table

Everything is a static page or a script, pinned by commit, AGPL:

Anything that can hold a Nostr key can add deposits, withdrawals and transfers with the client and a ledger hash — a tip jar, a paywall, another game. Poker is the first flower.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment