on master help sign in
Merge branch 'jkmallard-galaxy-planet-check'
bf5080eJared Tobin
src/views/IssueChild.js+53−49
@@ -1,6 +1,6 @@
1−import Maybe from 'folktale/maybe'
1+import { Just, Nothing } from 'folktale/maybe'
2import React from 'react'
2import React from 'react'
3−import * as azimuth from 'azimuth-js'
3+import { azimuth, ecliptic } from 'azimuth-js'
4import * as ob from 'urbit-ob'
4import * as ob from 'urbit-ob'
5
5
6import { Row, Col, H1, H3, P, Anchor, Warning } from '../components/Base'
6import { Row, Col, H1, H3, P, Anchor, Warning } from '../components/Base'
@@ -13,11 +13,7 @@ import { ROUTE_NAMES } from '../lib/router'
13import { NETWORK_NAMES } from '../lib/network'
13import { NETWORK_NAMES } from '../lib/network'
14import { BRIDGE_ERROR } from '../lib/error'
14import { BRIDGE_ERROR } from '../lib/error'
15import { getSpawnCandidate } from '../lib/child'
15import { getSpawnCandidate } from '../lib/child'
16−import {
17− canDecodePatp,
18− sendSignedTransaction,
16+import { canDecodePatp, sendSignedTransaction, fromWei } from '../lib/txn'
19− fromWei,
20− } from '../lib/txn'
21
17
22import {
18import {
23 ETH_ZERO_ADDR,
19 ETH_ZERO_ADDR,
@@ -30,7 +26,6 @@ class IssueChild extends React.Component {
30 constructor(props) {
26 constructor(props) {
31 super(props)
27 super(props)
32
28
33−
34 const issuingPoint = props.pointCursor.matchWith({
29 const issuingPoint = props.pointCursor.matchWith({
35 Just: (pt) => parseInt(pt.value, 10),
30 Just: (pt) => parseInt(pt.value, 10),
36 Nothing: () => {
31 Nothing: () => {
@@ -48,25 +43,24 @@ class IssueChild extends React.Component {
48 ]
43 ]
49
44
50 this.state = {
45 this.state = {
51− txError: Maybe.Nothing(),
46+ txError: Nothing(),
52 receivingAddress: '',
47 receivingAddress: '',
53 issuingPoint: issuingPoint,
48 issuingPoint: issuingPoint,
54 desiredPoint: '',
49 desiredPoint: '',
55− isAvailable: Maybe.Nothing(), // allow attempt when offline
50+ isAvailable: Nothing(), // use Nothing to allow attempt when offline
56 userApproval: false,
51 userApproval: false,
57 nonce: '',
52 nonce: '',
58 gasPrice: '5',
53 gasPrice: '5',
59 chainId: '',
54 chainId: '',
60 gasLimit: '600000',
55 gasLimit: '600000',
61− txn: Maybe.Nothing(),
56+ txn: Nothing(),
62− stx: Maybe.Nothing(),
57+ stx: Nothing(),
63 suggestions: suggestions,
58 suggestions: suggestions,
64 }
59 }
65
60
66 this.handlePointInput = this.handlePointInput.bind(this)
61 this.handlePointInput = this.handlePointInput.bind(this)
67 this.handleAddressInput = this.handleAddressInput.bind(this)
62 this.handleAddressInput = this.handleAddressInput.bind(this)
68 this.handleConfirmAvailability = this.handleConfirmAvailability.bind(this)
63 this.handleConfirmAvailability = this.handleConfirmAvailability.bind(this)
69− // Transaction
70 this.handleCreateUnsignedTxn = this.handleCreateUnsignedTxn.bind(this)
64 this.handleCreateUnsignedTxn = this.handleCreateUnsignedTxn.bind(this)
71 this.handleSubmit = this.handleSubmit.bind(this)
65 this.handleSubmit = this.handleSubmit.bind(this)
72 this.handleSetUserApproval = this.handleSetUserApproval.bind(this)
66 this.handleSetUserApproval = this.handleSetUserApproval.bind(this)
@@ -97,20 +91,20 @@ class IssueChild extends React.Component {
97 validWeb3.eth.getTransactionCount(addr),
91 validWeb3.eth.getTransactionCount(addr),
98 validWeb3.eth.net.getId(),
92 validWeb3.eth.net.getId(),
99 validWeb3.eth.getGasPrice()
93 validWeb3.eth.getGasPrice()
100− ];
94+ ]
101
95
102 Promise.all(getTxMetadata).then(r => {
96 Promise.all(getTxMetadata).then(r => {
103 const txMetadata = {
97 const txMetadata = {
104 nonce: r[0],
98 nonce: r[0],
105 chainId: r[1],
99 chainId: r[1],
106 gasPrice: fromWei(r[2], 'gwei'),
100 gasPrice: fromWei(r[2], 'gwei'),
107− };
101+ }
108
102
109 this.setState({...txMetadata})
103 this.setState({...txMetadata})
110
104
111 })
105 })
112 }
106 }
113− });
107+ })
114
108
115 }
109 }
116
110
@@ -127,7 +121,7 @@ class IssueChild extends React.Component {
127 if (desiredPoint.length < 15) {
121 if (desiredPoint.length < 15) {
128 this.setState({
122 this.setState({
129 desiredPoint,
123 desiredPoint,
130− isAvailable: Maybe.Nothing()
124+ isAvailable: Nothing()
131 })
125 })
132 this.handleClearTxn()
126 this.handleClearTxn()
133 }
127 }
@@ -205,7 +199,7 @@ class IssueChild extends React.Component {
205 handleClearStx() {
199 handleClearStx() {
206 this.setState({
200 this.setState({
207 userApproval: false,
201 userApproval: false,
208− stx: Maybe.Nothing(),
202+ stx: Nothing(),
209 })
203 })
210 }
204 }
211
205
@@ -214,8 +208,8 @@ class IssueChild extends React.Component {
214 handleClearTxn() {
208 handleClearTxn() {
215 this.setState({
209 this.setState({
216 userApproval: false,
210 userApproval: false,
217− txn: Maybe.Nothing(),
211+ txn: Nothing(),
218− stx: Maybe.Nothing(),
212+ stx: Nothing(),
219 })
213 })
220 }
214 }
221
215
@@ -224,8 +218,8 @@ class IssueChild extends React.Component {
224 handleClearTransaction() {
218 handleClearTransaction() {
225 this.setState({
219 this.setState({
226 userApproval: false,
220 userApproval: false,
227− txn: Maybe.Nothing(),
221+ txn: Nothing(),
228− stx: Maybe.Nothing(),
222+ stx: Nothing(),
229 })
223 })
230 }
224 }
231
225
@@ -244,40 +238,48 @@ class IssueChild extends React.Component {
244 })
238 })
245 }
239 }
246
240
247−
248−
249 async confirmPointAvailability() {
241 async confirmPointAvailability() {
250− const { state, props } = this
242+ const { contracts } = this.props
251−
243+ const { desiredPoint } = this.state
252− if (canDecodePatp(state.desiredPoint) === false) return Maybe.Just(false)
253
244
254− const validContracts = props.contracts.matchWith({
245+ const validContracts = contracts.matchWith({
255− Just: (cs) => cs.value,
246+ Just: cs => cs.value,
256− Nothing: () => {
247+ Nothing: _ => {
257 throw BRIDGE_ERROR.MISSING_CONTRACTS
248 throw BRIDGE_ERROR.MISSING_CONTRACTS
258 }
249 }
259 })
250 })
260
251
261− const pointDec = ob.patp2dec(state.desiredPoint)
252+ if (canDecodePatp(desiredPoint) === false) {
253+ return Just(false)
254+ }
262
255
263− const owner = await azimuth.azimuth.getOwner(
256+ const point = ob.patp2dec(desiredPoint)
264− validContracts,
257+ const pointSize = azimuth.getPointSize(point)
265− pointDec
266− )
267
258
268− if (eqAddr(owner, ETH_ZERO_ADDR)) return Maybe.Just(true)
259+ const prefix = azimuth.getPrefix(point)
260+ const prefixSize = azimuth.getPointSize(prefix)
269
261
262+ // NB (jtobin): this prevents galaxies from attempting to spawn planets
263+ //
264+ if (pointSize !== prefixSize + 1) {
270− return Maybe.Just(false)
265+ return Just(false)
271− }
266+ }
272
267
268+ const owner = await azimuth.getOwner(validContracts, point)
273
269
270+ if (eqAddr(owner, ETH_ZERO_ADDR)) {
271+ return Just(true)
272+ }
273+
274+ return Just(false)
275+ }
274
276
275 createUnsignedTxn() {
277 createUnsignedTxn() {
276 const { state, props } = this
278 const { state, props } = this
277
279
278− if (isValidAddress(state.receivingAddress) === false) return Maybe.Nothing()
280+ if (isValidAddress(state.receivingAddress) === false) return Nothing()
279− if (state.isAvailable === false) return Maybe.Nothing()
281+ if (state.isAvailable === false) return Nothing()
280− if (canDecodePatp(state.desiredPoint) === false) return Maybe.Nothing()
282+ if (canDecodePatp(state.desiredPoint) === false) return Nothing()
281
283
282 const validContracts = props.contracts.matchWith({
284 const validContracts = props.contracts.matchWith({
283 Just: (cs) => cs.value,
285 Just: (cs) => cs.value,
@@ -288,20 +290,20 @@ class IssueChild extends React.Component {
288
290
289 const pointDec = ob.patp2dec(state.desiredPoint)
291 const pointDec = ob.patp2dec(state.desiredPoint)
290
292
291− const txn = azimuth.ecliptic.spawn(
293+ const txn = ecliptic.spawn(
292 validContracts,
294 validContracts,
293 pointDec,
295 pointDec,
294 state.receivingAddress
296 state.receivingAddress
295 )
297 )
296
298
297− return Maybe.Just(txn)
299+ return Just(txn)
298 }
300 }
299
301
300
302
301
303
302 buttonTriState() {
304 buttonTriState() {
303 const a = this.state.isAvailable
305 const a = this.state.isAvailable
304− if (Maybe.Nothing.hasInstance(a)) return 'blue'
306+ if (Nothing.hasInstance(a)) return 'blue'
305 if (a.value === false) return 'yellow'
307 if (a.value === false) return 'yellow'
306 if (a.value === true) return 'green'
308 if (a.value === true) return 'green'
307 }
309 }
@@ -310,7 +312,7 @@ class IssueChild extends React.Component {
310
312
311 buttonTriStateText() {
313 buttonTriStateText() {
312 const a = this.state.isAvailable
314 const a = this.state.isAvailable
313− if (Maybe.Nothing.hasInstance(a)) return 'Confirm Availablility'
315+ if (Nothing.hasInstance(a)) return 'Confirm Availablility'
314 if (a.value === false) return 'Point is Not Available'
316 if (a.value === false) return 'Point is Not Available'
315 if (a.value === true) return 'Available'
317 if (a.value === true) return 'Available'
316 }
318 }
@@ -352,9 +354,11 @@ class IssueChild extends React.Component {
352 }
354 }
353 })
355 })
354
356
355− const canSign = !Maybe.Nothing.hasInstance(state.txn)
357+ const canSign = Just.hasInstance(state.txn)
356− const canApprove = !Maybe.Nothing.hasInstance(state.stx)
358+ const canApprove = Just.hasInstance(state.stx)
359+ const canSend =
360+ Just.hasInstance(state.stx)
357− const canSend = !Maybe.Nothing.hasInstance(state.stx) && state.userApproval === true
361+ && state.userApproval === true
358
362
359 const esvisible =
363 const esvisible =
360 props.networkType === NETWORK_NAMES.ROPSTEN ||
364 props.networkType === NETWORK_NAMES.ROPSTEN ||
@@ -494,7 +498,7 @@ class IssueChild extends React.Component {
494 handleSubmit={this.handleSubmit} />
498 handleSubmit={this.handleSubmit} />
495
499
496 {
500 {
497− Maybe.Nothing.hasInstance(state.txError)
501+ Nothing.hasInstance(state.txError)
498 ? ''
502 ? ''
499 : <Warning className={'mt-8'}>
503 : <Warning className={'mt-8'}>
500 <H3 style={{marginTop: 0, paddingTop: 0}}>
504 <H3 style={{marginTop: 0, paddingTop: 0}}>