refactor(machine): remove dead Lightning.Pub nprofile UI (post-3d cutover)

The LP backend was deleted on dev, so VITE_LIGHTNING_PUB_PUBKEY /
config.lightningPubPubkey are never set — the "add this ATM's node to your
wallet" nprofile QR (IdleView dev button + overlay, SupportView ShockWallet
card + deep-link) rendered empty, and the LP fields in RuntimeConfig
(lightningPubPubkey/lightningPubApiUrl/extensionApiUrl) were never populated.
Remove them. The concept has no clean LNbits analog (the ATM is a cash↔LN
gateway, not a node customers peer with) — tracked as a fresh feature request
on lnbits. ShockWallet stays listed as a downloadable wallet (plain URL).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Padreug 2026-07-02 18:33:31 +02:00 • committed by padreug
commit 7abc2e3305
4 changed files with 3 additions and 128 deletions

View file

@ -6,10 +6,6 @@ export interface RuntimeConfig {
relayUrl: string
/** LNbits nostr-transport server pubkey (hex, 64 chars). */
lnbitsServerPubkey: string
/** Legacy LP fields — retained until 3d removes the LP backend. Optional. */
lightningPubPubkey?: string
lightningPubApiUrl?: string
extensionApiUrl?: string
appId: string
machineModel: string
fiatCode: string

View file

@ -1,7 +1,6 @@
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { nip19 } from 'nostr-tools'
import { useAtmStore } from '@/stores/atm'
import { useBranding } from '@/composables/useBranding'
import { initialContext } from '@bitSpire/state-machine'
@ -15,18 +14,8 @@ const atmStore = useAtmStore()
const { logoUrl, title: brandTitle } = useBranding()
const lndconnectUrl = import.meta.env.VITE_LNDCONNECT_URL || ''
const showZeusQR = ref(false)
const showLpQR = ref(false)
const copied = ref(false)
// Build nprofile for Lightning.Pub (pubkey + relay hint)
const lpNprofile = computed(() => {
const pubkey = import.meta.env.VITE_LIGHTNING_PUB_PUBKEY
if (!pubkey) return ''
const relayUrl = import.meta.env.VITE_RELAY_URL
const relays = relayUrl ? [relayUrl.replace('ws://', 'wss://')] : []
return nip19.nprofileEncode({ pubkey, relays })
})
async function copyToClipboard(value: string) {
try {
await navigator.clipboard.writeText(value)
@ -157,15 +146,6 @@ function handleCashOut() {
>
Zeus QR (lnd-alice)
</Button>
<Button
v-if="lpNprofile"
variant="ghost"
size="sm"
class="text-xs text-muted-foreground"
@click="showLpQR = true"
>
Lightning.Pub nprofile
</Button>
</div>
<!-- Zeus QR fullscreen overlay -->
@ -193,27 +173,6 @@ function handleCashOut() {
</div>
</div>
<!-- Lightning.Pub nprofile QR fullscreen overlay -->
<div
v-if="showLpQR"
class="fixed inset-0 z-[100] flex flex-col items-center justify-center gap-4 bg-black/90 p-4"
@click.self="showLpQR = false"
>
<p class="text-sm text-white/70">Lightning.Pub nprofile</p>
<div class="rounded-2xl">
<QRCode :value="lpNprofile" :size="400" />
</div>
<code class="max-w-[90vw] truncate text-xs text-white/50">{{ lpNprofile }}</code>
<div class="flex items-center gap-2">
<Button variant="outline" size="sm" class="text-white" @click="copyToClipboard(lpNprofile)">
{{ copied ? 'Copied!' : 'Copy' }}
</Button>
<Button variant="outline" size="sm" class="text-white" @click="showLpQR = false">
Close
</Button>
</div>
</div>
<!-- Help button (top-left) -->
<Button
variant="outline"

View file

@ -1,7 +1,6 @@
<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import { nip19 } from 'nostr-tools'
import { marked } from 'marked'
import { Button } from '@/components/ui/button'
import { Card, CardContent } from '@/components/ui/card'
@ -23,35 +22,6 @@ import { QrCode, ExternalLink } from 'lucide-vue-next'
const router = useRouter()
const isElectron = typeof window !== 'undefined' && window.electronAPI !== undefined
// Lightning.Pub config loaded at runtime from Electron main process
const lpPubkey = ref('')
const relayUrl = ref('')
onMounted(async () => {
if (isElectron && window.electronAPI) {
const config = await window.electronAPI.getConfig()
lpPubkey.value = config.lightningPubPubkey || ''
relayUrl.value = config.relayUrl || ''
} else {
// Dev fallback: use Vite env vars
lpPubkey.value = import.meta.env.VITE_LIGHTNING_PUB_PUBKEY || ''
relayUrl.value = import.meta.env.VITE_RELAY_URL || ''
}
})
// Build nprofile for Lightning.Pub (pubkey + relay hint)
const lpNprofile = computed(() => {
if (!lpPubkey.value) return ''
const relays = relayUrl.value ? [relayUrl.value.replace('ws://', 'wss://')] : []
return nip19.nprofileEncode({ pubkey: lpPubkey.value, relays })
})
// Deep link URL: opens ShockWallet with this ATM's Lightning.Pub pre-filled
const shockwalletDeepLink = computed(() => {
if (!lpNprofile.value) return ''
return `https://wallet.aiolabs.dev/sources/add?nprofile=${encodeURIComponent(lpNprofile.value)}`
})
interface SupportPage {
id: string
title: string
@ -74,17 +44,11 @@ const defaultPages: SupportPage[] = [
| Blink | No | Partial | Yes | Yes | https://www.blink.sv |
| Zeus | Yes | Yes | Yes | Yes | https://zeusln.com |
| Breez | Yes | Yes | Yes | Yes | https://breez.technology |
| ShockWallet | No | Yes | Yes | Yes | [shockwallet-deep-link] |
| ShockWallet | No | Yes | Yes | Yes | https://shockwallet.app |
Tap a QR icon to scan and download a wallet.
**Non-custodial** means you hold your own keys and have full control of your Bitcoin. **KYC-free** means no identity verification is required. Partial (~) means limits apply without verification.
## Using ShockWallet with this ATM
Scan the QR code below to add this ATM's Lightning node to your ShockWallet. This lets you send and receive sats directly through the ATM's payment system.
[lp-nprofile]`,
**Non-custodial** means you hold your own keys and have full control of your Bitcoin. **KYC-free** means no identity verification is required. Partial (~) means limits apply without verification.`,
},
{
id: 'faq',
@ -153,7 +117,6 @@ type Segment =
| { type: 'qr'; content: string }
| { type: 'table'; table: ParsedTable }
| { type: 'qr-placeholder' }
| { type: 'lp-nprofile' }
/** Parse markdown table into structured data */
function parseMarkdownTable(tableLines: string[]): ParsedTable | null {
@ -176,17 +139,8 @@ function parseMarkdownTable(tableLines: string[]): ParsedTable | null {
return { headers, rows }
}
/** Resolve dynamic placeholders in markdown content */
function resolvePlaceholders(md: string): string {
return md.replace(
'[shockwallet-deep-link]',
shockwalletDeepLink.value || 'https://wallet.aiolabs.dev'
)
}
/** Parse content into segments: html, qr, or table */
function parseContent(md: string): Segment[] {
md = resolvePlaceholders(md)
const segments: Segment[] = []
const lines = md.split('\n')
let htmlBlock = ''
@ -235,9 +189,6 @@ function parseContent(md: string): Segment[] {
} else if (trimmed === '[operator-qr-placeholder]') {
flushHtml()
segments.push({ type: 'qr-placeholder' })
} else if (trimmed === '[lp-nprofile]') {
flushHtml()
segments.push({ type: 'lp-nprofile' })
} else {
htmlBlock += line + '\n'
}
@ -375,33 +326,6 @@ onUnmounted(() => {
</CardContent>
</Card>
<!-- Lightning.Pub nprofile QR (scannable by ShockWallet) -->
<Card v-else-if="seg.type === 'lp-nprofile'" class="my-6 mx-auto max-w-xs">
<CardContent class="flex flex-col items-center gap-3 p-6">
<template v-if="lpNprofile">
<div class="rounded-xl bg-white p-3">
<QrcodeVue
:value="lpNprofile"
:size="180"
level="L"
render-as="svg"
background="#ffffff"
foreground="#000000"
/>
</div>
<span class="text-xs text-muted-foreground text-center px-2">
Scan with ShockWallet to connect
</span>
</template>
<template v-else>
<QrCode class="h-16 w-16 text-muted-foreground/30" />
<span class="text-sm text-muted-foreground/50 text-center">
Lightning.Pub not configured
</span>
</template>
</CardContent>
</Card>
<!-- Table with inline QR codes -->
<div v-else-if="seg.type === 'table'" class="mb-8">
<Table class="text-sm sm:text-base lg:text-xl w-full">