Void Toolkit Architecture Design
High-level architecture for the new void-toolkit - a framework for building verifiable applications that derive state from void blocks and generate ZK proofs of state transitions.
Core Philosophy & Goals
The void-toolkit is designed around one principle: minimize what Claude Code needs to generate while maximizing what it can build .
Design Goals:
Obvious patterns - An app developer (human or AI) should look at the API and immediately know how to use it. No hidden macros, no fragmented knowledge across repos.
Type-driven state - Developers think in types, not key-value pairs. A proc macro translates typed state definitions into merkle-compatible storage.
Linear pipeline - Blocks → Events → State Transition → Proof. No over-engineered stream combinators. Just an async loop.
Runtime flexibility - Same code runs as prover or verifier. Storage backend chosen at startup. Indexer toggled on/off.
Single import - use void_toolkit::prelude::* gives you everything. Feature flags control what's compiled.
What the toolkit handles:
Event fetching and caching from blockchains
P2P networking for blocks and proofs
Storage abstraction (memory, persistent, database)
ZK proof generation
API server for state queries
Indexer infrastructure
What the app developer provides:
Event type definitions
State schema (via #[derive(VoidState)])
State transition function
Indexer logic (optional)
Custom API handlers (optional)
Crate Structure
void-toolkit/
├── crates/
│ ├── types/ # Shared types (blocks, events, hashes, proofs)
│ ├── state/ # State trait, storage backends, proc macros
│ ├── events/ # Event fetcher, blockchain clients, cache
│ ├── p2p/ # P2P networking for blocks and proofs
│ ├── prove/ # ZK proof generation (RISC Zero integration)
│ ├── api/ # HTTP/WebSocket API server for state queries
│ ├── indexer/ # Indexer infrastructure for auxiliary state
│ ├── node/ # Node runtime that ties everything together
│ └── toolkit/ # Facade crate with re-exports
├── skills/
│ ├── creating-void-app/
│ ├── defining-state-schema/
│ ├── writing-stf/
│ ├── adding-indexer/
│ ├── exposing-api/
│ ├── testing-void-apps/
│ ├── running-node/
│ └── deploying-node/
└── examples/
├── counter/ # Minimal: single state value, one event type
├── token/ # Basic: balances map, transfer events
├── auction/ # Intermediate: time-based logic, multiple event types
└── orderbook/ # Complex: full matching engine, indexer, custom API
Facade crate (toolkit/):
[package ]
name = " void-toolkit"
[features ]
default = [" node" ]
node = [" void-node" ]
prover = [" void-prove" ]
indexer = [" void-indexer" ]
full = [" node" , " prover" , " indexer" ]
Data Flow
flowchart TB
subgraph External
BC[Blockchain Contracts]
BP[Block Producer]
PN[Peer Nodes]
end
subgraph EventFetcher["events/ crate"]
EF[Event Fetcher]
EC[Event Cache]
end
subgraph P2P["p2p/ crate"]
BR[Block Receiver]
PR[Proof Receiver]
PB[Proof Broadcaster]
end
subgraph Node["node/ crate"]
BL[Block Loop]
STF[State Transition Function]
end
subgraph State["state/ crate"]
PS[Proven State]
SB[(Storage Backend)]
end
subgraph Prove["prove/ crate"]
PG[Proof Generator]
ZK[RISC Zero Guest]
end
subgraph Indexer["indexer/ crate"]
IL[Indexer Logic]
IS[(Indexed State)]
end
subgraph API["api/ crate"]
AS[API Server]
end
BC -->|fetch events| EF
EF -->|store| EC
BP -->|blocks with hashes| BR
PN -->|blocks & proofs| BR
PN -->|proofs| PR
BR -->|block| BL
EC -->|resolve hashes| BL
BL -->|block + events| STF
STF -->|read/write| PS
PS -->|persist| SB
STF -->|witness| PG
PG -->|execute STF| ZK
ZK -->|proof| PB
PB -->|broadcast| PN
PR -->|verify| PS
STF -->|events + state| IL
IL -->|store| IS
PS -->|query| AS
IS -->|query| AS
Loading
The core loop:
Block arrives via P2P (contains event hashes only)
Event hashes resolved against cache (events fetched from blockchains)
State transition function executes with events
Proven state updated
If prover mode: generate ZK proof, broadcast
If indexer enabled: update indexed state
API serves queries against both state types
Component Overview
Crate
Purpose
types/
Shared types (blocks, events, hashes, proofs)
events/
Fetch and cache events from blockchains by hash
state/
Type-driven state storage with proc macros
p2p/
Block and proof gossip between nodes
prove/
ZK proof generation via RISC Zero
api/
HTTP/WebSocket server for state queries
indexer/
Auxiliary state derived from events + proven state
node/
Runtime that orchestrates all components
toolkit/
Facade with re-exports and feature flags
Key design notes:
types/ : Blocks contain event hashes only, not event data. Events resolved separately via events crate.
state/ : Storage is trait-based and runtime-selectable (memory, persistent, database).
indexer/ : Indexed state is plain Rust types, not proven. Derives from events and proven state.
Component interaction:
graph LR
subgraph "External"
Chains[Blockchains]
Peers[Peer Nodes]
end
subgraph "void-toolkit"
events --> node
p2p --> node
node --> state
node --> prove
node --> indexer
state --> api
indexer --> api
prove --> p2p
end
Chains --> events
Peers <--> p2p
Loading
Node Operating Modes
A void-toolkit node can run in different configurations based on feature flags and runtime config:
flowchart TB
subgraph "Prover Node"
direction TB
P_blocks[Receive Blocks] --> P_stf[Run STF]
P_stf --> P_state[Update State]
P_stf --> P_prove[Generate Proof]
P_prove --> P_broadcast[Broadcast Proof]
end
subgraph "Verifier Node"
direction TB
V_blocks[Receive Blocks] --> V_stf[Run STF]
V_proofs[Receive Proofs] --> V_verify[Verify Proof]
V_stf --> V_state[Update State]
V_verify --> V_state
end
subgraph "Optional: Indexer"
direction TB
I_events[Events + State] --> I_derive[Derive Indexed State]
I_derive --> I_store[Store Indexed State]
end
subgraph "Optional: API"
direction TB
A_proven[Proven State] --> A_serve[Serve Queries]
A_indexed[Indexed State] --> A_serve
end
Loading
Mode combinations:
Mode
Proves
Verifies
Indexes
API
Full Prover
✓
-
✓
✓
Light Prover
✓
-
-
-
Full Verifier
-
✓
✓
✓
Light Verifier
-
✓
-
-
All modes run the state transition function. The difference is whether they generate proofs, and which optional components are enabled.
App Developer Interface
What the app developer provides vs what the toolkit handles:
flowchart LR
subgraph "App Developer Provides"
Events[Event Types]
Schema[State Schema]
STF[State Transition Function]
Idx[Indexer Logic]
Handlers[API Handlers]
end
subgraph "Toolkit Generates/Provides"
Decode[Event Decoding]
Storage[Storage Layer]
Merkle[Merkle Integration]
Guest[ZK Guest Program]
Server[API Server]
Runtime[Node Runtime]
end
Events --> Decode
Schema --> Storage
Schema --> Merkle
STF --> Guest
Idx --> Runtime
Handlers --> Server
Loading
App structure:
my-void-app/
├── src/
│ ├── events.rs # Event type definitions
│ ├── state.rs # State schema (derive macro)
│ ├── stf.rs # State transition function
│ ├── indexer.rs # Optional: indexed state logic
│ └── api.rs # Optional: custom query handlers
├── Cargo.toml
└── config/
└── node.toml # Node runner configuration
Developer workflow:
Define event types that match blockchain contracts
Define state schema using #[derive(VoidState)]
Write state transition function that processes events
Optionally add indexer logic and custom API handlers
Build and run node with desired mode
Skills for Claude Code
Skills guide Claude Code through common tasks when building void apps:
flowchart TB
subgraph "App Development"
S1[creating-void-app]
S2[defining-state-schema]
S3[writing-stf]
S4[adding-indexer]
S5[exposing-api]
S6[testing-void-apps]
end
subgraph "Operations"
S7[running-node]
S8[deploying-node]
end
S1 --> S2 --> S3
S3 --> S4
S3 --> S5
S3 --> S6
S6 --> S7 --> S8
Loading
Skill purposes:
Skill
When to use
creating-void-app
Scaffold new project with correct structure
defining-state-schema
Design state using derive macros correctly
writing-stf
Patterns for processing events and updating state
adding-indexer
When and how to derive auxiliary state
exposing-api
Add custom query endpoints
testing-void-apps
Test STF with mock blocks and events
running-node
Start node locally in different modes
deploying-node
Deploy to production infrastructure
Each skill contains step-by-step guidance, common patterns, and pitfalls to avoid.
Architecture Summary
flowchart TB
subgraph "Blockchains"
ETH[Ethereum]
SOL[Solana]
BASE[Base]
end
subgraph "void-toolkit"
subgraph "Data Ingestion"
events[events/]
p2p[p2p/]
end
subgraph "Core Runtime"
node[node/]
state[state/]
types[types/]
end
subgraph "Optional Components"
prove[prove/]
indexer[indexer/]
api[api/]
end
toolkit[toolkit/ - facade]
end
subgraph "App Code"
APP[State Schema + STF + Indexer + API Handlers]
end
subgraph "Consumers"
Peers[Peer Nodes]
Clients[API Clients]
end
ETH & SOL & BASE --> events
Peers <--> p2p
events --> node
p2p --> node
types --> node
APP --> node
node --> state
node --> prove
node --> indexer
state --> api
indexer --> api
prove --> p2p
api --> Clients
toolkit -.-> events & p2p & node & state & prove & indexer & api
Loading
Key architectural principles:
Separation of concerns - Each crate has one job
Blocks carry hashes, not data - Events resolved separately
All nodes run STF - Prover/verifier distinction is only about proof generation
Type-driven state - Developers define types, toolkit handles storage
Optional components - Indexer, prover, API toggled via features
Single facade - void-toolkit re-exports everything needed
Next Steps
This document serves as guidance for detailed design documents for each component:
types/ - Define exact type structures
state/ - Design the proc macro and storage trait
events/ - Design blockchain clients and cache
p2p/ - Design networking protocol
prove/ - Design RISC Zero integration
api/ - Design server and query interface
indexer/ - Design indexer infrastructure
node/ - Design runtime orchestration
Skills - Write each skill with patterns and examples
Void Toolkit Architecture Design
High-level architecture for the new void-toolkit - a framework for building verifiable applications that derive state from void blocks and generate ZK proofs of state transitions.
Core Philosophy & Goals
The void-toolkit is designed around one principle: minimize what Claude Code needs to generate while maximizing what it can build.
Design Goals:
Obvious patterns - An app developer (human or AI) should look at the API and immediately know how to use it. No hidden macros, no fragmented knowledge across repos.
Type-driven state - Developers think in types, not key-value pairs. A proc macro translates typed state definitions into merkle-compatible storage.
Linear pipeline - Blocks → Events → State Transition → Proof. No over-engineered stream combinators. Just an async loop.
Runtime flexibility - Same code runs as prover or verifier. Storage backend chosen at startup. Indexer toggled on/off.
Single import -
use void_toolkit::prelude::*gives you everything. Feature flags control what's compiled.What the toolkit handles:
What the app developer provides:
#[derive(VoidState)])Crate Structure
Facade crate (
toolkit/):Data Flow
flowchart TB subgraph External BC[Blockchain Contracts] BP[Block Producer] PN[Peer Nodes] end subgraph EventFetcher["events/ crate"] EF[Event Fetcher] EC[Event Cache] end subgraph P2P["p2p/ crate"] BR[Block Receiver] PR[Proof Receiver] PB[Proof Broadcaster] end subgraph Node["node/ crate"] BL[Block Loop] STF[State Transition Function] end subgraph State["state/ crate"] PS[Proven State] SB[(Storage Backend)] end subgraph Prove["prove/ crate"] PG[Proof Generator] ZK[RISC Zero Guest] end subgraph Indexer["indexer/ crate"] IL[Indexer Logic] IS[(Indexed State)] end subgraph API["api/ crate"] AS[API Server] end BC -->|fetch events| EF EF -->|store| EC BP -->|blocks with hashes| BR PN -->|blocks & proofs| BR PN -->|proofs| PR BR -->|block| BL EC -->|resolve hashes| BL BL -->|block + events| STF STF -->|read/write| PS PS -->|persist| SB STF -->|witness| PG PG -->|execute STF| ZK ZK -->|proof| PB PB -->|broadcast| PN PR -->|verify| PS STF -->|events + state| IL IL -->|store| IS PS -->|query| AS IS -->|query| ASThe core loop:
Component Overview
types/events/state/p2p/prove/api/indexer/node/toolkit/Key design notes:
Component interaction:
graph LR subgraph "External" Chains[Blockchains] Peers[Peer Nodes] end subgraph "void-toolkit" events --> node p2p --> node node --> state node --> prove node --> indexer state --> api indexer --> api prove --> p2p end Chains --> events Peers <--> p2pNode Operating Modes
A void-toolkit node can run in different configurations based on feature flags and runtime config:
flowchart TB subgraph "Prover Node" direction TB P_blocks[Receive Blocks] --> P_stf[Run STF] P_stf --> P_state[Update State] P_stf --> P_prove[Generate Proof] P_prove --> P_broadcast[Broadcast Proof] end subgraph "Verifier Node" direction TB V_blocks[Receive Blocks] --> V_stf[Run STF] V_proofs[Receive Proofs] --> V_verify[Verify Proof] V_stf --> V_state[Update State] V_verify --> V_state end subgraph "Optional: Indexer" direction TB I_events[Events + State] --> I_derive[Derive Indexed State] I_derive --> I_store[Store Indexed State] end subgraph "Optional: API" direction TB A_proven[Proven State] --> A_serve[Serve Queries] A_indexed[Indexed State] --> A_serve endMode combinations:
All modes run the state transition function. The difference is whether they generate proofs, and which optional components are enabled.
App Developer Interface
What the app developer provides vs what the toolkit handles:
flowchart LR subgraph "App Developer Provides" Events[Event Types] Schema[State Schema] STF[State Transition Function] Idx[Indexer Logic] Handlers[API Handlers] end subgraph "Toolkit Generates/Provides" Decode[Event Decoding] Storage[Storage Layer] Merkle[Merkle Integration] Guest[ZK Guest Program] Server[API Server] Runtime[Node Runtime] end Events --> Decode Schema --> Storage Schema --> Merkle STF --> Guest Idx --> Runtime Handlers --> ServerApp structure:
Developer workflow:
#[derive(VoidState)]Skills for Claude Code
Skills guide Claude Code through common tasks when building void apps:
flowchart TB subgraph "App Development" S1[creating-void-app] S2[defining-state-schema] S3[writing-stf] S4[adding-indexer] S5[exposing-api] S6[testing-void-apps] end subgraph "Operations" S7[running-node] S8[deploying-node] end S1 --> S2 --> S3 S3 --> S4 S3 --> S5 S3 --> S6 S6 --> S7 --> S8Skill purposes:
creating-void-appdefining-state-schemawriting-stfadding-indexerexposing-apitesting-void-appsrunning-nodedeploying-nodeEach skill contains step-by-step guidance, common patterns, and pitfalls to avoid.
Architecture Summary
flowchart TB subgraph "Blockchains" ETH[Ethereum] SOL[Solana] BASE[Base] end subgraph "void-toolkit" subgraph "Data Ingestion" events[events/] p2p[p2p/] end subgraph "Core Runtime" node[node/] state[state/] types[types/] end subgraph "Optional Components" prove[prove/] indexer[indexer/] api[api/] end toolkit[toolkit/ - facade] end subgraph "App Code" APP[State Schema + STF + Indexer + API Handlers] end subgraph "Consumers" Peers[Peer Nodes] Clients[API Clients] end ETH & SOL & BASE --> events Peers <--> p2p events --> node p2p --> node types --> node APP --> node node --> state node --> prove node --> indexer state --> api indexer --> api prove --> p2p api --> Clients toolkit -.-> events & p2p & node & state & prove & indexer & apiKey architectural principles:
void-toolkitre-exports everything neededNext Steps
This document serves as guidance for detailed design documents for each component:
types/- Define exact type structuresstate/- Design the proc macro and storage traitevents/- Design blockchain clients and cachep2p/- Design networking protocolprove/- Design RISC Zero integrationapi/- Design server and query interfaceindexer/- Design indexer infrastructurenode/- Design runtime orchestration