How to create a new Farcaster account with Neynar

Currently, this feature is available only for Enterprise tier customers. Please get in touch with us if you wish to access this feature.

πŸ“˜

Each new user account costs $X (based on the contract) and the total will be charged at the end of the month

This guide enables Enterprise tier customers to seamlessly create and register new user accounts on Farcaster through Neynar. By the end, you will:

  • Claim and register a new user account.
  • Assign a fname and username to the new user account.
  • Obtain a signer_uuid for the new user account and make changes on Farcaster.
  • Get an understanding of the entire flow behind the scenes.

Prerequisites

Step 1: Claim an account for the new user

To register a new user, you need to claim an account for that user.

API Call

curl --location 'https://api.neynar.com/v2/farcaster/user/fid' \
--header 'api_key: NEYNAR_API_KEY'

Note: Replace NEYNAR_API_KEY with your actual API key.

Responses

{
	"fid": UNIQUE_FID // UNIQUE_FID is a number
}
{
	"message": "Please try again later"
}

In the next step, you'll need this fid here to generate a signature.

Step 2: Ask the user to sign a message accepting their new Farcaster account

To create a Farcaster account, users must sign a message proving they're willing to accept the account using a particular wallet address. The user needs to sign a message containing

  1. fid (fetched in the previous step)
  2. the address that will custody the Farcaster account (connected address on the client/app developer)
  3. and a deadline until which their signature is valid. (generated by the client/app developer)

Usually, client or application developers must implement this step by constructing a message and asking the user to sign it in their connected web3 wallet.

However, for the sake of testing out the flow, here's a script that effectively produces the equivalent signatures you would get back from eth.sign

Setup project

mkdir generate-required-parameters
cd generate-required-parameters

Install Dependencies

yarn add @farcaster/hub-nodejs viem
npm install @farcaster/hub-nodejs viem

Create the Script

Create a file named generate-required-parameters.js

touch generate-required-parameters.js

Paste the following script in it. This script generates certain parameters that you'll need to make the next API call.

Replace FID_TO_COLLECT_SIGNATURE_FOR with fid returned from GET - /v2/farcaster/user/fid
and NEW_ACCOUNT_MNEMONIC with a new account MNEMONIC.

// generate-required-parameters.js --> Filename

const {
    ID_REGISTRY_ADDRESS,
    ViemLocalEip712Signer,
    idRegistryABI,
} = require('@farcaster/hub-nodejs');
const { bytesToHex, createPublicClient, http } = require('viem');
const { mnemonicToAccount } = require('viem/accounts');
const { optimism } = require('viem/chains');

const publicClient = createPublicClient({
    chain: optimism,
    transport: http(),
});

const FID = 'FID_TO_COLLECT_SIGNATURE_FOR'; // fid returned from GET - /v2/farcaster/user/fid
const MNEMONIC = 'NEW_ACCOUNT_MNEMONIC';

const getDeadline = () => {
    const now = Math.floor(Date.now() / 1000);
    const oneHour = 60 * 60;
    return BigInt(now + oneHour);
};

(async () => {
    const deadline = getDeadline();

    console.log('\ndeadline: ', parseInt(deadline));

    const requestedUserAccount = mnemonicToAccount(MNEMONIC);
    const requestedUserAccountSigner = new ViemLocalEip712Signer(
        requestedUserAccount
    );

    console.log(
        '\nrequested_user_custody_address: ',
        requestedUserAccount.address
    );

    let requestedUserNonce = await publicClient.readContract({
        address: ID_REGISTRY_ADDRESS,
        abi: idRegistryABI,
        functionName: 'nonces',
        args: [requestedUserAccount.address],
    });

    console.log('\nfid: ', parseInt(FID));

    let requestedUserSignature = await requestedUserAccountSigner.signTransfer({
        fid: BigInt(FID),
        to: requestedUserAccount.address,
        nonce: requestedUserNonce,
        deadline,
    });

    console.log(
        '\nsignature: ',
        bytesToHex(requestedUserSignature.value),
        '\n'
    );
})();

Execute Script

Run the script to generate the necessary parameters for user registration. Get the FID i.e UNIQUE_FID from Step 1 and pass it on in the following command

node generate-required-parameters.js

Script Output

You'll receive output containing several values, including deadline, requested_user_custody_address, fid, signature

Step 3: Ask the user to pick their fname (optional)

Client applications should ask users to pick a username for their Farcaster account. The fname availability API should be used to check if their chosen username is available. The fname should match the following regex - /^[a-z0-9][a-z0-9-]{0,15}$/. Official regex defined in the farcaster/core library

Step 4: Register the User

Construct a POST request with the generated parameters to finalize the user's registration.

Finalize Registration

curl --location 'https://api.neynar.com/v2/farcaster/user' \
--header 'api_key: NEYNAR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
	"deadline": "DEADLINE_FROM_SCRIPT",
	"requested_user_custody_address": "CUSTODY_ADDRESS_FROM_SCRIPT",
	"fid": 0,
	"signature": "SIGNATURE_FROM_SCRIPT",
	"fname": "desired-username"
}'

Responses

{
	"success": true,
	"message": "Account transferred successfully.",
  	"signer": {
  		"fid": 0,
  		"signer_uuid": "35b0bbd5-4e20-4213-a30c-4183258a73ab",
  		"status": "APPROVED",
  		"public_key": "0x123412341234123412341234123412341234"
  }
}
  
{
	"message": "Account not found"
}
{
	"message": "Account is not issued to you"
}
{
	"message": "Account not found"
}
{
	"message": "Account is already registered to another user"
}
{
	"success": false,
	"message": "Failed to sign transfer",
}

Step 5: Profile setup (optional)

Using the approved signer_uuid from the response in Step 4, you can ask the user to update their profile by picking a profile photo, display name, bio, and more.