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
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import hashlib
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from Cryptodome import Random
|
|
6
|
+
from Cryptodome.Cipher import AES
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AESCipher:
|
|
10
|
+
"""
|
|
11
|
+
A classical AES Cipher. Can use any size of data and any size of password thanks to padding.
|
|
12
|
+
Also ensure the coherence and the type of the data with a unicode to byte converter.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(self, key: Any) -> None:
|
|
16
|
+
self.bs: int = 32
|
|
17
|
+
self.key = hashlib.sha256(AESCipher.str_to_bytes(key)).digest()
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def str_to_bytes(data: Any) -> bytes:
|
|
21
|
+
u_type = type(b"".decode("utf8"))
|
|
22
|
+
if isinstance(data, u_type):
|
|
23
|
+
return data.encode("utf8")
|
|
24
|
+
return data
|
|
25
|
+
|
|
26
|
+
def _pad(self, s: bytes) -> bytes:
|
|
27
|
+
return s + (self.bs - len(s) % self.bs) * AESCipher.str_to_bytes(
|
|
28
|
+
chr(self.bs - len(s) % self.bs)
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
@staticmethod
|
|
32
|
+
def _unpad(s: bytes) -> bytes:
|
|
33
|
+
count = s[-1]
|
|
34
|
+
# Validate padding to prevent padding oracle attacks
|
|
35
|
+
if s[-count:] == bytes([count]) * count:
|
|
36
|
+
return s[:-count]
|
|
37
|
+
raise ValueError("Invalid padding")
|
|
38
|
+
|
|
39
|
+
def encrypt(self, raw: Any) -> str:
|
|
40
|
+
raw = self._pad(AESCipher.str_to_bytes(raw))
|
|
41
|
+
iv = Random.new().read(AES.block_size)
|
|
42
|
+
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
|
43
|
+
return base64.b64encode(iv + cipher.encrypt(raw)).decode("utf-8")
|
|
44
|
+
|
|
45
|
+
def decrypt(self, enc: str) -> str:
|
|
46
|
+
enc_bytes = base64.b64decode(enc)
|
|
47
|
+
iv = enc_bytes[: AES.block_size]
|
|
48
|
+
cipher = AES.new(self.key, AES.MODE_CBC, iv)
|
|
49
|
+
return self._unpad(cipher.decrypt(enc_bytes[AES.block_size :])).decode("utf-8")
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import logging
|
|
3
|
+
import string
|
|
4
|
+
from binascii import hexlify, unhexlify
|
|
5
|
+
from typing import Any, Optional, Union
|
|
6
|
+
|
|
7
|
+
from .prefix import Prefix
|
|
8
|
+
|
|
9
|
+
log = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Base58(Prefix):
|
|
13
|
+
"""Base58 base class
|
|
14
|
+
|
|
15
|
+
This class serves as an abstraction layer to deal with base58 encoded
|
|
16
|
+
strings and their corresponding hex and binary representation throughout the
|
|
17
|
+
library.
|
|
18
|
+
|
|
19
|
+
:param data: Data to initialize object, e.g. pubkey data, address data, ...
|
|
20
|
+
:type data: hex, wif, bip38 encrypted wif, base58 string
|
|
21
|
+
:param str prefix: Prefix to use for Address/PubKey strings (defaults to ``GPH``)
|
|
22
|
+
:return: Base58 object initialized with ``data``
|
|
23
|
+
:rtype: Base58
|
|
24
|
+
:raises ValueError: if data cannot be decoded
|
|
25
|
+
|
|
26
|
+
* ``bytes(Base58)``: Returns the raw data
|
|
27
|
+
* ``str(Base58)``: Returns the readable ``Base58CheckEncoded`` data.
|
|
28
|
+
* ``repr(Base58)``: Gives the hex representation of the data.
|
|
29
|
+
* ``format(Base58,_format)``: Formats the instance according to ``_format``
|
|
30
|
+
|
|
31
|
+
* ``"btc"``: prefixed with ``0x80``. Yields a valid btc address
|
|
32
|
+
* ``"wif"``: prefixed with ``0x00``. Yields a valid wif key
|
|
33
|
+
* ``"bts"``: prefixed with ``BTS``
|
|
34
|
+
* etc.
|
|
35
|
+
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, data: Any, prefix: Optional[str] = None) -> None:
|
|
39
|
+
self.set_prefix(prefix)
|
|
40
|
+
if isinstance(data, Base58):
|
|
41
|
+
data = repr(data)
|
|
42
|
+
if all(c in string.hexdigits for c in data):
|
|
43
|
+
self._hex = data
|
|
44
|
+
elif data[0] == "5" or data[0] == "6":
|
|
45
|
+
self._hex = base58CheckDecode(data)
|
|
46
|
+
elif data[0] == "K" or data[0] == "L":
|
|
47
|
+
self._hex = base58CheckDecode(data)[:-2]
|
|
48
|
+
elif data[: len(self.prefix)] == self.prefix:
|
|
49
|
+
self._hex = gphBase58CheckDecode(data[len(self.prefix) :])
|
|
50
|
+
else:
|
|
51
|
+
raise ValueError("Error loading Base58 object")
|
|
52
|
+
|
|
53
|
+
def __format__(self, _format: str) -> str:
|
|
54
|
+
"""Format output according to argument _format (wif,btc,...)
|
|
55
|
+
|
|
56
|
+
:param str _format: Format to use
|
|
57
|
+
:return: formatted data according to _format
|
|
58
|
+
:rtype: str
|
|
59
|
+
|
|
60
|
+
"""
|
|
61
|
+
if _format.upper() == "WIF":
|
|
62
|
+
return base58CheckEncode(0x80, self._hex)
|
|
63
|
+
elif _format.upper() == "ENCWIF":
|
|
64
|
+
return base58encode(self._hex)
|
|
65
|
+
elif _format.upper() == "BTC":
|
|
66
|
+
return base58CheckEncode(0x00, self._hex)
|
|
67
|
+
else:
|
|
68
|
+
return _format.upper() + str(self)
|
|
69
|
+
|
|
70
|
+
def __repr__(self) -> str:
|
|
71
|
+
"""Returns hex value of object
|
|
72
|
+
|
|
73
|
+
:return: Hex string of instance's data
|
|
74
|
+
:rtype: hex string
|
|
75
|
+
"""
|
|
76
|
+
return self._hex
|
|
77
|
+
|
|
78
|
+
def __str__(self) -> str:
|
|
79
|
+
"""Return graphene-base58CheckEncoded string of data
|
|
80
|
+
|
|
81
|
+
:return: Base58 encoded data
|
|
82
|
+
:rtype: str
|
|
83
|
+
"""
|
|
84
|
+
return gphBase58CheckEncode(self._hex)
|
|
85
|
+
|
|
86
|
+
def __bytes__(self) -> bytes:
|
|
87
|
+
"""Return raw bytes
|
|
88
|
+
|
|
89
|
+
:return: Raw bytes of instance
|
|
90
|
+
:rtype: bytes
|
|
91
|
+
|
|
92
|
+
"""
|
|
93
|
+
return unhexlify(self._hex)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# https://github.com/tochev/python3-cryptocoins/raw/master/cryptocoins/base58.py
|
|
97
|
+
BASE58_ALPHABET = b"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def base58decode(base58_str: str) -> str:
|
|
101
|
+
base58_text = bytes(base58_str, "ascii")
|
|
102
|
+
n = 0
|
|
103
|
+
leading_zeroes_count = 0
|
|
104
|
+
for b in base58_text:
|
|
105
|
+
# b is always int in Python 3 when iterating bytes
|
|
106
|
+
n = n * 58 + BASE58_ALPHABET.find(bytes([b]))
|
|
107
|
+
if n == 0:
|
|
108
|
+
leading_zeroes_count += 1
|
|
109
|
+
res = bytearray()
|
|
110
|
+
while n >= 256:
|
|
111
|
+
div, mod = divmod(n, 256)
|
|
112
|
+
res.insert(0, mod)
|
|
113
|
+
n = div
|
|
114
|
+
else:
|
|
115
|
+
res.insert(0, n)
|
|
116
|
+
return hexlify(bytearray(1) * leading_zeroes_count + res).decode("ascii")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def base58encode(hexstring: str) -> str:
|
|
120
|
+
# Handle odd-length hex strings by padding with leading zero
|
|
121
|
+
if len(hexstring) % 2 == 1:
|
|
122
|
+
hexstring = "0" + hexstring
|
|
123
|
+
byteseq = bytes(unhexlify(bytes(hexstring, "ascii")))
|
|
124
|
+
n = 0
|
|
125
|
+
leading_zeroes_count = 0
|
|
126
|
+
for c in byteseq:
|
|
127
|
+
n = n * 256 + c
|
|
128
|
+
if n == 0:
|
|
129
|
+
leading_zeroes_count += 1
|
|
130
|
+
res = bytearray()
|
|
131
|
+
while n >= 58:
|
|
132
|
+
div, mod = divmod(n, 58)
|
|
133
|
+
res.insert(0, BASE58_ALPHABET[mod])
|
|
134
|
+
n = div
|
|
135
|
+
else:
|
|
136
|
+
res.insert(0, BASE58_ALPHABET[n])
|
|
137
|
+
return (BASE58_ALPHABET[0:1] * leading_zeroes_count + res).decode("ascii")
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def ripemd160(s: Union[str, bytes]) -> bytes:
|
|
141
|
+
ripemd160 = hashlib.new("ripemd160")
|
|
142
|
+
ripemd160.update(unhexlify(s))
|
|
143
|
+
return ripemd160.digest()
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def doublesha256(s: Union[str, bytes]) -> bytes:
|
|
147
|
+
if isinstance(s, str):
|
|
148
|
+
# Handle odd-length hex strings by padding with leading zero
|
|
149
|
+
if len(s) % 2 == 1:
|
|
150
|
+
s = "0" + s
|
|
151
|
+
s = unhexlify(s)
|
|
152
|
+
return hashlib.sha256(hashlib.sha256(s).digest()).digest()
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def b58encode(v: str) -> str:
|
|
156
|
+
return base58encode(v)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def b58decode(v: str) -> str:
|
|
160
|
+
return base58decode(v)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def base58CheckEncode(version: int, payload: str) -> str:
|
|
164
|
+
if isinstance(version, str):
|
|
165
|
+
s = version + payload
|
|
166
|
+
else:
|
|
167
|
+
s = ("%.2x" % version) + payload
|
|
168
|
+
checksum = doublesha256(s)[:4]
|
|
169
|
+
result = s + hexlify(checksum).decode("ascii")
|
|
170
|
+
return base58encode(result)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def base58CheckDecode(s: str, skip_first_bytes: bool = True) -> str:
|
|
174
|
+
s_bytes = unhexlify(base58decode(s))
|
|
175
|
+
dec = hexlify(s_bytes[:-4]).decode("ascii")
|
|
176
|
+
checksum = doublesha256(dec)[:4]
|
|
177
|
+
if not (s_bytes[-4:] == checksum):
|
|
178
|
+
raise AssertionError()
|
|
179
|
+
if skip_first_bytes:
|
|
180
|
+
return dec[2:]
|
|
181
|
+
else:
|
|
182
|
+
return dec
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def gphBase58CheckEncode(s: str) -> str:
|
|
186
|
+
checksum = ripemd160(s)[:4]
|
|
187
|
+
result = s + hexlify(checksum).decode("ascii")
|
|
188
|
+
return base58encode(result)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def gphBase58CheckDecode(s: str) -> str:
|
|
192
|
+
s_bytes = unhexlify(base58decode(s))
|
|
193
|
+
dec = hexlify(s_bytes[:-4]).decode("ascii")
|
|
194
|
+
checksum = ripemd160(dec)[:4]
|
|
195
|
+
if not (s_bytes[-4:] == checksum):
|
|
196
|
+
raise AssertionError()
|
|
197
|
+
return dec
|