aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ark
Commit message (Collapse)AuthorAgeFilesLines
* Note the Cloudflare managed-WAF exception the ASP hostname needsAdam Soltys2026-08-011-0/+4
| | | | | | | Binary protobuf POSTs trip signature rules above ~1.5KB; the demo now runs entirely over public HTTPS with a path-scoped skip in place. Co-Authored-By: Claude Fable 5 <[email protected]>
* Add the live bridge demo against the coinos mutinynet ASPAdam Soltys2026-07-311-0/+103
| | | | | | | | | | | | | Reference run for the upstream proposal: real deployed ASP, real deployed bridge, real Lightning settlement — no regtest. Boards a fresh wallet, quotes a 25 sat zap (1 sat fee vs second's 20 sat mainnet floor), locks the HTLC, lets the bridge pay and claim, then reads the revealed preimage back out of the ASP via GetHtlcPreimage. Board funding goes through a helper on cs because a board output must be vout 0 and sendtoaddress randomizes output order. Co-Authored-By: Claude Fable 5 <[email protected]>
* Add the trustless Ark->Lightning swap bridgeAdam Soltys2026-07-311-0/+190
| | | | | | | | | | | | | | | | | | | | | | | | | | | A third-party swap provider built on the proposed VtxoPolicy::Htlc: users pay bolt11 invoices from their Ark balance without the ASP being the counterparty and without trusting the bridge with custody. Scope is deliberately one-directional. An ASP's lightning *receive* is already free (0 base / 0 ppm on mainnet); the expensive leg is *send*, with a 20 sat floor that eats 80% of a 25 sat zap. Only that leg is worth undercutting. - bridge/server.js: /info, /quote, /swap, /refund over Bun.serve. Validates the user's HTLC fully (policy, hash, amount, expiry margin, full vtxo chain) before spending anything on Lightning, pays, then claims with the preimage. Crash-safe: state is written atomically and every step re-checks reality (listpays before paying, so a resumed bridge never double-pays). - bridge/ln.js: minimal CLN backend (unix socket or docker exec), named params, maxfee-capped pay, pending/paid introspection. - /refund is safe to expose publicly: the ASP only cosigns a preimage-less HTLC spend when every output pays the refunder, so it cannot be redirected. tools/ark/bridge-e2e-test.js drives the real HTTP API against the patched regtest ASP: a 25 sat zap costs 1 sat, the far-end invoice really settles, the preimage checks out, resubmission is idempotent, an unroutable invoice reports refundable rather than done, and the refund lands every sat back. Co-Authored-By: Claude Fable 5 <[email protected]>
* Client support for third-party HTLC vtxos (trustless swap bridges)Adam Soltys2026-07-311-0/+201
| | | | | | | | | | | | | | | | | | Speaks the proposed VtxoPolicy::Htlc (type byte 0x08): policy encode/decode, two-leaf taproot (claimer-with-preimage / refunder-after-expiry), preimage field on the arkoor cosign request, and GetHtlcPreimage. ArkManager gains the swap primitives: htlcLock (lock funds claimable only against a payment hash, refundable by us after expiry), htlcClaim (reveal the preimage), htlcCosignRefund (hand an unclaimable HTLC back — the server constrains the outputs to the refunder, so this is safe to expose publicly) and acceptHtlcRefund. tools/ark/htlc-bridge-test.js drives a full submarine swap between two independent wallets against a patched captaind, and asserts the ASP rejects both a wrong-preimage claim and a preimage-less spend to the bridge itself. Co-Authored-By: Claude Fable 5 <[email protected]>
* Fix send-form UX around lightning pays; harden ln state machinesAdam Soltys2026-07-311-0/+3
| | | | | | | | | | | | | | | | | | | - a rejected cosign (gRPC INVALID_ARGUMENT) returns the input vtxo to spendable and fails the action instead of leaving it pending forever — the stuck-pending state that pushed small zaps onto Boltz's 25k minimum - ark ln-pay now takes over when funds are settling (retrying quote) rather than falling through to Boltz - typing a destination clears stale send errors (also cleared on tab switch); paste path likewise - typed lightning addresses no longer auto-advance mid-keystroke (the matcher fired at `[email protected]` before `.com`, yanking the form away): the send form offers an explicit "Zap <addr>" button; pasted/scanned addresses still advance immediately - ln-recv: HTLC vtxos anchored to a not-yet-confirmed pool round park and retry instead of throwing; the requested HTLC expiry is anchored on first prepare so retries can't inflate it past the server's grant Co-Authored-By: Claude Fable 5 <[email protected]>
* Dust-isolate arkoor outputs; prove lightning E2E on regtestAdam Soltys2026-07-311-0/+137
| | | | | | | | | | | | | | | | | The server rejects an arkoor mixing dust and non-dust outputs, which broke small Lightning payments (a 45-sat HTLC next to change) and tiny plain sends. Mirror bark's isolation: dust outputs route through a combined isolation output spent by a fanout tx, splitting a non-dust output to pad the dust below-threshold. Outputs can therefore split across two vtxos, so the manager now classifies results by policy instead of index (legacy single-field actions still resume). Regtest now runs the full stack: dedicated cln-ark node (secondark/cln-hold, hold plugin + xpay) wired into captaind with a channel to the coinos dev clc node. tools/ark/ln-e2e-test.js proves pay (5000 sat and a 25-sat dust zap), hold-invoice receive with claim, and spending the claimed vtxos. Co-Authored-By: Claude Fable 5 <[email protected]>
* Add Ark <-> Lightning via the ASP (captaind-native submarine swaps)Adam Soltys2026-07-312-3/+154
| | | | | | | | | | | | | | | | | | | | | | | | | | | The ASP is the HTLC counterparty (second.tech's protocol), so no external swap provider is needed: paying a bolt11 converts pubkey vtxos into ServerHtlcSend vtxos the server can only claim by revealing the invoice preimage; receiving grants ServerHtlcRecv vtxos claimed by revealing ours. Failure paths cosign the HTLC back (revocation) — proven end-to-end against regtest captaind, which independently derives the HTLC taproots. - ark/lightning.js: bolt11 decode, lightning fee schedules, all pay/receive gRPC-web wrappers (cosign, initiate, status, revocation, hold-invoice receive flow, anti-DoS attestation) - ark/send.js: arkoor builder generalized to policy outputs (pubkey / serverHtlcSend / serverHtlcRecv), two-leaf taproot trees, HTLC clause scripts, reusable per-part cosign helpers for package RPCs - ark/manager.js: ln-pay and ln-recv crash-safe action state machines (deterministic receive preimages from the seed, chain 5), mailbox lightning notifications, unpayable-invoice -> instant revocation - proto.js: lightning ArkInfo fields + mailbox lightning message decode - validate/refresh: policy-aware vtxo validation and reconstruction - features: bolt11 routes via ark when the balance covers it (Boltz stays the fallback), lightning-invoice receive on the Ark pane - tools/ark/ln-test.js: harness proving HTLC cosign + revocation against captaind; manager-test.js updated for the consolidated bc-container chain Co-Authored-By: Claude Fable 5 <[email protected]>
* Features phase 2: gift/swap/ark primitives leave the core walletAdam Soltys2026-07-041-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* History: gifts are timeline entries, not a separate sectionAdam Soltys2026-07-041-0/+17
| | | | | | | | | | | | | | | 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
* Gift claim: instant 'Payment received!' after claimingAdam Soltys2026-07-041-0/+7
| | | | | | | | | | | | 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
* Gift claim: correct copy when claiming into an existing walletAdam Soltys2026-07-041-0/+6
| | | | | | | | | "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
* Gift claim: make the wallet chooser read as a choiceAdam Soltys2026-07-041-0/+82
| | | | | | | | | | | | 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
* Ark: 'Sent!' screen matches the receive celebrationAdam Soltys2026-07-041-0/+2
| | | | | | | | 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
* Ark: history rows open a detail viewAdam Soltys2026-07-041-0/+8
| | | | | | | | | | | 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
* Ark: hide fee-rate, coin control, Max, and add-recipient for Ark sendsAdam Soltys2026-07-041-0/+5
| | | | | | | | | 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
* Ark: boarding success screen with txid link instead of a toastAdam Soltys2026-07-041-1/+5
| | | | | | | | | | 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
* Ark: boarding lives on the Receive tab's Ark viewAdam Soltys2026-07-031-3/+10
| | | | | | | | | | | 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
* Ark: connect lazily — only dial the server once the wallet uses ArkAdam Soltys2026-07-031-2/+9
| | | | | | | | | | | 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
* Ark: show Ark movements in the History tabAdam Soltys2026-07-031-0/+7
| | | | | | | | | Receives, sends, and boards interleave with on-chain transactions in one time-sorted, paginated timeline, each tagged 'Ark'. Refreshes are internal churn and stay in the Settings activity list only. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
* Ark: 'Payment received!' celebration for Ark receivesAdam Soltys2026-07-031-0/+4
| | | | | | | | | Same card and tap-to-acknowledge flow as on-chain receives; the ack persists in the ark state (shows exactly once) and a 2h recency guard keeps old payments from celebrating when a wallet is opened later. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
* Ark: wire into the wallet UIAdam Soltys2026-07-032-0/+233
| | | | | | | | | | | | | | | | | | | | - Settings: Ark server card (off by default, per-network presets incl. Second mainnet + local regtest, custom URLs) with balance, coin count, board form (on-chain -> Ark; funding output pinned to vout 0 via the new buildTx noSort option), refresh/consolidate, and recent activity. - Receive: Ark option in the address-type dropdown (QR + copy). - Send: t?ark1 addresses are recognized in the normal send form and route to an Ark confirmation (no mining fee) with a success view. - Balance card: Ark balance line under the on-chain figure. - ArkManager lifecycle: per-wallet instance created on account activation, background sync every 5s (regtest) / 30s, state persisted under the wallet cache key. Verified end-to-end in a real browser (tools/ark/ui-test.js, puppeteer against the regtest stack): receive, send, board, and refresh all green. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
* Ark: native-JS protocol client + persistent ArkManagerAdam Soltys2026-07-035-0/+607
Speaks Second's bark/captaind Ark protocol directly from the browser — gRPC-web over fetch with hand-rolled protobuf, no wasm, no new deps (crypto via the existing @scure/@noble stack incl. btc-signer's BIP-327 musig2 module). src/ark: - proto.js transport, ark address codec, mailbox blinding/auth, VTXO ProtocolEncoding v2 decode - send.js arkoor send: checkpoint+arkoor txs, BIP-341 sighashes, MuSig2 cosign ceremony, signed-VTXO assembly - board.js onchain -> ark: funding taproot, exit-tx cosign - refresh.js delegated round (hArk): participation, tx-chain reconstruction, hash-locked leaf cosign, forfeit swap - validate.js receive-side verification: chain must land on the vtxo point, anchor checked onchain, every transition sig verified - manager.js persistent wallet layer: storage-checkpointed step-machine actions (send/board/refresh) that survive crashes, mailbox sync with validation, multi-input consolidation refresh tools/ark: end-to-end regtest tests (receive, send, board, refresh, manager incl. crash-mid-send + resume), all passing against captaind with the bark CLI as counterparty. Co-Authored-By: Claude Fable 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy