UNPKG

@onekeyfe/blockchain-libs

Version:
154 lines 6.86 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StcClient = void 0; const starcoin_1 = require("@starcoin/starcoin"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const json_rpc_1 = require("../../../basic/request/json-rpc"); const provider_1 = require("../../../types/provider"); const abc_1 = require("../../abc"); const DEFAULT_GAS_LIMIT = 127845; class StcClient extends abc_1.BaseClient { constructor(url) { super(); this.rpc = new json_rpc_1.JsonRPCRequest(url); } async getInfo() { const blockInfo = await this.rpc.call('chain.info', []); const bestBlockNumber = parseInt(blockInfo.head.number); const isReady = !isNaN(bestBlockNumber) && bestBlockNumber > 0; return { bestBlockNumber, isReady }; } async getAddresses(addresses) { var _a, _b; const calls = addresses.reduce((acc, cur) => { acc.push([ 'state.get_resource', [cur, '0x1::Account::Account', { decode: true }], ]); acc.push(['txpool.next_sequence_number', [cur]]); acc.push([ 'state.get_resource', [cur, '0x1::Account::Balance<0x1::STC::STC>', { decode: true }], ]); return acc; }, []); const resp = await this.rpc.batchCall(calls); const result = []; for (let i = 0, count = resp.length; i < count; i += 3) { const [state, nextSequenceNumber, _balance] = resp.slice(i, i + 3); let info = undefined; if (typeof state !== 'undefined' && typeof nextSequenceNumber !== 'undefined' && typeof _balance !== 'undefined') { const balance = new bignumber_js_1.default((_a = _balance === null || _balance === void 0 ? void 0 : _balance.json.token.value) !== null && _a !== void 0 ? _a : 0); const existing = state === null ? false : true; const nonce = Math.max((_b = state === null || state === void 0 ? void 0 : state.json.sequence_number) !== null && _b !== void 0 ? _b : 0, nextSequenceNumber !== null && nextSequenceNumber !== void 0 ? nextSequenceNumber : 0); info = { balance, nonce, existing }; } result.push(info); } return result; } async getBalances(requests) { const calls = requests.map((req) => { var _a; return [ 'state.get_resource', [ req.address, `0x1::Account::Balance<${(_a = req.coin.tokenAddress) !== null && _a !== void 0 ? _a : '0x1::STC::STC'}>`, { decode: true }, ], ]; }); const resps = await this.rpc.batchCall(calls); return resps.map((resp) => { var _a; let balance = undefined; if (typeof resp !== 'undefined') { balance = new bignumber_js_1.default((_a = resp === null || resp === void 0 ? void 0 : resp.json.token.value) !== null && _a !== void 0 ? _a : 0); } return balance; }); } async getTransactionStatuses(txids) { const calls = txids.reduce((acc, cur) => { acc.push(['txpool.pending_txn', [cur]]); acc.push(['chain.get_transaction_info', [cur]]); return acc; }, []); const resp = await this.rpc.batchCall(calls); const result = []; for (let i = 0, count = resp.length; i < count; i += 2) { const [pendingTx, receipt] = resp.slice(i, i + 2); let status = undefined; if (typeof receipt !== 'undefined' && typeof pendingTx !== 'undefined') { if (pendingTx === null && receipt === null) { status = provider_1.TransactionStatus.NOT_FOUND; } else if (pendingTx) { status = provider_1.TransactionStatus.PENDING; } else { status = (receipt === null || receipt === void 0 ? void 0 : receipt.status) === 'Executed' ? provider_1.TransactionStatus.CONFIRM_AND_SUCCESS : provider_1.TransactionStatus.CONFIRM_BUT_FAILED; } } result.push(status); } return result; } async getFeePricePerUnit() { const resp = await this.rpc.call('txpool.gas_price', []); const price = parseInt(resp !== null && resp !== void 0 ? resp : '1'); return { normal: { price: new bignumber_js_1.default(price) }, }; } async broadcastTransaction(rawTx) { return await this.rpc.call('txpool.submit_hex_transaction', [rawTx]); } async estimateGasLimitAndTokensChangedTo(rawUserTransactionHex, senderPublicKeyHex) { const addressHex = starcoin_1.encoding.publicKeyToAddress(senderPublicKeyHex); const resp = await this.rpc.call('contract.dry_run_raw', [ rawUserTransactionHex, senderPublicKeyHex, ]); let feeLimit; let tokensChangedTo; if ((resp === null || resp === void 0 ? void 0 : resp.status) === 'Executed') { feeLimit = new bignumber_js_1.default(parseInt(resp.gas_used)); tokensChangedTo = this.getTokensChangedTo(resp, addressHex); } else { if (isNaN(parseInt(resp === null || resp === void 0 ? void 0 : resp.gas_used))) { feeLimit = new bignumber_js_1.default(DEFAULT_GAS_LIMIT); } else { // In case of insufficient balance. feeLimit = new bignumber_js_1.default(parseInt(resp === null || resp === void 0 ? void 0 : resp.gas_used)); } tokensChangedTo = {}; } return { feeLimit, tokensChangedTo }; } getTokensChangedTo(dryRunRawResult, addressHex) { const matches = dryRunRawResult.write_set.reduce((acc, item) => { var _a; const reg = /^(0x[a-zA-Z0-9]{32})\/[01]\/0x00000000000000000000000000000001::Account::Balance<(.*)>$/i; const result = item.access_path.match(reg); if (result && result.length === 3 && addressHex === result[1]) { acc[result[2]] = new bignumber_js_1.default((_a = item.value.Resource.json.token.value) !== null && _a !== void 0 ? _a : 0).toFixed(); } return acc; }, {}); return matches; } } exports.StcClient = StcClient; //# sourceMappingURL=starcoin.js.map