← Back to Archive
GreenTech / Web3 Mobility Case Study

EcoRydes

A decentralized P2P carpooling platform that rewards carbon savings with Solana-based tokens.

Expo (React Native) NestJS Solana Web3.js Pusher MoonPay MongoDB

Architecture Overview

A mobile-first architecture where a NestJS backend acts as the bridge between real-time geospatial tracking (Pusher/Haversine) and on-chain settlement (Solana), managing custodial wallets to abstract gas fees from users.

The Challenges

Off-Chain Liquidity Locking

Problem

Locking funds on-chain (Escrow Smart Contract) for every ride request is expensive and slow. We needed to prevent 'Double Spending' without the latency of a blockchain transaction.

Solution

Implemented a 'Soft Escrow' ledger in MongoDB. When a ride is booked, we validate `(OnChainBalance - LockedBalance)` and atomically increment the `LockedBalance`. The actual on-chain USDC transfer only occurs upon ride completion. This provides instant UX with the security of a solvent balance sheet.

wallet.service.ts

Green Tokenomics Engine

Problem

We needed to quantify 'Sustainability', translating physical ride data into a fungible on-chain reward without allowing users to game the system.

Solution

Engineered a Tokenomics Service that ingests telemetry: `(Distance * 0.12kg/km * PassengerCount)`. This CO2 savings value is fed into a weighted formula to mint ERD tokens via the Solana `TOKEN_2022_PROGRAM`. This connects physical impact directly to digital value.

ride-request.service.ts

Multi-Passenger State Machine

Problem

A single 'Ride' has complex, asynchronous states. Passenger A might be 'Dropped Off' while Passenger B is 'Picked Up', all while the Driver is 'En Route'. Managing these overlapping states caused race conditions.

Solution

Designed a Nested State Machine. The parent `Ride` tracks the vehicle trajectory, while child `Passenger` objects track individual statuses. We implemented strict transition guards (e.g., 'Ride cannot complete if Passenger B is still onboard') to ensure logical consistency across the entire trip.

ride-status.service.ts

Geospatial Event Triggering

Problem

Polling the driver's location every second to check if they arrived drained the battery and flooded the server.

Solution

Built a reactive Haversine Geofence. The backend receives driver coordinates via Pusher and calculates the delta to the passenger's waypoint. Proximity events (e.g., 'Driver is 500m away') are triggered server-side and pushed to the client, eliminating client-side polling entirely.

rooms.service.ts