@@ -1,4 +1,4 @@
1−import React, { useMemo, useCallback } from 'react';
1+import React, { useMemo, useCallback, useState } from 'react';
22import cn from 'classnames';
33import {
44 Grid,
@@ -8,11 +8,16 @@ import {
88 LinkButton,
99 H5,
1010 Text,
11+ IconButton,
1112} from 'indigo-react';
13+import { toBN } from 'web3-utils';
14+
15+import { ReactComponent as InfoIcon } from 'assets/info.svg';
1216
1317import { useExploreTxUrls } from 'lib/explorer';
1418import { hexify } from 'lib/txn';
1519import pluralize from 'lib/pluralize';
20+import { safeFromWei, safeToWei } from 'lib/lib';
1621
1722import { composeValidator, buildCheckboxValidator } from 'form/validators';
1823import BridgeForm from 'form/BridgeForm';
@@ -45,6 +50,8 @@ export default function InlineEthereumTransaction({
4550 needFunds,
4651 signedTransactions,
4752 confirmationProgress,
53+ gasLimit,
54+ unsignedTransactions,
4855
4956 // additional from parent
5057 label = 'Generate & Sign Transaction',
@@ -52,7 +59,11 @@ export default function InlineEthereumTransaction({
5259 onReturn,
5360}) {
5461 // show receipt after successful broadcast
55− const showReceipt = broadcasted || confirmed || completed;
62+ const [showReceipt, setShowReceipt] = useState(false);
63+ const toggleShowReceipt = useCallback(() => setShowReceipt(!showReceipt), [
64+ setShowReceipt,
65+ showReceipt,
66+ ]);
5667 // show configure controls pre-broadcast
5768 const showConfigureInput = !(signed || broadcasted || confirmed || completed);
5869 // show the send/loading button while signed, broadcasting, or confirme
@@ -62,6 +73,12 @@ export default function InlineEthereumTransaction({
6273 // show signed tx only when signing (for offline usage)
6374 const showSignedTx = signed;
6475
76+ const [showGasDetails, _setShowGasDetails] = useState(false);
77+ const toggleGasDetails = useCallback(
78+ () => _setShowGasDetails(!showGasDetails),
79+ [_setShowGasDetails, showGasDetails]
80+ );
81+
6582 const validate = useMemo(
6683 () =>
6784 composeValidator({
@@ -88,11 +105,7 @@ export default function InlineEthereumTransaction({
88105 </Grid.Item>
89106 );
90107 } else if (completed) {
91− return (
92− <Grid.Item full className="pv4 black f5">
93− Transaction Complete
94− </Grid.Item>
95− );
108+ return undefined;
96109 } else if (showBroadcastButton) {
97110 return (
98111 <Grid.Item
@@ -137,6 +150,29 @@ export default function InlineEthereumTransaction({
137150 [signedTransactions]
138151 );
139152
153+ const numTxs = useMemo(() => (unsignedTransactions || []).length || 1, [
154+ unsignedTransactions,
155+ ]);
156+ const maxCost = useMemo(
157+ () =>
158+ safeFromWei(
159+ safeToWei(
160+ toBN(gasLimit)
161+ .mul(toBN(gasPrice))
162+ .mul(toBN(numTxs)),
163+ 'gwei'
164+ )
165+ ),
166+ [gasLimit, gasPrice, numTxs]
167+ );
168+
169+ const gasInfo = useMemo(() => {
170+ const extra = numTxs === 1 ? '' : `* ${numTxs} TXN`;
171+ return showGasDetails
172+ ? `${gasPrice} Gwei * ${gasLimit} ${extra} = ${maxCost} ETH`
173+ : `${maxCost} ETH`;
174+ }, [showGasDetails, maxCost, gasPrice, gasLimit, numTxs]);
175+
140176 return (
141177 <Grid className={cn(className, 'mt1')}>
142178 <BridgeForm validate={validate} onValues={onValues}>
@@ -172,6 +208,7 @@ export default function InlineEthereumTransaction({
172208 />
173209
174210 <Condition when="useAdvanced" is={true}>
211+ <Grid.Item full className="mb2"></Grid.Item>
175212 <Grid.Divider />
176213 <Grid.Item
177214 full
@@ -180,8 +217,16 @@ export default function InlineEthereumTransaction({
180217 justify="between"
181218 className="mt2">
182219 <Flex.Item as={H5}>Gas Price</Flex.Item>
183− <Flex.Item as={H5}>{gasPrice} Gwei</Flex.Item>
220+
221+ <Flex.Item as={H5}>
222+ {gasInfo}{' '}
223+ <InfoIcon
224+ className="pointer"
225+ onClick={toggleGasDetails}
226+ />
227+ </Flex.Item>
184228 </Grid.Item>
229+
185230 {/* TODO(shrugs): move to indigo/RangeInput */}
186231 <Grid.Item
187232 full
@@ -228,21 +273,28 @@ export default function InlineEthereumTransaction({
228273 </>
229274 )}
230275
231− {showReceipt && (
232− <>
233− <Grid.Divider />
234− <HashReceiptList txHashes={txHashes} />
235−
236− <Grid.Divider />
237− </>
238− )}
239−
240276 {completed && (
241277 <>
242278 <Grid.Item full as={RestartButton} onClick={onReturn}>
243279 Return
244280 </Grid.Item>
245281 <Grid.Divider />
282+ {showReceipt && (
283+ <TransactionReceipt
284+ txHashes={txHashes}
285+ maxCost={maxCost}
286+ onClose={toggleShowReceipt}
287+ />
288+ )}
289+
290+ {!showReceipt && (
291+ <Grid.Item
292+ className="underline mv2 pointer"
293+ full
294+ onClick={toggleShowReceipt}>
295+ View Receipt
296+ </Grid.Item>
297+ )}
246298 </>
247299 )}
248300 </>
@@ -278,34 +330,42 @@ function SignedTransactionList({ serializedTxsHex, nonce, gasPrice }) {
278330 ));
279331}
280332
281−function HashReceiptList({ txHashes }) {
333+function TransactionReceipt({ txHashes, maxCost, onClose }) {
282334 const txUrls = useExploreTxUrls(txHashes);
283− const header = pluralize(txHashes.length, 'Hash', 'Hashes');
284335 return (
285336 <>
337+ <Grid.Item full as={Flex} justify="between" className="pv2 black f5">
338+ <Flex.Item>Receipt</Flex.Item>
339+ <Flex.Item onClick={onClose} className="underline pointer">
340+ Close
341+ </Flex.Item>
342+ </Grid.Item>
343+ <Grid.Item full as={Flex} justify="between" className="pv2 black f5">
344+ <Flex.Item>Gas Price</Flex.Item>
345+ <Flex.Item className="mono">{maxCost} ETH</Flex.Item>
346+ </Grid.Item>
286347 <Grid.Divider />
287348 <Grid.Item full as={Flex} col className="pv4">
288− <Flex.Item as={H5}>Transaction {header}</Flex.Item>
349+ <Flex.Item as={H5}>Receipt</Flex.Item>
289350
290351 {txHashes &&
291352 txHashes.map((txHash, i) => (
292− <Flex.Item as={Flex}>
353+ <Flex.Item as={Flex} className="mv3">
293354 <>
294355 <Flex.Item
295356 key={i}
296357 flex
297358 as="code"
298− className="f6 mono gray4 wrap">
359+ className="f6 mono gray4 wrap ">
299360 {txHash}
300361 </Flex.Item>
301− <Flex.Item as={LinkButton} href={txUrls[i]}>
362+ <Flex.Item className="ml8" as={LinkButton} href={txUrls[i]}>
302363 Etherscan↗
303364 </Flex.Item>
304365 </>
305366 </Flex.Item>
306367 ))}
307368 </Grid.Item>
308− <Grid.Divider />
309369 </>
310370 );
311371}