<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/static, 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-13T06:51:32Z</updated>
<entry>
<title>Android 1.14 (code 15) APK: UnifiedPush only without Play Services, built and signed on lap from 90bc4d3 (76:64:83:AB…). sha256 58a5c4787efbb52d3b34924e51ede844c3b17d8e20b5fc6524e24fd59f5bdfc1.</title>
<updated>2026-10-13T06:51:32Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-13T06:51:32Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=cd058495e11d76bb5afe4fe85b5131adaa387ca1'/>
<id>urn:sha1:cd058495e11d76bb5afe4fe85b5131adaa387ca1</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
</content>
</entry>
<entry>
<title>Android 1.13 (code 14) APK: sticky-immersive, built and signed on lap from bcf5f54 (the key assetlinks.json names: 76:64:83:AB…). sha256 63dac2e8b5b6b3d2d4b1f0fe4d73daa3c4c42b23bd11c81ba0d47da483efa26c.</title>
<updated>2026-10-13T06:29:31Z</updated>
<author>
<name>Adam Soltys</name>
<email>asoltys@gmail.com</email>
</author>
<published>2026-10-13T06:29:31Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=4db2b77bd249e365fc4a4f1ba22311feb60ac294'/>
<id>urn:sha1:4db2b77bd249e365fc4a4f1ba22311feb60ac294</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01KPw21NEpWeTGu6swVASmBt
</content>
</entry>
<entry>
<title>Android 1.11 (code 12): 1.9's per-theme system-bar colours, rebuilt to sit above a 1.10 test build. The navigation buttons stay white on white on Android 17 / Chrome 154 whatever the app asks for: the TWA's Custom Tab window ignores the navigation-bar colour (plain Chrome tabs are fine), reported to Chromium</title>
<updated>2026-10-09T16:30:07Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-09T16:30:07Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=4d0fc6bf4fd0494df1405899f51f9abbf5ab34a1'/>
<id>urn:sha1:4d0fc6bf4fd0494df1405899f51f9abbf5ab34a1</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MgAFLnkF7KrdhuyCLMNgtL
</content>
</entry>
<entry>
<title>PWA maskable icon is the inner mark on white, like the native app's adaptive icon: it was a copy of the full logo, so Chrome's home-screen Coinos showed an extra outer ring</title>
<updated>2026-10-09T05:26:44Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-09T05:26:44Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=7cea4ccb253d9802d92ee93881ed545e38391870'/>
<id>urn:sha1:7cea4ccb253d9802d92ee93881ed545e38391870</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Setup wizard: a cover behind the avatar — twelve nature covers (self-hosted, Unsplash) cycled with arrows or a swipe, or upload your own; untouched, each pubkey gets its own default, published as the kind-0 banner beside the punk</title>
<updated>2026-10-07T20:25:49Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-10-07T20:25:49Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=39ce1ef4c04bf010c75b3431be69174d6ef2c80a'/>
<id>urn:sha1:39ce1ef4c04bf010c75b3431be69174d6ef2c80a</id>
<content type='text'>
Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>The Android app's system bars follow the system theme, and the page's theme colour follows the app's.</title>
<updated>2026-09-28T06:58:44Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-28T06:58:44Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=318fef4880373fe5c12c366cd8b1c322771714e6'/>
<id>urn:sha1:318fef4880373fe5c12c366cd8b1c322771714e6</id>
<content type='text'>
One dark colour for both bars gave white navigation icons over a light page
under gesture navigation. The wrapper (1.9, versionCode 10) now uses the
page background in light mode and the dark theme colour in dark mode, for
the status bar and the navigation bar alike. The page updates its
theme-color meta when its own theme is applied, so a PWA's status bar and
the wrapper's follow the same 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>Public Sans, the coinos.io face, across the app.</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=9fdbc82fecf17cefed08e8fe1cfee03546d41c5e'/>
<id>urn:sha1:9fdbc82fecf17cefed08e8fe1cfee03546d41c5e</id>
<content type='text'>
One variable-weight woff2 each for upright and italic (41 KB + 45 KB, OFL),
shipped with the build and precached by the service worker; the system stack
paints first and stays when the file never arrives.

Co-Authored-By: Claude Fable 5.1 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01VhUKyXKtsJ67QAFfb7QR9D
</content>
</entry>
<entry>
<title>End to end over the real network, and the advice now fits the app it's in.</title>
<updated>2026-09-13T00:06:14Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-13T00:06:14Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=ce61a0f20a2c535e0c69f59836a17f31a3d88468'/>
<id>urn:sha1:ce61a0f20a2c535e0c69f59836a17f31a3d88468</id>
<content type='text'>
A push sent to ntfy.sh reached a killed app on a real phone:

  17:02:21.259  ntfy.sh → the phone's ntfy → broadcast to io.coinos.webview
  17:02:21.308  app process started (it had been killed)
  17:02:21.458  wake: job started
  17:02:22.926  wake: finishing (page said so)   — 1.7s, and "You were paid"

One thing that took two goes: `adb shell am force-stop` marks a package
STOPPED, and Android delivers no broadcasts to a stopped package unless the
sender sets FLAG_INCLUDE_STOPPED_PACKAGES — which `am broadcast` does and a
real distributor rightly doesn't. The first attempt looked like a failure and
was a test artefact; `am kill`, which is what Android itself does to a
backgrounded app, delivers fine.

And the WebView build can now say something useful about push. It was
inheriting the browser's line — "your browser has no push service, try
Firefox" — which is nonsense inside a WebView that IS the app. It asks the
host what's actually there and says: install a push app like ntfy (nothing
installed), or wait a moment and reopen (a distributor that hasn't answered
yet). Payments and messages still arrive whenever coinos is open, which is
the part that matters most to someone reading an apology.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
</content>
</entry>
<entry>
<title>Proven on a phone: woken from a cold stop in four seconds.</title>
<updated>2026-09-12T22:52:54Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-12T22:52:54Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=7fcad2ddfbaae862d150430b27674606ebca299e'/>
<id>urn:sha1:7fcad2ddfbaae862d150430b27674606ebca299e</id>
<content type='text'>
The whole chain, on real hardware, with the shipping APK installed:

  am broadcast → PushReceiver → expedited job → off-screen WebView →
  v3.coinos.io/?wake= → the wallet restored from its vault → CoinosHost.done()

  15:49:52.341  schedule -&gt; 1
  15:49:52.390  job started          (49ms later)
  15:49:56.602  finishing (page said so)

Four and a bit seconds from a force-stopped app to the page reporting it had
dealt with the payload — not the timeout, the page. A notify payload raised
the right notification too ("You were paid", "New message"), and the wallet
it woke was one imported into the WebView build minutes earlier, restored
from the vault in a process that had been killed.

The payload no longer goes to logcat. It carries the user's push, and
anything with ADB can read that.

Unproven, and the one link I couldn't close here: the distributor handshake.
There's no UnifiedPush distributor on this phone, so every push above was a
broadcast I sent by hand — which is exactly what a distributor sends, but
it isn't the same as watching ntfy do it.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
</content>
</entry>
<entry>
<title>The wake had to be a job, not a foreground service — Android says so.</title>
<updated>2026-09-12T22:47:56Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-12T22:47:56Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=85d7858a0ef4b4f3ee60eb2bd5621e4899195935'/>
<id>urn:sha1:85d7858a0ef4b4f3ee60eb2bd5621e4899195935</id>
<content type='text'>
Tested on a real phone, and the first attempt didn't work at all:

  Background started FGS: Disallowed [... code:DENIED ...]
  startForegroundService() not allowed due to mAllowStartForeground false

Android 12 forbids starting a foreground service from a broadcast receiver.
An expedited job is the sanctioned replacement — it runs promptly from the
background and needs no notification of its own to apologise for existing —
so WakeService is now WakeJob, and the notification is decided by what
arrived rather than by whether we could wake: a payment or a message is news
either way, a wallet-connect request the wallet answers by itself is not.

Two more things the phone found. A job with a connectivity constraint needs
ACCESS_NETWORK_STATE, or schedule() throws and nothing runs at all. And a
wake with nothing to answer used to hold a WebView open for the full thirty
seconds — a locked wallet, no wallet on the device, or no NWC connections all
end the job immediately now.

Also a bug worth naming: ctx carried `wakeDone` by shorthand, which captured
the binding while it was still undefined (ctx is built before it's defined).
The page could never say it had finished, so every wake ran its full timeout.
It reads through a closure now, like its neighbour.

Co-Authored-By: Claude Opus 5 (1M context) &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_019mrt228Upn9nNCwGixzSLx
</content>
</entry>
</feed>
