eth-portfolio-temp 0.2.16__cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.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.cpython-312-i386-linux-gnu.so +0 -0
- eth_portfolio/_argspec.py +42 -0
- eth_portfolio/_cache.py +121 -0
- eth_portfolio/_config.cpython-312-i386-linux-gnu.so +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.cpython-312-i386-linux-gnu.so +0 -0
- eth_portfolio/_loaders/_nonce.py +196 -0
- eth_portfolio/_loaders/balances.cpython-312-i386-linux-gnu.so +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.cpython-312-i386-linux-gnu.so +0 -0
- eth_portfolio/_loaders/utils.py +68 -0
- eth_portfolio/_shitcoins.cpython-312-i386-linux-gnu.so +0 -0
- eth_portfolio/_shitcoins.py +330 -0
- eth_portfolio/_stableish.cpython-312-i386-linux-gnu.so +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.cpython-312-i386-linux-gnu.so +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.cpython-312-i386-linux-gnu.so +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.cpython-312-i386-linux-gnu.so +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__.cpython-312-i386-linux-gnu.so +0 -0
- eth_portfolio_scripts/docker/__init__.py +16 -0
- eth_portfolio_scripts/docker/check.cpython-312-i386-linux-gnu.so +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.cpython-312-i386-linux-gnu.so +0 -0
- eth_portfolio_scripts/docker/docker_compose.py +96 -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.16.dist-info/METADATA +26 -0
- eth_portfolio_temp-0.2.16.dist-info/RECORD +83 -0
- eth_portfolio_temp-0.2.16.dist-info/WHEEL +7 -0
- eth_portfolio_temp-0.2.16.dist-info/entry_points.txt +2 -0
- eth_portfolio_temp-0.2.16.dist-info/top_level.txt +3 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import decimal
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Union
|
|
4
|
+
|
|
5
|
+
from evmspec.data import Wei
|
|
6
|
+
from typing_extensions import Self
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
# we need to enlarge the precision for Decimal objects so we don't get errors when doing math
|
|
12
|
+
decimal.getcontext().prec = 100
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class Decimal(decimal.Decimal):
|
|
16
|
+
"""
|
|
17
|
+
A subclass of :class:`decimal.Decimal` with additional functionality for JSON serialization.
|
|
18
|
+
|
|
19
|
+
This class extends the :class:`decimal.Decimal` class to provide an additional
|
|
20
|
+
method for JSON serialization. It also overrides arithmetic operations to ensure
|
|
21
|
+
that the result is of type :class:`Decimal`.
|
|
22
|
+
|
|
23
|
+
See Also:
|
|
24
|
+
- :class:`decimal.Decimal`
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def jsonify(self) -> Union[str, int]:
|
|
28
|
+
"""
|
|
29
|
+
Converts the :class:`Decimal` to a JSON-friendly format.
|
|
30
|
+
|
|
31
|
+
This method attempts to represent the :class:`Decimal` in the most compact form
|
|
32
|
+
possible for JSON serialization. It returns an integer if the :class:`Decimal`
|
|
33
|
+
is exactly equal to an integer, otherwise it returns a string in either
|
|
34
|
+
standard or scientific notation, depending on which is shorter.
|
|
35
|
+
|
|
36
|
+
If the integer representation is exactly equal to the :class:`Decimal`,
|
|
37
|
+
the integer is returned. Otherwise, the method returns the shorter of the
|
|
38
|
+
standard string representation or the scientific notation.
|
|
39
|
+
|
|
40
|
+
Examples:
|
|
41
|
+
>>> Decimal('123.4500').jsonify()
|
|
42
|
+
'123.45'
|
|
43
|
+
>>> Decimal('123000').jsonify()
|
|
44
|
+
123000
|
|
45
|
+
>>> Decimal('0.000123').jsonify()
|
|
46
|
+
'1.23E-4'
|
|
47
|
+
>>> Decimal('1000000').jsonify()
|
|
48
|
+
1000000
|
|
49
|
+
"""
|
|
50
|
+
string = str(self)
|
|
51
|
+
integer = int(self)
|
|
52
|
+
|
|
53
|
+
if integer == self:
|
|
54
|
+
scientific_notation = "%E" % self
|
|
55
|
+
return (
|
|
56
|
+
integer
|
|
57
|
+
if len(str(integer)) <= len(scientific_notation) + 2
|
|
58
|
+
else scientific_notation
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
if "E" in string:
|
|
62
|
+
return string
|
|
63
|
+
|
|
64
|
+
scientific_notation = "%E" % self
|
|
65
|
+
while string[-1] == "0":
|
|
66
|
+
string = string[:-1]
|
|
67
|
+
|
|
68
|
+
if type(self)(scientific_notation) == self and len(scientific_notation) < len(string):
|
|
69
|
+
return scientific_notation
|
|
70
|
+
|
|
71
|
+
return string
|
|
72
|
+
|
|
73
|
+
def __add__(self, other) -> Self:
|
|
74
|
+
try:
|
|
75
|
+
return type(self)(super().__add__(other))
|
|
76
|
+
except TypeError as e:
|
|
77
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
78
|
+
|
|
79
|
+
def __radd__(self, other) -> Self:
|
|
80
|
+
try:
|
|
81
|
+
return type(self)(super().__radd__(other))
|
|
82
|
+
except TypeError as e:
|
|
83
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
84
|
+
|
|
85
|
+
def __sub__(self, other) -> Self:
|
|
86
|
+
try:
|
|
87
|
+
return type(self)(super().__sub__(other))
|
|
88
|
+
except TypeError as e:
|
|
89
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
90
|
+
|
|
91
|
+
def __rsub__(self, other) -> Self:
|
|
92
|
+
try:
|
|
93
|
+
return type(self)(super().__rsub__(other))
|
|
94
|
+
except TypeError as e:
|
|
95
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
96
|
+
|
|
97
|
+
def __mul__(self, other) -> Self:
|
|
98
|
+
try:
|
|
99
|
+
return type(self)(super().__mul__(other))
|
|
100
|
+
except TypeError as e:
|
|
101
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
102
|
+
|
|
103
|
+
def __rmul__(self, other) -> Self:
|
|
104
|
+
try:
|
|
105
|
+
return type(self)(super().__rmul__(other))
|
|
106
|
+
except TypeError as e:
|
|
107
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
108
|
+
|
|
109
|
+
def __truediv__(self, other) -> Self:
|
|
110
|
+
try:
|
|
111
|
+
return type(self)(super().__truediv__(other))
|
|
112
|
+
except TypeError as e:
|
|
113
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
114
|
+
|
|
115
|
+
def __rtruediv__(self, other) -> Self:
|
|
116
|
+
try:
|
|
117
|
+
return type(self)(super().__rtruediv__(other))
|
|
118
|
+
except TypeError as e:
|
|
119
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
120
|
+
|
|
121
|
+
def __floordiv__(self, other) -> Self:
|
|
122
|
+
try:
|
|
123
|
+
return type(self)(super().__floordiv__(other))
|
|
124
|
+
except TypeError as e:
|
|
125
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
126
|
+
|
|
127
|
+
def __rfloordiv__(self, other) -> Self:
|
|
128
|
+
try:
|
|
129
|
+
return type(self)(super().__rfloordiv__(other))
|
|
130
|
+
except TypeError as e:
|
|
131
|
+
raise TypeError(str(e), other) from e.__cause__
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class Gwei(Decimal):
|
|
135
|
+
"""
|
|
136
|
+
A subclass of :class:`Decimal` representing Gwei values.
|
|
137
|
+
|
|
138
|
+
This class provides a property to convert Gwei to Wei.
|
|
139
|
+
|
|
140
|
+
See Also:
|
|
141
|
+
- :class:`Decimal`
|
|
142
|
+
- :class:`evmspec.data.Wei`
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
@property
|
|
146
|
+
def as_wei(self) -> Wei:
|
|
147
|
+
"""
|
|
148
|
+
Converts the Gwei value to Wei.
|
|
149
|
+
|
|
150
|
+
This property multiplies the Gwei value by 10^9 to convert it to Wei.
|
|
151
|
+
|
|
152
|
+
Examples:
|
|
153
|
+
>>> Gwei('1').as_wei
|
|
154
|
+
Wei(1000000000)
|
|
155
|
+
"""
|
|
156
|
+
return Wei(self * 10**9)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from asyncio import iscoroutinefunction
|
|
3
|
+
from functools import wraps
|
|
4
|
+
from inspect import isasyncgenfunction
|
|
5
|
+
from typing import AsyncIterator, Callable, Optional, overload
|
|
6
|
+
|
|
7
|
+
from a_sync.iter import ASyncGeneratorFunction
|
|
8
|
+
from brownie import chain
|
|
9
|
+
from typing_extensions import Concatenate
|
|
10
|
+
from y.datatypes import Block
|
|
11
|
+
|
|
12
|
+
from eth_portfolio import _config
|
|
13
|
+
from eth_portfolio._utils import get_buffered_chain_height
|
|
14
|
+
from eth_portfolio.typing import _I, _P, _T
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@overload
|
|
20
|
+
def set_end_block_if_none(
|
|
21
|
+
func: Callable[Concatenate[_I, Block, Block, _P], AsyncIterator[_T]],
|
|
22
|
+
) -> Callable[Concatenate[_I, Block, Optional[Block], _P], AsyncIterator[_T]]: ...
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@overload
|
|
26
|
+
def set_end_block_if_none(
|
|
27
|
+
func: Callable[Concatenate[_I, Block, Block, _P], _T],
|
|
28
|
+
) -> Callable[Concatenate[_I, Block, Optional[Block], _P], _T]: ...
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def set_end_block_if_none(
|
|
32
|
+
func: Callable[Concatenate[_I, Block, Block, _P], _T],
|
|
33
|
+
) -> Callable[Concatenate[_I, Block, Optional[Block], _P], _T]:
|
|
34
|
+
"""
|
|
35
|
+
Used to set `end_block` = `chain.height - _config.REORG_BUFFER` if `end_block` is None.
|
|
36
|
+
Only works with a class function that takes args (self, start_block, end_block, *args, **kwargs).
|
|
37
|
+
"""
|
|
38
|
+
if isasyncgenfunction(func) or isinstance(func, ASyncGeneratorFunction):
|
|
39
|
+
|
|
40
|
+
@wraps(func) # type: ignore [arg-type]
|
|
41
|
+
async def wrap(
|
|
42
|
+
obj: _I,
|
|
43
|
+
start_block: Block,
|
|
44
|
+
end_block: Optional[Block],
|
|
45
|
+
*args: _P.args,
|
|
46
|
+
**kwargs: _P.kwargs,
|
|
47
|
+
) -> AsyncIterator[_T]:
|
|
48
|
+
if end_block is None:
|
|
49
|
+
end_block = await get_buffered_chain_height()
|
|
50
|
+
logger.debug("end_block not provided, using %s", end_block)
|
|
51
|
+
async for thing in func(obj, start_block, end_block, *args, **kwargs):
|
|
52
|
+
yield thing
|
|
53
|
+
|
|
54
|
+
elif iscoroutinefunction(func):
|
|
55
|
+
|
|
56
|
+
@wraps(func)
|
|
57
|
+
async def wrap(
|
|
58
|
+
obj: _I,
|
|
59
|
+
start_block: Block,
|
|
60
|
+
end_block: Block,
|
|
61
|
+
*args: _P.args,
|
|
62
|
+
**kwargs: _P.kwargs,
|
|
63
|
+
) -> _T:
|
|
64
|
+
if end_block is None:
|
|
65
|
+
end_block = await get_buffered_chain_height()
|
|
66
|
+
logger.debug("end_block not provided, using %s", end_block)
|
|
67
|
+
return await func(obj, start_block, end_block, *args, **kwargs)
|
|
68
|
+
|
|
69
|
+
else:
|
|
70
|
+
|
|
71
|
+
@wraps(func)
|
|
72
|
+
def wrap(
|
|
73
|
+
obj: _I,
|
|
74
|
+
start_block: Block,
|
|
75
|
+
end_block: Block,
|
|
76
|
+
*args: _P.args,
|
|
77
|
+
**kwargs: _P.kwargs,
|
|
78
|
+
) -> _T:
|
|
79
|
+
if end_block is None:
|
|
80
|
+
end_block = chain.height - _config.REORG_BUFFER
|
|
81
|
+
logger.debug("end_block not provided, using %s", end_block)
|
|
82
|
+
return func(obj, start_block, end_block, *args, **kwargs)
|
|
83
|
+
|
|
84
|
+
return wrap
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from asyncio import gather
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from y.datatypes import Block
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from eth_portfolio._ledgers.address import AddressLedgerBase
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class BlockRangeIsCached(Exception):
|
|
11
|
+
"""
|
|
12
|
+
Exception raised when a block range is already cached.
|
|
13
|
+
|
|
14
|
+
This exception indicates that the requested block range
|
|
15
|
+
has already been loaded into memory and does not need to be fetched again.
|
|
16
|
+
|
|
17
|
+
Examples:
|
|
18
|
+
>>> raise BlockRangeIsCached("Block range is already cached.")
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BlockRangeOutOfBounds(Exception):
|
|
25
|
+
"""
|
|
26
|
+
Exception raised when a block range is out of bounds.
|
|
27
|
+
|
|
28
|
+
This exception indicates that the requested block range
|
|
29
|
+
is outside the bounds of the cached data. It provides a method to
|
|
30
|
+
handle the loading of the remaining ledger entries that are out of bounds
|
|
31
|
+
by invoking the appropriate method in the associated ledger.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
start_block: The starting block number of the out-of-bounds range.
|
|
35
|
+
end_block: The ending block number of the out-of-bounds range.
|
|
36
|
+
ledger: The ledger associated with the block range.
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
>>> raise BlockRangeOutOfBounds(100, 200, ledger)
|
|
40
|
+
|
|
41
|
+
See Also:
|
|
42
|
+
- :class:`~eth_portfolio._ledgers.address.AddressLedgerBase`: The base class for address ledgers.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def __init__(self, start_block: Block, end_block: Block, ledger: "AddressLedgerBase") -> None:
|
|
46
|
+
self.ledger = ledger
|
|
47
|
+
self.start_block = start_block
|
|
48
|
+
self.end_block = end_block
|
|
49
|
+
|
|
50
|
+
async def load_remaining(self) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Asynchronously handles the loading of the remaining ledger entries that are out of bounds.
|
|
53
|
+
|
|
54
|
+
This method invokes the :meth:`~eth_portfolio._ledgers.address.AddressLedgerBase._load_new_objects`
|
|
55
|
+
method of the associated ledger to fetch the ledger entries for the blocks that are outside
|
|
56
|
+
the cached range, ensuring that the entire requested block range is covered.
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
>>> await exception.load_remaining()
|
|
60
|
+
|
|
61
|
+
See Also:
|
|
62
|
+
- :meth:`~eth_portfolio._ledgers.address.AddressLedgerBase._load_new_objects`: Method to load new ledger entries.
|
|
63
|
+
"""
|
|
64
|
+
return await gather(
|
|
65
|
+
self.ledger._load_new_objects(self.start_block, self.ledger.cached_thru - 1, True),
|
|
66
|
+
self.ledger._load_new_objects(self.ledger.cached_from + 1, self.end_block, True),
|
|
67
|
+
)
|
|
File without changes
|