UNPKG

@ledgerhq/coin-stellar

Version:
170 lines 7.25 kB
"use strict"; /* * Serialization functions from Horizon to Ledger Live types */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.rawOperationsToOperations = exports.getReservedBalance = exports.getAccountSpendableBalance = void 0; const operation_1 = require("@ledgerhq/coin-framework/operation"); const currencies_1 = require("@ledgerhq/cryptoassets/currencies"); const parseCurrencyUnit_1 = require("@ledgerhq/coin-framework/currencies/parseCurrencyUnit"); const horizon_1 = require("./horizon"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const currency = (0, currencies_1.getCryptoCurrencyById)("stellar"); async function getAccountSpendableBalance(balance, account) { const minimumBalance = getMinimumBalance(account); const { recommendedFee } = await (0, horizon_1.fetchBaseFee)(); return bignumber_js_1.default.max(balance.minus(minimumBalance).minus(recommendedFee), 0); } exports.getAccountSpendableBalance = getAccountSpendableBalance; const getMinimumBalance = (account) => { return (0, parseCurrencyUnit_1.parseCurrencyUnit)(currency.units[0], getReservedBalance(account).toString()); }; function getReservedBalance(account) { const numOfSponsoringEntries = Number(account.num_sponsoring); const numOfSponsoredEntries = Number(account.num_sponsored); const nativeAsset = account.balances?.find(b => b.asset_type === "native"); const amountInOffers = new bignumber_js_1.default(nativeAsset?.selling_liabilities || 0); const numOfEntries = new bignumber_js_1.default(account.subentry_count || 0); return new bignumber_js_1.default(horizon_1.BASE_RESERVE_MIN_COUNT) .plus(numOfEntries) .plus(numOfSponsoringEntries) .minus(numOfSponsoredEntries) .times(horizon_1.BASE_RESERVE) .plus(amountInOffers); } exports.getReservedBalance = getReservedBalance; async function rawOperationsToOperations(operations, addr, accountId, minHeight) { const supportedOperationTypes = [ "create_account", "payment", "path_payment_strict_send", "path_payment_strict_receive", "change_trust", ]; const ops = await Promise.all(operations .filter(operation => { return (operation.from === addr || operation.to === addr || operation.funder === addr || operation.account === addr || operation.trustor === addr || operation.source_account === addr); }) .filter(operation => supportedOperationTypes.includes(operation.type)) .map(operation => formatOperation(operation, accountId, addr, minHeight))); return ops.filter(op => op !== undefined); } exports.rawOperationsToOperations = rawOperationsToOperations; async function formatOperation(rawOperation, accountId, addr, minHeight) { const transaction = await rawOperation.transaction(); if (transaction.ledger_attr < minHeight) return undefined; const { hash: blockHash, closed_at: blockTime } = await transaction.ledger(); const type = getOperationType(rawOperation, addr); const value = getValue(rawOperation, transaction, type); const recipients = getRecipients(rawOperation); const memo = transaction.memo ? transaction.memo_type === "hash" || transaction.memo_type === "return" ? Buffer.from(transaction.memo, "base64").toString("hex") : transaction.memo : null; const operation = { id: (0, operation_1.encodeOperationId)(accountId, rawOperation.transaction_hash, type), accountId, fee: new bignumber_js_1.default(transaction.fee_charged), value: rawOperation?.asset_code ? new bignumber_js_1.default(transaction.fee_charged) : value, // Using type NONE to hide asset operations from the main account (show them // only on sub-account) type: rawOperation?.asset_code && !["OPT_IN", "OPT_OUT"].includes(type) ? "NONE" : type, hash: rawOperation.transaction_hash, blockHeight: transaction.ledger_attr, date: new Date(rawOperation.created_at), senders: [rawOperation.source_account], recipients, transactionSequenceNumber: Number(transaction.source_account_sequence), hasFailed: !rawOperation.transaction_successful, blockHash: blockHash, extra: { ledgerOpType: type, blockTime: new Date(blockTime), index: rawOperation.id, }, }; if (rawOperation.paging_token) { operation.extra.pagingToken = rawOperation.paging_token; } if (rawOperation.asset_code) { operation.extra.assetCode = rawOperation.asset_code; operation.extra.assetAmount = rawOperation.asset_code ? value.toString() : undefined; } if (rawOperation.asset_issuer) { operation.extra.assetIssuer = rawOperation.asset_issuer; } if (memo) { operation.extra.memo = memo; } return operation; } function getRecipients(operation) { switch (operation.type) { case "create_account": return [operation.account]; case "payment": return [operation.to_muxed || operation.to]; case "path_payment_strict_send": return [operation.to]; default: return []; } } function getValue(operation, transaction, type) { let value = new bignumber_js_1.default(0); if (!operation.transaction_successful) { return type === "IN" ? value : new bignumber_js_1.default(transaction.fee_charged || 0); } switch (operation.type) { case "create_account": value = (0, parseCurrencyUnit_1.parseCurrencyUnit)(currency.units[0], operation.starting_balance); if (type === "OUT") { value = value.plus(transaction.fee_charged); } return value; case "payment": case "path_payment_strict_send": case "path_payment_strict_receive": return (0, parseCurrencyUnit_1.parseCurrencyUnit)(currency.units[0], operation.amount); default: return type !== "IN" ? new bignumber_js_1.default(transaction.fee_charged) : value; } } function getOperationType(operation, addr) { switch (operation.type) { case "create_account": return operation.funder === addr ? "OUT" : "IN"; case "payment": if (operation.from === addr && operation.to !== addr) { return "OUT"; } return "IN"; case "path_payment_strict_send": if (operation.to === addr) return "IN"; return "OUT"; case "path_payment_strict_receive": return "IN"; case "change_trust": if (new bignumber_js_1.default(operation.limit).eq(0)) { return "OPT_OUT"; } return "OPT_IN"; default: if (operation.source_account === addr) { return "OUT"; } return "IN"; } } //# sourceMappingURL=serialization.js.map