Skip to content

Commit f26b65a

Browse files
committed
internal/jsre: upgrade offline wallet for goja
1 parent 66ded3c commit f26b65a

File tree

2 files changed

+45
-103
lines changed

2 files changed

+45
-103
lines changed

internal/jsre/jsre.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ func New(assetPath string, output io.Writer) *JSRE {
7979
go re.runEventLoop()
8080
re.Set("loadScript", MakeCallback(re.vm, re.loadScript))
8181
re.Set("inspect", re.prettyPrintJS)
82-
re.Set("loadFile", re.loadFile)
83-
re.Set("msleep", re.msleep)
84-
re.Set("offlineWalletOpen", re.offlineWalletOpen)
85-
re.Set("offlineWalletAddress", re.offlineWalletAddress)
86-
re.Set("offlineWalletClose", re.offlineWalletClose)
87-
re.Set("offlineWalletSignTx", re.offlineWalletSignTx)
88-
re.Set("offlineWalletList", re.offlineWalletList)
82+
re.Set("loadFile", MakeCallback(re.vm, re.loadFile))
83+
re.Set("msleep", MakeCallback(re.vm, re.msleep))
84+
re.Set("offlineWalletOpen", MakeCallback(re.vm, re.offlineWalletOpen))
85+
re.Set("offlineWalletAddress", MakeCallback(re.vm, re.offlineWalletAddress))
86+
re.Set("offlineWalletClose", MakeCallback(re.vm, re.offlineWalletClose))
87+
re.Set("offlineWalletSignTx", MakeCallback(re.vm, re.offlineWalletSignTx))
88+
re.Set("offlineWalletList", MakeCallback(re.vm, re.offlineWalletList))
8989
return re
9090
}
9191

@@ -330,8 +330,8 @@ func (re *JSRE) loadFile(call Call) (goja.Value, error) {
330330
}
331331

332332
// msleep sleeps in ms resolution
333-
func (re *JSRE) msleep(call Call) goja.Value {
333+
func (re *JSRE) msleep(call Call) (goja.Value, error) {
334334
delay := call.Argument(0).ToInteger()
335335
time.Sleep(time.Duration(delay) * time.Millisecond)
336-
return re.vm.ToValue(true)
336+
return re.vm.ToValue(true), nil
337337
}

internal/jsre/offline_wallet.go

+36-94
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"strings"
1515
"sync"
1616

17+
"github.com/dop251/goja"
1718
"github.com/ethereum/go-ethereum"
1819
"github.com/ethereum/go-ethereum/accounts"
1920
"github.com/ethereum/go-ethereum/accounts/keystore"
@@ -22,10 +23,8 @@ import (
2223
"github.com/ethereum/go-ethereum/common/hexutil"
2324
"github.com/ethereum/go-ethereum/core/types"
2425
"github.com/ethereum/go-ethereum/crypto"
25-
"github.com/ethereum/go-ethereum/log"
2626
"github.com/ethereum/go-ethereum/rlp"
2727
"github.com/pborman/uuid"
28-
"github.com/robertkrimen/otto"
2928
)
3029

3130
var (
@@ -66,17 +65,6 @@ type gethAccount struct {
6665
key *keystore.Key
6766
}
6867

69-
// copied from 'console' package.
70-
// throwJSException panics on an otto.Value. The Otto VM will recover from the
71-
// Go panic and throw msg as a JavaScript error.
72-
func throwJSException(err error) otto.Value {
73-
val, err2 := otto.ToValue(err.Error())
74-
if err2 != nil {
75-
log.Error("Failed to serialize JavaScript exception", "exception", err, "err", err2)
76-
}
77-
panic(val)
78-
}
79-
8068
// id is sha3 of random uuid
8169
func offlineWalletNewId() string {
8270
return hex.EncodeToString(
@@ -165,28 +153,25 @@ func openUsbWallet(scheme, path string) (string, *common.Address, error) {
165153
offlineWallets[id] = drv
166154
addr, err := drv.Derive(accounts.DefaultBaseDerivationPath)
167155
if err != nil {
168-
throwJSException(err)
156+
return "", nil, err
169157
}
170158
return id, &addr, nil
171159
}
172160

173161
// { "id": string, "address": address } offlneWalletOpen(string url, string password)
174-
func (re *JSRE) offlineWalletOpen(call otto.FunctionCall) otto.Value {
175-
rawurl, err := call.Argument(0).ToString()
176-
if err != nil {
177-
throwJSException(err)
178-
}
162+
func (re *JSRE) offlineWalletOpen(call Call) (goja.Value, error) {
163+
rawurl := call.Argument(0).ToString().String()
179164
password := ""
180-
if call.Argument(1).IsString() {
181-
password, _ = call.Argument(1).ToString()
165+
if len(call.Arguments) >= 2 && call.Argument(1).ToString() != nil {
166+
password = call.Argument(1).ToString().String()
182167
}
183168

184169
offlineWalletLock.Lock()
185170
defer offlineWalletLock.Unlock()
186171

187172
u, err := url.Parse(rawurl)
188173
if err != nil {
189-
throwJSException(err)
174+
return nil, err
190175
}
191176

192177
path := u.Path
@@ -199,86 +184,62 @@ func (re *JSRE) offlineWalletOpen(call otto.FunctionCall) otto.Value {
199184
case "", "geth", "gmet":
200185
id, addr, err := loadGethAccount(password, path)
201186
if err != nil {
202-
throwJSException(err)
187+
return nil, err
203188
} else {
204189
r := map[string]string{
205190
"id": id,
206191
"address": addr.Hex(),
207192
}
208-
env := otto.New()
209-
v, err := env.ToValue(r)
210-
if err != nil {
211-
throwJSException(err)
212-
}
213-
return v
193+
return re.vm.ToValue(r), nil
214194
}
215195
case "ledger", "trezor":
216196
id, addr, err := openUsbWallet(u.Scheme, path)
217197
if err != nil {
218-
throwJSException(err)
198+
return nil, err
219199
} else {
220200
r := map[string]string{
221201
"id": id,
222202
"address": addr.Hex(),
223203
}
224-
env := otto.New()
225-
v, err := env.ToValue(r)
226-
if err != nil {
227-
throwJSException(err)
228-
}
229-
return v
204+
return re.vm.ToValue(r), nil
230205
}
231206
default:
232207
// not supported
233-
throwJSException(errors.New("Not Supported"))
208+
return nil, errors.New("Not Supported")
234209
}
235-
return otto.UndefinedValue()
236210
}
237211

238212
// address offlneWalletAddress(string id)
239-
func (re *JSRE) offlineWalletAddress(call otto.FunctionCall) otto.Value {
240-
id, err := call.Argument(0).ToString()
241-
if err != nil {
242-
throwJSException(err)
243-
}
213+
func (re *JSRE) offlineWalletAddress(call Call) (goja.Value, error) {
214+
id := call.Argument(0).ToString().String()
244215

245216
offlineWalletLock.Lock()
246217
w, ok := offlineWallets[id]
247218
offlineWalletLock.Unlock()
248219

249220
if !ok {
250-
throwJSException(ethereum.NotFound)
251-
return otto.UndefinedValue()
221+
return nil, ethereum.NotFound
252222
} else {
253223
addr, err := w.Derive(accounts.DefaultBaseDerivationPath)
254224
if err != nil {
255-
throwJSException(err)
256-
}
257-
v, err := otto.ToValue(addr.Hex())
258-
if err != nil {
259-
throwJSException(err)
225+
return nil, err
260226
}
261-
return v
227+
return re.vm.ToValue(addr.Hex()), nil
262228
}
263229
}
264230

265231
// address offlneWalletClose(string id)
266-
func (re *JSRE) offlineWalletClose(call otto.FunctionCall) otto.Value {
267-
id, err := call.Argument(0).ToString()
268-
if err != nil {
269-
throwJSException(err)
270-
}
271-
232+
func (re *JSRE) offlineWalletClose(call Call) (goja.Value, error) {
233+
id := call.Argument(0).ToString().String()
272234
offlineWalletLock.Lock()
273235
defer offlineWalletLock.Unlock()
274236

275237
if w, ok := offlineWallets[id]; !ok {
276-
throwJSException(ethereum.NotFound)
277-
return otto.FalseValue()
238+
return re.vm.ToValue(false), nil
278239
} else {
279240
delete(offlineWallets, id)
280241
w.Close()
281-
return otto.TrueValue()
242+
return re.vm.ToValue(true), nil
282243
}
283244
}
284245

@@ -382,31 +343,22 @@ func (re *JSRE) getTxArgs(jtx string) (*SendTxArgs, error) {
382343
}
383344

384345
// []byte offlineWalletSignTx(string id, transaction tx, chainID int)
385-
func (re *JSRE) offlineWalletSignTx(call otto.FunctionCall) otto.Value {
386-
id, err := call.Argument(0).ToString()
387-
if err != nil {
388-
throwJSException(err)
389-
}
390-
chainID, err := call.Argument(2).ToInteger()
391-
if err != nil {
392-
throwJSException(err)
393-
}
346+
func (re *JSRE) offlineWalletSignTx(call Call) (goja.Value, error) {
347+
id := call.Argument(0).ToString().String()
348+
chainID := call.Argument(2).ToInteger()
394349

395350
var (
396351
tx *types.Transaction
397352
input []byte
398353
)
399354

400-
// javascript json object -> string -> jsTx -> types.Transaction
401-
JSON, _ := call.Otto.Object("JSON")
402-
jtx, err := JSON.Call("stringify", call.Argument(1))
355+
jtx, err := call.Argument(1).ToObject(re.vm).MarshalJSON()
403356
if err != nil {
404-
throwJSException(err)
357+
return nil, err
405358
}
406-
407-
txargs, err := re.getTxArgs(jtx.String())
359+
txargs, err := re.getTxArgs(string(jtx))
408360
if err != nil {
409-
throwJSException(err)
361+
return nil, err
410362
}
411363

412364
if txargs.Data != nil {
@@ -429,41 +381,31 @@ func (re *JSRE) offlineWalletSignTx(call otto.FunctionCall) otto.Value {
429381
offlineWalletLock.Unlock()
430382

431383
if !ok {
432-
throwJSException(ethereum.NotFound)
433-
return otto.UndefinedValue()
384+
return nil, ethereum.NotFound
434385
} else {
435386
_, stx, err := w.SignTx(accounts.DefaultBaseDerivationPath, tx,
436387
big.NewInt(chainID))
437388
if err != nil {
438-
throwJSException(err)
389+
return nil, err
439390
}
440391
data, err := rlp.EncodeToBytes(stx)
441392
if err != nil {
442-
throwJSException(err)
393+
return nil, err
443394
}
444-
v, err := otto.ToValue(hexutil.Encode(data))
445-
if err != nil {
446-
throwJSException(err)
447-
}
448-
return v
395+
return re.vm.ToValue(hexutil.Encode(data)), nil
449396
}
450397
}
451398

452399
// offlineWalletList returns the array of ledger or trezor device paths
453400
// for mostly informational use
454-
func (re *JSRE) offlineWalletList(call otto.FunctionCall) otto.Value {
401+
func (re *JSRE) offlineWalletList(call Call) (goja.Value, error) {
455402
scheme := ""
456-
if call.Argument(0).IsString() {
457-
scheme, _ = call.Argument(0).ToString()
403+
if len(call.Arguments) >= 1 && call.Argument(0).ToString() != nil {
404+
scheme = call.Argument(0).ToString().String()
458405
}
459406

460407
paths := usbwallet.ListDevices(scheme)
461-
env := otto.New()
462-
v, err := env.ToValue(paths)
463-
if err != nil {
464-
throwJSException(err)
465-
}
466-
return v
408+
return re.vm.ToValue(paths), nil
467409
}
468410

469411
// EOF

0 commit comments

Comments
 (0)