eth-portfolio-temp 0.2.14__cp313-cp313-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- eth_portfolio/__init__.py +25 -0
- eth_portfolio/_argspec.cp313-win_amd64.pyd +0 -0
- eth_portfolio/_argspec.py +42 -0
- eth_portfolio/_cache.py +121 -0
- eth_portfolio/_config.cp313-win_amd64.pyd +0 -0
- eth_portfolio/_config.py +4 -0
- eth_portfolio/_db/__init__.py +0 -0
- eth_portfolio/_db/decorators.py +147 -0
- eth_portfolio/_db/entities.py +311 -0
- eth_portfolio/_db/utils.py +604 -0
- eth_portfolio/_decimal.py +156 -0
- eth_portfolio/_decorators.py +84 -0
- eth_portfolio/_exceptions.py +67 -0
- eth_portfolio/_ledgers/__init__.py +0 -0
- eth_portfolio/_ledgers/address.py +938 -0
- eth_portfolio/_ledgers/portfolio.py +327 -0
- eth_portfolio/_loaders/__init__.py +33 -0
- eth_portfolio/_loaders/_nonce.cp313-win_amd64.pyd +0 -0
- eth_portfolio/_loaders/_nonce.py +196 -0
- eth_portfolio/_loaders/balances.cp313-win_amd64.pyd +0 -0
- eth_portfolio/_loaders/balances.py +94 -0
- eth_portfolio/_loaders/token_transfer.py +217 -0
- eth_portfolio/_loaders/transaction.py +240 -0
- eth_portfolio/_loaders/utils.cp313-win_amd64.pyd +0 -0
- eth_portfolio/_loaders/utils.py +68 -0
- eth_portfolio/_shitcoins.cp313-win_amd64.pyd +0 -0
- eth_portfolio/_shitcoins.py +329 -0
- eth_portfolio/_stableish.cp313-win_amd64.pyd +0 -0
- eth_portfolio/_stableish.py +42 -0
- eth_portfolio/_submodules.py +73 -0
- eth_portfolio/_utils.py +225 -0
- eth_portfolio/_ydb/__init__.py +0 -0
- eth_portfolio/_ydb/token_transfers.py +145 -0
- eth_portfolio/address.py +397 -0
- eth_portfolio/buckets.py +194 -0
- eth_portfolio/constants.cp313-win_amd64.pyd +0 -0
- eth_portfolio/constants.py +82 -0
- eth_portfolio/portfolio.py +661 -0
- eth_portfolio/protocols/__init__.py +67 -0
- eth_portfolio/protocols/_base.py +108 -0
- eth_portfolio/protocols/convex.py +17 -0
- eth_portfolio/protocols/dsr.py +51 -0
- eth_portfolio/protocols/lending/README.md +6 -0
- eth_portfolio/protocols/lending/__init__.py +50 -0
- eth_portfolio/protocols/lending/_base.py +57 -0
- eth_portfolio/protocols/lending/compound.py +187 -0
- eth_portfolio/protocols/lending/liquity.py +110 -0
- eth_portfolio/protocols/lending/maker.py +104 -0
- eth_portfolio/protocols/lending/unit.py +46 -0
- eth_portfolio/protocols/liquity.py +16 -0
- eth_portfolio/py.typed +0 -0
- eth_portfolio/structs/__init__.py +43 -0
- eth_portfolio/structs/modified.py +69 -0
- eth_portfolio/structs/structs.py +637 -0
- eth_portfolio/typing/__init__.py +1447 -0
- eth_portfolio/typing/balance/single.py +176 -0
- eth_portfolio__mypyc.cp313-win_amd64.pyd +0 -0
- eth_portfolio_scripts/__init__.py +20 -0
- eth_portfolio_scripts/_args.py +26 -0
- eth_portfolio_scripts/_logging.py +15 -0
- eth_portfolio_scripts/_portfolio.py +194 -0
- eth_portfolio_scripts/_utils.py +106 -0
- eth_portfolio_scripts/balances.cp313-win_amd64.pyd +0 -0
- eth_portfolio_scripts/balances.py +52 -0
- eth_portfolio_scripts/docker/.grafana/dashboards/Portfolio/Balances.json +1962 -0
- eth_portfolio_scripts/docker/.grafana/dashboards/dashboards.yaml +10 -0
- eth_portfolio_scripts/docker/.grafana/datasources/datasources.yml +11 -0
- eth_portfolio_scripts/docker/__init__.cp313-win_amd64.pyd +0 -0
- eth_portfolio_scripts/docker/__init__.py +16 -0
- eth_portfolio_scripts/docker/check.cp313-win_amd64.pyd +0 -0
- eth_portfolio_scripts/docker/check.py +67 -0
- eth_portfolio_scripts/docker/docker-compose.yaml +61 -0
- eth_portfolio_scripts/docker/docker_compose.cp313-win_amd64.pyd +0 -0
- eth_portfolio_scripts/docker/docker_compose.py +81 -0
- eth_portfolio_scripts/main.py +119 -0
- eth_portfolio_scripts/py.typed +1 -0
- eth_portfolio_scripts/victoria/__init__.py +73 -0
- eth_portfolio_scripts/victoria/types.py +38 -0
- eth_portfolio_temp-0.2.14.dist-info/METADATA +26 -0
- eth_portfolio_temp-0.2.14.dist-info/RECORD +83 -0
- eth_portfolio_temp-0.2.14.dist-info/WHEEL +5 -0
- eth_portfolio_temp-0.2.14.dist-info/entry_points.txt +2 -0
- eth_portfolio_temp-0.2.14.dist-info/top_level.txt +3 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from asyncio import gather
|
|
2
|
+
from typing import Final, List, Optional
|
|
3
|
+
|
|
4
|
+
from a_sync import igather
|
|
5
|
+
from brownie import ZERO_ADDRESS
|
|
6
|
+
from dank_mids.exceptions import Revert
|
|
7
|
+
from eth_typing import HexStr
|
|
8
|
+
from faster_async_lru import alru_cache
|
|
9
|
+
from faster_eth_abi import encode
|
|
10
|
+
from y import Contract, Network, contract_creation_block_async, get_price
|
|
11
|
+
from y._decorators import stuck_coro_debugger
|
|
12
|
+
from y.constants import dai
|
|
13
|
+
from y.datatypes import Address, Block
|
|
14
|
+
|
|
15
|
+
from eth_portfolio._utils import Decimal
|
|
16
|
+
from eth_portfolio.protocols.lending._base import LendingProtocolWithLockedCollateral
|
|
17
|
+
from eth_portfolio.typing import Balance, TokenBalances
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
yfi: Final = "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e"
|
|
21
|
+
dai: Contract
|
|
22
|
+
_1e18: Final = Decimal(10**18)
|
|
23
|
+
_1e45: Final = Decimal(10**45)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def encode_bytes(bytestring: str) -> bytes:
|
|
27
|
+
return encode(["bytes32"], [bytestring])
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Maker(LendingProtocolWithLockedCollateral):
|
|
31
|
+
networks = [Network.Mainnet]
|
|
32
|
+
|
|
33
|
+
def __init__(self) -> None:
|
|
34
|
+
self.proxy_registry = Contract("0x4678f0a6958e4D2Bc4F1BAF7Bc52E8F3564f3fE4")
|
|
35
|
+
self.cdp_manager = Contract("0x5ef30b9986345249bc32d8928B7ee64DE9435E39")
|
|
36
|
+
self.ilk_registry = Contract("0x5a464C28D19848f44199D003BeF5ecc87d090F87")
|
|
37
|
+
self.vat = Contract("0x35D1b3F3D7966A1DFe207aa4514C12a259A0492B")
|
|
38
|
+
|
|
39
|
+
@stuck_coro_debugger
|
|
40
|
+
async def _balances(self, address: Address, block: Optional[Block] = None) -> TokenBalances:
|
|
41
|
+
ilks, urn = await gather(self.get_ilks(block), self._urn(address))
|
|
42
|
+
|
|
43
|
+
gem_coros = igather(map(self.get_gem, map(str, ilks)))
|
|
44
|
+
ink_coros = igather(
|
|
45
|
+
self.vat.urns.coroutine(ilk, urn, block_identifier=block) for ilk in ilks
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
gems, ink_data = await gather(gem_coros, ink_coros)
|
|
49
|
+
|
|
50
|
+
balances: TokenBalances = TokenBalances(block=block)
|
|
51
|
+
for token, data in zip(gems, ink_data):
|
|
52
|
+
if token != ZERO_ADDRESS and (ink := data.dict()["ink"]):
|
|
53
|
+
balance = ink / _1e18
|
|
54
|
+
value = round(balance * Decimal(await get_price(token, block, sync=False)), 18)
|
|
55
|
+
balances[token] = Balance(balance, value, token=token, block=block)
|
|
56
|
+
return balances
|
|
57
|
+
|
|
58
|
+
@stuck_coro_debugger
|
|
59
|
+
async def _debt(self, address: Address, block: Optional[int] = None) -> TokenBalances:
|
|
60
|
+
if block is not None and block <= await contract_creation_block_async(self.ilk_registry):
|
|
61
|
+
return TokenBalances(block=block)
|
|
62
|
+
|
|
63
|
+
ilks, urn = await gather(self.get_ilks(block), self._urn(address))
|
|
64
|
+
|
|
65
|
+
data = await igather(
|
|
66
|
+
gather(
|
|
67
|
+
self.vat.urns.coroutine(ilk, urn, block_identifier=block),
|
|
68
|
+
self.vat.ilks.coroutine(ilk, block_identifier=block),
|
|
69
|
+
)
|
|
70
|
+
for ilk in ilks
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
balances: TokenBalances = TokenBalances(block=block)
|
|
74
|
+
for urns, ilk_info in data:
|
|
75
|
+
art = urns.dict()["art"]
|
|
76
|
+
rate = ilk_info.dict()["rate"]
|
|
77
|
+
debt = art * rate / _1e45
|
|
78
|
+
balances[dai.address] += Balance(debt, debt, token=dai, block=block)
|
|
79
|
+
return balances
|
|
80
|
+
|
|
81
|
+
async def get_ilks(self, block: Optional[int]) -> List[HexStr]:
|
|
82
|
+
"""List all ilks (cdp keys of sorts) for MakerDAO"""
|
|
83
|
+
try:
|
|
84
|
+
return await self.ilk_registry.list.coroutine(block_identifier=block)
|
|
85
|
+
except Revert:
|
|
86
|
+
return []
|
|
87
|
+
|
|
88
|
+
@alru_cache
|
|
89
|
+
async def get_gem(self, ilk: bytes) -> str:
|
|
90
|
+
return await self.ilk_registry.gem.coroutine(ilk)
|
|
91
|
+
|
|
92
|
+
@alru_cache
|
|
93
|
+
async def _proxy(self, address: Address) -> Address:
|
|
94
|
+
return await self.proxy_registry.proxies.coroutine(address)
|
|
95
|
+
|
|
96
|
+
@alru_cache
|
|
97
|
+
async def _cdp(self, address: Address) -> Address:
|
|
98
|
+
proxy = await self._proxy(address)
|
|
99
|
+
return await self.cdp_manager.first.coroutine(proxy)
|
|
100
|
+
|
|
101
|
+
@alru_cache
|
|
102
|
+
async def _urn(self, address: Address) -> Address:
|
|
103
|
+
cdp = await self._cdp(address)
|
|
104
|
+
return await self.cdp_manager.urns.coroutine(cdp)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
from typing import Optional
|
|
2
|
+
|
|
3
|
+
from y import Contract, Network
|
|
4
|
+
from y._decorators import stuck_coro_debugger
|
|
5
|
+
from y.datatypes import Address, Block
|
|
6
|
+
|
|
7
|
+
from eth_portfolio._decimal import Decimal
|
|
8
|
+
from eth_portfolio._utils import _get_price
|
|
9
|
+
from eth_portfolio.protocols.lending._base import LendingProtocolWithLockedCollateral
|
|
10
|
+
from eth_portfolio.typing import Balance, TokenBalances
|
|
11
|
+
|
|
12
|
+
# NOTE: This only works for YFI collateral, must extend before using for other collaterals
|
|
13
|
+
yfi = "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e"
|
|
14
|
+
usdp = "0x1456688345527bE1f37E9e627DA0837D6f08C925"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class UnitXyz(LendingProtocolWithLockedCollateral):
|
|
18
|
+
networks = [Network.Mainnet]
|
|
19
|
+
|
|
20
|
+
def __init__(self) -> None:
|
|
21
|
+
self.unitVault = Contract("0xb1cff81b9305166ff1efc49a129ad2afcd7bcf19")
|
|
22
|
+
self.start_block = 11315910
|
|
23
|
+
|
|
24
|
+
@stuck_coro_debugger
|
|
25
|
+
async def _balances(self, address: Address, block: Optional[Block] = None) -> TokenBalances:
|
|
26
|
+
balances: TokenBalances = TokenBalances(block=block)
|
|
27
|
+
if block and block < self.start_block:
|
|
28
|
+
return balances
|
|
29
|
+
bal: int = await self.unitVault.collaterals.coroutine(yfi, address, block_identifier=block)
|
|
30
|
+
if bal:
|
|
31
|
+
bal = Decimal(bal) / 10**18
|
|
32
|
+
balances[yfi] = Balance(bal, bal * await _get_price(yfi, block), token=yfi, block=block)
|
|
33
|
+
return balances
|
|
34
|
+
|
|
35
|
+
@stuck_coro_debugger
|
|
36
|
+
async def _debt(self, address: Address, block: Optional[Block] = None) -> TokenBalances:
|
|
37
|
+
balances: TokenBalances = TokenBalances(block=block)
|
|
38
|
+
if block and block < self.start_block:
|
|
39
|
+
return balances
|
|
40
|
+
# NOTE: This only works for YFI based debt, must extend before using for other collaterals
|
|
41
|
+
if debt := await self.unitVault.getTotalDebt.coroutine(
|
|
42
|
+
yfi, address, block_identifier=block
|
|
43
|
+
):
|
|
44
|
+
debt = Decimal(debt) / 10**18
|
|
45
|
+
balances[usdp] = Balance(debt, debt, token=usdp, block=block)
|
|
46
|
+
return balances
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from eth_portfolio.protocols._base import SingleTokenStakingPoolABC
|
|
2
|
+
from y import ERC20, Network
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LqtyStakingPool(SingleTokenStakingPoolABC):
|
|
6
|
+
networks = [Network.Mainnet]
|
|
7
|
+
contract_address = "0x4f9Fbb3f1E99B56e0Fe2892e623Ed36A76Fc605d"
|
|
8
|
+
balance_method_name = "stakes"
|
|
9
|
+
token = ERC20("0x6DEA81C8171D0bA574754EF6F8b412F2Ed88c54D") # LQTY
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class LiquityStabilityPool(SingleTokenStakingPoolABC):
|
|
13
|
+
networks = [Network.Mainnet]
|
|
14
|
+
contract_address = "0x66017D22b0f8556afDd19FC67041899Eb65a21bb"
|
|
15
|
+
balance_method_name = "getCompoundedLUSDDeposit"
|
|
16
|
+
token = ERC20("0x5f98805A4E8be255a32880FDeC7F6728C6568bA0") # LUSD
|
eth_portfolio/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module provides the primary union type and specific ledger entry types used in the `eth_portfolio` package.
|
|
3
|
+
|
|
4
|
+
The `__all__` list defines the public API for this module, which includes the main union type `LedgerEntry` and its specific types: `Transaction`, `InternalTransfer`, `TokenTransfer`, and `TransactionRLP`.
|
|
5
|
+
|
|
6
|
+
Examples:
|
|
7
|
+
Importing the main union type and specific ledger entry types:
|
|
8
|
+
|
|
9
|
+
>>> from eth_portfolio.structs import LedgerEntry, Transaction, InternalTransfer, TokenTransfer, TransactionRLP
|
|
10
|
+
|
|
11
|
+
Using the `LedgerEntry` union type to annotate a variable that can hold any ledger entry type:
|
|
12
|
+
|
|
13
|
+
>>> entry: LedgerEntry = Transaction(...)
|
|
14
|
+
>>> entry = InternalTransfer(...)
|
|
15
|
+
>>> entry = TokenTransfer(...)
|
|
16
|
+
>>> entry = TransactionRLP(...)
|
|
17
|
+
|
|
18
|
+
See Also:
|
|
19
|
+
- :class:`~eth_portfolio.structs.structs.LedgerEntry`
|
|
20
|
+
- :class:`~eth_portfolio.structs.structs.Transaction`
|
|
21
|
+
- :class:`~eth_portfolio.structs.structs.InternalTransfer`
|
|
22
|
+
- :class:`~eth_portfolio.structs.structs.TokenTransfer`
|
|
23
|
+
- :class:`~eth_portfolio.structs.structs.TransactionRLP`
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
from eth_portfolio.structs.structs import (
|
|
27
|
+
InternalTransfer,
|
|
28
|
+
LedgerEntry,
|
|
29
|
+
TokenTransfer,
|
|
30
|
+
Transaction,
|
|
31
|
+
TransactionRLP,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
__all__ = [
|
|
35
|
+
# main union type
|
|
36
|
+
"LedgerEntry",
|
|
37
|
+
# LedgerEntry types
|
|
38
|
+
"Transaction",
|
|
39
|
+
"InternalTransfer",
|
|
40
|
+
"TokenTransfer",
|
|
41
|
+
# TODO figure out how to get rid of this
|
|
42
|
+
"TransactionRLP",
|
|
43
|
+
]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
|
|
3
|
+
from evmspec.structs.trace import call, create, reward, suicide
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CallTrace(
|
|
7
|
+
call.Trace,
|
|
8
|
+
frozen=True,
|
|
9
|
+
kw_only=True,
|
|
10
|
+
array_like=True,
|
|
11
|
+
forbid_unknown_fields=True,
|
|
12
|
+
omit_defaults=True,
|
|
13
|
+
repr_omit_defaults=True,
|
|
14
|
+
): # type: ignore [call-arg]
|
|
15
|
+
"""
|
|
16
|
+
It works just like a :class:`evmspec.trace.call.Trace` but it encodes to a tuple instead of a dict to save space since keys are known.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CreateTrace(
|
|
21
|
+
create.Trace,
|
|
22
|
+
frozen=True,
|
|
23
|
+
kw_only=True,
|
|
24
|
+
array_like=True,
|
|
25
|
+
forbid_unknown_fields=True,
|
|
26
|
+
omit_defaults=True,
|
|
27
|
+
repr_omit_defaults=True,
|
|
28
|
+
): # type: ignore [call-arg]
|
|
29
|
+
"""
|
|
30
|
+
It works just like a :class:`evmspec.trace.create.Trace` but it encodes to a tuple instead of a dict to save space since keys are known.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class RewardTrace(
|
|
35
|
+
reward.Trace,
|
|
36
|
+
frozen=True,
|
|
37
|
+
kw_only=True,
|
|
38
|
+
array_like=True,
|
|
39
|
+
forbid_unknown_fields=True,
|
|
40
|
+
omit_defaults=True,
|
|
41
|
+
repr_omit_defaults=True,
|
|
42
|
+
): # type: ignore [call-arg]
|
|
43
|
+
"""
|
|
44
|
+
It works just like a :class:`evmspec.trace.reward.Trace` but it encodes to a tuple instead of a dict to save space since keys are known.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class SuicideTrace(
|
|
49
|
+
suicide.Trace,
|
|
50
|
+
frozen=True,
|
|
51
|
+
kw_only=True,
|
|
52
|
+
array_like=True,
|
|
53
|
+
forbid_unknown_fields=True,
|
|
54
|
+
omit_defaults=True,
|
|
55
|
+
repr_omit_defaults=True,
|
|
56
|
+
): # type: ignore [call-arg]
|
|
57
|
+
"""
|
|
58
|
+
It works just like a :class:`evmspec.trace.suicide.Trace` but it encodes to a tuple instead of a dict to save space since keys are known.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
_modified_trace_type_map = {
|
|
63
|
+
call.Trace: CallTrace,
|
|
64
|
+
create.Trace: CreateTrace,
|
|
65
|
+
reward.Trace: RewardTrace,
|
|
66
|
+
suicide.Trace: SuicideTrace,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
ModifiedTrace = Union[CallTrace, CreateTrace, RewardTrace, SuicideTrace]
|