@@ -0,0 +1,156 @@
1+import React, { useCallback, useMemo } from 'react';
2+import cn from 'classnames';
3+import { Grid, Text } from 'indigo-react';
4+import * as azimuth from 'azimuth-js';
5+import { memoize } from 'lodash';
6+
7+import { useNetwork } from 'store/network';
8+import { useWallet } from 'store/wallet';
9+import { useHistory } from 'store/history';
10+
11+import * as need from 'lib/need';
12+import useEthereumTransaction from 'lib/useEthereumTransaction';
13+import { GAS_LIMITS } from 'lib/constants';
14+import { useLocalRouter } from 'lib/LocalRouter';
15+import { useFlowCommand } from 'lib/flowCommand';
16+import { isValidAddress, eqAddr } from 'lib/wallet';
17+
18+import ViewHeader from 'components/ViewHeader';
19+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
20+import View from 'components/View';
21+
22+import BridgeForm from 'form/BridgeForm';
23+import { AddressInput } from 'form/Inputs';
24+import { composeValidator } from 'form/validators';
25+
26+function useAcceptLockup() {
27+ const { contracts } = useNetwork();
28+ const { push, names } = useHistory();
29+
30+ const flow = useFlowCommand();
31+
32+ const _contracts = need.contracts(contracts);
33+
34+ const transaction = useEthereumTransaction(
35+ useCallback(
36+ from => {
37+ if (flow.lock === 'conditional') {
38+ return azimuth.conditionalSR.transferCommitment(_contracts, from);
39+ } else {
40+ return azimuth.linearSR.transferBatch(_contracts, from);
41+ }
42+ },
43+ [_contracts, flow]
44+ ),
45+ useCallback(() => push(names.STAR_RELEASE), [push, names]),
46+ GAS_LIMITS.TRANSFER_LOCKUP
47+ );
48+
49+ return {
50+ ...transaction,
51+ };
52+}
53+
54+export default function AcceptLockup() {
55+ const { pop } = useLocalRouter();
56+ const { contracts } = useNetwork();
57+ const { wallet } = useWallet();
58+ const flow = useFlowCommand();
59+
60+ const _contracts = need.contracts(contracts);
61+ const _address = need.addressFromWallet(wallet);
62+
63+ const {
64+ completed,
65+ bind,
66+ inputsLocked,
67+ construct,
68+ unconstruct,
69+ } = useAcceptLockup();
70+
71+ const initialValues = useMemo(() => {
72+ if (!flow.from) return {};
73+ return { from: flow.from };
74+ }, [flow]);
75+
76+ const getApproved = useMemo(() => {
77+ return memoize(async from => {
78+ console.log('------ looking up');
79+ const lok = await (flow.lock === 'conditional'
80+ ? azimuth.conditionalSR.getCommitment(_contracts, from)
81+ : azimuth.linearSR.getBatch(_contracts, from));
82+ return lok.approvedTransferTo;
83+ });
84+ }, [flow, _contracts]);
85+
86+ const validate = useMemo(
87+ () =>
88+ composeValidator({
89+ from: async from => {
90+ if (!isValidAddress(from)) {
91+ return 'This is not a valid Ethereum address.';
92+ }
93+ const approved = await getApproved(from);
94+ if (!eqAddr(_address, approved)) {
95+ return 'Not permitted to take lockup from this address.';
96+ }
97+ },
98+ }),
99+ [_address, getApproved]
100+ );
101+
102+ const onValues = useCallback(
103+ ({ valid, values, form }) => {
104+ if (valid) {
105+ construct(values.from);
106+ } else {
107+ unconstruct();
108+ }
109+ },
110+ [construct, unconstruct]
111+ );
112+
113+ return (
114+ <View pop={pop} inset>
115+ <Grid>
116+ <Grid.Item full as={ViewHeader}>
117+ Accept Star Lockup
118+ </Grid.Item>
119+
120+ <Grid.Item
121+ full
122+ as={Text}
123+ className={cn('f5 wrap', {
124+ green3: completed,
125+ })}>
126+ {completed
127+ ? `You have accepted the star lockup.`
128+ : `Accept the incoming transfer of a star lockup.`}
129+ </Grid.Item>
130+
131+ <BridgeForm
132+ validate={validate}
133+ initialValues={initialValues}
134+ onValues={onValues}>
135+ {() => (
136+ <Grid.Item
137+ full
138+ as={AddressInput}
139+ name="from"
140+ label="Previous owner of the star lockup"
141+ disabled={inputsLocked}
142+ className="mv4"
143+ />
144+ )}
145+ </BridgeForm>
146+
147+ <Grid.Item
148+ full
149+ as={InlineEthereumTransaction}
150+ {...bind}
151+ onReturn={() => pop()}
152+ />
153+ </Grid>
154+ </View>
155+ );
156+}