on master help sign in
feat: implement transaction configuration
commit764521d000b96e46a2b85b1612d1e5cf3fd63a63 authorMatt Condon (shrugs) <mattgcondon@gmail.com> dateTue 16 Jul 2019, 21:44 (7 years ago) parente7ae14d
8 files changed+151−41
src/components/InlineEthereumTransaction.js+54−14 src/components/NoticeBox.js+11 src/lib/constants.js+2 src/lib/txn.js+12−14 src/lib/useEthereumTransaction.js+5−2 src/style/bridge.scss+54 src/views/Admin/AdminNetworkingKeys.js+7−7 src/views/Invite/InviteEmail.js+6−4
src/components/InlineEthereumTransaction.js+54−14
@@ -7,6 +7,8 @@ import {
77 Flex,
88 LinkButton,
99 H5,
10+ Text,
11+ HelpText,
1012} from 'indigo-react';
1113import { GenerateButton, ForwardButton, RestartButton } from './Buttons';
1214import { useCheckboxInput } from 'lib/useInputs';
@@ -25,20 +27,30 @@ export default function InlineEthereumTransaction({
2527 confirmed,
2628 reset,
2729 error,
30+ gasPrice,
2831 setGasPrice,
2932 txHash,
33+ nonce,
34+ chainId,
3035 signedTransaction,
3136
3237 // additional from parent
3338 className,
3439 onReturn,
3540}) {
41+ // show receipt after successful broadcast
42+ const showReceipt = broadcasted || confirmed;
43+ // show configure controls pre-broadcast
44+ const showConfigureInput = !(signed || broadcasted || confirmed);
45+ // show signed tx after signing
46+ const showSignedTx = signed;
47+
3648 const exploreHashUrl = useExploreTxUrl(txHash);
37− const [configureInput, { data: configurationOpen }] = useCheckboxInput({
38− name: 'configure',
39− label: 'Configure Transaction',
40− inverseLabel: 'Cancel Configure Transaction',
41− disabled: signed || broadcasted || confirmed,
49+ const [advancedInput, { data: advancedOpen }] = useCheckboxInput({
50+ name: 'advanced',
51+ label: 'Advanced Configuration',
52+ inverseLabel: 'Hide Advanced Configuration',
53+ disabled: !showConfigureInput,
4254 });
4355
4456 const [
@@ -48,16 +60,9 @@ export default function InlineEthereumTransaction({
4860 name: 'viewsigned',
4961 label: 'View Signed Transaction',
5062 inverseLabel: 'Hide Signed Transaction',
51− disabled: !signed,
63+ disabled: !showSignedTx,
5264 });
5365
54− // show receipt after successful broadcast
55− const showReceipt = broadcasted || confirmed;
56− // show configure controls pre-broadcast
57− const showConfigureInput = !(broadcasted || confirmed);
58− // show signed tx after signing
59− const showSignedTx = signed;
60−
6166 const renderButton = () => {
6267 if (error) {
6368 return (
@@ -122,7 +127,42 @@ export default function InlineEthereumTransaction({
122127 )}
123128
124129 {showConfigureInput && (
125− <Grid.Item full as={ToggleInput} {...configureInput} />
130+ <>
131+ {!advancedOpen ? (
132+ <Grid.Item full as={ToggleInput} {...advancedInput} />
133+ ) : (
134+ <>
135+ <Grid.Item full as={Flex} row justify="between" className="mt2">
136+ <Flex.Item as={H5}>Gas Price</Flex.Item>
137+ <Flex.Item as={H5}>{gasPrice} Gwei</Flex.Item>
138+ </Grid.Item>
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+ </>
164+ )}
165+ </>
126166 )}
127167
128168 {showSignedTx && (
src/components/NoticeBox.jsnew file+11
@@ -0,0 +1,11 @@
1+import React from 'react';
2+import cn from 'classnames';
3+import { Flex, Text } from 'indigo-react';
4+
5+export default function NoticeBox({ className, children }) {
6+ return (
7+ <Flex className={cn('bg-gray2 pv3 ph4', className)} align="center">
8+ <Text className="f6 fw-bold gray4">{children}</Text>
9+ </Flex>
10+ );
11+}
src/lib/constants.js+2
@@ -1,6 +1,7 @@
11import { isDevelopment } from './flags';
22
33const CHECK_BLOCK_EVERY_MS = isDevelopment ? 1000 : 5000;
4+const DEFAULT_GAS_PRICE_GWEI = 20;
45
56const MIN_GALAXY = 0;
67const MAX_GALAXY = 255;
@@ -72,6 +73,7 @@ const PROFILE_STATES = {
7273
7374export {
7475 CHECK_BLOCK_EVERY_MS,
76+ DEFAULT_GAS_PRICE_GWEI,
7577 GAS_LIMITS,
7678 GEN_STATES,
7779 BUTTON_STATES,
src/lib/txn.js+12−14
@@ -16,20 +16,18 @@ const RETRY_OPTIONS = {
1616 randomize: false,
1717};
1818
19−const signTransaction = async config => {
20− let {
21− wallet,
22− walletType,
23− walletHdPath,
24− networkType,
25− txn,
26− nonce,
27− chainId,
28− gasPrice,
29− gasLimit,
30− } = config;
31−
32− //TODO require these in txn object
19+const signTransaction = async ({
20+ wallet,
21+ walletType,
22+ walletHdPath,
23+ networkType,
24+ txn,
25+ nonce, // number
26+ chainId, // number
27+ gasPrice, // string
28+ gasLimit, // string | number
29+}) => {
30+ // TODO: require these in txn object
3331 nonce = toHex(nonce);
3432 chainId = toHex(chainId);
3533 gasPrice = toHex(toWei(gasPrice, 'gwei'));
src/lib/useEthereumTransaction.js+5−2
@@ -73,7 +73,7 @@ export default function useEthereumTransaction(initialGasLimit = 0) {
7373 txn: unsignedTransaction,
7474 nonce,
7575 chainId,
76− gasPrice,
76+ gasPrice: gasPrice.toFixed(0),
7777 gasLimit,
7878 });
7979
@@ -134,7 +134,7 @@ export default function useEthereumTransaction(initialGasLimit = 0) {
134134
135135 setNonce(nonce);
136136 setChainId(chainId);
137− setGasPrice(fromWei(estimatedGasPrice, 'gwei'));
137+ setGasPrice(parseInt(fromWei(estimatedGasPrice, 'gwei'), 10));
138138 } catch (error) {
139139 setError(error);
140140 }
@@ -166,8 +166,11 @@ export default function useEthereumTransaction(initialGasLimit = 0) {
166166 confirmed,
167167 reset,
168168 error,
169+ gasPrice,
169170 setGasPrice,
170171 txHash,
172+ nonce,
173+ chainId,
171174 signedTransaction,
172175 },
173176 };
src/style/bridge.scss+54
@@ -26,3 +26,57 @@ body {
2626#root {
2727 min-height: 100vh;
2828}
29+
30+// range slider
31+
32+input[type='range'] {
33+ overflow: hidden;
34+ -webkit-appearance: none;
35+ background-color: #e6e6e6;
36+
37+ /* Chrome */
38+ &::-webkit-slider-runnable-track {
39+ height: 24px;
40+ -webkit-appearance: none;
41+ background-color: #e6e6e6;
42+ margin-top: -1px;
43+ }
44+
45+ &::-webkit-slider-thumb {
46+ -webkit-appearance: none;
47+ width: 24px;
48+ height: 100%;
49+ background-color: #000;
50+ border: none;
51+ border-radius: 0;
52+ cursor: ew-resize;
53+ }
54+
55+ /* FF */
56+ &::-moz-range-progress {
57+ height: 100%;
58+ background-color: #000;
59+ }
60+
61+ &::-moz-range-track {
62+ background-color: #e6e6e6;
63+ }
64+
65+ &::-moz-range-thumb {
66+ width: 24px;
67+ height: 100%;
68+ background-color: #000;
69+ border: none;
70+ border-radius: 0;
71+ cursor: ew-resize;
72+ }
73+
74+ /* IE */
75+ &::-ms-fill-lower {
76+ background-color: #000;
77+ }
78+
79+ &::-ms-fill-upper {
80+ background-color: #e6e6e6;
81+ }
82+}
src/views/Admin/AdminNetworkingKeys.js+7−7
@@ -6,6 +6,8 @@ import { randomHex } from 'web3-utils';
66
77import { usePointCursor } from 'store/pointCursor';
88import { usePointCache } from 'store/pointCache';
9+import { useNetwork } from 'store/network';
10+import { useWallet } from 'store/wallet';
911
1012import { useLocalRouter } from 'lib/LocalRouter';
1113import * as need from 'lib/need';
@@ -15,19 +17,17 @@ import {
1517 deriveNetworkKeys,
1618} from 'lib/keys';
1719import { formatDotsWithTime } from 'lib/dateFormat';
20+import useEthereumTransaction from 'lib/useEthereumTransaction';
21+import { GAS_LIMITS, ZERO_KEY } from 'lib/constants';
22+import { addHexPrefix } from 'lib/wallet';
1823
1924import ViewHeader from 'components/ViewHeader';
2025import MiniBackButton from 'components/MiniBackButton';
2126import { BootArvoButton, ForwardButton } from 'components/Buttons';
2227import FooterButton from 'components/FooterButton';
23−import WarningBox from 'components/WarningBox';
2428import DownloadKeyfileButton from 'components/DownloadKeyfileButton';
25−import useEthereumTransaction from 'lib/useEthereumTransaction';
26−import { GAS_LIMITS, ZERO_KEY } from 'lib/constants';
2729import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
28−import { addHexPrefix } from 'lib/wallet';
29−import { useNetwork } from 'store/network';
30−import { useWallet } from 'store/wallet';
30+import NoticeBox from 'components/NoticeBox';
3131
3232const CRYPTO_SUITE_VERSION = 1;
3333
@@ -290,7 +290,7 @@ export default function AdminNetworkingKeys() {
290290 )}
291291
292292 {confirmed && (
293− <Grid.Item full as={WarningBox} className="mb3">
293+ <Grid.Item full as={NoticeBox} className="mb3">
294294 You need this keyfile to authenticate with Arvo.
295295 </Grid.Item>
296296 )}
src/views/Invite/InviteEmail.js+6−4
@@ -32,7 +32,7 @@ import * as tank from 'lib/tank';
3232import { useLocalRouter } from 'lib/LocalRouter';
3333import useArray from 'lib/useArray';
3434import { buildEmailInputConfig } from 'lib/useInputs';
35−import { MIN_PLANET, GAS_LIMITS } from 'lib/constants';
35+import { MIN_PLANET, GAS_LIMITS, DEFAULT_GAS_PRICE_GWEI } from 'lib/constants';
3636import * as need from 'lib/need';
3737import * as wg from 'lib/walletgen';
3838import useSetState from 'lib/useSetState';
@@ -43,9 +43,11 @@ import MiniBackButton from 'components/MiniBackButton';
4343import LoadableButton from 'components/LoadableButton';
4444import Highlighted from 'components/Highlighted';
4545
46−const GAS_PRICE_GWEI = 20; // we pay the premium for faster ux
4746const GAS_LIMIT = GAS_LIMITS.GIFT_PLANET;
48−const INVITE_COST = toWei((GAS_PRICE_GWEI * GAS_LIMIT).toString(), 'gwei');
47+const INVITE_COST = toWei(
48+ (DEFAULT_GAS_PRICE_GWEI * GAS_LIMIT).toString(),
49+ 'gwei'
50+);
4951const HAS_RECEIVED_TEXT = 'This email has already received an invite.';
5052
5153const STATUS = {
@@ -252,7 +254,7 @@ export default function InviteEmail() {
252254 networkType,
253255 // TODO: ^ make a useTransactionSigner to encapsulate this logic
254256 txn: inviteTx,
255− gasPrice: GAS_PRICE_GWEI.toString(),
257+ gasPrice: DEFAULT_GAS_PRICE_GWEI.toString(),
256258 gasLimit: GAS_LIMIT.toString(),
257259 nonce: nonce + i,
258260 chainId,