Searchers
Searcher API reference
Exact searcher JSON-RPC methods, request authentication, bundle shape, payment encoding and unsupported options.
3 min readEndpoint and authentication#
POST https://rpc.blockferret.win/builders
Content-Type: application/json
X-Flashbots-Signature: 0xAUTH_ADDRESS:0xSIGNATUREPersonal-sign the UTF-8 hex string of the exact body’s Keccak-256 hash, including 0x. Do not sign the decoded hash bytes. JSON whitespace and field order must match the transmitted body. Authentication proves the signing identity; the original transactions retain their own signatures.
const body = JSON.stringify({ jsonrpc: "2.0", id: 1, method, params: [params] });
const signature = await wallet.signMessage(id(body));
// ethers 6: id(body) returns the hexadecimal Keccak-256 string.Supported methods#
| Method | Single params object |
|---|---|
| blockferret_getSearcherTerms | {} |
| eth_sendBundle | txs, hex blockNumber; optional parentHash, numeric minTimestamp/maxTimestamp, UUID replacementUuid |
| eth_sendPrivateTransaction | tx; optional hex maxBlockNumber, parentHash |
| eth_cancelBundle | UUID replacementUuid |
| eth_cancelPrivateTransaction | txHash |
| blockferret_getSubmissionStatus | submissionId |
All calls require one object in params, a non-null JSON-RPC ID and signed authentication. Status, replacement and cancellation are scoped to the signing address. Terms return live flags, bridge readiness, router and builder addresses, chain ID, fee split, rebate recipient and limits.
Bundle request#
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_sendBundle",
"params": [
{
"txs": [
"0xSIGNED_ARB_TRANSACTION",
"0xSIGNED_ROUTER_PAYMENT"
],
"blockNumber": "0xTARGET_BLOCK",
"parentHash": "0xCURRENT_PARENT_HASH",
"replacementUuid": "756e9444-c71f-4b69-aaf5-5b53c992aa65"
}
]
}txs contains 1–16 signed transaction hex strings in execution order, with no duplicates and no more than 256 KiB total. Chain 369 legacy, access-list and EIP-1559 envelopes are supported. Use properly encoded hexadecimal quantities for block numbers and numeric Unix seconds for timestamp bounds. Unknown options and nonempty revertingTxHashes are rejected.
A private single transaction still needs verified router payment, normally called within its execution contract. Its intake lifetime is 30 minutes, but an exact-block router payment cannot execute after its target. Bundles expire after at most two minutes.
Encode the router payment#
const router = new Interface([
"function pay(bytes32 paymentId,uint256 targetBlock,bytes32 expectedParent,address proposerRecipient) payable"
]);
const data = router.encodeFunctionData("pay", [
paymentId, BigInt(context.blockNumber), context.parentHash, context.validatorRecipient
]);
// Sign locally: to = terms.paymentRouter, value = chosen fee in wei,
// data = data, chainId = 369, correct nonce and funded gas.The deployed runtime, immutable builder wallet and chain ID are verified by the gateway. InclusionPaid(bytes32,address,address,uint256,uint256,uint256) receipt evidence and actual balance deltas establish payment; a log from a different contract does not qualify. See settlement rules.
Run the example client#
npm install ethers@6
# Set SEARCHER_AUTH_KEY locally in your environment.
node submit-searcher.mjs terms
node submit-searcher.mjs context
node submit-searcher.mjs submit bundle.json
node submit-searcher.mjs status 0xSUBMISSION_ID
node submit-searcher.mjs cancel 756e9444-c71f-4b69-aaf5-5b53c992aa65Download submit-searcher.mjs. The JSON file contains the single params object, not a full RPC envelope. The example also supports private private.json and cancel-private 0xTX_HASH. It authenticates requests; it does not discover routes, sign your trades or simulate profitability. It never retries an ambiguous submission automatically.
Errors and inclusion checks#
HTTP 429 indicates rate or concurrent-request capacity; back off. HTTP 503 or unavailable bridge/context means no usable current duty. Invalid authentication returns HTTP 401; JSON-RPC errors identify malformed envelopes, unsupported options or unavailable intake. A successful bundle queue response includes submissionId and bundleHash. A single private transaction returns its transaction hash; that hash also works as submissionId for owner-signed status. Inspect status for later verification or commitment.
After a timeout, check status, transaction nonces and canonical receipts before replacing. No eth_callBundle, JSON-RPC batch, notification, MEV-Share refund interface or allowed-revert bundle behavior is offered. Local simulation and on-chain inclusion checks remain necessary.