on c262e73 help sign in
bridge/src/views/Activate/ActivateCode.js
154 lines 4.6 kB history raw
1import React, { useCallback, useEffect, useState } from 'react';
2import { Just, Nothing } from 'folktale/maybe';
3import * as azimuth from 'azimuth-js';
4import { Grid, Input, H4, ErrorText } from 'indigo-react';
6import View from 'components/View';
7import { ForwardButton } from 'components/Buttons';
8import Passport from 'components/Passport';
10import { useHistory } from 'store/history';
12import { useTicketInput } from 'lib/useInputs';
13import * as need from 'lib/need';
14import { ROUTE_NAMES } from 'lib/routeNames';
15import { useSyncKnownPoints } from 'lib/useSyncPoints';
16import FooterButton from 'components/FooterButton';
17import Blinky from 'components/Blinky';
18import { DEFAULT_HD_PATH, walletFromMnemonic } from 'lib/wallet';
19import { useNetwork } from 'store/network';
20import { generateWallet } from 'lib/invite';
21import { generateTemporaryOwnershipWallet } from 'lib/walletgen';
22import { useActivateFlow } from './ActivateFlow';
23import { useLocalRouter } from 'lib/LocalRouter';
25export default function ActivateCode() {
26 const history = useHistory();
27 const { names, push } = useLocalRouter();
28 const { contracts } = useNetwork();
29 const [generalError, setGeneralError] = useState();
30 const [deriving, setDeriving] = useState(false);
31 const {
32 derivedWallet,
33 setDerivedWallet,
34 setInviteWallet,
35 derivedPoint,
36 setDerivedPoint,
37 } = useActivateFlow();
39 const [ticketInput, { pass: validTicket }] = useTicketInput({
40 name: 'ticket',
41 label: 'Code',
42 autoFocus: true,
43 });
45 const goToLogin = useCallback(() => history.popAndPush(ROUTE_NAMES.LOGIN), [
46 history,
47 ]);
48 const goToDisclaimer = useCallback(() => push(names.DISCLAIMER), [
49 names,
50 push,
51 ]);
53 const pass = derivedWallet.matchWith({
54 Nothing: () => false,
55 Just: () => true,
56 });
58 useEffect(() => {
59 if (validTicket) {
60 const _contracts = need.contracts(contracts);
62 setDeriving(true);
63 // when the ticket becomes valid, derive the point
64 (async () => {
65 const { seed } = await generateTemporaryOwnershipWallet(
66 ticketInput.data
67 );
69 //TODO isn't all this accessible in the ownership object?
70 const inviteWallet = walletFromMnemonic(seed, DEFAULT_HD_PATH);
71 const _inviteWallet = need.wallet(inviteWallet);
73 const owned = await azimuth.azimuth.getOwnedPoints(
74 _contracts,
75 _inviteWallet.address
76 );
77 const transferring = await azimuth.azimuth.getTransferringFor(
78 _contracts,
79 _inviteWallet.address
80 );
81 const incoming = [...owned, ...transferring];
83 let realPoint = Nothing();
84 let wallet = Nothing();
86 if (incoming.length > 0) {
87 const pointNum = parseInt(incoming[0], 10);
88 realPoint = Just(pointNum);
89 wallet = Just(await generateWallet(pointNum));
91 if (incoming.length > 1) {
92 setGeneralError(
93 'This invite code has multiple points available.\n' +
94 "Once you've activated this point, activate the next with the same process."
95 );
96 }
97 } else {
98 setGeneralError(
99 'Invite code has no claimable point.\n' +
100 'Check your invite code and try again?'
101 );
102 }
104 setDerivedPoint(realPoint);
105 setDerivedWallet(wallet);
106 setInviteWallet(inviteWallet);
107 setDeriving(false);
108 })();
109 } else {
110 setGeneralError(false);
111 }
112 }, [
113 validTicket,
114 contracts,
115 ticketInput.data,
116 setDerivedPoint,
117 setDerivedWallet,
118 setInviteWallet,
119 ]);
121 // when we know the derived point, ensure we have the data to display it
122 useSyncKnownPoints([derivedPoint.getOrElse(null)].filter(p => p !== null));
124 return (
125 <View>
126 <Grid>
127 <Grid.Item as={Passport} point={derivedPoint} full />
128 <Grid.Item as={H4} className="mt3 mb2" full>
129 Activate
130 </Grid.Item>
131 <Grid.Item as={Input} {...ticketInput} full />
132 {generalError && (
133 <Grid.Item full>
134 <ErrorText>{generalError}</ErrorText>{' '}
135 </Grid.Item>
136 )}
137 <Grid.Item
138 as={ForwardButton}
139 className="mt4"
140 disabled={!pass || deriving}
141 accessory={deriving ? <Blinky /> : undefined}
142 onClick={goToDisclaimer}
143 solid
144 full>
145 {deriving && 'Deriving...'}
146 {!deriving && 'Go'}
147 </Grid.Item>
148 </Grid>
149 <FooterButton as={ForwardButton} onClick={goToLogin}>
150 Login
151 </FooterButton>
152 </View>
153 );