From 1c00cffaa59750ef117ed08ce426e86616e351bc Mon Sep 17 00:00:00 2001 From: darwintree <17946284+darwintree@users.noreply.github.com> Date: Fri, 15 Nov 2024 15:06:39 +0800 Subject: [PATCH] feat: compatible wallet construction api with web3py v7 --- conflux_web3/middleware/__init__.py | 6 ++++-- conflux_web3/middleware/wallet.py | 11 +++++++---- conflux_web3/types/__init__.py | 16 ++++++++++++---- docs/en/README.md | 22 +++++++++++++--------- tests/middleware/test_wallet.py | 22 +++++++++++++++++++++- 5 files changed, 57 insertions(+), 20 deletions(-) diff --git a/conflux_web3/middleware/__init__.py b/conflux_web3/middleware/__init__.py index ebdde77..ac41024 100644 --- a/conflux_web3/middleware/__init__.py +++ b/conflux_web3/middleware/__init__.py @@ -8,6 +8,7 @@ ) from conflux_web3.middleware.wallet import ( Wallet, + construct_sign_and_send_raw_middleware, ) from conflux_web3.middleware.names import ( name_to_address_middleware @@ -23,12 +24,13 @@ def conflux_default_middlewares(w3: "Web3") -> Sequence[Tuple[Middleware, str]]: return [ (name_to_address_middleware(w3), "name_to_address"), (PendingTransactionMiddleware, "PendingTransactionMiddleware"), - (Wallet(), "wallet"), + (Wallet(), "wallet"), # type: ignore ] __all__ = [ "PendingTransactionMiddleware", "Wallet", - "conflux_default_middlewares" + "conflux_default_middlewares", + "construct_sign_and_send_raw_middleware", ] diff --git a/conflux_web3/middleware/wallet.py b/conflux_web3/middleware/wallet.py index eea3545..4a0ea45 100644 --- a/conflux_web3/middleware/wallet.py +++ b/conflux_web3/middleware/wallet.py @@ -9,8 +9,6 @@ ) import warnings -from toolz import curry - from eth_keys.datatypes import ( PrivateKey, ) @@ -192,5 +190,10 @@ def pop(self, address: str) -> LocalAccount: def construct_sign_and_send_raw_middleware( account_or_accounts: Union[Sequence[_PrivateKey], _PrivateKey], forced_chain_id: Optional[int]=None -) -> Wallet: - return Wallet(account_or_accounts, forced_chain_id) +): + return Wallet(account_or_accounts, forced_chain_id) # type: ignore + +class SignAndSendRawMiddlewareBuilder: + @classmethod + def build(cls, account_or_accounts: Union[Sequence[_PrivateKey], _PrivateKey], forced_chain_id: Optional[int]=None): + return Wallet(account_or_accounts, forced_chain_id) # type: ignore diff --git a/conflux_web3/types/__init__.py b/conflux_web3/types/__init__.py index 425cb45..3f41e1e 100644 --- a/conflux_web3/types/__init__.py +++ b/conflux_web3/types/__init__.py @@ -1,13 +1,14 @@ from typing import ( TYPE_CHECKING, Any, - Type, List, NewType, Optional, Sequence, Union, - Dict + Dict, + Callable, + Protocol, ) from typing_extensions import ( Literal, @@ -18,6 +19,7 @@ from web3.datastructures import ( NamedElementOnion, ) +from web3.types import RPCResponse, RPCEndpoint from cfx_address import Base32Address from cfx_utils.types import ( @@ -371,9 +373,15 @@ class BlockData(TypedDict): posReference: Hash32 transactions: Sequence[Union[Hash32, TxData]] baseFeePerGas: Drip - -Middleware = Type["ConfluxWeb3Middleware"] +class Web3MiddlewareProtocol(Protocol): + def request_processor(self, method: RPCEndpoint, params: Any) -> Any: + ... + + def response_processor(self, method: RPCEndpoint, response: RPCResponse) -> RPCResponse: + ... + +Middleware = Callable[["Web3"], Web3MiddlewareProtocol] MiddlewareOnion = NamedElementOnion[str, Middleware] class StorageRoot(TypedDict): diff --git a/docs/en/README.md b/docs/en/README.md index 0bf9694..80b6524 100644 --- a/docs/en/README.md +++ b/docs/en/README.md @@ -18,11 +18,13 @@ ## Overview -Python-conflux-sdk helps to interact with Conflux network using python. It is built over [web3.py](https://github.com/ethereum/web3.py) and most of its APIs are consistent with [web3.py](https://github.com/ethereum/web3.py). +Python-conflux-sdk (or conflux-web3) helps to interact with Conflux network using python. It is built over [web3.py](https://github.com/ethereum/web3.py) and most of its APIs are consistent with [web3.py](https://github.com/ethereum/web3.py). + +> Note: python-conflux-sdk v1.3.0 is the version compatible with web3.py v6.x. If you are using web3.py v7.x, please use the v1.4.0 or later. ## Quickstart -Requirements: python version >= 3.7 +Requirements: python version >= 3.8 ```bash $ pip3 install conflux-web3 @@ -35,7 +37,9 @@ w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com")) acct = w3.account.from_key("0xxxxxxxxxxxxxx") w3.cfx.default_account = acct -w3.cfx.contract(name="Faucet").claimCfx().transact().executed() + +# Uncomment the following line if there is not CFX in your account +# w3.cfx.contract(name="Faucet").claimCfx().transact().executed() w3.cfx.send_transaction({ 'to': w3.address.zero_address(), @@ -43,16 +47,16 @@ w3.cfx.send_transaction({ }).executed() ``` -Or you can also use API as you do in `web3.py`: +Or you can also use API as you do in `web3.py` before v6.20: ``` python -# modified from https://web3py.readthedocs.io/en/stable/middleware.html#signing +# modified from https://web3py.readthedocs.io/en/v6.20.2/transactions.html#chapter-1-w3-eth-send-transaction-signer-middleware from conflux_web3 import Web3 -w3 = Web3("https://test.confluxrpc.com") -from conflux_web3.middleware import construct_sign_and_send_raw_middleware +w3 = Web3(Web3.HTTPProvider("https://test.confluxrpc.com")) +from conflux_web3.middleware import SignAndSendRawMiddlewareBuilder from cfx_account import Account -acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530') -w3.middleware_onion.add(construct_sign_and_send_raw_middleware(acct)) +acct = Account.create('KEYSMASH FJAFJKLDSKF7JKFDJ 1530', network_id=w3.cfx.chain_id) +w3.middleware_onion.inject(SignAndSendRawMiddlewareBuilder.build(acct), layer=0) w3.cfx.default_account = acct.address transaction = { diff --git a/tests/middleware/test_wallet.py b/tests/middleware/test_wallet.py index 431fa3a..58c7029 100644 --- a/tests/middleware/test_wallet.py +++ b/tests/middleware/test_wallet.py @@ -6,7 +6,8 @@ from conflux_web3 import Web3 from conflux_web3.middleware.wallet import ( Wallet, - construct_sign_and_send_raw_middleware + construct_sign_and_send_raw_middleware, + SignAndSendRawMiddlewareBuilder ) @pytest.mark.xdist_group(name="account") @@ -28,6 +29,25 @@ def test_wallet_middleware_single_init(w3:Web3, account: LocalAccount): assert hash w3.cfx.wait_for_transaction_receipt(hash) +@pytest.mark.xdist_group(name="account") +def test_wallet_middleware_single_init_by_builder(w3:Web3, account: LocalAccount): + wallet = SignAndSendRawMiddlewareBuilder.build(account, w3.cfx.chain_id) + w3.middleware_onion.inject(wallet, layer=0) + tx = { + 'from': account.address, + # 'nonce': w3.cfx.get_next_nonce(addr), + # 'gas': 21000, + 'to': w3.cfx.account.create().address, + 'value': 10**9, + # 'gasPrice': 10**9, + # 'chainId': w3.cfx.chain_id, + # 'storageLimit': 0, + # 'epochHeight': status['epochNumber'] + } + hash = w3.cfx.send_transaction(tx) + assert hash + w3.cfx.wait_for_transaction_receipt(hash) + @pytest.mark.xdist_group(name="account") def test_no_chain_id_wallet_middleware_single_init(w3:Web3, account: LocalAccount): wallet = construct_sign_and_send_raw_middleware(account)