Kindly check this code below.
const { Wallet, JsonRpcProvider, id, getBytes, FetchRequest } = require('ethers');
async function send(relayUrl, body, header) {
const req = new FetchRequest(relayUrl);
req.setHeader('Content-Type', 'application/json');
req.setHeader('X-Flashbots-Signature', header);
req.body = body;
const resp = await req.send();
return { status: resp.statusCode, text: resp.bodyText };
}
(async () => {
const relayUrl = 'https://relay-sepolia.flashbots.net';
const provider = new JsonRpcProvider('https://rpc.ankr.com/eth_sepolia/.../');
const authSigner = Wallet.createRandom();
const txSigner = Wallet.createRandom();
const blockNumber = await provider.getBlockNumber();
const signedTx = await txSigner.signTransaction({
chainId: 11155111,
type: 2,
to: Wallet.createRandom().address,
value: 0n,
nonce: 0,
gasLimit: 21000n,
maxFeePerGas: 20_000_000_000n,
maxPriorityFeePerGas: 1_000_000_000n
});
const paramsObj = [{
txs: [signedTx],
blockNumber: '0x' + (blockNumber + 1).toString(16),
stateBlockNumber: 'latest'
}];
const body = JSON.stringify({ method: 'eth_callBundle', params: paramsObj, id: 1, jsonrpc: '2.0' });
const addr = await authSigner.getAddress();
const sigA = await authSigner.signMessage(id(body)); // string "0x..."
const sigB = await authSigner.signMessage(getBytes(id(body))); // bytes 32
for (const [name, sig] of [['signMessage(id(body))', sigA], ['signMessage(getBytes(id(body)))', sigB]]) {
const header = `${addr}:${sig}`;
const { status, text } = await send(relayUrl, body, header);
let msg = text;
try { msg = JSON.parse(text).error?.message || text; } catch {}
console.log(name, '->', status, msg);
}
})().catch((e) => {
console.error('ERR', e && e.stack ? e.stack : e);
process.exit(1);
});
Output:
signMessage(id(body)) -> 200 signature is required
signMessage(getBytes(id(body))) -> 403 invalid flashbots signature
It worked so well, but now always facing “signature is required” error. Probably, flashbot relay has error now? Anyone knows this?