earth

How to Reserve a Farcaster Username

April 11, 2025

Usernames on Farcaster, also known as Fnames, are like Twitter handles. They let others find and mention you on the network.

Fnames are offchain, ENS-compliant names managed by the Farcaster team. Getting an fname is a two-step process. First, you reserve the name through the Fname Registry API. Then, you link it to your FID by submitting a message to a hub.

In this post we’ll focus on the first step, reserving a username. Before you begin, make sure you’ve already set up your account and added a signer:

You can view the complete script on GitHub to copy, customize, or run it end-to-end.

Choose a Username

First, decide on a username. Fnames have to meet these requirements:

  • Must be lowercase
  • Must start with a letter or number
  • Can include letters, numbers, and hyphens
  • Can be up to 16 characters long

These rules are enforced by the Fname Registry and match the pattern /^[a-z0-9][a-z0-9-]{0,15}$/.

import { mnemonicToAccount } from 'viem/accounts';

const FNAME_API_ENDPOINT = 'https://fnames.farcaster.xyz';
const account = mnemonicToAccount(process.env.WALLET_MNEMONIC!);
const fid = Number(process.env.WALLET_FID);

// the username you'd like to reserve
const name = 'dololand';
console.log(`Attempting to reserve "${name}" for fid ${fid}...`);

Make sure wallet’s address if the owner of the FID since you’ll need to sign a verification message in a later step. You can confirm this with the idOf function of IdRegistry contract if needed.

Check Username Availability

We can use the Fname Registry API to check if the name is already reserved. It returns ownership info for any name that’s been claimed. If the name isn’t found or isn’t assigned to anyone, it’s available to reserve.

const transferResponse = await fetch(`${FNAME_API_ENDPOINT}/transfers/current?name=${name}`);
const transferData = (await transferResponse.json()) as any;

const isAvailable = transferResponse.status === 404 || transferData.transfer.to === 0;

if (!isAvailable) {
	console.log('Username is not available.');
	process.exit(0);
}

The script exits early if the name is already taken. You can try again with an alternative. Otherwise, you’re good to move on to the next step.

Generate a Signed Claim

To reserve a name, the FID owner must sign a message for the claim. The message uses EIP-712 typed data, allowing the API to validate the signature and verify ownership.

const timestamp = Math.floor(Date.now() / 1000); // current time in seconds

const proofMessage = {
	name,
	owner: account.address,
	timestamp: BigInt(timestamp),
};

const proofTypedData = {
	domain: {
		name: 'Farcaster name verification',
		version: '1',
		chainId: 1,
		verifyingContract: '0xe3be01d99baa8db9905b33a3ca391238234b79d1',
	},
	types: {
		UserNameProof: [
			{ name: 'name', type: 'string' },
			{ name: 'timestamp', type: 'uint256' },
			{ name: 'owner', type: 'address' },
		],
	},
	primaryType: 'UserNameProof',
	message: proofMessage,
} as const;

const signature = await account.signTypedData(proofTypedData);
console.log('Proof Signature:', signature);

Submit the Reservation

Now you can send the signature to the Fname Registry API to reserve the name for your FID.

const claimResponse = await fetch(`${FNAME_API_ENDPOINT}/transfers`, {
	method: 'post',
	headers: { 'Content-Type': 'application/json' },
	body: JSON.stringify({
		name,
		from: 0,
		to: fid,
		fid,
		owner: account.address,
		signature,
		timestamp,
	}),
});

const claimData = await claimResponse.json();
console.log('Response:', claimData);

If successful, the name is now reserved.

Next steps

You’ve successfully reserved an fname for your FID in the Fname Registry and no one else can claim it.

However, it won’t appear in your Farcaster profile just yet. To complete the process, you need to send a message to a hub to set the username.