aboutsummaryrefslogtreecommitdiffstats
path: root/lib/ecash.ts
Commit message (Collapse)AuthorAgeFilesLines
* ecash: identify our own tokens by keyset, not by the mint urlAdam Soltys2026-09-211-20/+28
| | | | | | | | | | | | | | The mint url in a cashu token is a label the sending wallet writes in, and tokens of ours turn up carrying stray ports and paths. Fetching it to compare pubkeys therefore rejected perfectly good tokens, and meant every /cash entry point made an outbound request to a user-supplied address. Keyset ids are derived from the mint's public keys, so a token whose proofs are all on our keysets is ours whatever url it names; a foreign one still fails, and now with a clear message instead of cashu-ts's short-id mapping error. A miss refreshes the cached keyset list once, in case of a rotation. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
* ecash: redeem tokens by melting to the user's own invoiceAdam Soltys2026-09-161-121/+108
| | | | | | | | | | | Redeeming ecash is now a plain NUT-05 melt into a Lightning invoice owned by the redeeming user, credited by the regular lightning listener. Drop the house proof pool and its lock, the /mint and /melt routes, and the special-casing of a mint account in NWC and payment routing. Tokens are decoded against the mint's keyset list so short v1 ids resolve, and an empty keyset list is never cached. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* ecash: make claims work against the v1 keyset mintAdam Soltys2026-09-141-19/+64
| | | | | | | | | | | | | | | cashu-ts 2.9.0 only derives v0 keyset ids, so CashuWallet rejected the mint's current keyset and receive() could never run. Build the wallet from keys preloaded off our own mint instead of verifying, decode tokens with the keysets (2.9.0 shortens v1 ids in the tokens it encodes, and won't expand them otherwise), and treat an unreadable house-pool value as empty rather than throwing — the pool key had been found holding a bare integer, which surfaced as "n.startsWith is not a function" on every redeem. The pool write is awaited so a dropped set can't strand freshly swapped proofs. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_0166Ci2XdCair1B9ych7w8dq
* security: drop the admin endpoint surface and land pending hardeningAdam Soltys2026-09-131-2/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Removes the admin-gated endpoints and the account flags they set, plus a batch of hardening that had accumulated uncommitted in the tree. These were deployed and verified together, so they land as one change. admin surface: - drop POST /hidepay, POST /unlimit and GET /users, their handlers, and the now-unused admin preValidation export - `unlimited` was only ever written, never read; `hidepay` only appeared in output projections. Both flags go, along with their whitelist, public-fields and type entries. request log: - redactBody now recurses. It only masked top-level keys, so a body that nests credentials one level down wrote them to the log in plaintext, and pin fields were not on the list at all. payments: - sendOnchain/build gate `aid` through requireAccount, so a caller can only spend from an account it owns - sendOnchain signs only a tx we composed, matched against a short-lived per-account build receipt - raise xpay retry_for to 60s; route-finding preferred a drained zero-fee hop and burned the whole budget on it. check()'s reversal window keeps its 2x margin. ecash / invoices / webhooks: - resolve a token's mint through the IP-pinning fetcher instead of plain fetch, closing an unauthenticated SSRF path into the internal network - reject non-positive amounts before the balance write - /sign requires the caller to own the address, rather than signing under any address the hot wallet controls - webhook delivery no longer disables TLS verification; the body carries the merchant's shared secret registration: - refuse a username the v3 registrar holds unless the caller's own nostr key is the holder (lib/names.ts) liquid: - honour the deposit kill switch at invoice generation and at credit elements image: - pin 23.3.4 and verify the release tarball checksum Co-Authored-By: Claude Opus 5 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_0112TGi9GGNWqji1XQ5jZRzc
* ecash: serialize the shared cash-key read-modify-write (S13)Adam Soltys2026-08-071-11/+36
| | | | | | | | | | | | The house Cashu holdings live as one token under redis `cash`. claim() and mint() decoded the current proofs, swapped at the mint, then wrote back — with no lock. Two concurrent claims read the same proofs and the later write clobbered the earlier, so already-swapped proofs vanished from the token while both users stayed credited (an insolvency leak, triggerable via the unauthenticated /ecash/:id callback). Wrap both read-swap-write sequences in an in-process mutex. Co-Authored-By: Claude Opus 4.8 <[email protected]>
* remove logsAdam Soltys2026-03-171-3/+1
|
* remove total user balancesAdam Soltys2025-03-281-0/+1
|
* picture not profileAdam Soltys2024-12-311-2/+0
|
* apiAdam Soltys2024-11-221-1/+1
|
* rm tagsAdam Soltys2024-11-221-2/+1
|
* mints arrayAdam Soltys2024-11-221-1/+1
|
* ecash receiveAdam Soltys2024-11-221-0/+23
|
* migrate info endpointAdam Soltys2024-11-221-2/+1
|
* migrate to new cashu-tsAdam Soltys2024-11-211-10/+8
|
* ecash requestsAdam Soltys2024-11-211-34/+18
|
* wipAdam Soltys2024-11-211-0/+20
|
* cash balanceAdam Soltys2024-11-061-0/+1
|
* save ecash idAdam Soltys2024-10-241-26/+51
|
* support multiple token versionsAdam Soltys2024-09-031-9/+16
|
* typescriptAdam Soltys2024-08-261-0/+60