Registry /
http-networking / eth-json-rpc-middleware
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslnode 18–226 runs
build_error
glibcnode 18–226 runs
build_error
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
createFetchMiddleware
✓ import { createFetchMiddleware } from 'eth-json-rpc-middleware';
✗ const createFetchMiddleware = require('eth-json-rpc-middleware').createFetchMiddleware;
ESM is preferred since v20.0.0 due to changes in package exports. CommonJS require() might not work or require specific subpath imports.
createBlockRefMiddleware
✓ import { createBlockRefMiddleware } from 'eth-json-rpc-middleware';
✗ const createBlockRefMiddleware = require('eth-json-rpc-middleware/dist/block-ref');
Direct subpath imports from `dist` are generally not recommended after v20.0.0 due to the `exports` field usage.
createWalletMiddleware
✓ import { createWalletMiddleware } from 'eth-json-rpc-middleware';
This middleware provides hooks for EIP-5792 and EIP-7715; ensure options match the desired EIP version.
createChainIdMiddleware
✓ import { createChainIdMiddleware } from 'eth-json-rpc-middleware';
A simple middleware to inject a `chainId` into requests if not present.
This quickstart demonstrates how to set up a `json-rpc-engine` with common `eth-json-rpc-middleware` components, including `createFetchMiddleware`, `createBlockRefMiddleware`, and `createChainIdMiddleware`. It includes a mock RPC service, essential since `createFetchMiddleware` v18.0.0, to illustrate request handling.
import { JsonRpcEngine } from 'json-rpc-engine';
import { createFetchMiddleware, createBlockRefMiddleware, createChainIdMiddleware } from 'eth-json-rpc-middleware';
// Mock RPC service for createFetchMiddleware (required since v18.0.0)
const mockRpcService = {
provider: {
request: async ({ method, params }) => {
console.log(`Mock RPC request: ${method} ${JSON.stringify(params)}`);
// In a real application, this would forward to an actual RPC endpoint
// using a provider from @metamask/network-controller or similar.
if (method === 'eth_chainId') return '0x1'; // Mainnet
if (method === 'eth_blockNumber') return '0x' + (123456789).toString(16);
if (method === 'eth_sendRawTransaction') return '0xmockTxHash';
return null; // Handle other methods as needed
},
},
// Other properties like 'currentChainId' might be expected by some versions/integrations
};
async function setupAndUseRpcEngine() {
const engine = new JsonRpcEngine();
// Add middleware
engine.add(createBlockRefMiddleware());
engine.add(createChainIdMiddleware('0x1')); // Example: force chainId to Ethereum Mainnet
engine.add(createFetchMiddleware({ rpcService: mockRpcService }));
// Example request
try {
const response = await engine.handle({ id: 1, jsonrpc: '2.0', method: 'eth_blockNumber' });
console.log('eth_blockNumber response:', response.result);
const chainIdResponse = await engine.handle({ id: 2, jsonrpc: '2.0', method: 'eth_chainId' });
console.log('eth_chainId response:', chainIdResponse.result);
// Example of a request that might pass through the fetch middleware
const sendTxResponse = await engine.handle({
id: 3,
jsonrpc: '2.0',
method: 'eth_sendRawTransaction',
params: ['0xmockrawtransactiondata'],
});
console.log('eth_sendRawTransaction response:', sendTxResponse.result);
} catch (error) {
console.error('RPC Error:', error);
}
}
setupAndUseRpcEngine();
Debug
Known issues
breakingVersion 20.0.0 introduced separate CommonJS and ESM distributions using the `exports` field in `package.json`. This breaks previously valid direct imports (e.g., from `dist/`) and may require updating `require()` statements to named imports.fixMigrate CommonJS `require` statements to ESM `import` statements (e.g., `import { Name } from 'eth-json-rpc-middleware';`). Ensure your build system supports `package.json` `exports`. affects: >=20.0.0
breakingThe `createFetchMiddleware` signature changed significantly in v18.0.0. It no longer accepts `fetch`, `btoa`, `rpcUrl`, or `originHttpHeaderKey` directly. Instead, it now strictly requires an `rpcService` object, typically sourced from `@metamask/network-controller`.fixRefactor `createFetchMiddleware` initialization to pass an `rpcService` object. For example: `createFetchMiddleware({ rpcService: { provider: { request: async () => {} } } })`. affects: >=18.0.0
breakingVersion 17.0.0 updated support for EIP-5792 to version 2.0.0, introducing changes like the `atomicRequired` property, making `from` optional in `SendCallsStruct`, and modifying error codes. This may require updates to dApps implementing EIP-5792.fixReview and update your EIP-5792 related data structures and validation logic to align with the 2.0.0 specification changes, particularly for `SendCallsStruct` and `GetCallsStatusResult`.
affects: >=17.0.0
gotchaPrior to v16.0.1, `fetch` middleware could treat non-standard JSON-RPC error responses (those with an `error` field but unexpected additional properties) as successful. This could lead to incorrect error handling or silent failures.fixUpgrade to v16.0.1 or newer to ensure non-standard JSON-RPC error responses are correctly processed as errors.
affects: <16.0.1
gotchaChanges in `PollingBlockTracker.getLatestBlock()` behavior in v19.0.1 and v17.0.1 (regarding `useCache` and error rejection vs. hanging) could affect dApps relying on specific block tracking update mechanisms.fixTest block tracking intensive parts of your application after upgrading. Be aware that `getLatestBlock` will now reject on errors rather than potentially hanging, and `useCache: false` is no longer included in some calls.
affects: >=17.0.1 <19.0.0, >=19.0.1
Errors
Common errors & fixes
ERR_PACKAGE_PATH_NOT_EXPORTED
Attempting to import modules using paths that are no longer exposed directly (e.g., `eth-json-rpc-middleware/dist/something.js`) after v20.0.0's change to `package.json` `exports`.
fixUpdate imports to use the top-level package name and named imports (e.g., `import { createSomeMiddleware } from 'eth-json-rpc-middleware';`). TypeError: createFetchMiddleware is not a function
Calling `createFetchMiddleware` with an outdated signature (e.g., passing `rpcUrl` directly) after the v18.0.0 breaking change.
fixEnsure `createFetchMiddleware` is called with an object containing an `rpcService` property, which itself has a `provider.request` method, as required since v18.0.0.
Error: PollingBlockTracker - encountered an error while attempting to update latest block
An error occurred during an RPC call to fetch the latest block, and this error is being wrapped by the `PollingBlockTracker`.
fixInspect the underlying RPC error; if using older versions, be aware that `getLatestBlock` might reject on errors now, which could be an upstream issue with your RPC provider or network configuration.
Audit
Dependencies
@metamask/json-rpc-enginerequiredCore dependency for creating and handling middleware pipelines.
@metamask/eth-block-trackerrequiredUsed by block-related middleware for tracking the latest blocks.
@metamask/network-controllerrequiredRequired for the `rpcService` object when using `createFetchMiddleware` since v18.0.0.