1import Maybe from 'folktale/maybe'
2import React from 'react'
3import { pour } from 'sigil-js'
4import * as ob from 'urbit-ob'
5import * as azimuth from 'azimuth-js'
7import PointList from '../components/PointList'
8import ReactSVGComponents from '../components/ReactSVGComponents'
9import KeysAndMetadata from './Point/KeysAndMetadata'
10import { BRIDGE_ERROR } from '../lib/error'
11import { ROUTE_NAMES } from '../lib/router'
12import { Row, Col, H1, H2, H3, P } from '../components/Base'
13import { Button } from '../components/Base'
17 addressFromSecp256k1Public,
19 } from '../lib/wallet'
21const isPlanet = point =>
22 parseInt(point, 10) > 65535
24class Point extends React.Component {
38 componentDidUpdate(prevProps) {
42 // When a link in the 'issued points' component is clicked, we don't
43 // actually leave the Point component, and componentDidMount will not fire
44 // again. But, we can force a call to cachePoints here.
46 const oldCursor = prevProps.pointCursor.getOrElse(true)
47 const newCursor = this.props.pointCursor.getOrElse(true)
49 if (oldCursor !== newCursor) {
55 const { web3, contracts, pointCursor, addToPointCache } = this.props
58 contracts.chain(ctrcs =>
59 pointCursor.chain(point => {
60 azimuth.azimuth.getPoint(ctrcs, point)
61 .then(details => addToPointCache({ [point]: details }))
62 this.updateSpawned(ctrcs, point)
66 updateSpawned = contracts => {
67 const { pointCursor } = this.props
69 pointCursor.matchWith({
72 azimuth.azimuth.getSpawned(contracts, point.value)
73 .then(spawned => this.setState({ spawned }))
81 const { web3, popRoute, pushRoute, wallet } = this.props
82 const { setPointCursor } = this.props
83 const { pointCursor, pointCache } = this.props
85 const { spawned } = this.state
87 const addr = wallet.matchWith({
88 Just: (wal) => addressFromSecp256k1Public(wal.value.publicKey),
90 throw BRIDGE_ERROR.MISSING_WALLET
94 const point = pointCursor.matchWith({
95 Just: (cursor) => cursor.value,
97 throw BRIDGE_ERROR.MISSING_POINT
103 ? Maybe.Just(pointCache[point])
106 const name = ob.patp(point)
110 renderer: ReactSVGComponents,
114 const online = Maybe.Just.hasInstance(web3)
116 const canSetTransferProxy = pointDetails.matchWith({
117 // also should check is addr is operator
119 Just: details => eqAddr(details.value.owner, addr)
122 const canSetSpawnProxy = pointDetails.matchWith({
125 eqAddr(details.value.owner, addr) && details.value.active
129 const canSetManagementProxy = pointDetails.matchWith({
132 eqAddr(details.value.owner, addr) && details.value.active
135 const canConfigureKeys = pointDetails.matchWith({
139 eqAddr(details.value.owner, addr)
140 || eqAddr(details.value.managementProxy, addr)
142 return canManage && details.value.active
146 const canIssueChild =
147 pointDetails.matchWith({
148 Nothing: () => false,
150 const hasPermission =
151 eqAddr(details.value.owner, addr)
152 || eqAddr(details.value.spawnProxy, addr)
155 details.value.keyRevisionNumber > 0
157 const isNotPlanet = !isPlanet(point)
159 return hasPermission && isBooted && isNotPlanet
163 const planet = isPlanet(point)
166 pointDetails.matchWith({
167 Nothing: () => false,
169 eqAddr(deets.value.transferProxy, addr) ||
170 eqAddr(deets.value.owner, addr)
173 const canGenKeyfile =
174 pointDetails.matchWith({
175 Nothing: () => false,
177 const hasPermission =
178 eqAddr(deets.value.owner, addr)
179 || eqAddr(deets.value.managementProxy, addr)
182 deets.value.keyRevisionNumber > 0
184 return hasPermission && isBooted
188 const canAcceptTransfer =
189 pointDetails.matchWith({
190 Nothing: () => false,
192 eqAddr(deets.value.transferProxy, addr)
195 const canCancelTransfer =
196 pointDetails.matchWith({
197 Nothing: () => false,
199 eqAddr(deets.value.owner, addr) &&
200 !eqAddr(deets.value.transferProxy, ETH_ZERO_ADDR)
203 const routeHandler = route => {
208 const issuedPointList =
212 <H3>{ 'Issued Points' }</H3>
215 setPointCursor={ setPointCursor }
216 routeHandler={ routeHandler }
222 const displayReminder = pointDetails.matchWith({
223 Nothing: () => false,
225 return deets.value.encryptionKey === CURVE_ZERO_ADDR
226 && deets.value.authenticationKey === CURVE_ZERO_ADDR
234 <div className={'mt-12 pt-6'}>
238 <H1><code>{ name }</code></H1>
240 <H2>{ 'Actions' }</H2>
244 ? <P>{`Before you can issue child points or generate your Arvo
245 keyfile, you need to set your public keys.`}</P>
250 <Col className={'flex flex-column items-start col-md-4'}>
254 disabled={ (online || planet) && !canIssueChild }
256 pushRoute(ROUTE_NAMES.ISSUE_CHILD)
265 disabled={ !canAcceptTransfer }
267 pushRoute(ROUTE_NAMES.ACCEPT_TRANSFER)
270 { 'Accept incoming transfer' }
276 disabled={ online && !canCancelTransfer }
278 pushRoute(ROUTE_NAMES.CANCEL_TRANSFER)
281 { 'Cancel outgoing transfer' }
287 disabled={ !canGenKeyfile }
289 pushRoute(ROUTE_NAMES.GEN_KEYFILE)
292 { 'Generate Arvo keyfile' }
296 <Col className={'flex flex-column items-start col-md-4'}>
299 disabled={ online && !canSetSpawnProxy }
303 pushRoute(ROUTE_NAMES.SET_SPAWN_PROXY)
306 { 'Set spawn proxy' }
310 disabled={ online && !canSetManagementProxy }
314 pushRoute(ROUTE_NAMES.SET_MANAGEMENT_PROXY)
317 { 'Set management proxy' }
321 disabled={ online && !canConfigureKeys }
325 pushRoute(ROUTE_NAMES.SET_KEYS)
328 { 'Set public keys' }
332 disabled={ online && !canTransfer }
336 pushRoute(ROUTE_NAMES.TRANSFER)
349 ? <KeysAndMetadata pointDetails={ pointDetails } />
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list