{"id":50316070,"url":"https://github.com/msitarzewski/prediction-space","last_synced_at":"2026-05-29T00:02:35.608Z","repository":{"id":341934758,"uuid":"1170414063","full_name":"msitarzewski/prediction-space","owner":"msitarzewski","description":"WebXR visualization of live Polymarket prediction markets. Gaze + pinch interaction for Apple Vision Pro and Quest. Three.js, zero build tools.","archived":false,"fork":false,"pushed_at":"2026-03-15T04:08:52.000Z","size":711,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-15T15:48:28.842Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msitarzewski.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-02T05:04:47.000Z","updated_at":"2026-03-15T04:08:56.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/msitarzewski/prediction-space","commit_stats":null,"previous_names":["msitarzewski/prediction-space"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/msitarzewski/prediction-space","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msitarzewski%2Fprediction-space","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msitarzewski%2Fprediction-space/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msitarzewski%2Fprediction-space/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msitarzewski%2Fprediction-space/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msitarzewski","download_url":"https://codeload.github.com/msitarzewski/prediction-space/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msitarzewski%2Fprediction-space/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33630999,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-29T00:02:32.386Z","updated_at":"2026-05-29T00:02:35.598Z","avatar_url":"https://github.com/msitarzewski.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Prediction Space\n\n**[Try it live](https://prediction-space.zerologic.com)**\n\nA WebXR visualization of live prediction markets from [Polymarket](https://polymarket.com). Walk through a 3D space of glowing spheres — each one a live market — sized by trading volume, colored by probability, and clustered by category. Built for Apple Vision Pro, Meta Quest, and desktop browsers.\n\n![Prediction Space](images/screen.png)\n\n## What It Does\n\nPrediction Space pulls live market data from Polymarket's API every 2 minutes and renders each active event as a sphere floating in 3D space:\n\n- **Size** reflects 24-hour trading volume (logarithmic scale)\n- **Color** maps probability to a red-green spectrum — high-confidence markets glow green, uncertain ones burn red\n- **Brightness** indicates activity — hot markets with surging volume are vivid and saturated, quiet ones fade into the background\n- **Position** groups markets by category (politics, crypto, sports, tech, science, culture, finance) in distinct 3D zones\n- **Near-resolution markets** drift toward the floor as their end date approaches\n- **Volume spikes** trigger a 5-second pulsing animation when a market's 24h volume jumps 50%+\n\nClick any sphere to see the full breakdown: outcome probabilities as colored bars, trading volume, time to resolution, and a link to the market on Polymarket.\n\n## VR Interaction\n\nIn WebXR (Vision Pro, Quest, or any WebXR-capable headset):\n\n| Gesture | Action |\n|---|---|\n| **Look at a sphere** | Highlights it (scale + glow) |\n| **Pinch while looking at a sphere** | Opens a 3D detail panel |\n| **Pinch while looking away** | Dismisses the panel |\n| **Two-hand pinch: spread/contract** | Move the scene forward/backward |\n| **Two-hand pinch: move up/down** | Move the scene vertically |\n| **Two-hand pinch: move left/right** | Move the scene laterally |\n| **Two-hand pinch: rotate** | Spin the scene around its center |\n\nA gaze reticle (small ring) follows your head direction so you always know where you're pointing. Hand tracking is used for pinch detection — no controllers required.\n\nOn desktop, orbit controls let you click-drag to rotate, scroll to zoom, and click spheres for the HTML detail panel.\n\n## Architecture\n\nZero dependencies on the client. No build step, no bundler — just ES modules served directly with an import map pointing to Three.js on CDN.\n\n```\nprediction-space/\n  index.html          # Single-page app with inline styles and import map\n  server.js           # Node.js server: static files + Polymarket API proxy\n  src/\n    main.js           # Animation loop, data polling, wires everything together\n    scene.js          # Three.js scene, camera, lighting, bloom, XR controllers + hands\n    visualization.js  # Market data → 3D spheres (sizing, coloring, layout, animation)\n    interaction.js    # Gaze tracking, pinch selection, 3D panel, two-hand gestures\n    data/\n      polymarket.js   # Polymarket Gamma API client with polling + change detection\n```\n\n**Server** (`server.js`): A lightweight Node.js HTTP server that serves static files and proxies requests to the Polymarket Gamma API (to avoid CORS issues). Includes rate limiting (30 req/min per IP), path whitelisting, and blocks sensitive files. Designed to sit behind a reverse proxy (Caddy, nginx) for TLS.\n\n**Scene** (`scene.js`): Sets up the Three.js renderer with WebXR enabled, bloom post-processing (UnrealBloomPass), orbit controls, atmospheric lighting (hemisphere + directional + point lights), a grid floor, and a starfield. Initializes XR controllers (indices 0-3 for standard + Vision Pro transient pointers) and hand tracking with `XRHandModelFactory`.\n\n**Visualization** (`visualization.js`): Transforms market events into `IcosahedronGeometry` spheres with glassy `MeshStandardMaterial`. Uses a golden-angle spiral layout within category zones, smooth position/scale lerping, distance-based label fading, and per-frame idle animations (bob + rotation). Detects volume spikes and triggers pulse effects.\n\n**Interaction** (`interaction.js`): Implements a gaze-first interaction model. In XR, raycasts from the camera's forward direction each frame for hover detection. Pinch events (via `selectstart` on all 4 controller indices) check the gazed target. The 3D detail panel is a canvas-textured plane with outcome bars rendered via Canvas 2D API — no HTML overlays (they don't work in VR). Two-hand pinch gestures track thumb-tip/index-finger-tip joint distances for zoom/pan/rotate with full 3-axis translation.\n\n**Data** (`polymarket.js`): Fetches from the Polymarket Gamma API, normalizes events with aggregated volumes across sub-markets, and handles binary Yes/No markets intelligently (uses `groupItemTitle` instead of generic \"Yes\"/\"No\" labels). Polls on an interval with change detection for volume spikes (\u003e50% increase) and price swings (\u003e10pp shift).\n\n## Running Locally\n\n```bash\nnode server.js\n```\n\nOpens on `http://localhost:8003`. To restrict CORS to a specific origin:\n\n```bash\nALLOWED_ORIGIN=https://yourdomain.com node server.js\n```\n\nFor WebXR testing you'll need HTTPS — put it behind a reverse proxy (Caddy, nginx) or generate self-signed certs for local development.\n\n## Tech\n\n- [Three.js](https://threejs.org/) r170 (via CDN import map)\n- WebXR Device API with `hand-tracking` optional feature\n- Polymarket Gamma API (proxied through the Node server)\n- Canvas 2D API for in-world text rendering\n- Zero client-side dependencies, zero build tools\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsitarzewski%2Fprediction-space","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsitarzewski%2Fprediction-space","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsitarzewski%2Fprediction-space/lists"}