ccxt 4.2.77__py2.py3-none-any.whl → 4.4.48__py2.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.
- ccxt/__init__.py +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +24 -0
- ccxt/abstract/kucoinfutures.py +34 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3030 -1087
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3104 -880
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +238 -49
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +199 -65
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +392 -148
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2231 -1193
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1454 -287
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +404 -109
- ccxt/async_support/deribit.py +557 -323
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1472 -463
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1633 -268
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +917 -357
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1776 -454
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1137 -296
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1722 -480
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3030 -1087
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3104 -880
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +238 -49
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +198 -65
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +392 -148
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2231 -1193
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1454 -287
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +404 -109
- ccxt/deribit.py +557 -323
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1472 -463
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1632 -268
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +917 -357
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1776 -454
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +62 -14
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +203 -81
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +965 -665
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +167 -31
- ccxt/pro/exmo.py +252 -20
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +92 -33
- ccxt/pro/poloniex.py +128 -49
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +92 -85
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +437 -65
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +456 -391
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +456 -393
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1137 -296
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -103
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -32
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt-4.2.77.dist-info/METADATA +0 -626
- ccxt-4.2.77.dist-info/RECORD +0 -534
- {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Generator, TypedDict, Union
|
3
|
+
|
4
|
+
from ...cairo.felt import uint256_range_check
|
5
|
+
from .._context import (
|
6
|
+
Context,
|
7
|
+
DeserializationContext,
|
8
|
+
SerializationContext,
|
9
|
+
)
|
10
|
+
from .cairo_data_serializer import (
|
11
|
+
CairoDataSerializer,
|
12
|
+
)
|
13
|
+
|
14
|
+
|
15
|
+
class Uint256Dict(TypedDict):
|
16
|
+
low: int
|
17
|
+
high: int
|
18
|
+
|
19
|
+
|
20
|
+
@dataclass
|
21
|
+
class UintSerializer(CairoDataSerializer[Union[int, Uint256Dict], int]):
|
22
|
+
"""
|
23
|
+
Serializer of uint. In Cairo there are few uints (u8, ..., u128 and u256).
|
24
|
+
u256 is represented by structure {low: u128, high: u128}.
|
25
|
+
Can serialize an int and dict.
|
26
|
+
Deserializes data to an int.
|
27
|
+
|
28
|
+
Examples:
|
29
|
+
if bits < 256:
|
30
|
+
0 => [0]
|
31
|
+
1 => [1]
|
32
|
+
2**128-1 => [2**128-1]
|
33
|
+
else:
|
34
|
+
0 => [0,0]
|
35
|
+
1 => [1,0]
|
36
|
+
2**128 => [0,1]
|
37
|
+
3 + 2**128 => [3,1]
|
38
|
+
"""
|
39
|
+
|
40
|
+
bits: int
|
41
|
+
|
42
|
+
def deserialize_with_context(self, context: DeserializationContext) -> int:
|
43
|
+
if self.bits < 256:
|
44
|
+
(uint,) = context.reader.read(1)
|
45
|
+
with context.push_entity("uint" + str(self.bits)):
|
46
|
+
self._ensure_valid_uint(uint, context, self.bits)
|
47
|
+
|
48
|
+
return uint
|
49
|
+
|
50
|
+
[low, high] = context.reader.read(2)
|
51
|
+
|
52
|
+
# Checking if resulting value is in [0, 2**256) range is not enough. Uint256 should be made of two uint128.
|
53
|
+
with context.push_entity("low"):
|
54
|
+
self._ensure_valid_uint(low, context, bits=128)
|
55
|
+
with context.push_entity("high"):
|
56
|
+
self._ensure_valid_uint(high, context, bits=128)
|
57
|
+
|
58
|
+
return (high << 128) + low
|
59
|
+
|
60
|
+
def serialize_with_context(
|
61
|
+
self, context: SerializationContext, value: Union[int, Uint256Dict]
|
62
|
+
) -> Generator[int, None, None]:
|
63
|
+
context.ensure_valid_type(value, isinstance(value, (int, dict)), "int or dict")
|
64
|
+
if isinstance(value, int):
|
65
|
+
yield from self._serialize_from_int(value, context, self.bits)
|
66
|
+
else:
|
67
|
+
yield from self._serialize_from_dict(context, value)
|
68
|
+
|
69
|
+
@staticmethod
|
70
|
+
def _serialize_from_int(
|
71
|
+
value: int, context: SerializationContext, bits: int
|
72
|
+
) -> Generator[int, None, None]:
|
73
|
+
if bits < 256:
|
74
|
+
UintSerializer._ensure_valid_uint(value, context, bits)
|
75
|
+
|
76
|
+
yield value
|
77
|
+
else:
|
78
|
+
uint256_range_check(value)
|
79
|
+
|
80
|
+
result = (value % 2**128, value >> 128)
|
81
|
+
yield from result
|
82
|
+
|
83
|
+
def _serialize_from_dict(
|
84
|
+
self, context: SerializationContext, value: Uint256Dict
|
85
|
+
) -> Generator[int, None, None]:
|
86
|
+
with context.push_entity("low"):
|
87
|
+
self._ensure_valid_uint(value["low"], context, bits=128)
|
88
|
+
yield value["low"]
|
89
|
+
with context.push_entity("high"):
|
90
|
+
self._ensure_valid_uint(value["high"], context, bits=128)
|
91
|
+
yield value["high"]
|
92
|
+
|
93
|
+
@staticmethod
|
94
|
+
def _ensure_valid_uint(value: int, context: Context, bits: int):
|
95
|
+
"""
|
96
|
+
Ensures that value is a valid uint on `bits` bits.
|
97
|
+
"""
|
98
|
+
context.ensure_valid_value(
|
99
|
+
0 <= value < 2**bits, "expected value in range [0;2**" + str(bits) + ")"
|
100
|
+
)
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Any, Generator, Optional
|
3
|
+
|
4
|
+
from .._context import (
|
5
|
+
DeserializationContext,
|
6
|
+
SerializationContext,
|
7
|
+
)
|
8
|
+
from .cairo_data_serializer import (
|
9
|
+
CairoDataSerializer,
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
@dataclass
|
14
|
+
class UnitSerializer(CairoDataSerializer[None, None]):
|
15
|
+
"""
|
16
|
+
Serializer for unit type.
|
17
|
+
Can only serialize None.
|
18
|
+
Deserializes data to None.
|
19
|
+
|
20
|
+
Example:
|
21
|
+
[] => None
|
22
|
+
"""
|
23
|
+
|
24
|
+
def deserialize_with_context(self, context: DeserializationContext) -> None:
|
25
|
+
return None
|
26
|
+
|
27
|
+
def serialize_with_context(
|
28
|
+
self, context: SerializationContext, value: Optional[Any]
|
29
|
+
) -> Generator[None, None, None]:
|
30
|
+
if value is not None:
|
31
|
+
raise ValueError("Can only serialize `None`.")
|
32
|
+
yield None
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class CairoSerializerException(Exception):
|
2
|
+
"""Exception thrown by CairoSerializer."""
|
3
|
+
|
4
|
+
|
5
|
+
class InvalidTypeException(CairoSerializerException, TypeError):
|
6
|
+
"""Exception thrown when invalid type was provided."""
|
7
|
+
|
8
|
+
|
9
|
+
class InvalidValueException(CairoSerializerException, ValueError):
|
10
|
+
"""Exception thrown when invalid value was provided."""
|
@@ -0,0 +1,229 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from collections import OrderedDict
|
4
|
+
from typing import Dict, List, Union
|
5
|
+
|
6
|
+
from ..abi.v0 import Abi as AbiV0
|
7
|
+
from ..abi.v1 import Abi as AbiV1
|
8
|
+
from ..abi.v2 import Abi as AbiV2
|
9
|
+
from ..cairo.data_types import (
|
10
|
+
ArrayType,
|
11
|
+
BoolType,
|
12
|
+
CairoType,
|
13
|
+
EnumType,
|
14
|
+
EventType,
|
15
|
+
FeltType,
|
16
|
+
NamedTupleType,
|
17
|
+
OptionType,
|
18
|
+
StructType,
|
19
|
+
TupleType,
|
20
|
+
UintType,
|
21
|
+
UnitType,
|
22
|
+
)
|
23
|
+
from .data_serializers import (
|
24
|
+
BoolSerializer,
|
25
|
+
ByteArraySerializer,
|
26
|
+
)
|
27
|
+
from .data_serializers.array_serializer import ArraySerializer
|
28
|
+
from .data_serializers.cairo_data_serializer import (
|
29
|
+
CairoDataSerializer,
|
30
|
+
)
|
31
|
+
from .data_serializers.enum_serializer import EnumSerializer
|
32
|
+
from .data_serializers.felt_serializer import FeltSerializer
|
33
|
+
from .data_serializers.named_tuple_serializer import (
|
34
|
+
NamedTupleSerializer,
|
35
|
+
)
|
36
|
+
from .data_serializers.option_serializer import (
|
37
|
+
OptionSerializer,
|
38
|
+
)
|
39
|
+
from .data_serializers.output_serializer import (
|
40
|
+
OutputSerializer,
|
41
|
+
)
|
42
|
+
from .data_serializers.payload_serializer import (
|
43
|
+
PayloadSerializer,
|
44
|
+
)
|
45
|
+
from .data_serializers.struct_serializer import (
|
46
|
+
StructSerializer,
|
47
|
+
)
|
48
|
+
from .data_serializers.tuple_serializer import TupleSerializer
|
49
|
+
from .data_serializers.uint256_serializer import (
|
50
|
+
Uint256Serializer,
|
51
|
+
)
|
52
|
+
from .data_serializers.uint_serializer import UintSerializer
|
53
|
+
from .data_serializers.unit_serializer import UnitSerializer
|
54
|
+
from .errors import InvalidTypeException
|
55
|
+
from .function_serialization_adapter import (
|
56
|
+
FunctionSerializationAdapter,
|
57
|
+
FunctionSerializationAdapterV1,
|
58
|
+
)
|
59
|
+
|
60
|
+
_uint256_type = StructType("Uint256", OrderedDict(low=FeltType(), high=FeltType()))
|
61
|
+
_byte_array_type = StructType(
|
62
|
+
"core::byte_array::ByteArray",
|
63
|
+
OrderedDict(
|
64
|
+
data=ArrayType(FeltType()),
|
65
|
+
pending_word=FeltType(),
|
66
|
+
pending_word_len=UintType(bits=32),
|
67
|
+
),
|
68
|
+
)
|
69
|
+
|
70
|
+
|
71
|
+
def serializer_for_type(cairo_type: CairoType) -> CairoDataSerializer:
|
72
|
+
"""
|
73
|
+
Create a serializer for cairo type.
|
74
|
+
|
75
|
+
:param cairo_type: CairoType.
|
76
|
+
:return: CairoDataSerializer.
|
77
|
+
"""
|
78
|
+
# pylint: disable=too-many-return-statements, too-many-branches
|
79
|
+
if isinstance(cairo_type, FeltType):
|
80
|
+
return FeltSerializer()
|
81
|
+
|
82
|
+
if isinstance(cairo_type, BoolType):
|
83
|
+
return BoolSerializer()
|
84
|
+
|
85
|
+
if isinstance(cairo_type, StructType):
|
86
|
+
# Special case: Uint256 is represented as struct
|
87
|
+
if cairo_type == _uint256_type:
|
88
|
+
return Uint256Serializer()
|
89
|
+
|
90
|
+
if cairo_type == _byte_array_type:
|
91
|
+
return ByteArraySerializer()
|
92
|
+
|
93
|
+
return StructSerializer(
|
94
|
+
OrderedDict(
|
95
|
+
(name, serializer_for_type(member_type))
|
96
|
+
for name, member_type in cairo_type.types.items()
|
97
|
+
)
|
98
|
+
)
|
99
|
+
|
100
|
+
if isinstance(cairo_type, ArrayType):
|
101
|
+
return ArraySerializer(serializer_for_type(cairo_type.inner_type))
|
102
|
+
|
103
|
+
if isinstance(cairo_type, TupleType):
|
104
|
+
return TupleSerializer(
|
105
|
+
[serializer_for_type(member) for member in cairo_type.types]
|
106
|
+
)
|
107
|
+
|
108
|
+
if isinstance(cairo_type, NamedTupleType):
|
109
|
+
return NamedTupleSerializer(
|
110
|
+
OrderedDict(
|
111
|
+
(name, serializer_for_type(member_type))
|
112
|
+
for name, member_type in cairo_type.types.items()
|
113
|
+
)
|
114
|
+
)
|
115
|
+
|
116
|
+
if isinstance(cairo_type, UintType):
|
117
|
+
return UintSerializer(bits=cairo_type.bits)
|
118
|
+
|
119
|
+
if isinstance(cairo_type, OptionType):
|
120
|
+
return OptionSerializer(serializer_for_type(cairo_type.type))
|
121
|
+
|
122
|
+
if isinstance(cairo_type, UnitType):
|
123
|
+
return UnitSerializer()
|
124
|
+
|
125
|
+
if isinstance(cairo_type, EnumType):
|
126
|
+
return EnumSerializer(
|
127
|
+
OrderedDict(
|
128
|
+
(name, serializer_for_type(variant_type))
|
129
|
+
for name, variant_type in cairo_type.variants.items()
|
130
|
+
)
|
131
|
+
)
|
132
|
+
if isinstance(cairo_type, EventType):
|
133
|
+
return serializer_for_payload(cairo_type.types)
|
134
|
+
|
135
|
+
raise InvalidTypeException(f"Received unknown Cairo type '{cairo_type}'.")
|
136
|
+
|
137
|
+
|
138
|
+
# We don't want to require users to use OrderedDict. Regular python requires order since python 3.7.
|
139
|
+
def serializer_for_payload(payload: Dict[str, CairoType]) -> PayloadSerializer:
|
140
|
+
"""
|
141
|
+
Create PayloadSerializer for types listed in a dictionary. Please note that the order of fields in the dict is
|
142
|
+
very important. Make sure the keys are provided in the right order.
|
143
|
+
|
144
|
+
:param payload: dictionary with cairo types.
|
145
|
+
:return: PayloadSerializer that can be used to (de)serialize events/function calls.
|
146
|
+
"""
|
147
|
+
return PayloadSerializer(
|
148
|
+
OrderedDict(
|
149
|
+
(name, serializer_for_type(cairo_type))
|
150
|
+
for name, cairo_type in payload.items()
|
151
|
+
)
|
152
|
+
)
|
153
|
+
|
154
|
+
|
155
|
+
def serializer_for_outputs(payload: List[CairoType]) -> OutputSerializer:
|
156
|
+
"""
|
157
|
+
Create OutputSerializer for types in list. Please note that the order of fields in the list is
|
158
|
+
very important. Make sure the types are provided in the right order.
|
159
|
+
|
160
|
+
:param payload: list with cairo types.
|
161
|
+
:return: OutputSerializer that can be used to deserialize function outputs.
|
162
|
+
"""
|
163
|
+
return OutputSerializer(
|
164
|
+
serializers=[serializer_for_type(cairo_type) for cairo_type in payload]
|
165
|
+
)
|
166
|
+
|
167
|
+
|
168
|
+
EventV0 = AbiV0.Event
|
169
|
+
EventV1 = AbiV1.Event
|
170
|
+
EventV2 = EventType
|
171
|
+
|
172
|
+
|
173
|
+
def serializer_for_event(event: EventV0 | EventV1 | EventV2) -> PayloadSerializer:
|
174
|
+
"""
|
175
|
+
Create serializer for an event.
|
176
|
+
|
177
|
+
:param event: parsed event.
|
178
|
+
:return: PayloadSerializer that can be used to (de)serialize events.
|
179
|
+
"""
|
180
|
+
if isinstance(event, EventV0):
|
181
|
+
return serializer_for_payload(event.data)
|
182
|
+
if isinstance(event, EventV1):
|
183
|
+
return serializer_for_payload(event.inputs)
|
184
|
+
return serializer_for_payload(event.types)
|
185
|
+
|
186
|
+
|
187
|
+
def serializer_for_function(
|
188
|
+
abi_function: AbiV0.Function,
|
189
|
+
) -> FunctionSerializationAdapter:
|
190
|
+
"""
|
191
|
+
Create FunctionSerializationAdapter for serializing function inputs and deserializing function outputs.
|
192
|
+
|
193
|
+
:param abi_function: parsed function's abi.
|
194
|
+
:return: FunctionSerializationAdapter.
|
195
|
+
"""
|
196
|
+
return FunctionSerializationAdapter(
|
197
|
+
inputs_serializer=serializer_for_payload(abi_function.inputs),
|
198
|
+
outputs_deserializer=serializer_for_payload(abi_function.outputs),
|
199
|
+
)
|
200
|
+
|
201
|
+
|
202
|
+
def serializer_for_function_v1(
|
203
|
+
abi_function: Union[AbiV1.Function, AbiV2.Function],
|
204
|
+
) -> FunctionSerializationAdapter:
|
205
|
+
"""
|
206
|
+
Create FunctionSerializationAdapter for serializing function inputs and deserializing function outputs.
|
207
|
+
|
208
|
+
:param abi_function: parsed function's abi.
|
209
|
+
:return: FunctionSerializationAdapter.
|
210
|
+
"""
|
211
|
+
return FunctionSerializationAdapterV1(
|
212
|
+
inputs_serializer=serializer_for_payload(abi_function.inputs),
|
213
|
+
outputs_deserializer=serializer_for_outputs(abi_function.outputs),
|
214
|
+
)
|
215
|
+
|
216
|
+
|
217
|
+
def serializer_for_constructor_v2(
|
218
|
+
abi_function: AbiV2.Constructor,
|
219
|
+
) -> FunctionSerializationAdapter:
|
220
|
+
"""
|
221
|
+
Create FunctionSerializationAdapter for serializing constructor inputs.
|
222
|
+
|
223
|
+
:param abi_function: parsed constructor's abi.
|
224
|
+
:return: FunctionSerializationAdapter.
|
225
|
+
"""
|
226
|
+
return FunctionSerializationAdapterV1(
|
227
|
+
inputs_serializer=serializer_for_payload(abi_function.inputs),
|
228
|
+
outputs_deserializer=serializer_for_outputs([]),
|
229
|
+
)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from dataclasses import dataclass, field
|
4
|
+
from typing import Dict, List, Set, Tuple
|
5
|
+
|
6
|
+
from ..cairo.felt import CairoData
|
7
|
+
from .data_serializers.output_serializer import (
|
8
|
+
OutputSerializer,
|
9
|
+
)
|
10
|
+
from .data_serializers.payload_serializer import (
|
11
|
+
PayloadSerializer,
|
12
|
+
)
|
13
|
+
from .errors import InvalidTypeException
|
14
|
+
from .tuple_dataclass import TupleDataclass
|
15
|
+
|
16
|
+
|
17
|
+
@dataclass
|
18
|
+
class FunctionSerializationAdapter:
|
19
|
+
"""
|
20
|
+
Class serializing ``*args`` and ``**kwargs`` by adapting them to function inputs.
|
21
|
+
"""
|
22
|
+
|
23
|
+
inputs_serializer: PayloadSerializer
|
24
|
+
outputs_deserializer: PayloadSerializer
|
25
|
+
|
26
|
+
expected_args: Tuple[str] = field(init=False)
|
27
|
+
|
28
|
+
def __post_init__(self):
|
29
|
+
self.expected_args = tuple(
|
30
|
+
self.inputs_serializer.serializers.keys()
|
31
|
+
) # pyright: ignore
|
32
|
+
|
33
|
+
def serialize(self, *args, **kwargs) -> CairoData:
|
34
|
+
"""
|
35
|
+
Method using args and kwargs to match members and serialize them separately.
|
36
|
+
|
37
|
+
:return: Members serialized separately in SerializedPayload.
|
38
|
+
"""
|
39
|
+
named_arguments = self._merge_arguments(args, kwargs)
|
40
|
+
return self.inputs_serializer.serialize(named_arguments)
|
41
|
+
|
42
|
+
def deserialize(self, data: List[int]) -> TupleDataclass:
|
43
|
+
"""
|
44
|
+
Deserializes data into TupleDataclass containing python representations.
|
45
|
+
|
46
|
+
:return: cairo data.
|
47
|
+
"""
|
48
|
+
return self.outputs_deserializer.deserialize(data)
|
49
|
+
|
50
|
+
def _merge_arguments(self, args: Tuple, kwargs: Dict) -> Dict:
|
51
|
+
"""
|
52
|
+
Merges positional and keyed arguments.
|
53
|
+
"""
|
54
|
+
# After this line we know that len(args) <= len(self.expected_args)
|
55
|
+
self._ensure_no_unnecessary_positional_args(args)
|
56
|
+
|
57
|
+
named_arguments = dict(kwargs)
|
58
|
+
for arg, input_name in zip(args, self.expected_args):
|
59
|
+
if input_name in kwargs:
|
60
|
+
raise InvalidTypeException(
|
61
|
+
f"Both positional and named argument provided for '{input_name}'."
|
62
|
+
)
|
63
|
+
named_arguments[input_name] = arg
|
64
|
+
|
65
|
+
expected_args = set(self.expected_args)
|
66
|
+
provided_args = set(named_arguments.keys())
|
67
|
+
|
68
|
+
# named_arguments might have unnecessary arguments coming from kwargs (we ensure that
|
69
|
+
# len(args) <= len(self.expected_args) above)
|
70
|
+
self._ensure_no_unnecessary_args(expected_args, provided_args)
|
71
|
+
|
72
|
+
# there might be some argument missing (not provided)
|
73
|
+
self._ensure_no_missing_args(expected_args, provided_args)
|
74
|
+
|
75
|
+
return named_arguments
|
76
|
+
|
77
|
+
def _ensure_no_unnecessary_positional_args(self, args: Tuple):
|
78
|
+
if len(args) > len(self.expected_args):
|
79
|
+
raise InvalidTypeException(
|
80
|
+
f"Provided {len(args)} positional arguments, {len(self.expected_args)} possible."
|
81
|
+
)
|
82
|
+
|
83
|
+
@staticmethod
|
84
|
+
def _ensure_no_unnecessary_args(expected_args: Set[str], provided_args: Set[str]):
|
85
|
+
excessive_arguments = provided_args - expected_args
|
86
|
+
if excessive_arguments:
|
87
|
+
raise InvalidTypeException(
|
88
|
+
f"Unnecessary named arguments provided: '{', '.join(excessive_arguments)}'."
|
89
|
+
)
|
90
|
+
|
91
|
+
@staticmethod
|
92
|
+
def _ensure_no_missing_args(expected_args: Set[str], provided_args: Set[str]):
|
93
|
+
missing_arguments = expected_args - provided_args
|
94
|
+
if missing_arguments:
|
95
|
+
raise InvalidTypeException(
|
96
|
+
f"Missing arguments: '{', '.join(missing_arguments)}'."
|
97
|
+
)
|
98
|
+
|
99
|
+
|
100
|
+
@dataclass
|
101
|
+
class FunctionSerializationAdapterV1(FunctionSerializationAdapter):
|
102
|
+
outputs_deserializer: OutputSerializer
|
103
|
+
|
104
|
+
def deserialize(self, data: List[int]) -> Tuple:
|
105
|
+
"""
|
106
|
+
Deserializes data into TupleDataclass containing python representations.
|
107
|
+
|
108
|
+
:return: cairo data.
|
109
|
+
"""
|
110
|
+
return self.outputs_deserializer.deserialize(data)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from dataclasses import dataclass, fields, make_dataclass
|
4
|
+
from typing import Dict, Optional, Tuple
|
5
|
+
|
6
|
+
|
7
|
+
@dataclass(frozen=True, eq=False)
|
8
|
+
class TupleDataclass:
|
9
|
+
"""
|
10
|
+
Dataclass that behaves like a tuple at the same time. Used when data has defined order and names.
|
11
|
+
For instance in case of named tuples or function responses.
|
12
|
+
"""
|
13
|
+
|
14
|
+
# getattr is called when attribute is not found in object. For instance when using object.unknown_attribute.
|
15
|
+
# This way pyright will know that there might be some arguments it doesn't know about and will stop complaining
|
16
|
+
# about some fields that don't exist statically.
|
17
|
+
def __getattr__(self, item):
|
18
|
+
# This should always fail - only attributes that don't exist end up in here.
|
19
|
+
# We use __getattribute__ to get the native error.
|
20
|
+
return super().__getattribute__(item)
|
21
|
+
|
22
|
+
def __getitem__(self, item: int):
|
23
|
+
field = fields(self)[item]
|
24
|
+
return getattr(self, field.name)
|
25
|
+
|
26
|
+
def __iter__(self):
|
27
|
+
return (getattr(self, field.name) for field in fields(self))
|
28
|
+
|
29
|
+
def as_tuple(self) -> Tuple:
|
30
|
+
"""
|
31
|
+
Creates a regular tuple from TupleDataclass.
|
32
|
+
"""
|
33
|
+
return tuple(self)
|
34
|
+
|
35
|
+
def as_dict(self) -> Dict:
|
36
|
+
"""
|
37
|
+
Creates a regular dict from TupleDataclass.
|
38
|
+
"""
|
39
|
+
return {field.name: getattr(self, field.name) for field in fields(self)}
|
40
|
+
|
41
|
+
# Added for backward compatibility with previous implementation based on NamedTuple
|
42
|
+
def _asdict(self):
|
43
|
+
return self.as_dict()
|
44
|
+
|
45
|
+
def __eq__(self, other):
|
46
|
+
if isinstance(other, TupleDataclass):
|
47
|
+
return self.as_tuple() == other.as_tuple()
|
48
|
+
return self.as_tuple() == other
|
49
|
+
|
50
|
+
@staticmethod
|
51
|
+
def from_dict(data: Dict, *, name: Optional[str] = None) -> TupleDataclass:
|
52
|
+
result_class = make_dataclass(
|
53
|
+
name or "TupleDataclass",
|
54
|
+
fields=[(key, type(value)) for key, value in data.items()],
|
55
|
+
bases=(TupleDataclass,),
|
56
|
+
frozen=True,
|
57
|
+
eq=False,
|
58
|
+
)
|
59
|
+
return result_class(**data)
|
File without changes
|
@@ -0,0 +1,86 @@
|
|
1
|
+
from typing import List, Optional, Union
|
2
|
+
|
3
|
+
from ..abi.v2 import shape as ShapeV2
|
4
|
+
from ..abi.v0 import AbiParser as AbiParserV0
|
5
|
+
from ..abi.v1 import AbiParser as AbiParserV1
|
6
|
+
from ..abi.v2 import AbiParser as AbiParserV2
|
7
|
+
from ..serialization import (
|
8
|
+
FunctionSerializationAdapter,
|
9
|
+
serializer_for_function,
|
10
|
+
)
|
11
|
+
from ..serialization.factory import (
|
12
|
+
serializer_for_constructor_v2,
|
13
|
+
serializer_for_function_v1,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
def translate_constructor_args(
|
18
|
+
abi: List, constructor_args: Optional[Union[List, dict]], *, cairo_version: int = 1
|
19
|
+
) -> List[int]:
|
20
|
+
serializer = (
|
21
|
+
_get_constructor_serializer_v1(abi)
|
22
|
+
if cairo_version == 1
|
23
|
+
else _get_constructor_serializer_v0(abi)
|
24
|
+
)
|
25
|
+
|
26
|
+
if serializer is None or len(serializer.inputs_serializer.serializers) == 0:
|
27
|
+
return []
|
28
|
+
|
29
|
+
if not constructor_args:
|
30
|
+
raise ValueError(
|
31
|
+
"Provided contract has a constructor and no arguments were provided."
|
32
|
+
)
|
33
|
+
|
34
|
+
args, kwargs = (
|
35
|
+
([], constructor_args)
|
36
|
+
if isinstance(constructor_args, dict)
|
37
|
+
else (constructor_args, {})
|
38
|
+
)
|
39
|
+
return serializer.serialize(*args, **kwargs)
|
40
|
+
|
41
|
+
|
42
|
+
def _get_constructor_serializer_v1(abi: List) -> Optional[FunctionSerializationAdapter]:
|
43
|
+
if _is_abi_v2(abi):
|
44
|
+
parsed = AbiParserV2(abi).parse()
|
45
|
+
constructor = parsed.constructor
|
46
|
+
|
47
|
+
if constructor is None or not constructor.inputs:
|
48
|
+
return None
|
49
|
+
|
50
|
+
return serializer_for_constructor_v2(constructor)
|
51
|
+
|
52
|
+
parsed = AbiParserV1(abi).parse()
|
53
|
+
constructor = parsed.functions.get("constructor", None)
|
54
|
+
|
55
|
+
# Constructor might not accept any arguments
|
56
|
+
if constructor is None or not constructor.inputs:
|
57
|
+
return None
|
58
|
+
|
59
|
+
return serializer_for_function_v1(constructor)
|
60
|
+
|
61
|
+
|
62
|
+
def _is_abi_v2(abi: List) -> bool:
|
63
|
+
for entry in abi:
|
64
|
+
if entry["type"] in [
|
65
|
+
ShapeV2.CONSTRUCTOR_ENTRY,
|
66
|
+
ShapeV2.L1_HANDLER_ENTRY,
|
67
|
+
ShapeV2.INTERFACE_ENTRY,
|
68
|
+
ShapeV2.IMPL_ENTRY,
|
69
|
+
]:
|
70
|
+
return True
|
71
|
+
if entry["type"] == ShapeV2.EVENT_ENTRY:
|
72
|
+
if "inputs" in entry:
|
73
|
+
return False
|
74
|
+
if "kind" in entry:
|
75
|
+
return True
|
76
|
+
return False
|
77
|
+
|
78
|
+
|
79
|
+
def _get_constructor_serializer_v0(abi: List) -> Optional[FunctionSerializationAdapter]:
|
80
|
+
parsed = AbiParserV0(abi).parse()
|
81
|
+
|
82
|
+
# Constructor might not accept any arguments
|
83
|
+
if not parsed.constructor or not parsed.constructor.inputs:
|
84
|
+
return None
|
85
|
+
|
86
|
+
return serializer_for_function(parsed.constructor)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from typing import Iterable, TypeVar, Union
|
2
|
+
|
3
|
+
T = TypeVar("T")
|
4
|
+
|
5
|
+
|
6
|
+
# pyright: reportGeneralTypeIssues=false
|
7
|
+
def ensure_iterable(value: Union[T, Iterable[T]]) -> Iterable[T]:
|
8
|
+
try:
|
9
|
+
iter(value)
|
10
|
+
# Now we now it is iterable
|
11
|
+
return value
|
12
|
+
except TypeError:
|
13
|
+
return [value]
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from ..marshmallow import EXCLUDE, RAISE
|
4
|
+
from ..marshmallow import Schema as MarshmallowSchema
|
5
|
+
|
6
|
+
MARSHMALLOW_UKNOWN_EXCLUDE = os.environ.get("STARKNET_PY_MARSHMALLOW_UKNOWN_EXCLUDE")
|
7
|
+
|
8
|
+
|
9
|
+
class Schema(MarshmallowSchema):
|
10
|
+
class Meta:
|
11
|
+
unknown = (
|
12
|
+
EXCLUDE if (MARSHMALLOW_UKNOWN_EXCLUDE or "").lower() == "true" else RAISE
|
13
|
+
)
|