Skip to content

Commit

Permalink
Release 2.3.2 (#170)
Browse files Browse the repository at this point in the history
### Release Summary

This release for the following
- #166
- #165
  • Loading branch information
bayological authored Dec 16, 2024
1 parent 64cce0a commit a391ba4
Show file tree
Hide file tree
Showing 7 changed files with 116 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.1",
"version": "2.3.2",
"description": "A simple DApp for Celo Mento exchanges",
"keywords": [
"Celo",
Expand Down
10 changes: 8 additions & 2 deletions src/components/nav/BalancesSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ export function BalancesSummary() {
{tokenIds.map((id) => {
const balance = fromWeiRounded(balances[id], Tokens[id].decimals)
if (balance !== '0') {
const token = Tokens[id]
// TODO: @bayo Either revert this !== 0 check or add some animation for when balances are loading
return (
<div style={{ minWidth: '35%' }} className="flex pb-4 dark:text-white" key={id}>
<TokenIcon token={Tokens[id]} size="xs" />
<div
style={{ minWidth: '35%' }}
className="flex pb-4 dark:text-white"
key={id}
data-testid={`walletSettings_${token.id}_balance`}
>
<TokenIcon token={token} size="xs" />
<div className="ml-3">{balance}</div>
</div>
)
Expand Down
16 changes: 13 additions & 3 deletions src/components/nav/NetworkModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface Props {
}

export function NetworkModal({ isOpen, close }: Props) {
const baseLocator = 'networkModal'
const latestBlock = useAppSelector((s) => s.block.latestBlock)
const chainId = useChainId()
const currentChain = chainIdToChain[chainId]
Expand Down Expand Up @@ -46,7 +47,10 @@ export function NetworkModal({ isOpen, close }: Props) {
<div className="text-neutral-500 dark:text-gray-400 text-[14px] sm:text-[15px] font-normal leading-tight">
Connected to:
</div>
<div className="opacity-90 text-right text-gray-950 dark:text-white text-[15px] font-medium leading-tight">
<div
className="opacity-90 text-right text-gray-950 dark:text-white text-[15px] font-medium leading-tight"
data-testid={`${baseLocator}_currentNetwork`}
>
{currentChain?.name || 'Unknown'}
</div>
</div>
Expand All @@ -55,7 +59,10 @@ export function NetworkModal({ isOpen, close }: Props) {
<div className="text-neutral-500 dark:text-gray-400 text-[14px] sm:text-[15px] font-normal leading-tight">
Block Number:
</div>
<div className="opacity-90 text-right text-gray-950 dark:text-white text-[14px] sm:text-[15px] font-medium leading-tight">
<div
className="opacity-90 text-right text-gray-950 dark:text-white text-[14px] sm:text-[15px] font-medium leading-tight"
data-testid={`${baseLocator}_currentBlockNumber`}
>
{latestBlock?.number || 'Unknown'}
</div>
</div>
Expand All @@ -64,7 +71,10 @@ export function NetworkModal({ isOpen, close }: Props) {
<div className="text-neutral-500 dark:text-gray-400 text-[14px] sm:text-[15px] font-normal leading-tight">
Node Rpc Url:
</div>
<div className="opacity-90 text-right text-gray-950 dark:text-white text-[14px] sm:text-[15px] font-medium leading-tight">
<div
className="opacity-90 text-right text-gray-950 dark:text-white text-[14px] sm:text-[15px] font-medium leading-tight"
data-testid={`${baseLocator}_currentNodeRpcUrl`}
>
{shortenUrl(currentChain?.rpcUrl) || 'Unknown'}
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions src/config/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ export const MAX_GAS_LIMIT = '10000000' // 10 million
export const MIN_ROUNDED_VALUE = 0.0001
export const DISPLAY_DECIMALS = 4
export const MAX_EXCHANGE_SPREAD = 0.1 // 10%

export const ERC20_ABI = [
'function allowance(address owner, address spender) view returns (uint256)',
]
53 changes: 44 additions & 9 deletions src/features/swap/SwapConfirm.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import BigNumber from 'bignumber.js'
import Lottie from 'lottie-react'
import { SVGProps, useEffect, useState } from 'react'
import mentoLoaderBlue from 'src/animations/Mentoloader_blue.json'
Expand All @@ -8,6 +9,7 @@ import { TokenId, Tokens } from 'src/config/tokens'
import { useAppDispatch, useAppSelector } from 'src/features/store/hooks'
import { setConfirmView, setFormValues } from 'src/features/swap/swapSlice'
import { SwapFormValues } from 'src/features/swap/types'
import { useAllowance } from 'src/features/swap/useAllowance'
import { useApproveTransaction } from 'src/features/swap/useApproveTransaction'
import { useSwapQuote } from 'src/features/swap/useSwapQuote'
import { useSwapTransaction } from 'src/features/swap/useSwapTransaction'
Expand Down Expand Up @@ -90,6 +92,21 @@ export function SwapConfirmCard({ formValues }: Props) {
)
const [isApproveConfirmed, setApproveConfirmed] = useState(false)

const { allowance, isLoading: isAllowanceLoading } = useAllowance(chainId, fromTokenId, address)
const needsApproval = !isAllowanceLoading && new BigNumber(allowance).lte(approveAmount)
const skipApprove = !isAllowanceLoading && !needsApproval

logger.info(`Allowance loading: ${isAllowanceLoading}`)
logger.info(`Needs approval: ${needsApproval}`)

useEffect(() => {
if (skipApprove) {
// Enables swap transaction preparation when approval isn't needed
// See useSwapTransaction hook for more details
setApproveConfirmed(true)
}
}, [skipApprove])

const { sendSwapTx, isSwapTxLoading, isSwapTxSuccess } = useSwapTransaction(
chainId,
fromTokenId,
Expand All @@ -104,13 +121,29 @@ export function SwapConfirmCard({ formValues }: Props) {
const onSubmit = async () => {
if (!rate || !amountWei || !address || !isConnected) return

setIsModalOpen(true)

if (skipApprove && sendSwapTx) {
try {
logger.info('Skipping approve, sending swap tx directly')
const swapResult = await sendSwapTx()
const swapReceipt = await swapResult.wait(1)
logger.info(`Tx receipt received for swap: ${swapReceipt?.transactionHash}`)
toastToYourSuccess('Swap Complete!', swapReceipt?.transactionHash, chainId)
dispatch(setFormValues(null))
} catch (error) {
logger.error('Failed to execute swap', error)
} finally {
setIsModalOpen(false)
}
return
}

if (!sendApproveTx || isApproveTxSuccess || isApproveTxLoading) {
logger.debug('Approve already started or finished, ignoring submit')
return
}

setIsModalOpen(true)

try {
logger.info('Sending approve tx')
const approveResult = await sendApproveTx()
Expand Down Expand Up @@ -207,7 +240,7 @@ export function SwapConfirmCard({ formValues }: Props) {
close={() => setIsModalOpen(false)}
width="max-w-[432px]"
>
<MentoLogoLoader />
<MentoLogoLoader needsApproval={needsApproval} />
</Modal>
</FloatingBox>
)
Expand Down Expand Up @@ -271,7 +304,7 @@ const ChevronRight = (props: SVGProps<SVGSVGElement>) => (
</svg>
)

const MentoLogoLoader = () => {
const MentoLogoLoader = ({ needsApproval }: { needsApproval: boolean }) => {
const { connector } = useAccount()

return (
Expand All @@ -286,12 +319,14 @@ const MentoLogoLoader = () => {
</div>

<div className="my-6">
<div className=" text-sm text-center text-[#636768] dark:text-[#AAB3B6]">
Sending two transactions: Approve and Swap
<div className="text-sm text-center text-[#636768] dark:text-[#AAB3B6]">
{needsApproval
? 'Sending two transactions: Approve and Swap'
: 'Sending swap transaction'}
</div>
<div className="mt-3 text-sm text-center text-[#636768] dark:text-[#AAB3B6]">
{`Sign with ${connector?.name || 'wallet'} to proceed`}
</div>
<div className="mt-3 text-sm text-center text-[#636768] dark:text-[#AAB3B6]">{`Sign with ${
connector?.name || 'wallet'
} to proceed`}</div>
</div>
</>
)
Expand Down
43 changes: 43 additions & 0 deletions src/features/swap/useAllowance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useQuery } from '@tanstack/react-query'
import { Contract } from 'ethers'
import { ERC20_ABI } from 'src/config/consts'
import { BrokerAddresses } from 'src/config/exchanges'
import { TokenId, getTokenAddress } from 'src/config/tokens'
import { getProvider } from 'src/features/providers'
import { logger } from 'src/utils/logger'

async function fetchAllowance(
tokenAddr: string,
accountAddress: string,
chainId: number
): Promise<string> {
logger.info(`Fetching allowance for token ${tokenAddr} on chain ${chainId}`)
const provider = getProvider(chainId)
const contract = new Contract(tokenAddr, ERC20_ABI, provider)
const brokerAddress = BrokerAddresses[chainId as keyof typeof BrokerAddresses]

const allowance = await contract.allowance(accountAddress, brokerAddress)
logger.info(`Allowance: ${allowance.toString()}`)
return allowance.toString()
}

export function useAllowance(chainId: number, tokenId: TokenId, accountAddress?: string) {
const { data: allowance, isLoading } = useQuery(
['tokenAllowance', chainId, tokenId, accountAddress],
async () => {
if (!accountAddress) return '0'
const tokenAddr = getTokenAddress(tokenId, chainId)
return fetchAllowance(tokenAddr, accountAddress, chainId)
},
{
retry: false,
enabled: Boolean(accountAddress && chainId && tokenId),
staleTime: 5000, // Consider allowance stale after 5 seconds
}
)

return {
allowance: allowance || '0',
isLoading,
}
}
4 changes: 3 additions & 1 deletion src/features/swap/useSwapTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ export function useSwapTransaction(
!isApproveConfirmed ||
new BigNumber(amountInWei).lte(0) ||
new BigNumber(thresholdAmountInWei).lte(0)
)
) {
logger.debug('Skipping swap transaction')
return null
}
const sdk = await getMentoSdk(chainId)
const fromTokenAddr = getTokenAddress(fromToken, chainId)
const toTokenAddr = getTokenAddress(toToken, chainId)
Expand Down

0 comments on commit a391ba4

Please sign in to comment.