batch_posting_status
Track batch posting activity to monitor sequencer inbox updates and backlog size. Essential for chain data availability insights on Arbitrum networks using RPC URLs and contract addresses.
Instructions
Monitor batch posting activity. Tracks when batches were last posted to the sequencer inbox and current backlog size. Essential for PM and support teams to understand chain data availability status.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| bridgeAddress | Yes | Bridge contract address | |
| chainName | No | Chain name (e.g., 'Xai', 'Arbitrum One') - will auto-resolve to RPC URL | |
| parentRpcUrl | Yes | Parent chain RPC URL (e.g., Ethereum mainnet RPC) | |
| rpcUrl | No | The RPC URL of the Arbitrum chain (optional if default is set) | |
| sequencerInboxAddress | Yes | Sequencer inbox contract address |
Implementation Reference
- src/index.ts:720-738 (handler)MCP tool handler implementation for 'batch_posting_status'. Resolves RPC URL, creates ArbitrumChainClient instance, calls getBatchPostingStatus method, and returns JSON stringified result.case "batch_posting_status": { const rpcUrl = await this.resolveRpcUrl( (args.rpcUrl as string) || (args.chainName as string) ); const chainDataClient = new ArbitrumChainClient(rpcUrl); const status = await chainDataClient.getBatchPostingStatus( args.parentRpcUrl as string, args.sequencerInboxAddress as string, args.bridgeAddress as string ); return { content: [ { type: "text", text: JSON.stringify(status, null, 2), }, ], }; }
- TypeScript interface defining the structure of BatchPostingStatus, which is the output type returned by the tool handler.export interface BatchPostingStatus { lastBatchPostedSecondsAgo: number; lastBlockReported: string; latestChildChainBlockNumber: string; backlogSize: string; summary: string; }
- src/index.ts:1558-1590 (registration)Tool registration in getAvailableTools() method, including name, description, and inputSchema validation for the 'batch_posting_status' tool.{ name: "batch_posting_status", description: "Monitor batch posting activity. Tracks when batches were last posted to the sequencer inbox and current backlog size. Essential for PM and support teams to understand chain data availability status.", inputSchema: { type: "object" as const, properties: { rpcUrl: { type: "string", description: "The RPC URL of the Arbitrum chain (optional if default is set)", }, chainName: { type: "string", description: "Chain name (e.g., 'Xai', 'Arbitrum One') - will auto-resolve to RPC URL", }, parentRpcUrl: { type: "string", description: "Parent chain RPC URL (e.g., Ethereum mainnet RPC)", }, sequencerInboxAddress: { type: "string", description: "Sequencer inbox contract address", }, bridgeAddress: { type: "string", description: "Bridge contract address", }, }, required: ["parentRpcUrl", "sequencerInboxAddress", "bridgeAddress"], }, },
- Supporting method getBatchPostingStatus in ArbitrumChainClient class that implements the core logic: queries parent chain for SequencerBatchDelivered events, computes time since last batch, backlog size from bridge, and generates summary.async getBatchPostingStatus( parentRpcUrl: string, sequencerInboxAddress: string, bridgeAddress: string ): Promise<BatchPostingStatus> { try { const parentClient = createPublicClient({ transport: http(parentRpcUrl), }); const sequencerBatchDeliveredEventAbi = { anonymous: false, inputs: [ { indexed: true, name: "batchSequenceNumber", type: "uint256" }, { indexed: true, name: "beforeAcc", type: "bytes32" }, { indexed: true, name: "afterAcc", type: "bytes32" }, { indexed: false, name: "delayedAcc", type: "bytes32" }, { indexed: false, name: "afterDelayedMessagesRead", type: "uint256" }, { components: [ { name: "minTimestamp", type: "uint64" }, { name: "maxTimestamp", type: "uint64" }, { name: "minBlockNumber", type: "uint64" }, { name: "maxBlockNumber", type: "uint64" }, ], name: "timeBounds", type: "tuple", }, { name: "dataLocation", type: "uint8" }, ], name: "SequencerBatchDelivered", type: "event", } as const; const latestBlockNumber = await parentClient.getBlockNumber(); const fromBlock = latestBlockNumber - BigInt(10000); const logs = await parentClient.getLogs({ address: sequencerInboxAddress as `0x${string}`, event: sequencerBatchDeliveredEventAbi, fromBlock, toBlock: latestBlockNumber, }); if (logs.length === 0) { return { lastBatchPostedSecondsAgo: 999999, lastBlockReported: "0", latestChildChainBlockNumber: "0", backlogSize: "0", summary: "No batches found in recent blocks" }; } const lastLog = logs[logs.length - 1]; const lastBatchBlock = await parentClient.getBlock({ blockNumber: lastLog.blockNumber, }); const lastBatchPostedSecondsAgo = Math.floor(Date.now() / 1000) - Number(lastBatchBlock.timestamp); const lastBlockReported = await parentClient.readContract({ address: bridgeAddress as `0x${string}`, abi: parseAbi([ 'function sequencerReportedSubMessageCount() view returns (uint256)', ]), functionName: 'sequencerReportedSubMessageCount', }); const latestChildChainBlockNumber = await this.publicClient.getBlockNumber(); const backlogSize = latestChildChainBlockNumber - lastBlockReported; const summary = `Last batch posted ${Math.floor(lastBatchPostedSecondsAgo / 3600)}h ${Math.floor((lastBatchPostedSecondsAgo % 3600) / 60)}m ago. Backlog: ${backlogSize} blocks.`; return { lastBatchPostedSecondsAgo, lastBlockReported: lastBlockReported.toString(), latestChildChainBlockNumber: latestChildChainBlockNumber.toString(), backlogSize: backlogSize.toString(), summary }; } catch (error) { return { lastBatchPostedSecondsAgo: 999999, lastBlockReported: "0", latestChildChainBlockNumber: "0", backlogSize: "0", summary: `Error checking batch posting: ${error instanceof Error ? error.message : 'Unknown error'}` }; } }