UNPKG

@ledgerhq/coin-celo

Version:
108 lines 4.77 kB
import { AmountRequired, FeeNotLoaded, InvalidAddress, InvalidAddressBecauseDestinationIsAlsoSource, NotEnoughBalance, RecipientRequired, } from "@ledgerhq/errors"; import { BigNumber } from "bignumber.js"; import { isValidAddress } from "@celo/utils/lib/address"; import { getPendingStakingOperationAmounts, getVote } from "../logic"; import { CeloAllFundsWarning } from "../errors"; import { celoKit } from "../network/sdk"; import { findSubAccountById } from "@ledgerhq/coin-framework/account/index"; const kit = celoKit(); // Arbitrary buffer for paying fees of next transactions. 0.05 Celo for ~100 transactions const FEES_SAFETY_BUFFER = new BigNumber(5000000000000000); export const getTransactionStatus = async (account, transaction) => { const errors = {}; const warnings = {}; const useAllAmount = !!transaction.useAllAmount; if (account.freshAddress === transaction.recipient) { errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource(); } if (!transaction.fees || !transaction.fees.gt(0)) { errors.fees = new FeeNotLoaded(); } const pendingOperationAmounts = getPendingStakingOperationAmounts(account); const lockedGold = await kit.contracts.getLockedGold(); const nonvotingLockedGoldBalance = await lockedGold.getAccountNonvotingLockedGold(account.freshAddress); // Deduct pending vote operations from the non-voting locked balance const totalNonVotingLockedBalance = nonvotingLockedGoldBalance.minus(pendingOperationAmounts.vote); // Deduct pending lock operations from the spendable balance const totalSpendableBalance = account.spendableBalance.minus(pendingOperationAmounts.lock); const estimatedFees = transaction.fees || new BigNumber(0); const tokenAccount = findSubAccountById(account, transaction.subAccountId || ""); const isTokenTransaction = tokenAccount?.type === "TokenAccount"; let amount = new BigNumber(0); if (useAllAmount && (transaction.mode === "unlock" || transaction.mode === "vote")) { amount = totalNonVotingLockedBalance ?? new BigNumber(0); } else if (useAllAmount && transaction.mode === "revoke") { const revoke = getVote(account, transaction.recipient, transaction.index); if (revoke?.amount) amount = revoke.amount; } else if (useAllAmount) { amount = isTokenTransaction ? tokenAccount.spendableBalance : totalSpendableBalance.minus(estimatedFees); } else { amount = new BigNumber(transaction.amount); } if (amount.lt(0)) amount = new BigNumber(0); if ((account.celoResources?.lockedBalance.gt(0) || !!account.celoResources?.pendingWithdrawals?.length) && (transaction.useAllAmount || totalSpendableBalance.minus(amount).lt(FEES_SAFETY_BUFFER)) && ["send", "lock"].includes(transaction.mode)) { warnings.amount = new CeloAllFundsWarning(); } if (!["register", "withdraw", "activate"].includes(transaction.mode)) { if (amount.lte(0) && !useAllAmount) { errors.amount = new AmountRequired(); } } const totalSpent = amount.plus(estimatedFees); if (transaction.mode === "unlock" || transaction.mode === "vote") { if (!errors.amount && totalNonVotingLockedBalance && amount.gt(totalNonVotingLockedBalance)) { errors.amount = new NotEnoughBalance(); } } else if (transaction.mode === "revoke") { const revoke = getVote(account, transaction.recipient, transaction.index); if (!errors.amount && revoke?.amount && amount.gt(revoke.amount)) errors.amount = new NotEnoughBalance(); } else { if (!errors.amount && totalSpent.gt(totalSpendableBalance)) { errors.amount = new NotEnoughBalance(); } } if (!errors.amount && totalSpendableBalance.lt(estimatedFees)) { errors.amount = new NotEnoughBalance(); } if (transaction.mode === "send") { if (!transaction.recipient && !errors.recipient) { errors.recipient = new RecipientRequired(); } else if (!isValidAddress(transaction.recipient) && !errors.recipient) { errors.recipient = new InvalidAddress("", { currencyName: account.currency.name, }); } if (isTokenTransaction) { return { errors, warnings, estimatedFees, amount, totalSpent: amount, }; } } return { errors, warnings, estimatedFees, amount, totalSpent, }; }; export default getTransactionStatus; //# sourceMappingURL=getTransactionStatus.js.map