</poke ai>
Point your camera at any Pokémon card: ID, prices, pack rips. App Store.

App Store
live
provably fair
commit-reveal pack engine
27+
edge functions
zero oversell
atomic pack inventory
SPECIFICATIONS
| ROLE | COFOUNDER |
|---|---|
| YEAR | 2025 |
| TYPE | iOS APP |
| STATUS | LIVE |
| STACK | swiftui · ios 17+ · swiftdata · supabase · deno edge functions · postgresql · storekit 2 · stripe +5 more |
| LINKS | [live ↗][app store ↗] |
| AVAILABILITY | App Store + web |
“Pokemon TCG collectors are stuck between multi-TCG apps that go a mile wide and an inch deep on Pokemon coverage, and price-aggregator websites that aren't built for a camera-first workflow.”
Live on the App Store.An iOS Pokemon TCG companion: point your camera at any card and Poke AI identifies it in seconds, pulls raw and graded prices (PSA / CGC / BGS / SGC), saves it to a vault, builds format-legal decks, and pushes alerts when the market moves.
== WHAT IS THIS ==
Live on the App Store. An iOS Pokemon TCG companion: point your camera at any card and Poke AI identifies it in seconds, pulls raw and graded prices (PSA / CGC / BGS / SGC), saves it to a vault, builds format-legal decks, and pushes alerts when the market moves. Now with digital pack openings · rip a pack in-app and the real card ships to your door · backed by provably-fair commit-reveal randomness, an earned-coins layer, and a monthly card sweepstakes. Pokemon-only depth where multi-TCG competitors run shallow.
== </the problem> ==
Pokemon TCG collectors are stuck between multi-TCG apps that go a mile wide and an inch deep on Pokemon coverage, and price-aggregator websites that aren't built for a camera-first workflow. Identifying a card, checking raw + graded comps, tracking it over time, and actually acquiring new cards takes five apps and a dozen browser tabs.
== </my approach> ==
Built an iOS-first product that compresses the whole collector loop · identify, value, vault, watch, and acquire · into one app. Pokemon-only depth means every set, every variant, every graded tier from PSA / CGC / BGS / SGC. SwiftUI front, Supabase + 27 Deno edge functions back, Claude vision for recognition, and a provably-fair digital-pack engine that ships real cards. Live on the App Store.
== </the story> ==
Poke AI is an iOS Pokemon TCG companion, live on the App Store, built for collectors who want depth. Multi-TCG apps (Cardly, Ludex, Collectr) all have visibly thin Pokemon coverage. Poke AI goes the other way: Pokemon-only, end-to-end.
Point the camera at any card and recognition runs through a Claude vision pipeline that aligns, identifies, and reveals the exact set + number in seconds. The card detail page shows raw market price plus PSA, CGC, BGS, and SGC graded tiers, set context, and live trend data. Save it to your vault, build format-legal Standard / Expanded decks, and Poke AI starts watching the market for you · push alerts fire when prices move past thresholds you care about, and the Discover tab surfaces what's pumping across the catalog.
The headline addition is pack openings. Buy a sealed digital pack in one of five tiers, tap to rip it open in a holo reveal ceremony, and the real card · sourced and vaulted · ships to your door. The pulls are provably fair: each pool is committed to a published hash before sales open, and the seed is revealed after the pool depletes so anyone can recompute the draw. Ripping packs and scanning cards earn coins, an engagement currency spent only on cosmetics, and every month a real near-mint Base Set Meowth goes to one collector through a sweepstakes with a free postal entry route.
I'm the full-scope engineer: SwiftUI views, view models, the design system, the Supabase backend, 27+ edge functions, schema, the payments rails, and the Next.js marketing site at pokeaiapp.com. A deliberate payment-rail split runs underneath · StoreKit 2 for the digital subscription, Stripe Apple Pay for physical packs and shipping, because Apple's Guideline 3.1.1 forbids IAP for physical goods. Visual sibling to Sentinel · same restraint and motion language, retuned for collector content with a black-to-grey gradient and a holo effect on rare-card surfaces.
== </architecture> ==
iOS frontend is SwiftUI targeting iOS 17+ with the Observation framework. Root state lives in a single @Observable AppState holding services, subscription state, and connectivity. ViewModels use ObservableObject + @Published for compatibility. A ServiceFactory returns either Live (Supabase-backed) or Mock implementations based on whether config keys are present · Views always bind to a protocol, never to a literal. SwiftData persists the vault via a @ModelActor data store for thread-safe writes.
Recognition is a Claude Sonnet vision pipeline with tool-use and ephemeral prompt caching, fronted by a SHA-256 image cache so byte-identical re-scans return in ~200ms, and a four-tier fallback (exact local match → name+set+number → image lookup → live pricing-API enrichment) that backfills the catalog on demand rather than bulk-ingesting it.
Backend runs on Supabase in eu-central-1: PostgreSQL with Row Level Security, 27+ Deno Edge Functions for scan recognition, price aggregation, pack rips, Stripe webhooks, coins, and shipping, plus Realtime channels for alert delivery. The pack inventory is the interesting bit · concurrent rips claim cards atomically with SELECT … FOR UPDATE SKIP LOCKED, so a 25-card pool hit by 50 simultaneous rips sells exactly 25 and zero overselling, no distributed lock needed. Randomness is commit-reveal (published pool hash + revealed seed), not on-chain. Pricing comes from PokemonPriceTracker with a JustTCG fallback, routed through a single rate-limited client (token bucket + priority queue + dual-key failover). APNs handles price-threshold push; PostHog handles analytics.
Payments split by rail: StoreKit 2 drives the subscription and entitlement (mirrored into Supabase for cross-device), while packs and shipping run on Stripe with Apple Pay via PassKit, idempotent client intents, and the Stripe webhook as the source of truth for payment state. The marketing site is Next.js 16 on Vercel sharing the same Supabase project.
== </key features> ==
Camera-first scanning
Claude vision pipeline with a SHA-256 image cache returns the exact set and card number in seconds.
Raw + graded pricing
Live market prices across raw and PSA / CGC / BGS / SGC graded tiers, dual-source with failover.
Pack openings → real cards
Rip a digital pack in a holo reveal ceremony; the real card ships to your door. Five tiers, Stripe Apple Pay.
Provably-fair pulls
Each pool is committed to a published hash and the seed revealed after depletion · recompute any draw offline. Atomic inventory means zero overselling under concurrent rips.
Vault, decks + alerts
SwiftData vault with cross-device sync, format-legal deck building, and APNs price alerts on thresholds you set.
Earned-coins layer
Coins from rips, scans, and referrals · spent only on cosmetics, never sold, keeping the app clean of Apple's physical-goods IAP rule.
== </key decisions> ==
DECISION 01
The biggest decision was Pokemon-only depth instead of multi-TCG breadth. Every multi-TCG competitor sacrifices Pokemon coverage to chase Magic and Yu-Gi-Oh. Going narrow lets Poke AI cover every set, every variant, every graded tier with the detail collectors actually want.
DECISION 02
Provably-fair commit-reveal instead of blockchain. The pack mechanic needs to be auditable, but Chainlink VRF and on-chain settlement add gas, latency, and complexity a retail collectibles app doesn't need. Committing each pool to a public hash and revealing the seed afterward lets any user recompute the pull sequence offline · all the fairness, none of the chain.
DECISION 03
Coins are earned-only, never sold. There is deliberately no "buy coins" surface anywhere in the app. Coins come from ripping packs, scanning, subscribing, and referrals, and they're spent only on digital cosmetics. That keeps the app clean of Apple's Guideline 3.1.1 trap where IAP currency funds physical goods downstream, and it makes the loop about engagement rather than a second checkout.
DECISION 04
Split the payment rails on purpose. Subscriptions go through StoreKit 2 because Apple requires IAP for digital features; physical packs and shipping go through Stripe Apple Pay because Apple forbids IAP for physical goods. The two never cross. Underneath, the mock service layer is a feature, not a workaround · every view binds to a protocol and ServiceFactory swaps Live in only when keys are present, so screenshots, demos, and dev all run against deterministic fixtures while production hits the live backend with zero view changes.
== </what i learned> ==
Atomic Postgres locking (SELECT … FOR UPDATE SKIP LOCKED) is enough to guarantee no oversell under concurrent load · no distributed lock or queue needed for a retail-scale drop.
Splitting payment rails by Apple's own rules (StoreKit for digital, Stripe for physical) is the difference between an approved app and a rejected one · design the boundary in from day one.
Provably-fair commit-reveal buys all the trust of on-chain randomness with none of the gas, latency, or complexity. Match the mechanism to the product, not the hype.
swiftui · ios 17+ · swiftdata · supabase · deno edge functions · postgresql · storekit 2 · stripe · apns · posthog · claude vision · next.js · vercel
interactive demo · loads on demand
LIVE · pokeaiapp.com · App Store