{"id":13759518,"url":"https://github.com/httptoolkit/mockthereum","last_synced_at":"2025-08-12T14:45:23.084Z","repository":{"id":58153862,"uuid":"427474440","full_name":"httptoolkit/mockthereum","owner":"httptoolkit","description":"Powerful friendly Ethereum mock node \u0026 proxy","archived":false,"fork":false,"pushed_at":"2023-06-07T14:51:13.000Z","size":131,"stargazers_count":26,"open_issues_count":1,"forks_count":4,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-01-15T04:48:51.654Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/httptoolkit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-11-12T19:29:37.000Z","updated_at":"2024-08-05T08:03:14.000Z","dependencies_parsed_at":"2024-01-17T16:58:14.046Z","dependency_job_id":"201d3f55-5d4a-4a45-9fb1-977de1ce7823","html_url":"https://github.com/httptoolkit/mockthereum","commit_stats":{"total_commits":36,"total_committers":1,"mean_commits":36.0,"dds":0.0,"last_synced_commit":"02c5c6363bcac5625134988d04a7798840f9bb8e"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httptoolkit%2Fmockthereum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httptoolkit%2Fmockthereum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httptoolkit%2Fmockthereum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/httptoolkit%2Fmockthereum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/httptoolkit","download_url":"https://codeload.github.com/httptoolkit/mockthereum/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235538025,"owners_count":19006071,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-08-03T13:00:54.621Z","updated_at":"2025-01-25T04:27:25.817Z","avatar_url":"https://github.com/httptoolkit.png","language":"TypeScript","funding_links":[],"categories":["dApps directory"],"sub_categories":["Development Frameworks"],"readme":"# Mockthereum [![Build Status](https://github.com/httptoolkit/mockthereum/workflows/CI/badge.svg)](https://github.com/httptoolkit/mockthereum/actions) [![Available on NPM](https://img.shields.io/npm/v/mockthereum.svg)](https://npmjs.com/package/mockthereum)\n\n\u003e _Part of [HTTP Toolkit](https://httptoolkit.tech): powerful tools for building, testing \u0026 debugging HTTP(S), Ethereum, IPFS, and more_\n\nMockthereum lets you build a fake Ethereum node, or proxy traffic to a real Ethereum node, to inspect \u0026 mock all Ethereum interactions made by any Ethereum client website or application.\n\n---\n\n:warning: _Mockthereum is still new \u0026 rapidly developing!_ :warning:\n\n_Everything described here works today, but there's lots more to come, and some advanced use cases may run into rough edges. If you hit any problems or missing features, please [open an issue](https://github.com/httptoolkit/mockthereum/issues/new)._\n\n---\n\n## Example\n\n```typescript\nimport * as Mockthereum from 'mockthereum'\n\n// Use any real Ethereum client:\nimport Web3 from 'web3';\n\n// Parameters for some real Web3 contract:\nconst CONTRACT_ADDRESS = \"0x...\";\nconst JSON_CONTRACT_ABI = { /* ... */ };\n\ndescribe(\"Mockthereum\", () =\u003e {\n\n    // Create a mock Ethereum node:\n    const mockNode = Mockthereum.getLocal();\n\n    // Start \u0026 stop your mock node to reset state between tests:\n    beforeEach(() =\u003e mockNode.start());\n    afterEach(() =\u003e mockNode.stop());\n\n    it(\"lets you mock behaviour and assert on Ethereum interactions\", async () =\u003e {\n        // Mock any address balance\n        await mockNode.forBalance('0x0000000000000000000000000000000000000001')\n            .thenReturn(1000);\n\n        // Mock any contract's function call:\n        const mockedFunction = await mockNode.forCall(CONTRACT_ADDRESS) // Match any contract address\n            // Optionally, match specific functions and parameters:\n            .forFunction('function getText(string key) returns (string)')\n            .withParams([\"test\"])\n            // Mock contract results:\n            .thenReturn('Mock result');\n\n        // Real code to make client requests to the Ethereum node:\n        const web3 = new Web3(mockNode.url);\n\n        const walletBalance = await web3.eth.getBalance('0x0000000000000000000000000000000000000001');\n        expect(walletBalance).to.equal(\"1000\"); // Returns our mocked wallet balance\n\n        const contract = new web3.eth.Contract(JSON_CONTRACT_ABI, CONTRACT_ADDRESS);\n        const contractResult = await contract.methods.getText(\"test\").call();\n\n        // Check contract call returns our fake contract result:\n        expect(contractResult).to.equal(\"Mock result\");\n\n        // Assert on inputs, to check we saw the contract calls we expected:\n        const mockedCalls = await mockedFunction.getRequests();\n        expect(mockedCalls.length).to.equal(1);\n\n        expect(mockedCalls[0]).to.deep.include({\n            // Examine full interaction data, included decoded parameters etc:\n            to: CONTRACT_ADDRESS,\n            params: [\"test\"]\n        });\n    });\n});\n```\n\n## Getting Started\n\nFirst, install Mockthereum:\n\n```bash\nnpm install --save-dev mockthereum\n```\n\nOnce you've installed the library, you'll want to use it in your test or automation code. To do so you need to:\n\n* Create an new Mockthereum node\n* Start the node, to make it listen for requests (and stop it when you're done)\n* Use the URL of the Mockthereum node as your Ethereum provider URL\n* Define some rules to mock behaviour\n\n### Creating a Mockthereum Node\n\nTo create a node in Node.js, you can simply call `Mockthereum.getLocal()` and you're done.\n\nIn many cases though, to test a web application you'll want to run your tests inside a browser, and create \u0026 manage your mock Ethereum node there too. It's not possible to launch a node from inside a browser, but Mockthereum provides a separate admin server you can run, which will host your mock Ethereum node externally.\n\nOnce your admin server is running, you can use the exact same code as for Node.js, but each method call is transparently turned into a remote-control call to the admin server.\n\nTo do this, you just need to run the admin server before you start your tests, and stop it afterwards. You can do that in one of two ways:\n\n* You can run your test suite using the provided launch helper:\n  ```\n  mockthereum -c \u003cyour test command\u003e\n  ```\n  This will start \u0026 stop the admin server automatically before and after your tests.\n* Or you can launch the admin server programmatically like so:\n  ```javascript\n  import * as Mockthereum from 'mockthereum';\n\n  const adminServer = Mockthereum.getAdminServer();\n  adminServer.start().then(() =\u003e\n      console.log('Admin server started')\n  );\n  ```\n\nNote that as this is a universal library (it works in Node.js \u0026 browsers) this code does reference some Node.js modules \u0026 globals in a couple of places. If you're using Mockthereum from inside a browser, this needs to be handled by your bundler. In many bundlers this will be handled automatically, but if it's not you may need to enable node polyfills for this. In Webpack that usually means enabling [node-polyfill-webpack-plugin](https://www.npmjs.com/package/node-polyfill-webpack-plugin), or in ESBuild you'll want the [`@esbuild-plugins/node-modules-polyfill`](https://www.npmjs.com/package/@esbuild-plugins/node-modules-polyfill) and [`@esbuild-plugins/node-globals-polyfill`](https://www.npmjs.com/package/@esbuild-plugins/node-globals-polyfill) plugins.\n\nOnce you have an admin server running, you can call `Mockthereum.getLocal()` in the browser in exactly the same way as in Node.js, and it will automatically find \u0026 use the local admin server to create a mock Ethereum node.\n\n### Starting \u0026 stopping your Mockthereum node\n\nNodes expose `.start()` and `.stop()` methods to start \u0026 stop the node. You should call `.start()` before you use the node, call `.stop()` when you're done with it, and in both cases wait for the promise that's returned to ensure everything is completed before continuing.\n\nIn automation, you'll want to create the node and start it immediately, and only stop it at shutdown. In testing environments it's usually better to start \u0026 stop the node between tests, like so:\n\n```javascript\nimport * as Mockthereum from 'mockthereum';\n\nconst mockNode = Mockthereum.getLocal();\n\ndescribe(\"A suite of tests\", () =\u003e {\n\n  beforeEach(async () =\u003e {\n    await mockNode.start();\n  });\n\n  afterEach(async () =\u003e {\n    await mockNode.stop();\n  });\n\n  it(\"A single test\", () =\u003e {\n    // ...\n  });\n\n});\n```\n\n### Using your Mockthereum Node\n\nTo use the Mockthereum node instead of connecting to your real provider, just use the HTTP URL exposed by `mockNode.url` as your Ethereum provider URL.\n\nFor example, for Web3.js:\n\n```javascript\nimport Web3 from \"web3\";\n\nconst web3 = new Web3(mockNode.url);\n\n// Now use web3 as normal, and all interactions will be sent to the mock node instead of\n// any real Ethereum node, and so will not touch the real Ethereum network (unless you\n// explicitly proxy them - see 'Proxying Ethereum Traffic' below).\n```\n\n### Defining mock rules\n\nOnce you have a mock node, you can define rules to mock behaviour, allowing you to precisely control the Ethereum environment your code runs in, and test a variety of scenarios isolated from the real Ethereum network.\n\nTo define a rule, once you have a mock node, call one of the `.forX()` methods to start defining the behaviour for a specific interaction through chained method calls, and call a `.thenX()` rule at the end (and wait for the returned promise) to complete the rule an activate that behaviour.\n\nThere's many interactions that can be mocked with many behaviours, here's some examples:\n\n```javascript\n// Mock the balance of a wallet:\nmockNode.forBalance('0x123412341234...')\n    .thenReturn(1000);\n\n// Mock a fixed result for a contract call:\nmockNode.forCall(CONTRACT_ADDRESS)\n    .forFunction(\"function foobar(bool, string) returns (int256)\")\n    .withParams([true, 'test'])\n    .thenReturn([1234]);\n\n// Mock transactions, to test transaction rejection:\nmockNode.forSendTransactionTo(WALLET_ADDRESS)\n    .thenRevert();\n\n// Simulate timeouts and connection issues:\nmockNode.forBlockNumber()\n    .thenTimeout();\n```\n\nFor the full list of interactions \u0026 behaviours, see the [detailed API Reference](https://httptoolkit.github.io/mockthereum/).\n\n### Examining received requests\n\nIn addition to defining behaviours, you can also examine the requests that have been received by the mock node, to verify that expected traffic is being received.\n\nTo do so, call either `mockNode.getSeenRequests()` or `mockNode.getSeenMethodCalls(methodName)` which returns a promise that resolves to an array of seen requests - each one with a `method` property (the Ethereum method name, like `eth_getBalance`), a `parameters` property (the parameters passed to that method), and a `rawRequest` property (the full raw HTTP request details).\n\nFor example, you can log all seen requests like so:\n\n```javascript\nmockNode.getSeenRequests().then(requests =\u003e {\n    requests.forEach(request =\u003e {\n        console.log(`${request.method}: ${JSON.stringify(request.parameters)}`);\n    });\n});\n```\n\nIn addition, methods to mock contract \u0026 transaction behaviour (e.g. rules defined with `forCall()` or `forSendTransaction()`) return a mocked contract from the promise returned by every `.thenX()` method, which can be used directly to query the interactions with that specific rule.\n\nEach interaction is returned as an object with `to`, `from`, `value`, `params` and `rawRequest` fields.\n\nFor example:\n\n```javascript\nconst mockedContract = await mockNode.forCall(CONTRACT_ADDRESS)\n    .forFunction(\"function foobar(bool, string) returns (int256)\")\n    .withParams([true, 'test'])\n    .thenReturn([1234]);\n\n// ...Call the above contract a few times...\n\nmockedContract.getRequests().then(requests =\u003e {\n    requests.forEach(request =\u003e {\n        console.log(`${request.from}-\u003e${request.to}: ${request.value} (${JSON.stringify(request.params)})`);\n    });\n});\n```\n\n### Proxying Ethereum traffic\n\nBy default Mockthereum will mock all interactions with default values (rejecting calls \u0026 transactions, reporting all wallets as empty, and returning default values for all query methods like `eth_gasPrice`) but you can change this to proxy traffic to a real Ethereum node instead.\n\nBy doing so, you can use Mockthereum as an intercepting proxy - returning real responses from the network for most cases, but allowing specific interactions to be mocked in isolation, and making it possible to query the list of interactions that were made.\n\nTo do this, pass `unmatchedRequests: { proxyTo: \"a-real-ethereum-node-HTTP-url\" }` as an option when creating your mock Ethereum node. This will disable the default stub responses, and proxy all unmatched requests to the given node instead. For example:\n\n```javascript\nimport * as Mockthereum from 'mockthereum'\nconst mockNode = Mockthereum.getLocal({\n  unmatchedRequests: { proxyTo: \"http://localhost:30303\" }\n});\nmockNode.start();\n```\n\nThis only changes the unmatched request behaviour, and all other methods will continue to define behaviour and query seen request data as normal.\n\n## API Reference Documentation\n\nFor more details, see the [Mockthereum reference docs](https://httptoolkit.github.io/mockthereum/).\n\n---\n\n_This‌ ‌project‌ ‌has‌ ‌received‌ ‌funding‌ ‌from‌ ‌the‌ ‌European‌ ‌Union’s‌ ‌Horizon‌ ‌2020‌‌ research‌ ‌and‌ ‌innovation‌ ‌programme‌ ‌within‌ ‌the‌ ‌framework‌ ‌of‌ ‌the‌ ‌NGI-POINTER‌‌ Project‌ ‌funded‌ ‌under‌ ‌grant‌ ‌agreement‌ ‌No‌ 871528._\n\n![The NGI logo and EU flag](./ngi-eu-footer.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhttptoolkit%2Fmockthereum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhttptoolkit%2Fmockthereum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhttptoolkit%2Fmockthereum/lists"}