This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
token-gated-economy/the-matrix
Replit Agent eb5dcfd48a
Some checks failed
CI / Typecheck & Lint (pull_request) Failing after 0s
task-29: Timmy as economic peer — Nostr identity, zap-out, vouching, engagement
1. TimmyIdentityService (artifacts/api-server/src/lib/timmy-identity.ts)
   - Loads nsec from TIMMY_NOSTR_NSEC env var at boot (bech32 decode)
   - Generates and warns about ephemeral key if env var absent
   - sign(EventTemplate) → finalizeEvent() with Timmy's key
   - encryptDm(recipientPubkeyHex, plaintext) → NIP-04 nip04.encrypt()
   - Logs npub at server startup

2. ZapService (artifacts/api-server/src/lib/zap.ts)
   - Constructs NIP-57 zap request event (kind 9734), signs with Timmy's key
   - Pays via lnbitsService.payInvoice() if bolt11 provided (stub-mode aware)
   - Logs every outbound event to timmy_nostr_events audit table
   - maybeZapOnJobComplete() wired in jobs.ts after trustService.recordSuccess()
   - Config: ZAP_PCT_DEFAULT (default 0 = disabled), ZAP_MIN_SATS (default 10)
   - Only fires for trusted/elite tier partners when ZAP_PCT_DEFAULT > 0

3. Engagement engine (artifacts/api-server/src/lib/engagement.ts)
   - Configurable cadence: ENGAGEMENT_INTERVAL_DAYS (default 0 = disabled)
   - Queries nostrIdentities for trustScore >= 50 AND lastSeen < threshold
   - Generates personalised DM via agentService.chatReply()
   - Encrypts as NIP-04 DM (kind 4), signs with Timmy's key
   - Logs to timmy_nostr_events; publishes to NOSTR_RELAY_URL if set
   - First run delayed 60s after startup to avoid cold-start noise

4. Vouching endpoint (artifacts/api-server/src/routes/identity.ts)
   - POST /api/identity/vouch: requires X-Nostr-Token with elite tier
   - Verifies optional Nostr event signature from voucher
   - Records relationship in nostr_trust_vouches table
   - Applies VOUCH_TRUST_BOOST (20 pts) to vouchee's trust score
   - GET /api/identity/timmy: public endpoint returning npub + zap count

5. DB schema additions (lib/db/src/schema/)
   - timmy_nostr_events: audit log for all outbound Nostr events
   - nostr_trust_vouches: voucher/vouchee social graph with boost amount
   - Tables created in production DB via drizzle-kit push

6. Frontend identity card (the-matrix/)
   - #timmy-id-card: fixed bottom-right widget with Timmy's npub + zap count
   - timmy-id.js: initTimmyId() fetches /api/identity/timmy on load
   - Npub shortened (npub1xxxx...yyyyyy), click-to-copy with feedback
   - Refreshes every 60s to show live zap count
   - Wired into main.js on firstInit
2026-03-19 19:27:13 +00:00
..

Timmy Tower World

A Three.js 3D visualization of the Timmy agent network. Agents appear as glowing icosahedra connected by lines, pulsing as they process jobs. A matrix-rain particle effect fills the background.

Quick start

npm install
npm run dev      # Vite dev server with hot reload → http://localhost:5173
npm run build    # Production bundle → dist/
npm run preview  # Serve dist/ locally

Configuration

Set these in a .env.local file (not committed):

VITE_WS_URL=ws://localhost:8080/ws/agents

Leave VITE_WS_URL unset to run in offline/demo mode (agents animate but receive no live updates).

Adding custom agents

Edit one file only: js/agent-defs.js

export const AGENT_DEFS = [
  // existing agents …
  {
    id:        'zeta',      // unique string — matches WebSocket message agentId
    label:     'ZETA',      // displayed in the 3D HUD
    color:     0xff00aa,    // hex integer (0xRRGGBB)
    role:      'observer',  // shown under the label sprite
    direction: 'east',      // cardinal facing direction (north/east/south/west)
    x:         12,          // world-space position (horizontal)
    z:         0,           // world-space position (depth)
  },
];

Nothing else needs to change. agents.js reads positions from x/z, and websocket.js reads colors and labels — both derive everything from AGENT_DEFS.

Architecture

js/
├── agent-defs.js   ← single source of truth: id, label, color, role, position
├── agents.js       ← Three.js scene objects, animation loop
├── effects.js      ← matrix rain particles, starfield
├── interaction.js  ← OrbitControls (pan, zoom, rotate)
├── main.js         ← entry point, rAF loop
├── ui.js           ← DOM HUD overlay (FPS, agent states, chat)
└── websocket.js    ← WebSocket reconnect, message dispatch

WebSocket protocol

The backend sends JSON messages on the agents channel:

type Fields Effect
agent_state agentId, state Update agent visual state
job_started agentId, jobId Increment job counter, pulse
job_completed agentId, jobId Decrement job counter
chat agentId, text Append to chat panel

Agent states: idle (dim pulse) · active (bright pulse + fast ring spin)

Stack

  • Three.js 0.171.0 — 3D rendering
  • Vite 5 — build + dev server
  • crypto.randomUUID() — secure client session IDs (no external library)