packageDocumentation module import { bip39 , hdkey , getAddress , BN , Signature } from '@harmony-js/crypto' ; import { HDPath , isHttp , isWs , ChainID , ChainType , Unit , isHex , hexToNumber , } from '@harmony-js/utils' ; import { Messenger , HttpProvider , WSProvider , RPCMethod } from '@harmony-js/network' ; import { Transaction , TxStatus , TransasctionReceipt } from '@harmony-js/transaction' ; import { Account } from './account' ; hidden export interface WalletsInterfaces { [ key ] : Account ; } hidden export interface Web3TxPrams { id ? : string ; from ? : string ; to ? : string ; nonce ? : number | string ; gasLimit ? : BN | number | string ; gasPrice ? : BN | number | string ; shardID ? : number | string ; toShardID ? : number | string ; data ? : string ; value ? : BN ; chainId ? : number ; rawTransaction ? : string ; unsignedRawTransaction ? : string ; signature ? : Signature | string ; receipt ? : TransasctionReceipt ; } export class HDNode { static isValidMnemonic ( phrase ) { if ( phrase . trim ( ) . split ( /\s+/g ) . length < 12 ) { return false ; } return bip39 . validateMnemonic ( phrase ) ; } static generateMnemonic ( ) { return bip39 . generateMnemonic ( ) ; } public provider : HttpProvider | WSProvider ; public gasLimit : string ; public gasPrice : string ; public messenger : Messenger ; hidden private shardID : number ; hidden private hdwallet : hdkey | undefined ; hidden private path : string ; hidden private index : number ; hidden private addressCount : number ; hidden private addresses : string [ ] ; hidden private wallets : WalletsInterfaces ; constructor ( provider = 'http://localhost:9500' , menmonic ? , index = 0 , addressCount = 1 , shardID = 0 , chainType = ChainType . Harmony , chainId = ChainID . Default , gasLimit = '1000000' , gasPrice = '2000000000' ) { this . provider = this . setProvider ( provider ) ; this . shardID = shardID ; this . messenger = new Messenger ( this . provider , chainType , chainId ) ; this . messenger . setDefaultShardID ( this . shardID ) ; this . hdwallet = undefined ; this . addresses = [ ] ; this . wallets = { } ; this . path = chainType === ChainType . Harmony ? HDPath : `m/44'/60'/0'/0/` ; this . index = index ; this . addressCount = addressCount ; if ( menmonic !== null && menmonic !== '' ) { this . getHdWallet ( menmonic || HDNode . generateMnemonic ( ) ) ; } this . gasLimit = gasLimit ; this . gasPrice = gasPrice ; } normalizePrivateKeys ( mnemonic ) { if ( Array . isArray ( mnemonic ) ) { return mnemonic ; } else if ( mnemonic && ! mnemonic . includes ( ' ' ) ) { return [ mnemonic ] ; } else { return false ; } } setProvider ( provider ) { if ( isHttp ( provider ) && typeof provider === 'string' ) { return new HttpProvider ( provider ) ; } else if ( provider instanceof HttpProvider ) { return provider ; } else if ( isWs ( provider ) && typeof provider === 'string' ) { return new WSProvider ( provider ) ; } else if ( provider instanceof WSProvider ) { return provider ; } else { throw new Error ( 'provider is not recognized' ) ; } } getHdWallet ( mnemonic ) { if ( ! HDNode . isValidMnemonic ( mnemonic ) ) { throw new Error ( 'Mnemonic invalid or undefined' ) ; } this . hdwallet = hdkey . fromMasterSeed ( bip39 . mnemonicToSeed ( mnemonic ) ) ; for ( let i = this . index ; i < this . index + this . addressCount ; i ++ ) { if ( ! this . hdwallet ) { throw new Error ( 'hdwallet is not found' ) ; } const childKey = this . hdwallet . derive ( `${ this . path }${ i }` ) ; const prv = childKey . privateKey . toString ( 'hex' ) ; const account = new Account ( prv ) ; const addr = account . checksumAddress ; this . addresses . push ( addr ) ; this . wallets [ addr ] = account ; } } getAccounts ( cb ? ) { if ( cb ) { cb ( null , this . addresses ) ; } return this . addresses ; } getPrivateKey ( address , cb ? ) { if ( ! cb ) { if ( ! this . wallets [ address ] ) { throw new Error ( 'Account not found' ) ; } else { return this . wallets [ address ] . privateKey ; } } if ( ! this . wallets [ address ] ) { return cb ( 'Account not found' ) ; } else { cb ( null , this . wallets [ address ] . privateKey ) ; } } async signTransaction ( txParams ) { const from = txParams . from ? getAddress ( txParams . from ) . checksum : '0x' ; const accountNonce = await this . messenger . send ( RPCMethod . GetAccountNonce , [ from , 'latest' ] , 'hmy' , this . shardID ) ; const to = txParams . to ? getAddress ( txParams . to ) . checksum : '0x' ; let gasLimit = new Unit ( '0' ) . asWei ( ) . toWei ( ) ; if ( txParams . gas !== undefined && isHex ( txParams . gas ) ) { gasLimit = new Unit ( txParams . gas ) . asWei ( ) . toWei ( ) . lt ( new Unit ( this . gasLimit ) . asWei ( ) . toWei ( ) ) ? new Unit ( txParams . gas ) . asWei ( ) . toWei ( ) : new Unit ( this . gasLimit ) . asWei ( ) . toWei ( ) ; } if ( txParams . gasLimit !== undefined && isHex ( txParams . gasLimit ) ) { gasLimit = new Unit ( txParams . gasLimit ) . asWei ( ) . toWei ( ) . lt ( new Unit ( this . gasLimit ) . asWei ( ) . toWei ( ) ) ? new Unit ( txParams . gasLimit ) . asWei ( ) . toWei ( ) : new Unit ( this . gasLimit ) . asWei ( ) . toWei ( ) ; } let gasPrice = new Unit ( '0' ) . asWei ( ) . toWei ( ) ; if ( txParams . gasPrice !== undefined && isHex ( txParams . gasPrice ) ) { gasPrice = new Unit ( txParams . gasPrice ) . asWei ( ) . toWei ( ) . lt ( new Unit ( this . gasPrice ) . asWei ( ) . toWei ( ) ) ? new Unit ( txParams . gasPrice ) . asWei ( ) . toWei ( ) : new Unit ( this . gasPrice ) . asWei ( ) . toWei ( ) ; } const value = txParams . value !== undefined && isHex ( txParams . value ) ? txParams . value : '0' ; const nonce = txParams . nonce !== undefined && isHex ( txParams . nonce ) ? Number . parseInt ( hexToNumber ( txParams . nonce ) , 10 ) : accountNonce . result ; const data = txParams . data !== undefined && isHex ( txParams . data ) ? txParams . data : '0x' ; const prv = this . wallets [ from ] . privateKey ; const signerAccount = new Account ( prv , this . messenger ) ; const tx = new Transaction ( { ... txParams , from , to , gasLimit , gasPrice , value , nonce , data , shardID : this . shardID , chainId : this . messenger . chainId , } , this . messenger , TxStatus . INTIALIZED ) ; const signed = await signerAccount . signTransaction ( tx ) ; return signed . getRawTransaction ( ) ; } getAddress ( idx ? ) { if ( ! idx ) { return this . addresses [ 0 ] ; } else { return this . addresses [ idx ] ; } } getAddresses ( ) { return this . addresses ; } addByPrivateKey ( privateKey ) { const account = new Account ( privateKey ) ; const addr = account . checksumAddress ; this . addresses . push ( addr ) ; this . wallets [ addr ] = account ; return addr ; } setSigner ( address ) { const foundIndex = this . addresses . findIndex ( ( value ) => value === address ) ; this . addresses . splice ( foundIndex , 1 ) ; this . addresses . unshift ( address ) ; } }