on e9a3a34 help sign in
bridge/src/Bridge.js
301 lines 8.6 kB history raw
1import Maybe from 'folktale/maybe'
2import * as lodash from 'lodash'
3import { Stack } from 'immutable'
4import React from 'react'
6import Footer from './components/Footer'
7import Header from './components/Header'
8import { Container, Row, Col } from './components/Base'
9import { AppNavigation } from './components/AppNavigation'
11import { ROUTE_NAMES, router } from './lib/router'
12import { NETWORK_NAMES } from './lib/network'
13import { WALLET_NAMES, DEFAULT_HD_PATH } from './lib/wallet'
14import { BRIDGE_ERROR } from './lib/error'
16class Bridge extends React.Component {
18 constructor(props) {
19 super(props)
21 const networkType =
22 process.env.NODE_ENV === 'development'
23 ? NETWORK_NAMES.LOCAL
24 : NETWORK_NAMES.MAINNET
26 // NB (jtobin):
27 //
28 // Note that the 'wallet' prop has type depending on the 'walletType' prop.
29 // These could be bound together in a single structure (so that
30 // 'walletType' acted more explicitly as a data constructor of sorts) but
31 // it doesn't necessarily help us much, since we branch on 'walletType'
32 // before setting 'wallet'.
33 //
34 // Wallets are always wrapped in Maybe. For most authentication
35 // mechanisms, Maybe wraps a BIP32 HD wallet; for Ethereum private keys,
36 // JSON keystore files, and Metamask authentication, it wraps an
37 // 'EthereumWallet'.
39 this.state = {
40 // routes
41 routeCrumbs: Stack([ ROUTE_NAMES.LANDING ]),
42 routeData: {},
43 // network
44 networkType: networkType,
45 web3: Maybe.Nothing(),
46 contracts: Maybe.Nothing(),
47 // wallet
48 walletType: WALLET_NAMES.MNEMONIC,
49 wallet: Maybe.Nothing(),
50 walletHdPath: DEFAULT_HD_PATH,
51 // urbit wallet-related
52 urbitWallet: Maybe.Nothing(),
53 authMnemonic: Maybe.Nothing(),
54 networkSeedCache: null,
55 // point
56 pointCursor: Maybe.Nothing(),
57 pointCache: {},
58 // txn
59 txnHashCursor: Maybe.Nothing()
60 }
62 this.pushRoute = this.pushRoute.bind(this)
63 this.popRoute = this.popRoute.bind(this)
64 this.skipRoute = this.skipRoute.bind(this)
65 this.setNetworkType = this.setNetworkType.bind(this)
66 this.setNetwork = this.setNetwork.bind(this)
67 this.setWalletType = this.setWalletType.bind(this)
68 this.setWallet = this.setWallet.bind(this)
69 this.setWalletHdPath = this.setWalletHdPath.bind(this)
70 this.setUrbitWallet = this.setUrbitWallet.bind(this)
71 this.setAuthMnemonic = this.setAuthMnemonic.bind(this)
72 this.setPointCursor = this.setPointCursor.bind(this)
73 this.setTxnHashCursor = this.setTxnHashCursor.bind(this)
74 this.setNetworkSeedCache = this.setNetworkSeedCache.bind(this)
75 this.addToPointCache = this.addToPointCache.bind(this)
76 }
78 componentDidMount() {
79 window.history.pushState(null, null, null);
81 window.onpopstate = (e) => {
82 window.history.pushState(null, null, null);
83 this.popRoute();
84 }
86 import('./style/index.css')
88 // NB (jtobin):
89 //
90 // If running in development, the following can be tweaked to get you set
91 // up with a desirable initial state.
93 // if (process.env.NODE_ENV === 'development') {
94 //
95 // const socket = 'ws://localhost:8545'
96 // const provider = new Web3.providers.WebsocketProvider(socket)
97 // const web3 = new Web3(provider)
98 // const contracts = azimuth.initContracts(web3, CONTRACT_ADDRESSES.DEV)
99 //
100 // const mnemonic = process.env.REACT_APP_DEV_MNEMONIC
101 // const hdpath = process.env.REACT_APP_HD_PATH
102 //
103 // this.setState({
104 // routeCrumbs: Stack([
105 // // ROUTE_NAMES.CREATE_GALAXY,
106 // // ROUTE_NAMES.SHIP,
107 // ROUTE_NAMES.SHIPS,
108 // // ROUTE_NAMES.MNEMONIC,
109 // ROUTE_NAMES.WALLET,
110 // ROUTE_NAMES.NETWORK,
111 // ROUTE_NAMES.LANDING
112 // ]),
113 // networkType: NETWORK_NAMES.LOCAL,
114 // pointCursor: Maybe.Just(0),
115 // web3: Maybe.Just(web3),
116 // contracts: Maybe.Just(contracts),
117 // walletType: WALLET_NAMES.MNEMONIC,
118 // wallet: walletFromMnemonic(mnemonic, hdpath),
119 // urbitWallet: Maybe.Nothing(),
120 // authMnemonic: Maybe.Just('benefit crew supreme gesture quantum web media hazard theory mercy wing kitten')
121 // })
122 // }
125 pushRoute(symbol, routeData) {
126 if (lodash.includes(ROUTE_NAMES, symbol)) {
127 this.setState((state, _) => ({
128 routeCrumbs: state.routeCrumbs.push(symbol),
129 routeData: routeData
130 }));
132 // Scroll to top of page with each route transition.
133 window.scrollTo(0, 0);
135 } else {
136 throw BRIDGE_ERROR.INVALID_ROUTE
137 }
138 }
140 skipRoute(len) {
141 this.setState((state, _) => ({
142 routeCrumbs: state.routeCrumbs.skip(len)
143 }))
144 }
146 popRoute() {
147 this.setState((state, _) => ({
148 routeCrumbs: state.routeCrumbs.shift()
149 }))
150 }
152 setNetworkType(symbol) {
153 if (lodash.includes(NETWORK_NAMES, symbol)) {
154 this.setState({
155 networkType: symbol
156 })
157 } else {
158 throw BRIDGE_ERROR.INVALID_NETWORK_TYPE
159 }
160 }
162 setNetworkSeedCache(networkSeed) {
163 this.setState({
164 networkSeedCache: networkSeed
165 })
166 }
168 setNetwork(web3, contracts) {
169 this.setState({
170 web3: web3,
171 contracts: contracts
172 })
173 }
175 setWalletType(symbol) {
176 if (lodash.includes(WALLET_NAMES, symbol)) {
177 this.setState({
178 walletType: symbol
179 })
180 } else {
181 throw BRIDGE_ERROR.INVALID_WALLET_TYPE
182 }
183 }
185 setWallet(wallet) {
186 this.setState({ wallet })
187 }
189 setWalletHdPath(walletHdPath) {
190 this.setState({ walletHdPath })
191 }
193 setUrbitWallet(urbitWallet) {
194 this.setState({ urbitWallet })
195 }
197 setAuthMnemonic(authMnemonic) {
198 this.setState({ authMnemonic })
199 }
201 setPointCursor(pointCursor) {
202 this.setState({ pointCursor })
203 }
205 addToPointCache(entry) {
206 this.setState((state, _) => ({
207 pointCache: Object.assign(state.pointCache, entry)
208 }))
209 }
211 setTxnHashCursor(txnHashCursor) {
212 this.setState({ txnHashCursor })
213 }
215 render() {
216 const {
217 routeCrumbs,
218 routeData,
219 networkType,
220 walletType,
221 walletHdPath,
222 wallet,
223 urbitWallet,
224 authMnemonic,
225 networkSeedCache,
226 pointCursor,
227 pointCache,
228 txnHashCursor,
229 web3,
230 contracts
231 } = this.state
233 const View = router(routeCrumbs.peek())
235 return (
236 <React.Fragment>
237 <Container>
238 <Row>
239 <Col className='col-md-1' />
240 <Col className='col-md-10' style={{maxWidth: '620px'}}>
241 <Header
242 routeCrumbs={ routeCrumbs }
243 skipRoute={ this.skipRoute }
244 networkType={ networkType }
245 wallet={ wallet }
246 pointCursor={ pointCursor } />
248 <Row className={ 'row wrapper' }>
250 <View
251 // router
252 pushRoute={ this.pushRoute }
253 popRoute={ this.popRoute }
254 routeData={ routeData }
255 // network
256 setNetworkType={ this.setNetworkType }
257 setNetwork={ this.setNetwork }
258 networkType={ networkType }
259 web3={ web3 }
260 contracts={ contracts }
261 // wallet
262 setWalletType={ this.setWalletType }
263 setWalletHdPath={ this.setWalletHdPath }
264 setWallet={ this.setWallet }
265 walletType={ walletType }
266 walletHdPath={ walletHdPath }
267 wallet={ wallet }
268 // urbit wallet
269 urbitWallet={ urbitWallet }
270 setUrbitWallet={ this.setUrbitWallet }
271 authMnemonic={ authMnemonic }
272 setAuthMnemonic={ this.setAuthMnemonic }
273 // point
274 setPointCursor={ this.setPointCursor }
275 addToPointCache={ this.addToPointCache }
276 pointCursor={ pointCursor }
277 pointCache={ pointCache }
278 networkSeedCache= { networkSeedCache }
279 setNetworkSeedCache= { this.setNetworkSeedCache }
280 // txn
281 setTxnHashCursor={ this.setTxnHashCursor }
282 txnHashCursor={ txnHashCursor } />
284 <div className={'push'} />
286 </Row>
288 <Footer />
289 </Col>
290 </Row>
291 </Container>
293 <AppNavigation
294 setView={this.props.setView}
295 appView={this.props.appView} />
296 </React.Fragment>
297 )
298 }
301export default Bridge