<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/ark, branch fdroid-v1.9</title>
<subtitle>coinos v3 — bitcoin, Ark, Lightning and nostr wallet (web + Android)</subtitle>
<id>https://git.coinos.io/coinosv3.git/atom?h=fdroid-v1.9</id>
<link rel='self' href='https://git.coinos.io/coinosv3.git/atom?h=fdroid-v1.9'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/'/>
<updated>2026-10-04T15:58:34Z</updated>
<entry>
<title>Ark: a double-tapped zap no longer spends one coin twice</title>
<updated>2026-10-04T15:58:34Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-04T15:58:34Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=7421218e987b0053f1ddbefaddc2c9ecfd664954'/>
<id>urn:sha1:7421218e987b0053f1ddbefaddc2c9ecfd664954</id>
<content type='text'>
A reconcile pass that began before the first zap took its coin handed
it back as spendable (the server still said so) while the zap was in
flight; the second zap picked it and the server refused: 'vtxo …
already spent'. Coins whose state changed during the pass are left
alone. And a payment refused for an already-spent coin now reconciles
and pays once more instead of failing with the raw error.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
</content>
</entry>
<entry>
<title>Renewing asks first, and a renewal links to its round's transaction</title>
<updated>2026-10-03T23:05:42Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-03T23:05:42Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=202dced76eb8617c094686ef86caa979c0074320'/>
<id>urn:sha1:202dced76eb8617c094686ef86caa979c0074320</id>
<content type='text'>
- The coins page's Renew button opens a confirmation instead of renewing
  at once: how many coins, their amount, the fee, and what is left to
  spend meanwhile — with a red notice when that is nothing (the button
  selects every coin by default, which is how a user locked their whole
  balance for an hour on 2026-10-03). It says the coins can't be spent
  until the round's transaction confirms and that a renewal can't be
  cancelled; the wallet renews for free near expiry anyway. The inline
  notice from 328f2db moves into it.
- A renewal keeps its round's transaction id as soon as the round has
  run (before it confirms): the in-progress card on the coins page links
  to it, and the finished renewal's history row carries it, so its
  detail shows the id with View/Copy like any on-chain movement.
  Renewals finished before this change have no id recorded.

tools/ark/renew-confirm-ui-test.js, tools/ark/renew-txid-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>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>Sending on-chain from Spending states the fee and minimum up front.</title>
<updated>2026-10-02T00:10:36Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-02T00:10:36Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=5c661b68c61d53a4684e47c2f306ce43cc76c1c0'/>
<id>urn:sha1:5c661b68c61d53a4684e47c2f306ce43cc76c1c0</id>
<content type='text'>
The form asks the ASP for a co-operative offboard quote (mining share +
service fee, minimum = fee + dust) for the address on screen, disables
Send for a balance below it and points to Lightning. A too-small amount
reads in words instead of the manager's internal error, and the
unilateral-exit note only appears when co-operation actually failed.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
</content>
</entry>
<entry>
<title>A zap refused for an old expired coin goes again on the other coins instead of showing the server error.</title>
<updated>2026-09-29T05:32:49Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-29T05:32:49Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=4b3291fdbd0b34b4d2df91a59bea93885de29508'/>
<id>urn:sha1:4b3291fdbd0b34b4d2df91a59bea93885de29508</id>
<content type='text'>
Sub-dust coins skip the local expiry check, so the ASP can refuse one at
cosign ("vtxo … expired at height …"). The coin was already marked
excluded, but the error still surfaced and the user had to tap again.
send() and payLnInvoice() now retry (up to 5 attempts) when that exact
refusal marks an input, without a failed history row for the retried try.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Du1qT1wbkYwYK6zkGH79Rp
</content>
</entry>
<entry>
<title>Expired dust gets a quiet line and a Forget button, not a red warning.</title>
<updated>2026-09-28T06:45:07Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-28T06:45:07Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=360c39400e219b9b4863e3ae6716f4e73b788045'/>
<id>urn:sha1:360c39400e219b9b4863e3ae6716f4e73b788045</id>
<content type='text'>
A coin past its expiry and under the 330-sat floor can be renewed by
nobody and exited by nobody; the home page said "the server can still
renew it" in red over 21 sats. Now a muted line points at Manage, where
the coin's row offers Forget: held as spent, quietly, so it stops
counting and stops warning. Larger expired coins keep the warning.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
</content>
</entry>
<entry>
<title>A renewal the round would refuse is retired, not resubmitted every sync; /feed opened before the wallet no longer doubles Popular.</title>
<updated>2026-09-28T06:17:12Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-28T06:17:12Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=a9a5d1fdce7a342394c2facb2344adbc7aa69aea'/>
<id>urn:sha1:a9a5d1fdce7a342394c2facb2344adbc7aa69aea</id>
<content type='text'>
A refresh at the created step with an input past its expiry (only the
server's backstop can renew it now), or whose fee leaves less than the
330-sat floor (a 21-sat coin with a 150-sat fee sat "in progress" for
days), is failed quietly and its inputs go back to spendable.

/feed read before the wallet restored made a visitor's session copy of
Popular beside the built-in one; the wallet's arrival now folds it away.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
</content>
</entry>
<entry>
<title>Three fixes: orphaned pending coins settle with the server; a saved start screen no longer shadows a restored wallet; stop() no longer throws.</title>
<updated>2026-09-27T22:07:31Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-27T22:07:31Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=31fea2d1e463424387828163bda9facc2fee8c0d'/>
<id>urn:sha1:31fea2d1e463424387828163bda9facc2fee8c0d</id>
<content type='text'>
Reconcile now asks the server about a 'pending' coin no live action or
standing renewal order holds: spendable again, or gone. Thirty zap-sized
coins another device had already spent counted in a balance for weeks.

A nav saved by a page with no wallet (the start screen) was restored over a
wallet that had since been saved to the device, painting the start page.

messages.stop() referenced feedAt, which no longer exists, so the rest of the
teardown never ran on an account switch.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
</content>
</entry>
<entry>
<title>Copy: no more em dashes, anywhere people read.</title>
<updated>2026-09-27T22:07:30Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-27T22:07:30Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=e6035849f9b88bdd8cd665b868bbe121fa77e538'/>
<id>urn:sha1:e6035849f9b88bdd8cd665b868bbe121fa77e538</id>
<content type='text'>
Every English string, the translations, the README and the messages the code
shows people now break with a full stop, a colon or a comma instead. Only
console logs and the "—" placeholder for an empty cell keep the dash.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
</content>
</entry>
</feed>
