flashbots / ethers-provider-flashbots-bundle Goto Github PK
View Code? Open in Web Editor NEWFlashbots provider for ethers.js
Flashbots provider for ethers.js
https://relay-goerli.flashbots.net returns Internal Server Error since yesterday on any bundle submission.
Hello, I'm trying to submit a very simple transfer transaction as a bundle but I get {"error":"unable to decode txs"}
in the body.
This is my code:
const tx = {
to: txWallet.address,
data: "0x",
gasPrice: ethers.utils.parseUnits('40', 'gwei'),
gasLimit: 200000,
}
const fullTxBundle = [{
transaction: tx,
signer: txWallet
}]
const signedTransactions = await flashbotsProvider.signBundle(fullTxBundle)
const currentblockNumber = await provider.getBlockNumber();
const simulation = await flashbotsProvider.simulate(signedTransactions, currentblockNumber + 1, currentblockNumber + 5)
The serialize
method, used in getConfictingBundle here: https://github.com/flashbots/ethers-provider-flashbots-bundle/blob/master/src/index.ts#L835 fails for legacy tx with an error Error: invalid object key - from
.
I am using ethers version 5.7.2
. I believe this is also the cause for #85
Hi,
Hi, I'm stuck trying to figure out what the conflict is with my bundle, im using:
getConflictingBundle
And I get this answer:
{ initialSimulation: { bundleGasPrice: '41031065837', bundleHash: '0xf25eaeb1a54b96cc6214a83f4e828209068ae0f83a99ffa33d7ed59c2dca24f7', coinbaseDiff: '16674245565912306', ethSentToCoinbase: '0', gasFees: '16674245565912306', results: [ [Object], [Object], [Object] ], stateBlockNumber: 17365166, totalGasUsed: 406381, firstRevert: undefined }, conflictType: 5, conflictingBundle: [], targetBundleGasPricing: { gasUsed: 406381, gasFeesPaidBySearcher: '38374796447176465', priorityFeesReceivedByMiner: '16674245565912306', ethSentToCoinbase: '0', txCount: 3, effectiveGasPriceToSearcher: '94430587176', effectivePriorityFeeToMiner: '41031065837' }, conflictingBundleGasPricing: undefined }
Buy im not sure what is conflictType: 5
.
Base on what i read in this function:
export enum FlashbotsBundleConflictType { NoConflict, NonceCollision, Error, CoinbasePayment, GasUsed, NoBundlesInBlock }
Update:
Based on what I understand, there are no other bundles in conflict, that's correct?
Also, i try the flashbots_getBundleStatsV2
:
{ isSimulated: true, isHighPriority: true, simulatedAt: '2023-05-29T15:08:06.998Z', receivedAt: '2023-05-29T15:08:06.995Z', consideredByBuildersAt: [ { pubkey: '0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f', timestamp: '2023-05-29T15:08:07.003Z' }, .... ], sealedByBuildersAt: [ { pubkey: '0x81beef03aafd3dd33ffd7deb337407142c80fea2690e5b3190cfc01bde5753f28982a7857c96172a75a234cb7bcb994f', timestamp: '2023-05-29T15:08:07.103Z' }, ..... ],
So, if the bundle has no conflicts, and was simulated and submitted within those times, I don't understand why it has not been included in the target block
This happens to me with all the bundles I send to flashbots.
Any help would be appreciated.
ethers-provider-flashbots-bundle/src/index.ts
Line 658 in 2b98fbe
After trying to troubleshoot some tx of mine that weren't included:
From the docs:
Effective Priority Fee - A bundle cannot significantly reduce its priority fee between simulating at the top of the block and when it is selected for inclusion. This commonly occurs when a bundle is operating on an arbitrage for which it pays a % of the profit to the miner, with an earlier bundle taking part, but not all, of the arbitrage opportunity.
It seems that getConflictingBundle should be comparing effective gas price, but instead its comparing gas used.
getConflictingBundle will give me an error when the initial sim shows that the tx used a certain amount of gas, and uses less gas when simulated after another bundle? Is this the correct behavior?
Currently maxTimestamp
is only defined as a number
export interface FlashbotsOptions {
--
| minTimestamp?: number,
| maxTimestamp?: number
| }
without restriction / upper-bound value on 'maxTimestamp malicious transaction submissions could fill the pool, making it necessary to manually flush said transactions out.
This is sort of similar to how 3rd Party service providers, e.g. Infura, limit transactions to within a certain threshold of some parameters, such as Gas Pricing, in an effort to prevent malicious transaction submission (i.e. DDoS).
Should some value be encoded? Should it be an equation or simply some number of blocks chosen? Is this sort of thing out of scope for MEV?
Cheers
Hi, well I don't know if this provider is only for transfers transactions, if so, my question doesn't have a point. But, if this module was built to support contract interactions so I want to know if I am doing something wrong. I have the following code:
const GWEI = 10n ** 9n
const CHAIN_ID = 5
const FLASHBOTS_ENDPOINT = 'https://relay-goerli.flashbots.net'
const provider = new providers.InfuraProvider('goerli', process.env.INFURA_API_KEY)
const signer = Wallet.createRandom()
const flashbot = await FlashbotsBundleProvider.create(provider, signer, FLASHBOTS_ENDPOINT)
const valueToSendParsed = utils.parseEther('0.01')
const encodedData = '0x7ff36ab500000000000000000000000000000000000000000000000016498f36d4b30300000000000000000000000000000000000000000000000000000000000000008000000000000000000000000054a1c450e8cf7dcde904aa9340375ced46d1cc8c00000000000000000000000000000000000000000000000000000180b94bcbd00000000000000000000000000000000000000000000000000000000000000002000000000000000000000000b4fbf271143f4fbf7b91a5ded31805e42b2208d60000000000000000000000009fffb5a9f5c6a55fa802318ff49936e672399b56'
const signedTx = await flashbot.signBundle([
{
signer: wallet,
transaction: {
chainId: CHAIN_ID,
// EIP 1559 transaction
type: 2,
value: valueToSendParsed,
data: encodedData,
maxFeePerGas: GWEI * 3n,
maxPriorityFeePerGas: GWEI * 2n,
gasLimit: 300000,
to: process.env.ROUTER_CONTRACT_ADDRESS
}
}
])
The method signBundle
always return body="{\"error\":{\"message\":\"bundle used too little gas, must use at least 42000\"}}"
, no matter if I increase the gas limit of the transaction. The data of the transaction is a swap of a DEX router. What am I doing wron? In advance thanks
BLOCKCHAIN: Binance Smart Chain - Testnet
PROVIDER: Moralis speedy nodes
I am unable to send transaction since it seems that the library overrides erroneously the chainId
of the transaction. Here's the relevant parts of the code:
this.ethers_provider = new providers.WebSocketProvider(this.WEBSOCKET_PROVIDER)
this.signer = new Wallet("0x" + this.private_keys[0], this.ethers_provider);
this.flashbotsProvider = await FlashbotsBundleProvider.create(
this.ethers_provider,
this.signer
);
const block_number = await this.ethers_provider.getBlockNumber()
const BLOCKS_IN_THE_FUTURE = 3
const populatedTransaction = await this.signer.populateTransaction(
{
gasLimit: "0x7A120",
data: '0x',
to: "0x51d522dfb50056ab41a1f6c248077ba85a2b97d5",
value: "0x1",
gasPrice: this.web3.utils.toHex(this.web3.utils.toWei("30", 'gwei')),
}
);
//populatedTransaction.chainId = await this.signer.getChainId(); //Even with it I still have the same error
const signedTransaction = await this.signer.signTransaction(populatedTransaction);
const signedBundle = await this.flashbotsProvider.signBundle([{ signedTransaction }]);
this.flashbotsProvider.simulate(signedBundle, block_number + BLOCKS_IN_THE_FUTURE).then(
(simulation : any) => {
if ('error' in simulation) {
console.warn(`Simulation Error: ${simulation.error.message}`)
process.exit(1)
} else {
console.log(`Simulation Success: ${JSON.stringify(simulation, null, 2)}`)
}
}
);
And I always end getting the same error:
Simulation Error: err: invalid chain id for signer; txhash 0x408c5a3a561f51e04ee1da4c534d8f385291a444deac871c065f5b25dc77b33f
Either the library overrides the chainId
of the transaction, or it overrides the provider used with another on chainId, I cannot explain to me why I keep getting alwas this same exact error
Hello flashbots community! I try to send a transaction to flashbots relay, but when executing Im get a signature error which looks like this
Request failed with status code 403 Response data: { error: 'error in signature check 0xEcDC4f8318e2E5d92369530871626d54A4eD9c9E' }
So I guess it has something to do with how Ive set up the signature in X-Flashbots-Signature. But I dont know whats wrong there as Ive set it up as mentioned in the docs.
My script looks like this
async function sendAsyncTransaction() {
try {
const pending = await provider.getTransactionCount(signer.address, "pending");
const exampleTx = {
to: "0x0C7172c8c5C000F39E2A11b04c52805aF29d945b",
value: 1,
gasLimit: "21000",
maxFeePerGas: 60000000000,
maxPriorityFeePerGas: 5000000000,
nonce: pending,
type: 2,
chainId: 1,
};
// sign tx
const txs = await signer.signTransaction(exampleTx);
// get current block
const blockNumber = '0x' + (await provider.getBlockNumber() + 1).toString(16);
const data = {
jsonrpc: '2.0',
id: '1',
method: "eth_sendPrivateTransaction",
params: [
{
tx: txs,
maxBlockNumber: blockNumber,
preferences: {
privacy: {
hints: ["calldata", "transaction_hash"],
builders: ["default"]
}
}
}
]
};
const signature = signer.address + ":" + await signer.signMessage(utils.id(data));
const config = {
headers: {
'Content-Type': 'application/json',
'X-Flashbots-Signature': `${signature}` // Add your Flashbots signature here
},
};
const response = await axios.post('https://relay.flashbots.net', data, config);
// Check the response status
if (response.status === 200) {
console.log(response.data);
} else {
console.error(`Unexpected response status: ${response.status}`);
console.error(response.data);
}
} catch (error: any) {
console.error("Error sending transaction:", error.message);
if (error.response) {
console.error("Response data:", error.response.data);
}
}
}
I hope someone here can help me out. Thanks in advance!
I have created a smart contract to pay a miner tip via a smart contract call to block.coinbase.transfer()
I have followed all required steps to send the bundle to MEV-Relay but still, it is not working.
I am following the below approach to make the transaction
populate contract transaction which contain block.coinbase.transfer().
sign the bundle transaction using populated
const signedBundle = await flashbotsProvider.sign bundle([
{
signer: wallet, // ethers signer
transaction: transaction // ethers populated transaction object
}
]);
send the raw bundle in a loop
for (var i = 1; i <= 10; i++) {
// const minTimestamp = (await provider.getBlock(blockNumber + i)).timestamp
const maxTimestamp = minTimestamp + 120
const bundleReceipt = await flashbotsProvider.sendRawBundle(
signedBundle, // bundle we signed above
blockNumber + i, // block number at which this bundle is valid
{
minTimestamp, // optional minimum timestamp at which this bundle is valid (inclusive)
maxTimestamp, // optional maximum timestamp at which this bundle is valid (inclusive)
}
);
I am trying to use getConflictingBundle endpoint and always get this error when my txs are 100% sure not reverting, doesn't make any sense .
when same tx sent to mainnet without any relevant state changes there are no reverts
when simed in tenderly no reverts
when siming with flashbots all good.
With getConflictingBundle however, this error happening almost everytime , even for bundles which were included!
What's this all about ? There is nothing in the documentation providing insights into this but seems like some issue with the way flashbots is simulating the transaction ?
The transaction can't be decoded if there is 0x
missing in front of the transaction - kind of inconsistent in Ethereum from my experience (we had this problem). Maybe add an automatic check for adding 0x
if it is missing? Or just write it in Readme.
simulate
takes an optional parameter stateBlockTag
that specifies the block that defines the state on which the simulation should be run. This is ignored in the case a block number is passed (the value of the required blockTag
parameter is used instead).
I got this error
flashbotsProvider.signBundle is not a function
`const ethers = require('ethers')
const { FlashbotsBundleProvider} = require('@flashbots/ethers-provider-bundle')
const ethNetwork = "https://goerli.infura.io/v3/711844c77f41457c55c3da7";
var provider = new ethers.providers.JsonRpcProvider({ url: ethNetwork })
const mykey='008438c*********9fef2a5d32e36ba';
const authSigner = new ethers.Wallet(mykey)
var moi_akkaunt=authSigner.address;
var to03 = "0x00aB86e5d07e7595C0EF4E3cBd0d8808Fa3900";
const flashbotsProvider = FlashbotsBundleProvider.create(
provider,
moi_akkaunt,
"https://relay-goerli.flashbots.net",
"goerli");
var signedTransactions= {
to: to03,
nonce: 55,
gasLimit:21000,
gasPrice:5,
chainId:5,
value:5005,
}
const signedBundle = flashbotsProvider.signBundle ([
{
signer: authSigner,
transaction: signedTransactions
}
])`
gasPricePaidBySearcher here is the priority fee -- it's already 'above' the base fee so subtracting base gas makes it go negative...
private calculateBundlePricing(
bundleTransactions: Array<BlocksApiResponseTransactionDetails | TransactionSimulation>,
baseFee: BigNumber
) {
console.log('DBG__ bundle Transactions = ', bundleTransactions);
const bundleGasPricing = bundleTransactions.reduce(
(acc, transactionDetail) => {
const gasUsed = 'gas_used' in transactionDetail ? transactionDetail.gas_used : transactionDetail.gasUsed
const gasPricePaidBySearcher = BigNumber.from(
'gas_price' in transactionDetail ? transactionDetail.gas_price : transactionDetail.gasPrice
)
const priorityFeeReceivedByMiner = gasPricePaidBySearcher.sub(baseFee) <<<<<<------------------- THIS is incorrect
Getting cors error from relay when trying to simulate/sendBundle/getUserStats
const fbProvider = await FlashbotsBundleProvider.create(
ethersProvider,
wallet,
'https://relay-goerli.flashbots.net/',
5
);
const userStatsV2 = await fbProvider.getUserStatsV2();
console.log("🚀 ~ file: provider.ts:61 ~ userStatsV2:", userStatsV2);
i am using eth_sendPrivateTransaction to send a transfer tx. no matter how i increase priority fee, it always pending.
where i am using it wrong
I'm trying to follow the example given in demo.ts and integrating with the docs at https://docs.flashbots.net/flashbots-auction/miners/mev-geth-spec/v03-rpc , yet I can't seem to get a valid simulation request going.
I keep getting an UnhandledPromiseRejectionWarning for a Bad Response error: particularly the code
field in the response is:
code=SERVER_ERROR
Attaching my function for clarity:
`async function simulateAndSendBundle(calldata) {
const CALL_DATA = encode(calldata);
const transaction = {
to: wallet.address,
gasPrice: utils.parseUnits("6", "gwei"),
gasLimit: 300000,
chainId: 5,
value: 0,
data: CALL_DATA,
};
const bundle = [
{
signer: wallet,
transaction: transaction,
},
];
const blockNumber = await provider.getBlockNumber();
const targetBlockNumber = blockNumber + 1;
const signedBundle = await flashbotsProvider.signBundle(bundle);
const simulation = await flashbotsProvider.simulate(
signedBundle,
targetBlockNumber
);
if ("error" in simulation) {
console.log(`Simulation Error: ${simulation.error.message}`);
} else {
console.log(
`Simulation Success: ${blockNumber} ${JSON.stringify(
simulation,
null,
2
)}`
);
}
console.log(signedBundle);
for (let i = 0; i < 10; i++) {
const bundleSubmission = flashbotsProvider.sendRawBundle(
signedBundle,
blockNumber + i
);
console.log("Submitted for block # ", blockNumber + i);
}
console.log("bundles submitted");
}`
Currently using an Infura provider to create the FlashbotsProvider.
When getting bug reports from searchers there is often no sane transaction logging to help debug.
It would be useful to have default logging that shows details of transactions which are fit to be copy and pasted into a bug report.
signBundle() can take a mix of FlashbotsBundleTransactions and FlashbotsBundleRawTransactions. In the case of FlashbotsBundleTransaction, the user provides an (unsigned) TransactionRequest and a Signer. signBundle() populates certain fields of the transaction in case they're missing, like: nonce, gasPrice, gasLimit; however it doesn't include chainId, which ends up being 0 even on Görli.
To be fair, the testnet example does explicitly set chainId to 5, however it could still make sense to automatically populate chainId, either using the Signer's getChainId() method or its populateTransaction(). Notably: when using a Contract's populateTransaction.XXX methods, chainId will be missing from the resulting object.
When trying to interact with a smart contract and do a sendPrivateTransaction() on ethereum mainnet, I get the error below:
Error: bad response (status=400, headers={"date":"Wed, 04 Oct 2023 17:34:08 GMT","content-type":"application/json","content-length":"29","connection":"close","x-amzn-requestid":"c96167df-a3fa-4186-89a709d7e2e","x-amz-apigw-id":"MSZiYcFfEw=","vary":"Origin","x-amzn-trace-id":"Root=1-6a210-46af8f6c40db38e426a04;Sampled=0;lineage=17d26d3c:0"}, body="{"error":"incorrect request"}", requestBody="{"method":"eth_sendPrivateTransaction","params":[{"tx":"0xf901a5071da6bf0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001bad5227ba8cae1c10a8e16f1c6920ae89ac5054df695d8cdce7c1c67e81c7612f95db155de0bd8bbe482046fa74f9f432b6c212622b4d73a6a562a8bc7225e0c3c63c7638efd28aff17c7bec9fbeb2c2e24ceb6cca75ff7a060caa0825de0b79c99654d2086bf8f67a1bb70eb753db17ae1465547e88"}],"id":42,"jsonrpc":"2.0"}", requestMethod="POST", url="https://relay.flashbots.net/", code=SERVER_ERROR, version=web/5.7.1)
Here is my code
const tx = {
from: wall.address,
to: contractAddress,
data: router.interface.encodeFunctionData('functionName', [
parameters...
]),
};
const privateTx = {
transaction: tx,
signer: wall,
}
const authSigner = ethers.Wallet.createRandom();
const flashbotsProvider = await FlashbotsBundleProvider.create(
provider, // a normal ethers.js provider, to perform gas estimiations and nonce lookups
authSigner // ethers.js signer wallet, only for signing request payloads, not transactions
)
const txResponse = await flashbotsProvider.sendPrivateTransaction(privateTx)
Hi
I've followed the example code provided in the repo and this is a snapshot of the code.
// Standard json rpc provider directly from ethers.js (NOT Flashbots)
const provider = new providers.JsonRpcProvider({ url }, 1);
// `authSigner` is an Ethereum private key that does NOT store funds and is NOT your bot's primary key.
const authSigner = new Wallet(PRIVATE_KEY, provider);
// Flashbots provider requires passing in a standard provider
const flashbotsProvider = await FlashbotsBundleProvider.create(
provider, // a normal ethers.js provider, to perform gas estimiations and nonce lookups
authSigner, // ethers.js signer wallet, only for signing request payloads, not transactions
)
await flashbotsProvider.getBlockNumber();
and i'm getting this response
{
reason: 'bad response',
code: 'SERVER_ERROR',
status: 403,
headers: {
date: 'Thu, 27 Jan 2022 00:23:14 GMT',
'content-type': 'application/json',
'content-length': '48',
connection: 'close',
'x-amzn-requestid': '53974b63-2bc8-4507-ab50-216723fc9513',
'x-amz-apigw-id': 'MlDd5GmrCYcFydg=',
'x-amzn-trace-id': 'Root=1-61f1e5f2-63f25f86151ed418579d7bdd;Sampled=0',
'cf-cache-status': 'DYNAMIC',
'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=En7ji626lKSgkt2Hao%2FJu75K3LPczw7R7B6xUs36V8YQXF647pHkSgF8ORC1WEk55k1k5l4%2B8psiPGnGpvWcVgGvouq1ogM5c6VTA971tx7d%2FFiFbJYSPWV%2Fy1qkNSfppBgPKiU%3D"}],"group":"cf-nel","max_age":604800}',
nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
server: 'cloudflare',
'cf-ray': '6d3dd4ca392916bd-SYD'
},
body: '{"error":"missing X-Flashbots-Signature header"}',
requestBody: '{"method":"eth_blockNumber","params":[],"id":42,"jsonrpc":"2.0"}',
requestMethod: 'POST',
url: 'https://relay.flashbots.net'
}
I've verified that the url passed into the ethers wallet and private key are correct. Can't see why it's breaking
{ error: { message: 'Invalid params', code: -32700 } }
Thus, if called getUserStats()
works without any issues.
import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle";
export const getUserStats = async (flashbotsProvider: FlashbotsBundleProvider) => {
const [userStats] = await Promise.all([flashbotsProvider.getUserStatsV2()]);
return userStats;
}
Where
const provider = new providers.JsonRpcProvider(process.env.ETHEREUM_RPC_URL, chainID);
const authSigner = generateRandomWallet();
const flashbotsProvider = await FlashbotsBundleProvider.create(
provider, // a normal ethers.js provider, to perform gas estimiations and nonce lookups
authSigner // ethers.js signer wallet, only for signing request payloads, not transactions
)
bombardier got frustrated in the Discord since his MEV transaction was uncled but his FlashbotsBundleResolution said that the tx was included.
Suggestion: specify an optional number of blocks to wait (= confirmations) until resolving the promise. By default I'd recommend 3 confirmations based on the current state of the network.
Running the demo
throws an error due to the inclusion of the legacy transaction with no chainId in the bundle.
Error:
Error: bad response (status=400, headers={"date":"Thu, 12 Jan 2023 22:38:57 GMT","content-type":"application/json","content-length":"32","connection":"close","x-amzn-requestid":"f3d78faf-0680-4d62-a6dc-1d43c49a43ea","x-amz-apigw-id":"eprQSFsOiYcFU2Q=","vary":"Origin","x-amzn-trace-id":"Root=1-63c08c01-4a1a1d4a0b7622d73999eba4;Sampled=0"}, body="{\"error\":\"unable to decode txs\"}", requestBody="{\"method\":\"eth_callBundle\",\"params\":[{\"txs\":[\"0xf864108502cb41780082520894a68e2f643e0fa7062a78dfb6c629577ae21ad82980801ba08b6a75eb729581b3994056336d505bd631b482fec4d51816db0caa07dc798831a0747ebc76784017d3e5a08fa1c84f1e3a75511d9987989740fdde9bb16891aab7\",\"0x02f86a051184b2d05e0084e6372b6c82520894a68e2f643e0fa7062a78dfb6c629577ae21ad8298080c001a04c0e0ce0de3b83428ed848b1e9f507a9acf2ed9c9d0ca09a46d38958b64b7ef7a06b008a96a90da85d60257da0f289443eb3c0785f6dde52fe488eab14f11af76e\"],\"blockNumber\":\"0x7ea9e3\",\"stateBlockNumber\":\"latest\"}],\"id\":43,\"jsonrpc\":\"2.0\"}", requestMethod="POST", url="https://relay-goerli.flashbots.net/", code=SERVER_ERROR, version=web/5.7.1)
Legacy transaction creation:
ethers-provider-flashbots-bundle/src/demo.ts
Lines 53 to 59 in acdc7e8
see rpc interface defined here:
https://github.com/flashbots/mev-geth/blob/91c3b1128c503fcf2cc473910c61bb2237a95c97/core/mev_bundle.go#L25-L30
Hello !!
src/flashloan.ts:151:41 - error TS2339: Property 'sendBundle' does not exist on type 'Promise'.
151 const resul = await flashbotsProvider.sendBundle(
~~~~~~~~~~
I have:
import { ethers } from "ethers";
import { providers, Wallet } from "ethers";
import { FlashbotsBundleProvider } from "@flashbots/ethers-provider-bundle";
...
/* Nodo */
const maticProvider = new providers.JsonRpcProvider(
process.env.ALCHEMY_POLYGON_RPC_URL
);
if (process.env.PRIVATE_KEY === undefined) {
throw new Error("Private key is not defined");
}
/* Mi Key Wallet */
const private_key = process.env.PRIVATE_KEY;
/* Mi Wallet */
const signer = new ethers.Wallet(private_key, maticProvider);
/* Usuario Wallet Random */
const user = ethers.Wallet.createRandom().connect(maticProvider)
/* Mi Wallet Random */
const authSigner = Wallet.createRandom();
...
const flashbotsProvider = FlashbotsBundleProvider.create(
provider,
authSigner,
"https://relay-goerli.flashbots.net",
"goerli")
...
const transactionBundle = [
{
signedTransaction: signer // serialized signed transaction hex
},
{
signer: authSigner,
trasaction: transaction
}
]
...
const resul = await flashbotsProvider.sendBundle(
transactionBundle,
blockNumber,
{
minTimestamp, // optional minimum timestamp at which this bundle is valid (inclusive)
maxTimestamp // optional maximum timestamp at which this bundle is valid (inclusive)
}
)
Why ?
Thanks !!
Hello, I have this code:
{
// ...
let txs = await Promise.all(
[
{
to: "0x0000000000000000000000000000000000000000",
from: account.wallet.address,
nonce: await account.rpcWss.getTransactionCount(account.wallet.address),
gasLimit: 21000,
data: "0x",
value: GWEI,
chainId: config.chainId,
type: 2,
maxPriorityFeePerGas: priorityFee,
maxFeePerGas: priorityFee.add(nextBaseFee),
},
{
to: "0x0000000000000000000000000000000000000000",
from: account.wallet.address,
nonce: (await account.rpcWss.getTransactionCount(account.wallet.address)) + 1,
gasLimit: 21000,
data: "0x",
value: GWEI.mul(2),
chainId: config.chainId,
type: 2,
maxPriorityFeePerGas: priorityFee,
maxFeePerGas: priorityFee.add(nextBaseFee),
},
].map(account.wallet.signTransaction.bind(account.wallet))
);
let simulation = await this.provider!.simulate(txs, targetBlock);
let res = await this.provider!.sendRawBundle(txs, txRequest.getBlockNumber());
if (isRelayError(res)) {
this.logger.warn("isRelayError");
throw new Error(`${res.error.code}: ${res.error.message}`);
}
this.logger.info(`Bundle sent!`, JSON.stringify(res));
return res.bundleTransactions.map(x => x.hash);
}
Simulation executing successfully as well as bundle itself executing in blockchain, but sendRawBundle
throws with this error:
Error: invalid rlp data (argument="data", value="0x02f870050a85174876e80085174876e80d825208940000000000000000000000000000000000000000843b9aca0080c080a0622457fb76b1cc100eec72684be93b19af78510ec280b793be41f7b258afb864a029869cfacb9d5af833358cb319557313f9a58b48cf46bbc5c61cc9d92b5e9ee1", code=INVALID_ARGUMENT, version=rlp/5.6.1)
The value in error is the first signed transaction.
Looks like this issue is related to ethers rlp decode implementation
https://github.com/ethers-io/ethers.js/blob/608864fc3f00390e1260048a157af00378a98e41/packages/rlp/src.ts/index.ts#L151
It happens with getConflictingBundle processes the first transaction of target block 14635131 (this one: https://etherscan.io/tx/0x7450798650f46ba9faf09a57d3a1e999763aba2aa9bb00b9f35e07216b6eeea7). Details:
Error: mismatch EIP-1559 gasPrice != maxFeePerGas (argument="tx", value={"gasPrice":{"type":"BigNumber","hex":"0x02ab9f29f6"},"maxFeePerGas":{"type":"BigNumber","hex":"0x046adcee56"}}, code=INVALID_ARGUMENT, version=transactions/5.6.0)
at Logger.makeError (C:\repos\blockchain\simple-arbitrage\node_modules\@ethersproject\logger\src.ts\index.ts:261:28) at Logger.throwError (C:\repos\blockchain\simple-arbitrage\node_modules\@ethersproject\logger\src.ts\index.ts:273:20)
at Logger.throwArgumentError (C:\repos\blockchain\simple-arbitrage\node_modules\@ethersproject\logger\src.ts\index.ts:277:21)
at _serializeEip1559 (C:\repos\blockchain\simple-arbitrage\node_modules\@ethersproject\transactions\src.ts\index.ts:174:20)
at serialize (C:\repos\blockchain\simple-arbitrage\node_modules\@ethersproject\transactions\src.ts\index.ts:319:20)
at C:\repos\blockchain\simple-arbitrage\src\FlashbotsConflictingBundle.spec.ts:163:38
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async Promise.all (index 0)
at async main (C:\repos\blockchain\simple-arbitrage\src\FlashbotsConflictingBundle.spec.ts:156:36) {
reason: 'mismatch EIP-1559 gasPrice != maxFeePerGas',
code: 'INVALID_ARGUMENT',
argument: 'tx',
value: {
gasPrice: BigNumber { _hex: '0x02ab9f29f6', _isBigNumber: true },
maxFeePerGas: BigNumber { _hex: '0x046adcee56', _isBigNumber: true }
}
}
It looks like getConflictingBundle
uses fetchBlocksApi
that has a hardcoded API endpoint (see https://github.com/flashbots/ethers-provider-flashbots-bundle/blob/master/src/index.ts#L814).
I think this means it does not work for bundles submitted to another network, e.g., Goerli.
Currently there is no official license information for flashbots bundle. While one could argue that this is licensed under the permissive ISC license some clarity as to the licensing would be appreciated.
Is transaction speed parameter for sendPrivateTransaction deprecated?
fast: boolean, // Deprecated; required until this is removed from the API. Value has no effect.
Why is that?
Is there a other way to make sure the transaction gets not only found by flashbot builder but all?
Thanks in advance!
i just test signBundle via flashbots, i feel confused. there is the code
// the transaction is get from geth mempool
const transaction = {
"blockHash": null,
"blockNumber": null,
"from": "0x0160ea15d2125dd9c211f23169c4e4f4fb7957a8",
"gas": "0x4c4b40",
"gasPrice": "0x1ca10",
"hash": "0x696968e15c7174609adca25769c4e7c0e2c18d1eedbca8e4b71e3a0f59c52797",
"input": "0xc652885f0000000000000000000000009bd2aa38429c356be17c8c7bb07dab299200eeb84178ca8820c1a8dae966f1fdd132a2a874394233000000000000000000000054000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004178ca8820c1a8dae966f1fdd132a2a8743942330000000000000000000000000000000000000000000000000000000000000320",
"nonce": "0x163",
"to": "0x7ede79ed0d3acf3d4843c919975fb7bd97ecccba",
"transactionIndex": null,
"value": "0x0",
"type": "0x0",
"chainId": "0x5",
"v": "0x2e",
"r": "0xf4556687cb3df0f345ab903a2c9c46bb1a9fb413a0f498e8dba3b74253caa313",
"s": "0x281adb2e3f2b73c685aaaec10120b9ade46d6c2cd069d1106ae5093833d0bbf1"
};
const signedBundle = await flashbotsProvider.signBundle([
{
signer: transactionFromSigner.connect(provider),
transaction: {
...baseTransaction,
gasPrice: '',
data: '0x'
},
},
{
// there, i don't know how to serialize transaction from mempool
signedTransaction: ethers.utils.serializeTransaction(transaction)
}
]);
in the "Simulate and Send" section, the code should read:
const signedTransactionBundle = await flashbotsProvider.signBundle(transactionBundle)
const simulation = await flashbotsProvider.simulate(signedTransactionBundle, targetBlockNumber)
instead of
const signedTransactionBundle = await flashbotsProvider.signBundle(transactionBundle)
const simulation = await flashbotsProvider.simulate(signedTransactions, targetBlockNumber)
I was confused for a second and looking back trying to figure out if I had a variable missing until I noticed whoever wrote the readme was copying and pasting from demo.ts
this requires passing environment configs for CI to succeed
When using the package from a repo with ethers-v6, since ethers/utils
got deprecated, it fails to compile.
When I construct a transaction, the transaction is to send a data to my personal contract through my account. Then simulate this transaction through the eth_callBundle method of flashbots, but the response I received shows an error, so I would like to ask you to help solve the problem, or point out the reason for the error, thank you for your help.
Below is my code and error message。
const Tx = {
to: my_contract.address,
from: Wallet.address,
data: Payload,
chainId: 1,
maxPriorityFeePerGas: 0,
maxFeePerGas: nextBaseFee,
gasLimit: 250000,
nonce: nonce + 1,
type: 2,
};
console.log(Tx);
const TxSigned = await Wallet.signTransaction(Tx);
const signedTxs = [TxSigned];
const simulatedResp = await callBundleFlashbots(signedTxs, targetBlockNumber);
the response is :
simulatedResp {
bundleGasPrice: '816000544',
bundleHash: '0x6114e885fcf513af79cdcd72ba3192eff297fc58772f6681b022a83594fbca43',
coinbaseDiff: '128523349703840',
ethSentToCoinbase: '0',
gasFees: '128523349703840',
results: [
{
coinbaseDiff: '0',
error: 'execution reverted',
ethSentToCoinbase: '0',
fromAddress: '0x446E90CDd028cBDf8aCcd47C2C3AD50F585C2e15',
gasFees: '0',
gasPrice: '0',
gasUsed: 28155,
revert: '\x00\x00\x00',
toAddress: '0x35e456AE04D641F2c13c52C7e637645CE92c293c',
txHash: '0xe78add5bc73e08ad291b8eafb77cff3b8f900264edf54e619fdb7a84eebd4d3c'
}
]
}
it take too much time to successfully mine tx in flashbots, 30-50s
i saw other like meastro or bannana very fast , < 10s, how they can do that ?
building an nft rescue on polygon gets me this error..any idea ?
Starting flashbot...
Retreiving Flashbots Provider...
Attempt: 0 - Preparing bundle for block: 51126019
Max base fee in block 51126019 is 114012669314 WEI
Priority fee: 17000000000 WEI, 17 GWEI
Base fee: 114012669314 WEI, 114.012669314 GWEI
Max fee per gas: 131012669314 WEI, 131.012669314 GWEI
Fund amount: 8520539961505304 WEI, 8520539.961505304 GWEI, 0.008520539961505304 ETH
Running simulation
{
error: {
message: 'the method eth_callBundle does not exist/is not available',
code: -32601
}
}
This problem wasnt added in this PR, but i'm not sure what's going on with this :
Originally posted by @epheph in #16 (comment)
Unable to decode the revert error from Simulation (and probably from real txs too).
What I've noticed when I decode the revert string to HEX, is that it contains a lot of "EFBFBD" bytes:
"EFBFBD" is used as a standard UTF8 replacement bytes if the source byte cannot be encoded into UTF8:
https://blog.gdssecurity.com/labs/2015/2/18/when-efbfbd-and-friends-come-knocking-observations-of-byte-a.html
As you can see it couldn't encode 9C.
If you replace EFBFBD with any random byte (like "FF") - then you have a proper length ABI-Encoded custom error (with 4 bytes in the beginning, and 32+32 bytes two uints after).
I'm not sure where this replacement happens - on the Ethers side (in fetchJson they use toUTF8 encoding) or on Flashbots Relay side.
But if it happens on Ether's side - maybe we can use another connector?
https://relay-sepolia.flashbots.net returns 500 Internal Server Error on eth_callBundle
method call:
{
"error": "Internal Server Error"
}
Though, for example, eth_sendBundle
method works.
I noticed that if you (incorrectly) submit a bundle with no ChainId specified an error message is not returned instead you keep receiving a failed bundle submit request indefinitely.
Hey everyone,
I have been trying to experiment with a browser-friendly version of this, using tools such as browserify
.
Up to this point, I have been unsuccessful. Things I have tried:
browserify -p esmify --standalone flashbots_old.js -o flashbots.js
browserify index.ts -p [ tsify --noImplicitAny esmify ] > bundle.js
I want to make a nice little tool for https://ethtools.odyslam.com
EDIT: After several hours, I manually edited the output bundle.js and managed to make the Flashbots objects available in window
. Will update this issue when I have a working PoC. Might be interesting.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.