@onekeyfe/blockchain-libs
Version:
OneKey Blockchain Libs
154 lines • 6.86 kB
JavaScript
;
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