> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neynar.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Farcaster Account with Wallet Integration

> This document outlines the steps to successfully create a Farcaster account without having a end user mnemonic.

<Card title="Follow the example code while reading the guide for better understanding" href="https://github.com/neynarxyz/farcaster-examples/pull/44" icon="github" iconType="solid" horizontal />

## Prerequisites

* A browser with a wallet extension (e.g., MetaMask, Coinbase, etc.) installed.
  * If you are using a Privy wallet, you can see this [guide](https://neynar.notion.site/Creating-new-accounts-with-embedded-wallets-14a655195a8b80999ccec0aa635b23af?pvs=4) written by community member [jpfraneto](https://warpcast.com/jpfraneto.eth), which includes source code for getting started.
* Access to the Farcaster API and ID Registry smart contract.
* Familiarity with JavaScript and Ethereum wallet interactions.
* **App Wallet with `wallet_id`** - Required for FID fetching and account registration. See [Managing Onchain Wallets](/docs/managing-onchain-wallets) to create one in the developer portal.
* **Funded wallet with \$5+ ETH on Optimism** - Covers initial account pre-registration on first call

<Note>
  **New to App Wallets?** The `/v2/farcaster/user/fid` endpoint requires a [`x-wallet-id` header](/docs/managing-onchain-wallets) to cover the costs of FID registration. Create your app wallet in the [Developer Portal](https://dev.neynar.com) first!

  **Recommended Setup Steps:**

  1. Log in to [dev.neynar.com](https://dev.neynar.com) and select your app
  2. Activate a wallet from the "App Wallet" tab
  3. Fund the wallet with \$5+ ETH on Optimism
  4. Add the `x-wallet-id` header to your API requests (treat it like a secret)
</Note>

## Step 1: Connect a Wallet

To connect a wallet in the browser:

1. Check if the browser supports `window.ethereum`.
2. Use `eth_requestAccounts` to request wallet connection.

### Code Example:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  if (typeof window === "undefined" || typeof window.ethereum === "undefined") {
    console.error("No wallet is installed.");
    window.open("https://metamask.io/download/", "_blank");
    return;
  }

  const accounts = await window.ethereum.request({
    method: "eth_requestAccounts",
  });
  if (accounts.length === 0) {
    console.error("No wallet detected. Please log in to a wallet.");
    return;
  }
  const userAddress = accounts[0];
  console.log("Wallet connected:", userAddress);
  ```
</CodeGroup>

## Step 2: Switch to the Optimism Network

To interact with the ID Registry contract, ensure the wallet is on the Optimism network.

### Code Example:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  try {
    await window.ethereum.request({
      method: "wallet_switchEthereumChain",
      params: [{ chainId: "0xA" }], // Optimism chainId in hex
    });
    console.log("Switched to Optimism network.");
  } catch (error) {
    console.error("Failed to switch to Optimism network:", error);
    return;
  }
  ```
</CodeGroup>

## Step 3: Fetch FID

Use the [`GET-/v2/farcaster/user/fid`](/reference/get-fresh-account-fid) endpoint to retrieve the FID of the account that will be transferred to the wallet's address. **This endpoint requires a [`x-wallet-id` header](/docs/managing-onchain-wallets).**

<Warning>
  **Cold Start (First Call Only):** The first time you call this endpoint with a new `wallet_id`, it will take approximately **1 minute** to complete as it pre-registers a few FID accounts. Subsequent calls will be fast (\< 1 second). Make sure your wallet has **\$5+ ETH on Optimism** before the first call.
</Warning>

<Warning>
  **Wallet Consistency Required:** The same `wallet_id` used here must also be used in Step 6 when calling `POST /v2/farcaster/user/`. Using different wallets will result in an error.
</Warning>

### Code Example:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  // Your backend API should forward the wallet_id header to Neynar
  const response = await fetch("/api/user", {
    headers: {
      // Your backend should include:
      // 'x-api-key': 'YOUR_NEYNAR_API_KEY',
      // 'x-wallet-id': 'your-wallet-id'
    }
  });
  if (!response.ok) {
    console.error("Failed to fetch FID from the API.");
    return;
  }
  const data = await response.json();
  const fid = data.fid;
  if (!fid) {
    console.error("FID not found in the API response.");
    return;
  }
  console.log("FID fetched:", fid);
  ```
</CodeGroup>

<Warning>
  **Backend Required:** The FID fetch should be done from your backend, not the frontend, to keep your `wallet_id` secure. Your backend should call Neynar's API with the `x-wallet-id` header.
</Warning>

## Step 4: Generate `signTypedData` with Viem

To generate a signature for FID registration:

1. Fetch the nonce from the ID Registry contract.
2. Create EIP-712 typed data and request a signature from the wallet.

### Code Example:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  import { createWalletClient, custom, publicActions } from "viem";
  import { optimism } from "viem/chains";
  import { ID_REGISTRY_ABI, ID_REGISTRY_ADDRESS } from "./constants";

  const wallet = createWalletClient({
    chain: optimism,
    transport: custom(window.ethereum),
  }).extend(publicActions);

  const nonce = await wallet.readContract({
    address: ID_REGISTRY_ADDRESS,
    abi: ID_REGISTRY_ABI,
    functionName: "nonces",
    args: [userAddress],
  });

  const now = Math.floor(Date.now() / 1000);
  const deadline = now + 3600; // 1 hour from now

  const domain = {
    name: "Farcaster IdRegistry",
    version: "1",
    chainId: 10,
    verifyingContract: ID_REGISTRY_ADDRESS,
  };

  const types = {
    Transfer: [
      { name: "fid", type: "uint256" },
      { name: "to", type: "address" },
      { name: "nonce", type: "uint256" },
      { name: "deadline", type: "uint256" },
    ],
  };

  const message = {
    fid: BigInt(fid),
    to: userAddress,
    nonce: BigInt(nonce),
    deadline: BigInt(deadline),
  };

  const signature = await wallet.signTypedData({
    account: userAddress,
    domain,
    types,
    primaryType: "Transfer",
    message,
  });
  console.log("Signature:", signature);
  ```
</CodeGroup>

## Step 5: Check `fname` Availability

Before registering a username, check if it is available using the [`GET /v2/farcaster/fname/availability`](/reference/is-fname-available) endpoint.

### Code Example:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  const fname = "desired_username";
  const response = await fetch(`/api/user/fname/availability?fname=${fname}`);
  if (!response.ok) {
    console.error("Failed to check fname availability.");
    return;
  }
  const data = await response.json();
  const isAvailable = data.available;
  console.log("Fname availability:", isAvailable);
  ```
</CodeGroup>

## Step 6: Call the [`POST-/v2/farcaster/user`](/reference/register-account) Endpoint

Submit the required data to create the Farcaster account. **This endpoint also requires a [`x-wallet-id` header](/docs/managing-onchain-wallets).**

### Code Example:

<CodeGroup>
  ```javascript Javascript theme={"system"}
  const metadata = {
    bio: "Your bio",
    pfp_url: "https://example.com/profile-pic.jpg",
    url: "https://yourwebsite.com",
    display_name: "Your Display Name",
    location: {
      latitude: 40.7128,
      longitude: -74.006,
    },
  };

  // Your backend should handle this with wallet_id
  const response = await fetch("/api/user", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      // Your backend should include:
      // 'x-api-key': 'YOUR_NEYNAR_API_KEY',
      // 'x-wallet-id': 'your-wallet-id'
    },
    body: JSON.stringify({
      fid,
      signature,
      requestedUserCustodyAddress: userAddress,
      deadline,
      fname,
      metadata,
    }),
  });

  if (!response.ok) {
    const errorData = await response.json();
    console.error("Error creating account:", errorData.message);
    return;
  }

  console.log("Account created successfully!");
  ```
</CodeGroup>

<Warning>
  **Backend Required:** Like Step 3, this registration should be done from your backend to keep your `wallet_id` secure. Your backend calls Neynar's API with the `x-wallet-id` header.
</Warning>

## Conclusion

By following these steps, you can create an account using the user's wallet. (No mnemonic required)
