"use client"; import { FormEvent, useEffect, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import Navbar from "@/components/Navbar"; import { useAccount } from "@/contexts/AccountContext"; import { useWallet } from "@/contexts/WalletContext"; import { getMerchantBtcAddress, isMerchantBtcConfigured } from "@/lib/merchantBtc"; export default function AddFundsPage() { const router = useRouter(); const { user, hydrated } = useAccount(); const { usdStoreCredit, verifyBtcDeposit } = useWallet(); const [txid, setTxid] = useState(""); const [busy, setBusy] = useState(false); const [msg, setMsg] = useState<{ kind: "ok" | "err"; text: string } | null>(null); const processorUrl = (process.env.NEXT_PUBLIC_BITCOIN_CHECKOUT_URL || "").trim(); useEffect(() => { if (hydrated && !user) router.replace("/sign-in?next=/account/add-funds"); }, [hydrated, user, router]); if (!hydrated || !user) { return (
Loading…
); } const merchant = getMerchantBtcAddress(); const ready = isMerchantBtcConfigured(); const onVerify = async (e: FormEvent) => { e.preventDefault(); setMsg(null); setBusy(true); try { const res = await verifyBtcDeposit(txid.trim()); if (res.ok) { setMsg({ kind: "ok", text: `Credited $${(res.creditedUsd ?? 0).toFixed(2)} USD to @${user.username}.`, }); setTxid(""); } else { setMsg({ kind: "err", text: res.error || "Verification failed" }); } } finally { setBusy(false); } }; return (

account

Add funds

One CyberLux handle — same USD balance on hub, market, forum, exchange, and checkout. Send Bitcoin to your configured receiving address, wait for at least one confirmation, then paste the transaction id here. We verify on-chain pays to{" "} MERCHANT_BTC_ADDRESS and credit USD at spot (see{" "} /api/btc/verify).

Current balance

${usdStoreCredit.toFixed(2)} USD

Spend at checkout →
{processorUrl ? (

Bitcoin checkout

Open your hosted payment / BTCPay / processor page (set{" "} NEXT_PUBLIC_BITCOIN_CHECKOUT_URL).

Open payment page
) : null}

On-chain deposit

{!ready ? (

Set NEXT_PUBLIC_MERCHANT_BTC_ADDRESS and{" "} MERCHANT_BTC_ADDRESS in{" "} .env.local, restart Next, then reload this page.

) : ( <>

Send from any wallet. After one confirmation, paste the 64-character txid. Credit is computed from outputs paying this address only.

{merchant}
void onVerify(e)} className="mt-6 space-y-3"> setTxid(e.target.value.replace(/\s+/g, ""))} className="w-full rounded-xl border border-white/10 bg-transparent px-4 py-3 font-mono text-sm" placeholder="64 hex characters" autoComplete="off" /> {msg ? (

{msg.text}

) : null}
)}

Dashboard {" · "} Cross-onion identity {" · "} Hub

); }