Decentralized football gate payments & ticketing for the Tether Developers Cup. One app, two hackathon tracks:
- WDK — self-custodial Sepolia USDT wallet; real on-chain payments
- Pears Stack — Hyperswarm P2P for session sync and ticket transfer (no Reno Pay backend)
Money moves on-chain. Tickets move device-to-device over encrypted P2P. QR codes bootstrap the session only.
- Node.js 18+
- Android SDK (API 29+, compile 36) — see AGENTS.md
- Physical Android phone(s) — arm64 (e.g. Pixel 8a). Do not use Expo Go.
source scripts/android-env.sh # sets ANDROID_HOME, JAVA_HOMEgit clone <repo-url>
cd renopay
npm install --legacy-peer-deps
npm run generate:wdk # WDK worklet bundle
npm run pack:p2p # Hyperswarm P2P worklet bundleBuilds native dev client, installs via USB, forwards Metro:
source scripts/android-env.sh
npm run android:deviceRepeat on a second phone (set export ANDROID_SERIAL=<device-id> if both are plugged in).
Terminal 1 — Metro (leave running):
source scripts/android-env.sh
export REACT_NATIVE_PACKAGER_HOSTNAME=localhost
adb reverse tcp:8081 tcp:8081
npm startTerminal 2 — install native app (first time or after native/plugin changes):
source scripts/android-env.sh
npm run android:deviceOpen the renopay app (not Expo Go). Shake → Reload after JS-only edits.
Required after native plugin changes, app.json icons, stale native/JS mismatch, or missing bundles:
source scripts/android-env.sh
npm run android:recoverBuild once on your laptop, share app-release.apk to any arm64 Android phone. Internet required on phones (Sepolia + Hyperswarm). No env vars on device.
cd renopay
source scripts/android-env.sh
npm install --legacy-peer-deps
npm run generate:wdk
npm run pack:p2p
npm run build:bare-kit
bash scripts/patch-bare-kit-android-vm.sh
npx expo prebuild --clean --platform android
cd android
./gradlew assembleReleaseAPK output:
android/app/build/outputs/apk/release/app-release.apk
Install on each phone (enable “Install unknown apps” for your file sender). Open renopay — no laptop or Metro needed.
If release signing fails, try:
npx expo run:android --variant release --no-install --no-bundler
find android/app/build/outputs/apk -name "*.apk"| Tab | Role |
|---|---|
| Gate | Receiver — create tickets, show payment QR, view attendees |
| Pay | Sender — scan payment QR, pay USDT, receive ticket |
| Tickets | Local ticket drawer (received + issued) |
| Settings | Wallet, P2P status, clear local data |
Swipe left/right between tabs (WhatsApp-style); bottom nav stays in sync.
- Phone A (Gate): Connect Tether Wallet → Create ticket → Receive Payment → show QR
- Phone B (Pay): Connect wallet → Scan QR Code → confirm amount → Pay & Unlock Ticket
- Phone B: Ticket appears under Tickets → Received
- Phone A: Attendee listed under Gate → Attendees
Both phones need internet. Payment QR must be scanned inside Reno Pay Pay tab (not Google Pay / generic camera).
Expo Router UI
├── WDK worklet → Sepolia USDT (self-custodial send)
└── P2P worklet → Hyperswarm topic rooms (session + ticket events)
src/config/wdk.ts— Sepolia USDT,safeModulesVersion: '0.3.0'src/features/tickets/— QR payloads, payment session, P2P ticket storesrc/services/p2p/p2p-worklet.entry.js— Hyperswarm swarm
Full agent runbook: AGENTS.md
Design specs: docs/superpowers/specs/
npm run verify # lint + typecheck| Service | Use |
|---|---|
| Sepolia RPC | On-chain USDT settlement |
| Candide bundler | ERC-4337 (WDK) |
| Hyperswarm DHT | P2P discovery (decentralized) |
No Reno Pay backend. No API keys in .env — config is in source (src/config/wdk.ts).
MIT (see repository license file)