feat(demo): iframe asset-rewrite proxy, AIUI mockArchy, QR 2s, dummy mints

- IndeeHub + Mempool: nginx reverse-proxy + strip X-Frame-Options/CSP + sub_filter
  rewrite of absolute asset paths so the frame-busting SPAs load in the iframe
  (mempool.space remains best-effort — third-party CSP/ws may still limit it).
- AIUI iframe gets ?mockArchy in demo → its built-in mock node data loads.
- Pay-with-mobile QR: invoice settles after ~2s (backend gate keyed by
  payment_hash) and the poll tightened to 1s, so the QR is visible before auto-pay.
- Wallet settings: dummy Cashu mints (4) + Fedimint federations (2, 222,500 sats),
  interactive per session (streaming.list/configure-mints, wallet.fedimint-list/
  join/balance).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
archipelago
2026-06-22 16:34:12 -04:00
co-authored by Claude Opus 4.8
parent 1b7335f4ac
commit 445f08a5c1
5 changed files with 103 additions and 14 deletions
+7 -7
View File
@@ -52,15 +52,15 @@ export function clearDemoIntroSeen(): void {
// Only these apps actually do something in the demo (a mock UI or a real
// 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 loaded directly in the in-app iframe.
indeedhub: 'https://indee.tx1138.com/',
mempool: 'https://mempool.space/testnet',
'mempool-web': 'https://mempool.space/testnet',
}
const DEMO_EXTERNAL_URLS: Record<string, string> = {}
// Apps with a same-origin mock UI served by the demo backend.
// Apps loaded in the in-app iframe via a same-origin path. IndeeHub and Mempool
// are reverse-proxied by nginx (X-Frame-Options/CSP stripped + asset paths
// rewritten) so the frame-busting real sites can be embedded.
const DEMO_MOCK_UI: Record<string, string> = {
indeedhub: '/app/indeedhub/',
mempool: '/app/mempool/',
'mempool-web': '/app/mempool/',
'bitcoin-knots': '/app/bitcoin-knots/',
'bitcoin-core': '/app/bitcoin-core/',
bitcoin: '/app/bitcoin-core/',
+6 -2
View File
@@ -62,6 +62,7 @@ import { ref, computed, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
import { ContextBroker } from '@/services/contextBroker'
import { IS_DEMO } from '@/composables/useDemoIntro'
const { t } = useI18n()
@@ -71,9 +72,12 @@ const aiuiConnected = ref(false)
let broker: ContextBroker | null = null
const aiuiUrl = computed(() => {
// Demo: ?mockArchy makes AIUI use its built-in mock node data (apps, system,
// network, wallet, bitcoin, files) and &seed pre-loads the example chats.
const demo = IS_DEMO ? '&mockArchy=1&seed=1' : ''
const envUrl = import.meta.env.VITE_AIUI_URL
if (envUrl) return `${envUrl}?embedded=true&hideClose=true`
if (import.meta.env.PROD) return '/aiui/?embedded=true&hideClose=true'
if (envUrl) return `${envUrl}?embedded=true&hideClose=true${demo}`
if (import.meta.env.PROD || IS_DEMO) return `/aiui/?embedded=true&hideClose=true${demo}`
return ''
})
+1 -1
View File
@@ -1304,7 +1304,7 @@ async function payWithLightning() {
function scheduleInvoicePoll() {
if (invoicePollTimer) clearTimeout(invoicePollTimer)
invoicePollTimer = setTimeout(pollInvoice, 3000)
invoicePollTimer = setTimeout(pollInvoice, 1000)
}
async function pollInvoice() {