Hi everyone,
I've been working on this project:
t.me/bitcointarotbot
It is still WIP. There may be bugs.
Madame Satoshi's is a Lightning-native Telegram bot.Madame Satoshi's is a Lightning-native Telegram bot.
Blending the ancient mysticism of tarot with the mathematics of Bitcoin.
Stack sats. Trust the cards. Have fun.
🔮 Madame Satoshi🔮 Madame Satoshi
Stack sats. Trust the cards. Have fun.
What Is This?What Is This?
Madame Satoshi's Bitcoin Fortune Oracle is a Lightning-native Telegram bot that blends the ancient mysticism of tarot with the mathematics of Bitcoin. For 21 sats, Madame Satoshi draws three cards from the Major Arcana and delivers a personalised Bitcoin fortune — each reading unique, each card a metaphor for your journey through the rabit hole.
Every draw is a permutation of fate: the order of the cards matters. The first card reveals a past influence, the second your present energy, the third your future outcome. With 9,240 possible permutations of the 22 Major Arcana, no two readings are quite alike.
How It Works
- Pay 21 sats via Lightning
- Receive an animated card reveal — three tarot cards flip over one by one
- Read your Bitcoin fortune, written in the language of the cards
- Win sats from the shared jackpot pool
Win Tiers
| Tier | Odds | Prize |
|------|------|-------|
| 🏆 JACKPOT!!! | 6 in 9,240 | 100% of pool |
| 🥇 MAJOR WIN!! | 66 in 9,240 | ~35% of pool |
| 🥈 MINOR WIN! | 666 in 9,240 | ~15% of pool |
The jackpot is shared across all players and grows with every draw. The rarest outcome — The Sun, The World, and The Magician, in any order — claims it all.
What We've BuiltWhat We've Built
- ⚡ Fully self-sovereign Lightning stack — no custodians, no third parties
- 🎴 Custom animated card reveals — real-time video generated per draw
- 🃏 Dedicated Bitcoin Tarot sticker pack — all 22 Major Arcana
- 💰 Live jackpot pool — grows with every play, paid out on the rarest draw
- 🔒 Balance system — deposit, play, and withdraw sats freely
- 👥 Group chat support — works in Telegram groups and private chats
- 🤖 Automated wallet management — routing reserves, fee handling, auto-recovery
Roadmap
- 🌐 Website — live jackpot display, recent draws, and public stats. Sponsors will be able to purchase a visible spot on the website, supporting the project while reaching the Bitcoin community
- 🟣 Nostr integration — receive your Bitcoin fortune over a decentralised protocol, pay with zaps
- 🔗 Wallet connect — let players link their own Lightning wallets
- 📖 Open source release — the full project will be open sourced under a FOSS license once completed and key milestones are reached
Why Support This?Why Support This?
Madame Satoshi is a love letter to Bitcoin culture — playful, self-sovereign, and built entirely on open protocols. No accounts. No KYC. No trusted third parties. Just sats, cards, and fate.
Your contribution funds server costs, Lightning liquidity, and continued development toward the website and Nostr integration.
Every sat contributed goes directly toward building something the Bitcoin community can enjoy and eventually own.
It would be cool if you could somehow base the randomness for the game on new bitcoin blocks. I have no idea how this would work, but getting a fortune told by the next bitcoin block seems like a really fun idea.
That is a great idea! No clue how to implement it.. but I will def. give it some thought. Thank you!
I think maybe the seed for the randomness could be based upon: seed = hash(blockHash + userId + timestamp)
Need to think about how this will change things. If it introduces attack vectors... and how it will influence the eventual website which should also have session IDs and nostr integration... hmmm..
I guess, if it is a hash that combines the blockhash with with huserId and a timestamp.. should be okay.. no‽
You probably know better than I. In my mind, I was thinking that it would be cool to tie card flips to the block at chaintip so that with each new block cards have different likelihoods of being selected, but this may mess up how you have set up the game.
I think players would enjoy a feeling that at any moment a new block might be found that changes their odds in the game. Or something like this.
The odds should be fair, pardoning the house, ofc. ;)
Only using the block-hash as a randomness-seed doesn't make sense. Everyone would get the same cards.
Making a new hash to use as a seed for the randomness that is individual per user, based on the newest block + userid + long/strong timestamp might make it more enjoyable/personal.
If I try and implement it, I would like to make it verifiable. for users too.
I Need to think about that.
How to give users this ability?
I guess all they would need is the blockhash, their user id, and the timestamp that was used plus the hash that came from it to in turn produce the randomness of the draw.
I don't know how much space it would take in the TG bot's text baloon to add all that.
Perhaps a better plan for the website.. Or maybe add a command..
I need to think about it a bit more.. It should take up minimum space.
Maybe it could be represented as a short code-block that pre-presents them the command they could run in their own terminal or on some website?
@Scoresby, added a /verify command.
You can now verify seed generation in your own terminal. Bot will give you instructions via /verify command.
For sure! I didn't mean to derail you, but it sounds like using some randomness from the most recent block could be cool.
Nah, you did not derail me. You presented a wonderful addition!
Implemented it tonight! Here's how it works:
Each draw is seeded by SHA256(blockHash + userId + timestamp) — combining the latest Bitcoin block hash with the user's Telegram ID and a millisecond timestamp. This means every draw is unique per user, unpredictable in advance, and anchored to the Bitcoin blockchain.
Users can run /verify after any draw to see the exact block height, full block hash, seed, cards drawn, and timestamp — plus a direct link to that block on mempool.space to confirm it's a real block.
The odds stay fair — the block hash is just entropy, not a variable that changes win probabilities. The house edge is unchanged.
Once the code is open sourced on GitHub, anyone will be able to fully reproduce any draw from those three inputs. Provably fair, Bitcoin-native. ⚡
Check out the new functionality if you wish: t.me/bitcointarotbot
And, play us a song on noderunnersradio.com ! ;)
Very cool i started a similar project on evm, got sidetracked and never polished it. This looks cool, will give it a spin
E: gave it a spin, would be cool to have the madame/bot interpret your tarot reading. I was toying with the idea of doing that with AI
Look closer at the output after a draw:
Card order matters — draws use permutations (P(22,3) = 9,240), not combinations.
Each permutation also has multiple possible fortune outcomes.
PS, the project is now FOSS under GPL v3 on github:
https://github.com/artdesignbySF/BTC-tarot-telegram-bot
Try multiple draws, and you will see that the Fortune told will differ for each.
etc.
I got the following draw that only listed the cards? it may be because this was my first freebie draw?
I've based the drawing on a traditional Major Arcana (22 cards, 0-21, with a 3 card spread.
Cards represent:
1st: Past
2nd: Present
3rd: Future
It picks from this TG sticker pack I made: https://t.me/addstickers/BitcoinTarot
22 cards, plus one face down card. I need the face down card for later stuff.
I'll send you some sats by tipping your previous comment so you can draw more times.
End yes, it only draws three random cards from the 22.
Read the readme on github, man.. If you don't believe me, II don't have time to explain it further. ;)
Major update.
You can now verify the randomness was created fairly!
Just type /verify to the t.me/@bitcointarotbot
Randomness is based on a seed created by combining latest Blockheight Hash + UserId + Timestamp.
In your terminal, type:
node -e "
const crypto = require('crypto');
const seed = crypto.createHash('sha256')
.update('000000000000000000001393dd546c5e3ad8281bd161134a698bd15929afe3d9' + 'USER ID REDACTED' + '1773318801023')
.digest('hex');
console.log('Seed:', parseInt(seed.substring(0,8), 16));
"
And it will give you, in this case:
Seed: 1226359555
Which will correspond to your unique draw.
Fellow Lightning-native bot here — interesting to see the block-based randomness approach.
The verifiable randomness via Bitcoin blocks is elegant. The only edge case: what's the UX when a user requests their card during a long block interval? 10-minute average means potentially long waits if the seed depends on the next block.
One approach: commit to the current block hash at request time, generate immediately, but let the user verify post-facto using that block's hash as the seed. Removes the wait, maintains verifiability.
What stack are you using for the LN payment layer? LNURL-pay or something else? I've been playing with NWC for headless bot payments and curious what works best for Telegram.