diff --git a/components/AssetInput/WhaleInput.tsx b/components/AssetInput/WhaleInput.tsx
index 6f708ed6..7e078d1a 100644
--- a/components/AssetInput/WhaleInput.tsx
+++ b/components/AssetInput/WhaleInput.tsx
@@ -126,11 +126,9 @@ ref) => {
onChange={({ target }) => {
onChange({
...token,
- amount: amountInputValidation(
- target.value,
- tokenInfo?.decimals
- ),
- });
+ amount: amountInputValidation(target.value,
+ tokenInfo?.decimals),
+ })
}}
/>
diff --git a/components/Navbar/Navbar.tsx b/components/Navbar/Navbar.tsx
index db15f8bd..e7300491 100644
--- a/components/Navbar/Navbar.tsx
+++ b/components/Navbar/Navbar.tsx
@@ -1,3 +1,4 @@
+import { InfoIcon } from '@chakra-ui/icons'
import {
Box,
Drawer,
@@ -10,9 +11,11 @@ import {
IconButton,
VStack,
useDisclosure,
+ Text,
} from '@chakra-ui/react'
import BurgerIcon from 'components/Icons/BurgerIcon'
import { ACTIVE_BONDING_NETWORKS, ChainId } from 'constants/index'
+import { useRouter } from 'next/router'
import { useRecoilValue } from 'recoil'
import { chainState } from 'state/chainState'
@@ -30,6 +33,7 @@ const Navbar = () => {
const { isOpen, onOpen, onClose } = useDisclosure()
const currentChainName = chainName
+ const router = useRouter()
const links = [
{
@@ -132,6 +136,27 @@ const Navbar = () => {
Open
+ {/* Announcement Banner */}
+ {chainId === 'phoenix-1' && router.push('/terra/pools/migrate')}
+ borderRadius="md"
+ marginTop={5}
+ >
+
+
+ Attention: We’re migrating pools. Click here to learn more and proceed.
+
+
+ }
diff --git a/components/Pages/Trade/Liquidity/DepositForm.tsx b/components/Pages/Trade/Liquidity/DepositForm.tsx
index 11edaa5f..18291280 100644
--- a/components/Pages/Trade/Liquidity/DepositForm.tsx
+++ b/components/Pages/Trade/Liquidity/DepositForm.tsx
@@ -31,6 +31,7 @@ type Props = {
poolId: string
openView: any
incentivesEnabled?:boolean
+ depositEris?: any
}
const DepositForm = ({
@@ -49,6 +50,7 @@ const DepositForm = ({
mobile,
poolId,
openView,
+ depositEris,
incentivesEnabled = false,
}: Props) => {
const { walletChainName } = useRecoilValue(chainState)
diff --git a/components/Pages/Trade/Liquidity/hooks/useDepositTransaction.tsx b/components/Pages/Trade/Liquidity/hooks/useDepositTransaction.tsx
index faf6d22e..0df4f185 100644
--- a/components/Pages/Trade/Liquidity/hooks/useDepositTransaction.tsx
+++ b/components/Pages/Trade/Liquidity/hooks/useDepositTransaction.tsx
@@ -56,7 +56,7 @@ export const useTransaction: any = ({
async () => {
setError(null)
setTxStep(TxStep.Estimating)
- if (!signingClient || !debouncedMsgs || debouncedMsgs?.length == 0) {
+ if (!signingClient || !debouncedMsgs || debouncedMsgs?.length === 0) {
return
}
try {
diff --git a/components/Pages/Trade/Liquidity/hooks/useProvideLP.ts b/components/Pages/Trade/Liquidity/hooks/useProvideLP.ts
index 6d3455b2..ca3c15e7 100644
--- a/components/Pages/Trade/Liquidity/hooks/useProvideLP.ts
+++ b/components/Pages/Trade/Liquidity/hooks/useProvideLP.ts
@@ -8,6 +8,7 @@ import useFactoryConfig from 'components/Pages/Trade/Incentivize/hooks/useFactor
import createLpMsg, { createLPExecuteMsgs } from 'components/Pages/Trade/Liquidity/hooks/createLPMsg'
import useTransaction from 'components/Pages/Trade/Liquidity/hooks/useDepositTransaction'
import useIsNewPosition from 'components/Pages/Trade/Liquidity/hooks/useIsNewPosition'
+import { createDepositErisMsgs } from 'components/Pages/Trade/Migrate/hooks/createDepositErisMsgs'
import { useQueryMatchingPoolForSwap } from 'components/Pages/Trade/Pools/hooks/useQueryMatchingPoolForSwap'
import { useQueryPoolLiquidity } from 'components/Pages/Trade/Pools/hooks/useQueryPoolsLiquidity'
import { useClients } from 'hooks/useClients'
@@ -17,7 +18,7 @@ import { useRecoilValue } from 'recoil'
import { chainState } from 'state/chainState'
import { tokenItemState } from 'state/tokenItemState'
-const useProvideLP = ({ reverse = false, bondingDays }) => {
+const useProvideLP = ({ reverse = false, bondingDays, isEris = false }) => {
const [lpTokenA, lpTokenB] = useRecoilValue(tokenItemState)
const { chainId, network, walletChainName } = useRecoilValue(chainState)
const { address } = useChain(walletChainName)
@@ -43,7 +44,7 @@ const useProvideLP = ({ reverse = false, bondingDays }) => {
})
const factoryConfig = useFactoryConfig(config?.incentive_factory)
- let minUnbondingDuration = 86400
+ let minUnbondingDuration = 86_400
if (factoryConfig) {
minUnbondingDuration = factoryConfig?.minUnbondingDuration
}
@@ -52,7 +53,7 @@ const useProvideLP = ({ reverse = false, bondingDays }) => {
useQueryPoolLiquidity({ poolId })
// Const lpBalance = liquidity?.providedTotal?.tokenAmount || 0
let provideInitialLiquidity = false
- if (liquidity?.reserves?.total[0] == 0 && window.debugLogsEnabled) {
+ if (liquidity?.reserves?.total[0] === 0 && window.debugLogsEnabled) {
provideInitialLiquidity = true
}
const [tokenA, tokenB, flipped] = useMemo(() => {
@@ -145,7 +146,25 @@ const useProvideLP = ({ reverse = false, bondingDays }) => {
? tokenBAmount
: toChainAmount(simulated, tokenInfoB?.decimals),
}),
- encodedMsgs: createLPExecuteMsgs({
+ encodedMsgs: isEris ? createDepositErisMsgs(
+ address, reverse
+ ? flipped
+ ? tokenAAmount
+ : toChainAmount(simulated, tokenInfoA?.decimals)
+ : flipped
+ ? tokenAAmount
+ : tokenAAmount, [{ denom: tokenA.denom,
+ amount: reverse
+ ? flipped
+ ? tokenAAmount
+ : toChainAmount(simulated, tokenInfoA?.decimals)
+ : tokenAAmount }, { denom: tokenB.denom,
+ amount: reverse
+ ? tokenBAmount
+ : flipped
+ ? tokenBAmount
+ : toChainAmount(simulated, tokenInfoB?.decimals) }],
+ ) : createLPExecuteMsgs({
minUnbondingDuration,
tokenA,
bondingDays,
@@ -156,14 +175,10 @@ const useProvideLP = ({ reverse = false, bondingDays }) => {
? flipped
? tokenAAmount
: toChainAmount(simulated, tokenInfoA?.decimals)
- : flipped
- ? tokenAAmount
- : tokenAAmount,
+ : tokenAAmount,
tokenB,
amountB: reverse
- ? flipped
- ? tokenBAmount
- : tokenBAmount
+ ? tokenBAmount
: flipped
? tokenBAmount
: toChainAmount(simulated, tokenInfoB?.decimals),
diff --git a/components/Pages/Trade/Migrate/Migrate.tsx b/components/Pages/Trade/Migrate/Migrate.tsx
new file mode 100644
index 00000000..f95da37c
--- /dev/null
+++ b/components/Pages/Trade/Migrate/Migrate.tsx
@@ -0,0 +1,222 @@
+import { useEffect, useMemo, useState } from 'react'
+
+import { Box, Button, Divider, Heading, Text, useMediaQuery, VStack } from '@chakra-ui/react' // Ensure you import Button if not already
+import { useChain } from '@cosmos-kit/react-lite'
+import DepositForm from 'components/Pages/Trade/Liquidity/DepositForm'
+import useProvideLP from 'components/Pages/Trade/Liquidity/hooks/useProvideLP'
+import { useFetchStaked } from 'components/Pages/Trade/Migrate/hooks/useFetchStaked'
+import useMigrateTx from 'components/Pages/Trade/Migrate/hooks/useMigrateTx'
+import { usePoolsListQuery } from 'components/Pages/Trade/Pools/hooks/usePoolsListQuery'
+import {
+ PoolEntityTypeWithLiquidity,
+ useQueryPoolsLiquidity,
+} from 'components/Pages/Trade/Pools/hooks/useQueryPoolsLiquidity'
+import { useClients } from 'hooks/useClients'
+import { useQueriesDataSelector } from 'hooks/useQueriesDataSelector'
+import { useTokenList } from 'hooks/useTokenList'
+import { useRecoilState, useRecoilValue } from 'recoil'
+import { chainState } from 'state/chainState'
+import { tokenItemState } from 'state/tokenItemState'
+import { TokenItemState, TxStep } from 'types/index'
+import { getDecimals } from 'util/conversion/index'
+
+const Migrate = () => {
+ const { walletChainName } = useRecoilValue(chainState)
+ const { isWalletConnected, address, openView } = useChain(walletChainName)
+ const [isMobile] = useMediaQuery('(max-width: 720px)')
+ const data = useFetchStaked(address)
+ const { submit } = useMigrateTx()
+ const ampLp = useMemo(() => data?.ampLpToken, [data])
+ const erisLp = useMemo(() => data?.erisLpToken, [data])
+ const wwLp = useMemo(() => data?.wwLpToken, [data])
+
+ const lpTokens = [wwLp, erisLp, ampLp]
+ const lpSum = lpTokens.reduce((acc, token) => acc + (token?.amount ?? 0), 0)
+ // States required for DepositForm:
+ const [reverse, setReverse] = useState(false)
+ const clearForm = () => {}
+ const chainId = 'phoenix-1'
+
+ const { data: poolData } = usePoolsListQuery()
+ const { cosmWasmClient } = useClients(walletChainName)
+
+ const [pools]: readonly [PoolEntityTypeWithLiquidity[], boolean, boolean] =
+ useQueriesDataSelector(useQueryPoolsLiquidity({
+ refetchInBackground: false,
+ pools: poolData?.pools,
+ cosmWasmClient,
+ }))
+
+ const pool = useMemo(() => pools?.find((p) => p.pool_id === 'USDC-USDt'), [pools])
+ const [tokenList] = useTokenList()
+ const [isTokenSet, setIsToken] = useState(false)
+
+ const [[tokenA, tokenB], setTokenItemState] = useRecoilState(tokenItemState)
+
+ useEffect(() => {
+ if (pool?.pool_id) {
+ const [tokenASymbol, tokenBSymbol] = pool?.pool_id?.split('-') || []
+ setTokenItemState([
+ {
+ tokenSymbol: tokenASymbol,
+ amount: 0,
+ decimals: getDecimals(tokenASymbol, tokenList),
+ },
+ {
+ tokenSymbol: tokenBSymbol,
+ amount: 0,
+ decimals: getDecimals(tokenBSymbol, tokenList),
+ },
+ ])
+ setIsToken(true)
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [pool])
+
+ const [bondingDays, setBondingDays] = useState(0)
+ const { simulated, tx } = useProvideLP({
+ reverse,
+ bondingDays,
+ isEris: true,
+ })
+
+ const onInputChange = ({ tokenSymbol, amount }: any, index: number) => {
+ if (tx?.txStep === TxStep.Failed || tx?.txStep === TxStep.Success) {
+ tx.reset()
+ }
+
+ const newState: [TokenItemState?, TokenItemState?] = [tokenA, tokenB]
+ newState[index] = {
+ ...newState.find((item) => item?.tokenSymbol === tokenSymbol),
+ tokenSymbol,
+ amount: Number(amount),
+ }
+ setTokenItemState(newState)
+ }
+
+ // Example button usage snippet:
+ const PrimaryButton = ({
+ label,
+ onClick,
+ isLoading = false,
+ isDisabled = false,
+ }: {
+ label: string
+ onClick?: () => void
+ isLoading?: boolean
+ isDisabled?: boolean
+ }) => (
+
+ )
+
+ return (
+
+
+
+
+ Migrate Liquidity to New USDC/USDT Pool
+
+
+
+
+ {/* Step 1 */}
+
+ Step 1: Check Old Pool Liquidity
+ {lpTokens.map((token, index) => {
+ const tokenAmount = token?.amount ?? 0
+ if (index === 0 && tokenAmount > 0) {
+ return You have {tokenAmount.toFixed(6)} WhiteWhale LP tokens in the old USDC/USDT XYK pool.
+ } else if (index === 1 && tokenAmount > 0) {
+ return You have {tokenAmount.toFixed(6)} Eris LP tokens in the old USDC/USDT XYK pool.
+ } else if (index === 2 && tokenAmount > 0) {
+ return You have {tokenAmount.toFixed(6)} Eris ampLP tokens in the old USDC/USDT XYK pool.
+ } else {
+ return <>>
+ }
+ })}
+ {lpSum === 0 && (
+ You have no liquidity in the old pool.
+ )}
+
+
+
+
+ {/* Step 2 */}
+
+ Step 2: Withdraw Liquidity
+ Withdraw all liquidity from the old XYK pool before migrating.
+ 0)) }
+ label={isWalletConnected && (lpSum > 0) ? 'Withdraw' : 'Nothing to withdraw'}
+ onClick={() => submit(lpTokens)}
+ />
+
+
+
+
+ {/* Step 3 */}
+
+ Step 3: Deposit into the New StableSwap Pool
+ Now deposit your USDC and USDT into the new StableSwap pool.
+
+
+
+
+
+ {/* Step 4 */}
+
+ Step 4: Vote with Your Liquidity
+ Your new liquidity is now deposited in the StableSwap pool.
+ Proceed to Eris Protocol to deposit your USDC/USDT Stable LP and adjust your VP to the new stable pool.
+
+
+
+
+
+ )
+}
+
+export default Migrate
diff --git a/components/Pages/Trade/Migrate/constants.ts b/components/Pages/Trade/Migrate/constants.ts
new file mode 100644
index 00000000..9b292d9e
--- /dev/null
+++ b/components/Pages/Trade/Migrate/constants.ts
@@ -0,0 +1,3 @@
+export const newPool = 'terra178ca7z2w6346wlkmxwpw80s2a5fmas9q28xlzegkt4c4rdam67aql5fgxj'
+export const oldPool = 'terra17vas9rhxhc6j6f5wrup9cqapxn74jvpft069py7l7l9kr7wx3tnsxrazux'
+export const newPoolLP = 'factory/terra178ca7z2w6346wlkmxwpw80s2a5fmas9q28xlzegkt4c4rdam67aql5fgxj/uLP'
diff --git a/components/Pages/Trade/Migrate/hooks/createDepositErisMsgs.ts b/components/Pages/Trade/Migrate/hooks/createDepositErisMsgs.ts
new file mode 100644
index 00000000..974f4dea
--- /dev/null
+++ b/components/Pages/Trade/Migrate/hooks/createDepositErisMsgs.ts
@@ -0,0 +1,40 @@
+import { newPool } from 'components/Pages/Trade/Migrate/constants'
+import { createExecuteMessage } from 'util/messages/index'
+
+export const createDepositErisMsgs = (
+ address: string, tokenAmount: string, assets: {denom: string, amount: string}[],
+) => {
+ const createLpMessage = {
+ create_lp: {
+ min_received: tokenAmount,
+ assets: [
+ {
+ native: 'ibc/2C962DAB9F57FE0921435426AE75196009FAA1981BF86991203C8411F8980FDB',
+ },
+ {
+ native: 'ibc/9B19062D46CAB50361CE9B0A3E6D0A7A53AC9E7CB361F32A73CC733144A9A9E5',
+ },
+ ],
+ stage: {
+ white_whale: {
+ pair: newPool,
+ },
+ },
+ post_action: {
+ stake: {
+ asset_staking: 'terra14mmvqn0kthw6sre75vku263lafn5655mkjdejqjedjga4cw0qx2qlf4arv',
+ receiver: null,
+ },
+ },
+ },
+ }
+
+ return [
+ createExecuteMessage({
+ senderAddress: address,
+ contractAddress: 'terra1qdjsxsv96aagrdxz83gwtjk8qvf2mrg4y8y3dqjxg556lm79pg5qdgmaxl',
+ message: createLpMessage,
+ funds: assets,
+ }),
+ ]
+}
diff --git a/components/Pages/Trade/Migrate/hooks/useFetchStaked.ts b/components/Pages/Trade/Migrate/hooks/useFetchStaked.ts
new file mode 100644
index 00000000..1ee62657
--- /dev/null
+++ b/components/Pages/Trade/Migrate/hooks/useFetchStaked.ts
@@ -0,0 +1,49 @@
+import { useQuery } from 'react-query'
+
+import { CosmWasmClient, JsonObject } from '@cosmjs/cosmwasm-stargate'
+import { WalletChainName } from 'constants/index'
+import { useClients } from 'hooks/useClients'
+
+const fetchStaked = async (client: CosmWasmClient,
+ address: string) => {
+ const oldDenom = 'factory/terra17vas9rhxhc6j6f5wrup9cqapxn74jvpft069py7l7l9kr7wx3tnsxrazux/uLP'
+ const wwLpToken = await client.getBalance(address, oldDenom)
+ const ampLpToken = await client.getBalance(address, 'factory/terra1zly98gvcec54m3caxlqexce7rus6rzgplz7eketsdz7nh750h2rqvu8uzx/7/bluechip/amplp')
+ const erisLpToken = { denom: oldDenom,
+ amount: '0' }
+ try {
+ const stakedLpBalance: JsonObject = await client.queryContractSmart('terra14mmvqn0kthw6sre75vku263lafn5655mkjdejqjedjga4cw0qx2qlf4arv',
+ {
+ staked_balance: {
+ address,
+ asset: {
+ native: oldDenom,
+ },
+ },
+ })
+ erisLpToken.amount = stakedLpBalance.asset.amount
+ } catch (e) {
+ console.error('Error: ', e)
+ }
+ return { wwLpToken: { denom: wwLpToken.denom,
+ amount: Number(wwLpToken.amount) * (10 ** -6) },
+ erisLpToken: { denom: erisLpToken.denom,
+ amount: Number(erisLpToken.amount) * (10 ** -6) },
+ ampLpToken: { denom: ampLpToken.denom,
+ amount: Number(ampLpToken.amount) * (10 ** -6) } }
+}
+export const useFetchStaked = (address: string): { wwLpToken: {amount: number, denom: string },
+ erisLpToken: {amount: number, denom: string },
+ ampLpToken: {amount: number, denom: string } } => {
+ const { cosmWasmClient } = useClients(WalletChainName.terra)
+ const { data } = useQuery({
+ queryKey: ['fetchStaked', address],
+ queryFn: () => fetchStaked(cosmWasmClient, address),
+ enabled: Boolean(cosmWasmClient) && Boolean(address),
+ staleTime: 30_000, // 30 seconds
+ cacheTime: 1 * 60 * 1_000, // 5 minutes
+ });
+
+ // Ensure the hook always returns an object with defaults
+ return data
+}
diff --git a/components/Pages/Trade/Migrate/hooks/useMigrateTx.tsx b/components/Pages/Trade/Migrate/hooks/useMigrateTx.tsx
new file mode 100644
index 00000000..c36e3810
--- /dev/null
+++ b/components/Pages/Trade/Migrate/hooks/useMigrateTx.tsx
@@ -0,0 +1,213 @@
+import { useCallback, useEffect, useMemo, useState } from 'react'
+import { useMutation, useQuery } from 'react-query'
+
+import { useToast } from '@chakra-ui/react'
+import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate/build/signingcosmwasmclient'
+import { useChain } from '@cosmos-kit/react-lite'
+import Finder from 'components/Finder'
+import { withdraw } from 'components/Pages/Trade/Migrate/hooks/withdraw'
+import { useClients } from 'hooks/useClients'
+import { useRecoilValue } from 'recoil'
+import { chainState } from 'state/chainState'
+import { TxStep } from 'types/index'
+
+export const useMigrateTx = () => {
+ const toast = useToast()
+ const { chainId, walletChainName } = useRecoilValue(chainState)
+ const { address } = useChain(walletChainName)
+ const { signingClient } = useClients(walletChainName)
+ const [txStep, setTxStep] = useState(TxStep.Idle)
+ const [txHash, setTxHash] = useState(null)
+ const [error, setError] = useState(null)
+ const [buttonLabel, setButtonLabel] = useState(null)
+
+ const { data: fee } = useQuery(
+ ['fee', error],
+ () => {
+ setError(null)
+ setTxStep(TxStep.Estimating)
+ try {
+ const response = 0 // Await client.simulate(senderAddress, debouncedMsgs, '')
+ if (buttonLabel) {
+ setButtonLabel(null)
+ }
+ setTxStep(TxStep.Ready)
+ return response
+ } catch (error) {
+ if (
+ (/insufficient funds/u).test(error.toString()) ||
+ (/Overflow: Cannot Sub with/u).test(error.toString())
+ ) {
+ console.error(error.toString())
+ setTxStep(TxStep.Idle)
+ setError('Insufficient Funds')
+ setButtonLabel('Insufficient Funds')
+ throw new Error('Insufficient Funds')
+ } else if ((/account sequence mismatch/u).test(error?.toString())) {
+ setError('You have pending transaction')
+ setButtonLabel('You have pending transaction')
+ throw new Error('You have pending transaction')
+ } else {
+ console.error(error.toString())
+ setTxStep(TxStep.Idle)
+ setError(error?.message)
+ throw Error(error?.message)
+ /*
+ * SetTxStep(TxStep.Idle)
+ * setError("Failed to execute transaction.")
+ * throw Error("Failed to execute transaction.")
+ */
+ }
+ }
+ },
+ {
+ enabled: txStep === TxStep.Idle && !error && Boolean(signingClient),
+ refetchOnWindowFocus: false,
+ retry: false,
+ staleTime: 0,
+ onSuccess: () => {
+ setTxStep(TxStep.Ready)
+ },
+ onError: () => {
+ setTxStep(TxStep.Idle)
+ },
+ },
+ )
+ const { data: txInfo } = useQuery(
+ ['txInfo', txHash],
+ () => {
+ if (!txHash) {
+ return null
+ }
+ return signingClient?.getTx(txHash)
+ },
+ {
+ enabled: Boolean(txHash),
+ retry: true,
+ },
+ )
+ const { mutate } = useMutation((data: { signingClient: SigningCosmWasmClient, address: string, lpTokens: {denom: string, amount: number}[] }) => withdraw(
+ signingClient, address, data.lpTokens,
+ ),
+ {
+ onMutate: () => {
+ setTxStep(TxStep.Posting)
+ },
+ onError: (e) => {
+ let message: any = ''
+ console.error(e?.toString())
+ setTxStep(TxStep.Failed)
+ if (
+ (/insufficient funds/u).test(e?.toString()) ||
+ (/Overflow: Cannot Sub with/u).test(e?.toString())
+ ) {
+ setError('Insufficient Funds')
+ message = 'Insufficient Funds'
+ } else if ((/Request rejected/u).test(e?.toString())) {
+ setError('User Denied')
+ message = 'User Denied'
+ } else if ((/account sequence mismatch/u).test(e?.toString())) {
+ setError('You have pending transaction')
+ message = 'You have pending transaction'
+ } else if ((/out of gas/u).test(e?.toString())) {
+ setError('Out of gas, try increasing gas limit on wallet.')
+ message = 'Out of gas, try increasing gas limit on wallet.'
+ } else if ((/before the new\/latest epoch/u).test(e?.toString())) {
+ setError('Epoch not yet created.')
+ message = 'Please force the pending epoch on the bonding page.'
+ } else if (
+ (/There are unclaimed rewards available./u).test(e?.toString())
+ ) {
+ setError('There are unclaimed rewards available.')
+ message =
+ 'There are unclaimed rewards available. Claim them before attempting to bond/unbond.'
+ } else if (
+ (/was submitted but was not yet found on the chain/u).test(e?.toString())
+ ) {
+ setError(e?.toString())
+ message = (
+
+ {' '}
+
+ )
+ } else {
+ setError('Failed to execute transaction.')
+ message = 'Failed to execute transaction.'
+ }
+
+ toast({
+ title: (() => 'Withdrawal Failed.')(),
+ description: message,
+ status: 'error',
+ duration: 9000,
+ position: 'top-right',
+ isClosable: true,
+ })
+ },
+ onSuccess: (data: any) => {
+ setTxStep(TxStep.Broadcasting)
+ setTxHash(data?.transactionHash)
+ toast({
+ title: (() => 'Withdrawal Successful.')(),
+ description: (
+
+ {' '}
+
+ ),
+ status: 'success',
+ duration: 9000,
+ position: 'top-right',
+ isClosable: true,
+ })
+ },
+ })
+ const reset = () => {
+ setError(null)
+ setTxHash(null)
+ setTxStep(TxStep.Idle)
+ }
+
+ const submit = useCallback((lpTokens: {denom: string, amount: number}[]) => {
+ mutate({
+ signingClient,
+ address,
+ lpTokens,
+ })
+ },
+ [address, fee, mutate])
+
+ useEffect(() => {
+ if (txInfo && txHash) {
+ if (txInfo?.code) {
+ setTxStep(TxStep.Failed)
+ } else {
+ setTxStep(TxStep.Success)
+ }
+ }
+ }, [txInfo, txHash, error])
+
+ useEffect(() => {
+ if (error) {
+ setError(null)
+ }
+
+ if (txStep !== TxStep.Idle) {
+ setTxStep(TxStep.Idle)
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []) // DebouncedMsgs
+
+ return useMemo(() => ({
+ fee,
+ buttonLabel,
+ submit,
+ txStep,
+ txInfo,
+ txHash,
+ error,
+ reset,
+ }),
+ [txStep, txInfo, txHash, error, fee])
+}
+
+export default useMigrateTx
diff --git a/components/Pages/Trade/Migrate/hooks/withdraw.ts b/components/Pages/Trade/Migrate/hooks/withdraw.ts
new file mode 100644
index 00000000..1290c06d
--- /dev/null
+++ b/components/Pages/Trade/Migrate/hooks/withdraw.ts
@@ -0,0 +1,87 @@
+import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate/build/signingcosmwasmclient'
+import { oldPool } from 'components/Pages/Trade/Migrate/constants'
+import { ADV_MEMO } from 'constants/index'
+import { createGasFee } from 'services/treasuryService'
+import { createExecuteMessage } from 'util/messages/createExecuteMessage'
+
+export const withdraw: any = async (
+ signingClient: SigningCosmWasmClient,
+ address: string,
+ lpTokens: {denom: string, amount: number}[],
+) => {
+ const withdrawWWLp = {
+ withdraw_liquidity: {},
+ }
+
+ const unstakeAmpLp = {
+ unstake: {
+ recipient: 'terra1qdjsxsv96aagrdxz83gwtjk8qvf2mrg4y8y3dqjxg556lm79pg5qdgmaxl',
+ },
+ }
+
+ const unstakeErisLp = {
+ unstake: {
+ asset: {
+ amount: lpTokens[1].amount,
+ info: {
+ native: lpTokens[1].denom,
+ },
+ },
+ recipient: 'terra1qdjsxsv96aagrdxz83gwtjk8qvf2mrg4y8y3dqjxg556lm79pg5qdgmaxl',
+ },
+ }
+
+ const withdrawErisLp = {
+ withdraw_lp: {
+ stage: {
+ white_whale: {
+ pair: oldPool,
+ },
+ },
+ },
+ }
+
+ const execMsgUnstakeAmpLp = createExecuteMessage({ senderAddress: address,
+ contractAddress: 'terra1zly98gvcec54m3caxlqexce7rus6rzgplz7eketsdz7nh750h2rqvu8uzx',
+ message: unstakeAmpLp,
+ funds: [{ amount: Math.ceil(lpTokens[2].amount * (10 ** 6)).toString(),
+ denom: lpTokens[2].denom }] })
+
+ const execMsgUnstakeErisLp = createExecuteMessage({ senderAddress: address,
+ contractAddress: 'terra14mmvqn0kthw6sre75vku263lafn5655mkjdejqjedjga4cw0qx2qlf4arv',
+ message: unstakeErisLp,
+ funds: [] })
+
+ const execMsgWithdrawErisLp = createExecuteMessage({ senderAddress: address,
+ contractAddress: 'terra1qdjsxsv96aagrdxz83gwtjk8qvf2mrg4y8y3dqjxg556lm79pg5qdgmaxl',
+ message: withdrawErisLp,
+ funds: [] })
+
+ const execMsgWithdrawWWLp = createExecuteMessage({ senderAddress: address,
+ contractAddress: oldPool,
+ message: withdrawWWLp,
+ funds: [{
+ amount: (lpTokens[0].amount * (10 ** 6)).toString(),
+ denom: lpTokens[0].denom,
+ }] })
+ const messages = []
+
+ if (lpTokens[2].amount > 0) {
+ messages.push(execMsgUnstakeAmpLp)
+ messages.push(execMsgWithdrawErisLp)
+ }
+ if (lpTokens[1].amount > 0) {
+ messages.push(execMsgUnstakeErisLp)
+ messages.push(execMsgWithdrawErisLp)
+ }
+ if (lpTokens[0].amount > 0) {
+ messages.push(execMsgWithdrawWWLp)
+ }
+ console.log({lpTokens})
+ console.log({messages})
+ return await signingClient.signAndBroadcast(
+ address, messages, await createGasFee(
+ signingClient, address, messages,
+ ), ADV_MEMO,
+ )
+}
diff --git a/components/Pages/Trade/Migrate/index.ts b/components/Pages/Trade/Migrate/index.ts
new file mode 100644
index 00000000..79e34dd1
--- /dev/null
+++ b/components/Pages/Trade/Migrate/index.ts
@@ -0,0 +1 @@
+export { default } from 'components/Pages/Trade/Migrate/Migrate'
diff --git a/pages/[chainId]/pools/migrate/index.tsx b/pages/[chainId]/pools/migrate/index.tsx
new file mode 100644
index 00000000..98703d88
--- /dev/null
+++ b/pages/[chainId]/pools/migrate/index.tsx
@@ -0,0 +1,5 @@
+import Migrate from 'components/Pages/Trade/Migrate/index'
+
+const MigratePage = () =>
+
+export default MigratePage
diff --git a/pages/pools/index.tsx b/pages/pools/index.tsx
deleted file mode 100644
index 658b6076..00000000
--- a/pages/pools/index.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import Pools from 'components/Pages/Trade/Pools'
-
-const PoolsPage = () =>
-
-export default PoolsPage