Inspiration
California solar homeowners earn $0.05/kWh selling back to the grid while their neighbors pay $0.32/kWh at peak rates — the utility captures a 6× spread for routing electrons 200 feet down the street. When Ripple introduced MPTs, native AMM, Batch transactions, and Lending on the XRP Ledger, we had the full stack to build a real neighborhood energy market.
What it does
SolarSwap is a peer-to-peer solar energy marketplace for neighborhoods. Homeowners join a shared room representing their local grid, then:
- Sell: Post a 1 XRP delivery bond via
EscrowCreate. At t+40s, an IoT smart meter verifies delivery. On success:EscrowFinishreleases the bond, SOLAR MPT tokens are minted with on-chain provenance (house ID, solar kW, battery level, timestamp), and a DEX ask is posted at the seller's price. - Buy: RLUSD bids match against the live DEX order book, with automatic AMM fallback if no asks exist.
- Batch settle: Multiple buyer-to-producer RLUSD payments settle atomically in a single
Batch(tfAllOrNothing) — all succeed or all roll back. - Credit lines: Buyers without RLUSD borrow SOLAR now via
LoanSet(bilateral countersign) and repay viaLoanPay. - Grid safety: Battery below 30% triggers
AMMVoteto push the fee to 3%; below 20% minting suspends entirely.
How we built it
Next.js 15 App Router with all XRPL logic in server-side API routes via xrpl.js v4. No external database — room state (participants, escrows, settlements, loans) lives in a server-side in-memory store. Each room gets a dedicated issuer wallet, a fresh MPTokenIssuanceCreate issuance (AssetScale: 2, 100 raw tokens = 1 kWh), and a seeded SOLAR/RLUSD AMM at 0.6% fee. Participants each get a funded testnet wallet with RLUSD trustlines. The frontend polls room state every 5 seconds and samples AMM/DEX prices on a 10-second interval via setInterval + useRef.
Challenges we ran into
- Escrow error isolation: 100% of sell attempts were failing with "Meter rejected." A single
try/catchwrappedEscrowFinish+ mint + DEX ask — whencreateDexAskthrew, the catch block calledEscrowCanceleven thoughEscrowFinishhad already succeeded. Fixed by splitting into three independent blocks where DEX ask failure only logs a warning. - MPT AssetScale price math:
AssetScale: 2means 100 raw tokens = 1 kWh. Every price calculation — AMM spot price, DEX ask, order book display, trade feed — must divide raw values by 100. One missed division caused inflated or zero-value orders anywhere in the stack. - RLUSD currency encoding:
ripple-binary-codecrejects 5-character ISO currency codes. RLUSD must be passed as its full 40-hex representation (524C555344000000000000000000000000000000). This caused every RLUSD transaction to fail with a cryptic serialization error until we found it in the codec internals.
Accomplishments that we're proud of
Seven XRPL primitives in one application — MPT, Escrow, DEX, AMM, Batch, Lending, TrustSet — each solving a real energy-market problem rather than used as a demo toy. The delivery bond escrow creates genuine accountability: no tokens are minted without IoT confirmation, and the bond is locked, verified, and released entirely on-chain. Batch settlement with tfAllOrNothing across multiple buyer wallets works end-to-end. Every SOLAR token carries verifiable on-chain provenance back to its physical generation event.
What we learned
XRPL's programmability maps cleanly to physical-world settlement — the hard part isn't writing logic, it's understanding how primitives interact at the binary encoding and ledger state level. Multi-step on-chain flows need full isolation: the escrow bug showed that wrapping multiple operations in one error handler is dangerous since some steps (like EscrowFinish) can't be undone once submitted. AssetScale is a first-class concern — one missed division propagates wrong prices through the entire stack.
What's next for Solar Swap
Replace simulated IoT with real smart meters (Shelly EM clamp or P1 DSMR port — the escrow FinishAfter window already fits the ~30s metering delay). Move room state to a persistent database so neighborhoods survive restarts. Build cross-neighborhood energy routing on the global map, matching supply in one room against demand in an adjacent one. Issue CO₂ offsets as a second MPT class (0.386 kg/kWh, already tracked) tradeable on the same DEX.
Built With
- next.js
- python
- react.js
- ripple
- supabase
- typescript
- xrpl.js
Log in or sign up for Devpost to join the conversation.