@@ -19,13 +19,11 @@ package console
1919import (
2020 "encoding/json"
2121 "errors"
22- "fmt"
2322 "io"
2423 "reflect"
2524 "strings"
2625 "time"
2726
28- "github.com/XinFinOrg/XDPoSChain/accounts/usbwallet"
2927 "github.com/XinFinOrg/XDPoSChain/common/hexutil"
3028 "github.com/XinFinOrg/XDPoSChain/internal/jsre"
3129 "github.com/XinFinOrg/XDPoSChain/rpc"
@@ -49,212 +47,6 @@ func newBridge(client *rpc.Client, prompter UserPrompter, printer io.Writer) *br
4947 }
5048}
5149
52- func getJeth (vm * goja.Runtime ) * goja.Object {
53- jeth := vm .Get ("jeth" )
54- if jeth == nil {
55- panic (vm .ToValue ("jeth object does not exist" ))
56- }
57- return jeth .ToObject (vm )
58- }
59-
60- // NewAccount is a wrapper around the personal.newAccount RPC method that uses a
61- // non-echoing password prompt to acquire the passphrase and executes the original
62- // RPC method (saved in jeth.newAccount) with it to actually execute the RPC call.
63- func (b * bridge ) NewAccount (call jsre.Call ) (goja.Value , error ) {
64- var (
65- password string
66- confirm string
67- err error
68- )
69- switch {
70- // No password was specified, prompt the user for it
71- case len (call .Arguments ) == 0 :
72- if password , err = b .prompter .PromptPassword ("Passphrase: " ); err != nil {
73- return nil , err
74- }
75- if confirm , err = b .prompter .PromptPassword ("Repeat passphrase: " ); err != nil {
76- return nil , err
77- }
78- if password != confirm {
79- return nil , errors .New ("passwords don't match" )
80- }
81- // A single string password was specified, use that
82- case len (call .Arguments ) == 1 && call .Argument (0 ).ToString () != nil :
83- password = call .Argument (0 ).ToString ().String ()
84- default :
85- return nil , errors .New ("expected 0 or 1 string argument" )
86- }
87- // Password acquired, execute the call and return
88- newAccount , callable := goja .AssertFunction (getJeth (call .VM ).Get ("newAccount" ))
89- if ! callable {
90- return nil , errors .New ("jeth.newAccount is not callable" )
91- }
92- ret , err := newAccount (goja .Null (), call .VM .ToValue (password ))
93- if err != nil {
94- return nil , err
95- }
96- return ret , nil
97- }
98-
99- // OpenWallet is a wrapper around personal.openWallet which can interpret and
100- // react to certain error messages, such as the Trezor PIN matrix request.
101- func (b * bridge ) OpenWallet (call jsre.Call ) (goja.Value , error ) {
102- // Make sure we have a wallet specified to open
103- if call .Argument (0 ).ToObject (call .VM ).ClassName () != "String" {
104- return nil , errors .New ("first argument must be the wallet URL to open" )
105- }
106- wallet := call .Argument (0 )
107-
108- var passwd goja.Value
109- if goja .IsUndefined (call .Argument (1 )) || goja .IsNull (call .Argument (1 )) {
110- passwd = call .VM .ToValue ("" )
111- } else {
112- passwd = call .Argument (1 )
113- }
114- // Open the wallet and return if successful in itself
115- openWallet , callable := goja .AssertFunction (getJeth (call .VM ).Get ("openWallet" ))
116- if ! callable {
117- return nil , errors .New ("jeth.openWallet is not callable" )
118- }
119- val , err := openWallet (goja .Null (), wallet , passwd )
120- if err == nil {
121- return val , nil
122- }
123-
124- // Wallet open failed, report error unless it's a PIN or PUK entry
125- switch {
126- case strings .HasSuffix (err .Error (), usbwallet .ErrTrezorPINNeeded .Error ()):
127- val , err = b .readPinAndReopenWallet (call )
128- if err == nil {
129- return val , nil
130- }
131- val , err = b .readPassphraseAndReopenWallet (call )
132- if err != nil {
133- return nil , err
134- }
135-
136- default :
137- // Unknown error occurred, drop to the user
138- return nil , err
139- }
140- return val , nil
141- }
142-
143- func (b * bridge ) readPassphraseAndReopenWallet (call jsre.Call ) (goja.Value , error ) {
144- wallet := call .Argument (0 )
145- input , err := b .prompter .PromptPassword ("Please enter your passphrase: " )
146- if err != nil {
147- return nil , err
148- }
149- openWallet , callable := goja .AssertFunction (getJeth (call .VM ).Get ("openWallet" ))
150- if ! callable {
151- return nil , errors .New ("jeth.openWallet is not callable" )
152- }
153- return openWallet (goja .Null (), wallet , call .VM .ToValue (input ))
154- }
155-
156- func (b * bridge ) readPinAndReopenWallet (call jsre.Call ) (goja.Value , error ) {
157- wallet := call .Argument (0 )
158- // Trezor PIN matrix input requested, display the matrix to the user and fetch the data
159- fmt .Fprintf (b .printer , "Look at the device for number positions\n \n " )
160- fmt .Fprintf (b .printer , "7 | 8 | 9\n " )
161- fmt .Fprintf (b .printer , "--+---+--\n " )
162- fmt .Fprintf (b .printer , "4 | 5 | 6\n " )
163- fmt .Fprintf (b .printer , "--+---+--\n " )
164- fmt .Fprintf (b .printer , "1 | 2 | 3\n \n " )
165-
166- input , err := b .prompter .PromptPassword ("Please enter current PIN: " )
167- if err != nil {
168- return nil , err
169- }
170- openWallet , callable := goja .AssertFunction (getJeth (call .VM ).Get ("openWallet" ))
171- if ! callable {
172- return nil , errors .New ("jeth.openWallet is not callable" )
173- }
174- return openWallet (goja .Null (), wallet , call .VM .ToValue (input ))
175- }
176-
177- // UnlockAccount is a wrapper around the personal.unlockAccount RPC method that
178- // uses a non-echoing password prompt to acquire the passphrase and executes the
179- // original RPC method (saved in jeth.unlockAccount) with it to actually execute
180- // the RPC call.
181- func (b * bridge ) UnlockAccount (call jsre.Call ) (goja.Value , error ) {
182- // Make sure we have an account specified to unlock.
183- if call .Argument (0 ).ExportType ().Kind () != reflect .String {
184- return nil , errors .New ("first argument must be the account to unlock" )
185- }
186- account := call .Argument (0 )
187-
188- // If password is not given or is the null value, prompt the user for it.
189- var passwd goja.Value
190- if goja .IsUndefined (call .Argument (1 )) || goja .IsNull (call .Argument (1 )) {
191- fmt .Fprintf (b .printer , "Unlock account %s\n " , account )
192- input , err := b .prompter .PromptPassword ("Passphrase: " )
193- if err != nil {
194- return nil , err
195- }
196- passwd = call .VM .ToValue (input )
197- } else {
198- if call .Argument (1 ).ExportType ().Kind () != reflect .String {
199- return nil , errors .New ("password must be a string" )
200- }
201- passwd = call .Argument (1 )
202- }
203-
204- // Third argument is the duration how long the account should be unlocked.
205- duration := goja .Null ()
206- if ! goja .IsUndefined (call .Argument (2 )) && ! goja .IsNull (call .Argument (2 )) {
207- if ! isNumber (call .Argument (2 )) {
208- return nil , errors .New ("unlock duration must be a number" )
209- }
210- duration = call .Argument (2 )
211- }
212-
213- // Send the request to the backend and return.
214- unlockAccount , callable := goja .AssertFunction (getJeth (call .VM ).Get ("unlockAccount" ))
215- if ! callable {
216- return nil , errors .New ("jeth.unlockAccount is not callable" )
217- }
218- return unlockAccount (goja .Null (), account , passwd , duration )
219- }
220-
221- // Sign is a wrapper around the personal.sign RPC method that uses a non-echoing password
222- // prompt to acquire the passphrase and executes the original RPC method (saved in
223- // jeth.sign) with it to actually execute the RPC call.
224- func (b * bridge ) Sign (call jsre.Call ) (goja.Value , error ) {
225- var (
226- message = call .Argument (0 )
227- account = call .Argument (1 )
228- passwd = call .Argument (2 )
229- )
230-
231- if message .ExportType ().Kind () != reflect .String {
232- return nil , errors .New ("first argument must be the message to sign" )
233- }
234- if account .ExportType ().Kind () != reflect .String {
235- return nil , errors .New ("second argument must be the account to sign with" )
236- }
237-
238- // if the password is not given or null ask the user and ensure password is a string
239- if goja .IsUndefined (passwd ) || goja .IsNull (passwd ) {
240- fmt .Fprintf (b .printer , "Give password for account %s\n " , account )
241- input , err := b .prompter .PromptPassword ("Password: " )
242- if err != nil {
243- return nil , err
244- }
245- passwd = call .VM .ToValue (input )
246- } else if passwd .ExportType ().Kind () != reflect .String {
247- return nil , errors .New ("third argument must be the password to unlock the account" )
248- }
249-
250- // Send the request to the backend and return
251- sign , callable := goja .AssertFunction (getJeth (call .VM ).Get ("unlockAccount" ))
252- if ! callable {
253- return nil , errors .New ("jeth.unlockAccount is not callable" )
254- }
255- return sign (goja .Null (), message , account , passwd )
256- }
257-
25850// Sleep will block the console for the specified number of seconds.
25951func (b * bridge ) Sleep (call jsre.Call ) (goja.Value , error ) {
26052 if ! isNumber (call .Argument (0 )) {
0 commit comments