What StableInvoice is
A tool for building professional invoices and payment requests that settle in stablecoins, straight between wallets. There is no account, no custody and no database: an invoice lives inside its own link, and your client opens that link to pay from their own wallet.
Everything runs in your browser. Your keys never leave it, and neither does your invoice data — the payload rides in the part of the URL that browsers never send to a server.
Three kinds of link
Payment links get forwarded. Which kind you send decides what the recipient can trust.
Unsigned
The default. Fast, and works without a wallet connected.
- Anyone holding the link can read it
- Anyone forwarding it can change the recipient address
- The payment page says exactly that, in plain words
Signed — recommended
One click. Binds the invoice to your Ethereum account.
- Recipient address, amount, token, chain and expiry are all covered
- Alter any of them and the payment page turns red and refuses to pay
- Still readable by anyone holding the link
Encrypted
For invoices whose contents are nobody else’s business.
- Only the holder of one X25519 key can read it
- Signed as well, so tampering is still detected
- Needs your client’s public key up front
What protects you
A correctly signed invoice can still be a fraudulent one. These cover that gap.
It remembers who you pay
The fraud that actually happens is not a stranger inventing a bill. It is a supplier you have paid eleven times, where the twelfth invoice quietly carries a different destination address. Everything else looks right because everything else is right — and no signature catches it, because the forged link is correctly signed by the forger.
So the payment page remembers which addresses you have paid each counterparty at. A familiar name with an unfamiliar address turns the page red and disables the pay button until you have checked. The record is written only after you actually pay — never just from opening a link, or a forged one would teach itself as trusted.
Safety numbers
“Confirm the address out of band” is useless advice when the address is 40 hexadecimal characters. In practice people check the first four and the last four — which is precisely the check a vanity-address generator beats.
So every recipient address also appears as a 20-digit safety number you can read down a phone line, in any language. The length is deliberate: a short fingerprint can be brute-forced until it collides.
What the app refuses to do
- Substitute a different token when the one you chose is not on that chain
- Build a link with an invalid or zero recipient address
- Round an amount it cannot represent exactly
- Show a green check for a sender it cannot genuinely confirm
- Put your bank details into a shareable link
Test networks are kept apart
Sepolia and other test chains sit in their own group in every network picker, labelled not real money. An invoice issued on a testnet can never be paid, and in a flat list that reads like just another option.
How encrypted invoices work
Encryption runs in both directions of a relationship: your client generates a key and proves it is theirs, and then you encrypt to it.
If you are being invoiced
- Open Generate Key and create an X25519 keypair. It is made in your browser and never uploaded.
- Export it with a passphrase. The plain-text option exists, but a passphrase-wrapped file is useless to anyone who finds it.
- Press Sign Public Key to bind it to your Ethereum address, then Copy signed bundle.
- Send that bundle to whoever invoices you.
If you are sending the invoice
- Paste their bundle into the recipient key field, or check it on Verify Key.
- The app recovers the signature and confirms the key really belongs to that address, rather than trusting a bare key someone pasted.
- Build the invoice and choose Create Encrypted Pay Link.
- Only their private key opens it. Lose that key and the invoice is unrecoverable, by design.
Privacy and custody
- No accounts, no sign-up, no invoice database
- Payments go wallet to wallet; funds never pass through us
- Private keys stay in your wallet, or are generated locally and never uploaded
- Invoice data rides in the URL fragment, which browsers do not send to servers
- Bank details stay in the PDF and are never embedded in a link
- Sanctions screening shares only the recipient address with Chainalysis — never amounts, names, or the invoice itself
Under the hood
- Vite multi-page build, Tailwind CSS, vanilla ES modules
- jsPDF for export, fetched only when you generate a PDF
- libsodium for X25519 encryption and Argon2id key wrapping
- EIP-712 signatures; EIP-681 wallet deep links and QR codes
- WalletConnect for mobile wallets; recipients screened against the OFAC SDN list before payment is enabled
- All third-party code is self-hosted — nothing loads from a CDN
- Strict Content Security Policy, with no inline scripts anywhere
From Telegram
Everything above assumes a browser. @StableInvoice_Bot does the common jobs from a chat, which is usually where the client already is.
Setting it up
/start— then/helpfor the full list/setwallet 0x…— the address you get paid at, stored once/setbillfromand/setbillto— company and client details for invoice PDFs/getwallet,/resetwallet— read it back, or delete it
Getting paid
/paymentlink charge 10 USDT on Polygon for 3 beers— plain English; the amount, token and network are read out of the sentence/invoice— the same, plus a PDF/payother— a transfer link for paying someone else/verify <tx> <chain>and/checkpayment— confirm a payment landed
What it stores, and how
- Your wallet address and billing details, so you do not retype them
- Encrypted at rest with AES-256-GCM, bound to your Telegram id so one record cannot be replayed as another
- Links are generated on demand — the bot keeps no invoice history
/resetwalletdeletes the stored address
Two honest limits
- Bot links are unsigned. They carry no signature, so a forwarded link can have its recipient address changed. For a stranger, make the link on the website and use Create Signed Link.
- Encryption is browser-only. Encrypted links need a key that never leaves your device, so the bot cannot make them. It will tell you so rather than pretend.
Get in touch
Questions, bug reports, or something that looks wrong on a payment page — we would rather hear about it.
Or message @StableInvoice_Bot on Telegram.
StableInvoice is powered by Bull Project.