|
| 1 | +--- |
| 2 | +title: Integrate Sign In with Farcaster with Web3Auth MPC CoreKit Web SDK |
| 3 | +image: "guides/banners/farcaster-mpc-ck-web.png" |
| 4 | +description: Learn how to use Sign In with Farcaster with Web3Auth MPC CoreKit Web SDK |
| 5 | +type: guide |
| 6 | +tags: ["@web3auth/mpc-core-kit", mpc, mpc-core-kit-web, farcaster, react, ethereum, next.js] |
| 7 | +date: May 8, 2024 |
| 8 | +author: Web3Auth Team |
| 9 | +communityPortalTopicId: |
| 10 | +pinned: false |
| 11 | +--- |
| 12 | + |
| 13 | +import SEO from "@site/src/components/SEO"; |
| 14 | + |
| 15 | +<SEO |
| 16 | + title="Integrate Sign In with Farcaster with Web3Auth MPC CoreKit Web SDK" |
| 17 | + description="Learn how to use Sign In with Farcaster with Web3Auth MPC CoreKit Web SDK" |
| 18 | + image="https://web3auth.io/docs/guides/banners/farcaster-mpc-ck-web.png" |
| 19 | + slug="/guides/farcaster-mpc-core-kit-web" |
| 20 | +/> |
| 21 | + |
| 22 | +### Prerequisites: |
| 23 | + |
| 24 | +- Basic understanding of React and Next.js |
| 25 | +- Familiarity with JavaScript and TypeScript |
| 26 | +- Basic knowledge of authentication and JWT tokens |
| 27 | + |
| 28 | +### Step 1: Install and Configure Sign In with Farcaster |
| 29 | + |
| 30 | +a. **Install Dependencies**: Install `auth-kit` and its peer dependency `viem` using npm. |
| 31 | + |
| 32 | +```bash |
| 33 | +npm install @farcaster/auth-kit viem |
| 34 | +``` |
| 35 | + |
| 36 | +Note: `auth-kit` is a React library. If you're using a different framework, take a look at the |
| 37 | +[client library](https://docs.farcaster.xyz/auth-kit/client/introduction) instead. |
| 38 | + |
| 39 | +b. **Import Libraries**: Import `auth-kit` and its CSS styles into your React component. |
| 40 | + |
| 41 | +```tsx |
| 42 | +import "@farcaster/auth-kit/styles.css"; |
| 43 | +import { AuthKitProvider, SignInButton, useProfile } from "@farcaster/auth-kit"; |
| 44 | +``` |
| 45 | + |
| 46 | +c. **Configure Provider**: Set up a provider with your desired configuration including the RPC URL, |
| 47 | +domain, and login URL. |
| 48 | + |
| 49 | +```tsx |
| 50 | +const config = { |
| 51 | + rpcUrl: "https://mainnet.optimism.io", |
| 52 | + domain: "example.com", |
| 53 | + siweUri: "https://example.com/login", |
| 54 | +}; |
| 55 | +``` |
| 56 | + |
| 57 | +d. **Integrate Sign-In Button**: Render the `SignInButton` component in your UI to prompt users to |
| 58 | +sign in. |
| 59 | + |
| 60 | +```tsx |
| 61 | +const App = () => { |
| 62 | + return ( |
| 63 | + <AuthKitProvider config={config}> |
| 64 | + {/* Your App */} |
| 65 | + <SignInButton /> |
| 66 | + </AuthKitProvider> |
| 67 | + ); |
| 68 | +}; |
| 69 | +``` |
| 70 | + |
| 71 | +### Step 2: Verify Signatures on Backend |
| 72 | + |
| 73 | +We will be using `NextAuth` to implement Authorization logic. |
| 74 | + |
| 75 | +a. **Create a NextAuth API**: Create an API route using NextAuth to handle authentication and |
| 76 | +signature verification. |
| 77 | + |
| 78 | +`pages/api/auth/[...nextauth].ts` |
| 79 | + |
| 80 | +```tsx |
| 81 | +import NextAuth from "next-auth"; |
| 82 | +import CredentialsProvider from "next-auth/providers/credentials"; |
| 83 | +import { createAppClient, viemConnector } from "@farcaster/auth-client"; |
| 84 | +``` |
| 85 | + |
| 86 | +b. **Authorization Logic**: Implement authorization logic to verify user signatures and credentials. |
| 87 | + |
| 88 | +```tsx |
| 89 | + async authorize(credentials) { |
| 90 | + const { body: { csrfToken } } = req; |
| 91 | + |
| 92 | + const appClient = createAppClient({ |
| 93 | + ethereum: viemConnector(), |
| 94 | + }); |
| 95 | + |
| 96 | + const verifyResponse = await appClient.verifySignInMessage({ |
| 97 | + message: credentials?.message as string, |
| 98 | + signature: credentials?.signature as `0x${string}`, |
| 99 | + domain: "example.com", |
| 100 | + nonce: csrfToken, |
| 101 | + }); |
| 102 | + const { success, fid } = verifyResponse; |
| 103 | + |
| 104 | + if (!success) { |
| 105 | + return null; |
| 106 | + } |
| 107 | + |
| 108 | + return { |
| 109 | + id: fid.toString(), |
| 110 | + name: credentials?.name, |
| 111 | + image: credentials?.pfp, |
| 112 | + }; |
| 113 | + }, |
| 114 | +``` |
| 115 | + |
| 116 | +### Step 3: Generate a JWT Token using Farcaster User's data |
| 117 | + |
| 118 | +a. **Create a JWT Token**: Create an API endpoint to generate JWT tokens containing user's data from |
| 119 | +Farcaster. |
| 120 | +[Follow these steps to setup your Custom Verifier with Web3Auth](https://web3auth.io/docs/auth-provider-setup/byo-jwt-provider#set-up-custom-jwt-verifier). |
| 121 | +`pages/api/login.ts` |
| 122 | + |
| 123 | +```tsx |
| 124 | +import jwt from "jsonwebtoken"; |
| 125 | +``` |
| 126 | + |
| 127 | +b. **JWT Signing**: Sign the JWT token using a |
| 128 | +[private key](https://web3auth.io/docs/auth-provider-setup/byo-jwt-provider#using-rsa-for-jwt-signing) |
| 129 | +and include necessary user data that you get from Farcaster. |
| 130 | + |
| 131 | +```tsx |
| 132 | +const userData = req.body.userData; |
| 133 | +// Get RS256 key of length 2048 |
| 134 | +const privateKey = process.env.PRIVATE_KEY!; |
| 135 | + |
| 136 | +const jwtToken = jwt.sign( |
| 137 | + { |
| 138 | + sub: userData?.fid.toString(), |
| 139 | + name: userData?.displayName, |
| 140 | + username: userData?.username, |
| 141 | + profileImage: userData?.pfpUrl, |
| 142 | + custody: userData?.custody, |
| 143 | + aud: "w3a:farcaster-server", |
| 144 | + iss: "https://web3auth.io", |
| 145 | + iat: Math.floor(Date.now() / 1000), |
| 146 | + exp: Math.floor(Date.now() / 1000) + 60 * 60, |
| 147 | + }, |
| 148 | + privateKey, |
| 149 | + { algorithm: "RS256", keyid: "REPLACE_KEY_ID" }, |
| 150 | +); |
| 151 | +``` |
| 152 | + |
| 153 | +### Step 4: Authenticate with Web3Auth |
| 154 | + |
| 155 | +a. **Initialize Web3Auth MPC CoreKit Web SDK**: Set up Web3Auth instance and configure it with |
| 156 | +necessary parameters. |
| 157 | + |
| 158 | +```tsx |
| 159 | +import { Web3AuthMPCCoreKit, WEB3AUTH_NETWORK, parseToken } from "@web3auth/mpc-core-kit"; |
| 160 | +import { EthereumSigningProvider } from "@web3auth/ethereum-mpc-provider"; |
| 161 | + |
| 162 | +const coreKitInstance = new Web3AuthMPCCoreKit({ |
| 163 | + web3AuthClientId, // Your Web3Auth Client ID |
| 164 | + web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET, // Web3Auth Network |
| 165 | + setupProviderOnInit: false, // if needed to skip the provider setup |
| 166 | + manualSync: true, // This is the recommended approach since it allows you to control the sync process |
| 167 | +}); |
| 168 | + |
| 169 | +const chainConfig = { |
| 170 | + chainNamespace: CHAIN_NAMESPACES.EIP155, |
| 171 | + chainId: "0x1", // Please use 0x1 for Mainnet |
| 172 | + rpcTarget: "https://rpc.ankr.com/eth", |
| 173 | + displayName: "Ethereum Mainnet", |
| 174 | + blockExplorer: "https://etherscan.io/", |
| 175 | + ticker: "ETH", |
| 176 | + tickerName: "Ethereum", |
| 177 | +}; |
| 178 | + |
| 179 | +const evmProvider = new EthereumSigningProvider({ config: { chainConfig } }); |
| 180 | +evmProvider.setupProvider(coreKitInstance); |
| 181 | + |
| 182 | +await coreKitInstance.init(); |
| 183 | +``` |
| 184 | + |
| 185 | +b. **Get idToken from your backend**: |
| 186 | + |
| 187 | +```tsx |
| 188 | +const response = await fetch("/api/login", { |
| 189 | + method: "POST", |
| 190 | + headers: { |
| 191 | + "Content-Type": "application/json", |
| 192 | + }, |
| 193 | + body: JSON.stringify({ userData: res }), |
| 194 | +}); |
| 195 | +const data = await response.json(); |
| 196 | +const token = data.token; |
| 197 | +``` |
| 198 | + |
| 199 | +c. **Initiate Web3Auth Login**: |
| 200 | + |
| 201 | +Implement login functionality using the generated JWT token. |
| 202 | + |
| 203 | +```tsx |
| 204 | +const login = async (idToken: any) => { |
| 205 | + // Login logic |
| 206 | + if (!coreKitInstance) { |
| 207 | + throw new Error("Web3Auth CoreKit not initialized"); |
| 208 | + } |
| 209 | + const { payload } = parseToken(idToken); |
| 210 | + |
| 211 | + await coreKitInstance.loginWithJWT({ |
| 212 | + verifier, // Your verifier name from Web3Auth Dashboard |
| 213 | + verifierId: (payload as any).sub, // based on your setup |
| 214 | + idToken, // JWT token from your backend |
| 215 | + }); |
| 216 | + if (coreKitInstance.status === COREKIT_STATUS.LOGGED_IN) { |
| 217 | + await coreKitInstance.commitChanges(); // Needed to commit for new accounts, when using manualSync: true |
| 218 | + } |
| 219 | +}; |
| 220 | +``` |
| 221 | + |
| 222 | +### Step 5 (Optional): Additional Features |
| 223 | + |
| 224 | +a. **Blockchain Interactions**: Include optional features like checking balances, signing messages, |
| 225 | +and sending transactions. |
| 226 | + |
| 227 | +```tsx |
| 228 | +const getBalance = async (provider: IProvider) => { |
| 229 | + // Get balance logic |
| 230 | +}; |
| 231 | +``` |
| 232 | + |
| 233 | +b. **Logout Functionality**: Implement logout functionality for users. |
| 234 | + |
| 235 | +```tsx |
| 236 | +const logOut = async () => { |
| 237 | + await coreKitInstance.logout(); |
| 238 | + await signOut(); |
| 239 | +}; |
| 240 | +``` |
| 241 | + |
| 242 | +### Full Implementation Example |
| 243 | + |
| 244 | +Here's |
| 245 | +[an example of how to integrate the above steps into your Next.js application](https://github.com/Web3Auth/web3auth-core-kit-examples/tree/main/mpc-core-kit-web/mpc-core-kit-farcaster) |
| 246 | + |
| 247 | +--- |
| 248 | + |
| 249 | +This guide should provide a clear structure and step-by-step instructions for integrating |
| 250 | +[`Sign In with Farcaster`](https://docs.farcaster.xyz/auth-kit/installation) using |
| 251 | +[Web3Auth SFA Web SDK](https://web3auth.io/docs/sdk/core-kit/sfa-web). Let me know if you need |
| 252 | +further clarification on any part! |
0 commit comments