UNPKG

@ledgerhq/coin-tron

Version:
302 lines 11.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createTronWeb = createTronWeb; exports.decodeTransaction = decodeTransaction; exports.getTronResources = getTronResources; const crypto_1 = require("crypto"); const tronweb_1 = __importDefault(require("tronweb")); const config_1 = __importDefault(require("../config")); const get_1 = __importDefault(require("lodash/get")); const bignumber_js_1 = __importDefault(require("bignumber.js")); function createTronWeb(trongridUrl) { if (!trongridUrl) { trongridUrl = config_1.default.getCoinConfig().explorer.url; } const HttpProvider = tronweb_1.default.providers.HttpProvider; const fullNode = new HttpProvider(trongridUrl); const solidityNode = new HttpProvider(trongridUrl); const eventServer = new HttpProvider(trongridUrl); return new tronweb_1.default(fullNode, solidityNode, eventServer); } /** * Convert `raw_data_hex` value from {@link https://developers.tron.network/reference/createtransaction|createTransaction API} to `raw_data` value. * The function try to find the correct Protobuf deserialization to use for inner (Contract)[] object. * @param rawTx * @returns */ async function decodeTransaction(rawTx) { const { Transaction } = globalThis.TronWebProto; const transaction = Transaction.raw.deserializeBinary(Buffer.from(rawTx, "hex")); return { txID: (0, crypto_1.createHash)("sha256").update(Buffer.from(rawTx, "hex")).digest("hex"), raw_data: convertTxFromRaw(transaction), raw_data_hex: rawTx, }; } /** * @see https://github.com/tronprotocol/protocol/blob/master/core/Tron.proto#L431 * @param tx */ function convertTxFromRaw(tx) { let transactionRawData = { ref_block_bytes: convertBufferToHex(tx.getRefBlockBytes()), ref_block_hash: convertBufferToHex(tx.getRefBlockHash()), expiration: tx.getExpiration(), contract: tx.getContractList().map(convertContractFromRaw), timestamp: tx.getTimestamp(), }; if (tx.getRefBlockNum()) { transactionRawData = { ...transactionRawData, ref_block_num: tx.getRefBlockNum(), }; } if (tx.getFeeLimit()) { transactionRawData = { ...transactionRawData, fee_limit: tx.getFeeLimit(), }; } if (tx.getData()) { transactionRawData = { ...transactionRawData, data: tx.getData(), }; } if (tx.getScripts()) { transactionRawData = { ...transactionRawData, scripts: tx.getScripts(), }; } return transactionRawData; } /** * @see https://github.com/tronprotocol/protocol/blob/master/core/contract/balance_contract.proto#L32 * @param contract */ function convertContractFromRaw(contract) { let value; switch (contract.getType()) { case 1: value = convertTransferContractFromRaw(contract); break; case 2: value = convertTransferAssetContractFromRaw(contract); break; case 31: value = convertTriggerSmartContractFromRaw(contract); break; default: throw new Error(`Missing deserializer for this contract: "${contract.getParameter().getTypeUrl()}"`); } return { type: convertNumberToContractType(contract.getType()), parameter: { value, type_url: contract.getParameter().getTypeUrl(), }, // provider: contract.getProvider(), // Permission_id: contract.getPermissionId(), }; } function convertTransferContractFromRaw(contract) { const { TransferContract } = globalThis.TronWebProto; const transferContract = TransferContract.deserializeBinary(contract.getParameter().getValue()); // Expected address format in Contract are in Hex and not in Base58, // despite what (tron API portal may say)[https://developers.tron.network/reference/createtransaction] return { amount: transferContract.getAmount(), owner_address: convertBufferToHex(transferContract.getOwnerAddress()), to_address: convertBufferToHex(transferContract.getToAddress()), }; } function convertTransferAssetContractFromRaw(contract) { const { TransferAssetContract } = globalThis.TronWebProto; const transferContract = TransferAssetContract.deserializeBinary(contract.getParameter().getValue()); // Expected address format in Contract are in Hex and not in Base58, // despite what (tron API portal may say)[https://developers.tron.network/reference/transferasset] return { amount: transferContract.getAmount(), asset_name: convertBufferToString(transferContract.getAssetName()), owner_address: convertBufferToHex(transferContract.getOwnerAddress()), to_address: convertBufferToHex(transferContract.getToAddress()), }; } function convertTriggerSmartContractFromRaw(contract) { const { TriggerSmartContract } = globalThis.TronWebProto; const transferContract = TriggerSmartContract.deserializeBinary(contract.getParameter().getValue()); // Expected address format in Contract are in Hex and not in Base58, // despite what (tron API portal may say)[https://developers.tron.network/reference/triggersmartcontract] return { data: convertBufferToHex(transferContract.getData()), owner_address: convertBufferToHex(transferContract.getOwnerAddress()), contract_address: convertBufferToHex(transferContract.getContractAddress()), }; } /** * @see https://github.com/tronprotocol/protocol/blob/master/core/Tron.proto#L338 */ const CONTRACT_TYPE = { 0: "AccountCreateContract", 1: "TransferContract", 2: "TransferAssetContract", 3: "VoteAssetContract", 4: "VoteWitnessContract", 5: "WitnessCreateContract", 6: "AssetIssueContract", 8: "WitnessUpdateContract", 9: "ParticipateAssetIssueContract", 10: "AccountUpdateContract", 11: "FreezeBalanceContract", 12: "UnfreezeBalanceContract", 13: "WithdrawBalanceContract", 14: "UnfreezeAssetContract", 15: "UpdateAssetContract", 16: "ProposalCreateContract", 17: "ProposalApproveContract", 18: "ProposalDeleteContract", 19: "SetAccountIdContract", 20: "CustomContract", 30: "CreateSmartContract", 31: "TriggerSmartContract", 32: "GetContract", 33: "UpdateSettingContract", 41: "ExchangeCreateContract", 42: "ExchangeInjectContract", 43: "ExchangeWithdrawContract", 44: "ExchangeTransactionContract", 45: "UpdateEnergyLimitContract", 46: "AccountPermissionUpdateContract", 48: "ClearABIContract", 49: "UpdateBrokerageContract", 51: "ShieldedTransferContract", 52: "MarketSellAssetContract", 53: "MarketCancelOrderContract", 54: "FreezeBalanceV2Contract", 55: "UnfreezeBalanceV2Contract", 56: "WithdrawExpireUnfreezeContract", 57: "DelegateResourceContract", 58: "UnDelegateResourceContract", 59: "CancelAllUnfreezeV2Contract", }; const convertNumberToContractType = (value) => CONTRACT_TYPE[value]; /** * Convert for instance: "41FD49EDA0F23FF7EC1D03B52C3A45991C24CD440E" to "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g" * @param address */ // eslint-disable-next-line @typescript-eslint/no-unused-vars function convertHexToBase58(address) { return tronweb_1.default.address.fromHex(address); } function convertBufferToHex(address) { return tronweb_1.default.utils.bytes.byteArray2hexStr(address).toLowerCase(); } function convertBufferToString(address) { return tronweb_1.default.utils.bytes.bytesToString(address); } function getTronResources(acc) { const delegatedFrozenBandwidth = (0, get_1.default)(acc, "delegated_frozenV2_balance_for_bandwidth", undefined); const delegatedFrozenEnergy = (0, get_1.default)(acc, "account_resource.delegated_frozenV2_balance_for_energy", undefined); const frozenBalances = (0, get_1.default)(acc, "frozenV2", []); const legacyFrozenBandwidth = (0, get_1.default)(acc, "frozen[0]", undefined); const legacyFrozenEnergy = (0, get_1.default)(acc, "account_resource.frozen_balance_for_energy", undefined); const legacyFrozen = { bandwidth: legacyFrozenBandwidth ? { amount: new bignumber_js_1.default(legacyFrozenBandwidth.frozen_balance), expiredAt: new Date(legacyFrozenBandwidth.expire_time), } : undefined, energy: legacyFrozenEnergy ? { amount: new bignumber_js_1.default(legacyFrozenEnergy.frozen_balance), expiredAt: new Date(legacyFrozenEnergy.expire_time), } : undefined, }; const { frozenEnergy, frozenBandwidth } = frozenBalances.reduce((accum, cur) => { const amount = new bignumber_js_1.default(cur?.amount ?? 0); if (cur.type === "ENERGY") { accum.frozenEnergy = accum.frozenEnergy.plus(amount); } else if (cur.type === undefined) { accum.frozenBandwidth = accum.frozenBandwidth.plus(amount); } return accum; }, { frozenEnergy: new bignumber_js_1.default(0), frozenBandwidth: new bignumber_js_1.default(0), }); const unFrozenBalances = (0, get_1.default)(acc, "unfrozenV2", []); const unFrozen = unFrozenBalances ? unFrozenBalances.reduce((accum, cur) => { if (cur && cur.type === "ENERGY") { accum.energy.push({ amount: new bignumber_js_1.default(cur.unfreeze_amount), expireTime: new Date(cur.unfreeze_expire_time), }); } else if (cur) { accum.bandwidth.push({ amount: new bignumber_js_1.default(cur.unfreeze_amount), expireTime: new Date(cur.unfreeze_expire_time), }); } return accum; }, { bandwidth: [], energy: [] }) : { bandwidth: [], energy: [] }; const frozen = { bandwidth: frozenBandwidth.isGreaterThan(0) ? { amount: frozenBandwidth, } : undefined, energy: frozenEnergy.isGreaterThan(0) ? { amount: frozenEnergy, } : undefined, }; const delegatedFrozen = { bandwidth: delegatedFrozenBandwidth ? { amount: new bignumber_js_1.default(delegatedFrozenBandwidth), } : undefined, energy: delegatedFrozenEnergy ? { amount: new bignumber_js_1.default(delegatedFrozenEnergy), } : undefined, }; const tronPower = new bignumber_js_1.default((0, get_1.default)(frozen, "bandwidth.amount", 0)) .plus((0, get_1.default)(frozen, "energy.amount", 0)) .plus((0, get_1.default)(delegatedFrozen, "bandwidth.amount", 0)) .plus((0, get_1.default)(delegatedFrozen, "energy.amount", 0)) .plus((0, get_1.default)(legacyFrozen, "energy.amount", 0)) .plus((0, get_1.default)(legacyFrozen, "bandwidth.amount", 0)) .dividedBy(1_000_000) .integerValue(bignumber_js_1.default.ROUND_FLOOR) .toNumber(); const votes = (0, get_1.default)(acc, "votes", []).map((v) => ({ address: v.vote_address, voteCount: v.vote_count, })); const lastWithdrawnRewardDate = acc.latest_withdraw_time ? new Date(acc.latest_withdraw_time) : undefined; return { frozen, unFrozen, delegatedFrozen, legacyFrozen, votes, tronPower, lastWithdrawnRewardDate, }; } //# sourceMappingURL=utils.js.map