<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/src/wallet.js, branch fdroid-v1.6</title>
<subtitle>coinos v3 — bitcoin, Ark, Lightning and nostr wallet (web + Android)</subtitle>
<id>https://git.coinos.io/coinosv3.git/atom?h=fdroid-v1.6</id>
<link rel='self' href='https://git.coinos.io/coinosv3.git/atom?h=fdroid-v1.6'/>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/'/>
<updated>2026-09-10T14:18:09Z</updated>
<entry>
<title>Ark state moves to IndexedDB: raw bytes on disk, memory-fronted, write-behind.</title>
<updated>2026-09-10T14:18:09Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-10T14:18:09Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=af4810e2ec8e454e4bb616c685e907eaee04c874'/>
<id>urn:sha1:af4810e2ec8e454e4bb616c685e907eaee04c874</id>
<content type='text'>
localStorage held a deep wallet's ark state as ~700KB of JSON (UTF-16 on
disk), parsed on every boot and stringified on every save, and the wallet
cache blob carried a second ~600KB copy. src/ark/store.js keeps the state
in IndexedDB (db coinos-ark) with each coin's signed bytes as a Uint8Array,
fronted by an in-memory map so loadArkState/saveArkState stay synchronous:
reads return clones, writes coalesce (200ms) and flush immediately when the
page hides. Existing localStorage copies migrate on first open (newest _rev
wins) and are removed only after the IndexedDB write completed; no
IndexedDB means localStorage exactly as before. Records keep their
btc-wallet-cache:&lt;id&gt;:ark… keys, and a wallet wipe clears both stores via
the new per-feature wipeCache hook.

The ark cache extension is now syncOnly: it still rides the sync snapshot
(and the Blossom blob) but the local wallet cache no longer embeds it —
measured on a live wallet the cache blob went from 655KB to 10KB.

Verified in the live tab: all wallets migrated, bytes raw on disk, balance
and coin set unchanged, localStorage ark keys gone. tools/ark-store-test.js
covers migration by _rev, clone-on-read, write-behind, wipe and fallback.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Nw1Dijik1tLVKRM1WkU7xE
</content>
</entry>
<entry>
<title>A snapshot only counts on its own network: the seed-keyed cache stops showing mainnet money under a mutinynet flag, and staging forgives the mainnet default it stamped before it knew better</title>
<updated>2026-08-17T21:44:26Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-17T21:44:26Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=00a0be5fcd8157f145c63df44982b4f74960c815'/>
<id>urn:sha1:00a0be5fcd8157f145c63df44982b4f74960c815</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JtaatFfAbx91Nh3xqKVqKz
</content>
</entry>
<entry>
<title>Own entropy means owned outcome: the typed text alone derives the seed, so re-typing it is an import on any device — the warn-box says what that guarantee costs, and Regenerate bows out of a deterministic job</title>
<updated>2026-08-17T18:16:25Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-17T18:16:25Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=6a78f8fefe71e636c847e1402b08b1d60483565b'/>
<id>urn:sha1:6a78f8fefe71e636c847e1402b08b1d60483565b</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JtaatFfAbx91Nh3xqKVqKz
</content>
</entry>
<entry>
<title>The seed takes dice: an optional entropy field folds open on the generate step, hashed with the device's own randomness so it can only strengthen the phrase — and the forget option now says all data, which is what it takes</title>
<updated>2026-08-17T15:12:34Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-17T15:12:34Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=b62ca1099ff996e333015142cb712687737d4637'/>
<id>urn:sha1:b62ca1099ff996e333015142cb712687737d4637</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01JtaatFfAbx91Nh3xqKVqKz
</content>
</entry>
<entry>
<title>Wallets go flat: every Spending and Savings is a top-level wallet in the switcher, named for its purpose, renamable apart — and a new wallet can carry its own seed or live at the next BIP84 account of one you already back up</title>
<updated>2026-08-15T21:32:28Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-15T21:32:28Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=643046319fa9a393374fc2348381d9505fe143eb'/>
<id>urn:sha1:643046319fa9a393374fc2348381d9505fe143eb</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>Gift records belong to one wallet, not to the browser</title>
<updated>2026-08-04T03:15:16Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-04T03:15:16Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=d59d667d3e4c6edb42b8a42fd120a1bdd96a58db'/>
<id>urn:sha1:d59d667d3e4c6edb42b8a42fd120a1bdd96a58db</id>
<content type='text'>
giftRecords() caches the parsed blob on the wallet object, but the app
runs a single Wallet for its lifetime and load() never dropped that
cache. Switching wallets carried the old wallet's gift links into the
new one, where they all rendered as claimed — none of their outpoints
are live in a wallet that never issued them — and the first save wrote
them back under the new wallet's key.

Clear the cache on load alongside the other two gift caches, and forget
records whose funding tx isn't in this wallet's own history, to clean up
what earlier builds already misfiled.

Co-Authored-By: Claude Opus 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
</content>
</entry>
<entry>
<title>Rebrand: hal → coinos v3</title>
<updated>2026-08-02T19:32:14Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-08-02T19:32:14Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=1fdaa920d7530ac2073ca50280d9531935446c7a'/>
<id>urn:sha1:1fdaa920d7530ac2073ca50280d9531935446c7a</id>
<content type='text'>
The app already presents as Coinos; this finishes the job in the repo:
package name, README, GitHub link, code comments, and the stale locale
lines that still explained the old "Hal Wallet" name (they fall back to
the English tribute line). Kept: the hal-nwc-pouch IndexedDB name (an
upgrade-compat identifier), the halwallet.app domain in the BIP-353
names feature (live infrastructure), and the Hal Finney tribute itself.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01Wvj4aoeMZwA7VUGdJP9Swi
</content>
</entry>
<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>Fee rates from live explorer + reconnect half-open socket on wake</title>
<updated>2026-07-06T21:55:40Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-06T21:55:40Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=312621af84136fddbe7d7e47ffecc1ba2b38920d'/>
<id>urn:sha1:312621af84136fddbe7d7e47ffecc1ba2b38920d</id>
<content type='text'>
- Fee rates on the electrum backend came from Fulcrum's estimatefee
  (Core's estimatesmartfee): historical, laggy, floored at 1 sat/vB, so
  it showed 1 across the board while mempool.space showed 11/10. Pull the
  configured explorer's live recommendation instead (/v1/fees/recommended,
  then /fee-estimates), falling back to estimatefee only when the explorer
  is unreachable — self-hosted/regtest behaviour unchanged.
- On mobile a backgrounded page leaves the socket half-open: TCP is dead
  but readyState still reads OPEN, so wake() never reconnected and fired
  scan RPCs into the void, waiting ~20s for the heartbeat to recover.
  wake() now forces a reconnect when the socket has been silent past the
  heartbeat window, so a payment shows the instant you refocus.

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Gift cross-device sync, snapshot size cap, reliable SW updates, gift-detail layout</title>
<updated>2026-07-06T18:12:31Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-07-06T18:12:31Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=d071a09604599831d370b06563144cf4ba028902'/>
<id>urn:sha1:d071a09604599831d370b06563144cf4ba028902</id>
<content type='text'>
- Gifts now sync across devices: gift records + reserved/reclaimed coin
  sets ride the encrypted snapshot as a merge-safe extension (like ark),
  and every gift state change (create/reclaim/revoke) triggers a
  saveCache so it actually publishes. A gift made on one device now
  shows on the others.
- Cap the published snapshot at ~40KB JSON (relay rejects &gt;64KB events,
  nip44 expands ~1.5x): trim oldest on-chain txs when oversized; another
  device backfills via rescan. Typical wallets untouched.
- Service worker: register with updateViaCache:'none' so a new build is
  detected immediately (not held by the 4h HTTP cache), and reload once
  on controllerchange so the fresh app runs without a manual second
  refresh.
- Gift detail: View/Reclaim share a row, Revoke on its own full-width
  line so 'Revoke now' stops wrapping.

Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
