Skip to content

Commit

Permalink
Added async eth.sign_transaction (#2848)
Browse files Browse the repository at this point in the history
Co-authored-by: kclowes <kclowes@users.noreply.github.com>
  • Loading branch information
Player256 and kclowes authored Apr 7, 2023
1 parent 8895bfc commit 402d001
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/providers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ Eth
- :meth:`web3.eth.send_raw_transaction() <web3.eth.Eth.send_raw_transaction>`
- :meth:`web3.eth.wait_for_transaction_receipt() <web3.eth.Eth.wait_for_transaction_receipt>`
- :meth:`web3.eth.sign() <web3.eth.Eth.sign>`
- :meth:`web3.eth.sign_transaction() <web3.eth.Eth.sign_transaction>`
- :meth:`web3.eth.replace_transaction() <web3.eth.Eth.replace_transaction>`

Net
Expand Down
1 change: 1 addition & 0 deletions newsfragments/2827.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add the ``sign_transaction`` method to the ``AsyncEth`` class
101 changes: 101 additions & 0 deletions web3/_utils/module_testing/eth_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,107 @@ async def test_eth_send_transaction_legacy(
assert txn["gas"] == 21000
assert txn["gasPrice"] == txn_params["gasPrice"]

@pytest.mark.asyncio
async def test_async_eth_sign_transaction(
self, async_w3: "AsyncWeb3", unlocked_account: ChecksumAddress
) -> None:
txn_params: TxParams = {
"from": unlocked_account,
"to": unlocked_account,
"value": Wei(1),
"gas": 21000,
"maxFeePerGas": async_w3.to_wei(2, "gwei"),
"maxPriorityFeePerGas": async_w3.to_wei(1, "gwei"),
"nonce": Nonce(0),
}
result = await async_w3.eth.sign_transaction(txn_params)
signatory_account = async_w3.eth.account.recover_transaction(result["raw"])
assert unlocked_account == signatory_account
assert result["tx"]["to"] == txn_params["to"]
assert result["tx"]["value"] == txn_params["value"]
assert result["tx"]["gas"] == txn_params["gas"]
assert result["tx"]["maxFeePerGas"] == txn_params["maxFeePerGas"]
assert (
result["tx"]["maxPriorityFeePerGas"] == txn_params["maxPriorityFeePerGas"]
)
assert result["tx"]["nonce"] == txn_params["nonce"]

@pytest.mark.asyncio
async def test_async_eth_sign_transaction_legacy(
self, async_w3: "AsyncWeb3", unlocked_account: ChecksumAddress
) -> None:
txn_params: TxParams = {
"from": unlocked_account,
"to": unlocked_account,
"value": Wei(1),
"gas": 21000,
"gasPrice": await async_w3.eth.gas_price,
"nonce": Nonce(0),
}
result = await async_w3.eth.sign_transaction(txn_params)
signatory_account = async_w3.eth.account.recover_transaction(result["raw"])
assert unlocked_account == signatory_account
assert result["tx"]["to"] == txn_params["to"]
assert result["tx"]["value"] == txn_params["value"]
assert result["tx"]["gas"] == txn_params["gas"]
assert result["tx"]["gasPrice"] == txn_params["gasPrice"]
assert result["tx"]["nonce"] == txn_params["nonce"]

@pytest.mark.asyncio
async def test_async_eth_sign_transaction_hex_fees(
self, async_w3: "AsyncWeb3", unlocked_account: ChecksumAddress
) -> None:
txn_params: TxParams = {
"from": unlocked_account,
"to": unlocked_account,
"value": Wei(1),
"gas": 21000,
"maxFeePerGas": hex(async_w3.to_wei(2, "gwei")),
"maxPriorityFeePerGas": hex(async_w3.to_wei(1, "gwei")),
"nonce": Nonce(0),
}
result = await async_w3.eth.sign_transaction(txn_params)
signatory_account = async_w3.eth.account.recover_transaction(result["raw"])
assert unlocked_account == signatory_account
assert result["tx"]["to"] == txn_params["to"]
assert result["tx"]["value"] == txn_params["value"]
assert result["tx"]["gas"] == txn_params["gas"]
assert result["tx"]["maxFeePerGas"] == int(str(txn_params["maxFeePerGas"]), 16)
assert result["tx"]["maxPriorityFeePerGas"] == int(
str(txn_params["maxPriorityFeePerGas"]), 16
)
assert result["tx"]["nonce"] == txn_params["nonce"]

@pytest.mark.asyncio
@pytest.mark.xfail(
reason="async name_to_address_middleware has not been implemented yet"
)
async def test_async_eth_sign_transaction_ens_names(
self, async_w3: "AsyncWeb3", unlocked_account: ChecksumAddress
) -> None:
with ens_addresses(async_w3, {"unlocked-account.eth": unlocked_account}):
txn_params: TxParams = {
"from": "unlocked-account.eth",
"to": "unlocked-account.eth",
"value": Wei(1),
"gas": 21000,
"maxFeePerGas": async_w3.to_wei(2, "gwei"),
"maxPriorityFeePerGas": async_w3.to_wei(1, "gwei"),
"nonce": Nonce(0),
}
result = await async_w3.eth.sign_transaction(txn_params)
signatory_account = async_w3.eth.account.recover_transaction(result["raw"])
assert unlocked_account == signatory_account
assert result["tx"]["to"] == unlocked_account
assert result["tx"]["value"] == txn_params["value"]
assert result["tx"]["gas"] == txn_params["gas"]
assert result["tx"]["maxFeePerGas"] == txn_params["maxFeePerGas"]
assert (
result["tx"]["maxPriorityFeePerGas"]
== txn_params["maxPriorityFeePerGas"]
)
assert result["tx"]["nonce"] == txn_params["nonce"]

@pytest.mark.asyncio
async def test_eth_send_transaction(
self, async_w3: "AsyncWeb3", unlocked_account_dual_type: ChecksumAddress
Expand Down
11 changes: 11 additions & 0 deletions web3/eth/async_eth.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
FilterParams,
LogReceipt,
Nonce,
SignedTx,
SyncStatus,
TxData,
TxParams,
Expand Down Expand Up @@ -547,6 +548,16 @@ async def sign(
) -> HexStr:
return await self._sign(account, data, hexstr, text)

# eth_signTransaction

_sign_transaction: Method[Callable[[TxParams], Awaitable[SignedTx]]] = Method(
RPC.eth_signTransaction,
mungers=[default_root_munger],
)

async def sign_transaction(self, transaction: TxParams) -> SignedTx:
return await self._sign_transaction(transaction)

# eth_newFilter, eth_newBlockFilter, eth_newPendingTransactionFilter

filter: Method[
Expand Down

0 comments on commit 402d001

Please sign in to comment.