UNPKG

@ledgerhq/coin-tron

Version:
74 lines 3.78 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.listOperations = listOperations; const live_promise_1 = require("@ledgerhq/live-promise"); const uniqBy_1 = __importDefault(require("lodash/uniqBy")); const network_1 = require("../network"); const trongrid_adapters_1 = require("../network/trongrid/trongrid-adapters"); const cursor_1 = require("./cursor"); const errors_1 = require("../types/errors"); async function listOperations(address, options) { const { limit, order, cursor } = options; const parsedCursor = (0, cursor_1.parseCursor)(cursor); // For asc: cursor timestamp is the new lower bound (we're moving forward in time) // For desc: cursor timestamp is the new upper bound (we're moving backward in time) // minTimestamp remains the lower bound (the stopping point) let fetchMinTimestamp; let fetchMaxTimestamp; if (order === "asc") { fetchMinTimestamp = parsedCursor ? parsedCursor.timestamp : options.minTimestamp; fetchMaxTimestamp = undefined; } else { fetchMinTimestamp = options.minTimestamp; fetchMaxTimestamp = parsedCursor?.timestamp; } // Fetch native and TRC20 transactions in parallel from TronGrid. // Both endpoints are queried with the same timestamp bounds to ensure // we can properly merge and sort them chronologically. const { nativeTxs, trc20Txs } = await (0, network_1.fetchTronAccountTxsPage)(address, { limit, minTimestamp: fetchMinTimestamp, maxTimestamp: fetchMaxTimestamp, order, }); // TronGrid occasionally returns an empty page for a valid cursor (transient API failure). // A cursor is only issued when TronGrid indicated hasNextPage=true, so 0 results here // is never a legitimate end-of-stream — throw so the client can retry with the same cursor. if (parsedCursor && nativeTxs.txs.length === 0 && trc20Txs.txs.length === 0) { throw new errors_1.TronEmptyPage(`TronGrid returned empty page for cursor ${cursor} — transient failure, retry required`); } // Merge and dedupe: some transactions appear in both native and TRC20 results const mergedTxs = (0, uniqBy_1.default)([...nativeTxs.txs, ...trc20Txs.txs], tx => tx.txID); const sortedTxs = [...mergedTxs].sort((0, cursor_1.compareTxsByTimestamp)(order)); const afterCursorTxs = (0, cursor_1.dropTxsBeforeCursor)({ txs: sortedTxs, order, cursor: parsedCursor }); const { txs: pageTxs, nextCursor } = (0, cursor_1.dropTxsAfterNextCursor)({ order, cursor, pageTxs: afterCursorTxs, nativeResult: nativeTxs, trc20Result: trc20Txs, }); const blocksByHeight = new Map(); const uniqueHeights = Array.from(new Set(pageTxs.map(tx => tx.blockHeight).filter((h) => typeof h === "number"))); await (0, live_promise_1.promiseAllBatched)(5, uniqueHeights, async (height) => { const fetchedBlock = await (0, network_1.getBlock)(height); blocksByHeight.set(height, fetchedBlock); }); const operations = pageTxs.map(tx => { const height = tx.blockHeight; if (typeof height !== "number") { throw new Error(`Transaction ${tx.txID} has no block height`); } const txBlock = blocksByHeight.get(height); if (!txBlock) { throw new Error(`Block ${height} not found for transaction ${tx.txID}`); } return (0, trongrid_adapters_1.fromTrongridTxInfoToOperation)(tx, txBlock, address); }); return { items: operations, next: nextCursor }; } //# sourceMappingURL=listOperations.js.map