From 4204fd5ad60aeec5312153a06908be3d3027e4a0 Mon Sep 17 00:00:00 2001 From: Bhargavasomu Date: Mon, 8 Apr 2019 21:15:42 +0530 Subject: [PATCH 1/2] Add support for eth_signTypedData, personal_signTypedData RPC call --- docs/web3.eth.rst | 21 ++- docs/web3.geth.rst | 3 +- docs/web3.parity.rst | 19 +- tests/integration/go_ethereum/common.py | 16 ++ tests/integration/parity/common.py | 16 ++ tests/integration/parity/test_parity_http.py | 2 + tests/integration/parity/test_parity_ipc.py | 2 + tests/integration/parity/test_parity_ws.py | 2 + tests/integration/test_ethereum_tester.py | 1 + web3/_utils/module_testing/eth_module.py | 99 ++++++++++ web3/_utils/module_testing/personal_module.py | 170 ++++++++++++++++++ web3/_utils/personal.py | 6 + web3/_utils/rpc_abi.py | 2 + web3/eth.py | 5 + web3/geth.py | 2 + web3/middleware/exception_retry_request.py | 4 +- web3/middleware/pythonic.py | 2 + web3/parity.py | 2 + 18 files changed, 364 insertions(+), 10 deletions(-) diff --git a/docs/web3.eth.rst b/docs/web3.eth.rst index 6646f6abe5..ceb3b912de 100644 --- a/docs/web3.eth.rst +++ b/docs/web3.eth.rst @@ -654,6 +654,19 @@ The following methods are available on the ``web3.eth`` namespace. '0x1a8bbe6eab8c72a219385681efefe565afd3accee35f516f8edf5ae82208fbd45a58f9f9116d8d88ba40fcd29076d6eada7027a3b412a9db55a0164547810cc401' +.. py:method:: Eth.signTypedData(account, jsonMessage) + + * Delegates to ``eth_signTypedData`` RPC Method + + Please note that the ``jsonMessage`` argument is the loaded JSON Object + and **NOT** the JSON String itself. + + Signs the ``Structured Data`` (or ``Typed Data``) with the private key of the given ``account``. + The account must be unlocked. + + ``account`` may be a hex address or an ENS name + + .. py:method:: Eth.call(transaction, block_identifier=web3.eth.defaultBlock) * Delegates to ``eth_call`` RPC Method @@ -864,8 +877,8 @@ with the filtering API. * Delegates to ``eth_submitHashrate`` RPC Method .. code-block:: python - - >>> node_id = '59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c' + + >>> node_id = '59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c' >>> web3.eth.submitHashrate(5000, node_id) True @@ -875,14 +888,14 @@ with the filtering API. * Delegates to ``eth_submitWork`` RPC Method. .. code-block:: python - + >>> web3.eth.submitWork( 1, '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef', '0xD1FE5700000000000000000000000000D1FE5700000000000000000000000000', ) True - + Contracts --------- diff --git a/docs/web3.geth.rst b/docs/web3.geth.rst index 181a66c718..dbf4883405 100644 --- a/docs/web3.geth.rst +++ b/docs/web3.geth.rst @@ -251,6 +251,7 @@ The following methods are available on the ``web3.geth.personal`` namespace. >>> web3.geth.personal.unlockAccount('0xd3cda913deb6f67967b99d67acdfa1712c293601', 'the-passphrase') True + .. py:method:: sendTransaction(self, transaction, passphrase) * Delegates to ``personal_sendTransaction`` RPC Method @@ -502,7 +503,7 @@ Full documentation for Geth-supported endpoints can be found `here >> web3.parity.personal.unlockAccount('0xd3cda913deb6f67967b99d67acdfa1712c293601', 'the-passphrase') True + .. py:method:: sendTransaction(self, transaction, passphrase) * Delegates to ``personal_sendTransaction`` RPC Method @@ -71,6 +72,16 @@ The following methods are available on the ``web3.parity.personal`` namespace. Sends the transaction. +.. py:method:: signTypedData(self, jsonMessage, account, passphrase) + + * Delegates to ``personal_signTypedData`` RPC Method + + Please note that the ``jsonMessage`` argument is the loaded JSON Object + and **NOT** the JSON String itself. + + Signs the ``Structured Data`` (or ``Typed Data``) with the passphrase of the given ``account`` + + ParityShh --------- @@ -121,14 +132,14 @@ Full documentation for Parity-supported endpoints can be found `here Date: Tue, 30 Apr 2019 16:29:26 -0600 Subject: [PATCH 2/2] Use pytest xfail marker, and pytest match error --- tests/integration/go_ethereum/common.py | 4 ++-- tests/integration/parity/common.py | 4 ++-- web3/_utils/module_testing/eth_module.py | 4 ++-- web3/_utils/module_testing/personal_module.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/integration/go_ethereum/common.py b/tests/integration/go_ethereum/common.py index 0be57d54e5..e2603a65c8 100644 --- a/tests/integration/go_ethereum/common.py +++ b/tests/integration/go_ethereum/common.py @@ -71,18 +71,18 @@ def test_eth_chainId(self, web3): pytest.xfail('eth_chainId not implemented in geth 1.7.2') super().test_eth_chainId(web3) + @pytest.mark.xfail(reason='eth_signTypedData has not been released in geth') def test_eth_signTypedData(self, web3, unlocked_account_dual_type): - pytest.xfail('eth_signTypedData JSON RPC call has not been released in geth') super().test_eth_signTypedData( web3, unlocked_account_dual_type ) + @pytest.mark.xfail(reason='eth_signTypedData has not been released in geth') def test_invalid_eth_signTypedData(self, web3, unlocked_account_dual_type): - pytest.xfail('eth_signTypedData JSON RPC call has not been released in geth') super().test_invalid_eth_signTypedData( web3, unlocked_account_dual_type ) diff --git a/tests/integration/parity/common.py b/tests/integration/parity/common.py index a277c5d49e..133e9c8e50 100644 --- a/tests/integration/parity/common.py +++ b/tests/integration/parity/common.py @@ -168,18 +168,18 @@ def test_eth_getLogs_without_logs(self, web3, block_with_txn_with_log): result = web3.eth.getLogs(filter_params) assert len(result) == 0 + @pytest.mark.xfail(reason='eth_signTypedData has not been released in Parity') def test_eth_signTypedData(self, web3, unlocked_account_dual_type): - pytest.xfail('eth_signTypedData JSON RPC call has not been released in parity') super().test_eth_signTypedData( web3, unlocked_account_dual_type ) + @pytest.mark.xfail(reason='eth_signTypedData has not been released in Parity') def test_invalid_eth_signTypedData(self, web3, unlocked_account_dual_type): - pytest.xfail('eth_signTypedData JSON RPC call has not been released in parity') super().test_invalid_eth_signTypedData( web3, unlocked_account_dual_type ) diff --git a/web3/_utils/module_testing/eth_module.py b/web3/_utils/module_testing/eth_module.py index 11044afa51..1dae7fd181 100644 --- a/web3/_utils/module_testing/eth_module.py +++ b/web3/_utils/module_testing/eth_module.py @@ -294,12 +294,12 @@ def test_invalid_eth_signTypedData(self, } } ''' - with pytest.raises(ValueError) as e: + with pytest.raises(ValueError, + match=r".*Expected 2 items for array type Person\[2\], got 1 items.*"): web3.eth.signTypedData( unlocked_account_dual_type, json.loads(invalid_typed_message) ) - assert "Expected 2 items for array type Person[2], got 1 items" in str(e.value) def test_eth_signTransaction(self, web3, unlocked_account): txn_params = { diff --git a/web3/_utils/module_testing/personal_module.py b/web3/_utils/module_testing/personal_module.py index d9c891a1ed..e7fc9f4e42 100644 --- a/web3/_utils/module_testing/personal_module.py +++ b/web3/_utils/module_testing/personal_module.py @@ -332,10 +332,10 @@ def test_invalid_personal_sign_typed_data(self, } } ''' - with pytest.raises(ValueError) as e: + with pytest.raises(ValueError, + match=r".*Expected 2 items for array type Person\[2\], got 1 items.*"): web3.parity.personal.signTypedData( json.loads(invalid_typed_message), unlockable_account_dual_type, unlockable_account_pw ) - assert "Expected 2 items for array type Person[2], got 1 items" in str(e.value)