- 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
119 lines
3.6 KiB
TypeScript
119 lines
3.6 KiB
TypeScript
export type BarterLane = "goods" | "services" | "data" | "open";
|
||
|
||
export type BarterListing = {
|
||
id: string;
|
||
author: string;
|
||
title: string;
|
||
/** What the poster brings to the table */
|
||
have: string;
|
||
/** What they want back (goods, labor, crypto, favor, etc.) */
|
||
want: string;
|
||
lane: BarterLane;
|
||
body: string;
|
||
ts: number;
|
||
};
|
||
|
||
const KEY = "cyberlux-barter-v1";
|
||
|
||
function uid(): string {
|
||
if (typeof crypto !== "undefined" && "randomUUID" in crypto) return crypto.randomUUID();
|
||
return `b_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
|
||
}
|
||
|
||
const seeds: BarterListing[] = [
|
||
{
|
||
id: "barter-seed-1",
|
||
author: "relay_op",
|
||
title: "Entropy dongles → signed opsec consult",
|
||
have: "Two hardware RNG sticks, sealed.",
|
||
want: "2h walkthrough on compartmentalized laptop setup (signals only).",
|
||
lane: "services",
|
||
body: "No clearnet video. Text + voice on agreed onion comms. PGP on first ping.",
|
||
ts: Date.now() - 7200000 * 10,
|
||
},
|
||
{
|
||
id: "barter-seed-2",
|
||
author: "ledger_moth",
|
||
title: "Monero for physical dead-tree cipher zines",
|
||
have: "XMR at spot-ish — negotiate in-thread.",
|
||
want: "High-res scans of 80s crypto zines, OCR optional.",
|
||
lane: "goods",
|
||
body: "Escrow via hub USD balance after Bitcoin verify, or agree plaintext terms in-thread.",
|
||
ts: Date.now() - 7200000 * 6,
|
||
},
|
||
{
|
||
id: "barter-seed-3",
|
||
author: "patchbay_7",
|
||
title: "Studio time ↔ exploit courseware slides",
|
||
have: "4h mixing desk + mastering chain on airgapped DAW session (training scenario).",
|
||
want: "De-weaponized slide deck on heap grooming for class (no live targets).",
|
||
lane: "data",
|
||
body: "You send PDF, I send stems. Both sides verify hashes before swap.",
|
||
ts: Date.now() - 7200000 * 3,
|
||
},
|
||
{
|
||
id: "barter-seed-4",
|
||
author: "EU_shift",
|
||
title: "Shipping label templates → mirror canary text",
|
||
have: "Sanitized HTML snippets that look like phish (for training).",
|
||
want: "Latest signed canary paragraph from hub ring — compare byte-for-byte.",
|
||
lane: "open",
|
||
body: "Teaching red-team vs blue-team reading. No live credential harvesting.",
|
||
ts: Date.now() - 7200000 * 2,
|
||
},
|
||
{
|
||
id: "barter-seed-5",
|
||
author: "void_cartographer",
|
||
title: "Physical meet token ↔ CPU time",
|
||
have: "Laser-cut acrylic ‘proof of attendance’ tokens (larp).",
|
||
want: "Someone to crunch log anonymization on an offline CSV (class data).",
|
||
lane: "services",
|
||
body: "Coordinate only through your institution’s lab policy — this board is data, not logistics.",
|
||
ts: Date.now() - 7200000 * 14,
|
||
},
|
||
];
|
||
|
||
export function loadBarter(): BarterListing[] {
|
||
if (typeof window === "undefined") return seeds;
|
||
try {
|
||
const raw = localStorage.getItem(KEY);
|
||
if (!raw) {
|
||
saveBarter(seeds);
|
||
return seeds;
|
||
}
|
||
const v = JSON.parse(raw) as BarterListing[];
|
||
if (!Array.isArray(v) || !v.length) {
|
||
saveBarter(seeds);
|
||
return seeds;
|
||
}
|
||
return v;
|
||
} catch {
|
||
return seeds;
|
||
}
|
||
}
|
||
|
||
export function saveBarter(list: BarterListing[]): void {
|
||
if (typeof window === "undefined") return;
|
||
localStorage.setItem(KEY, JSON.stringify(list));
|
||
}
|
||
|
||
const SEED_IDS = new Set(seeds.map((s) => s.id));
|
||
|
||
export function addBarterListing(
|
||
L: Omit<BarterListing, "id" | "ts">,
|
||
): BarterListing {
|
||
const row: BarterListing = {
|
||
id: uid(),
|
||
ts: Date.now(),
|
||
author: L.author.trim() || "Anonymous",
|
||
title: L.title.trim(),
|
||
have: L.have.trim(),
|
||
want: L.want.trim(),
|
||
lane: L.lane,
|
||
body: L.body.trim(),
|
||
};
|
||
const userRows = loadBarter().filter((r) => !SEED_IDS.has(r.id));
|
||
saveBarter([row, ...userRows, ...seeds]);
|
||
return row;
|
||
}
|