on 80f2d29 help sign in
bridge/src/views/Transfer.js
139 lines 3.7 kB history raw
1import Maybe from 'folktale/maybe';
2import React from 'react';
3import * as azimuth from 'azimuth-js';
4import * as ob from 'urbit-ob';
5import * as need from '../lib/need';
7import {
8 Row,
9 Col,
10 H1,
11 InnerLabel,
12 ShowBlockie,
13 P,
14 Anchor,
15} from '../components/old/Base';
16import { AddressInput } from '../components/old/Base';
17import StatelessTransaction from '../components/old/StatelessTransaction';
19import { NETWORK_TYPES } from '../lib/network';
21import { isValidAddress } from '../lib/wallet';
22import { withNetwork } from '../store/network';
23import { compose } from '../lib/lib';
24import { withPointCursor } from '../store/pointCursor';
26class Transfer extends React.Component {
27 constructor(props) {
28 super(props);
30 const issuingPoint = need.pointCursor(props);
32 this.state = {
33 receivingAddress: '',
34 issuingPoint: issuingPoint,
35 };
37 this.handleAddressInput = this.handleAddressInput.bind(this);
38 this.createUnsignedTxn = this.createUnsignedTxn.bind(this);
39 this.statelessRef = React.createRef();
40 }
42 handleAddressInput(receivingAddress) {
43 this.setState({ receivingAddress });
44 this.statelessRef.current.clearTxn();
45 }
47 handleConfirmAvailability() {
48 this.confirmPointAvailability().then(r => {
49 this.setState({ isAvailable: r });
50 });
51 }
53 createUnsignedTxn() {
54 const { state, props } = this;
56 const validContracts = need.contracts(props);
58 const validPoint = need.pointCursor(props);
60 const txn = azimuth.ecliptic.setTransferProxy(
61 validContracts,
62 validPoint,
63 state.receivingAddress
64 );
66 return Maybe.Just(txn);
67 }
69 render() {
70 const { props, state } = this;
72 const validAddress = isValidAddress(state.receivingAddress);
73 const canGenerate = validAddress === true;
75 const esvisible =
76 props.networkType === NETWORK_TYPES.ROPSTEN ||
77 props.networkType === NETWORK_TYPES.MAINNET;
79 const esdomain =
80 props.networkType === NETWORK_TYPES.ROPSTEN
81 ? 'ropsten.etherscan.io'
82 : 'etherscan.io';
84 return (
85 <Row>
86 <Col>
87 <H1>
88 {'Transfer'} <code>{` ${ob.patp(state.issuingPoint)} `}</code>
89 {'To a New Owner'}
90 </H1>
92 <P>
93 {`Please provide the Ethereum address of the new owner. You own these
94 points until the recipient accepts the incoming transfer.
95 You may cancel the transfer until the transfer is accepted.`}
96 </P>
98 <AddressInput
99 className={'mono mt-8'}
100 prop-size="lg"
101 prop-format="innerLabel"
102 value={state.receivingAddress}
103 placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
104 onChange={v => this.handleAddressInput(v)}>
105 <InnerLabel>{'New ownership address'}</InnerLabel>
106 <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
107 </AddressInput>
109 <Anchor
110 className={'mt-1'}
111 prop-size={'s'}
112 prop-disabled={
113 !isValidAddress(state.receivingAddress) || !esvisible
114 }
115 target={'_blank'}
116 href={`https://${esdomain}/address/${state.receivingAddress}`}>
117 {'View on Etherscan ↗'}
118 </Anchor>
120 <StatelessTransaction
121 // Upper scope
122 {...props}
123 // Checks
124 userApproval={state.userApproval}
125 canGenerate={canGenerate}
126 // Methods
127 createUnsignedTxn={this.createUnsignedTxn}
128 ref={this.statelessRef}
129 />
130 </Col>
131 </Row>
132 );
133 }
136export default compose(
137 withNetwork,
138 withPointCursor
139)(Transfer);