auradefi 0.1.1
PyPI GitHub

EtherscanSource

auradefi.sources.evm.source · source

Both source seams over one Etherscan V2 client.

balances(chain_id, address) -> list[BalanceRecord] and fetch_txlist(chain_id, address, *, start_block, end_block, page, offset, sort) -> list[dict] of RAW rows for the decoder seam.

The client is injected: this constructor performs no I/O and opens no connection. from_key is the convenience that builds one.

Fields

clientpropertyThe client this source uses, for a caller that wants to share it.

__init__

__init__(self, client: httpx.Client, api_key: str | None = None, base_url: str = https://api.etherscan.io/v2/api, page_size: int = 1000) -> None

Bind the client and credentials. ZERO I/O happens here.

api_key=None is servable: the apikey param is omitted and Etherscan's keyless tier applies. page_size is the balance source's token-discovery page size; the history seam is paged by the engine, which passes its own offset per call.

Parameters

clientrequired, httpx.Client

Injected httpx.Client. Nothing is opened here.

api_keyoptional, str | None, default None

None omits the apikey param entirely: the keyless tier, not an empty key.

base_urloptional, str, default 'https://api.etherscan.io/v2/api'

Override to point at a proxy or a compatible endpoint.

page_sizeoptional, int, default 1000

Token-discovery page size for balances.

from_key

from_key(cls, api_key: str | None = None, *, timeout_s: float = 10.0, base_url: str = https://api.etherscan.io/v2/api, page_size: int = 1000) -> EtherscanSource

Build a source owning its own httpx.Client.

The one place in this package that constructs a client from a credential, which is why it lives in sources: an I/O domain. A host that wants connection pooling, proxies, custom TLS or its own retry policy passes the client to __init__ instead; this classmethod is a default, never a requirement.

Parameters

api_keyoptional, str | None, default None

Optional. One key covers every eip155:* chain.

timeout_soptional, float, default 10.0

Applied to the client this builds for you.

base_urloptional, str, default 'https://api.etherscan.io/v2/api'

Override to point at a proxy.

page_sizeoptional, int, default 1000

Token-discovery page size for balances.

balances

balances(self, chain_id: str, address: str) -> list[BalanceRecord]

What address holds on chain_id now (SPEC §6.1).

Delegated verbatim to EtherscanV2.balances: native coin plus every token the address has ever touched, deduplicated, with undecodable rows skipped rather than guessed at. Raises CaipParseError for a non-CAIP-2 chain before any request, and SourceError for anything Etherscan refuses.

Parameters

chain_idrequired, str

none

addressrequired, str

none

Raises

CaipParseError, SourceError

fetch_txlist

fetch_txlist(self, chain_id: str, address: str, *, start_block: int, end_block: int, page: int, offset: int, sort: str) -> list[dict]

One page of raw history rows for exactly the window asked for.

The engine owns the window and the budget: it picks start_block/end_block/page/sort, and a page shorter than offset is how it learns the window drained. So this method widens nothing, retries nothing and pages nothing: one request, one answer.

Rows are returned RAW (list[dict]) because parsing belongs to the decoder seam, which a host may replace. Raises SourceError on any upstream refusal, which Auradefi.sync contains to this one connection's report row rather than losing the whole tick.

Parameters

chain_idrequired, str

CAIP-2 id; converted to Etherscan's numeric chainid.

addressrequired, str

The account whose history this page covers.

start_blockrequired, int

Inclusive lower bound the ENGINE chose.

end_blockrequired, int

Inclusive upper bound the ENGINE chose.

pagerequired, int

1-based page within that window.

offsetrequired, int

Rows per page. A shorter page means the window drained.

sortrequired, str

asc or desc. The engine anchors desc and walks live asc.
Possible values: "asc", "desc"

Raises

SourceError