/** * Client Batching — Multi-Call UserOperations for TotalReclaw. * * Batches multiple encrypted fact payloads into a SINGLE ERC-4337 UserOperation, * resulting in one on-chain transaction that emits multiple Log(bytes) events. * * Why batch? * - Gas savings: ~21,000 gas base tx overhead paid once instead of N times * - Rate limit efficiency: 1 UserOp counted against paymaster limit, not N * - UX improvement: single confirmation for multi-fact extraction cycles * - Network efficiency: one bundler submission instead of N sequential ones * * How it works: * The ERC-4337 SimpleSmartAccount supports multi-call execution natively. * Each call in the `calls` array triggers a separate `fallback()` on the * EventfulDataEdge contract, emitting an independent `Log(bytes)` event. * The subgraph indexes each event separately (using txHash-logIndex as ID). * * Gas savings estimate (Base Sepolia / Gnosis): * Single fact: ~5,300 gas (base) + ~21,000 (tx overhead) = ~26,300 * Batch of 5: ~26,500 gas (base) + ~21,000 (tx overhead) = ~47,500 * Savings: 5 × 26,300 = 131,500 vs 47,500 → ~64% gas reduction * * Constraints: * - MAX_BATCH_SIZE = 15 (matches extraction cap per cycle) * - Empty batches are rejected * - Each payload is independently encoded (no aggregation) * - Paymaster counts this as 1 UserOp (not N) * * @module userop/batcher */ import type { Hex } from "viem"; /** * Maximum number of facts per batch UserOperation. * * Set to 15 to match the extraction cap (15 facts per cycle). * Going higher risks hitting block gas limits on some chains. */ export declare const MAX_BATCH_SIZE = 15; /** * Minimum batch size — use regular sendFactOnChain for single facts. * A batch of 1 is technically valid but offers no savings. */ export declare const MIN_BATCH_SIZE = 1; /** * Configuration for a batched UserOperation. */ export interface BatchUserOperationConfig { /** 32-byte private key derived from BIP-39 seed */ privateKey: Buffer; /** EventfulDataEdge contract address */ dataEdgeAddress: `0x${string}`; /** Chain ID (100 for Gnosis, 10200 for Chiado, 84532 for Base Sepolia) */ chainId: number; /** Array of encrypted Protobuf payloads to write on-chain */ encryptedPayloads: Buffer[]; /** TotalReclaw relay server URL (proxies bundler + paymaster JSON-RPC) */ serverUrl: string; /** Optional: override nonce (for sequential operations) */ nonce?: bigint; } /** * Result of a batched UserOperation submission. */ export interface BatchUserOperationResult { /** Number of facts included in the batch */ batchSize: number; /** Hex-encoded calldata for each fact */ callDataArray: string[]; /** Target contract address */ target: string; /** Operation nonce */ nonce: bigint; /** Sender (Smart Account) address */ sender: string; /** UserOperation hash returned by the bundler */ userOpHash: string; } /** * Configuration for the high-level batch send function. */ export interface SendBatchConfig { /** 32-byte private key derived from BIP-39 seed */ privateKey: Buffer; /** EventfulDataEdge contract address */ dataEdgeAddress: `0x${string}`; /** Chain ID (100 for Gnosis, 10200 for Chiado, 84532 for Base Sepolia) */ chainId: number; /** Array of encrypted Protobuf payloads to write on-chain */ encryptedPayloads: Buffer[]; /** TotalReclaw relay server URL (proxies bundler + paymaster JSON-RPC) */ serverUrl: string; /** Timeout in ms to wait for on-chain confirmation (default: 120_000) */ timeout?: number; } /** * Result of a completed batch send (built + confirmed on-chain). */ export interface SendBatchResult { /** Number of facts included in the batch */ batchSize: number; /** UserOperation hash from the bundler */ userOpHash: string; /** Transaction hash of the mined UserOperation */ transactionHash: string; } /** * Encode multiple encrypted payloads as an array of call objects * for the SmartAccountClient. * * Each call targets the same EventfulDataEdge contract with value=0. * The calldata for each is just the raw encrypted bytes (fallback function). */ export declare function encodeBatchCalls(encryptedPayloads: Buffer[], dataEdgeAddress: `0x${string}`): Array<{ to: `0x${string}`; value: bigint; data: Hex; }>; /** * Validate batch configuration. * * @throws Error if batch is empty or exceeds MAX_BATCH_SIZE */ export declare function validateBatchConfig(encryptedPayloads: Buffer[]): void; /** * Estimate gas savings from batching vs individual UserOps. * * Returns approximate savings percentage and absolute gas saved. * These are rough estimates — actual savings depend on chain and payload sizes. * * @param batchSize - Number of facts in the batch * @param avgPayloadBytes - Average encrypted payload size in bytes (default: 256) * @returns Gas savings estimate */ export declare function estimateGasSavings(batchSize: number, avgPayloadBytes?: number): { savingsPercent: number; individualGas: number; batchedGas: number; }; /** * Build an ERC-4337 UserOperation containing multiple fact writes. * * This creates a single UserOperation with multiple calls to the * EventfulDataEdge contract. Each call triggers the fallback() function, * emitting a separate Log(bytes) event that the subgraph indexes independently. * * The SmartAccountClient handles: * - initCode generation for first-time users * - Gas estimation for the multi-call UserOp * - Paymaster sponsorship (single sponsorship for all calls) * - Canonical ERC-4337 signing * - Bundler submission * * @param config - Batch UserOperation configuration * @returns Batch result with the userOp hash from the bundler * @throws Error if batch is empty, exceeds MAX_BATCH_SIZE, or chain is unsupported */ export declare function buildBatchUserOperation(config: BatchUserOperationConfig): Promise; /** * High-level function: build, sponsor, sign, submit a batched UserOperation, * and wait for on-chain confirmation. * * This is the primary entry point for writing multiple encrypted facts on-chain * in a single transaction. It combines buildBatchUserOperation + waitForReceipt. * * Default timeout is 120s (longer than single-fact 60s to account for larger gas). * * @param config - Complete configuration for sending a batch on-chain * @returns Object with batchSize, userOpHash, and transactionHash */ export declare function sendBatchOnChain(config: SendBatchConfig): Promise; //# sourceMappingURL=batcher.d.ts.map