coinex-api 0.0.89__py3-none-any.whl → 0.0.110__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.

Potentially problematic release.


This version of coinex-api might be problematic. Click here for more details.

Files changed (197) hide show
  1. coinex/ccxt/__init__.py +1 -1
  2. coinex/ccxt/async_support/__init__.py +1 -1
  3. coinex/ccxt/async_support/base/exchange.py +139 -10
  4. coinex/ccxt/async_support/base/throttler.py +1 -1
  5. coinex/ccxt/async_support/base/ws/cache.py +1 -0
  6. coinex/ccxt/async_support/base/ws/client.py +26 -4
  7. coinex/ccxt/async_support/coinex.py +2 -2
  8. coinex/ccxt/base/exchange.py +587 -91
  9. coinex/ccxt/base/types.py +11 -2
  10. coinex/ccxt/coinex.py +2 -2
  11. coinex/ccxt/pro/__init__.py +1 -1
  12. coinex/ccxt/pro/coinex.py +10 -7
  13. coinex/ccxt/static_dependencies/bip/__init__.py +6 -0
  14. coinex/ccxt/static_dependencies/bip/addr/P2PKH_addr.py +205 -0
  15. coinex/ccxt/static_dependencies/bip/addr/__init__.py +5 -0
  16. coinex/ccxt/static_dependencies/bip/addr/addr_dec_utils.py +125 -0
  17. coinex/ccxt/static_dependencies/bip/addr/addr_key_validator.py +162 -0
  18. coinex/ccxt/static_dependencies/bip/addr/iaddr_decoder.py +48 -0
  19. coinex/ccxt/static_dependencies/bip/addr/iaddr_encoder.py +50 -0
  20. coinex/ccxt/static_dependencies/bip/base58/__init__.py +3 -0
  21. coinex/ccxt/static_dependencies/bip/base58/base58.py +207 -0
  22. coinex/ccxt/static_dependencies/bip/base58/base58_ex.py +25 -0
  23. coinex/ccxt/static_dependencies/bip/base58/base58_xmr.py +155 -0
  24. coinex/ccxt/static_dependencies/bip/bech32/__init__.py +4 -0
  25. coinex/ccxt/static_dependencies/bip/bech32/bch_bech32.py +220 -0
  26. coinex/ccxt/static_dependencies/bip/bech32/bech32.py +235 -0
  27. coinex/ccxt/static_dependencies/bip/bech32/bech32_base.py +246 -0
  28. coinex/ccxt/static_dependencies/bip/bech32/bech32_ex.py +25 -0
  29. coinex/ccxt/static_dependencies/bip/bech32/segwit_bech32.py +173 -0
  30. coinex/ccxt/static_dependencies/bip/bip32/__init__.py +14 -0
  31. coinex/ccxt/static_dependencies/bip/bip32/base/__init__.py +3 -0
  32. coinex/ccxt/static_dependencies/bip/bip32/base/bip32_base.py +581 -0
  33. coinex/ccxt/static_dependencies/bip/bip32/base/ibip32_key_derivator.py +83 -0
  34. coinex/ccxt/static_dependencies/bip/bip32/base/ibip32_mst_key_generator.py +47 -0
  35. coinex/ccxt/static_dependencies/bip/bip32/bip32_const.py +35 -0
  36. coinex/ccxt/static_dependencies/bip/bip32/bip32_ex.py +29 -0
  37. coinex/ccxt/static_dependencies/bip/bip32/bip32_key_data.py +500 -0
  38. coinex/ccxt/static_dependencies/bip/bip32/bip32_key_net_ver.py +83 -0
  39. coinex/ccxt/static_dependencies/bip/bip32/bip32_key_ser.py +294 -0
  40. coinex/ccxt/static_dependencies/bip/bip32/bip32_keys.py +457 -0
  41. coinex/ccxt/static_dependencies/bip/bip32/bip32_path.py +247 -0
  42. coinex/ccxt/static_dependencies/bip/bip32/bip32_utils.py +72 -0
  43. coinex/ccxt/static_dependencies/bip/bip32/kholaw/__init__.py +4 -0
  44. coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_ed25519.py +82 -0
  45. coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_ed25519_key_derivator.py +118 -0
  46. coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_key_derivator_base.py +204 -0
  47. coinex/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_mst_key_generator.py +119 -0
  48. coinex/ccxt/static_dependencies/bip/bip32/slip10/__init__.py +1 -0
  49. coinex/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_key_derivator.py +200 -0
  50. coinex/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_mst_key_generator.py +168 -0
  51. coinex/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_secp256k1.py +82 -0
  52. coinex/ccxt/static_dependencies/bip/bip44/__init__.py +1 -0
  53. coinex/ccxt/static_dependencies/bip/bip44/bip44.py +265 -0
  54. coinex/ccxt/static_dependencies/bip/bip44_base/__init__.py +3 -0
  55. coinex/ccxt/static_dependencies/bip/bip44_base/bip44_base.py +624 -0
  56. coinex/ccxt/static_dependencies/bip/bip44_base/bip44_base_ex.py +25 -0
  57. coinex/ccxt/static_dependencies/bip/bip44_base/bip44_keys.py +225 -0
  58. coinex/ccxt/static_dependencies/bip/coin_conf/__init__.py +2 -0
  59. coinex/ccxt/static_dependencies/bip/coin_conf/coin_conf.py +68 -0
  60. coinex/ccxt/static_dependencies/bip/coin_conf/coins_conf.py +890 -0
  61. coinex/ccxt/static_dependencies/bip/conf/__init__.py +0 -0
  62. coinex/ccxt/static_dependencies/bip/conf/bip44/__init__.py +3 -0
  63. coinex/ccxt/static_dependencies/bip/conf/bip44/bip44_coins.py +126 -0
  64. coinex/ccxt/static_dependencies/bip/conf/bip44/bip44_conf.py +1360 -0
  65. coinex/ccxt/static_dependencies/bip/conf/bip44/bip44_conf_getter.py +153 -0
  66. coinex/ccxt/static_dependencies/bip/conf/bip49/__init__.py +3 -0
  67. coinex/ccxt/static_dependencies/bip/conf/bip49/bip49_coins.py +53 -0
  68. coinex/ccxt/static_dependencies/bip/conf/bip49/bip49_conf.py +366 -0
  69. coinex/ccxt/static_dependencies/bip/conf/bip49/bip49_conf_getter.py +80 -0
  70. coinex/ccxt/static_dependencies/bip/conf/bip84/__init__.py +3 -0
  71. coinex/ccxt/static_dependencies/bip/conf/bip84/bip84_coins.py +39 -0
  72. coinex/ccxt/static_dependencies/bip/conf/bip84/bip84_conf.py +113 -0
  73. coinex/ccxt/static_dependencies/bip/conf/bip84/bip84_conf_getter.py +66 -0
  74. coinex/ccxt/static_dependencies/bip/conf/bip86/__init__.py +3 -0
  75. coinex/ccxt/static_dependencies/bip/conf/bip86/bip86_coins.py +37 -0
  76. coinex/ccxt/static_dependencies/bip/conf/bip86/bip86_conf.py +83 -0
  77. coinex/ccxt/static_dependencies/bip/conf/bip86/bip86_conf_getter.py +64 -0
  78. coinex/ccxt/static_dependencies/bip/conf/common/__init__.py +8 -0
  79. coinex/ccxt/static_dependencies/bip/conf/common/atom_addr.py +104 -0
  80. coinex/ccxt/static_dependencies/bip/conf/common/bip_bitcoin_cash_conf.py +106 -0
  81. coinex/ccxt/static_dependencies/bip/conf/common/bip_coin_conf.py +217 -0
  82. coinex/ccxt/static_dependencies/bip/conf/common/bip_coins.py +28 -0
  83. coinex/ccxt/static_dependencies/bip/conf/common/bip_conf_const.py +30 -0
  84. coinex/ccxt/static_dependencies/bip/conf/common/bip_litecoin_conf.py +121 -0
  85. coinex/ccxt/static_dependencies/bip/ecc/__init__.py +42 -0
  86. coinex/ccxt/static_dependencies/bip/ecc/common/__init__.py +0 -0
  87. coinex/ccxt/static_dependencies/bip/ecc/common/dummy_point.py +219 -0
  88. coinex/ccxt/static_dependencies/bip/ecc/common/ikeys.py +263 -0
  89. coinex/ccxt/static_dependencies/bip/ecc/common/ipoint.py +190 -0
  90. coinex/ccxt/static_dependencies/bip/ecc/conf.py +28 -0
  91. coinex/ccxt/static_dependencies/bip/ecc/curve/__init__.py +0 -0
  92. coinex/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve.py +121 -0
  93. coinex/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve_getter.py +74 -0
  94. coinex/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve_types.py +37 -0
  95. coinex/ccxt/static_dependencies/bip/ecc/ecdsa/__init__.py +0 -0
  96. coinex/ccxt/static_dependencies/bip/ecc/ecdsa/ecdsa_keys.py +36 -0
  97. coinex/ccxt/static_dependencies/bip/ecc/secp256k1/__init__.py +0 -0
  98. coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1.py +36 -0
  99. coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_const.py +59 -0
  100. coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_keys_ecdsa.py +248 -0
  101. coinex/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_point_ecdsa.py +234 -0
  102. coinex/ccxt/static_dependencies/bip/slip/__init__.py +0 -0
  103. coinex/ccxt/static_dependencies/bip/slip/slip173/__init__.py +1 -0
  104. coinex/ccxt/static_dependencies/bip/slip/slip173/slip173.py +60 -0
  105. coinex/ccxt/static_dependencies/bip/slip/slip32/__init__.py +4 -0
  106. coinex/ccxt/static_dependencies/bip/slip/slip32/slip32.py +322 -0
  107. coinex/ccxt/static_dependencies/bip/slip/slip32/slip32_key_net_ver.py +62 -0
  108. coinex/ccxt/static_dependencies/bip/slip/slip44/__init__.py +1 -0
  109. coinex/ccxt/static_dependencies/bip/slip/slip44/slip44.py +81 -0
  110. coinex/ccxt/static_dependencies/bip/utils/__init__.py +0 -0
  111. coinex/ccxt/static_dependencies/bip/utils/conf/__init__.py +1 -0
  112. coinex/ccxt/static_dependencies/bip/utils/conf/coin_names.py +59 -0
  113. coinex/ccxt/static_dependencies/bip/utils/crypto/__init__.py +10 -0
  114. coinex/ccxt/static_dependencies/bip/utils/crypto/aes_ecb.py +152 -0
  115. coinex/ccxt/static_dependencies/bip/utils/crypto/blake2.py +191 -0
  116. coinex/ccxt/static_dependencies/bip/utils/crypto/chacha20_poly1305.py +101 -0
  117. coinex/ccxt/static_dependencies/bip/utils/crypto/hash160.py +57 -0
  118. coinex/ccxt/static_dependencies/bip/utils/crypto/hmac.py +118 -0
  119. coinex/ccxt/static_dependencies/bip/utils/crypto/pbkdf2.py +66 -0
  120. coinex/ccxt/static_dependencies/bip/utils/crypto/ripemd.py +58 -0
  121. coinex/ccxt/static_dependencies/bip/utils/crypto/scrypt.py +66 -0
  122. coinex/ccxt/static_dependencies/bip/utils/crypto/sha2.py +182 -0
  123. coinex/ccxt/static_dependencies/bip/utils/crypto/sha3.py +99 -0
  124. coinex/ccxt/static_dependencies/bip/utils/misc/__init__.py +7 -0
  125. coinex/ccxt/static_dependencies/bip/utils/misc/algo.py +108 -0
  126. coinex/ccxt/static_dependencies/bip/utils/misc/base32.py +151 -0
  127. coinex/ccxt/static_dependencies/bip/utils/misc/bit.py +115 -0
  128. coinex/ccxt/static_dependencies/bip/utils/misc/bytes.py +200 -0
  129. coinex/ccxt/static_dependencies/bip/utils/misc/data_bytes.py +181 -0
  130. coinex/ccxt/static_dependencies/bip/utils/misc/integer.py +97 -0
  131. coinex/ccxt/static_dependencies/bip/utils/misc/string.py +54 -0
  132. coinex/ccxt/static_dependencies/bip/utils/typing/__init__.py +1 -0
  133. coinex/ccxt/static_dependencies/bip/utils/typing/literal.py +27 -0
  134. coinex/ccxt/static_dependencies/bip/wif/__init__.py +1 -0
  135. coinex/ccxt/static_dependencies/bip/wif/wif.py +144 -0
  136. coinex/ccxt/static_dependencies/dydx_v4_client/amino/amino_pb2.py +31 -0
  137. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/base/v1beta1/coin_pb2.py +47 -0
  138. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/multisig/keys_pb2.py +33 -0
  139. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/multisig/v1beta1/multisig_pb2.py +33 -0
  140. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/secp256k1/keys_pb2.py +34 -0
  141. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/msg/v1/msg_pb2.py +27 -0
  142. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/tx/signing/v1beta1/signing_pb2.py +38 -0
  143. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos/tx/v1beta1/tx_pb2.py +75 -0
  144. coinex/ccxt/static_dependencies/dydx_v4_client/cosmos_proto/cosmos_pb2.py +36 -0
  145. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/accountplus_pb2.py +31 -0
  146. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/genesis_pb2.py +40 -0
  147. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/models_pb2.py +26 -0
  148. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/params_pb2.py +29 -0
  149. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/query_pb2.py +57 -0
  150. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/tx_pb2.py +51 -0
  151. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/block_rate_limit_config_pb2.py +37 -0
  152. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/clob_pair_pb2.py +41 -0
  153. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/equity_tier_limit_config_pb2.py +35 -0
  154. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/finalize_block_pb2.py +27 -0
  155. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/liquidations_config_pb2.py +39 -0
  156. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/liquidations_pb2.py +38 -0
  157. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/matches_pb2.py +55 -0
  158. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/mev_pb2.py +49 -0
  159. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/operation_pb2.py +32 -0
  160. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/order_pb2.py +86 -0
  161. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/order_removals_pb2.py +32 -0
  162. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/process_proposer_matches_events_pb2.py +42 -0
  163. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/query_pb2.py +124 -0
  164. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/streaming_pb2.py +29 -0
  165. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/tx_pb2.py +117 -0
  166. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/genesis_pb2.py +26 -0
  167. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/query_pb2.py +26 -0
  168. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/transfer_pb2.py +61 -0
  169. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/tx_pb2.py +37 -0
  170. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/asset_position_pb2.py +29 -0
  171. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/genesis_pb2.py +30 -0
  172. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/perpetual_position_pb2.py +33 -0
  173. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/query_pb2.py +63 -0
  174. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/streaming_pb2.py +31 -0
  175. coinex/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/subaccount_pb2.py +33 -0
  176. coinex/ccxt/static_dependencies/dydx_v4_client/gogoproto/gogo_pb2.py +102 -0
  177. coinex/ccxt/static_dependencies/dydx_v4_client/registry.py +38 -0
  178. coinex/ccxt/static_dependencies/ecdsa/ellipticcurve.py +842 -0
  179. coinex/ccxt/static_dependencies/ecdsa/keys.py +15 -4
  180. coinex/ccxt/static_dependencies/mnemonic/__init__.py +4 -0
  181. coinex/ccxt/static_dependencies/mnemonic/mnemonic.py +282 -0
  182. coinex/ccxt/static_dependencies/mnemonic/py.typed +1 -0
  183. coinex/ccxt/static_dependencies/mnemonic/wordlist/chinese_simplified.txt +2048 -0
  184. coinex/ccxt/static_dependencies/mnemonic/wordlist/chinese_traditional.txt +2048 -0
  185. coinex/ccxt/static_dependencies/mnemonic/wordlist/czech.txt +2048 -0
  186. coinex/ccxt/static_dependencies/mnemonic/wordlist/english.txt +2048 -0
  187. coinex/ccxt/static_dependencies/mnemonic/wordlist/french.txt +2048 -0
  188. coinex/ccxt/static_dependencies/mnemonic/wordlist/italian.txt +2048 -0
  189. coinex/ccxt/static_dependencies/mnemonic/wordlist/japanese.txt +2048 -0
  190. coinex/ccxt/static_dependencies/mnemonic/wordlist/korean.txt +2048 -0
  191. coinex/ccxt/static_dependencies/mnemonic/wordlist/portuguese.txt +2048 -0
  192. coinex/ccxt/static_dependencies/mnemonic/wordlist/russian.txt +2048 -0
  193. coinex/ccxt/static_dependencies/mnemonic/wordlist/spanish.txt +2048 -0
  194. coinex/ccxt/static_dependencies/mnemonic/wordlist/turkish.txt +2048 -0
  195. {coinex_api-0.0.89.dist-info → coinex_api-0.0.110.dist-info}/METADATA +3 -3
  196. {coinex_api-0.0.89.dist-info → coinex_api-0.0.110.dist-info}/RECORD +197 -17
  197. {coinex_api-0.0.89.dist-info → coinex_api-0.0.110.dist-info}/WHEEL +1 -1
@@ -103,15 +103,26 @@ class VerifyingKey:
103
103
  verifying_keys = [klass.from_public_point(pk.point, curve, hashfunc) for pk in pks]
104
104
  return verifying_keys
105
105
 
106
- def to_string(self):
107
- # VerifyingKey.from_string(vk.to_string()) == vk as long as the
108
- # curves are the same: the curve itself is not included in the
109
- # serialized form
106
+ def _raw_encode(self):
107
+ """Convert the point to the :term:`raw encoding`."""
110
108
  order = self.pubkey.order
111
109
  x_str = number_to_string(self.pubkey.point.x(), order)
112
110
  y_str = number_to_string(self.pubkey.point.y(), order)
113
111
  return x_str + y_str
114
112
 
113
+ def _compressed_encode(self):
114
+ """Encode the point into the compressed form."""
115
+ order = self.pubkey.order
116
+ x_str = number_to_string(self.pubkey.point.x(), order)
117
+ if self.pubkey.point.y() & 1:
118
+ return b"\x03" + x_str
119
+ return b"\x02" + x_str
120
+
121
+ def to_string(self, encoding = 'uncompressed'):
122
+ if encoding == "compressed":
123
+ return self._compressed_encode()
124
+ return self._raw_encode()
125
+
115
126
  def to_pem(self):
116
127
  return der.topem(self.to_der(), "PUBLIC KEY")
117
128
 
@@ -0,0 +1,4 @@
1
+ # https://github.com/trezor/python-mnemonic/tree/v0.21
2
+ from .mnemonic import Mnemonic
3
+
4
+ __all__ = ["Mnemonic"]
@@ -0,0 +1,282 @@
1
+ #
2
+ # Copyright (c) 2013 Pavol Rusnak
3
+ # Copyright (c) 2017 mruddy
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ # this software and associated documentation files (the "Software"), to deal in
7
+ # the Software without restriction, including without limitation the rights to
8
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
+ # of the Software, and to permit persons to whom the Software is furnished to do
10
+ # so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+ #
22
+ from __future__ import annotations
23
+
24
+ import hashlib
25
+ import hmac
26
+ import itertools
27
+ import os
28
+ import secrets
29
+ import typing as t
30
+ import unicodedata
31
+
32
+ PBKDF2_ROUNDS = 2048
33
+
34
+
35
+ class ConfigurationError(Exception):
36
+ pass
37
+
38
+
39
+ # Refactored code segments from <https://github.com/keis/base58>
40
+ def b58encode(v: bytes) -> str:
41
+ alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
42
+
43
+ p, acc = 1, 0
44
+ for c in reversed(v):
45
+ acc += p * c
46
+ p = p << 8
47
+
48
+ string = ""
49
+ while acc:
50
+ acc, idx = divmod(acc, 58)
51
+ string = alphabet[idx : idx + 1] + string
52
+ return string
53
+
54
+
55
+ class Mnemonic(object):
56
+ def __init__(self, language: str = "english", wordlist: list[str] | None = None):
57
+ self.radix = 2048
58
+ self.language = language
59
+
60
+ if wordlist is None:
61
+ d = os.path.join(os.path.dirname(__file__), f"wordlist/{language}.txt")
62
+ if os.path.exists(d) and os.path.isfile(d):
63
+ with open(d, "r", encoding="utf-8") as f:
64
+ wordlist = [w.strip() for w in f.readlines()]
65
+ else:
66
+ raise ConfigurationError("Language not detected")
67
+
68
+ if len(wordlist) != self.radix:
69
+ raise ConfigurationError(f"Wordlist must contain {self.radix} words.")
70
+
71
+ self.wordlist = wordlist
72
+ # Japanese must be joined by ideographic space
73
+ self.delimiter = "\u3000" if language == "japanese" else " "
74
+
75
+ @classmethod
76
+ def list_languages(cls) -> list[str]:
77
+ return [
78
+ f.split(".")[0]
79
+ for f in os.listdir(os.path.join(os.path.dirname(__file__), "wordlist"))
80
+ if f.endswith(".txt")
81
+ ]
82
+
83
+ @staticmethod
84
+ def normalize_string(txt: t.AnyStr) -> str:
85
+ if isinstance(txt, bytes):
86
+ utxt = txt.decode("utf8")
87
+ elif isinstance(txt, str):
88
+ utxt = txt
89
+ else:
90
+ raise TypeError("String value expected")
91
+
92
+ return unicodedata.normalize("NFKD", utxt)
93
+
94
+ @classmethod
95
+ def detect_language(cls, code: str) -> str:
96
+ """Scan the Mnemonic until the language becomes unambiguous, including as abbreviation prefixes.
97
+
98
+ Unfortunately, there are valid words that are ambiguous between languages, which are complete words
99
+ in one language and are prefixes in another:
100
+
101
+ english: abandon ... about
102
+ french: abandon ... aboutir
103
+
104
+ If prefixes remain ambiguous, require exactly one language where word(s) match exactly.
105
+ """
106
+ code = cls.normalize_string(code)
107
+ possible = set(cls(lang) for lang in cls.list_languages())
108
+ words = set(code.split())
109
+ for word in words:
110
+ # possible languages have candidate(s) starting with the word/prefix
111
+ possible = set(
112
+ p for p in possible if any(c.startswith(word) for c in p.wordlist)
113
+ )
114
+ if not possible:
115
+ raise ConfigurationError(f"Language unrecognized for {word!r}")
116
+ if len(possible) == 1:
117
+ return possible.pop().language
118
+ # Multiple languages match: A prefix in many, but an exact match in one determines language.
119
+ complete = set()
120
+ for word in words:
121
+ exact = set(p for p in possible if word in p.wordlist)
122
+ if len(exact) == 1:
123
+ complete.update(exact)
124
+ if len(complete) == 1:
125
+ return complete.pop().language
126
+ raise ConfigurationError(
127
+ f"Language ambiguous between {', '.join(p.language for p in possible)}"
128
+ )
129
+
130
+ def generate(self, strength: int = 128) -> str:
131
+ """
132
+ Create a new mnemonic using a random generated number as entropy.
133
+
134
+ As defined in BIP39, the entropy must be a multiple of 32 bits, and its size must be between 128 and 256 bits.
135
+ Therefore the possible values for `strength` are 128, 160, 192, 224 and 256.
136
+
137
+ If not provided, the default entropy length will be set to 128 bits.
138
+
139
+ The return is a list of words that encodes the generated entropy.
140
+
141
+ :param strength: Number of bytes used as entropy
142
+ :type strength: int
143
+ :return: A randomly generated mnemonic
144
+ :rtype: str
145
+ """
146
+ if strength not in [128, 160, 192, 224, 256]:
147
+ raise ValueError(
148
+ "Invalid strength value. Allowed values are [128, 160, 192, 224, 256]."
149
+ )
150
+ return self.to_mnemonic(secrets.token_bytes(strength // 8))
151
+
152
+ # Adapted from <http://tinyurl.com/oxmn476>
153
+ def to_entropy(self, words: list[str] | str) -> bytearray:
154
+ if not isinstance(words, list):
155
+ words = words.split(" ")
156
+ if len(words) not in [12, 15, 18, 21, 24]:
157
+ raise ValueError(
158
+ "Number of words must be one of the following: [12, 15, 18, 21, 24], but it is not (%d)."
159
+ % len(words)
160
+ )
161
+ # Look up all the words in the list and construct the
162
+ # concatenation of the original entropy and the checksum.
163
+ concatLenBits = len(words) * 11
164
+ concatBits = [False] * concatLenBits
165
+ wordindex = 0
166
+ for word in words:
167
+ # Find the words index in the wordlist
168
+ ndx = self.wordlist.index(self.normalize_string(word))
169
+ if ndx < 0:
170
+ raise LookupError('Unable to find "%s" in word list.' % word)
171
+ # Set the next 11 bits to the value of the index.
172
+ for ii in range(11):
173
+ concatBits[(wordindex * 11) + ii] = (ndx & (1 << (10 - ii))) != 0
174
+ wordindex += 1
175
+ checksumLengthBits = concatLenBits // 33
176
+ entropyLengthBits = concatLenBits - checksumLengthBits
177
+ # Extract original entropy as bytes.
178
+ entropy = bytearray(entropyLengthBits // 8)
179
+ for ii in range(len(entropy)):
180
+ for jj in range(8):
181
+ if concatBits[(ii * 8) + jj]:
182
+ entropy[ii] |= 1 << (7 - jj)
183
+ # Take the digest of the entropy.
184
+ hashBytes = hashlib.sha256(entropy).digest()
185
+ hashBits = list(
186
+ itertools.chain.from_iterable(
187
+ [c & (1 << (7 - i)) != 0 for i in range(8)] for c in hashBytes
188
+ )
189
+ )
190
+ # Check all the checksum bits.
191
+ for i in range(checksumLengthBits):
192
+ if concatBits[entropyLengthBits + i] != hashBits[i]:
193
+ raise ValueError("Failed checksum.")
194
+ return entropy
195
+
196
+ def to_mnemonic(self, data: bytes) -> str:
197
+ if len(data) not in [16, 20, 24, 28, 32]:
198
+ raise ValueError(
199
+ f"Data length should be one of the following: [16, 20, 24, 28, 32], but it is not {len(data)}."
200
+ )
201
+ h = hashlib.sha256(data).hexdigest()
202
+ b = (
203
+ bin(int.from_bytes(data, byteorder="big"))[2:].zfill(len(data) * 8)
204
+ + bin(int(h, 16))[2:].zfill(256)[: len(data) * 8 // 32]
205
+ )
206
+ result = []
207
+ for i in range(len(b) // 11):
208
+ idx = int(b[i * 11 : (i + 1) * 11], 2)
209
+ result.append(self.wordlist[idx])
210
+ return self.delimiter.join(result)
211
+
212
+ def check(self, mnemonic: str) -> bool:
213
+ mnemonic_list = self.normalize_string(mnemonic).split(" ")
214
+ # list of valid mnemonic lengths
215
+ if len(mnemonic_list) not in [12, 15, 18, 21, 24]:
216
+ return False
217
+ try:
218
+ idx = map(
219
+ lambda x: bin(self.wordlist.index(x))[2:].zfill(11), mnemonic_list
220
+ )
221
+ b = "".join(idx)
222
+ except ValueError:
223
+ return False
224
+ l = len(b) # noqa: E741
225
+ d = b[: l // 33 * 32]
226
+ h = b[-l // 33 :]
227
+ nd = int(d, 2).to_bytes(l // 33 * 4, byteorder="big")
228
+ nh = bin(int(hashlib.sha256(nd).hexdigest(), 16))[2:].zfill(256)[: l // 33]
229
+ return h == nh
230
+
231
+ def expand_word(self, prefix: str) -> str:
232
+ if prefix in self.wordlist:
233
+ return prefix
234
+ else:
235
+ matches = [word for word in self.wordlist if word.startswith(prefix)]
236
+ if len(matches) == 1: # matched exactly one word in the wordlist
237
+ return matches[0]
238
+ else:
239
+ # exact match not found.
240
+ # this is not a validation routine, just return the input
241
+ return prefix
242
+
243
+ def expand(self, mnemonic: str) -> str:
244
+ return " ".join(map(self.expand_word, mnemonic.split(" ")))
245
+
246
+ @classmethod
247
+ def to_seed(cls, mnemonic: str, passphrase: str = "") -> bytes:
248
+ mnemonic = cls.normalize_string(mnemonic)
249
+ passphrase = cls.normalize_string(passphrase)
250
+ passphrase = "mnemonic" + passphrase
251
+ mnemonic_bytes = mnemonic.encode("utf-8")
252
+ passphrase_bytes = passphrase.encode("utf-8")
253
+ stretched = hashlib.pbkdf2_hmac(
254
+ "sha512", mnemonic_bytes, passphrase_bytes, PBKDF2_ROUNDS
255
+ )
256
+ return stretched[:64]
257
+
258
+ @staticmethod
259
+ def to_hd_master_key(seed: bytes, testnet: bool = False) -> str:
260
+ if len(seed) != 64:
261
+ raise ValueError("Provided seed should have length of 64")
262
+
263
+ # Compute HMAC-SHA512 of seed
264
+ seed = hmac.new(b"Bitcoin seed", seed, digestmod=hashlib.sha512).digest()
265
+
266
+ # Serialization format can be found at: https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format
267
+ xprv = b"\x04\x88\xad\xe4" # Version for private mainnet
268
+ if testnet:
269
+ xprv = b"\x04\x35\x83\x94" # Version for private testnet
270
+ xprv += b"\x00" * 9 # Depth, parent fingerprint, and child number
271
+ xprv += seed[32:] # Chain code
272
+ xprv += b"\x00" + seed[:32] # Master key
273
+
274
+ # Double hash using SHA256
275
+ hashed_xprv = hashlib.sha256(xprv).digest()
276
+ hashed_xprv = hashlib.sha256(hashed_xprv).digest()
277
+
278
+ # Append 4 bytes of checksum
279
+ xprv += hashed_xprv[:4]
280
+
281
+ # Return base58
282
+ return b58encode(xprv)
@@ -0,0 +1 @@
1
+ # Marker file for PEP 561.