DEV Community

sasi
sasi

Posted on

VeriAid — AI-Audited Micro-Philanthropy on Solana

DEV Weekend Challenge: Generosity Edition Submission 💜

This is a submission for Weekend Challenge: Generosity Edition

What I Built

VeriAid is a micro-philanthropy platform where Google Gemini audits every campaign and Solana settles every donation — built for the International Day of Charity.

Two things stop people from giving small amounts to grassroots causes:

  1. You can't tell if it's real. Grassroots campaigns have no audit trail. Donors either give blindly or don't give at all.
  2. Small gifts don't survive the fees. At 2.9% + $0.30, a $2 donation loses 17% before it lands. Micro-giving is economically impossible on card rails.

VeriAid attacks both:

  • Gemini campaign intake audit — every submitted aid request is scored 0–99 for credibility by gemini-2.5-flash, with an urgency classification, a budget-plausibility check against regional market prices, itemized findings, and named risk factors. The prompt is deliberately harsh: vague campaigns with no verifiable location or organizer land in the 30–49 band, and the score is shown to donors before they give.
  • Milestone-gated funds, not lump sums — a campaign is split into milestones (pending → funded → audited). To unlock the next one, the organizer submits a vendor receipt and deliverable notes, and Gemini audits the claimed expense against that milestone's stated scope before approving disbursement.
  • Solana micro-settlement — donations go peer-to-peer from donor to organizer wallet on Devnet with a Memo Program instruction carrying the campaign ID and the donor's message. Fees are ~0.000005 SOL, so a 0.05 SOL gift arrives essentially whole.
  • Zero-install evaluator wallet — the app generates a persistent keypair in localStorage and airdrops Devnet SOL on one click, so you can sign a real transaction without a browser extension.
  • Generosity Copilot — ask "I have 0.2 SOL and want to fund clean water" and Gemini reads the live campaign registry and returns matched campaigns with their trust scores and one-click donate buttons.

Demo

🔗 Live app: https://dev-to-weekend-challenge-generosity-edition-ballsh20t-koodam.vercel.app/

60-second tour:

  1. Look at the top bar — your Devnet evaluator wallet is already provisioned. Hit +Faucet for 1 SOL.
  2. Click "AI Audit" on Maya's Urgent Pediatric Cardiac Surgery (99% trust) or Kerala Monsoon Relief (96%) — you get the full Gemini report: trust score, urgency, budget sanity check, key findings, risk factors.
  3. Click "Request Aid" and submit a deliberately vague campaign ("need money for stuff"). Gemini will score it in the 30s and tell you exactly why. This is the fun part — the auditor actually pushes back.
  4. Donate 0.05 SOL with a message of hope → transaction signs, confetti fires, and you get an explorer link.
  5. Submit a receipt inside a campaign's milestone and watch Gemini audit the expense against the deliverable.
  6. Ask the Copilot for causes matching your budget.

The flow:

       [ Grassroots Aid Request ]
                   │
                   ▼
     ┌────────────────────────────┐
     │  Google Gemini 2.5 Flash   │ ──► Trust Score (0-99)
     │  Intake Verification Agent │ ──► Budget Sanity Check
     └────────────────────────────┘ ──► Urgency Classification
                   │
                   ▼ (Verified)
     ┌────────────────────────────┐
     │   VeriAid Registry Feed    │
     └────────────────────────────┘
                   │
                   ▼ (Donor Micro-Contribution)
     ┌────────────────────────────┐
     │       Solana Devnet        │ ──► Sub-second finality
     │   Peer-to-Peer + Memo      │ ──► Fees < $0.001
     └────────────────────────────┘ ──► On-chain donor message
                   │
                   ▼ (Milestone Completion)
     ┌────────────────────────────┐
     │  Gemini AI Receipt Auditor │ ──► Vendor & deliverable audit
     └────────────────────────────┘ ──► Disbursement authorization
Enter fullscreen mode Exit fullscreen mode

Code

https://github.com/voiddata/dev-to-challenges/tree/main/weekend_challenge_generosity_edition

src/lib/gemini.ts            # 3 Gemini agents: intake audit, receipt audit, donor copilot
src/lib/solana.ts            # Devnet connection, sandbox keypair, airdrop, transfer + memo
src/lib/campaign-store.ts    # Campaign registry, donation recording, milestone state machine
src/lib/sample-data.ts       # 5 seeded campaigns across 5 aid categories
src/app/api/
  gemini/verify              # POST — audit a new campaign
  gemini/copilot             # POST — conversational campaign matching
  campaigns/[id]/donate      # POST — record an on-chain donation
  campaigns/[id]/audit-receipt  # POST — audit a milestone receipt
src/components/              # 13 components: cards, detail modal, donate, receipt audit, copilot, ledger
scripts/test-engine.ts       # End-to-end suite across store, Gemini, and Solana layers
Enter fullscreen mode Exit fullscreen mode

Next.js 14 App Router + TypeScript, Tailwind, @google/genai, @solana/web3.js. No database, no external backend — clone, npm install, npm run dev.

How I Built It

Gemini as an auditor, not a chatbot

The interesting design decision was making Gemini adversarial toward its own users. A trust score is worthless if everything scores 95%, so the intake prompt hands Gemini an explicit scoring rubric with anchored bands:

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: prompt,
  config: {
    responseMimeType: 'application/json',
    temperature: 0.2,
  },
});
Enter fullscreen mode Exit fullscreen mode

responseMimeType: 'application/json' is what makes this production-viable — Gemini returns parseable structured output directly, no regex-scraping fenced code blocks. temperature: 0.2 keeps scores stable across identical submissions, which matters when a number is a trust signal to a donor.

The rubric bands (0–29 fake, 30–49 vague, 50–64 gaps, 65–79 credible, 80–94 strong, 95–99 exceptional) were the fix for a real problem: with an unanchored "score 0–100" prompt, Gemini clustered everything at 85+ and flattered every campaign. Anchoring the bands with concrete failure criteria made it genuinely willing to fail a submission.

Every parsed field is then clamped and defaulted server-side, so a malformed model response degrades into a low-confidence report instead of a crash:

trustScore: Math.min(99, Math.max(0, parsed.trustScore ?? 50)),
Enter fullscreen mode Exit fullscreen mode

The receipt auditor is the same pattern pointed at a narrower question: does this vendor, amount, and description actually match the milestone's stated deliverable? It returns a confidence score plus a flaggedDiscrepancies array, and disbursementApproved gates the milestone transition.

Solana as the reason micro-giving works at all

Solana isn't decoration here — it's the enabling constraint. The entire product premise (fund one water filter for 0.05 SOL) only exists on a chain where fees round to zero.

Donations carry a Memo Program v2 instruction, so the donor's message and campaign reference live on-chain alongside the transfer rather than in my database:

const transaction = new Transaction().add(
  SystemProgram.transfer({
    fromPubkey: fromKeypair.publicKey,
    toPubkey: recipientPubkey,
    lamports: Math.round(amountSol * LAMPORTS_PER_SOL),
  })
);

transaction.add({
  keys: [{ pubkey: fromKeypair.publicKey, isSigner: true, isWritable: true }],
  programId: new PublicKey('MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr'),
  data: Buffer.from(`VeriAid Giving: ${memoText}`, 'utf-8'),
});
Enter fullscreen mode Exit fullscreen mode

The friction I actually spent the most time on

Wallet onboarding kills demos. Asking a judge to install Phantom, switch to Devnet, and find a faucet is three chances to lose them before they see anything.

So the app provisions its own keypair in localStorage on first load and wires a one-click faucet button next to the balance. Before every transfer it checks the on-chain balance and auto-airdrops if you're short. When the public Devnet faucet rate-limits (429s are common on hackathon weekends), the donation completes in a Sandbox Relayer mode that records the gift locally and labels the receipt accordingly, so a rate-limited faucet doesn't dead-end the walkthrough. With a funded wallet, transfers are fully on-chain and explorer-verifiable.

There's also a settings modal for bringing your own Gemini key at runtime, and every Gemini call falls back to a deterministic heuristic audit if no key is configured — so a fresh clone with an empty .env still demos end to end.

Prize Categories

🌟 Best Use of Google AI

Gemini is the product's trust layer, not a feature bolted on. Three distinct agents on gemini-2.5-flash via @google/genai, all using structured JSON output: an adversarial intake auditor with an anchored scoring rubric that will fail a weak campaign, a receipt auditor that gates real fund disbursement on expense-to-deliverable matching, and a donor copilot that reasons over the live campaign registry. Remove Gemini and VeriAid is just another donation form.

⚡ Best Use of Solana

Solana is the precondition for the whole idea. Sub-penny fees are what make a 0.05 SOL gift viable when card rails would eat 17% of it, and sub-second finality is what makes the donate-and-see-it-land moment feel instant. Donations are non-custodial peer-to-peer transfers with on-chain memos, paired with a zero-install sandbox wallet that generates, funds, and signs in the browser in seconds.


Generosity scales when it's verifiable. VeriAid makes small giving both provable and worth doing.

Top comments (3)

Collapse
 
dreainno profile image
Mayuresh Pandit • • Edited

Is gemini 2.5 we still able to use ? As I am facing the error while using that through API

Collapse
 
sasi_13316d9aacdc95ef0d00 profile image
sasi •

yes able to use gemini 2.5

i used antigravity

Some comments may only be visible to logged-in visitors. Sign in to view all comments.