UNPKG

@ledgerhq/coin-hedera

Version:
192 lines 9.51 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createApi = createApi; const rejectBalanceOptions_1 = require("@ledgerhq/coin-module-framework/api/getBalance/rejectBalanceOptions"); const craftTransactionData_1 = require("@ledgerhq/coin-module-framework/logic/craftTransactionData"); const currencies_1 = require("@ledgerhq/cryptoassets/currencies"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const invariant_1 = __importDefault(require("invariant")); const validateAddress_1 = require("../bridge/validateAddress"); const config_1 = __importDefault(require("../config")); const constants_1 = require("../constants"); const logic_1 = require("../logic"); const utils_1 = require("../logic/utils"); const api_1 = require("../network/api"); const utils_2 = require("../network/utils"); function createApi(config, currencyId) { config_1.default.setCoinConfig(() => ({ ...config, status: { type: "active" } })); const currency = (0, currencies_1.getCryptoCurrencyById)(currencyId); return { broadcast: async (tx) => { const response = await (0, logic_1.broadcast)(tx); return Buffer.from(response.transactionHash).toString("base64"); }, combine: logic_1.combine, craftTransaction: async (txIntent, customFees) => { (0, invariant_1.default)(!txIntent.useAllAmount, "useAllAmount is not supported"); const { serializedTx } = await (0, logic_1.craftTransaction)({ txIntent, ...(customFees && { customFees }), config, }); return { transaction: serializedTx, }; }, craftRawTransaction: (_transaction, _sender, _publicKey, _sequence) => { throw new Error("craftRawTransaction is not supported"); }, estimateFees: async (txIntent) => { let estimateFeesParams; const operationType = (0, utils_1.mapIntentToSDKOperation)(txIntent); if (operationType === constants_1.HEDERA_OPERATION_TYPES.ContractCall) { estimateFeesParams = { operationType, txIntent }; } else { estimateFeesParams = { currency, operationType }; } const estimatedFee = await (0, logic_1.estimateFees)(estimateFeesParams); return { value: BigInt(estimatedFee.tinybars.toString()), }; }, getBalance: (address, options) => (0, rejectBalanceOptions_1.rejectBalanceOptions)(() => (0, logic_1.getBalance)(currency, address), options), getBlock: height => { if (config.useHgraphForErc20) { return (0, logic_1.getBlockV2)(height); } return (0, logic_1.getBlock)(height); }, getBlockInfo: height => (0, logic_1.getBlockInfo)(height), lastBlock: () => { if (config.useHgraphForErc20) { return (0, logic_1.lastBlockV2)(); } return (0, logic_1.lastBlock)(); }, listOperations: async (address, { cursor, limit, order, minHeight }) => { (0, invariant_1.default)(minHeight === 0, "minHeight is not supported"); let latestAccountOperations; if (config.useHgraphForErc20) { const evmAddress = await (0, utils_1.toEVMAddress)(address); (0, invariant_1.default)(evmAddress, `hedera: evm address is missing for ${address}`); const [mirrorTokens, erc20TokenBalances] = await Promise.all([ api_1.apiClient.getAccountTokens(address), (0, utils_2.getERC20BalancesForAccountV2)(address), ]); latestAccountOperations = await (0, logic_1.listOperationsV2)({ currency, address, evmAddress, mirrorTokens, ...(typeof cursor === "string" && { cursor }), ...(typeof limit === "number" && { limit }), ...(typeof order === "string" && { order }), erc20Tokens: erc20TokenBalances, fetchAllPages: false, skipFeesForTokenOperations: true, useEncodedHash: false, useSyntheticBlocks: true, }); } else { const mirrorTokens = await api_1.apiClient.getAccountTokens(address); latestAccountOperations = await (0, logic_1.listOperations)({ currency, address, cursor, limit, order, mirrorTokens, fetchAllPages: false, skipFeesForTokenOperations: true, useEncodedHash: false, useSyntheticBlocks: true, }); } const liveOperations = [ ...latestAccountOperations.coinOperations, ...latestAccountOperations.tokenOperations, ]; const sortedLiveOperations = [...liveOperations].sort((a, b) => { const aConsensusTime = a.extra.consensusTimestamp; const bConsensusTime = b.extra.consensusTimestamp; const aTime = a.date.getTime(); const bTime = b.date.getTime(); const dateDiff = order === "desc" ? bTime - aTime : aTime - bTime; if (aConsensusTime && bConsensusTime) { const aTime = new bignumber_js_1.default(aConsensusTime); const bTime = new bignumber_js_1.default(bConsensusTime); const timeDiff = order === "desc" ? bTime.minus(aTime) : aTime.minus(bTime); // REWARD operations have the same consensus time as operation that triggered them return timeDiff.isZero() ? dateDiff : timeDiff.toNumber(); } return dateDiff; }); const coinFrameworkOperations = sortedLiveOperations.map(liveOp => { const asset = liveOp.contract ? { type: liveOp.standard ?? "token", assetReference: liveOp.contract, assetOwner: address, } : { type: "native" }; // Prefer inferred payer from operation extra, fallback to transaction_id parsing for legacy ops. let feesPayer = liveOp.extra?.feesPayer; if (!feesPayer && liveOp.extra?.transactionId) feesPayer = (0, utils_1.extractInitiator)(liveOp.extra.transactionId); // REWARD operations append a suffix to the tx.hash to ensure uniqueness const hash = liveOp.type === "REWARD" ? liveOp.hash.replace(constants_1.STAKING_REWARD_HASH_SUFFIX, "") : liveOp.hash; return { id: liveOp.id, type: liveOp.type, senders: liveOp.senders, recipients: liveOp.recipients, value: (0, utils_1.getOperationValue)({ asset, operation: liveOp }), asset, details: { ...liveOp.extra, ledgerOpType: liveOp.type, ...(asset.type !== "native" && { assetAmount: liveOp.value.toFixed(0) }), ...(liveOp.extra.stakedAmount && { stakedAmount: BigInt(liveOp.extra.stakedAmount.toFixed(0)), }), }, tx: { hash, fees: BigInt(liveOp.fee.toFixed(0)), ...(feesPayer && { feesPayer }), date: liveOp.date, block: { height: liveOp.blockHeight ?? constants_1.HARDCODED_BLOCK_HEIGHT, hash: liveOp.blockHash ?? (0, utils_1.getBlockHash)(liveOp.blockHeight ?? constants_1.HARDCODED_BLOCK_HEIGHT), time: liveOp.date, }, failed: liveOp.hasFailed ?? false, }, }; }); return { items: coinFrameworkOperations, next: latestAccountOperations.nextCursor || undefined, }; }, getValidators: cursor => (0, logic_1.getValidators)(cursor), getStakes: async (address) => (0, logic_1.getStakes)(address), getRewards: async (address, cursor) => (0, logic_1.getRewards)(address, cursor), validateIntent: async (_transactionIntent, _balances, _customFees) => { throw new Error("validateIntent is not supported"); }, getNextSequence: async (_address) => { throw new Error("getNextSequence is not supported"); }, validateAddress: validateAddress_1.validateAddress, craftTransactionData: craftTransactionData_1.craftTransactionData, }; } //# sourceMappingURL=index.js.map