on e006bf2 help sign in
bridge/src/views/Activate/ActivateCode.js
156 lines 4.8 kB history raw
1import React, { useCallback, useMemo } from 'react';
2import { Just } from 'folktale/maybe';
3import * as azimuth from 'azimuth-js';
4import { Grid, H4 } from 'indigo-react';
6import View from 'components/View';
7import { ForwardButton } from 'components/Buttons';
8import Passport from 'components/Passport';
10import { useHistory } from 'store/history';
12import * as need from 'lib/need';
13import { ROUTE_NAMES } from 'lib/routeNames';
14import FooterButton from 'components/FooterButton';
15import { DEFAULT_HD_PATH, walletFromMnemonic } from 'lib/wallet';
16import { useNetwork } from 'store/network';
17import { generateWallet } from 'lib/invite';
18import { generateTemporaryOwnershipWallet } from 'lib/walletgen';
19import { useActivateFlow } from './ActivateFlow';
20import { useLocalRouter } from 'lib/LocalRouter';
21import useImpliedTicket from 'lib/useImpliedTicket';
22import timeout from 'lib/timeout';
23import useHasDisclaimed from 'lib/useHasDisclaimed';
25import BridgeForm from 'form/BridgeForm';
26import SubmitButton from 'form/SubmitButton';
27import { TicketInput } from 'form/Inputs';
28import { composeValidator, buildPatqValidator } from 'form/validators';
29import FormError from 'form/FormError';
30import { FORM_ERROR } from 'final-form';
32export default function ActivateCode() {
33 const history = useHistory();
34 const { names, push } = useLocalRouter();
35 const { contracts } = useNetwork();
36 const impliedTicket = useImpliedTicket();
37 const [hasDisclaimed] = useHasDisclaimed();
39 const {
40 setDerivedWallet,
41 setInviteWallet,
42 derivedPoint,
43 setDerivedPoint,
44 } = useActivateFlow();
46 const goToLogin = useCallback(() => history.popAndPush(ROUTE_NAMES.LOGIN), [
47 history,
48 ]);
50 const goToPassport = useCallback(() => {
51 push(names.PASSPORT);
53 if (!hasDisclaimed) {
54 push(names.DISCLAIMER);
55 }
56 }, [names, push, hasDisclaimed]);
58 const validate = useMemo(
59 () => composeValidator({ ticket: buildPatqValidator() }),
60 []
61 );
63 // set our state on submission
64 const onSubmit = useCallback(
65 async values => {
66 await timeout(100); // allow the ui changes to flush before we lag it out
68 const _contracts = need.contracts(contracts);
69 const { seed } = await generateTemporaryOwnershipWallet(values.ticket);
71 const inviteWallet = walletFromMnemonic(seed, DEFAULT_HD_PATH);
73 const _inviteWallet = need.wallet(inviteWallet);
75 const owned = await azimuth.azimuth.getOwnedPoints(
76 _contracts,
77 _inviteWallet.address
78 );
79 const transferring = await azimuth.azimuth.getTransferringFor(
80 _contracts,
81 _inviteWallet.address
82 );
83 const incoming = [...owned, ...transferring];
85 if (incoming.length > 0) {
86 if (incoming.length > 1) {
87 // TODO: putting a warning here doesn't make sense since the user
88 // will be immediately redirected away — what do?
89 // 'This invite code has multiple points available.\n' +
90 // "Once you've activated this point, activate the next with the same process.";
91 }
93 const point = parseInt(incoming[0], 10);
95 setDerivedPoint(Just(point));
96 setInviteWallet(inviteWallet);
97 setDerivedWallet(Just(await generateWallet(point)));
98 } else {
99 return {
100 [FORM_ERROR]:
101 'Invite code has no claimable point.\n' +
102 'Check your invite code and try again?',
103 };
104 }
105 },
106 [contracts, setDerivedPoint, setDerivedWallet, setInviteWallet]
107 );
109 const initialValues = useMemo(() => ({ ticket: impliedTicket || '' }), [
110 impliedTicket,
111 ]);
113 return (
114 <View inset>
115 <Grid>
116 <Grid.Item full as={Passport} point={derivedPoint} />
117 <Grid.Item full as={H4} className="mt3 mb2">
118 Activate
119 </Grid.Item>
120 <BridgeForm
121 validate={validate}
122 onSubmit={onSubmit}
123 afterSubmit={goToPassport}
124 initialValues={initialValues}>
125 {({ validating, submitting, handleSubmit }) => (
126 <>
127 <Grid.Item
128 full
129 as={TicketInput}
130 name="ticket"
131 label="Activation Code"
132 />
134 <Grid.Item full as={FormError} />
136 <Grid.Item
137 full
138 as={SubmitButton}
139 className="mt4"
140 handleSubmit={handleSubmit}>
141 {validating
142 ? 'Deriving...'
143 : submitting
144 ? 'Generating...'
145 : 'Go'}
146 </Grid.Item>
147 </>
148 )}
149 </BridgeForm>
150 </Grid>
151 <FooterButton as={ForwardButton} onClick={goToLogin}>
152 Login
153 </FooterButton>
154 </View>
155 );