Coder Social home page Coder Social logo

apeworx / ape-trezor Goto Github PK

View Code? Open in Web Editor NEW
4.0 4.0 6.0 53 KB

Trezor Hardware Wallet account plugin for the Ape Framework

Home Page: https://www.apeworx.io/

License: Apache License 2.0

Python 100.00%
python trezor wallet smart-contracts web3 ape apeworx trezor-wallet

ape-trezor's Introduction

Quick Start

Ape Trezor is a plugin for Ape Framework which integrates Trezorlib ethereum.py to load and create accounts, sign messages, and sign transactions.

Dependencies

Note: USB does not work in WSL2 environments natively and is not currently supported.

Installation

via pip

You can install the latest release via pip:

pip install ape-trezor

via setuptools

You can clone the repository and use setuptools for the most up-to-date version:

git clone https://github.com/ApeWorX/ape-trezor.git
cd ape-trezor
python3 setup.py install

Quick Usage

Trezor accounts have the following capabilities in ape:

  1. Can sign transactions (both static-fee and EIP-1559 compliant)
  2. Can sign messages using the default EIP-191 specification

To use the Trezor plugin, you must have the Trezor USB device connected and unlocked.

WARNING: When the Trezor Suite is open, you may face additional connection issues. It is recommended to not have the Trezor Suite application open while using the plugin.

Add Accounts

Add accounts using the add command:

ape trezor add <alias>

You can also specify the HD Path:

ape trezor add <alias> --hd-path "m/44'/1'/0'/0"

WARNING: When using 3rd party wallets, such as this plugin, trezorlib discourages signing transactions from the default Ethereum HD Path m/44'/60'/0'/0. Changing the HD-Path in that circumstance will allow fewer warnings from both Ape and the device, as well as improved security. See trezor/trezor-firmware#1336 (comment) for more information.

trezor:
  hd_path: "m/44'/1'/0'/0"

List Accounts

To list just your Trezor accounts in ape, do:

ape trezor list

Remove accounts

You can also remove accounts:

ape trezor delete <alias>
ape trezor delete-all

Sign Messages

You can sign messages with your accounts:

ape trezor sign-message <alias> "hello world"

Verify Messages

You can also verify a message with a signature:

ape trezor verify-message "hello world" <signature>

Development

Please see the contributing guide to learn more how to contribute to this project. Comments, questions, criticisms and pull requests are welcomed.

ape-trezor's People

Contributors

antazoey avatar dtdang avatar fubuloubu avatar merc1er avatar ninjagod1251 avatar notpeopling2day avatar sabotagebeats avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ape-trezor's Issues

`DataError: Safety check failed` when sending ETH

Environment information

  • ape and plugin versions:
$ ape --version
0.5.1

$ ape plugins list
Installed Plugins:
  vyper       0.5.0
  optimism    0.5.0a1
  polygon     0.5.0a1
  trezor      0.5.0
  bsc         0.5.0a1
  • Python Version: 3.10.6
  • OS: macOS

What went wrong?

I am unable to call account.transfer() with a Trezor. Here is how to reproduce the issue:

ape console --network ethereum:ropsten:geth
account = accounts.load("trezor")
account.transfer("0x1aC90B367a9f49069C34EeE3b59E7677C3DFdc6D", 10000000)

# TrezorFailure: DataError: Safety check failed
Full traceback
In [11]: account.transfer("0x1aC90B367a9f49069C34EeE3b59E7677C3DFdc6D", 100000220)
---------------------------------------------------------------------------
TrezorFailure                             Traceback (most recent call last)
<ipython-input-11-6dcb1a66d1eb> in <cell line: 1>()
----> 1 account.transfer("0x1aC90B367a9f49069C34EeE3b59E7677C3DFdc6D", 100000220)

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape/api/accounts.py in transfer(self, account, value, data, **kwargs)
    146                 raise AccountsError("Cannot use 'send_everything=True' with 'VALUE'.")
    147             txn.value = self._convert(value, int)
--> 148             return self.call(txn)
    149 
    150         elif not kwargs.get("send_everything"):

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape/api/accounts.py in call(self, txn, send_everything)
    106                 )
    107 
--> 108         txn.signature = self.sign_transaction(txn)
    109         if not txn.signature:
    110             raise SignatureError("The transaction was not signed.")

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape_trezor/accounts.py in sign_transaction(self, txn)
     92 
     93     def sign_transaction(self, txn: TransactionAPI) -> Optional[TransactionSignature]:
---> 94         signed_txn = self.client.sign_transaction(txn.dict())
     95 
     96         return TransactionSignature(*signed_txn)  # type: ignore

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape_trezor/client.py in sign_transaction(self, txn)
    125             )
    126         elif tx_type == "0x02":  # Dynamic transaction type
--> 127             tuple_reply = ethereum.sign_tx_eip1559(
    128                 self.client,
    129                 parse_hdpath(self._account_hd_path.path),

    [... skipping hidden 1 frame]

~/.pyenv/versions/ape/lib/python3.10/site-packages/trezor-0.13.3-py3.10.egg/trezorlib/ethereum.py in sign_tx_eip1559(client, n, nonce, gas_limit, to, value, data, chain_id, max_gas_fee, max_priority_fee, access_list)
    249     )
    250 
--> 251     response = client.call(msg)
    252     assert isinstance(response, messages.EthereumTxRequest)
    253 

    [... skipping hidden 1 frame]

~/.pyenv/versions/ape/lib/python3.10/site-packages/trezor-0.13.3-py3.10.egg/trezorlib/client.py in call(self, msg)
    256                 if resp.code == messages.FailureType.ActionCancelled:
    257                     raise exceptions.Cancelled
--> 258                 raise exceptions.TrezorFailure(resp)
    259             else:
    260                 return resp

TrezorFailure: DataError: Safety check failed

Note that the same commands work fine a local wallet.

Add trezor CLI to ape CLI

Overview

Trezor uses Click, so we can do like we do for other click integrations and attach the commands to ape trezor somehow

Specification

Describe the syntax and semantics of how you would like to see this feature implemented. The more detailed the better!

Remember, your feature is much more likely to be included if it does not involve any breaking changes.

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

`Recovered signer doesn't match sender` when calling contract function

Environment information

  • ape and plugin versions:
$ ape --version
0.5.1

$ ape plugins list
Installed Plugins:
  polygon     0.5.0a1
  trezor      0.5.0
  vyper       0.5.0
  • Python Version: 3.10.6
  • OS: macOS

What went wrong?

When calling contract.mint(), I am facing the following error:

❯ ape console --network ethereum:ropsten:geth
INFO: Connecting to existing Erigon node at 'https://rpc.ankr.com/eth_ropsten'.
account = accounts.load("trezor")
contract = project.Token.at("0x53410C23f709337c50006C2D76E17fEDfc494348")  # I am the owner of this ERC20 contract

contract.mint(account, 3 * int(1e8), sender=account)

# Passphrase required: 
# Confirm your passphrase: 
# Please confirm action on your Trezor device.
# SignatureError: Recovered signer doesn't match sender!
Full traceback
In [3]: contract.mint(account, 3 * int(1e8), sender=account)

Passphrase required: 
Confirm your passphrase: 
Please confirm action on your Trezor device.
---------------------------------------------------------------------------
SignatureError                            Traceback (most recent call last)
<ipython-input-3-99455129c2a0> in <cell line: 1>()
----> 1 contract.mint(account, 3 * int(1e8), sender=account)

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape/contracts/base.py in __call__(self, *args, **kwargs)
    283         function_arguments = self._convert_tuple(args)
    284         contract_transaction = self._as_transaction(*function_arguments)
--> 285         return contract_transaction(*function_arguments, **kwargs)
    286 
    287     def _as_transaction(self, *args) -> ContractTransaction:

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape/contracts/base.py in __call__(self, *args, **kwargs)
    212 
    213         if "sender" in kwargs and isinstance(kwargs["sender"], AccountAPI):
--> 214             return kwargs["sender"].call(txn)
    215 
    216         return self.provider.send_transaction(txn)

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape/api/accounts.py in call(self, txn, send_everything)
    110             raise SignatureError("The transaction was not signed.")
    111 
--> 112         return self.provider.send_transaction(txn)
    113 
    114     @cached_property

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape/api/providers.py in send_transaction(self, txn)
    877     def send_transaction(self, txn: TransactionAPI) -> ReceiptAPI:
    878         try:
--> 879             txn_hash = self.web3.eth.send_raw_transaction(txn.serialize_transaction())
    880         except ValueError as err:
    881             raise self.get_virtual_machine_error(err) from err

~/.pyenv/versions/ape/lib/python3.10/site-packages/ape_ethereum/transactions.py in serialize_transaction(self)
     64 
     65         if self.sender and EthAccount.recover_transaction(signed_txn) != self.sender:
---> 66             raise SignatureError("Recovered signer doesn't match sender!")
     67 
     68         return signed_txn

SignatureError: Recovered signer doesn't match sender!

The same code works with a local account. I also believe it worked fine before with the same Trezor, so maybe it is due to a faulty newer version of web3py?

`Forbidden key path` when using default derivation path

Environment information

  • ape and plugin versions:
$ ape --version
0.5.1

$ ape plugins list
Installed Plugins:
  trezor      0.5.0
  optimism    0.5.0a1
  vyper       0.5.0
  bsc         0.5.0a1
  • Python Version: 3.10.6
  • OS: macOS

What went wrong?

After entering my PIN, I am getting the error:

trezorlib.exceptions.TrezorFailure: DataError: Forbidden key path
Full traceback.
The layout is:

    7 8 9        e r t
    4 5 6  -or-  d f g
    1 2 3        c v b
Please enter current PIN: 
Traceback (most recent call last):
  File "/Users/cloudfloat/.pyenv/versions/ape/bin/ape", line 8, in <module>
    sys.exit(cli())
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape/_cli.py", line 40, in invoke
    return super().invoke(ctx)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape_run/_cli.py", line 23, in invoke
    return super().invoke(ctx)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape/cli/commands.py", line 18, in invoke
    super().invoke(ctx)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape_run/_cli.py", line 73, in call
    ns["main"]()  # Execute the script
  File "/Users/cloudfloat/Documents/cloud-aud/scripts/deploy.py", line 14, in main
    account.deploy(project.Token)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape/api/accounts.py", line 174, in deploy
    receipt = self.call(txn)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape/api/accounts.py", line 108, in call
    txn.signature = self.sign_transaction(txn)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape_trezor/accounts.py", line 94, in sign_transaction
    signed_txn = self.client.sign_transaction(txn.dict())
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/ape_trezor/client.py", line 129, in sign_transaction
    tuple_reply = ethereum.sign_tx_eip1559(
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/trezor-0.13.3-py3.10.egg/trezorlib/tools.py", line 288, in wrapped_f
    return f(client, *args, **kwargs)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/trezor-0.13.3-py3.10.egg/trezorlib/ethereum.py", line 251, in sign_tx_eip1559
    response = client.call(msg)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/trezor-0.13.3-py3.10.egg/trezorlib/tools.py", line 288, in wrapped_f
    return f(client, *args, **kwargs)
  File "/Users/cloudfloat/.pyenv/versions/ape/lib/python3.10/site-packages/trezor-0.13.3-py3.10.egg/trezorlib/client.py", line 258, in call
    raise exceptions.TrezorFailure(resp)
trezorlib.exceptions.TrezorFailure: DataError: Forbidden key path

I believe this is due to using a different derivation path ("m/44'/1'/0'/0") from the default one, because I am able to deploy the same contract just fine with the custom path of "m/44'/1'/0'/0".

Is this a limitation from trezorlib? If so, maybe it would be best to force "m/44'/1'/0'/0" as the only possible derivation path.

Unable to deploy contract with Trezor - trezorlib attribute error

Environment information

  • ape and plugin versions:
$ ape --version
0.4.0

$ ape plugins list
Installed Plugins:
  template    0.4.0
  trezor      0.4.0
  vyper       0.4.0
  infura      0.4.0
  • Python Version: 3.10.4
  • OS: macOS 12.5

What went wrong?

When deploying the default ERC20 token template with a Trezor account, I am getting:

❯ ape run scripts/deploy.py --network ethereum:ropsten:infura
0. local
1. trezor
2. trezor-ropsten

Select an account: 2
Traceback (most recent call last):
  File "/Users/me/.pyenv/versions/3.10.4/bin/ape", line 8, in <module>
    sys.exit(cli())
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape/_cli.py", line 40, in invoke
    return super().invoke(ctx)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape_run/_cli.py", line 23, in invoke
    return super().invoke(ctx)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape/cli/commands.py", line 18, in invoke
    super().invoke(ctx)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape_run/_cli.py", line 73, in call
    ns["main"]()  # Execute the script
  File "/Users/me/Desktop/token/scripts/deploy.py", line 7, in main
    account.deploy(project.Token)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape/api/accounts.py", line 172, in deploy
    receipt = self.call(txn)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape/api/accounts.py", line 108, in call
    txn.signature = self.sign_transaction(txn)
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape_trezor/accounts.py", line 94, in sign_transaction
    signed_txn = self.client.sign_transaction(txn.dict())
  File "/Users/me/.pyenv/versions/3.10.4/lib/python3.10/site-packages/ape_trezor/client.py", line 114, in sign_transaction
    if isinstance(tx_type, TransactionType.STATIC):
AttributeError: type object 'TransactionType' has no attribute 'STATIC'

How can it be fixed?

It seems the Trezor lib is not used properly as TransactionType does not have the STATIC attribute: https://github.com/trezor/trezor-firmware/blob/459270ef3ffe691a2e017aa8d6ccdd7178fefff9/python/src/trezorlib/messages.py#L1673

Note that I looked at the latest version or trezorlib, this might have been removed.

On next trezorlib release, we can delete mypy type ignore statements on all imports

Overview

This PR merged: https://github.com/trezor/trezor-firmware/pull/2543/files
So now on the next release, the types will be available.
Thus, we can remove the type: ignore comments.

Specification

Describe the syntax and semantics of how you would like to see this feature implemented. The more detailed the better!

Remember, your feature is much more likely to be included if it does not involve any breaking changes.

Dependencies

Include links to any open issues that must be resolved before this feature can be implemented.

ImportError: cannot import name 'Abort' from 'ape.utils'

ImportError is raised when attempting to add an account to ape trezor plugin.

Scenario:

$ ape plugins add trezor
$ ape trezor add test

Result:

WARNING: Unable to load CLI endpoint for plugin 'ape_trezor'
        ImportError: cannot import name 'Abort' from 'ape.utils' (/Users/worx/ape/src/ape/utils.py)
        (Use `--verbosity DEBUG` to see full stack-trace)
Usage: ape [OPTIONS] COMMAND [ARGS]...
Try 'ape -h' for help.

Error: No such command 'trezor'.

Environment:
macOS 12.1
Python 3.9.2

ape git:(main) ape plugins list
Installed Plugins:
  infura     0.1.0a4
  trezor     0.1.0a1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.