a parametric drought insurance platform for African smallholder farmers. When satellite data confirms a drought, USDC automatically releases from a Stellar smart contract to the affected farmer's wallet. No claim forms. No adjusters. No delays.
# Nimbus
> **When rain fails, Nimbus pays.**
Parametric drought insurance for Africa's smallholder farmers, built on
Stellar, Trustless Work, and Open-Meteo. Submitted to the **Boundless ×
Trustless Work** hackathon, 13–16 May 2026.
---
## The idea
A smallholder farmer in Kano enrols her sorghum field with a phone number and
a GPS pin. Every morning at 06:00 UTC, an oracle pulls cumulative seasonal
rainfall for her exact coordinates from Open-Meteo. If that figure stays
below her contracted threshold, a Trustless Work escrow on Stellar approves
and releases USDC to her custodial wallet — in seconds, with no claim form,
no adjuster, and no paperwork. Sponsors and NGOs deposit USDC into coverage
pools and watch every payout settle on-chain.
Lemonade did this on Avalanche. Etherisc did it on Ethereum. Nimbus is the
first on Stellar — and ships it with a free weather API and around a hundred
lines of oracle code.
---
## Architecture
```
┌──────────────────────────────────────────┐
│ Vercel Cron · 06:00 UTC daily │
└────────────────────┬─────────────────────┘
│
▼
┌──────────────┐ ┌───────────────────────────┐ ┌──────────────┐
│ Open-Meteo │ ─────▶ │ /api/oracle/check │ ─────▶ │ Supabase │
│ (free API) │ │ │ │ oracle_checks│
└──────────────┘ │ if rainfall ` — her dashboard now shows `TRIGGER` and a
payout card.
---
## How the oracle works (the 11 lines that matter)
```ts
const { totalMm } = await fetchSeasonRainfall(lat, lon, seasonStart);
if (totalMm < farmer.drought_threshold_mm) {
const approveXdr = await approveMilestone(farmer.contract_id);
await submitToStellar(signXDR(approveXdr, PLATFORM_SECRET));
const releaseXdr = await releaseFunds(farmer.contract_id);
const tx = await submitToStellar(signXDR(releaseXdr, PLATFORM_SECRET));
await markPayout(farmer.id, totalMm, tx.hash);
await sendSMS(farmer.phone, payoutMessage(farmer, totalMm, tx.hash));
}
```
That is the e …