OpenChart
Free Desktop charting with Claude or Codex. Describe alerts, research chart moves, and choose your data providers.
Payment links and QR codes for MUSD on Mezo, with a payer-side guard that checks the token, the recipient and the amount before any transfer is built.
FinanceGitHub @theluckystrikeOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
Safe EIP-681 payment links and QR codes for MUSD on Mezo. A payer-side guard checks the token, recipient and amount before any transfer.
Taken from the repository README
Loading the full README.
Read the full README ↗Payment links, QR codes and invoices for MUSD on Mezo. A payer-side guard checks every link before a transfer is built. Built by Michael Lip (Warsaw, Poland) for the Mezo Buildathon on AKINDO, Access and Distribution track.
Testnet only. No real money. Each row was checked on chain or on the live Worker.
| What | Proof | Result |
|---|---|---|
Own borrow. pnpm testnet-borrow opens a trove | 0x1de64d3a...26f2 | 0.049 test BTC locked, 1,800 MUSD minted, block 16370809 |
Own payment of invoice INV-65ZVUMXW | 0x7abfedb1...cc0b | 5 MUSD with the reference in the transfer data, block 16370829 |
| Invoice found by its reference, no hash given | live GET /api/invoices/INV-65ZVUMXW | paid |
Signed invoice INV-P92MNPCN, made by pnpm create-invoice with the merchant key | live POST /api/invoices | 201, signed: true. Unsigned create gives 401 |
Payment of that invoice, then POST .../confirm | 0x9b8285c1...825c | confirming at 3 of 5 confirmations, then paid |
A second 5 MUSD payment to the paid invoice INV-65ZVUMXW | 0x95ef25c8...2dc4 | listed under duplicates, refund due |
| Same payment with a wrong reference or a later invoice block | live /api/verify | mismatch |
| MUSD contracts on testnet and mainnet | name(), symbol(), decimals() | "Mezo USD", "MUSD", 18 |
| Borrow quote from the live MUSD protocol | PriceFeed, TroveManager, BorrowerOperations, InterestRateManager | price, MCR, CCR, fee, minimum debt |
| Tests | LIVE=1 pnpm test on 26 October 2026 | 337 of 337 passed |
The payer and the merchant are both test addresses of the project. The payments came from scripts. No browser wallet has paid a link yet.
personal_sign, a free message). The Worker gives the invoice a unique reference and stamps it with the current block./?invoice=...) is payer-only. It shows the amount, recipient, token, network, reference, status with confirmation depth, the QR code and the Pay action. The merchant panels stay hidden.transfer call. It never holds a key.referenceMissing: true.CONFIRMATIONS_REQUIRED). Before that, the answer is confirming with the depth.GET /api/verify always returns final. It is false until the payment reaches 5 confirmations, and the pay page shows Confirming until final is true.POST /api/invoices/:memo/confirm with {"tx":"0x..."} records a payment by hash. It checks the stored invoice, not the caller. Use it for invoices older than the search window of about 23 hours.POST /api/invoices/:memo/accept with {"tx":"0x...","timestamp":...,"signature":"0x..."} records a payment that arrived without the reference. Only the invoice recipient can sign it. The signature covers the chain, recipient, reference, transaction hash and time. The payment must be the exact amount and at least 5 blocks deep. The stored payment has referenceMissing: true.recipient_no_checksum. A mixed-case address with a wrong checksum is refused.The guard also refuses fake and lookalike tokens, the wrong chain, amounts above uint256, unicode tricks, percent-encoding, extra or duplicated parameters, and approve or other functions. The tests in test/guard.test.ts list every case.
From the Mezo docs page "MUSD Payments With x402". Both are verified source on the Mezo explorers.
| Network | Chain id | MUSD contract |
|---|---|---|
| Mezo Testnet | 31611 | 0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503 |
| Mezo Mainnet | 31612 | 0xdD468A1DDc392dcdbEf6db6e34E89AA338F9F186 |
The MUSD protocol addresses come from the deployment files in https://github.com/mezo-org/musd and are in src/chains.ts.
ethereum:0x118917a40FAF1CD7a13dB0Ef56C86De7973Ac503@31611/transfer?address=0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed&uint256=12500000000000000000&memo=INV-1042
The amount is in base units (12.5 MUSD here). The memo is up to 32 characters. The guard appends its bytes after the transfer arguments. The MUSD contract ignores them. memo is not part of EIP-681, so a wallet that does not know it may drop the reference. Such a payment shows as a possible match for a person to check.
| Endpoint | Purpose |
|---|---|
GET /api/check?link=...&max=50 | Payer guard. 200 with the transaction, 422 with reasons. &checksum=1 refuses addresses with no checksum |
GET /api/link?chain=31611&to=0x...&amount=12.5 | Link and QR code |
POST /api/invoices | Signed create. Body has chain, to, amount, memo, timestamp, signature. 401 without a valid signature |
GET /api/invoices/INV-...?chain=31611 | Check one invoice on chain. paid, confirming or open. A paid answer lists later transfers with the same reference as duplicates, with duplicatesChecked |
POST /api/invoices/INV-.../confirm?chain=31611 | Confirm by hash with {"tx":"0x..."} |
POST /api/invoices/INV-.../accept?chain=31611 | Accept a no-reference payment. Body has tx, timestamp, signature by the invoice recipient |
GET /api/invoices?chain=31611&to=0x... | The 20 newest invoices of an address |
GET /api/verify?chain=31611&tx=0x...&to=0x...&amount=5&memo=INV-1 | Check one payment. Always gives final, with confirmations and required. final is true only at 5 confirmations |
GET /api/payments?chain=31611&to=0x... | Merchant inbox. matches and possible are null when not evaluated |
GET /api/borrow?chain=31611&need=25 | Borrow quote from the live MUSD protocol |
HTTP codes follow the answer. 200 for paid, paid_no_memo, confirming, open and pending. 401 for a bad signature. 404 for not_found. 409 for a used reference or transaction, and for a second payment of a paid invoice (already_paid). 422 for mismatch, failed and not_possible (a transaction for the other action, with or without the reference). 503 when the network does not answer. Errors never contain internal detail.
Chain routes send no CORS header. They allow 30 calls a minute per client. Writes allow 10 a minute. A Durable Object keeps the exact count.
Node 22 or later and pnpm.
pnpm install
pnpm test # no network
LIVE=1 pnpm test # also reads the real contracts
pnpm typecheck
pnpm deploy # Cloudflare Workers
Scripts that use a testnet key file. The key stays outside the repo and is never printed.
MEZO_KEY_FILE=/path/to/key pnpm testnet-borrow --dry-run
MEZO_KEY_FILE=/path/to/key pnpm testnet-pay "ethereum:..." 5
MEZO_KEY_FILE=/path/to/key pnpm create-invoice 5 # signed invoice for the key's address
signed: false.POST .../accept request for its transaction hash, so a person checks it first.MIT. See LICENSE.