Skip to content

Instantly share code, notes, and snippets.

@alongcamewayne
Created April 11, 2025 03:47
Show Gist options
  • Select an option

  • Save alongcamewayne/3fe9e975a537dead0121df2690b0ac74 to your computer and use it in GitHub Desktop.

Select an option

Save alongcamewayne/3fe9e975a537dead0121df2690b0ac74 to your computer and use it in GitHub Desktop.
Script to reserve a Farcaster usernaem. https://dololand.com/reserve-farcaster-username
/**
* Reserve a Farcaster username (fname) for a given FID.
*
* This script:
* - Loads an account from a mnemonic
* - Checks if a desired username is available
* - Signs an EIP-712 claim proving ownership of the FID
* - Submits the claim to the Fname Registry API
*
* Requirements:
* - A registered Farcaster ID (FID)
* - A signer capable of signing typed data
*
* .env:
* WALLET_MNEMONIC="your twelve word seed phrase"
* WALLET_FID=1234
*/
import { mnemonicToAccount } from 'viem/accounts';
const FNAME_API_ENDPOINT = 'https://fnames.farcaster.xyz';
// Load the wallet and FID from environment variables
const account = mnemonicToAccount(process.env.WALLET_MNEMONIC!);
const fid = Number(process.env.WALLET_FID);
// Define the username you'd like to reserve
const name = 'dololand';
console.log(`Attempting to reserve "${name}" for fid ${fid}...`);
// Check if the username is available via Fname Registry API
const transferResponse = await fetch(`${FNAME_API_ENDPOINT}/transfers/current?name=${name}`);
const transferData = (await transferResponse.json()) as any;
// If the name is not registered or not assigned, it's available
const isAvailable = transferResponse.status === 404 || transferData.transfer.to === 0;
if (!isAvailable) {
console.log('Username is not available.');
process.exit(0);
}
// Create a timestamped EIP-712 structured message for name ownership proof
const timestamp = Math.floor(Date.now() / 1000);
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;
// Sign the proof using the account's private key
const signature = await account.signTypedData(proofTypedData);
console.log('Proof Signature:', signature);
// Submit the signed claim to the Fname Registry API
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,
}),
});
// Log the API response
const claimData = await claimResponse.json();
console.log('Response:', claimData);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment