Skip to content

Method and schema reference

TOOL Reference

This page defines the public methods and endpoints mentioned in the integration and architecture docs. It focuses on the current TOOL-facing surface: source bundle ingress, the quote flow, native searcher bundles, subscriptions, preconfirmed state reads, TEE attestation, callbacks, and MEV-Boost-compatible relay endpoints. Where bundles go after they are accepted is described in Delivery Rules.

Method Index

Conventions

Convention Meaning
JSON-RPC envelope All RPC examples use {"jsonrpc":"2.0","id":1,"method":"...","params":[...]}.
Hash 0x-prefixed 32-byte value. Used for commitment ids, transaction hashes, block hashes, storage slots, and parent hashes.
Address 0x-prefixed 20-byte Ethereum address.
Signed transaction 0x-prefixed Ethereum transaction bytes, not a transaction object.
Block number Ethereum JSON-RPC block number or tag. For eth_sendBundle, ofp_sendUnsignedBundle, and ofp_sendSignedBundle, TOOL accepts only "0x0", "pending", "latest", or the node's exact next block number. Anything else fails with state not ready.
Time Block and timestamp fields are Unix seconds unless otherwise noted.
Operation mask Access masks use 1 for read, 2 for write, and 3 for read/write.
WebSocket subscriptions Use tool_subscribe to create a subscription and tool_unsubscribe with the returned subscription id to cancel it.
Request signature Send an X-Flashbots-Signature header with eth_sendBundle, eth_sendRawTransaction, ofp_sendUnsignedBundle and ofp_sendSignedBundle requests, signed with the standard Flashbots scheme: <address>:<signature> over the Keccak-256 hash of the request body. Clients that already sign requests for the Flashbots relay can use the same signing code.

Current compatibility boundary

Blob transactions are not supported anywhere: every bundle path rejects them. The Flashbots-style builders field is supported on eth_sendBundle and ofp_sendSignedBundle; see The builders Field. The Flashbots-style replacementUuid field is recognized by the request shape but is not product-supported; clients should omit it.

Shared Schemas

Schema: SendBundleArgs

SendBundleArgs is the request object for inbound eth_sendBundle and the body TOOL sends to callbacks and builders (see Callback Receiver Contract). The delivered body never contains builders or callbackUrl.

{
  "txs": ["0x..."],
  "blockNumber": "0x...",
  "minTimestamp": 0,
  "maxTimestamp": 0,
  "revertingTxHashes": ["0x..."],
  "callbackUrl": "https://source.example/tool-callback",
  "builders": ["titan"]
}
Field Type Required Description
txs string[] Yes Signed Ethereum transactions encoded as 0x bytes. Must be non-empty. Blob transactions are rejected.
blockNumber quantity \| tag Yes Target block: "0x0", "pending", "latest", or the node's exact next block number. Anything else fails with state not ready.
minTimestamp uint64 No eth_sendBundle only. Minimum acceptable TOOL block timestamp. The bundle is rejected if this is greater than the current TOOL block time.
maxTimestamp uint64 No eth_sendBundle only. Maximum acceptable TOOL block timestamp. The bundle is rejected if this is less than the current TOOL block time.
revertingTxHashes hash[] No eth_sendBundle only. Transaction hashes from txs that may revert without invalidating the bundle. Every listed hash must be present in txs.
callbackUrl string No Source callback endpoint. Must be an http or https URL with a host and no more than 512 characters. Rejected with callback URL provided but callback mode is disabled when the node runs without callback mode.
builders string[] \| null No Allow-list of external builders that may receive bundles built from this order flow. Omitted or null: the default (all builders without callbackUrl, none with it). []: none; send it literally, a client that drops empty arrays (Go omitempty) sends no field and gets the default. ["*"]: every registered builder. Names are case-insensitive, surrounding whitespace is ignored, duplicates are removed. Unknown names are dropped silently; if none is known the call fails with unknown builders: .... Registered on mainnet: flashbots, beaverbuild.org, buildernet, titan, btcs, bobthebuilder, eureka, bombora, quasar, ethgas, ultrasound. See The builders Field.
replacementUuid uuid No Flashbots-style field. Not currently product-supported.

Schema: UnsignedTxArgs

UnsignedTxArgs is an eth_call-style transaction object used in txs of ofp_sendUnsignedBundle. It is not a signed transaction.

{
  "from": "0x1111111111111111111111111111111111111111",
  "to": "0x2222222222222222222222222222222222222222",
  "value": "0x2386f26fc10000",
  "gas": "0x5208",
  "maxFeePerGas": "0x77359400",
  "maxPriorityFeePerGas": "0x3b9aca00",
  "nonce": "0x0",
  "chainId": "0x0"
}
Field Type Required Description
from address Yes A real, funded account.
to address No Omitted for contract creation.
nonce quantity Yes Not filled from chain state.
gas quantity Yes Gas limit. Not estimated.
value quantity No Wei transferred.
gasPrice quantity No Legacy pricing.
maxFeePerGas, maxPriorityFeePerGas quantity No EIP-1559 pricing.
data / input bytes No Call data.
accessList AccessList No EIP-2930 access list.
chainId quantity No Chain id.
authorizationList Authorization[] No EIP-7702 authorizations.

Schema: SignedBundleArgs

SignedBundleArgs is the request object for ofp_sendSignedBundle.

{
  "txs": ["0x02f8b0..."],
  "blockNumber": "0x0",
  "callbackUrl": "https://your-ofp-endpoint.example.com/tool-final",
  "builders": ["titan", "flashbots"],
  "unsignedCmtId": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
}
Field Type Required Description
txs string[] Yes The signed versions of the ofp_sendUnsignedBundle transactions, in the same order. Blob transactions are rejected.
blockNumber quantity \| tag Yes "0x0", "pending", "latest", or the node's exact next block number.
callbackUrl string No Final callback endpoint, independent of the step 1 URL. Without it there is no final callback. Same URL rules as SendBundleArgs.
builders string[] \| null No As in SendBundleArgs, then intersected with the chosen candidate's extBuilders as stored in the pool.
unsignedCmtId hash Yes The id of the chosen quote, not the bundleHash of ofp_sendUnsignedBundle.

minTimestamp, maxTimestamp, and revertingTxHashes are ignored by this call.

Schema: ToolBundle

ToolBundle is the native request object for tool_sendBundle and tool_simulateBundle.

{
  "basedCommitments": ["0x..."],
  "blockTime": 0,
  "blockParent": "0x...",
  "subslot": 0,
  "expirySubslot": 14,
  "newTxs": ["0x..."]
}
Field Type Required Description
basedCommitments hash[] No Existing commitment ids this bundle builds on. At least one basedCommitments entry or one newTxs entry is required.
blockTime uint64 No Target block timestamp. If omitted, TOOL uses the current block time. If provided, it must match the current TOOL block time.
blockParent hash No Target parent block hash. If omitted, TOOL uses the current parent. If provided, it must match the current TOOL parent.
subslot uint8 No First subslot where the resulting commitment may be accepted. Defaults to the current next subslot.
expirySubslot uint8 No Last subslot where the resulting commitment may be accepted. Must not be earlier than the current next subslot.
newTxs string[] No New signed transactions encoded as 0x bytes. Blob transactions are rejected.

Schema: Commitment

Commitment is the result for native bundle submission/simulation, the commitment of a quote, and the notification payload for tool_subscribe commitments.

{
  "id": "0x...",
  "blockTime": 0,
  "blockParent": "0x...",
  "subslot": 0,
  "expirySubslot": 14,
  "txsSize": 0,
  "execGasUsed": 0,
  "stateGasUsed": 0,
  "maxExecGasLimit": 0,
  "maxStateGasLimit": 0,
  "fees": "0",
  "accesses": {},
  "callbackUrl": "0x...<hash of the callback URL>",
  "extBuilders": ["flashbots", "titan"],
  "unsignedTxs": ["0x..."],
  "logs": [],
  "stateDiff": { "accounts": {} }
}
Field Type Description
id hash Commitment identifier. For eth_sendBundle, this is returned as bundleHash. Covers the transactions, parent, subslot, expiry, block time, and reverting transactions; extBuilders and callbackUrl are not part of it.
blockTime uint64 Block timestamp the commitment targets.
blockParent hash Parent block hash the commitment targets.
dirty boolean Present only when set.
subslot uint8 First acceptable subslot.
expirySubslot uint8 Last acceptable subslot.
txsSize uint64 Total encoded transaction size in bytes.
execGasUsed uint64 Execution gas consumed by the commitment.
stateGasUsed uint64 State gas consumed by the commitment.
maxExecGasLimit uint64 Largest remaining execution gas requirement for inclusion.
maxStateGasLimit uint64 Largest remaining state gas requirement for inclusion.
fees integer Total fees paid by the commitment transactions.
accesses Accesses Account and storage read/write footprint.
callbackUrl hash Keccak256 of the RLP encoding of the stored callback value, never the URL. Absent when there is no callback. The mixed-origin marker appears as 0x412ef0d083d26bfee59b608aa779a3b180b7b1c2f59dbb9b944c2df04be67fcf. Decoding keeps the hash string as the value, so a commitment decoded from JSON has no usable callback.
extBuilders string[] External builders allowed to receive this commitment's bundle. Omitted when empty.
unsignedTxs hash[] Hashes of quote-flow transactions not signed yet.
logs Log[] Ethereum logs generated by execution. May be omitted when trimmed.
stateDiff StateDiff \| null State changes generated by execution. May be null when trimmed.

Transaction hashes and reverting hashes are not in JSON. A locally built commitment is gossiped without stateDiff and logs when it is 400 KB or more or needs more gas than its subslot offered. Where a commitment is delivered follows from callbackUrl and extBuilders; see Delivery Rules.

Schema: Accesses and StateDiff

Accesses is encoded as an object keyed by account address.

{
  "0x0000000000000000000000000000000000000000": {
    "balance": 1,
    "nonce": 2,
    "code": 0,
    "storage": {
      "0x...slot": 3
    }
  }
}
Field Type Description
balance uint8 Balance access mask. 1 read, 2 write, 3 read/write.
nonce uint8 Nonce access mask.
code uint8 Code access mask.
storage object<hash,uint8> Storage slot access masks keyed by slot hash.

StateDiff is encoded as an object keyed by account address under accounts.

{
  "accounts": {
    "0x0000000000000000000000000000000000000000": {
      "balance": "0",
      "nonce": 1,
      "code": "0x...",
      "storage": {
        "0x...slot": "0x...value"
      }
    }
  }
}
Field Type Description
balance string Net balance change as a signed decimal string.
nonce uint64 New account nonce, when changed.
code bytes New contract code or delegation bytes, when changed.
storage object<hash,hash> New storage values keyed by slot hash.

Schema: Subslot, BuildSchedule, and BlockParams

Subslot is the notification payload for tool_subscribe subslots.

{
  "id": "0x...",
  "txs": ["0x..."],
  "blockTime": 0,
  "blockParent": "0x...",
  "index": 0,
  "txsSize": 0,
  "execGasUsed": 0,
  "stateGasUsed": 0,
  "receiptGasUsed": 0,
  "accesses": {},
  "stateDiff": { "accounts": {} },
  "receipts": []
}
Field Type Description
id hash Subslot identifier.
txs hash[] Transaction hashes accepted in the subslot.
blockTime uint64 Target block timestamp.
blockParent hash Target parent block hash.
index uint8 Subslot index within the block.
txsSize uint64 Total transaction size in bytes.
execGasUsed uint64 Execution gas used by accepted transactions.
stateGasUsed uint64 State gas used by accepted transactions. Always zero before Amsterdam.
receiptGasUsed uint64 Gas used by accepted transactions as reported in receipts. Equals execGasUsed before Amsterdam.
accesses Accesses Combined read/write footprint.
stateDiff StateDiff \| null Combined state changes.
receipts Receipt[] Ethereum receipts for executed transactions.

BuildSchedule is the notification payload for tool_subscribe buildSchedule.

{
  "blockParent": "0x...",
  "blockTime": 0,
  "firstSubslotStartsAt": "2026-01-01T00:00:00Z",
  "blockSealAt": "2026-01-01T00:00:11Z"
}
Field Type Description
blockParent hash Parent block for the slot.
blockTime uint64 Slot block timestamp.
firstSubslotStartsAt time Scheduled wall-clock time for the first subslot.
blockSealAt time Scheduled wall-clock time when the block is sealed.

BlockParams is the result for tool_nextBlockParams.

{
  "reservedGas": 0,
  "reservedSize": 0,
  "proposerPreferences": {
    "blockSealOffsetMs": 0,
    "filterOFAC": false
  }
}
Field Type Description
reservedGas uint64 Gas reserved for non-TOOL block assembly.
reservedSize uint64 Block byte size reserved for non-TOOL block assembly.
proposerPreferences object \| null TOOL settings selected for the block, or null when none are set. blockSealOffsetMs (uint64) is the block seal offset in milliseconds. filterOFAC (boolean) is true when transactions involving OFAC listed addresses are rejected.

Schema: GetAttestationRequest and GetAttestationResponse
{
  "userNonce": "00112233445566778899aabbccddeeff",
  "certScope": "tool"
}
Field Type Required Description
userNonce hex string Yes Caller-generated random nonce, hex without a 0x prefix. Must decode to 16 to 32 bytes.
certScope string Yes TLS certificate scope name to bind into the attestation.
{
  "evidenceBundle": {},
  "tlsCertFingerprint": "...",
  "challenge": "...",
  "sessionId": "...",
  "keyDelegation": "..."
}
Field Type Description
evidenceBundle object Session evidence bundle from the node's attestation portal, used by the verifier. Pass evidenceBundle to the verifier byte for byte as received: re-serializing evidenceBundle invalidates the proof.
tlsCertFingerprint hex string SHA-256 fingerprint of the TLS certificate served for certScope, without a 0x prefix.
challenge hex string SHA256(keccak256("TOOL_TLS_ATTESTATION_V1") || keccak256(userNonce) || keccak256(tlsCertPubKeyDER)), returned for diagnostics. Verifiers recompute the challenge themselves and do not use the returned challenge.
sessionId hex string 32-byte id of the attested session that signed keyDelegation.
keyDelegation hex string 65-byte signature by the attested session key that authorizes the TLS certificate key.

eth_sendBundle

eth_sendBundle

JSON-RPC eth namespace Source ingress

Use eth_sendBundle when an orderflow provider or external PBS builder wants to submit a Flashbots-style bundle into TOOL. TOOL validates the signed transactions, executes the bundle against the current TOOL block state, creates a source commitment, and returns the commitment id as bundleHash. The response confirms only acceptance. Where the bundle and solutions on it go depends on callbackUrl and builders (table in The builders Field): without a callback the bundle itself is forwarded to its builders in the background; with a callback nothing is forwarded and the callback receives solutions. Builder failures are never reported. The bundle is gossiped, so callbacks come from whichever node built a solution, signed with that node's key: expect zero, one, or several per submission.

eth_sendRawTransaction takes the same path in miniature: the transaction is also wrapped into a bundle with all builders and no callback, so it is forwarded to all builders right away.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_sendBundle",
  "params": [
    {
      "txs": ["0x..."],
      "blockNumber": "0x...",
      "minTimestamp": 0,
      "maxTimestamp": 0,
      "revertingTxHashes": [],
      "callbackUrl": "https://source.example/tool-callback",
      "builders": ["titan"]
    }
  ]
}
Parameter Type Description
params[0] SendBundleArgs Source bundle request.
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "bundleHash": "0x..."
  }
}
Result field Type Description
bundleHash hash Commitment id created from the accepted source bundle.

Common rejection cases (full list in Errors):

Case Behavior
TOOL is not enabled or not preconfirmed for the target block, or blockNumber is not accepted. state not ready.
Node is not in P2P TOOL mode. Reject as unavailable in WS mode.
txs is empty. bundle missing txs.
Any transaction is a blob transaction. blob transactions not allowed.
revertingTxHashes contains a hash not present in txs. some reverting txs not found in bundle: ....
callbackUrl is not an http(s) URL with a host, or is over 512 characters. invalid callback URL.
callbackUrl is set but the node runs without callback mode. callback URL provided but callback mode is disabled.
None of the builders names is registered. unknown builders: ....
Timestamp does not match current TOOL state. Reject.

ofp_sendUnsignedBundle

ofp_sendUnsignedBundle

JSON-RPC ofp namespace Quote flow

Use ofp_sendUnsignedBundle as step 1 of the quote flow, when the user must not sign until the outcome of a backrun is known. TOOL creates an unsigned commitment and gossips it; searchers build solutions on it, and the node that accepted this call POSTs each candidate to callbackUrl as a quote. Only that node holds the unsigned bodies, so the follow-up ofp_sendSignedBundle must go to the same node.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "ofp_sendUnsignedBundle",
  "params": [
    {
      "txs": [{
        "from": "0x1111111111111111111111111111111111111111",
        "to": "0x2222222222222222222222222222222222222222",
        "value": "0x2386f26fc10000",
        "gas": "0x5208",
        "maxFeePerGas": "0x77359400",
        "maxPriorityFeePerGas": "0x3b9aca00",
        "nonce": "0x0",
        "chainId": "0x0"
      }],
      "blockNumber": "0x0",
      "callbackUrl": "https://your-ofp-endpoint.example.com/tool-quote"
    }
  ]
}
Field Type Required Description
txs UnsignedTxArgs[] Yes Call-style transaction objects. nonce is required.
blockNumber quantity \| tag Yes "0x0", "pending", "latest", or the node's exact next block number.
callbackUrl string Yes Quote endpoint. http or https URL with a host, at most 512 characters.
builders string[] No Ignored; the unsigned commitment allows all builders. Pass builders to ofp_sendSignedBundle.
revertingTxHashes hash[] No Rejected.
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "bundleHash": "0x..."
  }
}
Result field Type Description
bundleHash hash Id of the unsigned commitment. Not the unsignedCmtId for ofp_sendSignedBundle; use the quote's commitment.id.

Rate limit: 100 requests per second.

Error Meaning
state not ready No TOOL state for blockNumber, or a value that is not accepted.
rate limit exceeded More than 100 requests per second.
invalid callback URL Missing, not an http(s) URL with a host, or over 512 characters.
unsigned bundles are only supported in callback mode Callbacks are off on this node.
revertingTxHashes not supported for unsigned bundle The field was sent.
bundle missing txs Empty txs.

ofp_sendSignedBundle

ofp_sendSignedBundle

JSON-RPC ofp namespace Quote flow

Use ofp_sendSignedBundle as step 5 of the quote flow to finalize the chosen quote, on the same node as ofp_sendUnsignedBundle. TOOL re-executes the signed transactions with the solver's and compares the resulting state diff with the quoted one: any change of the outcome fails with signed bundle state diff mismatch; differences that leave the state untouched (a higher gas limit with the same gas used) are accepted. The signed bundle then always joins the pool and gossip, so relay merging can include it and searchers can build on it. If callbackUrl is set, TOOL sends the final callback (Callback Receiver Contract) before the RPC response, then forwards the bundle to the selected builders in the background.

If a transaction of the chosen candidate has not reached the node yet, the call waits up to 1 second for the missing transaction, or until the block is sealed if that comes first. A shorter client timeout ends the call first.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "ofp_sendSignedBundle",
  "params": [
    {
      "txs": ["0x02f8b0..."],
      "blockNumber": "0x0",
      "callbackUrl": "https://your-ofp-endpoint.example.com/tool-final",
      "builders": ["titan", "flashbots"],
      "unsignedCmtId": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
    }
  ]
}
Parameter Type Description
params[0] SignedBundleArgs Signed transactions and the chosen quote id.
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "bundleHash": "0x..."
  }
}
Result field Type Description
bundleHash hash Id of the signed commitment.

Do not retry after a callback error

The node validates the bundle, stores it, gossips it, and only then delivers it. Your callback endpoint must not wait for the RPC response. If the callback fails, the call returns the error, but the bundle is already in the network and builders may already have it. A retry is rejected as already known.

Error Meaning
state not ready No TOOL state for blockNumber, or a value that is not accepted.
invalid callback URL Not an http(s) URL with a host, or over 512 characters.
blob transactions not allowed A blob transaction.
unknown builders: ... None of the names is registered.
unsignedCmtId is required Zero or missing unsignedCmtId.
unsigned commitment not found The id is wrong (use the quote's id), the block moved on, or the candidate left the pool while the call waited.
signed tx count mismatch with unsigned commitment txs is empty or does not line up with the candidate.
some signed txs not found The solver's transactions did not arrive before the block was sealed or changed.
unsigned txs not found The candidate has no state diff here and this node does not hold your unsigned bodies: call the step 1 node.
signed bundle state diff mismatch The signed parameters change the outcome: start again from step 1.
a callback delivery error Your callback endpoint did not acknowledge. The commitment is already stored and gossiped: do not retry.

tool_sendBundle

tool_sendBundle

JSON-RPC tool namespace Searcher submission

Use tool_sendBundle when a TOOL searcher has built a native bundle from one or more base commitments and optional new signed transactions. The method creates the solution, stores it in the TOOL pool, gossips it, and starts its delivery in the background. It returns before delivery: the response does not say whether the solution was delivered, and delivery failures are only logged on the node. already known means the solution is already in the network; do not resubmit. The call is bounded by the node's RPC execution timeout, which covers preparation and execution but not delivery.

The solution's callback and builders are derived from its bases: without bases it gets all builders and no callback; with bases the builders are the intersection and the callback is kept only if every base has the same one, otherwise it becomes mixed-origin (see Callback and Builders of a Solution). Read callbackUrl and extBuilders in the returned Commitment to see where it goes. See Submitting Solutions.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tool_sendBundle",
  "params": [
    {
      "basedCommitments": ["0x..."],
      "newTxs": ["0x..."],
      "blockTime": 0,
      "blockParent": "0x...",
      "subslot": 0,
      "expirySubslot": 14
    }
  ]
}
Parameter Type Description
params[0] ToolBundle Native TOOL bundle request. At least one base commitment or one new transaction is required.
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "0x...",
    "blockTime": 0,
    "blockParent": "0x...",
    "subslot": 0,
    "expirySubslot": 14,
    "txsSize": 0,
    "execGasUsed": 0,
    "stateGasUsed": 0,
    "maxExecGasLimit": 0,
    "maxStateGasLimit": 0,
    "fees": "0",
    "accesses": {},
    "extBuilders": ["flashbots", "titan"],
    "stateDiff": { "accounts": {} }
  }
}
Result field Type Description
result Commitment Full commitment object created from the native bundle.

Common rejection cases (see Rejection Checks):

Case Behavior
basedCommitments and newTxs are both empty. empty transactions list.
Any newTxs transaction is a blob transaction. blob transactions are not supported.
Provided blockTime, blockParent, or subslot does not match current TOOL state. Reject.
A base commitment is unknown, future-dated, or targets a different parent. Reject.
A base expires earlier than the bundle. invalid commitment <hash> expiration.
A base with unsigned transactions is not first. commitments with unsigned txs must be first in the list.
A conflicting base's transactions did not arrive within one second, or the block changed meanwhile. access lists are not compatible and N based txs not found.
An unsigned base without callback mode or without a single callback. unsigned commitment requires callback mode and a single callback URL (...).
No usable callback and no common builder, outside relay merging. commitment has no delivery target (...).
Resulting size or gas exceeds current block/subslot limits. Reject.

tool_simulateBundle

tool_simulateBundle

JSON-RPC tool namespace Searcher simulation

Use tool_simulateBundle to evaluate the same native ToolBundle shape used by tool_sendBundle. It runs the same preparation, including the merge rules and rejection checks, and returns the commitment without storing, gossiping, or delivering anything.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tool_simulateBundle",
  "params": [
    {
      "basedCommitments": ["0x..."],
      "newTxs": ["0x..."]
    }
  ]
}
Parameter Type Description
params[0] ToolBundle Native TOOL bundle request. Same schema as tool_sendBundle.
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "0x...",
    "blockTime": 0,
    "blockParent": "0x...",
    "subslot": 0,
    "expirySubslot": 14,
    "txsSize": 0,
    "execGasUsed": 0,
    "stateGasUsed": 0,
    "maxExecGasLimit": 0,
    "maxStateGasLimit": 0,
    "fees": "0",
    "accesses": {},
    "stateDiff": { "accounts": {} }
  }
}
Result field Type Description
result Commitment Simulated commitment object. It is not submitted or propagated.

tool_nextBlockParams

tool_nextBlockParams

JSON-RPC tool namespace Block constraints

Use tool_nextBlockParams to read the current block-building constraints before creating or sizing a native TOOL bundle.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tool_nextBlockParams",
  "params": [
    "0x...parentHash",
    0
  ]
}
Parameter Type Description
params[0] hash Parent block hash expected by the caller. Must match current TOOL state.
params[1] uint64 Block timestamp expected by the caller. Must match current TOOL state.
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "reservedGas": 0,
    "reservedSize": 0,
    "proposerPreferences": {
      "blockSealOffsetMs": 0,
      "filterOFAC": false
    }
  }
}
Result field Type Description
reservedGas uint64 Gas reserved for non-TOOL block assembly.
reservedSize uint64 Byte size reserved for non-TOOL block assembly.
proposerPreferences object \| null blockSealOffsetMs and filterOFAC selected for the block, or null when none are set. See BlockParams.

tool_subscribe

tool_subscribe

WebSocket JSON-RPC tool namespace Events

Use tool_subscribe over WebSocket for live TOOL events. The initial result is a subscription id. Notifications use the standard JSON-RPC subscription shape.

Topic Parameters Notification payload Use case
commitments ["commitments", {}] or ["commitments", {"0x...address": true}] Commitment Receive commitment events. Address filters match storage writes for the listed addresses. Use {} for all commitments.
subslots ["subslots"] Subslot Observe accepted subslot events.
nextHeaders ["nextHeaders"] Ethereum Header Observe the header currently being built.
buildSchedule ["buildSchedule"] BuildSchedule Observe the scheduled first subslot start and block seal time after consensus bootstrap.
{
  "jsonrpc": "2.0",
  "method": "tool_subscription",
  "params": {
    "subscription": "0x...",
    "result": {}
  }
}
Result source Type Description
tool_subscribe result subscriptionId Subscription id returned by the initial JSON-RPC response.
tool_subscription.params.subscription subscriptionId Id of the subscription that produced a notification.
tool_subscription.params.result Commitment, Subslot, Ethereum Header, or BuildSchedule Topic-specific event payload.
tool_unsubscribe result boolean true when a live subscription was cancelled.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tool_subscribe",
  "params": [
    "commitments",
    {
      "0x0000000000000000000000000000000000000000": true
    }
  ]
}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tool_subscribe",
  "params": ["subslots"]
}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tool_subscribe",
  "params": ["nextHeaders"]
}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tool_subscribe",
  "params": ["buildSchedule"]
}

eth_call / eth_getTransactionCount / eth_getTransactionReceipt / eth_getBlockByHash

Preconfirmed eth_* Overrides

JSON-RPC eth namespace Compatibility

TOOL preserves standard Ethereum JSON-RPC method names for selected read paths. When the requested block is available in TOOL preconfirmed state, these methods read from that state. When TOOL state is not available for the selector or object, the implementation falls back to the normal Ethereum behavior.

Method Standard parameters
eth_call Transaction call object, block selector, optional state overrides, optional block overrides.
eth_getTransactionCount Address, block selector.
eth_getTransactionReceipt Transaction hash.
eth_getBlockByHash Block hash, fullTx boolean.
Method TOOL result behavior
eth_call Executes the call against TOOL preconfirmed state when available. Revert handling matches the normal eth_call path.
eth_getTransactionCount Returns the TOOL preconfirmed nonce when available. Falls back to the normal nonce otherwise.
eth_getTransactionReceipt Returns a standard receipt for TOOL-layer accepted subslot transactions when available. Falls back to the normal receipt otherwise.
eth_getBlockByHash Returns a standard block object for a TOOL preconfirmed block view when available. Falls back to the normal block lookup otherwise.

Integration guidance

Treat these as compatibility overrides, not separate TOOL methods. Clients can keep standard Ethereum call shapes and use explicit block selectors where they need preconfirmed state.

tee_getAttestation

tee_getAttestation

JSON-RPC tee namespace Verification

Use tee_getAttestation when an integrator needs a fresh TEE attestation quote bound to a caller-provided nonce and the TLS certificate public key served by the node.

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tee_getAttestation",
  "params": [
    {
      "userNonce": "00112233445566778899aabbccddeeff",
      "certScope": "network"
    }
  ]
}
Parameter Type Description
params[0] GetAttestationRequest Freshness challenge and TLS certificate scope.
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "evidenceBundle": {},
    "tlsCertFingerprint": "...",
    "challenge": "...",
    "sessionId": "...",
    "keyDelegation": "..."
  }
}
Result field Type Description
evidenceBundle object Session evidence bundle used by the verifier. Keep evidenceBundle byte for byte as received.
tlsCertFingerprint hex string SHA-256 fingerprint of the TLS certificate served for certScope, without a 0x prefix.
challenge hex string The challenge the bundle answers, returned for diagnostics only.
sessionId hex string 32-byte id of the attested session that signed keyDelegation.
keyDelegation hex string 65-byte signature by the attested session key that authorizes the TLS certificate key.

Verifier checklist (tlsCertPubKeyDER is the DER-encoded public key of the certificate observed during the TLS handshake):

Check Reason
userNonce is newly generated and 16 to 32 random bytes. Prevents replay.
tlsCertFingerprint matches the SHA-256 of the certificate observed during the TLS handshake. Proves the attested service owns the live TLS endpoint.
Recompute the challenge yourself: SHA256(keccak256("TOOL_TLS_ATTESTATION_V1") || keccak256(userNonce) || keccak256(tlsCertPubKeyDER)). Binds the evidence to your nonce and the certificate public key.
evidenceBundle, unchanged, verifies against your recomputed challenge and the deployment attestation policy. Confirms the expected enclave/service identity and gives the attested session id and session key.
sessionId equals the verified session id, and keyDelegation recovers to the verified session key over keccak256("ATAKIT_SESSION_SIGN_V1" || keccak256("TOOL_TLS_DELEGATION_V1") || sessionId || keccak256(tlsCertPubKeyDER)). Proves the attested CVM holds this TLS key. Without the key delegation check, any server could relay a bundle from another node.

Callback Receiver Contract

TOOL sends a Flashbots-compatible JSON-RPC POST to a callback for solutions on the source's own flow (and for the final ofp_sendSignedBundle bundle). A callback sees only its own source's transactions: a solution that merges bundles of different sources, or with a bundle without a callback, is mixed-origin and is never delivered to a callback. See Delivery Rules.

POST {callbackUrl}
Content-Type: application/json
Accept: application/json
X-Flashbots-Signature: <address>:<hex signature>
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_sendBundle",
  "params": [
    {
      "txs": ["0x02f8b0...", "0x02f8a3..."],
      "blockNumber": "0x152dd21",
      "minTimestamp": 1753000000,
      "maxTimestamp": 1753000000
    }
  ]
}
Requirement Description
Method Callback receivers should accept eth_sendBundle with SendBundleArgs.
Body txs: every transaction in order, bases first (the source's, then the searcher's), ready to broadcast. blockNumber: parent plus one. minTimestamp and maxTimestamp: the block time. revertingTxHashes appears only when not empty. builders is never included. The same body goes to every URL of every allowed builder.
Signature header Signed with the FlashbotsKey of the node that built and delivers the bundle; empty if that node has no FlashbotsKey. Builders also receive their additional_headers.
Sender Solutions are sent from whichever node built them, with that node's key. Expect zero, one, or many calls per submission, from different nodes. Deduplicate by transaction hashes.
Timeout 5 seconds per request, independent of the timeout of the RPC call that caused the delivery.
Retries None.
Success response HTTP status must be below 300, and the JSON-RPC response must not contain an error.
Response size TOOL reads at most 64 KiB of the callback response body.

Verifying a signed callback (the standard Flashbots scheme):

  1. Split X-Flashbots-Signature on : into signerAddress and signatureHex.
  2. bodyHashHex = the hex string (0x..., 66 characters) of keccak256(rawBody).
  3. digest = keccak256("\x19Ethereum Signed Message:\n66" + bodyHashHex).
  4. ecrecover(digest, signatureHex) must equal signerAddress and a TOOL signing address you trust (for solutions built by other nodes, that node's address).

Quote Callback Contract

For each candidate solution on an ofp_sendUnsignedBundle commitment, TOOL POSTs a quote to that call's callbackUrl. Quotes come only from the node that accepted the unsigned call, because only it holds the unsigned transaction bodies. The X-Flashbots-Signature header is empty: do not require a signature on quotes. Timeout (5 seconds), success response, and no-retry rules are the same as the Callback Receiver Contract.

{
  "commitment": {
    "id": "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    "blockTime": 1753000000,
    "blockParent": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
    "subslot": 0,
    "expirySubslot": 15,
    "txsSize": 340,
    "execGasUsed": 145000,
    "stateGasUsed": 0,
    "maxExecGasLimit": 30000000,
    "maxStateGasLimit": 0,
    "fees": "210000000000000",
    "accesses": {},
    "callbackUrl": "0x5f0e...<hash of your callback URL>",
    "extBuilders": ["flashbots", "titan"],
    "unsignedTxs": ["0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"],
    "stateDiff": {
      "accounts": {
        "0x1111111111111111111111111111111111111111": { "balance": "-3120000000000000", "nonce": 1 },
        "0x2222222222222222222222222222222222222222": { "balance": "3000000000000000" }
      }
    }
  },
  "messages": [{
    "from": "0x1111111111111111111111111111111111111111",
    "to": "0x2222222222222222222222222222222222222222",
    "value": "0x2386f26fc10000",
    "gasLimit": "0x5208",
    "gasPrice": "0x77359400",
    "gasFeeCap": "0x77359400",
    "gasTipCap": "0x3b9aca00",
    "data": "0x",
    "blobGasFeeCap": "0x0"
  }]
}
Field Meaning
commitment The candidate Commitment.
commitment.id Pass it as unsignedCmtId to ofp_sendSignedBundle for the candidate you choose.
commitment.unsignedTxs Hashes of your own transactions, identical for every candidate of one submission. Use it to correlate quotes; callbackUrl cannot be used for that, it is a hash of the URL.
commitment.stateDiff.accounts Map keyed by address. balance is a signed decimal string; an absent address means no change. Can be null (and logs absent) for a candidate of 400 KB or more, or one that needs more gas than one subslot offers; such a candidate cannot be ranked by balance.
commitment.extBuilders Builders that may receive this candidate's final bundle; the ofp_sendSignedBundle builders is limited to it. Omitted when empty.
messages Resolved execution arguments of every transaction in the candidate, in order (yours, then the searcher's).

Choose a candidate by comparing stateDiff.accounts[target].balance across candidates, within the block: candidates stop being resolvable when the chain head moves. Zero quotes is normal; use a timeout. A quote can arrive later than its solution appeared, if the searcher's transactions had not reached the node yet. A quote never contains another source's transactions.

MEV-Boost Builder HTTP

The relay surface is HTTP, not JSON-RPC. Endpoints are MEV-Boost-compatible and are served by TOOL's in-process relay.

Endpoint Method Request Response Use case
/eth/v1/builder/status GET None 200 OK Health check.
/eth/v1/builder/validators POST Signed validator registrations 200 OK Register validators and optional block seal offset.
/eth/v1/builder/header/{slot}/{parentHash}/{pubKey} GET Path params Versioned signed builder bid, 204, or 404 Retrieve a builder bid.
/eth/v1/builder/blinded_blocks POST Signed blinded beacon block Versioned payload response Submit blinded block and receive payload.
/eth/v2/builder/blinded_blocks POST Signed blinded beacon block 202 Accepted Submit blinded block using the v2 path.

Relay format and parameter notes:

Item Description
Content-Type / Accept Supports application/json and application/octet-stream. Octet-stream uses SSZ.
Eth-Consensus-Version Set on successful header and payload responses.
block_seal_offset_ms Optional query parameter on /validators. Must be no more than 4000 ms.
slot Decimal slot number in the header path.
parentHash 0x-encoded 32-byte parent hash in the header path.
pubKey 0x-encoded 48-byte validator public key in the header path.
X-Timeout-Ms and Date-Milliseconds Optional request headers used to derive a header-request deadline.

Errors

"unsigned" is ofp_sendUnsignedBundle; "signed" is ofp_sendSignedBundle; tool_* is tool_sendBundle and tool_simulateBundle.

Error Calls Meaning
state not ready all OFP calls No TOOL state for blockNumber, or a value that is not accepted
rate limit exceeded unsigned More than 100 requests per second
invalid callback URL all OFP calls Missing (unsigned), not an http(s) URL with a host, or over 512 characters
callback URL provided but callback mode is disabled eth_sendBundle Callbacks are off on this node
unsigned bundles are only supported in callback mode unsigned Callbacks are off on this node
revertingTxHashes not supported for unsigned bundle unsigned The field was sent
bundle missing txs eth_sendBundle, unsigned Empty txs
blob transactions not allowed eth_sendBundle, signed A blob transaction
some reverting txs not found in bundle: ... eth_sendBundle A revertingTxHashes entry is not in txs
unknown builders: ... eth_sendBundle, signed None of the names is registered
unsignedCmtId is required signed Zero or missing unsignedCmtId
unsigned commitment not found signed The id is wrong (use the quote's id), the block moved on, or the candidate left the pool while the call waited
signed tx count mismatch with unsigned commitment signed txs is empty or does not line up with the candidate
some signed txs not found signed The solver's transactions did not arrive before the block was sealed or changed
unsigned txs not found signed The candidate has no state diff here and this node does not hold your unsigned bodies: call the node that accepted ofp_sendUnsignedBundle
signed bundle state diff mismatch signed The signed parameters change the outcome: start again from ofp_sendUnsignedBundle
a callback delivery error signed Your callback endpoint did not acknowledge. The commitment is already stored and gossiped: do not retry
already known signed, tool_sendBundle The bundle or solution is already in the network: do not resubmit
blob transactions are not supported, empty transactions list tool_* Pre-validation
commitments with unsigned txs must be first in the list tool_* An unsigned (quote-flow) base is not the first base
invalid commitment <hash> expiration tool_* A base expires earlier than the bundle
access lists are not compatible and N based txs not found tool_* A conflicting base's transactions did not arrive within one second, or the block changed meanwhile; try again a moment later
unsigned commitment requires callback mode and a single callback URL (...) tool_* An unsigned base merged with a base that has a different callback, or callbacks are off on this node (Rejection Checks)
commitment has no delivery target (...) tool_* No usable callback and no common builder on a node that is not a relay merging node (Rejection Checks)

Implementation Notes

Area Current behavior
Blob transactions Not supported anywhere: rejected on eth_sendBundle, ofp_sendSignedBundle, tool_sendBundle, and tool_simulateBundle.
Native bundle field name The JSON field for base commitments is basedCommitments. Role guides may use "based" as conceptual shorthand.
Commitment transaction hashes Commitment JSON includes id and execution metadata, but does not include the internal txs hash list.
Commitment trimming A locally built commitment of 400 KB or more, or needing more gas than its subslot offered, is gossiped without logs and with StateDiff-backed stateDiff set to null.
Commitment filters tool_subscribe commitments address filters match storage writes, not every read or account-level access.
Callback routing A callback receives only solutions whose bases all share its callback; any other merge becomes mixed-origin and goes only to the builders all bases allow, or to the external relay on relay merging nodes. Delivery is best effort and runs in the background except for ofp_sendSignedBundle. See Delivery Rules.