A modular settlement network with native rollups, smart accounts, privacy primitives, and intent-aware execution.
Solen narrows the responsibilities of the base layer and treats execution domains as first-class components. The design combines a minimal settlement chain, native rollups, smart accounts by default, privacy-capable proof interfaces, and intent-oriented transaction flow.
Status: Development prototype (v0.1.0). Not audited. Not for production use.
Getting started? Follow the Build Your First dApp tutorial to deploy a token contract in 15 minutes.
┌───────────────────────────────────────────────────────────────┐
│ Solen Node │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
│ │Consensus │ │Execution │ │ WASM │ │ System │ │
│ │ Engine │◄─┤ Engine │◄─┤ VM │ │ Contracts │ │
│ │ (BFT) │ │ │ │(wasmtime)│ │ │ │
│ └────┬─────┘ └────┬─────┘ └──────────┘ │ ■ Staking │ │
│ │ │ │ ■ Bridge │ │
│ ┌────┴─────┐ ┌────┴─────┐ │ ■ Governance │ │
│ │ P2P │ │ Storage │ │ ■ Treasury │ │
│ │(libp2p) │ │(RocksDB) │ └───────────────┘ │
│ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ JSON-RPC │ │ Indexer │ │ Explorer │ │
│ │ :9944 │ │ │ │ API :9955│ │
│ └──────────┘ └──────────┘ └──────────┘ │
└───────────────────────────────────────────────────────────────┘
Settlement layer — BFT proof-of-stake consensus with deterministic finality, round-robin proposers, 2/3+ stake-weighted quorum, epoch-based rewards, and slashing for double-sign and downtime.
Execution engine — Processes user operations (transfer, contract call, deploy), manages account state, verifies signatures, deducts fees, and supports transaction simulation.
WASM VM — Contracts execute as WASM bytecode via wasmtime. Host functions provide storage read/write, event emission, caller identity, and block height. Gas metering uses wasmtime's fuel mechanism.
Smart accounts — Every account is programmable. No externally owned accounts. Supports Ed25519 keys, passkeys, threshold authorization, guardians, and session credentials.
solen/
├── crates/
│ ├── solen-types/ # Core types: Hash, AccountId, BlockHeader, UserOperation
│ ├── solen-crypto/ # Ed25519 signing, BLAKE3 hashing
│ ├── solen-storage/ # StateStore trait + MemoryStore + RocksDB backend
│ ├── solen-consensus/ # BFT engine, validator set, epochs, slashing, checkpoints
│ ├── solen-execution/ # Block executor, state manager, fees, genesis
│ ├── solen-vm/ # Wasmtime WASM runtime with host functions
│ ├── solen-system-contracts/ # Staking, bridge, governance, treasury
│ ├── solen-rollup-kit/ # Sequencer, batch publisher, prover, messenger
│ ├── solen-p2p/ # libp2p gossipsub networking
│ ├── solen-rpc/ # JSON-RPC server (jsonrpsee)
│ ├── solen-indexer/ # Event indexer + explorer REST API
│ ├── solen-cli/ # CLI tool (key management, transactions, staking, governance)
│ ├── solen-faucet/ # Testnet faucet server
│ ├── solen-intents/ # Intent pool, solver interface, constraint types
│ └── solen-node/ # Node binary (ties everything together)
├── sdks/
│ ├── wallet-sdk-rs/ # Rust wallet SDK
│ └── wallet-sdk-ts/ # TypeScript wallet SDK
├── tools/
│ ├── submit-batch/ # Rollup batch submission tool
│ └── devnet/ # Local devnet launcher
├── fuzz/ # Fuzz targets (executor, VM, tx decode)
├── specs/ # Protocol specifications
└── audits/ # Security audit reports (placeholder)
- Rust 1.78+ (
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh) - C build tools (
build-essential,clang)
cargo build --workspaceNote: On some systems, RocksDB compilation requires:
export C_INCLUDE_PATH=/usr/lib/gcc/x86_64-linux-gnu/11/include
cargo test --workspace135 tests covering storage, crypto, execution, consensus, VM, system contracts, rollup kit, intents, wallet SDK, and 4 property-based invariant tests.
cargo run --bin solen-nodeThis starts a single-validator devnet with:
- JSON-RPC on
http://127.0.0.1:29944 - Explorer API on
http://127.0.0.1:29955 - P2P on port
50333 - RocksDB persistence at
data/devnet - 2-second block times
- Three genesis accounts (faucet, alice with 1M SOLEN, bob with 500K SOLEN)
Use --network to select the environment. Each sets default ports, data directory, and block time:
solen-node --network devnet # default
solen-node --network testnet
solen-node --network mainnet| RPC | P2P | Explorer | Data Directory | Block Time | |
|---|---|---|---|---|---|
| mainnet | 9944 | 30333 | 9955 | data/mainnet |
6s |
| testnet | 19944 | 40333 | 19955 | data/testnet |
2s |
| devnet | 29944 | 50333 | 29955 | data/devnet |
2s |
Any default can be overridden explicitly:
solen-node --network testnet --rpc-port 8888solen-node [OPTIONS]
Options:
--network <NETWORK> devnet, testnet, or mainnet [default: devnet]
--rpc-port <PORT> JSON-RPC port
--p2p-port <PORT> P2P listen port
--data-dir <DIR> RocksDB data directory
--block-time <MS> Block interval in ms
--bootstrap <MULTIADDR> Bootstrap peer address (repeatable)
--validator-seed <HEX> 32-byte hex seed for validator key
--no-p2p Disable P2P networking
--in-memory Use in-memory storage (no persistence)
--explorer-port <PORT> Explorer API port (0 to disable)
--genesis <PATH> Path to genesis.json config file
--prune Enable block pruning (default: archive mode)
# Terminal 1 — Node A
cargo run --bin solen-node
# Terminal 2 — Node B (auto-avoids port conflicts with different data dir)
cargo run --bin solen-node -- \
--rpc-port 29945 \
--p2p-port 50334 \
--data-dir data/devnet-2 \
--explorer-port 29956 \
--bootstrap /ip4/127.0.0.1/tcp/50333All methods use standard JSON-RPC 2.0. The RPC server accepts both HTTP POST and WebSocket connections on the same port.
| Method | Parameters | Description |
|---|---|---|
solen_chainStatus |
— | Chain height, state root, pending op count |
solen_getBalance |
account_id (hex) |
Account balance as string |
solen_getAccount |
account_id (hex) |
Full account info (balance, nonce, code_hash) |
solen_getBlock |
height (u64) |
Block header and execution summary |
solen_getLatestBlock |
— | Latest finalized block |
solen_getValidators |
— | Active validator set with stakes |
solen_submitOperation |
UserOperation |
Submit a signed operation to the mempool |
solen_simulateOperation |
UserOperation |
Dry-run without state changes |
solen_checkSponsorship |
UserOperation |
Check if a paymaster will sponsor |
solen_getStakingInfo |
account_id (hex) |
Delegations and pending undelegations |
solen_getVestingInfo |
account_id (hex) |
Vesting schedule and claimable amount |
solen_getGovernanceProposals |
— | All governance proposals |
solen_submitIntent |
IntentRequest |
Submit an intent for solver resolution |
solen_getPendingIntents |
limit? |
Get pending intents available for solvers |
solen_submitSolution |
SolutionRequest |
Submit a solver's solution for an intent |
solen_getRollupStatus |
rollup_id (u64) |
Rollup registration and latest state root |
solen_getRollupBatches |
rollup_id, limit? |
Verified batch history for a rollup |
solen_submitBatch |
BatchSubmitRequest |
Submit a rollup batch commitment |
Connect via ws://host:port (same port as HTTP). All RPC methods above are also callable over WebSocket. Additionally, the following subscriptions stream real-time events:
| Subscribe | Unsubscribe | Notification | Parameters | Description |
|---|---|---|---|---|
solen_subscribeNewBlocks |
solen_unsubscribeNewBlocks |
solen_newBlock |
— | Stream finalized blocks (height, epoch, proposer, tx count, gas) |
solen_subscribeTxConfirmation |
solen_unsubscribeTxConfirmation |
solen_txConfirmation |
sender, nonce |
Watch for a specific transaction confirmation (auto-closes after delivery) |
solen_subscribeValidatorChanges |
solen_unsubscribeValidatorChanges |
solen_validatorChange |
— | Validator set changes at epoch boundaries |
HTTP Example:
curl -s -X POST http://127.0.0.1:9944 \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"solen_chainStatus","params":[],"id":1}'WebSocket Example:
websocat ws://127.0.0.1:9944
{"jsonrpc":"2.0","id":1,"method":"solen_subscribeNewBlocks","params":[]}Available on the explorer port (default 9955).
| Endpoint | Description |
|---|---|
GET /api/status |
Indexing status (height, block/tx/event counts) |
GET /api/blocks?limit=N&offset=N |
Recent blocks |
GET /api/blocks/{height} |
Block by height |
GET /api/blocks/{height}/txs |
Transactions in a block |
GET /api/tx/{height}/{index} |
Transaction by block height and index |
GET /api/txs?limit=N&offset=N |
Recent transactions |
GET /api/accounts/{id}/txs?limit=N&offset=N |
Account transaction history |
GET /api/events?limit=N&offset=N |
Recent events |
GET /api/validators |
Validator set with stakes and commission |
GET /api/validators/stats |
Proposer statistics and uptime |
GET /api/accounts/{id}/tokens |
Token contracts held by an account |
GET /api/contracts |
All deployed contracts |
GET /api/contracts/{id}/holders |
Token holders for a contract |
GET /api/contracts/{hash}/source |
Published/verified contract source |
GET /api/rollups |
Registered rollups |
GET /api/rollups/{id} |
Rollup detail with batch count |
GET /api/rollups/{id}/batches |
Verified batch history |
GET /api/intents?limit=N |
Recently fulfilled intents |
Solen contracts are WASM modules compiled from any language that targets WebAssembly. Contracts interact with chain state through host functions.
| Function | Signature | Description |
|---|---|---|
storage_read |
(key_ptr, key_len, val_ptr) -> i32 |
Read from contract storage |
storage_write |
(key_ptr, key_len, val_ptr, val_len) |
Write to contract storage |
emit_event |
(topic_ptr, topic_len, data_ptr, data_len) |
Emit an event |
get_caller |
(out_ptr) |
Get the caller's 32-byte account ID |
get_block_height |
() -> i64 |
Current block height |
set_return_data |
(ptr, len) |
Set return data |
Contracts must export:
memory— linear memorycall(input_ptr: i32, input_len: i32) -> i32— entry point, returns output length
Contracts are deployed via Action::Deploy and called via Action::Call within a UserOperation. Gas is metered using wasmtime's fuel mechanism.
Validators register with a minimum stake (500,000 tokens). Delegators stake to validators and share epoch rewards proportionally. Undelegation has a 7-epoch cooldown.
Each rollup has a bridge vault. Deposits are instant. Withdrawals go through a challenge window (100 blocks) plus a withdrawal delay (50 blocks). Disputed withdrawals are blocked.
Proposals require 30% quorum and 66.67% supermajority to pass. Passed proposals have a 3-epoch timelock before execution. Supports parameter changes, rollup registration, and emergency pause/resume.
Each block has a configurable base fee per gas unit. After an operation executes, fees are deducted from the sender's balance. A configurable portion is burned and the remainder credited to the treasury account.
| Parameter | Default |
|---|---|
| Base fee per gas | 1 |
| Burn rate | 50% |
| Treasury share | 50% |
- Unit tests: 155 tests across all crates (including 6 rollup e2e tests)
- Property-based tests: Supply conservation, nonce monotonicity, state root determinism, no negative balances (via proptest)
- Fuzz targets: Executor, WASM VM, and transaction deserialization
cargo install cargo-fuzz
cd fuzz
cargo fuzz run fuzz_executor -- -max_total_time=300
cargo fuzz run fuzz_vm -- -max_total_time=300
cargo fuzz run fuzz_tx_decode -- -max_total_time=300Validators are slashed for:
- Double signing — 10% stake penalty + jailing
- Downtime — 1% penalty after 50 consecutive missed blocks
The solen CLI interacts with the network from the command line. Keys are stored locally in ~/.solen/keys.json with optional password encryption (Argon2id + AES-256-GCM).
cargo build -p solen-cli
# Key management
solen key generate alice
solen key import bob <seed-hex>
solen key list
solen key lock # encrypt with password
solen key unlock # decrypt
# Queries
solen status
solen balance alice
solen account alice
solen block 100
solen validators
# Transactions
solen transfer alice bob 100
solen stake alice <validator> 1000
solen unstake alice <validator> 500
# Governance
solen propose-block-time alice 4000 "Reduce block time"
solen vote alice 0 --yes --weight 1000
solen finalize-proposal alice 0
solen execute-proposal alice 0
# Rollups
solen register-rollup alice 1 "My Rollup" --proof-type mock
# Connect to testnet
solen --rpc https://testnet-rpc.solenchain.io --chain-id 9000 balance alicecd sdks/wallet-sdk-ts
npm install
npm run buildimport { SolenClient, SmartAccount } from "@solen/wallet-sdk";
const client = new SolenClient({ rpcUrl: "http://127.0.0.1:9944" });
// Query chain status
const status = await client.chainStatus();
console.log(`Height: ${status.height}`);
// Query account
const balance = await client.getBalance("616c69636500...");
// Build and submit a transfer
const alice = new SmartAccount("616c69636500...", client);
const op = await alice.buildTransfer("626f6200...", 500);
// ... sign op.signature with Ed25519 ...
const result = await alice.submit(op);| Principle | Implication |
|---|---|
| Minimal base layer | L1 handles consensus, settlement, and verification — not general-purpose execution |
| Native modularity | Rollups, proofs, and messaging are protocol-native |
| User safety by default | Every account is a smart account with recovery and policy |
| Bounded privacy | Proof systems allow selective disclosure without full transparency |
| Decentralization over throughput | Credible settlement over single-chain benchmarks |
| Metric | Value |
|---|---|
| Rust crates | 17 |
| TypeScript packages | 2 |
| Rust source lines | ~21,000 |
| Test functions | 198 |
| Property tests | 4 (hundreds of cases each) |
| Fuzz targets | 3 |
| RPC methods | 20 |
| Explorer endpoints | 18 |
| Transfer TPS | ~15,000 |
| Contract call TPS | ~10,000 |
198 passed, 0 failed
solen-consensus 30 tests (engine, validator, slashing, epoch, mempool, checkpoint, snapshot)
adversarial_tests 6 tests (double-sign, [0xFF] rejection, validator sync, per-sender limit)
solen-execution 22 tests (executor, state, fees, proof verification)
property_tests 4 tests (supply conservation, nonce monotonicity, state root, no negative balance)
security_tests 5 tests (withdraw idempotent, multi-action rollback, nonce replay, balance wrapping)
solen-vm 5 tests (WASM execution, gas metering, caching)
sandbox_tests 8 tests (malformed WASM, negative lengths, bounded return data, fuel metering)
solen-system-contracts 30 tests (staking, bridge, governance, guardian, vesting, treasury)
solen-storage 18 tests (memory store, rocks store, merkle root, snapshot)
determinism_tests 9 tests (cross-backend root identity, non-state key filtering, scan correctness)
solen-crypto 4 tests (Ed25519 sign/verify, deterministic keys)
solen-p2p 2 tests (message encoding roundtrip)
message_tests 5 tests (decompression bomb, malformed messages, empty input)
solen-rollup-kit 15 tests (sequencer, batch, prover, messenger, relayer)
rollup_e2e 6 tests (full lifecycle, invalid proof, stale state, multi-rollup, large batch)
solen-intents 6 tests (pool submit/fulfill, solution selection, expiry)
pool_security_tests 6 tests (solution cap, fulfilled rejection, pool bounds, cancel-by-sender)
solen-wallet-sdk 17 tests (account builder, auth, policy, recovery, sponsorship, transaction)
Licensed under MIT OR Apache-2.0 at your option.
