on 58fbcd2 help sign in
bridge/src/views/Admin/Reticket/ReticketExecute.js
186 lines 5.6 kB history raw
1import React, { useState, useCallback } from 'react';
2import { Just, Nothing } from 'folktale/maybe';
3import { Grid, H4, Text, ErrorText } from 'indigo-react';
4import { fromWei } from 'web3-utils';
6import {
7 reticketPointBetweenWallets,
8 TRANSACTION_PROGRESS,
9} from 'lib/reticket';
10import * as need from 'lib/need';
11import useLifecycle from 'lib/useLifecycle';
13import { useNetwork } from 'store/network';
14import { useWallet } from 'store/wallet';
15import { usePointCursor } from 'store/pointCursor';
16import { usePointCache } from 'store/pointCache';
17import { useHistory } from 'store/history';
19import { RestartButton, ForwardButton } from 'components/Buttons';
20import WarningBox from 'components/WarningBox';
21import LoadingBar from 'components/LoadingBar';
22import Highlighted from 'components/Highlighted';
23import { WALLET_TYPES } from 'lib/wallet';
25const labelForProgress = progress => {
26 if (progress <= 0) {
27 return 'Starting...';
28 } else if (progress <= TRANSACTION_PROGRESS.GENERATING) {
29 return 'Generating Transactions...';
30 } else if (progress <= TRANSACTION_PROGRESS.SIGNING) {
31 return 'Signing Transactions...';
32 } else if (progress <= TRANSACTION_PROGRESS.FUNDING) {
33 return 'Funding Transactions...';
34 } else if (progress <= TRANSACTION_PROGRESS.TRANSFERRING) {
35 return 'Transferring Point...';
36 } else if (progress <= TRANSACTION_PROGRESS.CLEANING) {
37 return 'Cleaning Up...';
38 } else if (progress <= TRANSACTION_PROGRESS.DONE) {
39 return 'Done';
40 }
41};
43export default function ReticketExecute({ newWallet, setNewWallet }) {
44 const { popTo, names, reset } = useHistory();
45 const { web3, contracts, networkType } = useNetwork();
46 const { wallet, setWalletType, resetWallet, setUrbitWallet } = useWallet();
47 const { pointCursor } = usePointCursor();
48 const { getDetails } = usePointCache();
50 const [generalError, setGeneralError] = useState();
51 const [progress, setProgress] = useState(0);
52 const [needFunds, setNeedFunds] = useState();
53 const isDone = progress >= 1.0;
55 // start reticketing transactions on mount
56 useLifecycle(() => {
57 (async () => {
58 const point = need.point(pointCursor);
59 const details = need.details(getDetails(point));
60 const networkRevision = parseInt(details.keyRevisionNumber, 10);
61 try {
62 await reticketPointBetweenWallets({
63 fromWallet: need.wallet(wallet),
64 toWallet: newWallet.value.wallet,
65 point: point,
66 web3: need.web3(web3),
67 contracts: need.contracts(contracts),
68 networkType,
69 onUpdate: handleUpdate,
70 nextRevision: networkRevision + 1,
71 });
72 } catch (err) {
73 setGeneralError(err);
74 }
75 })();
76 });
78 const goToRestart = useCallback(() => {
79 reset();
80 setNewWallet(Nothing());
81 }, [reset, setNewWallet]);
83 const loginAndGoHome = useCallback(() => {
84 // set wallet state
85 resetWallet();
86 setWalletType(WALLET_TYPES.TICKET);
87 setUrbitWallet(Just(newWallet.value.wallet));
88 // (implicit) pointCursor stays the same
89 // rediect to point
90 popTo(names.POINT);
91 }, [resetWallet, setWalletType, setUrbitWallet, newWallet, popTo, names]);
93 const handleUpdate = useCallback(
94 ({ type, state, value }) => {
95 switch (type) {
96 case 'progress':
97 return setProgress(state);
98 case 'askFunding':
99 return setNeedFunds(value);
100 case 'gotFunding':
101 return setNeedFunds(false);
102 default:
103 console.error(`Unknown update: ${type}`);
104 }
105 },
106 [setProgress, setNeedFunds]
107 );
109 const renderAdditionalInfo = () => {
110 if (generalError) {
111 return (
112 <>
113 <Grid.Item full>
114 <ErrorText>{generalError.message.toString()}</ErrorText>
115 </Grid.Item>
116 <Grid.Item
117 full
118 className="mt3"
119 as={RestartButton}
120 solid
121 onClick={goToRestart}>
122 Restart
123 </Grid.Item>
124 </>
125 );
126 }
128 if (needFunds) {
129 return (
130 <Grid.Item full>
131 <Highlighted warning>
132 The address {needFunds.address} needs at least{' '}
133 {fromWei(needFunds.minBalance)} ETH and currently has{' '}
134 {fromWei(needFunds.balance)} ETH. Waiting until the account has
135 enough funds.
136 </Highlighted>
137 </Grid.Item>
138 );
139 }
141 return (
142 <Grid.Item full as={WarningBox}>
143 Never give your Master Ticket to anyone
144 </Grid.Item>
145 );
146 };
148 return (
149 <Grid gap={4} className="mt4">
150 <Grid.Item full as={H4}>
151 {labelForProgress(progress)}
152 </Grid.Item>
154 {isDone ? (
155 <>
156 <Grid.Item full as={Text}>
157 Your changes are now reflected on-chain and you can use the new
158 ticket to manage your point.
159 </Grid.Item>
160 <Grid.Item
161 full
162 as={ForwardButton}
163 solid
164 accessory="↺"
165 onClick={loginAndGoHome}>
166 Login with New Master Ticket
167 </Grid.Item>
168 </>
169 ) : (
170 <>
171 <Grid.Item full as={Grid} className="mt3" gap={3}>
172 <Grid.Item full as={LoadingBar} progress={progress} />
173 <Grid.Item full>
174 <Text className="f5 green4">
175 This process can take up to 5 minutes to complete. Don't close
176 this page until the process is complete.
177 </Text>
178 </Grid.Item>
179 </Grid.Item>
181 {renderAdditionalInfo()}
182 </>
183 )}
184 </Grid>
185 );