From 4cc808c73e8fbc9d8ddc79c75e537a802f47757f Mon Sep 17 00:00:00 2001 From: archipelago Date: Mon, 22 Jun 2026 12:39:33 -0400 Subject: [PATCH] fix(demo): /app proxy (fixes 404s), mempool iframe, LND UI, icons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - nginx-demo.conf + vite proxy now route every /app// to the mock backend, so the per-app mock UIs and the generic "Not available in the demo" notice render (previously only /app/filebrowser was proxied → most apps 404'd). - Mempool and IndeeHub now load in the in-app iframe (not a new tab). - Add an LND Lightning mock UI (channels, balances, routing) with dummy data; lnd/thunderhub are demoable. Notice page reworded to "Not available in the demo". - Fix missing icons: Bitcoin Core → bitcoin-core.png, Mempool → mempool.webp. - Pre-install only Bitcoin Core (drop duplicate Bitcoin Knots; still installable). Co-Authored-By: Claude Opus 4.8 (1M context) --- neode-ui/docker/nginx-demo.conf | 10 ++++++ neode-ui/mock-backend.js | 41 ++++++++++++++++-------- neode-ui/src/composables/useDemoIntro.ts | 15 ++++++--- neode-ui/vite.config.ts | 5 +++ 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/neode-ui/docker/nginx-demo.conf b/neode-ui/docker/nginx-demo.conf index a80acba5..f8ec0819 100644 --- a/neode-ui/docker/nginx-demo.conf +++ b/neode-ui/docker/nginx-demo.conf @@ -72,6 +72,16 @@ http { proxy_request_buffering off; } + # Proxy every other app UI (/app//) to the mock backend, which serves + # the per-app mock UIs (bitcoin-ui, electrumx, lnd, fedimint) and the + # generic "Not available in the demo" notice for the rest. + location /app/ { + proxy_pass http://neode-backend:5959; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + } + # Serve AIUI SPA location /aiui/ { alias /usr/share/nginx/html/aiui/; diff --git a/neode-ui/mock-backend.js b/neode-ui/mock-backend.js index 92d8f723..2a4a58a7 100755 --- a/neode-ui/mock-backend.js +++ b/neode-ui/mock-backend.js @@ -757,18 +757,10 @@ function staticApp({ id, title, version, shortDesc, longDesc, license, state, la } } -// Static dev apps (always shown in My Apps when using mock backend) +// Static dev apps (always shown in My Apps when using mock backend). +// Only one Bitcoin implementation is pre-installed (Bitcoin Core); Bitcoin Knots +// remains installable from the marketplace. const staticDevApps = { - 'bitcoin-knots': staticApp({ - id: 'bitcoin-knots', - title: 'Bitcoin Knots', - version: '27.1', - shortDesc: 'Full Bitcoin node', - longDesc: 'Validate and relay Bitcoin blocks and transactions with the Archipelago custom node UI.', - state: 'running', - lanPort: 8334, - icon: '/assets/img/app-icons/bitcoin-knots.webp', - }), bitcoin: staticApp({ id: 'bitcoin', title: 'Bitcoin Core', @@ -777,6 +769,7 @@ const staticDevApps = { longDesc: 'Validate every transaction and block. Full consensus enforcement — the bedrock of sovereignty.', state: 'running', lanPort: 8332, + icon: '/assets/img/app-icons/bitcoin-core.png', }), lnd: staticApp({ id: 'lnd', @@ -805,6 +798,7 @@ const staticDevApps = { license: 'AGPL-3.0', state: 'running', lanPort: 4080, + icon: '/assets/img/app-icons/mempool.webp', }), lorabell: staticApp({ id: 'lorabell', @@ -1073,6 +1067,27 @@ app.get(['/app/electrumx/', '/app/electrs/', '/app/archy-electrs-ui/'], (_req, r `)) }) +app.get(['/app/lnd/', '/app/lnd-ui/', '/app/archy-lnd-ui/', '/app/thunderhub/'], (_req, res) => { + res.type('html').send(demoAppShell('LND — Lightning', '#f7931a', ` +

LND

Lightning Network Daemon · signet
+
+
Node
● Synced to chain
+
Channel balance
8,250,000 sat
+
On-chain balance
2,350,000 sat
+
Active channels
4
+
Peers
11
+
Routing (30d)
1,284 sat
+
+
Channels
+ + + + + +
PeerCapacityLocal / RemoteState
ACINQ5,000,0002,450,000 / 2,550,000active
Wallet of Satoshi2,000,0001,200,000 / 800,000active
Voltage10,000,0004,500,000 / 5,500,000active
Kraken3,000,0001,800,000 / 1,200,000active
+
`)) +}) + app.get(['/app/fedimint/', '/app/fedimintd/'], (_req, res) => { res.type('html').send(demoAppShell('Fedimint — Guardian', '#a78bfa', `

Fedimint Guardian

Archipelago Federation · 4-of-5 consensus
@@ -4059,8 +4074,8 @@ p{color:#8b93a7;font-size:14px;line-height:1.5}

${title}

-

This app isn't interactive in the demo, but it runs fully on a real Archipelago node.

-
Demo preview
+

Not available in the demo.
This app runs fully on a real Archipelago node.

+
Demo
`) }) diff --git a/neode-ui/src/composables/useDemoIntro.ts b/neode-ui/src/composables/useDemoIntro.ts index c3942726..26c65f8b 100644 --- a/neode-ui/src/composables/useDemoIntro.ts +++ b/neode-ui/src/composables/useDemoIntro.ts @@ -53,7 +53,7 @@ export function clearDemoIntroSeen(): void { // external site). Everything else shows "No demo" on a disabled install button // and is not launchable. const DEMO_EXTERNAL_URLS: Record = { - // Real, public sites that we open instead of mocking. + // Real, public sites loaded in the in-app iframe. indeedhub: 'https://indee.tx1138.com/', mempool: 'https://mempool.space/testnet', 'mempool-web': 'https://mempool.space/testnet', @@ -68,14 +68,21 @@ const DEMO_MOCK_UI: Record = { electrs: '/app/electrumx/', electrumx: '/app/electrumx/', 'archy-electrs-ui': '/app/electrumx/', + lnd: '/app/lnd/', + 'lnd-ui': '/app/lnd/', + 'archy-lnd-ui': '/app/lnd/', + thunderhub: '/app/lnd/', fedimint: '/app/fedimint/', fedimintd: '/app/fedimint/', filebrowser: '/app/filebrowser/', } -/** Apps that open in a new tab (external real sites) rather than an iframe. */ -export function isDemoExternal(appId: string): boolean { - return appId === 'mempool' || appId === 'mempool-web' +/** + * Whether a demo app opens in a new tab. Nothing does now — both real external + * sites (mempool.space, indee.tx1138.com) load in the in-app iframe. + */ +export function isDemoExternal(_appId: string): boolean { + return false } /** Can this app be launched/installed in the demo? */ diff --git a/neode-ui/vite.config.ts b/neode-ui/vite.config.ts index 2b3ed52b..d601ec53 100644 --- a/neode-ui/vite.config.ts +++ b/neode-ui/vite.config.ts @@ -151,6 +151,11 @@ export default defineConfig({ changeOrigin: true, secure: false, }, + // Demo mock app UIs (electrumx, lnd, fedimint) + generic notice page. + '/app/electrumx': { target: process.env.BACKEND_URL || 'http://localhost:5959', changeOrigin: true, secure: false }, + '/app/electrs': { target: process.env.BACKEND_URL || 'http://localhost:5959', changeOrigin: true, secure: false }, + '/app/lnd': { target: process.env.BACKEND_URL || 'http://localhost:5959', changeOrigin: true, secure: false }, + '/app/fedimint': { target: process.env.BACKEND_URL || 'http://localhost:5959', changeOrigin: true, secure: false }, // Serve the node's deployed AIUI same-origin like production (set VITE_AIUI_URL=/aiui/) '/aiui': { target: process.env.AIUI_PROXY_TARGET || 'http://127.0.0.1:80',