@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
107 lines • 4.43 kB
JavaScript
import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/formatCurrencyUnit";
import { BigNumber } from "bignumber.js";
import { useMemo } from "react";
import { getUTXOStatus } from "./logic";
import { bitcoinPickingStrategy, } from "./types";
export const useFeesStrategy = (a, t) => {
const networkInfo = t.networkInfo;
if (!networkInfo)
return [];
const strategies = networkInfo.feeItems.items
.map(feeItem => {
return {
label: feeItem.speed,
amount: feeItem.feePerByte,
unit: a.currency.units[a.currency.units.length - 1], // Should be sat
};
})
.reverse();
return strategies;
};
function isBitcoinBasedAccount(account) {
return "bitcoinResources" in account && account.bitcoinResources !== undefined;
}
function hasUtxoStrategy(tx) {
return "utxoStrategy" in tx && tx.utxoStrategy != null;
}
function isBitcoinTransactionStatus(s) {
return "txInputs" in s;
}
// Object.keys returns string[]; cast needed for keyof typeof
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const pickingStrategyKeys = Object.keys(bitcoinPickingStrategy);
const pickingStrategyOptions = pickingStrategyKeys.map(key => ({
value: bitcoinPickingStrategy[key],
labelKey: `bitcoin.pickingStrategyLabels.${String(key)}`,
}));
function utxoToRowDisplayData(utxo, utxoStatus, context) {
const exclusionReason = utxoStatus.excluded ? utxoStatus.reason : undefined;
const isUsedInTx = (context.txInputs ?? []).some(input => input.previousOutputIndex === utxo.outputIndex && input.previousTxHash === utxo.hash);
const unconfirmed = exclusionReason === "pickPendingUtxo";
const isLastSelected = !utxoStatus.excluded && context.totalExcludedUTXOS + 1 === context.utxosLength;
const disabled = unconfirmed || isLastSelected;
const confirmations = utxo.blockHeight ? Math.max(0, context.blockHeight - utxo.blockHeight) : 0;
const formattedValue = formatCurrencyUnit(context.accountUnit, utxo.value, {
showCode: true,
disableRounding: true,
locale: context.locale,
});
const address = utxo.address ?? "";
const addressLabel = address ? `${address.slice(0, 8)}...${address.slice(-4)}` : "";
const titleLabel = `#${context.rowIndex + 1} ${addressLabel}`.trim();
return {
utxo,
titleLabel,
formattedValue,
excluded: utxoStatus.excluded,
exclusionReason,
isUsedInTx,
unconfirmed,
isLastSelected,
disabled,
confirmations,
};
}
/**
* Fetches all parameters needed to display Bitcoin UTXO rows and the picking strategy selector,
* derived from account bitcoin resources, transaction utxoStrategy, and status.
* Returns null when the account is not Bitcoin-based or the transaction has no utxoStrategy.
*/
export function useBitcoinUtxoDisplayData({ account, transaction, status, locale, }) {
return useMemo(() => {
if (!isBitcoinBasedAccount(account))
return null;
if (!hasUtxoStrategy(transaction))
return null;
if (!isBitcoinTransactionStatus(status))
return null;
const bitcoinAccount = account;
const bitcoinResources = bitcoinAccount.bitcoinResources;
if (!bitcoinResources?.utxos?.length)
return null;
const accountUnit = bitcoinAccount.currency.units[0];
const { utxoStrategy } = transaction;
const utxos = bitcoinResources.utxos;
const blockHeight = bitcoinAccount.blockHeight ?? 0;
const utxoStatuses = utxos.map(u => getUTXOStatus(u, utxoStrategy));
const totalExcludedUTXOS = utxoStatuses.filter(s => s.excluded).length;
const txInputs = status.txInputs ?? [];
const utxoRows = utxos.map((utxo, rowIndex) => utxoToRowDisplayData(utxo, utxoStatuses[rowIndex], {
rowIndex,
txInputs,
totalExcludedUTXOS,
utxosLength: utxos.length,
blockHeight,
accountUnit,
locale,
}));
return {
pickingStrategyOptions,
pickingStrategyValue: utxoStrategy.strategy,
totalExcludedUTXOS,
totalSpent: status.totalSpent ?? new BigNumber(0),
utxoRows,
};
}, [account, locale, status, transaction]);
}
//# sourceMappingURL=react.js.map