Hi @vjgee ,
Currently we don’t have the app deployed, so I won’t be available to share the link.
For WalletConnect, we are using V2. More specifically we are using package @web3auth/wallet-connect-v2-adapter
with version 5.2.0
.
We tried some other versions of the package but none of them solved the issue.
Implementation-
Also just to clarify we are using wagmi with web3Auth for web3 connectivity.
Web3Auth setup file with all adapters setup.
import { Chain } from "wagmi";
import { CHAIN_NAMESPACES } from "@web3auth/base";
import { Web3AuthNoModal } from "@web3auth/no-modal";
import { CoinbaseAdapter } from "@web3auth/coinbase-adapter";
import { MetamaskAdapter } from "@web3auth/metamask-adapter";
import { OpenloginAdapter } from "@web3auth/openlogin-adapter";
import { WalletConnectV2Adapter } from "@web3auth/wallet-connect-v2-adapter";
export default function Web3AuthNoModalConnectorInstance(chains: Chain[]) {
if (typeof window !== "undefined") {
const web3AuthInstance = new Web3AuthNoModal({
clientId: process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID as string,
chainConfig: {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: `0x${chains[0].id.toString(16)}`,
rpcTarget: chains[0].rpcUrls.default.http[0],
displayName: chains[0].name,
tickerName: chains[0].nativeCurrency?.name,
ticker: chains[0].nativeCurrency?.symbol,
},
web3AuthNetwork: "testnet",
enableLogging: false,
});
const verifier = [verifier];
const openloginAdapter = new OpenloginAdapter({
clientId: [clientId],
adapterSettings: {
redirectUrl: [redirectUrl],
clientId: process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID as string,
uxMode: "popup",
loginConfig: {
google: {
name: "Google",
verifier,
verifierSubIdentifier: [google sub verifier name],
typeOfLogin: "google",
clientId: [google client Id],
},
twitterauth0: {
name: "Twitter",
verifier, // Pass the Verifier name here. eg. w3a-agg-example
verifierSubIdentifier: [twitter sub verifier name],
typeOfLogin: "twitter",
clientId: [twitter client Id],
},
discordauth0: {
name: "Discord",
verifier, // Pass the Verifier name here. eg. w3a-agg-example
verifierSubIdentifier: [discord sub verifier name],
typeOfLogin: "discord",
clientId: [discord client Id],
},
},
},
});
const metamaskAdapter = new MetamaskAdapter({
clientId: process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID as string,
sessionTime: 3600,
web3AuthNetwork: "testnet",
});
const walletConnectV2Adapter = new WalletConnectV2Adapter({
clientId: process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID as string,
sessionTime: 3600,
web3AuthNetwork: "testnet",
});
const coinbaseAdapter = new CoinbaseAdapter({
clientId: process.env.NEXT_PUBLIC_WEB3AUTH_CLIENT_ID as string,
sessionTime: 3600,
web3AuthNetwork: "testnet",
});
web3AuthInstance.configureAdapter(openloginAdapter);
web3AuthInstance.configureAdapter(metamaskAdapter);
web3AuthInstance.configureAdapter(walletConnectV2Adapter);
web3AuthInstance.configureAdapter(coinbaseAdapter);
return web3AuthInstance;
}
}
app file where we are using the above function-
"use client";
import "@/styles/globals.css";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
import React from "react";
import Script from "next/script";
import { WagmiConfig, createClient } from "wagmi";
import { PriceProvider } from "@/context/PriceSelector";
import { ReactQueryDevtools } from "react-query/devtools";
import { MetaMaskConnector } from "wagmi/connectors/metaMask";
import { QueryClient, QueryClientProvider } from "react-query";
import { Web3AuthConnector } from "@web3auth/web3auth-wagmi-connector";
import { WalletConnectConnector } from "wagmi/connectors/walletConnect";
import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet";
import { ToastProvider } from "@/components/ui/toast";
import { TooltipProvider } from "@/components/ui/tooltip";
import { chains, provider, webSocketProvider } from "@/config/chains";
import Web3AuthNoModalConnectorInstance from "@/config/Web3AuthNoModalConnectorInstance";
import { CartProvider } from "@/context/Cart";
import { UserProvider } from "@/context/User";
const instance = Web3AuthNoModalConnectorInstance(chains);
const config = createClient({
autoConnect: false,
connectors: [
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
...[
instance &&
new Web3AuthConnector({
chains,
options: {
web3AuthInstance: instance,
loginParams: {
loginProvider: "discord",
mfaLevel: "optional",
getWalletKey: true,
extraLoginOptions: {
prompt: "select_account",
},
},
},
}),
instance &&
new Web3AuthConnector({
chains,
options: {
web3AuthInstance: instance,
loginParams: {
loginProvider: "google",
mfaLevel: "optional",
getWalletKey: true,
extraLoginOptions: {
prompt: "select_account",
},
},
},
}),
instance &&
new Web3AuthConnector({
chains,
options: {
web3AuthInstance: instance,
loginParams: {
loginProvider: "twitter",
mfaLevel: "optional",
getWalletKey: true,
extraLoginOptions: {
prompt: "select_account",
},
},
},
}),
instance &&
new MetaMaskConnector({
chains,
options: {
shimDisconnect: true,
shimChainChangedDisconnect: true,
},
}),
instance &&
new WalletConnectConnector({
chains,
options: {
projectId: [projectId]
qrcode: true,
},
}),
instance &&
new CoinbaseWalletConnector({
chains,
options: {
appName: [appName],
},
}),
],
],
provider,
webSocketProvider,
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export default function App({ Component, pageProps }: any) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const Layout = Component.layout || (({ children }: any) => <>{children}</>);
const [queryClient] = React.useState(() => new QueryClient());
return (
<>
<WagmiConfig client={config}>
<QueryClientProvider client={queryClient}>
<ToastProvider>
<TooltipProvider>
<PriceProvider>
<UserProvider>
<CartProvider>
<Layout>
<Component {...pageProps} />
</Layout>
</CartProvider>
</UserProvider>
</PriceProvider>
</TooltipProvider>
</ToastProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</WagmiConfig>
</>
);
}
login file where we are implementing all the web3Auth connectors-
import Navbar from "@/components/layout/Navbar";
import { verifySignature } from "@/utils/apiCalls";
import { MouseEventHandler, useEffect, useState } from "react";
import {
Connector,
useAccount,
useConnect,
useDisconnect,
useSignMessage,
} from "wagmi";
export default function Home() {
const { disconnect } = useDisconnect();
const { address, connector, isConnected } = useAccount();
const { data, signMessage, variables } = useSignMessage();
const { connect, connectors, error, isLoading, pendingConnector } =
useConnect();
const [hydrated, setHydrated] = useState(false);
const returnConnectionName = (conn: Connector) => {
return conn?.options?.loginParams?.loginProvider || conn?.name;
};
const returnValidatorForConnection = (conn: Connector) => {
if (conn.id === "web3auth") {
return (
conn?.options?.loginParams?.loginProvider ===
pendingConnector?.options?.loginParams?.loginProvider
);
}
return conn?.id === pendingConnector?.id;
};
const verifyUserSignature = async () => {
try {
const response = await verifySignature({
walletAddress: address,
message: variables?.message,
signature: data,
});
console.log(response);
} catch (err: unknown) {
console.error(err);
}
};
useEffect(() => {
setHydrated(true);
}, []);
useEffect(() => {
if (!address || !isConnected) return;
signMessage({
message: "message",
});
}, [address, isConnected]);
useEffect(() => {
if (data) {
verifyUserSignature();
}
}, [data]);
if (!hydrated) {
return null;
}
return (
<div className="main">
<Navbar />
{isConnected ? (
<div>
<div className="title">
Connected to{" "}
{connector?.options.loginParams?.loginProvider ||
connector?.name}
</div>
<div>{address}</div>
<button
type="button"
className="card"
onClick={disconnect as unknown as MouseEventHandler}
>
Disconnect
</button>
</div>
) : (
<>
<div className="flex flex-col">
{connectors &&
connectors.map((conn: Connector, index) => {
const connectionName =
returnConnectionName(conn);
const validator =
returnValidatorForConnection(conn);
return (
<div
className="flex-auto"
key={index as unknown as number}
>
<button
type="button"
disabled={!conn?.ready}
key={conn?.id}
onClick={() =>
connect({ connector: conn })
}
>
{connectionName}
{!conn?.ready && " (unsupported)"}
{isLoading &&
validator &&
" (connecting)"}
</button>
<br />
<br />
{validator && error && (
<div>{error.message}</div>
)}
</div>
);
})}
</div>
</>
)}
</div>
);
}
Let me know if any other details are needed.
Thank you.