degenbot.provider¶
High-performance Ethereum RPC provider using Alloy.
This module provides a Rust-based provider for fast log fetching and RPC calls.
RPC methods return the LogData / BlockData mappings defined in
degenbot.types.rpc_types: plain bytes for hash and data fields,
EIP-55 checksummed strings for addresses, and Python int for numeric
fields. Log dicts use camelCase keys; block/transaction dicts use
snake_case.
The provider surface is split by concurrency: the sync mixins and
AlloyProvider live in degenbot.provider.sync, the async
twins in degenbot.provider.async_provider.
Example
>>> from degenbot.provider import AlloyProvider, LogFilter
>>> provider = AlloyProvider("https://eth-mainnet.example.com")
>>>
>>> # Direct property access
>>> chain_id = provider.chain_id
>>> block_number = provider.block_number
>>>
>>> # Log fetching with LogFilter
>>> logs = provider.get_logs(
... LogFilter(
... from_block=18_000_000,
... to_block=18_010_000,
... addresses=["0x..."],
... )
... )
>>>
>>> # Or using keyword arguments
>>> logs = provider.get_logs(
... from_block=18_000_000,
... to_block=18_010_000,
... addresses=["0x..."],
... )
Submodules¶
Package Contents¶
- degenbot.provider.RustAlloyProvider¶
- degenbot.provider.RustAsyncAlloyProvider¶
- class degenbot.provider.AsyncAlloyProvider(rust_provider: degenbot.provider._rust.RustAsyncAlloyProvider)¶
Bases:
_AsyncAlloyEndpointMixin,_AsyncAlloyQueryMixin,_AsyncAlloyIntrospectionMixinHigh-performance async Ethereum RPC provider using Alloy.
A thin Python wrapper around the Rust
AsyncAlloyProviderpyclass. Adds string block-identifier resolution ('latest','earliest','pending') and exposes the inner Rust pyclass viaas_async_alloy()for Rust-side call seams. The public surface is assembled from the async query mixins.- Parameters:
rust_provider – The underlying Rust
AsyncAlloyProviderpyclass.
Prefer
create()to construct an instance from an RPC URL.- static create(rpc_url: str, max_retries: int = 10, max_blocks_per_request: int = 5000, *, requests_per_second: int | None = None, burst: int | None = None, chain_id: int | None = None) AsyncAlloyProvider¶
- Async:
Create an
AsyncAlloyProviderasynchronously.- Parameters:
rpc_url – HTTP/HTTPS/WS/IPC endpoint URL.
max_retries – Maximum retry attempts.
max_blocks_per_request – Maximum blocks per log request.
requests_per_second – Optional rate limit.
burst – Optional burst size for rate limiting.
chain_id – Chain to bind the endpoint to; the Rust core raises
ValueErrorwhen the endpoint serves another chain.
- Returns:
An
AsyncAlloyProviderinstance.
- exception degenbot.provider.ChainIdentityMismatchError¶
Bases:
degenbot.exceptions.base.DegenbotValueError,ValueErrorThe core’s chain-binding refusal, re-homed into this package’s hierarchy.
The check is the core’s invariant; only the error class is re-homed here. It stays a
ValueErroras well as aDegenbotValueError, so a caller that already handled a misconfigured endpoint keeps catching it exactly as it caught the core’s own refusal.
- async degenbot.provider.get_async_provider_from_config(*, chain_id: int | str | None = None, node: str | None = None, resolve_uri: collections.abc.Callable[..., str] = resolve_http_rpc_uri, provider_factory: collections.abc.Callable[..., Any] | None = None, chain_mismatch_error: type[degenbot.provider.ChainMismatchError] = ChainMismatchError) degenbot.provider.async_provider.AsyncAlloyProvider¶
Build a chain-bound
AsyncAlloyProviderfor the session chain.Async counterpart of
get_provider_from_config(): the same resolution, the same core check, awaited on the caller’s event loop. The DI seams are the sync factory’s; an omittedprovider_factoryresolves toAsyncAlloyProvider.create.- Parameters:
chain_id – The explicit chain override; resolved from the config layers when absent.
node – The explicit endpoint override, classified by its own value.
resolve_uri – The endpoint resolver called as
resolve_uri(session_chain_id, node=node).provider_factory – The awaited provider constructor called as
provider_factory(endpoint, chain_id=session_chain_id).chain_mismatch_error – The exception class the core’s refusal is caught as before re-homing.
- Returns:
A chain-bound AsyncAlloyProvider over the resolved RPC endpoint.
- Raises:
ChainIdentityMismatchError – When the endpoint serves another chain than the session targets. It is both a
DegenbotValueErrorand aValueError.
- degenbot.provider.get_provider_from_config(*, chain_id: int | str | None = None, node: str | None = None, resolve_uri: collections.abc.Callable[..., str] = resolve_http_rpc_uri, provider_factory: collections.abc.Callable[..., degenbot.provider.sync.AlloyProvider] | None = None, chain_mismatch_error: type[degenbot.provider.ChainMismatchError] = ChainMismatchError) degenbot.provider.sync.AlloyProvider¶
Build a chain-bound
AlloyProviderfor the session chain.The endpoint resolves through the request scope of the four-layer cascade and the chain through the chain-id cascade, both from the installed typed config;
chain_id/nodeare the explicit override layer when given.The constructed provider is BOUND to that chain: the Rust core verifies the endpoint’s
eth_chainIdonce, and its refusal is translated into aDegenbotValueErrorhere.resolve_uri/provider_factory/chain_mismatch_errorare the DI seams (tests inject a recording resolver, a stand-in constructor, and a constructible stand-in for the PyO3 refusal class); omitted kwargs keep the production bindings.- Parameters:
chain_id – The explicit chain override; resolved from the config layers when absent.
node – The explicit endpoint override, classified by its own value.
resolve_uri – The endpoint resolver called as
resolve_uri(session_chain_id, node=node).provider_factory – The provider constructor called as
provider_factory(endpoint, chain_id=session_chain_id).chain_mismatch_error – The exception class the core’s refusal is caught as before re-homing.
- Returns:
A chain-bound AlloyProvider over the resolved RPC endpoint.
- Raises:
ChainIdentityMismatchError – When the endpoint serves another chain than the session targets. It is both a
DegenbotValueErrorand aValueError.
- class degenbot.provider.OfflineProvider(chain_id: int, blocks: dict[str, dict[str, Any]])¶
Bases:
_OfflineDataMixin,_OfflineLifecycleMixinEthereum provider that serves pre-recorded chain data.
Delegates every data-serving RPC (
call,get_code,get_block,get_block_number,get_block_timestamp) to a real RustAlloyProviderbuilt over an in-memory offline transport, so it is indistinguishable from a live provider to any consumer (includingBotIo). Recorded-JSON metadata (chain_id,block_numbers) is parsed in Python for the convenience accessors; the public surface is assembled from the mixins.- chain_id¶
The chain ID this provider serves data for
- blocks¶
Dictionary of recorded block data keyed by block number string
Example
>>> offline = OfflineProvider( ... chain_id=1, ... blocks={ ... "24945700": { ... "timestamp": 1776984059, ... "calls": {"0x...:0x...": "0x..."}, ... "code": {"0x...": "0x..."}, ... } ... }, ... ) >>> result = offline.call(to="0x...", data=b"...", block=24945700)
- classmethod from_json_file(path: pathlib.Path) OfflineProvider¶
Load recorded data from a JSON file.
Supports both old multi-block format (with “blocks” key) and new single-block format (with “block_number” key).
- Parameters:
path – Path to the JSON file containing recorded data
- Returns:
An OfflineProvider instance loaded from the file.
- class degenbot.provider.AlloyProvider(rpc_url: str, max_retries: int = 10, max_blocks_per_request: int = 5000, chain_id: int | None = None)¶
Bases:
_AlloyEndpointMixin,_AlloyQueryMixin,_AlloyIntrospectionMixinHigh-performance Ethereum RPC provider using Alloy.
Backs log fetching and basic RPC calls with a Rust HTTP client using connection pooling for optimal performance. The public surface is assembled from the query mixins; this class owns construction and teardown of the wrapped Rust provider.
- Parameters:
rpc_url – HTTP/HTTPS endpoint URL
max_retries – Maximum retry attempts (default: 10)
max_blocks_per_request – Maximum logs per request (default: 5000)
chain_id – Chain to bind the endpoint to. The Rust core reads
eth_chainIdonce at construction and raisesValueErrorwhen the endpoint serves another chain;Noneconstructs the provider with no binding.
Example
>>> provider = AlloyProvider("https://eth-mainnet.example.com") >>> >>> # Properties >>> chain_id = provider.chain_id >>> block_number = provider.block_number >>> >>> # Methods >>> block = provider.get_block(18_000_000) >>> logs = provider.get_logs(from_block=18_000_000, to_block=18_010_000) >>> code = provider.get_code("0x...") >>> result = provider.call("0x...", calldata)
- class degenbot.provider.LogFilter¶
Filter criteria for log fetching.
- Parameters:
from_block – Starting block number (inclusive)
to_block – Ending block number (inclusive)
addresses – Contract addresses to filter (optional)
topics – Event topic signatures, nested by position (optional)
Example
>>> filter = LogFilter( ... from_block=18_000_000, ... to_block=18_010_000, ... addresses=["0xContractAddress..."], ... topics=[["0xTransfer..."]], # Match first topic ... )
- from_block: degenbot.types.aliases.BlockNumber¶
- to_block: degenbot.types.aliases.BlockNumber¶