| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The Device sync card and toggle are gone — sync is always on, riding
the user's own NIP-65 (kind 10002) write relays: the login npub's
first, else the wallet key's, coinos relay as the fallback and always
included. A fresh wallet identity with no NIP-65 publishes one
(default relay) so other clients can find its events.
The npub-locked-gift remnants go with it: the per-wallet nostr address
card that pitched gift-locking, the how-it-works sentence, the dead
NostrSync.sendDM/sendNostrDM path, and the orphaned claim-code field.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
| |
They're called wallets everywhere else — Add wallet, Wallet 1, wallet
settings — so the list heading matches. Stale locale translations
pruned to fall back.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
| |
Twelve words + what losing them means, one paragraph; no-server plus
offline, one paragraph; standards/restorability, one line. Stale locale
translations pruned to fall back to English.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
| |
electrum.coinos.io is the default data source now, not mempool.space,
and the basics card reads better without plumbing details. Stale locale
translations of the paragraph fall back to the new English.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The app already presents as Coinos; this finishes the job in the repo:
package name, README, GitHub link, code comments, and the stale locale
lines that still explained the old "Hal Wallet" name (they fall back to
the English tribute line). Kept: the hal-nwc-pouch IndexedDB name (an
upgrade-compat identifier), the halwallet.app domain in the BIP-353
names feature (live infrastructure), and the Hal Finney tribute itself.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
- 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]>
|
| |
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
- 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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|