diff --git a/src/components/walletconnect/HeaderWidget/Icon.tsx b/src/components/walletconnect/HeaderWidget/Icon.tsx
index d47393067a..c2b8c7915e 100644
--- a/src/components/walletconnect/HeaderWidget/Icon.tsx
+++ b/src/components/walletconnect/HeaderWidget/Icon.tsx
@@ -1,10 +1,32 @@
-import { ButtonBase, SvgIcon } from '@mui/material'
+import { Badge, ButtonBase, SvgIcon } from '@mui/material'
import WalletConnectIcon from '@/public/images/common/walletconnect.svg'
+import SafeAppIconCard from '@/components/safe-apps/SafeAppIconCard'
-const Icon = (props: { onClick: () => void }) => (
+type IconProps = {
+ onClick: () => void
+ sessionCount: number
+ sessionInfo?: {
+ name: string
+ iconUrl: string
+ }
+}
+
+const Icon = ({ sessionCount, sessionInfo, ...props }: IconProps): React.ReactElement => (
-
+ 1
+ ? sessionCount
+ : sessionInfo &&
+ }
+ anchorOrigin={{
+ vertical: 'bottom',
+ horizontal: 'right',
+ }}
+ >
+
+
)
diff --git a/src/components/walletconnect/HeaderWidget/index.tsx b/src/components/walletconnect/HeaderWidget/index.tsx
index 6b2af8c27a..96f26df263 100644
--- a/src/components/walletconnect/HeaderWidget/index.tsx
+++ b/src/components/walletconnect/HeaderWidget/index.tsx
@@ -2,6 +2,7 @@ import { useCallback, useContext, useRef, useState } from 'react'
import { Badge, Box } from '@mui/material'
import { WalletConnectContext } from '@/services/walletconnect/WalletConnectContext'
+import useWalletConnectSessions from '@/services/walletconnect/useWalletConnectSessions'
import Icon from './Icon'
import SessionManager from '../SessionManager'
import Popup from '../Popup'
@@ -10,18 +11,28 @@ const WalletConnectHeaderWidget = () => {
const { error } = useContext(WalletConnectContext)
const [popupOpen, setPopupOpen] = useState(false)
const iconRef = useRef(null)
+ const sessions = useWalletConnectSessions()
+
const onOpen = useCallback(() => setPopupOpen(true), [])
const onClose = useCallback(() => setPopupOpen(false), [])
return (
-
+
-
+
)
diff --git a/src/components/walletconnect/SessionManager/index.tsx b/src/components/walletconnect/SessionManager/index.tsx
index 8852ae9833..d0e1881b76 100644
--- a/src/components/walletconnect/SessionManager/index.tsx
+++ b/src/components/walletconnect/SessionManager/index.tsx
@@ -4,24 +4,22 @@ import type { SessionTypes } from '@walletconnect/types'
import useSafeInfo from '@/hooks/useSafeInfo'
import { WalletConnectContext } from '@/services/walletconnect/WalletConnectContext'
-import useWalletConnectSessions from '@/services/walletconnect/useWalletConnectSessions'
import { asError } from '@/services/exceptions/utils'
import ProposalForm from '../ProposalForm'
import WcInput from '../WcInput'
import ErrorMessage from '@/components/tx/ErrorMessage'
import SessionList from '../SessionList'
-const SessionManager = () => {
+const SessionManager = ({ sessions }: { sessions: SessionTypes.Struct[] }) => {
const { safe, safeAddress } = useSafeInfo()
const { chainId } = safe
const { walletConnect, error: walletConnectError } = useContext(WalletConnectContext)
- const sessions = useWalletConnectSessions()
const [proposal, setProposal] = useState()
const [error, setError] = useState()
// On session approve
const onApprove = useCallback(async () => {
- if (!chainId || !safeAddress || !proposal) return
+ if (!walletConnect || !chainId || !safeAddress || !proposal) return
try {
await walletConnect.approveSession(proposal, chainId, safeAddress)
@@ -35,7 +33,7 @@ const SessionManager = () => {
// On session reject
const onReject = useCallback(async () => {
- if (!proposal) return
+ if (!walletConnect || !proposal) return
try {
await walletConnect.rejectSession(proposal)
@@ -49,6 +47,7 @@ const SessionManager = () => {
// On session disconnect
const onDisconnect = async (session: SessionTypes.Struct) => {
+ if (!walletConnect) return
try {
await walletConnect.disconnectSession(session)
} catch (error) {
@@ -58,6 +57,7 @@ const SessionManager = () => {
// Subscribe to session proposals
useEffect(() => {
+ if (!walletConnect) return
return walletConnect.onSessionPropose(setProposal)
}, [walletConnect])
diff --git a/src/components/walletconnect/WcInput/index.tsx b/src/components/walletconnect/WcInput/index.tsx
index 2ecdf2c473..19d29d68ba 100644
--- a/src/components/walletconnect/WcInput/index.tsx
+++ b/src/components/walletconnect/WcInput/index.tsx
@@ -1,6 +1,6 @@
-import { TextField, Typography } from '@mui/material'
-import { useContext, useState } from 'react'
+import { useCallback, useContext, useState } from 'react'
import type { ChangeEvent } from 'react'
+import { TextField, Typography } from '@mui/material'
import { WalletConnectContext } from '@/services/walletconnect/WalletConnectContext'
import { asError } from '@/services/exceptions/utils'
@@ -10,18 +10,27 @@ const WcInput = () => {
const [error, setError] = useState()
const [connecting, setConnecting] = useState(false)
- const onInput = async (e: ChangeEvent) => {
- const uri = e.target.value
-
- try {
- await walletConnect.connect(uri)
- } catch (e) {
- setError(asError(e))
- return
- }
-
- setConnecting(true)
- }
+ const onInput = useCallback(
+ async (e: ChangeEvent) => {
+ if (!walletConnect) return
+
+ const uri = e.target.value
+ if (!uri) {
+ setError(undefined)
+ return
+ }
+
+ try {
+ await walletConnect.connect(uri)
+ } catch (e) {
+ setError(asError(e))
+ return
+ }
+
+ setConnecting(true)
+ },
+ [walletConnect],
+ )
return (
<>
diff --git a/src/services/walletconnect/WalletConnectContext.tsx b/src/services/walletconnect/WalletConnectContext.tsx
index a89be49c19..481bcb8361 100644
--- a/src/services/walletconnect/WalletConnectContext.tsx
+++ b/src/services/walletconnect/WalletConnectContext.tsx
@@ -6,13 +6,13 @@ import WalletConnectWallet from './WalletConnectWallet'
import { asError } from '../exceptions/utils'
import { stripEip155Prefix } from './utils'
-const walletConnect = new WalletConnectWallet()
+const walletConnectSingleton = new WalletConnectWallet()
export const WalletConnectContext = createContext<{
- walletConnect: WalletConnectWallet
+ walletConnect: WalletConnectWallet | null
error: Error | null
}>({
- walletConnect,
+ walletConnect: null,
error: null,
})
@@ -21,31 +21,35 @@ export const WalletConnectProvider = ({ children }: { children: ReactNode }) =>
safe: { chainId },
safeAddress,
} = useSafeInfo()
+ const [walletConnect, setWalletConnect] = useState(null)
const [error, setError] = useState(null)
const safeWalletProvider = useSafeWalletProvider()
// Init WalletConnect
useEffect(() => {
- walletConnect.init().catch(setError)
+ walletConnectSingleton
+ .init()
+ .then(() => setWalletConnect(walletConnectSingleton))
+ .catch(setError)
}, [])
// Update chainId
useEffect(() => {
- if (chainId) {
- walletConnect.chainChanged(chainId).catch(setError)
- }
- }, [chainId])
+ if (!walletConnect || !chainId) return
+
+ walletConnect.chainChanged(chainId).catch(setError)
+ }, [walletConnect, chainId])
// Update accounts
useEffect(() => {
- if (safeAddress && chainId) {
- walletConnect.accountsChanged(chainId, safeAddress).catch(setError)
- }
- }, [chainId, safeAddress])
+ if (!walletConnect || !chainId || !safeAddress) return
+
+ walletConnect.accountsChanged(chainId, safeAddress).catch(setError)
+ }, [walletConnect, chainId, safeAddress])
// Subscribe to requests
useEffect(() => {
- if (!safeWalletProvider || !chainId) return
+ if (!walletConnect || !safeWalletProvider || !chainId) return
return walletConnect.onRequest(async (event) => {
const { topic } = event
@@ -69,7 +73,7 @@ export const WalletConnectProvider = ({ children }: { children: ReactNode }) =>
setError(asError(e))
}
})
- }, [chainId, safeWalletProvider])
+ }, [walletConnect, chainId, safeWalletProvider])
return {children}
}
diff --git a/src/services/walletconnect/useWalletConnectSessions.ts b/src/services/walletconnect/useWalletConnectSessions.ts
index 5958b06467..1b9d1138d7 100644
--- a/src/services/walletconnect/useWalletConnectSessions.ts
+++ b/src/services/walletconnect/useWalletConnectSessions.ts
@@ -7,6 +7,7 @@ function useWalletConnectSessions(): SessionTypes.Struct[] {
const [sessions, setSessions] = useState([])
const updateSessions = useCallback(() => {
+ if (!walletConnect) return
setSessions(walletConnect.getActiveSessions())
}, [walletConnect])
@@ -15,11 +16,13 @@ function useWalletConnectSessions(): SessionTypes.Struct[] {
// On session add
useEffect(() => {
+ if (!walletConnect) return
return walletConnect.onSessionAdd(updateSessions)
}, [walletConnect, updateSessions])
// On session delete
useEffect(() => {
+ if (!walletConnect) return
return walletConnect.onSessionDelete(updateSessions)
}, [walletConnect, updateSessions])