aboutsummaryrefslogtreecommitdiffstats
path: root/src/routes/(app)
Commit message (Collapse)AuthorAgeFilesLines
* nostr: fetch the encrypted key with the password when there's no session keyHEADmasterAdam Soltys29 hours2-1/+8
| | | | | | | | | Without the sk cookie from a password login (nostr logins, older sessions) the reveal button was hidden and signing failed. Ask for the password and get the key from /nsec instead. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UjHzoBmW1iPpEe5qC2LDYB
* nostr: sign with the session key instead of the encrypted key from /meAdam Soltys6 days1-1/+1
| | | | Co-Authored-By: Claude Opus 5.5 <[email protected]>
* send: explain duplicate submits instead of reporting a routing failureAdam Soltys13 days1-0/+17
| | | | | | | | | Resubmitting an invoice that was already paid, is still in flight, or is awaiting reconciliation came back as the generic "failed to route" error, which reads as if the payment never went out. Map those server responses to specific messages with a link to the payment history. Co-Authored-By: Claude Opus 5.5 <[email protected]>
* ecash: carry pasted tokens in the URL instead of storing them server-sideAdam Soltys2026-09-271-2/+11
| | | | | | | | The server no longer accepts anonymous token uploads. A pasted token now redirects straight to /ecash/<token>, and the page asks the server for the token's status statelessly. Ids from previously shared links still resolve. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* invoice: a reusable bolt12 offer has no terminal paid stateAdam Soltys2026-09-222-6/+44
| | | | | | | | | | | | | | | | | | | | | A bolt12 offer is a standing payment code. CLN derives the same offer_id from the same (amount, description), so re-creating one hands back the original record, whose `received` has accumulated over the offer's whole lifetime. The invoice layout read that as "this invoice was paid" and redirected to the success screen, so reopening a long-lived offer never showed the QR and left no way to copy the lno. Treat a payment as celebratory only when it arrives while the page is open: the socket handler now passes the amount of that payment as `?paid=<amount>`, and the layout uses it in place of the lifetime total for reusable offers. Single-use invoices keep the existing logic, so a partly-paid invoice still stays on the QR rather than celebrating early. The success screen showed lifetime `received` for the same reason, which misreported a single payment to a long-lived offer; it now renders the amount the socket reported, which is already net of tip. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
* Web flasher moves from /pos to /flash; /pos redirects there.Adam Soltys2026-09-213-0/+6
| | | | | | | | coinos v3 takes /pos for the point-of-sale till, so the terminal flasher needs its own address. Old links keep working through the redirect. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01Tmfg8k5f3TbNJS34qiqHAp
* send: stop the Max buttons from cancelling their own submit, show LNURL ↵Adam Soltys2026-09-212-5/+14
| | | | | | | | | | | | | | | | | | | | | | | action errors Choosing Max on the LNURL-pay page left the button spinning forever. Two things combined: The Max buttons set `loading` from their click handler. Svelte flushes `disabled={loading}` to the DOM before the browser runs the button's submit activation, and a disabled button submits nothing. Set loading from the form's onsubmit instead, the way the Send button always did. The /ln page never passed `form` into the Lnurlp and Lnurlw components, so any action failure (pay, max or withdraw) rendered nothing and never reset the spinner. Pass it through, and reset loading when a result arrives. Verified in headless Chrome against the dev stack: the bolt11 Max lands on the fee view, and the LNURL Max surfaces the server's error and re-enables the buttons. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* funds: remove the create, deposit, withdraw and gift buttonsAdam Soltys2026-09-212-41/+0
| | | | | | | | | | | | | Funds are retired, and the server now refuses deposits, withdrawals and pre-authorizations outright, so every one of these buttons led to an error. Gone: "Create a fund" on the send screen, and Add/Take funds plus the gift link on a fund's page. A fund's page still shows its balance, managers, share link and payment history, so existing funds stay readable while they are settled out of band. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
* send: quote the lightning routing fee up front and add Max to lightning sendsAdam Soltys2026-09-213-10/+166
| | | | | | | | | | | | | | | | | | | The lightning send page now asks the server what the payment will cost before showing the Send button: the exact routing fee from the route query, the platform fee, and the total. The quoted fee is submitted as the maxfee, so what the user sees is what gets debited; advanced settings still let them override it, and if the quote fails the page falls back to the old 2% reserve. Max on the amount step asks the server for the largest amount whose amount + routing fee + platform fee lands exactly on the balance, and for an offer picks up the invoice fetched for that exact amount. LNURL-pay gets a Max button too. The invoice only exists once we name an amount, so the action fetches a probe invoice at the ceiling, lets the server solve for the amount, then fetches the real invoice for it. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* ecash: drop the mint account special-case and the mint routeAdam Soltys2026-09-161-7/+0
| | | | | | | The server no longer keeps a house ecash pool, so there is no mint account to skip when parsing a payment and no /ecash/mint endpoint. Co-Authored-By: Claude Fable 5.1 <[email protected]>
* pos: reset the device and release the serial port when leaving the flasherAdam Soltys2026-09-141-6/+34
| | | | | | | | | | | | Connecting loads the esptool stub and parks the chip in the ROM download mode; only a successful flash reset it and closed the port. Navigating away, a failed connect, or a failed flash left the device looking frozen (OLED keeps its last frame, LED pin pulled up, keypad dead) with the browser still holding the port. Reset + release on component destroy and pagehide, on connect failure, and from a new Disconnect button. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01VMi2Y1oKPZ3TeeFmLej47y
* pos: offer "Flash latest release" from a published firmware manifestAdam Soltys2026-09-041-1/+70
| | | | | | | | | | | | Host the ESP32-C3 firmware under static/firmware (bootloader, partition table, boot_app0, app) with a manifest.json written by coinos-pos's publish.sh. The flasher fetches the manifest, downloads every part, verifies sizes, flashes them at their offsets and resets the device. The config partition is not in the manifest so credentials survive. Manual .bin upload stays available underneath. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_014gVYGi29FjTeLdNTiutkZx
* pos: hard-reset the device after flashingAdam Soltys2026-09-041-0/+28
| | | | | | | | | | esptool-js leaves the chip in the ROM bootloader stub after writeFlash, so the device appeared dead until power-cycled. Pulse RTS the way esptool.py does, drop the port (the C3 re-enumerates), and show a "device restarted" message next to the Connect button. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_014gVYGi29FjTeLdNTiutkZx
* pos: refuse to flash anything that is not a valid LittleFS imageAdam Soltys2026-09-042-1/+40
| | | | | | | | | | The flasher hex-encoded whatever the /flash endpoint returned, so a server error body was written to devices as the config partition. Check the response status, require a 128KB image with the LittleFS magic, and surface the error above the form instead. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_014gVYGi29FjTeLdNTiutkZx
* migrate: hand the name over to the registrar too — after flagging the ↵Adam Soltys2026-08-301-0/+28
| | | | | | | account, tell names.coinos.io which v3 identity may claim it (MIGRATE_TOKEN), with retries; without the grant the registrar squat guard refused every migrated claim Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01MrkLsNScXe9b6BviUSdmMr
* migrate: shorter button, drop the destination rowAdam Soltys2026-08-031-5/+2
| | | | | | | | | | "Move my balance and address to coinos v3" wrapped on a phone; the paragraph above already says what happens, so the button is just "Migrate". The destination row went with it — it only ever said "your coinos v3 wallet". Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
* migrate: flag the account instead of renaming itAdam Soltys2026-08-032-38/+12
| | | | | | | | | | Renaming to <name>v2 was a hack for freeing the username, and v3/v4/v9 fallbacks made it worse. The page now sweeps the balance and sets the new `migrated` flag: the registrar takes over receiving for the name while the old account keeps working here, unchanged. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
* migrate: the retired name has to be letters and numbers onlyAdam Soltys2026-08-032-9/+32
| | | | | | | | | | The server enforces /^[\p{L}\p{N}]{2,24}$/u, so <name>_v2 was rejected outright. Candidates are <name>v2, v3, … each trimmed to fit the 24-char limit (so a long username still lands inside it), and the rename walks to the next one if a retired name is already taken. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
* migrate: don't show the temporary v3 addressAdam Soltys2026-08-031-1/+3
| | | | | | | | | | It's an npub-shaped placeholder, and the whole point of the page is that the user keeps their real username — seeing "[email protected]" as the destination just reads as a mistake. The row says "your coinos v3 wallet" instead. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
* migrate: run the sweep server-side, and send the whole balanceAdam Soltys2026-08-032-88/+121
| | | | | | | | | | | | | | | | | | Two fixes from the first live test: The POST went out from the browser, where $lib/utils' base is "" — so it hit the SvelteKit page route and came back "POST method not allowed". Payments in this app all run server-side with auth(cookies), because that's where the session token is usable; /migrate is a form action now like the rest of the send flows. And the routing reserve is gone: the ASP's node has two direct channels to ln.coinos.io, so a sweep is one hop and costs nothing. It sends the full balance, only retrying 0.5% lighter if a payment actually comes back short. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
* migrate: satisfy the type checker on the error pathAdam Soltys2026-08-031-1/+1
|
* Add /migrate: hand a legacy account over to coinos v3Adam Soltys2026-08-032-0/+128
| | | | | | | | | | | | coinos v3 links here with ?to=<the user's new payment address>&back=<url>. The user is already signed in on this site, so no password or key has to travel anywhere: we fetch an invoice from the v3 registrar for the balance (less a small routing reserve), pay it, then rename the account to <username>_v2 — which releases the username so v3's registrar will let them claim it. Old account stays, renamed, and stops receiving. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
* payments: show lightning sends as pending until settledAdam Soltys2026-07-301-2/+12
| | | | | | | | | | | Lightning/bolt12 sends now start unconfirmed (server sets confirmed=false until the HTLC settles and the preimage arrives). Reflect that in the UI: the payment list and detail page show 'Pending' for an unsettled send, and the detail page shows a pending note in place of the empty preimage. Prevents the misleading 'Sent/completed with no preimage' state for held HTLCs (e.g. Ark hold invoices that stay in-flight for hours). Co-Authored-By: Claude Opus 4.8 <[email protected]>
* bolt12 zaps: accept offers in send flow, show/publish user offerAdam Soltys2026-07-303-6/+84
| | | | | | | | | | - parse lno= from BIP-321 bitcoin: URIs; send page parses offers for preview now that /parse handles them - settings/nostr shows the user's standing lno1 offer with copy/QR and a button to publish it as a kind 10058 offer list for NIP-177 zaps - new locale strings translated Co-Authored-By: Claude Fable 5 <[email protected]>
* receive/invoice: build POST body from snapshot, don't mutate $derivedAdam Soltys2026-06-192-22/+24
| | | | | | | | | | | | | | The merchant receive and invoice pages mutated the $derived `invoice` proxy (setType/setAmount/setMemo) then POSTed it. Mutating a $derived and JSON.stringify-ing it serializes unreliably, so a stale type (on-chain when lightning was expected) and a stale/10x-shifted amount could leak from a prior interaction into POST /invoice (funk POS bug). Build the body as { ...$state.snapshot(invoice), ...changes } so the intended type/amount/address_type reliably win; update() takes the plain body. Front-end only. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
* invoices fixAdam Soltys2026-06-171-20/+56
|
* fix invoices pageAdam Soltys2026-06-171-25/+72
|
* use searchparams for lnurlAdam Soltys2026-03-271-2/+4
|
* lnurl proxyAdam Soltys2026-03-271-3/+6
|
* max fee calcAdam Soltys2026-03-161-14/+7
|
* Fix subdomain matching in LNURL callback redirectAdam Soltys2026-02-251-2/+2
| | | | Co-Authored-By: Claude Opus 4.6 <[email protected]>
* display lightning invoice on payment detailsAdam Soltys2026-02-231-0/+5
|
* fix: rename hidden maxfee field to fee to match form handlerAdam Soltys2026-02-151-1/+1
| | | | Co-Authored-By: Claude Opus 4.6 <[email protected]>
* fix importsAdam Soltys2026-02-099-6/+12
|
* skip captcha for fundsAdam Soltys2026-02-062-145/+50
|
* pass captcha when sweepingAdam Soltys2026-02-062-46/+146
|
* fix captcha checksAdam Soltys2026-01-271-10/+10
|
* skip captcha for torAdam Soltys2026-01-271-0/+4
|
* redirect on invalid tokenAdam Soltys2026-01-212-5/+24
|
* move site key to envAdam Soltys2026-01-211-2/+3
|
* captchaAdam Soltys2026-01-212-2/+56
|
* increase default maxfeeAdam Soltys2025-12-101-2/+2
|
* fix nostr cancel buttonAdam Soltys2025-09-301-5/+2
|
* update flash pageAdam Soltys2025-09-262-50/+173
|
* pass cookies to parseAdam Soltys2025-09-182-8/+8
|
* default tokenAdam Soltys2025-09-132-10/+13
|
* pos routeAdam Soltys2025-09-112-0/+126
|
* remove unused importAdam Soltys2025-09-091-1/+0
|
* dark mode fixAdam Soltys2025-09-091-1/+2
|
* daisy fixesAdam Soltys2025-09-092-21/+21
|