Compare commits

...
16 Commits
Author SHA1 Message Date
archipelago 562871b1ce chore: prepare signed release v1.8.19-alpha 2026-09-28 13:18:34 -04:00
archipelago cca3f8bfcd docs: include AIUI packaging fix in v1.8.19 release notes
Demo images / Build & push demo images (push) Failing after 44s
2026-09-28 13:13:31 -04:00
archipelago 89c08be712 fix(aiui): match host color scheme for iframe transparency
Demo images / Build & push demo images (push) Failing after 56s
2026-09-28 12:37:40 -04:00
archipelago b4ecf86c13 chore: stage v1.8.19-alpha version bump 2026-09-28 12:33:59 -04:00
archipelago b14fe78306 fix(aiui): expose host wallpaper and package fresh production builds 2026-09-28 12:32:18 -04:00
archipelago 3f0c1038c3 docs: add v1.8.19 release notes to settings 2026-09-28 12:23:57 -04:00
archipelago 1fbefce6df docs: add v1.8.19-alpha release notes 2026-09-28 12:23:05 -04:00
archipelago 63cb68451a fix(aiui): keep embedded chat background transparent 2026-09-22 05:04:59 -04:00
archipelago 17cfebbe26 chore: publish release v1.8.18-alpha 2026-09-20 11:49:39 -04:00
archipelago 379fb930fc chore: prepare release v1.8.18-alpha
Demo images / Build & push demo images (push) Failing after 43s
2026-09-20 11:45:35 -04:00
archipelago 1bebdeac0f Prepare v1.8.18-alpha release notes 2026-09-18 06:36:43 -04:00
archipelago f458591132 Document Minibits description customization limits
Demo images / Build & push demo images (push) Failing after 45s
2026-09-15 16:13:14 -04:00
archipelago 6155539254 Confirm Primal automatic-comment cause and successful workaround 2026-09-15 16:11:09 -04:00
archipelago 76e0f1f3b6 Trace Primal Spark auto-comment failure against Framework address 2026-09-15 16:09:16 -04:00
archipelago ba6ce2cdb6 Record live LNURL comment limit investigation 2026-09-15 16:06:21 -04:00
archipelago 8212049f57 Shorten ecash backup copy and stack card actions 2026-09-15 16:03:52 -04:00
17 changed files with 265 additions and 111 deletions
+12
View File
@@ -2,6 +2,18 @@
## Unreleased
## v1.8.19-alpha (2026-09-28)
- Fixed the embedded AIUI chat page painting a second background and dark scrim over Archy’s dashboard background.
- Embedded AIUI now stays transparent so the dashboard background appears once.
- AIUI background fixes are now included reliably in OTA updates and fresh installations.
## v1.8.18-alpha (2026-09-18)
- Framework startup prioritizes Bitcoin and LND before unrelated containers, and unavailable LND balances remain unavailable instead of appearing as false zeroes.
- Cashu Receive guides unseeded wallets through recovery-phrase setup, with shorter backup guidance and a single-column layout.
- Added live Framework verification for automatic LND unlock, native balance preservation, Cashu address registration, and proof preservation.
## v1.8.17-alpha (2026-09-15)
- Minibits claims that every mint reports as already spent leave the retry queue, clearing repeated failure notices. Network errors and mixed mint failures remain queued for another attempt.
+3 -2
View File
@@ -46,13 +46,14 @@ interface RateBucket {
const rateBuckets = new Map<string, RateBucket>()
// Clean up stale buckets every 5 minutes
// Vite imports this module during builds too; cleanup must not keep the
// process alive once compilation has finished.
setInterval(() => {
const now = Date.now()
for (const [key, bucket] of rateBuckets) {
if (now > bucket.resetAt) rateBuckets.delete(key)
}
}, 5 * 60_000)
}, 5 * 60_000).unref()
function getClientIp(req: IncomingMessage): string {
return req.socket.remoteAddress ?? 'unknown'
+1
View File
@@ -33,6 +33,7 @@ const PWA_CACHE_VERSION = '2'
// Only embedded when explicitly requested via ?embedded param
const _embeddedFlag = new URLSearchParams(window.location.search).has('embedded')
;(window as unknown as Record<string, unknown>).__AIUI_EMBEDDED__ = _embeddedFlag
document.documentElement.classList.toggle('aiui-embedded', _embeddedFlag)
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
+5 -5
View File
@@ -2,13 +2,13 @@
<div
class="h-full flex flex-col relative overflow-hidden transition-colors duration-300"
:class="[]"
:style="isDark
? { background: '#000 url(' + bgImageUrl + ') center center / cover no-repeat fixed' }
: isEmbedded
? { background: 'transparent' }
:style="isEmbedded
? { background: 'transparent' }
: isDark
? { background: '#000 url(' + bgImageUrl + ') center center / cover no-repeat fixed' }
: { backgroundColor: '#f5f4f1' }"
>
<div v-if="isDark" class="absolute inset-0 pointer-events-none bg-black/20" />
<div v-if="isDark && !isEmbedded" class="absolute inset-0 pointer-events-none bg-black/20" />
<!-- Desktop layout -->
<div
+15 -6
View File
@@ -57,12 +57,8 @@ body {
width: 100%;
height: 100%;
overflow: hidden;
/* Every page paints its own explicit background (bg-[#0a0a0a] / bg-[#faf9f6])
EXCEPT the embedded Chat page, which intentionally goes transparent so
Archy's own dark chrome can show behind it (Chat.vue's iframe host). With
no background-color here, "transparent" fell through to the browser's
default white canvas instead. Match the theme's own dark/light default so
nothing above this ever needs to guess. */
/* Standalone canvas fallback. Embedded mode overrides this below so
Archy's wallpaper remains visible through the iframe. */
background-color: #0a0a0a;
}
@@ -70,6 +66,19 @@ html.light body {
background-color: #faf9f6;
}
/* The host owns the wallpaper when AIUI is embedded. The document canvas
must be transparent too, otherwise it hides the host behind ChatPage. */
html.aiui-embedded {
/* Match Archy's dark canvas scheme. Browsers otherwise give an iframe
with a different scheme an opaque canvas despite transparent CSS. */
color-scheme: dark;
}
html.aiui-embedded,
html.aiui-embedded body {
background: transparent;
}
/* ===== DARK MODE GLASSMORPHISM — from Archy ===== */
@layer components {
+1 -1
View File
@@ -104,7 +104,7 @@ dependencies = [
[[package]]
name = "archipelago"
version = "1.8.17-alpha"
version = "1.8.19-alpha"
dependencies = [
"anyhow",
"archipelago-container",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "archipelago"
version = "1.8.17-alpha"
version = "1.8.19-alpha"
edition = "2021"
license.workspace = true
description = "Archipelago Bitcoin Node OS - Native backend"
+90
View File
@@ -286,3 +286,93 @@ record final human confirmation of the rendered dashboard balance (native balanc
match exactly, and UI failure/recovery regressions pass). Keep this follow-up
visible across sessions; do not rebuild/reboot/reinitialize a working wallet just
to repeat already completed checks.
### Backup copy and layout — 2026-09-15
At the user's request, shortened the ecash backup explanations and stacked each
card section's text and full-width action vertically. Kept the distinction
between node-derived and separate phrases, and the warning that a newly created
phrase covers future coins rather than existing legacy coins.
All 10 Receive/backup tests and the production UI build pass. Deployed the UI to
Framework without a restart; served index and backup-component bundle match the
build byte-for-byte. The prior UI is saved as `web-ui-before-backup-copy` in the
protected incident directory. Source integration and final rendered dashboard
balance confirmation remain pending as above.
### LNURL comment-length report — 2026-09-15
User reports a maximum-comment-length error in some sending wallets. Live
Framework address metadata advertises integer `commentAllowed: 100`. The QR
contains the address only; Archy's Receive UI does not add a comment. The
Minibits-hosted callback returned invoices for omitted/empty comments, 100 ASCII
characters, 101 ASCII characters, and 100 accented characters. These were unpaid
invoice requests at the advertised minimum amount; no funds were sent.
The callback did not reproduce the error, including beyond its advertised limit.
Sending-wallet validation against the advertised 100-character limit is therefore
a hypothesis, not a confirmed root cause. Asked which wallets fail and whether
an empty comment also fails. Need that result before selecting a code fix.
The service controls the advertised limit; changing local Receive text or QR
cannot raise it for other wallets.
### Primal Spark: automatic recipient note exceeds the address limit
User clarified that no comment was entered and the sender is Primal Spark.
Checked Framework's management journal over the preceding 20 minutes: no
comment-length errors, service active, and zero pending Minibits claims. Recent
claim polling connected to and disconnected from the relay normally. Historical
seed-authentication failures preceded the successful setup already documented.
The live address's Minibits `text/plain` description is **101 ASCII characters**,
while `commentAllowed` is **100**. Description template (address redacted):
`Pay to [ADDRESS] with Lightning. Receiver will receive ecash into Minibits Wallet.`
Primal Android source at `36939db97213e7f8eeefaa4adaf125d839fc662e`:
- `WalletTextParserImpl.handleLnUrlText` assigns the parsed description to
`DraftTx.noteRecipient`, including for Lightning-address input.
- `TransactionEditor` initializes its editable recipient note from that value.
- `SparkWalletServiceImpl` passes it untrimmed to `PrepareLnurlPayRequest.comment`.
- Breez Spark source at `8bb38ec292a590907360c4e7f2a4134b8f09de9e`,
`common/src/lnurl/pay.rs::validate_user_input`, rejects a comment exceeding the
limit with the exact reported error before requesting the callback.
This identifies a concrete compatibility failure: the address description can
become an automatic over-limit comment without the sender typing anything.
The user confirmed that explicitly clearing the prefilled recipient note made
the payment work, and supplied the same description observed in live metadata.
This confirms the automatic-comment compatibility failure. The installed Primal
platform/version was not captured. Node logs alone cannot show sender-side
validation or requests to the external Minibits callback.
Durable upstream correction: Primal should keep receiver metadata separate from
the sender's comment and enforce the limit on actual user comments. Minibits can
also shorten its description or raise its advertised comment limit. Archy does
not serve this external LNURL metadata; do not rename an existing wallet address,
rotate its seed, or claim that a local dashboard edit fixes this sender behavior.
### Primal workaround confirmed by user
The user confirmed successful payment after removing the automatic description.
The permanent sender-side correction is to leave the recipient comment empty by
default and retain receiver metadata only as display text. In Primal Android,
remove the assignment of the LNURL description to the draft recipient note in
`WalletTextParserImpl.handleLnUrlText`; also validate explicitly entered comments
against the endpoint's limit. No upstream change has been submitted or deployed.
Existing Framework addresses and wallet identities remain unchanged.
### Can Archy shorten the current address description?
Inspected Minibits' public wallet client (`src/services/minibitsService.ts`,
`updateWalletProfile`) and `WalletProfileRecord`. The supported profile update
fields are name, lud16, and avatar; there is no exposed LNURL description or
comment-limit setting. Its public web repository also contains no implementation
of the LNURL metadata endpoint or description template.
For the existing `@minibits.cash` address, no supported client-side mechanism
to shorten this text was found. Do not send guessed profile-update fields or
rename the address to disguise the problem. A Minibits server change could use
`Pay to [ADDRESS]`, well below the current limit. Controlling this metadata in
Archy would instead require an Archy-hosted LNURL service/address and correct
invoice metadata binding; rewriting the QR label or only proxying edited metadata
is insufficient. No wallet/profile mutations were made during this investigation.
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "neode-ui",
"version": "1.8.17-alpha",
"version": "1.8.19-alpha",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "neode-ui",
"version": "1.8.17-alpha",
"version": "1.8.19-alpha",
"dependencies": {
"@scure/bip39": "^2.2.0",
"@types/dompurify": "^3.0.5",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "neode-ui",
"private": true,
"version": "1.8.17-alpha",
"version": "1.8.19-alpha",
"type": "module",
"scripts": {
"start": "./start-dev.sh",
+32 -40
View File
@@ -226,61 +226,54 @@ async function restoreFromPhrase() {
Your ecash has no backup yet
</div>
<div class="flex items-start justify-between gap-4">
<div class="flex flex-col gap-3">
<div class="min-w-0">
<h2 class="text-xl font-semibold text-white/96 mb-1">{{ setupOnly ? 'Set up your Cashu Lightning address' : 'Ecash backup phrase' }}</h2>
<p v-if="status?.active && status?.source === 'node-seed'" class="text-sm text-white/60">
Your ecash wallet has its own 24-word phrase, derived from this node's recovery
phrase — so the words you already wrote down cover your ecash too. Reveal it here
if you want to restore your ecash into another wallet (Minibits, Nutstash,
<span class="font-mono">cdk-cli</span>) without handing over the node's own seed.
<p v-if="status?.active && status?.source === 'node-seed'" class="text-sm leading-relaxed text-white/60">
Your node's recovery phrase also recovers this ecash phrase. Reveal its 24 words
to restore in a compatible Cashu wallet without sharing your node's phrase.
</p>
<p v-else-if="status?.active" class="text-sm text-white/60">
Your ecash wallet has its own 24-word phrase. Reveal it to write it down, or to
restore your ecash into another wallet (Minibits, Nutstash,
<span class="font-mono">cdk-cli</span>).
<p v-else-if="status?.active" class="text-sm leading-relaxed text-white/60">
Save your 24-word ecash phrase to restore this wallet here or in another
compatible Cashu wallet.
</p>
<p v-else class="text-sm text-white/60">
Ecash is a bearer instrument: the coins live in a file on this node, and right now
nothing can bring them back if that file is lost. Setting up a backup phrase fixes
that for every coin minted from then on.
<p v-else class="text-sm leading-relaxed text-white/60">
If this node's coin file is lost, your ecash is lost. Set up a phrase to recover
future coins; existing coins aren't covered.
<template v-if="status?.derivable_from_node_seed">
It's derived from this node's recovery phrase, so there's nothing new to write down.
Your node's recovery phrase will also recover this phrase.
</template>
<template v-else>
This node has no encrypted seed backup to derive from, so the phrase will be its
own — you'll need to write these words down and keep them.
This node has no saved seed, so write down and keep the new phrase separately.
</template>
</p>
<p v-if="status?.source === 'independent' || status?.source === 'imported'" class="mt-2 text-xs text-orange-300/90">
This wallet's phrase was <strong>not</strong> derived from the node's recovery
phrase{{ status?.source === 'imported' ? ' — it was imported' : '' }}, so restoring
the node will not bring the ecash back. Only these words will.
{{ status?.source === 'imported' ? 'This imported phrase' : 'This phrase' }} is separate
from your node's backup. <strong>Only these words recover this ecash wallet.</strong>
</p>
</div>
<button
type="button"
class="shrink-0 glass-button rounded-lg px-4 py-2 text-sm font-medium"
class="w-full glass-button rounded-lg px-4 py-2 text-sm font-medium"
:class="!status?.active ? 'bg-orange-500/20 border-orange-400/30' : ''"
@click="openReveal"
>{{ status?.active ? 'Reveal' : (setupOnly ? 'Set up address' : 'Set up backup') }}</button>
</div>
<div v-if="status?.active && !setupOnly" class="mt-4 pt-4 border-t border-white/10">
<div class="flex items-start justify-between gap-4">
<p class="text-sm text-white/60 min-w-0">
<div class="flex flex-col gap-3">
<p class="text-sm leading-relaxed text-white/60 min-w-0">
<span class="text-white/80 font-medium">Restore from this phrase.</span>
Asks your mint which coins it has signed for these words and puts back any that
are still unspent. Safe to run at any time — it never duplicates coins you already
hold.
Recover unspent coins from your mint. Safe to repeat; coins you already hold
won't be duplicated.
</p>
<button
type="button"
class="shrink-0 glass-button rounded-lg px-4 py-2 text-sm font-medium disabled:opacity-50"
class="w-full glass-button rounded-lg px-4 py-2 text-sm font-medium disabled:opacity-50"
:disabled="restoring"
@click="restoreFromPhrase"
>{{ restoring ? 'Scanning…' : 'Restore' }}</button>
@@ -290,15 +283,15 @@ async function restoreFromPhrase() {
</div>
<div v-if="!setupOnly" class="mt-4 pt-4 border-t border-white/10">
<div class="flex items-start justify-between gap-4">
<p class="text-sm text-white/60 min-w-0">
<div class="flex flex-col gap-3">
<p class="text-sm leading-relaxed text-white/60 min-w-0">
<span class="text-white/80 font-medium">Use a phrase from another wallet.</span>
Point this wallet at a phrase you already have — from Minibits, Nutstash or
<span class="font-mono">cdk-cli</span> — so its coins can be restored here.
Import a phrase from Minibits, Nutstash or <span class="font-mono">cdk-cli</span>
to restore its coins here.
</p>
<button
type="button"
class="shrink-0 glass-button rounded-lg px-4 py-2 text-sm font-medium"
class="w-full glass-button rounded-lg px-4 py-2 text-sm font-medium"
@click="openImport"
>Import</button>
</div>
@@ -324,7 +317,7 @@ async function restoreFromPhrase() {
</template>
<template v-else>
<p class="text-sm text-white/60 mb-4">
<p class="text-sm leading-relaxed text-white/60 mb-4">
Paste the 24-word phrase from the other wallet. The coins already in this wallet
stay spendable either way.
</p>
@@ -381,9 +374,8 @@ async function restoreFromPhrase() {
</h3>
<template v-if="revealedWords.length === 0">
<p class="text-sm text-white/60 mb-4">
Confirm your credentials to
{{ status?.active ? 'display the 24-word ecash phrase' : 'derive and display your ecash backup phrase' }}.
<p class="text-sm leading-relaxed text-white/60 mb-4">
Confirm your credentials to {{ status?.active ? 'reveal' : 'set up' }} your ecash phrase.
</p>
<form @submit.prevent="submitReveal" class="space-y-3">
<div>
@@ -412,12 +404,12 @@ async function restoreFromPhrase() {
<SeedRevealPanel :words="revealedWords" />
<p class="text-xs text-white/40 mt-3">
<template v-if="revealedSource === 'node-seed'">
Derived from this node's recovery phrase — restoring the node restores this
ecash wallet too. These words also restore it into any NUT-13 wallet.
Your node's recovery phrase recovers this ecash wallet too. Use these words
separately in a compatible Cashu (NUT-13) wallet.
</template>
<template v-else>
This phrase is independent of the node's recovery phrase. It is the
<strong>only</strong> way to restore this ecash wallet — write it down.
Write these words down. They are the <strong>only</strong> way to recover
this ecash wallet; your node's phrase won't recover it.
</template>
</p>
<div class="flex gap-2 pt-4">
@@ -362,6 +362,30 @@ init()
</button>
</div>
<div class="overflow-y-auto flex-1 min-h-0 space-y-6 pr-1">
<!-- v1.8.19-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">
<span class="text-xs font-mono px-2 py-0.5 rounded bg-orange-500/20 text-orange-300">v1.8.19-alpha</span>
<span class="text-xs text-white/40">September 28, 2026</span>
</div>
<div class="space-y-3 text-sm text-white/80 pl-3 border-l border-white/10">
<p>Fixed the embedded AIUI chat page painting a second background and dark scrim over Archy’s dashboard background.</p>
<p>Embedded AIUI now stays transparent so the dashboard background appears once.</p>
<p>AIUI background fixes are now included reliably in OTA updates and fresh installations.</p>
</div>
</div>
<!-- v1.8.18-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">
<span class="text-xs font-mono px-2 py-0.5 rounded bg-orange-500/20 text-orange-300">v1.8.18-alpha</span>
<span class="text-xs text-white/40">September 18, 2026</span>
</div>
<div class="space-y-3 text-sm text-white/80 pl-3 border-l border-white/10">
<p>Framework startup prioritizes Bitcoin and LND before unrelated containers, and unavailable LND balances remain unavailable instead of appearing as false zeroes.</p>
<p>Cashu Receive guides unseeded wallets through recovery-phrase setup, with shorter backup guidance and a single-column layout.</p>
<p>Added live Framework verification for automatic LND unlock, native balance preservation, Cashu address registration, and proof preservation.</p>
</div>
</div>
<!-- v1.8.17-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">
+17 -18
View File
@@ -1,30 +1,29 @@
{
"changelog": [
"Minibits claims that every mint reports as already spent leave the retry queue, clearing repeated failure notices. Network errors and mixed mint failures remain queued for another attempt.",
"Minibits polls its primary relay first and connects to public fallback relays only when the primary is unreachable, reducing unnecessary connections.",
"Large payment backlogs are fetched from newest to oldest with a saved cursor, so polling can resume after interruptions or page limits. Payments sharing the same timestamp remain reachable.",
"Added regression coverage for spent-claim classification, wrapped and mixed mint errors, same-second payments, and interrupted or multi-poll backlogs."
"Framework startup prioritizes Bitcoin and LND before unrelated containers, and unavailable LND balances remain unavailable instead of appearing as false zeroes.",
"Cashu Receive guides unseeded wallets through recovery-phrase setup, with shorter backup guidance and a single-column layout.",
"Added live Framework verification for automatic LND unlock, native balance preservation, Cashu address registration, and proof preservation."
],
"components": [
{
"current_version": "1.8.17-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.17-alpha/archipelago",
"current_version": "1.8.18-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.18-alpha/archipelago",
"name": "archipelago",
"new_version": "1.8.17-alpha",
"sha256": "32a7b009eb58f8c9f256e6597711a77ded11e15d5865a3fe16901603264e1f70",
"size_bytes": 64953344
"new_version": "1.8.18-alpha",
"sha256": "c76415c295dd42159e45e74d93f7c2f6fa39b0351946a8303f8cfba1dd3a6087",
"size_bytes": 64497240
},
{
"current_version": "1.8.17-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.17-alpha/archipelago-frontend-1.8.17-alpha.tar.gz",
"name": "archipelago-frontend-1.8.17-alpha.tar.gz",
"new_version": "1.8.17-alpha",
"sha256": "faf692e9a0e16268357bcac2bf86b62950ae49663e3c95982e54a132bb761980",
"size_bytes": 98801608
"current_version": "1.8.18-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.18-alpha/archipelago-frontend-1.8.18-alpha.tar.gz",
"name": "archipelago-frontend-1.8.18-alpha.tar.gz",
"new_version": "1.8.18-alpha",
"sha256": "57da88b1a8f3d2841867994a95e9e4e728c19616abcde8e3d3f151c6d94ed501",
"size_bytes": 98801020
}
],
"release_date": "2026-09-15",
"signature": "c8196fe278a5747b3c3ba3bf70998874f1e3e6eedbdab33b9e33c3339a3769ab4431f41d99924ec4cdd15a5ffed299a5af786c7ab5e9d084cdc11beabbee9103",
"release_date": "2026-09-20",
"signature": "84e0e1a20750f0d4ff27ba539c2e9424a5b02c19a5689f73cdf82813212acae19e0af244a62e66ac37a35d97d80deb2833819d809b91a7822f2bfd785d3fe30d",
"signed_by": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
"version": "1.8.17-alpha"
"version": "1.8.18-alpha"
}
+17 -18
View File
@@ -1,30 +1,29 @@
{
"changelog": [
"Minibits claims that every mint reports as already spent leave the retry queue, clearing repeated failure notices. Network errors and mixed mint failures remain queued for another attempt.",
"Minibits polls its primary relay first and connects to public fallback relays only when the primary is unreachable, reducing unnecessary connections.",
"Large payment backlogs are fetched from newest to oldest with a saved cursor, so polling can resume after interruptions or page limits. Payments sharing the same timestamp remain reachable.",
"Added regression coverage for spent-claim classification, wrapped and mixed mint errors, same-second payments, and interrupted or multi-poll backlogs."
"Framework startup prioritizes Bitcoin and LND before unrelated containers, and unavailable LND balances remain unavailable instead of appearing as false zeroes.",
"Cashu Receive guides unseeded wallets through recovery-phrase setup, with shorter backup guidance and a single-column layout.",
"Added live Framework verification for automatic LND unlock, native balance preservation, Cashu address registration, and proof preservation."
],
"components": [
{
"current_version": "1.8.17-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.17-alpha/archipelago",
"current_version": "1.8.18-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.18-alpha/archipelago",
"name": "archipelago",
"new_version": "1.8.17-alpha",
"sha256": "32a7b009eb58f8c9f256e6597711a77ded11e15d5865a3fe16901603264e1f70",
"size_bytes": 64953344
"new_version": "1.8.18-alpha",
"sha256": "c76415c295dd42159e45e74d93f7c2f6fa39b0351946a8303f8cfba1dd3a6087",
"size_bytes": 64497240
},
{
"current_version": "1.8.17-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.17-alpha/archipelago-frontend-1.8.17-alpha.tar.gz",
"name": "archipelago-frontend-1.8.17-alpha.tar.gz",
"new_version": "1.8.17-alpha",
"sha256": "faf692e9a0e16268357bcac2bf86b62950ae49663e3c95982e54a132bb761980",
"size_bytes": 98801608
"current_version": "1.8.18-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.18-alpha/archipelago-frontend-1.8.18-alpha.tar.gz",
"name": "archipelago-frontend-1.8.18-alpha.tar.gz",
"new_version": "1.8.18-alpha",
"sha256": "57da88b1a8f3d2841867994a95e9e4e728c19616abcde8e3d3f151c6d94ed501",
"size_bytes": 98801020
}
],
"release_date": "2026-09-15",
"signature": "c8196fe278a5747b3c3ba3bf70998874f1e3e6eedbdab33b9e33c3339a3769ab4431f41d99924ec4cdd15a5ffed299a5af786c7ab5e9d084cdc11beabbee9103",
"release_date": "2026-09-20",
"signature": "84e0e1a20750f0d4ff27ba539c2e9424a5b02c19a5689f73cdf82813212acae19e0af244a62e66ac37a35d97d80deb2833819d809b91a7822f2bfd785d3fe30d",
"signed_by": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
"version": "1.8.17-alpha"
"version": "1.8.18-alpha"
}
@@ -0,0 +1,29 @@
{
"changelog": [
"Fixed the embedded AIUI chat page painting a second background and dark scrim over Archy’s dashboard background.",
"Embedded AIUI now stays transparent so the dashboard background appears once.",
"AIUI background fixes are now included reliably in OTA updates and fresh installations."
],
"components": [
{
"current_version": "1.8.19-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.19-alpha/archipelago",
"name": "archipelago",
"new_version": "1.8.19-alpha",
"sha256": "bb500d02567ad16179179d43138cc6fdafee680835262026eeaa7d1bc8cdd307",
"size_bytes": 64495784
},
{
"current_version": "1.8.19-alpha",
"download_url": "https://source.archipelago-foundation.org/lfg2025/archy/releases/download/v1.8.19-alpha/archipelago-frontend-1.8.19-alpha.tar.gz",
"name": "archipelago-frontend-1.8.19-alpha.tar.gz",
"new_version": "1.8.19-alpha",
"sha256": "fbbaa237e2ea4e9e576dda9b15fdcf3c59c40bc55bfee4ebbea303b0172fc49b",
"size_bytes": 97142031
}
],
"release_date": "2026-09-28",
"signature": "4da9bf766d94c2de6641619a36663106791c7a1d342b729c666662cdde1feabdf11c51994c1cbbe2a0e2b270c316d77763435e976ce22730855b3822bc9d390a",
"signed_by": "did:key:z6Mkfu5LT8d4DjETtrkATvHh9Dvcbnr7zBCUwfau8Sw7DLWT",
"version": "1.8.19-alpha"
}
+10 -8
View File
@@ -78,15 +78,17 @@ if [ -z "$FRONTEND_ARCHIVE" ]; then
STAGING_DIR=$(mktemp -d -t archipelago-frontend.XXXXXX)
echo "Staging frontend archive in $STAGING_DIR..."
cp -r "$FRONTEND_DIST/." "$STAGING_DIR/"
# Bake AIUI in so fresh installs pick it up. OTA already
# carries-forward the existing aiui/ if the tarball lacks one
# (update.rs:922), but including it here makes the tarball
# the single source of truth instead of relying on a side-
# effect of the in-place swap.
if [ -d "$PROJECT_ROOT/demo/aiui" ] && [ -f "$PROJECT_ROOT/demo/aiui/index.html" ]; then
echo " Including AIUI from demo/aiui/"
cp -r "$PROJECT_ROOT/demo/aiui" "$STAGING_DIR/aiui"
# create-release.sh folds the freshly built AIUI into FRONTEND_DIST.
# Never overlay it with the older demo bundle (or nest aiui/aiui/).
if [ ! -f "$STAGING_DIR/aiui/index.html" ] || \
[ ! -f "$STAGING_DIR/aiui/BUILD-INFO" ]; then
echo "Error: fresh AIUI payload missing from frontend dist" >&2
exit 1
fi
grep -Fxq "commit=$(git -C "$PROJECT_ROOT" rev-parse HEAD)" "$STAGING_DIR/aiui/BUILD-INFO" || {
echo "Error: AIUI payload was not built from the current commit" >&2
exit 1
}
# OTA bridge for nodes running older updaters: they only know how to
# apply the backend binary and frontend archive. Carry host runtime
# assets inside the frontend tarball; the new backend promotes them
+5 -9
View File
@@ -169,15 +169,11 @@ else
fi
cd "$PROJECT_ROOT"
# npm run build wipes web/dist — fold AIUI straight back in. The OTA tarball
# bakes it from demo/aiui independently, but build-iso-release.sh's
# verify-artifacts guard checks web/dist/neode-ui/aiui and failed on two
# consecutive releases (.127, .129) because this fold-in was manual.
if [ -d "$PROJECT_ROOT/demo/aiui" ] && [ -f "$PROJECT_ROOT/demo/aiui/index.html" ]; then
rm -rf "$PROJECT_ROOT/web/dist/neode-ui/aiui"
cp -r "$PROJECT_ROOT/demo/aiui" "$PROJECT_ROOT/web/dist/neode-ui/aiui"
echo " AIUI folded into web/dist from demo/aiui"
fi
# Build AIUI from the same source as the release. The checked-in demo bundle
# can predate source fixes and must never overwrite the production payload.
bash "$SCRIPT_DIR/build-aiui.sh"
rm -rf "$PROJECT_ROOT/web/dist/neode-ui/aiui"
cp -r "$PROJECT_ROOT/aiui/packages/app/dist" "$PROJECT_ROOT/web/dist/neode-ui/aiui"
# npm run build can silently no-op (vue-tsc EACCES burned us before) — a stale
# dist would ship with a perfectly valid sha256. Require the freshly built