on 368f024 help sign in
bridge/src/views/UrbitID/Transfer.js
188 lines 6.0 kB history raw
1import React, { useCallback, useMemo, useState } from 'react';
2import cn from 'classnames';
3import { Grid, Text, Button } from 'indigo-react';
4import * as azimuth from 'azimuth-js';
5import { Row } from '@tlon/indigo-react';
7import { useNetwork } from 'store/network';
8import { usePointCursor } from 'store/pointCursor';
9import { usePointCache } from 'store/pointCache';
10import { useStarReleaseCache } from 'store/starRelease';
11import { useRollerStore } from 'store/rollerStore';
13import * as need from 'lib/need';
14import { useLocalRouter } from 'lib/LocalRouter';
15import useCurrentPointName from 'lib/useCurrentPointName';
16import useEthereumTransaction from 'lib/useEthereumTransaction';
17import { GAS_LIMITS } from 'lib/constants';
18import useRoller from 'lib/useRoller';
20import NoticeBox from 'components/NoticeBox';
21import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
22import { AddressInput } from 'form/Inputs';
23import { composeValidator, buildAddressValidator } from 'form/validators';
24import BridgeForm from 'form/BridgeForm';
25import FormError from 'form/FormError';
26import Window from 'components/L2/Window/Window';
27import HeaderPane from 'components/L2/Window/HeaderPane';
28import BodyPane from 'components/L2/Window/BodyPane';
30function useTransfer() {
31 const { contracts } = useNetwork();
32 const { pointCursor } = usePointCursor();
33 const { syncDetails } = usePointCache();
35 const _contracts = need.contracts(contracts);
36 const _point = need.point(pointCursor);
38 return useEthereumTransaction(
39 useCallback(
40 address => azimuth.ecliptic.setTransferProxy(_contracts, _point, address),
41 [_contracts, _point]
42 ),
43 useCallback(() => syncDetails(_point), [_point, syncDetails]),
44 GAS_LIMITS.SET_PROXY
45 );
48export default function AdminTransfer() {
49 const { pop } = useLocalRouter();
50 const name = useCurrentPointName();
51 const { pointCursor } = usePointCursor();
52 const { starReleaseDetails } = useStarReleaseCache();
53 const {
54 point: { isL2 },
55 } = useRollerStore();
56 const { setProxyAddress, getPendingTransactions } = useRoller();
57 const [owner, setNewOwner] = useState('');
59 const {
60 construct,
61 unconstruct,
62 completed,
63 inputsLocked,
64 bind,
65 } = useTransfer();
67 const point = need.point(pointCursor);
69 const needLockupWarning = useMemo(() => {
70 const az = azimuth.azimuth;
71 return (
72 az.getPointSize(point) === az.PointSize.Galaxy &&
73 starReleaseDetails.map(a => a.kind).getOrElse('none') !== 'none'
74 );
75 }, [starReleaseDetails, point]);
77 const validate = useMemo(
78 () => composeValidator({ address: buildAddressValidator() }),
79 []
80 );
82 const transferPoint = useCallback(async () => {
83 // setLoading(true);
84 if (owner === '') return;
85 try {
86 await setProxyAddress('transfer', owner);
87 getPendingTransactions(point);
88 pop();
89 } catch (error) {
90 // setError(error);
91 } finally {
92 // setLoading(false);
93 }
94 }, [owner, getPendingTransactions, point, pop, setProxyAddress]);
96 const onValues = useCallback(
97 ({ valid, values }) => {
98 if (valid) {
99 construct(values.address);
100 setNewOwner(values.address);
101 } else {
102 unconstruct();
103 setNewOwner('');
104 }
105 },
106 [construct, unconstruct, setNewOwner]
107 );
109 return (
110 <Window>
111 <HeaderPane>
112 <Row className="header-row">
113 <h5>Transfer Point</h5>
114 </Row>
115 </HeaderPane>
116 <BodyPane>
117 <Grid style={{ width: '100%' }} full gap={1}>
118 <BridgeForm validate={validate} onValues={onValues}>
119 {({ handleSubmit, values }) => (
120 <>
121 {!completed && (
122 <Grid.Item full as={Text} className={cn('f5 wrap')}>
123 Transfer {name} to a new owner.
124 </Grid.Item>
125 )}
126 {!completed && needLockupWarning && (
127 <Grid.Item full as={NoticeBox}>
128 You have stars in lockup. These will not transfer with the{' '}
129 galaxy. If you wish, you must transfer the lockup
130 separately.
131 </Grid.Item>
132 )}
133 {completed && (
134 <>
135 <Grid.Item full as={Text} className="wrap">
136 Started transferring <span className="mono">{name}</span>
137 to{' '}
138 </Grid.Item>
139 <Grid.Item full as={Text}>
140 <span className="mono gray4">{values.address}</span>
141 </Grid.Item>
142 <Grid.Item full as={Text} className="mt6">
143 Until they accept the transfer, you still own{' '}
144 <span className="mono">{name}</span>
145 </Grid.Item>
146 </>
147 )}
149 {!completed && (
150 <Grid.Item
151 full
152 as={AddressInput}
153 className="mv4"
154 name="address"
155 label="Ethereum Address"
156 disabled={inputsLocked}
157 />
158 )}
160 <Grid.Item full as={FormError} />
162 {isL2 ? (
163 <Grid.Item
164 as={Button}
165 full
166 className="set-proxy"
167 center
168 solid
169 disabled={values.unset}
170 onClick={transferPoint}>
171 {'Transfer'}
172 </Grid.Item>
173 ) : (
174 <Grid.Item
175 full
176 as={InlineEthereumTransaction}
177 {...bind}
178 onReturn={() => pop()}
179 />
180 )}
181 </>
182 )}
183 </BridgeForm>
184 </Grid>
185 </BodyPane>
186 </Window>
187 );