Solar energy tracking on Solana. Register solar devices, record energy generation, and visualize real-time data on-chain.
┌─────────────────────────┐
│ .mock_device_solar CLI │
│ register / record / run │
└───────────┬─────────────┘
│ RPC
▼
┌─────────────────────────┐
│ Solana Program │
│ SolarDevice account │
│ EnergyRecord account │
└───────────┬─────────────┘
│ getProgramAccounts
▼
┌─────────────────────────┐
│ React Frontend │
│ Dashboard / Devices │
│ Consumption / History │
│ Network Switcher │
└─────────────────────────┘
Program ID: 36D7U8McCLZF9ahuGmoiXehXzFLFm6v8N1gQVAfricSY
| Instruction | Description |
|---|---|
initialize |
Initialize the program |
register_device |
Create a SolarDevice PDA |
record_energy |
Record energy generation for a device |
update_device |
Update device name or active status |
SolarDevice — PDA seeds: ["solar_device", owner, unique_id]
| Field | Type | Description |
|---|---|---|
| owner | Pubkey | Device owner |
| unique_id | String | Hardware serial |
| name | String | Human-readable name |
| total_energy_wh | u64 | Cumulative energy (Wh) |
| current_wattage_mw | u64 | Latest wattage (mW) |
| record_count | u64 | Number of records |
| active | bool | Device status |
| registered_at | i64 | Registration timestamp |
| last_record_at | i64 | Last record timestamp |
EnergyRecord — PDA seeds: ["energy_record", device, record_index]
| Field | Type | Description |
|---|---|---|
| device | Pubkey | Parent SolarDevice |
| owner | Pubkey | Device owner |
| wattage_mw | u64 | Wattage reading (mW) |
| energy_wh | u64 | Energy since last record (Wh) |
| cumulative_energy_wh | u64 | Running total (Wh) |
| record_index | u64 | Sequential index |
| timestamp | i64 | Record timestamp |
- Rust 1.89+
- Solana CLI 2.2+
- Anchor CLI
- Node.js 24+
- Surfpool CLI
bash surfpool-dev.sh start
bash surfpool-dev.sh deploybash seed-localnet.sh seedThis registers 3 devices and records energy data:
| Device | Records | Total Energy |
|---|---|---|
| PANEL-ROOF-01 | 8 | ~228 Wh |
| PANEL-BALC-01 | 5 | ~55 Wh |
| PANEL-GARAGE | 3 | ~48 Wh |
cd app && npm install && npm run devSwitch to Local network in the UI to see on-chain data.
# Register a device
cargo run --manifest-path .mock_device_solar/Cargo.toml -- register \
--unique-id "MY-PANEL" --name "My Solar Panel"
# Record energy
cargo run --manifest-path .mock_device_solar/Cargo.toml -- record \
--unique-id "MY-PANEL" --wattage 3500 --energy 25
# Continuous recording (every 5s)
cargo run --manifest-path .mock_device_solar/Cargo.toml -- run \
--unique-id "MY-PANEL" --interval 5
# View device info
cargo run --manifest-path .mock_device_solar/Cargo.toml -- info \
--unique-id "MY-PANEL"Options:
--rpc <URL>— RPC endpoint (default:http://127.0.0.1:8899)--keypair <PATH>— Signer keypair (default:~/.config/solana/id.json)
| Page | Path | Description |
|---|---|---|
| Dashboard | / |
Overview with total supply, solar generation, tokens minted |
| Consumption | /consumption |
Solar generation tracking with monthly comparison heatmap |
| Devices | /devices |
Registered on-chain devices with details and status |
| Blockchain | /blockchain |
Transaction history with contribution graph |
| KYC | /kyc |
Identity verification |
| Swap | /swap |
Token swap interface |
Each page supports mock mode (local data) and on-chain mode (real Solana data) via the network switcher.
| Network | RPC | Description |
|---|---|---|
| Mock | — | Local mock data, no blockchain |
| Local | http://127.0.0.1:8899 |
Surfpool local network |
| Testnet | https://api.devnet.solana.com |
Solana devnet |
greenmove/
├── programs/greenmove/src/ # Anchor on-chain program
│ ├── lib.rs # Program entrypoint
│ ├── state.rs # SolarDevice, EnergyRecord
│ ├── instructions/ # Instruction handlers
│ ├── constants.rs # PDA seeds, limits
│ └── error.rs # Error codes
├── .mock_device_solar/src/ # Mock device CLI
│ ├── main.rs # CLI (register/record/run/info)
│ ├── instruction.rs # Anchor instruction builders
│ ├── pda.rs # PDA derivation
│ ├── rpc.rs # RPC client + account parser
│ └── device.rs # Device trait + mock impl
├── app/src/ # React frontend
│ ├── lib/
│ │ ├── program.ts # Program constants + types
│ │ ├── accountParser.ts # Deserialize on-chain accounts
│ │ └── SolanaContext.tsx # Wallet provider
│ ├── hooks/
│ │ ├── useOnchainDevices.ts # Fetch SolarDevice accounts
│ │ ├── useOnchainRecords.ts # Fetch EnergyRecord accounts
│ │ ├── useConsumptionData.ts # Consumption data (mock/on-chain)
│ │ ├── useDashboardData.ts # Dashboard data (mock/on-chain)
│ │ └── useBlockchainData.ts # Blockchain history (mock/on-chain)
│ ├── components/features/
│ │ ├── consumption/ # SolarGenerationCard, TokensMintedCard,
│ │ │ # MonthlyComparisonTable, LocalConsumption
│ │ ├── devices/ # DeviceCard, DeviceList
│ │ └── blockchain/ # ContributionGraph
│ ├── pages/ # Dashboard, Consumption, Devices, Blockchain, etc.
│ └── stores/ # Zustand state (network, wallet)
├── surfpool-dev.sh # Surfpool lifecycle (start/stop/deploy/test/reset)
├── surfpool-stop.sh # Stop surfpool standalone
├── seed-localnet.sh # Seed mock device data
└── Anchor.toml # Anchor config
anchor build
cargo test # 7 litesvm integration testsbash surfpool-dev.sh testbash surfpool-dev.sh reset./surfpool-stop.shcd app && npm run buildDevelopment progress tracked in .plans/:
| # | Plan | Status |
|---|---|---|
| 01 | Solar cell device model | Done |
| 02 | Network switcher + Surfpool integration | Done |
| 03 | Solana wallet integration | Done |
| 04 | Mock device → blockchain → frontend | Done |
| 05 | Consumption local UI components | Done |
ISC