Skip to content

Commit

Permalink
feat: eip-6963 (#7869)
Browse files Browse the repository at this point in the history
  • Loading branch information
gomesalexandre authored Oct 15, 2024
1 parent ddd7c54 commit 0d5c449
Show file tree
Hide file tree
Showing 69 changed files with 1,067 additions and 1,065 deletions.
3 changes: 0 additions & 3 deletions .env.base
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ REACT_APP_FEATURE_WHEREVER=true
REACT_APP_FEATURE_YAT=true
REACT_APP_FEATURE_NFT_METADATA=false
REACT_APP_FEATURE_CHATWOOT=false
REACT_APP_FEATURE_COINBASE_WALLET=true
REACT_APP_FEATURE_ADVANCED_SLIPPAGE=true
REACT_APP_FEATURE_LEDGER_WALLET=true
REACT_APP_FEATURE_WALLET_CONNECT_V2=true
Expand Down Expand Up @@ -170,8 +169,6 @@ REACT_APP_SNAP_ID=npm:@shapeshiftoss/metamask-snaps
REACT_APP_SNAP_VERSION=1.0.9
# REACT_APP_SNAP_ID=local:http://localhost:9000

REACT_APP_EXPERIMENTAL_MM_SNAPPY_FINGERS=true

# Experemental features (not production ready)
REACT_APP_EXPERIMENTAL_CUSTOM_SEND_NONCE=false

Expand Down
28 changes: 13 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,28 +85,25 @@
"@ledgerhq/hw-transport-webusb": "^6.29.2",
"@lifi/sdk": "^3.1.5",
"@lukemorales/query-key-factory": "^1.3.4",
"@metamask/detect-provider": "^2.0.0",
"@react-spring/web": "^9.7.4",
"@reduxjs/toolkit": "^1.9.7",
"@sentry-internal/browser-utils": "^8.26.0",
"@sentry/react": "^8.26.0",
"@shapeshiftoss/caip": "workspace:^",
"@shapeshiftoss/chain-adapters": "workspace:^",
"@shapeshiftoss/errors": "workspace:^",
"@shapeshiftoss/hdwallet-coinbase": "1.55.10",
"@shapeshiftoss/hdwallet-core": "1.55.10",
"@shapeshiftoss/hdwallet-keepkey": "1.55.10",
"@shapeshiftoss/hdwallet-keepkey-webusb": "1.55.10",
"@shapeshiftoss/hdwallet-keplr": "1.55.10",
"@shapeshiftoss/hdwallet-ledger": "1.55.10",
"@shapeshiftoss/hdwallet-ledger-webusb": "1.55.10",
"@shapeshiftoss/hdwallet-metamask": "1.55.10",
"@shapeshiftoss/hdwallet-native": "1.55.10",
"@shapeshiftoss/hdwallet-native-vault": "1.55.10",
"@shapeshiftoss/hdwallet-phantom": "1.55.10",
"@shapeshiftoss/hdwallet-shapeshift-multichain": "1.55.10",
"@shapeshiftoss/hdwallet-walletconnectv2": "1.55.10",
"@shapeshiftoss/hdwallet-xdefi": "1.55.10",
"@shapeshiftoss/hdwallet-coinbase": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-core": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-keepkey": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-keepkey-webusb": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-keplr": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-ledger": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-ledger-webusb": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-metamask-multichain": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-native": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-native-vault": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-phantom": "1.55.11-mipd.5",
"@shapeshiftoss/hdwallet-walletconnectv2": "1.55.11-mipd.5",
"@shapeshiftoss/swapper": "workspace:^",
"@shapeshiftoss/types": "workspace:^",
"@shapeshiftoss/unchained-client": "workspace:^",
Expand Down Expand Up @@ -159,6 +156,7 @@
"localforage": "^1.10.0",
"lodash": "^4.17.21",
"match-sorter": "^6.3.0",
"mipd": "^0.0.7",
"mixpanel-browser": "^2.45.0",
"myzod": "^1.10.1",
"node-polyglot": "^2.4.0",
Expand Down
1 change: 1 addition & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"name": "ShapeShift",
"short_name": "ShapeShift",
"description": "Your Web3 & DeFi Portal",
"iconPath": "/icon-512x512.png",
"icons": [
{
"src": "/icon-192x192.png",
Expand Down
1 change: 1 addition & 0 deletions react-app-rewired/headers/csps/defi/safe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Csp } from '../../types'

export const csp: Csp = {
'connect-src': [
'https://app.safe.global',
'https://safe-transaction-mainnet.safe.global',
'https://safe-transaction-avalanche.safe.global',
'https://safe-transaction-optimism.safe.global',
Expand Down
41 changes: 11 additions & 30 deletions src/assets/translations/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -1518,20 +1518,21 @@
"connectWarning": "Before connecting a chain, make sure you have the app open on your device.",
"signWarning": "Before signing, make sure you have the %{chain} app open on your device."
},
"metaMask": {
"errors": {
"unknown": "An unexpected error occurred communicating with MetaMask",
"connectFailure": "Unable to connect MetaMask wallet",
"multipleWallets": "Detected Ethereum provider is not MetaMask. Do you have multiple wallets installed?"
},
"mipd": {
"connect": {
"header": "Pair MetaMask",
"body": "Click Pair and login to MetaMask from the popup window",
"header": "Pair %{name}",
"body": "Click Pair and login to %{name} from the popup window",
"button": "Pair"
},
"failure": {
"body": "Unable to connect MetaMask wallet"
"errors": {
"unknown": "An unexpected error occurred communicating with %{name}",
"connectFailure": "Unable to connect %{name}"
},
"failure": {
"body": "Unable to connect %{name}"
}
},
"metaMask": {
"redirect": {
"header": "Open in MetaMask App",
"body": "Click to open ShapeShift dashboard in MetaMask",
Expand Down Expand Up @@ -1620,26 +1621,6 @@
"body": "Unable to connect WalletConnect wallet"
}
},
"xdefi": {
"errors": {
"unknown": "An unexpected error occurred communicating with XDEFI",
"connectFailure": "Unable to connect XDEFI wallet",
"multipleWallets": "Detected Ethereum provider is not XDEFI. Do you have multiple wallets installed and switched on? Prioritize XDEFI in settings and press pair again."
},
"connect": {
"header": "Pair XDEFI",
"body": "Click Pair and login to XDEFI from the popup window",
"button": "Pair"
},
"failure": {
"body": "Unable to connect XDEFI wallet"
},
"redirect": {
"header": "Open in XDEFI App",
"body": "Click to open ShapeShift dashboard in XDEFI",
"button": "Open"
}
},
"shapeShift": {
"load": {
"error": {
Expand Down
32 changes: 0 additions & 32 deletions src/components/Icons/XDEFIIcon.tsx

This file was deleted.

53 changes: 34 additions & 19 deletions src/components/Layout/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { InfoIcon } from '@chakra-ui/icons'
import { Box, Flex, HStack, useMediaQuery, usePrevious, useToast } from '@chakra-ui/react'
import { btcAssetId } from '@shapeshiftoss/caip'
import { MetaMaskShapeShiftMultiChainHDWallet } from '@shapeshiftoss/hdwallet-shapeshift-multichain'
import { btcAssetId, fromAccountId } from '@shapeshiftoss/caip'
import { isEvmChainId } from '@shapeshiftoss/chain-adapters'
import { MetaMaskMultiChainHDWallet } from '@shapeshiftoss/hdwallet-metamask-multichain'
import { useScroll } from 'framer-motion'
import { lazy, memo, Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useTranslate } from 'react-polyglot'
Expand All @@ -13,15 +14,16 @@ import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag'
import { useIsSnapInstalled } from 'hooks/useIsSnapInstalled/useIsSnapInstalled'
import { useModal } from 'hooks/useModal/useModal'
import { useWallet } from 'hooks/useWallet/useWallet'
import { isUtxoAccountId } from 'lib/utils/utxo'
import { METAMASK_RDNS } from 'lib/mipd'
import { selectWalletRdns } from 'state/slices/localWalletSlice/selectors'
import { portfolio } from 'state/slices/portfolioSlice/portfolioSlice'
import {
selectEnabledWalletAccountIds,
selectPortfolioDegradedState,
selectShowSnapsModal,
selectWalletId,
} from 'state/slices/selectors'
import { useAppDispatch } from 'state/store'
import { useAppDispatch, useAppSelector } from 'state/store'
import { breakpoints } from 'theme/theme'

import { AppLoadingIcon } from './AppLoadingIcon'
Expand Down Expand Up @@ -97,21 +99,23 @@ export const Header = memo(() => {
[dispatch],
)

const currentWalletId = useSelector(selectWalletId)
const walletAccountIds = useSelector(selectEnabledWalletAccountIds)
const hasUtxoAccountIds = useMemo(
() => walletAccountIds.some(accountId => isUtxoAccountId(accountId)),
const connectedRdns = useAppSelector(selectWalletRdns)
const previousConnectedRdns = usePrevious(connectedRdns)
const currentWalletId = useAppSelector(selectWalletId)
const walletAccountIds = useAppSelector(selectEnabledWalletAccountIds)
const hasNonEvmAccountIds = useMemo(
() => walletAccountIds.some(accountId => !isEvmChainId(fromAccountId(accountId).chainId)),
[walletAccountIds],
)

useEffect(() => {
const isMetaMaskMultichainWallet = wallet instanceof MetaMaskShapeShiftMultiChainHDWallet
const isMetaMaskMultichainWallet = wallet instanceof MetaMaskMultiChainHDWallet
if (!(currentWalletId && isMetaMaskMultichainWallet && isSnapInstalled === false)) return

// We have just detected that the user doesn't have the snap installed currently
// We need to check whether or not the user had previous non-EVM AccountIds and clear those
if (hasUtxoAccountIds) appDispatch(portfolio.actions.clearWalletMetadata(currentWalletId))
}, [appDispatch, currentWalletId, hasUtxoAccountIds, isSnapInstalled, wallet, walletAccountIds])
if (hasNonEvmAccountIds) appDispatch(portfolio.actions.clearWalletMetadata(currentWalletId))
}, [appDispatch, currentWalletId, hasNonEvmAccountIds, isSnapInstalled, wallet, walletAccountIds])

useEffect(() => {
if (!isCorrectVersion && isSnapInstalled) return
Expand All @@ -122,18 +126,27 @@ export const Header = memo(() => {
isSnapInstalled === false &&
previousIsCorrectVersion === true
) {
// they uninstalled the snap
toast({
status: 'success',
title: translate('walletProvider.metaMaskSnap.snapUninstalledToast'),
position: 'bottom',
})
if (previousConnectedRdns === METAMASK_RDNS && connectedRdns === METAMASK_RDNS) {
// they uninstalled the snap
toast({
status: 'success',
title: translate('walletProvider.metaMaskSnap.snapUninstalledToast'),
position: 'bottom',
})
}
const walletId = currentWalletId
if (!walletId) return
appDispatch(portfolio.actions.clearWalletMetadata(walletId))
return snapModal.open({ isRemoved: true })
if (previousConnectedRdns === METAMASK_RDNS && connectedRdns === METAMASK_RDNS) {
return snapModal.open({ isRemoved: true })
}
}
if (previousSnapInstall === false && isSnapInstalled === true) {
if (
previousSnapInstall === false &&
isSnapInstalled === true &&
previousConnectedRdns === METAMASK_RDNS &&
connectedRdns === METAMASK_RDNS
) {
history.push(`/assets/${btcAssetId}`)

// they installed the snap
Expand All @@ -146,11 +159,13 @@ export const Header = memo(() => {
}
}, [
appDispatch,
connectedRdns,
currentWalletId,
dispatch,
history,
isCorrectVersion,
isSnapInstalled,
previousConnectedRdns,
previousIsCorrectVersion,
previousSnapInstall,
showSnapModal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const ChangePassphrase = () => {
// Trigger a refresh of the wallet metadata only once the settings have been applied
// and the previous wallet meta is gone from the store
dispatch({ type: WalletActions.SET_WALLET_MODAL, payload: true })
connect(KeyManager.KeepKey)
connect(KeyManager.KeepKey, false)
}, [
appDispatch,
connect,
Expand Down
29 changes: 25 additions & 4 deletions src/components/Layout/Header/NavBar/UserMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ChevronDownIcon, WarningTwoIcon } from '@chakra-ui/icons'
import type { ComponentWithAs, IconProps } from '@chakra-ui/react'
import {
Box,
Button,
Expand Down Expand Up @@ -27,6 +28,9 @@ import { RawText, Text } from 'components/Text'
import { WalletActions } from 'context/WalletProvider/actions'
import type { InitialState } from 'context/WalletProvider/WalletProvider'
import { useWallet } from 'hooks/useWallet/useWallet'
import { useMipdProviders } from 'lib/mipd'
import { selectWalletRdns } from 'state/slices/localWalletSlice/selectors'
import { useAppSelector } from 'state/store'

export const entries = [WalletConnectedRoutes.Connected]

Expand All @@ -50,7 +54,11 @@ export type WalletConnectedProps = {
onDisconnect: () => void
onSwitchProvider: () => void
onClose?: () => void
} & Pick<InitialState, 'walletInfo' | 'isConnected' | 'connectedType'>
walletInfo: {
icon: ComponentWithAs<'svg', IconProps> | string
name: string
} | null
} & Pick<InitialState, 'isConnected' | 'connectedType'>

export const WalletConnected = (props: WalletConnectedProps) => {
return (
Expand Down Expand Up @@ -86,6 +94,14 @@ const WalletButton: FC<WalletButtonProps> = ({
const bgColor = useColorModeValue('gray.200', 'gray.800')
const [ensName, setEnsName] = useState<string | null>('')

const maybeRdns = useAppSelector(selectWalletRdns)

const mipdProviders = useMipdProviders()
const maybeMipdProvider = useMemo(
() => mipdProviders.find(provider => provider.info.rdns === maybeRdns),
[mipdProviders, maybeRdns],
)

useEffect(() => {
if (!walletInfo?.meta?.address) return
viemEthMainnetClient
Expand Down Expand Up @@ -118,10 +134,10 @@ const WalletButton: FC<WalletButtonProps> = ({
() => (
<HStack>
{!(isConnected || isDemoWallet) && <WarningTwoIcon ml={2} w={3} h={3} color='yellow.500' />}
<WalletImage walletInfo={walletInfo} />
<WalletImage walletInfo={maybeMipdProvider?.info || walletInfo} />
</HStack>
),
[isConnected, isDemoWallet, walletInfo],
[isConnected, isDemoWallet, maybeMipdProvider, walletInfo],
)
const connectIcon = useMemo(() => <FaWallet />, [])

Expand Down Expand Up @@ -162,6 +178,11 @@ export const UserMenu: React.FC<{ onClick?: () => void }> = memo(({ onClick }) =
const { isConnected, isDemoWallet, walletInfo, connectedType, isLocked, isLoadingLocalWallet } =
state

const maybeRdns = useAppSelector(selectWalletRdns)

const mipdProviders = useMipdProviders()
const maybeMipdProvider = mipdProviders.find(provider => provider.info.rdns === maybeRdns)

const hasWallet = Boolean(walletInfo?.deviceId)
const handleConnect = useCallback(() => {
onClick && onClick()
Expand Down Expand Up @@ -189,7 +210,7 @@ export const UserMenu: React.FC<{ onClick?: () => void }> = memo(({ onClick }) =
{hasWallet || isLoadingLocalWallet ? (
<WalletConnected
isConnected={isConnected || isDemoWallet}
walletInfo={walletInfo}
walletInfo={maybeMipdProvider?.info || walletInfo}
onDisconnect={disconnect}
onSwitchProvider={handleConnect}
connectedType={connectedType}
Expand Down
18 changes: 11 additions & 7 deletions src/components/Layout/Header/NavBar/WalletImage.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import type { InitialState } from 'context/WalletProvider/WalletProvider'
import { type ComponentWithAs, type IconProps, Image } from '@chakra-ui/react'

type WalletImageProps = Pick<InitialState, 'walletInfo'>
type WalletImageProps = {
walletInfo: {
icon: ComponentWithAs<'svg', IconProps> | string
} | null
}

export const WalletImage = ({ walletInfo }: WalletImageProps) => {
const Icon = walletInfo?.icon
if (Icon) {
return <Icon width='6' height='auto' />
}
return null
if (!walletInfo) return null
if (typeof walletInfo.icon === 'string')
return <Image src={walletInfo.icon} width={6} height='auto' alt='Wallet Icon' />
const Icon = walletInfo.icon
return <Icon width='6' height='auto' />
}
Loading

0 comments on commit 0d5c449

Please sign in to comment.