diff options
| author | Adam Soltys <[email protected]> | 2026-07-31 00:49:21 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-07-31 00:49:21 -0700 |
| commit | 78789e0b2eaf91e2de6b4e488324fbec0fcefb9d (patch) | |
| tree | 0fb96db0a8fcc62771bb86e9e0f14791c9bc1715 /src/features/swaps.js | |
| parent | 6dc7f9f89a071e43de77bf6dd82cf8d4012ce8c3 (diff) | |
| download | coinosv3-78789e0b2eaf91e2de6b4e488324fbec0fcefb9d.tar.gz coinosv3-78789e0b2eaf91e2de6b4e488324fbec0fcefb9d.zip | |
Add Ark <-> Lightning via the ASP (captaind-native submarine swaps)
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]>
Diffstat (limited to 'src/features/swaps.js')
| -rw-r--r-- | src/features/swaps.js | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/features/swaps.js b/src/features/swaps.js index 091ca32..bad823c 100644 --- a/src/features/swaps.js +++ b/src/features/swaps.js @@ -132,7 +132,11 @@ export function swapsFeature(ctx) { line(t('status'), swap.status === 'claimed' ? 'Settled ✓' : swap.status)); } - async function startLnSend(invoice, meta = null) { + async function startLnSend(invoice, meta = null, skipArk = false) { + // The ark feature pays bolt11 straight from the ark balance when it can + // cover it (the ASP is the swap counterparty) — cheaper and instant, so + // it gets first refusal before the on-chain Boltz submarine path. + if (!skipArk && ctx.hook('startArkLnPay', invoice, meta)) return; ui.sendError = ''; ui.lnSend = null; ui.lnSent = null; ui.lnPayMeta = meta; ui.lnSendBusy = true; render(); try { ui.lnSend = await swaps.quoteSubmarine(invoice); } catch (e) { ui.sendError = e.message; } @@ -228,5 +232,8 @@ export function swapsFeature(ctx) { // the review as a zap (recipient name, comment). Returns true so the hook // dispatcher stops here. startLnPay(invoice, meta) { startLnSend(invoice, meta || null); return true; }, + // The ark feature falls back here when the ark balance can't cover an + // invoice after fees — skipArk avoids bouncing back and forth. + startLnPayBoltz(invoice, meta) { startLnSend(invoice, meta || null, true); return true; }, }; } |
