From 1e61cd77f8a028d92bdf408f94c1ca268efe0b0e Mon Sep 17 00:00:00 2001 From: ManuGowda Date: Mon, 2 Oct 2023 13:52:22 +0200 Subject: [PATCH 1/7] :bug: Fix transaction incoming and outgoing icon --- src/modules/transaction/api/index.test.js | 8 ++++---- .../components/TransactionDetails/amount.js | 4 ++-- .../components/TransactionRow/components.js | 10 +++++----- src/modules/transaction/utils/transaction.js | 6 +++--- .../components/RequestSignSummary/summary.test.js | 2 +- .../components/signMultisigSummary/summary.test.js | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/modules/transaction/api/index.test.js b/src/modules/transaction/api/index.test.js index cb99a83619..a5223e21df 100644 --- a/src/modules/transaction/api/index.test.js +++ b/src/modules/transaction/api/index.test.js @@ -1,6 +1,6 @@ /* eslint-disable max-lines */ import { MODULE_COMMANDS_NAME_MAP } from 'src/modules/transaction/configuration/moduleCommand'; -import { getTotalSpendingAmount } from '@transaction/utils/transaction'; +import { getTransactionAmount } from '@transaction/utils/transaction'; import http from 'src/utils/api/http'; import moduleCommandSchemas from '@tests/constants/schemas'; import accounts from '@tests/constants/wallets'; @@ -35,7 +35,7 @@ describe('API: LSK Transactions', () => { fee: '0', }; - describe('getTotalSpendingAmount', () => { + describe('getTransactionAmount', () => { it('should return amount of transfer in Beddows', () => { const tx = { module: 'token', @@ -43,7 +43,7 @@ describe('API: LSK Transactions', () => { params: { amount: '100000000' }, }; - expect(getTotalSpendingAmount(tx)).toEqual(tx.params.amount); + expect(getTransactionAmount(tx)).toEqual(tx.params.amount); }); it('should return amount of stakes in Beddows', () => { @@ -65,7 +65,7 @@ describe('API: LSK Transactions', () => { }, }; - expect(getTotalSpendingAmount(tx)).toEqual('200000000'); + expect(getTransactionAmount(tx)).toEqual('200000000'); }); }); diff --git a/src/modules/transaction/components/TransactionDetails/amount.js b/src/modules/transaction/components/TransactionDetails/amount.js index 84f0cfda6f..c28260ca7b 100644 --- a/src/modules/transaction/components/TransactionDetails/amount.js +++ b/src/modules/transaction/components/TransactionDetails/amount.js @@ -1,5 +1,5 @@ import React from 'react'; -import { getTotalSpendingAmount } from '@transaction/utils/transaction'; +import { getTransactionAmount } from '@transaction/utils/transaction'; import DiscreetMode from 'src/modules/common/components/discreetMode'; import { extractAddressFromPublicKey } from '@wallet/utils/account'; import TokenAmount from '@token/fungible/components/tokenAmount'; @@ -18,7 +18,7 @@ const Amount = ({ t }) => { - + diff --git a/src/modules/transaction/components/TransactionRow/components.js b/src/modules/transaction/components/TransactionRow/components.js index cc4c403ebd..4d88bc195d 100644 --- a/src/modules/transaction/components/TransactionRow/components.js +++ b/src/modules/transaction/components/TransactionRow/components.js @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; import { Link } from 'react-router-dom'; -import { getTotalSpendingAmount } from '@transaction/utils/transaction'; +import { getTransactionAmount } from '@transaction/utils/transaction'; import { MODULE_COMMANDS_NAME_MAP } from 'src/modules/transaction/configuration/moduleCommand'; import DateTimeFromTimestamp from 'src/modules/common/components/timestamp'; import WalletVisual from '@wallet/components/walletVisual'; @@ -24,8 +24,8 @@ import TransactionRowContext from '../../context/transactionRowContext'; import TransactionTypeFigure from '../TransactionTypeFigure'; import TransactionAmount from '../TransactionAmount'; -export const ID = ({ address, isWallet }) => { - const { data } = useContext(TransactionRowContext); +export const ID = ({ isWallet }) => { + const { data, address } = useContext(TransactionRowContext); return ( {isWallet && ( @@ -151,14 +151,14 @@ export const Amount = () => { showRounded recipient={data.params.recipientAddress} moduleCommand={data.moduleCommand} - amount={getTotalSpendingAmount(data)} + amount={getTransactionAmount(data)} /> ); } return ( - + diff --git a/src/modules/transaction/utils/transaction.js b/src/modules/transaction/utils/transaction.js index f98b2e77e4..3c7261f2e8 100644 --- a/src/modules/transaction/utils/transaction.js +++ b/src/modules/transaction/utils/transaction.js @@ -75,9 +75,9 @@ const normalizeTransactionParams = (params, token) => }, {}); /** - * Get the total spending amount for a given module command + * Get transaction amount in total for a given module command */ -const getTotalSpendingAmount = ({ module, command, params = {} }) => { +const getTransactionAmount = ({ module, command, params = {} }) => { const moduleCommand = joinModuleAndCommand({ module, command }); if (Object.keys(params).length === 0) { @@ -419,7 +419,7 @@ const normalizeNumberRange = (distributions) => { export { containsTransactionType, downloadJSON, - getTotalSpendingAmount, + getTransactionAmount, getUnsignedBytes, getNumberOfSignatures, getAccountKeys, diff --git a/src/modules/wallet/components/RequestSignSummary/summary.test.js b/src/modules/wallet/components/RequestSignSummary/summary.test.js index 96dc54bb64..97dd8e5d52 100644 --- a/src/modules/wallet/components/RequestSignSummary/summary.test.js +++ b/src/modules/wallet/components/RequestSignSummary/summary.test.js @@ -15,7 +15,7 @@ jest.mock('src/utils/searchParams', () => ({ })); jest.mock('@transaction/utils/transaction', () => ({ - getTotalSpendingAmount: () => '1000000000', + getTransactionAmount: () => '1000000000', })); jest.mock('@transaction/hooks/useTxInitiatorAccount'); diff --git a/src/modules/wallet/components/signMultisigSummary/summary.test.js b/src/modules/wallet/components/signMultisigSummary/summary.test.js index dd07b73214..44601ad0a8 100644 --- a/src/modules/wallet/components/signMultisigSummary/summary.test.js +++ b/src/modules/wallet/components/signMultisigSummary/summary.test.js @@ -22,7 +22,7 @@ jest.mock('src/utils/searchParams', () => ({ })); jest.mock('@transaction/utils/transaction', () => ({ - getTotalSpendingAmount: () => '1000000000', + getTransactionAmount: () => '1000000000', })); jest.mock('@transaction/hooks/useTxInitiatorAccount'); jest.mock('@pos/validator/hooks/usePosToken'); From 13b3df1526e320688e907dfb101a5018b694e2b0 Mon Sep 17 00:00:00 2001 From: ManuGowda Date: Mon, 2 Oct 2023 14:12:35 +0200 Subject: [PATCH 2/7] :recycle: Update test and format files --- e2e/fixtures/page.mjs | 2 +- e2e/steps/common.mjs | 2 +- src/locales/en/common.json | 3 +- .../manage/store/action.js | 2 +- .../fungible/components/SendForm/form.test.js | 8 ++-- .../token/fungible/hooks/useAmountField.js | 16 ++------ .../components/TxComposer/Feedback.js | 39 +++++++++++++------ .../components/TxComposer/index.js | 18 +++++---- 8 files changed, 51 insertions(+), 39 deletions(-) diff --git a/e2e/fixtures/page.mjs b/e2e/fixtures/page.mjs index 107004b9bd..485be64589 100644 --- a/e2e/fixtures/page.mjs +++ b/e2e/fixtures/page.mjs @@ -1,3 +1,3 @@ export const fixture = { page: null, -} +}; diff --git a/e2e/steps/common.mjs b/e2e/steps/common.mjs index 694d150234..1fbf8f3486 100644 --- a/e2e/steps/common.mjs +++ b/e2e/steps/common.mjs @@ -181,7 +181,7 @@ Then('Element {string} should contain class {string}', async function (testId, c Then('Element {string} should not contain class {string}', async function (testId, className) { const selector = await fixture.page.getByTestId(testId); - const classList = await selector.evaluate(el => [...el.classList]); + const classList = await selector.evaluate((el) => [...el.classList]); const hasClassname = classList.find((classItem) => classItem.includes(className)); await expect(hasClassname).toBeFalsy(); diff --git a/src/locales/en/common.json b/src/locales/en/common.json index 4b0591ae12..ebb131aea4 100644 --- a/src/locales/en/common.json +++ b/src/locales/en/common.json @@ -648,8 +648,8 @@ "The list shown only contains peers connected to the current Lisk Service node.": "The list shown only contains peers connected to the current Lisk Service node.", "The message can't contain whitespace at the beginning or end.": "The message can't contain whitespace at the beginning or end.", "The message signature has been canceled on your {{model}}": "The message signature has been canceled on your {{model}}", - "The minimum required balance for this action is {{minRequiredBalance}} {{token}}": "The minimum required balance for this action is {{minRequiredBalance}} {{token}}", "The number of transactions submitted over the selected time period.": "The number of transactions submitted over the selected time period.", + "The provided amount exceeds the available balance {{availableBalance}} {{token}}, so the maximum usable balance is {{usableBalance}} {{token}}.": "The provided amount exceeds the available balance {{availableBalance}} {{token}}, so the maximum usable balance is {{usableBalance}} {{token}}.", "The provided amount is higher than your available staking balance.": "The provided amount is higher than your available staking balance.", "The selected account for signing the requested transaction is missing. Please add the missing account “": "The selected account for signing the requested transaction is missing. Please add the missing account “", "The statistics shown only reflects peers connected to the current Lisk Service node.": "The statistics shown only reflects peers connected to the current Lisk Service node.", @@ -691,6 +691,7 @@ "This validator will be punished in upcoming rounds": "This validator will be punished in upcoming rounds", "To": "To", "To application": "To application", + "To complete this transaction, deposit at least {{usableBalance}} {{token}} into the account, which currently has a balance of {{availableBalance}} {{token}}.": "To complete this transaction, deposit at least {{usableBalance}} {{token}} into the account, which currently has a balance of {{availableBalance}} {{token}}.", "To create a signed message use the \"Sign message\" tool in the sidebar.": "To create a signed message use the \"Sign message\" tool in the sidebar.", "To recover, you can try to reload the page, by clicking the button below. If the problem persists, report the error via email.": "To recover, you can try to reload the page, by clicking the button below. If the problem persists, report the error via email.", "To verify the integrity of a signed message use the \"Verify message\" tool in the sidebar.": "To verify the integrity of a signed message use the \"Verify message\" tool in the sidebar.", diff --git a/src/modules/blockchainApplication/manage/store/action.js b/src/modules/blockchainApplication/manage/store/action.js index 872d0689f4..87c3442a72 100644 --- a/src/modules/blockchainApplication/manage/store/action.js +++ b/src/modules/blockchainApplication/manage/store/action.js @@ -51,7 +51,7 @@ export const deleteNetworksInApplications = (networks) => ({ export const updateNetworkNameInApplications = (currentName, newName) => ({ type: actionTypes.updateNetworkNameInApplications, currentName, - newName + newName, }); /** diff --git a/src/modules/token/fungible/components/SendForm/form.test.js b/src/modules/token/fungible/components/SendForm/form.test.js index 61f9643cf3..0b8296fae8 100644 --- a/src/modules/token/fungible/components/SendForm/form.test.js +++ b/src/modules/token/fungible/components/SendForm/form.test.js @@ -347,8 +347,8 @@ describe('Form', () => { await flushPromises(); wrapper.update(); - expect(wrapper.find('.amount Feedback')).toHaveText( - 'Provided amount is higher than your current balance.' + expect(wrapper.find('.form.feedback')).toHaveText( + 'The provided amount exceeds the available balance {{availableBalance}} {{token}}, so the maximum usable balance is {{usableBalance}} {{token}}.' ); }); @@ -362,8 +362,8 @@ describe('Form', () => { }); wrapper.update(); - expect(wrapper.find('.amount Feedback')).toHaveText( - 'Provided amount will result in a wallet with less than the minimum balance.' + expect(wrapper.find('.form.feedback')).toHaveText( + 'The provided amount exceeds the available balance {{availableBalance}} {{token}}, so the maximum usable balance is {{usableBalance}} {{token}}.' ); expect(wrapper.find('.confirm-btn').at(0)).toBeDisabled(); }); diff --git a/src/modules/token/fungible/hooks/useAmountField.js b/src/modules/token/fungible/hooks/useAmountField.js index 628c53896d..3ca47c7175 100644 --- a/src/modules/token/fungible/hooks/useAmountField.js +++ b/src/modules/token/fungible/hooks/useAmountField.js @@ -3,7 +3,6 @@ import { useTranslation } from 'react-i18next'; import { regex } from 'src/const/regex'; import { validateAmount } from 'src/utils/validators'; -import { convertToBaseDenom } from '../utils/helpers'; let loaderTimeout = null; @@ -27,26 +26,17 @@ const getAmountFieldState = (initialValue, getAmountFeedbackAndError) => }; const useAmountField = (initialValue, balance = '0', token) => { - const { t, i18n } = useTranslation(); + const { i18n } = useTranslation(); const getAmountFeedbackAndError = (value, maxAmount = balance) => { - const checklist = [ - 'FORMAT', - 'MAX_ACCURACY', - 'NEGATIVE_AMOUNT', - 'INSUFFICIENT_FUNDS', - 'MIN_BALANCE', - ]; - let { message: feedback } = validateAmount({ + const checklist = ['FORMAT', 'MAX_ACCURACY', 'NEGATIVE_AMOUNT']; + const { message: feedback } = validateAmount({ amount: value, token, accountBalance: maxAmount, checklist: [...checklist], }); - if (!feedback && BigInt(maxAmount) < BigInt(convertToBaseDenom(value, token))) { - feedback = t('Provided amount is higher than your current balance.'); - } return { error: !!feedback, feedback }; }; diff --git a/src/modules/transaction/components/TxComposer/Feedback.js b/src/modules/transaction/components/TxComposer/Feedback.js index 39e5692270..e54435224d 100644 --- a/src/modules/transaction/components/TxComposer/Feedback.js +++ b/src/modules/transaction/components/TxComposer/Feedback.js @@ -4,23 +4,40 @@ import { isEmpty } from 'src/utils/helpers'; import { convertFromBaseDenom } from '@token/fungible/utils/helpers'; import styles from './txComposer.css'; -const Feedback = ({ minRequiredBalance, feedback, token = {} }) => { +// eslint-disable-next-line max-statements +const Feedback = ({ feedback, amountAndBalances, enableMinimumBalanceFeedback, token = {} }) => { const { t } = useTranslation(); - const hasMinRequiredBalance = - BigInt(minRequiredBalance || 0) <= BigInt(token.availableBalance || 0); + const { transactionAmount, availableBalance, spendingBalance } = amountAndBalances; + const isOverspending = spendingBalance > availableBalance; + const usableBalance = transactionAmount - (spendingBalance - availableBalance); + let message = feedback?.[0]; - if (hasMinRequiredBalance && isEmpty(feedback)) { + if (isOverspending && enableMinimumBalanceFeedback) { + message = t( + 'To complete this transaction, deposit at least {{usableBalance}} {{token}} into the account, which currently has a balance of {{availableBalance}} {{token}}.', + { + availableBalance: convertFromBaseDenom(availableBalance, token), + usableBalance: convertFromBaseDenom(spendingBalance - availableBalance, token), + token: token.symbol, + } + ); + } else if (isOverspending) { + message = t( + 'The provided amount exceeds the available balance {{availableBalance}} {{token}}, so the maximum usable balance is {{usableBalance}} {{token}}.', + { + usableBalance: convertFromBaseDenom(usableBalance, token), + availableBalance: convertFromBaseDenom(availableBalance, token), + token: token.symbol, + } + ); + } + + if (!message && isEmpty(feedback)) { return null; } - const message = hasMinRequiredBalance - ? feedback[0] - : t('The minimum required balance for this action is {{minRequiredBalance}} {{token}}', { - token: token.symbol, - minRequiredBalance: convertFromBaseDenom(minRequiredBalance, token), - }); return ( -
+
{message}
); diff --git a/src/modules/transaction/components/TxComposer/index.js b/src/modules/transaction/components/TxComposer/index.js index 904b9c0f72..6599399ed5 100644 --- a/src/modules/transaction/components/TxComposer/index.js +++ b/src/modules/transaction/components/TxComposer/index.js @@ -15,7 +15,7 @@ import { splitModuleAndCommand, } from '@transaction/utils'; import { dryRunTransaction } from '@transaction/api'; -import { getTotalSpendingAmount } from '@transaction/utils/transaction'; +import { getTransactionAmount } from '@transaction/utils/transaction'; import { convertFromBaseDenom, convertToBaseDenom } from '@token/fungible/utils/helpers'; import { useDeprecatedAccount } from '@account/hooks/useDeprecatedAccount'; import { useTransactionFee } from '@transaction/hooks/useTransactionFee'; @@ -142,8 +142,6 @@ const TxComposer = ({ setCustomFee({}); }, [minimumFee, messageFee]); - const minRequiredBalance = - BigInt(transactionFee) + BigInt(getTotalSpendingAmount(transactionJSON)); const { recipientChain, sendingChain } = formProps; const composedFees = [ { @@ -181,6 +179,11 @@ const TxComposer = ({ ? convertToBaseDenom(customFee.value.transactionFee, feeToken) : transactionFee; + const availableBalance = BigInt(formProps.fields?.token?.availableBalance || 0); + const transactionAmount = BigInt(getTransactionAmount(transactionJSON)); + const spendingBalance = transactionAmount + BigInt(transactionJSON.fee); + const amountAndBalances = { transactionAmount, availableBalance, spendingBalance }; + // eslint-disable-next-line max-statements const onSubmit = async () => { setIsRunningDryRun(true); @@ -224,14 +227,15 @@ const TxComposer = ({ loadError={prioritiesLoadError} isLoading={loadingPriorities || isLoadingFee} composedFees={composedFees} - minRequiredBalance={minRequiredBalance} + minRequiredBalance={spendingBalance} computedMinimumFees={{ transactionFee: minimumFee, messageFee }} formProps={formProps} /> BigInt(formProps.fields?.token?.availableBalance || 0) || + spendingBalance > availableBalance || !isFetched || !!feeEstimateError || isLoadingFee From 858f592f08451d960bf5dc78367fbd398313f6ae Mon Sep 17 00:00:00 2001 From: ManuGowda Date: Mon, 2 Oct 2023 14:47:09 +0200 Subject: [PATCH 3/7] :recycle: Handle transaction dry run results for register validator --- src/modules/transaction/api/index.js | 25 +++++++++++++++++++------ src/modules/transaction/constants.js | 9 ++++++++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/modules/transaction/api/index.js b/src/modules/transaction/api/index.js index b6cfae481a..f4d5eb1d4c 100644 --- a/src/modules/transaction/api/index.js +++ b/src/modules/transaction/api/index.js @@ -6,7 +6,13 @@ import to from 'await-to-js'; import { httpPaths } from '../configuration'; import { sign } from '../utils'; import { fromTransactionJSON } from '../utils/encoding'; -import { ERROR_EVENTS, EVENT_DATA_RESULT, TransactionExecutionResult } from '../constants'; +import { + ERROR_EVENTS, + TOKEN_EVENT_DATA_RESULT, + VALIDATOR_EVENT_DATA_RESULT, + TransactionExecutionResult, +} from '../constants'; +import { MODULE_COMMANDS_NAME_MAP } from '../configuration/moduleCommand'; /** * Returns a dictionary of base fees for low, medium and high processing speeds @@ -68,24 +74,26 @@ export const broadcast = async ({ transaction, serviceUrl, moduleCommandSchemas }); }; -const getEventDataResultError = (events) => { +const getEventDataResultError = (events, moduleCommand) => { const event = events?.find((e) => e.data?.result && e.data?.result !== 0); if (event) { - return EVENT_DATA_RESULT[event.data.result]; + return moduleCommand === MODULE_COMMANDS_NAME_MAP.registerValidator + ? VALIDATOR_EVENT_DATA_RESULT[event.data.result] + : TOKEN_EVENT_DATA_RESULT[event.data.result]; } return 'Transaction dry run failed with errors, hence aborting next step.'; }; -const getDryRunErrors = (events) => { +const getDryRunErrors = (events, moduleCommand) => { const event = events?.find((e) => ERROR_EVENTS[e.name]); if (event) { return ERROR_EVENTS[event.name]; } - return getEventDataResultError(events); + return getEventDataResultError(events, moduleCommand); }; /** @@ -113,7 +121,12 @@ export const dryRunTransaction = async ({ let errorMessage = error?.message || response?.data?.errorMessage; if (!isOk && !errorMessage) { - errorMessage = getDryRunErrors(response?.data?.events); + const moduleCommand = joinModuleAndCommand({ + module: transaction.module, + command: transaction.command, + }); + + errorMessage = getDryRunErrors(response?.data?.events, moduleCommand); } return { diff --git a/src/modules/transaction/constants.js b/src/modules/transaction/constants.js index a3fa956055..aa0aa74387 100644 --- a/src/modules/transaction/constants.js +++ b/src/modules/transaction/constants.js @@ -18,7 +18,7 @@ export const ERROR_EVENTS = { 'Failed to process transaction due to invalid signature, please restart the transaction from scratch.', }; -export const EVENT_DATA_RESULT = { +export const TOKEN_EVENT_DATA_RESULT = { 1: 'Failed to process this transaction due to insufficient balance.', 2: 'Failed to process this transaction due to message too long', 3: 'Failed to process this transaction due to invalid token ID', @@ -29,3 +29,10 @@ export const EVENT_DATA_RESULT = { 13: 'Failed to process this transaction due to insufficient escrow balance.', 14: 'Failed to process this transaction due to invalid receiving chain.', }; + +export const VALIDATOR_EVENT_DATA_RESULT = { + 1: 'This address is not registered as validator. Only validators can register a generator key.', + 2: 'This address is already registered as validator.', + 3: 'The BLS key has already been registered in the chain, please check and add a valid BLS key.', + 4: 'Invalid proof of possession for the given BLS key, please check and add a valid proof of possession.', +}; From 843dbcc6270ab1b186bc0810a4a9fe3e8513bd4c Mon Sep 17 00:00:00 2001 From: ManuGowda Date: Mon, 2 Oct 2023 14:53:12 +0200 Subject: [PATCH 4/7] :recycle: Update staking text --- src/locales/en/common.json | 2 +- src/modules/pos/validator/components/EditStake/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/locales/en/common.json b/src/locales/en/common.json index ebb131aea4..d1590d95f3 100644 --- a/src/locales/en/common.json +++ b/src/locales/en/common.json @@ -230,6 +230,7 @@ "Error": "Error", "Error loading application data": "Error loading application data", "Error retrieving conversion rates.": "Error retrieving conversion rates.", + "Estimated reward": "Estimated reward", "Events": "Events", "Execution status": "Execution status", "Expand": "Expand", @@ -809,7 +810,6 @@ "You received tokens": "You received tokens", "You will be able to:": "You will be able to:", "You will be notified when your transaction is confirmed.": "You will be notified when your transaction is confirmed.", - "You will get": "You will get", "Your LSK tokens could not be reclaimed, you can try again or report to us via email": "Your LSK tokens could not be reclaimed, you can try again or report to us via email", "Your account just received {{value}}": "Your account just received {{value}}", "Your commission rate request has been successfully submitted, it will be reflected in your profile shortly.": "Your commission rate request has been successfully submitted, it will be reflected in your profile shortly.", diff --git a/src/modules/pos/validator/components/EditStake/index.js b/src/modules/pos/validator/components/EditStake/index.js index 4480ab1894..9053837689 100644 --- a/src/modules/pos/validator/components/EditStake/index.js +++ b/src/modules/pos/validator/components/EditStake/index.js @@ -240,7 +240,7 @@ const EditStake = ({ history, stakeEdited, network, staking }) => { )}
- {t('You will get')} + {t('Estimated reward')} Date: Tue, 3 Oct 2023 18:59:05 +0200 Subject: [PATCH 5/7] :recycle: Handle error events and fix page crash due to API client not resolving --- src/modules/token/fungible/store/service.js | 2 +- src/modules/transaction/api/index.js | 17 ++++++++++++----- src/modules/transaction/constants.js | 7 +++++++ .../transaction/hooks/useTransactionPriority.js | 4 ++-- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/modules/token/fungible/store/service.js b/src/modules/token/fungible/store/service.js index 5098f0713b..32a3ba2e6e 100644 --- a/src/modules/token/fungible/store/service.js +++ b/src/modules/token/fungible/store/service.js @@ -17,7 +17,7 @@ export const pricesRetrieved = () => (dispatch, getState) => { const activeToken = tokenMap.LSK.key; return getPrices({ network }) - .then(({ data }) => { + ?.then(({ data }) => { const priceTickerReduced = data.reduce(tickerReducer, {}); dispatch({ type: actionTypes.pricesRetrieved, diff --git a/src/modules/transaction/api/index.js b/src/modules/transaction/api/index.js index f4d5eb1d4c..abb2fe6d2c 100644 --- a/src/modules/transaction/api/index.js +++ b/src/modules/transaction/api/index.js @@ -24,7 +24,7 @@ export const getTransactionBaseFees = (network) => path: httpPaths.fees, searchParams: {}, network, - }).then((response) => { + })?.then((response) => { const { feeEstimatePerByte } = response.data; return { @@ -78,12 +78,19 @@ const getEventDataResultError = (events, moduleCommand) => { const event = events?.find((e) => e.data?.result && e.data?.result !== 0); if (event) { - return moduleCommand === MODULE_COMMANDS_NAME_MAP.registerValidator - ? VALIDATOR_EVENT_DATA_RESULT[event.data.result] - : TOKEN_EVENT_DATA_RESULT[event.data.result]; + switch (moduleCommand) { + case MODULE_COMMANDS_NAME_MAP.transfer || MODULE_COMMANDS_NAME_MAP.transferCrossChain: + return TOKEN_EVENT_DATA_RESULT[event.data.result]; + case MODULE_COMMANDS_NAME_MAP.registerValidator: + return VALIDATOR_EVENT_DATA_RESULT[event.data.result]; + case MODULE_COMMANDS_NAME_MAP.stake || MODULE_COMMANDS_NAME_MAP.unlock: + return TOKEN_EVENT_DATA_RESULT[event.data.result]; + default: + return `Transaction dry run failed for module: ${event.module}, name: ${event.name} and result: ${event.data.result}, hence aborting next step.`; + } } - return 'Transaction dry run failed with errors, hence aborting next step.'; + return 'Transaction dry run failed with no events, hence aborting next step.'; }; const getDryRunErrors = (events, moduleCommand) => { diff --git a/src/modules/transaction/constants.js b/src/modules/transaction/constants.js index aa0aa74387..7cfa4a5436 100644 --- a/src/modules/transaction/constants.js +++ b/src/modules/transaction/constants.js @@ -36,3 +36,10 @@ export const VALIDATOR_EVENT_DATA_RESULT = { 3: 'The BLS key has already been registered in the chain, please check and add a valid BLS key.', 4: 'Invalid proof of possession for the given BLS key, please check and add a valid proof of possession.', }; + +export const POS_EVENT_DATA_RESULT = { + 1: 'Failed to stake for an unregistered validator.', + 2: 'The unstaking attempt failed due to parameters that were not valid.', + 3: 'Failed due to an excessive number of stakes being unlocked.', + 4: 'Failed to stake due to exceeding the staking limit.', +}; diff --git a/src/modules/transaction/hooks/useTransactionPriority.js b/src/modules/transaction/hooks/useTransactionPriority.js index c7408feb9d..96d696c704 100644 --- a/src/modules/transaction/hooks/useTransactionPriority.js +++ b/src/modules/transaction/hooks/useTransactionPriority.js @@ -22,10 +22,10 @@ const useTransactionPriority = () => { useEffect(() => { setLoading(true); getTransactionBaseFees(network) - .then(setBaseFees) + ?.then(setBaseFees) .catch(setPrioritiesLoadError) .finally(() => setLoading(false)); - }, []); + }, [network]); const selectTransactionPriority = ({ item, index }) => { setSelectedPriority({ From 6cf5328ca5602aaf9dcebc769b1c0bdcfefee90e Mon Sep 17 00:00:00 2001 From: ManuGowda Date: Wed, 4 Oct 2023 09:27:41 +0200 Subject: [PATCH 6/7] :recycle: Fix pos event handling --- src/modules/transaction/api/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/transaction/api/index.js b/src/modules/transaction/api/index.js index abb2fe6d2c..4441fe6d84 100644 --- a/src/modules/transaction/api/index.js +++ b/src/modules/transaction/api/index.js @@ -11,6 +11,7 @@ import { TOKEN_EVENT_DATA_RESULT, VALIDATOR_EVENT_DATA_RESULT, TransactionExecutionResult, + POS_EVENT_DATA_RESULT, } from '../constants'; import { MODULE_COMMANDS_NAME_MAP } from '../configuration/moduleCommand'; @@ -84,7 +85,7 @@ const getEventDataResultError = (events, moduleCommand) => { case MODULE_COMMANDS_NAME_MAP.registerValidator: return VALIDATOR_EVENT_DATA_RESULT[event.data.result]; case MODULE_COMMANDS_NAME_MAP.stake || MODULE_COMMANDS_NAME_MAP.unlock: - return TOKEN_EVENT_DATA_RESULT[event.data.result]; + return POS_EVENT_DATA_RESULT[event.data.result]; default: return `Transaction dry run failed for module: ${event.module}, name: ${event.name} and result: ${event.data.result}, hence aborting next step.`; } From bdc14f93c3d96e394e62e9f58417736faf5c59c4 Mon Sep 17 00:00:00 2001 From: ManuGowda Date: Wed, 4 Oct 2023 10:35:13 +0200 Subject: [PATCH 7/7] :recycle: Skip staking e2e until we setup the local environment --- e2e/features/staking/Staking.feature | 156 +++++++++++++-------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/e2e/features/staking/Staking.feature b/e2e/features/staking/Staking.feature index 0adffefba8..d6124b5749 100644 --- a/e2e/features/staking/Staking.feature +++ b/e2e/features/staking/Staking.feature @@ -1,83 +1,83 @@ -Feature: Staking - Background: Add an account and navigate to validators - Given I wait for "1 seconds" - Given I add an account with passphrase "attract squeeze option inflict dynamic end evoke love proof among random blanket table pumpkin general impose access toast undo extend fun employ agree dash" password "Password@1" name "genesis_60" custom derivation path "m/44'/134'/60'" - And I go to page "validators" - And I wait for "1 seconds" +# Feature: Staking +# Background: Add an account and navigate to validators +# Given I wait for "1 seconds" +# Given I add an account with passphrase "attract squeeze option inflict dynamic end evoke love proof among random blanket table pumpkin general impose access toast undo extend fun employ agree dash" password "Password@1" name "genesis_60" custom derivation path "m/44'/134'/60'" +# And I go to page "validators" +# And I wait for "1 seconds" - Scenario: Validators should be displayed on the page - Then I should see 103 validators in table +# Scenario: Validators should be displayed on the page +# Then I should see 103 validators in table - Scenario: Validators can be randomly selected - Then I should select a random validator and see their details - Given I go back to the previous page - And I wait for "2 seconds" - Then I should select a random validator and see their details - Given I go back to the previous page - And I wait for "3 seconds" - Then I should select a random validator and see their details +# Scenario: Validators can be randomly selected +# Then I should select a random validator and see their details +# Given I go back to the previous page +# And I wait for "2 seconds" +# Then I should select a random validator and see their details +# Given I go back to the previous page +# And I wait for "3 seconds" +# Then I should select a random validator and see their details - Scenario: Stake validator then unstake validator - Edit stake - When I do a global search for "genesis_29" - And I wait for "1 seconds" - Given I click on an element with testId "validators-content" - Then I should see "genesis_29" validator details - Given I click on a button with text "Stake validator" - Then I should see "Add to staking queue" - Then button with text "Confirm" should be disabled - When I type "10" in "stake" - Then button with text "Confirm" should be enabled - Given I click on a button with text "Confirm" - Then I should see "Stake added to queue" - Then I should see "Continue staking" - When I click on a button with text "Go to the staking queue" - Then I should see staking queue details for validator "genesis_29" with amount "10 LSK" - And I wait for "1 seconds" - When I click on a button with text "Continue" - And I click on a button with text "Confirm" - When I type "Password@1" in "password" - And I click on a button with text "Continue" - And I wait for "1 seconds" - Then I should see staking confirmation details with amount "10 LSK" - Given I click on an element with testId "dialog-close-button" - And I wait for "10 seconds" - Given I click on a button with text "Edit stake" - Then I should see "Edit stake" - Then button with text "Confirm" should be disabled - When I type "30" in "stake" - Then button with text "Confirm" should be enabled - Given I click on a button with text "Confirm" - Then I should see "Stake added to queue" - Then I should see "Continue staking" - When I click on a button with text "Go to the staking queue" - Then I should see staking queue details for validator "genesis_29" with amount "30 LSK" - And I wait for "1 seconds" - When I click on a button with text "Continue" - And I click on a button with text "Confirm" - When I type "Password@1" in "password" - And I click on a button with text "Continue" - Then I should see staking confirmation details with amount "20 LSK" +# Scenario: Stake validator then unstake validator - Edit stake +# When I do a global search for "genesis_29" +# And I wait for "1 seconds" +# Given I click on an element with testId "validators-content" +# Then I should see "genesis_29" validator details +# Given I click on a button with text "Stake validator" +# Then I should see "Add to staking queue" +# Then button with text "Confirm" should be disabled +# When I type "10" in "stake" +# Then button with text "Confirm" should be enabled +# Given I click on a button with text "Confirm" +# Then I should see "Stake added to queue" +# Then I should see "Continue staking" +# When I click on a button with text "Go to the staking queue" +# Then I should see staking queue details for validator "genesis_29" with amount "10 LSK" +# And I wait for "1 seconds" +# When I click on a button with text "Continue" +# And I click on a button with text "Confirm" +# When I type "Password@1" in "password" +# And I click on a button with text "Continue" +# And I wait for "1 seconds" +# Then I should see staking confirmation details with amount "10 LSK" +# Given I click on an element with testId "dialog-close-button" +# And I wait for "10 seconds" +# Given I click on a button with text "Edit stake" +# Then I should see "Edit stake" +# Then button with text "Confirm" should be disabled +# When I type "30" in "stake" +# Then button with text "Confirm" should be enabled +# Given I click on a button with text "Confirm" +# Then I should see "Stake added to queue" +# Then I should see "Continue staking" +# When I click on a button with text "Go to the staking queue" +# Then I should see staking queue details for validator "genesis_29" with amount "30 LSK" +# And I wait for "1 seconds" +# When I click on a button with text "Continue" +# And I click on a button with text "Confirm" +# When I type "Password@1" in "password" +# And I click on a button with text "Continue" +# Then I should see staking confirmation details with amount "20 LSK" - Scenario: Unstake validator - Remove stake - When I do a global search for "genesis_29" - And I wait for "1 seconds" - Given I click on an element with testId "validators-content" - Then I should see "genesis_29" validator details - Given I click on a button with text "Edit stake" - Then I should see "Edit stake" - Given I click on a button with text "Remove stake" - Then I should see "Stake added to queue" - Then I should see "Continue staking" - When I click on a button with text "Go to the staking queue" - And I wait for "1 seconds" - When I click on a button with text "Continue" - And I click on a button with text "Confirm" - When I type "Password@1" in "password" - And I click on a button with text "Continue" - And I wait for "1 seconds" - Then I should see unstaking confirmation details with amount "30 LSK" +# Scenario: Unstake validator - Remove stake +# When I do a global search for "genesis_29" +# And I wait for "1 seconds" +# Given I click on an element with testId "validators-content" +# Then I should see "genesis_29" validator details +# Given I click on a button with text "Edit stake" +# Then I should see "Edit stake" +# Given I click on a button with text "Remove stake" +# Then I should see "Stake added to queue" +# Then I should see "Continue staking" +# When I click on a button with text "Go to the staking queue" +# And I wait for "1 seconds" +# When I click on a button with text "Continue" +# And I click on a button with text "Confirm" +# When I type "Password@1" in "password" +# And I click on a button with text "Continue" +# And I wait for "1 seconds" +# Then I should see unstaking confirmation details with amount "30 LSK" - Scenario: View stakes - Given I click on a button with text "Stakes" - Then I should see "Stake amount" - Then I should see 2 stakes in stakes list +# Scenario: View stakes +# Given I click on a button with text "Stakes" +# Then I should see "Stake amount" +# Then I should see 2 stakes in stakes list