Skip to content

Commit d40dd70

Browse files
Add Contract info to signing step (#4234)
* Add TxIntermediaryDisplay to signing step * Move contract info below content on WC screen * Add tests
1 parent 97a889a commit d40dd70

File tree

9 files changed

+147
-31
lines changed

9 files changed

+147
-31
lines changed

Diff for: jest_config/__fixtures__/txConfig.ts

+17-15
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import { BigNumber } from '@ethersproject/bignumber';
33
import {
44
ITxConfig,
55
ITxData,
6+
ITxFromAddress,
67
ITxGasLimit,
78
ITxGasPrice,
89
ITxNonce,
910
ITxToAddress,
1011
ITxValue,
12+
NetworkId,
1113
StoreAccount,
1214
TAddress,
15+
TAssetType,
1316
TTicker,
1417
TUuid
1518
} from '@types';
@@ -102,27 +105,26 @@ export const fApproveErc20TxConfig = {
102105
decimal: 18,
103106
isCustom: false,
104107
name: 'REPv1',
105-
networkId: 'Ethereum',
106-
ticker: 'REPv1',
107-
type: 'erc20',
108-
uuid: 'd017a1e8-bdd3-5c32-8866-da258f75b0e9'
108+
networkId: 'Ethereum' as NetworkId,
109+
ticker: 'REPv1' as TTicker,
110+
type: 'erc20' as TAssetType,
111+
uuid: 'd017a1e8-bdd3-5c32-8866-da258f75b0e9' as TUuid
109112
},
110113
baseAsset: { ...fAssets[0], balance: BigNumber.from('0x1b9ced41465be000') },
111114
rawTransaction: {
112115
chainId: 1,
113-
data:
114-
'0x095ea7b3000000000000000000000000221657776846890989a759ba2973e427dff5c9bb0000000000000000000000000000000000000000000000004563918244f40000',
115-
from: '0xfE5443FaC29fA621cFc33D41D1927fd0f5E0bB7c',
116-
gasLimit: '0x249f0',
117-
gasPrice: '0x12a05f200',
118-
nonce: '0x1',
119-
to: '0x1985365e9f78359a9B6AD760e32412f4a445E862',
120-
value: '0x0'
116+
data: '0x095ea7b3000000000000000000000000221657776846890989a759ba2973e427dff5c9bb0000000000000000000000000000000000000000000000004563918244f40000' as ITxData,
117+
from: '0xfE5443FaC29fA621cFc33D41D1927fd0f5E0bB7c' as ITxFromAddress,
118+
gasLimit: '0x249f0' as ITxGasLimit,
119+
gasPrice: '0x12a05f200' as ITxGasPrice,
120+
nonce: '0x1' as ITxNonce,
121+
to: '0x1985365e9f78359a9B6AD760e32412f4a445E862' as ITxToAddress,
122+
value: '0x0' as ITxValue
121123
},
122-
receiverAddress: '0xfE5443FaC29fA621cFc33D41D1927fd0f5E0bB7c',
124+
receiverAddress: '0xfE5443FaC29fA621cFc33D41D1927fd0f5E0bB7c' as TAddress,
123125
senderAccount: fAccounts[0],
124-
from: '0xfE5443FaC29fA621cFc33D41D1927fd0f5E0bB7c',
125-
networkId: 'Ethereum'
126+
from: '0xfE5443FaC29fA621cFc33D41D1927fd0f5E0bB7c' as TAddress,
127+
networkId: 'Ethereum' as NetworkId
126128
};
127129

128130
export const fTokenMigrationTxConfig = {

Diff for: src/components/SignTransactionWallets/Hardware.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ComponentProps } from 'react';
22

33
import { DEFAULT_NETWORK } from '@config';
4-
import { fAccounts } from '@fixtures';
4+
import { fAccounts, fApproveErc20TxConfig } from '@fixtures';
55
import { translateRaw } from '@translations';
66
import { BusyBottomConfig, WalletId } from '@types';
77

@@ -16,7 +16,9 @@ const initialProps: ComponentProps<typeof SignTxHardwareUI> = {
1616
}),
1717
wallet: BusyBottomConfig.LEDGER,
1818
senderAccount: { ...fAccounts[0], wallet: WalletId.LEDGER_NANO_S_NEW },
19-
signingState: WalletSigningState.REJECTED
19+
signingState: WalletSigningState.REJECTED,
20+
rawTransaction: fApproveErc20TxConfig.rawTransaction,
21+
contractName: '0x Proxy'
2022
};
2123

2224
export const HardwareWalletUI = () => {

Diff for: src/components/SignTransactionWallets/Hardware.tsx

+23-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,17 @@ import { TAddress, Wallet } from '@mycrypto/wallets';
55
import styled from 'styled-components';
66

77
import { Body, Box, BusyBottom, Heading, Icon, InlineMessage, TIcon } from '@components';
8+
import { TxIntermediaryDisplay } from '@components/TransactionFlow/displays';
9+
import { isContractInteraction } from '@components/TransactionFlow/helpers';
810
import { HARDWARE_CONFIG, WALLETS_CONFIG } from '@config';
911
import { WalletFactory } from '@services/WalletService';
10-
import { connectWallet, getWalletConnection, useDispatch, useSelector } from '@store';
12+
import {
13+
connectWallet,
14+
getContractName,
15+
getWalletConnection,
16+
useDispatch,
17+
useSelector
18+
} from '@store';
1119
import { FONT_SIZE, SPACING } from '@theme';
1220
import translate, { translateRaw } from '@translations';
1321
import {
@@ -135,6 +143,8 @@ export default function HardwareSignTransaction({
135143
);
136144

137145
const walletType = HARDWARE_CONFIG[senderAccount.wallet as HardwareWalletId].busyBottom;
146+
const network = senderAccount.networkId;
147+
const contractName = useSelector(getContractName(network, rawTransaction.to));
138148

139149
return (
140150
<SignTxHardwareUI
@@ -143,6 +153,8 @@ export default function HardwareSignTransaction({
143153
signingState={signingState}
144154
wallet={walletType}
145155
senderAccount={senderAccount}
156+
rawTransaction={rawTransaction}
157+
contractName={contractName}
146158
/>
147159
);
148160
}
@@ -153,14 +165,18 @@ interface UIProps {
153165
signingState: WalletSigningState;
154166
wallet: BusyBottomConfig;
155167
senderAccount: IAccount;
168+
rawTransaction: ITxObject;
169+
contractName?: string;
156170
}
157171

158172
export const SignTxHardwareUI = ({
159173
walletIconType,
160174
signerDescription,
161175
signingState,
162176
wallet,
163-
senderAccount
177+
senderAccount,
178+
rawTransaction,
179+
contractName
164180
}: UIProps) => (
165181
<>
166182
<Heading textAlign="center" fontWeight="bold" fontSize={FONT_SIZE.XXL}>
@@ -171,6 +187,11 @@ export const SignTxHardwareUI = ({
171187
<Body fontSize={FONT_SIZE.MD} marginTop={SPACING.MD}>
172188
{signerDescription}
173189
</Body>
190+
{isContractInteraction(rawTransaction.data) && rawTransaction.to && (
191+
<Box mt={3}>
192+
<TxIntermediaryDisplay address={rawTransaction.to} contractName={contractName} />
193+
</Box>
194+
)}
174195
<div>
175196
<SImgContainer>
176197
<Icon type={walletIconType} />

Diff for: src/components/SignTransactionWallets/WalletConnect.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import isEmpty from 'ramda/src/isEmpty';
44
import styled, { css } from 'styled-components';
55

66
import {
7+
Box,
78
BusyBottom,
89
Button,
910
CodeBlock,
@@ -12,9 +13,12 @@ import {
1213
Spinner,
1314
Typography
1415
} from '@components';
16+
import { TxIntermediaryDisplay } from '@components/TransactionFlow/displays';
17+
import { isContractInteraction } from '@components/TransactionFlow/helpers';
1518
import { getNetworkByChainId } from '@services';
1619
import { useNetworks } from '@services/Store';
1720
import { TActionError, useWalletConnect, WcReducer } from '@services/WalletService';
21+
import { getContractName, useSelector } from '@store';
1822
import { BREAK_POINTS, COLORS, FONT_SIZE } from '@theme';
1923
import translate, { translateRaw } from '@translations';
2024
import { BusyBottomConfig, ISignComponentProps, ITxHash, TAddress } from '@types';
@@ -159,6 +163,8 @@ export function SignTransactionWalletConnect({
159163
sendTx();
160164
}, [state.isConnected, state.promptSignRetry, state.errors]);
161165

166+
const contractName = useSelector(getContractName(network.id, rawTransaction.to));
167+
162168
return (
163169
<>
164170
<SHeader>
@@ -198,6 +204,11 @@ export function SignTransactionWalletConnect({
198204
<Typography as="div">{translateRaw('SIGN_TX_WALLETCONNECT_INSTRUCTIONS_3')}</Typography>
199205
</SSection>
200206
)}
207+
{isContractInteraction(rawTransaction.data) && rawTransaction.to && (
208+
<Box mt={3}>
209+
<TxIntermediaryDisplay address={rawTransaction.to} contractName={contractName} />
210+
</Box>
211+
)}
201212
<SSection center={true} withOverlay={true}>
202213
<Overlay absolute={true} center={true} show={state.isConnected || !isEmpty(state.errors)}>
203214
<SContainer>

Diff for: src/components/SignTransactionWallets/Web3.stories.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { WALLETS_CONFIG } from '@config';
2-
import { fAccounts } from '@fixtures';
2+
import { fAccounts, fApproveErc20TxConfig } from '@fixtures';
33
import { WalletId } from '@types';
44

55
import { SignTransactionWeb3UI, UIProps, WalletSigningState } from './Web3';
@@ -10,7 +10,9 @@ const initialProps: UIProps = {
1010
walletConfig: WALLETS_CONFIG[WalletId.METAMASK],
1111
walletState: WalletSigningState.SUBMITTING,
1212
networkName: 'Ethereum',
13-
senderAccount: { ...fAccounts[0], wallet: WalletId.METAMASK }
13+
senderAccount: { ...fAccounts[0], wallet: WalletId.METAMASK },
14+
rawTransaction: fApproveErc20TxConfig.rawTransaction,
15+
contractName: '0x Proxy'
1416
};
1517

1618
export const SignTransactionWeb3 = () => {

Diff for: src/components/SignTransactionWallets/Web3.tsx

+19-1
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,18 @@ import { Web3Provider } from '@ethersproject/providers';
55
import styled from 'styled-components';
66

77
import { Body, Box, BusyBottom, Heading, InlineMessage } from '@components';
8+
import { TxIntermediaryDisplay } from '@components/TransactionFlow/displays';
9+
import { isContractInteraction } from '@components/TransactionFlow/helpers';
810
import { IWalletConfig, WALLETS_CONFIG } from '@config';
911
import { useNetworks } from '@services/Store';
12+
import { getContractName, useSelector } from '@store';
1013
import { BREAK_POINTS, FONT_SIZE, SPACING } from '@theme';
1114
import translate, { translateRaw } from '@translations';
1215
import {
1316
BusyBottomConfig,
1417
InlineMessageType,
1518
ISignComponentProps,
19+
ITxObject,
1620
StoreAccount,
1721
TAddress,
1822
WalletId
@@ -113,12 +117,17 @@ export default function SignTransactionWeb3({
113117
});
114118
};
115119

120+
const network = senderAccount.networkId;
121+
const contractName = useSelector(getContractName(network, rawTransaction.to));
122+
116123
return (
117124
<SignTransactionWeb3UI
118125
walletConfig={walletConfig}
119126
walletState={walletState}
120127
networkName={networkName}
121128
senderAccount={senderAccount}
129+
rawTransaction={rawTransaction}
130+
contractName={contractName}
122131
/>
123132
);
124133
}
@@ -158,13 +167,17 @@ export interface UIProps {
158167
walletState: WalletSigningState;
159168
networkName: string;
160169
senderAccount: StoreAccount;
170+
rawTransaction: ITxObject;
171+
contractName?: string;
161172
}
162173

163174
export const SignTransactionWeb3UI = ({
164175
walletConfig,
165176
walletState,
166177
networkName,
167-
senderAccount
178+
senderAccount,
179+
rawTransaction,
180+
contractName
168181
}: UIProps) => (
169182
<Box>
170183
<Heading fontSize="32px" textAlign="center" fontWeight="bold">
@@ -177,6 +190,11 @@ export const SignTransactionWeb3UI = ({
177190
$walletName: walletConfig.name || WALLETS_CONFIG.WEB3.name
178191
})}
179192
</Body>
193+
{isContractInteraction(rawTransaction.data) && rawTransaction.to && (
194+
<Box mt={3}>
195+
<TxIntermediaryDisplay address={rawTransaction.to} contractName={contractName} />
196+
</Box>
197+
)}
180198
<Web3ImgContainer>
181199
<Web3Img>
182200
<img src={walletConfig.icon} />

Diff for: src/components/SignTransactionWallets/__tests__/SignTransactionGridPlus.test.tsx

+23-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { ComponentProps } from 'react';
33
import { APP_STATE, mockAppState, simpleRender, waitFor } from 'test-utils';
44

55
import SignTransaction from '@features/SendAssets/components/SignTransaction';
6-
import { fTxConfig } from '@fixtures';
6+
import { fApproveErc20TxConfig, fTxConfig } from '@fixtures';
7+
import { translateRaw } from '@translations';
78
import { WalletId } from '@types';
89

910
import { getHeader } from './helper';
@@ -81,4 +82,25 @@ describe('SignTransactionWallets: GridPlus', () => {
8182
{ timeout: 60000 }
8283
);
8384
});
85+
86+
it('Shows contract info if needed', async () => {
87+
const { getByText } = getComponent({
88+
...defaultProps,
89+
txConfig: {
90+
...fApproveErc20TxConfig,
91+
senderAccount: {
92+
...fTxConfig.senderAccount,
93+
wallet: WalletId.GRIDPLUS
94+
}
95+
}
96+
});
97+
expect(
98+
getByText(
99+
translateRaw('TRANSACTION_PERFORMED_VIA_CONTRACT', {
100+
$contractName: translateRaw('UNKNOWN').toLowerCase()
101+
}),
102+
{ exact: false }
103+
)
104+
).toBeInTheDocument();
105+
});
84106
});

Diff for: src/components/SignTransactionWallets/__tests__/SignTransactionWeb3.test.tsx

+27-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { ComponentProps } from 'react';
33
import { simpleRender, waitFor } from 'test-utils';
44

55
import SignTransaction from '@features/SendAssets/components/SignTransaction';
6-
import { fTxConfig } from '@fixtures';
6+
import { fApproveErc20TxConfig, fTxConfig } from '@fixtures';
7+
import { translateRaw } from '@translations';
78
import { WalletId } from '@types';
89

910
// eslint-disable-next-line jest/no-mocks-import
@@ -15,8 +16,8 @@ const defaultProps: ComponentProps<typeof SignTransaction> = {
1516
onComplete: jest.fn()
1617
};
1718

18-
const getComponent = () => {
19-
return simpleRender(<SignTransaction {...defaultProps} />);
19+
const getComponent = (props = defaultProps) => {
20+
return simpleRender(<SignTransaction {...props} />);
2021
};
2122

2223
jest.mock('@ethersproject/providers', () => {
@@ -31,11 +32,11 @@ jest.mock('@ethersproject/providers', () => {
3132
});
3233

3334
describe('SignTransactionWallets: Web3', () => {
34-
afterEach(() => {
35+
afterAll(() => {
3536
jest.resetAllMocks();
3637
});
3738

38-
test('Can handle Web3 signing', async () => {
39+
it('Can handle Web3 signing', async () => {
3940
const customWindow = window as CustomWindow;
4041
// Mock window.ethereum
4142
mockWindow(customWindow);
@@ -46,4 +47,25 @@ describe('SignTransactionWallets: Web3', () => {
4647
await waitFor(() => expect(customWindow.ethereum.on).toHaveBeenCalled());
4748
await waitFor(() => expect(defaultProps.onComplete).toHaveBeenCalledWith('txhash'));
4849
});
50+
51+
it('Shows contract info if needed', async () => {
52+
const customWindow = window as CustomWindow;
53+
// Mock window.ethereum
54+
mockWindow(customWindow);
55+
const { getByText } = getComponent({
56+
...defaultProps,
57+
txConfig: {
58+
...fApproveErc20TxConfig,
59+
senderAccount: { ...fTxConfig.senderAccount, wallet: WalletId.WEB3 }
60+
}
61+
});
62+
expect(
63+
getByText(
64+
translateRaw('TRANSACTION_PERFORMED_VIA_CONTRACT', {
65+
$contractName: translateRaw('UNKNOWN').toLowerCase()
66+
}),
67+
{ exact: false }
68+
)
69+
).toBeInTheDocument();
70+
});
4971
});

0 commit comments

Comments
 (0)