UNPKG

@dioxide-js/silas

Version:

RPC utility for Silas

188 lines (185 loc) 7.32 kB
import { __awaiter } from '../node_modules/tslib/tslib.es6.mjs'; import { encode } from '../node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.mjs'; import { s as sha256Exports } from '../_virtual/sha256.mjs'; import base32Encode from '../_virtual/index2.mjs'; import { dataview } from '../node_modules/@dioxide-js/misc/dist/misc.es5.mjs'; import TransactionService from '../api/transactions.mjs'; import { toUint8Array } from '../utils/buffer.mjs'; import '../node_modules/bignumber.js/bignumber.mjs'; import '../_virtual/index3.mjs'; import { isValidAddress } from '../utils/validator.mjs'; import '../_virtual/index.mjs'; import '../_virtual/crc32c.mjs'; import { DIOAddress } from '../utils/address/index.mjs'; import PowDifficulty from '../utils/powDifficulty.mjs'; import OverviewService from '../api/overview.mjs'; class Transaction { constructor(opts) { this.alg = 'sm2'; this.n = 0; this.duration = { compose: 0, sign: 0, verify: 0, computedNonce: 0, all: 0, }; this.getTx = (hash) => __awaiter(this, void 0, void 0, function* () { return this.txnServices.getTransactionByHash(hash); }); const { alg = 'sm2', showTxFlow = false, apiKey, n, customSign } = opts; this.txnServices = new TransactionService({ apiKey }); this.overViewServices = new OverviewService({ apiKey }); this.alg = alg; this.customSign = customSign; this.showTxFlow = showTxFlow; if (typeof n !== 'undefined' && typeof n !== 'number') { throw 'n muse be number'; } this.n = n !== null && n !== void 0 ? n : 3; } compose(originalTxn) { return __awaiter(this, void 0, void 0, function* () { const ret = yield this.txnServices.compose(originalTxn); return ret.TxData; }); } sign(originalTxn, secretKey, option) { return __awaiter(this, void 0, void 0, function* () { const t0 = Date.now(); if (typeof secretKey === 'string') { secretKey = toUint8Array(secretKey); } const dioAddress = new DIOAddress(this.alg, secretKey); const txdata = yield this.compose(originalTxn); this.duration.compose = Date.now() - t0; const t1 = Date.now(); let pk = null; let longPK = null; if (dioAddress.alg === 'sm2') { pk = yield dioAddress.getPubicKeyFromPrivateKey(secretKey); longPK = dataview.concat(new Uint8Array([4]), pk); } else { longPK = pk = dioAddress.addressToPublicKey(originalTxn.sender); } if (!pk) { throw new Error('pk error'); } const dataWithPK = dioAddress.insertPKIntoTxData(txdata, [ { encryptedMethodOrderNumber: dioAddress.methodNum, publicKey: pk }, ]); const raw = encode(dataWithPK); const signedInfo = this.customSign ? yield this.customSign(dataWithPK, secretKey) : yield dioAddress.sign(dataWithPK, secretKey, option); this.duration.sign = Date.now() - t1; const t2 = Date.now(); this.duration.verify = Date.now() - t2; const t3 = Date.now(); const finalInfo = dataview.concat(dataWithPK, signedInfo); const powDiff = new PowDifficulty({ originTxn: finalInfo.buffer, ttl: originalTxn.ttl, n: this.n, debug: this.showTxFlow, }); const finalInfowithNonce = powDiff.getHashMixinNonnce(); this.duration.computedNonce = Date.now() - t3; const hash = base32Encode(sha256Exports.sha256.arrayBuffer(finalInfowithNonce), 'Crockford'); this.duration.all = Date.now() - t0; if (this.showTxFlow) { console.log('Tx Flow =>', this.duration); } return { composedTxDataWithPK: raw, signature: encode(signedInfo), longPK: encode(longPK), rawTxData: encode(finalInfowithNonce), hash: hash.toLowerCase(), pk: encode(pk), txFlow: this.duration, nonceTime: powDiff.t, }; }); } send(originTxn, secretKey) { return __awaiter(this, void 0, void 0, function* () { const { rawTxData } = yield this.sign(originTxn, secretKey); const ret = yield this.txnServices.sendTransaction({ txdata: rawTxData, }); return ret.Hash; }); } sendRawTx(rawTxData) { return __awaiter(this, void 0, void 0, function* () { const ret = yield this.txnServices.sendTransaction({ txdata: rawTxData, }); return ret.Hash; }); } getEstimatedFee(originTxn) { return __awaiter(this, void 0, void 0, function* () { const { function: func, args, delegatee, scale = 3, tokens } = originTxn; const overview = yield this.overViewServices.chainStatus(); const avgGasPrice = (overview === null || overview === void 0 ? void 0 : overview.AvgGasPrice) || 0; const to = args.to || args.To; const ret = yield this.txnServices.compose({ sender: to, gasprice: avgGasPrice, delegatee: delegatee, function: func, args, tokens, }); const gasLimit = ret.GasOffered.toString(); const gasFee = this.calculateGasFee({ average: avgGasPrice, scale: scale, gasLimit: Number(gasLimit), }); return gasFee; }); } calculateGasFee(options) { const { average, scale = 3, gasLimit } = options; const gasPrice = parseInt(((scale - 1) * 0.25 + 0.5) * average + '', 10); const gasFee = gasPrice * gasLimit; return gasFee; } transfer(params) { return __awaiter(this, void 0, void 0, function* () { const { to, amount, secretKey, ttl, sender } = params; if (!sender) { throw 'sender unfilled'; } if (!isValidAddress(sender)) { throw 'invalid sender'; } return this.send({ sender, gasprice: 100, function: 'core.coin.transfer', args: { To: to, Amount: amount, }, ttl, }, secretKey); }); } sk2base32Address(sk, alg) { return __awaiter(this, void 0, void 0, function* () { if (typeof sk === 'string') { sk = toUint8Array(sk); } const dioAddress = new DIOAddress(alg, sk); const { address } = yield dioAddress.generate(); return address.toLowerCase(); }); } } export { Transaction }; //# sourceMappingURL=transaction.mjs.map