@@ -0,0 +1,190 @@
1+import React, { useState, useMemo, useCallback, useEffect } from 'react';
2+import { Grid } from 'indigo-react';
3+import * as ob from 'urbit-ob';
4+import { azimuth, ecliptic } from 'azimuth-js';
6+import { useNetwork } from 'store/network';
7+import { usePointCache } from 'store/pointCache';
9+import { PointInput } from 'form/Inputs';
10+import FormError from 'form/FormError';
11+import BridgeForm from 'form/BridgeForm';
13+import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
14+import ViewHeader from 'components/ViewHeader';
19+} from 'form/validators';
21+import * as need from 'lib/need';
22+import { validateMinimumPatpByteLength } from 'lib/validators';
23+import { usePointCursor } from 'store/pointCursor';
24+import useEthereumTransaction from 'lib/useEthereumTransaction';
26+function useChangeSponsor() {
27+ const { contracts } = useNetwork();
28+ const { pointCursor } = usePointCursor();
29+ const { syncOwnedPoint } = usePointCache();
31+ const _contracts = need.contracts(contracts);
32+ const point = need.point(pointCursor);
34+ return useEthereumTransaction(
35+ useCallback(sponsor => ecliptic.escape(_contracts, point, sponsor), [
40+ syncOwnedPoint(point);
41+ }, [syncOwnedPoint, point])
45+function ChangeSponsor({ onDone }) {
46+ const { contracts } = useNetwork();
48+ const _contracts = need.contracts(contracts);
49+ const { construct, unconstruct, inputsLocked, bind } = useChangeSponsor();
51+ const [newSponsor, setNewSponsor] = useState(false);
53+ const validateFormAsync = useCallback(
55+ const sponsor = ob.patp2dec(values.sponsor);
56+ const details = await azimuth.getPoint(_contracts, sponsor);
57+ console.log(details);
58+ console.log(details.keyRevisionNumber);
60+ if (details.keyRevisionNumber === 0) {
61+ return { sponsor: 'Sponsor is not online' };
67+ const validateForm = useCallback(
68+ (values, errors) => {
69+ if (hasErrors(errors)) {
72+ return validateFormAsync(values);
77+ const validate = useMemo(
81+ sponsor: buildPointValidator(2, [validateMinimumPatpByteLength(2)]),
88+ const onValues = useCallback(
89+ ({ valid, values }) => {
91+ construct(ob.patp2dec(values.sponsor));
92+ setNewSponsor(values.sponsor);
97+ [construct, unconstruct]
101+ <Grid.Item full as={ViewHeader}>
104+ <BridgeForm validate={validate} onValues={onValues}>
111+ disabled={inputsLocked}
114+ <Grid.Item full as={FormError} />
117+ as={InlineEthereumTransaction}
129+function useCancelEscape() {
130+ const { contracts } = useNetwork();
131+ const { pointCursor } = usePointCursor();
132+ const { syncOwnedPoint } = usePointCache();
134+ const _contracts = need.contracts(contracts);
135+ const point = need.point(pointCursor);
137+ return useEthereumTransaction(
138+ useCallback(() => ecliptic.cancelEscape(_contracts, point), [
142+ useCallback(() => syncOwnedPoint(point), [point, syncOwnedPoint])
146+function CurrentEscape({ onDone }) {
147+ const { construct, bind } = useCancelEscape();
154+ <Grid.Item full as={ViewHeader}>
155+ Currently requesting <span className="mono">~dopzod</span> as a new
160+ as={InlineEthereumTransaction}
161+ label="Cancel Request"
169+export default function UrbitOSChangeSponsor() {
170+ const { contracts } = useNetwork();
171+ const { pointCursor } = usePointCursor();
173+ const point = need.point(pointCursor);
175+ const { getDetails } = usePointCache();
177+ const details = need.details(getDetails(point));
179+ const [requested, setRequested] = useState(details.escapeRequested);
181+ const onDone = useCallback(() => {
182+ setRequested(details.escapeRequested);
183+ }, [details, setRequested]);
185+ return requested ? (
186+ <CurrentEscape onDone={onDone} />
188+ <ChangeSponsor onDone={onDone} />