1import React, { useMemo, useCallback, useState } from 'react';
2import cn from 'classnames';
11import { toBN } from 'web3-utils';
13import { useExploreTxUrls } from 'lib/explorer';
14import { hexify } from 'lib/txn';
15import { safeFromWei, safeToWei } from 'lib/lib';
17import { composeValidator, buildCheckboxValidator } from 'form/validators';
18import BridgeForm from 'form/BridgeForm';
19import Condition from 'form/Condition';
21import { GenerateButton, ForwardButton, RestartButton } from './Buttons';
22import ProgressButton from './ProgressButton';
23import NeedFundsNotice from './NeedFundsNotice';
24import NoticeBox from './NoticeBox';
25import FeeDropdown from './L2/Dropdowns/FeeDropdown';
26import CopyButton from './copiable/CopyButton';
28import './InlineEthereumTransaction.scss';
30export default function InlineEthereumTransaction({
31 // from useEthereumTransaction.bind
56 // additional from parent
57 label = 'Generate & Sign Transaction',
61 // show receipt after successful broadcast
62 const [showReceipt, setShowReceipt] = useState(false);
63 const toggleShowReceipt = useCallback(() => setShowReceipt(!showReceipt), [
67 // show configure controls pre-broadcast
68 const showConfigureInput = !(signed || broadcasted || confirmed || completed);
69 // show the send/loading button while signed, broadcasting, or confirme
70 const showBroadcastButton = signed;
71 const showLoadingButton = broadcasted || confirmed;
72 const canBroadcast = signed && !needFunds;
73 // show signed tx only when signing (for offline usage)
74 const showSignedTx = signed;
76 const validate = useMemo(
79 useAdvanced: buildCheckboxValidator(),
80 viewSigned: buildCheckboxValidator(),
85 const onValues = useCallback(
86 ({ valid, values, form }) => {
87 if (!values.useAdvanced) {
94 const renderPrimarySection = () => {
98 className="eth-tx-button"
103 onClick={() => reset()}>
107 } else if (completed) {
112 className="eth-tx-button"
123 finalCost={finalCost}
124 onClose={toggleShowReceipt}
130 className="underline mv2 pointer"
132 onClick={toggleShowReceipt}>
138 } else if (showBroadcastButton) {
141 className="ph4 eth-tx-button"
147 disabled={!canBroadcast}
148 onClick={() => broadcast()}>
152 } else if (showLoadingButton) {
155 className="ph4 eth-tx-button"
161 progress={confirmationProgress}>
168 className="ph4 eth-tx-button"
172 onClick={generateAndSign}
174 loading={!canSign && initializing}>
181 const serializedTxsHex = useMemo(
183 signedTransactions &&
184 signedTransactions.map(stx => hexify(stx.serialize())),
188 const numTxs = useMemo(() => (unsignedTransactions || []).length || 1, [
189 unsignedTransactions,
191 const maxCost = useMemo(
202 [gasLimit, gasPrice, numTxs]
206 <Grid className={cn(className, 'mt1', 'inline-ethereum-tx')}>
207 <BridgeForm validate={validate} onValues={onValues}>
210 {showConfigureInput && (
213 className="mt2 text eth-tx-button"
218 <Flex.Item as={H5}>Gas Fee</Flex.Item>
219 <FeeDropdown setGasPrice={setGasPrice} />
223 className="mt2 text eth-tx-button"
228 <Flex.Item as={H5}>Max Transaction Cost</Flex.Item>
229 <Flex.Item as={H5}>{maxCost} ETH</Flex.Item>
231 <Grid.Divider className="mt4" />
235 {renderPrimarySection()}
238 <Grid.Item full as={ErrorText} className="mv1">
252 {showSignedTx && fakeSigned && (
254 <Grid.Item full as={NoticeBox} className="mt2">
255 Your wallet will sign the transaction upon sending it.
260 {showSignedTx && !fakeSigned && (
263 className="eth-tx-button text"
267 label="Signed Transaction"
269 disabled={!showSignedTx}
271 <Condition when="viewSigned" is={true}>
272 <SignedTransactionList
273 serializedTxsHex={serializedTxsHex}
287function SignedTransactionList({ serializedTxsHex, nonce, maxCost }) {
288 return serializedTxsHex.map((serializedTxHex, i) => (
289 <React.Fragment key={i}>
291 <Grid.Item full as={Flex} justify="between" className="pv4 black f5">
292 <Flex.Item>Nonce</Flex.Item>
293 <Flex.Item>{nonce + i}</Flex.Item>
296 <Grid.Item full as={Flex} justify="between" className="pv4 black f5">
297 <Flex.Item>Transaction Cost</Flex.Item>
298 <Flex.Item>{maxCost} ETH</Flex.Item>
301 <Grid.Item full as={Flex} justify="between" className="mt3 mb2">
302 <Flex.Item as={H5}>Signed Transaction Hex</Flex.Item>
303 <Flex.Item as={CopyButton} text={serializedTxHex} />
305 <Grid.Item full as="code" className="mb4 f6 mono gray4 wrap">
313function TransactionReceipt({ txHashes, finalCost, onClose }) {
314 const txUrls = useExploreTxUrls(txHashes);
318 className="pv2 black f5 eth-tx-button"
322 <Flex.Item>Receipt</Flex.Item>
323 <Flex.Item onClick={onClose} className="underline pointer">
328 className="pv2 black f5 eth-tx-button"
332 <Flex.Item>Transaction Cost</Flex.Item>
333 <Flex.Item className="mono">{finalCost} ETH</Flex.Item>
336 <Grid.Item className="pv4 eth-tx-button" full as={Flex} col>
337 <Flex.Item as={H5}>Receipt</Flex.Item>
340 txHashes.map((txHash, i) => (
341 <Flex.Item as={Flex} className="mv3">
347 className="f6 mono gray4 wrap ">
350 <Flex.Item className="ml8" as={LinkButton} href={txUrls[i]}>
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list