From 87cd65c54599103f3bcd12130162b3f1aa77d18c Mon Sep 17 00:00:00 2001 From: vkulinich Date: Tue, 5 Nov 2024 20:06:09 +0100 Subject: [PATCH 01/10] wip --- .../farms/modals/join/JoinFarmsModal.tsx | 56 +------- .../joinedFarmDetails/JoinedFarmsDetails.tsx | 2 +- .../modals/AddLiquidity/AddLiquidity.tsx | 81 +++--------- .../modals/AddLiquidity/AddLiquidityForm.tsx | 101 +++++---------- .../JoinFarmsSection/JoinFarmsSection.tsx | 59 +++++++++ src/utils/farms/deposit.tsx | 120 +++++------------- 6 files changed, 146 insertions(+), 273 deletions(-) create mode 100644 src/sections/pools/modals/AddLiquidity/components/JoinFarmsSection/JoinFarmsSection.tsx diff --git a/src/sections/pools/farms/modals/join/JoinFarmsModal.tsx b/src/sections/pools/farms/modals/join/JoinFarmsModal.tsx index 5e850d243..4f22bbd3c 100644 --- a/src/sections/pools/farms/modals/join/JoinFarmsModal.tsx +++ b/src/sections/pools/farms/modals/join/JoinFarmsModal.tsx @@ -1,10 +1,7 @@ import { TFarmAprData, useFarmCurrentPeriod } from "api/farms" import { Modal } from "components/Modal/Modal" import { useModalPagination } from "components/Modal/Modal.utils" -import { - LoadingPage, - ModalContents, -} from "components/Modal/contents/ModalContents" +import { ModalContents } from "components/Modal/contents/ModalContents" import { Text } from "components/Typography/Text/Text" import { useState } from "react" import { useTranslation } from "react-i18next" @@ -13,7 +10,6 @@ import { FarmDetailsCard } from "sections/pools/farms/components/detailsCard/Far import { FarmDetailsModal } from "sections/pools/farms/modals/details/FarmDetailsModal" import { TLPData } from "utils/omnipool" import { JoinFarmsForm } from "./JoinFarmsForm" -import { getStepState, Stepper } from "components/Stepper/Stepper" import { usePoolData } from "sections/pools/pool/Pool" import { TDeposit } from "api/deposits" @@ -27,7 +23,6 @@ type JoinFarmModalProps = { export enum Page { JOIN_FARM, FARM_DETAILS, - WAIT, } export const JoinFarmModal = ({ @@ -41,25 +36,16 @@ export const JoinFarmModal = ({ pool: { meta, id: poolId, farms: allFarms }, } = usePoolData() const [selectedFarm, setSelectedFarm] = useState(null) - const [currentStep, setCurrentStep] = useState(0) const { getCurrentPeriod } = useFarmCurrentPeriod() const { page, direction, paginateTo } = useModalPagination() const farms = initialFarms ?? allFarms - const isMultipleFarms = farms.length > 1 const joinFarms = useJoinFarms({ poolId, farms, - deposit: { - onClose, - disableAutoClose: isMultipleFarms, - onSuccess: () => setCurrentStep(1), - onSubmitted: () => (isMultipleFarms ? paginateTo(Page.WAIT) : null), - onError: onClose, - }, - redeposit: { + options: { onClose, onError: onClose, }, @@ -74,39 +60,8 @@ export const JoinFarmModal = ({ setSelectedFarm(null) } - const steps = [ - { - id: 0, - label: t("farms.modal.join.first"), - loadingLabel: t("farms.modal.join.first.loading"), - }, - ...(isMultipleFarms - ? [ - { - id: 1, - label: t("farms.modal.join.rest"), - loadingLabel: t("farms.modal.join.rest.loading"), - }, - ] - : []), - ] - return ( - ({ - label: step.label, - state: getStepState(step.id, currentStep), - }))} - /> - ) : undefined - } - > + ), }, - { - title: steps[currentStep].label, - headerVariant: "gradient", - content: , - }, ]} /> diff --git a/src/sections/pools/farms/modals/joinedFarmDetails/JoinedFarmsDetails.tsx b/src/sections/pools/farms/modals/joinedFarmDetails/JoinedFarmsDetails.tsx index 492545584..4f6860290 100644 --- a/src/sections/pools/farms/modals/joinedFarmDetails/JoinedFarmsDetails.tsx +++ b/src/sections/pools/farms/modals/joinedFarmDetails/JoinedFarmsDetails.tsx @@ -50,7 +50,7 @@ function JoinedFarmsDetailsRedeposit(props: { const joinFarms = useJoinFarms({ poolId, farms: availableFarms, - redeposit: { + options: { onSubmitted: () => props.onTxClose(), onBack: () => {}, onClose: () => props.onTxClose(), diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx index 170a933dc..d0518dbaa 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx @@ -48,22 +48,22 @@ export const AddLiquidity = ({ isOpen, onClose }: Props) => { const isXYK = isXYKPoolType(pool) const willJoinFarms = farms.length > 0 && isJoinFarms - const joinFarms = useJoinFarms({ - poolId: pool.id, - farms, - deposit: { - onClose, - disableAutoClose: farms.length > 1, - onSuccess: () => { - setCurrentStep(2) - }, - onError: onClose, - }, - redeposit: { - onClose, - onError: onClose, - }, - }) + // const joinFarms = useJoinFarms({ + // poolId: pool.id, + // farms, + // deposit: { + // onClose, + // disableAutoClose: farms.length > 1, + // onSuccess: () => { + // setCurrentStep(2) + // }, + // onError: onClose, + // }, + // redeposit: { + // onClose, + // onError: onClose, + // }, + // }) const onSuccess = async (result: ISubmittableResult, value: string) => { if (willJoinFarms) { @@ -138,44 +138,8 @@ export const AddLiquidity = ({ isOpen, onClose }: Props) => { } } - const steps = [ - { - id: 0, - label: t("liquidity.add.modal.provideLiquidity"), - loadingLabel: t("liquidity.add.modal.provideLiquidity.loading"), - }, - { - id: 1, - label: t("farms.modal.join.first"), - loadingLabel: t("farms.modal.join.first.loading"), - }, - ...(farms.length > 1 - ? [ - { - id: 2, - label: t("farms.modal.join.rest"), - loadingLabel: t("farms.modal.join.rest.loading"), - }, - ] - : []), - ] - return ( - ({ - label: step.label, - state: getStepState(step.id, currentStep), - }))} - /> - ) : undefined - } - > + { ) : ( paginateTo(Page.WAIT)} - onSuccess={onSuccess} - isJoinFarms={isJoinFarms} - setIsJoinFarms={setIsJoinFarms} + onClose={onClose} /> ), }, @@ -218,11 +178,6 @@ export const AddLiquidity = ({ isOpen, onClose }: Props) => { /> ), }, - { - title: steps[currentStep].label, - headerVariant: "gradient", - content: , - }, ]} /> diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx index 75343c36c..ca1754ca1 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx @@ -1,4 +1,4 @@ -import { Controller, FieldErrors, useForm } from "react-hook-form" +import { Controller, useForm } from "react-hook-form" import BigNumber from "bignumber.js" import { BN_0 } from "utils/constants" import { WalletTransferAssetSelect } from "sections/wallet/transfer/WalletTransferAssetSelect" @@ -27,38 +27,33 @@ import { Alert } from "components/Alert/Alert" import { useDebouncedValue } from "hooks/useDebouncedValue" import { createToastMessages } from "state/toasts" import { ISubmittableResult } from "@polkadot/types/types" -import { useEffect } from "react" +import { useEffect, useState } from "react" import { useAssets } from "providers/assets" -import { Switch } from "components/Switch/Switch" -import { FarmDetailsRow } from "sections/pools/farms/components/detailsCard/FarmDetailsRow" +import { JoinFarmsSection } from "./components/JoinFarmsSection/JoinFarmsSection" type Props = { assetId: string initialAmount?: string onClose: () => void onAssetOpen?: () => void - onSubmitted?: () => void - onSuccess: (result: ISubmittableResult, value: string) => void + onSuccess?: (result: ISubmittableResult, value: string) => void farms: TFarmAprData[] - isJoinFarms: boolean - setIsJoinFarms: (value: boolean) => void } export const AddLiquidityForm = ({ assetId, onClose, onAssetOpen, - onSubmitted, onSuccess, initialAmount, farms, - isJoinFarms, - setIsJoinFarms, }: Props) => { const { t } = useTranslation() const { api } = useRpcProvider() const { native } = useAssets() const { createTransaction } = useStore() + const isFarms = farms.length > 0 + const [isJoinFarms, setIsJoinFarms] = useState(isFarms) const zodSchema = useAddToOmnipoolZod(assetId, farms) const form = useForm<{ @@ -92,18 +87,24 @@ export const AddLiquidityForm = ({ const amount = scale(values.amount, assetMeta.decimals).toString() return await createTransaction( - { tx: api.tx.omnipool.addLiquidity(assetId, amount) }, + { + tx: isJoinFarms + ? api.tx.omnipoolLiquidityMining.addLiquidityAndJoinFarms( + farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + assetId, + amount, + ) + : api.tx.omnipool.addLiquidity(assetId, amount), + }, { onSuccess: (result) => { - onSuccess(result, amount) + onSuccess?.(result, amount) }, onSubmitted: () => { - !farms.length && !isJoinFarms && onClose() + onClose() reset() - onSubmitted?.() }, onClose, - disableAutoClose: !!farms.length && isJoinFarms, onBack: () => {}, toast: createToastMessages("liquidity.add.modal.toast", { t, @@ -119,15 +120,6 @@ export const AddLiquidityForm = ({ ) } - const onInvalidSubmit = (errors: FieldErrors>) => { - if ( - !isJoinFarms && - (errors.amount as { farm?: { message: string } }).farm - ) { - onSubmit(form.getValues()) - } - } - const customErrors = formState.errors.amount as unknown as | { cap?: { message: string } @@ -137,25 +129,24 @@ export const AddLiquidityForm = ({ | undefined const isJoinFarmDisabled = !!customErrors?.farm - const isSubmitDisabled = - farms.length > 0 && isJoinFarms - ? !!Object.keys(formState.errors).length - : !!Object.keys(formState.errors.amount ?? {}).filter( - (key) => key !== "farm", - ).length + const isSubmitDisabled = isJoinFarms + ? !!Object.keys(formState.errors).length + : !!Object.keys(formState.errors.amount ?? {}).filter( + (key) => key !== "farm", + ).length useEffect(() => { - if (!farms.length) return + if (!isFarms) return if (isJoinFarmDisabled) { setIsJoinFarms(false) } else { setIsJoinFarms(true) } - }, [farms.length, isJoinFarmDisabled, setIsJoinFarms]) + }, [isFarms, isJoinFarmDisabled, setIsJoinFarms]) return (
- {farms.length > 0 && ( - <> - - - {isJoinFarms ? t("yes") : t("no")} - - - - } - /> - {isJoinFarms && ( -
- {farms.map((farm) => { - return - })} -
- )} - {customErrors?.farm && ( - - {customErrors.farm.message} - - )} - - )} + {farms.length > 0 ? ( + + ) : null} {t("liquidity.add.modal.positionDetails")} diff --git a/src/sections/pools/modals/AddLiquidity/components/JoinFarmsSection/JoinFarmsSection.tsx b/src/sections/pools/modals/AddLiquidity/components/JoinFarmsSection/JoinFarmsSection.tsx new file mode 100644 index 000000000..7c5a6bd81 --- /dev/null +++ b/src/sections/pools/modals/AddLiquidity/components/JoinFarmsSection/JoinFarmsSection.tsx @@ -0,0 +1,59 @@ +import { TFarmAprData } from "api/farms" +import { Alert } from "components/Alert/Alert" +import { SummaryRow } from "components/Summary/SummaryRow" +import { Switch } from "components/Switch/Switch" +import { Text } from "components/Typography/Text/Text" +import { useTranslation } from "react-i18next" +import { FarmDetailsRow } from "sections/pools/farms/components/detailsCard/FarmDetailsRow" + +type JoinFarmsSectionProps = { + isJoinFarms: boolean + isJoinFarmDisabled: boolean + farms: TFarmAprData[] + error?: string + setIsJoinFarms: (v: boolean) => void +} + +export const JoinFarmsSection = ({ + isJoinFarms, + isJoinFarmDisabled, + farms, + error, + setIsJoinFarms, +}: JoinFarmsSectionProps) => { + const { t } = useTranslation() + + return ( + <> + + + {isJoinFarms ? t("yes") : t("no")} + + + + } + /> + {isJoinFarms && ( +
+ {farms.map((farm) => { + return + })} +
+ )} + {error && ( + + {error} + + )} + + ) +} diff --git a/src/utils/farms/deposit.tsx b/src/utils/farms/deposit.tsx index 81e0e5831..632f543ac 100644 --- a/src/utils/farms/deposit.tsx +++ b/src/utils/farms/deposit.tsx @@ -3,8 +3,6 @@ import { Trans } from "react-i18next" import { ToastMessage, TransactionOptions, useStore } from "state/store" import { useRpcProvider } from "providers/rpcProvider" import { TOAST_MESSAGES } from "state/toasts" -import { useAccount } from "sections/web3-connect/Web3Connect.utils" -import { isEvmAccount } from "utils/evm" import { ApiPromise } from "@polkadot/api" import { t } from "i18next" import BN from "bignumber.js" @@ -22,34 +20,7 @@ const isXYKData = (data: TJoinFarmsInput): data is XYKInput => { return (data as XYKInput).shares !== undefined } -export const xykDepositTx = ( - api: ApiPromise, - farm: TFarmAprData, - shares: string, - { assetIn, assetOut }: { assetIn: string; assetOut: string }, -) => - api.tx.xykLiquidityMining.depositShares( - farm.globalFarmId, - farm.yieldFarmId, - { - assetIn, - assetOut, - }, - shares, - ) - -export const depositTx = ( - api: ApiPromise, - farm: TFarmAprData, - positionId: string, -) => - api.tx.omnipoolLiquidityMining.depositShares( - farm.globalFarmId, - farm.yieldFarmId, - positionId, - ) - -export const xykRedepositTx = ( +const xykRedepositTx = ( api: ApiPromise, farm: TFarmAprData, depositId: string, @@ -65,11 +36,7 @@ export const xykRedepositTx = ( depositId, ) -export const redepositTx = ( - api: ApiPromise, - farm: TFarmAprData, - depositId: string, -) => +const redepositTx = (api: ApiPromise, farm: TFarmAprData, depositId: string) => api.tx.omnipoolLiquidityMining.redepositShares( farm.globalFarmId, farm.yieldFarmId, @@ -98,14 +65,11 @@ export const getToasts = (value: BN, symbol: string) => type TArgs = { poolId: string farms: TFarmAprData[] - deposit?: TransactionOptions - redeposit?: TransactionOptions + options?: TransactionOptions } -export const useJoinFarms = ({ farms, deposit, redeposit, poolId }: TArgs) => { +export const useJoinFarms = ({ farms, poolId, options }: TArgs) => { const { api } = useRpcProvider() - const { account } = useAccount() - const isEvm = isEvmAccount(account?.address) const refetchAccountAssets = useRefetchAccountAssets() const { getAsset } = useAssets() @@ -113,26 +77,11 @@ export const useJoinFarms = ({ farms, deposit, redeposit, poolId }: TArgs) => { const meta = getAsset(poolId) - const getDepositId = async (nftId: string) => { - const positions = await api.query.uniques.account.entries( - account?.address, - nftId, - ) - - return positions - .map((position) => position[0].args[2].toNumber()) - .sort((a, b) => b - a)[0] - .toString() - } - return async (data: TJoinFarmsInput) => { if (!farms.length) throw new Error("There are no farms to join") if (!meta) throw new Error("Missing asset meta") const isXyk = isXYKData(data) - const [firstFarm, ...restFarms] = farms - - const isRestFarms = restFarms?.length const depositId = data.depositId const toast = getToasts( @@ -165,11 +114,11 @@ export const useJoinFarms = ({ farms, deposit, redeposit, poolId }: TArgs) => { }, { toast, - ...redeposit, + ...options, onSuccess: (result) => { refetchAccountAssets() - redeposit?.onSuccess?.(result) + options?.onSuccess?.(result) }, }, ) @@ -181,14 +130,23 @@ export const useJoinFarms = ({ farms, deposit, redeposit, poolId }: TArgs) => { if (isXyk) { const { assets } = meta as TShareToken - tx = xykDepositTx(api, firstFarm, data.shares, { - assetIn: assets[0].id, - assetOut: assets[1].id, - }) + tx = api.tx.xykLiquidityMining.joinFarms( + farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + { + assetIn: assets[0].id, + assetOut: assets[1].id, + }, + data.shares, + ) } else { - tx = depositTx(api, firstFarm, data.positionId) + tx = api.tx.omnipoolLiquidityMining.joinFarms( + farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + data.positionId, + ) } - const rewardCurrencySymbol = getAsset(firstFarm.rewardCurrency)?.symbol + + const [farm] = farms + const rewardCurrencySymbol = getAsset(farm.rewardCurrency)?.symbol await createTransaction( { @@ -199,34 +157,10 @@ export const useJoinFarms = ({ farms, deposit, redeposit, poolId }: TArgs) => { }, { toast, - ...deposit, + ...options, onSuccess: async (result) => { refetchAccountAssets() - deposit?.onSuccess?.(result) - - if (isRestFarms) { - let depositId: string | undefined = undefined - - const pallet = isXyk - ? "xykLiquidityMining" - : "omnipoolLiquidityMining" - - if (isEvm) { - const nftId = - await api.consts[pallet].nftCollectionId.toString() - depositId = await getDepositId(nftId) - } else { - for (const record of result.events) { - if (api.events[pallet].SharesDeposited.is(record.event)) { - depositId = record.event.data.depositId.toString() - } - } - } - - if (depositId) { - await executeRedeposit(depositId, restFarms) - } - } + options?.onSuccess?.(result) }, }, ) @@ -235,3 +169,11 @@ export const useJoinFarms = ({ farms, deposit, redeposit, poolId }: TArgs) => { } } } + +export const useRedepositFarms = ({ + farms, + poolId, +}: { + farms: TFarmAprData[] + poolId: string +}) => {} From f3e2b551ca5b7cfec24fcd69e333f5446f46734a Mon Sep 17 00:00:00 2001 From: vkulinich Date: Thu, 7 Nov 2024 15:23:16 +0100 Subject: [PATCH 02/10] use joinFarms extrinsic when adding liquidity --- .../components/detailsCard/FarmDetailsRow.tsx | 2 +- .../modals/AddLiquidity/AddLiquidity.tsx | 130 +----------- .../modals/AddLiquidity/AddLiquidity.utils.ts | 40 ++-- .../modals/AddLiquidity/AddLiquidityForm.tsx | 7 +- .../AddLiquidity/AddLiquidityFormXYK.tsx | 195 +++++++----------- .../transfer/AddStablepoolLiquidity.tsx | 64 ++---- .../stablepool/transfer/TransferModal.tsx | 108 ++-------- src/sections/pools/table/PoolsTable.utils.tsx | 20 +- 8 files changed, 150 insertions(+), 416 deletions(-) diff --git a/src/sections/pools/farms/components/detailsCard/FarmDetailsRow.tsx b/src/sections/pools/farms/components/detailsCard/FarmDetailsRow.tsx index a3cd7c102..ef3cb3fa0 100644 --- a/src/sections/pools/farms/components/detailsCard/FarmDetailsRow.tsx +++ b/src/sections/pools/farms/components/detailsCard/FarmDetailsRow.tsx @@ -50,7 +50,7 @@ export const FarmDetailsRow = ({ farm }: FarmDetailsRowProps) => { />
- {BN(farm.apr).gt(0) && t("value.APR", { apr: BN(farm.apr) })} + {t("value.APR", { apr: BN(farm.apr) })}
diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx index d0518dbaa..bcf7174bd 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidity.tsx @@ -1,142 +1,32 @@ import { Modal } from "components/Modal/Modal" import { useModalPagination } from "components/Modal/Modal.utils" -import { - LoadingPage, - ModalContents, -} from "components/Modal/contents/ModalContents" +import { ModalContents } from "components/Modal/contents/ModalContents" import { useState } from "react" import { useTranslation } from "react-i18next" import { AssetsModalContent } from "sections/assets/AssetsModal" import { AddLiquidityForm } from "./AddLiquidityForm" import { isXYKPoolType } from "sections/pools/PoolsPage.utils" import { AddLiquidityFormXYK } from "./AddLiquidityFormXYK" -import { getStepState, Stepper } from "components/Stepper/Stepper" -import { useRpcProvider } from "providers/rpcProvider" -import { ISubmittableResult } from "@polkadot/types/types" -import { useJoinFarms } from "utils/farms/deposit" -import { useRefetchAccountAssets } from "api/deposits" -import { isEvmAccount } from "utils/evm" -import { useAccount } from "sections/web3-connect/Web3Connect.utils" -import { scaleHuman } from "utils/balance" import { usePoolData } from "sections/pools/pool/Pool" export enum Page { ADD_LIQUIDITY, ASSET_SELECTOR, - WAIT, } -type Props = { +type AddLiquidityProps = { isOpen: boolean onClose: () => void } -export const AddLiquidity = ({ isOpen, onClose }: Props) => { - const { api } = useRpcProvider() +export const AddLiquidity = ({ isOpen, onClose }: AddLiquidityProps) => { const { pool } = usePoolData() const { t } = useTranslation() - const { account } = useAccount() - const { page, direction, back, paginateTo } = useModalPagination() - const refetch = useRefetchAccountAssets() - const isEvm = isEvmAccount(account?.address) - const farms = pool.farms - - const [assetId, setAssetId] = useState(pool.id) - const [currentStep, setCurrentStep] = useState(0) - const [isJoinFarms, setIsJoinFarms] = useState(farms.length > 0) + const { page, direction, back } = useModalPagination() + const [assetId, setAssetId] = useState(pool.id) + const farms = pool.farms const isXYK = isXYKPoolType(pool) - const willJoinFarms = farms.length > 0 && isJoinFarms - - // const joinFarms = useJoinFarms({ - // poolId: pool.id, - // farms, - // deposit: { - // onClose, - // disableAutoClose: farms.length > 1, - // onSuccess: () => { - // setCurrentStep(2) - // }, - // onError: onClose, - // }, - // redeposit: { - // onClose, - // onError: onClose, - // }, - // }) - - const onSuccess = async (result: ISubmittableResult, value: string) => { - if (willJoinFarms) { - let positionId: string | undefined - - if (isEvm) { - const nftId = await api.consts.omnipool.nftCollectionId.toString() - const positions = await api.query.uniques.account.entries( - account?.address, - nftId, - ) - - positionId = positions - .map((position) => position[0].args[2].toNumber()) - .sort((a, b) => b - a)[0] - .toString() - } else { - for (const record of result.events) { - if (api.events.omnipool.PositionCreated.is(record.event)) { - positionId = record.event.data.positionId.toString() - } - } - } - - if (positionId) { - setCurrentStep(1) - joinFarms({ positionId, value }) - } - } - refetch() - } - - const onXykSuccess = async ( - result: ISubmittableResult, - calculatedShares: string, - ) => { - if (willJoinFarms) { - setCurrentStep(1) - - let shares = "" - - if (!isEvm) { - for (const record of result.events) { - if (api.events.tokens.Deposited.is(record.event)) { - if (record.event.data.currencyId.toString() === pool.id) { - shares = record.event.data.amount.toString() - } - } - } - } else { - const balance = await api.query.tokens.accounts( - account?.address ?? "", - pool.id, - ) - - const free = balance.free.toBigNumber() - const diff = scaleHuman(free, pool.meta.decimals) - .minus(scaleHuman(calculatedShares, pool.meta.decimals)) - .abs() - - // go with the whole balance - if (diff.lt(0.1)) { - shares = free.toString() - } else { - shares = calculatedShares - } - } - - if (shares) { - joinFarms({ shares }) - } - } - } return ( @@ -149,13 +39,7 @@ export const AddLiquidity = ({ isOpen, onClose }: Props) => { { title: t("liquidity.add.modal.title"), content: isXYK ? ( - paginateTo(Page.WAIT)} - setIsJoinFarms={setIsJoinFarms} - /> + ) : ( { - const txs = [api.tx.omnipool.addLiquidity("0", "1")] - const [firstFarm, ...restFarm] = farms - - if (firstFarm) - txs.push( - api.tx.omnipoolLiquidityMining.depositShares( - firstFarm.globalFarmId, - firstFarm.yieldFarmId, - "0", - ), - ) - - if (restFarm.length) { - const restFarmTxs = restFarm.map((farm) => - api.tx.omnipoolLiquidityMining.redepositShares( - farm.globalFarmId, - farm.yieldFarmId, +export const getAddToOmnipoolFee = ( + api: ApiPromise, + isJoinFarms: boolean, + farms: TFarmAprData[], +) => { + const tx = isJoinFarms + ? api.tx.omnipoolLiquidityMining.addLiquidityAndJoinFarms( + farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), "0", - ), - ) - - txs.push( - restFarmTxs.length > 1 - ? api.tx.utility.batch(restFarmTxs) - : restFarmTxs[0], - ) - } + "1", + ) + : api.tx.omnipool.addLiquidity("0", "1") - return txs + return [tx] } const getSharesToGet = ( diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx index ca1754ca1..24ae552f1 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx @@ -30,6 +30,7 @@ import { ISubmittableResult } from "@polkadot/types/types" import { useEffect, useState } from "react" import { useAssets } from "providers/assets" import { JoinFarmsSection } from "./components/JoinFarmsSection/JoinFarmsSection" +import { useRefetchAccountAssets } from "api/deposits" type Props = { assetId: string @@ -54,6 +55,7 @@ export const AddLiquidityForm = ({ const { createTransaction } = useStore() const isFarms = farms.length > 0 const [isJoinFarms, setIsJoinFarms] = useState(isFarms) + const refetchAccountAssets = useRefetchAccountAssets() const zodSchema = useAddToOmnipoolZod(assetId, farms) const form = useForm<{ @@ -71,7 +73,9 @@ export const AddLiquidityForm = ({ const { poolShare, spotPrice, omnipoolFee, assetMeta, assetBalance } = useAddLiquidity(assetId, debouncedAmount) - const estimatedFees = useEstimatedFees(getAddToOmnipoolFee(api, farms)) + const estimatedFees = useEstimatedFees( + getAddToOmnipoolFee(api, isJoinFarms, farms), + ) const balance = assetBalance?.balance ?? BN_0 const balanceMax = @@ -98,6 +102,7 @@ export const AddLiquidityForm = ({ }, { onSuccess: (result) => { + refetchAccountAssets() onSuccess?.(result, amount) }, onSubmitted: () => { diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx index 0724fa16c..5c5ef80d8 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx @@ -1,36 +1,39 @@ -import { Controller, FieldErrors, useForm } from "react-hook-form" +import { Controller, useForm } from "react-hook-form" import BigNumber from "bignumber.js" import { BN_0, BN_1 } from "utils/constants" import { WalletTransferAssetSelect } from "sections/wallet/transfer/WalletTransferAssetSelect" import { SummaryRow } from "components/Summary/SummaryRow" import { Spacer } from "components/Spacer/Spacer" import { Text } from "components/Typography/Text/Text" -import { Trans, useTranslation } from "react-i18next" +import { useTranslation } from "react-i18next" import { PoolAddLiquidityInformationCard } from "./AddLiquidityInfoCard" import { Separator } from "components/Separator/Separator" import { Button } from "components/Button/Button" import { scale, scaleHuman } from "utils/balance" -import { ToastMessage, useStore } from "state/store" -import { BaseSyntheticEvent, useCallback, useMemo } from "react" +import { useStore } from "state/store" +import { useCallback, useEffect, useMemo, useState } from "react" import { useRpcProvider } from "providers/rpcProvider" import { useSpotPrice } from "api/spotPrice" import { TXYKPool } from "sections/pools/PoolsPage.utils" import { TokensConversion } from "./components/TokensConvertion/TokensConversion" import { useTokensBalances } from "api/balances" -import * as xyk from "@galacticcouncil/math-xyk" +import { + calculate_shares, + calculate_liquidity_in, +} from "@galacticcouncil/math-xyk" import { getXYKPoolShare, useXYKZodSchema } from "./AddLiquidity.utils" import { zodResolver } from "@hookform/resolvers/zod" -import { TOAST_MESSAGES } from "state/toasts" +import { createToastMessages } from "state/toasts" import { Alert } from "components/Alert/Alert" import { ISubmittableResult } from "@polkadot/types/types" import { useRefetchAccountAssets } from "api/deposits" +import { JoinFarmsSection } from "./components/JoinFarmsSection/JoinFarmsSection" type Props = { onClose: () => void pool: TXYKPool - onSuccess: (result: ISubmittableResult, shares: string) => void + onSuccess?: (result: ISubmittableResult, shares: string) => void onSubmitted?: () => void - setIsJoinFarms: (value: boolean) => void } type FormValues = { @@ -44,19 +47,19 @@ type FormValues = { const opposite = (value: "assetA" | "assetB") => value === "assetA" ? "assetB" : "assetA" -export const AddLiquidityFormXYK = ({ - pool, - onClose, - onSuccess, - onSubmitted, - setIsJoinFarms, -}: Props) => { +export const AddLiquidityFormXYK = ({ pool, onClose, onSuccess }: Props) => { const { t } = useTranslation() - const refetch = useRefetchAccountAssets() + const refetchAccountAssets = useRefetchAccountAssets() + const { api } = useRpcProvider() + const { createTransaction } = useStore() - const { assets, decimals } = pool.meta + const { + meta: { assets, decimals }, + farms = [], + } = pool const [assetA, assetB] = assets - const farms = pool.farms ?? [] + const isFarms = farms.length > 0 + const [isJoinFarms, setIsJoinFarms] = useState(isFarms) const { zodSchema, balanceAMax, balanceBMax, balanceA, balanceB } = useXYKZodSchema(assetA, assetB, pool.meta, farms) @@ -72,7 +75,7 @@ export const AddLiquidityFormXYK = ({ resolver: zodSchema ? zodResolver(zodSchema) : undefined, }) - const { formState } = form + const { formState, reset } = form const spotPrice = useSpotPrice(assetA.id, assetB.id) const [{ data: assetAReserve }, { data: assetBReserve }] = useTokensBalances( @@ -104,14 +107,7 @@ export const AddLiquidityFormXYK = ({ } }, [assetA, assetAReserve, assetB, assetBReserve, assetValueA, assetValueB]) - const { api } = useRpcProvider() - const { createTransaction } = useStore() - - const onSubmit = async (_: FormValues, e?: BaseSyntheticEvent) => { - const submitAction = (e?.nativeEvent as SubmitEvent) - ?.submitter as HTMLButtonElement - const isJoiningFarms = submitAction?.name === "joinFarms" - + const onSubmit = async () => { const inputData = { assetA: { id: assetValues[lastUpdated].meta.id, @@ -129,66 +125,46 @@ export const AddLiquidityFormXYK = ({ }, } - const toast = TOAST_MESSAGES.reduce((memo, type) => { - const msType = type === "onError" ? "onLoading" : type - memo[type] = ( - - - - - ) - return memo - }, {} as ToastMessage) - return await createTransaction( { - tx: api.tx.xyk.addLiquidity( - inputData.assetA.id, - inputData.assetB.id, - inputData.assetA.amount.toFixed(), - inputData.assetB.amount.toFixed(), - ), + tx: isJoinFarms + ? api.tx.xykLiquidityMining.addLiquidityAndJoinFarms( + inputData.assetA.id, + inputData.assetB.id, + inputData.assetA.amount.toFixed(), + inputData.assetB.amount.toFixed(), + farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + ) + : api.tx.xyk.addLiquidity( + inputData.assetA.id, + inputData.assetB.id, + inputData.assetA.amount.toFixed(), + inputData.assetB.amount.toFixed(), + ), }, { onSuccess: (result) => { - refetch() - onSuccess(result, scale(shares, decimals).toString()) + refetchAccountAssets() + onSuccess?.(result, scale(shares, decimals).toString()) }, onSubmitted: () => { - !farms.length && !isJoiningFarms && onClose() - form.reset() - onSubmitted?.() + onClose() + reset() }, onClose, - disableAutoClose: !!farms.length && isJoiningFarms, onBack: () => {}, - toast, + toast: createToastMessages("liquidity.add.modal.xyk.toast", { + t, + tOptions: { + shares: shares, + fixedPointScale: decimals, + }, + components: ["span", "span.highlight"], + }), }, ) } - const onInvalidSubmit = ( - errors: FieldErrors, - e?: BaseSyntheticEvent, - ) => { - const submitAction = (e?.nativeEvent as SubmitEvent) - ?.submitter as HTMLButtonElement - - if ( - submitAction?.name === "addLiquidity" && - (errors.shares as { farm?: { message: string } }).farm - ) { - onSubmit({} as FormValues, e) - } - } - const handleChange = useCallback( (value: string, name: "assetA" | "assetB") => { const assetDecimals = assetValues[name].meta.decimals @@ -199,7 +175,7 @@ export const AddLiquidityFormXYK = ({ if (currReserves && nextReserves) { const pairTokenValue = scaleHuman( - xyk.calculate_liquidity_in( + calculate_liquidity_in( currReserves.balance.toFixed(), nextReserves.balance.toFixed(), scale(value, assetDecimals).toFixed(), @@ -217,7 +193,7 @@ export const AddLiquidityFormXYK = ({ const { totalShare } = pool.shareTokenIssuance ?? {} if (assetAReserve && totalShare) { - const shares = xyk.calculate_shares( + const shares = calculate_shares( assetAReserve.balance.toString(), scale(form.getValues("assetA"), assetA.decimals).toFixed(), totalShare.toString(), @@ -250,15 +226,26 @@ export const AddLiquidityFormXYK = ({ } | undefined - const isAddOnlyLiquidityDisabled = + const isJoinFarmDisabled = !!customErrors?.farm + + const isSubmitDisabled = !!Object.keys(formState.errors.shares ?? {}).filter((key) => key !== "farm") .length || !!formState.errors.assetA || !!formState.errors.assetB + useEffect(() => { + if (!isFarms) return + if (isJoinFarmDisabled) { + setIsJoinFarms(false) + } else { + setIsJoinFarms(true) + } + }, [isFarms, isJoinFarmDisabled, setIsJoinFarms]) + return ( + {farms.length > 0 ? ( + + ) : null} + {t("liquidity.add.modal.positionDetails")} @@ -332,7 +329,7 @@ export const AddLiquidityFormXYK = ({ label="Received amount of Pool Shares:" content={t("value.token", { value: shares, - fixedPointScale: decimals, + //fixedPointScale: decimals, })} /> @@ -358,43 +355,11 @@ export const AddLiquidityFormXYK = ({ width: "auto", }} /> - {farms.length ? ( -
- - -
- ) : ( - - )} + ) } diff --git a/src/sections/pools/stablepool/transfer/AddStablepoolLiquidity.tsx b/src/sections/pools/stablepool/transfer/AddStablepoolLiquidity.tsx index 4a4e961b3..1251f0a65 100644 --- a/src/sections/pools/stablepool/transfer/AddStablepoolLiquidity.tsx +++ b/src/sections/pools/stablepool/transfer/AddStablepoolLiquidity.tsx @@ -27,27 +27,23 @@ import { getAddToOmnipoolFee, useAddToOmnipoolZod, } from "sections/pools/modals/AddLiquidity/AddLiquidity.utils" -import { TFarmAprData } from "api/farms" import { scale } from "utils/balance" import { Alert } from "components/Alert/Alert" import { useEffect } from "react" -import { Switch } from "components/Switch/Switch" -import { FarmDetailsRow } from "sections/pools/farms/components/detailsCard/FarmDetailsRow" import { Separator } from "components/Separator/Separator" import { useAccountAssets } from "api/deposits" +import { JoinFarmsSection } from "sections/pools/modals/AddLiquidity/components/JoinFarmsSection/JoinFarmsSection" +import { usePoolData } from "sections/pools/pool/Pool" +import { TPoolFullData } from "sections/pools/PoolsPage.utils" type Props = { - poolId: string - fee: BigNumber asset: TAsset onSuccess: (result: ISubmittableResult, shares: string) => void onClose: () => void onCancel: () => void onAssetOpen: () => void onSubmitted: (shares?: string) => void - reserves: { asset_id: number; amount: string }[] isStablepoolOnly: boolean - farms: TFarmAprData[] isJoinFarms: boolean setIsJoinFarms: (value: boolean) => void } @@ -58,23 +54,25 @@ const createFormSchema = (balance: BigNumber, decimals: number) => }) export const AddStablepoolLiquidity = ({ - poolId, asset, onSuccess, onAssetOpen, onSubmitted, onClose, onCancel, - reserves, - fee, isStablepoolOnly, - farms, isJoinFarms, setIsJoinFarms, }: Props) => { const { api } = useRpcProvider() const { createTransaction } = useStore() const accountBalances = useAccountAssets() + const { + reserves, + stablepoolFee: fee = BN_0, + farms, + id: poolId, + } = usePoolData().pool as TPoolFullData const { t } = useTranslation() @@ -88,7 +86,7 @@ export const AddStablepoolLiquidity = ({ api.tx.stableswap.addLiquidity(poolId, [ { assetId: asset.id, amount: "1" }, ]), - ...(!isStablepoolOnly ? getAddToOmnipoolFee(api, farms) : []), + ...(!isStablepoolOnly ? getAddToOmnipoolFee(api, isJoinFarms, farms) : []), ] const estimatedFees = useEstimatedFees(estimationTxs) @@ -256,39 +254,15 @@ export const AddStablepoolLiquidity = ({ width: "auto", }} /> - {farms.length > 0 && !isStablepoolOnly && ( - <> - - - {isJoinFarms ? t("yes") : t("no")} - - -
- } - /> - {isJoinFarms && ( -
- {farms.map((farm) => ( - - ))} -
- )} - {customErrors?.farm && ( - - {customErrors.farm.message} - - )} - - )} + {farms.length > 0 ? ( + + ) : null} diff --git a/src/sections/pools/stablepool/transfer/TransferModal.tsx b/src/sections/pools/stablepool/transfer/TransferModal.tsx index c1f8870c5..401b96f05 100644 --- a/src/sections/pools/stablepool/transfer/TransferModal.tsx +++ b/src/sections/pools/stablepool/transfer/TransferModal.tsx @@ -14,10 +14,9 @@ import { AddLiquidityForm } from "sections/pools/modals/AddLiquidity/AddLiquidit import { useRpcProvider } from "providers/rpcProvider" import { useModalPagination } from "components/Modal/Modal.utils" import { TPoolFullData } from "sections/pools/PoolsPage.utils" -import { BN_0, STABLEPOOL_TOKEN_DECIMALS } from "utils/constants" +import { STABLEPOOL_TOKEN_DECIMALS } from "utils/constants" import { useAccount } from "sections/web3-connect/Web3Connect.utils" import { TFarmAprData } from "api/farms" -import { useJoinFarms } from "utils/farms/deposit" import { ISubmittableResult } from "@polkadot/types/types" import { useRefetchAccountAssets } from "api/deposits" import { useStore } from "state/store" @@ -51,13 +50,7 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { const isEvm = isEvmAccount(account?.address) const [isJoinFarms, setIsJoinFarms] = useState(farms.length > 0) - const { - id: poolId, - reserves, - stablepoolFee: fee, - canAddLiquidity, - meta, - } = pool as TPoolFullData + const { id: poolId, canAddLiquidity, meta } = pool as TPoolFullData const assets = Object.keys(pool.meta.meta ?? {}) @@ -75,41 +68,6 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { const isOptionsPage = defaultPage === Page.OPTIONS const isOnlyStablepool = selectedOption === "STABLEPOOL" const isAddingToOmnipool = defaultPage === Page.MOVE_TO_OMNIPOOL - const isVisibleStepper = farms.length > 0 || !isAddingToOmnipool - const willJoinFarms = farms.length > 0 && isJoinFarms - const isMultipleFarms = farms.length > 1 - - const joinFarms = useJoinFarms({ - poolId: pool.id, - farms, - deposit: { - onClose, - disableAutoClose: isMultipleFarms, - onSuccess: () => { - setCurrentStep(currentStep + 1) - }, - onError: () => onClose(), - }, - redeposit: { - onClose, - onError: () => onClose(), - }, - }) - - const farmSteps = [ - { - label: t("farms.modal.join.first"), - loadingLabel: t("farms.modal.join.first.loading"), - }, - ...(isMultipleFarms - ? [ - { - label: t("farms.modal.join.rest"), - loadingLabel: t("farms.modal.join.rest.loading"), - }, - ] - : []), - ] const steps = [ ...(isOptionsPage @@ -135,46 +93,9 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { label: t("liquidity.stablepool.transfer.move"), loadingLabel: t("liquidity.stablepool.transfer.adding"), }, - ...(willJoinFarms ? farmSteps : []), ]), ] - const onAddToOmnipoolSuccess = async ( - result: ISubmittableResult, - value: string, - ) => { - refetch() - if (willJoinFarms) { - let positionId: string | undefined - - if (isEvm) { - const nftId = await api.consts.omnipool.nftCollectionId.toString() - const positions = await api.query.uniques.account.entries( - account?.address, - nftId, - ) - - positionId = positions - .map((position) => position[0].args[2].toNumber()) - .sort((a, b) => b - a)[0] - .toString() - } else { - for (const record of result.events) { - if (api.events.omnipool.PositionCreated.is(record.event)) { - positionId = record.event.data.positionId.toString() - } - } - } - - if (positionId) { - setCurrentStep((step) => step + 1) - joinFarms({ positionId, value }) - } else { - onClose() - } - } - } - const onAddToStablepoolSuccess = async ( result: ISubmittableResult, calculatedShares: string, @@ -210,19 +131,24 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { if (shares) { await createTransaction( { - tx: api.tx.omnipool.addLiquidity(pool.id, shares), + tx: isJoinFarms + ? api.tx.omnipoolLiquidityMining.addLiquidityAndJoinFarms( + farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + assetId, + shares, + ) + : api.tx.omnipool.addLiquidity(pool.id, shares), title: t("liquidity.stablepool.transfer.move"), }, { - onSuccess: (result) => { - onAddToOmnipoolSuccess(result, shares) + onSuccess: () => { + refetch() }, onSubmitted: () => { - !willJoinFarms && onClose() + onClose() }, onError: () => onClose(), onClose, - disableAutoClose: !!willJoinFarms, toast: createToastMessages("liquidity.add.modal.toast", { t, tOptions: { @@ -257,7 +183,7 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { onClose={onClose} disableCloseOutside={true} topContent={ - isVisibleStepper && steps.length > 1 ? ( + steps.length > 1 ? ( ({ @@ -308,9 +234,7 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { content: ( { if (isOnlyStablepool) { @@ -330,10 +254,8 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { onAddToStablepoolSuccess(result, shares) paginateTo(Page.WAIT) }} - reserves={reserves} onAssetOpen={() => paginateTo(Page.ASSETS)} asset={getAssetWithFallback(assetId ?? poolId)} - fee={fee ?? BN_0} isJoinFarms={isJoinFarms && !isOnlyStablepool} setIsJoinFarms={setIsJoinFarms} /> @@ -353,10 +275,6 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { assetId={poolId} onClose={onClose} farms={farms} - onSuccess={onAddToOmnipoolSuccess} - onSubmitted={() => paginateTo(Page.WAIT)} - isJoinFarms={isJoinFarms} - setIsJoinFarms={setIsJoinFarms} /> ), }, diff --git a/src/sections/pools/table/PoolsTable.utils.tsx b/src/sections/pools/table/PoolsTable.utils.tsx index 33807809b..bba5e7662 100644 --- a/src/sections/pools/table/PoolsTable.utils.tsx +++ b/src/sections/pools/table/PoolsTable.utils.tsx @@ -45,6 +45,7 @@ import { Page, TransferModal, } from "sections/pools/stablepool/transfer/TransferModal" +import { AddLiquidity } from "sections/pools/modals/AddLiquidity/AddLiquidity" const NonClickableContainer = ({ children, @@ -206,6 +207,7 @@ const LiquidityModalWrapper: React.FC<{ const poolDetails = usePoolDetails(pool.id) if (!pool) return null + return ( - + {pool.meta.isStableSwap ? ( + + ) : ( + + )} ) } @@ -502,7 +506,7 @@ export const usePoolTable = ( justify: "end", }} > - {!isXyk && } + Date: Tue, 3 Dec 2024 11:51:53 +0100 Subject: [PATCH 03/10] fix lint --- src/components/Layout/Page/Page.tsx | 2 -- src/sections/lending/ui/reserve-overview/EModeInfo.tsx | 1 - .../pools/modals/AddLiquidity/AddLiquidity.utils.ts | 5 ++++- .../pools/modals/AddLiquidity/AddLiquidityForm.tsx | 5 ++++- .../pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx | 5 ++++- .../pools/stablepool/transfer/TransferModal.tsx | 7 +++++-- src/utils/farms/deposit.tsx | 10 ++++++++-- 7 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/components/Layout/Page/Page.tsx b/src/components/Layout/Page/Page.tsx index cab8073e6..8ecf27166 100644 --- a/src/components/Layout/Page/Page.tsx +++ b/src/components/Layout/Page/Page.tsx @@ -23,7 +23,6 @@ import { } from "./Page.styled" import { useControlScroll } from "./Page.utils" import { usePreviousUrl } from "hooks/usePreviousUrl" -import { useRpcProvider } from "providers/rpcProvider" type Props = { className?: string @@ -51,7 +50,6 @@ const useSubheaderComponent = () => { const matchRoute = useMatchRoute() const search = useSearch() const isDesktop = useMedia(theme.viewport.gte.sm) - const { featureFlags } = useRpcProvider() const prevUrl = usePreviousUrl() diff --git a/src/sections/lending/ui/reserve-overview/EModeInfo.tsx b/src/sections/lending/ui/reserve-overview/EModeInfo.tsx index 7a97c872e..ec0f5b2bd 100644 --- a/src/sections/lending/ui/reserve-overview/EModeInfo.tsx +++ b/src/sections/lending/ui/reserve-overview/EModeInfo.tsx @@ -1,7 +1,6 @@ import { DataValue, DataValueList } from "components/DataValue" import { Text } from "components/Typography/Text/Text" import { PercentageValue } from "components/PercentageValue" -import { ROUTES } from "sections/lending/components/primitives/Link" import { getEmodeMessage } from "sections/lending/components/transactions/Emode/EmodeNaming" import { ComputedReserveData } from "sections/lending/hooks/app-data-provider/useAppDataProvider" diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidity.utils.ts b/src/sections/pools/modals/AddLiquidity/AddLiquidity.utils.ts index 1f577d40a..a5c17a3b1 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidity.utils.ts +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidity.utils.ts @@ -37,7 +37,10 @@ export const getAddToOmnipoolFee = ( ) => { const tx = isJoinFarms ? api.tx.omnipoolLiquidityMining.addLiquidityAndJoinFarms( - farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + farms.map<[string, string]>((farm) => [ + farm.globalFarmId, + farm.yieldFarmId, + ]), "0", "1", ) diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx index a85bf53b0..3e7785422 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx @@ -94,7 +94,10 @@ export const AddLiquidityForm = ({ { tx: isJoinFarms ? api.tx.omnipoolLiquidityMining.addLiquidityAndJoinFarms( - farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + farms.map<[string, string]>((farm) => [ + farm.globalFarmId, + farm.yieldFarmId, + ]), assetId, amount, ) diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx index ce2a70bea..55c410bf7 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx @@ -133,7 +133,10 @@ export const AddLiquidityFormXYK = ({ pool, onClose, onSuccess }: Props) => { inputData.assetB.id, inputData.assetA.amount.toFixed(), inputData.assetB.amount.toFixed(), - farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + farms.map<[string, string]>((farm) => [ + farm.globalFarmId, + farm.yieldFarmId, + ]), ) : api.tx.xyk.addLiquidity( inputData.assetA.id, diff --git a/src/sections/pools/stablepool/transfer/TransferModal.tsx b/src/sections/pools/stablepool/transfer/TransferModal.tsx index 401b96f05..524ef556b 100644 --- a/src/sections/pools/stablepool/transfer/TransferModal.tsx +++ b/src/sections/pools/stablepool/transfer/TransferModal.tsx @@ -128,12 +128,15 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { } } - if (shares) { + if (shares && assetId) { await createTransaction( { tx: isJoinFarms ? api.tx.omnipoolLiquidityMining.addLiquidityAndJoinFarms( - farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + farms.map<[string, string]>((farm) => [ + farm.globalFarmId, + farm.yieldFarmId, + ]), assetId, shares, ) diff --git a/src/utils/farms/deposit.tsx b/src/utils/farms/deposit.tsx index 632f543ac..3ceff2bc0 100644 --- a/src/utils/farms/deposit.tsx +++ b/src/utils/farms/deposit.tsx @@ -131,7 +131,10 @@ export const useJoinFarms = ({ farms, poolId, options }: TArgs) => { const { assets } = meta as TShareToken tx = api.tx.xykLiquidityMining.joinFarms( - farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + farms.map<[string, string]>((farm) => [ + farm.globalFarmId, + farm.yieldFarmId, + ]), { assetIn: assets[0].id, assetOut: assets[1].id, @@ -140,7 +143,10 @@ export const useJoinFarms = ({ farms, poolId, options }: TArgs) => { ) } else { tx = api.tx.omnipoolLiquidityMining.joinFarms( - farms.map((farm) => [farm.globalFarmId, farm.yieldFarmId]), + farms.map<[string, string]>((farm) => [ + farm.globalFarmId, + farm.yieldFarmId, + ]), data.positionId, ) } From 9fb2c5b1d4b302b0c5286b8049400fc998bfbee4 Mon Sep 17 00:00:00 2001 From: vkulinich Date: Tue, 3 Dec 2024 12:06:09 +0100 Subject: [PATCH 04/10] wip --- .../pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx index 55c410bf7..d563ff45c 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx @@ -329,7 +329,7 @@ export const AddLiquidityFormXYK = ({ pool, onClose, onSuccess }: Props) => { label="Received amount of Pool Shares:" content={t("value.token", { value: shares, - //fixedPointScale: decimals, + fixedPointScale: decimals, })} /> @@ -338,11 +338,6 @@ export const AddLiquidityFormXYK = ({ pool, onClose, onSuccess }: Props) => { {t("liquidity.xyk.addLiquidity.warning")} )} - {customErrors?.farm && ( - - {customErrors.farm.message} - - )} From d04089a6401ae2c50987abb4dadf4d71e6f88b5f Mon Sep 17 00:00:00 2001 From: vkulinich Date: Tue, 3 Dec 2024 13:05:07 +0100 Subject: [PATCH 05/10] improvements --- src/components/AssetInput/AssetInput.tsx | 4 +- src/components/AssetSelect/AssetSelect.tsx | 20 ++++++--- .../pools/farms/position/FarmingPosition.tsx | 43 +++++++++++-------- src/utils/farms/deposit.tsx | 6 ++- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/components/AssetInput/AssetInput.tsx b/src/components/AssetInput/AssetInput.tsx index 9675fb0fe..bdf884489 100644 --- a/src/components/AssetInput/AssetInput.tsx +++ b/src/components/AssetInput/AssetInput.tsx @@ -17,7 +17,7 @@ export type AssetInputProps = { onChange: (val: string) => void name: string label: string - displayValue?: BigNumber | 0 | null + displayValue?: string unit?: Maybe type?: string placeholder?: string @@ -56,7 +56,7 @@ export const AssetInput = forwardRef( {props.displayValue != null ? ( - ≈ + ≈ ) : null} diff --git a/src/components/AssetSelect/AssetSelect.tsx b/src/components/AssetSelect/AssetSelect.tsx index 36ef6a53a..851f71930 100644 --- a/src/components/AssetSelect/AssetSelect.tsx +++ b/src/components/AssetSelect/AssetSelect.tsx @@ -7,7 +7,7 @@ import React, { forwardRef, ReactNode, useMemo } from "react" import { useTranslation } from "react-i18next" import { theme } from "theme" import { getFloatingPointAmount } from "utils/balance" -import { useDisplayPrice } from "utils/displayAsset" +import { useDisplayPrice, useDisplayShareTokenPrice } from "utils/displayAsset" import { Maybe } from "utils/helpers" import { SContainer, SMaxButton } from "./AssetSelect.styled" import { AssetSelectButton } from "./AssetSelectButton" @@ -49,15 +49,23 @@ export const AssetSelect = forwardRef( const spotPriceId = isBond(asset) && !asset.isTradable ? asset.underlyingAssetId : asset.id + const { isShareToken } = asset - const spotPriceAsset = useDisplayPrice(spotPriceId) + const spotPriceAsset = useDisplayPrice( + isShareToken ? undefined : spotPriceId, + ) + const shareTokenSpotPrice = useDisplayShareTokenPrice( + isShareToken ? [spotPriceId] : [], + ) - const spotPrice = spotPriceAsset.data + const spotPrice = isShareToken + ? shareTokenSpotPrice.data?.[0].spotPrice + : spotPriceAsset.data?.spotPrice.toString() const displayValue = useMemo(() => { - if (!props.value) return 0 - if (spotPrice?.spotPrice == null) return null - return spotPrice.spotPrice.times(props.value) + if (!props.value || !spotPrice) return undefined + + return BigNumber(spotPrice).times(props.value).toString() }, [props.value, spotPrice]) return ( diff --git a/src/sections/pools/farms/position/FarmingPosition.tsx b/src/sections/pools/farms/position/FarmingPosition.tsx index a690cb390..d9440c636 100644 --- a/src/sections/pools/farms/position/FarmingPosition.tsx +++ b/src/sections/pools/farms/position/FarmingPosition.tsx @@ -165,23 +165,27 @@ export const FarmingPosition = ({ } }) - const totalRewardsValue = claimableAssets - .map((claimableAsset) => - t("value.tokenWithSymbol", { - value: claimableAsset.value.rewards, - symbol: claimableAsset.symbol, - }), - ) - .join(" + ") - - const maxTotalRewardsValue = claimableAssets - .map((claimableAsset) => - t("value.tokenWithSymbol", { - value: BigNumber(claimableAsset.value.maxRewards), - symbol: claimableAsset.symbol, - }), - ) - .join(" + ") + const totalRewardsValue = claimableAssets.length + ? claimableAssets + .map((claimableAsset) => + t("value.tokenWithSymbol", { + value: claimableAsset.value.rewards, + symbol: claimableAsset.symbol, + }), + ) + .join(" + ") + : "0" + + const maxTotalRewardsValue = claimableAssets.length + ? claimableAssets + .map((claimableAsset) => + t("value.tokenWithSymbol", { + value: BigNumber(claimableAsset.value.maxRewards), + symbol: claimableAsset.symbol, + }), + ) + .join(" + ") + : "0" // use latest entry date const enteredDate = useEnteredDate( @@ -341,7 +345,10 @@ export const FarmingPosition = ({ )}
{isDesktop && ( - + {totalRewardsValue} )} diff --git a/src/utils/farms/deposit.tsx b/src/utils/farms/deposit.tsx index 3ceff2bc0..10bfb283f 100644 --- a/src/utils/farms/deposit.tsx +++ b/src/utils/farms/deposit.tsx @@ -1,4 +1,4 @@ -import { TFarmAprData } from "api/farms" +import { TFarmAprData, useAccountClaimableFarmValues } from "api/farms" import { Trans } from "react-i18next" import { ToastMessage, TransactionOptions, useStore } from "state/store" import { useRpcProvider } from "providers/rpcProvider" @@ -72,6 +72,7 @@ export const useJoinFarms = ({ farms, poolId, options }: TArgs) => { const { api } = useRpcProvider() const refetchAccountAssets = useRefetchAccountAssets() const { getAsset } = useAssets() + const { refetch: refetchClaimableValues } = useAccountClaimableFarmValues() const { createTransaction } = useStore() @@ -117,7 +118,7 @@ export const useJoinFarms = ({ farms, poolId, options }: TArgs) => { ...options, onSuccess: (result) => { refetchAccountAssets() - + refetchClaimableValues() options?.onSuccess?.(result) }, }, @@ -166,6 +167,7 @@ export const useJoinFarms = ({ farms, poolId, options }: TArgs) => { ...options, onSuccess: async (result) => { refetchAccountAssets() + refetchClaimableValues() options?.onSuccess?.(result) }, }, From 83864d40ae1a3cc0ad9a0cde105b8e92f4e94d70 Mon Sep 17 00:00:00 2001 From: vkulinich Date: Tue, 3 Dec 2024 14:41:33 +0100 Subject: [PATCH 06/10] fix lint --- src/components/AssetSelect/AssetSelectSkeleton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/AssetSelect/AssetSelectSkeleton.tsx b/src/components/AssetSelect/AssetSelectSkeleton.tsx index 78eda2594..2b3dded0d 100644 --- a/src/components/AssetSelect/AssetSelectSkeleton.tsx +++ b/src/components/AssetSelect/AssetSelectSkeleton.tsx @@ -68,7 +68,7 @@ export const AssetSelectSkeleton = (props: { name={props.name} label={t("selectAsset.input.label")} onChange={() => null} - displayValue={0} + displayValue="0" placeholder="0.00" unit="HDX" css={css` From 5f9b0a1936719854ebbf9b6d1d902124492c9418 Mon Sep 17 00:00:00 2001 From: vkulinich Date: Fri, 6 Dec 2024 16:32:32 +0100 Subject: [PATCH 07/10] fix stableswap --- src/sections/pools/stablepool/transfer/TransferModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sections/pools/stablepool/transfer/TransferModal.tsx b/src/sections/pools/stablepool/transfer/TransferModal.tsx index 524ef556b..000ce0f92 100644 --- a/src/sections/pools/stablepool/transfer/TransferModal.tsx +++ b/src/sections/pools/stablepool/transfer/TransferModal.tsx @@ -137,7 +137,7 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { farm.globalFarmId, farm.yieldFarmId, ]), - assetId, + pool.id, shares, ) : api.tx.omnipool.addLiquidity(pool.id, shares), From 194e0d1194a9c588f3b010f803a4154139dd1d97 Mon Sep 17 00:00:00 2001 From: vkulinich Date: Wed, 11 Dec 2024 14:52:17 +0100 Subject: [PATCH 08/10] fix --- .../pools/modals/AddLiquidity/AddLiquidityForm.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx index 3e7785422..3bef15d19 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx @@ -1,4 +1,4 @@ -import { Controller, useForm } from "react-hook-form" +import { Controller, FieldErrors, useForm } from "react-hook-form" import BN from "bignumber.js" import { WalletTransferAssetSelect } from "sections/wallet/transfer/WalletTransferAssetSelect" import { SummaryRow } from "components/Summary/SummaryRow" @@ -136,6 +136,15 @@ export const AddLiquidityForm = ({ } | undefined + const onInvalidSubmit = (errors: FieldErrors>) => { + if ( + !isJoinFarms && + (errors.amount as { farm?: { message: string } }).farm + ) { + onSubmit(form.getValues()) + } + } + const isJoinFarmDisabled = !!customErrors?.farm const isSubmitDisabled = isJoinFarms ? !!Object.keys(formState.errors).length @@ -154,7 +163,7 @@ export const AddLiquidityForm = ({ return (
Date: Thu, 12 Dec 2024 16:20:16 +0100 Subject: [PATCH 09/10] fix --- .../modals/AddLiquidity/AddLiquidityFormXYK.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx index d563ff45c..07cc5e050 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityFormXYK.tsx @@ -1,4 +1,4 @@ -import { Controller, useForm } from "react-hook-form" +import { Controller, FieldErrors, useForm } from "react-hook-form" import BN from "bignumber.js" import { BN_0, BN_1 } from "utils/constants" import { WalletTransferAssetSelect } from "sections/wallet/transfer/WalletTransferAssetSelect" @@ -168,6 +168,15 @@ export const AddLiquidityFormXYK = ({ pool, onClose, onSuccess }: Props) => { ) } + const onInvalidSubmit = (errors: FieldErrors) => { + if ( + !isJoinFarms && + (errors.shares as { farm?: { message: string } }).farm + ) { + onSubmit() + } + } + const handleChange = useCallback( (value: string, name: "assetA" | "assetB") => { const assetDecimals = assetValues[name].meta.decimals @@ -245,7 +254,7 @@ export const AddLiquidityFormXYK = ({ pool, onClose, onSuccess }: Props) => { return ( Date: Fri, 13 Dec 2024 15:28:27 +0100 Subject: [PATCH 10/10] update label --- src/api/deposits.ts | 2 +- src/components/Stepper/Stepper.tsx | 2 +- src/i18n/locales/en/translations.json | 3 ++ .../modals/AddLiquidity/AddLiquidityForm.tsx | 19 +++++++----- .../stablepool/transfer/TransferModal.tsx | 29 +++++++++++++------ 5 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/api/deposits.ts b/src/api/deposits.ts index 8d95d3c88..8dd24f9c3 100644 --- a/src/api/deposits.ts +++ b/src/api/deposits.ts @@ -65,7 +65,7 @@ export const useRefetchAccountAssets = () => { const { account } = useAccount() return () => { - queryClient.refetchQueries(QUERY_KEYS.accountAssets(account?.address)) + queryClient.resetQueries(QUERY_KEYS.accountAssets(account?.address)) } } diff --git a/src/components/Stepper/Stepper.tsx b/src/components/Stepper/Stepper.tsx index d9a2a4820..350d3ff48 100644 --- a/src/components/Stepper/Stepper.tsx +++ b/src/components/Stepper/Stepper.tsx @@ -72,7 +72,7 @@ export const Stepper = ({ steps, className, width }: StepperProps) => { const activeIndex = steps.findIndex((step) => step.state === "active") const activeStep = steps[activeIndex] - const width_ = width ?? steps.length * 100 + const width_ = width ?? steps.length * 120 return (
diff --git a/src/i18n/locales/en/translations.json b/src/i18n/locales/en/translations.json index 01dc7cb98..4368d590e 100644 --- a/src/i18n/locales/en/translations.json +++ b/src/i18n/locales/en/translations.json @@ -230,6 +230,7 @@ "liquidity.stablepool.transfer.confirm": "Confirm", "liquidity.stablepool.transfer.adding": "Adding liquidity", "liquidity.stablepool.transfer.move": "Add to Omnipool", + "liquidity.stablepool.transfer.moveAndJoinFarms": "Add to Omnipool and join farms", "liquidity.stablepool.asset.details.total": "Value in Stablepool", "liquidity.stablepool.asset.positions.title": "Stablepool positions", "liquidity.stablepool.asset.incentives.title": "Farming incentives", @@ -300,6 +301,8 @@ "liquidity.add.modal.information.linkText": "Learn more about risks?", "liquidity.add.modal.toast.onLoading": "<0>Adding <1>{{value}} {{symbol}}<0> to <1>{{where}}<0>...", "liquidity.add.modal.toast.onSuccess": "<0>Added <1>{{value}} {{symbol}}<0> to <1>{{where}}<0>.", + "liquidity.add.modal.andJoinFarms.toast.onLoading": "<0>Adding <1>{{value}} {{symbol}}<0> to <1>{{where}}<0> and joining farms... ", + "liquidity.add.modal.andJoinFarms.toast.onSuccess": "<0>Added <1>{{value}} {{symbol}}<0> to <1>{{where}}<0> and joined farms.", "liquidity.add.modal.xyk.toast.onLoading": "<0>Adding liquidity in exchange for <1>{{shares, bignumber(type: 'token')}}<0> asset shares.", "liquidity.add.modal.xyk.toast.onSuccess": "<0>Added liquidity in exchange for <1>{{shares, bignumber(type: 'token')}}<0> asset shares.", "liquidity.remove.modal.title": "Remove liquidity", diff --git a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx index 3bef15d19..f26dde8e3 100644 --- a/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx +++ b/src/sections/pools/modals/AddLiquidity/AddLiquidityForm.tsx @@ -114,15 +114,18 @@ export const AddLiquidityForm = ({ }, onClose, onBack: () => {}, - toast: createToastMessages("liquidity.add.modal.toast", { - t, - tOptions: { - value: values.amount, - symbol: assetMeta?.symbol, - where: "Omnipool", + toast: createToastMessages( + `liquidity.add.modal.${isJoinFarms ? "andJoinFarms." : ""}toast`, + { + t, + tOptions: { + value: values.amount, + symbol: assetMeta?.symbol, + where: "Omnipool", + }, + components: ["span", "span.highlight"], }, - components: ["span", "span.highlight"], - }), + ), onError: onClose, }, ) diff --git a/src/sections/pools/stablepool/transfer/TransferModal.tsx b/src/sections/pools/stablepool/transfer/TransferModal.tsx index 000ce0f92..62c3cce45 100644 --- a/src/sections/pools/stablepool/transfer/TransferModal.tsx +++ b/src/sections/pools/stablepool/transfer/TransferModal.tsx @@ -90,7 +90,11 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { ? [] : [ { - label: t("liquidity.stablepool.transfer.move"), + label: t( + isJoinFarms + ? "liquidity.stablepool.transfer.moveAndJoinFarms" + : "liquidity.stablepool.transfer.move", + ), loadingLabel: t("liquidity.stablepool.transfer.adding"), }, ]), @@ -141,7 +145,11 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { shares, ) : api.tx.omnipool.addLiquidity(pool.id, shares), - title: t("liquidity.stablepool.transfer.move"), + title: t( + isJoinFarms + ? "liquidity.stablepool.transfer.moveAndJoinFarms" + : "liquidity.stablepool.transfer.move", + ), }, { onSuccess: () => { @@ -152,14 +160,17 @@ export const TransferModal = ({ onClose, defaultPage, farms }: Props) => { }, onError: () => onClose(), onClose, - toast: createToastMessages("liquidity.add.modal.toast", { - t, - tOptions: { - value: scaleHuman(shares, meta.decimals), - symbol: meta.symbol, - where: "Omnipool", + toast: createToastMessages( + `liquidity.add.modal.${isJoinFarms ? "andJoinFarms." : ""}toast`, + { + t, + tOptions: { + value: scaleHuman(shares, meta.decimals), + symbol: meta.symbol, + where: "Omnipool", + }, }, - }), + ), }, ) } else {