on e366ef3 help sign in
bridge/src/views/CreateGalaxy.js
199 lines 5.7 kB history raw
1import React from 'react';
2import Maybe from 'folktale/maybe';
3import * as azimuth from 'azimuth-js';
4import * as ob from 'urbit-ob';
5import * as need from '../lib/need';
7import { Button } from '../components/old/Base';
8import { Row, Col, H1, P, Anchor } from '../components/old/Base';
9import {
10 InnerLabel,
11 GalaxyInput,
12 AddressInput,
13 ValidatedSigil,
14 ShowBlockie,
15} from '../components/old/Base';
16import StatelessTransaction from '../components/old/StatelessTransaction';
18import { NETWORK_TYPES } from '../lib/network';
19import { canDecodePatp } from '../lib/txn';
21import { ETH_ZERO_ADDR, isValidAddress, eqAddr } from '../lib/wallet';
23import { isValidGalaxy, compose } from '../lib/lib';
24import { withNetwork } from '../store/network';
25import { withWallet } from '../store/wallet';
27const buttonTriState = status => {
28 if (status === null) return 'blue';
29 if (status === false) return 'yellow';
30 if (status === true) return 'green';
31};
33const buttonTriStateText = status => {
34 if (status === null) return 'Confirm Galaxy Availablility';
35 if (status === false) return 'Galaxy is Not Available';
36 if (status === true) return 'Galaxy is Available';
37};
39class CreateGalaxy extends React.Component {
40 constructor(props) {
41 super(props);
43 const galaxyOwner = need.address(props);
45 this.state = {
46 galaxyOwner: galaxyOwner,
47 galaxyName: '',
48 isAvailable: null,
49 };
51 this.handleAddressInput = this.handleAddressInput.bind(this);
52 this.handleGalaxyNameInput = this.handleGalaxyNameInput.bind(this);
53 this.confirmAvailability = this.confirmAvailability.bind(this);
54 this.createUnsignedTxn = this.createUnsignedTxn.bind(this);
55 this.statelessRef = React.createRef();
56 }
58 handleGalaxyNameInput = galaxyName => {
59 this.setState({ galaxyName, isAvailable: null });
60 this.statelessRef.current.clearTxn();
61 };
63 handleAddressInput = galaxyOwner => {
64 this.setState({ galaxyOwner });
65 this.statelessRef.current.clearTxn();
66 };
68 createUnsignedTxn = () => {
69 const { state, props } = this;
70 if (isValidAddress(state.galaxyOwner) === false) return Maybe.Nothing();
71 if (state.isAvailable === false) return Maybe.Nothing();
72 if (canDecodePatp(state.galaxyName) === false) return Maybe.Nothing();
73 if (isValidGalaxy(state.galaxyName) === false) return Maybe.Nothing();
75 const validContracts = need.contracts(props);
77 const galaxyDec = parseInt(ob.patp2dec(state.galaxyName), 10);
79 const txn = azimuth.ecliptic.createGalaxy(
80 validContracts,
81 galaxyDec,
82 state.galaxyOwner
83 );
85 return Maybe.Just(txn);
86 };
88 confirmAvailability = async () => {
89 const { state, props } = this;
91 if (canDecodePatp(state.galaxyName) === false) {
92 this.setState({ isAvailable: false });
93 return;
94 }
96 const validContracts = need.contracts(props);
98 const galaxyDec = ob.patp2dec(state.galaxyName);
100 const currentOwner = await azimuth.azimuth.getOwner(
101 validContracts,
102 galaxyDec
103 );
105 const available = eqAddr(currentOwner, ETH_ZERO_ADDR);
107 this.setState({ isAvailable: available });
108 };
110 render() {
111 const { props, state } = this;
113 const validAddress = isValidAddress(state.galaxyOwner);
114 const validGalaxy = isValidGalaxy(state.galaxyName);
116 const canGenerate =
117 validAddress === true &&
118 validGalaxy === true &&
119 state.isAvailable === true;
121 const esvisible =
122 props.networkType === NETWORK_TYPES.ROPSTEN ||
123 props.networkType === NETWORK_TYPES.MAINNET;
125 const esdomain =
126 props.networkType === NETWORK_TYPES.ROPSTEN
127 ? 'ropsten.etherscan.io'
128 : 'etherscan.io';
130 return (
131 <Row>
132 <Col>
133 <H1> {'Create a Galaxy'} </H1>
135 <P>
136 {'Enter the galaxy to create and the address that will own ' +
137 'it (defaulting to this account, if not provided).'}
138 </P>
140 <GalaxyInput
141 className="mono"
142 prop-size="lg"
143 prop-format="innerLabel"
144 autoFocus
145 placeholder="e.g. ~zod"
146 value={state.galaxyName}
147 onChange={v => this.handleGalaxyNameInput(v)}>
148 <InnerLabel>{'Galaxy Name'}</InnerLabel>
149 <ValidatedSigil
150 className="tr-0 mt-05 mr-0 abs"
151 patp={state.galaxyName}
152 size={68}
153 margin={8}
154 />
155 </GalaxyInput>
157 <AddressInput
158 className="mono mt-8"
159 prop-size="lg"
160 prop-format="innerLabel"
161 value={state.galaxyOwner}
162 onChange={v => this.handleAddressInput(v)}>
163 <InnerLabel>{'Address that will own this galaxy'}</InnerLabel>
164 <ShowBlockie className={'mt-1'} address={state.galaxyOwner} />
165 </AddressInput>
167 <Anchor
168 className={'mt-1'}
169 prop-size={'sm'}
170 prop-disabled={!validAddress || !esvisible}
171 target={'_blank'}
172 href={`https://${esdomain}/address/${state.galaxyOwner}`}>
173 {'View on Etherscan ↗'}
174 </Anchor>
176 <Button
177 prop-size="lg wide"
178 className="mt-8"
179 prop-color={buttonTriState(state.isAvailable)}
180 disabled={!validGalaxy}
181 onClick={() => this.confirmAvailability()}>
182 {buttonTriStateText(state.isAvailable)}
183 </Button>
185 <StatelessTransaction
186 ref={this.statelessRef}
187 canGenerate={canGenerate}
188 createUnsignedTxn={this.createUnsignedTxn}
189 />
190 </Col>
191 </Row>
192 );
193 }
196export default compose(
197 withNetwork,
198 withWallet
199)(CreateGalaxy);