883 Commits

Author SHA1 Message Date
archipelago
8af2ca4ac2 docs: complete the v1.7.112-alpha changelog — audio/TV-input/companion-mesh/paid-sharing batch + What's New re-sync
All checks were successful
Demo images / Build & push demo images (push) Successful in 2m45s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:18:37 -04:00
Dorian
e679b4e886 feat(companion): night-test polish sweep — 0.5.9
Everything from tonight's remote field testing:

- Back-to-dashboard fixed: JS bridges on the retained WebView delegated
  through live-composition callbacks (stale closures made apps refuse to
  launch after remote ⇄ dashboard), and reattach forces a layout pass
  (top/bottom UI was wrong until a tap).
- F*CK IPs MESH branded loader: full-screen on relaunch (startup race)
  and during the first connect after scanning a node QR.
- Party 'Share this app' is now a QR of the public vps2 download link
  (scan with any camera → install over any internet); direct APK
  file-share kept as a secondary action.
- Mesh party pairing is MUTUAL: scanner announces itself to the scanned
  phone's Flare /hello — both sides get the peer, a chat entry and a
  '👋 joined the party' message; scanner auto-opens the chat.
- Party scanner asks for CAMERA permission (fresh installs/reinstalls
  landed on a black preview).
- Node: device tokens mint unique companion-<id> names — pairing a
  second phone no longer revokes the first phone's login (the source of
  'reconnecting a lot' and the second phone's failure).

Served APK: 0.5.9 (vc29).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 02:03:47 +01:00
Dorian
1e20b79c3c feat(companion): kiosk session survives remote ⇄ dashboard navigation
The WEB_VIEW route recreated the WebView on every return from the
remote screen — full reload + re-login every time. The kiosk WebView is
now retained in a holder and reattached live (no race, no reload);
clients/bridges/listeners are re-bound to the new composition on
reattach, and the instance is dropped on retry, disconnect, or server
change so errored/stale sessions still reload for real.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 01:19:57 +01:00
Dorian
1bcf6ccadb feat(companion): share-the-app from Mesh Party + party entry on the intro screen — 0.5.8
- Party screen 'Share this app': shares this install's own APK through
  the system sheet (FileProvider over cache/share/), so a nearby friend
  gets the companion via Quick Share/Bluetooth with zero internet — the
  party-mode premise end to end.
- Intro screen: Mesh Party button under Get Started — party works with
  no node at all, so it belongs on the first screen a fresh install
  shows.
- Served APK: 0.5.8 (vc28), ready for the QR/OTA/ISO cut.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 01:16:54 +01:00
Dorian
f0926ece94 feat(companion): mesh party + Flare, keep-warm mesh, restored fast-start, UI fixes — 0.5.7
Combined session state from both agents (shared checkout):

- Mesh Party / Flare (experimental): phone-to-phone FIPS via party QR,
  Flare chat/beam on :5680, optional fixed UDP listen (2121); party-only
  phones get the baked-in Archipelago anchor so two bare phones reach
  each other across the internet, not just on a hotspot.
- Keep-warm mesh: a running healthy node survives app opens (restart
  only when dead or peers changed — peersDirty); requestMeshRestart for
  config changes. Cold start measured on-device: session in ~3.1s.
- Restored after regression: startup LAN-vs-mesh race (the party work
  was based on a pre-#114 file copy) and same-node routing (BTCPay/
  Pine/HA had returned to opening in the external browser).
- UI: top status-bar scrim removed (bottom-only bars); web app-session
  mobile bar is solid black — app theme colour no longer bleeds through
  the bar and its safe-area strip.

Served APK: 0.5.7 (vc27).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 01:04:36 +01:00
Dorian
75ecd1d3ea feat(companion): 60s mesh probe window + session pre-warm from the VPN service
Implements the app-side recommendations from the node diagnosis
(HANDOFF-2026-07-23): first session through the public tree takes 15s+
when it works at all, far beyond the old ~8s probe window.

- connect(): mesh ULA probed inside a 60s budget, 15s per-phase timeouts.
- ArchyVpnService: session warmer probes every saved node ULA as soon as
  the tunnel is up (5s cadence first minute, then 60s keep-warm) so the
  UI hits a warm session and it never idles out.
- Served APK: 0.5.5 (vc25); handoff updated with 25-ping evidence that
  public-tree discovery currently fails outright (supports the
  private-tree infra decision).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 23:36:34 +01:00
Dorian
53037b2b71 fix(companion): TUN reader no longer dies on non-blocking fd + VPN not metered
On-device diagnosis (phone on adb, 5G): mesh sessions established but no
packet ever entered the tunnel — Android hands the VpnService TUN fd over
non-blocking, and the fips fork's dedicated blocking-read thread treats
EAGAIN as fatal, dying at startup. archy-fips-core now forces the fd into
blocking mode before Node::start_with_tun_fd. Verified on-device: reader
survives, packets flow into the mesh, and the 30s anchor-link flap is
gone (stable 8+ min on 5G).

Also setMetered(false): Android 10+ defaults VPNs to metered, flipping
the phone into data-restricted behaviour whenever the mesh is up.

Served APK: 0.5.4 (vc24). Handoff updated with the remaining node-side
blocker: phone->anchor works, phone->node ULA gets no reply — needs
fipsctl introspection on Framework PT (suspect fork/daemon session or
routing mismatch).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 22:47:26 +01:00
Dorian
e49af6ff40 fix(companion): guarantee dual-path peering — LAN p2p + public anchor, always
The whole point of FIPS: the phone peers with the node's npub using the
LAN endpoint as a direct p2p dial hint AND rendezvouses via a public
anchor when away — neither LAN nor 5G location may matter. The anchor
half only existed when the scanned QR carried fanchors, so pairing
against an older node left the phone LAN-only and everything died on 5G.

The Archipelago vps2 anchor (npub + 146.59.87.168:8444/tcp, lockstep
with core fips/anchors.rs) is now baked into upsertNodePeer as a
guaranteed peer. Mesh connect retry window widened so a first-ever
pairing survives the VPN consent dialog. Served APK: 0.5.3 (vc23).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 22:17:24 +01:00
Dorian
979113c598 fix(companion): mesh VPN no longer blocks IPv4 + off-LAN connect via mesh ULA
Field test on 5G (Framework PT): pairing scanned fine but connect
hard-failed on the scanned LAN IP, and enabling the mesh VPN killed the
phone's internet.

- ArchyVpnService: the TUN is IPv6-only, and Android blocks every
  address family the VPN holds no address for — allowFamily(AF_INET)
  (+ allowBypass) so normal traffic flows while only fd00::/8 is routed.
- ServerConnectScreen.connect(): when the LAN address doesn't answer and
  the entry carries a mesh ULA, bring the tunnel up (autoStartIfReady)
  and probe the ULA with retries before reporting failure — the scanned
  IP is a dial hint, the npub/ULA is the identity (npub-first contract).
- Served companion APK refreshed as 0.5.2 (vc22); handoff doc updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 22:00:15 +01:00
Dorian
35849c88c6 chore(android): companion 0.5.1 (vc21) — refresh served APK + deploy handoff
The APK served from the pairing QR predated today's scanner fixes, so
the download-then-scan flow still hit the laggy scanner. Bumps the
version so phones update in place, refreshes the served artifact
(signed v1+v2+v3, verified), and adds the archi-dev-box deploy handoff.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:53:29 +01:00
archipelago
ed2c14c88a fix(companion): pairing QR scannable again — cap anchors at 2, EC level L, 768px source
Three npub-bearing anchors pushed the pairing URI to ~600 chars (QR ~v23 at
EC-M) — phone cameras couldn't lock onto it off a screen. The phone only
needs the node itself (LAN p2p) plus one public rendezvous (vps2 preferred),
and screen scans don't need EC-M's damage tolerance — L drops a full
version tier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:46:51 -04:00
archipelago
4199c43cc9 Merge gitea-ai/main — companion native-scan PR #104 (newer scanner rev wins in WalletScanModal)
Some checks failed
Demo images / Build & push demo images (push) Has been cancelled
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:25:02 -04:00
archipelago
54ddd043bd feat(tv-input): gamepad->keyboard bridge daemon + controller-navigable modals
- archipelago-gamepad-keys: evdev->uinput daemon (pure python3 stdlib) that
  mirrors any attached controller as a virtual keyboard — D-pad/stick to
  arrows, A/B to Enter/Escape, X/Y to Space/f, shoulders to Tab/Shift+Tab.
  The browser sees real keys, so controllers work inside EVERY app iframe
  (IndeeHub, Jellyfin…) with zero per-app code. Ships via the ISO splice and
  bootstrap self-heal (kiosk nodes only), hotplug via 5s rescans.
  Implements docs/tv-input-iframe-apps.md.
- useControllerNav: an open [role=dialog][aria-modal] owns navigation —
  focus is pulled inside, arrows move spatially between its controls, Enter
  activates, Escape stays with the modal's own close handling. One standard
  mapping for every modal.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:17:11 -04:00
archipelago
402183c0ae feat(appsession): mode switches never reload the iframe + strictly per-app display modes + TV focus
- The session subtree now ALWAYS lives under <body>; inline panel mode is
  emulated with a fixed-position rect synced from the layout placeholder
  (ResizeObserver + resize), so toggling panel/overlay/fullscreen no longer
  re-parents — and therefore no longer reloads — the app iframe.
- Display modes are strictly per-app: saved per-app pick → app default
  (IndeeHub: fullscreen) → panel. The global fallback is gone, so one app's
  mode can never change how another opens.
- The iframe takes focus when the app loads, so keyboard / the gamepad
  bridge work inside it immediately (TV).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:15:43 -04:00
archipelago
80875a2ed4 feat(wallet): invoice-first lightning send — amount locks from the pasted invoice
A pasted fixed-amount invoice auto-fills and locks the amount ('set by
invoice' — nothing to type, just review and send); zero-amount invoices get
an explicit 'enter how many sats' hint. Plus a clipboard Paste button on the
destination field (hidden where clipboard read can't work).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:15:43 -04:00
archipelago
f72d4b92ac feat(content): seller-picked payment methods + music always in the bottom bar + video PiP
- Paid sharing: AccessControl::Paid gains an accepted-methods list
  (lightning/onchain/ecash/fedimint; empty = all, back-compat). Sellers pick
  methods in ShareModal, gated on what the node can actually receive (LND
  running/channel open, ecash wallet, fedimint joined) with an ⓘ that
  explains exactly how to enable a missing rail. Enforced server-side (the
  invoice/onchain mints refuse non-accepted methods; the serve gate only
  honors tokens/hashes for accepted rails) and the buyer's pay modal only
  offers what the seller accepts.
- Purchased music: the two remaining lightbox paths now use the bottom-bar
  player — the immediate post-ecash-purchase viewer and the Paid Files
  tab's window.open.
- Picture-in-picture buttons on the peer video player and the cloud media
  lightbox (utils/pip.ts; Chromium/Safari, no-op elsewhere).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 16:15:11 -04:00
Dorian
fbed32f95d feat(wallet): hand live scanning to the companion's native camera when present
The scan/upload chooser (already on main) keeps the first move; when the
Android companion's window.ArchipelagoQr bridge exists, 'Scan with
camera' opens the native CameraX modal instead of getUserMedia — which
the companion's plain-http origin doesn't even have, so the button now
shows there too. Decodes come back via window.__archyQrResult, status
lines mirror out via setStatus, and stopScanning closes the native
modal once a code is accepted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 21:00:28 +01:00
archipelago
d5fc3d01a4 Merge companion native-scan branch — scan/upload choose pane supersedes today's interstitial
Another agent's feat/companion-3finger-native-scan: native wallet QR scanner
in the companion (WalletQrScannerModal.kt), three-finger menu gesture,
WebView file uploads, and the same every-open scan/upload chooser as a
dedicated pane with native-scanner handoff. Conflict in WalletScanModal.vue
resolved in the branch's favor — its choose-pane implementation replaces the
in-pane interstitial from 6502f13e (same UX, plus the native handoff).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:58:17 -04:00
Dorian
ff4013bd3b feat(wallet): scan/upload chooser on every open + native scanner handoff
The scan modal now always lands on a chooser pane — Scan with camera /
Upload image / paste — instead of auto-starting the camera. When the
Android companion's ArchipelagoQr bridge is present, live scanning is
delegated to the native camera modal (WebView getUserMedia lags);
animated-QR progress and errors mirror onto it via setStatus.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 20:52:42 +01:00
archipelago
9f1daa0f8c feat(ui): per-app display-mode defaults (IndeeHub fullscreen) + gamepad plays media + node list scales
- Per-app default display mode: explicit user pick (remembered per app) ->
  app default -> last global -> panel; IndeeHub defaults to fullscreen.
- data-controller-primary: a media file card's gamepad-select clicks the
  card (audio -> bottom-bar player, video -> lightbox) instead of the
  card's download link.
- Discovered-nodes list scales with the viewport (max(14rem,45vh)) instead
  of cramming a long list into a fixed 224px box.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:31:02 -04:00
archipelago
960e41e164 fix(content): audio always plays in the bottom-bar player + ecash purchase is explicit two-step
- Owned/purchased and cloud audio never opens a lightbox: PeerFiles'
  owned-content viewer and the Cloud/CloudFolder preview route audio to the
  global bottom-bar player (video keeps the lightbox).
- Web5 shared-content 'Buy' no longer fires the node-ecash payment on
  click: it opens a confirmation with balance -> price -> balance-after,
  and pays only on explicit confirm.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:31:01 -04:00
archipelago
6502f13e29 feat(wallet): paste-send confirmation step + every-time scan/upload chooser
- Pasting an invoice/address now gets the same second-step confirmation the
  scan flow has: method, destination, live balance -> amount -> balance
  after (invoice-fixed amounts win over the typed one), for every rail
  including token minting. Nothing pays until Confirm & Send.
- The scan modal opens on a chooser every time: scan with camera or
  upload/take a photo of the QR — the camera no longer auto-starts, and
  Back only relights it if camera was the user's choice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:30:42 -04:00
archipelago
c58f84c6e9 feat(companion): npub-first pairing — node self-anchor + guaranteed public anchor in the QR
The pairing QR was effectively IP-first: the phone dialed the scanned LAN
host and went dark when the LAN renumbered or it left home. FIPS peers on
npubs; IPs are only dial hints. fanchors now leads with the paired node
ITSELF (fnpub @ current host, npub-keyed so LAN contact is direct p2p over
FIPS and survives DHCP), and fips.pair-info always includes the Archipelago
vps2 public anchor (pairing hint only — the node's own anchor file is not
modified) so the phone can rendezvous through the public mesh when away.
Contract doc updated with the REQUIRED app-side changes (built on the Mac).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 15:30:40 -04:00
archipelago
b991c18e73 fix(aiui): color-scheme meta keeps iframe transparent so background art survives dark shell
Some checks failed
Demo images / Build & push demo images (push) Failing after 34s
Browsers only honor a transparent same-origin iframe canvas when the
embedder and the iframe agree on color-scheme; the neode-ui shell's
:root{color-scheme:dark} was forcing the AIUI frame opaque and hiding
the background art behind the chat.

Also adds neode-ui/vite.preview.config.mts (preview on :8100 against
the mock backend on :5959).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 04:43:42 -04:00
archipelago
f339358109 fix(content): double-pay is now impossible + purchases auto-file + Paid Files tab
Some checks failed
Demo images / Build & push demo images (push) Failing after 32s
The double-share/double-pay chain (user hit it live, 2026-07-22):
ShareModal's already-shared lookup compared the slash-stripped stored
path against the leading-slash filepath — never matched — so every
re-share minted a NEW catalog entry with a new id, and the buyer's
owned-guard (keyed by id) saw the duplicate as unowned and paid again.
Three independent walls now: (1) ShareModal normalizes both sides so
re-shares reuse the entry; (2) content_server::add_item dedupes by
filename server-side (updates in place, keeps the id so buyers' owned
records stay valid); (3) the buyer REFUSES to pay for content it
already owns — matched by (onion, content_id) OR (onion, filename) —
and serves the cached copy instead, before any ecash is minted.

Purchases also auto-file into Photos/Music/Documents on the node (same
buckets as the Cloud view, collision-safe naming) so bought files show
up where files live on every device, and Cloud gains a Paid Files tab
listing every purchase (name, size, sats paid, date) with in-app view.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 21:10:48 -04:00
archipelago
df9b9905b6 feat(wallet): LND wedge watchdog + Fedi send rail + token QRs + Auto hidden
Some checks failed
Demo images / Build & push demo images (push) Failing after 33s
- LND watchdog: framework-pt's LND sat wedged 14h (RPC up, server never
  ready, channels inactive) with nothing noticing. 15 consecutive bad
  minutes now bounce the container automatically (30min cooldown) —
  silent multi-hour Lightning outages become self-healed blips.
- Send modal: Auto tab hidden; Ecash splits into Cashu and Fedi (new
  wallet.fedimint-send RPC wrapping the existing spend_from_any); both
  rails render the generated token as a scannable QR alongside the
  copyable text.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:55:37 -04:00
archipelago
e68fe071a7 docs: v1.7.112-alpha changelog + What's New sync + flasher integration point
Some checks failed
Demo images / Build & push demo images (push) Failing after 32s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:40:05 -04:00
archipelago
cbb108a636 fix(wallet): photo QR decode uses native BarcodeDetector first — dense Lightning invoices scan reliably
Some checks failed
Demo images / Build & push demo images (push) Failing after 33s
On the companion (plain-http LAN = no secure context = no live camera)
the photo path IS the scanner, and qr-scanner's single wasm pass often
misses the dense QR of a full BOLT11 invoice. Android WebView's native
BarcodeDetector handles them easily — try it first, wasm as fallback,
plus a 'Reading photo…' status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:16:35 -04:00
archipelago
bfd8bc5b9a fix(wallet): channel funding-tx link uses the explorer flow + consent modal above nested modals
Some checks failed
Demo images / Build & push demo images (push) Failing after 35s
The Channels panel's 'Funding tx in Mempool' link still hardcoded the
local app (missed in the explorer rollout): now it routes like every
other tx link — local Mempool when running, else the saved external
explorer, with the first-time consent modal setting it up and then
opening the tx. The consent modal moves to z-3600 so it renders above
the Wallet Settings modal that can trigger it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 20:02:35 -04:00
archipelago
b193e64ffb fix(ui): kiosk dropdown flash + never inherit the OS light theme
Outside-close listeners move from click to pointerdown: pointerdown
fires before the open-toggle re-render, so the kiosk's slow software
compositing can no longer detach the click target mid-flight and close
the menu the instant it opens. color-scheme:dark (CSS + meta) pins every
native control — select popups, scrollbars, pickers — dark regardless of
the user's OS theme; explicit select/option colors cover Firefox.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:44:32 -04:00
archipelago
770e3386f4 perf(nodes): Connected Nodes refresh — parallel probes, instant list, 12s health timeout
Reachability probes ran one at a time with a 30s Tor timeout each, so
Refresh sat disabled for N-offline-peers × 30s. Now the list renders and
the button re-enables immediately; probes run concurrently and fill the
dots in as they land.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:44:31 -04:00
archipelago
8f4c32b93f feat(ui): modal contract — pinned title+tabs, scrolling middle, pinned footer
Some checks failed
Demo images / Build & push demo images (push) Failing after 33s
BaseModal becomes a flex column: title row and the new #header slot
(tabs) stay fixed at the top, #footer (action buttons) fixed at the
bottom, only the default slot scrolls (default max-h 90vh unless the
caller sets one). Wallet Settings migrates: tabs pinned, four duplicated
in-pane Close rows collapse into one pinned footer that carries the
active tab's primary action.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:08:38 -04:00
archipelago
30a4343b83 fix(ui): kill console spam — pine/mempool icon 404s + filebrowser 401 loop
pine/mempool get explicit icon entries (their extensions aren't .png, so
the default guess 404'd on every render). filebrowser-client: central
authedFetch does ONE transparent re-login when the short-lived JWT
expires (an expired cookie previously kept _authenticated=true and every
Files-card poll 401'd forever), plus a 60s login cooldown so a missing
filebrowser doesn't spam either.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:08:31 -04:00
archipelago
cad68eb941 fix(mesh): setup modal re-fires on EVERY plug — dismissals key on plug time
detected_device_info now carries plugged_at (the /dev node's creation
time; udev recreates it per plug). Dismissals store (path -> plugged_at),
so swapping sticks or a fast unplug/replug between status polls can no
longer be suppressed by an old 'Not Now' (v1 path-only dismissals are
abandoned wholesale).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:08:18 -04:00
archipelago
197e351880 fix(companion): pairing QR advertises the LAN address, never a tailnet IP
The QR mirrored the browser origin — an operator browsing over Tailscale
handed the phone a 100.x address it has no route to, so pairing silently
never connected (reported 2026-07-22; the 'random password' alongside it
was the device token working as designed). system.get-hostname now also
returns the default-route LAN IPv4; the QR substitutes it (or the mDNS
name) whenever the origin is localhost or a CGNAT/tailnet 100.64/10 IP.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 19:08:17 -04:00
archipelago
d86043193b feat(mock): mesh.probe-device + manage_radio for the hot-swap modal demo
Some checks failed
Demo images / Build & push demo images (push) Failing after 2m53s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:35:55 -04:00
archipelago
b3796546aa fix(ui): apps open ABOVE the modal that launched them
AppLauncherOverlay sat at z-2400 under BaseModal's z-3000, so an app
opened from e.g. the Transactions modal loaded invisibly underneath it.
z-4000 lets the existing enter animation play over the modal; closing
the app returns to the modal you came from.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:31:48 -04:00
archipelago
c0aef2f03e feat(wallet): external tx-explorer fallback with consent + On-chain settings tab
Pruned nodes can't run the Mempool app, but tx links blindly opened it
anyway. Now: local app when running; otherwise an external explorer
(default tx1138.com) behind a one-time amber consent modal that spells
out what the other server's operator learns (tx of interest + IP) and
lets the user point at their own instance (placeholder mempool.guide).
Wallet Settings gains an On-chain tab (explorer URL + don't-warn toggle);
tabs renamed Cashu/Fedi so five fit in the row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:31:48 -04:00
archipelago
5e7e928650 feat(wallet): real-time tx push — 0-conf shows in seconds, not on poll
Backend streams LND /v1/transactions/subscribe (fires on mempool arrival
and each confirmation) and nudges the /ws/db revision per event; the Home
wallet card subscribes and refetches (debounced 800ms). An incoming
broadcast now appears while the 30s poll is still asleep. Reconnects
forever with capped backoff when LND is down/locked/absent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:31:47 -04:00
archipelago
088b3e255a fix(lnd): retry channel opens during LND startup + calm non-red notice
LND's RPC answers before its p2p server finishes loading, so connect/open
during that window failed red with the raw "server is still in the
process of starting". Now: quiet ~30s retry first; if still starting, a
calm amber "still finishing its startup" notice instead of an error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 17:31:47 -04:00
Dorian
97464779d4 chore(android): update companion APK download [skip ci] 2026-07-22 22:06:32 +01:00
Dorian
4b91765cc7 feat(companion): embedded FIPS mesh replaces WireGuard for remote access
- Android/rust/archy-fips-core: leaf-only fips node as a JNI cdylib (fips
  pinned to the fips-native fork rev with VpnService fd support), built by
  gradle via cargo-ndk (arm64), tested on host
- ArchyVpnService: split-tunnel VpnService routing only fd00::/8 (MTU 1280,
  foreground specialUse); FipsManager handles the one-time VPN consent and
  silent auto-start — no settings surface at all
- pairing QR now fully configures the mesh: fnpub/fip/fhost/fudp/ftcp plus
  fanchors (the node's seed-anchor list, npub@addr/transport) so the phone
  can rendezvous through public anchors when the LAN endpoint is unreachable
- default seed anchors gain the two dual-transport join.fips.network test
  anchors (23.182.128.74:443/tcp, 217.77.8.91:443/tcp); anchor adverts are
  Nostr kind-37195 events
- device token rides the password field end-to-end: backend accepts tokens
  wherever it accepts the password, so scan = instant login (WebSocket auth
  + WebView form injection unchanged); token logins skip TOTP
- ServerEntry.meshIp + IPv6-bracketed URLs; WebView retries the mesh address
  on main-frame errors, auto-login and origin checks honor it
- companion v0.5.0 (versionCode 20), arm64 abiFilter; FipsNative.available
  gates everything so non-arm64 still runs as a plain companion

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:06:32 +01:00
Dorian
b88609e0ff feat: instant companion pairing — device tokens, named QR, FIPS pair-info
- auth.createDeviceToken / listDeviceTokens / revokeDeviceToken RPCs; only
  SHA-256 hashes persist in data_dir/device-tokens.json
- auth.login accepts {token} (same rate limiter, skips TOTP like remember-me)
- pairing QR now carries name (server name, fallback "My Archipelago"),
  tok (instant login), and FIPS mesh params from new fips.pair-info RPC
  (npub, fips0 ULA, transport ports)
- companion onboarding drops the WireGuard install/tunnel screens — remote
  access moves to the FIPS mesh embedded in the companion app
- fix: fips daemon UDP bind now 2121, matching the published container port
  and fleet rosters (was upstream's 8668 — inbound UDP was dead on bridged
  installs, mesh silently rode TCP 8443)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 22:04:59 +01:00
archipelago
8b744d377c feat(mesh): radio hot-swap — probe on plug-in, keep-as-is vs apply-our-settings
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m49s
Plugging in any LoRa radio now surfaces the device setup modal EVERY time
(dismissals clear on unplug; works while mesh is enabled; 2-poll debounce
so ordinary reconnect blips don't flash it), showing what's currently on
the stick before anything is written:

- mesh.probe-device RPC: identifies the firmware read-only in the same
  Reticulum->Meshcore->Meshtastic order as auto-detect. Meshtastic yields
  region/modem-preset/channels (want_config is a read); MeshCore yields
  name/node-id + firmware version via the previously-unused
  CMD_DEVICE_QUERY; RNode via the bare KISS DETECT (no daemon spawn).
  Path must be a detected candidate port; the live session's port refuses.
- "Keep As Is": manage_radio=false persists in MeshConfig and the session
  skips every on-connect config write (region, channel, PHY params, advert
  name) — the radio runs exactly as flashed, hot-swappable.
- "Set Up with Archipelago Settings": second screen shows the params that
  will be applied (channel, region, the node's persisted RF params - e.g.
  the validated Portugal preset - with the per-region community plan as
  fallback) before writing anything.
- Stale-type fix: disconnect now resets device_type/firmware_version, so
  a swapped stick no longer shows the previous radio's firmware; probed
  kind pins device_kind so the right probe runs first on connect.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 16:25:19 -04:00
archipelago
7e7b6bd474 fix(neode-ui): instant payments no longer stuck as 'Incoming' forever
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m42s
The Home wallet card counted every incoming tx with num_confirmations < 3
in the pulsing 'Incoming N' badge. Lightning history hardcodes 1 conf and
ecash/fedimint/ark receives are normalized to 1 conf, so instant payments
qualified permanently — old receives showed as 'incoming' forever (seen
on .228 with week-old lightning orders).

- On-chain keeps confirmation-based logic (< 3 confs, expires naturally).
- Instant rails (lightning/cashu/fedimint/ark) now surface in the incoming
  panel only for 5 minutes after receipt — the nice arrival moment without
  the perpetual pending state.
- Panel rows: 'Unconfirmed / N conf' badge and mempool link are now
  on-chain-only; instant rows get a rail badge instead.
- Home now polls wallet balances+transactions every 30s (like Web5.vue),
  so pending on-chain receives actually flip to confirmed and the badge
  appears/expires without a manual wallet action.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 12:43:53 -04:00
archipelago
1931371058 chore: release v1.7.111-alpha
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m45s
2026-07-22 05:40:40 -04:00
archipelago
693f4bb947 docs: v1.7.111-alpha changelog + What's New sync
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m39s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 05:04:11 -04:00
archipelago
cc2c06c6dc fix(neode-ui): companion app opens every app in the native WebView, never an iframe
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m42s
Regression: only X-Frame-Options apps were routed to the companion's
in-app WebView; iframeable apps fell through to the iframe session, which
is slower on the phone and loses the native back/forward/reload controls.
Now any launch inside the companion (ArchipelagoNative.openInApp bridge
present) goes to the WebView — both openSession and the legacy open()
overlay fallback. Mobile web/PWA keeps the iframe session. With regression
tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 04:54:20 -04:00
archipelago
317a72aafe fix(federation): presence-sign modal scales and scrolls on small phones
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m37s
The info card above the action buttons now shrinks with the viewport and
scrolls internally (min-h-0 + overflow-y-auto in a max-h-full flex column),
keeping Cancel / Sign & Publish always visible. The hero disc and viz ring
scale down on narrow or short screens via a --seg-radius CSS variable so
the animation honors the smaller ring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 03:12:15 -04:00
archipelago
184257390d feat(pine): 1.3.0 manifests — openwakeword member + live node status on the launcher page
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m40s
pine-openwakeword manifest (wyoming-openwakeword 2.1.0, :10400, /custom model
dir for the future Yo Archy model). Pine 1.3.0: launcher page gains a live
node-status card fed by /api/pine/status via a same-origin nginx proxy, and
copy for the new intents / Claude fallback / mesh announcements. Catalogs,
app-session config, drift ids regenerated; release catalog embeds 56
manifests (unsigned until the ceremony). Framework PT test plan in docs/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 02:59:34 -04:00