diff --git a/src/pages/connect.tsx b/src/pages/connect.tsx new file mode 100644 index 0000000000..caa3a96b19 --- /dev/null +++ b/src/pages/connect.tsx @@ -0,0 +1,31 @@ +import type { NextPage } from 'next' +import Head from 'next/head' +import { useRouter } from 'next/router' +import useLastSafe from '@/hooks/useLastSafe' +import useSafeWalletConnect from '@/safe-wallet-provider/useSafeWalletConnect' + +const Connect: NextPage = () => { + const router = useRouter() + const { safe } = router.query + const lastSafe = useLastSafe() + + if (!safe && lastSafe) { + router.replace(`/connect?safe=${lastSafe}`) + } + + useSafeWalletConnect() + + return ( + <> + + {'Safe{Wallet} – Connect'} + + +
+

Connect

+
+ + ) +} + +export default Connect diff --git a/src/safe-wallet-provider/provider.ts b/src/safe-wallet-provider/provider.ts index bcc16e6ac1..0e77616fd9 100644 --- a/src/safe-wallet-provider/provider.ts +++ b/src/safe-wallet-provider/provider.ts @@ -8,10 +8,11 @@ type WalletSDK = { signTypedMessage: (typedData: unknown) => Promise<{ signature?: string }> send: (params: { txs: unknown[]; params: { safeTxGas: number } }) => Promise<{ safeTxHash: string }> getBySafeTxHash: (safeTxHash: string) => Promise<{ txHash?: string }> - proxy: (method: string, params: unknown[]) => Promise + proxy: (method: string, params: unknown[]) => Promise<{ result: unknown }> } interface RpcRequest { + id: number method: string params?: unknown[] } @@ -26,10 +27,13 @@ export class SafeWalletProvider { this.sdk = sdk } - async request(request: RpcRequest): Promise { + private async makeRequest(request: RpcRequest): Promise { const { method, params = [] } = request switch (method) { + case 'wallet_switchEthereumChain': + return true + case 'eth_accounts': return [this.safe.safeAddress] @@ -137,4 +141,17 @@ export class SafeWalletProvider { return await this.sdk.proxy(method, params) } } + + async request(request: RpcRequest): Promise<{ + jsonrpc: string + id: number + result?: unknown + }> { + const result = await this.makeRequest(request) + return { + jsonrpc: '2.0', + id: request.id, + result, + } + } } diff --git a/src/safe-wallet-provider/useSafeWalletConnect.ts b/src/safe-wallet-provider/useSafeWalletConnect.ts new file mode 100644 index 0000000000..0bbe5946cc --- /dev/null +++ b/src/safe-wallet-provider/useSafeWalletConnect.ts @@ -0,0 +1,35 @@ +import { useEffect } from 'react' +import useSafeWalletProvider from './useSafeWalletProvider' + +const useSafeWalletConnect = () => { + const safeWalletProvider = useSafeWalletProvider() + + useEffect(() => { + if (!safeWalletProvider) return + + const handler = async (e: MessageEvent) => { + if (e.origin === location.origin) return + + if (e.data.safeRpcRequest) { + const response = await safeWalletProvider.request(e.data.safeRpcRequest) + + window.opener?.postMessage( + { + safeRpcResponse: response, + }, + e.origin, + ) + } + } + + window.addEventListener('message', handler) + + window.opener?.postMessage('safeWalletLoaded', '*') + + return () => { + window.removeEventListener('message', handler) + } + }, [safeWalletProvider]) +} + +export default useSafeWalletConnect diff --git a/src/safe-wallet-provider/useSafeWalletProvider.tsx b/src/safe-wallet-provider/useSafeWalletProvider.tsx index 87c6369ded..1449e35c9d 100644 --- a/src/safe-wallet-provider/useSafeWalletProvider.tsx +++ b/src/safe-wallet-provider/useSafeWalletProvider.tsx @@ -69,7 +69,8 @@ const useSafeWalletProvider = (): SafeWalletProvider | undefined => { }, async proxy(method: string, params: unknown[]) { - return web3ReadOnly?.send(method, params) + const data = await web3ReadOnly?.send(method, params) + return data.result }, } }, [safeAddress, chainId, setTxFlow, web3ReadOnly])