hive-nectar 0.2.9__py3-none-any.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.
- hive_nectar-0.2.9.dist-info/METADATA +194 -0
- hive_nectar-0.2.9.dist-info/RECORD +87 -0
- hive_nectar-0.2.9.dist-info/WHEEL +4 -0
- hive_nectar-0.2.9.dist-info/entry_points.txt +2 -0
- hive_nectar-0.2.9.dist-info/licenses/LICENSE.txt +23 -0
- nectar/__init__.py +37 -0
- nectar/account.py +5076 -0
- nectar/amount.py +553 -0
- nectar/asciichart.py +303 -0
- nectar/asset.py +122 -0
- nectar/block.py +574 -0
- nectar/blockchain.py +1242 -0
- nectar/blockchaininstance.py +2590 -0
- nectar/blockchainobject.py +263 -0
- nectar/cli.py +5937 -0
- nectar/comment.py +1552 -0
- nectar/community.py +854 -0
- nectar/constants.py +95 -0
- nectar/discussions.py +1437 -0
- nectar/exceptions.py +152 -0
- nectar/haf.py +381 -0
- nectar/hive.py +630 -0
- nectar/imageuploader.py +114 -0
- nectar/instance.py +113 -0
- nectar/market.py +876 -0
- nectar/memo.py +542 -0
- nectar/message.py +379 -0
- nectar/nodelist.py +309 -0
- nectar/price.py +603 -0
- nectar/profile.py +74 -0
- nectar/py.typed +0 -0
- nectar/rc.py +333 -0
- nectar/snapshot.py +1024 -0
- nectar/storage.py +62 -0
- nectar/transactionbuilder.py +659 -0
- nectar/utils.py +630 -0
- nectar/version.py +3 -0
- nectar/vote.py +722 -0
- nectar/wallet.py +472 -0
- nectar/witness.py +728 -0
- nectarapi/__init__.py +12 -0
- nectarapi/exceptions.py +126 -0
- nectarapi/graphenerpc.py +596 -0
- nectarapi/node.py +194 -0
- nectarapi/noderpc.py +79 -0
- nectarapi/openapi.py +107 -0
- nectarapi/py.typed +0 -0
- nectarapi/rpcutils.py +98 -0
- nectarapi/version.py +3 -0
- nectarbase/__init__.py +15 -0
- nectarbase/ledgertransactions.py +106 -0
- nectarbase/memo.py +242 -0
- nectarbase/objects.py +521 -0
- nectarbase/objecttypes.py +21 -0
- nectarbase/operationids.py +102 -0
- nectarbase/operations.py +1357 -0
- nectarbase/py.typed +0 -0
- nectarbase/signedtransactions.py +89 -0
- nectarbase/transactions.py +11 -0
- nectarbase/version.py +3 -0
- nectargraphenebase/__init__.py +27 -0
- nectargraphenebase/account.py +1121 -0
- nectargraphenebase/aes.py +49 -0
- nectargraphenebase/base58.py +197 -0
- nectargraphenebase/bip32.py +575 -0
- nectargraphenebase/bip38.py +110 -0
- nectargraphenebase/chains.py +15 -0
- nectargraphenebase/dictionary.py +2 -0
- nectargraphenebase/ecdsasig.py +309 -0
- nectargraphenebase/objects.py +130 -0
- nectargraphenebase/objecttypes.py +8 -0
- nectargraphenebase/operationids.py +5 -0
- nectargraphenebase/operations.py +25 -0
- nectargraphenebase/prefix.py +13 -0
- nectargraphenebase/py.typed +0 -0
- nectargraphenebase/signedtransactions.py +221 -0
- nectargraphenebase/types.py +557 -0
- nectargraphenebase/unsignedtransactions.py +288 -0
- nectargraphenebase/version.py +3 -0
- nectarstorage/__init__.py +57 -0
- nectarstorage/base.py +317 -0
- nectarstorage/exceptions.py +15 -0
- nectarstorage/interfaces.py +244 -0
- nectarstorage/masterpassword.py +237 -0
- nectarstorage/py.typed +0 -0
- nectarstorage/ram.py +27 -0
- nectarstorage/sqlite.py +343 -0
nectar/amount.py
ADDED
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
from decimal import ROUND_DOWN, Decimal
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Tuple, Union
|
|
3
|
+
|
|
4
|
+
from nectar.asset import Asset
|
|
5
|
+
from nectar.instance import shared_blockchain_instance
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .price import Price
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def check_asset(other: Any, self: Any, hv: Any) -> None:
|
|
12
|
+
"""
|
|
13
|
+
Assert that two asset representations refer to the same asset.
|
|
14
|
+
|
|
15
|
+
If both `other` and `self` are dicts containing an "asset" key, each asset id is wrapped in an Asset using the provided blockchain instance and compared for equality. Otherwise the two values are compared directly. Raises AssertionError if the values do not match.
|
|
16
|
+
"""
|
|
17
|
+
if isinstance(other, dict) and "asset" in other and isinstance(self, dict) and "asset" in self:
|
|
18
|
+
if not Asset(other["asset"], blockchain_instance=hv) == Asset(
|
|
19
|
+
self["asset"], blockchain_instance=hv
|
|
20
|
+
):
|
|
21
|
+
raise AssertionError()
|
|
22
|
+
else:
|
|
23
|
+
if not other == self:
|
|
24
|
+
raise AssertionError()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def quantize(amount: Union[str, int, float, Decimal], precision: int) -> Decimal:
|
|
28
|
+
# make sure amount is decimal and has the asset precision
|
|
29
|
+
amount = Decimal(amount)
|
|
30
|
+
places = Decimal(10) ** (-precision)
|
|
31
|
+
return amount.quantize(places, rounding=ROUND_DOWN)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Amount(dict):
|
|
35
|
+
"""This class deals with Amounts of any asset to simplify dealing with the tuple::
|
|
36
|
+
|
|
37
|
+
(amount, asset)
|
|
38
|
+
|
|
39
|
+
:param list args: Allows to deal with different representations of an amount
|
|
40
|
+
:param float amount: Let's create an instance with a specific amount
|
|
41
|
+
:param str asset: Let's you create an instance with a specific asset (symbol)
|
|
42
|
+
:param boolean fixed_point_arithmetic: when set to True, all operations are fixed
|
|
43
|
+
point operations and the amount is always be rounded down to the precision
|
|
44
|
+
:param Blockchain blockchain_instance: Blockchain instance
|
|
45
|
+
:returns: All data required to represent an Amount/Asset
|
|
46
|
+
:rtype: dict
|
|
47
|
+
:raises ValueError: if the data provided is not recognized
|
|
48
|
+
|
|
49
|
+
Way to obtain a proper instance:
|
|
50
|
+
|
|
51
|
+
* ``args`` can be a string, e.g.: "1 HBD"
|
|
52
|
+
* ``args`` can be a dictionary containing ``amount`` and ``asset_id``
|
|
53
|
+
* ``args`` can be a dictionary containing ``amount`` and ``asset``
|
|
54
|
+
* ``args`` can be a list of a ``float`` and ``str`` (symbol)
|
|
55
|
+
* ``args`` can be a list of a ``float`` and a :class:`nectar.asset.Asset`
|
|
56
|
+
* ``amount`` and ``asset`` are defined manually
|
|
57
|
+
|
|
58
|
+
An instance is a dictionary and comes with the following keys:
|
|
59
|
+
|
|
60
|
+
* ``amount`` (float)
|
|
61
|
+
* ``symbol`` (str)
|
|
62
|
+
* ``asset`` (instance of :class:`nectar.asset.Asset`)
|
|
63
|
+
|
|
64
|
+
Instances of this class can be used in regular mathematical expressions
|
|
65
|
+
(``+-*/%``) such as:
|
|
66
|
+
|
|
67
|
+
.. testcode::
|
|
68
|
+
|
|
69
|
+
from nectar.amount import Amount
|
|
70
|
+
from nectar.asset import Asset
|
|
71
|
+
a = Amount("1 HIVE")
|
|
72
|
+
b = Amount(1, "HIVE")
|
|
73
|
+
c = Amount("20", Asset("HIVE"))
|
|
74
|
+
a + b
|
|
75
|
+
a * 2
|
|
76
|
+
a += b
|
|
77
|
+
a /= 2.0
|
|
78
|
+
|
|
79
|
+
.. testoutput::
|
|
80
|
+
|
|
81
|
+
2.000 HIVE
|
|
82
|
+
2.000 HIVE
|
|
83
|
+
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
def __init__(
|
|
87
|
+
self,
|
|
88
|
+
amount: Union[str, int, float, Decimal, list, dict, "Amount"],
|
|
89
|
+
asset: Union[str, Asset, None] = None,
|
|
90
|
+
fixed_point_arithmetic: bool = False,
|
|
91
|
+
new_appbase_format: bool = True,
|
|
92
|
+
blockchain_instance: Any = None,
|
|
93
|
+
json_str: bool = False,
|
|
94
|
+
**kwargs,
|
|
95
|
+
) -> None:
|
|
96
|
+
"""
|
|
97
|
+
Initialize an Amount object representing a quantity of a specific blockchain asset.
|
|
98
|
+
|
|
99
|
+
The constructor accepts many input formats and normalizes them into internal keys:
|
|
100
|
+
- amount may be another Amount, a three-element list [amount, precision, asset],
|
|
101
|
+
a new appbase-format dict with keys ("amount", "nai", "precision"), a legacy dict
|
|
102
|
+
with ("amount", "asset_id") or ("amount", "asset"), a string like "1.000 HIVE",
|
|
103
|
+
or a numeric value (int, float, Decimal) paired with an `asset` argument.
|
|
104
|
+
- asset may be an Asset instance, an asset dict, or a symbol string; when omitted,
|
|
105
|
+
the asset will be inferred from the provided `amount` representation.
|
|
106
|
+
|
|
107
|
+
After parsing, the instance stores:
|
|
108
|
+
- "amount" as a Decimal (or quantized Decimal when fixed-point mode is enabled),
|
|
109
|
+
- "symbol" as the asset symbol,
|
|
110
|
+
- "asset" as an Asset-like object.
|
|
111
|
+
|
|
112
|
+
Parameters:
|
|
113
|
+
amount: Various accepted formats (see description) representing the quantity.
|
|
114
|
+
asset: Asset instance, asset dict, or asset symbol string used when `amount`
|
|
115
|
+
is a bare numeric value or when explicit asset resolution is required.
|
|
116
|
+
fixed_point_arithmetic (bool): When True, the numeric amount is quantized
|
|
117
|
+
to the asset's precision using floor rounding.
|
|
118
|
+
new_appbase_format (bool): Indicates whether to prefer the new appbase JSON
|
|
119
|
+
format when producing serialized representations.
|
|
120
|
+
|
|
121
|
+
Raises:
|
|
122
|
+
ValueError: If `amount` and `asset` do not match any supported input format.
|
|
123
|
+
"""
|
|
124
|
+
self["asset"] = {}
|
|
125
|
+
self.new_appbase_format = new_appbase_format
|
|
126
|
+
self.fixed_point_arithmetic = fixed_point_arithmetic
|
|
127
|
+
|
|
128
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
129
|
+
|
|
130
|
+
if amount and asset is None and isinstance(amount, Amount):
|
|
131
|
+
# Copy Asset object
|
|
132
|
+
self["amount"] = amount["amount"]
|
|
133
|
+
self["symbol"] = amount["symbol"]
|
|
134
|
+
self["asset"] = amount["asset"]
|
|
135
|
+
|
|
136
|
+
elif amount and asset is None and isinstance(amount, list) and len(amount) == 3:
|
|
137
|
+
# Copy Asset object
|
|
138
|
+
self["amount"] = Decimal(amount[0]) / Decimal(10 ** amount[1])
|
|
139
|
+
self["asset"] = Asset(amount[2], blockchain_instance=self.blockchain)
|
|
140
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
141
|
+
|
|
142
|
+
elif (
|
|
143
|
+
amount
|
|
144
|
+
and asset is None
|
|
145
|
+
and isinstance(amount, dict)
|
|
146
|
+
and "amount" in amount
|
|
147
|
+
and "nai" in amount
|
|
148
|
+
and "precision" in amount
|
|
149
|
+
):
|
|
150
|
+
# Copy Asset object
|
|
151
|
+
self.new_appbase_format = True
|
|
152
|
+
self["amount"] = Decimal(amount["amount"]) / Decimal(10 ** amount["precision"])
|
|
153
|
+
self["asset"] = Asset(amount["nai"], blockchain_instance=self.blockchain)
|
|
154
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
155
|
+
|
|
156
|
+
elif amount is not None and asset is None and isinstance(amount, str):
|
|
157
|
+
self["amount"], self["symbol"] = amount.split(" ")
|
|
158
|
+
self["asset"] = Asset(self["symbol"], blockchain_instance=self.blockchain)
|
|
159
|
+
|
|
160
|
+
elif (
|
|
161
|
+
amount
|
|
162
|
+
and asset is None
|
|
163
|
+
and isinstance(amount, dict)
|
|
164
|
+
and "amount" in amount
|
|
165
|
+
and "asset_id" in amount
|
|
166
|
+
):
|
|
167
|
+
self["asset"] = Asset(amount["asset_id"], blockchain_instance=self.blockchain)
|
|
168
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
169
|
+
self["amount"] = Decimal(amount["amount"]) / Decimal(10 ** self["asset"]["precision"])
|
|
170
|
+
|
|
171
|
+
elif (
|
|
172
|
+
amount
|
|
173
|
+
and asset is None
|
|
174
|
+
and isinstance(amount, dict)
|
|
175
|
+
and "amount" in amount
|
|
176
|
+
and "asset" in amount
|
|
177
|
+
):
|
|
178
|
+
self["asset"] = Asset(amount["asset"], blockchain_instance=self.blockchain)
|
|
179
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
180
|
+
self["amount"] = Decimal(amount["amount"]) / Decimal(10 ** self["asset"]["precision"])
|
|
181
|
+
|
|
182
|
+
elif isinstance(amount, (float)) and asset and isinstance(asset, Asset):
|
|
183
|
+
self["amount"] = str(amount)
|
|
184
|
+
self["asset"] = asset
|
|
185
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
186
|
+
|
|
187
|
+
elif isinstance(amount, (int, Decimal)) and asset and isinstance(asset, Asset):
|
|
188
|
+
self["amount"] = amount
|
|
189
|
+
self["asset"] = asset
|
|
190
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
191
|
+
|
|
192
|
+
elif isinstance(amount, (float)) and asset and isinstance(asset, dict):
|
|
193
|
+
self["amount"] = str(amount)
|
|
194
|
+
self["asset"] = asset
|
|
195
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
196
|
+
|
|
197
|
+
elif isinstance(amount, (int, Decimal)) and asset and isinstance(asset, dict):
|
|
198
|
+
self["amount"] = amount
|
|
199
|
+
self["asset"] = asset
|
|
200
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
201
|
+
|
|
202
|
+
elif isinstance(amount, (float)) and asset and isinstance(asset, str):
|
|
203
|
+
self["amount"] = str(amount)
|
|
204
|
+
self["asset"] = Asset(asset, blockchain_instance=self.blockchain)
|
|
205
|
+
self["symbol"] = asset
|
|
206
|
+
|
|
207
|
+
elif isinstance(amount, (int, Decimal)) and asset and isinstance(asset, str):
|
|
208
|
+
self["amount"] = amount
|
|
209
|
+
self["asset"] = Asset(asset, blockchain_instance=self.blockchain)
|
|
210
|
+
self["symbol"] = asset
|
|
211
|
+
elif amount and asset and isinstance(asset, Asset):
|
|
212
|
+
self["amount"] = amount
|
|
213
|
+
self["symbol"] = asset["symbol"]
|
|
214
|
+
self["asset"] = asset
|
|
215
|
+
elif amount and asset and isinstance(asset, str):
|
|
216
|
+
self["amount"] = amount
|
|
217
|
+
self["asset"] = Asset(asset, blockchain_instance=self.blockchain)
|
|
218
|
+
self["symbol"] = self["asset"]["symbol"]
|
|
219
|
+
else:
|
|
220
|
+
raise ValueError
|
|
221
|
+
if self.fixed_point_arithmetic:
|
|
222
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
223
|
+
else:
|
|
224
|
+
self["amount"] = Decimal(self["amount"])
|
|
225
|
+
|
|
226
|
+
def copy(self) -> "Amount":
|
|
227
|
+
"""Copy the instance and make sure not to use a reference"""
|
|
228
|
+
return Amount(
|
|
229
|
+
amount=self["amount"],
|
|
230
|
+
asset=self["asset"].copy(),
|
|
231
|
+
new_appbase_format=self.new_appbase_format,
|
|
232
|
+
fixed_point_arithmetic=self.fixed_point_arithmetic,
|
|
233
|
+
blockchain_instance=self.blockchain,
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def amount(self) -> float:
|
|
238
|
+
"""Returns the amount as float"""
|
|
239
|
+
return float(self["amount"])
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def amount_decimal(self) -> Decimal:
|
|
243
|
+
"""Returns the amount as decimal"""
|
|
244
|
+
return self["amount"]
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def symbol(self) -> str:
|
|
248
|
+
"""Returns the symbol of the asset"""
|
|
249
|
+
return self["symbol"]
|
|
250
|
+
|
|
251
|
+
def as_tuple(self) -> Tuple[float, str]:
|
|
252
|
+
return float(self), self.symbol
|
|
253
|
+
|
|
254
|
+
@property
|
|
255
|
+
def asset(self) -> Asset:
|
|
256
|
+
"""
|
|
257
|
+
Return the Asset object for this Amount, constructing it lazily if missing.
|
|
258
|
+
|
|
259
|
+
If the internal 'asset' entry is falsy, this creates a nectar.asset.Asset using the stored symbol
|
|
260
|
+
and this Amount's blockchain instance, stores it in 'asset', and returns it. Always returns an
|
|
261
|
+
Asset instance.
|
|
262
|
+
"""
|
|
263
|
+
if not isinstance(self["asset"], Asset):
|
|
264
|
+
self["asset"] = Asset(self["symbol"], blockchain_instance=self.blockchain)
|
|
265
|
+
return self["asset"]
|
|
266
|
+
|
|
267
|
+
def json(self) -> Union[str, dict, list]:
|
|
268
|
+
asset_obj = self["asset"]
|
|
269
|
+
if isinstance(asset_obj, Asset):
|
|
270
|
+
asset_precision = asset_obj["precision"]
|
|
271
|
+
asset_identifier = asset_obj["asset"]
|
|
272
|
+
elif isinstance(asset_obj, dict):
|
|
273
|
+
asset_precision = asset_obj.get("precision")
|
|
274
|
+
asset_identifier = asset_obj.get("asset")
|
|
275
|
+
else:
|
|
276
|
+
resolved_asset = Asset(self["symbol"], blockchain_instance=self.blockchain)
|
|
277
|
+
self["asset"] = resolved_asset
|
|
278
|
+
asset_precision = resolved_asset["precision"]
|
|
279
|
+
asset_identifier = resolved_asset["asset"]
|
|
280
|
+
|
|
281
|
+
if asset_precision is None or asset_identifier is None:
|
|
282
|
+
return str(self)
|
|
283
|
+
|
|
284
|
+
amount_value = str(int(self))
|
|
285
|
+
|
|
286
|
+
if self.new_appbase_format:
|
|
287
|
+
payload = {
|
|
288
|
+
"amount": amount_value,
|
|
289
|
+
"nai": asset_identifier,
|
|
290
|
+
"precision": asset_precision,
|
|
291
|
+
}
|
|
292
|
+
else:
|
|
293
|
+
payload = [amount_value, asset_precision, asset_identifier]
|
|
294
|
+
return payload
|
|
295
|
+
|
|
296
|
+
def __str__(self) -> str:
|
|
297
|
+
amount = quantize(self["amount"], self["asset"]["precision"])
|
|
298
|
+
symbol = self["symbol"]
|
|
299
|
+
return "{:.{prec}f} {}".format(amount, symbol, prec=self["asset"]["precision"])
|
|
300
|
+
|
|
301
|
+
def __float__(self) -> float:
|
|
302
|
+
if self.fixed_point_arithmetic:
|
|
303
|
+
return float(quantize(self["amount"], self["asset"]["precision"]))
|
|
304
|
+
else:
|
|
305
|
+
return float(self["amount"])
|
|
306
|
+
|
|
307
|
+
def __int__(self) -> int:
|
|
308
|
+
amount = quantize(self["amount"], self["asset"]["precision"])
|
|
309
|
+
return int(amount * 10 ** self["asset"]["precision"])
|
|
310
|
+
|
|
311
|
+
def __add__(self, other: Union["Amount", int, float, str]) -> "Amount":
|
|
312
|
+
a = self.copy()
|
|
313
|
+
if isinstance(other, Amount):
|
|
314
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
315
|
+
a["amount"] += other["amount"]
|
|
316
|
+
else:
|
|
317
|
+
a["amount"] += Decimal(other)
|
|
318
|
+
if self.fixed_point_arithmetic:
|
|
319
|
+
a["amount"] = quantize(a["amount"], self["asset"]["precision"])
|
|
320
|
+
return a
|
|
321
|
+
|
|
322
|
+
def __sub__(self, other: Union["Amount", int, float, str]) -> "Amount":
|
|
323
|
+
a = self.copy()
|
|
324
|
+
if isinstance(other, Amount):
|
|
325
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
326
|
+
a["amount"] -= other["amount"]
|
|
327
|
+
else:
|
|
328
|
+
a["amount"] -= Decimal(other)
|
|
329
|
+
if self.fixed_point_arithmetic:
|
|
330
|
+
a["amount"] = quantize(a["amount"], self["asset"]["precision"])
|
|
331
|
+
return a
|
|
332
|
+
|
|
333
|
+
def __mul__(self, other: Union[int, float, Decimal, "Amount", "Price"]) -> "Amount":
|
|
334
|
+
from .price import Price
|
|
335
|
+
|
|
336
|
+
a = self.copy()
|
|
337
|
+
if isinstance(other, Amount):
|
|
338
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
339
|
+
a["amount"] *= other["amount"]
|
|
340
|
+
elif isinstance(other, Price):
|
|
341
|
+
if not self["asset"] == other["quote"]["asset"]:
|
|
342
|
+
raise AssertionError()
|
|
343
|
+
a = self.copy() * other["price"]
|
|
344
|
+
a["asset"] = other["base"]["asset"].copy()
|
|
345
|
+
a["symbol"] = other["base"]["asset"]["symbol"]
|
|
346
|
+
else:
|
|
347
|
+
a["amount"] *= Decimal(other)
|
|
348
|
+
if self.fixed_point_arithmetic:
|
|
349
|
+
a["amount"] = quantize(a["amount"], self["asset"]["precision"])
|
|
350
|
+
return a
|
|
351
|
+
|
|
352
|
+
def __floordiv__(self, other: Union[int, float, Decimal, "Amount"]) -> Union["Amount", "Price"]:
|
|
353
|
+
a = self.copy()
|
|
354
|
+
if isinstance(other, Amount):
|
|
355
|
+
from .price import Price
|
|
356
|
+
|
|
357
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
358
|
+
return Price(self, other, blockchain_instance=self.blockchain)
|
|
359
|
+
else:
|
|
360
|
+
a["amount"] //= Decimal(other)
|
|
361
|
+
if self.fixed_point_arithmetic:
|
|
362
|
+
a["amount"] = quantize(a["amount"], self["asset"]["precision"])
|
|
363
|
+
return a
|
|
364
|
+
|
|
365
|
+
def __div__(
|
|
366
|
+
self, other: Union[int, float, Decimal, "Amount", "Price"]
|
|
367
|
+
) -> Union["Amount", "Price"]:
|
|
368
|
+
from .price import Price
|
|
369
|
+
|
|
370
|
+
a = self.copy()
|
|
371
|
+
if isinstance(other, Amount):
|
|
372
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
373
|
+
return Price(self, other, blockchain_instance=self.blockchain)
|
|
374
|
+
elif isinstance(other, Price):
|
|
375
|
+
if not self["asset"] == other["base"]["asset"]:
|
|
376
|
+
raise AssertionError()
|
|
377
|
+
a = self.copy()
|
|
378
|
+
a["amount"] = a["amount"] / other["price"]
|
|
379
|
+
a["asset"] = other["quote"]["asset"].copy()
|
|
380
|
+
a["symbol"] = other["quote"]["asset"]["symbol"]
|
|
381
|
+
else:
|
|
382
|
+
a["amount"] /= Decimal(other)
|
|
383
|
+
if self.fixed_point_arithmetic:
|
|
384
|
+
a["amount"] = quantize(a["amount"], self["asset"]["precision"])
|
|
385
|
+
return a
|
|
386
|
+
|
|
387
|
+
def __mod__(self, other: Union[int, float, Decimal, "Amount"]) -> "Amount":
|
|
388
|
+
a = self.copy()
|
|
389
|
+
if isinstance(other, Amount):
|
|
390
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
391
|
+
a["amount"] %= other["amount"]
|
|
392
|
+
else:
|
|
393
|
+
a["amount"] %= Decimal(other)
|
|
394
|
+
if self.fixed_point_arithmetic:
|
|
395
|
+
a["amount"] = quantize(a["amount"], self["asset"]["precision"])
|
|
396
|
+
return a
|
|
397
|
+
|
|
398
|
+
def __pow__(self, other: Union[int, float, Decimal, "Amount"]) -> "Amount":
|
|
399
|
+
a = self.copy()
|
|
400
|
+
if isinstance(other, Amount):
|
|
401
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
402
|
+
a["amount"] **= other["amount"]
|
|
403
|
+
else:
|
|
404
|
+
a["amount"] **= Decimal(other)
|
|
405
|
+
if self.fixed_point_arithmetic:
|
|
406
|
+
a["amount"] = quantize(a["amount"], self["asset"]["precision"])
|
|
407
|
+
return a
|
|
408
|
+
|
|
409
|
+
def __iadd__(self, other: Union["Amount", int, float, str]) -> "Amount":
|
|
410
|
+
if isinstance(other, Amount):
|
|
411
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
412
|
+
self["amount"] += other["amount"]
|
|
413
|
+
else:
|
|
414
|
+
self["amount"] += Decimal(other)
|
|
415
|
+
if self.fixed_point_arithmetic:
|
|
416
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
417
|
+
return self
|
|
418
|
+
|
|
419
|
+
def __isub__(self, other: Union["Amount", int, float, str]) -> "Amount":
|
|
420
|
+
if isinstance(other, Amount):
|
|
421
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
422
|
+
self["amount"] -= other["amount"]
|
|
423
|
+
else:
|
|
424
|
+
self["amount"] -= Decimal(other)
|
|
425
|
+
if self.fixed_point_arithmetic:
|
|
426
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
427
|
+
return self
|
|
428
|
+
|
|
429
|
+
def __imul__(self, other: Union[int, float, Decimal, "Amount"]) -> "Amount":
|
|
430
|
+
if isinstance(other, Amount):
|
|
431
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
432
|
+
self["amount"] *= other["amount"]
|
|
433
|
+
else:
|
|
434
|
+
self["amount"] *= Decimal(other)
|
|
435
|
+
|
|
436
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
437
|
+
return self
|
|
438
|
+
|
|
439
|
+
def __idiv__(self, other: Union[int, float, Decimal]) -> "Amount":
|
|
440
|
+
"""
|
|
441
|
+
In-place division: divide this Amount by another Amount or numeric value and return self.
|
|
442
|
+
|
|
443
|
+
If `other` is an Amount, asserts asset compatibility and divides this object's internal amount by the other's amount. If `other` is numeric, divides by Decimal(other). When `fixed_point_arithmetic` is enabled, the result is quantized to this asset's precision.
|
|
444
|
+
|
|
445
|
+
Returns:
|
|
446
|
+
self (Amount): The mutated Amount instance.
|
|
447
|
+
|
|
448
|
+
Raises:
|
|
449
|
+
AssertionError: If `other` is an Amount with a different asset (via check_asset).
|
|
450
|
+
"""
|
|
451
|
+
if isinstance(other, Amount):
|
|
452
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
453
|
+
self["amount"] = self["amount"] / other["amount"]
|
|
454
|
+
else:
|
|
455
|
+
self["amount"] /= Decimal(other)
|
|
456
|
+
if self.fixed_point_arithmetic:
|
|
457
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
458
|
+
return self
|
|
459
|
+
|
|
460
|
+
def __ifloordiv__(self, other: Union[int, float, Decimal, "Amount"]) -> "Amount":
|
|
461
|
+
if isinstance(other, Amount):
|
|
462
|
+
self["amount"] //= other["amount"]
|
|
463
|
+
else:
|
|
464
|
+
self["amount"] //= Decimal(other)
|
|
465
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
466
|
+
return self
|
|
467
|
+
|
|
468
|
+
def __imod__(self, other: Union[int, float, Decimal]) -> "Amount":
|
|
469
|
+
if isinstance(other, Amount):
|
|
470
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
471
|
+
self["amount"] %= other["amount"]
|
|
472
|
+
else:
|
|
473
|
+
self["amount"] %= Decimal(other)
|
|
474
|
+
if self.fixed_point_arithmetic:
|
|
475
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
476
|
+
return self
|
|
477
|
+
|
|
478
|
+
def __ipow__(self, other: Union[int, float, Decimal, "Amount"]) -> "Amount":
|
|
479
|
+
if isinstance(other, Amount):
|
|
480
|
+
self["amount"] **= other["amount"]
|
|
481
|
+
else:
|
|
482
|
+
self["amount"] **= Decimal(other)
|
|
483
|
+
if self.fixed_point_arithmetic:
|
|
484
|
+
self["amount"] = quantize(self["amount"], self["asset"]["precision"])
|
|
485
|
+
return self
|
|
486
|
+
|
|
487
|
+
def __lt__(self, other: Union["Amount", int, float, str]) -> bool:
|
|
488
|
+
quant_amount = quantize(self["amount"], self["asset"]["precision"])
|
|
489
|
+
if isinstance(other, Amount):
|
|
490
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
491
|
+
return quant_amount < quantize(other["amount"], self["asset"]["precision"])
|
|
492
|
+
else:
|
|
493
|
+
return quant_amount < quantize((other or 0), self["asset"]["precision"])
|
|
494
|
+
|
|
495
|
+
def __le__(self, other: Union["Amount", int, float, str]) -> bool:
|
|
496
|
+
quant_amount = quantize(self["amount"], self["asset"]["precision"])
|
|
497
|
+
if isinstance(other, Amount):
|
|
498
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
499
|
+
return quant_amount <= quantize(other["amount"], self["asset"]["precision"])
|
|
500
|
+
else:
|
|
501
|
+
return quant_amount <= quantize((other or 0), self["asset"]["precision"])
|
|
502
|
+
|
|
503
|
+
def __eq__(self, other: object) -> bool:
|
|
504
|
+
quant_amount = quantize(self["amount"], self["asset"]["precision"])
|
|
505
|
+
if isinstance(other, Amount):
|
|
506
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
507
|
+
return quant_amount == quantize(other["amount"], self["asset"]["precision"])
|
|
508
|
+
if isinstance(other, (int, float, str, Decimal)):
|
|
509
|
+
return quant_amount == quantize((other or 0), self["asset"]["precision"])
|
|
510
|
+
return False
|
|
511
|
+
|
|
512
|
+
def __ne__(self, other: object) -> bool:
|
|
513
|
+
"""
|
|
514
|
+
Return True if this Amount is not equal to `other`.
|
|
515
|
+
|
|
516
|
+
Compares values after quantizing both sides to this amount's asset precision. If `other` is an Amount, its asset must match this Amount's asset (an assertion is raised on mismatch) and the comparison uses both amounts quantized to the shared precision. If `other` is numeric or None, it is treated as a numeric value (None → 0) and compared after quantization.
|
|
517
|
+
|
|
518
|
+
Returns:
|
|
519
|
+
bool: True when the quantized values differ, False otherwise.
|
|
520
|
+
"""
|
|
521
|
+
quant_amount = quantize(self["amount"], self["asset"]["precision"])
|
|
522
|
+
if isinstance(other, Amount):
|
|
523
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
524
|
+
return quant_amount != quantize(other["amount"], self["asset"]["precision"])
|
|
525
|
+
if isinstance(other, (int, float, str, Decimal)):
|
|
526
|
+
return quant_amount != quantize((other or 0), self["asset"]["precision"])
|
|
527
|
+
return True
|
|
528
|
+
|
|
529
|
+
def __ge__(self, other: Union["Amount", int, float, str]) -> bool:
|
|
530
|
+
"""
|
|
531
|
+
Return True if this Amount is greater than or equal to `other`.
|
|
532
|
+
|
|
533
|
+
Performs comparison after quantizing both values to this Amount's asset precision. If `other` is an Amount, its asset must match this Amount's asset (an AssertionError is raised on mismatch). If `other` is None, it is treated as zero. Returns a boolean.
|
|
534
|
+
"""
|
|
535
|
+
quant_amount = quantize(self["amount"], self["asset"]["precision"])
|
|
536
|
+
if isinstance(other, Amount):
|
|
537
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
538
|
+
return quant_amount >= quantize(other["amount"], self["asset"]["precision"])
|
|
539
|
+
else:
|
|
540
|
+
return quant_amount >= quantize((other or 0), self["asset"]["precision"])
|
|
541
|
+
|
|
542
|
+
def __gt__(self, other: Union["Amount", int, float, str]) -> bool:
|
|
543
|
+
quant_amount = quantize(self["amount"], self["asset"]["precision"])
|
|
544
|
+
if isinstance(other, Amount):
|
|
545
|
+
check_asset(other["asset"], self["asset"], self.blockchain)
|
|
546
|
+
return quant_amount > quantize(other["amount"], self["asset"]["precision"])
|
|
547
|
+
else:
|
|
548
|
+
return quant_amount > quantize((other or 0), self["asset"]["precision"])
|
|
549
|
+
|
|
550
|
+
__repr__ = __str__
|
|
551
|
+
__truediv__ = __div__
|
|
552
|
+
__itruediv__ = __idiv__
|
|
553
|
+
__truemul__ = __mul__
|