@ledgerhq/coin-ton
Version:
114 lines • 4.76 kB
JavaScript
import { isTokenAccount } from "@ledgerhq/coin-framework/account/index";
import { AmountRequired, InvalidAddress, InvalidAddressBecauseDestinationIsAlsoSource, NotEnoughBalance, RecipientRequired, } from "@ledgerhq/errors";
import { toNano } from "@ton/core";
import BigNumber from "bignumber.js";
import { MINIMUM_REQUIRED_BALANCE, TOKEN_TRANSFER_MAX_FEE } from "./constants";
import { TonCommentInvalid, TonExcessFee, TonMinimumRequired, TonNotEnoughBalanceInParentAccount, } from "./errors";
import { addressesAreEqual, commentIsValid, findSubAccountById, isAddressValid } from "./utils";
/**
* Validate an address for account transaction
*/
const validateRecipient = (account, tx) => {
const errors = {};
if (tx.recipient) {
// Check if recipient is matching the format of account valid eth address or not
const isRecipientValidate = isAddressValid(tx.recipient);
if (!isRecipientValidate) {
errors.recipient = new InvalidAddress("", {
currencyName: account.currency.name,
});
}
if (addressesAreEqual(account.freshAddress, tx.recipient)) {
errors.recipient = new InvalidAddressBecauseDestinationIsAlsoSource("", {
currencyName: account.currency.name,
});
}
}
else {
errors.recipient = new RecipientRequired(); // ""
}
return [errors];
};
/**
* Validate the sender address for account transaction
*/
const validateSender = (account) => {
const errors = {};
// Check if sender is matching the format of account valid ton address or not
const isSenderValidate = isAddressValid(account.freshAddress);
if (!isSenderValidate) {
errors.sender = new InvalidAddress("", {
currencyName: account.currency.name,
});
}
return [errors];
};
const validateAmount = (account, transaction, totalSpent) => {
const errors = {};
const warnings = {};
const subAccount = findSubAccountById(account, transaction.subAccountId ?? "");
const tokenTransfer = Boolean(subAccount && isTokenAccount(subAccount));
// if no amount or 0
if (!transaction.amount || transaction.amount.isZero()) {
errors.amount = new AmountRequired(); // "Amount required"
}
else if (totalSpent.isGreaterThan(tokenTransfer && subAccount ? subAccount?.spendableBalance : account.balance)) {
// if not enough to make the transaction
errors.amount = new NotEnoughBalance(); // "Sorry, insufficient funds"
}
if (tokenTransfer) {
if (account.balance.isLessThan(new BigNumber(toNano(TOKEN_TRANSFER_MAX_FEE).toString()))) {
// if not enough for the fee to make the transaction
errors.amount = new TonNotEnoughBalanceInParentAccount(); // "Sorry, insufficient funds in the parent account"
}
warnings.amount = new TonExcessFee();
}
else {
if (account.balance.isLessThan(new BigNumber(toNano(MINIMUM_REQUIRED_BALANCE).toString()))) {
errors.amount = new TonMinimumRequired();
}
}
return [errors, warnings];
};
const validateComment = (transaction) => {
const errors = {};
// if the comment isn'transaction encrypted, it should be valid
if (transaction.comment.isEncrypted || !commentIsValid(transaction.comment)) {
// We use transaction as an error here.
// It will be usefull to block a memo wrong format
// on the ledger-live mobile
errors.transaction = new TonCommentInvalid();
}
return [errors];
};
export const getTransactionStatus = async (account, transaction) => {
const subAccount = findSubAccountById(account, transaction.subAccountId ?? "");
const tokenTransfer = Boolean(subAccount && isTokenAccount(subAccount));
const totalSpent = tokenTransfer ? transaction.amount : transaction.amount.plus(transaction.fees);
// Recipient related errors and warnings
const [recipientErr] = validateRecipient(account, transaction);
// Sender related errors and warnings
const [senderErr] = validateSender(account);
// Amount related errors and warnings
const [amountErr, amountWarn] = validateAmount(account, transaction, totalSpent);
// Transaction related errors and warnings
const [transactionErr] = validateComment(transaction);
const errors = {
...recipientErr,
...senderErr,
...amountErr,
...transactionErr,
};
const warnings = {
...amountWarn,
};
return {
amount: transaction.amount,
errors,
warnings,
estimatedFees: transaction.fees,
totalSpent,
};
};
export default getTransactionStatus;
//# sourceMappingURL=getTransactionStatus.js.map