diff options
author | Péter Szilágyi <peterke@gmail.com> | 2017-08-14 23:52:40 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-14 23:52:40 +0800 |
commit | ef0edc6e32d98d2fca54076f38cb317f43704900 (patch) | |
tree | 3c110e3aa936721d90537074ea187cbfb5f5991c /console | |
parent | 6ca59d98f88d4b4cc8bdeb2f023ff8c1fa228c6f (diff) | |
parent | 02656f9f614374b3f30b0cc57562e31c570cdf3d (diff) | |
download | dexon-ef0edc6e32d98d2fca54076f38cb317f43704900.tar dexon-ef0edc6e32d98d2fca54076f38cb317f43704900.tar.gz dexon-ef0edc6e32d98d2fca54076f38cb317f43704900.tar.bz2 dexon-ef0edc6e32d98d2fca54076f38cb317f43704900.tar.lz dexon-ef0edc6e32d98d2fca54076f38cb317f43704900.tar.xz dexon-ef0edc6e32d98d2fca54076f38cb317f43704900.tar.zst dexon-ef0edc6e32d98d2fca54076f38cb317f43704900.zip |
Merge pull request #14885 from karalabe/trezor-boom
accounts, console, internal: support trezor hardware wallet
Diffstat (limited to 'console')
-rw-r--r-- | console/bridge.go | 44 | ||||
-rw-r--r-- | console/console.go | 12 |
2 files changed, 53 insertions, 3 deletions
diff --git a/console/bridge.go b/console/bridge.go index 75be68188..b28cc438e 100644 --- a/console/bridge.go +++ b/console/bridge.go @@ -23,6 +23,7 @@ import ( "strings" "time" + "github.com/ethereum/go-ethereum/accounts/usbwallet" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rpc" "github.com/robertkrimen/otto" @@ -83,6 +84,49 @@ func (b *bridge) NewAccount(call otto.FunctionCall) (response otto.Value) { return ret } +// OpenWallet is a wrapper around personal.openWallet which can interpret and +// react to certain error messages, such as the Trezor PIN matrix request. +func (b *bridge) OpenWallet(call otto.FunctionCall) (response otto.Value) { + // Make sure we have an wallet specified to open + if !call.Argument(0).IsString() { + throwJSException("first argument must be the wallet URL to open") + } + wallet := call.Argument(0) + + var passwd otto.Value + if call.Argument(1).IsUndefined() || call.Argument(1).IsNull() { + passwd, _ = otto.ToValue("") + } else { + passwd = call.Argument(1) + } + // Open the wallet and return if successful in itself + val, err := call.Otto.Call("jeth.openWallet", nil, wallet, passwd) + if err == nil { + return val + } + // Wallet open failed, report error unless it's a PIN entry + if !strings.HasSuffix(err.Error(), usbwallet.ErrTrezorPINNeeded.Error()) { + throwJSException(err.Error()) + } + // Trezor PIN matrix input requested, display the matrix to the user and fetch the data + fmt.Fprintf(b.printer, "Look at the device for number positions\n\n") + fmt.Fprintf(b.printer, "7 | 8 | 9\n") + fmt.Fprintf(b.printer, "--+---+--\n") + fmt.Fprintf(b.printer, "4 | 5 | 6\n") + fmt.Fprintf(b.printer, "--+---+--\n") + fmt.Fprintf(b.printer, "1 | 2 | 3\n\n") + + if input, err := b.prompter.PromptPassword("Please enter current PIN: "); err != nil { + throwJSException(err.Error()) + } else { + passwd, _ = otto.ToValue(input) + } + if val, err = call.Otto.Call("jeth.openWallet", nil, wallet, passwd); err != nil { + throwJSException(err.Error()) + } + return val +} + // UnlockAccount is a wrapper around the personal.unlockAccount RPC method that // uses a non-echoing password prompt to acquire the passphrase and executes the // original RPC method (saved in jeth.unlockAccount) with it to actually execute diff --git a/console/console.go b/console/console.go index 389d52858..3cd2ad34b 100644 --- a/console/console.go +++ b/console/console.go @@ -160,10 +160,15 @@ func (c *Console) init(preload []string) error { if err != nil { return err } - // Override the unlockAccount, newAccount and sign methods since these require user interaction. - // Assign these method in the Console the original web3 callbacks. These will be called by the jeth.* - // methods after they got the password from the user and send the original web3 request to the backend. + // Override the openWallet, unlockAccount, newAccount and sign methods since + // these require user interaction. Assign these method in the Console the + // original web3 callbacks. These will be called by the jeth.* methods after + // they got the password from the user and send the original web3 request to + // the backend. if obj := personal.Object(); obj != nil { // make sure the personal api is enabled over the interface + if _, err = c.jsre.Run(`jeth.openWallet = personal.openWallet;`); err != nil { + return fmt.Errorf("personal.openWallet: %v", err) + } if _, err = c.jsre.Run(`jeth.unlockAccount = personal.unlockAccount;`); err != nil { return fmt.Errorf("personal.unlockAccount: %v", err) } @@ -173,6 +178,7 @@ func (c *Console) init(preload []string) error { if _, err = c.jsre.Run(`jeth.sign = personal.sign;`); err != nil { return fmt.Errorf("personal.sign: %v", err) } + obj.Set("openWallet", bridge.OpenWallet) obj.Set("unlockAccount", bridge.UnlockAccount) obj.Set("newAccount", bridge.NewAccount) obj.Set("sign", bridge.Sign) |