148 lines
5.2 KiB
Vue
148 lines
5.2 KiB
Vue
<script setup lang="ts">
|
|||
|
|
import { ref, watch } from 'vue'
|
||
|
|
import { useWallet } from '../composables/useWallet'
|
||
|
|
|
||
|
|
const { isWalletConnected, walletMethod, paymentStatus, disconnectWallet, connectNWC, connectLightningAddress } = useWallet()
|
||
|
|
|
||
|
|
const isExpanded = ref(false)
|
||
|
|
const nwcInput = ref('')
|
||
|
|
const lnAddressInput = ref('')
|
||
|
|
const connectError = ref('')
|
||
|
|
const isConnecting = ref(false)
|
||
|
|
|
||
|
|
async function handleConnectNWC() {
|
||
|
|
if (!nwcInput.value.trim()) return
|
||
|
|
isConnecting.value = true
|
||
|
|
connectError.value = ''
|
||
|
|
try {
|
||
|
|
await connectNWC(nwcInput.value.trim())
|
||
|
|
isExpanded.value = false
|
||
|
|
nwcInput.value = ''
|
||
|
|
} catch (err) {
|
||
|
|
connectError.value = err instanceof Error ? err.message : 'Connection failed'
|
||
|
|
}
|
||
|
|
isConnecting.value = false
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleConnectLnAddress() {
|
||
|
|
if (!lnAddressInput.value.trim()) return
|
||
|
|
isConnecting.value = true
|
||
|
|
connectError.value = ''
|
||
|
|
try {
|
||
|
|
await connectLightningAddress(lnAddressInput.value.trim())
|
||
|
|
isExpanded.value = false
|
||
|
|
lnAddressInput.value = ''
|
||
|
|
} catch (err) {
|
||
|
|
connectError.value = err instanceof Error ? err.message : 'Connection failed'
|
||
|
|
}
|
||
|
|
isConnecting.value = false
|
||
|
|
}
|
||
|
|
|
||
|
|
async function handleDisconnect() {
|
||
|
|
await disconnectWallet()
|
||
|
|
}
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<!-- Paying state -->
|
||
|
|
<div v-if="paymentStatus === 'paying' || paymentStatus === 'invoiced'" class="text-center py-3">
|
||
|
|
<div class="flex items-center justify-center gap-2">
|
||
|
|
<span class="w-4 h-4 border-2 border-neon-cyan/30 border-t-neon-cyan rounded-full animate-spin" />
|
||
|
|
<span class="font-display font-bold text-xs tracking-wider text-neon-cyan">PAYING 21 SATS...</span>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Confirmed flash -->
|
||
|
|
<div v-else-if="paymentStatus === 'confirmed'" class="text-center py-3">
|
||
|
|
<span class="font-display font-bold text-xs tracking-wider text-green-400 animate-pulse">LOCKED IN</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Connected state -->
|
||
|
|
<div v-else-if="isWalletConnected" class="flex items-center justify-center gap-2 py-2">
|
||
|
|
<span class="text-neon-cyan">⚡</span>
|
||
|
|
<span class="font-display font-bold text-[10px] tracking-wider text-neon-cyan">WALLET READY</span>
|
||
|
|
<button
|
||
|
|
class="font-mono text-[9px] text-text-muted hover:text-ko transition-colors ml-2 underline"
|
||
|
|
@click="handleDisconnect"
|
||
|
|
>
|
||
|
|
disconnect
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Not connected -->
|
||
|
|
<div v-else class="space-y-2">
|
||
|
|
<button
|
||
|
|
v-if="!isExpanded"
|
||
|
|
class="w-full py-2 border border-neon-cyan/30 text-neon-cyan
|
||
|
|
font-display font-bold text-[10px] tracking-wider
|
||
|
|
hover:bg-neon-cyan/10 transition-all"
|
||
|
|
@click="isExpanded = true"
|
||
|
|
>
|
||
|
|
⚡ CONNECT WALLET
|
||
|
|
</button>
|
||
|
|
|
||
|
|
<div v-else class="border border-border p-3 space-y-3">
|
||
|
|
<p class="font-display font-bold text-[10px] tracking-wider text-text-secondary text-center">CONNECT WALLET</p>
|
||
|
|
|
||
|
|
<!-- NWC input -->
|
||
|
|
<div>
|
||
|
|
<label class="font-mono text-[9px] text-text-muted block mb-1">NWC CONNECTION STRING</label>
|
||
|
|
<input
|
||
|
|
v-model="nwcInput"
|
||
|
|
type="text"
|
||
|
|
placeholder="nostr+walletconnect://..."
|
||
|
|
class="w-full bg-surface border border-border px-2 py-1.5 font-mono text-[10px] text-text-primary
|
||
|
|
focus:border-neon-cyan/50 focus:outline-none"
|
||
|
|
/>
|
||
|
|
<button
|
||
|
|
class="w-full mt-1 py-1.5 bg-neon-cyan/10 border border-neon-cyan/30 text-neon-cyan
|
||
|
|
font-display font-bold text-[9px] tracking-wider
|
||
|
|
hover:bg-neon-cyan/20 transition-all disabled:opacity-50"
|
||
|
|
:disabled="!nwcInput.trim() || isConnecting"
|
||
|
|
@click="handleConnectNWC"
|
||
|
|
>
|
||
|
|
{{ isConnecting ? 'CONNECTING...' : 'CONNECT NWC' }}
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="flex items-center gap-2">
|
||
|
|
<div class="flex-1 border-t border-border" />
|
||
|
|
<span class="font-mono text-[8px] text-text-muted">OR</span>
|
||
|
|
<div class="flex-1 border-t border-border" />
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Lightning Address input -->
|
||
|
|
<div>
|
||
|
|
<label class="font-mono text-[9px] text-text-muted block mb-1">LIGHTNING ADDRESS (payouts only)</label>
|
||
|
|
<input
|
||
|
|
v-model="lnAddressInput"
|
||
|
|
type="text"
|
||
|
|
placeholder="you@getalby.com"
|
||
|
|
class="w-full bg-surface border border-border px-2 py-1.5 font-mono text-[10px] text-text-primary
|
||
|
|
focus:border-neon-cyan/50 focus:outline-none"
|
||
|
|
/>
|
||
|
|
<button
|
||
|
|
class="w-full mt-1 py-1.5 bg-neon-purple/10 border border-neon-purple/30 text-neon-purple
|
||
|
|
font-display font-bold text-[9px] tracking-wider
|
||
|
|
hover:bg-neon-purple/20 transition-all disabled:opacity-50"
|
||
|
|
:disabled="!lnAddressInput.trim() || isConnecting"
|
||
|
|
@click="handleConnectLnAddress"
|
||
|
|
>
|
||
|
|
{{ isConnecting ? 'CONNECTING...' : 'SET ADDRESS' }}
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div v-if="connectError" class="text-center">
|
||
|
|
<p class="font-mono text-[9px] text-ko">{{ connectError }}</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<button
|
||
|
|
class="w-full py-1 font-mono text-[9px] text-text-muted hover:text-text-secondary transition-colors"
|
||
|
|
@click="isExpanded = false"
|
||
|
|
>
|
||
|
|
cancel
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|