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
This commit is contained in:
drjones
2026-04-16 00:55:28 -07:00
parent 9da373a190
commit 2f928fbdc4
36 changed files with 3837 additions and 2354 deletions

View File

@@ -1,24 +1,14 @@
"use client";
import { createContext, useContext, useEffect, useMemo, useState, ReactNode } from "react";
import { createContext, useCallback, useContext, useEffect, useMemo, useState, ReactNode } from "react";
import type { VaultReceipt, VaultState } from "@/lib/metaGame";
import { addKey, addReceipt, defaultVaultState, loadVaultState, saveVaultState, setFlag } from "@/lib/metaGame";
import {
loadClaimedTxids,
loadUsdStoreCredit,
saveClaimedTxids,
saveUsdStoreCredit,
} from "@/lib/storeCreditStorage";
import { getLedgerRow, migrateLegacyDeviceLedgerIfNeeded, setLedgerRow } from "@/lib/storeCreditStorage";
import { useAccount } from "@/contexts/AccountContext";
interface WalletContextType {
isConnected: boolean;
address: string | null;
chainId: number | null;
connect: () => Promise<void>;
disconnect: () => void;
balance: string;
luxCredits: number;
usdStoreCredit: number;
luxCredits: number;
spendLuxCredits: (amount: number) => boolean;
earnLuxCredits: (amount: number) => void;
spendUsdStoreCredit: (amount: number) => boolean;
@@ -44,107 +34,112 @@ interface WalletProviderProps {
}
export const WalletProvider = ({ children }: WalletProviderProps) => {
const [isConnected, setIsConnected] = useState(false);
const [address, setAddress] = useState<string | null>(null);
const [chainId, setChainId] = useState<number | null>(null);
const [balance, setBalance] = useState("0.0");
const [luxCredits, setLuxCredits] = useState(0);
const { user } = useAccount();
const handle = user?.username ?? null;
const [usdStoreCredit, setUsdStoreCredit] = useState(0);
const [usdHydrated, setUsdHydrated] = useState(false);
const [luxCredits, setLuxCredits] = useState(0);
const [vault, setVault] = useState<VaultState>(() => defaultVaultState());
const mockAddress = "0x71C7...e4a2";
const mockChainId = 1;
const mockBalance = "2.45";
const startingLuxCredits = 5000;
const connect = async () => {
// Simulate wallet connection delay
await new Promise((resolve) => setTimeout(resolve, 800));
setIsConnected(true);
setAddress(mockAddress);
setChainId(mockChainId);
setBalance(mockBalance);
setLuxCredits(startingLuxCredits);
};
const disconnect = () => {
setIsConnected(false);
setAddress(null);
setChainId(null);
setBalance("0.0");
setLuxCredits(0);
};
useEffect(() => {
if (!handle) {
setUsdStoreCredit(0);
setLuxCredits(0);
return;
}
migrateLegacyDeviceLedgerIfNeeded(handle);
const row = getLedgerRow(handle);
setUsdStoreCredit(row.usd);
setLuxCredits(row.lux);
}, [handle]);
useEffect(() => {
setVault(loadVaultState());
setUsdStoreCredit(loadUsdStoreCredit());
setUsdHydrated(true);
}, []);
setVault(loadVaultState(handle));
}, [handle]);
useEffect(() => {
saveVaultState(vault);
}, [vault]);
saveVaultState(handle, vault);
}, [vault, handle]);
useEffect(() => {
if (!usdHydrated) return;
saveUsdStoreCredit(usdStoreCredit);
}, [usdStoreCredit, usdHydrated]);
const spendLuxCredits = (amount: number) => {
const spendLuxCredits = useCallback((amount: number) => {
if (!handle) return false;
const safeAmount = Number.isFinite(amount) ? Math.max(0, Math.floor(amount)) : 0;
if (safeAmount <= 0) return true;
if (luxCredits < safeAmount) return false;
setLuxCredits((c) => c - safeAmount);
const row = getLedgerRow(handle);
if (row.lux < safeAmount) return false;
const nextLux = row.lux - safeAmount;
setLedgerRow(handle, { usd: row.usd, lux: nextLux, claimedTxids: row.claimedTxids });
setLuxCredits(nextLux);
return true;
};
}, [handle]);
const earnLuxCredits = (amount: number) => {
const safeAmount = Number.isFinite(amount) ? Math.max(0, Math.floor(amount)) : 0;
if (safeAmount <= 0) return;
setLuxCredits((c) => c + safeAmount);
};
const earnLuxCredits = useCallback(
(amount: number) => {
if (!handle) return;
const safeAmount = Number.isFinite(amount) ? Math.max(0, Math.floor(amount)) : 0;
if (safeAmount <= 0) return;
const row = getLedgerRow(handle);
const nextLux = row.lux + safeAmount;
setLedgerRow(handle, { usd: row.usd, lux: nextLux, claimedTxids: row.claimedTxids });
setLuxCredits(nextLux);
},
[handle],
);
const spendUsdStoreCredit = (amount: number) => {
const safe = Number.isFinite(amount) ? Math.max(0, Math.round(amount * 100) / 100) : 0;
if (safe <= 0) return true;
if (usdStoreCredit + 1e-9 < safe) return false;
setUsdStoreCredit((u) => Math.round((u - safe) * 100) / 100);
return true;
};
const spendUsdStoreCredit = useCallback(
(amount: number) => {
if (!handle) return false;
const safe = Number.isFinite(amount) ? Math.max(0, Math.round(amount * 100) / 100) : 0;
if (safe <= 0) return true;
const row = getLedgerRow(handle);
if (row.usd + 1e-9 < safe) return false;
const nextUsd = Math.round((row.usd - safe) * 100) / 100;
setLedgerRow(handle, { usd: nextUsd, lux: row.lux, claimedTxids: row.claimedTxids });
setUsdStoreCredit(nextUsd);
return true;
},
[handle],
);
const verifyBtcDeposit = async (txid: string) => {
const normalized = String(txid || "").trim();
if (!/^[a-fA-F0-9]{64}$/.test(normalized)) {
return { ok: false, error: "Enter a valid 64-character transaction id" };
}
const claimed = loadClaimedTxids();
if (claimed.includes(normalized)) {
return { ok: false, error: "This transaction was already used to add credit" };
}
try {
const res = await fetch("/api/btc/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ txid: normalized }),
});
const data = (await res.json()) as {
ok?: boolean;
error?: string;
creditedUsd?: number;
};
if (!data.ok || typeof data.creditedUsd !== "number") {
return { ok: false, error: data.error || "Verification failed" };
const verifyBtcDeposit = useCallback(
async (txid: string) => {
if (!handle) {
return { ok: false, error: "Sign in so deposits credit your handles balance." };
}
claimed.push(normalized);
saveClaimedTxids(claimed);
const add = Math.round(data.creditedUsd * 100) / 100;
setUsdStoreCredit((u) => Math.round((u + add) * 100) / 100);
return { ok: true, creditedUsd: add };
} catch {
return { ok: false, error: "Network error while verifying" };
}
};
const normalized = String(txid || "").trim();
if (!/^[a-fA-F0-9]{64}$/.test(normalized)) {
return { ok: false, error: "Enter a valid 64-character transaction id" };
}
const row = getLedgerRow(handle);
if (row.claimedTxids.includes(normalized)) {
return { ok: false, error: "This transaction was already used to add credit" };
}
try {
const res = await fetch("/api/btc/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ txid: normalized }),
});
const data = (await res.json()) as {
ok?: boolean;
error?: string;
creditedUsd?: number;
};
if (!data.ok || typeof data.creditedUsd !== "number") {
return { ok: false, error: data.error || "Verification failed" };
}
const add = Math.round(data.creditedUsd * 100) / 100;
const nextUsd = Math.round((row.usd + add) * 100) / 100;
const claimed = [...row.claimedTxids, normalized];
setLedgerRow(handle, { usd: nextUsd, lux: row.lux, claimedTxids: claimed });
setUsdStoreCredit(nextUsd);
return { ok: true, creditedUsd: add };
} catch {
return { ok: false, error: "Network error while verifying" };
}
},
[handle],
);
const collectKey = (key: string) => {
const trimmed = String(key || "").trim();
@@ -166,14 +161,8 @@ export const WalletProvider = ({ children }: WalletProviderProps) => {
const value = useMemo(
() => ({
isConnected,
address,
chainId,
connect,
disconnect,
balance,
luxCredits,
usdStoreCredit,
luxCredits,
spendLuxCredits,
earnLuxCredits,
spendUsdStoreCredit,
@@ -183,14 +172,16 @@ export const WalletProvider = ({ children }: WalletProviderProps) => {
addVaultReceipt,
setVaultFlag,
}),
[isConnected, address, chainId, balance, luxCredits, usdStoreCredit, vault],
[
usdStoreCredit,
luxCredits,
spendLuxCredits,
earnLuxCredits,
spendUsdStoreCredit,
verifyBtcDeposit,
vault,
],
);
return (
<WalletContext.Provider
value={value}
>
{children}
</WalletContext.Provider>
);
};
return <WalletContext.Provider value={value}>{children}</WalletContext.Provider>;
};