on 0705a40 help sign in
bridge/src/components/InlineEthereumTransaction.js
202 lines 5.3 kB history raw
1import React, { useEffect } from 'react';
2import cn from 'classnames';
3import {
4 Grid,
5 ToggleInput,
6 ErrorText,
7 Flex,
8 LinkButton,
9 H5,
10 Text,
11 HelpText,
12} from 'indigo-react';
14import { useCheckboxInput } from 'lib/useInputs';
15import { hexify } from 'lib/txn';
16import { useExploreTxUrl } from 'lib/explorer';
18import { GenerateButton, ForwardButton, RestartButton } from './Buttons';
20export default function InlineEthereumTransaction({
21 // from useEthereumTransaction.bind
22 initializing,
23 canSign,
24 generateAndSign,
25 signed,
26 broadcast,
27 broadcasted,
28 confirmed,
29 reset,
30 error,
31 gasPrice,
32 setGasPrice,
33 resetGasPrice,
34 txHash,
35 nonce,
36 chainId,
37 signedTransaction,
39 // additional from parent
40 label = 'Generate & Sign Transaction',
41 className,
42 onReturn,
43}) {
44 // show receipt after successful broadcast
45 const showReceipt = broadcasted || confirmed;
46 // show configure controls pre-broadcast
47 const showConfigureInput = !(signed || broadcasted || confirmed);
48 // show signed tx only when signing (for offline usage)
49 const showSignedTx = signed;
51 const exploreTxUrl = useExploreTxUrl(txHash);
52 const [advancedInput, { data: advancedOpen }] = useCheckboxInput({
53 name: 'advanced',
54 label: 'Advanced Configuration',
55 inverseLabel: 'Cancel Advanced Configuration',
56 disabled: !showConfigureInput,
57 });
59 const [
60 viewSignedTransaction,
61 { data: signedTransactionOpen },
62 ] = useCheckboxInput({
63 name: 'viewsigned',
64 label: 'View Signed Transaction',
65 inverseLabel: 'Hide Signed Transaction',
66 disabled: !showSignedTx,
67 });
69 // reset gas price when closing advanced configuration
70 useEffect(() => {
71 if (!advancedOpen) {
72 resetGasPrice();
73 }
74 }, [advancedOpen, resetGasPrice]);
76 const renderPrimaryButton = () => {
77 if (error) {
78 return (
79 <Grid.Item full as={RestartButton} solid onClick={() => reset()}>
80 Reset Transaction
81 </Grid.Item>
82 );
83 } else if (confirmed) {
84 return (
85 <>
86 <Grid.Divider />
87 <Grid.Item full as={RestartButton} onClick={onReturn}>
88 Return
89 </Grid.Item>
90 </>
91 );
92 } else if (signed || broadcasted) {
93 return (
94 <Grid.Item
95 full
96 as={ForwardButton}
97 solid
98 success
99 disabled={broadcasted}
100 loading={broadcasted}
101 onClick={() => broadcast()}>
102 Send Transaction
103 </Grid.Item>
104 );
105 } else {
106 return (
107 <Grid.Item
108 full
109 as={GenerateButton}
110 onClick={generateAndSign}
111 disabled={!canSign}
112 loading={!canSign && initializing}>
113 {label}
114 </Grid.Item>
115 );
116 }
117 };
119 return (
120 <Grid className={cn(className, 'mt1')}>
121 {renderPrimaryButton()}
123 {error && (
124 <Grid.Item full as={ErrorText} className="mt1">
125 {error.message}
126 </Grid.Item>
127 )}
129 {showConfigureInput && (
130 <>
131 <Grid.Item full as={ToggleInput} {...advancedInput} />
132 {advancedOpen && (
133 <>
134 <Grid.Item full as={Flex} row justify="between" className="mt2">
135 <Flex.Item as={H5}>Gas Price</Flex.Item>
136 <Flex.Item as={H5}>{gasPrice} Gwei</Flex.Item>
137 </Grid.Item>
138 {/* TODO(shrugs): move to indigo/RangeInput */}
139 <Grid.Item
140 full
141 as="input"
142 type="range"
143 min="1"
144 max="100"
145 value={gasPrice}
146 onChange={e => setGasPrice(parseInt(e.target.value, 10))}
147 />
148 <Grid.Item
149 full
150 as={Flex}
151 row
152 justify="between"
153 className="f6 mt1">
154 <Flex.Item as={Text}>Cheap</Flex.Item>
155 <Flex.Item as={Text}>Fast</Flex.Item>
156 </Grid.Item>
157 <Grid.Item full as={HelpText} className="mt3">
158 Nonce: {nonce}
159 </Grid.Item>
160 <Grid.Item full as={HelpText} className="mt1">
161 Chain ID: {chainId}
162 </Grid.Item>
163 <Grid.Divider className="mt3" />
164 </>
165 )}
166 </>
167 )}
169 {showSignedTx && (
170 <>
171 <Grid.Item full as={ToggleInput} {...viewSignedTransaction} />
172 {signedTransactionOpen && (
173 <Grid.Item full as="code" className="f6 mono gray4 wrap">
174 {hexify(signedTransaction.serialize())}
175 </Grid.Item>
176 )}
177 </>
178 )}
180 {showReceipt && (
181 <>
182 <Grid.Divider />
183 <Grid.Item full as={Flex} col className="pv4">
184 <Flex.Item as={Flex} row justify="between">
185 <Flex.Item as={H5}>Transaction Hash</Flex.Item>
186 <Flex.Item as={LinkButton} href={exploreTxUrl}>
187 Etherscan↗
188 </Flex.Item>
189 </Flex.Item>
190 <Flex.Item as={Flex}>
191 <Flex.Item flex as="code" className="f6 mono gray4 wrap">
192 {txHash}
193 </Flex.Item>
194 <Flex.Item flex />
195 </Flex.Item>
196 </Grid.Item>
197 <Grid.Divider />
198 </>
199 )}
200 </Grid>
201 );