<feed xmlns='http://www.w3.org/2005/Atom'>
<title>coinosv3.git/android/app/src/main/AndroidManifest.xml, 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-12T17:05:10Z</updated>
<entry>
<title>UnifiedPush: reach a phone that has no Google in it.</title>
<updated>2026-09-12T17:05:10Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-12T17:05:10Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=a846211262f37238c001e5210938749294f8db6a'/>
<id>urn:sha1:a846211262f37238c001e5210938749294f8db6a</id>
<content type='text'>
Web push on Android is Firebase's, so a phone without Google Play Services —
GrapheneOS, CalyxOS, any de-Googled Android — cannot be woken by a web app at
all. UnifiedPush is the way that doesn't involve Google: the user runs a
distributor (ntfy and friends), apps ask it for an endpoint, and whoever
wants to reach the device POSTs to that endpoint.

THE WRAPPER speaks the protocol directly — four broadcasts each way, so it
pulls in no library; an APK this small has no business growing a Kotlin
runtime for eight intents. It asks the distributor on every launch (the call
is idempotent, and it's how a distributor installed later gets noticed),
raises a notification when a message arrives, and acknowledges it so the
distributor stops resending.

THE ENDPOINT reaches the web app on the launch URL as ?up=, the same road
payment intents already travel — because the distributor talks to the app and
only the web app knows which pubkeys are worth watching. It's registered with
the notifier in place of a browser subscription, for notifications and for
NWC alike, and needs neither permission nor push service.

THE NOTIFIER sends to either kind: one deliver() that POSTs the payload to a
UnifiedPush endpoint, or hands it to web-push as before. Same payloads, same
404/410 pruning. The endpoint is the only secret there, so it's never logged
in full.

Verified: a POST to a live ntfy endpoint delivers the payload byte for byte,
so the app parses exactly what the notifier sent; the APK builds, carries the
receiver, and is signed with the certificate assetlinks already pins (v1.6).
tools/unifiedpush-test.js drives a browser with no push service and checks
the endpoint is taken off the URL, kept, and registered.

Honest about the limit: a UnifiedPush message wakes the ANDROID app, not
Chrome's service worker, and the wallet's keys live in the browser's storage
where nothing here can reach them. So a zap request arrives as a notification
you tap, and the wallet answers when it opens — one tap instead of none.
Automatic answering while closed still needs a browser with a push service.

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>Android APK: fix the white status bar (TWA had no system-bar color set).</title>
<updated>2026-09-07T04:10:39Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-07T04:10:39Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=050c944036c32200618f78f1924c81b8c881bb91'/>
<id>urn:sha1:050c944036c32200618f78f1924c81b8c881bb91</id>
<content type='text'>
androidbrowserhelper defaults the TWA status/navigation bars to white when no color is declared — the PWA doesn't hit this because it uses the manifest theme_color. Added STATUS_BAR_COLOR / NAVIGATION_BAR_COLOR meta-data (light + dark variants) pointing at new color resources set to the PWA's theme_color #15171a, so the top bar matches the dark app chrome. Bumped to versionCode 6 / versionName 1.5 and rebuilt static/coinos.apk (meta-data verified present via aapt).

Co-Authored-By: Claude Opus 4.8 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
</content>
</entry>
<entry>
<title>Android wrapper v1.1: scheme + NFC intents move onto a per-intent trampoline (IntentActivity, noHistory) — a TWA already on screen ignores a new intent delivered to its still-alive launcher, so a second lightning: tap did nothing; the trampoline maps the URI to ?u= form and relaunches the TWA with CLEAR_TOP, which navigates the open app. Verified on a real phone over adb: URL-bar-less fullscreen (assetlinks verified after the site began serving /.well-known/assetlinks.json — the deploy hook's dist/* glob was blind to dot-directories, fixed on cs), lightning: intent lands on Send with the invoice filled, and a second bitcoin: intent fired while the app was open navigated it (BIP-21 parsed, address + amount). NFC NDEF filters ride the trampoline for bolt cards / NDEF tags</title>
<updated>2026-09-05T03:53:13Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-05T03:53:13Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=e5e375d8ea2f1193ffe01ff02639f002f91f8035'/>
<id>urn:sha1:e5e375d8ea2f1193ffe01ff02639f002f91f8035</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
</content>
</entry>
<entry>
<title>Android wrapper app (android/): a minimal TWA around v3.coinos.io whose whole reason to exist is intent registration — lightning:/bitcoin:/nostr:/lnurl:/lnurlw:/lnurlp: VIEW intents and the same schemes via NFC NDEF dispatch (bolt cards, address stickers; NFC declared required=false), plus verified https links to the site. LauncherActivity forwards a scheme URI into the web app as ?u=&lt;encoded&gt;; the web app reads it BEFORE features construct — a nostr npub/nprofile rewrites itself onto the existing /npub profile deep link, payment URIs stash and dispatch through handleScanned (the QR path) once a wallet is open, and the param is stripped from the URL either way. assetlinks.json (static/.well-known/, copied by build.js) vouches for the signing cert so the TWA runs URL-bar-less; the built APK is served at /coinos.apk for sideloading. Signing keystore lives in android/ GITIGNORED (keystore.properties beside it) — the assetlinks fingerprint pins it, so losing it means re-shipping assetlinks too. Verified: headless ?u= routing (lightning → Send with invoice filled + URL cleaned; nostr → profile page), APK installed on a real phone via adb, schemes registered (chooser appears where other wallets also claim lightning:)</title>
<updated>2026-09-05T03:48:27Z</updated>
<author>
<name>Adam Soltys</name>
<email>adam@coinos.io</email>
</author>
<published>2026-09-05T03:48:27Z</published>
<link rel='alternate' type='text/html' href='https://git.coinos.io/coinosv3.git/commit/?id=8d27a5d2c59e0f1824753d59a7326b6b76887bf7'/>
<id>urn:sha1:8d27a5d2c59e0f1824753d59a7326b6b76887bf7</id>
<content type='text'>
Co-Authored-By: Claude Fable 5 &lt;noreply@anthropic.com&gt;
Claude-Session: https://claude.ai/code/session_01MGzU12QrAA4G6BYGzGVdXz
</content>
</entry>
</feed>
