"use client"; import { useState } from "react"; import Link from "next/link"; import { useAccount } from "@/contexts/AccountContext"; import { useWallet } from "@/contexts/WalletContext"; type Props = { /** USD amount to charge (2 decimals) */ amountUsd: number; /** Receipt / vault title */ title: string; description?: string; className?: string; size?: "sm" | "md"; /** Override LUX granted (default: based on USD amount) */ luxBonus?: number; /** Called after a successful charge */ onSuccess?: () => void; }; /** * Spend verified Bitcoin-funded USD balance without going through full checkout cart. */ export default function PayWithUsdBalanceButton({ amountUsd, title, description, className = "", size = "md", luxBonus, onSuccess, }: Props) { const { user } = useAccount(); const { usdStoreCredit, spendUsdStoreCredit, earnLuxCredits, addVaultReceipt } = useWallet(); const [msg, setMsg] = useState<{ kind: "ok" | "err"; text: string } | null>(null); const [busy, setBusy] = useState(false); const safe = Math.round(amountUsd * 100) / 100; const pad = size === "sm" ? "px-3 py-1.5 text-xs" : "px-5 py-2.5 text-sm"; const pay = () => { setMsg(null); if (!user) { setMsg({ kind: "err", text: "Sign in to spend your USD balance." }); return; } if (!(safe > 0)) { setMsg({ kind: "err", text: "Invalid amount." }); return; } setBusy(true); try { if (!spendUsdStoreCredit(safe)) { setMsg({ kind: "err", text: `Need $${safe.toFixed(2)} — you have $${usdStoreCredit.toFixed(2)}. Add funds first.`, }); return; } const lux = luxBonus != null && Number.isFinite(luxBonus) ? Math.max(0, Math.floor(luxBonus)) : Math.min(500, Math.max(10, Math.floor(safe))); earnLuxCredits(lux); const oid = typeof crypto !== "undefined" && "randomUUID" in crypto ? `PAY-${crypto.randomUUID().slice(0, 8).toUpperCase()}` : `PAY-${Date.now().toString(36).toUpperCase()}`; addVaultReceipt({ id: oid, title, desc: description ?? `${title} · $${safe.toFixed(2)} USD`, date: new Date().toISOString().slice(0, 10), severity: "normal", }); setMsg({ kind: "ok", text: `Paid $${safe.toFixed(2)}. +${lux} LUX · receipt ${oid}` }); onSuccess?.(); } finally { setBusy(false); } }; return (
{!user ? (

Sign in {" "} to use BTC-funded USD credit.

) : (

Balance: ${usdStoreCredit.toFixed(2)}

)} {msg ? (

{msg.text}

) : null}
); }