Overview
The Batcher is a production-ready service for aggregating and batching user transactions across multiple blockchains. It provides a unified HTTP API for submitting inputs while abstracting away blockchain-specific complexity through a pluggable adapter system.
Quick Startβ
Get started quickly with these essential guides:
- Introduction - Overview and architecture
- Core Concepts - Understanding the building blocks
- Configuration - Setting up your batcher
- The Batching Pipeline - How inputs flow through the system
Key Featuresβ
π Multi-Chain Supportβ
Batch transactions for multiple blockchains simultaneously. Each blockchain gets its own adapter with independent batching rules and configuration.
π Flexible Batching Strategiesβ
Configure when batches are submitted using time-based, size-based, value-based, hybrid, or custom criteriaβindependently per blockchain.
πΎ Crash-Safe Storageβ
All inputs are persisted immediately to storage (file, PostgreSQL, Redis, or custom). No in-memory queues that can be lost on restart.
π Pluggable Architectureβ
- Adapters: Add support for new blockchains by implementing the
BlockchainAdapterinterface - Storage: Use any backend by implementing the
BatcherStorageinterface - Criteria: Define custom batching logic with user-defined functions
π Production-Readyβ
- RESTful HTTP API with OpenAPI documentation
- Event system for monitoring and observability
- Graceful shutdown with configurable hooks
- Structured concurrency using Effection
Architecture Overviewβ
βββββββββββββββ
β HTTP Client β
ββββββββ¬βββββββ
β POST /send-input
βΌ
ββββββββββββββββββββββββββββββββββββ
β Batcher Core β
β - Validation β
β - Storage Persistence β
β - Batching Criteria Check β
ββββββββββ¬ββββββββββββββββββββββββββ
β
ββββββ΄ββββββ¬βββββββββββ
βΌ βΌ βΌ
ββββββββββ ββββββββββ ββββββββββ
βEVM β βMidnightβ βCustom β
βAdapter β βAdapter β βAdapter β
βββββ¬βββββ βββββ¬βββββ βββββ¬βββββ
β β β
βΌ βΌ βΌ
ββββββββββ ββββββββββ ββββββββββ
βEthereumβ βMidnightβ βCustom β
βChain β βNetwork β βChain β
ββββββββββ ββββββββββ ββββββββββ
Documentation Structureβ
Getting Startedβ
- Introduction - What is the Batcher and why use it?
- Core Concepts - Key abstractions:
Batcher,BlockchainAdapter,Target,DefaultBatcherInput
Configuration & Setupβ
- Configuration - Complete setup guide with dynamic and unified configuration approaches
- The Batching Pipeline - Understanding the input lifecycle from submission to confirmation
Customizationβ
- Custom Adapters - Implementing
BlockchainAdapterfor new blockchains - Advanced Topics - HTTP API, batching criteria, event system, storage backends, and Effection integration
Common Use Casesβ
Multi-Chain Gamingβ
Batch player actions across multiple chains with different batching rules per chain.
batcher
.addBlockchainAdapter("ethereum", ethAdapter, {
criteriaType: "hybrid",
timeWindowMs: 5000, // 5 seconds max wait
maxBatchSize: 50 // or 50 moves
})
.addBlockchainAdapter("polygon", polygonAdapter, {
criteriaType: "time",
timeWindowMs: 1000 // Submit every second (cheaper gas)
});
Financial Applicationsβ
Batch payments when accumulated value reaches a threshold.
batcher.addBlockchainAdapter("payments", paymentsAdapter, {
criteriaType: "value",
valueAccumulatorFn: (input) => input.amount,
targetValue: 100000 // Batch when $1000 accumulated
});
NFT Mintingβ
Process mints in batches based on queue size.
batcher.addBlockchainAdapter("nft", nftAdapter, {
criteriaType: "size",
maxBatchSize: 20 // Mint 20 NFTs per batch
});
Example: Complete Setupβ
import { main, suspend } from "effection";
import { PaimaBatcher, FileStorage, PaimaL2DefaultAdapter } from "@effectstream/batcher";
// 1. Create adapter
const adapter = new PaimaL2DefaultAdapter(
"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb", // Contract address
process.env.PRIVATE_KEY!, // Private key
0n, // Fee
"mainEvmRPC" // Sync protocol name
);
// 2. Create batcher
const batcher = new PaimaBatcher({
pollingIntervalMs: 1000,
port: 3334,
enableHttpServer: true,
enableEventSystem: true,
adapters: {} // Start empty, add dynamically
}, new FileStorage("./batcher-data"));
// 3. Wire adapter with criteria
batcher.addBlockchainAdapter("ethereum", adapter, {
criteriaType: "hybrid",
timeWindowMs: 5000,
maxBatchSize: 50
}).setDefaultTarget("ethereum");
// 4. Add monitoring
batcher.addStateTransition("startup", ({ publicConfig }) => {
console.log(`π Batcher started on port ${publicConfig.port}`);
});
batcher.addStateTransition("batch:submit", ({ txHash }) => {
console.log(`π Batch submitted: ${txHash}`);
});
// 5. Run with Effection
main(function* () {
yield* batcher.runBatcher();
yield* suspend();
});
API Endpointsβ
Once running, the batcher exposes these HTTP endpoints:
POST /send-input- Submit a new inputGET /status- Batcher status and configurationGET /queue-stats- Queue statistics per targetGET /health- Health checkPOST /force-batch- Manually trigger batching (dev)GET /documentation- Interactive OpenAPI docs
See HTTP API for complete documentation.
Next Stepsβ
Choose your path:
I'm new to the batcher:
- Read Introduction
- Understand Core Concepts
- Follow Configuration Guide
I want to customize:
- Learn The Batching Pipeline
- Implement Custom Adapters
- Explore Advanced Topics
I'm ready to deploy:
- Review Configuration
- Set up Event System for monitoring
- Configure Storage for production