gate-io-api 0.0.15__py3-none-any.whl → 0.0.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of gate-io-api might be problematic. Click here for more details.
- gate/__init__.py +7 -0
- gate/ccxt/__init__.py +101 -0
- gate/ccxt/abstract/gate.py +284 -0
- gate/ccxt/async_support/__init__.py +80 -0
- gate/ccxt/async_support/base/__init__.py +1 -0
- gate/ccxt/async_support/base/exchange.py +2100 -0
- gate/ccxt/async_support/base/throttler.py +50 -0
- gate/ccxt/async_support/base/ws/__init__.py +38 -0
- gate/ccxt/async_support/base/ws/aiohttp_client.py +147 -0
- gate/ccxt/async_support/base/ws/cache.py +213 -0
- gate/ccxt/async_support/base/ws/client.py +214 -0
- gate/ccxt/async_support/base/ws/fast_client.py +97 -0
- gate/ccxt/async_support/base/ws/functions.py +59 -0
- gate/ccxt/async_support/base/ws/future.py +69 -0
- gate/ccxt/async_support/base/ws/order_book.py +78 -0
- gate/ccxt/async_support/base/ws/order_book_side.py +174 -0
- gate/ccxt/async_support/gate.py +7739 -0
- gate/ccxt/base/__init__.py +27 -0
- gate/ccxt/base/decimal_to_precision.py +174 -0
- gate/ccxt/base/errors.py +267 -0
- gate/ccxt/base/exchange.py +6769 -0
- gate/ccxt/base/precise.py +297 -0
- gate/ccxt/base/types.py +577 -0
- gate/ccxt/gate.py +7738 -0
- gate/ccxt/pro/__init__.py +21 -0
- gate/ccxt/pro/gate.py +1950 -0
- gate/ccxt/static_dependencies/README.md +1 -0
- gate/ccxt/static_dependencies/__init__.py +1 -0
- gate/ccxt/static_dependencies/ecdsa/__init__.py +14 -0
- gate/ccxt/static_dependencies/ecdsa/_version.py +520 -0
- gate/ccxt/static_dependencies/ecdsa/curves.py +56 -0
- gate/ccxt/static_dependencies/ecdsa/der.py +221 -0
- gate/ccxt/static_dependencies/ecdsa/ecdsa.py +310 -0
- gate/ccxt/static_dependencies/ecdsa/ellipticcurve.py +197 -0
- gate/ccxt/static_dependencies/ecdsa/keys.py +332 -0
- gate/ccxt/static_dependencies/ecdsa/numbertheory.py +531 -0
- gate/ccxt/static_dependencies/ecdsa/rfc6979.py +100 -0
- gate/ccxt/static_dependencies/ecdsa/util.py +266 -0
- gate/ccxt/static_dependencies/ethereum/__init__.py +7 -0
- gate/ccxt/static_dependencies/ethereum/abi/__init__.py +16 -0
- gate/ccxt/static_dependencies/ethereum/abi/abi.py +19 -0
- gate/ccxt/static_dependencies/ethereum/abi/base.py +152 -0
- gate/ccxt/static_dependencies/ethereum/abi/codec.py +217 -0
- gate/ccxt/static_dependencies/ethereum/abi/constants.py +3 -0
- gate/ccxt/static_dependencies/ethereum/abi/decoding.py +565 -0
- gate/ccxt/static_dependencies/ethereum/abi/encoding.py +720 -0
- gate/ccxt/static_dependencies/ethereum/abi/exceptions.py +139 -0
- gate/ccxt/static_dependencies/ethereum/abi/grammar.py +443 -0
- gate/ccxt/static_dependencies/ethereum/abi/packed.py +13 -0
- gate/ccxt/static_dependencies/ethereum/abi/py.typed +0 -0
- gate/ccxt/static_dependencies/ethereum/abi/registry.py +643 -0
- gate/ccxt/static_dependencies/ethereum/abi/tools/__init__.py +3 -0
- gate/ccxt/static_dependencies/ethereum/abi/tools/_strategies.py +230 -0
- gate/ccxt/static_dependencies/ethereum/abi/utils/__init__.py +0 -0
- gate/ccxt/static_dependencies/ethereum/abi/utils/numeric.py +83 -0
- gate/ccxt/static_dependencies/ethereum/abi/utils/padding.py +27 -0
- gate/ccxt/static_dependencies/ethereum/abi/utils/string.py +19 -0
- gate/ccxt/static_dependencies/ethereum/account/__init__.py +3 -0
- gate/ccxt/static_dependencies/ethereum/account/encode_typed_data/__init__.py +4 -0
- gate/ccxt/static_dependencies/ethereum/account/encode_typed_data/encoding_and_hashing.py +239 -0
- gate/ccxt/static_dependencies/ethereum/account/encode_typed_data/helpers.py +40 -0
- gate/ccxt/static_dependencies/ethereum/account/messages.py +263 -0
- gate/ccxt/static_dependencies/ethereum/account/py.typed +0 -0
- gate/ccxt/static_dependencies/ethereum/hexbytes/__init__.py +5 -0
- gate/ccxt/static_dependencies/ethereum/hexbytes/_utils.py +54 -0
- gate/ccxt/static_dependencies/ethereum/hexbytes/main.py +65 -0
- gate/ccxt/static_dependencies/ethereum/hexbytes/py.typed +0 -0
- gate/ccxt/static_dependencies/ethereum/typing/__init__.py +63 -0
- gate/ccxt/static_dependencies/ethereum/typing/abi.py +6 -0
- gate/ccxt/static_dependencies/ethereum/typing/bls.py +7 -0
- gate/ccxt/static_dependencies/ethereum/typing/discovery.py +5 -0
- gate/ccxt/static_dependencies/ethereum/typing/encoding.py +7 -0
- gate/ccxt/static_dependencies/ethereum/typing/enums.py +17 -0
- gate/ccxt/static_dependencies/ethereum/typing/ethpm.py +9 -0
- gate/ccxt/static_dependencies/ethereum/typing/evm.py +20 -0
- gate/ccxt/static_dependencies/ethereum/typing/networks.py +1122 -0
- gate/ccxt/static_dependencies/ethereum/typing/py.typed +0 -0
- gate/ccxt/static_dependencies/ethereum/utils/__init__.py +115 -0
- gate/ccxt/static_dependencies/ethereum/utils/abi.py +72 -0
- gate/ccxt/static_dependencies/ethereum/utils/address.py +171 -0
- gate/ccxt/static_dependencies/ethereum/utils/applicators.py +151 -0
- gate/ccxt/static_dependencies/ethereum/utils/conversions.py +190 -0
- gate/ccxt/static_dependencies/ethereum/utils/currency.py +107 -0
- gate/ccxt/static_dependencies/ethereum/utils/curried/__init__.py +269 -0
- gate/ccxt/static_dependencies/ethereum/utils/debug.py +20 -0
- gate/ccxt/static_dependencies/ethereum/utils/decorators.py +132 -0
- gate/ccxt/static_dependencies/ethereum/utils/encoding.py +6 -0
- gate/ccxt/static_dependencies/ethereum/utils/exceptions.py +4 -0
- gate/ccxt/static_dependencies/ethereum/utils/functional.py +75 -0
- gate/ccxt/static_dependencies/ethereum/utils/hexadecimal.py +74 -0
- gate/ccxt/static_dependencies/ethereum/utils/humanize.py +188 -0
- gate/ccxt/static_dependencies/ethereum/utils/logging.py +159 -0
- gate/ccxt/static_dependencies/ethereum/utils/module_loading.py +31 -0
- gate/ccxt/static_dependencies/ethereum/utils/numeric.py +43 -0
- gate/ccxt/static_dependencies/ethereum/utils/py.typed +0 -0
- gate/ccxt/static_dependencies/ethereum/utils/toolz.py +76 -0
- gate/ccxt/static_dependencies/ethereum/utils/types.py +54 -0
- gate/ccxt/static_dependencies/ethereum/utils/typing/__init__.py +18 -0
- gate/ccxt/static_dependencies/ethereum/utils/typing/misc.py +14 -0
- gate/ccxt/static_dependencies/ethereum/utils/units.py +31 -0
- gate/ccxt/static_dependencies/keccak/__init__.py +3 -0
- gate/ccxt/static_dependencies/keccak/keccak.py +197 -0
- gate/ccxt/static_dependencies/lark/__init__.py +38 -0
- gate/ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- gate/ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- gate/ccxt/static_dependencies/lark/ast_utils.py +59 -0
- gate/ccxt/static_dependencies/lark/common.py +86 -0
- gate/ccxt/static_dependencies/lark/exceptions.py +292 -0
- gate/ccxt/static_dependencies/lark/grammar.py +130 -0
- gate/ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- gate/ccxt/static_dependencies/lark/grammars/common.lark +59 -0
- gate/ccxt/static_dependencies/lark/grammars/lark.lark +62 -0
- gate/ccxt/static_dependencies/lark/grammars/python.lark +302 -0
- gate/ccxt/static_dependencies/lark/grammars/unicode.lark +7 -0
- gate/ccxt/static_dependencies/lark/indenter.py +143 -0
- gate/ccxt/static_dependencies/lark/lark.py +658 -0
- gate/ccxt/static_dependencies/lark/lexer.py +678 -0
- gate/ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- gate/ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- gate/ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- gate/ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- gate/ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- gate/ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- gate/ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- gate/ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- gate/ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- gate/ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- gate/ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- gate/ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- gate/ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- gate/ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- gate/ccxt/static_dependencies/lark/py.typed +0 -0
- gate/ccxt/static_dependencies/lark/reconstruct.py +107 -0
- gate/ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- gate/ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- gate/ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- gate/ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- gate/ccxt/static_dependencies/lark/tree.py +267 -0
- gate/ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- gate/ccxt/static_dependencies/lark/tree_templates.py +180 -0
- gate/ccxt/static_dependencies/lark/utils.py +343 -0
- gate/ccxt/static_dependencies/lark/visitors.py +596 -0
- gate/ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- gate/ccxt/static_dependencies/marshmallow/base.py +65 -0
- gate/ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- gate/ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- gate/ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- gate/ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- gate/ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- gate/ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- gate/ccxt/static_dependencies/marshmallow/py.typed +0 -0
- gate/ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- gate/ccxt/static_dependencies/marshmallow/types.py +12 -0
- gate/ccxt/static_dependencies/marshmallow/utils.py +378 -0
- gate/ccxt/static_dependencies/marshmallow/validate.py +678 -0
- gate/ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- gate/ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- gate/ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- gate/ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- gate/ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- gate/ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- gate/ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- gate/ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- gate/ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- gate/ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- gate/ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- gate/ccxt/static_dependencies/msgpack/__init__.py +55 -0
- gate/ccxt/static_dependencies/msgpack/_cmsgpack.pyx +11 -0
- gate/ccxt/static_dependencies/msgpack/_packer.pyx +374 -0
- gate/ccxt/static_dependencies/msgpack/_unpacker.pyx +547 -0
- gate/ccxt/static_dependencies/msgpack/buff_converter.h +8 -0
- gate/ccxt/static_dependencies/msgpack/exceptions.py +48 -0
- gate/ccxt/static_dependencies/msgpack/ext.py +168 -0
- gate/ccxt/static_dependencies/msgpack/fallback.py +951 -0
- gate/ccxt/static_dependencies/msgpack/pack.h +89 -0
- gate/ccxt/static_dependencies/msgpack/pack_template.h +820 -0
- gate/ccxt/static_dependencies/msgpack/sysdep.h +194 -0
- gate/ccxt/static_dependencies/msgpack/unpack.h +391 -0
- gate/ccxt/static_dependencies/msgpack/unpack_define.h +95 -0
- gate/ccxt/static_dependencies/msgpack/unpack_template.h +464 -0
- gate/ccxt/static_dependencies/parsimonious/__init__.py +10 -0
- gate/ccxt/static_dependencies/parsimonious/exceptions.py +105 -0
- gate/ccxt/static_dependencies/parsimonious/expressions.py +479 -0
- gate/ccxt/static_dependencies/parsimonious/grammar.py +487 -0
- gate/ccxt/static_dependencies/parsimonious/nodes.py +325 -0
- gate/ccxt/static_dependencies/parsimonious/utils.py +40 -0
- gate/ccxt/static_dependencies/starknet/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/abi/v0/__init__.py +2 -0
- gate/ccxt/static_dependencies/starknet/abi/v0/model.py +44 -0
- gate/ccxt/static_dependencies/starknet/abi/v0/parser.py +216 -0
- gate/ccxt/static_dependencies/starknet/abi/v0/schemas.py +72 -0
- gate/ccxt/static_dependencies/starknet/abi/v0/shape.py +63 -0
- gate/ccxt/static_dependencies/starknet/abi/v1/__init__.py +2 -0
- gate/ccxt/static_dependencies/starknet/abi/v1/core_structures.json +14 -0
- gate/ccxt/static_dependencies/starknet/abi/v1/model.py +39 -0
- gate/ccxt/static_dependencies/starknet/abi/v1/parser.py +220 -0
- gate/ccxt/static_dependencies/starknet/abi/v1/parser_transformer.py +179 -0
- gate/ccxt/static_dependencies/starknet/abi/v1/schemas.py +66 -0
- gate/ccxt/static_dependencies/starknet/abi/v1/shape.py +47 -0
- gate/ccxt/static_dependencies/starknet/abi/v2/__init__.py +2 -0
- gate/ccxt/static_dependencies/starknet/abi/v2/model.py +89 -0
- gate/ccxt/static_dependencies/starknet/abi/v2/parser.py +293 -0
- gate/ccxt/static_dependencies/starknet/abi/v2/parser_transformer.py +192 -0
- gate/ccxt/static_dependencies/starknet/abi/v2/schemas.py +132 -0
- gate/ccxt/static_dependencies/starknet/abi/v2/shape.py +107 -0
- gate/ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- gate/ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- gate/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- gate/ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- gate/ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- gate/ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- gate/ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- gate/ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- gate/ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- gate/ccxt/static_dependencies/starknet/common.py +15 -0
- gate/ccxt/static_dependencies/starknet/constants.py +39 -0
- gate/ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/hash/address.py +79 -0
- gate/ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- gate/ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- gate/ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- gate/ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- gate/ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- gate/ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- gate/ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- gate/ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- gate/ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- gate/ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- gate/ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- gate/ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- gate/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- gate/ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- gate/ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- gate/ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- gate/ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- gate/ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- gate/ccxt/static_dependencies/starkware/__init__.py +0 -0
- gate/ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- gate/ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- gate/ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- gate/ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- gate/ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- gate/ccxt/static_dependencies/sympy/__init__.py +0 -0
- gate/ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- gate/ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- gate/ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- gate/ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- gate/ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- gate/ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- gate/ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- gate/ccxt/static_dependencies/toolz/__init__.py +26 -0
- gate/ccxt/static_dependencies/toolz/_signatures.py +784 -0
- gate/ccxt/static_dependencies/toolz/_version.py +520 -0
- gate/ccxt/static_dependencies/toolz/compatibility.py +30 -0
- gate/ccxt/static_dependencies/toolz/curried/__init__.py +101 -0
- gate/ccxt/static_dependencies/toolz/curried/exceptions.py +22 -0
- gate/ccxt/static_dependencies/toolz/curried/operator.py +22 -0
- gate/ccxt/static_dependencies/toolz/dicttoolz.py +339 -0
- gate/ccxt/static_dependencies/toolz/functoolz.py +1049 -0
- gate/ccxt/static_dependencies/toolz/itertoolz.py +1057 -0
- gate/ccxt/static_dependencies/toolz/recipes.py +46 -0
- gate/ccxt/static_dependencies/toolz/utils.py +9 -0
- gate/ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- gate/ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- {gate_io_api-0.0.15.dist-info → gate_io_api-0.0.16.dist-info}/METADATA +1 -1
- gate_io_api-0.0.16.dist-info/RECORD +288 -0
- gate_io_api-0.0.15.dist-info/RECORD +0 -3
- {gate_io_api-0.0.15.dist-info → gate_io_api-0.0.16.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Callable,
|
|
3
|
+
Union,
|
|
4
|
+
)
|
|
5
|
+
|
|
6
|
+
from ...typing.abi import (
|
|
7
|
+
TypeStr,
|
|
8
|
+
)
|
|
9
|
+
from ..utils import (
|
|
10
|
+
to_checksum_address,
|
|
11
|
+
)
|
|
12
|
+
from hypothesis import (
|
|
13
|
+
strategies as st,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
from ..grammar import (
|
|
17
|
+
ABIType,
|
|
18
|
+
normalize,
|
|
19
|
+
parse,
|
|
20
|
+
)
|
|
21
|
+
from ..registry import (
|
|
22
|
+
BaseEquals,
|
|
23
|
+
BaseRegistry,
|
|
24
|
+
Lookup,
|
|
25
|
+
PredicateMapping,
|
|
26
|
+
has_arrlist,
|
|
27
|
+
is_base_tuple,
|
|
28
|
+
)
|
|
29
|
+
from ..utils.numeric import (
|
|
30
|
+
scale_places,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
StrategyFactory = Callable[[ABIType, "StrategyRegistry"], st.SearchStrategy]
|
|
34
|
+
StrategyRegistration = Union[st.SearchStrategy, StrategyFactory]
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class StrategyRegistry(BaseRegistry):
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self._strategies = PredicateMapping("strategy registry")
|
|
40
|
+
|
|
41
|
+
def register_strategy(
|
|
42
|
+
self, lookup: Lookup, registration: StrategyRegistration, label: str = None
|
|
43
|
+
) -> None:
|
|
44
|
+
self._register(self._strategies, lookup, registration, label=label)
|
|
45
|
+
|
|
46
|
+
def unregister_strategy(self, lookup_or_label: Lookup) -> None:
|
|
47
|
+
self._unregister(self._strategies, lookup_or_label)
|
|
48
|
+
|
|
49
|
+
def get_strategy(self, type_str: TypeStr) -> st.SearchStrategy:
|
|
50
|
+
"""
|
|
51
|
+
Returns a hypothesis strategy for the given ABI type.
|
|
52
|
+
|
|
53
|
+
:param type_str: The canonical string representation of the ABI type
|
|
54
|
+
for which a hypothesis strategy should be returned.
|
|
55
|
+
|
|
56
|
+
:returns: A hypothesis strategy for generating Python values that are
|
|
57
|
+
encodable as values of the given ABI type.
|
|
58
|
+
"""
|
|
59
|
+
registration = self._get_registration(self._strategies, type_str)
|
|
60
|
+
|
|
61
|
+
if isinstance(registration, st.SearchStrategy):
|
|
62
|
+
# If a hypothesis strategy was registered, just return it
|
|
63
|
+
return registration
|
|
64
|
+
else:
|
|
65
|
+
# Otherwise, assume the factory is a callable. Call it with the abi
|
|
66
|
+
# type to get an appropriate hypothesis strategy.
|
|
67
|
+
normalized_type_str = normalize(type_str)
|
|
68
|
+
abi_type = parse(normalized_type_str)
|
|
69
|
+
strategy = registration(abi_type, self)
|
|
70
|
+
|
|
71
|
+
return strategy
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def get_uint_strategy(
|
|
75
|
+
abi_type: ABIType, registry: StrategyRegistry
|
|
76
|
+
) -> st.SearchStrategy:
|
|
77
|
+
bits = abi_type.sub
|
|
78
|
+
|
|
79
|
+
return st.integers(
|
|
80
|
+
min_value=0,
|
|
81
|
+
max_value=2**bits - 1,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def get_int_strategy(
|
|
86
|
+
abi_type: ABIType, registry: StrategyRegistry
|
|
87
|
+
) -> st.SearchStrategy:
|
|
88
|
+
bits = abi_type.sub
|
|
89
|
+
|
|
90
|
+
return st.integers(
|
|
91
|
+
min_value=-(2 ** (bits - 1)),
|
|
92
|
+
max_value=2 ** (bits - 1) - 1,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
address_strategy = st.binary(min_size=20, max_size=20).map(to_checksum_address)
|
|
97
|
+
bool_strategy = st.booleans()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_ufixed_strategy(
|
|
101
|
+
abi_type: ABIType, registry: StrategyRegistry
|
|
102
|
+
) -> st.SearchStrategy:
|
|
103
|
+
bits, places = abi_type.sub
|
|
104
|
+
|
|
105
|
+
return st.decimals(
|
|
106
|
+
min_value=0,
|
|
107
|
+
max_value=2**bits - 1,
|
|
108
|
+
places=0,
|
|
109
|
+
).map(scale_places(places))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def get_fixed_strategy(
|
|
113
|
+
abi_type: ABIType, registry: StrategyRegistry
|
|
114
|
+
) -> st.SearchStrategy:
|
|
115
|
+
bits, places = abi_type.sub
|
|
116
|
+
|
|
117
|
+
return st.decimals(
|
|
118
|
+
min_value=-(2 ** (bits - 1)),
|
|
119
|
+
max_value=2 ** (bits - 1) - 1,
|
|
120
|
+
places=0,
|
|
121
|
+
).map(scale_places(places))
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def get_bytes_strategy(
|
|
125
|
+
abi_type: ABIType, registry: StrategyRegistry
|
|
126
|
+
) -> st.SearchStrategy:
|
|
127
|
+
num_bytes = abi_type.sub
|
|
128
|
+
|
|
129
|
+
return st.binary(
|
|
130
|
+
min_size=num_bytes,
|
|
131
|
+
max_size=num_bytes,
|
|
132
|
+
)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
bytes_strategy = st.binary(min_size=0, max_size=4096)
|
|
136
|
+
string_strategy = st.text()
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def get_array_strategy(
|
|
140
|
+
abi_type: ABIType, registry: StrategyRegistry
|
|
141
|
+
) -> st.SearchStrategy:
|
|
142
|
+
item_type = abi_type.item_type
|
|
143
|
+
item_type_str = item_type.to_type_str()
|
|
144
|
+
item_strategy = registry.get_strategy(item_type_str)
|
|
145
|
+
|
|
146
|
+
last_dim = abi_type.arrlist[-1]
|
|
147
|
+
if len(last_dim) == 0:
|
|
148
|
+
# Is dynamic list. Don't restrict length.
|
|
149
|
+
return st.lists(item_strategy)
|
|
150
|
+
else:
|
|
151
|
+
# Is static list. Restrict length.
|
|
152
|
+
dim_size = last_dim[0]
|
|
153
|
+
return st.lists(item_strategy, min_size=dim_size, max_size=dim_size)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def get_tuple_strategy(
|
|
157
|
+
abi_type: ABIType, registry: StrategyRegistry
|
|
158
|
+
) -> st.SearchStrategy:
|
|
159
|
+
component_strategies = [
|
|
160
|
+
registry.get_strategy(comp_abi_type.to_type_str())
|
|
161
|
+
for comp_abi_type in abi_type.components
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
return st.tuples(*component_strategies)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
strategy_registry = StrategyRegistry()
|
|
168
|
+
|
|
169
|
+
strategy_registry.register_strategy(
|
|
170
|
+
BaseEquals("uint"),
|
|
171
|
+
get_uint_strategy,
|
|
172
|
+
label="uint",
|
|
173
|
+
)
|
|
174
|
+
strategy_registry.register_strategy(
|
|
175
|
+
BaseEquals("int"),
|
|
176
|
+
get_int_strategy,
|
|
177
|
+
label="int",
|
|
178
|
+
)
|
|
179
|
+
strategy_registry.register_strategy(
|
|
180
|
+
BaseEquals("address", with_sub=False),
|
|
181
|
+
address_strategy,
|
|
182
|
+
label="address",
|
|
183
|
+
)
|
|
184
|
+
strategy_registry.register_strategy(
|
|
185
|
+
BaseEquals("bool", with_sub=False),
|
|
186
|
+
bool_strategy,
|
|
187
|
+
label="bool",
|
|
188
|
+
)
|
|
189
|
+
strategy_registry.register_strategy(
|
|
190
|
+
BaseEquals("ufixed"),
|
|
191
|
+
get_ufixed_strategy,
|
|
192
|
+
label="ufixed",
|
|
193
|
+
)
|
|
194
|
+
strategy_registry.register_strategy(
|
|
195
|
+
BaseEquals("fixed"),
|
|
196
|
+
get_fixed_strategy,
|
|
197
|
+
label="fixed",
|
|
198
|
+
)
|
|
199
|
+
strategy_registry.register_strategy(
|
|
200
|
+
BaseEquals("bytes", with_sub=True),
|
|
201
|
+
get_bytes_strategy,
|
|
202
|
+
label="bytes<M>",
|
|
203
|
+
)
|
|
204
|
+
strategy_registry.register_strategy(
|
|
205
|
+
BaseEquals("bytes", with_sub=False),
|
|
206
|
+
bytes_strategy,
|
|
207
|
+
label="bytes",
|
|
208
|
+
)
|
|
209
|
+
strategy_registry.register_strategy(
|
|
210
|
+
BaseEquals("function", with_sub=False),
|
|
211
|
+
get_bytes_strategy,
|
|
212
|
+
label="function",
|
|
213
|
+
)
|
|
214
|
+
strategy_registry.register_strategy(
|
|
215
|
+
BaseEquals("string", with_sub=False),
|
|
216
|
+
string_strategy,
|
|
217
|
+
label="string",
|
|
218
|
+
)
|
|
219
|
+
strategy_registry.register_strategy(
|
|
220
|
+
has_arrlist,
|
|
221
|
+
get_array_strategy,
|
|
222
|
+
label="has_arrlist",
|
|
223
|
+
)
|
|
224
|
+
strategy_registry.register_strategy(
|
|
225
|
+
is_base_tuple,
|
|
226
|
+
get_tuple_strategy,
|
|
227
|
+
label="is_base_tuple",
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
get_abi_strategy = strategy_registry.get_strategy
|
|
File without changes
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import decimal
|
|
2
|
+
from typing import (
|
|
3
|
+
Callable,
|
|
4
|
+
Tuple,
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
ABI_DECIMAL_PREC = 999
|
|
8
|
+
|
|
9
|
+
abi_decimal_context = decimal.Context(prec=ABI_DECIMAL_PREC)
|
|
10
|
+
|
|
11
|
+
ZERO = decimal.Decimal(0)
|
|
12
|
+
TEN = decimal.Decimal(10)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def ceil32(x: int) -> int:
|
|
16
|
+
return x if x % 32 == 0 else x + 32 - (x % 32)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def compute_unsigned_integer_bounds(num_bits: int) -> Tuple[int, int]:
|
|
20
|
+
return (
|
|
21
|
+
0,
|
|
22
|
+
2**num_bits - 1,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def compute_signed_integer_bounds(num_bits: int) -> Tuple[int, int]:
|
|
27
|
+
return (
|
|
28
|
+
-1 * 2 ** (num_bits - 1),
|
|
29
|
+
2 ** (num_bits - 1) - 1,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def compute_unsigned_fixed_bounds(
|
|
34
|
+
num_bits: int,
|
|
35
|
+
frac_places: int,
|
|
36
|
+
) -> Tuple[decimal.Decimal, decimal.Decimal]:
|
|
37
|
+
int_upper = compute_unsigned_integer_bounds(num_bits)[1]
|
|
38
|
+
|
|
39
|
+
with decimal.localcontext(abi_decimal_context):
|
|
40
|
+
upper = decimal.Decimal(int_upper) * TEN**-frac_places
|
|
41
|
+
|
|
42
|
+
return ZERO, upper
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def compute_signed_fixed_bounds(
|
|
46
|
+
num_bits: int,
|
|
47
|
+
frac_places: int,
|
|
48
|
+
) -> Tuple[decimal.Decimal, decimal.Decimal]:
|
|
49
|
+
int_lower, int_upper = compute_signed_integer_bounds(num_bits)
|
|
50
|
+
|
|
51
|
+
with decimal.localcontext(abi_decimal_context):
|
|
52
|
+
exp = TEN**-frac_places
|
|
53
|
+
lower = decimal.Decimal(int_lower) * exp
|
|
54
|
+
upper = decimal.Decimal(int_upper) * exp
|
|
55
|
+
|
|
56
|
+
return lower, upper
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def scale_places(places: int) -> Callable[[decimal.Decimal], decimal.Decimal]:
|
|
60
|
+
"""
|
|
61
|
+
Returns a function that shifts the decimal point of decimal values to the
|
|
62
|
+
right by ``places`` places.
|
|
63
|
+
"""
|
|
64
|
+
if not isinstance(places, int):
|
|
65
|
+
raise ValueError(
|
|
66
|
+
f"Argument `places` must be int. Got value {places} "
|
|
67
|
+
f"of type {type(places)}.",
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
with decimal.localcontext(abi_decimal_context):
|
|
71
|
+
scaling_factor = TEN**-places
|
|
72
|
+
|
|
73
|
+
def f(x: decimal.Decimal) -> decimal.Decimal:
|
|
74
|
+
with decimal.localcontext(abi_decimal_context):
|
|
75
|
+
return x * scaling_factor
|
|
76
|
+
|
|
77
|
+
places_repr = f"Eneg{places}" if places > 0 else f"Epos{-places}"
|
|
78
|
+
func_name = f"scale_by_{places_repr}"
|
|
79
|
+
|
|
80
|
+
f.__name__ = func_name
|
|
81
|
+
f.__qualname__ = func_name
|
|
82
|
+
|
|
83
|
+
return f
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from ...utils.toolz import (
|
|
2
|
+
curry,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@curry
|
|
7
|
+
def zpad(value: bytes, length: int) -> bytes:
|
|
8
|
+
return value.rjust(length, b"\x00")
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
zpad32 = zpad(length=32)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@curry
|
|
15
|
+
def zpad_right(value: bytes, length: int) -> bytes:
|
|
16
|
+
return value.ljust(length, b"\x00")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
zpad32_right = zpad_right(length=32)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@curry
|
|
23
|
+
def fpad(value: bytes, length: int) -> bytes:
|
|
24
|
+
return value.rjust(length, b"\xff")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
fpad32 = fpad(length=32)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def abbr(value: Any, limit: int = 79) -> str:
|
|
7
|
+
"""
|
|
8
|
+
Converts a value into its string representation and abbreviates that
|
|
9
|
+
representation based on the given length `limit` if necessary.
|
|
10
|
+
"""
|
|
11
|
+
rep = repr(value)
|
|
12
|
+
|
|
13
|
+
if len(rep) > limit:
|
|
14
|
+
if limit < 3:
|
|
15
|
+
raise ValueError("Abbreviation limit may not be less than 3")
|
|
16
|
+
|
|
17
|
+
rep = rep[: limit - 3] + "..."
|
|
18
|
+
|
|
19
|
+
return rep
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
Dict,
|
|
4
|
+
List,
|
|
5
|
+
Tuple,
|
|
6
|
+
Union,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
from ...abi import (
|
|
10
|
+
encode,
|
|
11
|
+
)
|
|
12
|
+
from ....keccak import (
|
|
13
|
+
SHA3 as keccak
|
|
14
|
+
)
|
|
15
|
+
from ...utils import (
|
|
16
|
+
to_bytes,
|
|
17
|
+
to_int,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
from .helpers import (
|
|
21
|
+
EIP712_SOLIDITY_TYPES,
|
|
22
|
+
is_0x_prefixed_hexstr,
|
|
23
|
+
is_array_type,
|
|
24
|
+
parse_core_array_type,
|
|
25
|
+
parse_parent_array_type,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def get_primary_type(types: Dict[str, List[Dict[str, str]]]) -> str:
|
|
30
|
+
custom_types = set(types.keys())
|
|
31
|
+
custom_types_that_are_deps = set()
|
|
32
|
+
|
|
33
|
+
for type_ in custom_types:
|
|
34
|
+
type_fields = types[type_]
|
|
35
|
+
for field in type_fields:
|
|
36
|
+
parsed_type = parse_core_array_type(field["type"])
|
|
37
|
+
if parsed_type in custom_types and parsed_type != type_:
|
|
38
|
+
custom_types_that_are_deps.add(parsed_type)
|
|
39
|
+
|
|
40
|
+
primary_type = list(custom_types.difference(custom_types_that_are_deps))
|
|
41
|
+
if len(primary_type) == 1:
|
|
42
|
+
return primary_type[0]
|
|
43
|
+
else:
|
|
44
|
+
raise ValueError("Unable to determine primary type")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def encode_field(
|
|
48
|
+
types: Dict[str, List[Dict[str, str]]],
|
|
49
|
+
name: str,
|
|
50
|
+
type_: str,
|
|
51
|
+
value: Any,
|
|
52
|
+
) -> Tuple[str, Union[int, bytes]]:
|
|
53
|
+
if type_ in types.keys():
|
|
54
|
+
# type is a custom type
|
|
55
|
+
if value is None:
|
|
56
|
+
return ("bytes32", b"\x00" * 32)
|
|
57
|
+
else:
|
|
58
|
+
return ("bytes32", keccak(encode_data(type_, types, value)))
|
|
59
|
+
|
|
60
|
+
elif type_ in ["string", "bytes"] and value is None:
|
|
61
|
+
return ("bytes32", b"")
|
|
62
|
+
|
|
63
|
+
# None is allowed only for custom and dynamic types
|
|
64
|
+
elif value is None:
|
|
65
|
+
raise ValueError(f"Missing value for field `{name}` of type `{type_}`")
|
|
66
|
+
|
|
67
|
+
elif is_array_type(type_):
|
|
68
|
+
# handle array type with non-array value
|
|
69
|
+
if not isinstance(value, list):
|
|
70
|
+
raise ValueError(
|
|
71
|
+
f"Invalid value for field `{name}` of type `{type_}`: "
|
|
72
|
+
f"expected array, got `{value}` of type `{type(value)}`"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
parsed_type = parse_parent_array_type(type_)
|
|
76
|
+
type_value_pairs = [
|
|
77
|
+
encode_field(types, name, parsed_type, item) for item in value
|
|
78
|
+
]
|
|
79
|
+
if not type_value_pairs:
|
|
80
|
+
# the keccak hash of `encode((), ())`
|
|
81
|
+
return (
|
|
82
|
+
"bytes32",
|
|
83
|
+
b"\xc5\xd2F\x01\x86\xf7#<\x92~}\xb2\xdc\xc7\x03\xc0\xe5\x00\xb6S\xca\x82';{\xfa\xd8\x04]\x85\xa4p", # noqa: E501
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
data_types, data_hashes = zip(*type_value_pairs)
|
|
87
|
+
return ("bytes32", keccak(encode(data_types, data_hashes)))
|
|
88
|
+
|
|
89
|
+
elif type_ == "bool":
|
|
90
|
+
return (type_, bool(value))
|
|
91
|
+
|
|
92
|
+
# all bytes types allow hexstr and str values
|
|
93
|
+
elif type_.startswith("bytes"):
|
|
94
|
+
if not isinstance(value, bytes):
|
|
95
|
+
if is_0x_prefixed_hexstr(value):
|
|
96
|
+
value = to_bytes(hexstr=value)
|
|
97
|
+
elif isinstance(value, str):
|
|
98
|
+
value = to_bytes(text=value)
|
|
99
|
+
else:
|
|
100
|
+
if isinstance(value, int) and value < 0:
|
|
101
|
+
value = 0
|
|
102
|
+
|
|
103
|
+
value = to_bytes(value)
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
# keccak hash if dynamic `bytes` type
|
|
107
|
+
("bytes32", keccak(value))
|
|
108
|
+
if type_ == "bytes"
|
|
109
|
+
# if fixed bytesXX type, do not hash
|
|
110
|
+
else (type_, value)
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
elif type_ == "string":
|
|
114
|
+
if isinstance(value, int):
|
|
115
|
+
value = to_bytes(value)
|
|
116
|
+
else:
|
|
117
|
+
value = to_bytes(text=value)
|
|
118
|
+
return ("bytes32", keccak(value))
|
|
119
|
+
|
|
120
|
+
# allow string values for int and uint types
|
|
121
|
+
elif type(value) == str and type_.startswith(("int", "uint")):
|
|
122
|
+
if is_0x_prefixed_hexstr(value):
|
|
123
|
+
return (type_, to_int(hexstr=value))
|
|
124
|
+
else:
|
|
125
|
+
return (type_, to_int(text=value))
|
|
126
|
+
|
|
127
|
+
return (type_, value)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def find_type_dependencies(type_, types, results=None):
|
|
131
|
+
if results is None:
|
|
132
|
+
results = set()
|
|
133
|
+
|
|
134
|
+
# a type must be a string
|
|
135
|
+
if not isinstance(type_, str):
|
|
136
|
+
raise ValueError(
|
|
137
|
+
"Invalid find_type_dependencies input: expected string, got "
|
|
138
|
+
f"`{type_}` of type `{type(type_)}`"
|
|
139
|
+
)
|
|
140
|
+
# get core type if it's an array type
|
|
141
|
+
type_ = parse_core_array_type(type_)
|
|
142
|
+
|
|
143
|
+
if (
|
|
144
|
+
# don't look for dependencies of solidity types
|
|
145
|
+
type_ in EIP712_SOLIDITY_TYPES
|
|
146
|
+
# found a type that's already been added
|
|
147
|
+
or type_ in results
|
|
148
|
+
):
|
|
149
|
+
return results
|
|
150
|
+
|
|
151
|
+
# found a type that isn't defined
|
|
152
|
+
elif type_ not in types:
|
|
153
|
+
raise ValueError(f"No definition of type `{type_}`")
|
|
154
|
+
|
|
155
|
+
results.add(type_)
|
|
156
|
+
|
|
157
|
+
for field in types[type_]:
|
|
158
|
+
find_type_dependencies(field["type"], types, results)
|
|
159
|
+
return results
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def encode_type(type_: str, types: Dict[str, List[Dict[str, str]]]) -> str:
|
|
163
|
+
result = ""
|
|
164
|
+
unsorted_deps = find_type_dependencies(type_, types)
|
|
165
|
+
if type_ in unsorted_deps:
|
|
166
|
+
unsorted_deps.remove(type_)
|
|
167
|
+
|
|
168
|
+
deps = [type_] + sorted(list(unsorted_deps))
|
|
169
|
+
for type_ in deps:
|
|
170
|
+
children_list = []
|
|
171
|
+
for child in types[type_]:
|
|
172
|
+
child_type = child["type"]
|
|
173
|
+
child_name = child["name"]
|
|
174
|
+
children_list.append(f"{child_type} {child_name}")
|
|
175
|
+
|
|
176
|
+
result += f"{type_}({','.join(children_list)})"
|
|
177
|
+
return result
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def hash_type(type_: str, types: Dict[str, List[Dict[str, str]]]) -> bytes:
|
|
181
|
+
return keccak(to_bytes(text=encode_type(type_, types)))
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def encode_data(
|
|
185
|
+
type_: str,
|
|
186
|
+
types: Dict[str, List[Dict[str, str]]],
|
|
187
|
+
data: Dict[str, Any],
|
|
188
|
+
) -> bytes:
|
|
189
|
+
encoded_types: List[str] = ["bytes32"]
|
|
190
|
+
encoded_values: List[Union[bytes, int]] = [hash_type(type_, types)]
|
|
191
|
+
|
|
192
|
+
for field in types[type_]:
|
|
193
|
+
type, value = encode_field(
|
|
194
|
+
types, field["name"], field["type"], data.get(field["name"])
|
|
195
|
+
)
|
|
196
|
+
encoded_types.append(type)
|
|
197
|
+
encoded_values.append(value)
|
|
198
|
+
|
|
199
|
+
return encode(encoded_types, encoded_values)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def hash_struct(
|
|
203
|
+
type_: str,
|
|
204
|
+
types: Dict[str, List[Dict[str, str]]],
|
|
205
|
+
data: Dict[str, Any],
|
|
206
|
+
) -> bytes:
|
|
207
|
+
encoded = encode_data(type_, types, data)
|
|
208
|
+
return keccak(encoded)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def hash_eip712_message(
|
|
212
|
+
# returns the same hash as `hash_struct`, but automatically determines primary type
|
|
213
|
+
message_types: Dict[str, List[Dict[str, str]]],
|
|
214
|
+
message_data: Dict[str, Any],
|
|
215
|
+
) -> bytes:
|
|
216
|
+
primary_type = get_primary_type(message_types)
|
|
217
|
+
return keccak(encode_data(primary_type, message_types, message_data))
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def hash_domain(domain_data: Dict[str, Any]) -> bytes:
|
|
221
|
+
eip712_domain_map = {
|
|
222
|
+
"name": {"name": "name", "type": "string"},
|
|
223
|
+
"version": {"name": "version", "type": "string"},
|
|
224
|
+
"chainId": {"name": "chainId", "type": "uint256"},
|
|
225
|
+
"verifyingContract": {"name": "verifyingContract", "type": "address"},
|
|
226
|
+
"salt": {"name": "salt", "type": "bytes32"},
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
for k in domain_data.keys():
|
|
230
|
+
if k not in eip712_domain_map.keys():
|
|
231
|
+
raise ValueError(f"Invalid domain key: `{k}`")
|
|
232
|
+
|
|
233
|
+
domain_types = {
|
|
234
|
+
"EIP712Domain": [
|
|
235
|
+
eip712_domain_map[k] for k in eip712_domain_map.keys() if k in domain_data
|
|
236
|
+
]
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return hash_struct("EIP712Domain", domain_types, domain_data)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
from ...utils import (
|
|
6
|
+
is_hexstr,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _get_eip712_solidity_types():
|
|
11
|
+
types = ["bool", "address", "string", "bytes", "uint", "int"]
|
|
12
|
+
ints = [f"int{(x + 1) * 8}" for x in range(32)]
|
|
13
|
+
uints = [f"uint{(x + 1) * 8}" for x in range(32)]
|
|
14
|
+
bytes_ = [f"bytes{x + 1}" for x in range(32)]
|
|
15
|
+
return types + ints + uints + bytes_
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
EIP712_SOLIDITY_TYPES = _get_eip712_solidity_types()
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def is_array_type(type_: str) -> bool:
|
|
22
|
+
return type_.endswith("]")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def is_0x_prefixed_hexstr(value: Any) -> bool:
|
|
26
|
+
return is_hexstr(value) and value.startswith("0x")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# strip all brackets: Person[][] -> Person
|
|
30
|
+
def parse_core_array_type(type_: str) -> str:
|
|
31
|
+
if is_array_type(type_):
|
|
32
|
+
type_ = type_[: type_.index("[")]
|
|
33
|
+
return type_
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# strip only last set of brackets: Person[3][1] -> Person[3]
|
|
37
|
+
def parse_parent_array_type(type_: str) -> str:
|
|
38
|
+
if is_array_type(type_):
|
|
39
|
+
type_ = type_[: type_.rindex("[")]
|
|
40
|
+
return type_
|