Files
dark-lord/app/account/hidden-services/page.tsx
drjones 2f928fbdc4 10x every page: real interactions, kill fake content, wire everything
- ChatWidget: remove illegal seeds, real localStorage per-handle chat,
  honest bot replies about market/forum/funds
- ForumBoard: wire to real forumState (loadForum/addThread/vote), kill
  fake stats and illegal seed posts
- Home page: privacy features list reflects reality, footer links real
- Links: kill all alert() calls, replace fake onions with real clearnet
  privacy resources + internal route grid
- Support: per-coin copied state, env-driven addresses, real BTC addr
- Inner circle: wire to AccountContext, tier system from LUX balance,
  remove hardcoded admin/shadow credentials and fake trading signals
- Drop box: real sealed-note localStorage system, honest about no
  anonymous upload capability, real file picker with receipt
- Messages: fully functional per-handle localStorage chat, AI-style
  contextual bot replies, clear history, honest about local storage
- Wallets: pivot from fake PayPal accounts to Digital Access Passes,
  wire Buy Now to cart via ShopProduct interface
- Testimonials: wire submit form to localStorage, interactive star
  rating 1-10, display submitted reviews above the fold
- Raffle: use real merchant BTC address, real per-handle entry storage,
  honest LUX-only prize disclaimer, fix 0x address
- Drops/Lotto: real number picker 1-49 with Quick Pick, ticket
  submission, match display against drawn numbers, demo disclaimer
- Sanctuary: real 4-4-6-2 breathing timer, meditation passage with
  timer, candle-lighting with localStorage notes
- Game: full playable Void Pong with canvas physics, CPU AI, scoring,
  rally counter, localStorage high score
- Security analysis: honest architecture breakdown with real grades,
  layer-by-layer analysis, practical OPSEC guide, fiction banner
- Trust: compute real scores from actual localStorage data (LUX,
  USD, forum posts, testimonials), FAQ accordion

Made-with: Cursor
2026-04-16 00:55:28 -07:00

166 lines
6.7 KiB
TypeScript

"use client";
import { FormEvent, useEffect, useState } from "react";
import Link from "next/link";
import { useAccount } from "@/contexts/AccountContext";
import { exportPortableAccountJson, importPortableAccountJson } from "@/lib/cyberluxAccount";
export default function HiddenServicesAccountPage() {
const { user, hydrated, refreshProfile } = useAccount();
const [importText, setImportText] = useState("");
const [importMsg, setImportMsg] = useState<{ kind: "ok" | "err"; text: string } | null>(null);
const [copyMsg, setCopyMsg] = useState<string | null>(null);
useEffect(() => {
setImportMsg(null);
}, [importText]);
const onCopyBundle = async () => {
setCopyMsg(null);
const json = exportPortableAccountJson();
if (!json) return;
try {
await navigator.clipboard.writeText(json);
setCopyMsg("Copied. Paste on another onion host → Import below.");
} catch {
setCopyMsg("Could not use clipboard — select and copy manually.");
}
};
const onImport = (e: FormEvent) => {
e.preventDefault();
setImportMsg(null);
const res = importPortableAccountJson(importText.trim());
if (!res.ok) {
setImportMsg({ kind: "err", text: res.error });
return;
}
refreshProfile();
setImportText("");
setImportMsg({ kind: "ok", text: "Identity loaded on this hostname. You can use dashboard, forum, exchange, and barter here." });
};
if (!hydrated) {
return (
<div className="flex min-h-[40vh] items-center justify-center font-mono text-sm text-zinc-500">
Loading
</div>
);
}
return (
<div className="min-h-screen bg-[#0a0a0a] px-4 py-14 text-zinc-200">
<div className="mx-auto max-w-lg">
<p className="font-mono text-[10px] uppercase tracking-[0.35em] text-emerald-500/80">hidden services</p>
<h1 className="mt-3 font-orbitron text-2xl font-bold text-zinc-100">Account on every entry node</h1>
<p className="mt-4 text-sm leading-relaxed text-zinc-500">
Each hidden-service hostname gets an isolated browser vault. Keys you mint on the forum onion do not
automatically exist on the exchange or wiki host mirror your identity deliberately or enroll separately.
Verified Bitcoin USD credits are stored the same way: per host. Use a portable bundle to reuse your handle,
then add funds on each hostname you actively use (
<Link href="/account/add-funds" className="text-emerald-400 hover:underline">
Add funds
</Link>
).
</p>
<ol className="mt-8 list-decimal space-y-4 border-l border-white/10 pl-5 text-sm text-zinc-400">
<li>
<strong className="text-zinc-300">Create a handle</strong> on this host:{" "}
<Link href="/sign-up" className="text-emerald-400 hover:underline">
Sign up
</Link>{" "}
(or{" "}
<Link href="/sign-in" className="text-emerald-400 hover:underline">
Sign in
</Link>
).
</li>
<li>
<strong className="text-zinc-300">Repeat on other mirrors</strong> with the{" "}
<strong className="text-zinc-300">same handle and passphrase</strong>,{" "}
<span className="text-zinc-500">or</span> export a bundle here (signed in) and import it on the other host.
</li>
<li>
Use{" "}
<Link href="/dashboard" className="text-emerald-400 hover:underline">
Dashboard
</Link>
,{" "}
<Link href="/forum" className="text-emerald-400 hover:underline">
Forum
</Link>
,{" "}
<Link href="/exchange" className="text-emerald-400 hover:underline">
Exchange
</Link>
, and{" "}
<Link href="/barter" className="text-emerald-400 hover:underline">
Barter
</Link>{" "}
once this hostname knows your session.
</li>
</ol>
{user ? (
<section className="glass mt-10 rounded-2xl border border-emerald-900/40 p-6">
<h2 className="font-mono text-xs font-bold uppercase tracking-widest text-emerald-400/90">Portable bundle</h2>
<p className="mt-2 text-xs text-zinc-500">
Signed in as <span className="font-mono text-emerald-200/90">@{user.username}</span>. The bundle contains a
passphrase fingerprint do not share it.
</p>
<button
type="button"
onClick={() => void onCopyBundle()}
className="mt-4 w-full rounded-xl border border-emerald-700/50 bg-emerald-950/40 py-3 font-mono text-sm font-bold text-emerald-200 hover:bg-emerald-900/30"
>
Copy identity bundle
</button>
{copyMsg ? <p className="mt-3 text-xs text-zinc-400">{copyMsg}</p> : null}
</section>
) : (
<p className="mt-10 rounded-xl border border-white/10 bg-white/[0.03] px-4 py-3 text-center text-sm text-zinc-500">
<Link href="/sign-in" className="text-emerald-400 hover:underline">
Sign in
</Link>{" "}
to copy an export bundle for another host.
</p>
)}
<section className="glass mt-8 rounded-2xl border border-white/10 p-6">
<h2 className="font-mono text-xs font-bold uppercase tracking-widest text-zinc-400">Import bundle</h2>
<p className="mt-2 text-xs text-zinc-500">Paste JSON from &quot;Copy identity bundle&quot; on the host where you exported it.</p>
<form onSubmit={onImport} className="mt-4 space-y-3">
<textarea
value={importText}
onChange={(e) => setImportText(e.target.value)}
rows={5}
placeholder='{"v":1,"username":"…", …}'
className="glass w-full rounded-xl border border-white/10 bg-black/30 px-3 py-2 font-mono text-[11px] text-zinc-300"
/>
<button
type="submit"
className="w-full rounded-xl bg-gradient-to-r from-emerald-800 to-emerald-700 py-3 font-bold text-white hover:opacity-95"
>
Import & sign in here
</button>
</form>
{importMsg ? (
<p
className={`mt-3 text-sm ${importMsg.kind === "ok" ? "text-emerald-300/90" : "text-red-300/90"}`}
>
{importMsg.text}
</p>
) : null}
</section>
<p className="mt-10 text-center">
<Link href="/hidden-wiki" className="text-xs text-zinc-600 hover:text-zinc-400">
Hidden wiki
</Link>
</p>
</div>
</div>
);
}