diff --git a/lp_ui/src/utils/consts.ts b/lp_ui/src/utils/consts.ts
index e4d683f6..ff13e7ea 100644
--- a/lp_ui/src/utils/consts.ts
+++ b/lp_ui/src/utils/consts.ts
@@ -1,11 +1,15 @@
import { clusterApiUrl } from "@solana/web3.js";
export const MIGRATION_PROGRAM_ADDRESS =
- process.env.REACT_APP_CLUSTER === "testnet"
+ process.env.REACT_APP_CLUSTER === "mainnet"
+ ? ""
+ : process.env.REACT_APP_CLUSTER === "testnet"
? ""
: "Ex9bCdVMSfx7EzB3pgSi2R4UHwJAXvTw18rBQm5YQ8gK";
export const SOLANA_URL =
- process.env.REACT_APP_CLUSTER === "testnet"
+ process.env.REACT_APP_CLUSTER === "mainnet"
+ ? clusterApiUrl("mainnet-beta")
+ : process.env.REACT_APP_CLUSTER === "testnet"
? clusterApiUrl("testnet")
: "http://localhost:8899";
diff --git a/lp_ui/src/views/Main.tsx b/lp_ui/src/views/Main.tsx
index 12230946..e0b02a84 100644
--- a/lp_ui/src/views/Main.tsx
+++ b/lp_ui/src/views/Main.tsx
@@ -1,6 +1,7 @@
import addLiquidityTx from "@certusone/wormhole-sdk/lib/migration/addLiquidity";
import getAuthorityAddress from "@certusone/wormhole-sdk/lib/migration/authorityAddress";
import claimSharesTx from "@certusone/wormhole-sdk/lib/migration/claimShares";
+import removeLiquidityTx from "@certusone/wormhole-sdk/lib/migration/removeLiquidity";
import createPoolAccount from "@certusone/wormhole-sdk/lib/migration/createPool";
import getFromCustodyAddress from "@certusone/wormhole-sdk/lib/migration/fromCustodyAddress";
import migrateTokensTx from "@certusone/wormhole-sdk/lib/migration/migrateTokens";
@@ -166,10 +167,13 @@ function Main() {
const [toggleAllData, setToggleAllData] = useState(false);
const [liquidityAmount, setLiquidityAmount] = useState("");
+ const [removeLiquidityAmount, setRemoveLiquidityAmount] = useState("");
const [migrationAmount, setMigrationAmount] = useState("");
const [redeemAmount, setRedeemAmount] = useState("");
const [liquidityIsProcessing, setLiquidityIsProcessing] = useState(false);
+ const [removeLiquidityIsProcessing, setRemoveLiquidityIsProcessing] =
+ useState(false);
const [migrationIsProcessing, setMigrationIsProcessing] = useState(false);
const [redeemIsProcessing, setRedeemIsProcessing] = useState(false);
const [createPoolIsProcessing, setCreatePoolIsProcessing] = useState(false);
@@ -445,6 +449,56 @@ function Main() {
toCustodyAddress,
]);
+ 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) => {
+ log("Successfully removed liquidity to the pool.");
+ getBalance(
+ connection,
+ fromCustodyAddress,
+ setFromCustodyBalance,
+ log
+ );
+ getBalance(connection, toCustodyAddress, setToCustodyBalance, log);
+ setRemoveLiquidityIsProcessing(false);
+ },
+ (error) => {
+ log("Could not complete the removeLiquidity transaction");
+ console.error(error);
+ setRemoveLiquidityIsProcessing(false);
+ }
+ );
+ } catch (e) {
+ log("Could not complete the removeLiquidity transaction");
+ console.error(e);
+ setRemoveLiquidityIsProcessing(false);
+ }
+ }, [
+ connection,
+ fromMint,
+ removeLiquidityAmount,
+ shareTokenAccount,
+ toMint,
+ toTokenAccount,
+ wallet,
+ log,
+ shareMintDecimals,
+ fromCustodyAddress,
+ toCustodyAddress,
+ ]);
+
const migrateTokens = useCallback(async () => {
try {
const instruction = await migrateTokensTx(
@@ -610,6 +664,30 @@ function Main() {
>
);
+ const removeLiquidityUI = (
+ <>
+ Remove Liquidity
+
+ This will remove 'Share' tokens from your wallet, and give you an equal
+ number of 'To' tokens.
+
+ setRemoveLiquidityAmount(event.target.value)}
+ label={"Amount to remove"}
+ >
+
+ {removeLiquidityIsProcessing ? : null}
+ >
+ );
+
const migrateTokensUI = (
<>
Migrate Tokens
@@ -736,6 +814,8 @@ function Main() {
{addLiquidityUI}
+ {removeLiquidityUI}
+
{redeemSharesUI}
{migrateTokensUI}
diff --git a/sdk/js/src/migration/removeLiquidity.ts b/sdk/js/src/migration/removeLiquidity.ts
new file mode 100644
index 00000000..5d7e9348
--- /dev/null
+++ b/sdk/js/src/migration/removeLiquidity.ts
@@ -0,0 +1,41 @@
+import { Token, TOKEN_PROGRAM_ID } from "@solana/spl-token";
+import { Connection, PublicKey, Transaction } from "@solana/web3.js";
+import { ixFromRust } from "../solana";
+
+export default async function removeLiquidity(
+ connection: Connection,
+ payerAddress: string,
+ program_id: string,
+ from_mint: string,
+ to_mint: string,
+ liquidity_token_account: string,
+ lp_share_token_account: string,
+ amount: BigInt
+) {
+ const { authority_address, remove_liquidity } = await import(
+ "../solana/migration/wormhole_migration"
+ );
+ const approvalIx = Token.createApproveInstruction(
+ TOKEN_PROGRAM_ID,
+ new PublicKey(lp_share_token_account),
+ new PublicKey(authority_address(program_id)),
+ new PublicKey(payerAddress),
+ [],
+ Number(amount)
+ );
+ const ix = ixFromRust(
+ remove_liquidity(
+ program_id,
+ from_mint,
+ to_mint,
+ liquidity_token_account,
+ lp_share_token_account,
+ amount
+ )
+ );
+ const transaction = new Transaction().add(approvalIx, ix);
+ const { blockhash } = await connection.getRecentBlockhash();
+ transaction.recentBlockhash = blockhash;
+ transaction.feePayer = new PublicKey(payerAddress);
+ return transaction;
+}