fix(demo): iframe mempool+indeehub directly, serve real UIs statically, AIUI canned

- Mempool and IndeeHub load their real site directly in the iframe (reverted the
  proxy/new-tab — per request "use https://indee.tx1138.com/").
- Real app UIs now served as whole static dirs under /app/<id>/ (express.static)
  so their bundled assets (qrcode.js, css, bg images) resolve; /app/<id>/assets/*
  redirect to the frontend's shared assets. Fixes the console 404 cascade.
- Bitcoin Core/Knots: register rpc/v1 + bitcoin-rpc on their paths (relay-status
  no longer 404s); per-impl bitcoin-status preserved.
- AIUI chat returns a fixed line in demo ("Not available in demo, check out the
  previous chats to experience AIUI") instead of calling Claude — no key spend.
- Add /api/app-catalog (serves the baked catalog) to stop that 404.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-06-22 14:45:04 -04:00
co-authored by Claude Opus 4.8
parent cf5f6d021a
commit b99c4a604f
4 changed files with 57 additions and 79 deletions
+7 -8
View File
@@ -53,15 +53,14 @@ 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<string, string> = {
// Real, public sites opened in a NEW TAB (they block iframing).
// Real, public sites loaded directly in the in-app iframe.
indeedhub: 'https://indee.tx1138.com/',
mempool: 'https://mempool.space/testnet',
'mempool-web': 'https://mempool.space/testnet',
}
// Apps with a same-origin URL loaded in the in-app iframe — either a mock UI
// served by the demo backend, or a header-stripping reverse-proxy (IndeeHub).
// Apps with a same-origin mock UI served by the demo backend.
const DEMO_MOCK_UI: Record<string, string> = {
indeedhub: '/app/indeedhub/',
'bitcoin-knots': '/app/bitcoin-knots/',
'bitcoin-core': '/app/bitcoin-core/',
bitcoin: '/app/bitcoin-core/',
@@ -79,11 +78,11 @@ const DEMO_MOCK_UI: Record<string, string> = {
}
/**
* Whether a demo app opens in a new tab. Mempool.space sets X-Frame-Options and
* cannot be iframed, so it opens in a new tab; IndeeHub still loads in-iframe.
* Whether a demo app opens in a new tab. Nothing does — IndeeHub and Mempool
* both load their real site directly in the in-app iframe.
*/
export function isDemoExternal(appId: string): boolean {
return appId === 'mempool' || appId === 'mempool-web'
export function isDemoExternal(_appId: string): boolean {
return false
}
/** Can this app be launched/installed in the demo? */