rename all libs from xxx.yyy to xxx-yyy
This commit is contained in:
		
							parent
							
								
									aff70d43f7
								
							
						
					
					
						commit
						07a88d9bc7
					
				
							
								
								
									
										280
									
								
								btc.js
									
									
									
									
									
								
							
							
						
						
									
										280
									
								
								btc.js
									
									
									
									
									
								
							| @ -3,148 +3,166 @@ | |||||||
| const axios = require('axios') | const axios = require('axios') | ||||||
| const HDNode = require('./utils/hdnode') | const HDNode = require('./utils/hdnode') | ||||||
| const bitcoinjs = require('bitcoinjs-lib') | const bitcoinjs = require('bitcoinjs-lib') | ||||||
| const Ticrypto = require('tic.crypto') | const Ticrypto = require('tic-crypto') | ||||||
| const BTC_NODE = require('./netConfig').BTC_NODE | const BTC_NODE = require('./netConfig').BTC_NODE | ||||||
| const BTC_NODE2 = require('./netConfig').BTC_NODE2 | const BTC_NODE2 = require('./netConfig').BTC_NODE2 | ||||||
| const BTC_TXFEE = 30 | const BTC_TXFEE = 30 | ||||||
| 
 | 
 | ||||||
| class BTC { | class BTC { | ||||||
|     constructor(privateKey){ |   constructor (privateKey) { | ||||||
|         if(!Ticrypto.isSeckey(privateKey)) throw new Error('Invalid PrivateKey') |     if (!Ticrypto.isSeckey(privateKey)) throw new Error('Invalid PrivateKey') | ||||||
|         var publicKey = Ticrypto.seckey2pubkey(privateKey) |     var publicKey = Ticrypto.seckey2pubkey(privateKey) | ||||||
|         Object.defineProperties(this,{ |     Object.defineProperties(this, { | ||||||
|             "privateKey" : { |       privateKey: { | ||||||
|                 enumerable : true, |         enumerable: true, | ||||||
|                 writable : false, |         writable: false, | ||||||
|                 value : privateKey |         value: privateKey | ||||||
|             }, |       }, | ||||||
|             "publicKey": { |       publicKey: { | ||||||
|                 enumerable : true, |         enumerable: true, | ||||||
|                 writable : false, |         writable: false, | ||||||
|                 value : Ticrypto.seckey2pubkey(privateKey,{coin:"BTC"}) |         value: Ticrypto.seckey2pubkey(privateKey, { coin: 'BTC' }) | ||||||
|             }, |       }, | ||||||
|             "address" : { |       address: { | ||||||
|                 enumerable : true, |         enumerable: true, | ||||||
|                 writable : false, |         writable: false, | ||||||
|                 value : Ticrypto.pubkey2address(publicKey,{coin:"BTC"})  |         value: Ticrypto.pubkey2address(publicKey, { coin: 'BTC' }) | ||||||
|             }, |       }, | ||||||
|             "url" : { |       url: { | ||||||
|                 enumerable : true, |         enumerable: true, | ||||||
|                 get: function() { return this._url }, |         get: function () { | ||||||
|                 set: function(url) { |           return this._url | ||||||
|                     if (typeof(url) !== 'string') { throw new Error('invalid url') } |         }, | ||||||
|                     this._url = url |         set: function (url) { | ||||||
|                 } |           if (typeof url !== 'string') { | ||||||
|             }, |             throw new Error('invalid url') | ||||||
|             "defaultGas":{ |           } | ||||||
|                 enumerable: true, |           this._url = url | ||||||
|                 get: function() { return this._defaultGasFee }, |  | ||||||
|                 set: function(value) { |  | ||||||
|                     if (typeof(value) !== 'number') { throw new Error('invalid defaultGasFee') } |  | ||||||
|                     this._defaultGasFee = value |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|         this._url = BTC_NODE |  | ||||||
|         this._defaultGasFee = BTC_TXFEE |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
|     static generateNewAccount(){ |  | ||||||
|         var mnemonic = Ticrypto.randomSecword() |  | ||||||
|         return Object.assign(new BTC(Ticrypto.secword2keypair(mnemonic, {coin:"BTC"}).seckey),{mnemonic : mnemonic}) |  | ||||||
|     } |  | ||||||
|     static fromMnemonic(mnemonic){ |  | ||||||
|         HDNode.isValidMnemonic(mnemonic) |  | ||||||
|         return Object.assign(new BTC(Ticrypto.secword2keypair(mnemonic, {coin:"BTC"}).seckey),{mnemonic:mnemonic}) |  | ||||||
|     } |  | ||||||
|     static async getBalance(address){ |  | ||||||
|         return (await axios.get(`${BTC_NODE}/addrs/${address}/balance`)).data.balance |  | ||||||
|     } |  | ||||||
|     static async getActions(address){ |  | ||||||
|         return (await axios.get(`${BTC_NODE}/addrs/${address}`)).data.txrefs |  | ||||||
|     } |  | ||||||
|     static async getUTXO(address){ |  | ||||||
|         // console.log(`${BTC_NODE2}/unspent?active=${address}`,`${BTC_NODE2}/unspent?active=${address}`)
 |  | ||||||
|         try { |  | ||||||
|             return (await axios.get(`${BTC_NODE2}/unspent?active=${address}`)).data.unspent_outputs |  | ||||||
|         } catch (error) { |  | ||||||
|             return null |  | ||||||
|         } |         } | ||||||
|     } |       }, | ||||||
|     static encrypt(data, key){ |       defaultGas: { | ||||||
|         if(!data || !key) throw new Error('Required Params Missing') |         enumerable: true, | ||||||
|         return Ticrypto.encrypt(data,key) |         get: function () { | ||||||
|     } |           return this._defaultGasFee | ||||||
|     static decrypt(data, key){ |         }, | ||||||
|         return Ticrypto.decrypt(data, key, {format:"json"})  //return null for wrong key
 |         set: function (value) { | ||||||
|     } |           if (typeof value !== 'number') { | ||||||
|     static isValidAddress(address){ |             throw new Error('invalid defaultGasFee') | ||||||
|         return address.length == 34 && address[0] == '1' |           } | ||||||
|     } |           this._defaultGasFee = value | ||||||
|     async sendTransaction(toAddress, amount, option = {gasFee : BTC_TXFEE}){ |  | ||||||
|         let set = bitcoinjs.ECPair.fromPrivateKey(Buffer.from(this.privateKey,'hex'))//导入私钥用于签名
 |  | ||||||
|         let txb = new bitcoinjs.TransactionBuilder()//初始化交易对象
 |  | ||||||
|         let tx = await BTC.getUTXO('1DEP8i3QJCsomS4BSMY2RpU1upv62aGvhD') |  | ||||||
|         if(!tx) return null |  | ||||||
|         var tot = 0//用于记录UTXO总量
 |  | ||||||
|         amount+=1e4//消费金额是转出金额加上10000的矿工费
 |  | ||||||
|         txb.setVersion(1)//设置交易版本号
 |  | ||||||
|         for(var i=0;i<tx.length;i++){   //将UTXO的相关信息依次填入交易体中
 |  | ||||||
|             txb.addInput(tx[i].tx_hash_big_endian, tx[i].tx_output_n) |  | ||||||
|             tot+=tx[i].value |  | ||||||
|         } |  | ||||||
|          |  | ||||||
|         txb.addOutput(toAddress, amount-1e4)//填入转出目标地址和对应的金额
 |  | ||||||
|         txb.addOutput(this.address, tot-amount) //填入找零地址,也就是原地址,并填入把找零金额
 |  | ||||||
|         for(var i=0;i<tx.length;i++){//对交易体中的UTXO依次签名
 |  | ||||||
|             txb.sign(i, set) |  | ||||||
|         } |  | ||||||
|         // let txBody = txb.buildIncomplete().toHex()
 |  | ||||||
|         let data = {tx : txb.buildIncomplete().toHex()} |  | ||||||
|         try { |  | ||||||
|             let res = await axios.post(`${BTC_NODE}/txs/push`,data) |  | ||||||
|             return res |  | ||||||
|         } catch (error) { |  | ||||||
|             return null |  | ||||||
|         } |         } | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     this._url = BTC_NODE | ||||||
|  |     this._defaultGasFee = BTC_TXFEE | ||||||
|  |   } | ||||||
|  |   static generateNewAccount () { | ||||||
|  |     var mnemonic = Ticrypto.randomSecword() | ||||||
|  |     return Object.assign( | ||||||
|  |       new BTC(Ticrypto.secword2keypair(mnemonic, { coin: 'BTC' }).seckey), | ||||||
|  |       { mnemonic: mnemonic } | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |   static fromMnemonic (mnemonic) { | ||||||
|  |     HDNode.isValidMnemonic(mnemonic) | ||||||
|  |     return Object.assign( | ||||||
|  |       new BTC(Ticrypto.secword2keypair(mnemonic, { coin: 'BTC' }).seckey), | ||||||
|  |       { mnemonic: mnemonic } | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |   static async getBalance (address) { | ||||||
|  |     return (await axios.get(`${BTC_NODE}/addrs/${address}/balance`)).data | ||||||
|  |       .balance | ||||||
|  |   } | ||||||
|  |   static async getActions (address) { | ||||||
|  |     return (await axios.get(`${BTC_NODE}/addrs/${address}`)).data.txrefs | ||||||
|  |   } | ||||||
|  |   static async getUTXO (address) { | ||||||
|  |     // console.log(`${BTC_NODE2}/unspent?active=${address}`,`${BTC_NODE2}/unspent?active=${address}`)
 | ||||||
|  |     try { | ||||||
|  |       return (await axios.get(`${BTC_NODE2}/unspent?active=${address}`)).data | ||||||
|  |         .unspent_outputs | ||||||
|  |     } catch (error) { | ||||||
|  |       return null | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   static encrypt (data, key) { | ||||||
|  |     if (!data || !key) throw new Error('Required Params Missing') | ||||||
|  |     return Ticrypto.encrypt(data, key) | ||||||
|  |   } | ||||||
|  |   static decrypt (data, key) { | ||||||
|  |     return Ticrypto.decrypt(data, key, { format: 'json' }) //return null for wrong key
 | ||||||
|  |   } | ||||||
|  |   static isValidAddress (address) { | ||||||
|  |     return address.length == 34 && address[0] == '1' | ||||||
|  |   } | ||||||
|  |   async sendTransaction (toAddress, amount, option = { gasFee: BTC_TXFEE }) { | ||||||
|  |     let set = bitcoinjs.ECPair.fromPrivateKey( | ||||||
|  |       Buffer.from(this.privateKey, 'hex') | ||||||
|  |     ) //导入私钥用于签名
 | ||||||
|  |     let txb = new bitcoinjs.TransactionBuilder() //初始化交易对象
 | ||||||
|  |     let tx = await BTC.getUTXO('1DEP8i3QJCsomS4BSMY2RpU1upv62aGvhD') | ||||||
|  |     if (!tx) return null | ||||||
|  |     var tot = 0 //用于记录UTXO总量
 | ||||||
|  |     amount += 1e4 //消费金额是转出金额加上10000的矿工费
 | ||||||
|  |     txb.setVersion(1) //设置交易版本号
 | ||||||
|  |     for (var i = 0; i < tx.length; i++) { | ||||||
|  |       //将UTXO的相关信息依次填入交易体中
 | ||||||
|  |       txb.addInput(tx[i].tx_hash_big_endian, tx[i].tx_output_n) | ||||||
|  |       tot += tx[i].value | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|  |     txb.addOutput(toAddress, amount - 1e4) //填入转出目标地址和对应的金额
 | ||||||
|  |     txb.addOutput(this.address, tot - amount) //填入找零地址,也就是原地址,并填入把找零金额
 | ||||||
|  |     for (var i = 0; i < tx.length; i++) { | ||||||
|  |       //对交易体中的UTXO依次签名
 | ||||||
|  |       txb.sign(i, set) | ||||||
|     } |     } | ||||||
|     // async sendTransaction(toAddress, amount, option = {gasFee : BTC_TXFEE}){
 |     // let txBody = txb.buildIncomplete().toHex()
 | ||||||
|     //     var privateKey = bitcore.PrivateKey(this.privateKey)
 |     let data = { tx: txb.buildIncomplete().toHex() } | ||||||
|     //     var ecdsa = new bitcore.crypto.ECDSA()
 |     try { | ||||||
|  |       let res = await axios.post(`${BTC_NODE}/txs/push`, data) | ||||||
|  |       return res | ||||||
|  |     } catch (error) { | ||||||
|  |       return null | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   // async sendTransaction(toAddress, amount, option = {gasFee : BTC_TXFEE}){
 | ||||||
|  |   //     var privateKey = bitcore.PrivateKey(this.privateKey)
 | ||||||
|  |   //     var ecdsa = new bitcore.crypto.ECDSA()
 | ||||||
| 
 | 
 | ||||||
|     //     var newtx = {
 |   //     var newtx = {
 | ||||||
|     //         inputs: [{addresses: [this.address]}],
 |   //         inputs: [{addresses: [this.address]}],
 | ||||||
|     //         outputs: [{addresses: [toAddress], value: amount}]
 |   //         outputs: [{addresses: [toAddress], value: amount}]
 | ||||||
|     //     }
 |   //     }
 | ||||||
|     //     try {
 |   //     try {
 | ||||||
|     //         var tmptx = (await axios.post('https://api.blockcypher.com/v1/btc/test3/txs/new',newtx)).data
 |   //         var tmptx = (await axios.post('https://api.blockcypher.com/v1/btc/test3/txs/new',newtx)).data
 | ||||||
|     //         tmptx.pubkeys = []
 |   //         tmptx.pubkeys = []
 | ||||||
|     //         tmptx.pubkeys.push(privateKey.toPublicKey().toString("hex"))
 |   //         tmptx.pubkeys.push(privateKey.toPublicKey().toString("hex"))
 | ||||||
|     //         ecdsa.hashbuf = bitcore.crypto.Hash.sha256(new Buffer(tmptx.tosign))
 |   //         ecdsa.hashbuf = bitcore.crypto.Hash.sha256(new Buffer(tmptx.tosign))
 | ||||||
|     //         ecdsa.privkey = privateKey
 |   //         ecdsa.privkey = privateKey
 | ||||||
|     //         ecdsa.pubkey = privateKey.toPublicKey()
 |   //         ecdsa.pubkey = privateKey.toPublicKey()
 | ||||||
|     //         ecdsa.deterministicK()
 |   //         ecdsa.deterministicK()
 | ||||||
|     //         let signatureExpected = ecdsa.sign()
 |   //         let signatureExpected = ecdsa.sign()
 | ||||||
|     //         tmptx.signatures = [Buffer.from(signatureExpected.sig.toDER()).toString('hex')]
 |   //         tmptx.signatures = [Buffer.from(signatureExpected.sig.toDER()).toString('hex')]
 | ||||||
|     //         let res = (await axios.post('https://api.blockcypher.com/v1/btc/test3/txs/send',tmptx)).data
 |   //         let res = (await axios.post('https://api.blockcypher.com/v1/btc/test3/txs/send',tmptx)).data
 | ||||||
|     //         return res
 |   //         return res
 | ||||||
|     //     } catch (error) {
 |   //     } catch (error) {
 | ||||||
|     //         return error.response.data
 |   //         return error.response.data
 | ||||||
|     //     }
 |   //     }
 | ||||||
|     // }       
 |   // }
 | ||||||
| 
 | 
 | ||||||
|     async getBalance(){ |   async getBalance () { | ||||||
|         return await BTC.getBalance(this.address) |     return await BTC.getBalance(this.address) | ||||||
|     } |   } | ||||||
|     async getActions(){ |   async getActions () { | ||||||
|         return await BTC.getActions(this.address) |     return await BTC.getActions(this.address) | ||||||
|     } |   } | ||||||
|     encrypt(key){ |   encrypt (key) { | ||||||
|         return BTC.encrypt(this,key) |     return BTC.encrypt(this, key) | ||||||
|     } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|     BTC |   BTC | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										875
									
								
								eth.js
									
									
									
									
									
								
							
							
						
						
									
										875
									
								
								eth.js
									
									
									
									
									
								
							| @ -2,460 +2,525 @@ | |||||||
| const eth = require('etherscan-api').init('E3ZFFAEMNN33KX4HHVUZ4KF8XY1FXMR4BI') | const eth = require('etherscan-api').init('E3ZFFAEMNN33KX4HHVUZ4KF8XY1FXMR4BI') | ||||||
| const secretStorage = require('./utils/secret-storage') | const secretStorage = require('./utils/secret-storage') | ||||||
| const SigningKey = require('./utils/signing-key.js') | const SigningKey = require('./utils/signing-key.js') | ||||||
| const Ticrypto = require('tic.crypto') | const Ticrypto = require('tic-crypto') | ||||||
| const HDNode = require('./utils/hdnode') | const HDNode = require('./utils/hdnode') | ||||||
| const utils = require('./util.js') | const utils = require('./util.js') | ||||||
| const axios = require('axios') | const axios = require('axios') | ||||||
| 
 | 
 | ||||||
| require('setimmediate') | require('setimmediate') | ||||||
| 
 | 
 | ||||||
| const GAS_UNIT_WEI = 1e18  //1wei
 | const GAS_UNIT_WEI = 1e18 //1wei
 | ||||||
| const GAS_UNIT_GWEI = 1e9  //1gwei = 1e9 wei
 | const GAS_UNIT_GWEI = 1e9 //1gwei = 1e9 wei
 | ||||||
| const GAS_Fee = 0.000021 | const GAS_Fee = 0.000021 | ||||||
| const GAS_Fee_ERC20 = 0.000060 | const GAS_Fee_ERC20 = 0.00006 | ||||||
| const GAS_LIMIT = 21000 | const GAS_LIMIT = 21000 | ||||||
| const GAS_LIMIT_ERC20 = 6e4 | const GAS_LIMIT_ERC20 = 6e4 | ||||||
| const defaultPath = "m/44'/60'/0'/0/0" | const defaultPath = "m/44'/60'/0'/0/0" | ||||||
| const ETH_NODE = require('./netConfig').ETH_NODE | const ETH_NODE = require('./netConfig').ETH_NODE | ||||||
| 
 | 
 | ||||||
| const transactionFields = [ | const transactionFields = [ | ||||||
|     {name: 'nonce',    maxLength: 32, }, |   { name: 'nonce', maxLength: 32 }, | ||||||
|     {name: 'gasPrice', maxLength: 32, }, |   { name: 'gasPrice', maxLength: 32 }, | ||||||
|     {name: 'gasLimit', maxLength: 32, }, |   { name: 'gasLimit', maxLength: 32 }, | ||||||
|     {name: 'to',          length: 20, }, |   { name: 'to', length: 20 }, | ||||||
|     {name: 'value',    maxLength: 32, }, |   { name: 'value', maxLength: 32 }, | ||||||
|     {name: 'data'}, |   { name: 'data' } | ||||||
| ] | ] | ||||||
| 
 | 
 | ||||||
| class ETH { | class ETH { | ||||||
|     constructor(privateKey){ |   constructor (privateKey) { | ||||||
|         if(privateKey.length == 64 && !(privateKey.split('x')[1] && privateKey.split('x')[0] === '0')) |     if ( | ||||||
|             privateKey = '0x'+privateKey |       privateKey.length == 64 && | ||||||
|         var signingKey = privateKey |       !(privateKey.split('x')[1] && privateKey.split('x')[0] === '0') | ||||||
|         if (!(privateKey instanceof SigningKey)) { |     ) | ||||||
|             signingKey = new SigningKey(privateKey) |       privateKey = '0x' + privateKey | ||||||
|  |     var signingKey = privateKey | ||||||
|  |     if (!(privateKey instanceof SigningKey)) { | ||||||
|  |       signingKey = new SigningKey(privateKey) | ||||||
|  |     } | ||||||
|  |     Object.defineProperties(this, { | ||||||
|  |       privateKey: { | ||||||
|  |         enumerable: true, | ||||||
|  |         writable: false, | ||||||
|  |         value: signingKey.privateKey | ||||||
|  |       }, | ||||||
|  |       address: { | ||||||
|  |         enumerable: true, | ||||||
|  |         writable: false, | ||||||
|  |         value: signingKey.address | ||||||
|  |       }, | ||||||
|  |       url: { | ||||||
|  |         enumerable: true, | ||||||
|  |         get: function () { | ||||||
|  |           return this._url | ||||||
|  |         }, | ||||||
|  |         set: function (url) { | ||||||
|  |           if (typeof url !== 'string') { | ||||||
|  |             throw new Error('invalid url') | ||||||
|  |           } | ||||||
|  |           this._url = url | ||||||
|         } |         } | ||||||
|         Object.defineProperties(this, { |       }, | ||||||
|             'privateKey' : { |       defaultGasFee: { | ||||||
|                 enumerable : true, |         enumerable: true, | ||||||
|                 writable : false, |         get: function () { | ||||||
|                 value : signingKey.privateKey |           return this._defaultGasFee | ||||||
|  |         }, | ||||||
|  |         set: function (value) { | ||||||
|  |           if (typeof value !== 'number') { | ||||||
|  |             throw new Error('invalid defaultGasFee') | ||||||
|  |           } | ||||||
|  |           this._defaultGasFee = value | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |     this._defaultGasFee = GAS_Fee | ||||||
|  |     this._url = ETH_NODE | ||||||
|  |   } | ||||||
|  |   static generateNewAccount (option = { path: defaultPath }) { | ||||||
|  |     //major path as default path >/0'/0/0
 | ||||||
|  |     var mnemonic = Ticrypto.randomSecword() | ||||||
|  |     return Object.assign(ETH.fromMnemonic(mnemonic, option), { | ||||||
|  |       mnemonic, | ||||||
|  |       mnemonic | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |   static fromMnemonic (mnemonic, option = { path: defaultPath }) { | ||||||
|  |     HDNode.isValidMnemonic(mnemonic) //check valid mnemonic,will throw Error if not valid
 | ||||||
|  |     let seed = HDNode.mnemonicToSeed(mnemonic) | ||||||
|  |     return new ETH(HDNode.fromSeed(seed).derivePath(option.path).privateKey) | ||||||
|  |   } | ||||||
|  |   static async getBalance (address) { | ||||||
|  |     if (!address) { | ||||||
|  |       throw new Error('Address is required') | ||||||
|  |     } | ||||||
|  |     let res = ( | ||||||
|  |       await axios.post(ETH_NODE, { | ||||||
|  |         jsonrpc: '2.0', | ||||||
|  |         method: 'eth_getBalance', | ||||||
|  |         params: [address, 'latest'], | ||||||
|  |         id: 1 | ||||||
|  |       }) | ||||||
|  |     ).data | ||||||
|  |     if (res) return parseInt(res.result) / 1e18 | ||||||
|  |     //1000000000000000000
 | ||||||
|  |     else return null | ||||||
|  |   } | ||||||
|  |   static async getActions (address) { | ||||||
|  |     let tx = await eth.account.txlist(address, 0, 'latast') | ||||||
|  |     if (tx && tx.message === 'OK') return tx.result | ||||||
|  |     else return [] | ||||||
|  |   } | ||||||
|  |   static fromEncryptedWallet (json, password, progressCallback) { | ||||||
|  |     if (progressCallback && typeof progressCallback !== 'function') { | ||||||
|  |       throw new Error('invalid callback') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return new Promise(function (resolve, reject) { | ||||||
|  |       if (secretStorage.isCrowdsaleWallet(json)) { | ||||||
|  |         try { | ||||||
|  |           var privateKey = secretStorage.decryptCrowdsale(json, password) | ||||||
|  |           resolve(new ETH(privateKey)) | ||||||
|  |         } catch (error) { | ||||||
|  |           reject(error) | ||||||
|  |         } | ||||||
|  |       } else if (secretStorage.isValidWallet(json)) { | ||||||
|  |         secretStorage | ||||||
|  |           .decrypt(json, password, progressCallback) | ||||||
|  |           .then( | ||||||
|  |             function (signingKey) { | ||||||
|  |               var wallet = new ETH(signingKey) | ||||||
|  |               if (signingKey.mnemonic && signingKey.path) { | ||||||
|  |                 utils.defineProperty(wallet, 'mnemonic', signingKey.mnemonic) | ||||||
|  |                 utils.defineProperty(wallet, 'path', signingKey.path) | ||||||
|  |               } | ||||||
|  |               resolve(wallet) | ||||||
|  |               return null | ||||||
|             }, |             }, | ||||||
|             'address' : { |             function (error) { | ||||||
|                 enumerable : true, |               reject(error) | ||||||
|                 writable : false, |  | ||||||
|                 value : signingKey.address, |  | ||||||
|             }, |  | ||||||
|             'url' : { |  | ||||||
|                 enumerable: true, |  | ||||||
|                 get: function() { return this._url }, |  | ||||||
|                 set: function(url) { |  | ||||||
|                     if (typeof(url) !== 'string') { throw new Error('invalid url') } |  | ||||||
|                     this._url = url |  | ||||||
|                 }, |  | ||||||
|             },       |  | ||||||
|             'defaultGasFee' : {  |  | ||||||
|                 enumerable: true, |  | ||||||
|                 get: function() { return this._defaultGasFee }, |  | ||||||
|                 set: function(value) { |  | ||||||
|                     if (typeof(value) !== 'number') { throw new Error('invalid defaultGasFee') } |  | ||||||
|                     this._defaultGasFee = value |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|  |           ) | ||||||
|  |           .catch(function (error) { | ||||||
|  |             reject(error) | ||||||
|  |           }) | ||||||
|  |       } else { | ||||||
|  |         reject('invalid wallet JSON') | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  |   } | ||||||
|  |   static parseTransaction (rawTransaction) { | ||||||
|  |     rawTransaction = utils.hexlify(rawTransaction, 'rawTransaction') | ||||||
|  |     var signedTransaction = utils.RLP.decode(rawTransaction) | ||||||
|  |     if (signedTransaction.length !== 9) { | ||||||
|  |       throw new Error('invalid transaction') | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     var raw = [] | ||||||
|  | 
 | ||||||
|  |     var transaction = {} | ||||||
|  |     transactionFields.forEach(function (fieldInfo, index) { | ||||||
|  |       transaction[fieldInfo.name] = signedTransaction[index] | ||||||
|  |       raw.push(signedTransaction[index]) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     if (transaction.to) { | ||||||
|  |       if (transaction.to == '0x') { | ||||||
|  |         delete transaction.to | ||||||
|  |       } else { | ||||||
|  |         transaction.to = utils.getAddress(transaction.to) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ;['gasPrice', 'gasLimit', 'nonce', 'value'].forEach(function (name) { | ||||||
|  |       if (!transaction[name]) { | ||||||
|  |         return | ||||||
|  |       } | ||||||
|  |       if (transaction[name].length === 0) { | ||||||
|  |         transaction[name] = utils.bigNumberify(0) | ||||||
|  |       } else { | ||||||
|  |         transaction[name] = utils.bigNumberify(transaction[name]) | ||||||
|  |       } | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     if (transaction.nonce) { | ||||||
|  |       transaction.nonce = transaction.nonce.toNumber() | ||||||
|  |     } else { | ||||||
|  |       transaction.nonce = 0 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     var v = utils.arrayify(signedTransaction[6]) | ||||||
|  |     var r = utils.arrayify(signedTransaction[7]) | ||||||
|  |     var s = utils.arrayify(signedTransaction[8]) | ||||||
|  | 
 | ||||||
|  |     if ( | ||||||
|  |       v.length >= 1 && | ||||||
|  |       r.length >= 1 && | ||||||
|  |       r.length <= 32 && | ||||||
|  |       s.length >= 1 && | ||||||
|  |       s.length <= 32 | ||||||
|  |     ) { | ||||||
|  |       transaction.v = utils.bigNumberify(v).toNumber() | ||||||
|  |       transaction.r = signedTransaction[7] | ||||||
|  |       transaction.s = signedTransaction[8] | ||||||
|  | 
 | ||||||
|  |       var chainId = (transaction.v - 35) / 2 | ||||||
|  |       if (chainId < 0) { | ||||||
|  |         chainId = 0 | ||||||
|  |       } | ||||||
|  |       chainId = parseInt(chainId) | ||||||
|  | 
 | ||||||
|  |       transaction.chainId = chainId | ||||||
|  | 
 | ||||||
|  |       var recoveryParam = transaction.v - 27 | ||||||
|  | 
 | ||||||
|  |       if (chainId) { | ||||||
|  |         raw.push(utils.hexlify(chainId)) | ||||||
|  |         raw.push('0x') | ||||||
|  |         raw.push('0x') | ||||||
|  |         recoveryParam -= chainId * 2 + 8 | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       var digest = utils.keccak256(utils.RLP.encode(raw)) | ||||||
|  |       try { | ||||||
|  |         transaction.from = SigningKey.recover(digest, r, s, recoveryParam) | ||||||
|  |       } catch (error) { | ||||||
|  |         console.log(error) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return transaction | ||||||
|  |   } | ||||||
|  |   static encrypt (data, key) { | ||||||
|  |     if (!data || !key) throw new Error('Required Params Missing') | ||||||
|  |     return Ticrypto.encrypt(data, key) | ||||||
|  |   } | ||||||
|  |   static decrypt (data, key) { | ||||||
|  |     return Ticrypto.decrypt(data, key, { format: 'json' }) //return null for wrong key
 | ||||||
|  |   } | ||||||
|  |   static async estimateGasPrice () { | ||||||
|  |     try { | ||||||
|  |       return ( | ||||||
|  |         parseInt( | ||||||
|  |           ( | ||||||
|  |             await axios.post(ETH_NODE, { | ||||||
|  |               method: 'eth_gasPrice', | ||||||
|  |               id: '6842', | ||||||
|  |               jsonrpc: '2.0' | ||||||
|  |             }) | ||||||
|  |           ).data.result | ||||||
|  |         ) / 1e9 | ||||||
|  |       ) | ||||||
|  |     } catch (err) { | ||||||
|  |       return 1 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static isValidAddress (address) { | ||||||
|  |     let res = address.match(/^(0x)?[0-9a-fA-F]{40}$/) | ||||||
|  |     return res && res[0].slice(0, 2) === '0x' | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   async getBalance () { | ||||||
|  |     return ETH.getBalance(this.address) | ||||||
|  |   } | ||||||
|  |   async getActions () { | ||||||
|  |     return ETH.getActions(this.address) | ||||||
|  |   } | ||||||
|  |   async getTransactionCount () { | ||||||
|  |     if (!this._url) { | ||||||
|  |       throw new Error('Base url required') | ||||||
|  |     } | ||||||
|  |     var self = this | ||||||
|  |     return ( | ||||||
|  |       ( | ||||||
|  |         await axios.post(this._url, { | ||||||
|  |           jsonrpc: '2.0', | ||||||
|  |           method: 'eth_getTransactionCount', | ||||||
|  |           params: [self.address, 'latest'], | ||||||
|  |           id: 1 | ||||||
|         }) |         }) | ||||||
|         this._defaultGasFee = GAS_Fee |       ).data.result || null | ||||||
|         this._url = ETH_NODE |     ) | ||||||
|  |   } | ||||||
|  |   signTransaction (transaction) { | ||||||
|  |     var chainId = transaction.chainId | ||||||
|  |     if (chainId == null && this.provider) { | ||||||
|  |       chainId = this.provider.chainId | ||||||
|     } |     } | ||||||
|     static generateNewAccount(option = {path:defaultPath}){ |     if (!chainId) { | ||||||
|         //major path as default path >/0'/0/0
 |       chainId = 0 | ||||||
|         var mnemonic =  Ticrypto.randomSecword() |  | ||||||
|         return Object.assign(ETH.fromMnemonic(mnemonic, option),{mnemonic,mnemonic}) |  | ||||||
|     } |     } | ||||||
|     static fromMnemonic(mnemonic, option = {path:defaultPath}){ | 
 | ||||||
|         HDNode.isValidMnemonic(mnemonic)    //check valid mnemonic,will throw Error if not valid
 |     var raw = [] | ||||||
|         let seed = HDNode.mnemonicToSeed(mnemonic) |     transactionFields.forEach(function (fieldInfo) { | ||||||
|         return new ETH(HDNode.fromSeed(seed).derivePath(option.path).privateKey) |       var value = transaction[fieldInfo.name] || [] | ||||||
|     } |       value = utils.arrayify(utils.hexlify(value), fieldInfo.name) | ||||||
|     static async getBalance(address){ | 
 | ||||||
|         if(!address){ throw new Error('Address is required') } |       // Fixed-width field
 | ||||||
|         let res = (await axios.post(ETH_NODE,{ |       if ( | ||||||
|             "jsonrpc":"2.0","method":"eth_getBalance","params":[address, "latest"],"id":1 |         fieldInfo.length && | ||||||
|         })).data |         value.length !== fieldInfo.length && | ||||||
|         if(res) |         value.length > 0 | ||||||
|         return parseInt(res.result)/1e18    //1000000000000000000
 |       ) { | ||||||
|         else return null |         var error = new Error('invalid ' + fieldInfo.name) | ||||||
|     } |         error.reason = 'wrong length' | ||||||
|     static async getActions(address){ |         error.value = value | ||||||
|         let tx = await eth.account.txlist(address, 0 ,'latast') |         throw error | ||||||
|         if(tx && tx.message === 'OK') |       } | ||||||
|             return tx.result | 
 | ||||||
|         else return []  |       // Variable-width (with a maximum)
 | ||||||
|     } |       if (fieldInfo.maxLength) { | ||||||
|     static fromEncryptedWallet(json, password, progressCallback) { |         value = utils.stripZeros(value) | ||||||
|         if (progressCallback && typeof(progressCallback) !== 'function') { |         if (value.length > fieldInfo.maxLength) { | ||||||
|             throw new Error('invalid callback') |           var error = new Error('invalid ' + fieldInfo.name) | ||||||
|         } |           error.reason = 'too long' | ||||||
|      |           error.value = value | ||||||
|         return new Promise(function(resolve, reject) { |           throw error | ||||||
|      |  | ||||||
|             if (secretStorage.isCrowdsaleWallet(json)) { |  | ||||||
|                 try { |  | ||||||
|                     var privateKey = secretStorage.decryptCrowdsale(json, password) |  | ||||||
|                     resolve(new ETH(privateKey)) |  | ||||||
|                 } catch (error) { |  | ||||||
|                     reject(error) |  | ||||||
|                 } |  | ||||||
|      |  | ||||||
|             } else if (secretStorage.isValidWallet(json)) { |  | ||||||
|      |  | ||||||
|                 secretStorage.decrypt(json, password, progressCallback).then(function(signingKey) { |  | ||||||
|                     var wallet = new ETH(signingKey) |  | ||||||
|                     if (signingKey.mnemonic && signingKey.path) { |  | ||||||
|                         utils.defineProperty(wallet, 'mnemonic', signingKey.mnemonic) |  | ||||||
|                         utils.defineProperty(wallet, 'path', signingKey.path) |  | ||||||
|                     } |  | ||||||
|                     resolve(wallet) |  | ||||||
|                     return null |  | ||||||
|                 }, function(error) { |  | ||||||
|                     reject(error) |  | ||||||
|                 }).catch(function(error) { reject(error) }) |  | ||||||
|      |  | ||||||
|             } else { |  | ||||||
|                 reject('invalid wallet JSON') |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|     } |  | ||||||
|     static parseTransaction(rawTransaction){ |  | ||||||
|         rawTransaction = utils.hexlify(rawTransaction, 'rawTransaction') |  | ||||||
|         var signedTransaction = utils.RLP.decode(rawTransaction) |  | ||||||
|         if (signedTransaction.length !== 9) { throw new Error('invalid transaction') } |  | ||||||
|      |  | ||||||
|         var raw = [] |  | ||||||
|      |  | ||||||
|         var transaction = {} |  | ||||||
|         transactionFields.forEach(function(fieldInfo, index) { |  | ||||||
|             transaction[fieldInfo.name] = signedTransaction[index] |  | ||||||
|             raw.push(signedTransaction[index]) |  | ||||||
|         }) |  | ||||||
|      |  | ||||||
|         if (transaction.to) { |  | ||||||
|             if (transaction.to == '0x') { |  | ||||||
|                 delete transaction.to |  | ||||||
|             } else { |  | ||||||
|                 transaction.to = utils.getAddress(transaction.to) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|         ['gasPrice', 'gasLimit', 'nonce', 'value'].forEach(function(name) { |  | ||||||
|             if (!transaction[name]) { return } |  | ||||||
|             if (transaction[name].length === 0) { |  | ||||||
|                 transaction[name] = utils.bigNumberify(0) |  | ||||||
|             } else { |  | ||||||
|                 transaction[name] = utils.bigNumberify(transaction[name]) |  | ||||||
|             } |  | ||||||
|         }) |  | ||||||
|      |  | ||||||
|         if (transaction.nonce) { |  | ||||||
|             transaction.nonce = transaction.nonce.toNumber() |  | ||||||
|         } else { |  | ||||||
|             transaction.nonce = 0 |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|         var v = utils.arrayify(signedTransaction[6]) |  | ||||||
|         var r = utils.arrayify(signedTransaction[7]) |  | ||||||
|         var s = utils.arrayify(signedTransaction[8]) |  | ||||||
|      |  | ||||||
|         if (v.length >= 1 && r.length >= 1 && r.length <= 32 && s.length >= 1 && s.length <= 32) { |  | ||||||
|             transaction.v = utils.bigNumberify(v).toNumber() |  | ||||||
|             transaction.r = signedTransaction[7] |  | ||||||
|             transaction.s = signedTransaction[8] |  | ||||||
|      |  | ||||||
|             var chainId = (transaction.v - 35) / 2 |  | ||||||
|             if (chainId < 0) { chainId = 0 } |  | ||||||
|             chainId = parseInt(chainId) |  | ||||||
|      |  | ||||||
|             transaction.chainId = chainId |  | ||||||
|      |  | ||||||
|             var recoveryParam = transaction.v - 27 |  | ||||||
|      |  | ||||||
|             if (chainId) { |  | ||||||
|                 raw.push(utils.hexlify(chainId)) |  | ||||||
|                 raw.push('0x') |  | ||||||
|                 raw.push('0x') |  | ||||||
|                 recoveryParam -= chainId * 2 + 8 |  | ||||||
|             } |  | ||||||
|      |  | ||||||
|             var digest = utils.keccak256(utils.RLP.encode(raw)) |  | ||||||
|             try { |  | ||||||
|                 transaction.from = SigningKey.recover(digest, r, s, recoveryParam) |  | ||||||
|             } catch (error) { |  | ||||||
|                 console.log(error) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|      |  | ||||||
|      |  | ||||||
|         return transaction |  | ||||||
|     } |  | ||||||
|     static encrypt(data, key){ |  | ||||||
|         if(!data || !key) throw new Error('Required Params Missing') |  | ||||||
|         return Ticrypto.encrypt(data,key) |  | ||||||
|     } |  | ||||||
|     static decrypt(data, key){ |  | ||||||
|         return Ticrypto.decrypt(data, key, {format:"json"})  //return null for wrong key
 |  | ||||||
|     } |  | ||||||
|     static async estimateGasPrice(){ |  | ||||||
|         try{ |  | ||||||
|             return parseInt((await axios.post(ETH_NODE, { |  | ||||||
|                 "method": "eth_gasPrice", |  | ||||||
|                 "id": "6842", |  | ||||||
|                 "jsonrpc": "2.0" |  | ||||||
|             })).data.result)/1e9 |  | ||||||
|         } |  | ||||||
|         catch(err){ |  | ||||||
|             return 1 |  | ||||||
|         } |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       raw.push(utils.hexlify(value)) | ||||||
|  |     }) | ||||||
|  | 
 | ||||||
|  |     if (chainId) { | ||||||
|  |       raw.push(utils.hexlify(chainId)) | ||||||
|  |       raw.push('0x') | ||||||
|  |       raw.push('0x') | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     static isValidAddress(address){ |     var digest = utils.keccak256(utils.RLP.encode(raw)) | ||||||
|         let res = address.match(/^(0x)?[0-9a-fA-F]{40}$/) |     var signingKey = new SigningKey(this.privateKey) | ||||||
|         return res && res[0].slice(0,2) === '0x' |     var signature = signingKey.signDigest(digest) | ||||||
|  | 
 | ||||||
|  |     var v = 27 + signature.recoveryParam | ||||||
|  |     if (chainId) { | ||||||
|  |       raw.pop() | ||||||
|  |       raw.pop() | ||||||
|  |       raw.pop() | ||||||
|  |       v += chainId * 2 + 8 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     async getBalance(){ |     raw.push(utils.hexlify(v)) | ||||||
|         return ETH.getBalance(this.address) |     raw.push(utils.stripZeros(utils.arrayify(signature.r))) | ||||||
|     } |     raw.push(utils.stripZeros(utils.arrayify(signature.s))) | ||||||
|     async getActions(){ |  | ||||||
|         return ETH.getActions(this.address) |  | ||||||
|     } |  | ||||||
|     async getTransactionCount(){ |  | ||||||
|         if(!this._url){ throw new Error('Base url required') } |  | ||||||
|         var self = this |  | ||||||
|         return (await axios.post(this._url,{ |  | ||||||
|             "jsonrpc":"2.0","method":"eth_getTransactionCount","params":[self.address, "latest"],"id":1 |  | ||||||
|         })).data.result||null |  | ||||||
|     } |  | ||||||
|     signTransaction(transaction){ |  | ||||||
|         var chainId = transaction.chainId |  | ||||||
|         if (chainId == null && this.provider) { chainId = this.provider.chainId } |  | ||||||
|         if (!chainId) { chainId = 0 } |  | ||||||
| 
 | 
 | ||||||
|         var raw = [] |     return utils.RLP.encode(raw) | ||||||
|         transactionFields.forEach(function(fieldInfo) { |   } | ||||||
|             var value = transaction[fieldInfo.name] || ([]) |   async sendTransaction (toAddress, amount, option = { gasFee: GAS_Fee }) { | ||||||
|             value = utils.arrayify(utils.hexlify(value), fieldInfo.name) |     /****************************************************************    | ||||||
| 
 |  | ||||||
|             // Fixed-width field
 |  | ||||||
|             if (fieldInfo.length && value.length !== fieldInfo.length && value.length > 0) { |  | ||||||
|                 var error = new Error('invalid ' + fieldInfo.name) |  | ||||||
|                 error.reason = 'wrong length' |  | ||||||
|                 error.value = value |  | ||||||
|                 throw error |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             // Variable-width (with a maximum)
 |  | ||||||
|             if (fieldInfo.maxLength) { |  | ||||||
|                 value = utils.stripZeros(value) |  | ||||||
|                 if (value.length > fieldInfo.maxLength) { |  | ||||||
|                     var error = new Error('invalid ' + fieldInfo.name) |  | ||||||
|                     error.reason = 'too long' |  | ||||||
|                     error.value = value |  | ||||||
|                     throw error |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             raw.push(utils.hexlify(value)) |  | ||||||
|         }) |  | ||||||
| 
 |  | ||||||
|         if (chainId) { |  | ||||||
|             raw.push(utils.hexlify(chainId)) |  | ||||||
|             raw.push('0x') |  | ||||||
|             raw.push('0x') |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         var digest = utils.keccak256(utils.RLP.encode(raw)) |  | ||||||
|         var signingKey = new SigningKey(this.privateKey) |  | ||||||
|         var signature = signingKey.signDigest(digest) |  | ||||||
| 
 |  | ||||||
|         var v = 27 + signature.recoveryParam |  | ||||||
|         if (chainId) { |  | ||||||
|             raw.pop() |  | ||||||
|             raw.pop() |  | ||||||
|             raw.pop() |  | ||||||
|             v += chainId * 2 + 8 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         raw.push(utils.hexlify(v)) |  | ||||||
|         raw.push(utils.stripZeros(utils.arrayify(signature.r))) |  | ||||||
|         raw.push(utils.stripZeros(utils.arrayify(signature.s))) |  | ||||||
| 
 |  | ||||||
|         return utils.RLP.encode(raw) |  | ||||||
|     } |  | ||||||
|     async sendTransaction(toAddress, amount, option = {gasFee : GAS_Fee}){ |  | ||||||
|         /****************************************************************    |  | ||||||
|             1 Ether = 1e18 wei   |             1 Ether = 1e18 wei   | ||||||
|             1Gwei = 1e9 wei    |             1Gwei = 1e9 wei    | ||||||
|             *GWei as the unit of gasPrice, minimum gasPrice is 1Gwei |             *GWei as the unit of gasPrice, minimum gasPrice is 1Gwei | ||||||
|             *unit of amount is ether,should be translate to wei |             *unit of amount is ether,should be translate to wei | ||||||
|         ****************************************************************/ |         ****************************************************************/ | ||||||
|         let nonce = await this.getTransactionCount() |     let nonce = await this.getTransactionCount() | ||||||
|         if(!nonce) nonce = '0x0' |     if (!nonce) nonce = '0x0' | ||||||
|         var gasPrice, gasLimit |     var gasPrice, gasLimit | ||||||
|         if(!option.gasPrice || !option.gasLimit){ |     if (!option.gasPrice || !option.gasLimit) { | ||||||
|             //Normal Mode:use customized gasFee( ether ) to caculate gasPrice( wei ), gasLimit use default value
 |       //Normal Mode:use customized gasFee( ether ) to caculate gasPrice( wei ), gasLimit use default value
 | ||||||
|             gasLimit = GAS_LIMIT |       gasLimit = GAS_LIMIT | ||||||
|             gasPrice = String(option.gasFee * GAS_UNIT_WEI / gasLimit) |       gasPrice = String((option.gasFee * GAS_UNIT_WEI) / gasLimit) | ||||||
|         } |     } else { | ||||||
|         else{ |       //Advance Mode:specified the gasLimit and gasPrice( gwei )
 | ||||||
|             //Advance Mode:specified the gasLimit and gasPrice( gwei )
 |       gasLimit = option.gasLimit | ||||||
|             gasLimit = option.gasLimit |       gasPrice = String(GAS_UNIT_GWEI * option.gasPrice) | ||||||
|             gasPrice = String(GAS_UNIT_GWEI * option.gasPrice) |     } | ||||||
|         } |     let transaction = { | ||||||
|         let transaction = { |       nonce: nonce, | ||||||
|             nonce: nonce, |       gasLimit: gasLimit, | ||||||
|             gasLimit: gasLimit, |       gasPrice: utils.bigNumberify(gasPrice), | ||||||
|             gasPrice: utils.bigNumberify(gasPrice), |       to: toAddress, | ||||||
|             to: toAddress, |  | ||||||
| 
 | 
 | ||||||
|             value: utils.parseEther(String(amount)), |       value: utils.parseEther(String(amount)) | ||||||
|         } |  | ||||||
|         try{ |  | ||||||
|             let signedTransaction = this.signTransaction(transaction) |  | ||||||
|             let ethTxRes = (await axios.post(ETH_NODE,{ |  | ||||||
|                 "jsonrpc":"2.0", |  | ||||||
|                 "method":"eth_sendRawTransaction", |  | ||||||
|                 "params":[signedTransaction.toString('hex')], |  | ||||||
|                 "id":6842 |  | ||||||
|             })).data |  | ||||||
|             if(ethTxRes && ethTxRes.result) |  | ||||||
|                 return ethTxRes |  | ||||||
|             return null |  | ||||||
|         } |  | ||||||
|         catch(err){ |  | ||||||
|             return null |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|     encrypt(key){ |     try { | ||||||
|         return ETH.encrypt(this, key) |       let signedTransaction = this.signTransaction(transaction) | ||||||
|  |       let ethTxRes = ( | ||||||
|  |         await axios.post(ETH_NODE, { | ||||||
|  |           jsonrpc: '2.0', | ||||||
|  |           method: 'eth_sendRawTransaction', | ||||||
|  |           params: [signedTransaction.toString('hex')], | ||||||
|  |           id: 6842 | ||||||
|  |         }) | ||||||
|  |       ).data | ||||||
|  |       if (ethTxRes && ethTxRes.result) return ethTxRes | ||||||
|  |       return null | ||||||
|  |     } catch (err) { | ||||||
|  |       return null | ||||||
|     } |     } | ||||||
|  |   } | ||||||
|  |   encrypt (key) { | ||||||
|  |     return ETH.encrypt(this, key) | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class ERC20 extends ETH{ | class ERC20 extends ETH { | ||||||
|     constructor(privateKey, contractAddress){ |   constructor (privateKey, contractAddress) { | ||||||
|         if(!contractAddress) throw new Error('Missing contractAddress') |     if (!contractAddress) throw new Error('Missing contractAddress') | ||||||
|         super(privateKey) |     super(privateKey) | ||||||
|         Object.defineProperty(this, 'contractAddress',{ |     Object.defineProperty(this, 'contractAddress', { | ||||||
|             enumerable:true, |       enumerable: true, | ||||||
|             writable:false, |       writable: false, | ||||||
|             value:contractAddress |       value: contractAddress | ||||||
|         }) |     }) | ||||||
|  |   } | ||||||
|  |   static async getDecimals (contractAddress) { | ||||||
|  |     if (!contractAddress) throw new Error('Missing params') | ||||||
|  |     let queryAddress = | ||||||
|  |       '0x313ce567' + contractAddress.split('x')[1].padStart(64, '0') | ||||||
|  |     let params = [{ to: contractAddress, data: queryAddress }, 'latest'] | ||||||
|  |     let queryData = { | ||||||
|  |       jsonrpc: '2.0', | ||||||
|  |       method: 'eth_call', | ||||||
|  |       params: params, | ||||||
|  |       id: 6842 | ||||||
|     } |     } | ||||||
|     static async getDecimals(contractAddress){ |     return parseInt((await axios.post(ETH_NODE, queryData)).data.result) | ||||||
|         if(!contractAddress) throw new Error('Missing params') |   } | ||||||
|         let queryAddress = '0x313ce567' + (contractAddress.split('x')[1]).padStart(64,'0') |   static async getBalance (address, contractAddress) { | ||||||
|         let params = [{"to":contractAddress, "data":queryAddress},"latest"] |     if (!address || !contractAddress) throw new Error('Missing params') | ||||||
|         let queryData = { |     let queryAddress = '0x70a08231' + address.split('x')[1].padStart(64, '0') | ||||||
|             "jsonrpc":"2.0", |     let params = [{ to: contractAddress, data: queryAddress }, 'latest'] | ||||||
|             "method":"eth_call", |     let queryData = { | ||||||
|             "params":params, |       jsonrpc: '2.0', | ||||||
|             "id":6842 |       method: 'eth_call', | ||||||
|         } |       params: params, | ||||||
|         return parseInt((await axios.post(ETH_NODE, queryData)).data.result) |       id: 6842 | ||||||
|     } |     } | ||||||
|     static async getBalance(address, contractAddress){ |     // return parseInt(erc20res.result)/Number('10'.padEnd(ERC20Table[obj.name].decimals+1,'0'))
 | ||||||
|         if(!address || !contractAddress) throw new Error('Missing params') |     let res = (await axios.post(ETH_NODE, queryData)).data.result | ||||||
|         let queryAddress = '0x70a08231' + (address.split('x')[1]).padStart(64,'0') |     if (res == '0x') return 0 | ||||||
|         let params = [{"to":contractAddress, "data":queryAddress},"latest"] |     return parseInt(res) | ||||||
|         let queryData = { |   } | ||||||
|             "jsonrpc":"2.0", |   static async getActions (address, contractAddress) { | ||||||
|             "method":"eth_call", |     try { | ||||||
|             "params":params, |       let res = await eth.account.tokentx(address, contractAddress) | ||||||
|             "id":6842 |       if (res && res.result) return res.result | ||||||
|         } |     } catch (err) { | ||||||
|         // return parseInt(erc20res.result)/Number('10'.padEnd(ERC20Table[obj.name].decimals+1,'0')) 
 |       return [] | ||||||
|         let res = (await axios.post(ETH_NODE, queryData)).data.result |  | ||||||
|         if(res == '0x') return 0 |  | ||||||
|         return parseInt(res) |  | ||||||
|     } |  | ||||||
|     static async getActions(address, contractAddress){ |  | ||||||
|         try{    |  | ||||||
|             let res = (await eth.account.tokentx(address,contractAddress)) |  | ||||||
|             if(res && res.result) |  | ||||||
|                 return res.result |  | ||||||
|         } |  | ||||||
|         catch(err){ |  | ||||||
|             return [] |  | ||||||
|         } |  | ||||||
|         return  |  | ||||||
|     } |     } | ||||||
|  |     return | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|     async getBalance(){ |   async getBalance () { | ||||||
|         return ERC20.getBalance(this.address, this.contractAddress) |     return ERC20.getBalance(this.address, this.contractAddress) | ||||||
|     } |   } | ||||||
|     async getActions(){ |   async getActions () { | ||||||
|         return ERC20.getActions(this.address, this.contractAddress) |     return ERC20.getActions(this.address, this.contractAddress) | ||||||
|     }   |   } | ||||||
|     async getDecimals(){ |   async getDecimals () { | ||||||
|         let decimals = await ERC20.getDecimals(this.contractAddress) |     let decimals = await ERC20.getDecimals(this.contractAddress) | ||||||
|         if(decimals) |     if (decimals) | ||||||
|             Object.defineProperty(this, 'decimals', { |       Object.defineProperty(this, 'decimals', { | ||||||
|                 enumerable:true, |         enumerable: true, | ||||||
|                 value:decimals, |         value: decimals, | ||||||
|                 writable:false |         writable: false | ||||||
|             }) |       }) | ||||||
|         else |     else return 0 // any good idea?
 | ||||||
|             return 0    // any good idea?
 |   } | ||||||
|     } |   async sendTransaction ( | ||||||
|     async sendTransaction(toAddress, amount, option = {gasFee : GAS_Fee_ERC20}){ |     toAddress, | ||||||
|         /****************************************************************    |     amount, | ||||||
|  |     option = { gasFee: GAS_Fee_ERC20 } | ||||||
|  |   ) { | ||||||
|  |     /****************************************************************    | ||||||
|             1 Ether = 1e18 wei   |             1 Ether = 1e18 wei   | ||||||
|             1 Gwei = 1e9 wei    |             1 Gwei = 1e9 wei    | ||||||
|             *GWei as the unit of gasPrice, minimum gasPrice is 1Gwei |             *GWei as the unit of gasPrice, minimum gasPrice is 1Gwei | ||||||
|             minimum gaslimit for erc20transaction is 6e4 |             minimum gaslimit for erc20transaction is 6e4 | ||||||
|         ****************************************************************/ |         ****************************************************************/ | ||||||
|         var nonce = await this.getTransactionCount() |     var nonce = await this.getTransactionCount() | ||||||
|         var gasPrice, gasLimit, decimals, contractAddress = this.contractAddress |     var gasPrice, | ||||||
|         if(!nonce) nonce = '0x0' |       gasLimit, | ||||||
|         if(!option.gasPrice || !option.gasLimit){ |       decimals, | ||||||
|             //Normal Mode:use customized gasFee( ether ) to caculate gasPrice( wei ), gasLimit use default value
 |       contractAddress = this.contractAddress | ||||||
|             gasLimit = GAS_LIMIT_ERC20 |     if (!nonce) nonce = '0x0' | ||||||
|             gasPrice = String(option.gasFee * GAS_UNIT_WEI / gasLimit) |     if (!option.gasPrice || !option.gasLimit) { | ||||||
|         } |       //Normal Mode:use customized gasFee( ether ) to caculate gasPrice( wei ), gasLimit use default value
 | ||||||
|         else{ |       gasLimit = GAS_LIMIT_ERC20 | ||||||
|             //Advance Mode:specified the gasLimit and gasPrice( gwei )
 |       gasPrice = String((option.gasFee * GAS_UNIT_WEI) / gasLimit) | ||||||
|             gasLimit = option.gasLimit |     } else { | ||||||
|             gasPrice = String(GAS_UNIT_GWEI * option.gasPrice) |       //Advance Mode:specified the gasLimit and gasPrice( gwei )
 | ||||||
|         } |       gasLimit = option.gasLimit | ||||||
|         if(!option.decimals) decimals = await ERC20.getDecimals(contractAddress) |       gasPrice = String(GAS_UNIT_GWEI * option.gasPrice) | ||||||
|         let txBody = '0x' + 'a9059cbb' + toAddress.split('x')[1].padStart(64,'0')+ Number(amount*Math.pow(10,decimals)).toString(16).padStart(64,'0') |  | ||||||
|         let transaction = { |  | ||||||
|             nonce: nonce, |  | ||||||
|             gasLimit: gasLimit, |  | ||||||
|             gasPrice : utils.bigNumberify(gasPrice), |  | ||||||
|             to: contractAddress, |  | ||||||
|             value : 0, |  | ||||||
|             data : txBody |  | ||||||
|         } |  | ||||||
|         let signedTransaction = this.signTransaction(transaction) |  | ||||||
|         try{ |  | ||||||
|             let erc20TxRes = (await axios.post(ETH_NODE, { |  | ||||||
|                 "jsonrpc":"2.0", |  | ||||||
|                 "method":"eth_sendRawTransaction", |  | ||||||
|                 "params":[signedTransaction.toString('hex')], |  | ||||||
|                 "id":6842 |  | ||||||
|             })).data |  | ||||||
|             if(erc20TxRes && erc20TxRes.result) |  | ||||||
|                 return erc20TxRes.result |  | ||||||
|             console.log(erc20TxRes) |  | ||||||
|             return null |  | ||||||
|         } |  | ||||||
|         catch(err){ |  | ||||||
|             return null |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 |     if (!option.decimals) decimals = await ERC20.getDecimals(contractAddress) | ||||||
|  |     let txBody = | ||||||
|  |       '0x' + | ||||||
|  |       'a9059cbb' + | ||||||
|  |       toAddress.split('x')[1].padStart(64, '0') + | ||||||
|  |       Number(amount * Math.pow(10, decimals)) | ||||||
|  |         .toString(16) | ||||||
|  |         .padStart(64, '0') | ||||||
|  |     let transaction = { | ||||||
|  |       nonce: nonce, | ||||||
|  |       gasLimit: gasLimit, | ||||||
|  |       gasPrice: utils.bigNumberify(gasPrice), | ||||||
|  |       to: contractAddress, | ||||||
|  |       value: 0, | ||||||
|  |       data: txBody | ||||||
|  |     } | ||||||
|  |     let signedTransaction = this.signTransaction(transaction) | ||||||
|  |     try { | ||||||
|  |       let erc20TxRes = ( | ||||||
|  |         await axios.post(ETH_NODE, { | ||||||
|  |           jsonrpc: '2.0', | ||||||
|  |           method: 'eth_sendRawTransaction', | ||||||
|  |           params: [signedTransaction.toString('hex')], | ||||||
|  |           id: 6842 | ||||||
|  |         }) | ||||||
|  |       ).data | ||||||
|  |       if (erc20TxRes && erc20TxRes.result) return erc20TxRes.result | ||||||
|  |       console.log(erc20TxRes) | ||||||
|  |       return null | ||||||
|  |     } catch (err) { | ||||||
|  |       return null | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = { | module.exports = { | ||||||
|     ETH, ERC20 |   ETH, | ||||||
|  |   ERC20 | ||||||
| } | } | ||||||
| 
 |  | ||||||
|  | |||||||
							
								
								
									
										26
									
								
								index.js
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								index.js
									
									
									
									
									
								
							| @ -1,16 +1,16 @@ | |||||||
| 'use strict' | 'use strict' | ||||||
| 
 | 
 | ||||||
| const TIC = require('./tic.js').TIC; | const TIC = require('./tic.js').TIC | ||||||
| const ETH = require('./eth.js').ETH; | const ETH = require('./eth.js').ETH | ||||||
| const ERC20 = require('./eth.js').ERC20; | const ERC20 = require('./eth.js').ERC20 | ||||||
| const BTC = require('./btc.js').BTC; | const BTC = require('./btc.js').BTC | ||||||
| const Account = require('./Account').Account; | const Account = require('./Account').Account | ||||||
| const Crypto = require('tic.crypto'); | const Crypto = require('tic-crypto') | ||||||
| module.exports = { | module.exports = { | ||||||
|     TIC, |   TIC, | ||||||
|     ETH, |   ETH, | ||||||
|     BTC, |   BTC, | ||||||
|     ERC20, |   ERC20, | ||||||
|     Account, |   Account, | ||||||
|     Crypto, |   Crypto | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | |||||||
| { | { | ||||||
|   "name": "tic.tool4chain", |   "name": "tic-chaintool", | ||||||
|   "version": "1.2.1", |   "version": "1.2.1", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "aes-js": "^3.1.1", |     "aes-js": "^3.1.1", | ||||||
| @ -11,15 +11,11 @@ | |||||||
|     "scrypt-js": "^2.0.3", |     "scrypt-js": "^2.0.3", | ||||||
|     "setimmediate": "^1.0.5", |     "setimmediate": "^1.0.5", | ||||||
|     "tic.action": "git+https://git.faronear.org/npm/tic.action#20190714_release_passtoken", |     "tic.action": "git+https://git.faronear.org/npm/tic.action#20190714_release_passtoken", | ||||||
|     "tic.crypto": "git+https://git.faronear.org/npm/tic.crypto#20190109_preview", |     "tic-crypto": "git+https://git.faronear.org/npm/tic-crypto#20190109_preview", | ||||||
|     "uuid": "^8.3.1" |     "uuid": "^8.3.1" | ||||||
|   }, |   }, | ||||||
|   "deprecated": false, |   "deprecated": false, | ||||||
|   "description": "blockchain tool for ticwallet", |   "description": "blockchain tool for ticwallet", | ||||||
|   "keywords": [ |   "keywords": ["tool", "blockchain", "tic"], | ||||||
|     "tool", |  | ||||||
|     "blockchain", |  | ||||||
|     "tic" |  | ||||||
|   ], |  | ||||||
|   "main": "index.js" |   "main": "index.js" | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										165
									
								
								tic.js
									
									
									
									
									
								
							
							
						
						
									
										165
									
								
								tic.js
									
									
									
									
									
								
							| @ -1,156 +1,155 @@ | |||||||
| "use strict"; | 'use strict' | ||||||
| const axios = require("axios"); | const axios = require('axios') | ||||||
| const ticCrypto = require("tic.crypto"); | const ticrypto = require('tic-crypto') | ||||||
| const ticActionTransfer = require("tic.action").ActionTransfer; | const ticActionTransfer = require('tic.action').ActionTransfer | ||||||
| 
 | 
 | ||||||
| const TIC_TXFEE = 10; | const TIC_TXFEE = 10 | ||||||
| const TIC_NODE = require("./netConfig").TIC_NODE; | const TIC_NODE = require('./netConfig').TIC_NODE | ||||||
| 
 | 
 | ||||||
| class TIC { | class TIC { | ||||||
|   constructor(seckey, option = {}) { |   constructor (seckey, option = {}) { | ||||||
|     if (!seckey || !ticCrypto.isSeckey(seckey)) throw "ERROR:Invalid Seckey"; |     if (!seckey || !ticrypto.isSeckey(seckey)) throw 'ERROR:Invalid Seckey' | ||||||
|     Object.defineProperties(this, { |     Object.defineProperties(this, { | ||||||
|       seckey: { |       seckey: { | ||||||
|         value: seckey, |         value: seckey, | ||||||
|         enumerable: true, |         enumerable: true, | ||||||
|         writable: false, |         writable: false | ||||||
|       }, |       }, | ||||||
|       pubkey: { |       pubkey: { | ||||||
|         value: ticCrypto.seckey2pubkey(seckey), |         value: ticrypto.seckey2pubkey(seckey), | ||||||
|         enumerable: true, |         enumerable: true, | ||||||
|         writable: false, |         writable: false | ||||||
|       }, |       }, | ||||||
|       address: { |       address: { | ||||||
|         value: ticCrypto.pubkey2address(ticCrypto.seckey2pubkey(seckey)), |         value: ticrypto.pubkey2address(ticrypto.seckey2pubkey(seckey)), | ||||||
|         enumerable: true, |         enumerable: true, | ||||||
|         writable: false, |         writable: false | ||||||
|       }, |       } | ||||||
|     }); |     }) | ||||||
|     Object.assign(this, { |     Object.assign(this, { | ||||||
|       _url: option._url || TIC_NODE, |       _url: option._url || TIC_NODE, | ||||||
|       _defaultFee: option.fee || TIC_TXFEE, //fee cannot be zero
 |       _defaultFee: option.fee || TIC_TXFEE //fee cannot be zero
 | ||||||
|     }); |     }) | ||||||
|   } |   } | ||||||
|   get url() { |   get url () { | ||||||
|     return this._url; |     return this._url | ||||||
|   } |   } | ||||||
|   set url(newURL) { |   set url (newURL) { | ||||||
|     this._url = newURL; |     this._url = newURL | ||||||
|   } |   } | ||||||
|   get txfee() { |   get txfee () { | ||||||
|     return this._defaultFee; |     return this._defaultFee | ||||||
|   } |   } | ||||||
|   set txfee(fee) { |   set txfee (fee) { | ||||||
|     this._defaultFee = fee; |     this._defaultFee = fee | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static generateNewAccount() { |   static generateNewAccount () { | ||||||
|     var secword = ticCrypto.randomSecword(); |     var secword = ticrypto.randomSecword() | ||||||
|     return Object.assign(new TIC(ticCrypto.secword2keypair(secword).seckey), { |     return Object.assign(new TIC(ticrypto.secword2keypair(secword).seckey), { | ||||||
|       secword: secword, |       secword: secword | ||||||
|     }); |     }) | ||||||
|   } |   } | ||||||
|   static fromMnemonic(secword) { |   static fromMnemonic (secword) { | ||||||
|     if (!secword || !ticCrypto.isSecword(secword)) |     if (!secword || !ticrypto.isSecword(secword)) throw 'ERROR:Invalid Secword' | ||||||
|       throw "ERROR:Invalid Secword"; |     return new TIC(ticrypto.secword2keypair(secword).seckey) | ||||||
|     return new TIC(ticCrypto.secword2keypair(secword).seckey); |  | ||||||
|   } |   } | ||||||
|   static async getBalance(address) { |   static async getBalance (address) { | ||||||
|     if (!address) { |     if (!address) { | ||||||
|       throw new Error("Address is required"); |       throw new Error('Address is required') | ||||||
|     } |     } | ||||||
|     return ( |     return ( | ||||||
|       await axios.post(TIC_NODE + "/Account/getBalance", { |       await axios.post(TIC_NODE + '/Account/getBalance', { | ||||||
|         Account: { |         Account: { | ||||||
|           address: address, |           address: address | ||||||
|         }, |         } | ||||||
|       }) |       }) | ||||||
|     ).data; |     ).data | ||||||
|   } |   } | ||||||
|   static async getActions(address) { |   static async getActions (address) { | ||||||
|     if (!address) { |     if (!address) { | ||||||
|       throw new Error("Address is required"); |       throw new Error('Address is required') | ||||||
|     } |     } | ||||||
|     return ( |     return ( | ||||||
|       await axios.post(TIC_NODE + "/Action/getActionList", { |       await axios.post(TIC_NODE + '/Action/getActionList', { | ||||||
|         Action: { |         Action: { | ||||||
|           actorAddress: address, |           actorAddress: address, | ||||||
|           toAddress: address, |           toAddress: address | ||||||
|         }, |         }, | ||||||
|         config: { |         config: { | ||||||
|           logic: "OR", |           logic: 'OR' | ||||||
|         }, |         } | ||||||
|       }) |       }) | ||||||
|     ).data; |     ).data | ||||||
|   } |   } | ||||||
|   static encrypt(data, key) { |   static encrypt (data, key) { | ||||||
|     if (!data || !key) throw new Error("Required Params Missing"); |     if (!data || !key) throw new Error('Required Params Missing') | ||||||
|     return ticCrypto.encrypt(data, key); |     return ticrypto.encrypt(data, key) | ||||||
|   } |   } | ||||||
|   static decrypt(data, key) { |   static decrypt (data, key) { | ||||||
|     return ticCrypto.decrypt(data, key, { format: "json" }); //return null for wrong key
 |     return ticrypto.decrypt(data, key, { format: 'json' }) //return null for wrong key
 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   static isValidAddress(address) { |   static isValidAddress (address) { | ||||||
|     return ticCrypto.isAddress(address); |     return ticrypto.isAddress(address) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   async sendTransaction(toAddress, amount, option = { gasFee: TIC_TXFEE }) { |   async sendTransaction (toAddress, amount, option = { gasFee: TIC_TXFEE }) { | ||||||
|     if (!toAddress || !amount) { |     if (!toAddress || !amount) { | ||||||
|       throw new Error("ERROR:RequiredParamsMissing"); |       throw new Error('ERROR:RequiredParamsMissing') | ||||||
|     } //amount cannot be zero
 |     } //amount cannot be zero
 | ||||||
|     let action = new ticActionTransfer({ |     let action = new ticActionTransfer({ | ||||||
|       amount: parseInt(amount), |       amount: parseInt(amount), | ||||||
|       toAddress: toAddress, |       toAddress: toAddress, | ||||||
|       fee: option.gasFee, |       fee: option.gasFee | ||||||
|     }); |     }) | ||||||
|     //对交易数据签名,packMe 内的参数是交易发起人的keypair
 |     //对交易数据签名,packMe 内的参数是交易发起人的keypair
 | ||||||
|     action.packMe({ |     action.packMe({ | ||||||
|       seckey: this.seckey, |       seckey: this.seckey, | ||||||
|       pubkey: this.pubkey, |       pubkey: this.pubkey | ||||||
|     }); |     }) | ||||||
|     let data = { |     let data = { | ||||||
|       Action: action, |       Action: action | ||||||
|     }; |     } | ||||||
|     try { |     try { | ||||||
|       let res = (await axios.post(this._url + "/Action/prepare", data)).data; |       let res = (await axios.post(this._url + '/Action/prepare', data)).data | ||||||
|       return res; |       return res | ||||||
|     } catch (err) { |     } catch (err) { | ||||||
|       return null; |       return null | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   async getBalance() { |   async getBalance () { | ||||||
|     return TIC.getBalance(this.address); |     return TIC.getBalance(this.address) | ||||||
|   } |   } | ||||||
|   async getActions() { |   async getActions () { | ||||||
|     return TIC.getActions(this.address); |     return TIC.getActions(this.address) | ||||||
|   } |   } | ||||||
|   getSerializedTx(option) { |   getSerializedTx (option) { | ||||||
|     if (!option.toAddress || !option.amount) { |     if (!option.toAddress || !option.amount) { | ||||||
|       throw new Error("ERROR:RequiredParamsMissing"); |       throw new Error('ERROR:RequiredParamsMissing') | ||||||
|     } |     } | ||||||
|     let action = new ticActionTransfer({ |     let action = new ticActionTransfer({ | ||||||
|       amount: parseInt(option.amount), |       amount: parseInt(option.amount), | ||||||
|       toAddress: option.toAddress, |       toAddress: option.toAddress, | ||||||
|       fee: option.fee || this._defaultFee, |       fee: option.fee || this._defaultFee | ||||||
|     }); |     }) | ||||||
|     //sign for txBody use function packMe, which needs actor's keypair as parameter
 |     //sign for txBody use function packMe, which needs actor's keypair as parameter
 | ||||||
|     action.packMe({ |     action.packMe({ | ||||||
|       seckey: this.seckey, |       seckey: this.seckey, | ||||||
|       pubkey: this.pubkey, |       pubkey: this.pubkey | ||||||
|     }); |     }) | ||||||
|     return action; |     return action | ||||||
|   } |   } | ||||||
|   //default key for sign&encrypt is account's seckey,other keys are optional.
 |   //default key for sign&encrypt is account's seckey,other keys are optional.
 | ||||||
|   sign(message, key = this.seckey) { |   sign (message, key = this.seckey) { | ||||||
|     return ticCrypto.sign({ data: message, seckey: key }); |     return ticrypto.sign({ data: message, seckey: key }) | ||||||
|   } |   } | ||||||
|   verify(message, signature) { |   verify (message, signature) { | ||||||
|     return ticCrypto.sign({ data: message, signature, seckey: this.seckey }); |     return ticrypto.sign({ data: message, signature, seckey: this.seckey }) | ||||||
|   } |   } | ||||||
|   encrypt(key) { |   encrypt (key) { | ||||||
|     return TIC.encrypt(this, key); |     return TIC.encrypt(this, key) | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| module.exports = { TIC }; | module.exports = { TIC } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user