Skip to content

Commit b9938cc

Browse files
feat: Implement unstaking confirmation
1 parent 30a34ec commit b9938cc

File tree

10 files changed

+159
-63
lines changed

10 files changed

+159
-63
lines changed

app/components/Views/confirmations/components/Confirm/AdvancedDetails/AdvancedDetails.styles.ts

-5
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ const styleSheet = () =>
55
container: {
66
paddingVertical: 8,
77
},
8-
networkContainer: {
9-
display: 'flex',
10-
flexDirection: 'row',
11-
alignItems: 'center',
12-
},
138
});
149

1510
export default styleSheet;
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,23 @@
1-
import { CHAIN_IDS, TransactionMeta } from '@metamask/transaction-controller';
21
import React from 'react';
32
import { View } from 'react-native';
43
import { strings } from '../../../../../../../locales/i18n';
5-
import { AvatarSize } from '../../../../../../component-library/components/Avatars/Avatar';
6-
import Badge, { BadgeVariant } from '../../../../../../component-library/components/Badges/Badge';
7-
import Text from '../../../../../../component-library/components/Texts/Text';
84
import { useStyles } from '../../../../../../component-library/hooks';
9-
import images from '../../../../../../images/image-icons';
10-
import Name from '../../../../../UI/Name';
11-
import { NameType } from '../../../../../UI/Name/Name.types';
12-
import { useTransactionMetadataRequest } from '../../../hooks/useTransactionMetadataRequest';
13-
import InfoRow from '../../UI/InfoRow';
145
import InfoSectionAccordion from '../../UI/InfoSectionAccordion';
15-
import InfoRowDivider from '../InfoRowDivider';
6+
import ContractInteractionDetails, { ContractInteractionDetailsVariant } from '../ContractInteractionDetails/ContractInteractionDetails';
167
import styleSheet from './AdvancedDetails.styles';
178

189
const AdvancedDetails = () => {
1910
const { styles } = useStyles(styleSheet, {});
20-
const transactionMeta = useTransactionMetadataRequest();
2111

2212
return (
2313
<View style={styles.container}>
2414
<InfoSectionAccordion header={strings('stake.advanced_details')}>
25-
<InfoRow
26-
label={strings('confirm.staking_from')}
27-
>
28-
<Name
29-
type={NameType.EthereumAddress}
30-
value={(transactionMeta as TransactionMeta).txParams.from}
31-
variation={CHAIN_IDS.MAINNET}
32-
/>
33-
</InfoRow>
34-
<InfoRow
35-
label={strings('confirm.label.interacting_with')}
36-
>
37-
<Name
38-
type={NameType.EthereumAddress}
39-
value={(transactionMeta as TransactionMeta).txParams.to as string}
40-
variation={CHAIN_IDS.MAINNET}
41-
/>
42-
</InfoRow>
43-
<InfoRowDivider />
44-
<InfoRow
45-
label={strings('confirm.label.network')}
46-
>
47-
<View style={styles.networkContainer}>
48-
<Badge
49-
size={AvatarSize.Xs}
50-
imageSource={images.ETHEREUM}
51-
variant={BadgeVariant.Network}
52-
isScaled={false}
53-
/>
54-
<Text>{' '}</Text>
55-
<Text>{strings('stake.ethereum_mainnet')}</Text>
56-
</View>
57-
</InfoRow>
15+
<ContractInteractionDetails variant={ContractInteractionDetailsVariant.StakingDeposit} />
5816
</InfoSectionAccordion>
5917
</View>
6018
);
6119
};
6220

21+
22+
6323
export default AdvancedDetails;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { StyleSheet } from 'react-native';
2+
3+
const styleSheet = () =>
4+
StyleSheet.create({
5+
networkContainer: {
6+
display: 'flex',
7+
flexDirection: 'row',
8+
alignItems: 'center',
9+
},
10+
});
11+
12+
export default styleSheet;

app/components/Views/confirmations/components/Confirm/ContractInteractionDetails/ContractInteractionDetails.test.tsx

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { CHAIN_IDS, TransactionMeta } from '@metamask/transaction-controller';
2+
import React from 'react';
3+
import { View } from 'react-native';
4+
import { useSelector } from 'react-redux';
5+
import { strings } from '../../../../../../../locales/i18n';
6+
import { AvatarSize } from '../../../../../../component-library/components/Avatars/Avatar';
7+
import Badge, { BadgeVariant } from '../../../../../../component-library/components/Badges/Badge';
8+
import Text from '../../../../../../component-library/components/Texts/Text';
9+
import { useStyles } from '../../../../../../component-library/hooks';
10+
import images from '../../../../../../images/image-icons';
11+
import { selectSelectedInternalAccountFormattedAddress } from '../../../../../../selectors/accountsController';
12+
import Name from '../../../../../UI/Name';
13+
import { NameType } from '../../../../../UI/Name/Name.types';
14+
import { useTransactionMetadataRequest } from '../../../hooks/useTransactionMetadataRequest';
15+
import InfoRow from '../../UI/InfoRow';
16+
import InfoRowDivider from '../InfoRowDivider';
17+
import styleSheet from './ContractInteractionDetails.styles';
18+
19+
export enum ContractInteractionDetailsVariant {
20+
StakingDeposit = 'staking_deposit',
21+
StakingWithdrawal = 'staking_withdrawal',
22+
StakingClaim = 'staking_claim',
23+
}
24+
25+
const ContractInteractionDetails = (
26+
{ variant }: { variant: ContractInteractionDetailsVariant }
27+
) => {
28+
const transactionMeta = useTransactionMetadataRequest();
29+
const { styles } = useStyles(styleSheet, {});
30+
const address = useSelector(selectSelectedInternalAccountFormattedAddress);
31+
32+
return (
33+
<>
34+
{variant === ContractInteractionDetailsVariant.StakingDeposit && (
35+
<InfoRow
36+
label={strings('stake.staking_from')}
37+
>
38+
<Name
39+
type={NameType.EthereumAddress}
40+
value={(transactionMeta as TransactionMeta).txParams.from}
41+
variation={CHAIN_IDS.MAINNET}
42+
/>
43+
</InfoRow>
44+
)}
45+
{variant === ContractInteractionDetailsVariant.StakingWithdrawal && (
46+
<InfoRow
47+
label={strings('stake.unstaking_to')}
48+
>
49+
<Name
50+
type={NameType.EthereumAddress}
51+
value={address as string}
52+
variation={CHAIN_IDS.MAINNET}
53+
/>
54+
</InfoRow>
55+
)}
56+
<InfoRow
57+
label={strings('confirm.label.interacting_with')}
58+
>
59+
<Name
60+
type={NameType.EthereumAddress}
61+
value={(transactionMeta as TransactionMeta).txParams.to as string}
62+
variation={CHAIN_IDS.MAINNET}
63+
/>
64+
</InfoRow>
65+
<InfoRowDivider />
66+
<InfoRow
67+
label={strings('confirm.label.network')}
68+
>
69+
<View style={styles.networkContainer}>
70+
<Badge
71+
size={AvatarSize.Xs}
72+
imageSource={images.ETHEREUM}
73+
variant={BadgeVariant.Network}
74+
isScaled={false}
75+
/>
76+
<Text>{' '}</Text>
77+
<Text>{strings('stake.ethereum_mainnet')}</Text>
78+
</View>
79+
</InfoRow>
80+
</>
81+
)
82+
}
83+
84+
export default ContractInteractionDetails;

app/components/Views/confirmations/components/Confirm/Info/StakingDeposit/StakingDeposit.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { strings } from '../../../../../../../../locales/i18n';
44
import { useConfirmActions } from '../../../../hooks/useConfirmActions';
55
import AdvancedDetails from '../../AdvancedDetails/AdvancedDetails';
66
import { getNavbar } from '../../Navbar/Navbar';
7-
import StakingDetails from '../../StakingDetails';
7+
import StakingDetails from '../../StakingDetails/StakingDetails';
88
import TokenHero from '../../TokenHero';
99
import GasFeesDetails from '../GasFeesDetails';
1010

app/components/Views/confirmations/components/Confirm/Info/StakingWithdrawal/StakingWithdrawal.test.tsx

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
import { merge } from 'lodash';
12
import React from 'react';
2-
3-
import renderWithProvider from '../../../../../../../util/test/renderWithProvider';
43
import { stakingWithdrawalConfirmationState } from '../../../../../../../util/test/confirm-data-helpers';
4+
import renderWithProvider from '../../../../../../../util/test/renderWithProvider';
55
import { useConfirmActions } from '../../../../hooks/useConfirmActions';
6-
import StakingWithdrawal from './StakingWithdrawal';
76
import { getNavbar } from '../../Navbar/Navbar';
7+
import StakingWithdrawal from './StakingWithdrawal';
88

99
jest.mock('../../../../../../../core/Engine', () => ({
1010
getTotalFiatAccountBalance: () => ({ tokenFiat: 10 }),
@@ -65,19 +65,35 @@ describe('StakingWithdrawal', () => {
6565
key: 'mockRouteKey',
6666
name: 'params'
6767
}} />, {
68-
state: stakingWithdrawalConfirmationState,
68+
state: merge(stakingWithdrawalConfirmationState, {
69+
engine: {
70+
backgroundState: {
71+
AccountsController: {
72+
internalAccounts: {
73+
accounts: {
74+
'0x0000000000000000000000000000000000000000': {
75+
address: '0x0000000000000000000000000000000000000000',
76+
},
77+
},
78+
selectedAccount: '0x0000000000000000000000000000000000000000',
79+
},
80+
},
81+
}
82+
}
83+
}),
6984
});
70-
expect(getByText('APR')).toBeDefined();
71-
expect(getByText('Est. annual reward')).toBeDefined();
72-
expect(getByText('Reward frequency')).toBeDefined();
7385
expect(getByText('Withdrawal time')).toBeDefined();
86+
87+
expect(getByText('Unstaking to')).toBeDefined();
88+
expect(getByText('Interacting with')).toBeDefined();
89+
expect(getByText('Network')).toBeDefined();
90+
7491
expect(getByText('Network Fee')).toBeDefined();
75-
expect(getByText('Advanced details')).toBeDefined();
7692

7793
expect(mockGetNavbar).toHaveBeenCalled();
7894
expect(mockGetNavbar).toHaveBeenCalledWith({
7995
title: 'Unstake',
8096
onReject: mockOnReject,
8197
});
8298
});
83-
});
99+
});

app/components/Views/confirmations/components/Confirm/Info/StakingWithdrawal/StakingWithdrawal.tsx

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ import React, { useEffect } from 'react';
33
import { strings } from '../../../../../../../../locales/i18n';
44
import { UnstakeConfirmationViewProps } from '../../../../../../UI/Stake/Views/UnstakeConfirmationView/UnstakeConfirmationView.types';
55
import { useConfirmActions } from '../../../../hooks/useConfirmActions';
6-
import AdvancedDetails from '../../AdvancedDetails/AdvancedDetails';
6+
import InfoSection from '../../../UI/InfoRow/InfoSection';
7+
import ContractInteractionDetails, { ContractInteractionDetailsVariant } from '../../ContractInteractionDetails/ContractInteractionDetails';
78
import { getNavbar } from '../../Navbar/Navbar';
8-
import StakingDetails from '../../StakingDetails';
99
import TokenHero from '../../TokenHero';
10+
import UnstakingTimeSection from '../../UnstakingTime/UnstakingTime';
1011
import GasFeesDetails from '../GasFeesDetails';
1112

1213
const StakingWithdrawal = ({ route }: UnstakeConfirmationViewProps) => {
@@ -25,9 +26,11 @@ const StakingWithdrawal = ({ route }: UnstakeConfirmationViewProps) => {
2526
return (
2627
<>
2728
<TokenHero amountWei={route?.params?.amountWei} />
28-
<StakingDetails />
29+
<UnstakingTimeSection />
30+
<InfoSection>
31+
<ContractInteractionDetails variant={ContractInteractionDetailsVariant.StakingWithdrawal} />
32+
</InfoSection>
2933
<GasFeesDetails />
30-
<AdvancedDetails />
3134
</>
3235
);
3336
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import React from 'react';
2+
import renderWithProvider from '../../../../../../util/test/renderWithProvider';
3+
import UnstakingTime from './UnstakingTime';
4+
5+
describe('UnstakingTime', () => {
6+
it('should render correctly', () => {
7+
const { getByText } = renderWithProvider(<UnstakingTime />);
8+
9+
expect(getByText('Withdrawal time')).toBeDefined();
10+
expect(getByText('1 to 11 days')).toBeDefined();
11+
});
12+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import React from 'react';
2+
import { strings } from '../../../../../../../locales/i18n';
3+
import InfoRow from '../../UI/InfoRow';
4+
import InfoSection from '../../UI/InfoRow/InfoSection';
5+
6+
const UnstakingTimeSection = () => (
7+
<InfoSection>
8+
<InfoRow label={strings('stake.withdrawal_time')}>
9+
{strings('stake.estimated_unstaking_time')}
10+
</InfoRow>
11+
</InfoSection>
12+
);
13+
14+
export default UnstakingTimeSection;

0 commit comments

Comments
 (0)