eth_portfolio package
Subpackages
- eth_portfolio.protocols package
- Subpackages
- Submodules
- eth_portfolio.protocols.convex module
- eth_portfolio.protocols.dsr module
- eth_portfolio.protocols.liquity module
LiquityStabilityPool
LiquityStabilityPool._balances()
LiquityStabilityPool.should_check()
LiquityStabilityPool.__call__
LiquityStabilityPool.balance_method_name
LiquityStabilityPool.balances
LiquityStabilityPool.contract
LiquityStabilityPool.contract_address
LiquityStabilityPool.contract_call
LiquityStabilityPool.deploy_block
LiquityStabilityPool.networks
LiquityStabilityPool.price
LiquityStabilityPool.scale
LiquityStabilityPool.token
LqtyStakingPool
LqtyStakingPool._balances()
LqtyStakingPool.should_check()
LqtyStakingPool.__call__
LqtyStakingPool.balance_method_name
LqtyStakingPool.balances
LqtyStakingPool.contract
LqtyStakingPool.contract_address
LqtyStakingPool.contract_call
LqtyStakingPool.deploy_block
LqtyStakingPool.networks
LqtyStakingPool.price
LqtyStakingPool.scale
LqtyStakingPool.token
- Module contents
Submodules
eth_portfolio.address module
This module defines the PortfolioAddress
class, which represents an address managed by the eth-portfolio system.
The eth-portfolio acts as a manager of addresses, handling various lending protocols and external interactions.
The PortfolioAddress
class is designed to manage different aspects of an Ethereum address within the portfolio,
such as transactions, transfers, balances, and interactions with both external and lending protocols.
Key components and functionalities provided by the PortfolioAddress
class include:
- Handling Ethereum and token balances
- Managing debt and collateral from lending protocols
- Tracking transactions and transfers (both internal and token transfers)
- Providing comprehensive balance descriptions at specific block heights
The class leverages asynchronous operations using the a_sync library to efficiently gather and process data. It also integrates with various submodules from eth-portfolio to load balances, manage ledgers, and interact with external protocols.
- class eth_portfolio.address.PortfolioAddress[source]
Bases:
_LedgeredBase
[AddressLedgerBase
]Represents a portfolio address within the eth-portfolio system.
When awaited, a list of all elements will be returned.
- __aiter__()
Return an async iterator that yields
T
objects from theASyncIterable
.- Return type:
AsyncIterator[_T]
- __getitem__(slice)
- Parameters:
slice (slice)
- Return type:
ASyncIterator[_T]
- __init__(address, portfolio, asynchronous=False)[source]
Initializes the PortfolioAddress instance.
- Parameters:
address (str | HexBytes | AnyAddress | EthAddress) – The address to manage.
portfolio (Portfolio) – The portfolio instance managing this address.
asynchronous (optional) – Flag for asynchronous operation. Defaults to False.
- Raises:
TypeError – If asynchronous is not a boolean.
- Return type:
None
Examples
>>> portfolio = Portfolio() >>> address = PortfolioAddress('0x1234...', portfolio)
- __iter__()
Return an iterator that yields
T
objects from theASyncIterable
.- Return type:
Iterator[T]
- filter(function)
Filters the contents of the
ASyncIterable
based on a function.- Parameters:
function (Callable[[T], Awaitable[bool]] | Callable[[T], bool]) – A function that returns a boolean that indicates if an item should be included in the filtered result. Can be sync or async.
- Returns:
An instance of
ASyncFilter
that yields the filtered objects from theASyncIterable
.- Return type:
ASyncFilter[T]
- sort(*, key=None, reverse=False)
Sort the contents of the
ASyncIterable
.- Parameters:
key (optional) – A function of one argument that is used to extract a comparison key from each list element. If None, the elements themselves will be sorted. Defaults to None.
reverse (optional) – If True, the yielded elements will be sorted in reverse order. Defaults to False.
- Returns:
An instance of
ASyncSorter
that will yield the objects yielded from thisASyncIterable
, but sorted.- Return type:
ASyncSorter[T]
- yield_forever()
- Return type:
ASyncIterator[_T]
- property _ledgers: Iterator[_LT]
An iterator with the 3 ledgers (transactions, internal transfers, token transfers)
- address
The address being managed.
- all[source]
Retrieves all ledger entries between two blocks.
- Parameters:
- Returns:
The ledger entries.
- Return type:
Dict[str,
PandableLedgerEntryList
]
Examples
>>> all_entries = await address.all(12000000, 12345678)
- assets[source]
Retrieves the balances for every asset in the wallet at a given block.
- Parameters:
block (optional) – The block number to query. Defaults to None, which uses the latest block.
- Returns:
The asset balances at block.
- Return type:
Examples
>>> assets = await address.assets(12345678)
- asynchronous
Flag indicating if the operations are asynchronous.
- balances[source]
Retrieves balances for all assets in the wallet at a given block.
- Parameters:
block (int | BlockNumber | None) – The block number.
- Returns:
The balances.
- Return type:
Examples
>>> balances = await address.balances(12345678)
- collateral[source]
Retrieves all balances held by lending protocols on behalf of the wallet at a given block.
- Parameters:
block (optional) – The block number. Defaults to None, which uses the latest block.
- Returns:
The collateral balances.
- Return type:
Examples
>>> collateral = await address.collateral(12345678)
- debt[source]
Retrieves all debt balances for the wallet at a given block.
- Parameters:
block (optional) – The block number. Defaults to None, which uses the latest block.
- Returns:
The debt balances at block.
- Return type:
Examples
>>> debt = await address.debt(12345678)
- describe[source]
Describes all of the wallet’s balances at a given block.
- Parameters:
block (int) – The block number.
- Returns:
The wallet balances.
- Return type:
- Raises:
TypeError – If block is not an integer.
Examples
>>> wallet_balances = await address.describe(12345678)
- eth_balance[source]
Retrieves the ETH balance for the wallet at a given block.
- Parameters:
block (int | BlockNumber | None) – The block number.
- Returns:
The ETH balance at block.
- Return type:
Examples
>>> eth_balance = await address.eth_balance(12345678)
- external_balances[source]
Retrieves the balances owned by the wallet, but not held in the wallet, at a given block.
- Parameters:
block (optional) – The block number. Defaults to None, which uses the latest block.
- Returns:
The external balances.
- Return type:
Examples
>>> external_balances = await address.external_balances(12345678)
- internal_transfers: _LT
Ledger for tracking internal transfers.
- load_prices
Indicates if price loading is enabled.
- property materialized: List[T]
Synchronously iterate through the
ASyncIterable
and return all objects.- Returns:
A list of the objects yielded by the
ASyncIterable
.
- staking[source]
Retrieves all balances staked in protocols supported by eth_portfolio on behalf of the wallet at a given block.
- Parameters:
block (optional) – The block number. Defaults to None, which uses the latest block.
- Returns:
The staked balances.
- Return type:
Examples
>>> staking_balances = await address.staking(12345678)
- token_balances[source]
Retrieves the balances for all tokens in the wallet at a given block.
- Parameters:
block – The block number.
- Returns:
The token balances at block.
- Return type:
Examples
>>> token_balances = await address.token_balances(12345678)
- token_transfers: _LT
Ledger for tracking token transfers.
- transactions: _LT
Ledger for tracking transactions.
eth_portfolio.buckets module
eth_portfolio.constants module
eth_portfolio.portfolio module
This module defines the Portfolio
and PortfolioWallets
classes, which are used to manage and interact with a collection of PortfolioAddress
objects.
It also includes the PortfolioLedger
class for handling transactions, internal transfers, and token transfers associated with the portfolio.
The Portfolio
class leverages the a_sync library to support both synchronous and asynchronous operations. This allows it to efficiently gather data, perform portfolio-related tasks, and handle network calls without blocking, thus improving the overall responsiveness and performance of portfolio operations.
This file is part of a larger system that includes modules for handling portfolio addresses, ledger entries, and other related tasks.
- class eth_portfolio.portfolio.Portfolio[source]
Bases:
ASyncGenericBase
Used to export information about a group of
PortfolioAddress
objects.Has all attributes of a
PortfolioAddress
.All calls to function(*args, **kwargs) will return {address: PortfolioAddress(Address).function(*args, **kwargs)}
- __getitem__(key)[source]
Get a
PortfolioAddress
by its key.- Parameters:
key (str | HexBytes | AnyAddress | EthAddress) – The address key.
- Returns:
The
PortfolioAddress
object.- Return type:
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> address = portfolio["0xAddress1"] >>> print(address)
- __init__(addresses, start_block=0, label='your portfolio', load_prices=True, asynchronous=False)[source]
Initialize a Portfolio instance.
- Parameters:
addresses (str | HexBytes | AnyAddress | EthAddress | Iterable[str | HexBytes | AnyAddress | EthAddress]) – The addresses to include in the portfolio.
start_block (int)
label (str)
load_prices (bool)
asynchronous (bool)
- Return type:
None
Examples
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> print(portfolio)
- __iter__()[source]
Iterate over the
PortfolioAddress
objects.- Returns:
An iterator over
PortfolioAddress
objects.- Return type:
Iterator[PortfolioAddress]
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> for address in portfolio: ... print(address)
- _start_block
The starting block number. Defaults to 0.
- addresses
A container for the
Portfolio
’sPortfolioAddress
objects.- Type:
PortfolioWallets
Works like a
Dict[Address, PortfolioAddress]
except you get the values when you iterate instead of the keys.
- describe[source]
Returns a full snapshot of your portfolio at a given block.
- Parameters:
block (int) – The block number.
- Returns:
A snapshot of the portfolio balances.
- Return type:
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> balances = await portfolio.describe(block=1200000) >>> print(balances)
- property internal_transfers: PortfolioInternalTransfersLedger
A container for all internal transfers to or from any of your
PortfolioAddress
.- Returns:
The
PortfolioInternalTransfersLedger
object.- Return type:
PortfolioInternalTransfersLedger
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> internal_transfers = portfolio.internal_transfers >>> print(internal_transfers)
- label
A label for the portfolio. Defaults to “your portfolio”
- ledger
A container for all of your fun taxable events.
- Type:
PortfolioLedger
- property token_transfers: PortfolioTokenTransfersLedger
A container for all token transfers to or from any of your
PortfolioAddress
.- Returns:
The
PortfolioTokenTransfersLedger
object.- Return type:
PortfolioTokenTransfersLedger
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> token_transfers = portfolio.token_transfers >>> print(token_transfers)
- property transactions: PortfolioTransactionsLedger
A container for all transactions to or from any of your
PortfolioAddress
.- Returns:
The
PortfolioTransactionsLedger
object.- Return type:
PortfolioTransactionsLedger
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> transactions = portfolio.transactions >>> print(transactions)
- class eth_portfolio.portfolio.PortfolioLedger[source]
Bases:
_LedgeredBase
[PortfolioLedgerBase
]A container for all transactions, internal transfers, and token transfers to or from any of the wallets in your
Portfolio
.When awaited, a list of all elements will be returned.
- __aiter__()
Return an async iterator that yields
T
objects from theASyncIterable
.- Return type:
AsyncIterator[_T]
- __getitem__(slice)
- Parameters:
slice (slice)
- Return type:
ASyncIterator[_T]
- __iter__()
Return an iterator that yields
T
objects from theASyncIterable
.- Return type:
Iterator[T]
- filter(function)
Filters the contents of the
ASyncIterable
based on a function.- Parameters:
function (Callable[[T], Awaitable[bool]] | Callable[[T], bool]) – A function that returns a boolean that indicates if an item should be included in the filtered result. Can be sync or async.
- Returns:
An instance of
ASyncFilter
that yields the filtered objects from theASyncIterable
.- Return type:
ASyncFilter[T]
- sort(*, key=None, reverse=False)
Sort the contents of the
ASyncIterable
.- Parameters:
key (optional) – A function of one argument that is used to extract a comparison key from each list element. If None, the elements themselves will be sorted. Defaults to None.
reverse (optional) – If True, the yielded elements will be sorted in reverse order. Defaults to False.
- Returns:
An instance of
ASyncSorter
that will yield the objects yielded from thisASyncIterable
, but sorted.- Return type:
ASyncSorter[T]
- yield_forever()
- Return type:
ASyncIterator[_T]
- property _ledgers: Iterator[_LT]
An iterator with the 3 ledgers (transactions, internal transfers, token transfers)
- all_entries[source]
Returns a mapping containing all transactions, internal transfers, and token transfers to or from each wallet in your portfolio.
- Parameters:
- Returns:
A dictionary mapping
PortfolioAddress
to their ledger entries.- Return type:
Dict[PortfolioAddress, Dict[str, PandableLedgerEntryList]]
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> entries = await portfolio.ledger.all_entries(start_block=1000000, end_block=1100000) >>> print(entries)
- asynchronous
True if default mode is async, False if sync.
- df[source]
Returns a DataFrame containing all transactions, internal transfers, and token transfers to or from any wallet in your portfolio.
- Parameters:
- Returns:
A DataFrame with the ledger entries.
- Return type:
DataFrame
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> df = await portfolio.ledger.df(start_block=1000000, end_block=1100000) >>> print(df)
- internal_transfers: _LT
A container for all internal transfers to or from any of your
PortfolioAddress
.
- property materialized: List[T]
Synchronously iterate through the
ASyncIterable
and return all objects.- Returns:
A list of the objects yielded by the
ASyncIterable
.
- token_transfers: _LT
A container for all token transfers to or from any of your
PortfolioAddress
.
- transactions: _LT
A container for all transactions to or from any of your
PortfolioAddress
.
- class eth_portfolio.portfolio.PortfolioWallets[source]
Bases:
Iterable
[PortfolioAddress
],Dict
[str
|HexBytes
|AnyAddress
|EthAddress
,PortfolioAddress
]A container that holds all
PortfolioAddress
objects for a specificPortfolio
.Works like a
Dict[Address, PortfolioAddress]
except when you iterate you get the values instead of the keys. You should not initialize these. They are created automatically duringPortfolio
initialization.- _wallets
A checksummed dictionary of
PortfolioAddress
objects.- Type:
checksum_dict.base.ChecksumAddressDict[eth_portfolio.address.PortfolioAddress]
- __getitem__(address)[source]
Get the
PortfolioAddress
object for a given address.- Parameters:
address (str | HexBytes | AnyAddress | EthAddress) – The address to look up.
- Returns:
The
PortfolioAddress
object.- Return type:
- __init__(portfolio, addresses)[source]
Initialize a PortfolioWallets instance.
- Parameters:
portfolio (Portfolio) – The
Portfolio
instance to which this wallet belongs.addresses (Iterable[str | HexBytes | AnyAddress | EthAddress]) – An iterable of addresses to be included in the portfolio.
- Return type:
None
- __iter__()[source]
Iterate over the
PortfolioAddress
objects in the wallets.- Returns:
An iterator over
PortfolioAddress
objects.- Return type:
Iterator[PortfolioAddress]
- clear() None. Remove all items from D.
- copy() a shallow copy of D
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items()[source]
Get the items (address,
PortfolioAddress
pairs) of the wallets.- Returns:
An iterable of (address,
PortfolioAddress
) tuples.- Return type:
Iterable[Tuple[Address, PortfolioAddress]]
- keys()[source]
Get the keys (addresses) of the wallets.
- Returns:
An iterable of addresses.
- Return type:
Iterable[Address]
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- update([E, ]**F) None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values()[source]
Get the values (
PortfolioAddress
objects) of the wallets.- Returns:
An iterable of
PortfolioAddress
objects.- Return type:
Iterable[PortfolioAddress]
- _wallets: ChecksumAddressDict[PortfolioAddress]
A checksummed dictionary of
PortfolioAddress
objects.- Type:
ChecksumAddressDict[PortfolioAddress]
eth_portfolio.structs module
Defines the data classes used to represent the various types of value-transfer actions on the blockchain. These include transactions, internal transfers, and token transfers.
The classes are designed to provide a consistent and flexible interface for working with blockchain data. Instance attributes can be fetched with either dot notation or key lookup. Classes are compatible with the standard dictionary interface.
- class eth_portfolio.structs.AccessListEntry[source]
Bases:
Struct
The
AccessListEntry
class represents an entry in an Ethereum transaction access list.Access lists are used in EIP-2930 and EIP-1559 transactions to specify storage slots that the transaction plans to access, potentially reducing gas costs.
Example
>>> entry = AccessListEntry( ... address="0x742d35Cc6634C0532925a3b844Bc454e4438f44e", ... storage_keys=(b'key1', b'key2') ... ) >>> entry.address '0x742d35Cc6634C0532925a3b844Bc454e4438f44e' >>> len(entry.storage_keys) 2
- class eth_portfolio.structs.InternalTransfer[source]
Bases:
_LedgerEntryBase
The :class:`~structs.InternalTransfer`class represents an internal transfer or call within a blockchain transaction.
Captures operations that occur during transaction execution, such as contract-to-contract calls, contract creations, or self-destructs. These are not separate on-chain transactions but part of the execution of a single transaction.
Example
>>> internal_tx = InternalTransfer( ... chainid=Network.Mainnet, ... block_number=Block(15537393), ... hash="0x123...", ... from_address="0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", ... to_address="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", ... value=Decimal("0"), ... block_hash="0xabc...", ... type="call", ... trace_address="0.1", ... gas=100000, ... gas_used=21000, ... subtraces=1, ... call_type="call", ... input="0x123...", ... output="0x456..." ... ) >>> internal_tx.type 'call' >>> internal_tx.trace_address '0.1' >>> internal_tx.gas_used 21000
- __getitem__(item)
Retrieves the value of the specified field.
- keys()
Returns an iterator over the field names of the struct.
- block_hash: str
The hash of the block containing the transaction that includes this InternalTransfer.
- call_type: str | None
The type of call made in this InternalTransfer (e.g., “call”, “delegatecall”, “staticcall”).
- entry_type: ClassVar[Literal['internal_transfer']] = 'internal_transfer'
Constant indicating this value transfer is an internal transfer or call entry.
- trace_address: str
The path of sub-calls to reach this InternalTransfer within the transaction. Represented as period-separated integers, e.g., “0.1.2” for the third sub-call of the second sub-call of the first top-level call.
- class eth_portfolio.structs.TokenTransfer[source]
Bases:
_LedgerEntryBase
The
TokenTransfer
class represents a token transfer event within a blockchain transaction.Captures the movement of ERC20-like tokens between addresses. These are typically emitted as events by token contracts and are not separate transactions but part of the execution of a transaction interacting with the token contract.
Example
>>> token_transfer = TokenTransfer( ... chainid=Network.Mainnet, ... block_number=Block(15537393), ... hash="0x123...", ... from_address="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", ... to_address="0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", ... value=Decimal("1000000"), # 1 USDC (assuming 6 decimals) ... log_index=3, ... token="USDC", ... token_address="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" ... ) >>> token_transfer.token 'USDC' >>> token_transfer.value Decimal('1000000') >>> token_transfer.log_index 3
- __getitem__(item)
Retrieves the value of the specified field.
- keys()
Returns an iterator over the field names of the struct.
- entry_type: ClassVar[Literal['token_transfer']] = 'token_transfer'
Constant indicating this value transfer is a token transfer entry.
- class eth_portfolio.structs.Transaction[source]
Bases:
_LedgerEntryBase
The
Transaction
class represents a complete on-chain blockchain transaction.Contains detailed information about a single executed transaction on the blockchain, including gas parameters, signature components, and transaction-specific data.
Example
>>> tx = Transaction( ... chainid=Network.Mainnet, ... block_number=Block(15537393), ... hash="0x123...", ... from_address="0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", ... to_address="0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", ... value=Decimal("0.1"), ... block_hash="0xabc...", ... nonce=42, ... type=2, # EIP-1559 transaction ... gas=21000, ... gas_price=20000000000, ... max_fee_per_gas=30000000000, ... max_priority_fee_per_gas=1000000000, ... input="0x", ... r="0x123...", ... s="0x456...", ... v=27 ... ) >>> tx.chainid Network.Mainnet >>> tx.type 2 >>> tx.max_fee_per_gas 30000000000
- __getitem__(item)
Retrieves the value of the specified field.
- keys()
Returns an iterator over the field names of the struct.
- access_list: Tuple[AccessListEntry, ...] | None
List of addresses and storage keys the transaction plans to access (for EIP-2930 and EIP-1559 transactions).
- entry_type: ClassVar[Literal['transaction']] = 'transaction'
Constant indicating this value transfer is an on-chain transaction entry.
- gas_price: int
The price per unit of gas the sender is willing to pay (for legacy and EIP-2930 transactions).
- max_fee_per_gas: int | None
The maximum total fee per gas the sender is willing to pay (for EIP-1559 transactions).
- max_priority_fee_per_gas: int | None
The maximum priority fee per gas the sender is willing to pay (for EIP-1559 transactions).
- type: int | None
The transaction type (e.g., 0 for legacy, 1 for EIP-2930, 2 for EIP-1559). None for chains that don’t specify transaction types.
- class eth_portfolio.structs._DictStruct[source]
Bases:
Struct
A base class that extends the
Struct
class to provide dictionary-like access to struct fields.Allows iteration over the fields of a struct and provides a dictionary-like interface for retrieving values by field name.
Example
>>> class MyStruct(_DictStruct): ... field1: str ... field2: int >>> s = MyStruct(field1="value", field2=42) >>> list(s.keys()) ['field1', 'field2'] >>> s['field1'] 'value'
- class eth_portfolio.structs._LE
Type variable for generic operations on ledger entries. Can be
Transaction
,InternalTransfer
, orTokenTransfer
.alias of TypeVar(‘_LE’, ~eth_portfolio.structs.Transaction, ~eth_portfolio.structs.InternalTransfer, ~eth_portfolio.structs.TokenTransfer)
- __init__(name, *constraints, bound=None, covariant=False, contravariant=False)
- class eth_portfolio.structs._LedgerEntryBase[source]
Bases:
_DictStruct
The
_LedgerEntryBase
class is a base class for ledger entries representing on-chain actions in a blockchain.Provides common attributes for transactions, internal transfers, and token transfers.
Extended by specific ledger entry types
Transaction
,InternalTransfer
, andTokenTransfer
.- __getitem__(item)
Retrieves the value of the specified field.
- keys()
Returns an iterator over the field names of the struct.
- eth_portfolio.structs.LedgerEntry
Type alias representing any type of ledger entry (
Transaction
,InternalTransfer
, orTokenTransfer
).alias of
Transaction
|InternalTransfer
|TokenTransfer
eth_portfolio.typing module
This module defines a set of classes to represent and manipulate various levels of balance structures within an Ethereum portfolio. The focus of these classes is on reading, aggregating, and summarizing balances, including the value in both tokens and their equivalent in USD.
The main classes and their purposes are as follows:
Balance
: Represents the balance of a single token, including its token amount and equivalent USD value.TokenBalances
: Manages a collection ofBalance
objects for multiple tokens, providing operations such as summing balances across tokens.RemoteTokenBalances
: ExtendsTokenBalances
to manage balances across different protocols, enabling aggregation and analysis of balances by protocol.WalletBalances
: Organizes token balances into categories such as assets, debts, and external balances for a single wallet. It combinesTokenBalances
andRemoteTokenBalances
to provide a complete view of a wallet’s balances.PortfolioBalances
: AggregatesWalletBalances
for multiple wallets, providing operations to sum balances across an entire portfolio.WalletBalancesRaw
: Similar toWalletBalances
, but with a key structure optimized for accessing balances directly by wallet and token.PortfolioBalancesByCategory
: Provides an inverted view ofPortfolioBalances
, allowing access by category first, then by wallet and token.
These classes are designed for efficient parsing, manipulation, and summarization of portfolio data, without managing or altering any underlying assets.
- class eth_portfolio.typing.Balance[source]
Bases:
_DictStruct
Represents the balance of a single token, including its token amount and equivalent USD value.
Example
>>> balance1 = Balance(Decimal('100'), Decimal('2000')) >>> balance2 = Balance(Decimal('50'), Decimal('1000')) >>> combined_balance = balance1 + balance2 >>> combined_balance.balance Decimal('150') >>> combined_balance.usd_value Decimal('3000')
- __getitem__(item)
Retrieves the value of the specified field.
- keys()
Returns an iterator over the field names of the struct.
- class eth_portfolio.typing.PortfolioBalances[source]
Bases:
DefaultChecksumDict
[WalletBalances
],_SummableNonNumericMixin
Aggregates
WalletBalances
for multiple wallets, providing operations to sum balances across an entire portfolio.The class uses wallet addresses as keys and
WalletBalances
objects as values.- Parameters:
seed – An initial seed of portfolio balances, either as a dictionary or an iterable of tuples.
Example
>>> portfolio_balances = PortfolioBalances({'0x123': WalletBalances({'assets': TokenBalances({'0x456': Balance(Decimal('100'), Decimal('2000'))})})}) >>> portfolio_balances['0x123']['assets']['0x456'].balance Decimal('100')
- __getitem__(key)
x.__getitem__(y) <==> x[y]
- Parameters:
key (AnyAddress)
- Return type:
T
- __init__(seed=None)[source]
- Parameters:
seed (Dict[str | HexBytes | AnyAddress | EthAddress, WalletBalances] | Iterable[Tuple[str | HexBytes | AnyAddress | EthAddress, WalletBalances]] | None)
- Return type:
None
- __iter__()
Implement iter(self).
- clear() None. Remove all items from D.
- copy() a shallow copy of D.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- sum_usd()[source]
Sums the USD values of all wallet balances in the portfolio.
- Returns:
The total USD value of all wallet balances in the portfolio.
- Return type:
Example
>>> portfolio_balances = PortfolioBalances({'0x123': WalletBalances({'assets': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})})}) >>> total_usd = portfolio_balances.sum_usd() >>> total_usd Decimal('2000')
- update([E, ]**F) None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values() an object providing a view on D's values
- property dataframe: DataFrame
Converts the portfolio balances into a pandas DataFrame.
- Returns:
A DataFrame representation of the portfolio balances.
- property inverted: PortfolioBalancesByCategory
Returns an inverted view of the portfolio balances, grouped by category first.
- Returns:
The inverted portfolio balances, grouped by category.
- Return type:
Example
>>> portfolio_balances = PortfolioBalances({'0x123': WalletBalances({'assets': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})})}) >>> inverted_pb = portfolio_balances.inverted >>> inverted_pb['assets']['0x123'].balance Decimal('100')
- class eth_portfolio.typing.PortfolioBalancesByCategory[source]
Bases:
DefaultDict
[Literal
[‘assets’, ‘debt’, ‘external’],WalletBalancesRaw
],_SummableNonNumericMixin
Provides an inverted view of
PortfolioBalances
, allowing access by category first, then by wallet and token.The class uses category labels as keys (assets, debt, external) and
WalletBalancesRaw
objects as values.- Parameters:
seed – An initial seed of portfolio balances by category, either as a dictionary or an iterable of tuples.
Example
>>> pb_by_category = PortfolioBalancesByCategory({'assets': WalletBalancesRaw({'0x123': TokenBalances({'0x456': Balance(Decimal('100'), Decimal('2000'))})})}) >>> pb_by_category['assets']['0x123']['0x456'].balance Decimal('100')
- __getitem__()
x.__getitem__(y) <==> x[y]
- __iter__()
Implement iter(self).
- clear() None. Remove all items from D.
- copy() a shallow copy of D.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- invert()[source]
Inverts the portfolio balances by category to group by wallet first.
- Returns:
The inverted portfolio balances, grouped by wallet first.
- Return type:
Example
>>> pb_by_category = PortfolioBalancesByCategory({'assets': WalletBalancesRaw({'0x123': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})})}) >>> inverted_pb = pb_by_category.invert() >>> inverted_pb['0x123']['assets']['0x123'].balance Decimal('100')
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- update([E, ]**F) None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values() an object providing a view on D's values
- property assets: WalletBalancesRaw
Returns the asset balances across all wallets.
- Returns:
The
WalletBalancesRaw
object representing the asset balances.- Return type:
- property debt: WalletBalancesRaw
Returns the debt balances across all wallets.
- Returns:
The
WalletBalancesRaw
object representing the debt balances.- Return type:
- class eth_portfolio.typing.RemoteTokenBalances[source]
Bases:
DefaultDict
[str
,TokenBalances
],_SummableNonNumericMixin
Manages token balances across different protocols, extending the
TokenBalances
functionality to multiple protocols.The class uses protocol labels as keys and
TokenBalances
objects as values.- Parameters:
seed – An initial seed of remote token balances, either as a dictionary or an iterable of tuples.
Example
>>> remote_balances = RemoteTokenBalances({'protocol1': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})}) >>> remote_balances['protocol1']['0x123'].balance Decimal('100')
- __getitem__()
x.__getitem__(y) <==> x[y]
- __init__(seed=None)[source]
- Parameters:
seed (Dict[str, TokenBalances] | None)
- Return type:
None
- __iter__()
Implement iter(self).
- clear() None. Remove all items from D.
- copy() a shallow copy of D.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- sum_usd()[source]
Sums the USD values of all token balances across all protocols.
- Returns:
The total USD value of all remote token balances.
- Return type:
Example
>>> remote_balances = RemoteTokenBalances({'protocol1': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})}) >>> total_usd = remote_balances.sum_usd() >>> total_usd Decimal('2000')
- update([E, ]**F) None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values() an object providing a view on D's values
- class eth_portfolio.typing.TokenBalances[source]
Bases:
DefaultChecksumDict
[Balance
],_SummableNonNumericMixin
A specialized defaultdict subclass made for holding a mapping of
token -> balance
.Manages a collection of
Balance
objects for multiple tokens, allowing for operations such as summing balances across tokens.The class uses token addresses as keys and
Balance
objects as values. It supports arithmetic operations like addition and subtraction of token balances.Token addresses are checksummed automatically when adding items to the dict, and the default value for a token not present is an empty
Balance
object.- Parameters:
seed – An initial seed of token balances, either as a dictionary or an iterable of tuples.
Example
>>> token_balances = TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))}) >>> token_balances['0x123'].balance Decimal('100')
- __getitem__(key)
x.__getitem__(y) <==> x[y]
- Parameters:
key (AnyAddress)
- Return type:
T
- __init__(seed=None)[source]
- Parameters:
seed (Dict[str | HexBytes | AnyAddress | EthAddress, Balance] | Iterable[Tuple[str | HexBytes | AnyAddress | EthAddress, Balance]] | None)
- Return type:
None
- __iter__()
Implement iter(self).
- clear() None. Remove all items from D.
- copy() a shallow copy of D.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- sum_usd()[source]
Sums the USD values of all token balances.
- Returns:
The total USD value of all token balances.
- Return type:
Example
>>> token_balances = TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))}) >>> total_usd = token_balances.sum_usd() >>> total_usd Decimal('2000')
- update([E, ]**F) None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values() an object providing a view on D's values
- class eth_portfolio.typing.WalletBalances[source]
Bases:
Dict
[Literal
[‘assets’, ‘debt’, ‘external’],TokenBalances
|RemoteTokenBalances
],_SummableNonNumericMixin
Organizes token balances into categories such as assets, debts, and external balances for a single wallet.
The class uses categories as keys (assets, debt, external) and
TokenBalances
orRemoteTokenBalances
objects as values.- Parameters:
seed – An initial seed of wallet balances, either as a dictionary or an iterable of tuples.
Example
>>> wallet_balances = WalletBalances({'assets': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})}) >>> wallet_balances['assets']['0x123'].balance Decimal('100')
- __getitem__(key)[source]
Retrieves the balance associated with the given category key.
- Parameters:
key (Literal['assets', 'debt', 'external']) – The category label (assets, debt, or external).
- Returns:
The balances associated with the category.
- Raises:
KeyError – If the key is not a valid category.
- Return type:
Example
>>> wallet_balances = WalletBalances({'assets': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})}) >>> assets_balances = wallet_balances['assets'] >>> assets_balances['0x123'].balance Decimal('100')
- __init__(seed=None)[source]
- Parameters:
seed (WalletBalances | Dict[Literal['assets', 'debt', 'external'], ~eth_portfolio.typing.TokenBalances] | ~typing.Iterable[~typing.Tuple[~typing.Literal['assets', 'debt', 'external'], ~eth_portfolio.typing.TokenBalances]] | None)
- Return type:
None
- __iter__()
Implement iter(self).
- __validateitem(key, item)
Validates that the given item is a valid balance type for the category.
- __validatekey(key)
Validates that the given key is a valid category.
Valid keys: “assets”, “debt”, “external”
- clear() None. Remove all items from D.
- copy() a shallow copy of D
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- sum_usd()[source]
Sums the USD values of the wallet’s assets, debts, and external balances.
- Returns:
The total USD value of the wallet’s net assets (assets - debt + external).
- Return type:
Example
>>> wallet_balances = WalletBalances({'assets': TokenBalances({'0x123': Balance(Decimal('100'), Decimal('2000'))})}) >>> total_usd = wallet_balances.sum_usd() >>> total_usd Decimal('2000')
- update([E, ]**F) None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values() an object providing a view on D's values
- property assets: TokenBalances
Returns the assets held by the wallet.
- Returns:
The
TokenBalances
object representing the wallet’s assets.- Return type:
- property dataframe: DataFrame
Converts the wallet balances into a pandas DataFrame.
- Returns:
A DataFrame representation of the wallet balances.
- property debt: RemoteTokenBalances
Returns the debts associated with the wallet.
- Returns:
The
RemoteTokenBalances
object representing the wallet’s debts.- Return type:
- property external: RemoteTokenBalances
Returns the external balances associated with the wallet.
- Returns:
The
RemoteTokenBalances
object representing the wallet’s external balances.- Return type:
- class eth_portfolio.typing.WalletBalancesRaw[source]
Bases:
DefaultChecksumDict
[TokenBalances
],_SummableNonNumericMixin
A structure for key pattern wallet -> token -> balance.
This class is similar to
WalletBalances
but optimized for key lookups by wallet and token directly. It managesTokenBalances
objects for multiple wallets.- Parameters:
seed – An initial seed of wallet balances, either as a dictionary or an iterable of tuples.
Example
>>> raw_balances = WalletBalancesRaw({'0x123': TokenBalances({'0x456': Balance(Decimal('100'), Decimal('2000'))})}) >>> raw_balances['0x123']['0x456'].balance Decimal('100')
- __getitem__(key)
x.__getitem__(y) <==> x[y]
- Parameters:
key (AnyAddress)
- Return type:
T
- __init__(seed=None)[source]
- Parameters:
seed (Dict[str | HexBytes | AnyAddress | EthAddress, TokenBalances] | Iterable[Tuple[str | HexBytes | AnyAddress | EthAddress, TokenBalances]] | None)
- Return type:
None
- __iter__()
Implement iter(self).
- clear() None. Remove all items from D.
- copy() a shallow copy of D.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items() a set-like object providing a view on D's items
- keys() a set-like object providing a view on D's keys
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- update([E, ]**F) None. Update D from dict/iterable E and F.
If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values() an object providing a view on D's values
Module contents
- class eth_portfolio.Portfolio[source]
Bases:
ASyncGenericBase
Used to export information about a group of
PortfolioAddress
objects.Has all attributes of a
PortfolioAddress
.All calls to function(*args, **kwargs) will return {address: PortfolioAddress(Address).function(*args, **kwargs)}
- __getitem__(key)[source]
Get a
PortfolioAddress
by its key.- Parameters:
key (str | HexBytes | AnyAddress | EthAddress) – The address key.
- Returns:
The
PortfolioAddress
object.- Return type:
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> address = portfolio["0xAddress1"] >>> print(address)
- __init__(addresses, start_block=0, label='your portfolio', load_prices=True, asynchronous=False)[source]
Initialize a Portfolio instance.
- Parameters:
addresses (str | HexBytes | AnyAddress | EthAddress | Iterable[str | HexBytes | AnyAddress | EthAddress]) – The addresses to include in the portfolio.
start_block (int)
label (str)
load_prices (bool)
asynchronous (bool)
- Return type:
None
Examples
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> print(portfolio)
- __iter__()[source]
Iterate over the
PortfolioAddress
objects.- Returns:
An iterator over
PortfolioAddress
objects.- Return type:
Iterator[PortfolioAddress]
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> for address in portfolio: ... print(address)
- _start_block
The starting block number. Defaults to 0.
- addresses
A container for the
Portfolio
’sPortfolioAddress
objects.- Type:
PortfolioWallets
Works like a
Dict[Address, PortfolioAddress]
except you get the values when you iterate instead of the keys.
- describe[source]
Returns a full snapshot of your portfolio at a given block.
- Parameters:
block (int) – The block number.
- Returns:
A snapshot of the portfolio balances.
- Return type:
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> balances = await portfolio.describe(block=1200000) >>> print(balances)
- property internal_transfers: PortfolioInternalTransfersLedger
A container for all internal transfers to or from any of your
PortfolioAddress
.- Returns:
The
PortfolioInternalTransfersLedger
object.- Return type:
PortfolioInternalTransfersLedger
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> internal_transfers = portfolio.internal_transfers >>> print(internal_transfers)
- label
A label for the portfolio. Defaults to “your portfolio”
- ledger
A container for all of your fun taxable events.
- Type:
PortfolioLedger
- property token_transfers: PortfolioTokenTransfersLedger
A container for all token transfers to or from any of your
PortfolioAddress
.- Returns:
The
PortfolioTokenTransfersLedger
object.- Return type:
PortfolioTokenTransfersLedger
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> token_transfers = portfolio.token_transfers >>> print(token_transfers)
- property transactions: PortfolioTransactionsLedger
A container for all transactions to or from any of your
PortfolioAddress
.- Returns:
The
PortfolioTransactionsLedger
object.- Return type:
PortfolioTransactionsLedger
Example
>>> portfolio = Portfolio(addresses=["0xAddress1", "0xAddress2"]) >>> transactions = portfolio.transactions >>> print(transactions)