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