Inspiration
Solar is one of the best long-term cash-flow assets there is, but most people can't own it. Rooftop and commercial projects (100 kW – 2 MW) are too small for infrastructure funds and too large for individuals. Commercial and industrial sites already make up 70–80% of India's rooftop solar, and financing them is a constant bottleneck.
Tokenized real-world assets were supposed to fix this. But almost every RWA product still asks investors to trust the issuer's PDF report. I wanted the energy data itself to be the proof: don't trust the report, check it.
What it does
Solaris Labs lets anyone buy shares in a real solar array with USDC, earn a pro-rata share of the revenue from every kilowatt-hour it sells, and verify every single payout.
- Own: each project is an on-chain offering with a fixed number of shares. Invest any time; you earn from the next distribution.
- Earn: revenue is settled on Solana every 5 minutes. Collect whenever you like.
- Verify: an ESP32 meter signs every reading with its own Ed25519 key, which is registered on-chain. Each payout stores the SHA-256 of the signed readings file. The app downloads the file and re-checks it in your browser: the hash, every signature, and the energy and payout math. 9 checks, no trust in us. Change one reading by 1 µA and verification fails.
- Trade: sell shares to other investors on a built-in on-chain market. Distribution rights move with the shares.
How I built it
Hardware. An ESP32 + INA219 current/voltage sensor on a 6 V solar panel. The firmware reads the panel about once a second, signs each reading as solaris-reading-v1:<boot>:<seq>:<mV>:<µA> with a key generated on the device, and sends it over USB or Wi-Fi.
Anchor program (Rust). PDAs for the project, the USDC vaults, the share mint, investor positions, settlement records and market listings. Because investors can join or sell at any time, revenue is tracked per share, the way staking rewards are:
$$\text{acc} \mathrel{+}= \frac{\text{amount} \times 10^{12}}{\text{total shares}}$$
$$\text{claimable} = \text{pending} + \frac{\text{shares} \times \text{acc} - \text{reward_debt}}{10^{12}}$$
Every position is checkpointed before its share count changes (on a purchase, or on either side of a trade). So a new investor earns only from later payouts, a seller keeps everything earned before the sale, and rounding always goes down, so the total paid out can never exceed the total funded.
Share market. list_shares moves shares into an escrow owned by the listing PDA, and the seller keeps earning until a sale. buy_listing pays the seller in USDC and moves the shares and revenue rights to the buyer, with a max_price guard. cancel_listing returns unsold shares.
Operator service (Bun + SQLite). It accepts only correctly signed, in-order readings that haven't been seen before. Every 5 minutes it computes energy and revenue, publishes the proof file, and calls fund_revenue with the proof's hash. It also indexes trades from TradeEvent logs.
Investor app (Next.js 16). Subscribe, collect, portfolio, trading, and a verification page that re-runs all the checks in the browser.
Testing. 20 LiteSVM tests, including randomized runs that check payouts never exceed funding and that trades conserve shares, plus 26 integration tests against the program deployed on devnet. I used Claude Code as a pair programmer throughout.
Challenges
- First time with hardware. I learned to solder for this project. I debugged a breadboard reading zero (wrong resistor, loose ground), an INA219 that dropped the first I²C message after being idle, and serial connections that reset the ESP32 every time the port opened. At night I tested the panel with my phone's flashlight.
- The meter died before the deadline. Because rotating a project's meter key (
set_meter) was already part of the design, it's a hardware swap, not a redesign. To keep the demo running day and night, a second, clearly labelled project uses a software meter with the same program and the same proofs. - Devnet reliability. Public RPC rate limits and wallets left on mainnet caused failed transactions. I fixed this by routing everything through a server-side RPC proxy with caching and retries, and by signing in the wallet but submitting the transaction myself.
- Fair revenue with continuous investing and trading. Getting the per-share accounting exact across purchases, trades and claims took several iterations and property tests.
What I learned
For a real-world asset, the on-chain program is the easy part to get right. The hard work is at the edges: the device, the data pipeline, the user's wallet, and being honest about exactly what is verified. Keeping the trust boundaries explicit made every design decision simpler.
What's next
- Pilot one 100–500 kW commercial rooftop with a developer partner.
- Set up a legal structure (project SPVs, likely through IFSCA's GIFT City sandbox).
- Put meter checkpoints on-chain, so payouts must match the energy the meter itself reported.
- Production meters, an audit, then mainnet.
Built With
- anchor
- arduino
- bun
- ed25519
- esp32
- helius
- ina219
- iot
- litesvm
- next.js
- ngrok
- phantom
- react
- rust
- shadcn-ui
- solana
- solana-wallet-adapter
- spl-token
- sqlite
- tailwindcss
- typescript
- vercel
Log in or sign up for Devpost to join the conversation.