Dev.to · 4 min read

I Built a Trustless Proof-and-Payout App on Solana (and What the Escrow Actually Looks Like)

I Built a Trustless Proof-and-Payout App on Solana (and What the Escrow Actually Looks Like)

The problem in one sentence Someone pays a stranger to check something in the real world — is this booth open, did that poster go up, is the menu price really what it says — and both sides have to trust each other with no proof either way. I built ProofQuest to remove the trust from that exchange: the requester locks USDC in an on-chain escrow, a nearby worker captures camera + GPS + timestamp evidence, submits a signed proof packet, and the requester approves to release the reward. All from an Android phone. No browser, no custodial account. Repo: https://github.com/iamaanahmad/proofquest Demo: https://www.youtube.com/watch?v=bNrGX_kuYrs Submitted to the MLH Solana Hackathon, DeFi track, Nov 6–8, 2026. Devnet only, test USDC, not production. How the loop works Two wallets, one phone, one trustless payout: Creator connects a wallet, creates a quest, sets the reward and claim window, funds and publishes. USDC moves into an on-chain vault. Worker connects a different wallet, sees nearby quests, claims one, and captures evidence in-app: camera photo, coarse GPS, timestamp. The worker submits. A canonical JSON manifest is SHA-256 hashed, the 32-byte digest is written on-chain, and the full manifest is stored in Appwrite. Creator reviews the proof — hash verified, evidence photo, metadata — and approves. The vault releases USDC to the worker. No raw location or photo ever touches the chain. Only the manifest hash is public. The escrow state machine The Anchor program (DmSc562EUuh9yvu2AmEupLLC8wQrXZGVSCZL61EpugvZ, Solana devnet) is a small state machine: Open → Claimed → Submitted → Approved ↓ Cancelled (Refunded after submit_deadline passes) Instructions: create_and_fund_quest, claim_quest, submit_evidence_hash, approve_and_release, cancel_unclaimed, refund_expired. The vault is an SPL token account owned by the quest PDA, so the money can only move on the program's rules: approve releases it to the worker, cancel or expiry refunds it to the creator. There is no admin key that can grab it. The evidence manifest Every submission produces a canonical JSON manifest before hashing: { "questAddress": "...", "workerWallet": "...", "captureTimestamp": 1234567890, "coarseLocation": { "geohash": "tutq", "accuracy": 15.5 }, "nonce": "uuid-v4", "mediaSha256": "...", "storageObjectId": "...", "appVersion": "1.0" } Keys are sorted, UTF-8 encoded, SHA-256 hashed. The raw photo and exact coordinates stay in private Appwrite storage. That split is the whole design: verifiable on-chain, private off-chain. The stack, and why each piece is there Mobile: React Native 0.87, TypeScript, Hermes. One codebase, Android-first. Wallet: Solana Mobile Wallet Adapter with Phantom. The phone is the signer. Chain: Anchor 0.32, SPL Token, Solana devnet. RPC: Helius devnet, for reliable broadcast and confirmation. Backend: Appwrite (self-hosted) — quest discovery cache and private evidence storage. Camera: react-native-vision-camera v5. State: Zustand. Appwrite is deliberately a cache, not the source of truth. If it goes down, the chain still knows who is owed what. If the chain is slow, the app still feels fast. Three quest templates, because "verify anything" is too vague Is this booth open? — photo of the entrance showing open/closed status. Did this poster go up? — photo of the poster in the specified location. Verify today's menu price — photo of the menu board showing item + price. Custom — open-ended evidence requirement. Templates mattered more than I expected. A worker needs to know exactly what counts as proof before they walk over, and a requester needs to know exactly what they will get back. What is honest about the limits Devnet only, test USDC. Not production ready. Phantom shows "Unknown Program" — expected for an unregistered devnet program. The QR challenge field is in the manifest schema and shown in Review, but in-app QR capture is not implemented yet. No push notifications — status updates are in-app only. The repo was started Sep 23, 2026 and polished through the hackathon weekend, not built from zero in two days. I would rather ship a narrow loop that actually works than a broad one that demos well and breaks on the second tap. What I would build next Dispute handling with a time-boxed challenge window, a reputation score tied to wallet history instead of usernames, and a web review view so a requester does not need the app to approve. Mainnet is a later conversation, after a real audit. Try it The APK is in the repo releases (v1.0.1, Nov 8, 2026). You need Android 10+, Phantom installed, and devnet SOL for fees. Setup is in the README: clone, set up the Appwrite schema, mint test USDC, run it. If you have built anything with Solana escrows or Mobile Wallet Adapter, I would genuinely like to hear what broke for you. What is the part of "trustless" that you still do not trust?

This is a summary aggregated from Dev.to. Read the complete article on the original site:

Read full article at Dev.to

More Programming & Dev News