on 8ca8b8a help sign in
bridge/src/views/Transfer.js
127 lines 3.6 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 { H1, InnerLabel, ShowBlockie, P, Anchor } from '../components/old/Base';
8import { AddressInput } from '../components/old/Base';
9import StatelessTransaction from '../components/old/StatelessTransaction';
11import { NETWORK_TYPES } from '../lib/network';
13import { isValidAddress } from '../lib/wallet';
14import { withNetwork } from '../store/network';
15import { compose } from '../lib/lib';
16import { withPointCursor } from '../store/pointCursor';
17import View from 'components/View';
19class Transfer extends React.Component {
20 constructor(props) {
21 super(props);
23 const issuingPoint = need.point(props.pointCursor);
25 this.state = {
26 receivingAddress: '',
27 issuingPoint: issuingPoint,
28 };
30 this.handleAddressInput = this.handleAddressInput.bind(this);
31 this.createUnsignedTxn = this.createUnsignedTxn.bind(this);
32 this.statelessRef = React.createRef();
33 }
35 handleAddressInput(receivingAddress) {
36 this.setState({ receivingAddress });
37 this.statelessRef.current.clearTxn();
38 }
40 handleConfirmAvailability() {
41 this.confirmPointAvailability().then(r => {
42 this.setState({ isAvailable: r });
43 });
44 }
46 createUnsignedTxn() {
47 const { state, props } = this;
49 const validContracts = need.contracts(props.contracts);
50 const validPoint = need.point(props.pointCursor);
52 const txn = azimuth.ecliptic.setTransferProxy(
53 validContracts,
54 validPoint,
55 state.receivingAddress
56 );
58 return Maybe.Just(txn);
59 }
61 render() {
62 const { props, state } = this;
64 const validAddress = isValidAddress(state.receivingAddress);
65 const canGenerate = validAddress === true;
67 const esvisible =
68 props.networkType === NETWORK_TYPES.ROPSTEN ||
69 props.networkType === NETWORK_TYPES.MAINNET;
71 const esdomain =
72 props.networkType === NETWORK_TYPES.ROPSTEN
73 ? 'ropsten.etherscan.io'
74 : 'etherscan.io';
76 return (
77 <View>
78 <H1>
79 {'Transfer'} <code>{` ${ob.patp(state.issuingPoint)} `}</code>
80 {'To a New Owner'}
81 </H1>
83 <P>
84 {`Please provide the Ethereum address of the new owner. You own these
85 points until the recipient accepts the incoming transfer.
86 You may cancel the transfer until the transfer is accepted.`}
87 </P>
89 <AddressInput
90 className={'mono mt-8'}
91 prop-size="lg"
92 prop-format="innerLabel"
93 value={state.receivingAddress}
94 placeholder={`e.g. 0x84295d5e054d8cff5a22428b195f5a1615bd644f`}
95 onChange={v => this.handleAddressInput(v)}>
96 <InnerLabel>{'New ownership address'}</InnerLabel>
97 <ShowBlockie className={'mt-1'} address={state.receivingAddress} />
98 </AddressInput>
100 <Anchor
101 className={'mt-1'}
102 prop-size={'s'}
103 prop-disabled={!isValidAddress(state.receivingAddress) || !esvisible}
104 target={'_blank'}
105 href={`https://${esdomain}/address/${state.receivingAddress}`}>
106 {'View on Etherscan ↗'}
107 </Anchor>
109 <StatelessTransaction
110 // Upper scope
111 {...props}
112 // Checks
113 userApproval={state.userApproval}
114 canGenerate={canGenerate}
115 // Methods
116 createUnsignedTxn={this.createUnsignedTxn}
117 ref={this.statelessRef}
118 />
119 </View>
120 );
121 }
124export default compose(
125 withNetwork,
126 withPointCursor
127)(Transfer);