diff --git a/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.test.tsx b/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.test.tsx
index 69182f1fa44..3f8d3caa69d 100644
--- a/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.test.tsx
+++ b/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.test.tsx
@@ -53,6 +53,15 @@ jest.mock('@react-navigation/native', () => {
};
});
+jest.mock('../../hooks/usePoolStakedDeposit', () => ({
+ __esModule: true,
+ default: () => ({
+ poolStakingContract: {},
+ estimateDepositGas: jest.fn(),
+ attemptDepositTransaction: jest.fn(),
+ }),
+}));
+
describe('StakeConfirmationView', () => {
it('render matches snapshot', () => {
const props: StakeConfirmationViewProps = {
diff --git a/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.tsx b/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.tsx
index c78b5afc813..48a7277df07 100644
--- a/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.tsx
+++ b/app/components/UI/Stake/Views/StakeConfirmationView/StakeConfirmationView.tsx
@@ -10,6 +10,7 @@ import RewardsCard from '../../components/StakingConfirmation/RewardsCard/Reward
import ConfirmationFooter from '../../components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter';
import { StakeConfirmationViewProps } from './StakeConfirmationView.types';
import { strings } from '../../../../../../locales/i18n';
+import { FooterButtonGroupActions } from '../../components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.types';
const MOCK_STAKING_CONTRACT_NAME = 'MM Pooled Staking';
@@ -44,7 +45,10 @@ const StakeConfirmationView = ({ route }: StakeConfirmationViewProps) => {
/>
-
+
);
};
diff --git a/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx b/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx
index d1ddb887028..ebfe8c6be93 100644
--- a/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx
+++ b/app/components/UI/Stake/Views/StakeInputView/StakeInputView.test.tsx
@@ -6,6 +6,8 @@ import Routes from '../../../../../constants/navigation/Routes';
import { backgroundState } from '../../../../../util/test/initial-root-state';
import { BN } from 'ethereumjs-util';
import { Stake } from '../../sdk/stakeSdkProvider';
+import { ChainId, PooledStakingContract } from '@metamask/stake-sdk';
+import { Contract } from 'ethers';
import { MOCK_GET_VAULT_RESPONSE } from '../../__mocks__/mockData';
function render(Component: React.ComponentType) {
@@ -54,11 +56,27 @@ jest.mock('../../../../../selectors/currencyRateController.ts', () => ({
const mockBalanceBN = new BN('1500000000000000000');
+const mockPooledStakingContractService: PooledStakingContract = {
+ chainId: ChainId.ETHEREUM,
+ connectSignerOrProvider: jest.fn(),
+ contract: new Contract('0x0000000000000000000000000000000000000000', []),
+ convertToShares: jest.fn(),
+ encodeClaimExitedAssetsTransactionData: jest.fn(),
+ encodeDepositTransactionData: jest.fn(),
+ encodeEnterExitQueueTransactionData: jest.fn(),
+ encodeMulticallTransactionData: jest.fn(),
+ estimateClaimExitedAssetsGas: jest.fn(),
+ estimateDepositGas: jest.fn(),
+ estimateEnterExitQueueGas: jest.fn(),
+ estimateMulticallGas: jest.fn(),
+};
+
jest.mock('../../hooks/useStakeContext.ts', () => ({
useStakeContext: jest.fn(() => {
const stakeContext: Stake = {
setSdkType: jest.fn(),
- stakingContract: undefined,
+ stakingContract: mockPooledStakingContractService,
+ stakingApiService: undefined,
};
return stakeContext;
}),
diff --git a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.test.tsx b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.test.tsx
index 36db2a000b1..011c63bfbf7 100644
--- a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.test.tsx
+++ b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.test.tsx
@@ -1,18 +1,58 @@
import React from 'react';
import renderWithProvider from '../../../../../../util/test/renderWithProvider';
import ConfirmationFooter from './ConfirmationFooter';
+import { ConfirmationFooterProps } from './ConfirmationFooter.types';
+import { createMockAccountsControllerState } from '../../../../../../util/test/accountsControllerTestUtils';
+import { backgroundState } from '../../../../../../util/test/initial-root-state';
+import { FooterButtonGroupActions } from './FooterButtonGroup/FooterButtonGroup.types';
+
+const MOCK_ADDRESS_1 = '0x0';
+const MOCK_ADDRESS_2 = '0x1';
+
+const MOCK_ACCOUNTS_CONTROLLER_STATE = createMockAccountsControllerState([
+ MOCK_ADDRESS_1,
+ MOCK_ADDRESS_2,
+]);
+
+const mockInitialState = {
+ settings: {},
+ engine: {
+ backgroundState: {
+ ...backgroundState,
+ AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
+ },
+ },
+};
jest.mock('@react-navigation/native', () => {
const actualReactNavigation = jest.requireActual('@react-navigation/native');
return {
...actualReactNavigation,
- useNavigation: jest.fn(),
+ useNavigation: () => ({
+ navigate: jest.fn(),
+ }),
};
});
+jest.mock('../../../hooks/usePoolStakedDeposit', () => ({
+ __esModule: true,
+ default: () => ({
+ poolStakingContract: {},
+ estimateDepositGas: jest.fn(),
+ attemptDepositTransaction: jest.fn(),
+ }),
+}));
+
describe('ConfirmationFooter', () => {
it('render matches snapshot', () => {
- const { toJSON } = renderWithProvider();
+ const props: ConfirmationFooterProps = {
+ valueWei: '3210000000000000',
+ action: FooterButtonGroupActions.STAKE,
+ };
+
+ const { toJSON } = renderWithProvider(, {
+ state: mockInitialState,
+ });
expect(toJSON()).toMatchSnapshot();
});
diff --git a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.tsx b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.tsx
index 6505cef13f7..acf580af357 100644
--- a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.tsx
+++ b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.tsx
@@ -4,14 +4,15 @@ import styleSheet from './ConfirmationFooter.styles';
import { View } from 'react-native';
import FooterLegalLinks from './LegalLinks/LegalLinks';
import FooterButtonGroup from './FooterButtonGroup/FooterButtonGroup';
+import { ConfirmationFooterProps } from './ConfirmationFooter.types';
-const ConfirmationFooter = () => {
+const ConfirmationFooter = ({ valueWei, action }: ConfirmationFooterProps) => {
const { styles } = useStyles(styleSheet, {});
return (
-
+
);
};
diff --git a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.types.ts b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.types.ts
new file mode 100644
index 00000000000..a2d10bc09eb
--- /dev/null
+++ b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/ConfirmationFooter.types.ts
@@ -0,0 +1,6 @@
+import { FooterButtonGroupActions } from './FooterButtonGroup/FooterButtonGroup.types';
+
+export interface ConfirmationFooterProps {
+ valueWei: string; // deposit, unstake, and claim value
+ action: FooterButtonGroupActions;
+}
diff --git a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.test.tsx b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.test.tsx
index 9f756063fa6..ffaec56ae87 100644
--- a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.test.tsx
+++ b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.test.tsx
@@ -3,9 +3,34 @@ import renderWithProvider from '../../../../../../../util/test/renderWithProvide
import { strings } from '../../../../../../../../locales/i18n';
import FooterButtonGroup from './FooterButtonGroup';
import { fireEvent } from '@testing-library/react-native';
+import {
+ FooterButtonGroupActions,
+ FooterButtonGroupProps,
+} from './FooterButtonGroup.types';
+import { createMockAccountsControllerState } from '../../../../../../../util/test/accountsControllerTestUtils';
+import { backgroundState } from '../../../../../../../util/test/initial-root-state';
+
+const MOCK_ADDRESS_1 = '0x0';
+const MOCK_ADDRESS_2 = '0x1';
+
+const MOCK_ACCOUNTS_CONTROLLER_STATE = createMockAccountsControllerState([
+ MOCK_ADDRESS_1,
+ MOCK_ADDRESS_2,
+]);
+
+const mockInitialState = {
+ settings: {},
+ engine: {
+ backgroundState: {
+ ...backgroundState,
+ AccountsController: MOCK_ACCOUNTS_CONTROLLER_STATE,
+ },
+ },
+};
const mockCanGoBack = jest.fn();
const mockGoBack = jest.fn();
+const mockNavigate = jest.fn();
jest.mock('@react-navigation/native', () => {
const actualReactNavigation = jest.requireActual('@react-navigation/native');
@@ -14,17 +39,35 @@ jest.mock('@react-navigation/native', () => {
useNavigation: () => ({
canGoBack: mockCanGoBack,
goBack: mockGoBack,
+ navigate: mockNavigate,
}),
};
});
+jest.mock('../../../../hooks/usePoolStakedDeposit', () => ({
+ __esModule: true,
+ default: () => ({
+ poolStakingContract: {},
+ estimateDepositGas: jest.fn(),
+ attemptDepositTransaction: jest.fn(),
+ }),
+}));
+
describe('FooterButtonGroup', () => {
beforeEach(() => {
jest.resetAllMocks();
});
it('render matches snapshot', () => {
- const { getByText, toJSON } = renderWithProvider();
+ const props: FooterButtonGroupProps = {
+ valueWei: '3210000000000000',
+ action: FooterButtonGroupActions.STAKE,
+ };
+
+ const { getByText, toJSON } = renderWithProvider(
+ ,
+ { state: mockInitialState },
+ );
expect(getByText(strings('stake.cancel'))).toBeDefined();
expect(getByText(strings('stake.confirm'))).toBeDefined();
@@ -32,15 +75,22 @@ describe('FooterButtonGroup', () => {
expect(toJSON()).toMatchSnapshot();
});
- it('navigates to previous page when cancel button is pressed', () => {
+ it('navigates to Asset page when cancel is pressed', () => {
mockCanGoBack.mockImplementationOnce(() => true);
+ const props: FooterButtonGroupProps = {
+ valueWei: '3210000000000000',
+ action: FooterButtonGroupActions.STAKE,
+ };
- const { getByText, toJSON } = renderWithProvider();
+ const { getByText, toJSON } = renderWithProvider(
+ ,
+ { state: mockInitialState },
+ );
fireEvent.press(getByText(strings('stake.cancel')));
- expect(mockCanGoBack).toHaveBeenCalledTimes(1);
- expect(mockGoBack).toHaveBeenCalledTimes(1);
+ expect(mockNavigate).toHaveBeenCalledTimes(1);
+ expect(mockNavigate).toHaveBeenCalledWith('Asset');
expect(toJSON()).toMatchSnapshot();
});
diff --git a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.tsx b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.tsx
index bd781bfc9a8..ceac4f03c97 100644
--- a/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.tsx
+++ b/app/components/UI/Stake/components/StakingConfirmation/ConfirmationFooter/FooterButtonGroup/FooterButtonGroup.tsx
@@ -13,16 +13,51 @@ import Text, {
} from '../../../../../../../component-library/components/Texts/Text';
import { useStyles } from '../../../../../../hooks/useStyles';
import styleSheet from './FooterButtonGroup.styles';
+import { useSelector } from 'react-redux';
+import { selectSelectedInternalAccount } from '../../../../../../../selectors/accountsController';
+import usePoolStakedDeposit from '../../../../hooks/usePoolStakedDeposit';
+import Engine from '../../../../../../../core/Engine';
+import {
+ FooterButtonGroupActions,
+ FooterButtonGroupProps,
+} from './FooterButtonGroup.types';
+import Routes from '../../../../../../../constants/navigation/Routes';
+import { useStakeContext } from '../../../../hooks/useStakeContext';
-const FooterButtonGroup = () => {
+const FooterButtonGroup = ({ valueWei, action }: FooterButtonGroupProps) => {
const { styles } = useStyles(styleSheet, {});
- const navigation = useNavigation();
+ const { navigate } = useNavigation();
- const handleGoBack = () => {
- if (navigation.canGoBack()) {
- navigation.goBack();
- }
+ const activeAccount = useSelector(selectSelectedInternalAccount);
+
+ const { sdkService } = useStakeContext();
+
+ const { attemptDepositTransaction } = usePoolStakedDeposit(sdkService);
+
+ const handleStake = async () => {
+ if (!activeAccount?.address) return;
+
+ const txRes = await attemptDepositTransaction(
+ valueWei,
+ activeAccount.address,
+ );
+
+ const transactionId = txRes?.transactionMeta?.id;
+
+ // Listening for confirmation
+ Engine.controllerMessenger.subscribeOnceIf(
+ 'TransactionController:transactionSubmitted',
+ () => {
+ navigate(Routes.TRANSACTIONS_VIEW);
+ },
+ ({ transactionMeta }) => transactionMeta.id === transactionId,
+ );
+ };
+
+ const handleConfirmation = () => {
+ if (action === FooterButtonGroupActions.STAKE) return handleStake();
+ // TODO: Add handler (STAKE-803)
};
return (
@@ -37,7 +72,7 @@ const FooterButtonGroup = () => {
variant={ButtonVariants.Secondary}
width={ButtonWidthTypes.Full}
size={ButtonSize.Lg}
- onPress={handleGoBack}
+ onPress={() => navigate('Asset')}
/>