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 ( Ship Select 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 ( }>
Migrating to Layer 2
{getContent()}
); }