1
1
import * as crypto from 'crypto'
2
- import * as ethUtil from 'ethereumjs-util'
2
+ import {
3
+ BN ,
4
+ keccak256 ,
5
+ bufferToHex ,
6
+ privateToAddress ,
7
+ publicToAddress ,
8
+ toChecksumAddress ,
9
+ privateToPublic ,
10
+ importPublic ,
11
+ isValidPrivate ,
12
+ isValidPublic ,
13
+ } from 'ethereumjs-util'
14
+ import { scrypt } from 'scrypt-js'
3
15
4
16
export { default as hdkey } from './hdkey'
5
17
export { default as thirdparty } from './thirdparty'
6
18
7
19
const bs58check = require ( 'bs58check' )
8
20
const randomBytes = require ( 'randombytes' )
9
- const scryptsy = require ( '@web3-js/scrypt-shim' )
10
21
const uuidv4 = require ( 'uuid/v4' )
11
22
12
23
// parameters for the toV3() method
@@ -235,11 +246,11 @@ export default class Wallet {
235
246
throw new Error ( 'Cannot supply both a private and a public key to the constructor' )
236
247
}
237
248
238
- if ( privateKey && ! ethUtil . isValidPrivate ( privateKey ) ) {
249
+ if ( privateKey && ! isValidPrivate ( privateKey ) ) {
239
250
throw new Error ( 'Private key does not satisfy the curve requirements (ie. it is invalid)' )
240
251
}
241
252
242
- if ( publicKey && ! ethUtil . isValidPublic ( publicKey ) ) {
253
+ if ( publicKey && ! isValidPublic ( publicKey ) ) {
243
254
throw new Error ( 'Invalid public key' )
244
255
}
245
256
}
@@ -253,10 +264,10 @@ export default class Wallet {
253
264
*/
254
265
public static generate ( icapDirect : boolean = false ) : Wallet {
255
266
if ( icapDirect ) {
256
- const max = new ethUtil . BN ( '088f924eeceeda7fe92e1f5b0fffffffffffffff' , 16 )
267
+ const max = new BN ( '088f924eeceeda7fe92e1f5b0fffffffffffffff' , 16 )
257
268
while ( true ) {
258
269
const privateKey = randomBytes ( 32 ) as Buffer
259
- if ( new ethUtil . BN ( ethUtil . privateToAddress ( privateKey ) ) . lte ( max ) ) {
270
+ if ( new BN ( privateToAddress ( privateKey ) ) . lte ( max ) ) {
260
271
return new Wallet ( privateKey )
261
272
}
262
273
}
@@ -275,7 +286,7 @@ export default class Wallet {
275
286
276
287
while ( true ) {
277
288
const privateKey = randomBytes ( 32 ) as Buffer
278
- const address = ethUtil . privateToAddress ( privateKey )
289
+ const address = privateToAddress ( privateKey )
279
290
280
291
if ( pattern . test ( address . toString ( 'hex' ) ) ) {
281
292
return new Wallet ( privateKey )
@@ -291,7 +302,7 @@ export default class Wallet {
291
302
*/
292
303
public static fromPublicKey ( publicKey : Buffer , nonStrict : boolean = false ) : Wallet {
293
304
if ( nonStrict ) {
294
- publicKey = ethUtil . importPublic ( publicKey )
305
+ publicKey = importPublic ( publicKey )
295
306
}
296
307
return new Wallet ( undefined , publicKey )
297
308
}
@@ -335,7 +346,7 @@ export default class Wallet {
335
346
* @param input A JSON serialized string, or an object representing V1 Keystore.
336
347
* @param password The keystore password.
337
348
*/
338
- public static fromV1 ( input : string | V1Keystore , password : string ) : Wallet {
349
+ public static async fromV1 ( input : string | V1Keystore , password : string ) : Promise < Wallet > {
339
350
const json : V1Keystore = typeof input === 'object' ? input : JSON . parse ( input )
340
351
if ( json . Version !== '1' ) {
341
352
throw new Error ( 'Not a V1 Wallet' )
@@ -345,24 +356,24 @@ export default class Wallet {
345
356
}
346
357
347
358
const kdfparams = json . Crypto . KeyHeader . KdfParams
348
- const derivedKey = scryptsy (
359
+ const derivedKey = await scrypt (
349
360
Buffer . from ( password ) ,
350
361
Buffer . from ( json . Crypto . Salt , 'hex' ) ,
351
362
kdfparams . N ,
352
363
kdfparams . R ,
353
364
kdfparams . P ,
354
365
kdfparams . DkLen ,
355
- ) as Buffer
366
+ )
356
367
357
368
const ciphertext = Buffer . from ( json . Crypto . CipherText , 'hex' )
358
- const mac = ethUtil . keccak256 ( Buffer . concat ( [ derivedKey . slice ( 16 , 32 ) , ciphertext ] ) )
369
+ const mac = keccak256 ( Buffer . concat ( [ derivedKey . slice ( 16 , 32 ) , ciphertext ] ) )
359
370
if ( mac . toString ( 'hex' ) !== json . Crypto . MAC ) {
360
371
throw new Error ( 'Key derivation failed - possibly wrong passphrase' )
361
372
}
362
373
363
374
const decipher = crypto . createDecipheriv (
364
375
'aes-128-cbc' ,
365
- ethUtil . keccak256 ( derivedKey . slice ( 0 , 16 ) ) . slice ( 0 , 16 ) ,
376
+ keccak256 ( derivedKey . slice ( 0 , 16 ) as Buffer ) . slice ( 0 , 16 ) ,
366
377
Buffer . from ( json . Crypto . IV , 'hex' ) ,
367
378
)
368
379
const seed = runCipherBuffer ( decipher , ciphertext )
@@ -375,31 +386,31 @@ export default class Wallet {
375
386
* @param input A JSON serialized string, or an object representing V3 Keystore.
376
387
* @param password The keystore password.
377
388
*/
378
- public static fromV3 (
389
+ public static async fromV3 (
379
390
input : string | V3Keystore ,
380
391
password : string ,
381
392
nonStrict : boolean = false ,
382
- ) : Wallet {
393
+ ) : Promise < Wallet > {
383
394
const json : V3Keystore =
384
395
typeof input === 'object' ? input : JSON . parse ( nonStrict ? input . toLowerCase ( ) : input )
385
396
386
397
if ( json . version !== 3 ) {
387
398
throw new Error ( 'Not a V3 wallet' )
388
399
}
389
400
390
- let derivedKey : Buffer , kdfparams : any
401
+ let derivedKey : Uint8Array , kdfparams : any
391
402
if ( json . crypto . kdf === 'scrypt' ) {
392
403
kdfparams = json . crypto . kdfparams
393
404
394
405
// FIXME: support progress reporting callback
395
- derivedKey = scryptsy (
406
+ derivedKey = await scrypt (
396
407
Buffer . from ( password ) ,
397
408
Buffer . from ( kdfparams . salt , 'hex' ) ,
398
409
kdfparams . n ,
399
410
kdfparams . r ,
400
411
kdfparams . p ,
401
412
kdfparams . dklen ,
402
- ) as Buffer
413
+ )
403
414
} else if ( json . crypto . kdf === 'pbkdf2' ) {
404
415
kdfparams = json . crypto . kdfparams
405
416
@@ -419,7 +430,7 @@ export default class Wallet {
419
430
}
420
431
421
432
const ciphertext = Buffer . from ( json . crypto . ciphertext , 'hex' )
422
- const mac = ethUtil . keccak256 ( Buffer . concat ( [ derivedKey . slice ( 16 , 32 ) , ciphertext ] ) )
433
+ const mac = keccak256 ( Buffer . concat ( [ derivedKey . slice ( 16 , 32 ) , ciphertext ] ) )
423
434
if ( mac . toString ( 'hex' ) !== json . crypto . mac ) {
424
435
throw new Error ( 'Key derivation failed - possibly wrong passphrase' )
425
436
}
@@ -455,7 +466,7 @@ export default class Wallet {
455
466
const decipher = crypto . createDecipheriv ( 'aes-128-cbc' , derivedKey , encseed . slice ( 0 , 16 ) )
456
467
const seed = runCipherBuffer ( decipher , encseed . slice ( 16 ) )
457
468
458
- const wallet = new Wallet ( ethUtil . keccak256 ( seed ) )
469
+ const wallet = new Wallet ( keccak256 ( seed ) )
459
470
if ( wallet . getAddress ( ) . toString ( 'hex' ) !== json . ethaddr ) {
460
471
throw new Error ( 'Decoded key mismatch - possibly wrong passphrase' )
461
472
}
@@ -469,7 +480,7 @@ export default class Wallet {
469
480
*/
470
481
private get pubKey ( ) : Buffer {
471
482
if ( ! keyExists ( this . publicKey ) ) {
472
- this . publicKey = ethUtil . privateToPublic ( this . privateKey as Buffer )
483
+ this . publicKey = privateToPublic ( this . privateKey as Buffer )
473
484
}
474
485
return this . publicKey
475
486
}
@@ -496,7 +507,7 @@ export default class Wallet {
496
507
}
497
508
498
509
public getPrivateKeyString ( ) : string {
499
- return ethUtil . bufferToHex ( this . privKey )
510
+ return bufferToHex ( this . privKey )
500
511
}
501
512
502
513
/**
@@ -511,29 +522,29 @@ export default class Wallet {
511
522
* Returns the wallet's public key as a "0x" prefixed hex string
512
523
*/
513
524
public getPublicKeyString ( ) : string {
514
- return ethUtil . bufferToHex ( this . getPublicKey ( ) )
525
+ return bufferToHex ( this . getPublicKey ( ) )
515
526
}
516
527
517
528
/**
518
529
* Returns the wallet's address.
519
530
*/
520
531
public getAddress ( ) : Buffer {
521
- return ethUtil . publicToAddress ( this . pubKey )
532
+ return publicToAddress ( this . pubKey )
522
533
}
523
534
524
535
/**
525
536
* Returns the wallet's address as a "0x" prefixed hex string
526
537
*/
527
538
public getAddressString ( ) : string {
528
- return ethUtil . bufferToHex ( this . getAddress ( ) )
539
+ return bufferToHex ( this . getAddress ( ) )
529
540
}
530
541
531
542
/**
532
543
* Returns the wallet's private key as a "0x" prefixed hex string checksummed
533
544
* according to [EIP 55](https://github.com/ethereum/EIPs/issues/55).
534
545
*/
535
546
public getChecksumAddressString ( ) : string {
536
- return ethUtil . toChecksumAddress ( this . getAddressString ( ) )
547
+ return toChecksumAddress ( this . getAddressString ( ) )
537
548
}
538
549
539
550
/**
@@ -542,15 +553,15 @@ export default class Wallet {
542
553
* @param password The password used to encrypt the Keystore.
543
554
* @param opts The options for the keystore. See [its spec](https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition) for more info.
544
555
*/
545
- public toV3 ( password : string , opts ?: Partial < V3Params > ) : V3Keystore {
556
+ public async toV3 ( password : string , opts ?: Partial < V3Params > ) : Promise < V3Keystore > {
546
557
if ( ! keyExists ( this . privateKey ) ) {
547
558
throw new Error ( 'This is a public key only wallet' )
548
559
}
549
560
550
561
const v3Params : V3ParamsStrict = mergeToV3ParamsWithDefaults ( opts )
551
562
552
563
let kdfParams : KDFParams
553
- let derivedKey : Buffer
564
+ let derivedKey : Uint8Array
554
565
switch ( v3Params . kdf ) {
555
566
case KDFFunctions . PBKDF :
556
567
kdfParams = kdfParamsForPBKDF ( v3Params )
@@ -565,14 +576,14 @@ export default class Wallet {
565
576
case KDFFunctions . Scrypt :
566
577
kdfParams = kdfParamsForScrypt ( v3Params )
567
578
// FIXME: support progress reporting callback
568
- derivedKey = scryptsy (
579
+ derivedKey = await scrypt (
569
580
Buffer . from ( password ) ,
570
581
kdfParams . salt ,
571
582
kdfParams . n ,
572
583
kdfParams . r ,
573
584
kdfParams . p ,
574
585
kdfParams . dklen ,
575
- ) as Buffer
586
+ )
576
587
break
577
588
default :
578
589
throw new Error ( 'Unsupported kdf' )
@@ -588,9 +599,7 @@ export default class Wallet {
588
599
}
589
600
590
601
const ciphertext = runCipherBuffer ( cipher , this . privKey )
591
- const mac = ethUtil . keccak256 (
592
- Buffer . concat ( [ derivedKey . slice ( 16 , 32 ) , Buffer . from ( ciphertext ) ] ) ,
593
- )
602
+ const mac = keccak256 ( Buffer . concat ( [ derivedKey . slice ( 16 , 32 ) , Buffer . from ( ciphertext ) ] ) )
594
603
595
604
return {
596
605
version : 3 ,
@@ -632,8 +641,8 @@ export default class Wallet {
632
641
)
633
642
}
634
643
635
- public toV3String ( password : string , opts ?: Partial < V3Params > ) : string {
636
- return JSON . stringify ( this . toV3 ( password , opts ) )
644
+ public async toV3String ( password : string , opts ?: Partial < V3Params > ) : Promise < string > {
645
+ return JSON . stringify ( await this . toV3 ( password , opts ) )
637
646
}
638
647
}
639
648
0 commit comments