| Commit message (Collapse) | Author | Age | Files | Lines |
| ... | |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The balance line and history-row icons read the LIVE ark manager,
which is null until connectArk() finishes its async handshake — so on
refresh the ark balance briefly vanished and ark rows flashed the
Bitcoin icon before flipping to the ark mark. Read-only hooks
(balance, decorateTxRow, historyEntries, detail views) now fall back
to the persisted ark state from storage via arkStateNow(), so they
paint correct on first render; the manager connecting later just keeps
it fresh with identical data (no visible change). Verified: balance
present and board row shows the ark icon from the first 50ms sample
after reload.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
Plain on-chain sends/receives fell through to ↓/↑ arrows in the row
circle; now they show the Bitcoin mark like the other rails (ark/sp/
gift). Direction stays legible via the green/red circle tint and the
signed amount. Consistent icon column across every payment type.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
Off-chain Ark rows (arkHistoryItem) showed an arrow + a redundant 'Ark'
text chip; now the Ark mark sits in the direction-colored circle and
the chip is gone — the label + signed amount carry direction. The
detail header gets the badge instead of the chip. And the receive
selector's Bitcoin option uses coinos's real bitcoin.svg (orange disc +
tilted white B) instead of a bare ₿ character.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The receive address-type picker was a native <select>, which can't
render SVG in <option>s. Replace it with a lightweight custom dropdown
(icon-select) that shows a glyph per rail — ₿ Bitcoin, ⚡ Lightning,
the Second mark for Ark, 🕶️ Silent payment — closing on select or an
outside tap. Receive modes gained an icon field; the address option is
built in app.js. Silent-payment receipts (which merge into history as
on-chain-looking rows) now get a rail glyph + SP tag via a
decorateTxRow so they're distinguishable, matching how ark/gift rows
already decorate.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
Use ARK_MARK (bare currentColor glyph) instead of the app-badge in the
settings card header, so it sits like the sibling feature glyphs
(lightning/SP/gifts) rather than a heavy dark square.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The ⚔ was a U+2694 emoji stand-in. Swap in Second's actual mark
(second.tech logo: a triangle with an evenodd inner cutout) as two
format.js helpers — ARK_ICON (dark rounded-square app badge + white
mark, for card/section headers) and ARK_MARK (bare currentColor glyph,
for the history-row circle). Wired into the Ark settings card, the
boarding/withdrawal/exit history rows + detail section, and the
How-it-works Ark section; the gift source toggle drops the emoji for
plain 'Ark'. Verified the badge renders (18px, #00090C square, white
evenodd mark).
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The clobber was structural: all devices published to one replaceable
event (same seed -> same nostr key -> one slot), so whoever saved last
won and a device saving before it merged wiped the others' coins. Now
each device publishes to its OWN d-tag (<base>:d:<deviceId>, deviceId
random per browser in localStorage), and readers pull ALL of the
identity's kind-30078 events — every device slot plus the legacy shared
tag for migration — merging ark vtxos across all of them and applying
the newest full snapshot for on-chain state. No device can overwrite
another's slot, so anti-entropy is no longer load-bearing (kept as
belt-and-suspenders). Live subscription drops its #d filter to see all
slots; publish and the echo-guard use the per-device tag.
Verified: two same-seed devices produce two distinct relay slots that
coexist, B sees A's funds, both converge after a spend.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
All devices share one replaceable-event slot (same seed -> same nostr
key), so a device that published its snapshot before merging in
another device's ark state wiped those coins from the slot — exactly
what stranded a phone showing no ark balance. Fix: on receiving any
snapshot, union it with local and, if we hold vtxos the snapshot
lacked, re-publish the superset. The slot converges to the union
regardless of publish order; the guard (mergedN>remoteN) stops the
push-back once every device agrees, so no loop.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Ark vtxos lived only in per-device storage, so a second device with the
same seed saw the right on-chain balance (that rides the snapshot) but
none of its ark funds — board/change vtxos exist only where created.
Ark state now rides the encrypted nostr snapshot as a merge-safe cache
extension: additive union (bring in vtxos a device is missing) with
each device's own server reconcile() as the authority for spent-ness,
so a stale or wrong 'spent' on one device can never propagate and
poison the others. A connect-time reconcile catches coins spent
elsewhere while a device was away, and a live subscription to our own
replaceable event merges another device's new coins within seconds.
New seam: registerCacheExtension({mergeAlways:true}) extensions get
fed snapshots that aren't newer than local state too (last-writer-wins
is right for rescannable chain data, wrong for merge-style vtxo state),
and nostr.subscribeStates for the live path.
Verified two same-seed devices over a mini relay: B sees A's boarded
balance with zero mailbox activity, spends a synced vtxo, A converges
to a stable balance with the spent vtxo correctly marked.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The compatibility play for ark zaps: an NWC wallet service (coinos,
eventually) receives pay_invoice from any nostr client, asks the hal
wallet to cover the amount over ark (kind 23196 funding request), hal
auto-pays within a user-set allowance and acks (23197), the bridge
receives the vtxo in its mailbox and settles the bolt11 over
lightning. Custody window is the seconds the sats are in flight.
hal side: a live nostr subscription primitive (nostrSubscribe through
the sync seam) and an allowance-gated funding handler that arms when
ark connects. PoC config via localStorage 'btc-wallet-arknwc'
({bridgePk, budgetSat}); proper UI when the protocol settles.
Proven end-to-end on regtest (tools/.arknwc-e2e.tmp.js): mini relay +
bridge process (ArkManager in bun + CLN) + NIP-47 client — invoice on
clb paid via cl, preimage returned over NWC, hal debited 1,000 sats
over ark, zero page errors.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Lightning zaps are welded to LNURL+bolt11; nutzaps (NIP-61) proved the
alternative shape, and ark fits it better than Cashu because delivery
already exists (the mailbox). Draft protocol, kinds provisional:
kind 10037 (replaceable) announces the wallet's ark address+network;
the zap itself is a plain instant arkoor send; kind 9737 is the
sender-signed receipt tagging recipient, amount, comment, and the
delivered vtxo id — so the receipt is checkable against the actual
payment, unlike a bare attestation.
UX: paste an npub into Send and hal offers the zap (needs both the ark
and sync features; npub decoding is inline bech32 so ark-only builds
stay lean). The nostr layer gains generic publishEvent/fetchEvents,
exposed through the sync seam as wallet.nostrPublish/nostrFetch.
Proven on regtest against a mini NIP-01 relay: announce, resolve,
zap 1,000 sats with a comment, instant receipt+delivery, vtxo match.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
| |
The in-app page grows plain-language cards for Lightning swaps, Ark
(instant off-chain, the unilateral escape hatch, expiry housekeeping,
fees), silent payments, and gift links. The README catches up with
reality: the native-JS Ark client headlines the feature list, and the
modular HAL_FEATURES build system gets its own section — every feature
is a plugin behind a build seam, and excluded code never ships.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
A gift-claimed wallet is a brand-new seed but the claim flow never
passed generated:true, so every gift wallet ground through the
indexer's full history (~336k tweaks) hunting silent payments it could
not have received — the CPU burn seen with a fresh gift wallet open.
Fresh claim wallets now fast-forward their scan watermark to the tip
like any other generated wallet. And two tabs on the same wallet no
longer duplicate a catch-up: a localStorage lease, refreshed per chunk,
lets the second tab yield.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
submitpackage answers HTTP 200 even when it rejects the package — the
verdict hides in package_msg/tx-results — so a mainnet no-fee-coin exit
sat at 'publishing on-chain…' forever believing its bare hop had
relayed. Rejections now surface (and become the actionable needs-a-fee-
coin message on the bumpless path). The status line shows hop progress
(step 2 of 9), the timelock wait counts down in blocks with a rough
wall-clock estimate, and a stuck exit that never published anything
gets a 'Cancel this exit' link that returns the vtxo to spendable.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
A fresh gift-only wallet has no on-chain coin for the CPFP fee child,
so its exit stalled behind 'hit a snag — retrying automatically' — a
precondition dressed up as a transient. When no fee coin exists the
hop is now tried bare (a zero-minrelay regtest relays it; a gift
wallet can exit with literally nothing but the gift), and if the node
refuses, the real message shows: exiting needs an on-chain coin for
fees. Errors now carry an actionable flag so the status line knows
when to tell the truth verbatim.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
100,000 in, 99,670 out was a surprise: the ASP's board fee (min/base/
ppm from its published schedule; it funds the exit tx's P2A fee anchor)
was only visible after the fact. The board form now shows the fee and
the net amount live as you type, and the funding tx's detail view gets
an 'Ark server fee' line.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
submitPackage falls back to sequential /tx posts when the esplora lacks
POST /txs/package (regtest electrs) — works wherever the node relays
zero-fee v3 parents. The ark card stops speaking developer: in-flight
operations summarize as '{n} deposit(s) confirming' instead of
'board:funded, exit:chain, …', exit lines read 'Exiting N sats —
publishing on-chain…', and transient errors show 'hit a snag — retrying
automatically' instead of raw gRPC/HTTP text.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An imported mainnet wallet's first scan pulled the indexer's whole
window (~336k tweaks, 25MB) and posted it to the worker as ONE message:
it blew the 30s worker timeout, fell back to the inline main-thread
loop (minutes of jank) while the worker kept grinding the orphaned
request — the runaway CPU/memory users saw. The catch-up now processes
100-block chunks: each worker call is seconds, the scan watermark
checkpoints after every chunk (an interrupted catch-up resumes instead
of restarting from zero), buffers free as it goes, and the UI yields
between chunks. Verified against the live indexer: full catch-up in
~5min of background work, main heap bounded (~80MB peak), no timeouts.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
The mailbox poll and live stream can process the same message
concurrently (validation awaits in between): the vtxo itself deduped
but both copies pushed a receive movement, so a claimed gift showed
twice in History. The movement now only records when _addVtxo actually
added the vtxo, and init() prunes duplicates the old race left behind.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The network is now a property of each wallet, not a global mode. Every
new wallet is born on the currently-selected network; activating a
wallet activates its network (features re-init through the same
networkChanged hooks the Settings switch uses); the Settings network
card moves the ACTIVE wallet and sets the default for new ones. The
stamp persists everywhere accounts do — session, durable directory,
and vault — and legacy accounts adopt the current global once.
Gift claims compose: an ark gift lists only wallets on its network as
claim targets, and when none exist the fresh claim wallet is simply
born on the gift's network — existing wallets keep theirs, so opening
a foreign-network gift never disturbs anything. The wallet switcher
tags non-mainnet wallets with their network.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
| |
Same trigger as pasting an ark address into Send: the gift form is a
send-intent signal, so stale vtxos (spent server-side while this state
was idle) drop before coin selection instead of erroring at cosign.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The trustless backstop behind the Ark card's promise. The vtxo's
genesis chain reconstructs to fully-signed txs (keyspend sigs for
cosigned/arkoor transitions, preimage script-path for hark leaves);
they are zero-fee v3 with P2A anchors, so each hop broadcasts as a
[parent, CPFP child] package via esplora POST /txs/package, one
confirmed hop at a time (TRUC allows a single unconfirmed parent).
After the vtxo tx confirms and the CSV exit delta passes, the claim
spends the delayed_sign leaf with only the user key into the wallet's
own receive address.
Settings gains 'Exit on-chain without the server' with live per-exit
status lines; the claim tx is labeled 'Ark exit' in History. Probing
uses /tx/:txid (definitive 404), never /tx/:txid/status, which answers
confirmed:false for unknown txids.
Also: a fresh visitor opening an ark gift link now adopts the gift's
network automatically instead of being sent to Settings.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
The Cancel-then-confirm step is gone: a reserved gift offers View /
Reclaim / Revoke immediately, a reclaimed one just Revoke. The summary
box only renders when it has content — a reclaimed gift with no
recorded date drew an empty gray box.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
| |
A pre-per-network-dtag event can hold ANY network's state; applying one
put regtest coins into a mainnet wallet (and its board tx was then
rightly rejected by the network). Unstamped snapshots are now skipped —
a full scan is safer than a wrong snapshot.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Ark can't presign a bearer spend, so an ark gift is a vtxo sent to an
ephemeral ark identity whose seed IS the link (/ag/<code>: net, amount,
32-byte secret). The claimer rebuilds the identity, reads its mailbox,
and sweeps to their own ark address — instant, free, and it works for a
brand-new empty wallet with zero on-chain footprint. The sender keeps
the secret, which is what makes revoke possible (first cosign wins).
The gift form gains an On-chain/Ark source toggle when ark balance
exists; ark gifts skip the lock/split logic entirely. Claim, choose-
wallet, already-claimed, and nostr-locked (/lg/) flows all branch by
code kind; unclaimed ark gifts list with one-tap revoke and lazily
mark themselves claimed via GetVtxoStatus. Features stay decoupled:
gifts asks for ark support via the new ctx.hook seam, so either
feature builds alone.
Also restores goHome in the feature ctx — lost in the plugin-seam
extraction, it made the already-claimed screen throw on render.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
A replaced/evicted unconfirmed tx lingered forever as a phantom pending
receive (signetfaucet fee-bumps its batch payout every few minutes, so
History grew a new copy per bump). The poll now status-checks pending
txs — via /tx/:txid, since /tx/:txid/status answers 200 confirmed:false
for txids the node no longer knows — drops the vanished ones, and
re-fetches their addresses' coins and history, which _reconcileHeld
skips when the replacement pays identical amounts.
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
| |
Co-Authored-By: Claude Fable 5 <[email protected]>
|
| |
|
|
|
|
|
|
|
|
| |
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]>
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Gift links now sort into the send/receive timeline like any entry: a
clickable row (🎁, status tag, age, amount) opening a detail page that
carries the date/status plus the actions that used to crowd the list
row (view gift link, cancel/reclaim with the existing confirm flow).
A claimed gift merges into its claim transaction's row — labeled as the
gift, clickable to the tx detail, which gains a "This transaction
delivered your gift" section (claim txid resolved via outspend and
cached on the gift record). The old pinned gifts header and the
paginated all-gifts view are gone.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Claiming into an existing wallet used to drop onto the Receive tab
(address/QR visibly rotating) until the background scan noticed the
credit and fired the celebration. The claim already knows it succeeded
and for how much, so the celebration now shows immediately; the scan
runs behind it and its receive-index advance is acknowledged so the
generic celebration doesn't fire a second time.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Claiming a gift whose funding tx is unknown to the claimer's data
source (different network/chain, or not yet propagated) used to fail
with the misleading "already been claimed". Now:
- the claim screen probes the funding tx up front (esplora's status/
outspend endpoints don't 404 for unknown txids, so outspend alone
can't detect this) and shows a network/data-source notice, and
- a missing-inputs broadcast rejection maps to the same explanation
instead of the generic already-claimed message.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
| |
"Claim it into a brand-new wallet that only you control." only fits the
new-wallet path; claiming into an existing wallet now says which wallet
it lands in ("Claim it into your wallet "Wallet 1".").
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
|
| |
The existing-wallet buttons looked like inert inputs. Now: a "Receive
into one of your wallets:" label, a chevron on each wallet row so it
reads as tappable, and an "or" divider before the new-wallet button.
(tools/ark/gift-shot.js: screenshot harness that mints a real regtest
gift and opens its link.)
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
| |
Tap anywhere to proceed instead of a Done button, and the sent amount
shows in red (amount-neg) rather than green.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
|
| |
grpcStream() parses gRPC-web frames incrementally off fetch's body
stream; the manager keeps a long-lived SubscribeMailbox subscription
(auto-reconnect, 3s backoff) whose messages flow through the same
duplicate-safe processing as the poll. Receives now land the moment the
sender delivers (~sub-second) instead of on the next poll; the poll
stays as fallback and to drive in-flight boards/refreshes.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
| |
Ark movements are clickable like on-chain txs. The detail view shows
amount, date, status, the destination address (sends, copyable), the
vtxo id, and for boards the funding txid with copy + explorer link.
Movements now record those fields at completion time; older records
without them still render (amount/date/status only).
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
| |
An arkoor send has no mining fee and no coin selection, so pasting an
Ark address now shows just the amount field plus a hint line; the
irrelevant on-chain controls stay hidden.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
| |
Broadcasting a board now lands on a checkmark screen showing the amount
that will arrive (after the board fee), a note about the confirmation,
and the funding txid with copy + explorer link; Done returns to the
Receive tab.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
| |
toast() takes an optional duration; the two informational Ark messages
(full sentences, not confirmations) show for 5s instead of 1.6s.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
| |
Selecting Ark on Receive now shows the address plus an inline "move
on-chain funds into Ark" form (with available balance / minimum hints).
The Settings card slims down to server choice, coin count, in-progress
operations, and refresh/consolidate; the balance already shows on the
balance card.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
|
| |
Opening a wallet no longer contacts the ASP unless it already holds
vtxos / history / unfinished operations. Fresh wallets connect on first
use instead: selecting Ark on the Receive tab, confirming an Ark send,
or the Connect button on the Settings card. connectArk() is idempotent
and generation-guarded against wallet switches mid-dial.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|
| |
|
|
|
|
|
|
|
|
| |
Mainnet defaults to Second (ark.second.tech), regtest to the local
stack. Testnet/mutinynet get their own preset lists (off/custom only —
no public ASP exists there) instead of falling back to mainnet's, and
stay off by default.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
|