@ledgerhq/coin-multiversx
Version:
Ledger MultiversX Coin integration
100 lines • 4.94 kB
JavaScript
import BigNumber from "bignumber.js";
import { NotEnoughBalance, RecipientRequired, InvalidAddress, FeeNotLoaded, InvalidAddressBecauseDestinationIsAlsoSource, FeeTooHigh, AmountRequired, } from "@ledgerhq/errors";
import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies";
import { getAccountCurrency } from "@ledgerhq/coin-framework/account";
import { DECIMALS_LIMIT, MIN_DELEGATION_AMOUNT } from "./constants";
import { isValidAddress, isSelfTransaction, isAmountSpentFromBalance } from "./logic";
import { MultiversXDecimalsLimitReached, MultiversXMinDelegatedAmountError, MultiversXMinUndelegatedAmountError, MultiversXDelegationBelowMinimumError, NotEnoughEGLDForFees, } from "./errors";
export const getTransactionStatus = async (account, transaction) => {
const errors = {};
const warnings = {};
if (!transaction.recipient) {
errors.recipient = new RecipientRequired();
}
else if (isSelfTransaction(account, transaction)) {
errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource();
}
else if (!isValidAddress(transaction.recipient)) {
errors.recipient = new InvalidAddress("", {
currencyName: account.currency.name,
});
}
if (!transaction.fees) {
errors.fees = new FeeNotLoaded();
}
if (!errors.amount &&
transaction.amount.eq(0) &&
!transaction.useAllAmount &&
!["unDelegate", "withdraw", "reDelegateRewards", "claimRewards"].includes(transaction.mode)) {
errors.amount = new AmountRequired();
}
let totalSpent = new BigNumber(0); // Will be in token amount for token transactions
let totalSpentEgld = new BigNumber(0); // Amount spent in main currency (EGLD)
const tokenAccount = (transaction.subAccountId &&
account.subAccounts &&
account.subAccounts.find(ta => ta.id === transaction.subAccountId)) ||
null;
if (tokenAccount) {
totalSpent = transaction.amount;
totalSpentEgld = transaction.fees || new BigNumber(0);
if (!errors.amount && transaction.amount.gt(tokenAccount.balance)) {
errors.amount = new NotEnoughBalance();
}
if (!errors.amount && !totalSpentEgld.decimalPlaces(DECIMALS_LIMIT).isEqualTo(totalSpentEgld)) {
errors.amount = new MultiversXDecimalsLimitReached();
}
}
else {
totalSpent = totalSpentEgld = isAmountSpentFromBalance(transaction.mode)
? transaction.fees?.plus(transaction.amount) || transaction.amount
: transaction.fees || new BigNumber(0);
if (transaction.mode === "send" &&
transaction.fees &&
transaction.amount.div(10).lt(transaction.fees)) {
warnings.feeTooHigh = new FeeTooHigh();
}
// All delegate and undelegate transactions must have an amount >= 1 EGLD
if (!errors.amount && transaction.amount.lt(MIN_DELEGATION_AMOUNT)) {
const formattedAmount = formatCurrencyUnit(getAccountCurrency(account).units[0], MIN_DELEGATION_AMOUNT, {
showCode: true,
});
if (transaction.mode === "delegate") {
errors.amount = new MultiversXMinDelegatedAmountError("", {
formattedAmount,
});
}
else if (transaction.mode === "unDelegate") {
errors.amount = new MultiversXMinUndelegatedAmountError("", {
formattedAmount,
});
}
}
// When undelegating, unless undelegating all, the delegation must remain >= 1 EGLD
const delegationBalance = account.multiversxResources.delegations.find(d => d.contract === transaction.recipient)?.userActiveStake;
const delegationRemainingBalance = new BigNumber(delegationBalance || 0).minus(transaction.amount);
const delegationBalanceForbidden = delegationRemainingBalance.gt(0) && delegationRemainingBalance.lt(MIN_DELEGATION_AMOUNT);
if (!errors.amount && transaction.mode === "unDelegate" && delegationBalanceForbidden) {
const formattedAmount = formatCurrencyUnit(getAccountCurrency(account).units[0], MIN_DELEGATION_AMOUNT, {
showCode: true,
});
errors.amount = new MultiversXDelegationBelowMinimumError("", {
formattedAmount,
});
}
}
if (!errors.amount && totalSpentEgld.gt(account.spendableBalance)) {
errors.amount =
tokenAccount || !["delegate", "send"].includes(transaction.mode)
? new NotEnoughEGLDForFees()
: new NotEnoughBalance();
}
return {
errors,
warnings,
estimatedFees: transaction.fees || new BigNumber(0),
amount: transaction.amount,
totalSpent,
};
};
export default getTransactionStatus;
//# sourceMappingURL=getTransactionStatus.js.map