Developer Getting Started Guide
Welcome to Rivellum development! This guide will help you set up your environment, run a local node, and build your first intent-based application.
š API Reference: Explore all available endpoints interactively in the API Explorer with live testing and code examples.
Prerequisites
Required Software
-
Rust: 1.81+ with cargo
rustup default stable rustup update -
Node.js: 20+ with npm
node --version # Should be v20+ npm --version -
Git: For cloning the repository
Optional Tools
- Docker: For running local devnets
- Move CLI: For compiling Move contracts
- VS Code: Recommended IDE with Rust and Move extensions
Quick Start (5 minutes)
1. Clone and Build
# Clone the repository
git clone https://github.com/rivellum/rivellum.git
cd rivellum
# Build all crates in release mode
cargo build --release
# Run tests to verify
cargo test --workspace
Expected build time: 2-5 minutes on modern hardware.
2. Start a Local Node
# Run with default configuration
.\target\release\rivellum-node.exe --config config\dev.toml
You should see:
[INFO] Starting Rivellum node...
[INFO] Network listening on /ip4/127.0.0.1/tcp/9000
[INFO] RPC server listening on 127.0.0.1:8545
[INFO] Node ready! ID: 12D3KooW...
3. Submit Your First Intent
Create my-intent.jsonl:
{"intent_id":"0x1234","from":"0xalice","nonce":0,"payload":{"Plain":[1,2,3]},"signature":"0xabc...","max_fee":1000}
Submit using CLI:
.\target\release\rivellum-node.exe intent submit my-intent.jsonl
Or using the TypeScript SDK:
import { RivellumClient } from '@rivellum/sdk';
const client = new RivellumClient('http://localhost:8545');
await client.submitIntent({
from: '0xalice',
payload: { type: 'transfer', to: '0xbob', amount: 100 },
});
Architecture Refresher
Before diving deeper, understand these core concepts:
- Intents: User declarations of desired outcomes (not imperative transactions)
- Batches: Groups of intents processed together for efficiency
- Shards: Parallel execution contexts (Aurora Fabric)
- Photon: BFT consensus algorithm with instant finality
- PoUW: Proof-of-Useful-Work for ZK proof generation
See Architecture Overview for full details.
Development Workflow
Project Structure
rivellum/
āāā crates/ # Rust workspace
ā āāā rivellum-node/ # Main binary
ā āāā rivellum-intents/ # Intent types & validation
ā āāā rivellum-execution/ # Aurora Fabric execution
ā āāā rivellum-ledger/ # State & storage
ā āāā rivellum-network/ # P2P networking
ā āāā rivellum-crypto/ # Cryptographic primitives
ā āāā rivellum-zk/ # ZK proof system
ā āāā rivellum-pouw/ # Proof-of-Useful-Work
ā āāā ...
āāā sdk/ # TypeScript SDK
āāā explorer/ # Block explorer UI
āāā portal/ # Developer playground
āāā contracts/ # Move smart contracts
āāā config/ # Node configuration files
āāā docs/ # Documentation (you are here!)
Configuration Files
Rivellum uses TOML configuration files in config/:
dev.toml: Local development (single node, mock ZK)testnet.toml: Multi-node testnetmainnet.example.toml: Production templatezk-real.toml: Enable real ZK proofs (requires prover)
Key settings:
chain_id = "devnet"
[network]
listen_addr = "127.0.0.1:9000"
bootstrap_peers = []
max_peers = 50
[rpc]
listen_addr = "127.0.0.1:8545"
max_concurrent_requests = 1000
request_timeout_secs = 30
[execution]
workers_per_committee = 4
max_queue_size = 50000
gas_limit = 1000000
lane_count = 4
[execution.sequencer]
window_k = 4
max_buffered_per_sender = 16
max_nonce_gap = 100
[events]
backend = "in_memory"
data_dir = "./data/events"
max_in_memory_events = 100000
durability = "async"
[startup]
seed_prefab_registry = true
Building Specific Crates
# Build only the node binary
cargo build --release --package rivellum-node
# Build with optimizations for size
cargo build --release --package rivellum-node --profile=release-small
# Check code without building
cargo check --workspace
# Run clippy linter
cargo clippy --workspace -- -D warnings
Running Tests
# Run all tests
cargo test --workspace
# Run tests for specific crate
cargo test --package rivellum-intents
# Run integration tests only
cargo test --test integration_tests
# Run with output
cargo test --workspace -- --nocapture
# Run specific test
cargo test test_intent_validation
Code Formatting
# Format all code
cargo fmt --all
# Check formatting without changes
cargo fmt --all -- --check
Working with Intents
Intent Structure
pub struct Intent {
pub intent_id: IntentId, // Unique identifier
pub from: Address, // Sender address
pub nonce: u64, // Replay protection
pub payload: PayloadKind, // Plain or Encrypted
pub signature: Signature, // EdDSA signature
pub max_fee: u64, // Maximum fee willing to pay
}
Creating Intents Programmatically
Rust:
use rivellum_intents::{Intent, IntentId, PayloadKind};
use rivellum_crypto::{KeyPair, sign_intent};
let keypair = KeyPair::generate();
let intent = Intent {
intent_id: IntentId::random(),
from: keypair.public_key().to_address(),
nonce: 0,
payload: PayloadKind::Plain(vec![1, 2, 3]),
signature: Signature::default(), // Placeholder
max_fee: 1000,
};
let signed = sign_intent(&intent, &keypair)?;
TypeScript SDK:
import { RivellumClient, Wallet } from '@rivellum/sdk';
const wallet = Wallet.fromMnemonic('your seed phrase...');
const client = new RivellumClient('http://localhost:8545');
const intent = await client.createIntent({
from: wallet.address,
payload: {
type: 'custom',
data: [1, 2, 3],
},
maxFee: 1000,
});
const signed = await wallet.signIntent(intent);
await client.submitIntent(signed);
Intent Types
Rivellum supports various built-in intent types:
- Transfer: Send tokens between accounts
- Contract Call: Invoke Move contract functions
- Contract Deploy: Deploy new Move modules
- Batch: Execute multiple operations atomically
- Custom: Application-specific payloads
Example transfer intent:
{
type: 'transfer',
to: '0xrecipient',
amount: 100,
token: '0x1::Coin::RIVL', // Native token
}
Smart Contracts with Move
Setting Up Move Development
# Install Move CLI (if not already installed)
cargo install --git https://github.com/move-language/move move-cli
# Create new Move project
mkdir my-contract
cd my-contract
move new MyModule
Your First Move Contract
Create sources/Counter.move:
module MyAddress::Counter {
use std::signer;
struct Counter has key {
value: u64,
}
public entry fun init(account: &signer) {
move_to(account, Counter { value: 0 });
}
public entry fun increment(account: &signer) acquires Counter {
let addr = signer::address_of(account);
let counter = borrow_global_mut<Counter>(addr);
counter.value = counter.value + 1;
}
public fun get_value(addr: address): u64 acquires Counter {
borrow_global<Counter>(addr).value
}
}
Compiling Move Contracts
# Compile to bytecode
move build
# Run Move unit tests
move test
# Generate documentation
move docgen
Deploying Contracts
Option 1: CLI
rivellum-node.exe contract deploy `
--bytecode ./build/MyModule/bytecode_modules/Counter.mv `
--sender 0xMyAddress
Option 2: SDK
import fs from 'fs';
const bytecode = fs.readFileSync('./build/MyModule/bytecode_modules/Counter.mv');
await client.deployContract({
bytecode,
sender: wallet.address,
});
Calling Contracts
await client.callContract({
module: 'MyAddress::Counter',
function: 'increment',
args: [],
sender: wallet.address,
});
const value = await client.view({
module: 'MyAddress::Counter',
function: 'get_value',
args: [wallet.address],
});
console.log('Counter value:', value);
Using the TypeScript SDK
Installation
npm install @rivellum/sdk
Basic Usage
import { RivellumClient, Wallet } from '@rivellum/sdk';
// Connect to node
const client = new RivellumClient('http://localhost:8545');
// Create wallet from private key
const wallet = Wallet.fromPrivateKey('0x123...');
// Check balance
const balance = await client.getBalance(wallet.address);
console.log('Balance:', balance);
// Submit transfer intent
const txHash = await client.transfer({
from: wallet.address,
to: '0xrecipient',
amount: 100,
signer: wallet,
});
// Wait for finality
const receipt = await client.waitForFinality(txHash);
console.log('Finalized in block:', receipt.blockNumber);
Advanced SDK Features
Batch Intents:
const batch = client.createBatch();
batch.addTransfer({ to: '0xalice', amount: 50 });
batch.addTransfer({ to: '0xbob', amount: 50 });
batch.addContractCall({
module: 'MyModule::MyContract',
function: 'do_something',
args: [42],
});
const txHash = await batch.submit(wallet);
Query State:
// Get account info
const account = await client.getAccount('0xaddress');
console.log('Nonce:', account.nonce);
console.log('Balance:', account.balance);
// Get batch by ID
const batch = await client.getBatch('0xbatchhash');
console.log('Intents:', batch.intents.length);
console.log('Status:', batch.status);
// Listen for events
client.on('batchFinalized', (batch) => {
console.log('New batch finalized:', batch.id);
});
Local Development Tools
Interactive Playground
The web-based playground allows testing intents without a running node:
cd portal
npm install
npm run dev
# Open http://localhost:3000/playground
Features:
- In-browser intent simulation
- Account management
- Contract deployment/testing
- Batch execution visualization
Block Explorer
Monitor your local node in real-time:
cd explorer
npm install
npm run dev
# Open http://localhost:3001
Shows:
- Recent batches and intents
- Account balances and nonces
- Shard utilization
- PoUW proof status
RPC API Testing
Use curl to test RPC endpoints directly:
# Get node info
curl http://localhost:8545/info
# Get account balance
curl -X POST http://localhost:8545/rpc `
-H "Content-Type: application/json" `
-d '{\"jsonrpc\":\"2.0\",\"method\":\"getBalance\",\"params\":[\"0xaddress\"],\"id\":1}'
# Submit intent
curl -X POST http://localhost:8545/rpc `
-H "Content-Type: application/json" `
-d '{\"jsonrpc\":\"2.0\",\"method\":\"submitIntent\",\"params\":[{...}],\"id\":1}'
Running a Multi-Node Devnet
For consensus testing, run multiple nodes:
# Start 3-node devnet with Docker
cd devnet
docker-compose up -d
# Check logs
docker-compose logs -f leader
docker-compose logs -f follower1
docker-compose logs -f follower2
# Shutdown
docker-compose down
Or manually:
# Terminal 1: Leader
rivellum-node.exe --config devnet\leader.toml
# Terminal 2: Follower 1
rivellum-node.exe --config devnet\follower1.toml
# Terminal 3: Follower 2
rivellum-node.exe --config devnet\follower2.toml
Debugging Tips
Enable Verbose Logging
# In your config.toml
[node]
log_level = "debug" # or "trace" for max verbosity
# Per-crate logging
[logging]
"rivellum_intents" = "debug"
"rivellum_execution" = "trace"
"rivellum_network" = "info"
Common Issues
Issue: Error: nonce mismatch
Solution: Each intent must have nonce = previous_nonce + 1. Query current nonce:
curl http://localhost:8545/account/0xaddress | jq .nonce
Issue: Error: insufficient balance
Solution: Check balance and ensure max_fee doesn't exceed available funds:
curl http://localhost:8545/account/0xaddress | jq .balance
Issue: Error: signature verification failed
Solution: Ensure you're signing the intent correctly. The signature covers:
hash(intent_id || from || nonce || payload_hash || max_fee)
Issue: Node won't start - "Address already in use" Solution: Change listen ports in config or kill existing process:
Get-Process rivellum-node | Stop-Process
Using Rust Debugger
# Build with debug symbols
cargo build --package rivellum-node
# Run with lldb (or gdb on Linux)
rust-lldb .\target\debug\rivellum-node.exe -- --config config\dev.toml
Or use VS Code debugger with .vscode/launch.json:
{
"type": "lldb",
"request": "launch",
"name": "Debug rivellum-node",
"cargo": {
"args": ["build", "--package=rivellum-node"]
},
"args": ["--config", "config/dev.toml"]
}
Performance Profiling
Benchmarking
# Run built-in benchmarks
cargo bench --package rivellum-intents
# Profile with flamegraph
cargo install flamegraph
cargo flamegraph --package rivellum-node -- --config config\dev.toml
Load Testing
# Generate 10,000 test intents
.\scripts\generate-test-intents.ps1 -Count 10000 -Output test-intents.jsonl
# Submit with parallel workers
.\scripts\load-test.ps1 -Intents test-intents.jsonl -Workers 10
Next Steps
Now that you have a working development environment:
- Build a dApp: See SDK Guide for full API reference
- Write Smart Contracts: Deep dive into Move Contracts
- Run a Prover: Learn PoUW Setup to earn rewards
- Deploy to Testnet: Follow Node Setup guide
Getting Help
- Discord: https://discord.gg/rivellum
- GitHub Issues: https://github.com/rivellum/rivellum/issues
- Docs: https://docs.rivellum.io
- Forum: https://forum.rivellum.io
Happy building! š