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
nectarbase/objects.py
ADDED
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
import decimal
|
|
2
|
+
import json
|
|
3
|
+
import struct
|
|
4
|
+
from collections import OrderedDict
|
|
5
|
+
from typing import Any, Dict, Union
|
|
6
|
+
|
|
7
|
+
from nectargraphenebase.account import PublicKey
|
|
8
|
+
from nectargraphenebase.chains import known_chains
|
|
9
|
+
from nectargraphenebase.objects import GrapheneObject, isArgsThisClass
|
|
10
|
+
from nectargraphenebase.objects import Operation as GPHOperation
|
|
11
|
+
from nectargraphenebase.types import (
|
|
12
|
+
Array,
|
|
13
|
+
Bytes,
|
|
14
|
+
Id,
|
|
15
|
+
Int16,
|
|
16
|
+
Map,
|
|
17
|
+
PointInTime,
|
|
18
|
+
Static_variant,
|
|
19
|
+
String,
|
|
20
|
+
Uint16,
|
|
21
|
+
Uint32,
|
|
22
|
+
Uint64,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
from .operationids import operations
|
|
26
|
+
|
|
27
|
+
default_prefix = "STM"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def value_to_decimal(value: Union[str, float, int], decimal_places: int) -> decimal.Decimal:
|
|
31
|
+
decimal.getcontext().rounding = decimal.ROUND_DOWN # define rounding method
|
|
32
|
+
return decimal.Decimal(str(float(value))).quantize(
|
|
33
|
+
decimal.Decimal("1e-{}".format(decimal_places))
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Amount:
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
d: Union[str, Any],
|
|
41
|
+
prefix: str = default_prefix,
|
|
42
|
+
json_str: bool = False,
|
|
43
|
+
**kwargs,
|
|
44
|
+
) -> None:
|
|
45
|
+
self.json_str = json_str
|
|
46
|
+
if isinstance(d, str):
|
|
47
|
+
self.amount, self.symbol = d.strip().split(" ")
|
|
48
|
+
self.precision = None
|
|
49
|
+
for c in known_chains:
|
|
50
|
+
if self.precision is not None:
|
|
51
|
+
continue
|
|
52
|
+
if known_chains[c]["prefix"] != prefix:
|
|
53
|
+
continue
|
|
54
|
+
for asset in known_chains[c]["chain_assets"]:
|
|
55
|
+
if self.precision is not None:
|
|
56
|
+
continue
|
|
57
|
+
if asset["symbol"] == self.symbol:
|
|
58
|
+
self.precision = asset["precision"]
|
|
59
|
+
self.asset = asset["asset"]
|
|
60
|
+
elif asset["asset"] == self.symbol:
|
|
61
|
+
self.precision = asset["precision"]
|
|
62
|
+
self.asset = asset["asset"]
|
|
63
|
+
if self.precision is None:
|
|
64
|
+
raise Exception("Asset unknown")
|
|
65
|
+
self.amount = round(
|
|
66
|
+
value_to_decimal(float(self.amount), self.precision) * 10**self.precision
|
|
67
|
+
)
|
|
68
|
+
# Workaround to allow transfers in HIVE
|
|
69
|
+
|
|
70
|
+
self.str_repr = "{:.{}f} {}".format(
|
|
71
|
+
(float(self.amount) / 10**self.precision), self.precision, self.symbol
|
|
72
|
+
)
|
|
73
|
+
elif isinstance(d, list):
|
|
74
|
+
self.amount = d[0]
|
|
75
|
+
self.asset = d[2]
|
|
76
|
+
self.precision = d[1]
|
|
77
|
+
self.symbol = None
|
|
78
|
+
for c in known_chains:
|
|
79
|
+
if known_chains[c]["prefix"] != prefix:
|
|
80
|
+
continue
|
|
81
|
+
for asset in known_chains[c]["chain_assets"]:
|
|
82
|
+
if asset["asset"] == self.asset:
|
|
83
|
+
self.symbol = asset["symbol"]
|
|
84
|
+
if self.symbol is None:
|
|
85
|
+
raise ValueError("Unknown NAI, cannot resolve symbol")
|
|
86
|
+
a = Array([String(d[0]), d[1], d[2]])
|
|
87
|
+
self.str_repr = str(a.__str__())
|
|
88
|
+
elif isinstance(d, dict) and "nai" in d:
|
|
89
|
+
self.asset = d["nai"]
|
|
90
|
+
self.symbol = None
|
|
91
|
+
for c in known_chains:
|
|
92
|
+
if known_chains[c]["prefix"] != prefix:
|
|
93
|
+
continue
|
|
94
|
+
for asset in known_chains[c]["chain_assets"]:
|
|
95
|
+
if asset["asset"] == d["nai"]:
|
|
96
|
+
self.symbol = asset["symbol"]
|
|
97
|
+
if self.symbol is None:
|
|
98
|
+
raise ValueError("Unknown NAI, cannot resolve symbol")
|
|
99
|
+
self.amount = d["amount"]
|
|
100
|
+
self.precision = d["precision"]
|
|
101
|
+
self.str_repr = json.dumps(d)
|
|
102
|
+
elif isinstance(d, dict) and "amount" in d and "asset" in d:
|
|
103
|
+
self.amount = d["amount"]
|
|
104
|
+
asset_obj = d["asset"]
|
|
105
|
+
self.precision = asset_obj["precision"]
|
|
106
|
+
self.asset = asset_obj.get("asset", asset_obj.get("nai"))
|
|
107
|
+
self.symbol = asset_obj.get("symbol")
|
|
108
|
+
self.amount = round(value_to_decimal(self.amount, self.precision) * 10**self.precision)
|
|
109
|
+
if hasattr(d, "json"):
|
|
110
|
+
self.str_repr = json.dumps(d.json())
|
|
111
|
+
else:
|
|
112
|
+
# Fallback or manual construction if needed, but for now just str(d) or skip
|
|
113
|
+
# If d is a dict with Decimal, we can't json dump it directly.
|
|
114
|
+
# But we only expect nectar.amount.Amount here which has .json()
|
|
115
|
+
self.str_repr = json.dumps(
|
|
116
|
+
d
|
|
117
|
+
) # This might still fail if not Amount object but just dict with Decimal
|
|
118
|
+
|
|
119
|
+
else:
|
|
120
|
+
self.amount = d.amount
|
|
121
|
+
self.symbol = d.symbol
|
|
122
|
+
self.asset = d.asset
|
|
123
|
+
self.precision = d.precision
|
|
124
|
+
self.amount = round(value_to_decimal(self.amount, self.precision) * 10**self.precision)
|
|
125
|
+
self.str_repr = str(d)
|
|
126
|
+
# self.str_repr = json.dumps((d.json()))
|
|
127
|
+
# self.str_repr = '{:.{}f} {}'.format((float(self.amount) / 10 ** self.precision), self.precision, self.asset)
|
|
128
|
+
|
|
129
|
+
def __bytes__(self) -> bytes:
|
|
130
|
+
# padding
|
|
131
|
+
# The nodes still serialize the legacy symbol name for HBD as 'SBD' and HIVE as 'STEEM' in wire format.
|
|
132
|
+
# To match get_transaction_hex and avoid digest mismatches, map 'HBD' -> 'SBD' and 'HIVE' -> 'STEEM' on serialization.
|
|
133
|
+
"""
|
|
134
|
+
Serialize the Amount into its wire-format byte representation.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
bytes: 8-byte little-endian signed integer amount, followed by a 1-byte precision,
|
|
138
|
+
followed by a 7-byte ASCII symbol padded with null bytes. On serialization,
|
|
139
|
+
the symbol is remapped for legacy wire-format compatibility: "HBD" -> "SBD"
|
|
140
|
+
and "HIVE" -> "STEEM".
|
|
141
|
+
"""
|
|
142
|
+
_sym = self.symbol
|
|
143
|
+
if _sym == "HBD":
|
|
144
|
+
_sym = "SBD"
|
|
145
|
+
elif _sym == "HIVE":
|
|
146
|
+
_sym = "STEEM"
|
|
147
|
+
symbol = str(_sym) + "\x00" * (7 - len(str(_sym)))
|
|
148
|
+
return (
|
|
149
|
+
struct.pack("<q", int(self.amount))
|
|
150
|
+
+ struct.pack("<b", self.precision)
|
|
151
|
+
+ bytes(symbol, "ascii")
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
def __str__(self) -> str:
|
|
155
|
+
if self.json_str:
|
|
156
|
+
return json.dumps(
|
|
157
|
+
{
|
|
158
|
+
"amount": str(self.amount),
|
|
159
|
+
"precision": self.precision,
|
|
160
|
+
"nai": self.asset,
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
return self.str_repr
|
|
164
|
+
|
|
165
|
+
def toJson(self):
|
|
166
|
+
try:
|
|
167
|
+
return json.loads(str(self))
|
|
168
|
+
except Exception:
|
|
169
|
+
return str(self)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
class Operation(GPHOperation):
|
|
173
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
174
|
+
self.appbase = kwargs.pop("appbase", False)
|
|
175
|
+
self.prefix = kwargs.pop("prefix", default_prefix)
|
|
176
|
+
super().__init__(*args, **kwargs)
|
|
177
|
+
|
|
178
|
+
def _getklass(self, name: str) -> type:
|
|
179
|
+
module = __import__("nectarbase.operations", fromlist=["operations"])
|
|
180
|
+
class_ = getattr(module, name)
|
|
181
|
+
return class_
|
|
182
|
+
|
|
183
|
+
def operations(self) -> Dict[str, int]:
|
|
184
|
+
return operations
|
|
185
|
+
|
|
186
|
+
def getOperationNameForId(self, i: int) -> str:
|
|
187
|
+
"""Convert an operation id into the corresponding string"""
|
|
188
|
+
for key in self.operations():
|
|
189
|
+
if int(self.operations()[key]) == int(i):
|
|
190
|
+
return key
|
|
191
|
+
return "Unknown Operation ID %d" % i
|
|
192
|
+
|
|
193
|
+
def json(self) -> Dict[str, Any]:
|
|
194
|
+
return json.loads(str(self))
|
|
195
|
+
# return json.loads(str(json.dumps([self.name, self.op.toJson()])))
|
|
196
|
+
|
|
197
|
+
def __bytes__(self) -> bytes:
|
|
198
|
+
if self.opId is not None:
|
|
199
|
+
return bytes(Id(self.opId)) + bytes(self.op)
|
|
200
|
+
return bytes(self.op)
|
|
201
|
+
|
|
202
|
+
def __str__(self) -> str:
|
|
203
|
+
if self.appbase:
|
|
204
|
+
op_data = self.op.toJson() if isinstance(self.op, GrapheneObject) else str(self.op)
|
|
205
|
+
return json.dumps({"type": self.name.lower() + "_operation", "value": op_data})
|
|
206
|
+
else:
|
|
207
|
+
op_data = self.op.toJson() if isinstance(self.op, GrapheneObject) else str(self.op)
|
|
208
|
+
return json.dumps([self.name.lower(), op_data])
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
class Memo(GrapheneObject):
|
|
212
|
+
def __init__(self, *args: Any, **kwargs: Any) -> None:
|
|
213
|
+
if isArgsThisClass(self, args):
|
|
214
|
+
self.data = args[0].data
|
|
215
|
+
else:
|
|
216
|
+
prefix = kwargs.pop("prefix", default_prefix)
|
|
217
|
+
if "encrypted" not in kwargs or not kwargs["encrypted"]:
|
|
218
|
+
super().__init__(None)
|
|
219
|
+
else:
|
|
220
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
221
|
+
kwargs = args[0]
|
|
222
|
+
if "encrypted" in kwargs and kwargs["encrypted"]:
|
|
223
|
+
super().__init__(
|
|
224
|
+
OrderedDict(
|
|
225
|
+
[
|
|
226
|
+
("from", PublicKey(kwargs["from"], prefix=prefix)),
|
|
227
|
+
("to", PublicKey(kwargs["to"], prefix=prefix)),
|
|
228
|
+
("nonce", Uint64(int(kwargs["nonce"]))),
|
|
229
|
+
("check", Uint32(int(kwargs["check"]))),
|
|
230
|
+
("encrypted", Bytes(kwargs["encrypted"])),
|
|
231
|
+
]
|
|
232
|
+
)
|
|
233
|
+
)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class WitnessProps(GrapheneObject):
|
|
237
|
+
def __init__(self, *args, **kwargs):
|
|
238
|
+
if isArgsThisClass(self, args):
|
|
239
|
+
self.data = args[0].data
|
|
240
|
+
else:
|
|
241
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
242
|
+
kwargs = args[0]
|
|
243
|
+
prefix = kwargs.get("prefix", default_prefix)
|
|
244
|
+
json_str = kwargs.get("json_str", False)
|
|
245
|
+
if "sbd_interest_rate" in kwargs:
|
|
246
|
+
super().__init__(
|
|
247
|
+
OrderedDict(
|
|
248
|
+
[
|
|
249
|
+
(
|
|
250
|
+
"account_creation_fee",
|
|
251
|
+
Amount(
|
|
252
|
+
kwargs["account_creation_fee"],
|
|
253
|
+
prefix=prefix,
|
|
254
|
+
json_str=json_str,
|
|
255
|
+
),
|
|
256
|
+
),
|
|
257
|
+
(
|
|
258
|
+
"maximum_block_size",
|
|
259
|
+
Uint32(kwargs["maximum_block_size"]),
|
|
260
|
+
),
|
|
261
|
+
("sbd_interest_rate", Uint16(kwargs["sbd_interest_rate"])),
|
|
262
|
+
]
|
|
263
|
+
)
|
|
264
|
+
)
|
|
265
|
+
elif "hbd_interest_rate" in kwargs:
|
|
266
|
+
super().__init__(
|
|
267
|
+
OrderedDict(
|
|
268
|
+
[
|
|
269
|
+
(
|
|
270
|
+
"account_creation_fee",
|
|
271
|
+
Amount(
|
|
272
|
+
kwargs["account_creation_fee"],
|
|
273
|
+
prefix=prefix,
|
|
274
|
+
json_str=json_str,
|
|
275
|
+
),
|
|
276
|
+
),
|
|
277
|
+
(
|
|
278
|
+
"maximum_block_size",
|
|
279
|
+
Uint32(kwargs["maximum_block_size"]),
|
|
280
|
+
),
|
|
281
|
+
("hbd_interest_rate", Uint16(kwargs["hbd_interest_rate"])),
|
|
282
|
+
]
|
|
283
|
+
)
|
|
284
|
+
)
|
|
285
|
+
else:
|
|
286
|
+
super().__init__(
|
|
287
|
+
OrderedDict(
|
|
288
|
+
[
|
|
289
|
+
(
|
|
290
|
+
"account_creation_fee",
|
|
291
|
+
Amount(
|
|
292
|
+
kwargs["account_creation_fee"],
|
|
293
|
+
prefix=prefix,
|
|
294
|
+
json_str=json_str,
|
|
295
|
+
),
|
|
296
|
+
),
|
|
297
|
+
(
|
|
298
|
+
"maximum_block_size",
|
|
299
|
+
Uint32(kwargs["maximum_block_size"]),
|
|
300
|
+
),
|
|
301
|
+
]
|
|
302
|
+
)
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class Price(GrapheneObject):
|
|
307
|
+
def __init__(self, *args, **kwargs):
|
|
308
|
+
if isArgsThisClass(self, args):
|
|
309
|
+
self.data = args[0].data
|
|
310
|
+
else:
|
|
311
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
312
|
+
kwargs = args[0]
|
|
313
|
+
prefix = kwargs.get("prefix", default_prefix)
|
|
314
|
+
super().__init__(
|
|
315
|
+
OrderedDict(
|
|
316
|
+
[
|
|
317
|
+
("base", Amount(kwargs["base"], prefix=prefix)),
|
|
318
|
+
("quote", Amount(kwargs["quote"], prefix=prefix)),
|
|
319
|
+
]
|
|
320
|
+
)
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
class Permission(GrapheneObject):
|
|
325
|
+
def __init__(self, *args, **kwargs):
|
|
326
|
+
if isArgsThisClass(self, args):
|
|
327
|
+
self.data = args[0].data
|
|
328
|
+
else:
|
|
329
|
+
prefix = kwargs.pop("prefix", default_prefix)
|
|
330
|
+
|
|
331
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
332
|
+
kwargs = args[0]
|
|
333
|
+
|
|
334
|
+
# Sort keys (FIXME: ideally, the sorting is part of Public
|
|
335
|
+
# Key and not located here)
|
|
336
|
+
kwargs["key_auths"] = sorted(
|
|
337
|
+
kwargs["key_auths"],
|
|
338
|
+
key=lambda x: repr(PublicKey(x[0], prefix=prefix)),
|
|
339
|
+
reverse=False,
|
|
340
|
+
)
|
|
341
|
+
kwargs["account_auths"] = sorted(
|
|
342
|
+
kwargs["account_auths"],
|
|
343
|
+
key=lambda x: x[0],
|
|
344
|
+
reverse=False,
|
|
345
|
+
)
|
|
346
|
+
accountAuths = Map([(String(e[0]), Uint16(e[1])) for e in kwargs["account_auths"]])
|
|
347
|
+
keyAuths = Map(
|
|
348
|
+
[(PublicKey(e[0], prefix=prefix), Uint16(e[1])) for e in kwargs["key_auths"]]
|
|
349
|
+
)
|
|
350
|
+
super().__init__(
|
|
351
|
+
OrderedDict(
|
|
352
|
+
[
|
|
353
|
+
("weight_threshold", Uint32(int(kwargs["weight_threshold"]))),
|
|
354
|
+
("account_auths", accountAuths),
|
|
355
|
+
("key_auths", keyAuths),
|
|
356
|
+
]
|
|
357
|
+
)
|
|
358
|
+
)
|
|
359
|
+
|
|
360
|
+
|
|
361
|
+
class Extension(Array):
|
|
362
|
+
def __str__(self):
|
|
363
|
+
"""We overload the __str__ function because the json
|
|
364
|
+
representation is different for extensions
|
|
365
|
+
"""
|
|
366
|
+
return json.dumps(self.data if hasattr(self, "data") else [])
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class ExchangeRate(GrapheneObject):
|
|
370
|
+
def __init__(self, *args, **kwargs):
|
|
371
|
+
if isArgsThisClass(self, args):
|
|
372
|
+
self.data = args[0].data
|
|
373
|
+
else:
|
|
374
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
375
|
+
kwargs = args[0]
|
|
376
|
+
|
|
377
|
+
prefix = kwargs.get("prefix", default_prefix)
|
|
378
|
+
json_str = kwargs.get("json_str", False)
|
|
379
|
+
super().__init__(
|
|
380
|
+
OrderedDict(
|
|
381
|
+
[
|
|
382
|
+
(
|
|
383
|
+
"base",
|
|
384
|
+
Amount(kwargs["base"], prefix=prefix, json_str=json_str),
|
|
385
|
+
),
|
|
386
|
+
(
|
|
387
|
+
"quote",
|
|
388
|
+
Amount(kwargs["quote"], prefix=prefix, json_str=json_str),
|
|
389
|
+
),
|
|
390
|
+
]
|
|
391
|
+
)
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class Beneficiary(GrapheneObject):
|
|
396
|
+
def __init__(self, *args, **kwargs):
|
|
397
|
+
if isArgsThisClass(self, args):
|
|
398
|
+
self.data = args[0].data
|
|
399
|
+
else:
|
|
400
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
401
|
+
kwargs = args[0]
|
|
402
|
+
super().__init__(
|
|
403
|
+
OrderedDict(
|
|
404
|
+
[
|
|
405
|
+
("account", String(kwargs["account"])),
|
|
406
|
+
("weight", Int16(kwargs["weight"])),
|
|
407
|
+
]
|
|
408
|
+
)
|
|
409
|
+
)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
class Beneficiaries(GrapheneObject):
|
|
413
|
+
def __init__(self, *args, **kwargs):
|
|
414
|
+
if isArgsThisClass(self, args):
|
|
415
|
+
self.data = args[0].data
|
|
416
|
+
else:
|
|
417
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
418
|
+
kwargs = args[0]
|
|
419
|
+
|
|
420
|
+
super().__init__(
|
|
421
|
+
OrderedDict(
|
|
422
|
+
[
|
|
423
|
+
(
|
|
424
|
+
"beneficiaries",
|
|
425
|
+
Array([Beneficiary(o) for o in kwargs["beneficiaries"]]),
|
|
426
|
+
),
|
|
427
|
+
]
|
|
428
|
+
)
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
class CommentOptionExtensions(Static_variant):
|
|
433
|
+
"""Serialize Comment Payout Beneficiaries.
|
|
434
|
+
|
|
435
|
+
:param list beneficiaries: A static_variant containing beneficiaries.
|
|
436
|
+
|
|
437
|
+
Example::
|
|
438
|
+
|
|
439
|
+
[0,
|
|
440
|
+
{'beneficiaries': [
|
|
441
|
+
{'account': 'furion', 'weight': 10000}
|
|
442
|
+
]}
|
|
443
|
+
]
|
|
444
|
+
|
|
445
|
+
"""
|
|
446
|
+
|
|
447
|
+
def __init__(self, o):
|
|
448
|
+
if isinstance(o, dict) and "type" in o and "value" in o:
|
|
449
|
+
if o["type"] == "comment_payout_beneficiaries":
|
|
450
|
+
type_id = 0
|
|
451
|
+
else:
|
|
452
|
+
type_id = ~0
|
|
453
|
+
data = o["value"]
|
|
454
|
+
else:
|
|
455
|
+
type_id, data = o
|
|
456
|
+
if type_id == 0:
|
|
457
|
+
data = Beneficiaries(data)
|
|
458
|
+
else:
|
|
459
|
+
raise Exception("Unknown CommentOptionExtension")
|
|
460
|
+
super().__init__(data, type_id)
|
|
461
|
+
|
|
462
|
+
def __str__(self):
|
|
463
|
+
if self.type_id == 0:
|
|
464
|
+
return json.dumps({"type": "comment_payout_beneficiaries", "value": self.data.json()})
|
|
465
|
+
return super().__str__()
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
class UpdateProposalEndDate(GrapheneObject):
|
|
469
|
+
def __init__(self, *args, **kwargs):
|
|
470
|
+
if isArgsThisClass(self, args):
|
|
471
|
+
self.data = args[0].data
|
|
472
|
+
else:
|
|
473
|
+
if len(args) == 1 and len(kwargs) == 0:
|
|
474
|
+
kwargs = args[0]
|
|
475
|
+
|
|
476
|
+
super().__init__(
|
|
477
|
+
OrderedDict(
|
|
478
|
+
[
|
|
479
|
+
("end_date", PointInTime(kwargs["end_date"])),
|
|
480
|
+
]
|
|
481
|
+
)
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
class UpdateProposalExtensions(Static_variant):
|
|
486
|
+
"""Serialize Update proposal extensions.
|
|
487
|
+
|
|
488
|
+
:param end_date: A static_variant containing the new end_date.
|
|
489
|
+
|
|
490
|
+
Example::
|
|
491
|
+
|
|
492
|
+
{
|
|
493
|
+
'type': '1',
|
|
494
|
+
'value':
|
|
495
|
+
{
|
|
496
|
+
'end_date': '2021-04-05T13:39:48'
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
"""
|
|
501
|
+
|
|
502
|
+
def __init__(self, o):
|
|
503
|
+
if isinstance(o, dict) and "type" in o and "value" in o:
|
|
504
|
+
if o["type"] == "update_proposal_end_date":
|
|
505
|
+
type_id = 1
|
|
506
|
+
else:
|
|
507
|
+
type_id = ~0
|
|
508
|
+
data = o["value"]
|
|
509
|
+
else:
|
|
510
|
+
type_id, data = o
|
|
511
|
+
|
|
512
|
+
if type_id == 1:
|
|
513
|
+
data = UpdateProposalEndDate(data)
|
|
514
|
+
else:
|
|
515
|
+
raise Exception("Unknown UpdateProposalExtension")
|
|
516
|
+
super().__init__(data, type_id, False)
|
|
517
|
+
|
|
518
|
+
def __str__(self):
|
|
519
|
+
if self.type_id == 1:
|
|
520
|
+
return json.dumps({"type": "update_proposal_end_date", "value": self.data.json()})
|
|
521
|
+
return super().__str__()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#: Object types for object ids
|
|
2
|
+
object_type = {}
|
|
3
|
+
object_type["dynamic_global_property"] = 0
|
|
4
|
+
object_type["reserved0"] = 1
|
|
5
|
+
object_type["account"] = 2
|
|
6
|
+
object_type["witness"] = 3
|
|
7
|
+
object_type["transaction"] = 4
|
|
8
|
+
object_type["block_summary"] = 5
|
|
9
|
+
object_type["chain_property"] = 6
|
|
10
|
+
object_type["witness_schedule"] = 7
|
|
11
|
+
object_type["comment"] = 8
|
|
12
|
+
object_type["category"] = 9
|
|
13
|
+
object_type["comment_vote"] = 10
|
|
14
|
+
object_type["vote"] = 11
|
|
15
|
+
object_type["witness_vote"] = 12
|
|
16
|
+
object_type["limit_order"] = 13
|
|
17
|
+
object_type["feed_history"] = 14
|
|
18
|
+
object_type["convert_request"] = 15
|
|
19
|
+
object_type["liquidity_reward_balance"] = 16
|
|
20
|
+
object_type["operation"] = 17
|
|
21
|
+
object_type["account_history"] = 18
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#: Operation ids
|
|
2
|
+
from typing import Dict, List
|
|
3
|
+
|
|
4
|
+
# https://gitlab.syncad.com/hive/hive/-/blob/master/libraries/protocol/include/hive/protocol/operations.hpp
|
|
5
|
+
ops: List[str] = [
|
|
6
|
+
"vote", # 0
|
|
7
|
+
"comment", # 1
|
|
8
|
+
"transfer", # 2
|
|
9
|
+
"transfer_to_vesting", # 3
|
|
10
|
+
"withdraw_vesting", # 4
|
|
11
|
+
"limit_order_create", # 5
|
|
12
|
+
"limit_order_cancel", # 6
|
|
13
|
+
"feed_publish", # 7
|
|
14
|
+
"convert", # 8
|
|
15
|
+
"account_create", # 9
|
|
16
|
+
"account_update", # 10
|
|
17
|
+
"witness_update", # 11
|
|
18
|
+
"account_witness_vote", # 12
|
|
19
|
+
"account_witness_proxy", # 13
|
|
20
|
+
"pow", # 14
|
|
21
|
+
"custom", # 15
|
|
22
|
+
"report_over_production", # 16
|
|
23
|
+
"delete_comment", # 17
|
|
24
|
+
"custom_json", # 18
|
|
25
|
+
"comment_options", # 19
|
|
26
|
+
"set_withdraw_vesting_route", # 20
|
|
27
|
+
"limit_order_create2", # 21
|
|
28
|
+
"claim_account", # 22
|
|
29
|
+
"create_claimed_account", # 23
|
|
30
|
+
"request_account_recovery", # 24
|
|
31
|
+
"recover_account", # 25
|
|
32
|
+
"change_recovery_account", # 26
|
|
33
|
+
"escrow_transfer", # 27
|
|
34
|
+
"escrow_dispute", # 28
|
|
35
|
+
"escrow_release", # 29
|
|
36
|
+
"pow2", # 30
|
|
37
|
+
"escrow_approve", # 31
|
|
38
|
+
"transfer_to_savings", # 32
|
|
39
|
+
"transfer_from_savings", # 33
|
|
40
|
+
"cancel_transfer_from_savings", # 34
|
|
41
|
+
"custom_binary", # 35
|
|
42
|
+
"decline_voting_rights", # 36
|
|
43
|
+
"reset_account", # 37
|
|
44
|
+
"set_reset_account", # 38
|
|
45
|
+
"claim_reward_balance", # 39
|
|
46
|
+
"delegate_vesting_shares", # 40
|
|
47
|
+
"account_create_with_delegation", # 41
|
|
48
|
+
"witness_set_properties", # 42
|
|
49
|
+
"account_update2", # 43
|
|
50
|
+
"create_proposal", # 44
|
|
51
|
+
"update_proposal_votes", # 45
|
|
52
|
+
"remove_proposal", # 46
|
|
53
|
+
"update_proposal", # 47
|
|
54
|
+
"collateralized_convert", # 48
|
|
55
|
+
"recurrent_transfer", # 49
|
|
56
|
+
# virtual operations below this point
|
|
57
|
+
"fill_convert_request", # last_regular + 1
|
|
58
|
+
"author_reward", # last_regular + 2
|
|
59
|
+
"curation_reward", # last_regular + 3
|
|
60
|
+
"comment_reward", # last_regular + 4
|
|
61
|
+
"liquidity_reward", # last_regular + 5
|
|
62
|
+
"interest", # last_regular + 6
|
|
63
|
+
"fill_vesting_withdraw", # last_regular + 7
|
|
64
|
+
"fill_order", # last_regular + 8
|
|
65
|
+
"shutdown_witness", # last_regular + 9
|
|
66
|
+
"fill_transfer_from_savings", # last_regular + 10
|
|
67
|
+
"hardfork", # last_regular + 11
|
|
68
|
+
"comment_payout_update", # last_regular + 12
|
|
69
|
+
"return_vesting_delegation", # last_regular + 13
|
|
70
|
+
"comment_benefactor_reward", # last_regular + 14
|
|
71
|
+
"producer_reward", # last_regular + 15
|
|
72
|
+
"clear_null_account_balance", # last_regular + 16
|
|
73
|
+
"proposal_pay", # last_regular + 17
|
|
74
|
+
"sps_fund", # last_regular + 18
|
|
75
|
+
"hardfork_hive", # last_regular + 19
|
|
76
|
+
"hardfork_hive_restore", # last_regular + 20
|
|
77
|
+
"delayed_voting", # last_regular + 21
|
|
78
|
+
"consolidate_treasury_balance", # last_regular + 22
|
|
79
|
+
"effective_comment_vote", # last_regular + 23
|
|
80
|
+
"ineffective_delete_comment", # last_regular + 24
|
|
81
|
+
"sps_convert", # last_regular + 25
|
|
82
|
+
"expired_account_notification", # last_regular + 26
|
|
83
|
+
"changed_recovery_account", # last_regular + 27
|
|
84
|
+
"transfer_to_vesting_completed", # last_regular + 28
|
|
85
|
+
"pow_reward", # last_regular + 29
|
|
86
|
+
"vesting_shares_split", # last_regular + 30
|
|
87
|
+
"account_created", # last_regular + 31
|
|
88
|
+
"fill_collateralized_convert_request", # last_regular + 32
|
|
89
|
+
"system_warning", # last_regular + 33,
|
|
90
|
+
"fill_recurrent_transfer", # last_regular + 34
|
|
91
|
+
"failed_recurrent_transfer", # last_regular + 35
|
|
92
|
+
]
|
|
93
|
+
|
|
94
|
+
operations: Dict[str, int] = {o: ops.index(o) for o in ops}
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def getOperationNameForId(i: int) -> str:
|
|
98
|
+
"""Convert an operation id into the corresponding string"""
|
|
99
|
+
for key in operations:
|
|
100
|
+
if operations[key] == i:
|
|
101
|
+
return key
|
|
102
|
+
return "Unknown Operation ID %d" % i
|