on master help sign in
feat: extract urbitWallet and authMnemonic into state container
feca660Matt Condon (shrugs)
src/bridge/Bridge.js+24−54
@@ -9,10 +9,10 @@ import nest from './lib/nest';
9import { router } from './lib/router';
9import { router } from './lib/router';
10import { ROUTE_NAMES } from './lib/routeNames';
10import { ROUTE_NAMES } from './lib/routeNames';
11import { NETWORK_TYPES } from './lib/network';
11import { NETWORK_TYPES } from './lib/network';
12−import { DEFAULT_HD_PATH, walletFromMnemonic } from './lib/wallet';
12+import { walletFromMnemonic } from './lib/wallet';
13import { isDevelopment } from './lib/flags';
13import { isDevelopment } from './lib/flags';
14
14
15−import { HistoryProvider, withHistory, useHistory } from './store/history';
15+import { HistoryProvider, useHistory } from './store/history';
16import { TxnConfirmationsProvider } from './store/txnConfirmations';
16import { TxnConfirmationsProvider } from './store/txnConfirmations';
17import { OnlineProvider } from './store/online';
17import { OnlineProvider } from './store/online';
18import { NetworkProvider } from './store/network';
18import { NetworkProvider } from './store/network';
@@ -42,6 +42,9 @@ const kInitialWallet = kIsStubbed
42 process.env.REACT_APP_HD_PATH
42 process.env.REACT_APP_HD_PATH
43 )
43 )
44 : undefined;
44 : undefined;
45+const kInitialMnemonic = kIsStubbed
46+ ? process.env.REACT_APP_DEV_MNEMONIC
47+ : Nothing();
45
48
46// the router itself is just a component that renders a specific view
49// the router itself is just a component that renders a specific view
47// depending on the history
50// depending on the history
@@ -52,23 +55,26 @@ const Router = function(props) {
52 return <Route {...props} />;
55 return <Route {...props} />;
53};
56};
54
57
55−// NB(shrugs): separate component because it needs withHistory
58+// NB(shrugs): separate component because it needs useHistory
56// this will be must better structured as part of the UI overhaul
59// this will be must better structured as part of the UI overhaul
57−const VariableWidthColumn = withHistory(({ history, children }) => (
60+const VariableWidthColumn = function({ children }) {
61+ const history = useHistory();
58 // For the invite acceptance flow, widen the screen to use the full
62 // For the invite acceptance flow, widen the screen to use the full
59 // container, and hide the breadcrumbs
63 // container, and hide the breadcrumbs
64+ return (
60− <Col
65+ <Col
61− className={
66+ className={
62− history.includes(ROUTE_NAMES.INVITE_TICKET)
67+ history.includes(ROUTE_NAMES.INVITE_TICKET)
63− ? 'col-md-12'
68+ ? 'col-md-12'
64− : 'col-md-offset-1 col-md-10'
69+ : 'col-md-offset-1 col-md-10'
65− }
70+ }
66− style={
71+ style={
67− history.includes(ROUTE_NAMES.INVITE_TICKET) ? {} : { maxWidth: '620px' }
72+ history.includes(ROUTE_NAMES.INVITE_TICKET) ? {} : { maxWidth: '620px' }
68− }>
73+ }>
69− {children}
74+ {children}
70− </Col>
75+ </Col>
71−));
76+ );
77+};
72
78
73// nest all of the providers within each other to avoid hella depth
79// nest all of the providers within each other to avoid hella depth
74const AllProviders = nest([
80const AllProviders = nest([
@@ -84,9 +90,6 @@ class Bridge extends React.Component {
84 super(props);
90 super(props);
85
91
86 this.state = {
92 this.state = {
87− // urbit wallet-related
88− urbitWallet: Nothing(),
89− authMnemonic: Nothing(),
90 networkSeedCache: null,
93 networkSeedCache: null,
91 // point
94 // point
92 pointCursor: Nothing(),
95 pointCursor: Nothing(),
@@ -96,8 +99,6 @@ class Bridge extends React.Component {
96 txnConfirmations: {},
99 txnConfirmations: {},
97 };
100 };
98
101
99− this.setUrbitWallet = this.setUrbitWallet.bind(this);
100− this.setAuthMnemonic = this.setAuthMnemonic.bind(this);
101 this.setPointCursor = this.setPointCursor.bind(this);
102 this.setPointCursor = this.setPointCursor.bind(this);
102 this.setTxnHashCursor = this.setTxnHashCursor.bind(this);
103 this.setTxnHashCursor = this.setTxnHashCursor.bind(this);
103 this.setNetworkSeedCache = this.setNetworkSeedCache.bind(this);
104 this.setNetworkSeedCache = this.setNetworkSeedCache.bind(this);
@@ -110,12 +111,8 @@ class Bridge extends React.Component {
110 // If running in development, the following can be tweaked to get you set
111 // If running in development, the following can be tweaked to get you set
111 // up with a desirable initial state.
112 // up with a desirable initial state.
112 if (kIsStubbed) {
113 if (kIsStubbed) {
113− const mnemonic = process.env.REACT_APP_DEV_MNEMONIC;
114−
115 this.setState({
114 this.setState({
116 pointCursor: Just(0),
115 pointCursor: Just(0),
117− urbitWallet: Nothing(),
118− authMnemonic: Just(mnemonic),
119 });
116 });
120 }
117 }
121 }
118 }
@@ -127,28 +124,6 @@ class Bridge extends React.Component {
127 });
124 });
128 }
125 }
129
126
130− // also sets wallet to ownership address
131− setUrbitWallet(urbitWallet) {
132− let wallet = this.state.wallet;
133− if (Just.hasInstance(urbitWallet)) {
134− const mnemonic = urbitWallet.value.ownership.seed;
135− wallet = walletFromMnemonic(
136− mnemonic,
137− DEFAULT_HD_PATH,
138− urbitWallet.value.meta.passphrase
139− );
140− wallet.map(wal => {
141− wal.address = urbitWallet.value.ownership.keys.address;
142− return wal;
143− });
144− }
145− this.setState({ urbitWallet, wallet });
146− }
147−
148− setAuthMnemonic(authMnemonic) {
149− this.setState({ authMnemonic });
150− }
151−
152 setPointCursor(pointCursor) {
127 setPointCursor(pointCursor) {
153 this.setState({ pointCursor });
128 this.setState({ pointCursor });
154 }
129 }
@@ -165,8 +140,6 @@ class Bridge extends React.Component {
165
140
166 render() {
141 render() {
167 const {
142 const {
168− urbitWallet,
169− authMnemonic,
170 networkSeedCache,
143 networkSeedCache,
171 networkRevisionCache,
144 networkRevisionCache,
172 pointCursor,
145 pointCursor,
@@ -178,7 +151,8 @@ class Bridge extends React.Component {
178 <AllProviders
151 <AllProviders
179 initialRoutes={kInitialRoutes}
152 initialRoutes={kInitialRoutes}
180 initialNetworkType={kInitialNetworkType}
153 initialNetworkType={kInitialNetworkType}
181− initialWallet={kInitialWallet}>
154+ initialWallet={kInitialWallet}
155+ initialMnemonic={kInitialMnemonic}>
182 <Container>
156 <Container>
183 <Row>
157 <Row>
184 <VariableWidthColumn>
158 <VariableWidthColumn>
@@ -186,10 +160,6 @@ class Bridge extends React.Component {
186
160
187 <Row className={'row wrapper'}>
161 <Row className={'row wrapper'}>
188 <Router
162 <Router
189− urbitWallet={urbitWallet}
190− setUrbitWallet={this.setUrbitWallet}
191− authMnemonic={authMnemonic}
192− setAuthMnemonic={this.setAuthMnemonic}
193 setPointCursor={this.setPointCursor}
163 setPointCursor={this.setPointCursor}
194 addToPointCache={this.addToPointCache}
164 addToPointCache={this.addToPointCache}
195 pointCursor={pointCursor}
165 pointCursor={pointCursor}
src/bridge/store/wallet.js+35−7
@@ -6,6 +6,7 @@ import {
6 WALLET_TYPES,
6 WALLET_TYPES,
7 DEFAULT_HD_PATH,
7 DEFAULT_HD_PATH,
8 addressFromSecp256k1Public,
8 addressFromSecp256k1Public,
9+ walletFromMnemonic,
9} from '../lib/wallet';
10} from '../lib/wallet';
10import { BRIDGE_ERROR } from '../lib/error';
11import { BRIDGE_ERROR } from '../lib/error';
11
12
@@ -23,10 +24,15 @@ export const WalletContext = createContext(null);
23// mechanisms, Maybe wraps a BIP32 HD wallet; for Ethereum private keys,
24// mechanisms, Maybe wraps a BIP32 HD wallet; for Ethereum private keys,
24// JSON keystore files, and Metamask authentication, it wraps an
25// JSON keystore files, and Metamask authentication, it wraps an
25// 'EthereumWallet'.
26// 'EthereumWallet'.
27+function _useWallet(
26−function _useWallet(initialWallet = Maybe.Nothing()) {
28+ initialWallet = Maybe.Nothing(),
29+ initialMnemonic = Maybe.Nothing()
30+) {
27 const [walletType, _setWalletType] = useState(WALLET_TYPES.MNEMONIC);
31 const [walletType, _setWalletType] = useState(WALLET_TYPES.MNEMONIC);
28 const [walletHdPath, setWalletHdPath] = useState(DEFAULT_HD_PATH);
32 const [walletHdPath, setWalletHdPath] = useState(DEFAULT_HD_PATH);
29 const [wallet, _setWallet] = useState(initialWallet);
33 const [wallet, _setWallet] = useState(initialWallet);
34+ const [urbitWallet, _setUrbitWallet] = useState(Maybe.Nothing());
35+ const [authMnemonic, setAuthMnemonic] = useState(initialMnemonic);
30
36
31 const setWalletType = walletType => {
37 const setWalletType = walletType => {
32 if (!includes(WALLET_TYPES, walletType)) {
38 if (!includes(WALLET_TYPES, walletType)) {
@@ -46,6 +52,28 @@ function _useWallet(initialWallet = Maybe.Nothing()) {
46 _setWallet(wallet);
52 _setWallet(wallet);
47 };
53 };
48
54
55+ const setUrbitWallet = urbitWallet => {
56+ if (Maybe.Just.hasInstance(urbitWallet)) {
57+ // when an urbit wallet is set, also derive
58+ // a normal bip32 wallet using the ownership address
59+ const wallet = walletFromMnemonic(
60+ urbitWallet.value.ownership.seed,
61+ DEFAULT_HD_PATH,
62+ urbitWallet.value.meta.passphrase
63+ );
64+
65+ // manually set the public address
66+ wallet.map(wal => {
67+ wal.address = urbitWallet.value.ownership.keys.address;
68+ return wal;
69+ });
70+
71+ setWallet(wallet);
72+ }
73+
74+ _setUrbitWallet(urbitWallet);
75+ };
76+
49 return {
77 return {
50 //
78 //
51 walletType,
79 walletType,
@@ -57,15 +85,15 @@ function _useWallet(initialWallet = Maybe.Nothing()) {
57 wallet,
85 wallet,
58 setWallet,
86 setWallet,
59 //
87 //
60− // urbitWallet
88+ urbitWallet,
61− // setUrbitWallet
89+ setUrbitWallet,
62− // authMnemonic
90+ authMnemonic,
63− // setAuthMnemonic
91+ setAuthMnemonic,
64 };
92 };
65}
93}
66
94
67−export function WalletProvider({ initialWallet, children }) {
95+export function WalletProvider({ initialWallet, initialMnemonic, children }) {
68− const wallet = _useWallet(initialWallet);
96+ const wallet = _useWallet(initialWallet, initialMnemonic);
69
97
70 return (
98 return (
71 <WalletContext.Provider value={wallet}>{children}</WalletContext.Provider>
99 <WalletContext.Provider value={wallet}>{children}</WalletContext.Provider>
src/bridge/views/InviteTicket.js+3−1
@@ -29,6 +29,7 @@ import {
29} from '../lib/invite';
29} from '../lib/invite';
30import { generateWallet, startTransactions } from '../lib/invite';
30import { generateWallet, startTransactions } from '../lib/invite';
31import { withNetwork } from '../store/network';
31import { withNetwork } from '../store/network';
32+import { withWallet } from '../store/wallet';
32
33
33class InviteTicket extends React.Component {
34class InviteTicket extends React.Component {
34 constructor(props) {
35 constructor(props) {
@@ -425,5 +426,6 @@ class InviteTicket extends React.Component {
425
426
426export default compose(
427export default compose(
427 withNetwork,
428 withNetwork,
428− withHistory
429+ withHistory,
430+ withWallet
429)(InviteTicket);
431)(InviteTicket);