auradefi 0.1.2
PyPI GitHub

Quickstart

Five lines, no credentials.

pip install auradefi
from auradefi import Auradefi

aura = Auradefi.sandbox()
for holding in aura.holdings()[0].holdings:
    print(holding.symbol, holding.quantity, holding.value)
ETH  2   5000.000000000000000000 USD
USDC 25  25.000000 USD

That is a complete program. It needs no API key, no database, no network and no configuration file.

What just happened

Auradefi.sandbox() opens the Sandbox environment: a recording of one address' real Etherscan and DefiLlama traffic, bundled inside the package and replayed locally. Everything above the transport is the production code path, using the same source, decoder, ledger and pricing arithmetic as a live instance.

Sandbox exists so you can write working code before anyone has approved an API key. It also keeps the examples in these docs from drifting away from the library.

Address 0x1111111111111111111111111111111111111111 on eip155:1
Holdings 2 ETH at 2500 USD and 25 USDC at 1 USD, totalling 5025 USD
History seven transactions in blocks 100 to 107
Time frozen at the instant the traffic was recorded

Because Sandbox is a recording, its answers are constants. Ask for something it does not hold, such as a different address, a second chain or a wider page, and you get CassetteMissError listing what it does hold. That is the offline guarantee working as intended.

Record your own Sandbox

One address is enough to learn the shape and not enough to test against your own data. Recorder is the other half: point it at the live service once, and every run after that is offline.

from auradefi.testing.cassettes import Recorder, load
from auradefi.sources.evm.source import EtherscanSource

with Recorder("mywallet.json") as recorder:                  # records
    EtherscanSource(recorder.client(), api_key=KEY).balances("eip155:1", ADDRESS)

source = EtherscanSource(load("mywallet.json").client())     # replays, no key

The saved file is keyless on purpose. Query parameters that carry credentials are stripped as it writes, which is also what lets the replay run without a key at all. Response bodies are saved whole, so read a recording before you commit it: a service that echoes your credential back to you defeats the stripping.

Committed alongside your tests, that file gives you the offline guarantee this package holds itself to, over your addresses instead of ours.

Sync some history

report = aura.sync(budget=10)
print(report.pages_fetched, report.transactions_ingested)   # 5 7

budget caps how many source pages one call may spend. Cursors let the next call resume where this one stopped, so a tick is bounded and keeps its place. Call it again inside sync_min_interval_s and it is a no-op that touches no transport:

aura.sync(budget=10).no_op       # True

That is the whole scheduling contract. You call sync() on your own schedule, from your own worker. The package starts no background thread, and nothing runs unless you ask for it.

Go live

One line changes:

aura = Auradefi.from_env()
user = aura.user("your-opaque-user-id")
user.connect_address("eip155:1", "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045")
aura.sync(budget=5)
export AURADEFI_ETHERSCAN_API_KEY=     # optional; see Authentication

The key is optional. Without one, Etherscan's keyless tier applies. Authentication & keys lists every service this package talks to, which of them need a credential (almost none do), and what each one covers.

Storage still defaults to memory at this point, so from_env() on its own loses everything when the process exits. Passing your own database is one keyword:

aura = Auradefi.from_env(ledger=SqlModelLedger(session_factory=))

Bring your own has that in full, along with the other four ports.

Or serve it over HTTP

The library is the product and the HTTP API is one adapter over it, so the same ports you just bound also make an app:

from auradefi.api.app import create_app
from auradefi.api.deps import Deps

app = create_app(Deps(ledger=, tenancy=, keys=, clock=, ))

It holds no state, opens no connections and creates no stores. Responses use Plaid's wire format, so a client that already reads Plaid reads this. The journey a caller makes:

POST /auth/token          server key -> short-lived user token
POST /connections         user token -> conn_…
GET  /crypto/sync         user token -> added/modified/removed + cursor
GET  /coverage            public     -> the capability matrix, as data

Deps has more fields than the four above, and every one of them is a port you already own. Guide 05 is a single file that wires all of them and drives the result, and the HTTP API page lists every route with its fields.

Where to go next

What this is not

auradefi is alpha, and the README keeps an explicit list of what is absent: one price oracle covering six EVM chains, no Bitcoin or Solana prices at all, no scheduler, and an EVM node path whose vectors were written by hand and never recorded from a chain. Read that list before you budget work against this. Sandbox makes the library easy to try, and the gaps are still there afterwards.