@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
164 lines • 7.32 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSwapTransaction = exports.useFromAmountStatusMessage = exports.selectorStateDefaultValues = void 0;
const index_1 = require("@ledgerhq/ledger-wallet-framework/account/index");
const index_2 = require("@ledgerhq/coin-framework/currencies/index");
const errors_1 = require("@ledgerhq/errors");
const react_1 = require("react");
const useBridgeTransaction_1 = __importDefault(require("../../../bridge/useBridgeTransaction"));
const useFromState_1 = require("./useFromState");
const useReverseAccounts_1 = require("./useReverseAccounts");
const useToState_1 = require("./useToState");
const useUpdateMaxAmount_1 = require("./useUpdateMaxAmount");
const useProviderRates_1 = require("./v5/useProviderRates");
exports.selectorStateDefaultValues = {
currency: undefined,
account: undefined,
parentAccount: undefined,
amount: undefined,
};
const useFromAmountStatusMessage = ({ account, parentAccount, status, transaction },
// The order of errors/warnings here will determine the precedence
statusTypeToInclude, sponsored) => {
const statusEntries = (0, react_1.useMemo)(() => statusTypeToInclude.map(statusType => (status.errors || status.warnings)?.[statusType]), [status.errors, status.warnings, statusTypeToInclude]);
const currency = (0, react_1.useMemo)(() => {
if (parentAccount) {
return (0, index_1.getAccountCurrency)(parentAccount);
}
if (account) {
return (0, index_1.getAccountCurrency)(account);
}
return undefined;
}, [account, parentAccount]);
const estimatedFees = (0, react_1.useMemo)(() => {
return status.estimatedFees;
}, [status]);
return (0, react_1.useMemo)(() => {
// don't return an error/warning if we have no transaction or if transaction.amount <= 0
if (transaction?.amount.lte(0))
return undefined;
const [relevantStatus] = statusEntries
.filter(maybeError => maybeError instanceof Error)
.filter(errorOrWarning => !(errorOrWarning instanceof errors_1.AmountRequired));
const isRelevantStatus = relevantStatus instanceof errors_1.NotEnoughGas;
// Skip gas validation for sponsored transactions since gas fees are covered by sponsor
if (isRelevantStatus && currency && estimatedFees && !sponsored) {
const query = new URLSearchParams({
// get account id first and set it equal to account.
// if parent account exists then overwrite the former.
...(account?.id ? { account: account.id } : {}),
...(parentAccount?.id ? { account: parentAccount.id } : {}),
});
return new errors_1.NotEnoughGasSwap(undefined, {
fees: (0, index_2.formatCurrencyUnit)((0, index_1.getFeesUnit)(currency), estimatedFees),
ticker: currency.ticker,
cryptoName: currency.name,
links: [`ledgerlive://buy?${query.toString()}`],
});
}
// convert to swap variation of error to display correct message to frontend.
if (relevantStatus instanceof errors_1.FeeNotLoaded) {
return new errors_1.NotEnoughBalanceSwap();
}
return relevantStatus;
}, [
statusEntries,
currency,
estimatedFees,
transaction?.amount,
account?.id,
parentAccount?.id,
sponsored,
]);
};
exports.useFromAmountStatusMessage = useFromAmountStatusMessage;
const useSwapTransaction = ({ accounts, setExchangeRate, defaultCurrency = exports.selectorStateDefaultValues.currency, defaultAccount = exports.selectorStateDefaultValues.account, defaultParentAccount = exports.selectorStateDefaultValues.parentAccount, onNoRates, excludeFixedRates, refreshRate, allowRefresh, isEnabled, sponsored, }) => {
const bridgeTransaction = (0, useBridgeTransaction_1.default)(() => ({
account: defaultAccount,
parentAccount: defaultParentAccount,
}));
const { fromState, setFromAccount, setFromAmount } = (0, useFromState_1.useFromState)({
accounts,
defaultCurrency,
defaultAccount,
defaultParentAccount,
bridgeTransaction,
});
const { toState, setToAccount, setToAmount, setToCurrency, targetAccounts } = (0, useToState_1.useToState)({
accounts,
fromCurrencyAccount: fromState.account,
});
const { account: fromAccount, parentAccount: fromParentAccount, currency: fromCurrency, } = fromState;
const { account: toAccount } = toState;
const fromAmountError = (0, exports.useFromAmountStatusMessage)(bridgeTransaction, ["gasPrice", "amount", "gasLimit"], sponsored);
const { isSwapReversable, reverseSwap } = (0, useReverseAccounts_1.useReverseAccounts)({
accounts,
fromAccount,
toAccount,
fromParentAccount,
fromCurrency,
setFromAccount,
setToAccount,
});
const { isMaxEnabled, toggleMax, isMaxLoading } = (0, useUpdateMaxAmount_1.useUpdateMaxAmount)({
setFromAmount,
account: fromAccount,
parentAccount: fromParentAccount,
bridge: bridgeTransaction,
});
const { rates, refetchRates, updateSelectedRate, countdown } = (0, useProviderRates_1.useProviderRates)({
fromState,
toState,
onNoRates,
setExchangeRate,
countdown: refreshRate,
allowRefresh,
isEnabled,
});
const [maxAmountLowerThanBallanceError, setMaxAmountLowerThanBallanceError] = (0, react_1.useState)(undefined);
(0, react_1.useEffect)(() => {
const timer = setTimeout(() => {
// libs/coin-modules/coin-evm/src/prepareTransaction.ts L47
// returns 0 if the balance - fees is less than 0
const error = isMaxEnabled && !isMaxLoading && fromState.amount?.eq(0)
? new errors_1.NotEnoughBalanceSwap()
: undefined;
setMaxAmountLowerThanBallanceError(error);
}, isMaxEnabled ? 500 : 0);
// Cleanup the timeout if the component unmounts or the dependencies change
return () => clearTimeout(timer);
}, [isMaxEnabled, isMaxLoading, fromState]);
return {
...bridgeTransaction,
swap: {
to: toState,
from: fromState,
isMaxEnabled,
isMaxLoading,
isSwapReversable,
rates: rates.value && excludeFixedRates
? {
...rates,
value: rates.value.filter(v => v.tradeMethod !== "fixed"),
}
: rates,
countdown,
refetchRates,
updateSelectedRate,
targetAccounts,
},
setFromAmount,
toggleMax,
fromAmountError: maxAmountLowerThanBallanceError || fromAmountError,
setToAccount,
setToCurrency,
setFromAccount,
setToAmount,
reverseSwap,
};
};
exports.useSwapTransaction = useSwapTransaction;
//# sourceMappingURL=useSwapTransaction.js.map