Files
dark-lord/lib/shopCatalog.ts
drjones 04d64fb993 Update market, account, and onion operations
Capture the current CyberLux UI, commerce, messaging, and Tor ops updates so local main can be pushed to the remote.

Made-with: Cursor
2026-04-24 23:23:48 -07:00

338 lines
28 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* CyberLux storefront catalog — in-universe listings (see site footer for real-world status).
*
* Images: each SKU gets a stable Unsplash URL via `resolveProductImage` (hashed by id).
* To use your own file: put it in `public/shop-assets/` and set `assetFile: "my-photo.webp"` on that SKU.
*/
import { sellerIdForProduct } from "@/lib/shopSellers";
export type ShopCurrency = "BTC" | "ETH" | "USD" | "XMR";
export type ShopProduct = {
id: string;
name: string;
description: string;
price: number;
currency: ShopCurrency;
category: string;
/** Assigned in SHOP_PRODUCTS from sellerIdForProduct — stable per SKU */
sellerId: string;
limited?: boolean;
glowColor?: string;
/** Drop a file at public/shop-assets/{assetFile} to override the remote image */
assetFile?: string;
};
/** Unsplash photo paths — royalty-free hotlink; rotate by product id */
const UNSPLASH_ROTATOR = [
"photo-1563013544-824ae1b704d3",
"photo-1553062407-98eeb64c6a62",
"photo-1523275335684-37898b6baf30",
"photo-1505740420928-5e560c06d30e",
"photo-1542291026-7eec264c27ff",
"photo-1526170375885-4d8ecf77b99f",
"photo-1518544801979-152483f7e79e",
"photo-1550751827-4bd374c3f58b",
"photo-1618005188914-3c8315f33e6f",
"photo-1558618047-3c8c76ca7d13",
"photo-1551288049-bebda4e38f71",
"photo-1635070041078-e363dbe005cb",
"photo-1517694712202-14dd9538aa97",
"photo-1526374965328-7f61d4dc18c5",
"photo-1555949963-aa79dcee981c",
"photo-1614854262312-209b1c0b2c7b",
"photo-1592503254549-83d24b4fc4a6",
"photo-1593359677876-a0bb1c3a8095",
"photo-1611162616305-c69b3fa7fbe0",
"photo-1581091226825-a6a2a5aee158",
"photo-1518770660439-4636190af475",
"photo-1460925895917-afdab827c52f",
"photo-1451187580459-43490279c0fa",
"photo-1582719478250-c89cae4dc85b",
"photo-1559757148-5c350d0d3c56",
"photo-1584433144859-1fc3ab64a54f",
"photo-1512941937669-90a1b58e7e9c",
"photo-1605812860427-4024433a70fd",
"photo-1563986768609-322da13575f3",
"photo-1639762681485-074b7f938ba0",
] as const;
function hashId(id: string): number {
let h = 0;
for (let i = 0; i < id.length; i++) h = (h + id.charCodeAt(i) * (i + 1)) % 2147483647;
return Math.abs(h);
}
/** Remote image URL (internet) or your file under public/shop-assets/ */
export function resolveProductImage(p: ShopProduct): string {
if (p.assetFile?.trim()) {
return `/shop-assets/${p.assetFile.replace(/^\/+/, "")}`;
}
const idx = hashId(p.id) % UNSPLASH_ROTATOR.length;
const path = UNSPLASH_ROTATOR[idx]!;
return `https://images.unsplash.com/${path}?w=800&q=85&auto=format&fit=crop`;
}
const GLOWS = [
"neon-cyan",
"neon-purple",
"neon-pink",
"neon-green",
"neon-yellow",
"neon-red",
"neon-blue",
] as const;
type Seed = Omit<ShopProduct, "id" | "glowColor" | "category" | "sellerId"> & { id?: string };
type ProductDraft = Omit<ShopProduct, "sellerId">;
function block(category: string, items: Seed[]): ProductDraft[] {
return items.map((raw, j) => {
const id = raw.id ?? `${category.slice(0, 3)}-${hashId(`${category}-${raw.name}-${j}`).toString(36)}`;
const { id: _drop, ...rest } = raw;
return {
id,
glowColor: GLOWS[hashId(id) % GLOWS.length],
...rest,
category,
};
});
}
/** Everything offered in the shop — expand by adding more `block(...)` rows */
const ALL_BLOCKS: ProductDraft[] = [
...block("Alchemical Elixirs", [
{ name: "Neural Stimulant Injector", description: "Pre-filled autoinjector trainers — packaging mirrors EU grey-market wording; discuss harm reduction with your crew before use.", price: 0.085, currency: "BTC", limited: true },
{ name: "Cognitive patch kit (12h)", description: "Transdermal placebo narrative for discussing FDA vs grey-market copy.", price: 0.019, currency: "XMR" },
{ name: "Synaptic dampener v2", description: "Plot device for too much focus cyberpunk arcs — pure chrome.", price: 0.042, currency: "ETH" },
{ name: "RNA mimic cream (theatrical)", description: "Salon-grade tub with aggressive RNA branding — parse the ingredient deck before you trust the claims.", price: 124, currency: "USD" },
{ name: "Dream-state diffuser oil", description: "Diffuser blend marketed for lucid downtime — ships as 30ml amber bottle, COA on request.", price: 0.007, currency: "BTC" },
{ name: "Circadian hijack glasses", description: "Blue-shift fable hardware — compare to real sleep science slides.", price: 0.011, currency: "ETH" },
{ name: "Quad-core adrenaline tabs", description: "Press-fit tabs, stim-forward copy — contraindicated if you run hot BP; novelty packaging only where law allows.", price: 0.003, currency: "BTC" },
{ name: "Empathy rollback serum", description: "Satirical item naming — discuss manipulation in vendor prose.", price: 0.028, currency: "XMR", limited: true },
{ name: "Vagus nerve tickler wand", description: "Machined aluminum grip, wellness-grade marketing — verify medical claims independently.", price: 89, currency: "USD" },
{ name: "Mitochondria vanity stack", description: "Stacks-Sigma meme inventory for listing trust workshops.", price: 0.015, currency: "ETH" },
{ name: "CRISPR cosplay pipette set", description: "Plastic props only; lab safety tangent.", price: 0.008, currency: "BTC" },
{ name: "Nano-lattice bandage roll", description: "Tactical-wrap roll with lattice weave claims — IFAK-adjacent staging prop.", price: 0.031, currency: "XMR" },
{ name: "Hormone whisperer lozenges", description: "Wild claims section — annotate red flags.", price: 42, currency: "USD" },
{ name: "Deep-sleep coffin pod (mini)", description: "Showpiece prop; ergonomics vs marketing photos.", price: 1.12, currency: "BTC", limited: true },
{ name: "Bio-firewall nasal gel", description: "Saline-forward gel marketed as bio-firewall — novelty wellness SKU with aggressive copy.", price: 0.006, currency: "ETH" },
]),
...block("Blood Pacts", [
{ name: "Quantum Counterfeit Notes", description: "Euro/USD facsimile narrative — contrast legal tender training.", price: 1.25, currency: "ETH", limited: true },
{ name: "QuantumForged Euros brick", description: "UV-reactive novelty brick facsimile — training prop for banknote exam teams.", price: 2.4, currency: "BTC" },
{ name: "Wash-trade tutorial ledger", description: "Ledger skinsheet pack demonstrating wash arcs — compliance training desks only.", price: 350, currency: "USD" },
{ name: "Tornado nostalgia mixer tile", description: "Ceramic coaster etched with retro tumbler motif — office lore for chain-hopping traders.", price: 0.018, currency: "XMR" },
{ name: "Bearer bond hologram folio", description: "Hologram theatre for verifying embossing vs phishing scans.", price: 0.055, currency: "BTC" },
{ name: "Flash-loan bedtime story PDF", description: "Illustrated DeFi risk fable — onboarding gift for desk traders; watermarked PDF drop.", price: 0.002, currency: "ETH" },
{ name: "OTC desk stress toy", description: "Squeeze toy shaped like a bid/ask spread arrow.", price: 19, currency: "USD" },
{ name: "Ponzi pyramid desk lamp", description: "Conversation starter for MLM vs crypto scams.", price: 0.009, currency: "BTC" },
{ name: "ISO-4217 mood ring set", description: "Currency-code jewelry — macroeconomics icebreaker.", price: 0.014, currency: "ETH" },
{ name: "Dark-pool goggles (UV)", description: "UV-party wraparounds with liquidity-pool etch — con-floor flex piece.", price: 76, currency: "USD" },
{ name: "Satoshi séance board", description: "Ouija-but-for-txids gag merch for history-of-Bitcoin week.", price: 0.022, currency: "XMR" },
{ name: "Rug-pull rip cord keychain", description: "Pull cord plays airhorn.wav — memes in risk lectures.", price: 12, currency: "USD" },
{ name: "Synthetic stablecoin snow globe", description: "Glitter settles slowly — talk peg mechanics.", price: 0.033, currency: "ETH" },
{ name: "Wire-instructions rubber stamp", description: "Rubber stamp of a phishing wire template — redact exercise.", price: 28, currency: "USD" },
{ name: "Credit-default swap aromatherapy", description: "Scented candles named after 2008 instruments — dark humor.", price: 0.004, currency: "BTC" },
]),
...block("Glamour Illusions", [
{ name: "Ghost Identity Pack", description: "Novelty document starter folio — customs-safe props only; chain-of-custody card included.", price: 3.8, currency: "BTC", limited: true },
{ name: "Burner SSN bingo card", description: "Bingo of invalid patterns; teaches checksum thinking.", price: 0.012, currency: "ETH" },
{ name: "Deepfake voice coupon (fake)", description: "Coupon promising cloned voice — discuss consent frameworks.", price: 54, currency: "USD" },
{ name: "Rubber face mesh MVP", description: "Theatrical mask — biometrics vs presentation attack discussion.", price: 0.19, currency: "XMR" },
{ name: "Nom de guerre generator dial", description: "Spinner toy producing alias suggestions — OPSEC naming.", price: 22, currency: "USD" },
{ name: "PGP key birthday card", description: "Paper card with mini public key block — party trick.", price: 0.005, currency: "BTC" },
{ name: "SIM-swap panic button (prop)", description: "Big red prop — carrier escalation roleplay.", price: 15, currency: "USD" },
{ name: "Synthetic genealogy tome", description: "Fake family tree book for social-engineering awareness.", price: 0.041, currency: "ETH" },
{ name: "Iris-print latte art stencil", description: "Coffee stencil of an iris — biometrics humor.", price: 9, currency: "USD" },
{ name: "Deadname incinerator USB shell", description: "Empty USB case labeled dramatically — data hygiene talk.", price: 0.017, currency: "XMR" },
{ name: "Notary cosplay embosser", description: "Manual embosser with comic sans seal — trust UX jokes.", price: 31, currency: "USD" },
{ name: "Ghost resume parchment", description: "Aged paper stock for redacted CV workshop.", price: 0.008, currency: "BTC" },
{ name: "Witness protection hoodie", description: "Blank hoodie with detachable name tag — anonymity chat.", price: 0.024, currency: "ETH" },
{ name: "Forged signature practice pad", description: "Legal-only handwriting exercise pad — anti-fraud angle.", price: 17, currency: "USD" },
]),
...block("Ward Enchantments", [
{ name: "ZeroDay Exploit Kit (sandbox)", description: "Lab-only PoC bundle narrative — legal use disclaimers printed on sleeve.", price: 12.5, currency: "ETH", limited: true },
{ name: "Darknet VPN Router", description: "Hardware VLAN folklore; compare to real router hardening checklists.", price: 0.5, currency: "XMR" },
{ name: "Air-gapped Faraday lunchbox", description: "Metal mesh tin for phones — teaches Faraday basics.", price: 44, currency: "USD" },
{ name: "EDR evasion board game", description: "Roll dice to patch telemetry — tabletop IR prep.", price: 0.026, currency: "BTC" },
{ name: "Tor-shaped stress squishy", description: "Slow-rise foam onion — desk lounge swag for relay operators.", price: 11, currency: "USD" },
{ name: "Memory-safe tea cozy", description: "Knitted cozy labeled no buffer overflows here.", price: 0.013, currency: "ETH" },
{ name: "ROP-chain friendship bracelet", description: "Stainless charms stamped with gadget glyphs — wear-stack for con-floor insiders.", price: 7, currency: "USD" },
{ name: "Purple-team piñata", description: "Filled with paper findings slips — team-building prop.", price: 33, currency: "USD" },
{ name: "Canary token confetti cannon", description: "Party cannon shoots paper canary strings — debut alerting.", price: 0.021, currency: "XMR" },
{ name: "SIEM-themed scented candle", description: "Smells like log rotation — joke SKU for SOC night shift.", price: 18, currency: "USD" },
{ name: "Firewall prayer candle", description: "Saints of iptables — discuss faith vs config management.", price: 0.004, currency: "BTC" },
{ name: "Quantum-safe bumper sticker", description: "Bumper sticker pack hyping PQC migration timelines.", price: 0.009, currency: "ETH" },
{ name: "Bug-bounty bingo night kit", description: "Cards with OWASP categories — socialize triage vocabulary.", price: 26, currency: "USD" },
{ name: "Yubikey trench coat lining", description: "Sew-in loops for 12 keys — physical key mgmt humor.", price: 0.038, currency: "BTC" },
{ name: "Password-spray supersoaker (empty)", description: "Bright plastic supersoaker — discuss rate limits metaphorically.", price: 14, currency: "USD" },
{ name: "Red-team nerf darts (foam)", description: "Foam darts tagged lateral movement — safe play fights.", price: 0.006, currency: "XMR" },
]),
...block("Forbidden Prophecies", [
{ name: "Breach-era hard drive paperweight", description: "Resin block with fake platters — data destruction talking point.", price: 0.016, currency: "BTC" },
{ name: "CSV of emotions (parody)", description: "Joke spreadsheet about feelings — privacy vs oversharing.", price: 3, currency: "USD" },
{ name: "Anonymized pet photos dataset", description: "Synthetic dog shots, metadata-stripped tarball — ML sandbox starter.", price: 0.011, currency: "ETH" },
{ name: "Pastebin snowshoes", description: "Foam snowshoes with expiring URL stickers — opsec metaphor.", price: 55, currency: "USD" },
{ name: "Doxxing dodgeball (foam)", description: "Foam stress ball stenciled PII — conference giveaway for privacy talks.", price: 12, currency: "USD" },
{ name: "Hash-slinging souvenir spatula", description: "Kitchen spatula etched with SHA-256 joke.", price: 0.007, currency: "BTC" },
{ name: "Journalists USB condom charm", description: "Tiny rubber USB blocker on keyring — supply-chain hygiene.", price: 8, currency: "USD" },
{ name: "DLC for older leaks (empty case)", description: "Empty steel case promising expansion packs — hype satire.", price: 0.029, currency: "XMR" },
{ name: "Redaction marker stadium pack", description: "Black markers labeled for FOIA fantasy workshops.", price: 19, currency: "USD" },
{ name: "Telemetry piñata (no network)", description: "Offline piñata with paper events — logging trivia.", price: 27, currency: "USD" },
{ name: "GDPR meditation tape", description: "Cassette of white noise labeled right to be forgotten.", price: 0.005, currency: "ETH" },
{ name: "Metadata shedding lint roller", description: "Gag lint roller removes EXIF — teach real exiftool after.", price: 6, currency: "USD" },
{ name: "Leak-themed escape room clue pack", description: "Chain-of-custody puzzle cards for escape-room operators — sealed deck.", price: 0.02, currency: "BTC" },
{ name: "Ransom note magnetic poetry", description: "Fridge magnets of cliché ransom phrases — decrypt jokes.", price: 15, currency: "USD" },
]),
...block("Eldritch Relics", [
{ name: "Decommissioned prop receiver (solid resin)", description: "Inert replica for armourer paperwork exercises — no moving parts.", price: 0.32, currency: "XMR", limited: true },
{ name: "Orange-tip training carbine (airsoft)", description: "Clear plastic training piece — jurisdiction checklist included.", price: 199, currency: "USD" },
{ name: "Ballistic gel dessert mold", description: "Silicone mold shaped like gel block — baking + terminal ballistics pun.", price: 24, currency: "USD" },
{ name: "Blade geometry slide rule", description: "Plastic slide rule for grind angles — metallurgy intro.", price: 0.014, currency: "ETH" },
{ name: "Non-firing museum rack mount", description: "Wall mount for decommissioned props — discuss secure storage law.", price: 48, currency: "USD" },
{ name: "Rubber training bayonet", description: "Soft bayonet for stage combat class.", price: 32, currency: "USD" },
{ name: "Blueprints wall art (demil)", description: "Poster schematics with demilled watermark — ITAR conversation.", price: 0.018, currency: "BTC" },
{ name: "Snap-cap choir set", description: "Harmless snap caps for chorus-line dry-fire drills (supervised).", price: 41, currency: "USD" },
{ name: "Range officer clipboard folio", description: "Clipboard with safety checklist prompts.", price: 17, currency: "USD" },
{ name: "Kevlar-thread friendship bracelet", description: "Braided accent band — marketing references aramid; tensile spec on vendor sheet.", price: 0.009, currency: "XMR" },
]),
...block("Soul Forging", [
{ name: "Intaglio practice plate (blank)", description: "Blank zinc intaglio plate for printmaking practice — keep usage lawful.", price: 67, currency: "USD" },
{ name: "UV counterfeit reveal postcard set", description: "Postcards with hidden UV layers — doc verification labs.", price: 0.012, currency: "BTC" },
{ name: "Microprint magnifier chain", description: "Jeweler loupe necklace — inspect fine printing legitimately.", price: 21, currency: "USD" },
{ name: "Hologram sticker starter pack", description: "generic shiny stickers — compare to banknote holograms.", price: 0.008, currency: "ETH" },
{ name: "Passport photo booth curtain (prop)", description: "Curtain fabric roll for mock booth setup.", price: 56, currency: "USD" },
{ name: "Raised-seal cosplay wax sticks", description: "Assorted wax sticks for hobby embossing — not for government documents.", price: 13, currency: "USD" },
{ name: "Typography-of-banknotes poster", description: "Serif anatomy poster for design-history class.", price: 0.015, currency: "XMR" },
{ name: "Frank Abagnale movie night kit", description: "Popcorn + discussion guide — fraud history framed responsibly.", price: 9, currency: "USD" },
{ name: "Watermark cotton paper sampler", description: "Sampler pack of cotton bond — conservation chemistry tangent.", price: 34, currency: "USD" },
{ name: "Forgery panic flowchart scroll", description: "Wall scroll for if you find a fake, then… decisions.", price: 0.006, currency: "BTC" },
{ name: "Embossing press desk toy", description: "Desktop lever press for foil hobby work — keep off official parchment.", price: 88, currency: "USD" },
{ name: "Counterfeit color-match Pantone joke book", description: "Parody swatch book — teach perceptual tricks.", price: 0.022, currency: "ETH" },
{ name: "Notarization rubber duck", description: "Duck with stamp hat — debug your trust assumptions.", price: 5, currency: "USD" },
]),
...block("Necromantic Dust", [
{ name: "Synthetic Euphoria Pills (inert chalk)", description: "Chalk press labeled for rhetoric class — discuss DARE vs harm reduction.", price: 0.024, currency: "BTC" },
{ name: "Liquid Dream Serum (colored water)", description: "Glass dram with dye — prop only, MSDS sheet is a poem.", price: 0.18, currency: "XMR", limited: true },
{ name: "Round-bottom flask stress orb", description: "Squishy flask — lab safety mascot.", price: 10, currency: "USD" },
{ name: "Periodic table shower curtain", description: "Actually useful chemistry dorm decor.", price: 29, currency: "USD" },
{ name: "Nitrogen dewar shot glass (steel)", description: "Steel mini cup shaped like dewar — LN₂ jokes, not included.", price: 0.011, currency: "ETH" },
{ name: "Fume hood sash height sticker pack", description: "Vinyl stickers reminding sash position — lab tours.", price: 7, currency: "USD" },
{ name: "GHS pictogram cookie cutters", description: "Bake hazard-symbol cookies — safety comms.", price: 16, currency: "USD" },
{ name: "Precursor-themed spice labels (joke)", description: "Labels for cumin jar saying not a precursor — legal humor.", price: 0.004, currency: "BTC" },
{ name: "Affinity chromatography plush column", description: "Stuffed toy shaped like a column — biochem softness.", price: 37, currency: "USD" },
{ name: "CRC Handbook coaster set", description: "Coasters printed with fake constants — trivia nights.", price: 0.019, currency: "XMR" },
{ name: "Ampoule snap practice kit (sugar)", description: "Sugar ampoules for snapping motion drills — no glass cuts.", price: 23, currency: "USD" },
{ name: "Titration mood light", description: "Lamp that shifts color like pH — aesthetics of indicators.", price: 44, currency: "USD" },
{ name: "Beaker creature plush", description: "Monster made of stacked beakers — PPE still required.", price: 0.013, currency: "ETH" },
{ name: "Lab notebook with waterproof lies", description: "Notebook advertising indestructible claims — epistemology gag.", price: 18, currency: "USD" },
]),
...block("Fey Offerings", [
{ name: "Blue Raspberry Bubblegum brick", description: "Bulk gum for candy-market grid — sticker claims encrypted flavor.", price: 0.002, currency: "BTC" },
{ name: "Sour Watermelon wedge bag", description: "Sour belts in Mylar — discuss packaging OPSEC as metaphor.", price: 0.0015, currency: "BTC" },
{ name: "Mystery Mix Cryptobag", description: "Assorted odds; QR on label resolves to nutrition facts PDF.", price: 0.005, currency: "BTC", limited: true },
{ name: "Glow-in-the-Dark Taffy rope", description: "UV-reactive taffy for blacklight display case only.", price: 0.003, currency: "ETH" },
{ name: "Tor onion gummy mold", description: "Silicone mold shaped like Tor logo onions — make gummies legally.", price: 14, currency: "USD" },
{ name: "Monero-mint chocolate bar", description: "Dark-mint bar in foil printed with ring-sig artwork — ships cold-packed.", price: 0.007, currency: "XMR" },
{ name: "Hash-brownie mix (literal potato)", description: "Potato hash brown mix — pun SKU for blockchain week.", price: 8, currency: "USD" },
{ name: "PGP-signed lollipop", description: "Lollipop with wrapper showing fake ASCII armor — unwrap carefully.", price: 0.004, currency: "BTC" },
{ name: "Dead-drop jawbreaker", description: "Layers of color like nested containers — tradecraft candy metaphor.", price: 6, currency: "USD" },
{ name: "Honey-pot honey jar", description: "Real jar of honey labeled honeypot — Infosec picnic.", price: 17, currency: "USD" },
{ name: "Zero-knowledge nougat", description: "Nougat bar claiming you taste it but cant prove it — ZKP joke.", price: 0.006, currency: "ETH" },
{ name: "Bitcoin-orange rock candy geode", description: "Rock candy geode dyed BTC orange — geology + crypto pun.", price: 11, currency: "USD" },
{ name: "Cold-storage ice pop molds", description: "Popsicle molds shaped like hardware wallets — summer syllabus.", price: 13, currency: "USD" },
{ name: "Mixer-themed cotton candy floss sugar", description: "Pastel sugars labeled hop1/hop2/hop3 — sweet talk about mixers.", price: 20, currency: "USD" },
]),
...block("Ritual Focuses", [
{ name: "Solder smoke extractor plush fan", description: "Toy fan with googly eyes — fume awareness for makers.", price: 36, currency: "USD" },
{ name: "JTAG duck debugger", description: "Rubber duck with labeled test points — hardware RE humor.", price: 0.017, currency: "BTC" },
{ name: "TPM tamper-evident sticker sheet", description: "Destructive void labels for chassis sealing — audits love these.", price: 12, currency: "USD" },
{ name: "Flipper Zero cosplay foam", description: "Foam replica — discuss responsible RF rules.", price: 0.01, currency: "ETH" },
{ name: "Airgap Ethernet cable (sewn shut)", description: "Cable sewn closed — literal air gap joke.", price: 9, currency: "USD" },
{ name: "SD-card sorting tray", description: "3D-print tray for forensic imaging class prop sorting.", price: 25, currency: "USD" },
{ name: "Logic analyzer hair clip (prop)", description: "Hair clip shaped like LA probes — signal integrity vibes.", price: 7, currency: "USD" },
{ name: "Raspberry Pi oven mitt", description: "Oven mitt with GPIO pinout print — kitchen cluster jokes.", price: 18, currency: "USD" },
{ name: "KVM switch fidget cube", description: "Cube with tiny clicky KVM toggles — focus toy for admins.", price: 0.014, currency: "XMR" },
{ name: "PDU power-strip storybook", description: "Kids book about not overloading circuits — datacenter bedtime.", price: 15, currency: "USD" },
]),
...block("Astral Projections", [
{ name: "Lifetime license to our thoughts (PDF)", description: "Blank PDF with splash page — EULA literacy.", price: 0.001, currency: "ETH" },
{ name: "NFT of this paragraph (screenshot)", description: "PNG screenshot — discuss provenance vs possession.", price: 0.008, currency: "BTC" },
{ name: "Vaporware roadmap deck template", description: "Keynote template full of vague quarters.", price: 5, currency: "USD" },
{ name: "SaaS subscription to nothing", description: "Stripe-looking receipt for $0/mo — dark patterns talk.", price: 0, currency: "USD" },
{ name: "Cracked screen wallpaper pack", description: "PNG wallpapers — social engineering bait awareness.", price: 3, currency: "USD" },
{ name: "ISO27001 compliance cat video", description: "MP4 of cat knocking audit binder off desk.", price: 0.003, currency: "XMR" },
{ name: "Phishing email mad-libs HTML", description: "Template with blanks for grammar of scams.", price: 0.006, currency: "BTC" },
{ name: "API rate-limit lullaby MP3", description: "Lo-fi beats for waiting on 429 responses.", price: 7, currency: "USD" },
{ name: "Kubernetes yaml horoscope", description: "Text files mapping star signs to misconfig jokes.", price: 0.004, currency: "ETH" },
{ name: "Dark-mode-only whitepaper (empty)", description: "White PDF named ironically — accessibility tangent.", price: 2, currency: "USD" },
]),
...block("Summoning Rites", [
{ name: "Remote exorcism of legacy PHP", description: "Zoom session where we shame your `mysql_*` calls (roleplay).", price: 0.09, currency: "BTC" },
{ name: "Tarot for TLS certificate expiry", description: "Performative reading of cert timelines — automate after.", price: 45, currency: "USD" },
{ name: "On-site donut-driven threat modeling", description: "Bring donuts, draw stride threats on napkins.", price: 120, currency: "USD" },
{ name: "ASMR packet capture whisper stream", description: "1hr ambient `.pcap` readout — sleep for nerds.", price: 0.016, currency: "XMR" },
{ name: "Corporate values alignment séance", description: "Parody workshop aligning synergy with firewall rules.", price: 0.027, currency: "ETH" },
{ name: "Retrospective on your retrospective", description: "Facilitator block booking — billed in 0.25 agile-day increments.", price: 88, currency: "USD" },
{ name: "Perl poetry code review", description: "Critique of badly written haiku in Perl — nostalgia service.", price: 0.012, currency: "BTC" },
{ name: "Blockchain-of-custody bakery pickup", description: "We sign a paper chain while you pick up muffins.", price: 35, currency: "USD" },
]),
];
function dedupeById(products: ProductDraft[]): ProductDraft[] {
const seen = new Set<string>();
const out: ProductDraft[] = [];
for (const p of products) {
if (seen.has(p.id)) continue;
seen.add(p.id);
out.push(p);
}
return out;
}
export const SHOP_PRODUCTS: ShopProduct[] = dedupeById(ALL_BLOCKS).map((p) => ({
...p,
sellerId: sellerIdForProduct(p.id),
}));
export function shopProductsForSeller(sellerId: string): ShopProduct[] {
return SHOP_PRODUCTS.filter((p) => p.sellerId === sellerId);
}
export const SHOP_PRODUCT_COUNT = SHOP_PRODUCTS.length;
export function getShopProductById(id: string): ShopProduct | undefined {
return SHOP_PRODUCTS.find((p) => p.id === id);
}
export function shopCategoryCounts(): { name: string; count: number; icon: string }[] {
const icons: Record<string, string> = {
"Alchemical Elixirs": "🧪",
"Blood Pacts": "🩸",
"Glamour Illusions": "🎭",
"Ward Enchantments": "🛡️",
"Forbidden Prophecies": "📜",
"Eldritch Relics": "🗡️",
"Soul Forging": "⚒️",
"Necromantic Dust": "⚱️",
"Fey Offerings": "🍄",
"Ritual Focuses": "🔮",
"Astral Projections": "✨",
"Summoning Rites": "🕯️",
};
const m = new Map<string, number>();
for (const p of SHOP_PRODUCTS) {
m.set(p.category, (m.get(p.category) ?? 0) + 1);
}
return [...m.entries()]
.map(([name, count]) => ({ name, count, icon: icons[name] ?? "⬡" }))
.sort((a, b) => a.name.localeCompare(b.name));
}
export function featuredShopProducts(n = 8): ShopProduct[] {
return [...SHOP_PRODUCTS].sort((a, b) => (b.limited ? 1 : 0) - (a.limited ? 1 : 0) || hashId(a.id) - hashId(b.id)).slice(0, n);
}