X.com POAP Dispenser

Twitter bot validates coded image tweets and lets users log in to claim unique POAP mint links now!

X.com POAP Dispenser

Created At

ETHGlobal Buenos Aires

Project Description

Community moments deserve more than a post—they deserve to be kept, remembered, and collected. Our project transforms social‑shared experiences into on‑chain souvenirs by turning posts into verifiable proof of presence. Whether it’s a concert, a community meetup, or a spontaneous street moment, participants don’t just share their memories online—they mint them into POAPs tied to their identity. The result is a bridge between lived experiences, social expression, and collectible digital artefacts.

Instead of claiming a POAP passively, we anchor each claim to user‑generated content. The memory itself becomes the ticket.

User scans QR

User logs in with Twitter

System assigns a unique claim code to that Twitter user

User posts a tweet including code + image

Bot monitors tweets for valid posts

Backend verifies tweet authenticity + code ownership + media

User is authorized to mint a unique POAP linked to their account

Why it matters :

Links real participation to real content converting social proof into on‑chain proof.

Rewards storytelling instead of passive claiming

Turns memories into permanent digital artifacts

By making experiences collectible, we give communities a new way to share, authenticate, and remember the moments that matter.

How it's Made

We built xbot as a full-stack TypeScript app where a single codebase orchestrates the Twitter bot, the admin console, and the claim experience. The frontend is Next.js 16 App Router + React 19 + Tailwind CSS, backed by PostgreSQL via Prisma. Authentication is handled with NextAuth.js using Twitter OAuth 2.0, so the same Twitter identity is used both to log into the claim UI and to link back to the tweets the bot processed.

On the backend, we keep things very explicit and boring-on-purpose. A set of API routes under /api/admin exposes configuration, stats, and CSV exports; /api/deliveries serves the authenticated user’s POAP deliveries; and /api/cron/process-tweets is the brain of the bot. That cron endpoint is hit by Vercel’s scheduled functions, protected by a CRON_SECRET check so it can’t be called publicly. On each run, the bot loads the current config from Postgres (hashtag, required code, POAP event, reply template), calls Twitter API v2 to pull eligible tweets, and then talks to the POAP API to reserve unique mint links before persisting a “delivery” record via Prisma. This cleanly decouples “found a tweet” from “user actually clicked and claimed”.

The web claim flow and admin UI are just thin React layers on top of those APIs. The claim page uses NextAuth session data to fetch deliveries for the logged-in Twitter account and renders a simple state machine: no deliveries / pending / ready-to-claim. The admin dashboard lives under /admin and is built as small Tailwind-styled components on top of /api/admin/config, /api/admin/stats, and /api/admin/deliveries so organizers can tune the bot and export results without touching code. Tests are wired with Jest and Playwright so we can exercise both the bot logic and the main flows end-to-end, and everything is deployed on Vercel with a single vercel.json wiring the cron job.

background image mobile

Join the mailing list

Get the latest news and updates