bitmart 0.0.116__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.
Files changed (466) hide show
  1. bitmart/__init__.py +7 -0
  2. bitmart/ccxt/__init__.py +102 -0
  3. bitmart/ccxt/abstract/bitmart.py +117 -0
  4. bitmart/ccxt/async_support/__init__.py +81 -0
  5. bitmart/ccxt/async_support/base/__init__.py +1 -0
  6. bitmart/ccxt/async_support/base/exchange.py +2315 -0
  7. bitmart/ccxt/async_support/base/throttler.py +88 -0
  8. bitmart/ccxt/async_support/base/ws/__init__.py +38 -0
  9. bitmart/ccxt/async_support/base/ws/cache.py +219 -0
  10. bitmart/ccxt/async_support/base/ws/client.py +350 -0
  11. bitmart/ccxt/async_support/base/ws/functions.py +59 -0
  12. bitmart/ccxt/async_support/base/ws/future.py +46 -0
  13. bitmart/ccxt/async_support/base/ws/order_book.py +78 -0
  14. bitmart/ccxt/async_support/base/ws/order_book_side.py +174 -0
  15. bitmart/ccxt/async_support/bitmart.py +5361 -0
  16. bitmart/ccxt/base/__init__.py +27 -0
  17. bitmart/ccxt/base/decimal_to_precision.py +178 -0
  18. bitmart/ccxt/base/errors.py +273 -0
  19. bitmart/ccxt/base/exchange.py +7642 -0
  20. bitmart/ccxt/base/precise.py +297 -0
  21. bitmart/ccxt/base/types.py +619 -0
  22. bitmart/ccxt/bitmart.py +5361 -0
  23. bitmart/ccxt/pro/__init__.py +66 -0
  24. bitmart/ccxt/pro/bitmart.py +1917 -0
  25. bitmart/ccxt/static_dependencies/README.md +1 -0
  26. bitmart/ccxt/static_dependencies/__init__.py +1 -0
  27. bitmart/ccxt/static_dependencies/bip/__init__.py +6 -0
  28. bitmart/ccxt/static_dependencies/bip/addr/P2PKH_addr.py +205 -0
  29. bitmart/ccxt/static_dependencies/bip/addr/__init__.py +5 -0
  30. bitmart/ccxt/static_dependencies/bip/addr/addr_dec_utils.py +125 -0
  31. bitmart/ccxt/static_dependencies/bip/addr/addr_key_validator.py +162 -0
  32. bitmart/ccxt/static_dependencies/bip/addr/iaddr_decoder.py +48 -0
  33. bitmart/ccxt/static_dependencies/bip/addr/iaddr_encoder.py +50 -0
  34. bitmart/ccxt/static_dependencies/bip/base58/__init__.py +3 -0
  35. bitmart/ccxt/static_dependencies/bip/base58/base58.py +207 -0
  36. bitmart/ccxt/static_dependencies/bip/base58/base58_ex.py +25 -0
  37. bitmart/ccxt/static_dependencies/bip/base58/base58_xmr.py +155 -0
  38. bitmart/ccxt/static_dependencies/bip/bech32/__init__.py +4 -0
  39. bitmart/ccxt/static_dependencies/bip/bech32/bch_bech32.py +220 -0
  40. bitmart/ccxt/static_dependencies/bip/bech32/bech32.py +235 -0
  41. bitmart/ccxt/static_dependencies/bip/bech32/bech32_base.py +246 -0
  42. bitmart/ccxt/static_dependencies/bip/bech32/bech32_ex.py +25 -0
  43. bitmart/ccxt/static_dependencies/bip/bech32/segwit_bech32.py +173 -0
  44. bitmart/ccxt/static_dependencies/bip/bip32/__init__.py +14 -0
  45. bitmart/ccxt/static_dependencies/bip/bip32/base/__init__.py +3 -0
  46. bitmart/ccxt/static_dependencies/bip/bip32/base/bip32_base.py +581 -0
  47. bitmart/ccxt/static_dependencies/bip/bip32/base/ibip32_key_derivator.py +83 -0
  48. bitmart/ccxt/static_dependencies/bip/bip32/base/ibip32_mst_key_generator.py +47 -0
  49. bitmart/ccxt/static_dependencies/bip/bip32/bip32_const.py +35 -0
  50. bitmart/ccxt/static_dependencies/bip/bip32/bip32_ex.py +29 -0
  51. bitmart/ccxt/static_dependencies/bip/bip32/bip32_key_data.py +500 -0
  52. bitmart/ccxt/static_dependencies/bip/bip32/bip32_key_net_ver.py +83 -0
  53. bitmart/ccxt/static_dependencies/bip/bip32/bip32_key_ser.py +294 -0
  54. bitmart/ccxt/static_dependencies/bip/bip32/bip32_keys.py +457 -0
  55. bitmart/ccxt/static_dependencies/bip/bip32/bip32_path.py +247 -0
  56. bitmart/ccxt/static_dependencies/bip/bip32/bip32_utils.py +72 -0
  57. bitmart/ccxt/static_dependencies/bip/bip32/kholaw/__init__.py +4 -0
  58. bitmart/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_ed25519.py +82 -0
  59. bitmart/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_ed25519_key_derivator.py +118 -0
  60. bitmart/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_key_derivator_base.py +204 -0
  61. bitmart/ccxt/static_dependencies/bip/bip32/kholaw/bip32_kholaw_mst_key_generator.py +119 -0
  62. bitmart/ccxt/static_dependencies/bip/bip32/slip10/__init__.py +1 -0
  63. bitmart/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_key_derivator.py +200 -0
  64. bitmart/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_mst_key_generator.py +168 -0
  65. bitmart/ccxt/static_dependencies/bip/bip32/slip10/bip32_slip10_secp256k1.py +82 -0
  66. bitmart/ccxt/static_dependencies/bip/bip44/__init__.py +1 -0
  67. bitmart/ccxt/static_dependencies/bip/bip44/bip44.py +265 -0
  68. bitmart/ccxt/static_dependencies/bip/bip44_base/__init__.py +3 -0
  69. bitmart/ccxt/static_dependencies/bip/bip44_base/bip44_base.py +624 -0
  70. bitmart/ccxt/static_dependencies/bip/bip44_base/bip44_base_ex.py +25 -0
  71. bitmart/ccxt/static_dependencies/bip/bip44_base/bip44_keys.py +225 -0
  72. bitmart/ccxt/static_dependencies/bip/coin_conf/__init__.py +2 -0
  73. bitmart/ccxt/static_dependencies/bip/coin_conf/coin_conf.py +68 -0
  74. bitmart/ccxt/static_dependencies/bip/coin_conf/coins_conf.py +890 -0
  75. bitmart/ccxt/static_dependencies/bip/conf/__init__.py +0 -0
  76. bitmart/ccxt/static_dependencies/bip/conf/bip44/__init__.py +3 -0
  77. bitmart/ccxt/static_dependencies/bip/conf/bip44/bip44_coins.py +126 -0
  78. bitmart/ccxt/static_dependencies/bip/conf/bip44/bip44_conf.py +1360 -0
  79. bitmart/ccxt/static_dependencies/bip/conf/bip44/bip44_conf_getter.py +153 -0
  80. bitmart/ccxt/static_dependencies/bip/conf/bip49/__init__.py +3 -0
  81. bitmart/ccxt/static_dependencies/bip/conf/bip49/bip49_coins.py +53 -0
  82. bitmart/ccxt/static_dependencies/bip/conf/bip49/bip49_conf.py +366 -0
  83. bitmart/ccxt/static_dependencies/bip/conf/bip49/bip49_conf_getter.py +80 -0
  84. bitmart/ccxt/static_dependencies/bip/conf/bip84/__init__.py +3 -0
  85. bitmart/ccxt/static_dependencies/bip/conf/bip84/bip84_coins.py +39 -0
  86. bitmart/ccxt/static_dependencies/bip/conf/bip84/bip84_conf.py +113 -0
  87. bitmart/ccxt/static_dependencies/bip/conf/bip84/bip84_conf_getter.py +66 -0
  88. bitmart/ccxt/static_dependencies/bip/conf/bip86/__init__.py +3 -0
  89. bitmart/ccxt/static_dependencies/bip/conf/bip86/bip86_coins.py +37 -0
  90. bitmart/ccxt/static_dependencies/bip/conf/bip86/bip86_conf.py +83 -0
  91. bitmart/ccxt/static_dependencies/bip/conf/bip86/bip86_conf_getter.py +64 -0
  92. bitmart/ccxt/static_dependencies/bip/conf/common/__init__.py +8 -0
  93. bitmart/ccxt/static_dependencies/bip/conf/common/atom_addr.py +104 -0
  94. bitmart/ccxt/static_dependencies/bip/conf/common/bip_bitcoin_cash_conf.py +106 -0
  95. bitmart/ccxt/static_dependencies/bip/conf/common/bip_coin_conf.py +217 -0
  96. bitmart/ccxt/static_dependencies/bip/conf/common/bip_coins.py +28 -0
  97. bitmart/ccxt/static_dependencies/bip/conf/common/bip_conf_const.py +30 -0
  98. bitmart/ccxt/static_dependencies/bip/conf/common/bip_litecoin_conf.py +121 -0
  99. bitmart/ccxt/static_dependencies/bip/ecc/__init__.py +42 -0
  100. bitmart/ccxt/static_dependencies/bip/ecc/common/__init__.py +0 -0
  101. bitmart/ccxt/static_dependencies/bip/ecc/common/dummy_point.py +219 -0
  102. bitmart/ccxt/static_dependencies/bip/ecc/common/ikeys.py +263 -0
  103. bitmart/ccxt/static_dependencies/bip/ecc/common/ipoint.py +190 -0
  104. bitmart/ccxt/static_dependencies/bip/ecc/conf.py +28 -0
  105. bitmart/ccxt/static_dependencies/bip/ecc/curve/__init__.py +0 -0
  106. bitmart/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve.py +121 -0
  107. bitmart/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve_getter.py +74 -0
  108. bitmart/ccxt/static_dependencies/bip/ecc/curve/elliptic_curve_types.py +37 -0
  109. bitmart/ccxt/static_dependencies/bip/ecc/ecdsa/__init__.py +0 -0
  110. bitmart/ccxt/static_dependencies/bip/ecc/ecdsa/ecdsa_keys.py +36 -0
  111. bitmart/ccxt/static_dependencies/bip/ecc/secp256k1/__init__.py +0 -0
  112. bitmart/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1.py +36 -0
  113. bitmart/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_const.py +59 -0
  114. bitmart/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_keys_ecdsa.py +248 -0
  115. bitmart/ccxt/static_dependencies/bip/ecc/secp256k1/secp256k1_point_ecdsa.py +234 -0
  116. bitmart/ccxt/static_dependencies/bip/slip/__init__.py +0 -0
  117. bitmart/ccxt/static_dependencies/bip/slip/slip173/__init__.py +1 -0
  118. bitmart/ccxt/static_dependencies/bip/slip/slip173/slip173.py +60 -0
  119. bitmart/ccxt/static_dependencies/bip/slip/slip32/__init__.py +4 -0
  120. bitmart/ccxt/static_dependencies/bip/slip/slip32/slip32.py +322 -0
  121. bitmart/ccxt/static_dependencies/bip/slip/slip32/slip32_key_net_ver.py +62 -0
  122. bitmart/ccxt/static_dependencies/bip/slip/slip44/__init__.py +1 -0
  123. bitmart/ccxt/static_dependencies/bip/slip/slip44/slip44.py +81 -0
  124. bitmart/ccxt/static_dependencies/bip/utils/__init__.py +0 -0
  125. bitmart/ccxt/static_dependencies/bip/utils/conf/__init__.py +1 -0
  126. bitmart/ccxt/static_dependencies/bip/utils/conf/coin_names.py +59 -0
  127. bitmart/ccxt/static_dependencies/bip/utils/crypto/__init__.py +10 -0
  128. bitmart/ccxt/static_dependencies/bip/utils/crypto/aes_ecb.py +152 -0
  129. bitmart/ccxt/static_dependencies/bip/utils/crypto/blake2.py +191 -0
  130. bitmart/ccxt/static_dependencies/bip/utils/crypto/chacha20_poly1305.py +101 -0
  131. bitmart/ccxt/static_dependencies/bip/utils/crypto/hash160.py +57 -0
  132. bitmart/ccxt/static_dependencies/bip/utils/crypto/hmac.py +118 -0
  133. bitmart/ccxt/static_dependencies/bip/utils/crypto/pbkdf2.py +66 -0
  134. bitmart/ccxt/static_dependencies/bip/utils/crypto/ripemd.py +58 -0
  135. bitmart/ccxt/static_dependencies/bip/utils/crypto/scrypt.py +66 -0
  136. bitmart/ccxt/static_dependencies/bip/utils/crypto/sha2.py +182 -0
  137. bitmart/ccxt/static_dependencies/bip/utils/crypto/sha3.py +99 -0
  138. bitmart/ccxt/static_dependencies/bip/utils/misc/__init__.py +7 -0
  139. bitmart/ccxt/static_dependencies/bip/utils/misc/algo.py +108 -0
  140. bitmart/ccxt/static_dependencies/bip/utils/misc/base32.py +151 -0
  141. bitmart/ccxt/static_dependencies/bip/utils/misc/bit.py +115 -0
  142. bitmart/ccxt/static_dependencies/bip/utils/misc/bytes.py +200 -0
  143. bitmart/ccxt/static_dependencies/bip/utils/misc/data_bytes.py +181 -0
  144. bitmart/ccxt/static_dependencies/bip/utils/misc/integer.py +97 -0
  145. bitmart/ccxt/static_dependencies/bip/utils/misc/string.py +54 -0
  146. bitmart/ccxt/static_dependencies/bip/utils/typing/__init__.py +1 -0
  147. bitmart/ccxt/static_dependencies/bip/utils/typing/literal.py +27 -0
  148. bitmart/ccxt/static_dependencies/bip/wif/__init__.py +1 -0
  149. bitmart/ccxt/static_dependencies/bip/wif/wif.py +144 -0
  150. bitmart/ccxt/static_dependencies/dydx_v4_client/amino/amino_pb2.py +31 -0
  151. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos/base/v1beta1/coin_pb2.py +47 -0
  152. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/multisig/keys_pb2.py +33 -0
  153. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/multisig/v1beta1/multisig_pb2.py +33 -0
  154. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos/crypto/secp256k1/keys_pb2.py +34 -0
  155. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos/msg/v1/msg_pb2.py +27 -0
  156. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos/tx/signing/v1beta1/signing_pb2.py +38 -0
  157. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos/tx/v1beta1/tx_pb2.py +75 -0
  158. bitmart/ccxt/static_dependencies/dydx_v4_client/cosmos_proto/cosmos_pb2.py +36 -0
  159. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/accountplus_pb2.py +31 -0
  160. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/genesis_pb2.py +40 -0
  161. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/models_pb2.py +26 -0
  162. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/params_pb2.py +29 -0
  163. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/query_pb2.py +57 -0
  164. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/accountplus/tx_pb2.py +51 -0
  165. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/block_rate_limit_config_pb2.py +37 -0
  166. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/clob_pair_pb2.py +41 -0
  167. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/equity_tier_limit_config_pb2.py +35 -0
  168. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/finalize_block_pb2.py +27 -0
  169. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/liquidations_config_pb2.py +39 -0
  170. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/liquidations_pb2.py +38 -0
  171. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/matches_pb2.py +55 -0
  172. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/mev_pb2.py +49 -0
  173. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/operation_pb2.py +32 -0
  174. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/order_pb2.py +86 -0
  175. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/order_removals_pb2.py +32 -0
  176. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/process_proposer_matches_events_pb2.py +42 -0
  177. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/query_pb2.py +124 -0
  178. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/streaming_pb2.py +29 -0
  179. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/clob/tx_pb2.py +117 -0
  180. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/genesis_pb2.py +26 -0
  181. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/query_pb2.py +26 -0
  182. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/transfer_pb2.py +61 -0
  183. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/sending/tx_pb2.py +37 -0
  184. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/asset_position_pb2.py +29 -0
  185. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/genesis_pb2.py +30 -0
  186. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/perpetual_position_pb2.py +33 -0
  187. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/query_pb2.py +63 -0
  188. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/streaming_pb2.py +31 -0
  189. bitmart/ccxt/static_dependencies/dydx_v4_client/dydxprotocol/subaccounts/subaccount_pb2.py +33 -0
  190. bitmart/ccxt/static_dependencies/dydx_v4_client/gogoproto/gogo_pb2.py +102 -0
  191. bitmart/ccxt/static_dependencies/dydx_v4_client/registry.py +38 -0
  192. bitmart/ccxt/static_dependencies/ecdsa/__init__.py +14 -0
  193. bitmart/ccxt/static_dependencies/ecdsa/_version.py +520 -0
  194. bitmart/ccxt/static_dependencies/ecdsa/curves.py +56 -0
  195. bitmart/ccxt/static_dependencies/ecdsa/der.py +221 -0
  196. bitmart/ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
  197. bitmart/ccxt/static_dependencies/ecdsa/ellipticcurve.py +1039 -0
  198. bitmart/ccxt/static_dependencies/ecdsa/keys.py +343 -0
  199. bitmart/ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
  200. bitmart/ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
  201. bitmart/ccxt/static_dependencies/ecdsa/util.py +266 -0
  202. bitmart/ccxt/static_dependencies/ethereum/__init__.py +7 -0
  203. bitmart/ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
  204. bitmart/ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
  205. bitmart/ccxt/static_dependencies/ethereum/abi/base.py +152 -0
  206. bitmart/ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
  207. bitmart/ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
  208. bitmart/ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
  209. bitmart/ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
  210. bitmart/ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
  211. bitmart/ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
  212. bitmart/ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
  213. bitmart/ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
  214. bitmart/ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
  215. bitmart/ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
  216. bitmart/ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
  217. bitmart/ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
  218. bitmart/ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
  219. bitmart/ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
  220. bitmart/ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
  221. bitmart/ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
  222. bitmart/ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
  223. bitmart/ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
  224. bitmart/ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
  225. bitmart/ccxt/static_dependencies/ethereum/account/messages.py +263 -0
  226. bitmart/ccxt/static_dependencies/ethereum/account/py.typed +0 -0
  227. bitmart/ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
  228. bitmart/ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
  229. bitmart/ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
  230. bitmart/ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
  231. bitmart/ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
  232. bitmart/ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
  233. bitmart/ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
  234. bitmart/ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
  235. bitmart/ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
  236. bitmart/ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
  237. bitmart/ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
  238. bitmart/ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
  239. bitmart/ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
  240. bitmart/ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
  241. bitmart/ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
  242. bitmart/ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
  243. bitmart/ccxt/static_dependencies/ethereum/utils/address.py +171 -0
  244. bitmart/ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
  245. bitmart/ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
  246. bitmart/ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
  247. bitmart/ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
  248. bitmart/ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
  249. bitmart/ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
  250. bitmart/ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
  251. bitmart/ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
  252. bitmart/ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
  253. bitmart/ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
  254. bitmart/ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
  255. bitmart/ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
  256. bitmart/ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
  257. bitmart/ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
  258. bitmart/ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
  259. bitmart/ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
  260. bitmart/ccxt/static_dependencies/ethereum/utils/types.py +54 -0
  261. bitmart/ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
  262. bitmart/ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
  263. bitmart/ccxt/static_dependencies/ethereum/utils/units.py +31 -0
  264. bitmart/ccxt/static_dependencies/keccak/__init__.py +3 -0
  265. bitmart/ccxt/static_dependencies/keccak/keccak.py +197 -0
  266. bitmart/ccxt/static_dependencies/lark/__init__.py +38 -0
  267. bitmart/ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  268. bitmart/ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  269. bitmart/ccxt/static_dependencies/lark/ast_utils.py +59 -0
  270. bitmart/ccxt/static_dependencies/lark/common.py +86 -0
  271. bitmart/ccxt/static_dependencies/lark/exceptions.py +292 -0
  272. bitmart/ccxt/static_dependencies/lark/grammar.py +130 -0
  273. bitmart/ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  274. bitmart/ccxt/static_dependencies/lark/grammars/common.lark +59 -0
  275. bitmart/ccxt/static_dependencies/lark/grammars/lark.lark +62 -0
  276. bitmart/ccxt/static_dependencies/lark/grammars/python.lark +302 -0
  277. bitmart/ccxt/static_dependencies/lark/grammars/unicode.lark +7 -0
  278. bitmart/ccxt/static_dependencies/lark/indenter.py +143 -0
  279. bitmart/ccxt/static_dependencies/lark/lark.py +658 -0
  280. bitmart/ccxt/static_dependencies/lark/lexer.py +678 -0
  281. bitmart/ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  282. bitmart/ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  283. bitmart/ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  284. bitmart/ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  285. bitmart/ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  286. bitmart/ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  287. bitmart/ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  288. bitmart/ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  289. bitmart/ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  290. bitmart/ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  291. bitmart/ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  292. bitmart/ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  293. bitmart/ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  294. bitmart/ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  295. bitmart/ccxt/static_dependencies/lark/py.typed +0 -0
  296. bitmart/ccxt/static_dependencies/lark/reconstruct.py +107 -0
  297. bitmart/ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  298. bitmart/ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  299. bitmart/ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  300. bitmart/ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  301. bitmart/ccxt/static_dependencies/lark/tree.py +267 -0
  302. bitmart/ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  303. bitmart/ccxt/static_dependencies/lark/tree_templates.py +180 -0
  304. bitmart/ccxt/static_dependencies/lark/utils.py +343 -0
  305. bitmart/ccxt/static_dependencies/lark/visitors.py +596 -0
  306. bitmart/ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  307. bitmart/ccxt/static_dependencies/marshmallow/base.py +65 -0
  308. bitmart/ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  309. bitmart/ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  310. bitmart/ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  311. bitmart/ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  312. bitmart/ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  313. bitmart/ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  314. bitmart/ccxt/static_dependencies/marshmallow/py.typed +0 -0
  315. bitmart/ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  316. bitmart/ccxt/static_dependencies/marshmallow/types.py +12 -0
  317. bitmart/ccxt/static_dependencies/marshmallow/utils.py +378 -0
  318. bitmart/ccxt/static_dependencies/marshmallow/validate.py +678 -0
  319. bitmart/ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  320. bitmart/ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  321. bitmart/ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  322. bitmart/ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  323. bitmart/ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  324. bitmart/ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  325. bitmart/ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  326. bitmart/ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  327. bitmart/ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  328. bitmart/ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  329. bitmart/ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  330. bitmart/ccxt/static_dependencies/mnemonic/__init__.py +4 -0
  331. bitmart/ccxt/static_dependencies/mnemonic/mnemonic.py +282 -0
  332. bitmart/ccxt/static_dependencies/mnemonic/py.typed +1 -0
  333. bitmart/ccxt/static_dependencies/mnemonic/wordlist/chinese_simplified.txt +2048 -0
  334. bitmart/ccxt/static_dependencies/mnemonic/wordlist/chinese_traditional.txt +2048 -0
  335. bitmart/ccxt/static_dependencies/mnemonic/wordlist/czech.txt +2048 -0
  336. bitmart/ccxt/static_dependencies/mnemonic/wordlist/english.txt +2048 -0
  337. bitmart/ccxt/static_dependencies/mnemonic/wordlist/french.txt +2048 -0
  338. bitmart/ccxt/static_dependencies/mnemonic/wordlist/italian.txt +2048 -0
  339. bitmart/ccxt/static_dependencies/mnemonic/wordlist/japanese.txt +2048 -0
  340. bitmart/ccxt/static_dependencies/mnemonic/wordlist/korean.txt +2048 -0
  341. bitmart/ccxt/static_dependencies/mnemonic/wordlist/portuguese.txt +2048 -0
  342. bitmart/ccxt/static_dependencies/mnemonic/wordlist/russian.txt +2048 -0
  343. bitmart/ccxt/static_dependencies/mnemonic/wordlist/spanish.txt +2048 -0
  344. bitmart/ccxt/static_dependencies/mnemonic/wordlist/turkish.txt +2048 -0
  345. bitmart/ccxt/static_dependencies/msgpack/__init__.py +55 -0
  346. bitmart/ccxt/static_dependencies/msgpack/_cmsgpack.pyx +11 -0
  347. bitmart/ccxt/static_dependencies/msgpack/_packer.pyx +374 -0
  348. bitmart/ccxt/static_dependencies/msgpack/_unpacker.pyx +547 -0
  349. bitmart/ccxt/static_dependencies/msgpack/buff_converter.h +8 -0
  350. bitmart/ccxt/static_dependencies/msgpack/exceptions.py +48 -0
  351. bitmart/ccxt/static_dependencies/msgpack/ext.py +168 -0
  352. bitmart/ccxt/static_dependencies/msgpack/fallback.py +951 -0
  353. bitmart/ccxt/static_dependencies/msgpack/pack.h +89 -0
  354. bitmart/ccxt/static_dependencies/msgpack/pack_template.h +820 -0
  355. bitmart/ccxt/static_dependencies/msgpack/sysdep.h +194 -0
  356. bitmart/ccxt/static_dependencies/msgpack/unpack.h +391 -0
  357. bitmart/ccxt/static_dependencies/msgpack/unpack_define.h +95 -0
  358. bitmart/ccxt/static_dependencies/msgpack/unpack_template.h +464 -0
  359. bitmart/ccxt/static_dependencies/parsimonious/__init__.py +10 -0
  360. bitmart/ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
  361. bitmart/ccxt/static_dependencies/parsimonious/expressions.py +479 -0
  362. bitmart/ccxt/static_dependencies/parsimonious/grammar.py +487 -0
  363. bitmart/ccxt/static_dependencies/parsimonious/nodes.py +325 -0
  364. bitmart/ccxt/static_dependencies/parsimonious/utils.py +40 -0
  365. bitmart/ccxt/static_dependencies/starknet/__init__.py +0 -0
  366. bitmart/ccxt/static_dependencies/starknet/abi/v0/__init__.py +2 -0
  367. bitmart/ccxt/static_dependencies/starknet/abi/v0/model.py +44 -0
  368. bitmart/ccxt/static_dependencies/starknet/abi/v0/parser.py +216 -0
  369. bitmart/ccxt/static_dependencies/starknet/abi/v0/schemas.py +72 -0
  370. bitmart/ccxt/static_dependencies/starknet/abi/v0/shape.py +63 -0
  371. bitmart/ccxt/static_dependencies/starknet/abi/v1/__init__.py +2 -0
  372. bitmart/ccxt/static_dependencies/starknet/abi/v1/core_structures.json +14 -0
  373. bitmart/ccxt/static_dependencies/starknet/abi/v1/model.py +39 -0
  374. bitmart/ccxt/static_dependencies/starknet/abi/v1/parser.py +220 -0
  375. bitmart/ccxt/static_dependencies/starknet/abi/v1/parser_transformer.py +179 -0
  376. bitmart/ccxt/static_dependencies/starknet/abi/v1/schemas.py +66 -0
  377. bitmart/ccxt/static_dependencies/starknet/abi/v1/shape.py +47 -0
  378. bitmart/ccxt/static_dependencies/starknet/abi/v2/__init__.py +2 -0
  379. bitmart/ccxt/static_dependencies/starknet/abi/v2/model.py +89 -0
  380. bitmart/ccxt/static_dependencies/starknet/abi/v2/parser.py +293 -0
  381. bitmart/ccxt/static_dependencies/starknet/abi/v2/parser_transformer.py +192 -0
  382. bitmart/ccxt/static_dependencies/starknet/abi/v2/schemas.py +132 -0
  383. bitmart/ccxt/static_dependencies/starknet/abi/v2/shape.py +107 -0
  384. bitmart/ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  385. bitmart/ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  386. bitmart/ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  387. bitmart/ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  388. bitmart/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  389. bitmart/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  390. bitmart/ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  391. bitmart/ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  392. bitmart/ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  393. bitmart/ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  394. bitmart/ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  395. bitmart/ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  396. bitmart/ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  397. bitmart/ccxt/static_dependencies/starknet/common.py +15 -0
  398. bitmart/ccxt/static_dependencies/starknet/constants.py +39 -0
  399. bitmart/ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  400. bitmart/ccxt/static_dependencies/starknet/hash/address.py +79 -0
  401. bitmart/ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  402. bitmart/ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  403. bitmart/ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  404. bitmart/ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  405. bitmart/ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  406. bitmart/ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  407. bitmart/ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  408. bitmart/ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  409. bitmart/ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  410. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  411. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  412. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  413. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  414. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  415. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  416. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  417. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  418. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  419. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  420. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  421. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  422. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  423. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  424. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  425. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  426. bitmart/ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  427. bitmart/ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  428. bitmart/ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  429. bitmart/ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  430. bitmart/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  431. bitmart/ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  432. bitmart/ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  433. bitmart/ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  434. bitmart/ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  435. bitmart/ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  436. bitmart/ccxt/static_dependencies/starkware/__init__.py +0 -0
  437. bitmart/ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  438. bitmart/ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  439. bitmart/ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  440. bitmart/ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  441. bitmart/ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  442. bitmart/ccxt/static_dependencies/sympy/__init__.py +0 -0
  443. bitmart/ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  444. bitmart/ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  445. bitmart/ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  446. bitmart/ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  447. bitmart/ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  448. bitmart/ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  449. bitmart/ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  450. bitmart/ccxt/static_dependencies/toolz/__init__.py +26 -0
  451. bitmart/ccxt/static_dependencies/toolz/_signatures.py +784 -0
  452. bitmart/ccxt/static_dependencies/toolz/_version.py +520 -0
  453. bitmart/ccxt/static_dependencies/toolz/compatibility.py +30 -0
  454. bitmart/ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
  455. bitmart/ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
  456. bitmart/ccxt/static_dependencies/toolz/curried/operator.py +22 -0
  457. bitmart/ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
  458. bitmart/ccxt/static_dependencies/toolz/functoolz.py +1049 -0
  459. bitmart/ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
  460. bitmart/ccxt/static_dependencies/toolz/recipes.py +46 -0
  461. bitmart/ccxt/static_dependencies/toolz/utils.py +9 -0
  462. bitmart/ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  463. bitmart/ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  464. bitmart-0.0.116.dist-info/METADATA +342 -0
  465. bitmart-0.0.116.dist-info/RECORD +466 -0
  466. bitmart-0.0.116.dist-info/WHEEL +4 -0
@@ -0,0 +1,88 @@
1
+ import asyncio
2
+ import collections
3
+ from time import time
4
+
5
+
6
+ class Throttler:
7
+ def __init__(self, config, loop=None):
8
+ self.loop = loop
9
+ self.config = {
10
+ 'refillRate': 1.0, # leaky bucket refill rate in tokens per second
11
+ 'delay': 0.001, # leaky bucket seconds before checking the queue after waiting
12
+ 'capacity': 1.0, # leaky bucket
13
+ 'tokens': 0, # leaky bucket
14
+ 'cost': 1.0, # leaky bucket and rolling window
15
+ 'algorithm': 'leakyBucket',
16
+ 'windowSize': 60000.0, # rolling window size in milliseconds
17
+ 'maxWeight': 0.0, # rolling window - rollingWindowSize / rateLimit // ms_of_window / ms_of_rate_limit
18
+ }
19
+ self.config.update(config)
20
+ if self.config['algorithm'] != 'leakyBucket':
21
+ self.config['maxWeight'] = self.config['windowSize'] / self.config['rateLimit']
22
+ self.queue = collections.deque()
23
+ self.running = False
24
+ self.timestamps = []
25
+
26
+ async def leaky_bucket_loop(self):
27
+ last_timestamp = time() * 1000
28
+ while self.running:
29
+ future, cost = self.queue[0]
30
+ cost = self.config['cost'] if cost is None else cost
31
+ if self.config['tokens'] >= 0:
32
+ self.config['tokens'] -= cost
33
+ if not future.done():
34
+ future.set_result(None)
35
+ self.queue.popleft()
36
+ # context switch
37
+ await asyncio.sleep(0)
38
+ if len(self.queue) == 0:
39
+ self.running = False
40
+ else:
41
+ await asyncio.sleep(self.config['delay'])
42
+ now = time() * 1000
43
+ elapsed = now - last_timestamp
44
+ last_timestamp = now
45
+ self.config['tokens'] = min(self.config['tokens'] + elapsed * self.config['refillRate'], self.config['capacity'])
46
+
47
+ async def rolling_window_loop(self):
48
+ while self.running:
49
+ future, cost = self.queue[0]
50
+ cost = self.config['cost'] if cost is None else cost
51
+ now = time() * 1000
52
+ cutoffTime = now - self.config['windowSize']
53
+ totalCost = 0
54
+ # Remove expired timestamps & sum the remaining requests
55
+ timestamps = []
56
+ for t in self.timestamps:
57
+ if t['timestamp'] > cutoffTime:
58
+ totalCost += t['cost']
59
+ timestamps.append(t)
60
+ self.timestamps = timestamps
61
+ # handle current request
62
+ if totalCost + cost <= self.config['maxWeight']:
63
+ self.timestamps.append({'timestamp': now, 'cost': cost})
64
+ if not future.done():
65
+ future.set_result(None)
66
+ self.queue.popleft()
67
+ # context switch
68
+ await asyncio.sleep(0)
69
+ if not self.queue:
70
+ self.running = False
71
+ else:
72
+ wait_time = (self.timestamps[0]['timestamp'] + self.config['windowSize']) - now
73
+ if wait_time > 0:
74
+ await asyncio.sleep(wait_time / 1000)
75
+
76
+ async def looper(self):
77
+ if self.config['algorithm'] == 'leakyBucket':
78
+ await self.leaky_bucket_loop()
79
+ else:
80
+ await self.rolling_window_loop()
81
+
82
+ def __call__(self, cost=None):
83
+ future = asyncio.Future()
84
+ self.queue.append((future, cost))
85
+ if not self.running:
86
+ self.running = True
87
+ asyncio.ensure_future(self.looper(), loop=self.loop)
88
+ return future
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from ccxt.base import errors
4
+
5
+ # -----------------------------------------------------------------------------
6
+
7
+ from ccxt.base import decimal_to_precision
8
+
9
+ from ccxt import BaseError # noqa: F401
10
+ from ccxt import ExchangeError # noqa: F401
11
+ from ccxt import NotSupported # noqa: F401
12
+ from ccxt import AuthenticationError # noqa: F401
13
+ from ccxt import PermissionDenied # noqa: F401
14
+ from ccxt import AccountSuspended # noqa: F401
15
+ from ccxt import InvalidNonce # noqa: F401
16
+ from ccxt import InsufficientFunds # noqa: F401
17
+ from ccxt import InvalidOrder # noqa: F401
18
+ from ccxt import OrderNotFound # noqa: F401
19
+ from ccxt import OrderNotCached # noqa: F401
20
+ from ccxt import DuplicateOrderId # noqa: F401
21
+ from ccxt import CancelPending # noqa: F401
22
+ from ccxt import NetworkError # noqa: F401
23
+ from ccxt import DDoSProtection # noqa: F401
24
+ from ccxt import RateLimitExceeded # noqa: F401
25
+ from ccxt import RequestTimeout # noqa: F401
26
+ from ccxt import ExchangeNotAvailable # noqa: F401
27
+ from ccxt import OnMaintenance # noqa: F401
28
+ from ccxt import InvalidAddress # noqa: F401
29
+ from ccxt import AddressPending # noqa: F401
30
+ from ccxt import ArgumentsRequired # noqa: F401
31
+ from ccxt import BadRequest # noqa: F401
32
+ from ccxt import BadResponse # noqa: F401
33
+ from ccxt import NullResponse # noqa: F401
34
+ from ccxt import OrderImmediatelyFillable # noqa: F401
35
+ from ccxt import OrderNotFillable # noqa: F401
36
+
37
+
38
+ __all__ = decimal_to_precision.__all__ + errors.__all__ # noqa: F405
@@ -0,0 +1,219 @@
1
+ import collections
2
+ import logging
3
+
4
+ logger = logging.getLogger(__name__)
5
+
6
+ class Delegate:
7
+ def __init__(self, name, delegated):
8
+ self.name = name
9
+ self.delegated = delegated
10
+
11
+ def __get__(self, instance, owner):
12
+ deque = getattr(instance, self.delegated)
13
+ return getattr(deque, self.name)
14
+
15
+
16
+ class BaseCache(list):
17
+ # implicitly called magic methods don't invoke __getattribute__
18
+ # https://docs.python.org/3/reference/datamodel.html#special-method-lookup
19
+ # all method lookups obey the descriptor protocol
20
+ # this is how the implicit api is defined in ccxt
21
+ __iter__ = Delegate('__iter__', '_deque')
22
+ __setitem__ = Delegate('__setitem__', '_deque')
23
+ __delitem__ = Delegate('__delitem__', '_deque')
24
+ __len__ = Delegate('__len__', '_deque')
25
+ __contains__ = Delegate('__contains__', '_deque')
26
+ __reversed__ = Delegate('__reversed__', '_deque')
27
+ clear = Delegate('clear', '_deque')
28
+ pop = Delegate('pop', '_deque')
29
+
30
+ def __init__(self, max_size=None):
31
+ super(BaseCache, self).__init__()
32
+ self.max_size = max_size
33
+ self._deque = collections.deque([], max_size)
34
+
35
+ def __eq__(self, other):
36
+ return list(self) == other
37
+
38
+ def __repr__(self):
39
+ return str(list(self))
40
+
41
+ def __add__(self, other):
42
+ return list(self) + other
43
+
44
+ def __getitem__(self, item):
45
+ # deque doesn't support slicing
46
+ deque = super(list, self).__getattribute__('_deque')
47
+ if isinstance(item, slice):
48
+ start, stop, step = item.indices(len(deque))
49
+ return [deque[i] for i in range(start, stop, step)]
50
+ else:
51
+ return deque[item]
52
+
53
+ # to be overriden
54
+ def getLimit(self, symbol, limit):
55
+ pass
56
+
57
+ # support transpiled snake_case calls
58
+ def get_limit(self, symbol, limit):
59
+ return self.getLimit(symbol, limit)
60
+
61
+
62
+ class ArrayCache(BaseCache):
63
+ def __init__(self, max_size=None):
64
+ super(ArrayCache, self).__init__(max_size)
65
+ self.hashmap = {}
66
+ self._nested_new_updates_by_symbol = False
67
+ self._new_updates_by_symbol = {}
68
+ self._clear_updates_by_symbol = {}
69
+ self._all_new_updates = 0
70
+ self._clear_all_updates = False
71
+
72
+ def getLimit(self, symbol, limit):
73
+ if symbol is None:
74
+ new_updates_value = self._all_new_updates
75
+ self._clear_all_updates = True
76
+ else:
77
+ new_updates_value = self._new_updates_by_symbol.get(symbol)
78
+ if new_updates_value is not None and self._nested_new_updates_by_symbol:
79
+ new_updates_value = len(new_updates_value)
80
+ self._clear_updates_by_symbol[symbol] = True
81
+
82
+ if new_updates_value is None:
83
+ return limit
84
+ elif limit is not None:
85
+ return min(new_updates_value, limit)
86
+ else:
87
+ return new_updates_value
88
+
89
+ def append(self, item):
90
+ self._deque.append(item)
91
+ if self._clear_all_updates:
92
+ self._clear_all_updates = False
93
+ self._clear_updates_by_symbol.clear()
94
+ self._all_new_updates = 0
95
+ self._new_updates_by_symbol.clear()
96
+ if self._clear_updates_by_symbol.get(item['symbol']):
97
+ self._clear_updates_by_symbol[item['symbol']] = False
98
+ self._new_updates_by_symbol[item['symbol']] = 0
99
+ self._new_updates_by_symbol[item['symbol']] = self._new_updates_by_symbol.get(item['symbol'], 0) + 1
100
+ self._all_new_updates = (self._all_new_updates or 0) + 1
101
+
102
+
103
+ class ArrayCacheByTimestamp(BaseCache):
104
+ def __init__(self, max_size=None):
105
+ super(ArrayCacheByTimestamp, self).__init__(max_size)
106
+ self.hashmap = {}
107
+ self._size_tracker = set()
108
+ self._new_updates = 0
109
+ self._clear_updates = False
110
+
111
+ def getLimit(self, symbol, limit):
112
+ self._clear_updates = True
113
+ if limit is None:
114
+ return self._new_updates
115
+ return min(self._new_updates, limit)
116
+
117
+ def append(self, item):
118
+ if item[0] in self.hashmap:
119
+ reference = self.hashmap[item[0]]
120
+ if reference != item:
121
+ reference[0:len(item)] = item
122
+ else:
123
+ self.hashmap[item[0]] = item
124
+ if len(self._deque) == self._deque.maxlen:
125
+ delete_reference = self._deque.popleft()
126
+ del self.hashmap[delete_reference[0]]
127
+ self._deque.append(item)
128
+ if self._clear_updates:
129
+ self._clear_updates = False
130
+ self._size_tracker.clear()
131
+ self._size_tracker.add(item[0])
132
+ self._new_updates = len(self._size_tracker)
133
+
134
+
135
+ class ArrayCacheBySymbolById(ArrayCache):
136
+ def __init__(self, max_size=None):
137
+ super(ArrayCacheBySymbolById, self).__init__(max_size)
138
+ self._nested_new_updates_by_symbol = True
139
+ self.hashmap = {}
140
+ self._index = collections.deque([], max_size)
141
+
142
+ def append(self, item):
143
+ by_id = self.hashmap.setdefault(item['symbol'], {})
144
+ if item['id'] in by_id:
145
+ reference = by_id[item['id']]
146
+ if reference != item:
147
+ reference.update(item)
148
+ item = reference
149
+ index = self._index.index(item['id'])
150
+ del self._deque[index]
151
+ del self._index[index]
152
+ else:
153
+ by_id[item['id']] = item
154
+ if len(self._deque) == self._deque.maxlen:
155
+ delete_item = self._deque.popleft()
156
+ self._index.popleft()
157
+ try:
158
+ del self.hashmap[delete_item['symbol']][delete_item['id']]
159
+ except Exception as e:
160
+ logger.error(f"Error deleting item from hashmap: {delete_item}. Error:{e}")
161
+ self._deque.append(item)
162
+ self._index.append(item['id'])
163
+ if self._clear_all_updates:
164
+ self._clear_all_updates = False
165
+ self._clear_updates_by_symbol.clear()
166
+ self._all_new_updates = 0
167
+ self._new_updates_by_symbol.clear()
168
+ if item['symbol'] not in self._new_updates_by_symbol:
169
+ self._new_updates_by_symbol[item['symbol']] = set()
170
+ if self._clear_updates_by_symbol.get(item['symbol']):
171
+ self._clear_updates_by_symbol[item['symbol']] = False
172
+ self._new_updates_by_symbol[item['symbol']].clear()
173
+ id_set = self._new_updates_by_symbol[item['symbol']]
174
+ before_length = len(id_set)
175
+ id_set.add(item['id'])
176
+ after_length = len(id_set)
177
+ self._all_new_updates = (self._all_new_updates or 0) + (after_length - before_length)
178
+
179
+
180
+ class ArrayCacheBySymbolBySide(ArrayCache):
181
+ def __init__(self, max_size=None):
182
+ super(ArrayCacheBySymbolBySide, self).__init__(max_size)
183
+ self._nested_new_updates_by_symbol = True
184
+ self.hashmap = {}
185
+ self._index = collections.deque([], max_size)
186
+
187
+ def append(self, item):
188
+ by_side = self.hashmap.setdefault(item['symbol'], {})
189
+ if item['side'] in by_side:
190
+ reference = by_side[item['side']]
191
+ if reference != item:
192
+ reference.update(item)
193
+ item = reference
194
+ index = self._index.index(item['symbol'] + item['side'])
195
+ del self._deque[index]
196
+ del self._index[index]
197
+ else:
198
+ by_side[item['side']] = item
199
+ if len(self._deque) == self._deque.maxlen:
200
+ delete_item = self._deque.popleft()
201
+ self._index.popleft()
202
+ del self.hashmap[delete_item['symbol']][delete_item['side']]
203
+ self._deque.append(item)
204
+ self._index.append(item['symbol'] + item['side'])
205
+ if self._clear_all_updates:
206
+ self._clear_all_updates = False
207
+ self._clear_updates_by_symbol.clear()
208
+ self._all_new_updates = 0
209
+ self._new_updates_by_symbol.clear()
210
+ if item['symbol'] not in self._new_updates_by_symbol:
211
+ self._new_updates_by_symbol[item['symbol']] = set()
212
+ if self._clear_updates_by_symbol.get(item['symbol']):
213
+ self._clear_updates_by_symbol[item['symbol']] = False
214
+ self._new_updates_by_symbol[item['symbol']].clear()
215
+ side_set = self._new_updates_by_symbol[item['symbol']]
216
+ before_length = len(side_set)
217
+ side_set.add(item['side'])
218
+ after_length = len(side_set)
219
+ self._all_new_updates = (self._all_new_updates or 0) + (after_length - before_length)
@@ -0,0 +1,350 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ orjson = None
4
+ try:
5
+ import orjson as orjson
6
+ except ImportError:
7
+ pass
8
+
9
+ import json
10
+
11
+ from asyncio import sleep, ensure_future, wait_for, TimeoutError, BaseEventLoop, Future as asyncioFuture
12
+ from .functions import milliseconds, iso8601, deep_extend, is_json_encoded_object
13
+ from ccxt import NetworkError, RequestTimeout
14
+ from ccxt.async_support.base.ws.future import Future
15
+ from ccxt.async_support.base.ws.functions import gunzip, inflate
16
+ from typing import Dict
17
+
18
+ from aiohttp import WSMsgType
19
+
20
+
21
+ class Client(object):
22
+
23
+ url = None
24
+ ws = None
25
+ futures: Dict[str, Future] = {}
26
+ options = {} # ws-specific options
27
+ subscriptions = {}
28
+ rejections = {}
29
+ on_message_callback = None
30
+ on_error_callback = None
31
+ on_close_callback = None
32
+ on_connected_callback = None
33
+ connectionStarted = None
34
+ connectionEstablished = None
35
+ isConnected = False
36
+ connectionTimeout = 10000 # ms, false to disable
37
+ connection = None
38
+ error = None # low-level networking exception, if any
39
+ connected = None # connection-related Future
40
+ keepAlive = 5000
41
+ heartbeat = True
42
+ maxPingPongMisses = 2.0 # how many missed pongs to raise a timeout
43
+ lastPong = None
44
+ ping = None # ping-function if defined
45
+ proxy = None
46
+ verbose = False # verbose output
47
+ gunzip = False
48
+ inflate = False
49
+ throttle = None
50
+ connecting = False
51
+ asyncio_loop: BaseEventLoop = None
52
+ ping_looper = None
53
+ decompressBinary = True # decompress binary messages by default
54
+
55
+ def __init__(self, url, on_message_callback, on_error_callback, on_close_callback, on_connected_callback, config={}):
56
+ defaults = {
57
+ 'url': url,
58
+ 'futures': {},
59
+ 'subscriptions': {},
60
+ 'rejections': {},
61
+ 'on_message_callback': on_message_callback,
62
+ 'on_error_callback': on_error_callback,
63
+ 'on_close_callback': on_close_callback,
64
+ 'on_connected_callback': on_connected_callback,
65
+ }
66
+ settings = {}
67
+ settings.update(defaults)
68
+ settings.update(config)
69
+ for key in settings:
70
+ if hasattr(self, key) and isinstance(getattr(self, key), dict):
71
+ setattr(self, key, deep_extend(getattr(self, key), settings[key]))
72
+ else:
73
+ setattr(self, key, settings[key])
74
+ # connection-related Future
75
+ self.options = config
76
+ self.connected = Future()
77
+
78
+ def future(self, message_hash):
79
+ if message_hash not in self.futures or self.futures[message_hash].cancelled():
80
+ self.futures[message_hash] = Future()
81
+ future = self.futures[message_hash]
82
+ if message_hash in self.rejections:
83
+ future.reject(self.rejections[message_hash])
84
+ del self.rejections[message_hash]
85
+ return future
86
+
87
+ def reusable_future(self, message_hash):
88
+ return self.future(message_hash) # only used in go
89
+
90
+ def reusableFuture(self, message_hash):
91
+ return self.future(message_hash) # only used in go
92
+
93
+ def resolve(self, result, message_hash):
94
+ if self.verbose and message_hash is None:
95
+ self.log(iso8601(milliseconds()), 'resolve received None messageHash')
96
+ if message_hash in self.futures:
97
+ future = self.futures[message_hash]
98
+ future.resolve(result)
99
+ del self.futures[message_hash]
100
+ return result
101
+
102
+ def reject(self, result, message_hash=None):
103
+ if message_hash is not None:
104
+ if message_hash in self.futures:
105
+ future = self.futures[message_hash]
106
+ future.reject(result)
107
+ del self.futures[message_hash]
108
+ else:
109
+ self.rejections[message_hash] = result
110
+ else:
111
+ message_hashes = list(self.futures.keys())
112
+ for message_hash in message_hashes:
113
+ self.reject(result, message_hash)
114
+ return result
115
+
116
+ def receive_loop(self):
117
+ if self.verbose:
118
+ self.log(iso8601(milliseconds()), 'receive loop')
119
+ if not self.closed():
120
+ # let's drain the aiohttp buffer to avoid latency
121
+ if self.buffer and len(self.buffer) > 1:
122
+ size_delta = 0
123
+ while len(self.buffer) > 1:
124
+ message, size = self.buffer.popleft()
125
+ size_delta += size
126
+ self.handle_message(message)
127
+ # we must update the size of the last message inside WebSocketDataQueue
128
+ # self.receive() calls WebSocketDataQueue.read() that calls WebSocketDataQueue._read_from_buffer()
129
+ # which updates the size of the buffer, the _size will overflow and pause the transport
130
+ # make sure to set the enviroment variable AIOHTTP_NO_EXTENSIONS=Y to check
131
+ # print(self.connection._conn.protocol._payload._size)
132
+ self.buffer[0] = (self.buffer[0][0], self.buffer[0][1] + size_delta)
133
+
134
+ task = self.asyncio_loop.create_task(self.receive())
135
+
136
+ def after_interrupt(resolved: asyncioFuture):
137
+ exception = resolved.exception()
138
+ if exception is None:
139
+ self.handle_message(resolved.result())
140
+ self.asyncio_loop.call_soon(self.receive_loop)
141
+ else:
142
+ error = NetworkError(str(exception))
143
+ if self.verbose:
144
+ self.log(iso8601(milliseconds()), 'receive_loop', 'Exception', error)
145
+ self.reject(error)
146
+
147
+ task.add_done_callback(after_interrupt)
148
+ else:
149
+ # connection got terminated after the connection was made and before the receive loop ran
150
+ self.on_close(1006)
151
+
152
+ async def open(self, session, backoff_delay=0):
153
+ # exponential backoff for consequent connections if necessary
154
+ if backoff_delay:
155
+ await sleep(backoff_delay)
156
+ if self.verbose:
157
+ self.log(iso8601(milliseconds()), 'connecting to', self.url, 'with timeout', self.connectionTimeout, 'ms')
158
+ self.connectionStarted = milliseconds()
159
+ try:
160
+ coroutine = self.create_connection(session)
161
+ self.connection = await wait_for(coroutine, timeout=int(self.connectionTimeout / 1000))
162
+ self.connecting = False
163
+ self.connectionEstablished = milliseconds()
164
+ self.isConnected = True
165
+ if self.verbose:
166
+ self.log(iso8601(milliseconds()), 'connected')
167
+ self.connected.resolve(self.url)
168
+ self.on_connected_callback(self)
169
+ # run both loops forever
170
+ self.ping_looper = ensure_future(self.ping_loop(), loop=self.asyncio_loop)
171
+ self.asyncio_loop.call_soon(self.receive_loop)
172
+ except TimeoutError:
173
+ # connection timeout
174
+ error = RequestTimeout('Connection timeout')
175
+ if self.verbose:
176
+ self.log(iso8601(milliseconds()), 'RequestTimeout', error)
177
+ self.on_error(error)
178
+ except Exception as e:
179
+ # connection failed or rejected (ConnectionRefusedError, ClientConnectorError)
180
+ error = NetworkError(e)
181
+ if self.verbose:
182
+ self.log(iso8601(milliseconds()), 'NetworkError', error)
183
+ self.on_error(error)
184
+
185
+ @property
186
+ def buffer(self):
187
+ # looks like they exposed it in C
188
+ # this means we can bypass it
189
+ # https://github.com/aio-libs/aiohttp/blob/master/aiohttp/_websocket/reader_c.pxd#L53C24-L53C31
190
+ # these checks are necessary to protect these errors: AttributeError: 'NoneType' object has no attribute '_buffer'
191
+ # upon getting an error message
192
+ if self.connection is None:
193
+ return None
194
+ if self.connection._conn is None:
195
+ return None
196
+ if self.connection._conn.protocol is None:
197
+ return None
198
+ if self.connection._conn.protocol._payload is None:
199
+ return None
200
+ return self.connection._conn.protocol._payload._buffer
201
+
202
+ def connect(self, session, backoff_delay=0):
203
+ if not self.connection and not self.connecting:
204
+ self.connecting = True
205
+ ensure_future(self.open(session, backoff_delay), loop=self.asyncio_loop)
206
+ return self.connected
207
+
208
+ def on_error(self, error):
209
+ if self.verbose:
210
+ self.log(iso8601(milliseconds()), 'on_error', error)
211
+ self.error = error
212
+ self.reject(error)
213
+ self.on_error_callback(self, error)
214
+ if not self.closed():
215
+ ensure_future(self.close(1006), loop=self.asyncio_loop)
216
+
217
+ def on_close(self, code):
218
+ if self.verbose:
219
+ self.log(iso8601(milliseconds()), 'on_close', code)
220
+ if not self.error:
221
+ self.reject(NetworkError('Connection closed by remote server, closing code ' + str(code)))
222
+ self.on_close_callback(self, code)
223
+ ensure_future(self.aiohttp_close(), loop=self.asyncio_loop)
224
+
225
+ def log(self, *args):
226
+ print(*args)
227
+
228
+ def closed(self):
229
+ return (self.connection is None) or self.connection.closed
230
+
231
+ def receive(self):
232
+ return self.connection.receive()
233
+
234
+ # helper method for binary and text messages
235
+ def handle_text_or_binary_message(self, data):
236
+ if self.verbose:
237
+ self.log(iso8601(milliseconds()), 'message', data)
238
+ if self.decompressBinary and isinstance(data, bytes):
239
+ data = data.decode()
240
+ # decoded = json.loads(data) if is_json_encoded_object(data) else data
241
+ decode = None
242
+ if is_json_encoded_object(data):
243
+ if orjson is None:
244
+ decode = json.loads(data)
245
+ else:
246
+ decode = orjson.loads(data)
247
+ else:
248
+ decode = data
249
+ self.on_message_callback(self, decode)
250
+
251
+ def handle_message(self, message):
252
+ # self.log(iso8601(milliseconds()), message)
253
+ if message.type == WSMsgType.TEXT:
254
+ self.handle_text_or_binary_message(message.data)
255
+ elif message.type == WSMsgType.BINARY:
256
+ data = message.data
257
+ if self.gunzip:
258
+ data = gunzip(data)
259
+ elif self.inflate:
260
+ data = inflate(data)
261
+ self.handle_text_or_binary_message(data)
262
+ # autoping is responsible for automatically replying with pong
263
+ # to a ping incoming from a server, we have to disable autoping
264
+ # with aiohttp's websockets and respond with pong manually
265
+ # otherwise aiohttp's websockets client won't trigger WSMsgType.PONG
266
+ elif message.type == WSMsgType.PING:
267
+ if self.verbose:
268
+ self.log(iso8601(milliseconds()), 'ping', message)
269
+ ensure_future(self.connection.pong(message.data), loop=self.asyncio_loop)
270
+ elif message.type == WSMsgType.PONG:
271
+ self.lastPong = milliseconds()
272
+ if self.verbose:
273
+ self.log(iso8601(milliseconds()), 'pong', message)
274
+ pass
275
+ elif message.type == WSMsgType.CLOSE:
276
+ if self.verbose:
277
+ self.log(iso8601(milliseconds()), 'close', self.closed(), message)
278
+ self.on_close(message.data)
279
+ elif message.type == WSMsgType.ERROR:
280
+ if self.verbose:
281
+ self.log(iso8601(milliseconds()), 'error', message)
282
+ error = NetworkError(str(message))
283
+ self.on_error(error)
284
+
285
+ def create_connection(self, session):
286
+ # autoping is responsible for automatically replying with pong
287
+ # to a ping incoming from a server, we have to disable autoping
288
+ # with aiohttp's websockets and respond with pong manually
289
+ # otherwise aiohttp's websockets client won't trigger WSMsgType.PONG
290
+ # call aenter here to simulate async with otherwise we get the error "await not called with future"
291
+ # if connecting to a non-existent endpoint
292
+ # set cookies if defined
293
+ if 'cookies' in self.options:
294
+ for key, value in self.options['cookies'].items():
295
+ session.cookie_jar.update_cookies({key: value})
296
+ if (self.proxy):
297
+ return session.ws_connect(self.url, autoping=False, autoclose=False, headers=self.options.get('headers'), proxy=self.proxy, max_msg_size=10485760).__aenter__()
298
+ return session.ws_connect(self.url, autoping=False, autoclose=False, headers=self.options.get('headers'), max_msg_size=10485760).__aenter__()
299
+
300
+ async def send(self, message):
301
+ if self.verbose:
302
+ self.log(iso8601(milliseconds()), 'sending', message)
303
+ send_msg = None
304
+ if isinstance(message, str):
305
+ send_msg = message
306
+ else:
307
+ if orjson is None:
308
+ send_msg = json.dumps(message, separators=(',', ':'))
309
+ else:
310
+ send_msg = orjson.dumps(message).decode('utf-8')
311
+ if self.closed():
312
+ raise ConnectionError('Cannot Send Message: Connection closed before send')
313
+ return await self.connection.send_str(send_msg)
314
+
315
+ async def close(self, code=1000):
316
+ if self.verbose:
317
+ self.log(iso8601(milliseconds()), 'closing', code)
318
+ for future in self.futures.values():
319
+ future.cancel()
320
+ await self.aiohttp_close()
321
+
322
+ async def aiohttp_close(self):
323
+ if not self.closed():
324
+ await self.connection.close()
325
+ # these will end automatically once self.closed() = True
326
+ # so we don't need to cancel them
327
+ if self.ping_looper:
328
+ self.ping_looper.cancel()
329
+
330
+ async def ping_loop(self):
331
+ if self.verbose:
332
+ self.log(iso8601(milliseconds()), 'ping loop')
333
+ while self.keepAlive and not self.closed():
334
+ now = milliseconds()
335
+ self.lastPong = now if self.lastPong is None else self.lastPong
336
+ if (self.lastPong + self.keepAlive * self.maxPingPongMisses) < now:
337
+ self.on_error(RequestTimeout('Connection to ' + self.url + ' timed out due to a ping-pong keepalive missing on time'))
338
+ # the following ping-clause is not necessary with aiohttp's built-in ws
339
+ # since it has a heartbeat option (see create_connection above)
340
+ # however some exchanges require a text-type ping message
341
+ # therefore we need this clause anyway
342
+ else:
343
+ if self.ping:
344
+ try:
345
+ await self.send(self.ping(self))
346
+ except Exception as e:
347
+ self.on_error(e)
348
+ else:
349
+ await self.connection.ping()
350
+ await sleep(self.keepAlive / 1000)