auradefi 0.1.2
PyPI GitHub

Authentication & keys

You need at most one key, and even that one is optional.

Key Where to get it What it unlocks
AURADEFI_ETHERSCAN_API_KEY etherscan.io/apis, free tier EVM balances and history on every eip155:* chain

Nothing else takes a key. DefiLlama prices, Blockstream Esplora for Bitcoin and the public Solana endpoint are all keyless, and Sandbox is a recording that makes no network call at all. Webhooks run the other way: we sign, you verify.

There is no auradefi account, no dashboard and no credential of ours to obtain. The key above belongs to a third party, and you bring it.

Environment variables

All configuration is read by Settings.from_env(), which Auradefi.from_env() calls. Copy .env.example and fill in what you need.

Variable Default Meaning
AURADEFI_ETHERSCAN_API_KEY none Etherscan V2 key. Optional.
AURADEFI_HELIUS_API_KEY none Parsed but not yet consumed. See Solana below.
AURADEFI_HTTP_TIMEOUT_S 10.0 Timeout for clients the library builds for you.
AURADEFI_SYNC_MIN_INTERVAL_S 60 Floor between two ticks for one connection.
AURADEFI_PROJECT_ID embed Namespace for derived tenant ids.
AURADEFI_TRUSTED_PROXY_HOPS 0 How many X-Forwarded-For hops your proxies add.

The AURADEFI_ prefix is mandatory. A bare ETHERSCAN_API_KEY in your shell is ignored on purpose, so an unrelated variable can never silently become this library's credential. A test pins that behaviour.

Etherscan V2

This is the only key worth setting.

export AURADEFI_ETHERSCAN_API_KEY=      # https://etherscan.io/apis

It is optional. Without it the apikey parameter is omitted from the request entirely, rather than sent empty, and Etherscan's keyless tier applies.

One key covers every EVM chain. The chain travels in the request as chainid, derived from the CAIP-2 id, so Ethereum, Polygon, Base and any other eip155:N Etherscan supports all use the same key.

The free tier allows 3 requests per second and 100k per day, and what one call costs against that allowance is on Limits and cost.

A wrong or revoked key is not a distinct error type. Etherscan answers HTTP 200 with {"status": "0", "message": "NOTOK", "result": "Invalid API Key"}, which surfaces as:

auradefi.errors.SourceError: etherscan balance error: message='NOTOK' result='Invalid API Key'

An empty history is a valid answer rather than an error. status: "0" with "No transactions found" is an empty page, because a fresh address is a valid address.

DefiLlama

There is no key to set. Two limits matter more than the credential does.

It covers six chains: ERC-20 prices resolve on chain ids 1, 10, 56, 137, 8453 and 42161, and native coin prices resolve on the four ETH-native ones.

It has no Bitcoin or Solana prices at all. Nothing in this package can price BTC or SOL. Those assets come back held but unpriced: listed in report.holdings with price=None, named in report.unpriced, and never counted as zero. To price them, bind your own prices port, described in Bring your own.

Bitcoin

Esplora needs no key. The base URL is the network selector:

Esplora(client)                                              # mainnet
Esplora(client, base_url="https://blockstream.info/testnet/api")

The thing to budget for here is request volume, which Limits and cost puts a number on.

The extended public key never leaves your process. Every request carries a derived bc1… address, and the test suite asserts that against recorded traffic.

Solana

The public mainnet-beta endpoint needs no key and is aggressively rate-limited upstream; a 429 surfaces as SourceError: solana rpc HTTP 429. For a keyed provider, pass the entire URL. AURADEFI_HELIUS_API_KEY is parsed by Settings and consumed by nothing, because the Helius adapter does not ship:

SolanaRpc(client, url="https://mainnet.helius-rpc.com/?api-key=…")

Solana transaction decode is not implemented. Balances and signature history only.

Webhooks

Here the direction is reversed: you hold no key of ours, because we sign and you verify. Each endpoint gets a secret, shown once at registration, and every delivery carries X-Auradefi-Signature (HMAC-SHA256 over timestamp.body) plus X-Auradefi-Timestamp. The verifier ships:

from auradefi.webhooks.sign import verify_signature

verify_signature(secret, timestamp_ms, raw_body, signature, now_ms)

It compares in constant time and refuses a stale timestamp, which gives a captured request a shelf life. See guide 09.

The HTTP API's own credentials

If you run the HTTP API, it has a second, unrelated credential model, and these credentials are yours to issue.

adk_live_… and adk_test_… server keys are created by your backend and scoped (users:admin, accounts:read, accounts:write, sync:trigger). They are stored as hashes, so a database dump does not yield working credentials.

Short-lived user tokens are minted from a server key for exactly one end user and signed with that project's secret. They are safe for a browser or a mobile app, and a token from one project can never verify under another's secret.

See guide 05 and guide 06.

What CassetteMissError means

If you are in Sandbox and see this, nothing is broken and no credential is missing:

auradefi.errors.CassetteMissError: GET https://api.etherscan.io/… is not
recorded in sandbox.json. Recorded interactions: …

It means you asked for something the recording does not contain, usually a different address, chain or page size. Three ways out: ask for what the recording holds, which Quickstart lists; switch to from_env() with a real key; or record your own once and replay it offline after that.