- /account/add-funds: full rebuild as Deposit Desk
- 3-step how-it-works explainer: you send crypto → we hold it →
you shop with USD credit → we pay vendors with your crypto
- Coin selector: BTC (auto-verify), ETH (manual review), XMR (manual review)
- Each coin shows deposit address from env var with copy button
- BTC: immediate on-chain verify via /api/btc/verify (mempool.space)
- ETH/XMR: submit txhash to /api/pending-deposit for manual review
- Pending deposit history stored in localStorage with status
- Important notes block explaining custody, no-withdrawal, confirmations
- Back-links to checkout, wallets, dashboard
- /api/pending-deposit: new route to log ETH/XMR manual review requests
(logs to console, ready to wire to DB/webhook)
- DepositWidget component: reusable compact + full variants
- compact: balance + "Deposit crypto →" CTA (used in checkout)
- full: balance + how-it-works summary (used in dashboard)
- Dashboard: replace balance section with DepositWidget + stats
- Checkout: add compact DepositWidget above CheckoutFlow, fix back link
from "Sanctuary" → "Market", update feature cards to be accurate
- .env.example: document all three coin address env vars + optional
payment processor URL
- .env.example: add NEXT_PUBLIC_ETH_ADDRESS, NEXT_PUBLIC_XMR_ADDRESS
Made-with: Cursor
86 lines
3.4 KiB
TypeScript
86 lines
3.4 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { useWallet } from "@/contexts/WalletContext";
|
|
import { useAccount } from "@/contexts/AccountContext";
|
|
import { isMerchantBtcConfigured } from "@/lib/merchantBtc";
|
|
|
|
type DepositWidgetProps = {
|
|
compact?: boolean;
|
|
};
|
|
|
|
export default function DepositWidget({ compact = false }: DepositWidgetProps) {
|
|
const { usdStoreCredit, luxCredits } = useWallet();
|
|
const { user } = useAccount();
|
|
const btcReady = isMerchantBtcConfigured();
|
|
|
|
if (compact) {
|
|
return (
|
|
<div className="glass rounded-2xl border border-neon-cyan/20 p-5">
|
|
<div className="flex items-center justify-between gap-4">
|
|
<div>
|
|
<div className="text-xs text-foreground/50">Your balance</div>
|
|
<div className="mt-0.5 font-orbitron text-2xl text-neon-cyan">
|
|
${usdStoreCredit.toFixed(2)}
|
|
<span className="ml-2 text-sm text-foreground/40">USD</span>
|
|
</div>
|
|
<div className="mt-0.5 text-xs text-neon-green">{luxCredits.toLocaleString()} LUX</div>
|
|
</div>
|
|
<Link
|
|
href="/account/add-funds"
|
|
className="shrink-0 rounded-xl bg-gradient-to-r from-neon-cyan to-neon-purple px-5 py-3 text-sm font-bold text-background hover:opacity-90"
|
|
>
|
|
Deposit crypto →
|
|
</Link>
|
|
</div>
|
|
{!user && (
|
|
<p className="mt-3 text-xs text-amber-300/70">
|
|
<Link href="/sign-in?next=/account/add-funds" className="underline">Sign in</Link> to link deposits to your handle.
|
|
</p>
|
|
)}
|
|
{!btcReady && (
|
|
<p className="mt-2 text-[10px] text-amber-400/60">
|
|
Operator: set <code>NEXT_PUBLIC_MERCHANT_BTC_ADDRESS</code> in .env.local to enable deposits.
|
|
</p>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="glass rounded-2xl border border-white/10 p-6">
|
|
<div className="mb-4 flex items-start justify-between gap-3">
|
|
<div>
|
|
<div className="text-xs text-foreground/50">Account balance</div>
|
|
<div className="mt-1 font-orbitron text-3xl text-neon-cyan">${usdStoreCredit.toFixed(2)}</div>
|
|
<div className="mt-0.5 text-sm text-neon-green">{luxCredits.toLocaleString()} LUX</div>
|
|
</div>
|
|
<Link
|
|
href="/account/add-funds"
|
|
className="rounded-xl bg-gradient-to-r from-neon-cyan to-neon-purple px-5 py-3 text-sm font-bold text-background hover:opacity-90"
|
|
>
|
|
Add crypto →
|
|
</Link>
|
|
</div>
|
|
|
|
<div className="mt-4 rounded-xl border border-white/10 bg-black/30 p-4 text-sm">
|
|
<div className="mb-2 text-xs font-bold uppercase tracking-wider text-foreground/50">How it works</div>
|
|
<div className="space-y-2 text-foreground/70">
|
|
<div className="flex items-start gap-2">
|
|
<span className="mt-0.5 shrink-0 text-neon-cyan">1.</span>
|
|
<span>You send crypto to our receiving address.</span>
|
|
</div>
|
|
<div className="flex items-start gap-2">
|
|
<span className="mt-0.5 shrink-0 text-neon-cyan">2.</span>
|
|
<span>We verify on-chain and credit your account at market USD rate.</span>
|
|
</div>
|
|
<div className="flex items-start gap-2">
|
|
<span className="mt-0.5 shrink-0 text-neon-cyan">3.</span>
|
|
<span>You shop with USD credits. We hold the crypto and pay vendors on your behalf.</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|