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,66 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Generator
|
3
|
+
|
4
|
+
from ...cairo.felt import decode_shortstring, encode_shortstring
|
5
|
+
from .._context import (
|
6
|
+
DeserializationContext,
|
7
|
+
SerializationContext,
|
8
|
+
)
|
9
|
+
from ._common import (
|
10
|
+
deserialize_to_list,
|
11
|
+
serialize_from_list,
|
12
|
+
)
|
13
|
+
from .cairo_data_serializer import (
|
14
|
+
CairoDataSerializer,
|
15
|
+
)
|
16
|
+
from .felt_serializer import FeltSerializer
|
17
|
+
|
18
|
+
BYTES_31_SIZE = 31
|
19
|
+
|
20
|
+
|
21
|
+
@dataclass
|
22
|
+
class ByteArraySerializer(CairoDataSerializer[str, str]):
|
23
|
+
"""
|
24
|
+
Serializer for ByteArrays. Serializes to and deserializes from str values.
|
25
|
+
|
26
|
+
Examples:
|
27
|
+
"" => [0,0,0]
|
28
|
+
"hello" => [0,448378203247,5]
|
29
|
+
"""
|
30
|
+
|
31
|
+
def deserialize_with_context(self, context: DeserializationContext) -> str:
|
32
|
+
with context.push_entity("data_array_len"):
|
33
|
+
[size] = context.reader.read(1)
|
34
|
+
|
35
|
+
data = deserialize_to_list([FeltSerializer()] * size, context)
|
36
|
+
|
37
|
+
with context.push_entity("pending_word"):
|
38
|
+
[pending_word] = context.reader.read(1)
|
39
|
+
|
40
|
+
with context.push_entity("pending_word_len"):
|
41
|
+
[pending_word_len] = context.reader.read(1)
|
42
|
+
|
43
|
+
pending_word = decode_shortstring(pending_word)
|
44
|
+
context.ensure_valid_value(
|
45
|
+
len(pending_word) == pending_word_len,
|
46
|
+
f"Invalid length {pending_word_len} for pending word {pending_word}",
|
47
|
+
)
|
48
|
+
|
49
|
+
data_joined = "".join(map(decode_shortstring, data))
|
50
|
+
return data_joined + pending_word
|
51
|
+
|
52
|
+
def serialize_with_context(
|
53
|
+
self, context: SerializationContext, value: str
|
54
|
+
) -> Generator[int, None, None]:
|
55
|
+
context.ensure_valid_type(value, isinstance(value, str), "str")
|
56
|
+
data = [
|
57
|
+
value[i : i + BYTES_31_SIZE] for i in range(0, len(value), BYTES_31_SIZE)
|
58
|
+
]
|
59
|
+
pending_word = (
|
60
|
+
"" if len(data) == 0 or len(data[-1]) == BYTES_31_SIZE else data.pop(-1)
|
61
|
+
)
|
62
|
+
|
63
|
+
yield len(data)
|
64
|
+
yield from serialize_from_list([FeltSerializer()] * len(data), context, data)
|
65
|
+
yield encode_shortstring(pending_word)
|
66
|
+
yield len(pending_word)
|
@@ -0,0 +1,71 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from typing import Generator, Generic, List, TypeVar
|
3
|
+
|
4
|
+
from .._calldata_reader import CairoData
|
5
|
+
from .._context import (
|
6
|
+
DeserializationContext,
|
7
|
+
SerializationContext,
|
8
|
+
)
|
9
|
+
|
10
|
+
# Python type that is accepted by a serializer
|
11
|
+
# pylint: disable=invalid-name
|
12
|
+
SerializationType = TypeVar("SerializationType")
|
13
|
+
|
14
|
+
# Python type that will be returned from a serializer. Often same as SerializationType.
|
15
|
+
# pylint: disable=invalid-name
|
16
|
+
DeserializationType = TypeVar("DeserializationType")
|
17
|
+
|
18
|
+
|
19
|
+
class CairoDataSerializer(ABC, Generic[SerializationType, DeserializationType]):
|
20
|
+
"""
|
21
|
+
Base class for serializing/deserializing data to/from calldata.
|
22
|
+
"""
|
23
|
+
|
24
|
+
def deserialize(self, data: List[int]) -> DeserializationType:
|
25
|
+
"""
|
26
|
+
Transform calldata into python value.
|
27
|
+
|
28
|
+
:param data: calldata to deserialize.
|
29
|
+
:return: defined DeserializationType.
|
30
|
+
"""
|
31
|
+
with DeserializationContext.create(data) as context:
|
32
|
+
return self.deserialize_with_context(context)
|
33
|
+
|
34
|
+
def serialize(self, data: SerializationType) -> CairoData:
|
35
|
+
"""
|
36
|
+
Transform python data into calldata.
|
37
|
+
|
38
|
+
:param data: data to serialize.
|
39
|
+
:return: calldata.
|
40
|
+
"""
|
41
|
+
with SerializationContext.create() as context:
|
42
|
+
serialized_data = list(self.serialize_with_context(context, data))
|
43
|
+
|
44
|
+
return self.remove_units_from_serialized_data(serialized_data)
|
45
|
+
|
46
|
+
@abstractmethod
|
47
|
+
def deserialize_with_context(
|
48
|
+
self, context: DeserializationContext
|
49
|
+
) -> DeserializationType:
|
50
|
+
"""
|
51
|
+
Transform calldata into python value.
|
52
|
+
|
53
|
+
:param context: context of this deserialization.
|
54
|
+
:return: defined DeserializationType.
|
55
|
+
"""
|
56
|
+
|
57
|
+
@abstractmethod
|
58
|
+
def serialize_with_context(
|
59
|
+
self, context: SerializationContext, value: SerializationType
|
60
|
+
) -> Generator[int, None, None]:
|
61
|
+
"""
|
62
|
+
Transform python value into calldata.
|
63
|
+
|
64
|
+
:param context: context of this serialization.
|
65
|
+
:param value: python value to serialize.
|
66
|
+
:return: defined SerializationType.
|
67
|
+
"""
|
68
|
+
|
69
|
+
@staticmethod
|
70
|
+
def remove_units_from_serialized_data(serialized_data: List) -> List:
|
71
|
+
return [x for x in serialized_data if x is not None]
|
@@ -0,0 +1,71 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Dict, Generator, OrderedDict, Tuple, Union
|
3
|
+
|
4
|
+
from .._context import (
|
5
|
+
DeserializationContext,
|
6
|
+
SerializationContext,
|
7
|
+
)
|
8
|
+
from .cairo_data_serializer import (
|
9
|
+
CairoDataSerializer,
|
10
|
+
)
|
11
|
+
from ..tuple_dataclass import TupleDataclass
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass
|
15
|
+
class EnumSerializer(CairoDataSerializer[Union[Dict, TupleDataclass], TupleDataclass]):
|
16
|
+
"""
|
17
|
+
Serializer of enums.
|
18
|
+
Can serialize a dictionary and TupleDataclass.
|
19
|
+
Deserializes data to a TupleDataclass.
|
20
|
+
|
21
|
+
Example:
|
22
|
+
enum MyEnum {
|
23
|
+
a: u128,
|
24
|
+
b: u128
|
25
|
+
}
|
26
|
+
|
27
|
+
{"a": 1} => [0, 1]
|
28
|
+
{"b": 100} => [1, 100]
|
29
|
+
TupleDataclass(variant='a', value=100) => [0, 100]
|
30
|
+
"""
|
31
|
+
|
32
|
+
serializers: OrderedDict[str, CairoDataSerializer]
|
33
|
+
|
34
|
+
def deserialize_with_context(
|
35
|
+
self, context: DeserializationContext
|
36
|
+
) -> TupleDataclass:
|
37
|
+
[variant_index] = context.reader.read(1)
|
38
|
+
variant_name, serializer = self._get_variant(variant_index)
|
39
|
+
|
40
|
+
with context.push_entity("enum.variant: " + variant_name):
|
41
|
+
result_dict = {
|
42
|
+
"variant": variant_name,
|
43
|
+
"value": serializer.deserialize_with_context(context),
|
44
|
+
}
|
45
|
+
|
46
|
+
return TupleDataclass.from_dict(result_dict)
|
47
|
+
|
48
|
+
def serialize_with_context(
|
49
|
+
self, context: SerializationContext, value: Union[Dict, TupleDataclass]
|
50
|
+
) -> Generator[int, None, None]:
|
51
|
+
if isinstance(value, Dict):
|
52
|
+
items = list(value.items())
|
53
|
+
if len(items) != 1:
|
54
|
+
raise ValueError(
|
55
|
+
"Can serialize only one enum variant, got: " + str(len(items))
|
56
|
+
)
|
57
|
+
|
58
|
+
variant_name, variant_value = items[0]
|
59
|
+
else:
|
60
|
+
variant_name, variant_value = value
|
61
|
+
|
62
|
+
yield self._get_variant_index(variant_name)
|
63
|
+
yield from self.serializers[variant_name].serialize_with_context(
|
64
|
+
context, variant_value
|
65
|
+
)
|
66
|
+
|
67
|
+
def _get_variant(self, variant_index: int) -> Tuple[str, CairoDataSerializer]:
|
68
|
+
return list(self.serializers.items())[variant_index]
|
69
|
+
|
70
|
+
def _get_variant_index(self, variant_name: str) -> int:
|
71
|
+
return list(self.serializers.keys()).index(variant_name)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import warnings
|
2
|
+
from dataclasses import dataclass
|
3
|
+
from typing import Generator
|
4
|
+
|
5
|
+
from ...cairo.felt import encode_shortstring, is_in_felt_range
|
6
|
+
from ...constants import FIELD_PRIME
|
7
|
+
from .._context import (
|
8
|
+
Context,
|
9
|
+
DeserializationContext,
|
10
|
+
SerializationContext,
|
11
|
+
)
|
12
|
+
from .cairo_data_serializer import (
|
13
|
+
CairoDataSerializer,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
@dataclass
|
18
|
+
class FeltSerializer(CairoDataSerializer[int, int]):
|
19
|
+
"""
|
20
|
+
Serializer for field element. At the time of writing it is the only existing numeric type.
|
21
|
+
"""
|
22
|
+
|
23
|
+
def deserialize_with_context(self, context: DeserializationContext) -> int:
|
24
|
+
[val] = context.reader.read(1)
|
25
|
+
self._ensure_felt(context, val)
|
26
|
+
return val
|
27
|
+
|
28
|
+
def serialize_with_context(
|
29
|
+
self, context: SerializationContext, value: int
|
30
|
+
) -> Generator[int, None, None]:
|
31
|
+
if isinstance(value, str):
|
32
|
+
warnings.warn(
|
33
|
+
"Serializing shortstrings in FeltSerializer is deprecated. "
|
34
|
+
"Use starknet_py.cairo.felt.encode_shortstring instead.",
|
35
|
+
category=DeprecationWarning,
|
36
|
+
)
|
37
|
+
value = encode_shortstring(value)
|
38
|
+
yield value
|
39
|
+
return
|
40
|
+
|
41
|
+
context.ensure_valid_type(value, isinstance(value, int), "int")
|
42
|
+
self._ensure_felt(context, value)
|
43
|
+
yield value
|
44
|
+
|
45
|
+
@staticmethod
|
46
|
+
def _ensure_felt(context: Context, value: int):
|
47
|
+
context.ensure_valid_value(
|
48
|
+
is_in_felt_range(value),
|
49
|
+
f"invalid value '{value}' - must be in [0, {FIELD_PRIME}) range",
|
50
|
+
)
|
@@ -0,0 +1,58 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Dict, Generator, NamedTuple, OrderedDict, Union
|
3
|
+
|
4
|
+
from .._context import (
|
5
|
+
DeserializationContext,
|
6
|
+
SerializationContext,
|
7
|
+
)
|
8
|
+
from ._common import (
|
9
|
+
deserialize_to_dict,
|
10
|
+
serialize_from_dict,
|
11
|
+
)
|
12
|
+
from .cairo_data_serializer import (
|
13
|
+
CairoDataSerializer,
|
14
|
+
)
|
15
|
+
from ..tuple_dataclass import TupleDataclass
|
16
|
+
|
17
|
+
|
18
|
+
@dataclass
|
19
|
+
class NamedTupleSerializer(
|
20
|
+
CairoDataSerializer[Union[Dict, NamedTuple, TupleDataclass], TupleDataclass]
|
21
|
+
):
|
22
|
+
"""
|
23
|
+
Serializer for tuples with named fields.
|
24
|
+
Can serialize a dictionary, a named tuple and TupleDataclass.
|
25
|
+
Deserializes data to a TupleDataclass.
|
26
|
+
|
27
|
+
Example:
|
28
|
+
{"a": 1, "b": 2} => [1,2]
|
29
|
+
"""
|
30
|
+
|
31
|
+
serializers: OrderedDict[str, CairoDataSerializer]
|
32
|
+
|
33
|
+
def deserialize_with_context(
|
34
|
+
self, context: DeserializationContext
|
35
|
+
) -> TupleDataclass:
|
36
|
+
as_dictionary = deserialize_to_dict(self.serializers, context)
|
37
|
+
return TupleDataclass.from_dict(as_dictionary)
|
38
|
+
|
39
|
+
def serialize_with_context(
|
40
|
+
self,
|
41
|
+
context: SerializationContext,
|
42
|
+
value: Union[Dict, NamedTuple, TupleDataclass],
|
43
|
+
) -> Generator[int, None, None]:
|
44
|
+
# We can't use isinstance(value, NamedTuple), because there is no NamedTuple type.
|
45
|
+
context.ensure_valid_type(
|
46
|
+
value,
|
47
|
+
isinstance(value, (dict, TupleDataclass)) or self._is_namedtuple(value),
|
48
|
+
"dict, NamedTuple or TupleDataclass",
|
49
|
+
)
|
50
|
+
|
51
|
+
# noinspection PyUnresolvedReferences, PyProtectedMember
|
52
|
+
values: Dict = value if isinstance(value, dict) else value._asdict()
|
53
|
+
|
54
|
+
yield from serialize_from_dict(self.serializers, context, values)
|
55
|
+
|
56
|
+
@staticmethod
|
57
|
+
def _is_namedtuple(value) -> bool:
|
58
|
+
return isinstance(value, tuple) and hasattr(value, "_fields")
|
@@ -0,0 +1,43 @@
|
|
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 OptionSerializer(CairoDataSerializer[Optional[Any], Optional[Any]]):
|
15
|
+
"""
|
16
|
+
Serializer for Option type.
|
17
|
+
Can serialize None and common CairoTypes.
|
18
|
+
Deserializes data to None or CairoType.
|
19
|
+
|
20
|
+
Example:
|
21
|
+
None => [1]
|
22
|
+
{"option1": 123, "option2": None} => [0, 123, 1]
|
23
|
+
"""
|
24
|
+
|
25
|
+
serializer: CairoDataSerializer
|
26
|
+
|
27
|
+
def deserialize_with_context(
|
28
|
+
self, context: DeserializationContext
|
29
|
+
) -> Optional[Any]:
|
30
|
+
(is_none,) = context.reader.read(1)
|
31
|
+
if is_none == 1:
|
32
|
+
return None
|
33
|
+
|
34
|
+
return self.serializer.deserialize_with_context(context)
|
35
|
+
|
36
|
+
def serialize_with_context(
|
37
|
+
self, context: SerializationContext, value: Optional[Any]
|
38
|
+
) -> Generator[int, None, None]:
|
39
|
+
if value is None:
|
40
|
+
yield 1
|
41
|
+
else:
|
42
|
+
yield 0
|
43
|
+
yield from self.serializer.serialize_with_context(context, value)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from typing import Dict, Generator, List, Tuple
|
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 OutputSerializer(CairoDataSerializer[List, Tuple]):
|
15
|
+
"""
|
16
|
+
Serializer for function output.
|
17
|
+
Can't serialize anything.
|
18
|
+
Deserializes data to a Tuple.
|
19
|
+
|
20
|
+
Example:
|
21
|
+
[1, 1, 1] => (340282366920938463463374607431768211457)
|
22
|
+
"""
|
23
|
+
|
24
|
+
serializers: List[CairoDataSerializer] = field(init=True)
|
25
|
+
|
26
|
+
def deserialize_with_context(self, context: DeserializationContext) -> Tuple:
|
27
|
+
result = []
|
28
|
+
|
29
|
+
for index, serializer in enumerate(self.serializers):
|
30
|
+
with context.push_entity("output[" + str(index) + "]"):
|
31
|
+
result.append(serializer.deserialize_with_context(context))
|
32
|
+
|
33
|
+
return tuple(result)
|
34
|
+
|
35
|
+
def serialize_with_context(
|
36
|
+
self, context: SerializationContext, value: Dict
|
37
|
+
) -> Generator[int, None, None]:
|
38
|
+
raise ValueError(
|
39
|
+
"Output serializer can't be used to transform python data into calldata."
|
40
|
+
)
|
@@ -0,0 +1,72 @@
|
|
1
|
+
from collections import OrderedDict as _OrderedDict
|
2
|
+
from dataclasses import InitVar, dataclass, field
|
3
|
+
from typing import Dict, Generator, OrderedDict
|
4
|
+
|
5
|
+
from .._context import (
|
6
|
+
DeserializationContext,
|
7
|
+
SerializationContext,
|
8
|
+
)
|
9
|
+
from ._common import (
|
10
|
+
deserialize_to_dict,
|
11
|
+
serialize_from_dict,
|
12
|
+
)
|
13
|
+
from .array_serializer import ArraySerializer
|
14
|
+
from .cairo_data_serializer import (
|
15
|
+
CairoDataSerializer,
|
16
|
+
)
|
17
|
+
from .felt_serializer import FeltSerializer
|
18
|
+
from ..tuple_dataclass import TupleDataclass
|
19
|
+
|
20
|
+
SIZE_SUFFIX = "_len"
|
21
|
+
SIZE_SUFFIX_LEN = len(SIZE_SUFFIX)
|
22
|
+
|
23
|
+
|
24
|
+
@dataclass
|
25
|
+
class PayloadSerializer(CairoDataSerializer[Dict, TupleDataclass]):
|
26
|
+
"""
|
27
|
+
Serializer for payloads like function arguments/function outputs/events.
|
28
|
+
Can serialize a dictionary.
|
29
|
+
Deserializes data to a TupleDataclass.
|
30
|
+
|
31
|
+
Example:
|
32
|
+
{"a": 1, "b": 2} => [1,2]
|
33
|
+
"""
|
34
|
+
|
35
|
+
# Value present only in constructor.
|
36
|
+
# We don't want to mutate the serializers received in constructor.
|
37
|
+
input_serializers: InitVar[OrderedDict[str, CairoDataSerializer]]
|
38
|
+
|
39
|
+
serializers: OrderedDict[str, CairoDataSerializer] = field(init=False)
|
40
|
+
|
41
|
+
def __post_init__(self, input_serializers):
|
42
|
+
"""
|
43
|
+
ABI adds ARG_len for every argument ARG that is an array. We parse length as a part of ArraySerializer, so we
|
44
|
+
need to remove those lengths from args.
|
45
|
+
"""
|
46
|
+
self.serializers = _OrderedDict(
|
47
|
+
(key, serializer)
|
48
|
+
for key, serializer in input_serializers.items()
|
49
|
+
if not self._is_len_arg(key, input_serializers)
|
50
|
+
)
|
51
|
+
|
52
|
+
def deserialize_with_context(
|
53
|
+
self, context: DeserializationContext
|
54
|
+
) -> TupleDataclass:
|
55
|
+
as_dictionary = deserialize_to_dict(self.serializers, context)
|
56
|
+
return TupleDataclass.from_dict(as_dictionary)
|
57
|
+
|
58
|
+
def serialize_with_context(
|
59
|
+
self, context: SerializationContext, value: Dict
|
60
|
+
) -> Generator[int, None, None]:
|
61
|
+
yield from serialize_from_dict(self.serializers, context, value)
|
62
|
+
|
63
|
+
@staticmethod
|
64
|
+
def _is_len_arg(arg_name: str, serializers: Dict[str, CairoDataSerializer]) -> bool:
|
65
|
+
return (
|
66
|
+
arg_name.endswith(SIZE_SUFFIX)
|
67
|
+
and isinstance(serializers[arg_name], FeltSerializer)
|
68
|
+
# There is an ArraySerializer under key that is arg_name without the size suffix
|
69
|
+
and isinstance(
|
70
|
+
serializers.get(arg_name[:-SIZE_SUFFIX_LEN]), ArraySerializer
|
71
|
+
)
|
72
|
+
)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Dict, Generator, OrderedDict
|
3
|
+
|
4
|
+
from .._context import (
|
5
|
+
DeserializationContext,
|
6
|
+
SerializationContext,
|
7
|
+
)
|
8
|
+
from ._common import (
|
9
|
+
deserialize_to_dict,
|
10
|
+
serialize_from_dict,
|
11
|
+
)
|
12
|
+
from .cairo_data_serializer import (
|
13
|
+
CairoDataSerializer,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
@dataclass
|
18
|
+
class StructSerializer(CairoDataSerializer[Dict, Dict]):
|
19
|
+
"""
|
20
|
+
Serializer of custom structures.
|
21
|
+
Can serialize a dictionary.
|
22
|
+
Deserializes data to a dictionary.
|
23
|
+
|
24
|
+
Example:
|
25
|
+
{"a": 1, "b": 2} => [1,2]
|
26
|
+
"""
|
27
|
+
|
28
|
+
serializers: OrderedDict[str, CairoDataSerializer]
|
29
|
+
|
30
|
+
def deserialize_with_context(self, context: DeserializationContext) -> Dict:
|
31
|
+
return deserialize_to_dict(self.serializers, context)
|
32
|
+
|
33
|
+
def serialize_with_context(
|
34
|
+
self, context: SerializationContext, value: Dict
|
35
|
+
) -> Generator[int, None, None]:
|
36
|
+
yield from serialize_from_dict(self.serializers, context, value)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Generator, Iterable, List, Tuple
|
3
|
+
|
4
|
+
from .._context import (
|
5
|
+
DeserializationContext,
|
6
|
+
SerializationContext,
|
7
|
+
)
|
8
|
+
from ._common import (
|
9
|
+
deserialize_to_list,
|
10
|
+
serialize_from_list,
|
11
|
+
)
|
12
|
+
from .cairo_data_serializer import (
|
13
|
+
CairoDataSerializer,
|
14
|
+
)
|
15
|
+
|
16
|
+
|
17
|
+
@dataclass
|
18
|
+
class TupleSerializer(CairoDataSerializer[Iterable, Tuple]):
|
19
|
+
"""
|
20
|
+
Serializer for tuples without named fields.
|
21
|
+
Can serialize any iterable.
|
22
|
+
Deserializes data to a python tuple.
|
23
|
+
|
24
|
+
Example:
|
25
|
+
(1,2,(3,4)) => [1,2,3,4]
|
26
|
+
"""
|
27
|
+
|
28
|
+
serializers: List[CairoDataSerializer]
|
29
|
+
|
30
|
+
def deserialize_with_context(self, context: DeserializationContext) -> Tuple:
|
31
|
+
return tuple(deserialize_to_list(self.serializers, context))
|
32
|
+
|
33
|
+
def serialize_with_context(
|
34
|
+
self, context: SerializationContext, value: Iterable
|
35
|
+
) -> Generator[int, None, None]:
|
36
|
+
yield from serialize_from_list(self.serializers, context, [*value])
|
@@ -0,0 +1,76 @@
|
|
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
|
+
U128_UPPER_BOUND = 2**128
|
15
|
+
|
16
|
+
|
17
|
+
class Uint256Dict(TypedDict):
|
18
|
+
low: int
|
19
|
+
high: int
|
20
|
+
|
21
|
+
|
22
|
+
@dataclass
|
23
|
+
class Uint256Serializer(CairoDataSerializer[Union[int, Uint256Dict], int]):
|
24
|
+
"""
|
25
|
+
Serializer of Uint256. In Cairo it is represented by structure {low: Uint128, high: Uint128}.
|
26
|
+
Can serialize an int.
|
27
|
+
Deserializes data to an int.
|
28
|
+
|
29
|
+
Examples:
|
30
|
+
0 => [0,0]
|
31
|
+
1 => [1,0]
|
32
|
+
2**128 => [0,1]
|
33
|
+
3 + 2**128 => [3,1]
|
34
|
+
"""
|
35
|
+
|
36
|
+
def deserialize_with_context(self, context: DeserializationContext) -> int:
|
37
|
+
[low, high] = context.reader.read(2)
|
38
|
+
|
39
|
+
# Checking if resulting value is in [0, 2**256) range is not enough. Uint256 should be made of two uint128.
|
40
|
+
with context.push_entity("low"):
|
41
|
+
self._ensure_valid_uint128(low, context)
|
42
|
+
with context.push_entity("high"):
|
43
|
+
self._ensure_valid_uint128(high, context)
|
44
|
+
|
45
|
+
return (high << 128) + low
|
46
|
+
|
47
|
+
def serialize_with_context(
|
48
|
+
self, context: SerializationContext, value: Union[int, Uint256Dict]
|
49
|
+
) -> Generator[int, None, None]:
|
50
|
+
context.ensure_valid_type(value, isinstance(value, (int, dict)), "int or dict")
|
51
|
+
if isinstance(value, int):
|
52
|
+
yield from self._serialize_from_int(value)
|
53
|
+
else:
|
54
|
+
yield from self._serialize_from_dict(context, value)
|
55
|
+
|
56
|
+
@staticmethod
|
57
|
+
def _serialize_from_int(value: int) -> Generator[int, None, None]:
|
58
|
+
uint256_range_check(value)
|
59
|
+
result = (value % 2**128, value // 2**128)
|
60
|
+
yield from result
|
61
|
+
|
62
|
+
def _serialize_from_dict(
|
63
|
+
self, context: SerializationContext, value: Uint256Dict
|
64
|
+
) -> Generator[int, None, None]:
|
65
|
+
with context.push_entity("low"):
|
66
|
+
self._ensure_valid_uint128(value["low"], context)
|
67
|
+
yield value["low"]
|
68
|
+
with context.push_entity("high"):
|
69
|
+
self._ensure_valid_uint128(value["high"], context)
|
70
|
+
yield value["high"]
|
71
|
+
|
72
|
+
@staticmethod
|
73
|
+
def _ensure_valid_uint128(value: int, context: Context):
|
74
|
+
context.ensure_valid_value(
|
75
|
+
0 <= value < U128_UPPER_BOUND, "expected value in range [0;2**128)"
|
76
|
+
)
|