Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d32b385
feat: integrate Conflux eSpace
Pana Mar 1, 2022
5bdd564
feat: update token logo
Pana Mar 1, 2022
6cd8ba6
feat: fix lint
Pana Mar 1, 2022
447dde5
feat: fix lint
Pana Mar 1, 2022
0870548
feat(wip): add smart contract
hanszhoou Mar 8, 2022
e434014
Merge branch 'develop' into develop
Pana Mar 15, 2022
6083ded
Merge branch 'develop' into feat/add-smart-contract-address
hanszhoou Mar 15, 2022
62640cb
feat: integrate smart contract
hanszhoou Mar 16, 2022
b1602f1
chore: remove debug code
hanszhoou Mar 16, 2022
892e8e5
Merge pull request #1 from conflux-fans/feat/add-smart-contract-address
Pana Mar 16, 2022
890f25a
chore: add contract address
hanszhoou Mar 16, 2022
ad9d446
chore: rpc address
hanszhoou Mar 16, 2022
b809500
chore: send conflux popup dashboard
hanszhoou Mar 16, 2022
126d880
chore: add token list
hanszhoou Mar 16, 2022
23c0489
chore: remove debug code
hanszhoou Mar 16, 2022
02dea06
chore: modify comment
hanszhoou Mar 16, 2022
bfdb17f
fix: asset list
hanszhoou Mar 16, 2022
f3578ec
chore: add empty config
hanszhoou Mar 16, 2022
e3fde8a
Merge pull request #3 from conflux-fans/add-config
hanszhoou Mar 16, 2022
4208831
Merge remote-tracking branch 'upstream/develop' into develop
hanszhoou Mar 21, 2022
1934c73
chore: solve conflict
hanszhoou Mar 21, 2022
5ec9514
chore: hiden gas option
hanszhoou Mar 21, 2022
943f891
fix: explorer url
hanszhoou Mar 21, 2022
6c84752
chore: conflux usd price
hanszhoou Mar 21, 2022
510e8d8
chore: conflux price
hanszhoou Mar 21, 2022
92185d5
chore: miss config
hanszhoou Mar 22, 2022
a062732
fix: conflux default gas price
hanszhoou Mar 23, 2022
598b9ab
chore: conflux disable swap
hanszhoou Mar 23, 2022
143e9ec
chore: remove debug code
hanszhoou Mar 23, 2022
69d8b0e
chore: get balance
hanszhoou Mar 23, 2022
eae37b5
chore: reply code review
hanszhoou Mar 23, 2022
1f7a7df
chore: simple syntax
hanszhoou Mar 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
useWeb3State,
Web3Plugin,
} from '@masknet/plugin-infra'
import { ChainId } from '@masknet/web3-shared-evm'
import { useDashboardI18N } from '../../../../locales'
import { ChangeNetworkTip } from './ChangeNetworkTip'
import { getTokenUSDValue } from '../../utils/getTokenUSDValue'
Expand Down Expand Up @@ -151,7 +152,7 @@ export const FungibleTokenTableRow = memo<TokenTableRowProps>(({ asset, onSend,
</span>
</Tooltip>
<Tooltip
disableHoverListener={isOnCurrentChain}
disableHoverListener={isOnCurrentChain || asset.token.chainId !== ChainId.Conflux}
disableTouchListener
title={<ChangeNetworkTip chainId={asset.token.chainId} />}
placement="top"
Expand All @@ -160,8 +161,12 @@ export const FungibleTokenTableRow = memo<TokenTableRowProps>(({ asset, onSend,
<span>
<Button
size="small"
style={!isOnCurrentChain ? { pointerEvents: 'none' } : {}}
disabled={!isOnCurrentChain}
style={
!isOnCurrentChain || asset.token.chainId === ChainId.Conflux
? { pointerEvents: 'none' }
: {}
}
disabled={!isOnCurrentChain || asset.token.chainId === ChainId.Conflux}
variant="outlined"
color="secondary"
onClick={onSwap}
Expand Down
11 changes: 8 additions & 3 deletions packages/mask/src/components/shared/ApplicationBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { MaskMessages } from '../../utils/messages'
import { useControlledDialog } from '../../utils/hooks/useControlledDialog'
import { RedPacketPluginID } from '../../plugins/RedPacket/constants'
import { ITO_PluginID } from '../../plugins/ITO/constants'
import { base as ITO_Definition } from '../../plugins/ITO/base'
import { PluginTransakMessages } from '../../plugins/Transak/messages'
import { PluginPetMessages } from '../../plugins/Pets/messages'
import { ClaimAllDialog } from '../../plugins/ITO/SNSAdaptor/ClaimAllDialog'
Expand Down Expand Up @@ -229,6 +230,10 @@ export function ApplicationBoard({ secondEntries, secondEntryChainTabs }: MaskAp
}
}

// Todo: remove this after refactor applicationBoard
const isITOSupportedChain =
ITO_Definition.enableRequirement.web3![NetworkPluginID.PLUGIN_EVM]?.supportedChainIds?.includes(currentChainId)

const firstLevelEntries: MaskAppEntry[] = [
createEntry(
'Lucky Drop',
Expand All @@ -250,14 +255,14 @@ export function ApplicationBoard({ secondEntries, secondEntryChainTabs }: MaskAp
new URL('./assets/token.png', import.meta.url).toString(),
() => openEncryptedMessage(ITO_PluginID),
undefined,
isNotEvm,
!isITOSupportedChain,
),
createEntry(
'Claim',
new URL('./assets/gift.png', import.meta.url).toString(),
onClaimAllDialogOpen,
undefined,
isNotEvm,
!isITOSupportedChain,
),
createEntry(
'Mask Bridge',
Expand Down Expand Up @@ -287,7 +292,7 @@ export function ApplicationBoard({ secondEntries, secondEntryChainTabs }: MaskAp
new URL('./assets/swap.png', import.meta.url).toString(),
onSwapDialogOpen,
undefined,
isNotEvm,
isNotEvm || currentChainId === ChainId.Conflux,
),
createEntry(
'Fiat On-Ramp',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { makeStyles } from '@masknet/theme'
import { isLessThan } from '@masknet/web3-shared-base'
import { isLessThan, pow10 } from '@masknet/web3-shared-base'
import { memo, useEffect, useMemo, useState } from 'react'
import { useI18N } from '../../../../../utils'
import { useAsync, useAsyncFn, useUpdateEffect } from 'react-use'
Expand Down Expand Up @@ -90,9 +90,10 @@ const useStyles = makeStyles()((theme) => ({
},
}))

const minGasPriceOfChain: ChainIdOptionalRecord<string> = {
[ChainId.BSC]: '0x12a05f200', // 5
[ChainId.Matic]: '0x6fc23ac00', // 30
const minGasPriceOfChain: ChainIdOptionalRecord<BigNumber.Value> = {
[ChainId.BSC]: pow10(9).multipliedBy(5), // 5 Gwei
[ChainId.Conflux]: pow10(9).multipliedBy(5), // 5 Gwei
[ChainId.Matic]: pow10(9).multipliedBy(30), // 30 Gwei
}

export const Prior1559GasSetting = memo(() => {
Expand All @@ -111,7 +112,8 @@ export const Prior1559GasSetting = memo(() => {
// #region Get gas options from debank
const { value: gasOptions } = useAsync(async () => {
const response = await WalletRPC.getGasPriceDictFromDeBank(chainId)
if (!response) return { slow: 0, standard: 0, fast: 0 }

if (!response) return null

return {
slow: response.data.slow.price,
Expand All @@ -122,20 +124,23 @@ export const Prior1559GasSetting = memo(() => {
// #endregion

const options = useMemo(
() => [
{
title: t('popups_wallet_gas_fee_settings_low'),
gasPrice: gasOptions?.slow ?? 0,
},
{
title: t('popups_wallet_gas_fee_settings_medium'),
gasPrice: gasOptions?.standard ?? 0,
},
{
title: t('popups_wallet_gas_fee_settings_high'),
gasPrice: gasOptions?.fast ?? 0,
},
],
() =>
gasOptions
? [
{
title: t('popups_wallet_gas_fee_settings_low'),
gasPrice: gasOptions?.slow ?? 0,
},
{
title: t('popups_wallet_gas_fee_settings_medium'),
gasPrice: gasOptions?.standard ?? 0,
},
{
title: t('popups_wallet_gas_fee_settings_high'),
gasPrice: gasOptions?.fast ?? 0,
},
]
: null,
[gasOptions],
)

Expand Down Expand Up @@ -222,7 +227,7 @@ export const Prior1559GasSetting = memo(() => {
}, [minGasLimit, gas, setValue])

useEffect(() => {
if (selected !== null) setValue('gasPrice', formatWeiToGwei(options[selected].gasPrice).toString())
if (selected !== null && options) setValue('gasPrice', formatWeiToGwei(options[selected].gasPrice).toString())
}, [selected, setValue, options])

const [{ loading }, handleConfirm] = useAsyncFn(
Expand Down Expand Up @@ -257,25 +262,27 @@ export const Prior1559GasSetting = memo(() => {

return (
<>
<div className={classes.options}>
{options.map(({ title, gasPrice }, index) => (
<div
key={index}
onClick={() => setOption(index)}
className={selected === index ? classes.selected : undefined}>
<Typography className={classes.optionsTitle}>{title}</Typography>
<Typography>{formatWeiToGwei(gasPrice ?? 0).toString()} Gwei</Typography>
<Typography className={classes.gasUSD}>
{t('popups_wallet_gas_fee_settings_usd', {
usd: formatWeiToEther(gasPrice)
.times(nativeTokenPrice)
.times(minGasLimit || 21000)
.toPrecision(3),
})}
</Typography>
</div>
))}
</div>
{options ? (
<div className={classes.options}>
{options.map(({ title, gasPrice }, index) => (
<div
key={index}
onClick={() => setOption(index)}
className={selected === index ? classes.selected : undefined}>
<Typography className={classes.optionsTitle}>{title}</Typography>
<Typography>{formatWeiToGwei(gasPrice ?? 0).toString()} Gwei</Typography>
<Typography className={classes.gasUSD}>
{t('popups_wallet_gas_fee_settings_usd', {
usd: formatWeiToEther(gasPrice)
.times(nativeTokenPrice)
.times(minGasLimit || 21000)
.toPrecision(3),
})}
</Typography>
</div>
))}
</div>
) : null}
<form onSubmit={onSubmit}>
<Typography className={classes.label}>{t('popups_wallet_gas_fee_settings_gas_limit')}</Typography>
<Controller
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ChainId, Web3ProviderType, createWeb3 } from '@masknet/web3-shared-evm'

export function createGetLatestBalance(context: Web3ProviderType) {
return (chainId: ChainId, account: string) => {
const web3 = createWeb3(context.request, () => ({
chainId,
}))
return web3.eth.getBalance(account)
}
}
90 changes: 70 additions & 20 deletions packages/mask/src/plugins/EVM/UI/Web3State/getAssetsFn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,27 @@ import {
Web3ProviderType,
FungibleAssetProvider,
createExternalProvider,
getCoinGeckoCoinId,
CurrencyType,
PriceRecord,
ChainId,
} from '@masknet/web3-shared-evm'
import BigNumber from 'bignumber.js'
import { Pageable, Pagination, TokenType, Web3Plugin } from '@masknet/plugin-infra'
import BalanceCheckerABI from '@masknet/web3-contracts/abis/BalanceChecker.json'
import ERC721ABI from '@masknet/web3-contracts/abis/ERC721.json'
import type { AbiItem } from 'web3-utils'
import { uniqBy } from 'lodash-unified'
import { PLUGIN_NETWORKS } from '../../constants'
import { makeSortAssertWithoutChainFn } from '../../utils/token'
import { createGetLatestBalance } from './createGetLatestBalance'
import type { ERC721 } from '@masknet/web3-contracts/types/ERC721'
import { pow10 } from '@masknet/web3-shared-base'
import { TokenPrice } from '@masknet/web3-providers'

// tokens unavailable neither from api or balance checker.
// https://forum.conflux.fun/t/how-to-upvote-debank-proposal-for-conflux-espace-integration/13935
const TokenUnavailableFromDebankList = [ChainId.Conflux]

export const getFungibleAssetsFn =
(context: Web3ProviderType) =>
Expand All @@ -28,9 +40,12 @@ export const getFungibleAssetsFn =
const wallet = context.wallets.getCurrentValue().find((x) => isSameAddress(x.address, address))
const socket = await context.providerSocket
const networks = PLUGIN_NETWORKS
const trustedTokens = context.erc20Tokens
.getCurrentValue()
.filter((x) => wallet?.erc20_token_whitelist.has(formatEthereumAddress(x.address)))
const trustedTokens = uniqBy(
context.erc20Tokens
.getCurrentValue()
.filter((x) => wallet?.erc20_token_whitelist.has(formatEthereumAddress(x.address))),
(x) => `${x.chainId}_${formatEthereumAddress(x.address)}`,
)

const web3 = new Web3(
createExternalProvider(context.request, context.getSendOverrides, context.getRequestOptions),
Expand Down Expand Up @@ -66,22 +81,28 @@ export const getFungibleAssetsFn =
},
}))

if (!BALANCE_CHECKER_ADDRESS) return assetsFromProvider
const balanceCheckerContract = createContract(web3, BALANCE_CHECKER_ADDRESS, BalanceCheckerABI as AbiItem[])
if (!balanceCheckerContract) return assetsFromProvider
let balanceList: string[]
try {
balanceList = await balanceCheckerContract?.methods
.balances(
[address],
trustedTokens.map((x) => x.address),
)
.call({
from: undefined,
})
if (balanceList.length !== trustedTokens?.length) return assetsFromProvider
} catch {
balanceList = []
const balanceCheckerContract = createContract(
web3,
BALANCE_CHECKER_ADDRESS ?? '',
BalanceCheckerABI as AbiItem[],
)

let balanceList: string[] = []

if (BALANCE_CHECKER_ADDRESS && balanceCheckerContract) {
try {
balanceList = await balanceCheckerContract?.methods
.balances(
[address],
trustedTokens.map((x) => x.address),
Comment thread
hanszhoou marked this conversation as resolved.
)
.call({
from: address,
})
if (balanceList.length !== trustedTokens?.length) return assetsFromProvider
} catch {
balanceList = []
}
}

const assetFromChain = balanceList.map(
Expand All @@ -101,6 +122,27 @@ export const getFungibleAssetsFn =

const allTokens = [...assetsFromProvider, ...assetFromChain]

const getBalance = createGetLatestBalance(context)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it impossible to use Utils here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cycle import

const allRequest = TokenUnavailableFromDebankList.map(async (x) => {
const balance = await getBalance(x, address)
const coinId = getCoinGeckoCoinId(x)
const price = (await TokenPrice.getNativeTokenPrice([coinId], CurrencyType.USD))[coinId]

return {
chainId: x,
price: price,
balance,
}
})

const tokenUnavailableFromDebankResults = (await Promise.allSettled(allRequest))
.map((x) => (x.status === 'fulfilled' ? x.value : null))
.filter((x) => Boolean(x)) as {
chainId: ChainId
balance: string
price: PriceRecord
}[]

const nativeTokens: Web3Plugin.Asset<Web3Plugin.FungibleToken>[] = networks
.filter(
(t) =>
Expand All @@ -113,11 +155,19 @@ export const getFungibleAssetsFn =
)
.map((x) => {
const nativeToken = createNativeToken(x.chainId)
const result = tokenUnavailableFromDebankResults.find((y) => y.chainId === x.chainId)
return {
id: nativeToken.address,
chainId: x.chainId,
token: { ...nativeToken, id: nativeToken.address!, type: TokenType.Fungible },
balance: '0',
balance: result?.balance ?? '0',
price: result?.price,
value: {
[CurrencyType.USD]: new BigNumber(result?.balance ?? '0')
.dividedBy(pow10(nativeToken.decimals))
.multipliedBy(result ? result.price[CurrencyType.USD] : '0')
.toFixed(),
},
}
})

Expand Down
10 changes: 3 additions & 7 deletions packages/mask/src/plugins/EVM/UI/Web3State/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ import {
createExternalProvider,
} from '@masknet/web3-shared-evm'
import { getStorage } from '../../storage'
import { getFungibleAssetsFn, getNonFungibleTokenFn } from './getAssetsFn'

import { getFungibleAssetsFn, getNonFungibleTokenFn } from './getAssetsFn'
import { createGetLatestBalance } from './createGetLatestBalance'
const ZERO_X_ERROR_ADDRESS = '0x'

export function fixWeb3State(state?: Web3Plugin.ObjectCapabilities.Capabilities, context?: Web3ProviderType) {
Expand Down Expand Up @@ -114,12 +115,7 @@ export function fixWeb3State(state?: Web3Plugin.ObjectCapabilities.Capabilities,
},
}
state.Utils = state.Utils ?? {
getLatestBalance: (chainId: ChainId, account: string) => {
const web3 = createWeb3(context.request, () => ({
chainId,
}))
return web3.eth.getBalance(account)
},
getLatestBalance: createGetLatestBalance(context),
getLatestBlockNumber: (chainId: ChainId) => {
const web3 = createWeb3(context.request, () => ({
chainId,
Expand Down
Binary file added packages/mask/src/plugins/EVM/assets/conflux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions packages/mask/src/plugins/EVM/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ export const PLUGIN_NETWORKS: Web3Plugin.NetworkDescriptor[] = [
iconColor: 'rgb(112, 212, 74)',
isMainnet: true,
},
{
ID: `${PLUGIN_ID}_conflux`,
networkSupporterPluginID: PLUGIN_ID,
chainId: ChainId.Conflux,
type: NetworkType.Conflux,
name: 'Conflux',
icon: new URL('./assets/conflux.png', import.meta.url),
iconColor: 'rgb(112, 212, 74)',
isMainnet: true,
},
]
export const PLUGIN_PROVIDERS: Web3Plugin.ProviderDescriptor[] = [
{
Expand Down
Loading