{"id":21470546,"url":"https://github.com/manifoldfinance/openmev-provider","last_synced_at":"2026-01-21T19:36:00.414Z","repository":{"id":39750768,"uuid":"409089276","full_name":"manifoldfinance/openmev-provider","owner":"manifoldfinance","description":"OpenMEV Ethers Provider ","archived":false,"fork":false,"pushed_at":"2022-12-06T18:04:04.000Z","size":1163,"stargazers_count":6,"open_issues_count":5,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-01-15T17:03:28.789Z","etag":null,"topics":["eden-network","ethers","flashbots","json-rpc","miningdao","openmev","web3","web3-provider"],"latest_commit_sha":null,"homepage":"https://manifoldfinance.github.io/openmev-provider/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/manifoldfinance.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.spdx","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-22T06:29:23.000Z","updated_at":"2022-10-24T04:08:09.000Z","dependencies_parsed_at":"2022-09-20T10:07:03.325Z","dependency_job_id":null,"html_url":"https://github.com/manifoldfinance/openmev-provider","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/manifoldfinance/openmev-provider","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manifoldfinance%2Fopenmev-provider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manifoldfinance%2Fopenmev-provider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manifoldfinance%2Fopenmev-provider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manifoldfinance%2Fopenmev-provider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manifoldfinance","download_url":"https://codeload.github.com/manifoldfinance/openmev-provider/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manifoldfinance%2Fopenmev-provider/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28641276,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T18:04:35.752Z","status":"ssl_error","status_checked_at":"2026-01-21T18:03:55.054Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eden-network","ethers","flashbots","json-rpc","miningdao","openmev","web3","web3-provider"],"created_at":"2024-11-23T09:28:12.504Z","updated_at":"2026-01-21T19:36:00.398Z","avatar_url":"https://github.com/manifoldfinance.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cspan align=\"center\"\u003e\n\n# `@openmev/ethers-provider`\n\n[![nodejs](https://github.com/manifoldfinance/openmev-provider/workflows/nodejs/badge.svg)](https://github.com/manifoldfinance/openmev-provider/actions?query=workflow:\"nodejs\")\n[![GitHub tag](https://img.shields.io/github/tag/manifoldfinance/openmev-provider?include_prereleases=\u0026sort=semver\u0026color=blue)](https://github.com/manifoldfinance/openmev-provider/releases/)\n[![License](https://img.shields.io/badge/License-Apache--2.0-blue)](#license)\n[![issues - openmev-provider](https://img.shields.io/github/issues/manifoldfinance/openmev-provider)](https://github.com/manifoldfinance/openmev-provider/issues)\n[![typedoc - latest](https://img.shields.io/badge/typedoc-latest-informational?logo=typescript\u0026logoColor=white)](https://openmev-provider.netlify.app/)\n\n\u003c/span\u003e\n\n## Overview\n\n**OpenMEV** provides automated e2e, integration, contract \u0026 component (_or\nservice level_) interfaces and testing utilities.\n\n- ⚡ Automated or Bypass RPC Routing\n- 🎈 Lightweight\n- 🛠️ Transaction Mock Server\n- 🔧 Extendable \u0026 Customizable\n- 📚 Clear \u0026 Comprehensive Documentation\n- 🔗 Component, Contract \u0026 E2E testing of RPC APIs\n\nThis repository contains the `OpenMevBundleProvider` EthersJS provider, an\nadditional `Provider` to `ethers.js` to enable high-level access to\n`eth_sendBundle` and `eth_callBundle`, and `eth_sendMegaBundle` RPC endpoints\nfor MEV-Geth enabled Mining Pools.\n\nOpenMEV interacts with Flashbots-compliant relays and miners. They expose at\nleast the following JSON-RPC endpoints:\n\n`eth_sendBundle`, `eth_callBundle`, `eth_sendMegaBundle`\n\nSince these are non-standard endpoints, ethers.js and other libraries do not\nnatively support these requests (like `getTransactionCount`). In order to\ninteract with these endpoints, you will need access to another full-featured\n(non-OpenMEV) endpoint for nonce-calculation, gas estimation, and transaction\nstatus.\n\nOne key feature this library provides is **payload signing**, a requirement to\nsubmit OpenMEV bundles to the `mev-relay` service. This library takes care of\nthe signing process via the `authSigner` passed into the constructor.\n[Read more about relay signatures here via Flashbots](https://github.com/flashbots/mev-relay-js#authentication)\n\nThis library is not a fully functional ethers.js implementation, just a simple\nprovider class, designed to interact with an existing\n[ethers.js v5 installation](https://github.com/ethers-io/ethers.js/).\n\n## Example\n\nInstall ethers.js and the OpenMev ethers bundle provider\n\n```bash\nnpm install --save ethers\nnpm install --save @openmev/ethers-provider\n```\n\nOpen up a new TypeScript file (this also works with JavaScript if you prefer)\n\n```ts\nimport { providers, Wallet } from 'ethers';\nimport { OpenMevBundleProvider } from '@OpenMev/ethers-provider';\n\n// Standard json rpc provider directly from ethers.js (NOT OpenMev)\nconst provider = new providers.JsonRpcProvider({ url: ETHEREUM_RPC_URL }, 1);\n\n// `authSigner` is an Ethereum private key that does NOT store funds and is NOT your bot's primary key.\n// This is an identifying key for signing payloads to establish reputation and whitelisting\n// In production, this should be used across multiple bundles to build relationship. In this example, we generate a new wallet each time\nconst authSigner = Wallet.createRandom();\n\n// OpenMev provider requires passing in a standard provider\nconst OpenMevProvider = await OpenMevBundleProvider.create(\n  provider, // a normal ethers.js provider, to perform gas estimations and nonce lookups\n  authSigner, // ethers.js signer wallet, only for signing request payloads, not transactions\n);\n```\n\nFrom here, you have a `OpenMevProvider` object setup which can now perform\neither an `eth_callBundle` (via `simulate()`) or `eth_sendBundle` (via\n`sendBundle`). Each of these functions act on an array of `Bundle Transactions`\n\n### Bundle Transactions\n\nBoth `simulate` and `sendBundle` operate on a bundle of strictly-ordered\ntransactions. While the miner requires signed transactions, the provider library\nwill accept a mix of pre-signed transaction and `TransactionRequest + Signer`\ntransactions (which it will estimate, nonce-calculate, and sign before sending\nto the `mev-relay`)\n\n```ts\nconst wallet = new Wallet(PRIVATE_KEY);\nconst transaction = {\n  to: CONTRACT_ADDRESS,\n  data: CALL_DATA,\n};\nconst transactionBundle = [\n  {\n    signedTransaction: SIGNED_ORACLE_UPDATE_FROM_PENDING_POOL, // serialized signed transaction hex\n  },\n  {\n    signer: wallet, // ethers signer\n    transaction: transaction, // ethers populated transaction object\n  },\n];\n```\n\n### Block Targeting\n\nThe last thing required for `sendBundle()` is block targeting. Every bundle\nspecifically references a single block. If your bundle is valid for multiple\nblocks (including all blocks until it is mined), `sendBundle()` must be called\nfor every block, ideally on one of the blocks immediately prior. This gives you\na chance to re-evaluate the opportunity you are capturing and re-sign your\ntransactions with a higher nonce, if necessary.\n\nThe block should always be a _future_ block, never the current one.\n\n```ts\nconst targetBlockNumber = (await provider.getBlockNumber()) + 1;\n```\n\n### Gas Prices and EIP-1559\n\nBefore EIP-1559 was activated, the most common way for searchers to submit\ntransactions is with `gasPrice=0`, with an on-chain payment to `block.coinbase`\nconditional on the transaction's success. All transactions must pay `baseFee`\nnow, an attribute of a block. For an example of how to ensure you are using this\n`baseFee`, see `demo.ts` in this repository.\n\n```\nconst block = await provider.getBlock(blockNumber)\nconst maxBaseFeeInFutureBlock = OpenMevBundleProvider.getMaxBaseFeeInFutureBlock(block.baseFeePerGas, BLOCKS_IN_THE_FUTURE)\nconst eip1559Transaction = {\n    to: wallet.address,\n    type: 2,\n    maxFeePerGas: PRIORITY_FEE.add(maxBaseFeeInFutureBlock),\n    maxPriorityFeePerGas: PRIORITY_FEE,\n    gasLimit: 21000,\n    data: '0x',\n    chainId: CHAIN_ID\n}\n```\n\n`OpenMevBundleProvider.getMaxBaseFeeInFutureBlock` calculates the maximum\nbaseFee that is possible `BLOCKS_IN_THE_FUTURE` blocks, given maximum expansion\non each block. You won't pay this fee, so long as it is specified as\n`maxFeePerGas`, you will only pay the block's `baseFee`.\n\n### Simulate and Send\n\nNow that we have:\n\n1. OpenMEV Provider `OpenMevProvider`\n2. Bundle of transactions `transactionBundle`\n3. Block Number `targetBlockNumber`\n\nWe can run simulations and submit directly to miners, via the `mev-relay`.\n\nSimulate:\n\n```ts\nconst signedTransactionBundle = await OpenMevProvider.signBundle(\n  transactionBundle,\n);\nconst simulation = await OpenMevProvider.simulate(\n  signedTransactions,\n  targetBlockNumber,\n);\nconsole.log(JSON.stringify(simulation, null, 2));\n```\n\nSend:\n\n```ts\nconst OpenMevTransactionResponse = await OpenMevProvider.sendBundle(\n  transactionBundle,\n  targetBlockNumber,\n);\n```\n\n## OpenMev Transaction Response\n\nAfter calling `sendBundle`, this provider will return a Promise of an object\nwith helper functions related to the bundle you submitted.\n\nThese functions return metadata available at transaction submission time, as\nwell as the following functions which can wait, track, and simulate the bundle's\nbehavior.\n\n- `bundleTransactions()` - An array of transaction descriptions sent to the\n  relay, including hash, nonce, and the raw transaction.\n- `receipts()` - Returns promise of an array of transaction receipts\n  corresponding to the transaction hashes that were relayed as part of the\n  bundle. Will not wait for block to be mined; could return incomplete\n  information\n- `wait()` - Returns a promise which will wait for target block number to be\n  reached _OR_ one of the transactions to become invalid due to nonce-issues\n  (including, but not limited to, one of the transactions from your bundle being\n  included too early). Returns the wait resolution as a status enum\n- `simulate()` - Returns a promise of the transaction simulation, once the\n  proper block height has been reached. Use this function to troubleshoot\n  failing bundles and verify miner profitability\n\n## Optional eth_sendBundle arguments\n\nBeyond target block number, an object can be passed in with optional attributes:\n\n```ts\n{\n  minTimestamp, // optional minimum timestamp at which this bundle is valid (inclusive)\n  maxTimestamp, // optional maximum timestamp at which this bundle is valid (inclusive)\n  revertingTxHashes: [tx1, tx2] // optional list of transaction hashes allowed to revert. Without specifying here, any revert invalidates the entire bundle.\n}\n```\n\n### minTimestamp / maxTimestamp\n\nWhile each bundle targets only a single block, you can add a filter for validity\nbased on the block's timestamp. This does _not_ allow for targeting any block\nnumber based on a timestamp or instruct miners on what timestamp to use, it\nmerely serves as a secondary filter.\n\nIf your bundle is not valid before a certain time or includes an expiring\nopportunity, setting these values allows the miner to skip bundle processing\nearlier in the phase.\n\nAdditionally, you could target several blocks in the future, but with a strict\nmaxTimestamp, to ensure your bundle is considered for inclusion up to a specific\ntime, regardless of how quickly blocks are mined in that timeframe.\n\n### Reverting Transaction Hashes\n\nTransaction bundles will not be considered for inclusion if they include _any_\ntransactions that revert or fail. While this is normally desirable, there are\nsome advanced use-cases where a searcher might WANT to bring a failing\ntransaction to the chain. This is normally desirable for nonce management.\nConsider:\n\nTransaction Nonce #1 = Failed (unrelated) token transfer Transaction Nonce #2 =\nDEX trade\n\nIf a searcher wants to bring #2 to the chain, #1 must be included first, and its\nfailure is not related to the desired transaction #2. This is especially common\nduring high gas times.\n\nOptional parameter `revertingTxHashes` allows a searcher to specify an array of\ntransactions that can (but are not required to) revert.\n\n## Paying for your bundle\n\nIn addition to paying for a bundle with gas price, bundles can also\nconditionally pay a miner via: `block.coinbase.transfer(_minerReward)` or\n`block.coinbase.call{value: _minerReward}(\"\");`\n\n(assuming \\_minerReward is a solidity `uint256` with the wei-value to be\ntransferred directly to the miner)\n\nThe entire value of the bundle is added up at the end, so not every transaction\nneeds to have a gas price or `block.coinbase` payment, so long as at least one\ndoes, and pays enough to support the gas used in non-paying transactions.\n\nNote: Gas-fees will ONLY benefit your bundle if the transaction is not already\npresent in the mempool. When including a pending transaction in your bundle, it\nis similar to that transaction having a gas price of `0`; other transactions in\nyour bundle will need to pay more for the gas it uses.\n\n## Bundle and User Statistics\n\nThe OpenMEV relay can also return statistics about you as a user (identified\nsolely by your signing address) and any bundle previously submitted.\n\n- `getUserStats()` returns aggregate metrics about past performance\n- `getBundleStats(bundleHash, targetBlockNumber)` returns data specific to a\n  single bundle submission, including detailed timestamps for the various phases\n  a bundle goes before reaching miners.\n\n## Testnetwork Example: Goerli\n\n\u003e Note that OpenMEV does not operate on Goerli, this is via flashbots \n\nTo test OpenMEV before going to mainnet, you can use the Goerli Flashbots relay,\nwhich works in conjunction with a OpenMEV-enabled Goerli validator. Running a compatible OpenMEV client on\nGoerli requires two simple changes:\n\n1. Ensure your genericProvider passed in to the `OpenMevBundleProvider` / `FlashbotsBundleProvider`\n   constructor is connected to Goerli (gas estimates and nonce requests need to\n   correspond to the correct chain):\n\n```ts\nimport { providers } from 'ethers';\nconst provider = providers.getDefaultProvider('goerli');\n```\n\n2. Set the relay endpoint to `https://testnet.flashbots.net/`\n\n```ts\nconst OpenMevProvider = await OpenMevBundleProvider.create(\n  provider,\n  authSigner,\n  'https://testnet.flashbots.net/',\n  'goerli',\n);\n```\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanifoldfinance%2Fopenmev-provider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanifoldfinance%2Fopenmev-provider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanifoldfinance%2Fopenmev-provider/lists"}