2022-09-05 16:57:11 -04:00
"use strict" ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
2022-12-02 21:27:06 -05:00
exports . getIndexedAccountPath = exports . getAccountPath = exports . HDNodeVoidWallet = exports . HDNodeWallet = exports . defaultPath = void 0 ;
2022-11-30 15:44:23 -05:00
/ * *
* Explain HD Wallets . .
*
* @ _subsection : api / wallet : HD Wallets [ hd - wallets ]
* /
2022-09-05 16:57:11 -04:00
const index _js _1 = require ( "../crypto/index.js" ) ;
const index _js _2 = require ( "../providers/index.js" ) ;
const index _js _3 = require ( "../transaction/index.js" ) ;
const index _js _4 = require ( "../utils/index.js" ) ;
const lang _en _js _1 = require ( "../wordlists/lang-en.js" ) ;
const base _wallet _js _1 = require ( "./base-wallet.js" ) ;
2022-11-30 15:44:23 -05:00
const mnemonic _js _1 = require ( "./mnemonic.js" ) ;
const json _keystore _js _1 = require ( "./json-keystore.js" ) ;
2022-12-02 21:27:06 -05:00
/ * *
* The default derivation path for Ethereum HD Nodes . ( i . e . ` ` "m/44'/60'/0'/0/0" ` ` )
* /
2022-09-05 16:57:11 -04:00
exports . defaultPath = "m/44'/60'/0'/0/0" ;
// "Bitcoin seed"
const MasterSecret = new Uint8Array ( [ 66 , 105 , 116 , 99 , 111 , 105 , 110 , 32 , 115 , 101 , 101 , 100 ] ) ;
const HardenedBit = 0x80000000 ;
const N = BigInt ( "0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" ) ;
const Nibbles = "0123456789abcdef" ;
function zpad ( value , length ) {
let result = "" ;
while ( value ) {
result = Nibbles [ value % 16 ] + result ;
value = Math . trunc ( value / 16 ) ;
}
while ( result . length < length * 2 ) {
result = "0" + result ;
}
return "0x" + result ;
}
function encodeBase58Check ( _value ) {
2022-09-15 22:58:45 -04:00
const value = ( 0 , index _js _4 . getBytes ) ( _value ) ;
2022-09-05 16:57:11 -04:00
const check = ( 0 , index _js _4 . dataSlice ) ( ( 0 , index _js _1 . sha256 ) ( ( 0 , index _js _1 . sha256 ) ( value ) ) , 0 , 4 ) ;
const bytes = ( 0 , index _js _4 . concat ) ( [ value , check ] ) ;
return ( 0 , index _js _4 . encodeBase58 ) ( bytes ) ;
}
const _guard = { } ;
function ser _I ( index , chainCode , publicKey , privateKey ) {
const data = new Uint8Array ( 37 ) ;
if ( index & HardenedBit ) {
2022-11-09 02:57:02 -05:00
( 0 , index _js _4 . assert ) ( privateKey != null , "cannot derive child of neutered node" , "UNSUPPORTED_OPERATION" , {
operation : "deriveChild"
} ) ;
2022-09-05 16:57:11 -04:00
// Data = 0x00 || ser_256(k_par)
2022-09-15 22:58:45 -04:00
data . set ( ( 0 , index _js _4 . getBytes ) ( privateKey ) , 1 ) ;
2022-09-05 16:57:11 -04:00
}
else {
// Data = ser_p(point(k_par))
2022-09-15 22:58:45 -04:00
data . set ( ( 0 , index _js _4 . getBytes ) ( publicKey ) ) ;
2022-09-05 16:57:11 -04:00
}
// Data += ser_32(i)
for ( let i = 24 ; i >= 0 ; i -= 8 ) {
data [ 33 + ( i >> 3 ) ] = ( ( index >> ( 24 - i ) ) & 0xff ) ;
}
2022-09-15 22:58:45 -04:00
const I = ( 0 , index _js _4 . getBytes ) ( ( 0 , index _js _1 . computeHmac ) ( "sha512" , chainCode , data ) ) ;
2022-09-05 16:57:11 -04:00
return { IL : I . slice ( 0 , 32 ) , IR : I . slice ( 32 ) } ;
}
function derivePath ( node , path ) {
const components = path . split ( "/" ) ;
2024-02-14 13:14:24 -05:00
( 0 , index _js _4 . assertArgument ) ( components . length > 0 , "invalid path" , "path" , path ) ;
2022-09-05 16:57:11 -04:00
if ( components [ 0 ] === "m" ) {
2024-02-14 13:14:24 -05:00
( 0 , index _js _4 . assertArgument ) ( node . depth === 0 , ` cannot derive root path (i.e. path starting with "m/") for a node at non-zero depth ${ node . depth } ` , "path" , path ) ;
2022-09-05 16:57:11 -04:00
components . shift ( ) ;
}
let result = node ;
for ( let i = 0 ; i < components . length ; i ++ ) {
const component = components [ i ] ;
if ( component . match ( /^[0-9]+'$/ ) ) {
const index = parseInt ( component . substring ( 0 , component . length - 1 ) ) ;
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assertArgument ) ( index < HardenedBit , "invalid path index" , ` path[ ${ i } ] ` , component ) ;
2022-09-05 16:57:11 -04:00
result = result . deriveChild ( HardenedBit + index ) ;
}
else if ( component . match ( /^[0-9]+$/ ) ) {
const index = parseInt ( component ) ;
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assertArgument ) ( index < HardenedBit , "invalid path index" , ` path[ ${ i } ] ` , component ) ;
2022-09-05 16:57:11 -04:00
result = result . deriveChild ( index ) ;
}
else {
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assertArgument ) ( false , "invalid path component" , ` path[ ${ i } ] ` , component ) ;
2022-09-05 16:57:11 -04:00
}
}
return result ;
}
2022-12-02 21:27:06 -05:00
/ * *
* An * * HDNodeWallet * * is a [ [ Signer ] ] backed by the private key derived
* from an HD Node using the [ [ link - bip - 32 ] ] stantard .
*
* An HD Node forms a hierarchal structure with each HD Node having a
* private key and the ability to derive child HD Nodes , defined by
* a path indicating the index of each child .
* /
2022-09-05 16:57:11 -04:00
class HDNodeWallet extends base _wallet _js _1 . BaseWallet {
2022-12-02 21:27:06 -05:00
/ * *
* The compressed public key .
* /
2022-09-05 16:57:11 -04:00
publicKey ;
2022-12-02 21:27:06 -05:00
/ * *
* The fingerprint .
*
* A fingerprint allows quick qay to detect parent and child nodes ,
* but developers should be prepared to deal with collisions as it
* is only 4 bytes .
* /
2022-09-05 16:57:11 -04:00
fingerprint ;
2022-12-02 21:27:06 -05:00
/ * *
* The parent fingerprint .
* /
2022-09-05 16:57:11 -04:00
parentFingerprint ;
2022-12-02 21:27:06 -05:00
/ * *
* The mnemonic used to create this HD Node , if available .
*
* Sources such as extended keys do not encode the mnemonic , in
* which case this will be ` ` null ` ` .
* /
2022-09-05 16:57:11 -04:00
mnemonic ;
2022-12-02 21:27:06 -05:00
/ * *
* The chaincode , which is effectively a public key used
* to derive children .
* /
2022-09-05 16:57:11 -04:00
chainCode ;
2022-12-02 21:27:06 -05:00
/ * *
* The derivation path of this wallet .
*
* Since extended keys do not provider full path details , this
* may be ` ` null ` ` , if instantiated from a source that does not
* enocde it .
* /
2022-09-05 16:57:11 -04:00
path ;
2022-12-02 21:27:06 -05:00
/ * *
* The child index of this wallet . Values over ` ` 2 * \ * 31 ` ` indicate
* the node is hardened .
* /
2022-09-05 16:57:11 -04:00
index ;
2022-12-02 21:27:06 -05:00
/ * *
* The depth of this wallet , which is the number of components
* in its path .
* /
2022-09-05 16:57:11 -04:00
depth ;
2022-11-30 15:44:23 -05:00
/ * *
* @ private
* /
2022-09-05 16:57:11 -04:00
constructor ( guard , signingKey , parentFingerprint , chainCode , path , index , depth , mnemonic , provider ) {
super ( signingKey , provider ) ;
2022-09-15 22:58:45 -04:00
( 0 , index _js _4 . assertPrivate ) ( guard , _guard , "HDNodeWallet" ) ;
2022-09-05 16:57:11 -04:00
( 0 , index _js _4 . defineProperties ) ( this , { publicKey : signingKey . compressedPublicKey } ) ;
const fingerprint = ( 0 , index _js _4 . dataSlice ) ( ( 0 , index _js _1 . ripemd160 ) ( ( 0 , index _js _1 . sha256 ) ( this . publicKey ) ) , 0 , 4 ) ;
( 0 , index _js _4 . defineProperties ) ( this , {
parentFingerprint , fingerprint ,
chainCode , path , index , depth
} ) ;
( 0 , index _js _4 . defineProperties ) ( this , { mnemonic } ) ;
}
connect ( provider ) {
return new HDNodeWallet ( _guard , this . signingKey , this . parentFingerprint , this . chainCode , this . path , this . index , this . depth , this . mnemonic , provider ) ;
}
2022-11-30 15:44:23 -05:00
# account ( ) {
const account = { address : this . address , privateKey : this . privateKey } ;
const m = this . mnemonic ;
if ( this . path && m && m . wordlist . locale === "en" && m . password === "" ) {
account . mnemonic = {
path : this . path ,
locale : "en" ,
entropy : m . entropy
} ;
}
return account ;
}
/ * *
* Resolves to a [ JSON Keystore Wallet ] ( json - wallets ) encrypted with
* % % password % % .
*
* If % % progressCallback % % is specified , it will receive periodic
* updates as the encryption process progreses .
* /
async encrypt ( password , progressCallback ) {
return await ( 0 , json _keystore _js _1 . encryptKeystoreJson ) ( this . # account ( ) , password , { progressCallback } ) ;
}
/ * *
* Returns a [ JSON Keystore Wallet ] ( json - wallets ) encryped with
* % % password % % .
*
* It is preferred to use the [ async version ] ( encrypt ) instead ,
* which allows a [ [ ProgressCallback ] ] to keep the user informed .
*
* This method will block the event loop ( freezing all UI ) until
* it is complete , which may be a non - trivial duration .
* /
encryptSync ( password ) {
return ( 0 , json _keystore _js _1 . encryptKeystoreJsonSync ) ( this . # account ( ) , password ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* The extended key .
*
* This key will begin with the prefix ` ` xpriv ` ` and can be used to
* reconstruct this HD Node to derive its children .
* /
2022-09-05 16:57:11 -04:00
get extendedKey ( ) {
// We only support the mainnet values for now, but if anyone needs
// testnet values, let me know. I believe current sentiment is that
// we should always use mainnet, and use BIP-44 to derive the network
// - Mainnet: public=0x0488B21E, private=0x0488ADE4
// - Testnet: public=0x043587CF, private=0x04358394
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assert ) ( this . depth < 256 , "Depth too deep" , "UNSUPPORTED_OPERATION" , { operation : "extendedKey" } ) ;
2022-09-05 16:57:11 -04:00
return encodeBase58Check ( ( 0 , index _js _4 . concat ) ( [
"0x0488ADE4" , zpad ( this . depth , 1 ) , this . parentFingerprint ,
zpad ( this . index , 4 ) , this . chainCode ,
( 0 , index _js _4 . concat ) ( [ "0x00" , this . privateKey ] )
] ) ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Returns true if this wallet has a path , providing a Type Guard
* that the path is non - null .
* /
2022-09-05 16:57:11 -04:00
hasPath ( ) { return ( this . path != null ) ; }
2022-12-02 21:27:06 -05:00
/ * *
* Returns a neutered HD Node , which removes the private details
* of an HD Node .
*
* A neutered node has no private key , but can be used to derive
* child addresses and other public data about the HD Node .
* /
2022-09-05 16:57:11 -04:00
neuter ( ) {
return new HDNodeVoidWallet ( _guard , this . address , this . publicKey , this . parentFingerprint , this . chainCode , this . path , this . index , this . depth , this . provider ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Return the child for % % index % % .
* /
2022-09-05 16:57:11 -04:00
deriveChild ( _index ) {
2022-09-15 22:58:45 -04:00
const index = ( 0 , index _js _4 . getNumber ) ( _index , "index" ) ;
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assertArgument ) ( index <= 0xffffffff , "invalid index" , "index" , index ) ;
2022-09-05 16:57:11 -04:00
// Base path
let path = this . path ;
if ( path ) {
path += "/" + ( index & ~ HardenedBit ) ;
if ( index & HardenedBit ) {
path += "'" ;
}
}
const { IR , IL } = ser _I ( index , this . chainCode , this . publicKey , this . privateKey ) ;
2022-12-09 18:24:58 -05:00
const ki = new index _js _1 . SigningKey ( ( 0 , index _js _4 . toBeHex ) ( ( ( 0 , index _js _4 . toBigInt ) ( IL ) + BigInt ( this . privateKey ) ) % N , 32 ) ) ;
2022-09-05 16:57:11 -04:00
return new HDNodeWallet ( _guard , ki , this . fingerprint , ( 0 , index _js _4 . hexlify ) ( IR ) , path , index , this . depth + 1 , this . mnemonic , this . provider ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Return the HDNode for % % path % % from this node .
* /
2022-09-05 16:57:11 -04:00
derivePath ( path ) {
return derivePath ( this , path ) ;
}
static # fromSeed ( _seed , mnemonic ) {
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assertArgument ) ( ( 0 , index _js _4 . isBytesLike ) ( _seed ) , "invalid seed" , "seed" , "[REDACTED]" ) ;
2022-09-15 22:58:45 -04:00
const seed = ( 0 , index _js _4 . getBytes ) ( _seed , "seed" ) ;
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assertArgument ) ( seed . length >= 16 && seed . length <= 64 , "invalid seed" , "seed" , "[REDACTED]" ) ;
2022-09-15 22:58:45 -04:00
const I = ( 0 , index _js _4 . getBytes ) ( ( 0 , index _js _1 . computeHmac ) ( "sha512" , MasterSecret , seed ) ) ;
2022-09-05 16:57:11 -04:00
const signingKey = new index _js _1 . SigningKey ( ( 0 , index _js _4 . hexlify ) ( I . slice ( 0 , 32 ) ) ) ;
return new HDNodeWallet ( _guard , signingKey , "0x00000000" , ( 0 , index _js _4 . hexlify ) ( I . slice ( 32 ) ) , "m" , 0 , 0 , mnemonic , null ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Creates a new HD Node from % % extendedKey % % .
*
* If the % % extendedKey % % will either have a prefix or ` ` xpub ` ` or
* ` ` xpriv ` ` , returning a neutered HD Node ( [ [ HDNodeVoidWallet ] ] )
* or full HD Node ( [ [ HDNodeWallet ) respectively .
* /
2022-09-05 16:57:11 -04:00
static fromExtendedKey ( extendedKey ) {
2022-12-09 18:24:58 -05:00
const bytes = ( 0 , index _js _4 . toBeArray ) ( ( 0 , index _js _4 . decodeBase58 ) ( extendedKey ) ) ; // @TODO: redact
2022-11-09 02:57:02 -05:00
( 0 , index _js _4 . assertArgument ) ( bytes . length === 82 || encodeBase58Check ( bytes . slice ( 0 , 78 ) ) === extendedKey , "invalid extended key" , "extendedKey" , "[ REDACTED ]" ) ;
2022-09-05 16:57:11 -04:00
const depth = bytes [ 4 ] ;
const parentFingerprint = ( 0 , index _js _4 . hexlify ) ( bytes . slice ( 5 , 9 ) ) ;
const index = parseInt ( ( 0 , index _js _4 . hexlify ) ( bytes . slice ( 9 , 13 ) ) . substring ( 2 ) , 16 ) ;
const chainCode = ( 0 , index _js _4 . hexlify ) ( bytes . slice ( 13 , 45 ) ) ;
const key = bytes . slice ( 45 , 78 ) ;
switch ( ( 0 , index _js _4 . hexlify ) ( bytes . slice ( 0 , 4 ) ) ) {
// Public Key
case "0x0488b21e" :
case "0x043587cf" : {
const publicKey = ( 0 , index _js _4 . hexlify ) ( key ) ;
return new HDNodeVoidWallet ( _guard , ( 0 , index _js _3 . computeAddress ) ( publicKey ) , publicKey , parentFingerprint , chainCode , null , index , depth , null ) ;
}
// Private Key
case "0x0488ade4" :
case "0x04358394 " :
if ( key [ 0 ] !== 0 ) {
break ;
}
return new HDNodeWallet ( _guard , new index _js _1 . SigningKey ( key . slice ( 1 ) ) , parentFingerprint , chainCode , null , index , depth , null , null ) ;
}
2022-11-09 02:57:02 -05:00
( 0 , index _js _4 . assertArgument ) ( false , "invalid extended key prefix" , "extendedKey" , "[ REDACTED ]" ) ;
2022-09-05 16:57:11 -04:00
}
2022-12-02 21:27:06 -05:00
/ * *
* Creates a new random HDNode .
* /
2022-11-10 04:05:51 -05:00
static createRandom ( password , path , wordlist ) {
if ( password == null ) {
password = "" ;
}
if ( path == null ) {
2022-09-05 16:57:11 -04:00
path = exports . defaultPath ;
}
2022-11-10 04:05:51 -05:00
if ( wordlist == null ) {
2022-11-30 15:44:23 -05:00
wordlist = lang _en _js _1 . LangEn . wordlist ( ) ;
2022-11-10 04:05:51 -05:00
}
2022-09-05 16:57:11 -04:00
const mnemonic = mnemonic _js _1 . Mnemonic . fromEntropy ( ( 0 , index _js _1 . randomBytes ) ( 16 ) , password , wordlist ) ;
return HDNodeWallet . # fromSeed ( mnemonic . computeSeed ( ) , mnemonic ) . derivePath ( path ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
2023-06-06 22:42:28 -04:00
* Create an HD Node from % % mnemonic % % .
2022-12-02 21:27:06 -05:00
* /
2022-11-10 04:05:51 -05:00
static fromMnemonic ( mnemonic , path ) {
if ( ! path ) {
path = exports . defaultPath ;
}
return HDNodeWallet . # fromSeed ( mnemonic . computeSeed ( ) , mnemonic ) . derivePath ( path ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Creates an HD Node from a mnemonic % % phrase % % .
* /
2022-11-10 04:05:51 -05:00
static fromPhrase ( phrase , password , path , wordlist ) {
if ( password == null ) {
password = "" ;
}
if ( path == null ) {
path = exports . defaultPath ;
}
if ( wordlist == null ) {
2022-11-30 15:44:23 -05:00
wordlist = lang _en _js _1 . LangEn . wordlist ( ) ;
2022-11-10 04:05:51 -05:00
}
const mnemonic = mnemonic _js _1 . Mnemonic . fromPhrase ( phrase , password , wordlist ) ;
return HDNodeWallet . # fromSeed ( mnemonic . computeSeed ( ) , mnemonic ) . derivePath ( path ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Creates an HD Node from a % % seed % % .
* /
2022-11-10 04:05:51 -05:00
static fromSeed ( seed ) {
return HDNodeWallet . # fromSeed ( seed , null ) ;
}
2022-09-05 16:57:11 -04:00
}
exports . HDNodeWallet = HDNodeWallet ;
2022-12-02 21:27:06 -05:00
/ * *
* A * * HDNodeVoidWallet * * cannot sign , but provides access to
* the children nodes of a [ [ link - bip - 32 ] ] HD wallet addresses .
*
* The can be created by using an extended ` ` xpub ` ` key to
* [ [ HDNodeWallet _fromExtendedKey ] ] or by
* [ nuetering ] ( HDNodeWallet - neuter ) a [ [ HDNodeWallet ] ] .
* /
2022-09-05 16:57:11 -04:00
class HDNodeVoidWallet extends index _js _2 . VoidSigner {
2022-12-02 21:27:06 -05:00
/ * *
* The compressed public key .
* /
2022-09-05 16:57:11 -04:00
publicKey ;
2022-12-02 21:27:06 -05:00
/ * *
* The fingerprint .
*
* A fingerprint allows quick qay to detect parent and child nodes ,
* but developers should be prepared to deal with collisions as it
* is only 4 bytes .
* /
2022-09-05 16:57:11 -04:00
fingerprint ;
2022-12-02 21:27:06 -05:00
/ * *
* The parent node fingerprint .
* /
2022-09-05 16:57:11 -04:00
parentFingerprint ;
2022-12-02 21:27:06 -05:00
/ * *
* The chaincode , which is effectively a public key used
* to derive children .
* /
2022-09-05 16:57:11 -04:00
chainCode ;
2022-12-02 21:27:06 -05:00
/ * *
* The derivation path of this wallet .
*
* Since extended keys do not provider full path details , this
* may be ` ` null ` ` , if instantiated from a source that does not
* enocde it .
* /
2022-09-05 16:57:11 -04:00
path ;
2022-12-02 21:27:06 -05:00
/ * *
* The child index of this wallet . Values over ` ` 2 * \ * 31 ` ` indicate
* the node is hardened .
* /
2022-09-05 16:57:11 -04:00
index ;
2022-12-02 21:27:06 -05:00
/ * *
* The depth of this wallet , which is the number of components
* in its path .
* /
2022-09-05 16:57:11 -04:00
depth ;
2022-11-30 15:44:23 -05:00
/ * *
* @ private
* /
2022-09-05 16:57:11 -04:00
constructor ( guard , address , publicKey , parentFingerprint , chainCode , path , index , depth , provider ) {
super ( address , provider ) ;
2022-09-15 22:58:45 -04:00
( 0 , index _js _4 . assertPrivate ) ( guard , _guard , "HDNodeVoidWallet" ) ;
2022-09-05 16:57:11 -04:00
( 0 , index _js _4 . defineProperties ) ( this , { publicKey } ) ;
const fingerprint = ( 0 , index _js _4 . dataSlice ) ( ( 0 , index _js _1 . ripemd160 ) ( ( 0 , index _js _1 . sha256 ) ( publicKey ) ) , 0 , 4 ) ;
( 0 , index _js _4 . defineProperties ) ( this , {
publicKey , fingerprint , parentFingerprint , chainCode , path , index , depth
} ) ;
}
connect ( provider ) {
return new HDNodeVoidWallet ( _guard , this . address , this . publicKey , this . parentFingerprint , this . chainCode , this . path , this . index , this . depth , provider ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* The extended key .
*
* This key will begin with the prefix ` ` xpub ` ` and can be used to
* reconstruct this neutered key to derive its children addresses .
* /
2022-09-05 16:57:11 -04:00
get extendedKey ( ) {
// We only support the mainnet values for now, but if anyone needs
// testnet values, let me know. I believe current sentiment is that
// we should always use mainnet, and use BIP-44 to derive the network
// - Mainnet: public=0x0488B21E, private=0x0488ADE4
// - Testnet: public=0x043587CF, private=0x04358394
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assert ) ( this . depth < 256 , "Depth too deep" , "UNSUPPORTED_OPERATION" , { operation : "extendedKey" } ) ;
2022-09-05 16:57:11 -04:00
return encodeBase58Check ( ( 0 , index _js _4 . concat ) ( [
"0x0488B21E" ,
zpad ( this . depth , 1 ) ,
this . parentFingerprint ,
zpad ( this . index , 4 ) ,
this . chainCode ,
this . publicKey ,
] ) ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Returns true if this wallet has a path , providing a Type Guard
* that the path is non - null .
* /
2022-09-05 16:57:11 -04:00
hasPath ( ) { return ( this . path != null ) ; }
2022-12-02 21:27:06 -05:00
/ * *
* Return the child for % % index % % .
* /
2022-09-05 16:57:11 -04:00
deriveChild ( _index ) {
2022-09-15 22:58:45 -04:00
const index = ( 0 , index _js _4 . getNumber ) ( _index , "index" ) ;
2022-11-09 06:22:17 -05:00
( 0 , index _js _4 . assertArgument ) ( index <= 0xffffffff , "invalid index" , "index" , index ) ;
2022-09-05 16:57:11 -04:00
// Base path
let path = this . path ;
if ( path ) {
path += "/" + ( index & ~ HardenedBit ) ;
if ( index & HardenedBit ) {
path += "'" ;
}
}
const { IR , IL } = ser _I ( index , this . chainCode , this . publicKey , null ) ;
2022-12-02 21:27:06 -05:00
const Ki = index _js _1 . SigningKey . addPoints ( IL , this . publicKey , true ) ;
2022-09-05 16:57:11 -04:00
const address = ( 0 , index _js _3 . computeAddress ) ( Ki ) ;
return new HDNodeVoidWallet ( _guard , address , Ki , this . fingerprint , ( 0 , index _js _4 . hexlify ) ( IR ) , path , index , this . depth + 1 , this . provider ) ;
}
2022-12-02 21:27:06 -05:00
/ * *
* Return the signer for % % path % % from this node .
* /
2022-09-05 16:57:11 -04:00
derivePath ( path ) {
return derivePath ( this , path ) ;
}
}
exports . HDNodeVoidWallet = HDNodeVoidWallet ;
2022-12-02 21:27:06 -05:00
/ *
export class HDNodeWalletManager {
# root : HDNodeWallet ;
constructor ( phrase : string , password ? : null | string , path ? : null | string , locale ? : null | Wordlist ) {
if ( password == null ) { password = "" ; }
if ( path == null ) { path = "m/44'/60'/0'/0" ; }
if ( locale == null ) { locale = LangEn . wordlist ( ) ; }
2022-09-05 16:57:11 -04:00
this . # root = HDNodeWallet . fromPhrase ( phrase , password , path , locale ) ;
}
2022-12-02 21:27:06 -05:00
getSigner ( index ? : number ) : HDNodeWallet {
return this . # root . deriveChild ( ( index == null ) ? 0 : index ) ;
2022-09-05 16:57:11 -04:00
}
}
2022-12-02 21:27:06 -05:00
* /
/ * *
2023-08-15 00:58:04 -04:00
* Returns the [ [ link - bip - 32 ] ] path for the account at % % index % % .
2022-12-02 21:27:06 -05:00
*
* This is the pattern used by wallets like Ledger .
*
* There is also an [ alternate pattern ] ( getIndexedAccountPath ) used by
* some software .
* /
2022-09-05 16:57:11 -04:00
function getAccountPath ( _index ) {
2022-09-15 22:58:45 -04:00
const index = ( 0 , index _js _4 . getNumber ) ( _index , "index" ) ;
2022-11-09 02:57:02 -05:00
( 0 , index _js _4 . assertArgument ) ( index >= 0 && index < HardenedBit , "invalid account index" , "index" , index ) ;
2022-09-05 16:57:11 -04:00
return ` m/44'/60'/ ${ index } '/0/0 ` ;
}
exports . getAccountPath = getAccountPath ;
2022-12-02 21:27:06 -05:00
/ * *
* Returns the path using an alternative pattern for deriving accounts ,
* at % % index % % .
*
* This derivation path uses the //index// component rather than the
* //account// component to derive sequential accounts.
*
* This is the pattern used by wallets like MetaMask .
* /
function getIndexedAccountPath ( _index ) {
const index = ( 0 , index _js _4 . getNumber ) ( _index , "index" ) ;
( 0 , index _js _4 . assertArgument ) ( index >= 0 && index < HardenedBit , "invalid account index" , "index" , index ) ;
return ` m/44'/60'/0'/0/ ${ index } ` ;
}
exports . getIndexedAccountPath = getIndexedAccountPath ;
2022-09-05 16:57:11 -04:00
//# sourceMappingURL=hdwallet.js.map