2021-11-22 19:13:06 -08:00
|
|
|
import addLiquidityTx from "@certusone/wormhole-sdk/lib/esm/migration/addLiquidity";
|
|
|
|
import getAuthorityAddress from "@certusone/wormhole-sdk/lib/esm/migration/authorityAddress";
|
|
|
|
import claimSharesTx from "@certusone/wormhole-sdk/lib/esm/migration/claimShares";
|
|
|
|
import createPoolAccount from "@certusone/wormhole-sdk/lib/esm/migration/createPool";
|
|
|
|
import getFromCustodyAddress from "@certusone/wormhole-sdk/lib/esm/migration/fromCustodyAddress";
|
|
|
|
import migrateTokensTx from "@certusone/wormhole-sdk/lib/esm/migration/migrateTokens";
|
|
|
|
import parsePool from "@certusone/wormhole-sdk/lib/esm/migration/parsePool";
|
|
|
|
import getPoolAddress from "@certusone/wormhole-sdk/lib/esm/migration/poolAddress";
|
|
|
|
import removeLiquidityTx from "@certusone/wormhole-sdk/lib/esm/migration/removeLiquidity";
|
|
|
|
import getShareMintAddress from "@certusone/wormhole-sdk/lib/esm/migration/shareMintAddress";
|
|
|
|
import getToCustodyAddress from "@certusone/wormhole-sdk/lib/esm/migration/toCustodyAddress";
|
2021-09-10 17:53:50 -07:00
|
|
|
import {
|
2021-09-13 08:13:12 -07:00
|
|
|
Button,
|
2021-09-28 20:23:51 -07:00
|
|
|
CircularProgress,
|
2021-09-10 17:53:50 -07:00
|
|
|
Container,
|
2021-09-13 08:13:12 -07:00
|
|
|
Divider,
|
2021-09-10 17:53:50 -07:00
|
|
|
makeStyles,
|
|
|
|
Paper,
|
2021-09-12 18:29:11 -07:00
|
|
|
TextField,
|
2021-09-13 08:13:12 -07:00
|
|
|
Typography,
|
2021-09-10 17:53:50 -07:00
|
|
|
} from "@material-ui/core";
|
2021-09-13 08:13:12 -07:00
|
|
|
import {
|
|
|
|
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
|
|
Token,
|
|
|
|
TOKEN_PROGRAM_ID,
|
|
|
|
} from "@solana/spl-token";
|
|
|
|
import { Connection, PublicKey } from "@solana/web3.js";
|
2021-11-22 19:13:06 -08:00
|
|
|
//import { pool_address } from "@certusone/wormhole-sdk/lib/esm/solana/migration/wormhole_migration";
|
2021-09-13 08:13:12 -07:00
|
|
|
import { parseUnits } from "ethers/lib/utils";
|
|
|
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
2021-09-10 17:53:50 -07:00
|
|
|
import LogWatcher from "../components/LogWatcher";
|
2021-09-13 08:13:12 -07:00
|
|
|
import SolanaCreateAssociatedAddress, {
|
|
|
|
useAssociatedAccountExistsState,
|
|
|
|
} from "../components/SolanaCreateAssociatedAddress";
|
2021-09-10 17:53:50 -07:00
|
|
|
import SolanaWalletKey from "../components/SolanaWalletKey";
|
2021-09-13 08:13:12 -07:00
|
|
|
import { useLogger } from "../contexts/Logger";
|
2021-09-10 17:53:50 -07:00
|
|
|
import { useSolanaWallet } from "../contexts/SolanaWalletContext";
|
2021-09-28 20:23:51 -07:00
|
|
|
import { MIGRATION_PROGRAM_ADDRESS, SOLANA_URL } from "../utils/consts";
|
2021-09-12 18:29:11 -07:00
|
|
|
import { getMultipleAccounts, signSendAndConfirm } from "../utils/solana";
|
2021-09-10 17:53:50 -07:00
|
|
|
|
2021-09-12 18:29:11 -07:00
|
|
|
const useStyles = makeStyles(() => ({
|
|
|
|
rootContainer: {},
|
|
|
|
mainPaper: {
|
|
|
|
"& > *": {
|
|
|
|
margin: "1rem",
|
|
|
|
},
|
|
|
|
padding: "2rem",
|
|
|
|
},
|
2021-09-12 22:35:00 -07:00
|
|
|
divider: {
|
|
|
|
margin: "2rem",
|
|
|
|
},
|
2021-09-16 07:49:46 -07:00
|
|
|
spacer: {
|
|
|
|
height: "1rem",
|
|
|
|
},
|
2021-09-12 18:29:11 -07:00
|
|
|
}));
|
2021-09-10 17:53:50 -07:00
|
|
|
|
2021-09-28 20:23:51 -07:00
|
|
|
export const compareWithDecimalOffset = (
|
2021-09-16 07:49:46 -07:00
|
|
|
valueA: string,
|
|
|
|
decimalsA: number,
|
|
|
|
valueB: string,
|
|
|
|
decimalsB: number
|
|
|
|
) => {
|
|
|
|
//find which is larger, and offset by that amount
|
|
|
|
const decimalsBasis = decimalsA > decimalsB ? decimalsA : decimalsB;
|
|
|
|
const normalizedA = parseUnits(valueA, decimalsBasis).toBigInt();
|
|
|
|
const normalizedB = parseUnits(valueB, decimalsBasis).toBigInt();
|
|
|
|
|
|
|
|
if (normalizedA < normalizedB) {
|
|
|
|
return -1;
|
|
|
|
} else if (normalizedA === normalizedB) {
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-09-13 08:13:12 -07:00
|
|
|
const getDecimals = async (
|
|
|
|
connection: Connection,
|
|
|
|
mint: string,
|
|
|
|
setter: (decimals: number | undefined) => void,
|
2021-09-16 07:49:46 -07:00
|
|
|
log: (value: string, type?: "error" | "info" | "success" | undefined) => void
|
2021-09-13 08:13:12 -07:00
|
|
|
) => {
|
|
|
|
setter(undefined);
|
|
|
|
if (mint) {
|
|
|
|
try {
|
|
|
|
const pk = new PublicKey(mint);
|
|
|
|
const info = await connection.getParsedAccountInfo(pk);
|
|
|
|
// @ts-ignore
|
|
|
|
const decimals = info.value?.data.parsed.info.decimals;
|
|
|
|
log(`${mint} has ${decimals} decimals`);
|
|
|
|
setter(decimals);
|
|
|
|
} catch (e) {
|
|
|
|
log(`Unable to determine decimals of ${mint}`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const getBalance = async (
|
|
|
|
connection: Connection,
|
|
|
|
address: string | undefined,
|
|
|
|
setter: (balance: string | undefined) => void,
|
2021-09-16 07:49:46 -07:00
|
|
|
log: (value: string, type?: "error" | "info" | "success" | undefined) => void
|
2021-09-13 08:13:12 -07:00
|
|
|
) => {
|
|
|
|
setter(undefined);
|
|
|
|
if (address) {
|
|
|
|
try {
|
|
|
|
const pk = new PublicKey(address);
|
|
|
|
const info = await connection.getParsedAccountInfo(pk);
|
|
|
|
// @ts-ignore
|
|
|
|
const balance = info.value?.data.parsed.info.tokenAmount.uiAmountString;
|
|
|
|
log(`${address} has a balance of ${balance}`);
|
|
|
|
setter(balance);
|
|
|
|
} catch (e) {
|
2021-09-16 07:49:46 -07:00
|
|
|
log(`Unable to determine balance of ${address}`, "error");
|
2021-09-13 08:13:12 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-09-10 17:53:50 -07:00
|
|
|
function Main() {
|
|
|
|
const classes = useStyles();
|
|
|
|
const wallet = useSolanaWallet();
|
2021-09-13 08:13:12 -07:00
|
|
|
const { log } = useLogger();
|
|
|
|
const connection = useMemo(() => new Connection(SOLANA_URL, "confirmed"), []);
|
2021-09-12 18:29:11 -07:00
|
|
|
|
2021-09-13 10:17:45 -07:00
|
|
|
const [fromMintHolder, setFromMintHolder] = useState("");
|
2021-09-13 08:13:12 -07:00
|
|
|
const [fromMintDecimals, setFromMintDecimals] = useState<number | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
2021-09-13 10:17:45 -07:00
|
|
|
const [toMintHolder, setToMintHolder] = useState("");
|
2021-09-16 07:49:46 -07:00
|
|
|
const [toMintDecimals, setToMintDecimals] = useState<number | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
2021-09-12 22:35:00 -07:00
|
|
|
const [shareMintAddress, setShareMintAddress] = useState<string | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
2021-09-13 08:13:12 -07:00
|
|
|
const [shareMintDecimals, setShareMintDecimals] = useState<any>(undefined);
|
2021-09-12 18:29:11 -07:00
|
|
|
|
2021-09-13 10:17:45 -07:00
|
|
|
let fromMint: string = "";
|
|
|
|
let toMint: string = "";
|
|
|
|
try {
|
|
|
|
fromMint = fromMintHolder && new PublicKey(fromMintHolder).toString();
|
|
|
|
toMint = toMintHolder && new PublicKey(toMintHolder).toString();
|
|
|
|
} catch (e) {}
|
|
|
|
|
2021-09-12 18:29:11 -07:00
|
|
|
const [poolAddress, setPoolAddress] = useState("");
|
2021-09-12 22:35:00 -07:00
|
|
|
const [poolExists, setPoolExists] = useState<boolean | undefined>(undefined);
|
2021-09-13 08:13:12 -07:00
|
|
|
const [poolAccountInfo, setPoolAccountInfo] = useState<any>(undefined);
|
2021-09-12 22:35:00 -07:00
|
|
|
const [parsedPoolData, setParsedPoolData] = useState(undefined);
|
|
|
|
|
|
|
|
//These are the user's personal token accounts corresponding to the mints for the connected wallet
|
|
|
|
const [fromTokenAccount, setFromTokenAccount] = useState<string | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
2021-09-16 07:49:46 -07:00
|
|
|
const [fromTokenAccountBalance, setFromTokenAccountBalance] = useState<
|
|
|
|
string | undefined
|
|
|
|
>();
|
2021-09-12 22:35:00 -07:00
|
|
|
const [toTokenAccount, setToTokenAccount] = useState<string | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
2021-09-16 07:49:46 -07:00
|
|
|
const [toTokenAccountBalance, setToTokenAccountBalance] = useState<
|
|
|
|
string | undefined
|
|
|
|
>();
|
2021-09-12 22:35:00 -07:00
|
|
|
const [shareTokenAccount, setShareTokenAccount] = useState<
|
|
|
|
string | undefined
|
|
|
|
>(undefined);
|
2021-09-16 07:49:46 -07:00
|
|
|
const [shareTokenAccountBalance, setShareTokenAccountBalance] = useState<
|
|
|
|
string | undefined
|
|
|
|
>();
|
2021-09-12 22:35:00 -07:00
|
|
|
|
|
|
|
//These hooks detect if the connected wallet has the requisite token accounts
|
|
|
|
const {
|
|
|
|
associatedAccountExists: fromTokenAccountExists,
|
|
|
|
setAssociatedAccountExists: setFromTokenAccountExists,
|
|
|
|
} = useAssociatedAccountExistsState(fromMint, fromTokenAccount);
|
|
|
|
const {
|
|
|
|
associatedAccountExists: toTokenAccountExists,
|
|
|
|
setAssociatedAccountExists: setToTokenAccountExists,
|
|
|
|
} = useAssociatedAccountExistsState(toMint, toTokenAccount);
|
|
|
|
const {
|
|
|
|
associatedAccountExists: shareTokenAccountExists,
|
|
|
|
setAssociatedAccountExists: setShareTokenAccountExists,
|
|
|
|
} = useAssociatedAccountExistsState(shareMintAddress, shareTokenAccount);
|
2021-09-12 18:29:11 -07:00
|
|
|
|
|
|
|
//these are all the other derived information
|
2021-09-12 22:35:00 -07:00
|
|
|
const [authorityAddress, setAuthorityAddress] = useState<string | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
|
|
|
const [fromCustodyAddress, setFromCustodyAddress] = useState<
|
|
|
|
string | undefined
|
|
|
|
>(undefined);
|
2021-09-13 08:13:12 -07:00
|
|
|
const [fromCustodyBalance, setFromCustodyBalance] = useState<
|
|
|
|
string | undefined
|
|
|
|
>(undefined);
|
2021-09-12 22:35:00 -07:00
|
|
|
const [toCustodyAddress, setToCustodyAddress] = useState<string | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
2021-09-13 08:13:12 -07:00
|
|
|
const [toCustodyBalance, setToCustodyBalance] = useState<string | undefined>(
|
|
|
|
undefined
|
|
|
|
);
|
2021-09-12 22:35:00 -07:00
|
|
|
|
|
|
|
const [toggleAllData, setToggleAllData] = useState(false);
|
|
|
|
|
|
|
|
const [liquidityAmount, setLiquidityAmount] = useState("");
|
2021-09-13 12:10:34 -07:00
|
|
|
const [removeLiquidityAmount, setRemoveLiquidityAmount] = useState("");
|
2021-09-12 22:35:00 -07:00
|
|
|
const [migrationAmount, setMigrationAmount] = useState("");
|
|
|
|
const [redeemAmount, setRedeemAmount] = useState("");
|
2021-09-12 18:29:11 -07:00
|
|
|
|
2021-09-13 10:17:45 -07:00
|
|
|
const [liquidityIsProcessing, setLiquidityIsProcessing] = useState(false);
|
2021-09-13 12:10:34 -07:00
|
|
|
const [removeLiquidityIsProcessing, setRemoveLiquidityIsProcessing] =
|
|
|
|
useState(false);
|
2021-09-13 10:17:45 -07:00
|
|
|
const [migrationIsProcessing, setMigrationIsProcessing] = useState(false);
|
|
|
|
const [redeemIsProcessing, setRedeemIsProcessing] = useState(false);
|
|
|
|
const [createPoolIsProcessing, setCreatePoolIsProcessing] = useState(false);
|
|
|
|
|
2021-09-12 18:29:11 -07:00
|
|
|
/*
|
|
|
|
Effects***
|
|
|
|
|
|
|
|
These are generally data fetchers which fire when requisite data populates.
|
|
|
|
|
|
|
|
*/
|
2021-09-13 08:13:12 -07:00
|
|
|
//Retrieve from mint information when fromMint changes
|
|
|
|
useEffect(() => {
|
|
|
|
getDecimals(connection, fromMint, setFromMintDecimals, log);
|
|
|
|
}, [connection, fromMint, log]);
|
|
|
|
|
|
|
|
//Retrieve to mint information when fromMint changes
|
|
|
|
useEffect(() => {
|
|
|
|
getDecimals(connection, toMint, setToMintDecimals, log);
|
|
|
|
}, [connection, toMint, log]);
|
|
|
|
|
|
|
|
//Retrieve to mint information when shareMint changes
|
|
|
|
useEffect(() => {
|
|
|
|
// TODO: cancellable
|
|
|
|
if (shareMintAddress) {
|
|
|
|
getDecimals(connection, shareMintAddress, setShareMintDecimals, log);
|
|
|
|
} else {
|
|
|
|
setShareMintDecimals(undefined);
|
|
|
|
}
|
|
|
|
}, [connection, shareMintAddress, log]);
|
|
|
|
|
|
|
|
//Retrieve from custody balance when fromCustodyAccount changes
|
|
|
|
useEffect(() => {
|
|
|
|
// TODO: cancellable
|
|
|
|
if (fromCustodyAddress) {
|
|
|
|
getBalance(connection, fromCustodyAddress, setFromCustodyBalance, log);
|
|
|
|
} else {
|
|
|
|
setFromCustodyBalance(undefined);
|
|
|
|
}
|
|
|
|
}, [connection, fromCustodyAddress, log]);
|
|
|
|
|
|
|
|
//Retrieve from custody balance when toCustodyAccount changes
|
|
|
|
useEffect(() => {
|
|
|
|
// TODO: cancellable
|
|
|
|
if (toCustodyAddress) {
|
|
|
|
getBalance(connection, toCustodyAddress, setToCustodyBalance, log);
|
|
|
|
} else {
|
|
|
|
setFromCustodyBalance(undefined);
|
|
|
|
}
|
|
|
|
}, [connection, toCustodyAddress, log]);
|
|
|
|
|
2021-09-16 07:49:46 -07:00
|
|
|
useEffect(() => {
|
|
|
|
if (fromTokenAccountExists) {
|
|
|
|
getBalance(connection, fromTokenAccount, setFromTokenAccountBalance, log);
|
|
|
|
}
|
|
|
|
}, [connection, fromTokenAccount, fromTokenAccountExists, log]);
|
|
|
|
useEffect(() => {
|
|
|
|
if (toTokenAccountExists) {
|
|
|
|
getBalance(connection, toTokenAccount, setToTokenAccountBalance, log);
|
|
|
|
}
|
|
|
|
}, [connection, toTokenAccount, toTokenAccountExists, log]);
|
|
|
|
useEffect(() => {
|
|
|
|
if (shareTokenAccountExists) {
|
|
|
|
getBalance(
|
|
|
|
connection,
|
|
|
|
shareTokenAccount,
|
|
|
|
setShareTokenAccountBalance,
|
|
|
|
log
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [connection, shareTokenAccount, shareTokenAccountExists, log]);
|
|
|
|
|
2021-09-12 18:29:11 -07:00
|
|
|
//Retrieve pool address on selectedTokens change
|
|
|
|
useEffect(() => {
|
|
|
|
if (toMint && fromMint) {
|
|
|
|
setPoolAddress("");
|
2021-09-13 10:17:45 -07:00
|
|
|
setPoolExists(undefined);
|
|
|
|
setPoolAccountInfo(undefined);
|
|
|
|
setParsedPoolData(undefined);
|
2021-09-12 18:29:11 -07:00
|
|
|
getPoolAddress(MIGRATION_PROGRAM_ADDRESS, fromMint, toMint).then(
|
|
|
|
(result) => {
|
|
|
|
const key = new PublicKey(result).toString();
|
2021-09-13 08:13:12 -07:00
|
|
|
log("Calculated the pool address at: " + key);
|
2021-09-12 18:29:11 -07:00
|
|
|
setPoolAddress(key);
|
|
|
|
},
|
2021-09-16 07:49:46 -07:00
|
|
|
(error) => log("Could not calculate pool address.", "error")
|
2021-09-12 18:29:11 -07:00
|
|
|
);
|
|
|
|
}
|
2021-09-13 08:13:12 -07:00
|
|
|
}, [log, toMint, fromMint, setPoolAddress]);
|
2021-09-12 18:29:11 -07:00
|
|
|
|
|
|
|
//Retrieve the poolAccount every time the pool address changes.
|
|
|
|
useEffect(() => {
|
2021-09-13 10:17:45 -07:00
|
|
|
console.log(
|
|
|
|
"fired the poolAccountInfo effect",
|
|
|
|
poolAddress,
|
|
|
|
poolAccountInfo
|
|
|
|
);
|
2021-09-13 08:13:12 -07:00
|
|
|
if (poolAddress && poolAccountInfo === undefined) {
|
2021-09-12 22:35:00 -07:00
|
|
|
setPoolExists(undefined);
|
2021-09-12 18:29:11 -07:00
|
|
|
try {
|
|
|
|
getMultipleAccounts(
|
|
|
|
connection,
|
|
|
|
[new PublicKey(poolAddress)],
|
2021-09-13 10:17:45 -07:00
|
|
|
"confirmed"
|
2021-09-12 18:29:11 -07:00
|
|
|
).then((result) => {
|
|
|
|
if (result.length && result[0] !== null) {
|
|
|
|
setPoolAccountInfo(result[0]);
|
2021-09-12 22:35:00 -07:00
|
|
|
parsePool(result[0].data).then(
|
|
|
|
(parsed) => setParsedPoolData(parsed),
|
|
|
|
(error) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Failed to parse the pool data.", "error");
|
2021-09-12 22:35:00 -07:00
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
);
|
2021-09-12 18:29:11 -07:00
|
|
|
setPoolExists(true);
|
2021-09-13 08:13:12 -07:00
|
|
|
log("Successfully found account info for the pool.");
|
2021-09-12 18:29:11 -07:00
|
|
|
} else if (result.length && result[0] === null) {
|
2021-09-13 08:13:12 -07:00
|
|
|
log("Confirmed that the pool does not exist.");
|
2021-09-12 18:29:11 -07:00
|
|
|
setPoolExists(false);
|
2021-09-13 08:13:12 -07:00
|
|
|
setPoolAccountInfo(null);
|
2021-09-12 18:29:11 -07:00
|
|
|
} else {
|
2021-09-13 08:13:12 -07:00
|
|
|
log(
|
2021-09-16 07:49:46 -07:00
|
|
|
"unexpected error in fetching pool address. Please reload and try again",
|
|
|
|
"error"
|
2021-09-12 18:29:11 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch (e) {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not fetch pool address", "error");
|
2021-09-12 18:29:11 -07:00
|
|
|
}
|
|
|
|
}
|
2021-09-13 08:13:12 -07:00
|
|
|
}, [connection, log, poolAddress, poolAccountInfo]);
|
2021-09-12 18:29:11 -07:00
|
|
|
|
2021-09-12 22:35:00 -07:00
|
|
|
//Set all the addresses which derive from poolAddress
|
2021-09-12 18:29:11 -07:00
|
|
|
useEffect(() => {
|
|
|
|
getAuthorityAddress(MIGRATION_PROGRAM_ADDRESS).then((result: any) =>
|
2021-09-12 22:35:00 -07:00
|
|
|
setAuthorityAddress(new PublicKey(result).toString())
|
2021-09-12 18:29:11 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
getToCustodyAddress(MIGRATION_PROGRAM_ADDRESS, poolAddress).then(
|
2021-09-12 22:35:00 -07:00
|
|
|
(result: any) => setToCustodyAddress(new PublicKey(result).toString())
|
2021-09-12 18:29:11 -07:00
|
|
|
);
|
|
|
|
getFromCustodyAddress(MIGRATION_PROGRAM_ADDRESS, poolAddress).then(
|
2021-09-12 22:35:00 -07:00
|
|
|
(result: any) => setFromCustodyAddress(new PublicKey(result).toString())
|
2021-09-12 18:29:11 -07:00
|
|
|
);
|
|
|
|
getShareMintAddress(MIGRATION_PROGRAM_ADDRESS, poolAddress).then(
|
2021-09-12 22:35:00 -07:00
|
|
|
(result: any) => setShareMintAddress(new PublicKey(result).toString())
|
2021-09-12 18:29:11 -07:00
|
|
|
);
|
|
|
|
}, [poolAddress]);
|
2021-09-12 22:35:00 -07:00
|
|
|
|
|
|
|
//Set the associated token accounts when the designated mint changes
|
|
|
|
useEffect(() => {
|
|
|
|
if (wallet?.publicKey && fromMint) {
|
|
|
|
Token.getAssociatedTokenAddress(
|
|
|
|
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
|
|
TOKEN_PROGRAM_ID,
|
|
|
|
new PublicKey(fromMint),
|
|
|
|
wallet?.publicKey || new PublicKey([])
|
|
|
|
).then(
|
|
|
|
(result) => {
|
|
|
|
setFromTokenAccount(result.toString());
|
|
|
|
},
|
|
|
|
(error) => {}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [fromMint, wallet?.publicKey]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (wallet?.publicKey && toMint) {
|
|
|
|
Token.getAssociatedTokenAddress(
|
|
|
|
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
|
|
TOKEN_PROGRAM_ID,
|
|
|
|
new PublicKey(toMint),
|
|
|
|
wallet?.publicKey || new PublicKey([])
|
|
|
|
).then(
|
|
|
|
(result) => {
|
|
|
|
setToTokenAccount(result.toString());
|
|
|
|
},
|
|
|
|
(error) => {}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [toMint, wallet?.publicKey]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (wallet?.publicKey && shareMintAddress) {
|
|
|
|
Token.getAssociatedTokenAddress(
|
|
|
|
ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
|
|
TOKEN_PROGRAM_ID,
|
|
|
|
new PublicKey(shareMintAddress || ""),
|
|
|
|
wallet?.publicKey || new PublicKey([])
|
|
|
|
).then(
|
|
|
|
(result) => {
|
|
|
|
setShareTokenAccount(result.toString());
|
|
|
|
},
|
|
|
|
(error) => {}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [shareMintAddress, wallet?.publicKey]);
|
2021-09-12 18:29:11 -07:00
|
|
|
/*
|
|
|
|
End Effects!
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Actions:
|
|
|
|
|
|
|
|
These are generally onClick actions which the user can perform. They read things off the state, do something,
|
|
|
|
and then potentially update something on the state.
|
|
|
|
|
|
|
|
*/
|
2021-09-16 07:49:46 -07:00
|
|
|
const refreshPoolBalances = useCallback(() => {
|
|
|
|
getBalance(connection, fromCustodyAddress, setFromCustodyBalance, log);
|
|
|
|
getBalance(connection, toCustodyAddress, setToCustodyBalance, log);
|
|
|
|
}, [connection, fromCustodyAddress, toCustodyAddress, log]);
|
|
|
|
|
|
|
|
const refreshWalletBalances = useCallback(() => {
|
|
|
|
if (fromTokenAccountExists) {
|
|
|
|
getBalance(connection, fromTokenAccount, setFromTokenAccountBalance, log);
|
|
|
|
}
|
|
|
|
if (toTokenAccountExists) {
|
|
|
|
getBalance(connection, toTokenAccount, setToTokenAccountBalance, log);
|
|
|
|
}
|
|
|
|
if (shareTokenAccountExists) {
|
|
|
|
getBalance(
|
|
|
|
connection,
|
|
|
|
shareTokenAccount,
|
|
|
|
setShareTokenAccountBalance,
|
|
|
|
log
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}, [
|
|
|
|
connection,
|
|
|
|
fromTokenAccount,
|
|
|
|
toTokenAccount,
|
|
|
|
shareTokenAccount,
|
|
|
|
fromTokenAccountExists,
|
|
|
|
toTokenAccountExists,
|
|
|
|
shareTokenAccountExists,
|
|
|
|
log,
|
|
|
|
]);
|
|
|
|
|
2021-09-13 08:13:12 -07:00
|
|
|
const createPool = useCallback(async () => {
|
2021-09-12 22:35:00 -07:00
|
|
|
console.log(
|
|
|
|
"createPool with these args",
|
|
|
|
connection,
|
|
|
|
wallet?.publicKey?.toString(),
|
|
|
|
MIGRATION_PROGRAM_ADDRESS,
|
|
|
|
fromMint,
|
|
|
|
toMint
|
|
|
|
);
|
2021-09-12 18:29:11 -07:00
|
|
|
try {
|
|
|
|
const instruction = await createPoolAccount(
|
|
|
|
connection,
|
|
|
|
wallet?.publicKey?.toString() || "",
|
|
|
|
MIGRATION_PROGRAM_ADDRESS,
|
|
|
|
wallet?.publicKey?.toString() || "",
|
|
|
|
fromMint,
|
|
|
|
toMint
|
|
|
|
);
|
2021-09-13 10:17:45 -07:00
|
|
|
setCreatePoolIsProcessing(true);
|
2021-09-12 18:29:11 -07:00
|
|
|
signSendAndConfirm(wallet, connection, instruction).then(
|
|
|
|
(transaction: any) => {
|
2021-09-12 22:35:00 -07:00
|
|
|
setPoolExists(undefined); //Set these to null to force a fetch on them
|
|
|
|
setPoolAccountInfo(undefined);
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Successfully created the pool.", "success");
|
2021-09-13 10:17:45 -07:00
|
|
|
setCreatePoolIsProcessing(false);
|
2021-09-12 18:29:11 -07:00
|
|
|
},
|
|
|
|
(error) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not create the pool", "error");
|
2021-09-12 18:29:11 -07:00
|
|
|
console.error(error);
|
2021-09-13 10:17:45 -07:00
|
|
|
setCreatePoolIsProcessing(false);
|
2021-09-12 18:29:11 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
} catch (e) {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Failed to create the pool.", "error");
|
2021-09-12 18:29:11 -07:00
|
|
|
console.error(e);
|
2021-09-13 10:17:45 -07:00
|
|
|
setCreatePoolIsProcessing(false);
|
2021-09-12 18:29:11 -07:00
|
|
|
}
|
2021-09-13 08:13:12 -07:00
|
|
|
}, [connection, fromMint, toMint, wallet, log]);
|
2021-09-12 22:35:00 -07:00
|
|
|
|
2021-09-13 08:13:12 -07:00
|
|
|
const addLiquidity = useCallback(async () => {
|
2021-09-12 22:35:00 -07:00
|
|
|
try {
|
|
|
|
const instruction = await addLiquidityTx(
|
|
|
|
connection,
|
|
|
|
wallet?.publicKey?.toString() || "",
|
|
|
|
MIGRATION_PROGRAM_ADDRESS,
|
|
|
|
fromMint,
|
|
|
|
toMint,
|
|
|
|
toTokenAccount || "",
|
|
|
|
shareTokenAccount || "",
|
2021-09-13 08:13:12 -07:00
|
|
|
parseUnits(liquidityAmount, toMintDecimals).toBigInt()
|
2021-09-12 22:35:00 -07:00
|
|
|
);
|
2021-09-13 10:17:45 -07:00
|
|
|
setLiquidityIsProcessing(true);
|
2021-09-12 22:35:00 -07:00
|
|
|
signSendAndConfirm(wallet, connection, instruction).then(
|
|
|
|
(transaction: any) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Successfully added liquidity to the pool.", "success");
|
2021-09-13 08:13:12 -07:00
|
|
|
getBalance(
|
|
|
|
connection,
|
|
|
|
fromCustodyAddress,
|
|
|
|
setFromCustodyBalance,
|
|
|
|
log
|
|
|
|
);
|
|
|
|
getBalance(connection, toCustodyAddress, setToCustodyBalance, log);
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances();
|
2021-09-13 10:17:45 -07:00
|
|
|
setLiquidityIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
},
|
|
|
|
(error) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the addLiquidity transaction", "error");
|
2021-09-12 22:35:00 -07:00
|
|
|
console.error(error);
|
2021-09-13 10:17:45 -07:00
|
|
|
setLiquidityIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
} catch (e) {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the addLiquidity transaction", "error");
|
2021-09-12 22:35:00 -07:00
|
|
|
console.error(e);
|
2021-09-13 10:17:45 -07:00
|
|
|
setLiquidityIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
}
|
2021-09-13 08:13:12 -07:00
|
|
|
}, [
|
|
|
|
connection,
|
|
|
|
fromMint,
|
|
|
|
liquidityAmount,
|
|
|
|
shareTokenAccount,
|
|
|
|
toMint,
|
|
|
|
toTokenAccount,
|
|
|
|
wallet,
|
|
|
|
log,
|
|
|
|
toMintDecimals,
|
|
|
|
fromCustodyAddress,
|
|
|
|
toCustodyAddress,
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances,
|
2021-09-13 08:13:12 -07:00
|
|
|
]);
|
|
|
|
|
2021-09-13 12:10:34 -07:00
|
|
|
const removeLiquidity = useCallback(async () => {
|
|
|
|
try {
|
|
|
|
const instruction = await removeLiquidityTx(
|
|
|
|
connection,
|
|
|
|
wallet?.publicKey?.toString() || "",
|
|
|
|
MIGRATION_PROGRAM_ADDRESS,
|
|
|
|
fromMint,
|
|
|
|
toMint,
|
|
|
|
toTokenAccount || "",
|
|
|
|
shareTokenAccount || "",
|
|
|
|
parseUnits(removeLiquidityAmount, shareMintDecimals).toBigInt()
|
|
|
|
);
|
|
|
|
setRemoveLiquidityIsProcessing(true);
|
|
|
|
signSendAndConfirm(wallet, connection, instruction).then(
|
|
|
|
(transaction: any) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Successfully removed liquidity to the pool.", "success");
|
2021-09-13 12:10:34 -07:00
|
|
|
getBalance(
|
|
|
|
connection,
|
|
|
|
fromCustodyAddress,
|
|
|
|
setFromCustodyBalance,
|
|
|
|
log
|
|
|
|
);
|
|
|
|
getBalance(connection, toCustodyAddress, setToCustodyBalance, log);
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances();
|
2021-09-13 12:10:34 -07:00
|
|
|
setRemoveLiquidityIsProcessing(false);
|
|
|
|
},
|
|
|
|
(error) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the removeLiquidity transaction", "error");
|
2021-09-13 12:10:34 -07:00
|
|
|
console.error(error);
|
|
|
|
setRemoveLiquidityIsProcessing(false);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
} catch (e) {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the removeLiquidity transaction", "error");
|
2021-09-13 12:10:34 -07:00
|
|
|
console.error(e);
|
|
|
|
setRemoveLiquidityIsProcessing(false);
|
|
|
|
}
|
|
|
|
}, [
|
|
|
|
connection,
|
|
|
|
fromMint,
|
|
|
|
removeLiquidityAmount,
|
|
|
|
shareTokenAccount,
|
|
|
|
toMint,
|
|
|
|
toTokenAccount,
|
|
|
|
wallet,
|
|
|
|
log,
|
|
|
|
shareMintDecimals,
|
|
|
|
fromCustodyAddress,
|
|
|
|
toCustodyAddress,
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances,
|
2021-09-13 12:10:34 -07:00
|
|
|
]);
|
|
|
|
|
2021-09-13 08:13:12 -07:00
|
|
|
const migrateTokens = useCallback(async () => {
|
2021-09-12 22:35:00 -07:00
|
|
|
try {
|
|
|
|
const instruction = await migrateTokensTx(
|
|
|
|
connection,
|
|
|
|
wallet?.publicKey?.toString() || "",
|
|
|
|
MIGRATION_PROGRAM_ADDRESS,
|
|
|
|
fromMint,
|
|
|
|
toMint,
|
|
|
|
fromTokenAccount || "",
|
|
|
|
toTokenAccount || "",
|
2021-09-13 08:13:12 -07:00
|
|
|
parseUnits(migrationAmount, fromMintDecimals).toBigInt()
|
2021-09-12 22:35:00 -07:00
|
|
|
);
|
2021-09-13 10:17:45 -07:00
|
|
|
setMigrationIsProcessing(true);
|
2021-09-12 22:35:00 -07:00
|
|
|
signSendAndConfirm(wallet, connection, instruction).then(
|
|
|
|
(transaction: any) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Successfully migrated the tokens.", "success");
|
2021-09-13 08:13:12 -07:00
|
|
|
getBalance(
|
|
|
|
connection,
|
|
|
|
fromCustodyAddress,
|
|
|
|
setFromCustodyBalance,
|
|
|
|
log
|
|
|
|
);
|
|
|
|
getBalance(connection, toCustodyAddress, setToCustodyBalance, log);
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances();
|
2021-09-13 10:17:45 -07:00
|
|
|
setMigrationIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
},
|
|
|
|
(error) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the migrateTokens transaction.", "error");
|
2021-09-12 22:35:00 -07:00
|
|
|
console.error(error);
|
2021-09-13 10:17:45 -07:00
|
|
|
setMigrationIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
} catch (e) {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the migrateTokens transaction.", "error");
|
2021-09-12 22:35:00 -07:00
|
|
|
console.error(e);
|
2021-09-13 10:17:45 -07:00
|
|
|
setMigrationIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
}
|
2021-09-13 08:13:12 -07:00
|
|
|
}, [
|
|
|
|
connection,
|
|
|
|
fromMint,
|
|
|
|
fromTokenAccount,
|
|
|
|
log,
|
|
|
|
migrationAmount,
|
|
|
|
toMint,
|
|
|
|
toTokenAccount,
|
|
|
|
wallet,
|
|
|
|
fromMintDecimals,
|
|
|
|
fromCustodyAddress,
|
|
|
|
toCustodyAddress,
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances,
|
2021-09-13 08:13:12 -07:00
|
|
|
]);
|
|
|
|
|
|
|
|
const redeemShares = useCallback(async () => {
|
2021-09-12 22:35:00 -07:00
|
|
|
try {
|
|
|
|
const instruction = await claimSharesTx(
|
|
|
|
connection,
|
|
|
|
wallet?.publicKey?.toString() || "",
|
|
|
|
MIGRATION_PROGRAM_ADDRESS,
|
|
|
|
fromMint,
|
|
|
|
toMint,
|
2021-09-13 08:13:12 -07:00
|
|
|
fromTokenAccount || "",
|
2021-09-12 22:35:00 -07:00
|
|
|
shareTokenAccount || "",
|
2021-09-13 08:13:12 -07:00
|
|
|
parseUnits(redeemAmount, shareMintDecimals).toBigInt()
|
2021-09-12 22:35:00 -07:00
|
|
|
);
|
2021-09-13 10:17:45 -07:00
|
|
|
setRedeemIsProcessing(true);
|
2021-09-12 22:35:00 -07:00
|
|
|
signSendAndConfirm(wallet, connection, instruction).then(
|
|
|
|
(transaction: any) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Successfully redeemed the shares.", "success");
|
2021-09-13 08:13:12 -07:00
|
|
|
getBalance(
|
|
|
|
connection,
|
|
|
|
fromCustodyAddress,
|
|
|
|
setFromCustodyBalance,
|
|
|
|
log
|
|
|
|
);
|
|
|
|
getBalance(connection, toCustodyAddress, setToCustodyBalance, log);
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances();
|
2021-09-13 10:17:45 -07:00
|
|
|
setRedeemIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
},
|
|
|
|
(error) => {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the claimShares transaction.", "error");
|
2021-09-12 22:35:00 -07:00
|
|
|
console.error(error);
|
2021-09-13 10:17:45 -07:00
|
|
|
setRedeemIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
}
|
|
|
|
);
|
|
|
|
} catch (e) {
|
2021-09-16 07:49:46 -07:00
|
|
|
log("Could not complete the claimShares transaction.", "error");
|
2021-09-12 22:35:00 -07:00
|
|
|
console.error(e);
|
2021-09-13 10:17:45 -07:00
|
|
|
setRedeemIsProcessing(false);
|
2021-09-12 22:35:00 -07:00
|
|
|
}
|
2021-09-13 08:13:12 -07:00
|
|
|
}, [
|
|
|
|
connection,
|
|
|
|
fromMint,
|
|
|
|
log,
|
|
|
|
redeemAmount,
|
|
|
|
shareTokenAccount,
|
|
|
|
toMint,
|
|
|
|
fromTokenAccount,
|
|
|
|
wallet,
|
|
|
|
shareMintDecimals,
|
|
|
|
fromCustodyAddress,
|
|
|
|
toCustodyAddress,
|
2021-09-16 07:49:46 -07:00
|
|
|
refreshWalletBalances,
|
2021-09-13 08:13:12 -07:00
|
|
|
]);
|
2021-09-12 18:29:11 -07:00
|
|
|
/*
|
|
|
|
End actions!
|
|
|
|
*/
|
|
|
|
|
|
|
|
const toAndFromSelector = (
|
|
|
|
<>
|
|
|
|
<Typography>
|
|
|
|
Please enter the mint addresses for the 'To' and 'From' tokens you're
|
|
|
|
interested in.
|
|
|
|
</Typography>
|
|
|
|
<TextField
|
2021-09-13 10:17:45 -07:00
|
|
|
value={fromMintHolder}
|
|
|
|
onChange={(event) => setFromMintHolder(event.target.value)}
|
2021-09-12 18:29:11 -07:00
|
|
|
label={"From Token"}
|
|
|
|
fullWidth
|
|
|
|
style={{ display: "block" }}
|
|
|
|
></TextField>
|
|
|
|
<TextField
|
2021-09-13 10:17:45 -07:00
|
|
|
value={toMintHolder}
|
|
|
|
onChange={(event) => setToMintHolder(event.target.value)}
|
2021-09-12 18:29:11 -07:00
|
|
|
label={"To Token"}
|
|
|
|
fullWidth
|
|
|
|
style={{ display: "block" }}
|
|
|
|
></TextField>
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
|
|
|
const createPoolButton = (
|
|
|
|
<div>
|
|
|
|
<Button
|
|
|
|
variant="contained"
|
|
|
|
onClick={() => createPool()}
|
2021-09-13 10:17:45 -07:00
|
|
|
disabled={poolExists || createPoolIsProcessing}
|
2021-09-12 18:29:11 -07:00
|
|
|
>
|
2021-09-12 22:35:00 -07:00
|
|
|
{poolExists
|
|
|
|
? "This Pool is instantiated."
|
|
|
|
: "This pool has not been instantiated! Click here to create it."}
|
2021-09-12 18:29:11 -07:00
|
|
|
</Button>
|
2021-09-13 10:17:45 -07:00
|
|
|
{createPoolIsProcessing ? <CircularProgress /> : null}
|
2021-09-12 18:29:11 -07:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
|
2021-09-16 07:49:46 -07:00
|
|
|
const addLiquidityIsReady =
|
|
|
|
poolExists &&
|
|
|
|
shareTokenAccountExists &&
|
|
|
|
toTokenAccountBalance &&
|
|
|
|
liquidityAmount &&
|
|
|
|
toMintDecimals &&
|
|
|
|
compareWithDecimalOffset(
|
|
|
|
liquidityAmount,
|
|
|
|
toMintDecimals,
|
|
|
|
toTokenAccountBalance,
|
|
|
|
toMintDecimals
|
|
|
|
) !== 1;
|
2021-09-12 22:35:00 -07:00
|
|
|
const addLiquidityUI = (
|
2021-09-12 18:29:11 -07:00
|
|
|
<>
|
2021-09-12 22:35:00 -07:00
|
|
|
<Typography variant="h4">Add Liquidity</Typography>
|
|
|
|
<Typography variant="body1">
|
|
|
|
This will remove 'To' tokens from your wallet, and give you an equal
|
|
|
|
number of 'Share' tokens.
|
2021-09-12 18:29:11 -07:00
|
|
|
</Typography>
|
|
|
|
<TextField
|
2021-09-12 22:35:00 -07:00
|
|
|
value={liquidityAmount}
|
|
|
|
type="number"
|
|
|
|
onChange={(event) => setLiquidityAmount(event.target.value)}
|
|
|
|
label={"Amount to add"}
|
|
|
|
></TextField>
|
2021-09-13 10:17:45 -07:00
|
|
|
<Button
|
|
|
|
variant="contained"
|
|
|
|
onClick={addLiquidity}
|
2021-09-16 07:49:46 -07:00
|
|
|
disabled={liquidityIsProcessing || !addLiquidityIsReady}
|
2021-09-13 10:17:45 -07:00
|
|
|
>
|
2021-09-12 22:35:00 -07:00
|
|
|
Add Liquidity
|
|
|
|
</Button>
|
2021-09-13 10:17:45 -07:00
|
|
|
{liquidityIsProcessing ? <CircularProgress /> : null}
|
2021-09-12 22:35:00 -07:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
2021-09-16 07:49:46 -07:00
|
|
|
const removeLiquidityIsReady =
|
|
|
|
poolExists &&
|
|
|
|
shareTokenAccountBalance &&
|
|
|
|
toCustodyBalance &&
|
|
|
|
removeLiquidityAmount &&
|
|
|
|
toMintDecimals &&
|
|
|
|
shareMintDecimals &&
|
|
|
|
compareWithDecimalOffset(
|
|
|
|
removeLiquidityAmount,
|
|
|
|
shareMintDecimals,
|
|
|
|
toCustodyBalance,
|
|
|
|
toMintDecimals
|
|
|
|
) !== 1;
|
2021-09-13 12:10:34 -07:00
|
|
|
const removeLiquidityUI = (
|
|
|
|
<>
|
|
|
|
<Typography variant="h4">Remove Liquidity</Typography>
|
|
|
|
<Typography variant="body1">
|
|
|
|
This will remove 'Share' tokens from your wallet, and give you an equal
|
|
|
|
number of 'To' tokens.
|
|
|
|
</Typography>
|
|
|
|
<TextField
|
|
|
|
value={removeLiquidityAmount}
|
|
|
|
type="number"
|
|
|
|
onChange={(event) => setRemoveLiquidityAmount(event.target.value)}
|
|
|
|
label={"Amount to remove"}
|
|
|
|
></TextField>
|
|
|
|
<Button
|
|
|
|
variant="contained"
|
|
|
|
onClick={removeLiquidity}
|
2021-09-16 07:49:46 -07:00
|
|
|
disabled={removeLiquidityIsProcessing || !removeLiquidityIsReady}
|
2021-09-13 12:10:34 -07:00
|
|
|
>
|
|
|
|
Remove Liquidity
|
|
|
|
</Button>
|
|
|
|
{removeLiquidityIsProcessing ? <CircularProgress /> : null}
|
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
2021-09-16 07:49:46 -07:00
|
|
|
const migrateIsReady =
|
|
|
|
poolExists &&
|
|
|
|
fromTokenAccountBalance &&
|
|
|
|
toCustodyBalance &&
|
|
|
|
migrationAmount &&
|
|
|
|
toMintDecimals &&
|
|
|
|
fromMintDecimals &&
|
|
|
|
compareWithDecimalOffset(
|
|
|
|
migrationAmount,
|
|
|
|
fromMintDecimals,
|
|
|
|
toCustodyBalance,
|
|
|
|
toMintDecimals
|
|
|
|
) !== 1;
|
2021-09-12 22:35:00 -07:00
|
|
|
const migrateTokensUI = (
|
|
|
|
<>
|
|
|
|
<Typography variant="h4">Migrate Tokens</Typography>
|
|
|
|
<Typography variant="body1">
|
|
|
|
This will remove 'From' tokens from your wallet, and give you an equal
|
|
|
|
number of 'To' tokens.
|
|
|
|
</Typography>
|
|
|
|
<TextField
|
|
|
|
value={migrationAmount}
|
|
|
|
type="number"
|
|
|
|
onChange={(event) => setMigrationAmount(event.target.value)}
|
2021-09-13 08:13:12 -07:00
|
|
|
label={"Amount to migrate"}
|
2021-09-12 22:35:00 -07:00
|
|
|
></TextField>
|
2021-09-13 10:17:45 -07:00
|
|
|
<Button
|
|
|
|
variant="contained"
|
|
|
|
onClick={migrateTokens}
|
2021-09-16 07:49:46 -07:00
|
|
|
disabled={migrationIsProcessing || !migrateIsReady}
|
2021-09-13 10:17:45 -07:00
|
|
|
>
|
2021-09-12 22:35:00 -07:00
|
|
|
Migrate Tokens
|
|
|
|
</Button>
|
2021-09-13 10:17:45 -07:00
|
|
|
{migrationIsProcessing ? <CircularProgress /> : null}
|
2021-09-12 22:35:00 -07:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
2021-09-16 07:49:46 -07:00
|
|
|
const redeemIsReady =
|
|
|
|
poolExists &&
|
|
|
|
fromCustodyBalance &&
|
|
|
|
shareTokenAccountBalance &&
|
|
|
|
redeemAmount &&
|
|
|
|
shareMintDecimals &&
|
|
|
|
fromMintDecimals &&
|
|
|
|
compareWithDecimalOffset(
|
|
|
|
redeemAmount,
|
|
|
|
shareMintDecimals,
|
|
|
|
fromCustodyBalance,
|
|
|
|
fromMintDecimals
|
|
|
|
) !== 1;
|
2021-09-12 22:35:00 -07:00
|
|
|
const redeemSharesUI = (
|
|
|
|
<>
|
|
|
|
<Typography variant="h4">Redeem Shares</Typography>
|
|
|
|
<Typography variant="body1">
|
|
|
|
This will remove 'Share' tokens from your wallet, and give you an equal
|
|
|
|
number of 'From' tokens.
|
|
|
|
</Typography>
|
|
|
|
<TextField
|
|
|
|
type="number"
|
|
|
|
value={redeemAmount}
|
|
|
|
onChange={(event) => setRedeemAmount(event.target.value)}
|
2021-09-13 08:13:12 -07:00
|
|
|
label={"Amount to redeem"}
|
2021-09-12 18:29:11 -07:00
|
|
|
></TextField>
|
2021-09-13 10:17:45 -07:00
|
|
|
<Button
|
|
|
|
variant="contained"
|
|
|
|
onClick={redeemShares}
|
2021-09-16 07:49:46 -07:00
|
|
|
disabled={redeemIsProcessing || !redeemIsReady}
|
2021-09-13 10:17:45 -07:00
|
|
|
>
|
2021-09-12 22:35:00 -07:00
|
|
|
Redeem Shares
|
|
|
|
</Button>
|
2021-09-13 10:17:45 -07:00
|
|
|
{redeemIsProcessing ? <CircularProgress /> : null}
|
2021-09-12 18:29:11 -07:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
2021-09-12 22:35:00 -07:00
|
|
|
const relevantTokenAccounts = (
|
|
|
|
<>
|
|
|
|
<Typography variant="h4">Your Relevant Token Accounts: </Typography>
|
|
|
|
<Typography variant="body1">
|
|
|
|
{"'From' SPL Token Account: " + fromTokenAccount}
|
|
|
|
</Typography>
|
|
|
|
<SolanaCreateAssociatedAddress
|
|
|
|
mintAddress={fromMint}
|
|
|
|
readableTargetAddress={fromTokenAccount}
|
|
|
|
associatedAccountExists={fromTokenAccountExists}
|
|
|
|
setAssociatedAccountExists={setFromTokenAccountExists}
|
|
|
|
/>
|
2021-09-16 07:49:46 -07:00
|
|
|
{fromTokenAccountExists ? (
|
|
|
|
<Typography>Balance: {fromTokenAccountBalance}</Typography>
|
|
|
|
) : null}
|
|
|
|
<div className={classes.spacer} />
|
2021-09-12 22:35:00 -07:00
|
|
|
<Typography variant="body1">
|
|
|
|
{"'To' SPL Token Account: " + toTokenAccount}
|
|
|
|
</Typography>
|
|
|
|
<SolanaCreateAssociatedAddress
|
|
|
|
mintAddress={toMint}
|
|
|
|
readableTargetAddress={toTokenAccount}
|
|
|
|
associatedAccountExists={toTokenAccountExists}
|
|
|
|
setAssociatedAccountExists={setToTokenAccountExists}
|
|
|
|
/>
|
2021-09-16 07:49:46 -07:00
|
|
|
{toTokenAccountExists ? (
|
|
|
|
<Typography>Balance: {toTokenAccountBalance}</Typography>
|
|
|
|
) : null}
|
|
|
|
<div className={classes.spacer} />
|
2021-09-12 22:35:00 -07:00
|
|
|
<Typography variant="body1">
|
|
|
|
{"Share SPL Token Account: " + shareTokenAccount}
|
|
|
|
</Typography>
|
|
|
|
<SolanaCreateAssociatedAddress
|
|
|
|
mintAddress={shareMintAddress}
|
|
|
|
readableTargetAddress={shareTokenAccount}
|
|
|
|
associatedAccountExists={shareTokenAccountExists}
|
|
|
|
setAssociatedAccountExists={setShareTokenAccountExists}
|
|
|
|
/>
|
2021-09-16 07:49:46 -07:00
|
|
|
{shareTokenAccountExists ? (
|
|
|
|
<Typography>Balance: {shareTokenAccountBalance}</Typography>
|
|
|
|
) : null}
|
|
|
|
<div className={classes.spacer} />
|
|
|
|
<Button variant="outlined" onClick={refreshWalletBalances}>
|
|
|
|
Refresh Account Balances
|
|
|
|
</Button>
|
2021-09-12 22:35:00 -07:00
|
|
|
</>
|
|
|
|
);
|
|
|
|
|
|
|
|
const poolInfo = (
|
|
|
|
<div>
|
|
|
|
{
|
|
|
|
<Button
|
|
|
|
variant="outlined"
|
|
|
|
onClick={() => setToggleAllData(!toggleAllData)}
|
|
|
|
>
|
|
|
|
{toggleAllData ? "Hide Verbose Pool Data" : "Show Verbose Pool Data"}
|
|
|
|
</Button>
|
|
|
|
}
|
|
|
|
{toggleAllData ? (
|
|
|
|
<>
|
|
|
|
<Typography>{"Pool Address: " + poolAddress}</Typography>
|
|
|
|
<Typography>{"Pool has been instantiated: " + poolExists}</Typography>
|
|
|
|
<Typography>{"'From' Token Mint Address: " + fromMint}</Typography>
|
|
|
|
<Typography>{"'To' Token Mint Address: " + toMint}</Typography>
|
|
|
|
<Typography>{"Share Token Mint: " + shareMintAddress}</Typography>
|
|
|
|
<Typography>{"Authority Address: " + authorityAddress}</Typography>
|
|
|
|
<Typography>
|
|
|
|
{"'From' Custody Mint: " + fromCustodyAddress}
|
|
|
|
</Typography>
|
|
|
|
<Typography>{"'To' Custody Mint: " + toCustodyAddress}</Typography>
|
|
|
|
<Typography>
|
|
|
|
{"Full Parsed Data for Pool: " + JSON.stringify(parsedPoolData)}
|
|
|
|
</Typography>
|
|
|
|
</>
|
|
|
|
) : null}
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
|
2021-09-12 18:29:11 -07:00
|
|
|
const mainContent = (
|
|
|
|
<>
|
|
|
|
{toAndFromSelector}
|
2021-09-12 22:35:00 -07:00
|
|
|
<Divider className={classes.divider} />
|
|
|
|
{poolInfo}
|
2021-09-12 18:29:11 -07:00
|
|
|
{createPoolButton}
|
2021-09-16 07:49:46 -07:00
|
|
|
<Divider className={classes.divider} />
|
|
|
|
{relevantTokenAccounts}
|
|
|
|
<Divider className={classes.divider} />
|
2021-09-13 08:13:12 -07:00
|
|
|
<Typography>'From' Balance In Pool</Typography>
|
|
|
|
<Typography>{fromCustodyBalance}</Typography>
|
|
|
|
<Typography>'To' Balance In Pool</Typography>
|
|
|
|
<Typography>{toCustodyBalance}</Typography>
|
2021-09-16 07:49:46 -07:00
|
|
|
<Button variant="outlined" onClick={refreshPoolBalances}>
|
|
|
|
Reload Balances
|
|
|
|
</Button>
|
2021-09-12 22:35:00 -07:00
|
|
|
<Divider className={classes.divider} />
|
|
|
|
{addLiquidityUI}
|
|
|
|
<Divider className={classes.divider} />
|
2021-09-13 12:10:34 -07:00
|
|
|
{removeLiquidityUI}
|
|
|
|
<Divider className={classes.divider} />
|
2021-09-12 22:35:00 -07:00
|
|
|
{redeemSharesUI}
|
|
|
|
<Divider className={classes.divider} />
|
|
|
|
{migrateTokensUI}
|
2021-09-12 18:29:11 -07:00
|
|
|
</>
|
2021-09-10 17:53:50 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
const content = !wallet.publicKey ? (
|
|
|
|
<Typography>Please connect your wallet.</Typography>
|
2021-09-12 22:35:00 -07:00
|
|
|
) : !poolAddress ? (
|
|
|
|
toAndFromSelector
|
2021-09-10 17:53:50 -07:00
|
|
|
) : (
|
2021-09-12 18:29:11 -07:00
|
|
|
mainContent
|
2021-09-10 17:53:50 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
return (
|
2021-09-15 09:17:07 -07:00
|
|
|
<>
|
|
|
|
<Container maxWidth="md" className={classes.rootContainer}>
|
|
|
|
<Paper className={classes.mainPaper}>
|
|
|
|
<SolanaWalletKey />
|
|
|
|
{content}
|
|
|
|
</Paper>
|
|
|
|
<LogWatcher />
|
|
|
|
</Container>
|
|
|
|
</>
|
2021-09-10 17:53:50 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
export default Main;
|