diff --git a/.husky/pre-commit b/.husky/pre-commit index c81f321caf..51b33fd9a1 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -10,7 +10,7 @@ echo 🧿 Running svg formatter... for file in `git diff --diff-filter=ACMRT --cached --name-only | grep ".svg\$"` do echo "Formatting $file" - ./node_modules/.bin/svgo -q $file + ./node_modules/.bin/svgo -q $file --config svgo.config.format.js git add $file done diff --git a/configs/app/features/web3Wallet.ts b/configs/app/features/web3Wallet.ts index 893f92394b..e54b1eaa10 100644 --- a/configs/app/features/web3Wallet.ts +++ b/configs/app/features/web3Wallet.ts @@ -13,7 +13,7 @@ const wallets = ((): Array | undefined => { const wallets = parseEnvJson>(envValue)?.filter((type) => SUPPORTED_WALLETS.includes(type)); if (!wallets || wallets.length === 0) { - return [ 'metamask' ]; + return [ 'metamask', 'rabby', 'coinbase', 'trust', 'okx', 'token_pocket' ]; } return wallets; diff --git a/deploy/values/review/values.yaml.gotmpl b/deploy/values/review/values.yaml.gotmpl index c47237fd67..66c47c7274 100644 --- a/deploy/values/review/values.yaml.gotmpl +++ b/deploy/values/review/values.yaml.gotmpl @@ -63,7 +63,6 @@ frontend: NEXT_PUBLIC_HOMEPAGE_CHARTS: "['daily_txs','coin_price','market_cap']" NEXT_PUBLIC_NETWORK_RPC_URL: https://eth-sepolia.public.blastapi.io NEXT_PUBLIC_NETWORK_EXPLORERS: "[{'title':'Bitquery','baseUrl':'https://explorer.bitquery.io/','paths':{'tx':'/goerli/tx','address':'/goerli/address','token':'/goerli/token','block':'/goerli/block'}},{'title':'Etherscan','logo':'https://github.com/blockscout/frontend-configs/blob/main/configs/explorer-logos/etherscan.png?raw=true','baseUrl':'https://goerli.etherscan.io/','paths':{'tx':'/tx','address':'/address','token':'/token','block':'/block'}}]" - NEXT_PUBLIC_WEB3_WALLETS: "['token_pocket','coinbase','metamask']" NEXT_PUBLIC_VIEWS_ADDRESS_IDENTICON_TYPE: gradient_avatar NEXT_PUBLIC_VIEWS_CONTRACT_SOLIDITYSCAN_ENABLED: true NEXT_PUBLIC_USE_NEXT_JS_PROXY: true diff --git a/docs/ENVS.md b/docs/ENVS.md index dd26a7320d..48ced32d09 100644 --- a/docs/ENVS.md +++ b/docs/ENVS.md @@ -649,7 +649,7 @@ This feature is **enabled by default** with the `['metamask']` value. To switch | Variable | Type| Description | Compulsoriness | Default value | Example value | Version | | --- | --- | --- | --- | --- | --- | --- | -| NEXT_PUBLIC_WEB3_WALLETS | `Array<'metamask' \| 'coinbase' \| 'token_pocket'>` | Array of Web3 wallets which will be used to add tokens or chain to. The first wallet which is enabled in user's browser will be shown. | - | `[ 'metamask' ]` | `[ 'coinbase' ]` | v1.10.0+ | +| NEXT_PUBLIC_WEB3_WALLETS | `Array<'metamask' \| 'coinbase' \| 'token_pocket' \| 'rabby' \| 'trust' \| 'okx'>` | Array of Web3 wallets which will be used to add tokens or chain to. The first wallet which is enabled in user's browser will be shown. | - | `[ 'metamask', 'rabby', 'coinbase', 'trust', 'okx', 'token_pocket' ]` | `[ 'coinbase' ]` | v1.10.0+ | | NEXT_PUBLIC_WEB3_DISABLE_ADD_TOKEN_TO_WALLET | `boolean`| Set to `true` to hide icon "Add to your wallet" next to token addresses | - | - | `true` | v1.0.x+ |   diff --git a/icons/ABI_slim.svg b/icons/ABI_slim.svg index 89532207b1..ca746a687a 100644 --- a/icons/ABI_slim.svg +++ b/icons/ABI_slim.svg @@ -1,12 +1,12 @@ - + - + diff --git a/icons/blobs/image.svg b/icons/blobs/image.svg index be08dd269c..aac019f234 100644 --- a/icons/blobs/image.svg +++ b/icons/blobs/image.svg @@ -1,10 +1,10 @@ - + - + diff --git a/icons/blobs/raw.svg b/icons/blobs/raw.svg index 8a97401ff5..086b084f12 100644 --- a/icons/blobs/raw.svg +++ b/icons/blobs/raw.svg @@ -1,10 +1,10 @@ - + - + diff --git a/icons/brands/celenium.svg b/icons/brands/celenium.svg index 8a5d645ac2..6c7e669294 100644 --- a/icons/brands/celenium.svg +++ b/icons/brands/celenium.svg @@ -1,15 +1,15 @@ - - + + - + - + diff --git a/icons/brands/solidity_scan.svg b/icons/brands/solidity_scan.svg index ac5747c69a..3f3ce6cdf5 100644 --- a/icons/brands/solidity_scan.svg +++ b/icons/brands/solidity_scan.svg @@ -1,7 +1,7 @@ - + - + diff --git a/icons/empty_search_result.svg b/icons/empty_search_result.svg index f4d62eff0e..4f36357152 100644 --- a/icons/empty_search_result.svg +++ b/icons/empty_search_result.svg @@ -1,15 +1,15 @@ - - + + - + - + diff --git a/icons/gas.svg b/icons/gas.svg index 4334fe93f5..459b11b242 100644 --- a/icons/gas.svg +++ b/icons/gas.svg @@ -1,9 +1,9 @@ - + - + diff --git a/icons/internal_txns.svg b/icons/internal_txns.svg index 683cc0761e..9a1de65cc9 100644 --- a/icons/internal_txns.svg +++ b/icons/internal_txns.svg @@ -1,9 +1,9 @@ - - - - + + + + diff --git a/icons/merits_colored.svg b/icons/merits_colored.svg index 4006f7e43a..76d4bab3b8 100644 --- a/icons/merits_colored.svg +++ b/icons/merits_colored.svg @@ -1,13 +1,13 @@ - - + + - + - + diff --git a/icons/minus.svg b/icons/minus.svg index 34b985100f..1bc9f08ecd 100644 --- a/icons/minus.svg +++ b/icons/minus.svg @@ -1,9 +1,9 @@ - + - + diff --git a/icons/nft_shield.svg b/icons/nft_shield.svg index 5f055f02ee..0d2a83e9a3 100644 --- a/icons/nft_shield.svg +++ b/icons/nft_shield.svg @@ -1,3 +1,3 @@ - + diff --git a/icons/plus.svg b/icons/plus.svg index 9f3d595ca5..846013df42 100644 --- a/icons/plus.svg +++ b/icons/plus.svg @@ -1,9 +1,9 @@ - + - + diff --git a/icons/wallets/coinbase.svg b/icons/wallets/coinbase.svg index 9a75b44e6d..149847fc18 100644 --- a/icons/wallets/coinbase.svg +++ b/icons/wallets/coinbase.svg @@ -1,6 +1,4 @@ - - - - - + + + diff --git a/icons/wallets/metamask.svg b/icons/wallets/metamask.svg index 220fbc130f..52f6fce78e 100644 --- a/icons/wallets/metamask.svg +++ b/icons/wallets/metamask.svg @@ -1,5 +1,5 @@ - + @@ -9,7 +9,7 @@ - + diff --git a/icons/wallets/okx.svg b/icons/wallets/okx.svg new file mode 100644 index 0000000000..3d2b0ab886 --- /dev/null +++ b/icons/wallets/okx.svg @@ -0,0 +1,4 @@ + + + + diff --git a/icons/wallets/rabby.svg b/icons/wallets/rabby.svg new file mode 100644 index 0000000000..32799b7b18 --- /dev/null +++ b/icons/wallets/rabby.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/icons/wallets/trust.svg b/icons/wallets/trust.svg new file mode 100644 index 0000000000..f6b6713795 --- /dev/null +++ b/icons/wallets/trust.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/lib/cookies.ts b/lib/cookies.ts index 28065cf5c2..578d93bd43 100644 --- a/lib/cookies.ts +++ b/lib/cookies.ts @@ -18,6 +18,7 @@ export enum NAMES { ADBLOCK_DETECTED = 'adblock_detected', MIXPANEL_DEBUG = '_mixpanel_debug', ADDRESS_NFT_DISPLAY_TYPE = 'address_nft_display_type', + HIDE_ADD_TO_WALLET_BUTTON = 'hide_add_to_wallet_button', UUID = 'uuid', SHOW_SCAM_TOKENS = 'show_scam_tokens', } diff --git a/lib/mixpanel/utils.ts b/lib/mixpanel/utils.ts index 0212a6405a..822fb36120 100644 --- a/lib/mixpanel/utils.ts +++ b/lib/mixpanel/utils.ts @@ -51,6 +51,7 @@ Type extends EventTypes.ADD_TO_WALLET ? ( { Wallet: WalletType; Target: 'network'; + Source: 'Footer' | 'Top bar' | 'Chain widget'; } | { Wallet: WalletType; Target: 'token'; diff --git a/lib/web3/detectWallet.ts b/lib/web3/detectWallet.ts new file mode 100644 index 0000000000..06ee166798 --- /dev/null +++ b/lib/web3/detectWallet.ts @@ -0,0 +1,78 @@ +import type { WalletType } from 'types/client/wallets'; +import type { WalletProvider } from 'types/web3'; + +const isWalletProvider = (wallet: WalletType) => (provider: WalletProvider): boolean | undefined => { + switch (wallet) { + case 'rabby': { + return provider.isRabby; + } + case 'coinbase': { + return provider.isCoinbaseWallet; + } + case 'token_pocket': { + return provider.isTokenPocket; + } + case 'okx': { + return provider.isOkxWallet; + } + case 'trust': { + return provider.isTrustWallet; + } + case 'metamask': { + // some wallets (e.g TokenPocket, Liquality, etc) try to look like MetaMask but they are not (not even close) + // found this hack in wagmi repo + // https://github.com/wevm/wagmi/blob/8c35b7adccb4f92c4e0e36a76b970e9126053772/packages/core/src/connectors/injected.ts#L553 + if (!provider.isMetaMask) { + return false; + } + if (!provider._events || !provider._state) { + return false; + } + // Other wallets that try to look like MetaMask + const flags = [ + 'isApexWallet', + 'isAvalanche', + 'isBitKeep', + 'isBlockWallet', + 'isKuCoinWallet', + 'isMathWallet', + 'isOkxWallet', + 'isOKExWallet', + 'isOneInchIOSWallet', + 'isOneInchAndroidWallet', + 'isOpera', + 'isPhantom', + 'isPortal', + 'isRabby', + 'isRainbow', + 'isTokenPocket', + 'isTokenary', + 'isUniswapWallet', + 'isZerion', + ] ; + for (const flag of flags) { + if (provider[flag as keyof WalletProvider]) { + return false; + } + } + return true; + } + default: + return false; + } +}; + +export default function detectWallet(wallet: WalletType): { wallet: WalletType; provider: WalletProvider } | undefined { + if (!('ethereum' in window && window.ethereum)) { + return; + } + + // if user has multiple wallets installed, they all are injected in the window.ethereum.providers array + // if user has only one wallet, the provider is injected in the window.ethereum directly + const providers = Array.isArray(window.ethereum.providers) ? window.ethereum.providers : [ window.ethereum ]; + const provider = providers.find(isWalletProvider(wallet)); + + if (provider) { + return { wallet, provider }; + } +} diff --git a/lib/web3/useAddChain.tsx b/lib/web3/useAddChain.tsx index 511ddbaea0..4864dbbfb1 100644 --- a/lib/web3/useAddChain.tsx +++ b/lib/web3/useAddChain.tsx @@ -28,7 +28,7 @@ function getParams(chainConfig: typeof config): AddEthereumChainParameter { } export default function useAddChain() { - const { wallet, provider } = useProvider(); + const { data: { wallet, provider } = {} } = useProvider(); const { trackUsage } = useRewardsActivity(); const multichainContext = useMultichainContext(); diff --git a/lib/web3/useAddChainClick.ts b/lib/web3/useAddChainClick.ts index aab2dc5779..fddb2f29a3 100644 --- a/lib/web3/useAddChainClick.ts +++ b/lib/web3/useAddChainClick.ts @@ -7,8 +7,13 @@ import useAddChain from './useAddChain'; import useProvider from './useProvider'; import useSwitchChain from './useSwitchChain'; -export default function useAddChainClick() { - const { provider, wallet } = useProvider(); +interface Props { + source: 'Footer' | 'Top bar' | 'Chain widget'; + onSuccess?: () => void; +} + +export default function useAddChainClick({ source, onSuccess }: Props) { + const { data: { wallet, provider } = {} } = useProvider(); const addChain = useAddChain(); const switchChain = useSwitchChain(); @@ -29,13 +34,15 @@ export default function useAddChainClick() { mixpanel.logEvent(mixpanel.EventTypes.ADD_TO_WALLET, { Target: 'network', Wallet: wallet, + Source: source, }); + onSuccess?.(); } catch (error) { toaster.error({ title: 'Error', description: (error as Error)?.message || 'Something went wrong', }); } - }, [ addChain, provider, wallet, switchChain ]); + }, [ addChain, provider, wallet, switchChain, source, onSuccess ]); } diff --git a/lib/web3/useDetectWalletEip6963.ts b/lib/web3/useDetectWalletEip6963.ts new file mode 100644 index 0000000000..e71b8dfb9f --- /dev/null +++ b/lib/web3/useDetectWalletEip6963.ts @@ -0,0 +1,71 @@ +// https://eips.ethereum.org/EIPS/eip-6963 + +import React from 'react'; + +import type { WalletType } from 'types/client/wallets'; +import type { WalletProvider } from 'types/web3'; + +interface EIP6963ProviderInfo { + uuid: string; + name: string; + icon: string; + rdns: string; +} + +interface EIP6963ProviderDetail { + info: EIP6963ProviderInfo; + provider: WalletProvider; +} + +const WALLET_RDNS_MAP: Record = { + metamask: 'io.metamask', + coinbase: 'com.coinbase.wallet', + token_pocket: 'io.tokenpocket', + rabby: 'io.rabby', + okx: 'com.okex.wallet', + trust: 'com.trustwallet.app', +} as const; + +const DETECTED_PROVIDERS: Partial> = {}; + +export default function useDetectWalletEip6963() { + const detectionTimeoutRef = React.useRef(null); + + const handleAnnounceProviderEvent = React.useCallback((event: CustomEvent) => { + const wallet = Object.entries(WALLET_RDNS_MAP) + .find(([ , rdns ]) => rdns === event.detail.info.rdns)?.[0] as WalletType | undefined; + + if (wallet && !DETECTED_PROVIDERS[wallet]) { + DETECTED_PROVIDERS[wallet] = event.detail.provider; + } + }, []); + + const detect = React.useCallback((wallet: WalletType) => { + return new Promise<{ wallet: WalletType; provider: WalletProvider } | undefined>((resolve) => { + const provider = DETECTED_PROVIDERS[wallet]; + + if (provider) { + resolve({ wallet, provider }); + return; + } + + window.addEventListener('eip6963:announceProvider', handleAnnounceProviderEvent as EventListener); + window.dispatchEvent(new Event('eip6963:requestProvider')); + + detectionTimeoutRef.current = window.setTimeout(() => { + const provider = DETECTED_PROVIDERS[wallet]; + resolve(provider ? { wallet, provider } : undefined); + }, 200); + }); + }, [ handleAnnounceProviderEvent ]); + + React.useEffect(() => { + return () => { + window.removeEventListener('eip6963:announceProvider', handleAnnounceProviderEvent as EventListener); + }; + }, [ handleAnnounceProviderEvent ]); + + return React.useMemo(() => ({ + detect, + }), [ detect ]); +} diff --git a/lib/web3/useProvider.tsx b/lib/web3/useProvider.tsx index 3043f81b8f..0ca4502d80 100644 --- a/lib/web3/useProvider.tsx +++ b/lib/web3/useProvider.tsx @@ -1,85 +1,73 @@ -import React from 'react'; +import { useQuery } from '@tanstack/react-query'; import { getFeaturePayload } from 'configs/app/features/types'; -import type { WalletType } from 'types/client/wallets'; -import type { WalletProvider } from 'types/web3'; import config from 'configs/app'; import { useMultichainContext } from 'lib/contexts/multichain'; -export default function useProvider() { - const [ provider, setProvider ] = React.useState(); - const [ wallet, setWallet ] = React.useState(); +import detectWallet from './detectWallet'; +import useDetectWalletEip6963 from './useDetectWalletEip6963'; +export default function useProvider() { const multichainContext = useMultichainContext(); - const feature = (multichainContext?.chain.config ?? config).features.web3Wallet; const wallets = getFeaturePayload(feature)?.wallets; - const initializeProvider = React.useMemo(() => async() => { - if (!feature.isEnabled || !wallets) { - return; - } - - if (!('ethereum' in window && window.ethereum)) { - if (wallets.includes('metamask') && window.navigator.userAgent.includes('Firefox')) { - const { WindowPostMessageStream } = (await import('@metamask/post-message-stream')); - const { initializeProvider } = (await import('@metamask/providers')); - - // workaround for MetaMask in Firefox - // Firefox blocks MetaMask injection script because of our CSP for 'script-src' - // so we have to inject it manually while the issue is not fixed - // https://github.com/MetaMask/metamask-extension/issues/3133#issuecomment-1025641185 - const metamaskStream = new WindowPostMessageStream({ - name: 'metamask-inpage', - target: 'metamask-contentscript', - }); + const { detect: detectWalletEip6963 } = useDetectWalletEip6963(); - // this will initialize the provider and set it as window.ethereum - initializeProvider({ - connectionStream: metamaskStream as never, - shouldShimWeb3: true, - }); - } else { + return useQuery({ + queryKey: [ 'web3-wallet' ], + queryFn: async() => { + if (!feature.isEnabled || !wallets) { return; } - } - // have to check again in case provider was not set as window.ethereum in the previous step for MM in FF - // and also it makes typescript happy - if (!('ethereum' in window && window.ethereum)) { - return; - } + if (!('ethereum' in window && window.ethereum)) { + if (wallets.includes('metamask') && window.navigator.userAgent.includes('Firefox')) { + const { WindowPostMessageStream } = (await import('@metamask/post-message-stream')); + const { initializeProvider } = (await import('@metamask/providers')); - // if user has multiple wallets installed, they all are injected in the window.ethereum.providers array - // if user has only one wallet, the provider is injected in the window.ethereum directly - const providers = Array.isArray(window.ethereum.providers) ? window.ethereum.providers : [ window.ethereum ]; + // workaround for MetaMask in Firefox + // Firefox blocks MetaMask injection script because of our CSP for 'script-src' + // so we have to inject it manually while the issue is not fixed + // https://github.com/MetaMask/metamask-extension/issues/3133#issuecomment-1025641185 + const metamaskStream = new WindowPostMessageStream({ + name: 'metamask-inpage', + target: 'metamask-contentscript', + }); - for (const wallet of wallets) { - const provider = providers.find((provider) => { - return ( - // some wallets (e.g TokenPocket, Liquality, etc) try to look like MetaMask but they are not (not even close) - // so we have to check in addition the presence of the provider._events property - // found this hack in wagmi repo - // https://github.com/wagmi-dev/wagmi/blob/399b9eab8cfd698b49bfaa8456598dad9b597e0e/packages/connectors/src/types.ts#L65 - // for now it's the only way to distinguish them - (wallet === 'metamask' && provider.isMetaMask && Boolean(provider._events)) || - (wallet === 'coinbase' && provider.isCoinbaseWallet) || - (wallet === 'token_pocket' && provider.isTokenPocket) - ); - }); + // this will initialize the provider and set it as window.ethereum + initializeProvider({ + connectionStream: metamaskStream as never, + shouldShimWeb3: true, + }); + } else { + return; + } + } - if (provider) { - setProvider(provider); - setWallet(wallet); - break; + // have to check again in case provider was not set as window.ethereum in the previous step for MM in FF + // and also it makes typescript happy + if (!('ethereum' in window && window.ethereum)) { + return; } - } - }, [ feature.isEnabled, wallets ]); - React.useEffect(() => { - initializeProvider(); - }, [ initializeProvider ]); + for (const wallet of wallets) { + const detectedWalletEip6963 = await detectWalletEip6963(wallet); + + if (detectedWalletEip6963) { + return detectedWalletEip6963; + } - return { provider, wallet }; + const detectedWallet = detectWallet(wallet); + + if (detectedWallet) { + return detectedWallet; + } + } + }, + enabled: Boolean(feature.isEnabled || !wallets), + refetchOnMount: false, + staleTime: Infinity, + }); } diff --git a/lib/web3/useSwitchChain.tsx b/lib/web3/useSwitchChain.tsx index 543cbd1513..7d3153671c 100644 --- a/lib/web3/useSwitchChain.tsx +++ b/lib/web3/useSwitchChain.tsx @@ -15,7 +15,7 @@ function getParams(chainConfig: typeof config): { chainId: string } { } export default function useSwitchChain() { - const { wallet, provider } = useProvider(); + const { data: { wallet, provider } = {} } = useProvider(); const multichainContext = useMultichainContext(); const chainConfig = multichainContext?.chain.config ?? config; diff --git a/lib/web3/useSwitchOrAddChain.tsx b/lib/web3/useSwitchOrAddChain.tsx index 7b2ee9f669..dcf00fd20e 100644 --- a/lib/web3/useSwitchOrAddChain.tsx +++ b/lib/web3/useSwitchOrAddChain.tsx @@ -8,7 +8,7 @@ import useProvider from './useProvider'; import useSwitchChain from './useSwitchChain'; export default function useSwitchOrAddChain() { - const { wallet, provider } = useProvider(); + const { data: { wallet, provider } = {} } = useProvider(); const addChain = useAddChain(); const switchChain = useSwitchChain(); diff --git a/lib/web3/wallets.ts b/lib/web3/wallets.ts index 6bcb257e67..d9a8031813 100644 --- a/lib/web3/wallets.ts +++ b/lib/web3/wallets.ts @@ -4,13 +4,31 @@ export const WALLETS_INFO: Record, WalletInfo> = { metamask: { name: 'MetaMask', icon: 'wallets/metamask', + color: '#FF8D5D', }, coinbase: { name: 'Coinbase Wallet', icon: 'wallets/coinbase', + color: '#0052FF', }, token_pocket: { name: 'TokenPocket', icon: 'wallets/token-pocket', + color: '#2980FE', + }, + rabby: { + name: 'Rabby', + icon: 'wallets/rabby', + color: '#8798FF', + }, + okx: { + name: 'OKX Wallet', + icon: 'wallets/okx', + color: '#6DB809', + }, + trust: { + name: 'Trust Wallet', + icon: 'wallets/trust', + color: '#2D77FF', }, }; diff --git a/package.json b/package.json index 56dc5faec9..31247810f1 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "lint:tsc": "tsc -p ./tsconfig.json", "lint:envs-validator:test": "cd ./deploy/tools/envs-validator && ./test.sh", "prepare": "husky install", - "svg:format": "svgo -r ./icons", + "svg:format": "svgo -r --config svgo.config.format.js ./icons", "svg:build-sprite": "./deploy/scripts/build_sprite.sh", "test:pw": "./tools/scripts/pw.sh", "test:pw:local": "export NODE_PATH=$(pwd)/node_modules && yarn test:pw", diff --git a/playwright/fixtures/injectMetaMaskProvider.ts b/playwright/fixtures/injectMetaMaskProvider.ts index f09ee81a43..f653b9c773 100644 --- a/playwright/fixtures/injectMetaMaskProvider.ts +++ b/playwright/fixtures/injectMetaMaskProvider.ts @@ -10,6 +10,7 @@ const fixture: TestFixture = async({ pag window.ethereum = { isMetaMask: true, _events: {}, + _state: {}, } as WalletProvider; }); }); diff --git a/public/icons/name.d.ts b/public/icons/name.d.ts index 7b7b22d35a..18ae89cf4b 100644 --- a/public/icons/name.d.ts +++ b/public/icons/name.d.ts @@ -203,6 +203,9 @@ | "wallet" | "wallets/coinbase" | "wallets/metamask" + | "wallets/okx" + | "wallets/rabby" | "wallets/token-pocket" + | "wallets/trust" | "watchlist"; \ No newline at end of file diff --git a/svgo.config.format.js b/svgo.config.format.js new file mode 100644 index 0000000000..9c34513866 --- /dev/null +++ b/svgo.config.format.js @@ -0,0 +1,22 @@ +module.exports = { + plugins: [ + { + name: 'preset-default', + params: { + overrides: { + removeViewBox: false, + removeHiddenElems: false, + }, + }, + }, + 'removeDimensions', + // during formatting we need to prefix ids to avoid conflicts with other icons + // this is not the case for building the sprite + // so we use a separate config only with one additional plugin + 'prefixIds', + ], + js2svg: { + indent: 2, + pretty: true, + }, +}; diff --git a/types/client/wallets.ts b/types/client/wallets.ts index a112cd766f..b349d74a45 100644 --- a/types/client/wallets.ts +++ b/types/client/wallets.ts @@ -6,6 +6,9 @@ export const SUPPORTED_WALLETS = [ 'metamask', 'coinbase', 'token_pocket', + 'rabby', + 'okx', + 'trust', ] as const; export type WalletType = ArrayElement; @@ -13,4 +16,5 @@ export type WalletType = ArrayElement; export interface WalletInfo { name: string; icon: IconName; + color: string; } diff --git a/ui/optimismSuperchain/home/ChainWidget.tsx b/ui/optimismSuperchain/home/ChainWidget.tsx index 10439decdd..4cbbb9afcb 100644 --- a/ui/optimismSuperchain/home/ChainWidget.tsx +++ b/ui/optimismSuperchain/home/ChainWidget.tsx @@ -30,7 +30,7 @@ const ChainWidget = ({ data }: Props) => { }, }); - const handleAddToWalletClick = useAddChainClick(); + const handleAddToWalletClick = useAddChainClick({ source: 'Chain widget' }); return ( void; +} -const NetworkAddToWallet = () => { - const { provider, wallet } = useProvider(); - const handleClick = useAddChainClick(); +const NetworkAddToWallet = ({ source, onAddSuccess }: Props) => { + const { data: { wallet } = {} } = useProvider(); - if (!provider || !wallet || !config.chain.rpcUrls.length || !feature.isEnabled) { + const handleClick = useAddChainClick({ source, onSuccess: onAddSuccess }); + + if (!wallet) { return null; } + const walletInfo = WALLETS_INFO[wallet]; + return ( -
} - - { config.features.deFiDropdown.isEnabled && ( - <> - - - + } + > + { (hasAddChainButton || hasDeFiDropdown) && ( + + { hasAddChainButton && } + { hasDeFiDropdown && } + ) } - + ); diff --git a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-1.png b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-1.png index c5d6fef84c..832919b53c 100644 Binary files a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-1.png and b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-1.png differ diff --git a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-2.png b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-2.png index 2c4846f6cb..80fe9380c2 100644 Binary files a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-2.png and b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_dark-color-mode_default-view-dark-mode-2.png differ diff --git a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-1.png b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-1.png index 841fb81a96..17822fba27 100644 Binary files a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-1.png and b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-1.png differ diff --git a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-2.png b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-2.png index 595f19a24c..e04d77eb27 100644 Binary files a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-2.png and b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_default_default-view-dark-mode-2.png differ diff --git a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_default-view-mobile---default-1.png b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_default-view-mobile---default-1.png index 431b86d9bf..4d377df5b9 100644 Binary files a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_default-view-mobile---default-1.png and b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_default-view-mobile---default-1.png differ diff --git a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-DeFi-dropdown-dark-mode-mobile-1.png b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-DeFi-dropdown-dark-mode-mobile-1.png index b518b7308b..cb15cb09d0 100644 Binary files a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-DeFi-dropdown-dark-mode-mobile-1.png and b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-DeFi-dropdown-dark-mode-mobile-1.png differ diff --git a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-secondary-coin-price-mobile-1.png b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-secondary-coin-price-mobile-1.png index 50525f9746..7b04b3bd08 100644 Binary files a/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-secondary-coin-price-mobile-1.png and b/ui/snippets/topBar/__screenshots__/TopBar.pw.tsx_mobile_with-secondary-coin-price-mobile-1.png differ