diff --git a/app/account/add-funds/page.tsx b/app/account/add-funds/page.tsx new file mode 100644 index 0000000..d0594ea --- /dev/null +++ b/app/account/add-funds/page.tsx @@ -0,0 +1,159 @@ +"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 ( +
account
+
+ 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
+
+ Open your hosted payment / BTCPay / processor page (set{" "}
+ NEXT_PUBLIC_BITCOIN_CHECKOUT_URL).
+
+ 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. +
++ + Dashboard + + {" · "} + + Cross-onion identity + + {" · "} + + Hub + +
+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 ( + + Add funds + + ).
Analyst-facing taxonomy for how underground ecosystems get clustered in threat intel — markets, access brokers, leak blogs,
- whistleblowing rails, opsec boutiques, and rumor boards. External rows ship with boilerplate{" "}
- {PLACEHOLDER_ONION_HOST} hostnames until you paste vetted mirrors; treat
- every link as unconfirmed until PGP cross-check.
+ whistleblowing rails, opsec boutiques, and rumor boards. In-app rows link to real CyberLux routes (forum, market, checkout, funding,
+ etc.); clearnet rows are curated references you should still verify out-of-band.
- {visible.length} / {DARKNET_ATLAS.length} top-level categories visible · default template host:{" "} - {PLACEHOLDER_ONION_URL} + {visible.length} / {DARKNET_ATLAS.length} top-level categories visible · internal links resolve inside this deployment.
- Status: {isConnected ? connected : not connected} +
+ USD is credited after verified Bitcoin deposits to your merchant address. LUX is loyalty currency (e.g. + completed checkouts).
- {address ? ( -- {address.slice(0, 10)}…{address.slice(-6)} -
- ) : null}
- Queue a fiction application — stored in this browser only.{" "}
+ Applications are stored in this browser under your handle (no remote queue yet).{" "}
Apply to vend →
diff --git a/app/drop-box/page.tsx b/app/drop-box/page.tsx
index 9fae62c..0ab365c 100644
--- a/app/drop-box/page.tsx
+++ b/app/drop-box/page.tsx
@@ -1,87 +1,205 @@
"use client";
-import { useState } from "react";
+import { useState, useRef } from "react";
+import Link from "next/link";
import ThemedLayout from "@/components/layouts/ThemedLayout";
-export default function WhistleblowerPage() {
- const [isUploading, setIsUploading] = useState(false);
- const [progress, setProgress] = useState(0);
+type DropReceipt = { id: string; size: string; ts: string; label: string };
- const handleUpload = () => {
- setIsUploading(true);
- let p = 0;
- const interval = setInterval(() => {
- p += 5;
- setProgress(p);
- if (p >= 100) {
- clearInterval(interval);
- setIsUploading(false);
- alert("File encrypted and dropped successfully.");
- }
- }, 200);
+function uid() {
+ return Math.random().toString(36).slice(2, 10).toUpperCase();
+}
+
+function storeReceipt(r: DropReceipt) {
+ if (typeof window === "undefined") return;
+ try {
+ const key = "cyberlux-dropbox-receipts";
+ const existing: DropReceipt[] = JSON.parse(localStorage.getItem(key) ?? "[]");
+ existing.push(r);
+ localStorage.setItem(key, JSON.stringify(existing.slice(-20)));
+ } catch {
+ // ignore
+ }
+}
+
+export default function DropBoxPage() {
+ const [label, setLabel] = useState("");
+ const [message, setMessage] = useState("");
+ const [fileName, setFileName] = useState Secure. Anonymous. Untraceable.
+ Client-side encrypted message or note. Stored locally in your browser only.
+
+ No server, no network — this is a local sealed-note system. For real whistleblowing use{" "}
+
+ SecureDrop
+
+ .
+
- We provide a secure channel for individuals to expose corruption and corporate
- malfeasance. Your identity is protected by the Shadow Network's multi-layered
- encryption protocol.
-
- We are a non-profit entity. All donations go towards server maintenance and legal defense funds.
-
- Drag and drop your encrypted archives here.
- Max file size: 2GB.
+ {receipt ? (
+
+ Your drop was sealed and stored locally. Receipt ID below.
Whistleblower Drop
- Sealed Drop
+ Our Mission
- Support the Cause
- Drop Your Files
- Drop Sealed
+