UNPKG

@ledgerhq/coin-algorand

Version:
132 lines 5.73 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTransactionStatus = void 0; const algosdk_1 = require("algosdk"); const bignumber_js_1 = require("bignumber.js"); const invariant_1 = __importDefault(require("invariant")); const errors_1 = require("@ledgerhq/errors"); const errors_2 = require("@ledgerhq/errors"); const errors_3 = require("./errors"); const logic_1 = require("./logic"); const tokens_1 = require("./tokens"); /* * Here are the list of the differents things we check * - Check if recipient is the same in case of send * - Check if recipient is valid * - Check if amounts are set * - Check if fees are loaded * - Check if is a send Max and set the amount * - Check if Token is already optin at the recipient * - Check if memo is too long */ const getTransactionStatus = async (account, transaction) => { const errors = {}; const warnings = {}; const tokenAccount = !transaction.subAccountId ? null : account.subAccounts && account.subAccounts.find(ta => ta.id === transaction.subAccountId); if (!transaction.recipient) { errors.recipient = new errors_1.RecipientRequired(); } else if (!(await (0, algosdk_1.isValidAddress)(transaction.recipient))) { errors.recipient = new errors_1.InvalidAddress("", { currencyName: account.currency.name, }); } else if (transaction.mode === "send" && account.freshAddress === transaction.recipient) { errors.recipient = new errors_1.InvalidAddressBecauseDestinationIsAlsoSource(); } const estimatedFees = transaction.fees || new bignumber_js_1.BigNumber(0); let amount = transaction.amount; let totalSpent = estimatedFees; (0, invariant_1.default)(account.algorandResources, "Algorand family expected"); const algorandResources = account.algorandResources; const algoSpendableBalance = (0, logic_1.computeAlgoMaxSpendable)({ accountBalance: account.balance, nbAccountAssets: algorandResources.nbAssets, mode: transaction.mode, }); switch (transaction.mode) { case "send": { if (amount.lte(0) && !transaction.useAllAmount) { errors.amount = new errors_1.AmountRequired(); } if (!transaction.fees || !transaction.fees.gt(0)) { errors.fees = new errors_1.FeeNotLoaded(); } if (tokenAccount && tokenAccount.type === "TokenAccount" && !errors.recipient && !(await (0, logic_1.recipientHasAsset)(transaction.recipient, (0, tokens_1.extractTokenId)(tokenAccount.token.id)))) { errors.recipient = new errors_3.AlgorandASANotOptInInRecipient(); } amount = transaction.useAllAmount ? tokenAccount ? tokenAccount.balance : algoSpendableBalance.minus(estimatedFees) : amount; if (amount.lt(0)) { amount = new bignumber_js_1.BigNumber(0); } totalSpent = tokenAccount ? amount : amount.plus(estimatedFees); if (!errors.recipient && !(await (0, logic_1.isAmountValid)(transaction.recipient, amount))) { errors.amount = new errors_1.NotEnoughBalanceBecauseDestinationNotCreated("", { minimalAmount: "0.1 ALGO", }); } if (!tokenAccount && amount.gt(0) && estimatedFees.times(10).gt(amount)) { warnings.feeTooHigh = new errors_1.FeeTooHigh(); } if ((amount.lte(0) && transaction.useAllAmount) || // if use all Amount sets an amount at 0 (!errors.recipient && !errors.amount && tokenAccount ? totalSpent.gt(tokenAccount.balance) : totalSpent.gt(algoSpendableBalance)) // if spendable balance lower than total ) { errors.amount = new errors_1.NotEnoughBalance(); } // if spendable balance lower than fees for token if (!errors.amount && tokenAccount && algoSpendableBalance.lt(estimatedFees)) { errors.amount = new errors_1.NotEnoughBalanceInParentAccount(); } break; } case "optIn": { if (!transaction.fees || !transaction.fees.gt(0)) { errors.fees = new errors_1.FeeNotLoaded(); } // This error doesn't need to be translate, // it will use to block until the user choose an assetId if (!transaction.assetId) { errors.assetId = new Error("Asset Id is not set"); } if (algoSpendableBalance.lt(estimatedFees)) { errors.amount = new errors_1.NotEnoughBalance(); } break; } case "claimReward": { if (algoSpendableBalance.lt(totalSpent)) { errors.amount = new errors_1.NotEnoughBalance(); } if (estimatedFees.gt(algorandResources.rewards)) { warnings.claimReward = new errors_2.ClaimRewardsFeesWarning(); } break; } } if (transaction.memo && transaction.memo.length > logic_1.ALGORAND_MAX_MEMO_SIZE) { throw new Error("Memo is too long"); } return { errors, warnings, estimatedFees, amount, totalSpent, }; }; exports.getTransactionStatus = getTransactionStatus; //# sourceMappingURL=getTransactionStatus.js.map