'use strict' ;
import Base58 from '../deps/Base58.js'
import { Sha256 , Sha512 } from 'asmcrypto.js'
import jsSHA from "jssha" ;
import RIPEMD160 from '../deps/ripemd160.js'
import utils from '../deps/utils.js'
import { EllipticCurve , BigInteger } from './ecbn.js' ;
export default class AltcoinHDWallet {
constructor ( addressParams ) {
/ * *
* Seed - 32 bytes
* /
this . seed = new Uint8Array ( 32 )
/ * *
* Version Bytes - 4 byte
* /
this . versionBytes = addressParams
/ * *
* Depth - 1 byte
* /
this . depth = 0
/ * *
* Parent Fingerprint - 4 bytes
* /
this . parentFingerprint = '0x00000000' // master key
/ * *
* Child Index - 4 bytes
* /
this . childIndex = '0x00000000' // master key
/ * *
* Chain Code - 32 bytes
* /
this . chainCode = new Uint8Array ( 32 )
/ * *
* Key Data - 33 bytes
* /
this . keyData = new Uint8Array ( 33 )
/ * *
* Seed Hash - 64 bytes
* /
this . seedHash = new Uint8Array ( 64 )
/ * *
* Private Key - 32 bytes
* /
this . privateKey = new Uint8Array ( 32 )
/ * *
* Public Key - 33 bytes ( compressed )
* /
this . publicKey = new Uint8Array ( 33 )
/ * *
* Public Key Hash160 ( used to derive the parent fingerprint for derived )
* /
this . publicKeyHash = new Uint8Array ( 20 )
/ * *
* Master Private Key ( Base58 encoded )
* /
this . masterPrivateKey = ''
/ * *
* Master Public Key ( Base58 encoded )
* /
this . masterPublicKey = ''
/ * *
* Testnet Master Private Key ( Base58 encoded ) - THIS IS TESTNET
* /
this . _tMasterPrivateKey = ''
/ * *
* Testnet Master Public Key ( Base58 encoded ) - THIS IS TESTNET
* /
this . _tmasterPublicKey = ''
/ * *
* Child Keys Derivation from the Parent Keys
* /
/ * *
* Child Private Key - 32 bytes
* /
this . childPrivateKey = new Uint8Array ( 32 )
/ * *
* Child Chain Code - 32 bytes
* /
this . childChainCode = new Uint8Array ( 32 )
/ * *
* Child Public Key - 33 bytes ( compressed )
* /
this . childPublicKey = new Uint8Array ( 33 )
/ * *
* Child Public Key Hash160 ( used to derive the parent fingerprint for derived )
* /
this . childPublicKeyHash = new Uint8Array ( 20 )
/ * *
* Extended Private Child Key - Base58 encoded
* /
this . xPrivateChildKey = ''
/ * *
* Extended Public Child Key - Base58 encoded
* /
this . xPublicChildKey = ''
/ * *
* Grand Child Keys Derivation from the Child Keys
* /
/ * *
* Grand Child Private Key - 32 bytes
* /
this . grandChildPrivateKey = new Uint8Array ( 32 )
/ * *
* Grand Child Chain Code - 32 bytes
* /
this . grandChildChainCode = new Uint8Array ( 32 )
/ * *
* Grand Child Public Key - 33 bytes ( compressed )
* /
this . grandChildPublicKey = new Uint8Array ( 33 )
/ * *
* Grand Public Key Hash160 ( used to derive the parent fingerprint for derived )
* /
this . grandChildPublicKeyHash = new Uint8Array ( 20 )
/ * *
* Extended Private Grand Child Key - Base58 encoded
* /
this . xPrivateGrandChildKey = ''
/ * *
* Extended Public Grand Child Key - Base58 encoded
* /
this . xPublicGrandChildKey = ''
/ * *
* Litecoin Legacy Address - Derived from the Grand Child Public Key Hash
* /
this . litecoinLegacyAddress = ''
/ * *
* TESTNET Litecoin Legacy Address ( Derived from the Grand Child Public Key Hash ) - THIS IS TESTNET
* /
this . _tlitecoinLegacyAddress = ''
/ * *
* Wallet - Wallet Object ( keys ... )
* /
this . wallet = { }
}
setSeed ( seed ) {
this . seed = seed
}
createWallet ( seed , isBIP44 , indicator = null ) {
// Set Seeed
this . setSeed ( seed )
// Generate Seed Hash
this . generateSeedHash ( this . seed , isBIP44 , indicator )
// Generate Private Key
this . generatePrivateKey ( this . seedHash )
// Generate Chain Code
this . generateChainCode ( this . seedHash )
// Generate Public Key from Private Key
this . generatePublicKey ( this . privateKey )
// Generate Mainnet Master Private Key
this . generateMainnetMasterPrivateKey ( )
// Generate Mainnet Master Public Key
this . generateMainnetMasterPublicKey ( )
// Generate Testnet Master Private Key
this . generateTestnetMasterPrivateKey ( )
// Generate Testnet Master Public Key
this . generateTestnetMasterPublicKey ( )
// Generate Child and Grand Child Keys
this . generateDerivedChildKeys ( )
// Return Wallet Object Specification
return this . returnWallet ( )
}
generateSeedHash ( seed , isBIP44 , indicator = null ) {
let buffer ;
if ( isBIP44 ) {
buffer = utils . appendBuffer ( seed . reverse ( ) , utils . int32ToBytes ( indicator ) )
} else {
if ( indicator !== null ) {
const indicatorString = utils . stringtoUTF8Array ( indicator ) ;
buffer = utils . appendBuffer ( seed . reverse ( ) , indicatorString ) ;
}
else
{
buffer = seed . reverse ( ) ;
}
}
const _reverseSeedHash = new Sha256 ( ) . process ( buffer ) . finish ( ) . result ;
this . seedHash = new Sha512 ( ) . process ( utils . appendBuffer ( seed , _reverseSeedHash ) ) . finish ( ) . result ;
}
generatePrivateKey ( seedHash ) {
const SECP256K1 _CURVE _ORDER = new BigInteger ( "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141" ) ;
const privateKeyHash = seedHash . slice ( 0 , 32 ) ;
const _privateKeyHash = [ ... privateKeyHash ]
let privateKeyBigInt = BigInteger . fromByteArrayUnsigned ( _privateKeyHash ) ;
const privateKey = ( privateKeyBigInt . mod ( SECP256K1 _CURVE _ORDER . subtract ( BigInteger . ONE ) ) ) . add ( BigInteger . ONE )
this . privateKey = privateKey . toByteArrayUnsigned ( )
}
generateChainCode ( seedHash ) {
this . chainCode = new Sha256 ( ) . process ( seedHash . slice ( 32 , 64 ) ) . finish ( ) . result ;
}
generatePublicKey ( privateKey ) {
const _privateKey = [ ... privateKey ]
const privateKeyBigInt = BigInteger . fromByteArrayUnsigned ( _privateKey ) ;
const epCurve = EllipticCurve . getSECCurveByName ( "secp256k1" ) ;
const curvePoints = epCurve . getG ( ) . multiply ( privateKeyBigInt ) ;
const x = curvePoints . getX ( ) . toBigInteger ( ) ;
const y = curvePoints . getY ( ) . toBigInteger ( ) ;
/ * *
* Deriving Uncompressed Public Key ( 65 bytes )
*
* const publicKeyBytes = EllipticCurve . integerToBytes ( x , 32 ) ;
* this . publicKey = publicKeyBytes . concat ( EllipticCurve . integerToBytes ( y , 32 ) ) ;
* this . publicKey . unshift ( 0x04 ) ; // append point indicator
* /
// Compressed Public Key (33 bytes)
this . publicKey = EllipticCurve . integerToBytes ( x , 32 )
if ( y . isEven ( ) ) {
this . publicKey . unshift ( 0x02 ) // append point indicator
} else {
this . publicKey . unshift ( 0x03 ) // append point indicator
}
// PublicKey Hash
const publicKeySHA256 = new Sha256 ( ) . process ( new Uint8Array ( this . publicKey ) ) . finish ( ) . result
const _publicKeyHash = new RIPEMD160 ( ) . update ( Buffer . from ( publicKeySHA256 ) ) . digest ( 'hex' )
this . publicKeyHash = _publicKeyHash
}
generateMainnetMasterPrivateKey ( ) {
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . mainnet . private ) ) )
// Append Depth
s . push ( this . depth )
// Append Parent Fingerprint
s . push ( ... ( utils . int32ToBytes ( this . parentFingerprint ) ) )
// Append Child Number
s . push ( ... ( utils . int32ToBytes ( this . childIndex ) ) )
// Append Chain Code
s . push ( ... this . chainCode )
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s . push ( 0 )
//if the private key length is less than 32 let's add leading zeros
if ( this . privateKey . length < 32 ) {
for ( let i = this . privateKey . length ; i < 32 ; i ++ ) {
s . push ( 0 )
}
}
// Append Private Key
s . push ( ... this . privateKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this . masterPrivateKey = Base58 . encode ( s )
}
generateMainnetMasterPublicKey ( ) {
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . mainnet . public ) ) )
// Append Depth
s . push ( this . depth )
// Append Parent Fingerprint
s . push ( ... ( utils . int32ToBytes ( this . parentFingerprint ) ) )
// Append Child Number
s . push ( ... ( utils . int32ToBytes ( this . childIndex ) ) )
// Append Chain Code
s . push ( ... this . chainCode )
// Append Public Key
s . push ( ... this . publicKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Public Key as Base58 encoded
this . masterPublicKey = Base58 . encode ( s )
}
generateTestnetMasterPrivateKey ( ) {
// To be Used ONLY in Testnet...
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . testnet . private ) ) )
// Append Depth
s . push ( this . depth )
// Append Parent Fingerprint
s . push ( ... ( utils . int32ToBytes ( this . parentFingerprint ) ) )
// Append Child Number
s . push ( ... ( utils . int32ToBytes ( this . childIndex ) ) )
// Append Chain Code
s . push ( ... this . chainCode )
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s . push ( 0 )
// Append Private Key
s . push ( ... this . privateKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this . _tMasterPrivateKey = Base58 . encode ( s )
}
generateTestnetMasterPublicKey ( ) {
// To be Used ONLY in Testnet...
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . testnet . public ) ) )
// Append Depth
s . push ( this . depth )
// Append Parent Fingerprint
s . push ( ... ( utils . int32ToBytes ( this . parentFingerprint ) ) )
// Append Child Number
s . push ( ... ( utils . int32ToBytes ( this . childIndex ) ) )
// Append Chain Code
s . push ( ... this . chainCode )
// Append Private Key
s . push ( ... this . publicKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this . _tmasterPublicKey = Base58 . encode ( s )
}
generateDerivedChildKeys ( ) {
// SPEC INFO: https://en.bitcoin.it/wiki/BIP_0032#Child_key_derivation_.28CKD.29_functions
// NOTE: will not be using some of derivations func as the value is known. (So I'd rather shove in the values and rewrite out the derivations later ?)
// NOTE: I "re-wrote" and "reduplicate" the code for child and grandChild keys derivations inorder to get the child and grandchild from the child
// TODO: Make this more better in the future
const path = 'm/0/0'
// let p = path.split('/');
// Get Public kEY
const derivePublicChildKey = ( ) => {
const _privateKey = [ ... this . childPrivateKey ]
const privateKeyBigInt = BigInteger . fromByteArrayUnsigned ( _privateKey ) ;
const epCurve = EllipticCurve . getSECCurveByName ( "secp256k1" ) ;
const curvePoints = epCurve . getG ( ) . multiply ( privateKeyBigInt ) ;
const x = curvePoints . getX ( ) . toBigInteger ( ) ;
const y = curvePoints . getY ( ) . toBigInteger ( ) ;
// Compressed Public Key (33 bytes)
this . childPublicKey = EllipticCurve . integerToBytes ( x , 32 )
if ( y . isEven ( ) ) {
this . childPublicKey . unshift ( 0x02 ) // append point indicator
} else {
this . childPublicKey . unshift ( 0x03 ) // append point indicator
}
// PublicKey Hash
const childPublicKeySHA256 = new Sha256 ( ) . process ( new Uint8Array ( this . childPublicKey ) ) . finish ( ) . result
const _childPublicKeyHash = new RIPEMD160 ( ) . update ( Buffer . from ( childPublicKeySHA256 ) ) . digest ( 'hex' )
this . childPublicKeyHash = _childPublicKeyHash
// Call deriveExtendedPublicChildKey // WIll be hardcoding the values...
deriveExtendedPublicChildKey ( 1 , 0 )
}
const derivePrivateChildKey = ( cI ) => {
let ib = [ ] ;
ib . push ( ( cI >> 24 ) & 0xff ) ;
ib . push ( ( cI >> 16 ) & 0xff ) ;
ib . push ( ( cI >> 8 ) & 0xff ) ;
ib . push ( cI & 0xff ) ;
const s = [ ... this . publicKey ] . concat ( ib ) ;
const _hmacSha512 = new jsSHA ( "SHA-512" , "UINT8ARRAY" , { numRounds : 1 , hmacKey : { value : this . chainCode , format : "UINT8ARRAY" } } ) ;
_hmacSha512 . update ( new Uint8Array ( s ) )
const IL = BigInteger . fromByteArrayUnsigned ( [ ... _hmacSha512 . getHMAC ( 'UINT8ARRAY' ) . slice ( 0 , 32 ) ] )
this . childChainCode = _hmacSha512 . getHMAC ( 'UINT8ARRAY' ) . slice ( 32 , 64 ) // IR according to the SPEC
// SECP256k1 init
const epCurve = EllipticCurve . getSECCurveByName ( "secp256k1" ) ;
const ki = IL . add ( BigInteger . fromByteArrayUnsigned ( this . privateKey ) ) . mod ( epCurve . getN ( ) ) ; // parse256(IL) + kpar (mod n) ==> ki
this . childPrivateKey = ki . toByteArrayUnsigned ( )
// Call deriveExtendedPrivateChildKey
deriveExtendedPrivateChildKey ( 1 , 0 )
}
const deriveExtendedPrivateChildKey = ( i , childIndex ) => {
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . mainnet . private ) ) )
// Append Depth (using the index as depth)
i = parseInt ( i )
s . push ( i )
// Append Parent Fingerprint
s . push ( ... ( this . publicKeyHash . slice ( 0 , 4 ) ) )
// Append Child Index
s . push ( childIndex >>> 24 ) ;
s . push ( ( childIndex >>> 16 ) & 0xff ) ;
s . push ( ( childIndex >>> 8 ) & 0xff ) ;
s . push ( childIndex & 0xff ) ;
// Append Chain Code
s . push ( ... this . childChainCode )
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s . push ( 0 )
// Append Private Key
s . push ( ... this . childPrivateKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this . xPrivateChildKey = Base58 . encode ( s )
}
const deriveExtendedPublicChildKey = ( i , childIndex ) => {
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . mainnet . public ) ) )
// Append Depth
i = parseInt ( i )
s . push ( i )
// Append Parent Fingerprint
s . push ( ... ( this . publicKeyHash . slice ( 0 , 4 ) ) )
// Append Child Index
s . push ( childIndex >>> 24 ) ;
s . push ( ( childIndex >>> 16 ) & 0xff ) ;
s . push ( ( childIndex >>> 8 ) & 0xff ) ;
s . push ( childIndex & 0xff ) ;
// Append Chain Code
s . push ( ... this . childChainCode )
// Append Public Key
s . push ( ... this . childPublicKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Public Key as Base58 encoded
this . xPublicChildKey = Base58 . encode ( s )
}
/ * *
* GRAND CHILD KEYS
*
* NOTE : I know this is not the best way to generate this ( even though it works the way it ought )
* Things to rewrite will be and not limited to deriving this through a for loop , removing hard code values , etc ...
* /
const derivePublicGrandChildKey = ( ) => {
const _privateKey = [ ... this . grandChildPrivateKey ]
const privateKeyBigInt = BigInteger . fromByteArrayUnsigned ( _privateKey ) ;
const epCurve = EllipticCurve . getSECCurveByName ( "secp256k1" ) ;
const curvePoints = epCurve . getG ( ) . multiply ( privateKeyBigInt ) ;
const x = curvePoints . getX ( ) . toBigInteger ( ) ;
const y = curvePoints . getY ( ) . toBigInteger ( ) ;
// Compressed Public Key (33 bytes)
this . grandChildPublicKey = EllipticCurve . integerToBytes ( x , 32 )
if ( y . isEven ( ) ) {
this . grandChildPublicKey . unshift ( 0x02 ) // append point indicator
} else {
this . grandChildPublicKey . unshift ( 0x03 ) // append point indicator
}
// PublicKey Hash
const grandChildPublicKeySHA256 = new Sha256 ( ) . process ( new Uint8Array ( this . grandChildPublicKey ) ) . finish ( ) . result
const _grandChildPublicKeyHash = new RIPEMD160 ( ) . update ( Buffer . from ( grandChildPublicKeySHA256 ) ) . digest ( 'hex' )
this . grandChildPublicKeyHash = _grandChildPublicKeyHash
// Call deriveExtendedPublicChildKey // WIll be hardcoding the values...
deriveExtendedPublicGrandChildKey ( 2 , 0 )
/ * *
* Derive Litecoin Legacy Address
* /
// Append Address Prefix
let prefix = [ this . versionBytes . mainnet . prefix ]
if ( 2 == this . versionBytes . mainnet . prefix . length ) {
prefix = [ this . versionBytes . mainnet . prefix [ 0 ] ]
prefix . push ( [ this . versionBytes . mainnet . prefix [ 1 ] ] )
}
const k = prefix . concat ( ... this . grandChildPublicKeyHash )
// Derive Checksum
const _addressCheckSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( new Uint8Array ( k ) ) . finish ( ) . result ) . finish ( ) . result
const addressCheckSum = _addressCheckSum . slice ( 0 , 4 )
// Append CheckSum
const _litecoinLegacyAddress = k . concat ( ... addressCheckSum )
// Convert to Base58
this . litecoinLegacyAddress = Base58 . encode ( _litecoinLegacyAddress )
/ * *
* Derive TESTNET Litecoin Legacy Address
* /
// Append Version Byte
const tK = [ this . versionBytes . testnet . prefix ] . concat ( ... this . grandChildPublicKeyHash )
// Derive Checksum
const _tAddressCheckSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( new Uint8Array ( tK ) ) . finish ( ) . result ) . finish ( ) . result
const tAddressCheckSum = _tAddressCheckSum . slice ( 0 , 4 )
// Append CheckSum
const _tlitecoinLegacyAddress = tK . concat ( ... tAddressCheckSum )
// Convert to Base58
this . _tlitecoinLegacyAddress = Base58 . encode ( _tlitecoinLegacyAddress )
}
const derivePrivateGrandChildKey = ( cI , i ) => {
let ib = [ ] ;
ib . push ( ( cI >> 24 ) & 0xff ) ;
ib . push ( ( cI >> 16 ) & 0xff ) ;
ib . push ( ( cI >> 8 ) & 0xff ) ;
ib . push ( cI & 0xff ) ;
const s = [ ... this . childPublicKey ] . concat ( ib ) ;
const _hmacSha512 = new jsSHA ( "SHA-512" , "UINT8ARRAY" , { numRounds : 1 , hmacKey : { value : this . childChainCode , format : "UINT8ARRAY" } } ) ;
_hmacSha512 . update ( new Uint8Array ( s ) )
const IL = BigInteger . fromByteArrayUnsigned ( [ ... _hmacSha512 . getHMAC ( 'UINT8ARRAY' ) . slice ( 0 , 32 ) ] )
this . grandChildChainCode = _hmacSha512 . getHMAC ( 'UINT8ARRAY' ) . slice ( 32 , 64 ) // IR according to the SPEC
// SECP256k1 init
const epCurve = EllipticCurve . getSECCurveByName ( "secp256k1" ) ;
const ki = IL . add ( BigInteger . fromByteArrayUnsigned ( this . childPrivateKey ) ) . mod ( epCurve . getN ( ) ) ; // parse256(IL) + kpar (mod n) ==> ki
this . grandChildPrivateKey = ki . toByteArrayUnsigned ( )
// Call deriveExtendedPrivateChildKey
deriveExtendedPrivateGrandChildKey ( 2 , 0 )
}
const deriveExtendedPrivateGrandChildKey = ( i , childIndex ) => {
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . mainnet . private ) ) )
// Append Depth (using the index as depth)
i = parseInt ( i )
s . push ( i )
// Append Parent Fingerprint
s . push ( ... ( this . childPublicKeyHash . slice ( 0 , 4 ) ) )
// Append Child Index
s . push ( childIndex >>> 24 ) ;
s . push ( ( childIndex >>> 16 ) & 0xff ) ;
s . push ( ( childIndex >>> 8 ) & 0xff ) ;
s . push ( childIndex & 0xff ) ;
// Append Chain Code
s . push ( ... this . grandChildChainCode )
// Append 1 byte '0x00' (to make the key data 33 bytes, DO THIS ONLY FOR PRIVATE KEYS )
s . push ( 0 )
// Append Private Key
s . push ( ... this . grandChildPrivateKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Private Key as Base58 encoded
this . xPrivateGrandChildKey = Base58 . encode ( s )
}
const deriveExtendedPublicGrandChildKey = ( i , childIndex ) => {
// Serialization Variable
const s = [ ]
// Append Version Byte
s . push ( ... ( utils . int32ToBytes ( this . versionBytes . mainnet . public ) ) )
// Append Depth
i = parseInt ( i )
s . push ( i )
// Append Parent Fingerprint
s . push ( ... ( this . childPublicKeyHash . slice ( 0 , 4 ) ) )
// Append Child Index
s . push ( childIndex >>> 24 ) ;
s . push ( ( childIndex >>> 16 ) & 0xff ) ;
s . push ( ( childIndex >>> 8 ) & 0xff ) ;
s . push ( childIndex & 0xff ) ;
// Append Chain Code
s . push ( ... this . grandChildChainCode )
// Append Public Key
s . push ( ... this . grandChildPublicKey )
// Generate CheckSum
const _s = new Uint8Array ( s )
const _checkSum = new Sha256 ( ) . process ( new Sha256 ( ) . process ( _s ) . finish ( ) . result ) . finish ( ) . result
const checkSum = _checkSum . slice ( 0 , 4 )
// Append CheckSum
s . push ( ... checkSum ) // And this brings us to the end of the serialization...
// Save to Public Key as Base58 encoded
this . xPublicGrandChildKey = Base58 . encode ( s )
}
// Hard Code value..
let childIndex = 0
// Call derivePrivateChildKey //Hard code value
derivePrivateChildKey ( childIndex )
// Call derivePublicChildKey
derivePublicChildKey ( )
// Call derivePrivateGrandChildKey // Hard Code value...
derivePrivateGrandChildKey ( 0 , 2 )
// Call derivePublicGrandChildKey
derivePublicGrandChildKey ( )
}
returnWallet ( ) {
// Will be limiting the exported Wallet Object to just the Master keys and Legacy Addresses
const wallet = {
derivedMasterPrivateKey : this . masterPrivateKey ,
derivedMasterPublicKey : this . masterPublicKey ,
_tDerivedMasterPrivateKey : this . _tMasterPrivateKey ,
_tDerivedmasterPublicKey : this . _tmasterPublicKey ,
// derivedPrivateChildKey: this.xPrivateChildKey,
// derivedPublicChildKey: this.xPublicChildKey,
// derivedPrivateGrandChildKey: this.xPrivateGrandChildKey,
// derivedPublicGrandChildKey: this.xPublicGrandChildKey,
address : this . litecoinLegacyAddress ,
_taddress : this . _tlitecoinLegacyAddress
}
this . wallet = wallet
return wallet
}
}