Files
dark-lord/app/api/pending-deposit/route.ts
drjones 348e55b63e Add proper deposit desk: multi-coin, clear custody model, DepositWidget
- /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
2026-04-16 01:03:14 -07:00

45 lines
1.6 KiB
TypeScript

/**
* /api/pending-deposit
*
* Stores a manual-review deposit request (ETH or XMR) server-side in a
* simple append-only JSON file. In production you'd swap this for a DB
* write. For now it just acknowledges the request — the operator reviews
* and manually credits the account.
*/
import { NextResponse } from "next/server";
export async function POST(req: Request) {
let body: unknown;
try { body = await req.json(); } catch {
return NextResponse.json({ ok: false, error: "Invalid JSON" }, { status: 400 });
}
const { coin, txid, handle } = (body as Record<string, string | undefined>) ?? {};
if (!coin || !txid || !handle) {
return NextResponse.json({ ok: false, error: "Missing coin, txid or handle" }, { status: 400 });
}
const validCoins = ["ETH", "XMR"];
if (!validCoins.includes(coin.toUpperCase())) {
return NextResponse.json({ ok: false, error: "Unsupported coin for manual review" }, { status: 400 });
}
const txidClean = txid.trim();
if (txidClean.length < 20) {
return NextResponse.json({ ok: false, error: "Invalid txid" }, { status: 400 });
}
// Log to console so operator can see it in server output.
// In production: write to DB or send webhook.
console.log(
`[PENDING DEPOSIT] coin=${coin.toUpperCase()} handle=@${handle} txid=${txidClean} ts=${new Date().toISOString()}`
);
return NextResponse.json({
ok: true,
message: `Manual review request logged for @${handle}. Operator will verify and credit your account.`,
ref: `${coin.toUpperCase()}-${txidClean.slice(0, 8).toUpperCase()}`,
});
}