@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
167 lines (154 loc) • 5.41 kB
text/typescript
import type { Unit } from "@ledgerhq/types-cryptoassets";
import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/formatCurrencyUnit";
import type { SendFlowTransactionActions, SendFlowUiConfig } from "../../types";
import type { Transaction, TransactionStatus } from "../../../../generated/types";
import type { Account, AccountLike } from "@ledgerhq/types-live";
import { useCallback, useMemo } from "react";
import { getChangeToReturn } from "../utils/changeToReturn";
import {
useBitcoinUtxoDisplayData,
type BitcoinUtxoDisplayData,
} from "../../../../families/bitcoin/react";
import { useSendFlowAmountReviewCore } from "../../hooks/useSendFlowAmountReviewCore";
import { useCoinControlAmountInput } from "./useCoinControlAmountInput";
export type CoinControlScreenViewModelLabels = Readonly<{
reviewCta: string;
getCtaLabel: (currency: string) => string;
strategyLabel: string;
learnMoreLabel: string;
coinToSendLabel: string;
changeToReturnLabel: string;
enterAmountPlaceholder: string;
amountToSendLabel: string;
amountInputLabel: string;
getStrategyOptionLabel: (labelKey: string) => string;
}>;
export type UseCoinControlScreenViewModelCoreParams<TNetworkFees = unknown> = Readonly<{
account: AccountLike;
parentAccount: Account | null;
transaction: Transaction;
status: TransactionStatus;
bridgePending: boolean;
uiConfig: SendFlowUiConfig;
transactionActions: SendFlowTransactionActions;
locale: string;
accountUnit: Unit;
amountError: string | undefined;
networkFees: TNetworkFees;
labels: CoinControlScreenViewModelLabels;
onLearnMoreClick: () => void;
}>;
export type CoinControlScreenViewModelCoreResult<TNetworkFees = unknown> = Readonly<{
amountValue: string | null;
onAmountChange: (rawValue: string) => void;
amountError: string | undefined;
utxoDisplayData: BitcoinUtxoDisplayData | null;
strategyOptionsWithLabels: readonly { value: number; label: string }[];
changeToReturnFormatted: string;
onSelectStrategy: (value: string) => void;
reviewLabel: string;
reviewShowIcon: boolean;
reviewDisabled: boolean;
reviewLoading: boolean;
strategyLabel: string;
onLearnMoreClick: () => void;
learnMoreLabel: string;
coinToSendLabel: string;
changeToReturnLabel: string;
enterAmountPlaceholder: string;
amountToSendLabel: string;
amountInputLabel: string;
networkFees: TNetworkFees;
}>;
export function useCoinControlScreenViewModelCore<TNetworkFees = unknown>({
account,
parentAccount,
transaction,
status,
bridgePending,
uiConfig: _uiConfig,
transactionActions,
locale,
accountUnit,
amountError,
networkFees,
labels,
onLearnMoreClick,
}: UseCoinControlScreenViewModelCoreParams<TNetworkFees>): CoinControlScreenViewModelCoreResult<TNetworkFees> {
const amountReviewCore = useSendFlowAmountReviewCore({
account,
parentAccount,
transaction,
status,
bridgePending,
transactionActions,
labels: {
getCtaLabel: labels.getCtaLabel,
reviewCta: labels.reviewCta,
},
});
const { updateTransactionWithPatch, amountComputationPending } = amountReviewCore;
const amountInput = useCoinControlAmountInput({
transaction,
status,
onUpdateTransaction: updateTransactionWithPatch,
locale,
accountUnit,
});
const utxoDisplayData = useBitcoinUtxoDisplayData({
account,
transaction,
status,
locale,
});
const changeToReturnFormatted = useMemo(() => {
const hasAmountForChange = transaction.useAllAmount || transaction.amount?.gt(0);
if (!hasAmountForChange) return "";
const changeAmount = getChangeToReturn(status);
return formatCurrencyUnit(accountUnit, changeAmount, {
showCode: true,
disableRounding: true,
locale,
});
}, [accountUnit, locale, status, transaction.amount, transaction.useAllAmount]);
const onSelectStrategy = useCallback(
(value: string) => {
const strategy = Number.parseInt(value, 10);
if (Number.isNaN(strategy)) return;
if (!("utxoStrategy" in transaction) || transaction.utxoStrategy == null) return;
updateTransactionWithPatch({
utxoStrategy: { ...transaction.utxoStrategy, strategy, excludeUTXOs: [] },
});
},
[transaction, updateTransactionWithPatch],
);
const strategyOptionsWithLabels = useMemo(() => {
const options = utxoDisplayData?.pickingStrategyOptions ?? [];
return options.map(opt => ({
value: opt.value,
label: labels.getStrategyOptionLabel(opt.labelKey),
}));
}, [utxoDisplayData?.pickingStrategyOptions, labels]);
return {
amountValue: amountInput.amountValue,
onAmountChange: amountInput.onAmountChange,
amountError,
utxoDisplayData,
strategyOptionsWithLabels,
changeToReturnFormatted,
onSelectStrategy,
reviewLabel: amountReviewCore.reviewLabel,
reviewShowIcon: amountReviewCore.reviewShowIcon,
reviewDisabled: amountReviewCore.reviewDisabled,
reviewLoading: amountComputationPending,
strategyLabel: labels.strategyLabel,
onLearnMoreClick,
learnMoreLabel: labels.learnMoreLabel,
coinToSendLabel: labels.coinToSendLabel,
changeToReturnLabel: labels.changeToReturnLabel,
enterAmountPlaceholder: labels.enterAmountPlaceholder,
amountToSendLabel: labels.amountToSendLabel,
amountInputLabel: labels.amountInputLabel,
networkFees,
};
}