Implement Sign In with Farcaster with Web3Auth SFA JS SDK
Prerequisites:
- Basic understanding of React and Next.js
- Familiarity with JavaScript and TypeScript
- Basic knowledge of authentication and JWT tokens
Step 1: Install and Configure Sign In with Farcaster
a. Install Dependencies: Install auth-kit
and its peer dependency viem
using npm.
npm install @farcaster/auth-kit viem
Note: auth-kit
is a React library. If you're using a different framework, take a look at the
client library instead.
b. Import Libraries: Import auth-kit
and its CSS styles into your React component.
import "@farcaster/auth-kit/styles.css";
import { AuthKitProvider, SignInButton, useProfile } from "@farcaster/auth-kit";
c. Configure Provider: Set up a provider with your desired configuration including the RPC URL, domain, and login URL.
const config = {
rpcUrl: "https://mainnet.optimism.io",
domain: "example.com",
siweUri: "https://example.com/login",
};
d. Integrate Sign-In Button: Render the SignInButton
component in your UI to prompt users to
sign in.
const App = () => {
return (
<AuthKitProvider config={config}>
{/* Your App */}
<SignInButton />
</AuthKitProvider>
);
};
Step 2: Verify Signatures on Backend
We will be using NextAuth
to implement Authorization logic.
a. Create a NextAuth API: Create an API route using NextAuth to handle authentication and signature verification.
pages/api/auth/[...nextauth].ts
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { createAppClient, viemConnector } from "@farcaster/auth-client";
b. Authorization Logic: Implement authorization logic to verify user signatures and credentials.
async authorize(credentials) {
const { body: { csrfToken } } = req;
const appClient = createAppClient({
ethereum: viemConnector(),
});
const verifyResponse = await appClient.verifySignInMessage({
message: credentials?.message as string,
signature: credentials?.signature as `0x${string}`,
domain: "example.com",
nonce: csrfToken,
});
const { success, fid } = verifyResponse;
if (!success) {
return null;
}
return {
id: fid.toString(),
name: credentials?.name,
image: credentials?.pfp,
};
},
Step 3: Generate a JWT Token using Farcaster User's data
a. Create a JWT Token: Create an API endpoint to generate JWT tokens containing user's data from
Farcaster.
Follow these steps to setup your Custom Verifier with Web3Auth.
pages/api/login.ts
import jwt from "jsonwebtoken";
b. JWT Signing: Sign the JWT token using a private key and include necessary user data that you get from Farcaster.
const userData = req.body.userData;
// Get RS256 key of length 2048
const privateKey = process.env.PRIVATE_KEY!;
const jwtToken = jwt.sign(
{
sub: userData?.fid.toString(),
name: userData?.displayName,
username: userData?.username,
profileImage: userData?.pfpUrl,
custody: userData?.custody,
aud: "w3a:farcaster-server",
iss: "https://web3auth.io",
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + 60 * 60,
},
privateKey,
{ algorithm: "RS256", keyid: "REPLACE_KEY_ID" },
);
Step 4: Authenticate with Web3Auth
a. Initialize Web3Auth SFA JS SDK: Set up Web3Auth instance and configure it with necessary parameters.
import { Web3Auth, decodeToken } from "@web3auth/single-factor-auth";
import { EthereumPrivateKeyProvider } from "@web3auth/ethereum-provider";
import { ADAPTER_EVENTS, CHAIN_NAMESPACES, IProvider, WEB3AUTH_NETWORK } from "@web3auth/base";
const web3auth = new Web3Auth({
clientId: "WEB3AUTH_CLIENT_ID", // Get your Client ID from the Web3Auth Dashboard
web3AuthNetwork: WEB3AUTH_NETWORK.SAPPHIRE_MAINNET,
});
const privateKeyProvider = new EthereumPrivateKeyProvider({
config: {
chainConfig: {
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0xaa36a7",
rpcTarget: "https://rpc.ankr.com/eth_sepolia",
displayName: "Ethereum Sepolia Testnet",
blockExplorerUrl: "https://sepolia.etherscan.io",
ticker: "ETH",
tickerName: "Ethereum",
},
},
});
// Use it inside useEffect
await web3auth.init(privateKeyProvider);
b. Get idToken from your backend:
const response = await fetch("/api/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ userData: res }),
});
const data = await response.json();
const token = data.token;
c. Initiate Web3Auth Login:
Implement login functionality using the generated JWT token.
const login = async (idToken: any) => {
// Login logic
if (!web3auth.ready) {
console.log("web3auth initialised yet");
return;
}
const { payload } = decodeToken(idToken);
const web3authProvider = await web3auth.connect({
verifier, // verifier name from the Web3Auth dashboard
verifierId: (payload as any).sub, // based on your setup
idToken, // token from the backend
});
return web3authProvider;
};
Step 5 (Optional): Additional Features
a. Blockchain Interactions: Include optional features like checking balances, signing messages, and sending transactions.
const getBalance = async (provider: IProvider) => {
// Get balance logic
};
b. Logout Functionality: Implement logout functionality for users.
const logOut = async () => {
await web3auth.logout();
await signOut();
};
Full Implementation Example
Here's an example of how to integrate the above steps into your Next.js application
This guide should provide a clear structure and step-by-step instructions for integrating
Sign In with Farcaster
using
Web3Auth SFA JS SDK. Let me know if you need further
clarification on any part!