import React, { useState, useEffect, useCallback } from 'react';
import { Grid } from 'indigo-react';
import { ecliptic } from 'azimuth-js';
import * as ob from 'urbit-ob';
import {
getHideMigrationMessage,
storeHideMigrationMessage,
} from 'store/storage/roller';
import { useNetwork } from 'store/network';
import { usePointCache } from 'store/pointCache';
import { useRollerStore } from 'store/rollerStore';
import { useLocalRouter } from 'lib/LocalRouter';
import * as need from 'lib/need';
import Point, { PointField } from 'lib/types/Point';
import useRoller from 'lib/useRoller';
import { L1TxnType } from 'lib/types/PendingL1Transaction';
import useEthereumTransaction from 'lib/useEthereumTransaction';
import { DUMMY_L2_ADDRESS, GAS_LIMITS } from 'lib/constants';
import { isPlanet } from 'lib/utils/point';
import View from 'components/View';
import L2BackHeader from 'components/L2/Headers/L2BackHeader';
import BodyPane from 'components/L2/Window/BodyPane';
import HeaderPane from 'components/L2/Window/HeaderPane';
import Window from 'components/L2/Window/Window';
import InlineEthereumTransaction from 'components/InlineEthereumTransaction';
import Dropdown from 'components/L2/Dropdowns/Dropdown';
import Sigil from 'components/Sigil';
import { ReactComponent as StarIcon } from 'assets/star.svg';
import {
Box,
Button,
Checkbox,
Icon,
RadioButton,
Row,
} from '@tlon/indigo-react';
import './MigrateL2.scss';
const PointEntry = ({
point,
select,
}: {
point: number;
select?: () => void;
}) => {
if (point < 0) {
return (
Select a point
);
}
const patp = ob.patp(point);
return (
{patp}
);
};
const useMigrate = () => {
const { contracts }: any = useNetwork();
const { syncDates }: any = usePointCache();
const _contracts = need.contracts(contracts);
const [selectedPoint, setSelectedPoint] = useState(null);
return useEthereumTransaction(
useCallback(
(selectedPoint: number, transfer: boolean) => {
if (selectedPoint < 0) {
return;
}
setSelectedPoint(selectedPoint);
return transfer || isPlanet(selectedPoint)
? ecliptic.transferPoint(
_contracts,
selectedPoint,
DUMMY_L2_ADDRESS,
false
)
: ecliptic.setSpawnProxy(_contracts, selectedPoint, DUMMY_L2_ADDRESS);
},
[_contracts]
),
useCallback(() => syncDates(selectedPoint), [selectedPoint, syncDates]),
GAS_LIMITS.DEFAULT
);
};
export default function MigrateL2() {
const { pop }: any = useLocalRouter();
const { point, pointList } = useRollerStore();
const { checkForUpdates } = useRoller();
const l1Points = pointList.filter(({ canMigrate }) => canMigrate);
const [proceed, setProceed] = useState(false);
const [hideMessage, setHideMessage] = useState(false);
const [showDropdown, setShowDropdown] = useState(false);
const [transfer, setTransfer] = useState(true);
const [selectedPoint, setSelectedPoint] = useState(
point.isL1 ? point : l1Points[0]
);
const hideInfo = getHideMigrationMessage();
const { construct, unconstruct, bind, completed, txHashes } = useMigrate();
useEffect(() => {
if (point.isGalaxy && point.isL1) {
setTransfer(false);
construct(point.value, false);
} else if (point.isL1) {
construct(point.value, transfer);
} else {
unconstruct();
}
}, []); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
if (completed) {
const message = transfer
? `${selectedPoint.patp} has been migrated to Layer 2!`
: `${selectedPoint.patp}'s spawn proxy has been set to Layer 2!`;
checkForUpdates({
point: selectedPoint,
message,
notify: true,
field: PointField.layer,
l1Txn: {
id: `${DUMMY_L2_ADDRESS}-${selectedPoint.value}`,
point: selectedPoint.value,
type: transfer ? L1TxnType.migrate : L1TxnType.migrateSpawn,
hash: txHashes[0],
time: new Date().getTime(),
},
});
pop();
}
}, [completed, pop]); // eslint-disable-line react-hooks/exhaustive-deps
const goBack = useCallback(() => {
if (proceed) {
setProceed(false);
} else {
pop();
}
}, [pop, proceed, setProceed]);
const goProceed = useCallback(() => {
if (hideMessage) {
storeHideMigrationMessage();
}
setProceed(true);
}, [hideMessage]);
const selectPoint = useCallback(
(point: Point) => {
if (point.isPlanet || (point.isStar && point.isL2Spawn)) {
setTransfer(true);
} else if (point.isGalaxy) {
setTransfer(false);
}
setSelectedPoint(point);
setShowDropdown(false);
bind.reset();
construct(point.value, transfer);
},
[setSelectedPoint, setShowDropdown, bind, construct, transfer]
);
const toggleTransfer = useCallback(() => {
construct(selectedPoint.value, !transfer);
setTransfer(!transfer);
}, [transfer, setTransfer, construct, selectedPoint]);
const getContent = () => {
if (l1Points.length === 0) {
return (
All of your eligible ships are already on Layer 2.
);
}
const isStar = Boolean(selectedPoint?.isStar);
const isGalaxy = Boolean(selectedPoint?.isGalaxy);
if (proceed) {
return (
ShipSelect one of your ships setShowDropdown(!showDropdown)}
value={}
className="migrate-selector">
{l1Points.map((p: Point) => (
selectPoint(p)}
/>
))}
{isStar && !selectedPoint?.isL2Spawn && (
Transfer Ship
Set Spawn Proxy
)}
{isStar && (
Transferring this point will allow you to conduct all
transactions on Layer 2. Setting the spawn proxy of a star to
Layer 2 will allow you to create planet invites for free, but
will require you to do all other transactions on Layer 1.
)}
{isGalaxy && (
Setting the spawn proxy of this galaxy to Layer 2 will allow you
to spawn stars on Layer 2 for free, but will still require you
to do all other transactions on Layer 1.
)}
pop()}
/>
);
}
return (
You are about to migrate a node from Layer 1 to Layer 2. This will
make transactions faster and cheaper. Here are some things you should
know.{' '}
Learn More
{!hideInfo && (
Migration to Layer 2 is irreversible
{'. '}
You will not be able to revert back to Layer 1.
$
A migration is expensive, but a one-time fee. The estimated
price is $120. Transaction fees
will be subsidized on Layer 2.
{/* */}
All transactions will now be pushed at the end of the day. A
timer will show when the next push is.
)}
{!hideInfo && (
setHideMessage(!hideMessage)}
/>
Do not show this again
)}
);
};
return (
}>