<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/ark/lightning.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-10-03T23:00:39Z</updated>
<entry>
<title>A Lightning payment that can't be covered says why, not 'Payment failed'</title>
<updated>2026-10-03T23:00:39Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-03T23:00:39Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=328f2db9af46cda473318bb3eada0f6e83bb42f1'/>
<id>urn:sha1:328f2db9af46cda473318bb3eada0f6e83bb42f1</id>
<content type='text'>
A user renewed all ten of their coins (55,611 sats) from the coins page,
tried to pay a 55,300-sat invoice three minutes later, and was told only
'Payment failed'. Nothing had failed: the renewal's round ran at once,
but its coins stay unspendable until the round's transaction confirms
on-chain, and that block took 64 minutes. The quote found no spendable
coin and gave up with the generic message; nothing reached the server.

- The quote now tells apart (lnShortfall): money held by another payment
  (wait, as before — now by sum, not one coin covering it all), money a
  renewal holds ('Nothing was sent. N sats are being renewed…'), and a
  real shortfall ('needs X sats with its fee, Y available'). Coins leaving
  in an offboard or exit are never waited for.
- The manager's 'insufficient ark balance' names a renewal too.
- The coins page says before the tap that renewed coins can't be spent
  until the round confirms, and that renewing every coin leaves nothing
  to pay with meanwhile.

tools/ark/ln-shortfall-test.js

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01ULQZS9MQa6iAsXnrJUD9Du
</content>
</entry>
<entry>
<title>NWC: lookup_invoice, so BTCPay Server can connect</title>
<updated>2026-10-02T14:19:29Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-02T14:19:29Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=e8d82b8b23c271aa57134d762e14fd6dcbed9c7a'/>
<id>urn:sha1:e8d82b8b23c271aa57134d762e14fd6dcbed9c7a</id>
<content type='text'>
BTCPay's NWC connector requires get_info, make_invoice, lookup_invoice
and list_transactions; we never offered lookup_invoice, so it refused the
connection string.

- ArkManager.lnLookup answers lookup_invoice from wallet state (by hash or
  bolt11, either direction; pending/settled/expired/failed, preimage once
  claimed). A retry's several actions on one hash defer to the furthest.
- The open app pushes a pending receive along before answering, so a
  merchant polling sees it settle.
- The service worker now answers make_invoice and lookup_invoice too, and
  claims a paid invoice's HTLCs during the lookup: a BTCPay sale settles
  with the wallet closed. Its list_transactions reports receives as well.
- get_info and the 13194 info event list the new method.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Dmcrt9KyNDKVWFKnb8BREo
</content>
</entry>
<entry>
<title>Staging gets the mainnet fee model end to end: /lnquote?network=mutinynet quotes from the staging ASP's own CLN (helpers take their backend), the client asks it by default on mutinynet, and the quote URL concat survives a query string</title>
<updated>2026-08-29T15:45:30Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-29T15:45:30Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=3a947830743f1db247ae0969378efe540f813342'/>
<id>urn:sha1:3a947830743f1db247ae0969378efe540f813342</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019WboeoetMF3MTmgT7Ew8yi
</content>
</entry>
<entry>
<title>The wallet learns to read BOLT 12 for itself: offers and invoices decode client-side, and every invoice the ASP fetches over onion messages is verified here — payment hash read from the raw TLVs, offer terms mirrored byte-for-byte, the issuer's schnorr signature checked against LDK's exact merkle construction (proven against a live CLN-signed fixture) — so no server can hand back an invoice whose preimage it already holds. Paste an lno1 or resolve a name whose record carries one and the existing HTLC pay flow carries it (captaind's Invoice enum takes lni strings natively); a name's owner may now publish their OWN node's offer in their DNS record, retiring the registrar's stand-in — senders fetch invoices straight from their node and no coinos service ever touches the money. The /lnquote fallback prices blinded paths by entry node + advertised payinfo</title>
<updated>2026-08-29T07:50:09Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-29T07:50:09Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=2023fe06d5cc4867f09d5916680b5fe92394dacb'/>
<id>urn:sha1:2023fe06d5cc4867f09d5916680b5fe92394dacb</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019WboeoetMF3MTmgT7Ew8yi
</content>
</entry>
<entry>
<title>Pay what the route costs: sends quote the network fee up front (zero between coinos wallets), lock exactly that, and a refunded miss retries with one more sat</title>
<updated>2026-08-14T07:02:06Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-14T07:02:06Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=5abf76764c445b742a50080ebb97c313531d5962'/>
<id>urn:sha1:5abf76764c445b742a50080ebb97c313531d5962</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_014tE4U5nEjGTQy8PwYqamfv
</content>
</entry>
<entry>
<title>Client support for third-party HTLC vtxos (trustless swap bridges)</title>
<updated>2026-07-31T19:05:59Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-31T19:05:59Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=142fa01322e624ac12dc24ee7af2583bda89e891'/>
<id>urn:sha1:142fa01322e624ac12dc24ee7af2583bda89e891</id>
<content type='text'>
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 &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>
</feed>
