'use strict' const axios = require('axios') const ticc = require('tic-crypto') const ticActionTransfer = require('tic.action').ActionTransfer const TIC_TXFEE = 10 const TIC_NODE = require('./netConfig').TIC_NODE class TIC { constructor (prikey, option = {}) { if (!prikey || !ticc.is_prikey({ prikey })) throw 'ERROR:Invalid Seckey' Object.defineProperties(this, { prikey: { value: prikey, enumerable: true, writable: false }, pubkey: { value: ticc.prikey_to_pubkey({ prikey }), enumerable: true, writable: false }, address: { value: ticc.pubkey_to_address({ pubkey: ticc.prikey_to_pubkey(prikey) }), enumerable: true, writable: false } }) Object.assign(this, { _url: option._url || TIC_NODE, _defaultFee: option.fee || TIC_TXFEE //fee cannot be zero }) } get url () { return this._url } set url (newURL) { this._url = newURL } get txfee () { return this._defaultFee } set txfee (fee) { this._defaultFee = fee } static generateNewAccount () { var secword = ticc.randomize_secword() return Object.assign(new TIC(ticc.secword_to_keypair({ secword }).prikey), { secword: secword }) } static fromMnemonic (secword) { if (!secword || !ticc.is_secword(secword)) throw 'ERROR:Invalid Secword' return new TIC(ticc.secword_to_keypair({ secword }).prikey) } static async getBalance (address) { if (!address) { throw new Error('Address is required') } return ( await axios.post(TIC_NODE + '/Account/getBalance', { Account: { address: address } }) ).data } static async getActions (address) { if (!address) { throw new Error('Address is required') } return ( await axios.post(TIC_NODE + '/Action/getActionList', { Action: { actorAddress: address, toAddress: address }, config: { logic: 'OR' } }) ).data } static encrypt (data, key) { if (!data || !key) throw new Error('Required Params Missing') return ticc.encrypt_easy({ data, key }) } static decrypt (data, key) { return ticc.decrypt_easy(data, key, { format: 'json' }) //return null for wrong key } static isValidAddress (address) { return ticc.which_chain_address({ address }) } async sendTransaction (toAddress, amount, option = { gasFee: TIC_TXFEE }) { if (!toAddress || !amount) { throw new Error('ERROR:RequiredParamsMissing') } //amount cannot be zero let action = new ticActionTransfer({ amount: parseInt(amount), toAddress: toAddress, fee: option.gasFee }) //对交易数据签名,packMe 内的参数是交易发起人的keypair action.packMe({ prikey: this.prikey, pubkey: this.pubkey }) let data = { Action: action } try { let res = (await axios.post(this._url + '/Action/prepare', data)).data return res } catch (err) { return null } } async getBalance () { return TIC.getBalance(this.address) } async getActions () { return TIC.getActions(this.address) } getSerializedTx (option) { if (!option.toAddress || !option.amount) { throw new Error('ERROR:RequiredParamsMissing') } let action = new ticActionTransfer({ amount: parseInt(option.amount), toAddress: option.toAddress, fee: option.fee || this._defaultFee }) //sign for txBody use function packMe, which needs actor's keypair as parameter action.packMe({ prikey: this.prikey, pubkey: this.pubkey }) return action } //default key for sign&encrypt is account's prikey,other keys are optional. sign (message, key = this.prikey) { return ticc.sign_easy({ data: message, prikey: key }) } verify (message, signature) { return ticc.sign_easy({ data: message, signature, prikey: this.prikey }) } encrypt (key) { return TIC.encrypt(this, key) } } module.exports = { TIC }