Ethereum Bloom Filters Client
ethereum-bloom-filters is a JavaScript/TypeScript library designed to efficiently test Ethereum bloom filters for set membership, currently at version 1.2.0. It provides a lightweight client for probabilistic checks, allowing developers to quickly ascertain if a particular address, topic, or other data might be present within a block's logBlooms without requiring a full node query. The package has a minimal dependency footprint, relying solely on `@noble/hashes` for its cryptographic hashing primitives, which is notably funded by the Ethereum Foundation. This approach helps reduce the computational overhead associated with monitoring on-chain events, such as updating user balances, by minimizing unnecessary database queries. While no explicit release cadence is documented, its active maintenance is implied by npm activity and recent versioning. A key differentiator is its focus on standalone bloom filter testing, offering a direct utility for common Ethereum development patterns.
Common errors
-
ReferenceError: require is not defined
cause Attempting to use CommonJS `require()` syntax in an environment that only supports ES Modules (e.g., Node.js with `"type": "module"` or modern browsers without a bundler).fixUse ES Module `import` syntax: `import { isBloom, ... } from 'ethereum-bloom-filters';`. If targeting a browser without a bundler, include the pre-built script tag as per the documentation. -
TypeError: ethereumBloomFilters.isBloom is not a function
cause This error typically occurs if `ethereumBloomFilters` was assigned the result of a `require()` call, but the functions are being accessed incorrectly, or if the global variable isn't properly loaded in a browser context.fixIf using CommonJS, ensure you're calling `require('ethereum-bloom-filters')` and then accessing named exports directly on the returned object (e.g., `ethereumBloomFilters.isBloom`). If using ES Modules, ensure named imports are used: `import { isBloom } from 'ethereum-bloom-filters';`. -
SyntaxError: Named export 'isBloom' not found
cause This happens when using ES Module `import` syntax but the module is fundamentally CommonJS-only or the bundler/runtime is misinterpreting the export map.fixThe library supports both ESM and CJS. Ensure your project's `tsconfig.json` (for TypeScript) or build configuration (Webpack, Rollup, Parcel) correctly resolves ES Modules. For pure Node.js ESM environments, named imports should work directly. If persistent, verify the package's `package.json` `exports` field or try CJS `require` if in a compatible environment.
Warnings
- gotcha Bloom filters are probabilistic data structures that can produce 'false positives'. A result of `true` from a membership test means the item *might* be in the set, but it is not a guarantee. A result of `false` means the item is *definitely not* in the set. This characteristic is fundamental to their space efficiency.
- gotcha The library explicitly states it does not expose a CDN for security reasons. Developers including this library in web applications without a module bundler must manually copy the script files from the `web-scripts` directory in the package or GitHub repository and include them via a `<script>` tag.
- gotcha Ethereum's use of bloom filters for `logBlooms` is primarily for events (logs), not for standard ETH transactions. Pure ETH transfers do not emit logs and therefore will not be reflected in a block's bloom filter. Contracts must emit events for their data to be queryable via bloom filters.
- deprecated The Ethereum protocol itself is moving towards deprecating and eventually removing bloom filters from block headers and transaction receipts, as described in EIP-7668. While this library will continue to function for existing historical blocks that include blooms, new blocks in a post-EIP-7668 Ethereum will have empty bloom filters.
Install
-
npm install ethereum-bloom-filters -
yarn add ethereum-bloom-filters -
pnpm add ethereum-bloom-filters
Imports
- isBloom
const isBloom = require('ethereum-bloom-filters').isBloom;import { isBloom } from 'ethereum-bloom-filters'; - ethereumBloomFilters
import ethereumBloomFilters from 'ethereum-bloom-filters';
const ethereumBloomFilters = require('ethereum-bloom-filters'); - isUserEthereumAddressInBloom
ethereumBloomFilters.isUserEthereumAddressInBloom(); // without prior require() or script tag
import { isUserEthereumAddressInBloom } from 'ethereum-bloom-filters';
Quickstart
import { isUserEthereumAddressInBloom, isTopicInBloom, isInBloom } from 'ethereum-bloom-filters';
// Example Ethereum block bloom (a 256-byte hex string, actual bloom from a real block would be much longer)
const blockBloom = '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
// A fake Ethereum address (20 bytes)
const userAddress = '0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B';
// A fake topic (32 bytes)
const eventTopic = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
const isAddressLikelyPresent = isUserEthereumAddressInBloom(blockBloom, userAddress);
const isTopicLikelyPresent = isTopicInBloom(blockBloom, eventTopic);
const isGenericValueLikelyPresent = isInBloom(blockBloom, 'some_arbitrary_value');
console.log(`Is address ${userAddress} likely in bloom? ${isAddressLikelyPresent}`); // Should be false with an empty bloom
console.log(`Is topic ${eventTopic} likely in bloom? ${isTopicLikelyPresent}`); // Should be false with an empty bloom
console.log(`Is generic value likely in bloom? ${isGenericValueLikelyPresent}`); // Should be false with an empty bloom
// Note: Bloom filters are probabilistic. A 'true' result means it *might* be present (false positive possible).
// A 'false' result means it is *definitely not* present (no false negatives).