"use strict"; const axios = require("axios"); const ticCrypto = require("tic.crypto"); const ticActionTransfer = require("tic.action").ActionTransfer; const TIC_TXFEE = 10; const TIC_NODE = require("./netConfig").TIC_NODE; class TIC { constructor(seckey, option = {}) { if (!seckey || !ticCrypto.isSeckey(seckey)) throw "ERROR:Invalid Seckey"; Object.defineProperties(this, { seckey: { value: seckey, enumerable: true, writable: false, }, pubkey: { value: ticCrypto.seckey2pubkey(seckey), enumerable: true, writable: false, }, address: { value: ticCrypto.pubkey2address(ticCrypto.seckey2pubkey(seckey)), 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 = ticCrypto.randomSecword(); return Object.assign(new TIC(ticCrypto.secword2keypair(secword).seckey), { secword: secword, }); } static fromMnemonic(secword) { if (!secword || !ticCrypto.isSecword(secword)) throw "ERROR:Invalid Secword"; return new TIC(ticCrypto.secword2keypair(secword).seckey); } 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 ticCrypto.encrypt(data, key); } static decrypt(data, key) { return ticCrypto.decrypt(data, key, { format: "json" }); //return null for wrong key } static isValidAddress(address) { return ticCrypto.isAddress(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({ seckey: this.seckey, 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({ seckey: this.seckey, pubkey: this.pubkey, }); return action; } //default key for sign&encrypt is account's seckey,other keys are optional. sign(message, key = this.seckey) { return ticCrypto.sign({ data: message, seckey: key }); } verify(message, signature) { return ticCrypto.sign({ data: message, signature, seckey: this.seckey }); } encrypt(key) { return TIC.encrypt(this, key); } } module.exports = { TIC };