Skip to content

Commit

Permalink
fix: mf-5110 popup approve activity (#10532)
Browse files Browse the repository at this point in the history
* fix: approve amount

* fix: approve amount

* fix: approve amount

* fix: approve amount
  • Loading branch information
zhouhanseng committed Aug 21, 2023
1 parent bf1a801 commit 8d971d7
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { useEverSeen } from '@masknet/shared-base-ui'
import { TextOverflowTooltip, makeStyles, useBoundedPopperProps } from '@masknet/theme'
import {
useAccount,
useFungibleToken,
useNativeToken,
useNetwork,
useNetworkDescriptors,
Expand Down Expand Up @@ -34,7 +35,7 @@ import { useQuery } from '@tanstack/react-query'
import { memo, useMemo } from 'react'
import { Trans } from 'react-i18next'
import { formatTokenBalance, useI18N } from '../../../../../../utils/index.js'
import { parseReceiverFromERC20TransferInput } from '../../utils.js'
import { parseAmountFromERC20ApproveInput, parseReceiverFromERC20TransferInput } from '../../utils.js'

const useStyles = makeStyles<{ cateType?: string }>()((theme, { cateType = '' }, __) => {
const colorMap: Record<string, string> = {
Expand Down Expand Up @@ -199,7 +200,7 @@ export const ActivityItem = memo<ActivityItemProps>(function ActivityItem({ tran
// This could be a transaction of SmartPay which Debank doesn't provide detailed info for it.
// This also could be an ERC20 transfer, which Debank returns the token contract rather than receiver as `to_address`.
// So we fetch via Chainbase
enabled: (!transaction.to || transaction.type === 'transfer') && seen,
enabled: (!transaction.to || transaction.type === 'transfer' || transaction.type === 'approve') && seen,
queryKey: ['chainbase', 'transaction', transaction.chainId, transaction.id, blockNumber],
queryFn: async () => {
if (!transaction.chainId || !transaction.id) return
Expand All @@ -226,6 +227,13 @@ export const ActivityItem = memo<ActivityItemProps>(function ActivityItem({ tran
transaction.type === 'transfer' ? !receiverAddress && (loadingTx || loadingTxInput) : !toAddress && loadingTx
const isOut = isSameAddress(fromAddress, account)
const popperProps = useBoundedPopperProps()
const approveAmount = parseAmountFromERC20ApproveInput(tx?.input ?? txInput)
const { data: approveToken } = useFungibleToken(
NetworkPluginID.PLUGIN_EVM,
transaction.type === 'approve' ? tx?.to_address : '',
undefined,
{ chainId: transaction.chainId },
)

return (
<ListItem
Expand Down Expand Up @@ -268,20 +276,36 @@ export const ActivityItem = memo<ActivityItemProps>(function ActivityItem({ tran
{transaction.isScam ? <span className={classes.scamLabel}>{t('scam_tx')}</span> : null}
</Typography>
</ListItemText>
<div className={classes.assets}>
{transaction.assets.map((token, i) => {
const isSend = token.direction === DebankTransactionDirection.SEND
const amount = isLessThan(token.amount, '0.0001') ? '<0.0001' : trimZero(toFixed(token.amount, 4))
return (
<Typography key={i} className={classes.asset}>
<strong className={classes.amount}>{`${isSend ? '-' : '+'} ${amount} `}</strong>
<TextOverflowTooltip title={token.symbol} PopperProps={popperProps}>
<span className={classes.symbol}>{token.symbol}</span>
</TextOverflowTooltip>
</Typography>
)
})}
</div>

{transaction.type === 'approve' && approveAmount && approveToken ? (
<Typography className={classes.asset}>
<strong className={classes.amount}>
{approveAmount === 'Infinite'
? approveAmount
: formatTokenBalance(approveAmount, approveToken.decimals)}
</strong>
<TextOverflowTooltip title={approveToken.symbol} PopperProps={popperProps}>
<span className={classes.symbol}>{approveToken.symbol}</span>
</TextOverflowTooltip>
</Typography>
) : (
<div className={classes.assets}>
{transaction.assets.map((token, i) => {
const isSend = token.direction === DebankTransactionDirection.SEND
const amount = isLessThan(token.amount, '0.0001')
? '<0.0001'
: trimZero(toFixed(token.amount, 4))
return (
<Typography key={i} className={classes.asset}>
<strong className={classes.amount}>{`${isSend ? '-' : '+'} ${amount} `}</strong>
<TextOverflowTooltip title={token.symbol} PopperProps={popperProps}>
<span className={classes.symbol}>{token.symbol}</span>
</TextOverflowTooltip>
</Typography>
)
})}
</div>
)}
</ListItem>
)
})
Expand Down
18 changes: 17 additions & 1 deletion packages/mask/src/extension/popups/pages/Wallet/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Web3 } from '@masknet/web3-providers'
import ERC20_ABI from '@masknet/web3-contracts/abis/ERC20.json'
import type { RecentTransaction } from '@masknet/web3-shared-base'
import { toFixed, type RecentTransaction } from '@masknet/web3-shared-base'
import {
ProviderType,
formatWeiToGwei,
Expand All @@ -12,9 +12,12 @@ import { toHex } from 'web3-utils'
import { GasSettingModal } from '../../modals/modals.js'
import { ReplaceType } from './type.js'
import { Interface } from '@ethersproject/abi'
import type { BigNumber } from 'bignumber.js'

const erc20InterFace = new Interface(ERC20_ABI)

const MaxUint256 = toFixed('0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')

export async function modifyTransaction(
transaction: RecentTransaction<ChainId, EvmTransaction>,
replaceType: ReplaceType,
Expand Down Expand Up @@ -63,3 +66,16 @@ export function parseReceiverFromERC20TransferInput(input?: string) {
return ''
}
}

// The Debank transaction history api does not return the input data and approved token info,
// so can not do the decoding within its scope.
export function parseAmountFromERC20ApproveInput(input?: string) {
if (!input) return
try {
const decodedInputParam = erc20InterFace.decodeFunctionData('approve', input ?? '')
const result = (decodedInputParam[1] as BigNumber).toString()
return MaxUint256 === result ? 'Infinite' : result
} catch {
return
}
}

0 comments on commit 8d971d7

Please sign in to comment.