| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
- warn-box, addr-box, summary, toast and green badge/notice borders used
hardcoded light colors that washed out or vanished in dark mode; route
them through theme variables (new --toast-bg/-fg and --green-line pairs).
- Drive the footer "Install app" link from a persisted localStorage flag
instead of the live beforeinstallprompt event so it's present on first
paint after a refresh, eliminating the layout shift.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Dark mode: theme variables + a footer "Dark mode/Light mode" toggle,
persisted and applied pre-paint via a small head script (defaults to the
OS preference). Hardcoded surfaces moved to CSS variables.
- Gift amount: the unit label is now the clickable sats/BTC toggle, and the
amount is parsed in the selected unit.
- Gifts can now span multiple coins: createGift selects several confirmed
coins (first input SIGHASH_SINGLE to lock the change, the rest
SIGHASH_NONE), so a gift larger than any single coin works. Claim/preview
sum all inputs and size the fee by input count. Verified end-to-end.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
| |
It now lives in the global footer, available on every screen.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
| |
The link already targets the selected explorer (explorerTx); only the
label said mempool.space. Now generic, across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Defense-in-depth so the "payment received" screen can never fire for an
old payment on opening a wallet: in addition to the ack baseline, require
an incoming tx that is pending or confirmed within the last ~2 hours.
Verified it still celebrates genuine new (pending/recent) payments.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
| |
It was redundant with the "Saved · forget" link shown beneath the name.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- The Accounts action is now "Clear all", which prompts a confirmation
warning that any wallet whose recovery phrase/key isn't backed up will
be lost. Confirming wipes everything from the device: session accounts,
the encrypted vault, and saved watch-only accounts.
- Each account has a rename (✎) control: edit the label inline and save.
Persists to the session, the watch-only store, and the vault as needed.
New strings translated across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Home screen is back to two tabs (Create / Import). The Import box now
takes a recovery phrase, an xpub/zpub, or an xprv/zprv:
- mnemonic → full wallet (as before)
- xpub/zpub → watch-only (view/receive, no Send)
- xprv/zprv → full spending wallet with no mnemonic. parseExtendedKey
classifies + normalizes version bytes; account() derives the BIP84
path from a master xprv (depth 0) or uses an account-level xprv as-is;
signing works (only watch-only blocks it). Vault persists xprv accounts
too; Settings shows an "Imported key" note instead of a recovery card
and hides Nostr sync (no seed). Public-key export still works.
Note: a seed phrase cannot be derived from an xprv (one-way KDF), so an
xprv wallet has no recovery words by design. New strings in all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The "payment received" screen is for payments that arrive while you're
using the wallet, but the seen-index is persisted per-seed, so
re-importing/unlocking/switching to a wallet used before would resurface
the celebration for a payment that had already arrived (and confirmed)
in between. Opening a wallet (import, unlock, account switch, watch-only
add, fresh-session restore) now baselines the ack to the current receive
frontier; only a same-session refresh keeps the persisted ack so an
unacknowledged live celebration survives the refresh.
Verified: with a stale persisted ack, a fresh import shows no
celebration and re-baselines to the current frontier.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Two paths left a tx's confirmed flag stale once the balance had already
reconciled:
- The frontier poll re-fetched an address's txs but only appended new
ones (`if (!txs.some(...))`), so a tx that moved from mempool to a
block kept its old pending status. Now it refreshes the record in place.
- On reload, scan() skipped the history re-pull when the cached balance
already matched on-chain, so a stale-pending cached tx never updated.
scan() now also re-pulls history whenever any tx is still pending.
Verified: a cached pending tx that is confirmed on-chain flips to
confirmed (and pending balance clears) after a scan.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Per-account "Save on this device" encrypts a seed account into a
localStorage vault (scrypt KDF + XChaCha20-Poly1305 via @noble), so it
survives a browser close. On reopen, a vault prompt unlocks all saved
wallets with the password (or "Use another wallet" to skip). Default
stays session-only; the password is held only in memory for the session
and re-encrypts on save/forget. Wrong password fails closed (AEAD).
Adds @noble/ciphers dependency. New strings translated across all 19
locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Accounts: a switcher (header chip → Accounts screen) lets you keep
several wallets loaded and flip between them without re-importing. Per
the chosen model, full (seed) accounts live only in sessionStorage —
ephemeral, no seed on disk; watch-only accounts (no seed) are persisted
in localStorage and reload across restarts. enterWallet is refactored
around an accounts list (add/switch/remove/lock); Add wallet reaches the
unlock screen with a back button.
Watch-only: load any wallet from its account xpub/zpub (parseAccountKey
normalizes zpub→xpub; the existing public-derivation path yields the
same addresses). Signing is blocked, the Send tab and seed/sync/offline
cards are hidden, and a watch-only note is shown. Settings gains a
"Public key" card (export this wallet's zpub) so it can be watched
read-only elsewhere.
Password-encrypted persistence for full accounts is the planned next
step. New strings translated across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Minimum: the flat 546-sat floor is replaced by a fee-aware minimum
(dust + one claim fee of headroom, floored at 546) via giftMinimum(),
so the recipient clears dust comfortably even if fees rise before they
claim — e.g. ~1000 sats at 5 sat/vB, ~7300 at 50. The create form shows
the live minimum and rejects below it; buildClaimTx keeps the hard
294-sat dust guard as a final backstop (claim fails rather than handing
over dust).
UI: the gift entrypoint moves from Settings to a "Gift some Bitcoin"
link on the Send page, opening the gift view as a send sub-view with a
back button.
New strings translated across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Passive reclaim previously dropped the coin from tracking, so there was
no way to revoke afterward. Now reclaim moves the coin from "reserved"
to a "reclaimed" set: it becomes spendable, but its still-live link
stays listed (tagged "still claimable") with a Revoke option, until the
coin is actually spent (by a payment or by revoking), at which point it
drops off. revokeGift and outstandingGifts handle both sets; existing
reserved gifts are unaffected. Strings updated across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The reserved-coin button is now "Reclaim". Tapping it prompts a choice:
- Reclaim (free): just un-reserves the coin so a future payment can
spend it — no fee, but the link stays claimable until then.
- Revoke now (pays a fee): sweeps the coin back immediately, killing
the link once it confirms.
New/updated strings translated across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The old "Reclaim" only un-reserved the coin locally, so the gift link
stayed claimable. Replace it with "Revoke": a confirmed action that
sweeps the reserved coin back into the sender's own wallet at a high
fee (wallet.revokeGift), double-spending the gift's presigned input so
the link can't be claimed once it confirms. Races a simultaneous
claimer; if the gift was already claimed the broadcast just fails.
New strings translated across all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Gifting no longer shares a seed. "Gift some Bitcoin" (Settings) presigns
a chosen amount as a #gift= link: one SIGHASH_SINGLE input (the sender's
change output is cryptographically fixed, so a front-runner can only take
the gift portion, never the change) plus the rest left open. The coin is
reserved per-wallet so normal sends skip it; reclaim it anytime.
Opening the link generates a brand-new wallet the sender never sees,
shows the amount, and on Claim adds the claimer's address as the output,
finalizes, and broadcasts — then prompts backup of the fresh seed. This
gives forward secrecy (sender locked out once confirmed), one-shot
semantics (claiming spends the input), and keeps funds in the sender's
wallet until claimed.
Crypto verified end-to-end (sign NONE/SINGLE -> add output -> finalize ->
valid tx; deterministic-signature equality proves the presigned sig is
valid for any output the claimer picks). Strings retranslated across all
19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Create a #claim=<code> link from Settings → "Gift this wallet" (gated
behind a reveal + warning, with a QR): the seed (and passphrase, if any)
are encoded as BIP39 entropy in base64url in the URL fragment, which
never reaches a server. Opening such a link loads that wallet and shows
a welcome → balance → firm "back up your recovery phrase" flow, then
drops into the wallet. The claim code is scrubbed from the address bar
on load.
Bearer by design — whoever opens the link controls the funds — so the
creator UI warns to keep amounts small. New strings translated into all
19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
Bump now opens its own screen with the Economy/Normal/Priority/Custom
fee tiers (defaults to Priority) and a live "fee: old → new" preview as
you change the rate, then Replace builds + signs + broadcasts. Refactor
bumpTx into prepareBump (async fetch/reconstruct) + planBump (pure
preview) + buildBump (sign), so the picker can preview each rate without
rebuilding. New bumpInsufficient string translated into all 19 locales.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Signal opt-in RBF (BIP125, sequence 0xfffffffd) on all new sends so
they're replaceable.
- "Bump fee" on an unconfirmed sent tx (its detail view): rebuilds the
same inputs + recipient outputs at the Priority rate, taking the extra
fee from the change output (pulling in a confirmed coin if change can't
cover it), re-signs, and routes to a "Replace with a higher fee?"
confirmation showing old → new fee before broadcasting.
- New keys translated into all 19 locales.
Honest scope: P2A/TRUC/package-relay are L2/pre-signed-tx + node-relay
features that don't apply to a single-sig wallet broadcasting single txs
via public explorers, so they're intentionally out. CPFP (for receives /
unbumpable sends) is a possible follow-up.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Only English is bundled in index.html now; the other 19 languages are
emitted as dist/locales/<code>.json and fetched on demand when a visitor
actually uses one (via auto-detect, the picker, or ?lang=xx). This drops
index.html from ~511KB to ~318KB; a non-English visitor fetches just
their one ~8-10KB locale, which the service worker then caches for
offline use. t() falls back to English until a locale resolves.
- i18n.js keeps only en + a loadLocale() fetcher; locale data moved to
src/locales/*.json.
- build.js emits dist/locales/; dev.js serves /locales/<code>.json.
- Deploy hook publishes the locales/ subdir.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- Rewrite README: Hal Wallet name, halwallet.app, configurable explorer,
QR scanner, optional/configurable Nostr sync, PWA, updated layout and
reconcile/security notes.
- Translate the ~31 UI keys added this cycle (explorer, device sync, QR
scanner, How it works, install, etc.) into all 19 languages. Brand and
technical tokens (Hal Wallet, Hal Finney, mempool.space, BIP39/BIP84,
Sparrow/Electrum, Nostr, URLs) kept literal so linkify still matches;
appTitle stays "Hal Wallet" via English fallback.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
A footnote at the bottom: "The name Hal Wallet is a tribute to
legendary cypherpunk and Bitcoin pioneer, Hal Finney (1956–2014)",
with his name linking to his Wikipedia article. The contextual nod,
rather than leaning on his name up front.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Settings → Block explorer: pick mempool.space (default, with
blockstream.info as a silent failover), blockstream.info only, or a
custom Esplora/electrs REST URL (e.g. your own node). The realtime
WebSocket only applies to mempool.space; other explorers fall back to
polling. Switching rebuilds the API and rescans. Replaces the old
undocumented explorer-proxy hack.
- How it works: merge the "For the technically curious" disclosure into
the main body so it's all visible under "The basics", and dedupe the
overlapping no-server/offline sentences. Mentions the new explorer
setting.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
- Name the app "Hal Wallet" (header, title, PWA manifest, package.json).
A nod to Hal Finney — just the name, no taglines or tributes.
- appTitle is a brand name now, so it's constant across locales (dropped
the translated overrides; they fall back to "Hal Wallet").
- Replace the native <select> caret with a custom chevron spaced off the
right border (the native one is crammed against the edge in Chrome).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Device sync:
- Add a "Device sync" settings card: toggle (on by default) + editable
relay list (defaults to wss://relay.coinos.io). When off, the wallet
never contacts a relay. nostr.js is now multi-relay and reads an
enabled/relays preference from localStorage.
Reconciliation (fixes a stray "payment received" + stale history on
import, especially via the Nostr/cache load path):
- Always full-scan on load instead of a frontier-only refreshLive, so
balance, history confirmations and spends are reconciled and the
celebration baselines against everything that already exists (cache/
Nostr still shows instantly first).
- Actually start the periodic full-scan safety net (_deepTimer, 2 min);
it was declared but never wired up.
- WS pushes now refresh an existing tx's pending→confirmed status, not
only add new transactions.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
refreshLive only walked the frontier forward, so a coin spent from an
already-scanned address never reconciled — the balance stayed stale
until a full rescan, even after the spend confirmed (e.g. a tx
broadcast from another device). Add _reconcileHeld: re-verify every
address that currently holds a UTXO and rebuild its balance/UTXOs from
the explorer, catching spends whether pending or confirmed. Runs in the
refreshLive path (load, poll, WS), so a refresh now self-corrects.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- Headline balance now shows wallet.total (confirmed + mempool) instead
of confirmed, so a pending outgoing spend is debited immediately rather
than waiting for confirmation. The chain_stats-based confirmed balance
counts a coin as yours until the spend is mined, which is why it didn't
drop after broadcasting (incl. scanned-tx broadcasts). Incoming pending
is still surfaced by the "+X pending" line.
- summary { cursor: pointer } so the "Show QR" disclosure (and any other
<summary>) shows the hand cursor.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
The address input scrolls/truncates on mobile, hiding the ends. Render
the full address as wrapping text beneath it with the first/last 6
chars emphasized, so paste/type/scan can be verified without scrolling.
Updated imperatively on input so the field keeps focus.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Scan a Bitcoin address, a BIP21 URI (fills address + amount), or a
signed-transaction QR (opens a broadcast confirmation, then relays it)
from a viewfinder button on the Send form.
Decoder strategy keeps the main bundle small:
- Prefer the native BarcodeDetector (Chrome desktop/Android) — no lib.
- Otherwise lazy-load jsQR from a separate dist/jsqr.js, only when the
scanner is opened. jsQR stays out of index.html (~424 KB vs ~551 KB)
and off the initial load.
- The service worker precaches jsqr.js so offline scanning works for
installed PWAs on browsers without BarcodeDetector.
The scanner needs a camera + secure context, so it never shows on a
standalone file:// page; offline air-gapped signing is unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
- Add a "Sign & export (broadcast elsewhere)" action on the online
review screen so you can sign here and broadcast from another device,
not just in offline mode.
- The signed-result screen now reads as an amber caution ("Signed, but
not sent yet… it will not send on its own") instead of a green
success banner, so it can't be mistaken for a completed send.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
| |
The reveal-phrase Hide button used the default size (16px) next to the
btn-sm Copy phrase button (13px). Add btn-sm so they match.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
Chrome no longer shows an automatic install prompt, so catch
beforeinstallprompt and surface an "Install app" link in the footer
that replays the prompt on a user tap (hides once installed).
(nginx on the host now serves manifest.webmanifest as
application/manifest+json instead of octet-stream.)
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- Don't celebrate historical payments on import. receiveSeenIndex was
baselined to 0 before the scan ran, so when the scan advanced the
index every past payment looked new and flashed "payment received".
Leave it null until the post-scan ack logic baselines it.
- PWA: add a web manifest, ₿ icons (192/512 + maskable), theme/apple
meta tags, and a service worker that precaches the shell so the
installed app works offline. index.html stays self-contained; the
sidecar files just 404 harmlessly from file://. build.js emits them.
- Send page: drop btn-sm from the amount unit toggle so "sats" matches
the "Max" button size (both 16px).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
- Drop the @scure/@noble crypto paragraph and the passphrase paragraph.
- Link mempool.space in the no-backend paragraph; trim its trailing
"only your addresses leave the device" clause.
- "This page is one static HTML file" (was "The whole thing").
- Remove the cold-storage sentence from the offline paragraph.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
- Rewrite the How it works page in a plainer, less generated voice;
drop the intro lead, the receive/send paragraph, and trim the rest.
- Fix passphrase wording: "13th word" (12-word phrase), not 25th.
- genIntro: "It's" instead of "It is".
- Unlock screen: label the field "Passphrase" (was "Optional
passphrase") and drop the "leave blank if unused" placeholder.
- Remove now-unused hiwLead / optionalPassphrase / leaveBlank keys
and the .lead style.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
UI / copy:
- Footer: "made by Adam Soltys" (drop the heart) + a "How it works"
link on its own line, matching the footer's size.
- New "How it works" page: plain-language basics plus an expandable
"for the technically curious" section. Routed via ui.screen, with
Back/logo returning to wherever you opened it from.
- Scrub jargon from the main UI for newcomers: drop BIP39, soften
"raw hex" -> "code", "txid" -> "transaction ID", "air-gapped" ->
"offline"; replace em dashes in the intro/keys notes. The technical
terms now live only in the How it works technical section.
Import / scan performance (fewer requests -> fewer 429s, faster):
- Skip the /utxo fetch for fully-settled, zero-balance addresses
(they can't hold UTXOs) -- the bulk of a history-heavy wallet.
- Show balance as soon as the address scan finishes, then load UTXOs
and history in the background.
- Probe the receive and change chains concurrently so their per-hit
delays overlap.
- History fills in progressively as each address resolves, with a
loading indicator on the History tab.
i18n.js is now tracked; new English keys fall back to English for the
other languages until translated.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Fix the key/value rows wrapping awkwardly on narrow screens (right-align +
wrap-safe values, fixed-width key). Drop the redundant "When: Unconfirmed…"
line; pending now shows a single "Status: Pending (in mempool)". Confirmed txs
show Status / Block / Date.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Clicking a history item now opens an in-wallet details view (status, block,
time, amount, fee, full copyable txid) instead of jumping straight to
mempool.space — works offline from cached data, with mempool as an optional
outbound link. Back returns to the list; switching tabs/logout resets it.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
WS-detected deposits now get added to history (previously the ingest advanced
past the address so the tx never entered history — balance showed but History
was empty). Pending txs render with a "⏳ pending" badge, an orange-tinted row,
and "awaiting confirmation" so they're clearly distinct from confirmed ones.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
| |
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
- The "Payment received!" celebration now persists: the acknowledged fresh
index is stored (per seed) in localStorage, so a received payment keeps
showing the dialog until you tap past it, even after a refresh.
- Footer: only "GitHub" is the link now.
- README rewritten for the current state (mainnet-only, realtime, Nostr sync,
multi-recipient, sats default, explorer resilience, etc.).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
When a deposit lands on the shown address, the Receive tab now shows a
"Payment received!" dialog (with the amount and a green check) and waits for a
tap before revealing the next address/QR — instead of silently swapping it.
Tracks the acknowledged fresh index so only payments that arrive while
watching trigger it.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
|