Skip to content

Commit

Permalink
fix: form validation (#194)
Browse files Browse the repository at this point in the history
### Description

The form validation was broken because we called the async function
`isSwappable` in the filter function without waiting for the promises to
be resolved.
This fix ensure only valid token combinations can be selected 

### Other changes



### Tested

Ensured both multihop and direct broker swaps work, verified only valid
pairs can be selected.


### Related issues



### Checklist before requesting a review
  • Loading branch information
philbow61 authored Feb 18, 2025
1 parent 593199f commit fdc248d
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 16 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@mento-protocol/mento-web",
"version": "2.3.6",
"version": "2.3.7",
"description": "A simple DApp for Celo Mento exchanges",
"keywords": [
"Celo",
Expand Down
18 changes: 14 additions & 4 deletions src/config/tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,20 @@ export async function isSwappable(token_1: string, token_2: string, chainId: num
)
}

export function getSwappableTokenOptions(token: string, chainId: ChainId) {
return getTokenOptionsByChainId(chainId)
.filter((tkn) => isSwappable(tkn, token, chainId))
.filter((tkn) => token !== tkn)
export async function getSwappableTokenOptions(token: string, chainId: ChainId) {
const options = getTokenOptionsByChainId(chainId)

const swappableOptions = await Promise.all(
options.map(async (tkn) => ({
token: tkn,
isSwappable: await isSwappable(tkn, token, chainId),
}))
).then((results) => {
return results
.filter((result) => result.isSwappable && result.token !== token)
.map((result) => result.token)
})
return swappableOptions
}

export function getTokenOptionsByChainId(chainId: ChainId): TokenId[] {
Expand Down
34 changes: 23 additions & 11 deletions src/features/swap/SwapForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useConnectModal } from '@rainbow-me/rainbowkit'
import { Form, Formik, useFormikContext } from 'formik'
import { ReactNode, SVGProps, useEffect, useMemo } from 'react'
import { ReactNode, SVGProps, useEffect, useMemo, useState } from 'react'
import { toast } from 'react-toastify'
import { Spinner } from 'src/components/animation/Spinner'
import { Button3D } from 'src/components/buttons/3DButton'
Expand Down Expand Up @@ -94,16 +94,24 @@ function SwapForm() {
function SwapFormInputs({ balances }: { balances: AccountBalances }) {
const { address, isConnected } = useAccount()
const { chain } = useNetwork()
const [swappableTokens, setSwappableTokens] = useState<TokenId[]>([])

const tokensForChain = useMemo(() => {
return chain ? getTokenOptionsByChainId(chain?.id) : getTokenOptionsByChainId(Celo.chainId)
}, [chain])

const { values, setFieldValue } = useFormikContext<SwapFormValues>()

const swappableTokenOptions = useMemo(() => {
return getSwappableTokenOptions(values.fromTokenId, chain ? chain?.id : Celo.chainId)
}, [chain, values])
useEffect(() => {
const fetchSwappableTokens = async () => {
const tokens = await getSwappableTokenOptions(
values.fromTokenId,
chain ? chain?.id : Celo.chainId
)
setSwappableTokens(tokens)
}
fetchSwappableTokens().catch(logger.error)
}, [chain, values.fromTokenId, values.toTokenId])

const { amount, direction, fromTokenId, toTokenId } = values

Expand All @@ -116,13 +124,17 @@ function SwapFormInputs({ balances }: { balances: AccountBalances }) {
}, [quote, setFieldValue, values.direction])

useEffect(() => {
if (chain && isConnected && !isSwappable(values.fromTokenId, values.toTokenId, chain?.id)) {
setFieldValue(
'toTokenId',
swappableTokenOptions.length < 1 ? TokenId.cUSD : swappableTokenOptions[0]
)
const setToToken = async () => {
if (
chain &&
isConnected &&
!(await isSwappable(values.fromTokenId, values.toTokenId, chain?.id))
) {
setFieldValue('toTokenId', swappableTokens.length < 1 ? TokenId.cUSD : swappableTokens[0])
}
}
}, [setFieldValue, chain, values, swappableTokenOptions, isConnected])
setToToken().catch(logger.error)
}, [setFieldValue, chain, values, swappableTokens, isConnected])

const roundedBalance = fromWeiRounded(balances[fromTokenId], Tokens[fromTokenId].decimals)
const isRoundedBalanceGreaterThanZero = Boolean(Number.parseFloat(roundedBalance) > 0)
Expand Down Expand Up @@ -177,7 +189,7 @@ function SwapFormInputs({ balances }: { balances: AccountBalances }) {
<TokenSelectField
name="toTokenId"
label="To Token"
tokenOptions={swappableTokenOptions}
tokenOptions={swappableTokens}
onChange={onChangeToken(false)}
/>
</div>
Expand Down

0 comments on commit fdc248d

Please sign in to comment.