A lightweight sequencer for the Stellar ZK L2 mesh network. Designed to run on both servers and mobile devices (with Mopro for native proving).
┌─────────────────────────────────────────────────────────────────┐
│ MESH NETWORK │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Mobile │◄───►│ Mobile │◄───►│ Server │ │
│ │ (Light) │ BLE │ (Full+Mopro)│ TCP │ (Full) │ │
│ └─────────────┘ └─────────────┘ └──────┬──────┘ │
│ │ │
│ Offline mesh continues working │ Online │
│ Proven batches relay to online nodes ▼ │
│ ┌──────────────┐ │
│ │ Stellar L1 │ │
│ │ (Settlement)│ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
- Collects and validates L2 transactions
- Builds batches
- Gossips transactions/batches to peers
- No proof generation - relays to full sequencers
- Runs on any device (very lightweight)
- Everything light does PLUS
- Generates Groth16 proofs (settlement circuit)
- Submits proven batches to Stellar L1
- Can use snarkjs (slower) or Mopro (fast native)
| Backend | Platform | Proof Time |
|---|---|---|
| Mopro | iOS (iPhone 13) | 39-42ms |
| Mopro | Android | 200-800ms |
| snarkjs | Node.js | 3-5 seconds |
| snarkjs | WASM (browser) | 10+ seconds |
With Mopro, mobile devices can run full sequencers!
npm installnpm run start:lightnpm run start:fullimport { Sequencer, createDefaultConfig } from '@lumenbro/zk-sequencer';
// Create a light sequencer
const config = createDefaultConfig('light');
const sequencer = new Sequencer(config);
// Start
await sequencer.start();
// Submit a transaction
await sequencer.submitTransaction({
id: 'tx-123',
type: 'transfer',
senderPubkey: '123...',
recipientPubkey: '456...',
assetId: '0',
amount: '1000000',
inputCommitment: 'abc...',
nonce: '1',
timestamp: Date.now(),
signature: { r: '...', s: '...' }
});
// Get stats
console.log(sequencer.getStats());
// Stop
await sequencer.stop();import { Sequencer, createDefaultConfig, MoproBackend } from '@lumenbro/zk-sequencer';
import MoproFfi from 'mopro-ffi';
const config = createDefaultConfig('full');
config.circuitPath = './assets/circuits';
const sequencer = new Sequencer(config);
// Use Mopro for fast native proving
sequencer.setProverBackend(new MoproBackend(MoproFfi));
await sequencer.start();Sequencers communicate via a gossip protocol supporting multiple transports:
| Transport | Use Case | Bandwidth |
|---|---|---|
| TCP/WebSocket | Online servers | High |
| Bluetooth LE | Offline mesh | Low (~247 bytes/msg) |
| WiFi Direct | Offline, close range | Medium |
NEW_TX- Broadcast new transactionNEW_BATCH- Broadcast unproven batchPROVEN_BATCH- Broadcast proven batch (ready for L1)REQUEST_TXS- Request missing transactionsSTATE_SYNC- Synchronize state rootsPEER_ANNOUNCE- Discover peers
Stores pending transactions waiting to be batched.
Aggregates transactions into batches based on:
- Max batch size (configurable)
- Timeout (create batch even if not full)
Manages L2 state:
- UTXO Merkle tree (Poseidon hashes)
- Nullifier accumulator
- State transitions
Generates Groth16 proofs using:
SnarkjsBackend- Universal, slowerMoproBackend- Native, fast (mobile)
P2P communication with multiple transports.
interface SequencerConfig {
mode: 'light' | 'full';
sequencerId: string;
networkId: 'testnet' | 'mainnet';
maxBatchSize: number;
batchTimeoutMs: number;
circuitPath?: string; // Full mode only
zkeyPath?: string; // Full mode only
settlementContractId: string;
stellarSecret?: string; // Full mode only
gossip: {
enableBluetooth: boolean;
enableWifiDirect: boolean;
tcpPort: number;
wsPort: number;
bootstrapPeers: string[];
};
storagePath: string;
}- lumenbro/Circuits - Circom circuits
- lumenbro/stellar-groth16 - Groth16 verifier library
- lumenbro/zk-l2-settlement - Settlement contract
- lumenbro/zk-bridge - Bridge contract
MIT