Skip to content

Commit 565bf44

Browse files
committed
feat: add Lightning view to web wallet asset page
- /web-wallet/asset/LN shows dedicated Lightning experience - LightningSetup for first-time node provisioning - Offers + Payments tabs once node is active - Node status display with pubkey
1 parent 029f43d commit 565bf44

File tree

1 file changed

+110
-0
lines changed
  • src/app/web-wallet/asset/[chain]

1 file changed

+110
-0
lines changed

src/app/web-wallet/asset/[chain]/page.tsx

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import type { WalletChain } from '@/lib/web-wallet/identity';
2121
import { isValidChain } from '@/lib/web-wallet/identity';
2222
import type { TransactionListOptions } from '@/lib/wallet-sdk/types';
2323
import { SUPPORTED_FIAT_CURRENCIES, type FiatCurrency } from '@/lib/web-wallet/settings';
24+
import { LightningSetup } from '@/components/lightning/LightningSetup';
25+
import { LightningOfferCard } from '@/components/lightning/LightningOfferCard';
26+
import { LightningPayments } from '@/components/lightning/LightningPayments';
2427

2528
const EXPLORER_URLS: Record<string, string> = {
2629
BTC: 'https://blockstream.info/tx/',
@@ -130,9 +133,116 @@ export default function AssetDetailPage() {
130133
);
131134
}
132135

136+
// Lightning Network gets its own dedicated view
137+
if (rawChain === 'LN') {
138+
return <LightningAssetView />;
139+
}
140+
133141
return <AssetDetailView chain={rawChain} />;
134142
}
135143

144+
// ── Lightning Asset View ──
145+
146+
function LightningAssetView() {
147+
const { wallet } = useWebWallet();
148+
const [lnNode, setLnNode] = useState<{ id: string; status: string; node_pubkey: string } | null>(null);
149+
const [loading, setLoading] = useState(true);
150+
const [activeTab, setActiveTab] = useState<'offers' | 'payments'>('offers');
151+
152+
useEffect(() => {
153+
if (!wallet) return;
154+
// Check if LN node exists for this wallet
155+
fetch(`/api/lightning/nodes?wallet_id=${wallet.id}`, {
156+
headers: { 'Authorization': `Bearer ${wallet.id}` },
157+
})
158+
.then((r) => r.json())
159+
.then((data) => {
160+
if (data.success && data.data?.node) {
161+
setLnNode(data.data.node);
162+
}
163+
})
164+
.catch(() => {})
165+
.finally(() => setLoading(false));
166+
}, [wallet]);
167+
168+
if (loading) {
169+
return (
170+
<>
171+
<WalletHeader />
172+
<div className="flex min-h-[60vh] items-center justify-center">
173+
<div className="h-8 w-8 animate-spin rounded-full border-2 border-purple-500 border-t-transparent" />
174+
</div>
175+
</>
176+
);
177+
}
178+
179+
return (
180+
<>
181+
<WalletHeader />
182+
<div className="mx-auto max-w-lg px-4 py-8">
183+
<div className="mb-6 flex items-center gap-3">
184+
<Link href="/web-wallet" className="text-gray-400 hover:text-white transition-colors">
185+
← Back
186+
</Link>
187+
<h1 className="text-2xl font-bold text-white">⚡ Lightning Network</h1>
188+
</div>
189+
190+
{!lnNode ? (
191+
<LightningSetup
192+
walletId={wallet?.id || ''}
193+
onNodeProvisioned={(node) => setLnNode(node)}
194+
/>
195+
) : (
196+
<div className="space-y-6">
197+
{/* Node status */}
198+
<div className="rounded-xl border border-white/10 bg-white/5 p-4">
199+
<div className="flex items-center justify-between">
200+
<span className="text-sm text-gray-400">Node Status</span>
201+
<span className={`text-sm font-medium ${lnNode.status === 'active' ? 'text-green-400' : 'text-yellow-400'}`}>
202+
{lnNode.status}
203+
</span>
204+
</div>
205+
<p className="mt-1 text-xs text-gray-500 font-mono truncate">{lnNode.node_pubkey}</p>
206+
</div>
207+
208+
{/* Tabs */}
209+
<div className="flex gap-2">
210+
<button
211+
onClick={() => setActiveTab('offers')}
212+
className={`flex-1 rounded-lg px-4 py-2 text-sm font-medium transition-colors ${
213+
activeTab === 'offers'
214+
? 'bg-purple-600 text-white'
215+
: 'bg-white/5 text-gray-400 hover:text-white'
216+
}`}
217+
>
218+
Offers
219+
</button>
220+
<button
221+
onClick={() => setActiveTab('payments')}
222+
className={`flex-1 rounded-lg px-4 py-2 text-sm font-medium transition-colors ${
223+
activeTab === 'payments'
224+
? 'bg-purple-600 text-white'
225+
: 'bg-white/5 text-gray-400 hover:text-white'
226+
}`}
227+
>
228+
Payments
229+
</button>
230+
</div>
231+
232+
{/* Tab content */}
233+
{activeTab === 'offers' && (
234+
<LightningOfferCard nodeId={lnNode.id} />
235+
)}
236+
{activeTab === 'payments' && (
237+
<LightningPayments nodeId={lnNode.id} />
238+
)}
239+
</div>
240+
)}
241+
</div>
242+
</>
243+
);
244+
}
245+
136246
// ── Asset Detail View ──
137247

138248
function AssetDetailView({ chain }: { chain: WalletChain }) {

0 commit comments

Comments
 (0)