DEV Community

Cover image for PlantChain: Because "Trust Me, I Planted a Tree" Was Never Going to Scale
Anshu Mandal
Anshu Mandal Subscriber

Posted on • Edited on

PlantChain: Because "Trust Me, I Planted a Tree" Was Never Going to Scale

DEV Weekend Challenge: Earth Day

This is a submission for the DEV Weekend Challenge: Earth Day Edition

What I Built (And Why Planting Trees Needed a Trust Problem Solved)

Here is the thing about tree planting initiatives: everyone loves them, nobody trusts them. You donate to a reforestation campaign, get a nice certificate, and then... hope for the best? There is no way to verify that a tree actually went into the ground, let alone that someone did not just photograph the same oak from three different angles.

PlantChain -- a community reforestation registry where every planting is AI-verified, publicly visible, and recorded on-chain. An AI agent with a verifiable Auth0 identity checks your submission, and the receipt lives permanently on Solana. Trust infrastructure for trees.

The pitch is simple: snap a photo of your freshly planted tree, drop a pin, and let an AI agent decide if you are telling the truth. No committees, no paperwork, no "we'll get back to you in 6-8 weeks."

Demo

Live app: PlantChain on Vercel

GitHub:

plantchain-new

This project was created with Better-T-Stack, a modern TypeScript stack that combines React, TanStack Router, Convex, and more.

Features

  • TypeScript - For type safety and improved developer experience
  • TanStack Router - File-based routing with full type safety
  • TailwindCSS - Utility-first CSS for rapid UI development
  • Shared UI package - shadcn/ui primitives live in packages/ui
  • Convex - Reactive backend-as-a-service platform
  • Authentication - Better-Auth
  • Turborepo - Optimized monorepo build system

Getting Started

First, install the dependencies:

pnpm install
Enter fullscreen mode Exit fullscreen mode

Convex Setup

This project uses Convex as a backend. You'll need to set up Convex before running the app:

pnpm run dev:setup
Enter fullscreen mode Exit fullscreen mode

Follow the prompts to create a new Convex project and connect it to your application.

Copy environment variables from packages/backend/.env.local to apps/*/.env.

Then, run the development server:

pnpm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:5173 in your browser to see the web application Your app will connect to the Convex cloud backend…

How it works in 30 seconds:

  1. Sign up (email + password, or Google sign-in)
  2. Hit "Log a Planting" -- pick your species, snap a photo, let the browser grab your GPS coordinates
  3. Submit. Within seconds, Gemini 3 Flash analyzes your photo and either verifies or rejects the submission
  4. Your planting appears in the public registry with a verification badge and an on-chain proof link

No human reviewer in the loop. The AI agent handles everything from "is this actually a tree?" to "did someone already submit this exact spot?" Verified plantings get a permanent receipt on Solana that anyone can audit.

How I Built It

The Stack

Frontend:  React 19 + Vite + TanStack Router (file-based routing) 
Backend:   Convex (real-time database + serverless functions)
Auth:      Better Auth via @convex-dev/better-auth
Agent ID:  Auth0 (M2M client credentials for AI agent identity)
AI:        Gemini 3 Flash via @ai-sdk/google (Vercel AI SDK)
Chain:     Solana Devnet (Memo Program for on-chain receipts)
UI:        shadcn/ui + Tailwind CSS
Monorepo:  pnpm + Turborepo
Enter fullscreen mode Exit fullscreen mode

Four packages in a pnpm monorepo: apps/web for the frontend, packages/backend for Convex, packages/ui for shared components, and packages/config for TypeScript config.

The Verification Flow (The Fun Part)

This is where PlantChain gets interesting. When you submit a planting, here is what happens behind the scenes:

Verfication Flow

The AI prompt is deliberately opinionated. It checks three things:

  1. Does the photo show a real tree or sapling that has been planted? (Not a houseplant. Not a stock photo. Not your cat.)

My Cat

  1. Are the GPS coordinates valid? (Not 0,0. Not the middle of the ocean.)
  2. Is this likely a genuine new planting?

Here is the actual verification code that talks to Gemini:

const result = await generateText({
  model: google("gemini-3-flash-preview"),
  messages: [
    {
      role: "user",
      content: photoUrl
        ? [
            { type: "image", image: new URL(photoUrl) },
            { type: "text", text: prompt },
          ]
        : [{ type: "text", text: prompt }],
    },
  ],
});
Enter fullscreen mode Exit fullscreen mode

Gemini responds with structured JSON -- passed, reason, and optionally tips for the planter. If it passes but there is already a verified planting within 5 meters, the system overrides the AI and flags it as a duplicate. Trust the math over the model.

Duplicate Detection: Surprisingly Tricky

Detecting duplicates sounds easy until you remember that GPS coordinates are floating point numbers and the Earth is round. The findNearby query converts a 5-meter radius into latitude/longitude deltas, accounting for the cosine correction at different latitudes:

const degPerMeter = 1 / 111320;
const latDelta = radiusMeters * degPerMeter;
const lngDelta =
  (radiusMeters * degPerMeter) / Math.cos((latitude * Math.PI) / 180);
Enter fullscreen mode Exit fullscreen mode

It is not a full Haversine calculation -- that would be overkill for a 5-meter radius where the curvature of the Earth is basically a rounding error. But the longitude correction matters. Without it, duplicate detection gets progressively worse as you move away from the equator. A 5-meter radius in Ecuador would be a 3-meter radius in Norway. Trees deserve equal treatment regardless of latitude.

Auth0: Giving the AI Agent a Verifiable Identity

Here is a detail that is easy to overlook: when an AI agent verifies your tree planting, who is that agent? In PlantChain, the verification agent is not anonymous -- it has an identity, and that identity comes from Auth0.

Auth0 turned out to be a natural fit for this kind of project. When you are building a trust registry -- something where the whole point is that anyone can audit the chain of custody -- you need every actor in the system to have a verifiable identity. That includes the AI. Auth0's M2M (machine-to-machine) client credentials flow gives the agent its own authenticated identity, separate from any user, with scoped permissions and a full audit trail.

Every verification result is stamped with the agent's client_id:

const { agentId } = await acquireAgentToken();
// ... verification logic ...
await ctx.runMutation(internal.plantings.updateVerification, {
  plantingId,
  passed,
  reason,
  tips,
  agentId, // Auth0 client_id, recorded with every decision
});
Enter fullscreen mode Exit fullscreen mode

The system gracefully falls back to "local-dev-agent" when Auth0 env vars are not set, but when they are, every verification carries a cryptographically verifiable agent identity. That matters when you are building a trust registry.

The roadmap here is exciting. Auth0 for AI Agents opens the door to:

  • Multi-agent verification -- different agents with different specialties (one for tropical species, one for temperate) each with their own Auth0 identity and audit trail
  • Token Vault integration -- if PlantChain ever needs to verify against external APIs (satellite imagery, weather data at planting time), Auth0 Token Vault handles the OAuth dance for third-party services without us managing refresh logic

Solana: On-Chain Receipts That Anyone Can Verify

Sample Proof

OnChain Record

Solana was the obvious choice for on-chain recording, and it turned out to be a great fit. The economics of a tree planting registry demand that recording a receipt costs fractions of a cent and confirms in under a second. Solana delivers both. Nobody wants to pay $5 in gas fees to prove they planted a sapling.

Once a planting passes AI verification, PlantChain automatically records a Memo Program transaction on Solana -- a permanent, tamper-proof receipt containing the species, coordinates, verification timestamp, and agent ID. Not an NFT. Not a token. Just an immutable log entry on a public ledger.

Here is the recording action:

const memo = JSON.stringify({
  app: "plantchain",
  id: plantingId,
  species: planting.species,
  lat: planting.latitude,
  lng: planting.longitude,
  verifiedAt: planting.verificationResult?.verifiedAt,
});

const tx = new Transaction().add(
  new TransactionInstruction({
    keys: [{ pubkey: payer.publicKey, isSigner: true, isWritable: true }],
    programId: MEMO_PROGRAM_ID,
    data: Buffer.from(memo, "utf-8"),
  }),
);

const signature = await sendAndConfirmTransaction(connection, tx, [payer]);
Enter fullscreen mode Exit fullscreen mode

The beauty is that verification and on-chain recording are decoupled. The AI agent does its job, the planting gets verified in the app immediately, and the Solana transaction happens asynchronously via Convex's scheduler. Users do not wait for blockchain confirmation to see their planting go green.

Every verified planting card now shows an "On-Chain Proof" block with the truncated transaction signature and a link to Solana Explorer. The homepage features a dedicated proof section with live stats -- how many plantings are recorded on-chain, recent transactions, and a step-by-step explanation of the verification-to-chain pipeline.

Combined with Auth0 agent identity, this creates a full chain of custody: who verified it (Auth0 agent ID), what was verified (photo + coordinates + species), and where the proof lives (Solana transaction). That is the kind of transparency that turns "we planted 10,000 trees" from a marketing claim into a verifiable fact.

The Frontend: Nature-Inspired, Not Nature-Cliche

I wanted the UI to feel like a forest without looking like a national park brochure. The color palette is built around deep greens (forest, forest-mid), a warm gold accent, and a soft sprout green for highlights. The hero section sets the tone:

Every tree planted, forever verified

Hero Section

The registry page renders plantings as cards with the photo, species, location, planter name, and a verification badge. Verified plantings get a green badge, rejected ones get red, pending gets amber. Each card also shows the AI's reasoning -- "Photo shows a healthy young oak sapling planted in soil" or "Image appears to be a screenshot, not a photograph." Verified plantings with on-chain receipts display a proof block with the Solana transaction signature and a direct link to Explorer.

Registry

Alongside the planting grid sits a global leaderboard -- top planters ranked by verified tree count, with crown, medal, and trophy icons for the top three. A little competitive motivation never hurt a reforestation effort.

Submit Form

The submit form uses the browser's Geolocation API to auto-detect coordinates (with a manual fallback), supports camera capture on mobile via capture="environment", and gives you a species picker with 16 common options plus a custom field.

Dashboard with Realtime Data

Dashboard

What is Next

The core trust pipeline is live -- AI verification with Auth0 agent identity, on-chain receipts on Solana, and a public registry anyone can audit. The immediate next steps:

  1. Solana mainnet. Currently running on Devnet. The code is mainnet-ready -- just swap the RPC URL and fund the wallet.
  2. Auth0 Token Vault for external data. Satellite imagery APIs, weather services at planting time, soil databases -- Auth0 Token Vault will manage the OAuth tokens so the verification agent can cross-reference submissions against real-world data.
  3. Multi-agent verification. Different Auth0-authenticated agents specializing in different regions or species, each with their own identity and audit trail.
  4. Map view. A global map with planting markers so you can watch the canopy grow in real time.

The Earth Day Connection

PlantChain exists because trust is the bottleneck in environmental action. People want to plant trees. Organizations want to fund tree planting. But the gap between "we planted 10,000 trees" and "here is verifiable proof of 10,000 trees" is enormous.

AI verification is not perfect -- Gemini can be fooled, GPS can be spoofed, and a determined bad actor will always find a way. But it raises the bar from "trust me bro" to "here is a photo, here are coordinates, an AI agent with a verifiable Auth0 identity confirmed this looks legit, and the receipt lives on Solana forever." That is a meaningful step.

Auth0 and Solana turned out to be a natural pairing for this kind of project. Auth0 solves the identity side -- giving every actor in the system (human or AI) a verifiable, auditable identity with scoped permissions. Solana solves the permanence side -- making every verification decision publicly auditable at negligible cost. Together they close the trust loop: you can trace who verified a planting, what they verified, and where the proof lives, all the way from the AI agent's Auth0 credentials to the Solana transaction on Explorer.

Every tree planted, forever verified. Happy Earth Day.


Prize Categories

Best Use of Auth0 for Agents
Best Use of Solana

Built with: React 19, Convex, Gemini 3 Flash, Auth0 (agent identity), Solana (on-chain receipts), Better Auth, TanStack Router, shadcn/ui, Tailwind CSS, Turborepo

Connect: GitHub @prime399

Top comments (0)