diff --git a/Makefile b/Makefile index 35a7ac6f..2fdecd66 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ SHELL := /bin/bash -.PHONY: test test37 test38 test39 mypy coverage +.PHONY: test test38 test39 mypy coverage TOX := docker-compose run --rm app tox @@ -8,9 +8,6 @@ test: $(TOX) -test37: - $(TOX) -e py37 - test38: $(TOX) -e py38 @@ -27,4 +24,4 @@ coverage: .coverage docker-compose run --rm app coverage report coverage.xml: .coverage - docker-compose run --rm app coverage xml \ No newline at end of file + docker-compose run --rm app coverage xml diff --git a/setup.cfg b/setup.cfg index afabb01c..4a4837fb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -13,7 +13,7 @@ install_requires = web3 >= 5.16 httpx >= 0.16 pydantic >= 1.7 - +python_requires = >=3.8 setup_requires = setuptools_scm>=3.5.0 @@ -36,8 +36,21 @@ zksync_sdk.contract_abi = [tox:tox] envlist = py{38,39},mypy -[testenv] +[testenv:py{38,39}] deps = coverage -extras = test setenv = ZK_SYNC_LIBRARY_PATH=/lib/zks-crypto-linux-x64.so commands = coverage run -m unittest + +[testenv:mypy] +extras = test +commands = mypy . + +[mypy] +show_error_codes = True +no_implicit_optional = True + +[mypy-setuptools.*] +ignore_missing_imports = True + +[mypy-eth_account.*] +ignore_missing_imports = True diff --git a/tests/test_wallet.py b/tests/test_wallet.py index 0620a4bd..513c36f2 100644 --- a/tests/test_wallet.py +++ b/tests/test_wallet.py @@ -62,7 +62,7 @@ async def test_deposit(self): async def test_change_pubkey(self): trans = await self.wallet.set_signing_key("ETH", eth_auth_data=ChangePubKeyEcdsa()) try: - status = await trans.await_committed() + status = await trans.await_committed(attempts=1000, attempts_timeout=1000) self.assertEqual(status, TransactionStatus.COMMITTED) except Exception as ex: assert False, str(ex) diff --git a/zksync_sdk/contract_utils.py b/zksync_sdk/contract_utils.py index 2c801162..eb339e29 100644 --- a/zksync_sdk/contract_utils.py +++ b/zksync_sdk/contract_utils.py @@ -1,10 +1,6 @@ +import importlib.resources as pkg_resources import json -try: - import importlib.resources as pkg_resources -except ImportError: - # Try backported to PY<37 `importlib_resources`. - import importlib_resources as pkg_resources from . import contract_abi zksync_abi_cache = None diff --git a/zksync_sdk/ethereum_provider.py b/zksync_sdk/ethereum_provider.py index 64b2b56f..1db57010 100644 --- a/zksync_sdk/ethereum_provider.py +++ b/zksync_sdk/ethereum_provider.py @@ -1,4 +1,5 @@ from decimal import Decimal +from typing import Optional from web3 import Web3 @@ -13,7 +14,7 @@ def __init__(self, web3: Web3, zksync: ZkSync): self.web3 = web3 self.zksync = zksync - async def approve_deposit(self, token: Token, limit: Decimal = None): + async def approve_deposit(self, token: Token, limit: Decimal): contract = ERC20Contract(self.web3, self.zksync.contract_address, token.address, self.zksync.account) return contract.approve_deposit(token.from_decimal(limit)) @@ -30,7 +31,7 @@ async def full_exit(self, token: Token, account_id: int): async def set_auth_pubkey_hash(self, pubkey_hash: bytes, nonce: int): return self.zksync.set_auth_pub_key_hash(pubkey_hash, nonce) - async def is_deposit_approved(self, token: Token, threshold: int = None) -> bool: + async def is_deposit_approved(self, token: Token, threshold: int) -> bool: contract = ERC20Contract(self.web3, self.zksync.contract_address, token.address, self.zksync.account) return contract.is_deposit_approved(threshold) diff --git a/zksync_sdk/lib.py b/zksync_sdk/lib.py index 960a4f63..892df15a 100644 --- a/zksync_sdk/lib.py +++ b/zksync_sdk/lib.py @@ -1,6 +1,7 @@ import ctypes from ctypes import (Structure, c_ubyte, cdll) import os +from typing import Optional PRIVATE_KEY_LEN = 32 PUBLIC_KEY_LEN = 32 @@ -48,9 +49,9 @@ class ZksOrders(Structure): class ZkSyncLibrary: - def __init__(self, library_path: str = None): + def __init__(self, library_path: Optional[str] = None): if library_path is None: - library_path = os.getenv("ZK_SYNC_LIBRARY_PATH") + library_path = os.environ["ZK_SYNC_LIBRARY_PATH"] self.lib = cdll.LoadLibrary(library_path) def private_key_from_seed(self, seed: bytes): @@ -68,17 +69,17 @@ def get_public_key(self, private_key: bytes): def get_pubkey_hash(self, public_key: bytes): assert len(public_key) == PUBLIC_KEY_LEN public_key_hash = ctypes.pointer(ZksPubkeyHash()) - public_key = ctypes.pointer( + public_key_ptr = ctypes.pointer( ZksPackedPublicKey(data=(c_ubyte * PUBLIC_KEY_LEN)(*public_key))) - self.lib.zks_crypto_public_key_to_pubkey_hash(public_key, public_key_hash) + self.lib.zks_crypto_public_key_to_pubkey_hash(public_key_ptr, public_key_hash) return bytes(public_key_hash.contents.data) def sign(self, private_key: bytes, message: bytes): assert len(private_key) == PRIVATE_KEY_LEN signature = ctypes.pointer(ZksSignature()) - private_key = ctypes.pointer( + private_key_ptr = ctypes.pointer( ZksPrivateKey(data=(c_ubyte * PRIVATE_KEY_LEN)(*private_key))) - self.lib.zks_crypto_sign_musig(private_key, message, len(message), signature) + self.lib.zks_crypto_sign_musig(private_key_ptr, message, len(message), signature) return bytes(signature.contents.data) def hash_orders(self, orders: bytes): diff --git a/zksync_sdk/serializers.py b/zksync_sdk/serializers.py index dd73deb4..ffa0f46f 100644 --- a/zksync_sdk/serializers.py +++ b/zksync_sdk/serializers.py @@ -203,6 +203,8 @@ def remove_address_prefix(address: str) -> str: if address.startswith('sync:'): return address[5:] + return address + def serialize_address(address: str) -> bytes: address = remove_address_prefix(address) diff --git a/zksync_sdk/transport/http.py b/zksync_sdk/transport/http.py index bc55090c..fe24dbf5 100644 --- a/zksync_sdk/transport/http.py +++ b/zksync_sdk/transport/http.py @@ -1,5 +1,5 @@ from http.client import OK -from typing import List +from typing import List, Optional import httpx @@ -11,7 +11,7 @@ class HttpJsonRPCTransport(JsonRPCTransport): def __init__(self, network: Network): self.network = network - async def request(self, method: str, params: List): + async def request(self, method: str, params: Optional[List]): async with httpx.AsyncClient() as client: response = await client.post(self.network.zksync_url, json=self.create_request(method, params)) diff --git a/zksync_sdk/types/responses.py b/zksync_sdk/types/responses.py index af02ab38..31c61bf0 100644 --- a/zksync_sdk/types/responses.py +++ b/zksync_sdk/types/responses.py @@ -58,6 +58,7 @@ class Config: alias_generator = to_camel def get_nonce(self) -> int: + assert self.committed is not None, "`get_nonce` needs `committed` to be set" return self.committed.nonce diff --git a/zksync_sdk/types/transactions.py b/zksync_sdk/types/transactions.py index 089032ec..40e1a42b 100644 --- a/zksync_sdk/types/transactions.py +++ b/zksync_sdk/types/transactions.py @@ -127,7 +127,7 @@ def find_by_symbol(self, symbol: str) -> Optional[Token]: else: return None - def find(self, token: TokenLike) -> Token: + def find(self, token: TokenLike) -> Optional[Token]: result = None if isinstance(token, int): result = self.find_by_id(token) @@ -167,9 +167,9 @@ class ChangePubKey(EncodedTx): nonce: int valid_from: int valid_until: int - eth_auth_data: Union[ChangePubKeyCREATE2, ChangePubKeyEcdsa] = None - eth_signature: TxEthSignature = None - signature: TxSignature = None + eth_auth_data: Union[ChangePubKeyCREATE2, ChangePubKeyEcdsa, None] = None + eth_signature: Optional[TxEthSignature] = None + signature: Optional[TxSignature] = None def human_readable_message(self) -> str: message = f"Set signing key: {self.new_pk_hash.replace('sync:', '').lower()}" @@ -240,7 +240,7 @@ class Transfer(EncodedTx): nonce: int valid_from: int valid_until: int - signature: TxSignature = None + signature: Optional[TxSignature] = None def tx_type(self) -> int: return 5 @@ -297,7 +297,7 @@ class Withdraw(EncodedTx): valid_from: int valid_until: int token: Token - signature: TxSignature = None + signature: Optional[TxSignature] = None def tx_type(self) -> int: return 3 @@ -351,7 +351,7 @@ class ForcedExit(EncodedTx): nonce: int valid_from: int valid_until: int - signature: TxSignature = None + signature: Optional[TxSignature] = None def tx_type(self) -> int: return 8 @@ -387,7 +387,7 @@ def dict(self): } @dataclass -class Order: +class Order(EncodedTx): account_id: int recipient: str nonce: int @@ -397,8 +397,11 @@ class Order: ratio: Fraction valid_from: int valid_until: int - signature: TxSignature = None - ethSignature: TxEthSignature = None + signature: Optional[TxSignature] = None + eth_signature: Optional[TxEthSignature] = None + + def tx_type(self) -> int: + raise NotImplementedError def msg_type(self) -> int: return b'o'[0] @@ -446,7 +449,7 @@ def dict(self): "validFrom": self.valid_from, "validUntil": self.valid_until, "signature": self.signature.dict() if self.signature else None, - "ethSignature": self.ethSignature.dict() if self.ethSignature else None, + "ethSignature": self.eth_signature.dict() if self.eth_signature else None, } @dataclass @@ -458,7 +461,7 @@ class Swap(EncodedTx): fee_token: Token fee: int nonce: int - signature: TxSignature = None + signature: Optional[TxSignature] = None def tx_type(self) -> int: return 11 @@ -511,7 +514,7 @@ class MintNFT(EncodedTx): fee: int fee_token: Token nonce: int - signature: TxSignature = None + signature: Optional[TxSignature] = None def tx_type(self) -> int: return 9 @@ -557,7 +560,7 @@ class WithdrawNFT(EncodedTx): valid_from: int valid_until: int token_id: int - signature: TxSignature = None + signature: Optional[TxSignature] = None def tx_type(self) -> int: return 10 diff --git a/zksync_sdk/wallet.py b/zksync_sdk/wallet.py index 22953541..04c5a72e 100644 --- a/zksync_sdk/wallet.py +++ b/zksync_sdk/wallet.py @@ -57,12 +57,12 @@ async def send_txs_batch(self, transactions: List[TransactionWithSignature], return await self.zk_provider.submit_txs_batch(transactions, signatures) async def set_signing_key(self, fee_token: TokenLike, *, - eth_auth_data: Union[ChangePubKeyCREATE2, ChangePubKeyEcdsa] = None, - fee: Decimal = None, nonce: int = None, + eth_auth_data: Union[ChangePubKeyCREATE2, ChangePubKeyEcdsa, None] = None, + fee: Optional[Decimal] = None, nonce: Optional[int] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL): if nonce is None: nonce = await self.zk_provider.get_account_nonce(self.address()) - fee_token = await self.resolve_token(fee_token) + fee_token_obj = await self.resolve_token(fee_token) if isinstance(eth_auth_data, ChangePubKeyEcdsa): eth_auth_type = ChangePubKeyTypes.ecdsa elif isinstance(eth_auth_data, ChangePubKeyCREATE2): @@ -72,23 +72,24 @@ async def set_signing_key(self, fee_token: TokenLike, *, if fee is None: if eth_auth_type == ChangePubKeyTypes.ecdsa: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.change_pub_key_ecdsa, + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.change_pub_key_ecdsa, self.address(), - fee_token.id) + fee_token_obj.id) elif eth_auth_type == ChangePubKeyTypes.onchain: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.change_pub_key_onchain, + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.change_pub_key_onchain, self.address(), - fee_token.id) - elif eth_auth_type == ChangePubKeyTypes.create2: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.change_pub_key_create2, + fee_token_obj.id) + else: + assert eth_auth_type == ChangePubKeyTypes.create2, "invalid eth_auth_type" + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.change_pub_key_create2, self.address(), - fee_token.id) - fee = fee.total_fee + fee_token_obj.id) + fee_int = fee_obj.total_fee else: - fee = fee_token.from_decimal(fee) + fee_int = fee_token_obj.from_decimal(fee) - change_pub_key, eth_signature = await self.build_change_pub_key(fee_token, - eth_auth_data, fee, + change_pub_key, eth_signature = await self.build_change_pub_key(fee_token_obj, + eth_auth_data, fee_int, nonce, valid_from, valid_until) @@ -102,10 +103,9 @@ async def build_change_pub_key( fee_token: Token, eth_auth_data: Union[ChangePubKeyCREATE2, ChangePubKeyEcdsa, None], fee: int, - nonce: int = None, + nonce: Optional[int] = None, valid_from=DEFAULT_VALID_FROM, - valid_until=DEFAULT_VALID_UNTIL - ): + valid_until=DEFAULT_VALID_UNTIL): if nonce is None: nonce = await self.zk_provider.get_account_nonce(self.address()) account_id = await self.get_account_id() @@ -132,17 +132,17 @@ async def build_change_pub_key( return change_pub_key, eth_signature - async def forced_exit(self, target: str, token: TokenLike, fee: Decimal = None, + async def forced_exit(self, target: str, token: TokenLike, fee: Optional[Decimal] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL) -> Transaction: nonce = await self.zk_provider.get_account_nonce(self.address()) - token = await self.resolve_token(token) + token_obj = await self.resolve_token(token) if fee is None: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.withdraw, target, token.id) - fee = fee.total_fee + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.withdraw, target, token_obj.id) + fee_int = fee_obj.total_fee else: - fee = token.from_decimal(fee) + fee_int = token_obj.from_decimal(fee) - transfer, eth_signature = await self.build_forced_exit(target, token, fee, nonce, + transfer, eth_signature = await self.build_forced_exit(target, token_obj, fee_int, nonce, valid_from, valid_until) return await self.send_signed_transaction(transfer, eth_signature) @@ -154,10 +154,9 @@ async def build_forced_exit( target: str, token: Token, fee: int, - nonce: int = None, + nonce: Optional[int] = None, valid_from=DEFAULT_VALID_FROM, - valid_until=DEFAULT_VALID_UNTIL - ) -> Tuple[ForcedExit, TxEthSignature]: + valid_until=DEFAULT_VALID_UNTIL) -> Tuple[ForcedExit, TxEthSignature]: if nonce is None: nonce = await self.zk_provider.get_account_nonce(self.address()) account_id = await self.get_account_id() @@ -175,17 +174,17 @@ async def build_forced_exit( return forced_exit, eth_signature - async def mint_nft(self, content_hash: str, recipient: str, - token: TokenLike, fee: Decimal = None) -> Transaction: - token = await self.resolve_token(token) + async def mint_nft(self, content_hash: str, recipient: str,token: TokenLike, fee: Optional[Decimal] = None) -> Transaction: + token_obj = await self.resolve_token(token) + nonce = await self.zk_provider.get_account_nonce(self.address()) if fee is None: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.mint_nft, recipient, token.id) - fee = fee.total_fee + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.mint_nft, recipient, token_obj.id) + fee_int = fee_obj.total_fee else: - fee = token.from_decimal(fee) + fee_int = token_obj.from_decimal(fee) - mint_nft, eth_signature = await self.build_mint_nft(content_hash, recipient, token, fee, nonce) + mint_nft, eth_signature = await self.build_mint_nft(content_hash, recipient, token_obj, fee_int, nonce) return await self.send_signed_transaction(mint_nft, eth_signature) # This function takes as a parameter the integer fee of @@ -196,7 +195,7 @@ async def build_mint_nft( recipient: str, token: Token, fee: int, - nonce: int = None, + nonce: Optional[int] = None ) -> Tuple[MintNFT, TxEthSignature]: if nonce is None: nonce = await self.zk_provider.get_account_nonce(self.address()) @@ -220,22 +219,20 @@ async def withdraw_nft( to_address: str, nft_token: NFT, fee_token: TokenLike, - fee: Decimal = None, + fee: Optional[Decimal] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL ) -> Transaction: nonce = await self.zk_provider.get_account_nonce(self.address()) - fee_token = await self.resolve_token(fee_token) + fee_token_obj = await self.resolve_token(fee_token) if fee is None: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.withdraw_nft, to_address, fee_token.id) - fee = fee.total_fee + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.withdraw_nft, to_address, fee_token_obj.id) + fee_int = fee_obj.total_fee else: - fee = fee_token.from_decimal(fee) - - withdraw_nft, eth_signature = await self.build_withdraw_nft(to_address, nft_token, fee_token, fee, + fee_int = fee_token_obj.from_decimal(fee) + withdraw_nft, eth_signature = await self.build_withdraw_nft(to_address, nft_token, fee_token_obj, fee_int, nonce, valid_from, valid_until) - return await self.send_signed_transaction(withdraw_nft, eth_signature) # This function takes as a parameter the integer fee of @@ -246,7 +243,7 @@ async def build_withdraw_nft( nft_token: NFT, fee_token: Token, fee: int, - nonce: int = None, + nonce: Optional[int] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL ) -> Tuple[WithdrawNFT, TxEthSignature]: @@ -279,7 +276,7 @@ async def build_transfer( amount: int, token: Token, fee: int, - nonce: int = None, + nonce: Optional[int] = None, valid_from: int = DEFAULT_VALID_FROM, valid_until: int = DEFAULT_VALID_UNTIL, ) -> Tuple[Transfer, TxEthSignature]: @@ -303,41 +300,41 @@ async def build_transfer( return transfer, eth_signature async def transfer(self, to: str, amount: Decimal, token: TokenLike, - fee: Decimal = None, + fee: Optional[Decimal] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL) -> Transaction: nonce = await self.zk_provider.get_account_nonce(self.address()) - token = await self.resolve_token(token) + token_obj = await self.resolve_token(token) if fee is None: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.transfer, to, token.id) - fee = fee.total_fee + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.transfer, to, token_obj.id) + fee_int = fee_obj.total_fee else: - fee = token.from_decimal(fee) + fee_int = token_obj.from_decimal(fee) - amount = token.from_decimal(amount) + amount_int = token_obj.from_decimal(amount) - transfer, eth_signature = await self.build_transfer(to, amount, token, fee, nonce, valid_from, valid_until) + transfer, eth_signature = await self.build_transfer(to, amount_int, token_obj, fee_int, nonce, valid_from, valid_until) return await self.send_signed_transaction(transfer, eth_signature) async def transfer_nft(self, to: str, nft: NFT, fee_token: TokenLike, - fee: Decimal = None, + fee: Optional[Decimal] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL ) -> List[Transaction]: nonce = await self.zk_provider.get_account_nonce(self.address()) - fee_token = await self.resolve_token(fee_token) + fee_token_obj = await self.resolve_token(fee_token) if fee is None: - fee = await self.zk_provider.get_transactions_batch_fee( + fee_int = await self.zk_provider.get_transactions_batch_fee( [FeeTxType.transfer, FeeTxType.transfer], [to, self.address()], - fee_token.symbol + fee_token_obj.symbol ) else: - fee = fee_token.from_decimal(fee) + fee_int = fee_token_obj.from_decimal(fee) nft_tx = await self.build_transfer(to, 1, nft, 0, nonce, valid_from, valid_until) - fee_tx = await self.build_transfer(self.address(), 0, fee_token, fee, nonce + 1, valid_from, valid_until) + fee_tx = await self.build_transfer(self.address(), 0, fee_token_obj, fee_int, nonce + 1, valid_from, valid_until) batch = [ TransactionWithSignature(nft_tx[0], nft_tx[1]), TransactionWithSignature(fee_tx[0], fee_tx[1]) @@ -346,28 +343,28 @@ async def transfer_nft(self, to: str, nft: NFT, fee_token: TokenLike, async def get_order(self, token_sell: TokenLike, token_buy: TokenLike, ratio: Fraction, ratio_type: RatioType, amount: Decimal, - recipient: str = None, - nonce: int = None, + recipient: Optional[str] = None, + nonce: Optional[int] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL) -> Order: if nonce is None: nonce = await self.zk_provider.get_account_nonce(self.address()) - token_sell = await self.resolve_token(token_sell) - token_buy = await self.resolve_token(token_buy) + token_sell_obj = await self.resolve_token(token_sell) + token_buy_obj = await self.resolve_token(token_buy) recipient = recipient or self.address() if ratio_type == RatioType.token: - num = token_sell.from_decimal(Decimal(ratio.numerator)) - den = token_buy.from_decimal(Decimal(ratio.denominator)) + num = token_sell_obj.from_decimal(Decimal(ratio.numerator)) + den = token_buy_obj.from_decimal(Decimal(ratio.denominator)) ratio = Fraction(num, den) account_id = await self.get_account_id() order = Order(account_id=account_id, recipient=recipient, - token_sell=token_sell, - token_buy=token_buy, + token_sell=token_sell_obj, + token_buy=token_buy_obj, ratio=ratio, - amount=token_sell.from_decimal(amount), + amount=token_sell_obj.from_decimal(amount), nonce=nonce, valid_from=valid_from, valid_until=valid_until) @@ -379,7 +376,7 @@ async def get_order(self, token_sell: TokenLike, token_buy: TokenLike, async def get_limit_order(self, token_sell: TokenLike, token_buy: TokenLike, ratio: Fraction, ratio_type: RatioType, - recipient: str = None, + recipient: Optional[str] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL): return await self.get_order(token_sell, token_buy, ratio, ratio_type, Decimal(0), recipient, valid_from, @@ -388,7 +385,7 @@ async def get_limit_order(self, token_sell: TokenLike, token_buy: TokenLike, # This function takes as a parameter the integer amounts/fee of # lowest token denominations (wei, satoshi, etc.) async def build_swap(self, orders: Tuple[Order, Order], fee_token: Token, - amounts: Tuple[int, int], fee: int, nonce: int = None): + amounts: Tuple[int, int], fee: int, nonce: Optional[int] = None): if nonce is None: nonce = await self.zk_provider.get_account_nonce(self.address()) account_id = await self.get_account_id() @@ -402,27 +399,27 @@ async def build_swap(self, orders: Tuple[Order, Order], fee_token: Token, return swap, eth_signature async def swap(self, orders: Tuple[Order, Order], fee_token: TokenLike, - amounts: Tuple[Decimal, Decimal] = None, fee: Decimal = None): + amounts: Optional[Tuple[Decimal, Decimal]] = None, fee: Optional[Decimal] = None): nonce = await self.zk_provider.get_account_nonce(self.address()) - fee_token = await self.resolve_token(fee_token) + fee_token_obj = await self.resolve_token(fee_token) if fee is None: - fee = await self.zk_provider.get_transaction_fee(FeeTxType.swap, self.address(), fee_token.id) - fee = fee.total_fee + fee_obj = await self.zk_provider.get_transaction_fee(FeeTxType.swap, self.address(), fee_token_obj.id) + fee_int = fee_obj.total_fee else: - fee = fee_token.from_decimal(fee) + fee_int = fee_token_obj.from_decimal(fee) if amounts is None: - amounts = (orders[0].amount, orders[1].amount) - if amounts[0] == 0 or amounts[1] == 0: + amounts_int = (orders[0].amount, orders[1].amount) + if amounts_int[0] == 0 or amounts_int[1] == 0: raise AmountsMissing("in this case you must specify amounts explicitly") else: - amounts = ( + amounts_int = ( orders[0].token_sell.from_decimal(amounts[0]), orders[1].token_sell.from_decimal(amounts[1]) ) - swap, eth_signature = await self.build_swap(orders, fee_token, amounts, fee, nonce) + swap, eth_signature = await self.build_swap(orders, fee_token_obj, amounts_int, fee_int, nonce) eth_signatures = [eth_signature, swap.orders[0].eth_signature, swap.orders[1].eth_signature] return await self.send_signed_transaction(swap, eth_signatures) @@ -430,7 +427,7 @@ async def swap(self, orders: Tuple[Order, Order], fee_token: TokenLike, # lowest token denominations (wei, satoshi, etc.) async def build_withdraw(self, eth_address: str, amount: int, token: Token, fee: int, - nonce: int = None, + nonce: Optional[int] = None, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL): if nonce is None: @@ -450,30 +447,30 @@ async def build_withdraw(self, eth_address: str, amount: int, token: Token, return withdraw, eth_signature async def withdraw(self, eth_address: str, amount: Decimal, token: TokenLike, - fee: Decimal = None, fast: bool = False, + fee: Optional[Decimal] = None, fast: bool = False, valid_from=DEFAULT_VALID_FROM, valid_until=DEFAULT_VALID_UNTIL) -> Transaction: nonce = await self.zk_provider.get_account_nonce(self.address()) - token = await self.resolve_token(token) + token_obj = await self.resolve_token(token) if fee is None: tx_type = FeeTxType.fast_withdraw if fast else FeeTxType.withdraw - fee = await self.zk_provider.get_transaction_fee(tx_type, eth_address, token.id) - fee = fee.total_fee + fee_obj = await self.zk_provider.get_transaction_fee(tx_type, eth_address, token_obj.id) + fee_int = fee_obj.total_fee else: - fee = token.from_decimal(fee) - amount = token.from_decimal(amount) + fee_int = token_obj.from_decimal(fee) + amount_int = token_obj.from_decimal(amount) - withdraw, eth_signature = await self.build_withdraw(eth_address, amount, token, fee, nonce, + withdraw, eth_signature = await self.build_withdraw(eth_address, amount_int, token_obj, fee_int, nonce, valid_from, valid_until) return await self.send_signed_transaction(withdraw, eth_signature, fast) async def get_balance(self, token: TokenLike, type: str): account_state = await self.get_account_state() - token = await self.resolve_token(token) + token_obj = await self.resolve_token(token) if type == "committed": - token_balance = account_state.committed.balances.get(token.symbol) + token_balance = account_state.committed.balances.get(token_obj.symbol) else: - token_balance = account_state.verified.balances.get(token.symbol) + token_balance = account_state.verified.balances.get(token_obj.symbol) if token_balance is None: token_balance = 0 return token_balance diff --git a/zksync_sdk/zksync.py b/zksync_sdk/zksync.py index 393c3114..d9964020 100644 --- a/zksync_sdk/zksync.py +++ b/zksync_sdk/zksync.py @@ -11,7 +11,7 @@ class Contract: def __init__(self, contract_address: str, web3: Web3, account: BaseAccount, abi): self.contract_address = contract_address self.web3 = web3 - self.contract = self.web3.eth.contract(self.contract_address, abi=abi) + self.contract = self.web3.eth.contract(self.contract_address, abi=abi) # type: ignore[call-overload] self.account = account def _call_method(self, method_name, *args, amount=None, **kwargs): diff --git a/zksync_sdk/zksync_provider/interface.py b/zksync_sdk/zksync_provider/interface.py index 3d6fb6ef..72c525af 100644 --- a/zksync_sdk/zksync_provider/interface.py +++ b/zksync_sdk/zksync_provider/interface.py @@ -63,7 +63,7 @@ async def get_priority_op_status(self, serial_id: int) -> EthOpInfo: raise NotImplementedError @abstractmethod - async def get_transactions_batch_fee(self, tx_types: List[FeeTxType], addresses: List[Address], + async def get_transactions_batch_fee(self, tx_types: List[FeeTxType], addresses: List[str], token_like) -> int: raise NotImplementedError diff --git a/zksync_sdk/zksync_provider/v01.py b/zksync_sdk/zksync_provider/v01.py index 29acf6a1..445bb839 100644 --- a/zksync_sdk/zksync_provider/v01.py +++ b/zksync_sdk/zksync_provider/v01.py @@ -77,7 +77,7 @@ async def get_priority_op_status(self, serial_id: int) -> EthOpInfo: # Please note that the batch fee returns the fee of the transaction in int and not in Fee # This is a server-side feature - async def get_transactions_batch_fee(self, tx_types: List[FeeTxType], addresses: List[Address], + async def get_transactions_batch_fee(self, tx_types: List[FeeTxType], addresses: List[str], token_like) -> int: data = await self.provider.request('get_txs_batch_fee_in_wei', diff --git a/zksync_sdk/zksync_signer.py b/zksync_sdk/zksync_signer.py index 4f6df2fb..17d761b0 100644 --- a/zksync_sdk/zksync_signer.py +++ b/zksync_sdk/zksync_signer.py @@ -9,8 +9,8 @@ def derive_private_key(library: ZkSyncLibrary, message: str, account: BaseAccoun chain_id: ChainId): if chain_id != ChainId.MAINNET: message = f"{message}\nChain ID: {chain_id}." - message = encode_defunct(message.encode()) - signature = account.sign_message(message) + signable_message = encode_defunct(message.encode()) + signature = account.sign_message(signable_message) private_key = library.private_key_from_seed(signature.signature) return private_key