@ledgerhq/coin-tron
Version:
Ledger Tron Coin integration
83 lines • 3.31 kB
JavaScript
export function serializeCursor(cursor) {
return `${cursor.timestamp}:${cursor.txHash}`;
}
export function parseCursor(cursor) {
if (!cursor)
return null;
const sepIdx = cursor.indexOf(":");
if (sepIdx <= 0 || sepIdx === cursor.length - 1) {
throw new Error("Invalid cursor format: missing timestamp or txHash");
}
const ts = Number(cursor.slice(0, sepIdx));
const txHash = cursor.slice(sepIdx + 1);
if (!Number.isFinite(ts) || !txHash) {
throw new Error("Invalid cursor format: invalid timestamp or txHash");
}
return { txHash, timestamp: ts };
}
export function compareTxsByTimestamp(order) {
return (a, b) => {
const diff = a.date.getTime() - b.date.getTime();
return order === "asc" ? diff : -diff;
};
}
// Drops transactions at or before the cursor position.
// For transactions with the same timestamp as the cursor, we rely on TronGrid's
// consistent ordering: find the cursor txHash in the list and drop everything
// at or before that position.
export function dropTxsBeforeCursor(params) {
const { txs, order, cursor } = params;
if (!cursor)
return txs;
const cursorIndex = txs.findIndex(tx => tx.txID === cursor.txHash);
if (cursorIndex !== -1) {
return txs.slice(cursorIndex + 1);
}
return txs.filter(tx => {
const txTimestamp = tx.date.getTime();
if (order === "asc") {
return txTimestamp > cursor.timestamp;
}
else {
return txTimestamp < cursor.timestamp;
}
});
}
function getLastTx(txs) {
return txs.length > 0 ? txs[txs.length - 1] : undefined;
}
// Computes the boundary for pagination and filters transactions accordingly.
// The boundary is the "earliest" (for asc) or "latest" (for desc) of the last
// transactions from each endpoint. This ensures we don't skip transactions
// that might appear on the next page of one endpoint but chronologically
// belong before the current page of the other endpoint.
export function dropTxsAfterNextCursor(params) {
const { order, cursor, pageTxs, nativeResult, trc20Result } = params;
if (!(nativeResult.hasNextPage || trc20Result.hasNextPage)) {
return { txs: pageTxs, nextCursor: undefined };
}
const lastTxs = [
getLastTx(nativeResult.txs),
getLastTx(trc20Result.txs),
].filter((tx) => tx !== undefined);
if (lastTxs.length === 0) {
return { txs: pageTxs, nextCursor: undefined };
}
const boundaryTx = lastTxs.reduce((selected, current) => {
const diff = current.date.getTime() - selected.date.getTime();
const shouldSelect = order === "asc" ? diff < 0 : diff > 0;
return shouldSelect ? current : selected;
});
const boundaryIndex = pageTxs.findIndex(tx => tx.txID === boundaryTx.txID);
if (boundaryIndex === -1) {
return { txs: [], nextCursor: undefined };
}
const txsUpToBoundary = pageTxs.slice(0, boundaryIndex + 1);
const nextCursorCandidate = serializeCursor({
txHash: boundaryTx.txID,
timestamp: boundaryTx.date.getTime(),
});
const nextCursor = nextCursorCandidate === cursor ? undefined : nextCursorCandidate;
return { txs: txsUpToBoundary, nextCursor };
}
//# sourceMappingURL=cursor.js.map