aboutsummaryrefslogtreecommitdiffstats
path: root/src/features
Commit message (Collapse)AuthorAgeFilesLines
* Collaborative offboard: move the ark balance back on-chainAdam Soltys2026-07-051-10/+66
| | | | | | | | | | | | | | | | | | | | PrepareOffboard/FinishOffboard against captaind — per-input ownership attestations, connector-based musig forfeits (with the deterministic fanout tx when there is more than one input), and fee math that mirrors the server bit-for-bit (weight fee rounds up, ppm-by-expiry rounds down) since it rejects any other net amount. The receive pane gains a 'Move back on-chain' button that withdraws everything to the wallet's own fresh address; the incoming tx is labeled 'Ark withdrawal' in History and the ark side records the movement. Crash-safe: the txid persists before FinishOffboard and resume asks GetVtxoStatus whether the forfeits landed (the server broadcasts the tx itself). Also fixes boarding to applySentTx after broadcasting the funding tx — without it the spent coin lingered in the utxo set (a second board double-spent it), and the post-board scan() could resurrect it by racing the explorer's indexing. Co-Authored-By: Claude Fable 5 <[email protected]>
* Boarding UX: label the funding tx and show an in-flight ark balanceAdam Soltys2026-07-051-2/+25
| | | | | | | | | | The board's on-chain send showed as a generic 'Sent' and the sats vanished from the balance until the vtxo registered. The funding tx now reads 'Ark board' in History (with a detail section showing the net credit), and an 'Ark (boarding…)' line carries the pending amount from broadcast until the board completes. Co-Authored-By: Claude Fable 5 <[email protected]>
* Per-network nostr sync + honest balance loading stateAdam Soltys2026-07-041-2/+9
| | | | | | | | | | | | One shared d-tag let a network switch apply the mainnet snapshot to a signet wallet (the flash of wrong balance) and clobber mainnet state on the relays. Each network now syncs its own replaceable event (mainnet keeps the legacy bare tag), snapshots carry netName, and a foreign-net snapshot is never applied. The balance card spins until cache, Nostr, or a scan has populated this network once — 'scanning' alone missed the cache/Nostr window after wallet.load(). Co-Authored-By: Claude Fable 5 <[email protected]>
* Ark: recover from stale vtxo stateAdam Soltys2026-07-041-1/+14
| | | | | | | | | | Match captaind's actual 'not spendable' error so a crashed or foreign spend fails the action instead of retrying forever, and reconcile locally-spendable vtxos against the server (GetVtxoStatus + ownership attestation) when an ark address lands in the send form. boardFee now treats absent proto3 fee fields as zero (Second's signet boards free). Co-Authored-By: Claude Fable 5 <[email protected]>
* Features phase 2b: silent payments + nostr sync leave the core walletAdam Soltys2026-07-045-3/+620
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | wallet.js drops from 2,374 to ~1,970 lines, holding only BIP84 on-chain logic plus generic feature seams. New seams added this pass: registerBalanceExtra extra confirmed/pending buckets registerInputProvider extra spendable inputs for buildTx registerSendPreparer destinations needing post-selection derivation registerInputSigner non-BIP84 input signing registerHistoryProvider / registerScanHook / registerRealtimeHook / registerLoadHook / registerCacheExtension / registerCacheSavedHook src/features/sp-wallet.js: the whole BIP-352 engine — key derivation, worker-accelerated indexer scanning, the live indexer WebSocket, SP outputs as spendable inputs, sp1 send preparation, and per-output-key signing — installs via those seams (installSpWallet). src/features/sync.js: nostr identity + encrypted cross-device state sync plus its Settings card, installed via load/cache-saved/realtime hooks. profileChip/nostrProfile move here-adjacent (into gifts, the only other nostr consumer), so core app.js no longer imports nostr at all. buildTx/sign are now feature-agnostic (input providers + preparers + signers); _recomputeBalance* use the balance-extra registry, so a core build with no SP no longer calls a missing spBalance() (that regression dropped the minimal build into offline mode — caught by the smoke test). New coverage: tools/sp-test.js drives two browser "devices" through an SP send, indexer discovery, and an SP-input spend on the ark regtest chain (needs tools/sp-indexer.js pointed at bitcoind:18543). Minimal smoke now also asserts no SP/nostr code ships. Minimal profile: 314KB, down from 412KB (full: 580KB). All suites green: minimal smoke, sp-test, ark UI, gift lifecycle. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
* Features phase 2: gift/swap/ark primitives leave the core walletAdam Soltys2026-07-044-3/+459
| | | | | | | | | | | | | | | | | | | | | | | | | | | wallet.js drops from 2,762 to 2,374 lines and now exposes two generic seams instead of feature code: - registerCoinLock()/lockedCoinIds(): features contribute coin ids that spending and the balance treat as unavailable (gift reservations). - loadFeatureState()/saveFeatureState(): namespaced per-wallet persisted state. src/features/gifts-wallet.js takes the whole gift engine — reservation sets, gift records, coin selection, the SIGHASH_SINGLE/NONE PSBT builder, the compact codec, claim building, nostr-locked gifts — as an installGiftWallet(wallet) instance install plus standalone exports. Swap storage/key helpers (loadSwaps/saveSwaps/swapNode/nextSwapIndex) install from swap.js; ark state storage installs from the ark feature. The silent-payment scan worker only embeds when the sp feature ships (wallet.js already tolerated its absence). Minimal profile: 412KB, down from 476KB (full: 578KB). All suites pass: ark UI e2e, ArkManager crash-resume, gift lifecycle, minimal smoke. SP's engine (scanning, BIP-352 signing) stays in wallet.js — extracting it safely wants an SP e2e harness on this stack first. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
* Build profiles: HAL_FEATURES selects which features shipAdam Soltys2026-07-041-0/+16
| | | | | | | | | | | | | | | | | | | | | | build.js swaps src/features/index.js for a generated module importing only the enabled features (gifts,swaps,ark,sp — unset means all, "none" means a plain on-chain wallet), so excluded feature code and its network endpoints never enter the bundle. Minimal profile: 476KB vs 577KB, with the Ark/gRPC, Boltz, and MuSig2 code verifiably absent. `bun run build:minimal` builds it. tools/minimal-smoke.js proves the minimal profile end-to-end: no receive-mode dropdown, no gift button, no swap/Ark/SP settings cards, no page errors, and a plain on-chain receive still lands. The two blessed profiles are full (everything, the existing e2e suites) and minimal (this smoke test); other combos should work but aren't CI'd. Gift and SP primitives still live inside wallet.js, so those bytes remain in the minimal bundle for now — extracting them is the next step if we want the core leaner still. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
* Features: extract gifts behind the plugin seamAdam Soltys2026-07-041-0/+805
| | | | | | | | | | | | | | | | | | | | | | The whole gift surface moves to src/features/gifts.js (~800 lines): create/split/lock flows, link viewing, revoke/reclaim, history rows + detail page, claim-tx row decoration and tx-detail section, the claim flow (fresh or existing wallet, nostr-locked gifts, claim codes, NIP-07 extension), the boot URL handling (/g/, /lg/, #gift=), the post-claim celebration, and the locked-in-gifts balance line. New seams this required: screenView (full-screen feature views), bootUrl (URL takeover at startup), giftOpened (claim pre-check on wallet activation), sendFormExtras, decorateTxRow, and multi-section txDetailSection. Account access goes through explicit ctx accessors (getAccounts/setAccounts) — the moved code briefly relied on an accidental cross-module binding that broke activeAccount() during claims; caught by the gift e2e. app.js: 4,206 → 3,000 lines. Ark + gift browser suites pass. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
* Features: extract swaps, Ark, and SP behind a plugin seamAdam Soltys2026-07-043-0/+704
First step toward optional build profiles. app.js gains a small feature registry (ctx + FEATURES + hook helpers); swaps/Ark/silent-payments UI moves wholesale to src/features/{swaps,ark,sp}.js, each exporting a factory returning integration hooks: init/stop/networkChanged wallet lifecycle receiveModes/receiveTakeover receive tab isSendDest/matchSendText/ interceptReview/sendView/ hideSendControls/sendFormNote send flow historyEntries/historyDetail/ txDetailSection history balanceLines/settingsCards balance card + settings No behavior change: ark + gift browser e2e suites pass, and a probe confirms LN receive, all receive modes, and the three settings cards render as before. Gifts extraction and build flags come next. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy