import React, { ReactNode } from 'react'; import { SiweMessage } from 'siwe'; import { WagmiProvider } from 'wagmi'; import { arbitrum, mainnet } from 'wagmi/chains'; import axios from 'axios'; import { createWeb3Modal } from '@web3modal/wagmi/react'; import { defaultWagmiConfig } from '@web3modal/wagmi/react/config'; import { createSIWEConfig } from '@web3modal/siwe'; import type { SIWECreateMessageArgs, SIWEVerifyMessageArgs, } from '@web3modal/core'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; const queryClient = new QueryClient(); const axiosInstance = axios.create({ baseURL: process.env.REACT_APP_SERVER_URL, headers: { 'Content-Type': 'application/json', 'Access-Control-Allow-Origin': '*', }, withCredentials: true, }); const metadata = { name: 'Web3Modal', description: 'Snowball Web3Modal', url: window.location.origin, icons: [ 'https://raw.githubusercontent.com/snowball-tools/mediakit/main/assets/logo.svg', ], }; const chains = [mainnet, arbitrum] as const; const config = defaultWagmiConfig({ chains, projectId: process.env.REACT_APP_WALLET_CONNECT_ID, metadata, }); const siweConfig = createSIWEConfig({ createMessage: ({ nonce, address, chainId }: SIWECreateMessageArgs) => new SiweMessage({ version: '1', domain: window.location.host, uri: window.location.origin, address, chainId, nonce, // Human-readable ASCII assertion that the user will sign, and it must not contain `\n`. statement: 'Sign in With Ethereum.', }).prepareMessage(), getNonce: async () => { const nonce = (await axiosInstance.get('/auth/nonce')).data; if (!nonce) { throw new Error('Failed to get nonce!'); } return nonce; }, getSession: async () => { try { const session = (await axiosInstance.get('/auth/session')).data; const { address, chainId } = session; return { address, chainId }; } catch (err) { if (window.location.pathname !== '/login') { window.location.href = '/login'; } throw new Error('Failed to get session!'); } }, verifyMessage: async ({ message, signature }: SIWEVerifyMessageArgs) => { try { const { success } = ( await axiosInstance.post('/auth/validate', { message, signature, }) ).data; return success; } catch (error) { return false; } }, signOut: async () => { try { const { success } = (await axiosInstance.post('/auth/logout')).data; return success; } catch (error) { return false; } }, onSignOut: () => { window.location.href = '/login'; }, onSignIn: () => { window.location.href = '/'; }, }); if (!process.env.REACT_APP_WALLET_CONNECT_ID) { throw new Error('Error: REACT_APP_WALLET_CONNECT_ID env config is not set'); } createWeb3Modal({ siweConfig, wagmiConfig: config, projectId: process.env.REACT_APP_WALLET_CONNECT_ID, }); export default function Web3ModalProvider({ children, }: { children: ReactNode; }) { return ( {children} ); }