<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/features/swaps.js, branch master</title>
<subtitle>coinos v3 — bitcoin, Ark, Lightning and nostr wallet (web + Android)</subtitle>
<id>https://git.coinos.io/coinosv3.git/atom?h=master</id>
<link rel='self' href='https://git.coinos.io/coinosv3.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/'/>
<updated>2026-08-02T02:38:30Z</updated>
<entry>
<title>Simplify: one Lightning path, one balance, fewer features</title>
<updated>2026-08-02T02:38:30Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-02T02:38:30Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=348a57004f94dd0f58c4e70769e65ca7ea3f7619'/>
<id>urn:sha1:348a57004f94dd0f58c4e70769e65ca7ea3f7619</id>
<content type='text'>
Dropped: silent payments (feature, wallet chains, scan worker, indexer
config), Boltz submarine/reverse swaps (feature + swap.js + tools), the
third-party ark swap bridge (config, client flows, settings card — the
ASP's own Lightning send is the one path now), and the Consolidate
coins settings action.

The NWC pouch is gone with them: background answering now spends the
WHOLE ark balance. The IndexedDB record mirrors the real manager state
plus the chain-3 keys for its live coins and a change-index window; the
worker pays through the ASP exactly like the open app, and the app
folds the worker's spends, change, and key allocations back in on
connect (additive merge + reconcile against the server). A leftover
chain-6 pouch from the short-lived pouch era is swept home
automatically using the keys stored in its own record. The stated
tradeoff: same-origin script access now reaches the ark balance, not a
carve-out — the ark balance is walking-around money, the on-chain
wallet's keys are never mirrored, and per-connection NWC budgets remain
the enforced ceiling.

Bundle: 726KB -&gt; 602KB.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add Ark &lt;-&gt; Lightning via the ASP (captaind-native submarine swaps)</title>
<updated>2026-07-31T07:49:21Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-31T07:49:21Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=78789e0b2eaf91e2de6b4e488324fbec0fcefb9d'/>
<id>urn:sha1:78789e0b2eaf91e2de6b4e488324fbec0fcefb9d</id>
<content type='text'>
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 -&gt; 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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Add NIP-57 Lightning zaps (npub / lightning address / lnurl)</title>
<updated>2026-07-30T15:43:47Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-30T15:43:47Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=6713f8d4e55db8d5344684b08b062cc9129ef6b0'/>
<id>urn:sha1:6713f8d4e55db8d5344684b08b062cc9129ef6b0</id>
<content type='text'>
Send a Lightning zap to a nostr npub, a lightning address (name@domain),
or an lnurl. New src/lnurl.js does the resolution half — target → LNURL-pay
params → signed kind-9734 zap request → callback → bolt11 — and the new
zaps feature (src/features/zaps.js) drives the amount/comment UI, then hands
the invoice to the existing Boltz submarine-swap flow via a new
swaps.startLnPay hook, so there's one tested pay/review/confirm/success path.

Routing: a bolt11 is still caught by swaps; an npub still prefers an instant
free Ark zap when Ark can serve it, and only falls through to a Lightning
zap otherwise — ark's "no Ark address" screen also offers an explicit
"Zap over Lightning" fallback (gated on the zaps feature's canLnZap). A real
zap receipt is attributed only when the server advertises allowsNostr and we
know the recipient's pubkey; otherwise it degrades to a plain LNURL-pay.

Nostr seam gains nostrSign (finalize without publishing), nostrProfile
(kind-0 with lud16/lud06), and nostrRelays. Lightning addresses are
debounced in matchSendText since their regex matches mid-typing.

Verified: unit tests for parse/encode/zap-request; a live resolve→signed
9734→payable mainnet bolt11 against coinos; and an in-browser DOM smoke
(zap form + LNURL params over CORS + allowsNostr hint + handoff).

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Filter swap providers by network; guard cross-network selection</title>
<updated>2026-07-29T15:49:41Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-29T15:49:41Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=fa31fb2721910604abef73049c04b3f872d34a83'/>
<id>urn:sha1:fa31fb2721910604abef73049c04b3f872d34a83</id>
<content type='text'>
Tag each BOLTZ_PRESET with the network(s) it serves and add
boltzPresetsFor(net) so the provider dropdown only lists backends
valid for the active network — a mainnet wallet no longer shows the
local (regtest) or coinos-staging (mutinynet) backends. getBoltzProviderId()
now only honors a stored choice if it's valid for the current network,
so switching to mainnet can't silently keep using a regtest/mutinynet
backend, and the getBoltzProvider() fallback can no longer resolve to
staging. Also point the testnet default at custom (was the mainnet
Boltz API).

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Icons in the receive selector and on silent-payment history rows</title>
<updated>2026-07-06T15:09:57Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-06T15:09:57Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=45a4a9d5cec8eafc7e98ebd7ca2a9790c0ee94b4'/>
<id>urn:sha1:45a4a9d5cec8eafc7e98ebd7ca2a9790c0ee94b4</id>
<content type='text'>
The receive address-type picker was a native &lt;select&gt;, which can't
render SVG in &lt;option&gt;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 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Features phase 2: gift/swap/ark primitives leave the core wallet</title>
<updated>2026-07-04T16:33:52Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-04T16:33:52Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=b7c5abd93868b97c25f52610510544764a3e44eb'/>
<id>urn:sha1:b7c5abd93868b97c25f52610510544764a3e44eb</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
</content>
</entry>
<entry>
<title>Features: extract swaps, Ark, and SP behind a plugin seam</title>
<updated>2026-07-04T15:55:45Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-04T15:55:45Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=11a14600da683769c74d49e3d973183aa1a2fe5e'/>
<id>urn:sha1:11a14600da683769c74d49e3d973183aa1a2fe5e</id>
<content type='text'>
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 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01QFAcD4V284DvYZZHP7Rxxy
</content>
</entry>
</feed>
