Make Wallet connect outside the Farcaster Mini App (wagmi)
Dieser Inhalt ist noch nicht in deiner Sprache verfügbar.
We assume you are familiar with what a Farcaster Mini App is. Additionally this guide assumes you are familiar with wagmi.sh. In case you are not learn how to build onchain Mini Apps and do transactions.
We know Mini Apps are web applications that run in Farcaster clients like Warpcast. But what if we want to use the same wallet connection logic on our website?
Many mini apps are just built for Farcaster clients like Warpcast, but could be lovely mobile first experiences. We can enable that by allowing users to bring their wallet from outside Farcaster on direct page visits too.


Prerequisites
You have built a Farcaster Mini App.
If your mini app does not have wallet connection functionality right now, skip over the existing mini app migration code in this guide and go straight to the migrated RainbowKit and Farcaster mini app setup.
Enable Wallet Connections beyond the Farcaster Mini App
In the Farcaster Mini App we use the @farcaster/frame-wagmi-connector
to connect wallets. That isn’t available when accessed outside of Farcaster Mini Apps.
The connector is only use by the Farcaster clients to plug the users wallet right in for us to use. On our webpage, we add it ourselves.
To add the wallet ourselves there are many options of connectors we can use. Wagmi, the underlying library we use, has a lot of options documented here. Since that does not give us a user interface right away, we’ll use a ready made UI for this guide.
1) Install RainbowKit
bun add @rainbow-me/rainbowkit
npm install @rainbow-me/rainbowkit
pnpm install @rainbow-me/rainbowkit
yarn add @rainbow-me/rainbowkit
2) Add the RainbowKit Wallet Connector to your website
Now that we have RainbowKit installed, we need to integrate it with your webpage. This may be a bit different depending on your setup, but here is a general guide. To learn more refer to the RainbowKit Docs as well.
Our mini app will have a WagmiProvider.txx
or similar file setup that is adding the frameConnector. We will adapt this to use Rainbowkit. Enabling us to connect all kinds
of wallets outside of Farcaster mini apps too. Turning our mini app into a full onchain app.
Your Mini App WagmiProvider setup for the config likely looks like this
import { createConfig, http, WagmiProvider } from "wagmi";import { base } from "wagmi/chains";import { QueryClient, QueryClientProvider } from "@tanstack/react-query";import farcasterFrame from "@farcaster/frame-wagmi-connector";
export const config = createConfig({ chains: [base], transports: { [base.id]: http(process.env.BASE_RPC_URL), }, connectors: [farcasterFrame()],});
const queryClient = new QueryClient();
export default function Provider({ children }: { children: React.ReactNode }) { return ( <WagmiProvider config={config}> <QueryClientProvider client={queryClient}> {children} </QueryClientProvider> </WagmiProvider> );}
In case you don’t have one just create the file. We’ll update the WagmiProvider.tsx
to use RainbowKit instead of the Farcaster Mini App connector.
We are adding the Mini App Connector a bit later.
We are using the default WagmiConfig provided by the RainbowKit Documentation.
import "@rainbow-me/rainbowkit/styles.css";import { RainbowKitProvider, getDefaultConfig } from "@rainbow-me/rainbowkit";import { WagmiProvider } from "wagmi";import { base } from "wagmi/chains";import { QueryClient, QueryClientProvider } from "@tanstack/react-query";import { http } from "wagmi";
export const config = getDefaultConfig({ appName: "Morpho Frame App", projectId: process.env.NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID || "", chains: [base], transports: { [base.id]: http(process.env.BASE_RPC_URL), }, ssr: true,});
const queryClient = new QueryClient();
export default function Provider({ children }: { children: React.ReactNode }) { return ( <WagmiProvider config={config}> <QueryClientProvider client={queryClient}> <RainbowKitProvider>{children}</RainbowKitProvider> </QueryClientProvider> </WagmiProvider> );}
Make sure that your default app/page (could be layout.tsx or index.tsx or app.tsx depending on your Framework) is wrapped in the Provider!
For a remix RootLayout this could look like the following layout.tsx
import { Providers } from "~/app/providers";
//... metadata and others
export default function RootLayout({ children,}: Readonly<{ children: React.ReactNode;}>) { return ( <html lang="en"> <body> <Providers>{children}</Providers> </body> </html> );}
Now to add connection functionality to our app in the page/app we use the ConnectButton provided from RainbowKit.
The ConnectButton handles the Wallet connection for us outside of the Farcaster Mini App. We’ll later see how we can automatically ensure the FrameConnector is used when we are inside a mini app using React (which you could adopt to any other Framework).
// your importsimport { ConnectButton } from "@rainbow-me/rainbowkit";
//your logic
export function Home() { return ( <div> // your user interface <ConnectButton /> // more userinterface </div> );}
In a live App this may now look something like our nice localized german wallet connect button example below:

Now the last step is to ensure that in mini apps we always connect. And when connected we don’t show the wallet connect button again. We only need it when not connected right?
3) Ensure the Mini App connector is used when available & Web Wallet Connect Button hidden
To make sure that when we are in the mini app we use the mini app connector and when we are on the website we use the RainbowKit connector we add some logic.
Let’s use Wagmi to tell us if there already is a user connected or not. The useAccount()
hook does that for us. If there is no account we show the ConnectButton.
The variable isConnected
is a boolean that tells us if the user is connected or not. If we conditionally render the ConnectButton based on it, we know it only shows
if there is no wallet connected.
// imports// your logicconst { address, isConnected } = useAccount();
// your user interface{ !isConnected && <ConnectButton />;}// your user interface
Now we have a webpage that lets people use what also is intended to be inside a Farcaster mini app. What is missing is the mini app wallet connection itself.
Let’s add back the Farcaster Wallet connector. We can do this by manually using the frameConnector
in our page.
Let's adjust the logic calling `sdk.actions.ready()`
Likely your existing logic in react looks like the following to call the Farcaster Mini App SDK ready function.
useEffect(() => { const load = async () => { setContext(await sdk.context); sdk.actions.ready(); }; if (sdk && !isSDKLoaded) { setIsSDKLoaded(true); load(); } }, [isSDKLoaded]);
By adding the following effect to the code we ensure that when we are in a Mini App we connect the Farcaster Mini App connector wallet. It also handles calling ready on the sdk. If we don’t call ready, the mini app will be stuck on the loading screen. To get the context, which has information about where the mini app was accessed from, we use the sdk and store it in state.
import type { Context } from '@farcaster/frame-core';// importsimport { useEffect, useState } from "react";import sdk from "@farcaster/frame-sdk";import farcasterFrame from "@farcaster/frame-wagmi-connector";import { useConnect } from "wagmi";
// your codeconst [isSDKLoaded, setIsSDKLoaded] = useState(false);const [context, setContext] = useState<Context.FrameContext>();// an effect to ensure if we are in mini app context we connect the FarcasterFrame connector walletuseEffect(() => { const load = async () => { sdk.context .then((context) => { console.log({ context }); if (context) { setContext(context); connect({ connector: farcasterFrame(), chainId: base.id }); sdk.actions.ready(); } }) .catch((err) => { console.error(err); }); }; if (sdk && !isSDKLoaded) { setIsSDKLoaded(true); load(); }}, [isSDKLoaded]);// rest of your code
Bonus: Advanced Implementation of Mini App Wallet connect/disconnect and webpage Wallet Connect
NOTICE: Since the mini app host (Farcaster client) announces the injected provider, we likely are fine without adding back the connector. RainbowKit should work out of the box without additional config as long as you include the injected provider.
You may have noticed that we have no logic to prompt the user for connecting the wallet, well we don’t because we automatically connect in Mini App or show the wallet connect button right? but what if we want to have the user take action and delay the need to prompt for the friction of connecting a wallet?
Then we want to know if we are connected at a later stage. Such a component could look like the following code, where we check if we are connected, if we are outside a mini app and tell the user to use the ConnectButton. If we are in a mini app, we use the Farcaster Mini App native connect/disconnect functionality. This is enabled by Wagmi.
The state and connect flows are explained previously, so we only show the relevant component here.
import { useAccount, useConnect, useDisconnect } from "wagmi";import { base } from "wagmi/chains";// rest of your imports
const { disconnect } = useDisconnect();const { connect } = useConnect();
// rest of your code
{ !isConnected ? ( !context?.user ? ( <div className="text-center text-sm text-gray-600 dark:text-gray-400"> To transact connect a wallet by clicking below <div className="flex justify-center my-4"> <ConnectButton /> </div> </div> ) : ( <div> <div className="flex flex-col items-center w-full"> <h2 className="text-xl font-bold mb-4">Connect Wallet</h2> </div> <div className="mb-4"> <Button onClick={() => isConnected ? disconnect() : connect({ chainId: base.id, connector: config.connectors[0], }) } > {isConnected ? "Disconnect" : "Connect"} </Button> </div> </div> ) ) : ( <div> Your Code/Component for when wallet is connected aka your onchain flow </div> );}
// rest of your code