on master help sign in
Merge pull request #1050 from urbit/t/skip-signing
a6af760tomholford
src/lib/useWalletConnect.ts+17−8
@@ -30,7 +30,13 @@ type ConnectEvent = {
30};
30};
31
31
32export const useWalletConnect = () => {
32export const useWalletConnect = () => {
33− const { setWallet, setAuthToken, resetWallet }: any = useWallet();
33+ const {
34+ setWallet,
35+ setAuthToken,
36+ setFakeToken,
37+ skipLoginSigning,
38+ resetWallet,
39+ }: any = useWallet();
34 const [connector, setConnector] = useState<WalletConnect | null>(null);
40 const [connector, setConnector] = useState<WalletConnect | null>(null);
35 const [address, setAddress] = useState<string | null>(null);
41 const [address, setAddress] = useState<string | null>(null);
36 const [peerMeta, setPeerMeta] = useState<PeerMeta | null>(null);
42 const [peerMeta, setPeerMeta] = useState<PeerMeta | null>(null);
@@ -81,6 +87,15 @@ export const useWalletConnect = () => {
81 return;
87 return;
82 }
88 }
83
89
90+ const wallet: WalletConnectWallet = {
91+ address,
92+ };
93+ setWallet(Just(wallet));
94+ if (skipLoginSigning) {
95+ setFakeToken();
96+ return;
97+ }
98+
84 let authToken = Nothing();
99 let authToken = Nothing();
85 try {
100 try {
86 const token = await getAuthToken({
101 const token = await getAuthToken({
@@ -89,6 +104,7 @@ export const useWalletConnect = () => {
89 walletType: WALLET_TYPES.WALLET_CONNECT,
104 walletType: WALLET_TYPES.WALLET_CONNECT,
90 });
105 });
91 authToken = Just(token);
106 authToken = Just(token);
107+ setAuthToken(authToken);
92 } catch (e) {
108 } catch (e) {
93 if (e.message === 'METHOD_NOT_SUPPORTED') {
109 if (e.message === 'METHOD_NOT_SUPPORTED') {
94 console.warn(
110 console.warn(
@@ -99,13 +115,6 @@ export const useWalletConnect = () => {
99 //TODO should errors with this *really* prevent login?
115 //TODO should errors with this *really* prevent login?
100 }
116 }
101 }
117 }
102−
103− const wallet: WalletConnectWallet = {
104− address,
105− };
106−
107− setAuthToken(authToken);
108− setWallet(Just(wallet));
109 };
118 };
110
119
111 const isConnected = () => {
120 const isConnected = () => {
src/store/wallet.js+24−1
@@ -8,6 +8,7 @@ import React, {
8} from 'react';
8} from 'react';
9import { Just, Nothing } from 'folktale/maybe';
9import { Just, Nothing } from 'folktale/maybe';
10import { includes } from 'lodash';
10import { includes } from 'lodash';
11+import { randomHex } from 'web3-utils';
11
12
12import { walletFromMnemonic } from 'lib/wallet';
13import { walletFromMnemonic } from 'lib/wallet';
13import {
14import {
@@ -52,6 +53,12 @@ function _useWallet(initialWallet = Nothing(), initialMnemonic = Nothing()) {
52 const [networkRevision, setNetworkRevision] = useState(Nothing());
53 const [networkRevision, setNetworkRevision] = useState(Nothing());
53
54
54 const [authToken, setAuthToken] = useState(Nothing());
55 const [authToken, setAuthToken] = useState(Nothing());
56+ // Allow users to skip signing the auth token on login
57+ const [skipLoginSigning, setSkipLoginSigning] = useState(false);
58+
59+ const setFakeToken = () => {
60+ setAuthToken(Just(randomHex(32)));
61+ };
55
62
56 // See: https://github.com/urbit/bridge/issues/549#issuecomment-1048359617
63 // See: https://github.com/urbit/bridge/issues/549#issuecomment-1048359617
57 // This is used for legacy compatibility; this flow should eventually be
64 // This is used for legacy compatibility; this flow should eventually be
@@ -72,6 +79,11 @@ function _useWallet(initialWallet = Nothing(), initialMnemonic = Nothing()) {
72
79
73 const _wallet = wallet.value;
80 const _wallet = wallet.value;
74 const _web3 = web3.value;
81 const _web3 = web3.value;
82+ if (skipLoginSigning) {
83+ setFakeToken();
84+ return;
85+ }
86+
75 const token = await getAuthToken({
87 const token = await getAuthToken({
76 wallet: _wallet,
88 wallet: _wallet,
77 walletType,
89 walletType,
@@ -82,7 +94,15 @@ function _useWallet(initialWallet = Nothing(), initialMnemonic = Nothing()) {
82
94
83 setAuthToken(Just(token));
95 setAuthToken(Just(token));
84 })();
96 })();
97+ }, [
98+ wallet,
99+ walletType,
100+ walletHdPath,
101+ web3,
85− }, [wallet, walletType, walletHdPath, web3, useLegacyTokenSigning]);
102+ useLegacyTokenSigning,
103+ setAuthToken,
104+ skipLoginSigning,
105+ ]);
86
106
87 const setWalletType = useCallback(
107 const setWalletType = useCallback(
88 walletType => {
108 walletType => {
@@ -176,6 +196,9 @@ function _useWallet(initialWallet = Nothing(), initialMnemonic = Nothing()) {
176 setAuthToken,
196 setAuthToken,
177 useLegacyTokenSigning,
197 useLegacyTokenSigning,
178 setUseLegacyTokenSigning,
198 setUseLegacyTokenSigning,
199+ skipLoginSigning,
200+ setSkipLoginSigning,
201+ setFakeToken,
179 };
202 };
180}
203}
181
204
src/views/Login/Ledger.tsx+15−5
@@ -52,7 +52,13 @@ interface LedgerProps {
52export default function Ledger({ className, goHome }: LedgerProps) {
52export default function Ledger({ className, goHome }: LedgerProps) {
53 useLoginView(WALLET_TYPES.LEDGER);
53 useLoginView(WALLET_TYPES.LEDGER);
54
54
55+ const {
56+ setWallet,
55− const { setWallet, setWalletHdPath, setAuthToken }: any = useWallet();
57+ setWalletHdPath,
58+ setAuthToken,
59+ setFakeToken,
60+ skipLoginSigning,
61+ }: any = useWallet();
56
62
57 const validate = useMemo(
63 const validate = useMemo(
58 () =>
64 () =>
@@ -77,20 +83,24 @@ export default function Ledger({ className, goHome }: LedgerProps) {
77 const chainCode = Buffer.from(info.chainCode!.toString(), 'hex');
83 const chainCode = Buffer.from(info.chainCode!.toString(), 'hex');
78 const pub = Buffer.from(publicKeyConvert(publicKey, true));
84 const pub = Buffer.from(publicKeyConvert(publicKey, true));
79 const hd = bip32.fromPublicKey(pub, chainCode);
85 const hd = bip32.fromPublicKey(pub, chainCode);
86+ setWallet(Just(hd));
87+ setWalletHdPath(addHdPrefix(values.hdpath));
88+ if (skipLoginSigning) {
89+ setFakeToken();
90+ return;
91+ }
92+
80 const authToken = await getAuthToken({
93 const authToken = await getAuthToken({
81 walletType: WALLET_TYPES.LEDGER,
94 walletType: WALLET_TYPES.LEDGER,
82 walletHdPath: addHdPrefix(values.hdpath),
95 walletHdPath: addHdPrefix(values.hdpath),
83 });
96 });
84−
85 setAuthToken(Just(authToken));
97 setAuthToken(Just(authToken));
86− setWallet(Just(hd));
87− setWalletHdPath(addHdPrefix(values.hdpath));
88 } catch (error) {
98 } catch (error) {
89 console.error(error);
99 console.error(error);
90 return { [FORM_ERROR]: error.message };
100 return { [FORM_ERROR]: error.message };
91 }
101 }
92 },
102 },
93− [setAuthToken, setWallet, setWalletHdPath]
103+ [setAuthToken, setFakeToken, setWallet, setWalletHdPath, skipLoginSigning]
94 );
104 );
95
105
96 const onValues = useCallback(({ valid, values, form }) => {
106 const onValues = useCallback(({ valid, values, form }) => {
src/views/Login/LoginSelector.scss+24
@@ -93,4 +93,28 @@
93 background-color: $washed-gray;
93 background-color: $washed-gray;
94 }
94 }
95 }
95 }
96+
97+ .advanced-options {
98+ margin-top: 16px;
99+ cursor: pointer;
100+ text-align: center;
101+ }
102+
103+ .skip-signing {
104+ margin-top: 16px;
105+ display: flex;
106+ flex-flow: row nowrap;
107+ cursor: pointer;
108+ width: 100%;
109+ justify-content: center;
110+ align-items: center;
111+ font-family: $default-font;
112+
113+ span {
114+ margin-left: 10px;
115+ width: 160px;
116+ font-size: 14px;
117+ line-height: 18px;
118+ }
119+ }
96}
120}
src/views/Login/LoginSelector.tsx+57−5
@@ -1,6 +1,6 @@
1import React, { useCallback, useState } from 'react';
1import React, { useCallback, useState } from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3−import { Grid } from 'indigo-react';
3+import { Flex, Grid } from 'indigo-react';
4import {
4import {
5 Box,
5 Box,
6 Button,
6 Button,
@@ -9,6 +9,7 @@ import {
9 Row,
9 Row,
10 Text,
10 Text,
11 Image,
11 Image,
12+ Checkbox,
12} from '@tlon/indigo-react';
13} from '@tlon/indigo-react';
13import Web3 from 'web3';
14import Web3 from 'web3';
14import { Just } from 'folktale/maybe';
15import { Just } from 'folktale/maybe';
@@ -57,12 +58,21 @@ export default function LoginSelector({
57 useLoginView(WALLET_TYPES.WALLET_CONNECT);
58 useLoginView(WALLET_TYPES.WALLET_CONNECT);
58
59
59 const { push, names }: any = useHistory();
60 const { push, names }: any = useHistory();
61+ const {
62+ setWallet,
60− const { setWallet, setWalletType, setAuthToken }: any = useWallet();
63+ setWalletType,
64+ setAuthToken,
65+ setFakeToken,
66+ skipLoginSigning,
67+ setSkipLoginSigning,
68+ }: any = useWallet();
61 const { setMetamask }: any = useNetwork();
69 const { setMetamask }: any = useNetwork();
62 const [showModal, setShowModal] = useState(false);
70 const [showModal, setShowModal] = useState(false);
63 // TODO: do we still need this? currently not being set
71 // TODO: do we still need this? currently not being set
64 const [metamaskSelected, setMetamaskSelected] = useState(false);
72 const [metamaskSelected, setMetamaskSelected] = useState(false);
65
73
74+ const [showAdvanced, setShowAdvanced] = useState(false);
75+
66 const {
76 const {
67 address,
77 address,
68 authenticate,
78 authenticate,
@@ -96,6 +106,15 @@ export default function LoginSelector({
96
106
97 const wallet = new MetamaskWallet(accounts[0]);
107 const wallet = new MetamaskWallet(accounts[0]);
98 const web3 = new Web3(window.ethereum);
108 const web3 = new Web3(window.ethereum);
109+ setWallet(Just(wallet));
110+ setWalletType(WALLET_TYPES.METAMASK);
111+
112+ if (skipLoginSigning) {
113+ setFakeToken();
114+ goHome();
115+ return;
116+ }
117+
99 const authToken = await getAuthToken({
118 const authToken = await getAuthToken({
100 address: wallet.address,
119 address: wallet.address,
101 walletType: WALLET_TYPES.METAMASK,
120 walletType: WALLET_TYPES.METAMASK,
@@ -103,8 +122,6 @@ export default function LoginSelector({
103 });
122 });
104
123
105 setAuthToken(Just(authToken));
124 setAuthToken(Just(authToken));
106− setWallet(Just(wallet));
107− setWalletType(WALLET_TYPES.METAMASK);
108
125
109 goHome();
126 goHome();
110 } catch (e) {
127 } catch (e) {
@@ -112,7 +129,15 @@ export default function LoginSelector({
112 setMetamask(false);
129 setMetamask(false);
113 setMetamaskSelected(false);
130 setMetamaskSelected(false);
114 }
131 }
132+ }, [
133+ setMetamask,
134+ setWallet,
115− }, [setAuthToken, setWallet, setWalletType, setMetamask, goHome]);
135+ setWalletType,
136+ skipLoginSigning,
137+ setAuthToken,
138+ goHome,
139+ setFakeToken,
140+ ]);
116
141
117 const onSubmitWalletConnect = useCallback(async () => {
142 const onSubmitWalletConnect = useCallback(async () => {
118 try {
143 try {
@@ -199,6 +224,33 @@ export default function LoginSelector({
199 onClick={() => setShowModal(true)}>
224 onClick={() => setShowModal(true)}>
200 <Icon icon="Info" />I have a wallet type not supported here
225 <Icon icon="Info" />I have a wallet type not supported here
201 </Grid.Item>
226 </Grid.Item>
227+ <Grid.Item
228+ className="advanced-options"
229+ full
230+ as={Text}
231+ onClick={() => setShowAdvanced(!showAdvanced)}>
232+ Advanced{' '}
233+ <Icon
234+ display="inline-block"
235+ icon={showAdvanced ? 'ChevronNorth' : 'ChevronSouth'}
236+ size="14px"
237+ color={'black'}
238+ />
239+ </Grid.Item>
240+ {showAdvanced ? (
241+ <Grid.Item
242+ full
243+ as={Box}
244+ onClick={() => setSkipLoginSigning(!skipLoginSigning)}>
245+ <Box className="skip-signing">
246+ <Checkbox
247+ selected={skipLoginSigning}
248+ onClick={() => setSkipLoginSigning(!skipLoginSigning)}
249+ />
250+ <Text>Skip Signing on Login</Text>
251+ </Box>
252+ </Grid.Item>
253+ ) : null}
202 <Modal show={showModal} hide={() => setShowModal(false)}>
254 <Modal show={showModal} hide={() => setShowModal(false)}>
203 <Box className="info-modal-content">
255 <Box className="info-modal-content">
204 <div className="fw-bold mb5">Other Wallet Types</div>
256 <div className="fw-bold mb5">Other Wallet Types</div>
src/views/Login/Metamask.js+23−5
@@ -22,7 +22,13 @@ import Web3 from 'web3';
22
22
23export default function Metamask({ className, goHome }) {
23export default function Metamask({ className, goHome }) {
24 useLoginView(WALLET_TYPES.METAMASK);
24 useLoginView(WALLET_TYPES.METAMASK);
25+ const {
26+ setWallet,
25− const { setWallet, setWalletType, setAuthToken } = useWallet();
27+ setWalletType,
28+ setAuthToken,
29+ setFakeToken,
30+ skipLoginSigning,
31+ } = useWallet();
26
32
27 const { setMetamask } = useNetwork();
33 const { setMetamask } = useNetwork();
28
34
@@ -37,8 +43,15 @@ export default function Metamask({ className, goHome }) {
37 method: 'eth_requestAccounts',
43 method: 'eth_requestAccounts',
38 });
44 });
39 const wallet = new MetamaskWallet(accounts.result[0]);
45 const wallet = new MetamaskWallet(accounts.result[0]);
40−
41 const web3 = new Web3(window.ethereum);
46 const web3 = new Web3(window.ethereum);
47+ setWallet(Just(wallet));
48+ setWalletType(WALLET_TYPES.METAMASK);
49+
50+ if (skipLoginSigning) {
51+ setFakeToken();
52+ return;
53+ }
54+
42 const authToken = await getAuthToken({
55 const authToken = await getAuthToken({
43 address: wallet.address,
56 address: wallet.address,
44 walletType: WALLET_TYPES.METAMASK,
57 walletType: WALLET_TYPES.METAMASK,
@@ -46,13 +59,18 @@ export default function Metamask({ className, goHome }) {
46 });
59 });
47
60
48 setAuthToken(Just(authToken));
61 setAuthToken(Just(authToken));
49− setWallet(Just(wallet));
50− setWalletType(WALLET_TYPES.METAMASK);
51 } catch (e) {
62 } catch (e) {
52 console.error(e);
63 console.error(e);
53 return { [FORM_ERROR]: e.message };
64 return { [FORM_ERROR]: e.message };
54 }
65 }
66+ }, [
67+ setMetamask,
68+ setWallet,
55− }, [setAuthToken, setWallet, setWalletType, setMetamask]);
69+ setWalletType,
70+ skipLoginSigning,
71+ setAuthToken,
72+ setFakeToken,
73+ ]);
56
74
57 return (
75 return (
58 <Grid className={className}>
76 <Grid className={className}>
src/views/Login/Trezor.tsx+15−4
@@ -41,7 +41,13 @@ interface TrezorProps {
41export default function Trezor({ className, goHome }: TrezorProps) {
41export default function Trezor({ className, goHome }: TrezorProps) {
42 useLoginView(WALLET_TYPES.TREZOR);
42 useLoginView(WALLET_TYPES.TREZOR);
43
43
44+ const {
45+ setWallet,
44− const { setWallet, setWalletHdPath, setAuthToken }: any = useWallet();
46+ setWalletHdPath,
47+ setAuthToken,
48+ setFakeToken,
49+ skipLoginSigning,
50+ }: any = useWallet();
45
51
46 const validate = useMemo(
52 const validate = useMemo(
47 () =>
53 () =>
@@ -81,6 +87,13 @@ export default function Trezor({ className, goHome }: TrezorProps) {
81
87
82 const pub = Buffer.from(publicKeyConvert(publicKey, true));
88 const pub = Buffer.from(publicKeyConvert(publicKey, true));
83 const hd = bip32.fromPublicKey(pub, chainCode);
89 const hd = bip32.fromPublicKey(pub, chainCode);
90+ setWallet(Just(hd));
91+ setWalletHdPath(values.hdPath);
92+
93+ if (skipLoginSigning) {
94+ setFakeToken();
95+ return;
96+ }
84
97
85 const authToken = await getAuthToken({
98 const authToken = await getAuthToken({
86 walletType: WALLET_TYPES.TREZOR,
99 walletType: WALLET_TYPES.TREZOR,
@@ -88,10 +101,8 @@ export default function Trezor({ className, goHome }: TrezorProps) {
88 });
101 });
89
102
90 setAuthToken(Just(authToken));
103 setAuthToken(Just(authToken));
91− setWallet(Just(hd));
92− setWalletHdPath(values.hdPath);
93 },
104 },
94− [setAuthToken, setWallet, setWalletHdPath]
105+ [setAuthToken, setFakeToken, setWallet, setWalletHdPath, skipLoginSigning]
95 );
106 );
96
107
97 const onValues = useCallback(({ valid, values, form }) => {
108 const onValues = useCallback(({ valid, values, form }) => {