Created
November 6, 2022 16:07
-
-
Save merlox/c425bf236738b40f0d390644e8167456 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. Import everything | |
import { Wallet, BigNumber, ethers, providers } from 'ethers' | |
const { FlashbotsBundleProvider, FlashbotsBundleResolution } = require('@flashbots/ethers-provider-bundle') | |
/* | |
Mainnet | |
const provider = new providers.JsonRpcProvider('https://eth-mainnet.g.alchemy.com/v2/cmHEQqWnoliAP0lgTieeUtwHi0KxEOlh') | |
const wsProvider = new providers.WebSocketProvider('wss://eth-mainnet.g.alchemy.com/v2/cmHEQqWnoliAP0lgTieeUtwHi0KxEOlh') | |
*/ | |
// 2. Setup a standard provider in goerli | |
const provider = new providers.JsonRpcProvider( | |
'https://eth-goerli.g.alchemy.com/v2/wOB3tqbHfs_RGAeFJqomylXrUOH_MrVT' | |
) | |
const wsProvider = new providers.WebSocketProvider( | |
'wss://eth-goerli.g.alchemy.com/v2/wOB3tqbHfs_RGAeFJqomylXrUOH_MrVT' | |
) | |
// 3. The unique ID for flashbots to identify you and build trust over time | |
const authSigner = new Wallet( | |
'0x83565a9dafb10577ed43b2a0b911656e18fbc25cf35f211db891f23815ff7c45', | |
provider | |
) | |
// The address of the authSigner is 0x09Dad4e56b1B2A7eeD9C41691EbDD4EdF0D80a46 | |
const start = async () => { | |
// 4. Create the flashbots provider | |
const flashbotsProvider = await FlashbotsBundleProvider.create( | |
provider, | |
authSigner, | |
'https://relay-goerli.flashbots.net', | |
) | |
const GWEI = BigNumber.from(10).pow(9) | |
const LEGACY_GAS_PRICE = GWEI.mul(13) | |
const PRIORITY_FEE = GWEI.mul(100) | |
const blockNumber = await provider.getBlockNumber() | |
const block = await provider.getBlock(blockNumber) | |
const maxBaseFeeInFutureBlock = | |
FlashbotsBundleProvider.getMaxBaseFeeInFutureBlock(block.baseFeePerGas, 6) // 100 blocks in the future | |
console.log('maxBaseFeeInFutureBlock', String(maxBaseFeeInFutureBlock), String(maxBaseFeeInFutureBlock.div('100000000000000000'))) | |
const amountInEther = '0.001' | |
// 5. Setup the transactions to send and sign | |
const signedTransactions = await flashbotsProvider.signBundle([ | |
{ // Both transactions are the same but one is type 1 and the other type 2 after the gas changes | |
signer: authSigner, | |
transaction: { | |
to: '0x2c3fF32c7F6C7f83fFd13C76Cfef67C0E9811240', | |
type: 2, | |
maxFeePerGas: PRIORITY_FEE.add(maxBaseFeeInFutureBlock), | |
maxPriorityFeePerGas: PRIORITY_FEE, | |
data: '0x', | |
chainId: 5, | |
value: ethers.utils.parseEther(amountInEther), | |
// gasLimit: 300000, | |
}, | |
}, | |
// we need this second tx because flashbots only accept bundles that use at least 42000 gas. | |
{ | |
signer: authSigner, | |
transaction: { | |
to: '0x2c3fF32c7F6C7f83fFd13C76Cfef67C0E9811240', | |
gasPrice: LEGACY_GAS_PRICE, | |
data: '0x', | |
value: ethers.utils.parseEther(amountInEther), | |
// gasLimit: 300000, | |
}, | |
}, | |
]) | |
// 6. We run a simulation for the next block number with the signed transactions | |
console.log(new Date()) | |
console.log('Starting to run the simulation...') | |
const simulation = await flashbotsProvider.simulate( | |
signedTransactions, | |
blockNumber + 1, | |
) | |
console.log(new Date()) | |
// 7. Check the result of the simulation | |
if (simulation.firstRevert) { | |
console.log(`Simulation Error: ${simulation.firstRevert.error}`) | |
} else { | |
console.log( | |
`Simulation Success: ${blockNumber}}` | |
) | |
} | |
// 8. Send 10 bundles to get this working for the next blocks in case flashbots doesn't become the block producer | |
for (var i = 1; i <= 10; i++) { | |
const bundleSubmission = await flashbotsProvider.sendRawBundle( | |
signedTransactions, | |
blockNumber + i | |
) | |
console.log('bundle submitted, waiting', bundleSubmission.bundleHash) | |
const waitResponse = await bundleSubmission.wait() | |
console.log(`Wait Response: ${FlashbotsBundleResolution[waitResponse]}`) | |
if ( | |
waitResponse === FlashbotsBundleResolution.BundleIncluded || | |
waitResponse === FlashbotsBundleResolution.AccountNonceTooHigh | |
) { | |
console.log('Bundle included!') | |
process.exit(0) | |
} else { | |
console.log({ | |
bundleStats: await flashbotsProvider.getBundleStats( | |
simulation.bundleHash, | |
blockNumber + 1, | |
), | |
userStats: await flashbotsProvider.getUserStats(), | |
}) | |
} | |
} | |
console.log('bundles submitted') | |
} | |
start() |
what are the languages to be know to understand this?
@haroonabbhas you should know javascript and solidity as programming languages. Also you should know what happens behind the scenes when a transaction is submitted.
Guys I don't understand why I get the following error when trying to send the bundled txs:
var error = new Error(message);
^
Error: bad response (status=400, headers={"date":"Sun, 04 Feb 2024 17:42:51 GMT","content-type":"application/json","content-length":"32","connection":"keep-alive","x-amzn-requestid":"d22c4e95-340c-400c-aa84-fdd4d9f12fba","x-amz-apigw-id":"SnzoRFH1iYcEGqw=","vary":"Origin","x-amzn-trace-id":"Root=1-65bfcc9b-0478538370ab13ec3ad74318;Sampled=0;lineage=3d257173:0"}, body="{\"error\":\"unable to decode txs\"}", requestBody="{\"method\":\"eth_callBundle\",\"params\":[{\"txs\":[\"0x02f873050285174876e80085174876e81982520894aaa9f42beeb20291b1d2729a61bddc271ed45ea387038d7ea4c6800080c080a0010eb5f694c3047e304c9e6362ff5cf365462c473e9c7e38225b86913cb94d67a055a1764412b709cd7eb5792109e53620d3d6729c84ed08b2e7542bfc95c4e662\",\"0xf86b03850306dc420082520894aaa9f42beeb20291b1d2729a61bddc271ed45ea387038d7ea4c68000801ca0c1c9d56354e4218436df12dad81a681d1b95c3b8cad2f46f0c2a64a9b9a1a17da03d75ad4a7358174f531d27e929fdaf03da18ad4d14e3d1c2f5e68b9c87a49dbd\"],\"blockNumber\":\"0x9ffc53\",\"stateBlockNumber\":\"latest\"}],\"id\":42,\"jsonrpc\":\"2.0\"}", requestMethod="POST", url="https://relay-goerli.flashbots.net/", code=SERVER_ERROR, version=web/5.7.1)
at Logger.makeError (F:\Programming\Blockchain\MEV\mev-mastery\node_modules\@ethersproject\logger\lib\index.js:238:21)
at Logger.throwError (F:\Programming\Blockchain\MEV\mev-mastery\node_modules\@ethersproject\logger\lib\index.js:247:20)
at F:\Programming\Blockchain\MEV\mev-mastery\node_modules\@ethersproject\web\lib\index.js:275:36
at step (F:\Programming\Blockchain\MEV\mev-mastery\node_modules\@ethersproject\web\lib\index.js:33:23)
at Object.next (F:\Programming\Blockchain\MEV\mev-mastery\node_modules\@ethersproject\web\lib\index.js:14:53)
at fulfilled (F:\Programming\Blockchain\MEV\mev-mastery\node_modules\@ethersproject\web\lib\index.js:5:58)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
reason: 'bad response',
code: 'SERVER_ERROR',
status: 400,
headers: {
date: 'Sun, 04 Feb 2024 17:42:51 GMT',
'content-type': 'application/json',
'content-length': '32',
connection: 'keep-alive',
'x-amzn-requestid': 'd22c4e95-340c-400c-aa84-fdd4d9f12fba',
'x-amz-apigw-id': 'SnzoRFH1iYcEGqw=',
vary: 'Origin',
'x-amzn-trace-id': 'Root=1-65bfcc9b-0478538370ab13ec3ad74318;Sampled=0;lineage=3d257173:0'
},
body: '{"error":"unable to decode txs"}',
requestBody: '{"method":"eth_callBundle","params":[{"txs":["0x02f873050285174876e80085174876e81982520894aaa9f42beeb20291b1d2729a61bddc271ed45ea387038d7ea4c6800080c080a0010eb5f694c3047e304c9e6362ff5cf365462c473e9c7e38225b86913cb94d67a055a1764412b709cd7eb5792109e53620d3d6729c84ed08b2e7542bfc95c4e662","0xf86b03850306dc420082520894aaa9f42beeb20291b1d2729a61bddc271ed45ea387038d7ea4c68000801ca0c1c9d56354e4218436df12dad81a681d1b95c3b8cad2f46f0c2a64a9b9a1a17da03d75ad4a7358174f531d27e929fdaf03da18ad4d14e3d1c2f5e68b9c87a49dbd"],"blockNumber":"0x9ffc53","stateBlockNumber":"latest"}],"id":42,"jsonrpc":"2.0"}',
requestMethod: 'POST',
url: 'https://relay-goerli.flashbots.net/'
}
Please help fix it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Ok.it seems you are pro.well master!introduse him some resource to quick strat learning.