UNPKG

@ledgerhq/coin-hedera

Version:
97 lines 4.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBlock = getBlock; const constants_1 = require("../constants"); const api_1 = require("../network/api"); const getBlockInfo_1 = require("./getBlockInfo"); const utils_1 = require("./utils"); function toHederaAsset(mirrorTransfer) { if ("token_id" in mirrorTransfer) { return { type: "hts", assetReference: mirrorTransfer.token_id, }; } return { type: "native" }; } function toBlockOperation(payerAccount, chargedFee, mirrorTransfer) { const isTokenTransfer = "token_id" in mirrorTransfer; const address = mirrorTransfer.account; const asset = toHederaAsset(mirrorTransfer); let amount = BigInt(mirrorTransfer.amount); // exclude fee from payer's operation amount (fees are accounted for separately, so operations must not represent fees) if (payerAccount === address && !isTokenTransfer) { amount += BigInt(chargedFee); } return { type: "transfer", address, asset, amount, }; } function createStakingRewardOperations(tx) { return tx.staking_reward_transfers.map(rewardTransfer => ({ type: "transfer", address: rewardTransfer.account, asset: { type: "native" }, amount: BigInt(rewardTransfer.amount), })); } async function getBlock(height) { const { start, end } = (0, utils_1.getDateRangeFromBlockHeight)(height); // block data should be immutable: do not allow querying blocks on non-finalized time range if (end.getTime() > new Date().getTime() - constants_1.FINALITY_MS) throw new Error(`Block ${height} is not available yet`); const blockInfo = await (0, getBlockInfo_1.getBlockInfo)(height); const transactions = await api_1.apiClient.getTransactionsByTimestampRange({ startTimestamp: `gte:${start.getTime() / 1000}`, endTimestamp: `lt:${end.getTime() / 1000}`, }); // analyze CRYPTOUPDATEACCOUNT transactions to distinguish staking operations from regular account updates. // this creates a map of transaction_hash -> StakingAnalysis to avoid repeated lookups. const stakingAnalyses = await Promise.all(transactions .filter(tx => tx.name === constants_1.HEDERA_TRANSACTION_NAMES.UpdateAccount) .map(async (tx) => { const payerAccount = (0, utils_1.extractFeesPayer)(tx); const analysis = await (0, utils_1.analyzeStakingOperation)(payerAccount, tx); return [tx.transaction_hash, analysis]; })); const stakingAnalysisMap = new Map(stakingAnalyses); const blockTransactions = transactions.map(tx => { const payerAccount = (0, utils_1.extractFeesPayer)(tx); const stakingAnalysis = stakingAnalysisMap.get(tx.transaction_hash); let operations; if (stakingAnalysis) { operations = [ { type: "other", operationType: stakingAnalysis.operationType, stakedNodeId: stakingAnalysis.targetStakingNodeId, previousStakedNodeId: stakingAnalysis.previousStakingNodeId, stakedAmount: stakingAnalysis.stakedAmount, }, ]; } else { const allTransfers = [...tx.transfers, ...tx.token_transfers]; operations = allTransfers.map(transfer => toBlockOperation(payerAccount, tx.charged_tx_fee, transfer)); } // add staking reward operations if present (can occur on any transaction type) const rewardOperations = createStakingRewardOperations(tx); operations.push(...rewardOperations); return { hash: tx.transaction_hash, failed: tx.result !== "SUCCESS", operations, fees: BigInt(tx.charged_tx_fee), feesPayer: payerAccount, details: { memo: (0, utils_1.getMemoFromBase64)(tx.memo_base64) }, }; }); return { info: blockInfo, transactions: blockTransactions, }; } //# sourceMappingURL=getBlock.js.map