From 9ba2a6af5a8203059d3cb74c15f49c881c9fdc32 Mon Sep 17 00:00:00 2001 From: unclebill Date: Tue, 12 Apr 2022 09:50:01 +0800 Subject: [PATCH 1/3] fix(tip): set significant to 6 for formatting max amount closes #MF-322 --- .../NextID/components/Tip/TokenSection/index.tsx | 1 + packages/mask/src/web3/UI/TokenAmountPanel.tsx | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx b/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx index 063b4b41571f..7b5e921f2924 100644 --- a/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx +++ b/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx @@ -41,6 +41,7 @@ export const TokenSection: FC = () => { token={token} amount={amount} maxAmount={maxAmount} + maxAmountSignificant={6} onAmountChange={setAmount} balance={tokenBalance} InputProps={{ diff --git a/packages/mask/src/web3/UI/TokenAmountPanel.tsx b/packages/mask/src/web3/UI/TokenAmountPanel.tsx index ebd591db85aa..3c1dc4fcef20 100644 --- a/packages/mask/src/web3/UI/TokenAmountPanel.tsx +++ b/packages/mask/src/web3/UI/TokenAmountPanel.tsx @@ -50,6 +50,7 @@ export interface TokenAmountPanelProps extends withClasses<'root'> { amount: string maxAmount?: string maxAmountShares?: number + maxAmountSignificant?: number balance: string disableToken?: boolean disableBalance?: boolean @@ -67,10 +68,11 @@ export function TokenAmountPanel(props: TokenAmountPanelProps) { const { amount, maxAmount, + maxAmountShares = 1, + maxAmountSignificant, balance, token, onAmountChange, - maxAmountShares = 1, label, disableToken = false, disableBalance = false, @@ -165,13 +167,11 @@ export function TokenAmountPanel(props: TokenAmountPanelProps) { color="primary" variant="outlined" onClick={() => { + const amount = new BigNumber(maxAmount ?? balance) + .dividedBy(maxAmountShares) + .decimalPlaces(0, 1) onAmountChange( - Utils?.formatBalance?.( - new BigNumber(maxAmount ?? balance) - .dividedBy(maxAmountShares) - .decimalPlaces(0, 1), - token.decimals, - ) ?? '0', + Utils?.formatBalance?.(amount, token.decimals, maxAmountSignificant) ?? '0', ) }} {...MaxChipProps} From 579897ef4eb6997334b78fb983861123570113e7 Mon Sep 17 00:00:00 2001 From: unclebill Date: Wed, 13 Apr 2022 15:08:13 +0800 Subject: [PATCH 2/3] fixup! fix(tip): set significant to 6 for formatting max amount --- .../components/Tip/TokenSection/index.tsx | 46 ++++++++++++++--- .../plugins/NextID/contexts/Tip/TipContext.ts | 3 ++ .../NextID/contexts/Tip/TipTaskProvider.tsx | 5 +- .../NextID/contexts/Tip/useTokenTip.ts | 12 +++-- .../SNSAdaptor/trader/hooks/useGasConfig.ts | 51 +++++++++---------- packages/web3-shared/evm/hooks/useGasPrice.ts | 6 ++- 6 files changed, 82 insertions(+), 41 deletions(-) diff --git a/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx b/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx index 7b5e921f2924..b8bec63ba883 100644 --- a/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx +++ b/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx @@ -1,14 +1,20 @@ import { usePickToken } from '@masknet/shared' -import { EthereumTokenType, isNativeTokenAddress, useFungibleTokenBalance } from '@masknet/web3-shared-evm' +import { + EthereumTokenType, + isNativeTokenAddress, + useFungibleTokenBalance, + useGasPrice, + isEIP1559Supported, +} from '@masknet/web3-shared-evm' import BigNumber from 'bignumber.js' -import { FC, useCallback, useMemo } from 'react' +import { FC, useCallback, useEffect, useMemo } from 'react' import { TokenAmountPanel } from '../../../../../web3/UI/TokenAmountPanel' import { useGasConfig } from '../../../../Trader/SNSAdaptor/trader/hooks/useGasConfig' import { TargetChainIdContext, useTip } from '../../../contexts' const GAS_LIMIT = 21000 export const TokenSection: FC = () => { - const { token, setToken, amount, setAmount, isSending } = useTip() + const { token, setToken, amount, setAmount, isSending, setGasConfig } = useTip() const { targetChainId: chainId } = TargetChainIdContext.useContainer() // balance const { value: tokenBalance = '0', loading: loadingTokenBalance } = useFungibleTokenBalance( @@ -16,13 +22,37 @@ export const TokenSection: FC = () => { token?.address || '', chainId, ) - const gasConfig = useGasConfig(chainId) + const { gasPrice, gasConfig } = useGasConfig(chainId) + const { value: defaultGasPrice = '1' } = useGasPrice(chainId) + const isNativeToken = useMemo(() => isNativeTokenAddress(token?.address), [token?.address]) + const maxAmount = useMemo(() => { - if (!isNativeTokenAddress(token?.address)) return tokenBalance - const gasPrice = gasConfig.gasPrice ?? '1' - const gasFee = new BigNumber(gasPrice).times(GAS_LIMIT) + if (!isNativeToken) return tokenBalance + const price = !gasPrice || gasPrice === '0' ? defaultGasPrice : gasPrice + const gasFee = new BigNumber(price).times(GAS_LIMIT) return new BigNumber(tokenBalance).minus(gasFee).toFixed() - }, [token?.address, tokenBalance, gasConfig.gasPrice]) + }, [isNativeToken, tokenBalance, gasPrice, defaultGasPrice]) + + useEffect(() => { + if (isNativeToken) { + const is1559Supported = isEIP1559Supported(chainId) + setGasConfig( + is1559Supported + ? { + gas: GAS_LIMIT, + maxFeePerGas: gasConfig?.maxFeePerGas || defaultGasPrice, + maxPriorityFeePerGas: gasConfig?.maxPriorityFeePerGas || '1', + } + : { + gas: GAS_LIMIT, + gasPrice: gasPrice || defaultGasPrice, + }, + ) + } else { + setGasConfig(undefined) + } + }, [isNativeToken, gasConfig, gasPrice, chainId]) + const pickToken = usePickToken() const onSelectTokenChipClick = useCallback(async () => { const picked = await pickToken({ diff --git a/packages/mask/src/plugins/NextID/contexts/Tip/TipContext.ts b/packages/mask/src/plugins/NextID/contexts/Tip/TipContext.ts index 477ac26dce70..b0579456dbff 100644 --- a/packages/mask/src/plugins/NextID/contexts/Tip/TipContext.ts +++ b/packages/mask/src/plugins/NextID/contexts/Tip/TipContext.ts @@ -2,6 +2,7 @@ import type { Web3Plugin } from '@masknet/plugin-infra/web3' import { ERC721ContractDetailed, FungibleTokenDetailed, + GasConfig, TransactionState, TransactionStateType, } from '@masknet/web3-shared-evm' @@ -30,6 +31,7 @@ export interface ContextOptions { sendState: TransactionState storedTokens: Web3Plugin.NonFungibleToken[] reset: () => void + setGasConfig: Dispatch> } export const TipContext = createContext({ @@ -53,4 +55,5 @@ export const TipContext = createContext({ sendState: { type: TransactionStateType.UNKNOWN }, storedTokens: [], reset: noop, + setGasConfig: noop, }) diff --git a/packages/mask/src/plugins/NextID/contexts/Tip/TipTaskProvider.tsx b/packages/mask/src/plugins/NextID/contexts/Tip/TipTaskProvider.tsx index 1c71b88292ca..6c19627aed0f 100644 --- a/packages/mask/src/plugins/NextID/contexts/Tip/TipTaskProvider.tsx +++ b/packages/mask/src/plugins/NextID/contexts/Tip/TipTaskProvider.tsx @@ -1,4 +1,5 @@ import { + GasConfig, TransactionStateType, useChainId, useERC721ContractDetailed, @@ -48,7 +49,8 @@ export const TipTaskProvider: FC> = ({ children, if (!nativeTokenDetailed) return setToken(nativeTokenDetailed) }, [nativeTokenDetailed]) - const tokenTipTuple = useTokenTip(recipient, token, amount) + const [gasConfig, setGasConfig] = useState() + const tokenTipTuple = useTokenTip(recipient, token, amount, gasConfig) const nftTipTuple = useNftTip(recipient, erc721TokenId, erc721Address) const sendTipTuple = tipType === TipType.Token ? tokenTipTuple : nftTipTuple @@ -89,6 +91,7 @@ export const TipTaskProvider: FC> = ({ children, sendState, storedTokens: storedTokens.filter((t) => t.contract?.chainId === chainId), reset, + setGasConfig, } }, [ chainId, diff --git a/packages/mask/src/plugins/NextID/contexts/Tip/useTokenTip.ts b/packages/mask/src/plugins/NextID/contexts/Tip/useTokenTip.ts index a5bb361c7438..37dd22236a83 100644 --- a/packages/mask/src/plugins/NextID/contexts/Tip/useTokenTip.ts +++ b/packages/mask/src/plugins/NextID/contexts/Tip/useTokenTip.ts @@ -2,6 +2,7 @@ import { rightShift } from '@masknet/web3-shared-base' import { EthereumTokenType, FungibleTokenDetailed, + GasConfig, isSameAddress, useTokenConstants, useTokenTransferCallback, @@ -9,7 +10,12 @@ import { import { useCallback } from 'react' import type { TipTuple } from './type' -export function useTokenTip(recipient: string, token: FungibleTokenDetailed | null, amount: string): TipTuple { +export function useTokenTip( + recipient: string, + token: FungibleTokenDetailed | null, + amount: string, + gasConfig?: GasConfig, +): TipTuple { const { NATIVE_TOKEN_ADDRESS } = useTokenConstants() const isNativeToken = isSameAddress(token?.address, NATIVE_TOKEN_ADDRESS) @@ -19,8 +25,8 @@ export function useTokenTip(recipient: string, token: FungibleTokenDetailed | nu const sendTip = useCallback(async () => { const transferAmount = rightShift(amount || '0', token?.decimals || 0).toFixed() - await transferCallback(transferAmount, recipient) - }, [amount, token, recipient, transferCallback]) + await transferCallback(transferAmount, recipient, gasConfig) + }, [amount, token, recipient, transferCallback, gasConfig]) return [transferState, sendTip] } diff --git a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/hooks/useGasConfig.ts b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/hooks/useGasConfig.ts index 6cb0142beb56..364405756024 100644 --- a/packages/mask/src/plugins/Trader/SNSAdaptor/trader/hooks/useGasConfig.ts +++ b/packages/mask/src/plugins/Trader/SNSAdaptor/trader/hooks/useGasConfig.ts @@ -9,37 +9,34 @@ export function useGasConfig(chainId: ChainId) { const [gasConfig, setGasConfig] = useState() const { value: gasPrice } = useAsync(async () => { try { - if (gasConfig) { - return new BigNumber( - (isEIP1559Supported(chainId) ? gasConfig.maxFeePerGas : gasConfig.gasPrice) ?? 0, - ).toString() - } else { - if (isEIP1559Supported(chainId)) { - const response = await WalletRPC.getEstimateGasFees(chainId) - const maxFeePerGas = formatGweiToWei(response?.medium?.suggestedMaxFeePerGas ?? 0).toFixed(0) - const maxPriorityFeePerGas = formatGweiToWei( - response?.medium?.suggestedMaxPriorityFeePerGas ?? 0, - ).toFixed(0) - setGasConfig({ - maxFeePerGas, - maxPriorityFeePerGas, - }) + if (isEIP1559Supported(chainId)) { + const response = await WalletRPC.getEstimateGasFees(chainId) + const maxFeePerGas = formatGweiToWei(response?.medium?.suggestedMaxFeePerGas ?? 0).toFixed(0) + const maxPriorityFeePerGas = formatGweiToWei( + response?.medium?.suggestedMaxPriorityFeePerGas ?? 0, + ).toFixed(0) + setGasConfig({ + maxFeePerGas, + maxPriorityFeePerGas, + }) - return maxFeePerGas - } else { - const response = await WalletRPC.getGasPriceDictFromDeBank(chainId) - const gasPrice = new BigNumber(response?.data.normal.price ?? 0).toString() - setGasConfig({ - gasPrice, - }) + return maxFeePerGas + } else { + const response = await WalletRPC.getGasPriceDictFromDeBank(chainId) + const gasPrice = response?.data.normal.price + ? new BigNumber(response.data.normal.price).toString() + : undefined + setGasConfig({ + gasPrice, + }) - return gasPrice - } + return gasPrice } - } catch { - return '0' + } catch (err) { + setGasConfig(undefined) + return } - }, [chainId, gasConfig]) + }, [chainId]) return { gasPrice, gasConfig, setGasConfig } } diff --git a/packages/web3-shared/evm/hooks/useGasPrice.ts b/packages/web3-shared/evm/hooks/useGasPrice.ts index 5fab4ea8a116..9b2523fdce8e 100644 --- a/packages/web3-shared/evm/hooks/useGasPrice.ts +++ b/packages/web3-shared/evm/hooks/useGasPrice.ts @@ -1,9 +1,11 @@ import { useAsyncRetry } from 'react-use' import { useWeb3 } from './useWeb3' import { useChainId } from './useChainId' +import type { ChainId } from '../types' -export function useGasPrice() { - const chainId = useChainId() +export function useGasPrice(expertedChainId?: ChainId) { + const currentChainId = useChainId() + const chainId = expertedChainId ?? currentChainId const web3 = useWeb3({ chainId }) return useAsyncRetry(async () => { From 5fa69c950b0bb1df02b1d5a2c5e2e1a06f87eb5c Mon Sep 17 00:00:00 2001 From: unclebill Date: Sun, 17 Apr 2022 10:31:30 +0800 Subject: [PATCH 3/3] fixup! fix(tip): set significant to 6 for formatting max amount --- .../src/plugins/NextID/components/Tip/TokenSection/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx b/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx index b8bec63ba883..2ad861a59cbc 100644 --- a/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx +++ b/packages/mask/src/plugins/NextID/components/Tip/TokenSection/index.tsx @@ -35,9 +35,8 @@ export const TokenSection: FC = () => { useEffect(() => { if (isNativeToken) { - const is1559Supported = isEIP1559Supported(chainId) setGasConfig( - is1559Supported + isEIP1559Supported(chainId) ? { gas: GAS_LIMIT, maxFeePerGas: gasConfig?.maxFeePerGas || defaultGasPrice,