### Get User Name Proof Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves the username proof for a given name. ```APIDOC ## GET /username_proof ### Description Retrieves the username proof for a given name. ### Method GET ### Endpoint /username_proof ### Parameters #### Query Parameters - **name** (bytes) - Required - The username to get the proof for. ``` -------------------------------- ### Example Cast with Mentions Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Illustrates how to represent a cast with user mentions, including the text and the positions of those mentions. ```typescript { text: '🤓 says hello', mentions: [1], mentionsPositions: [5], } ``` -------------------------------- ### Add Post Message Example Source: https://github.com/farcasterxyz/protocol/blob/main/docs/OVERVIEW.md Illustrates an 'add-post' message, including author, message content, timestamp, and hash. This is a fundamental message type for user-generated content. ```mermaid flowchart TD W2(add-post
author: alice
message: Hello World!
timestamp: 1000001
hash: 0x...4448 ) W1(add-like
author: bob
target: 0x...4448
timestamp: 1000002
hash: 0x...72d5 ) style W1 text-align:left style W2 text-align:left ``` -------------------------------- ### Get Storage Limits Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves the storage limits for different store types. ```APIDOC ## GET /storage_limits ### Description Retrieves the storage limits for different store types. ### Method GET ### Endpoint /storage_limits ``` -------------------------------- ### Get Hub Status and Version Source: https://context7.com/farcasterxyz/protocol/llms.txt Returns the Hub's protocol version, sync status, nickname, and root trie hash for health checks and version verification. ```APIDOC ## GetInfo — Hub Status and Version ### Description Returns the Hub's protocol version, sync status, nickname, and root trie hash — useful for health checks and ensuring the Hub is on the expected protocol version before submitting messages. ### Method `client.getInfo` ### Parameters #### Request Body - **dbStats** (boolean) - Optional - Whether to include database statistics. ### Request Example ```typescript const info = await client.getInfo({ dbStats: true }); ``` ### Response #### Success Response - **value** (object) - An object containing hub information. - **version** (string) - The protocol version of the Hub. - **isSynced** (boolean) - Indicates if the Hub is currently synced. - **nickname** (string) - The nickname of the Hub. - **rootHash** (string) - The root hash of the Hub's Merkle Patricia Trie. #### Response Example ```typescript if (info.isOk()) { const { version, isSynced, nickname, rootHash } = info.value; console.log(`Hub: ${nickname} | Version: ${version} | Synced: ${isSynced}`); console.log(`Trie root: ${rootHash}`); // Hub: "mainnet-hub-1" | Version: "1.9.0" | Synced: true // Trie root: "0xabc123..." } ``` ``` -------------------------------- ### Get Verification Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves verification information for a given FID and address. ```APIDOC ## GET /verification ### Description Retrieves verification information for a given FID and address. ### Method GET ### Endpoint /verification ### Parameters #### Query Parameters - **fid** (uint64) - Required - The FID to retrieve verification for. - **address** (bytes) - Required - The address to check for verification. ``` -------------------------------- ### Message Reversibility Example Source: https://github.com/farcasterxyz/protocol/blob/main/docs/OVERVIEW.md Demonstrates how messages like posts and likes can be reversed using 'remove' messages. The network prioritizes messages with higher order values (timestamp, then hash) to determine the latest state. ```mermaid flowchart TD W3(add-post
author: alice
message: Hello World!
timestamp: 1000001
hash: 0x...4448 ) W4(remove-post
author: alice
target: 0x...4448
timestamp: 1000004
hash: 0x...8e3d ) W1(add-like
author: bob
target: 0x...4448
timestamp: 1000001
hash: 0x...72d5 ) W2(remove-like
author: bob
target: 0x...1234
timestamp: 1000003
hash: 0x...b4da ) style W1 text-align:left style W2 text-align:left style W3 text-align:left style W4 text-align:left ``` -------------------------------- ### Verify Fname Ownership and Get Server Signer Source: https://context7.com/farcasterxyz/protocol/llms.txt Fetches Fname transfer records to verify ownership and retrieves the current nameserver public key. The server signature in the transfer response confirms server attestation. ```typescript // Verify fname ownership const transfers = await fetch( "https://fnames.farcaster.xyz/transfers?name=alice&fid=8930123" ).then((r) => r.json()); // transfers.transfers[0].server_signature confirms server attestation // Look up current signer (nameserver public key) const signer = await fetch("https://fnames.farcaster.xyz/signer").then((r) => r.json()); // { "address": "0x" } ``` -------------------------------- ### Get Sync Snapshot by Prefix Source: https://context7.com/farcasterxyz/protocol/llms.txt Fetches a trie snapshot, including exclusion hashes, for the diff sync algorithm. Exclusion hashes are compared left-to-right to identify the first point of divergence. ```typescript // Fetch a trie snapshot (with exclusion hashes for diff algorithm) const snapshot = await client.getSyncSnapshotByPrefix({ prefix: new Uint8Array(), }); console.log("Excluded hashes:", snapshot.value.excludedHashes); // Exclusion hashes are compared left-to-right; first mismatch = divergence point ``` -------------------------------- ### Get Sync Metadata by Prefix Source: https://context7.com/farcasterxyz/protocol/llms.txt Fetches trie metadata at a specified prefix to compare with a peer. This is part of the diff sync process for discovering missing messages. ```typescript // Fetch trie metadata at a prefix to compare with a peer const metadata = await client.getSyncMetadataByPrefix({ prefix: new Uint8Array(), // empty = root }); console.log( `Messages: ${metadata.value.numMessages} | Hash: ${metadata.value.hash}` ); ``` -------------------------------- ### Get All Sync IDs by Prefix Source: https://context7.com/farcasterxyz/protocol/llms.txt Fetches all Sync IDs under a given prefix. This is used to identify specific messages within a divergent part of the trie during diff sync. ```typescript // Fetch all Sync IDs under a divergent prefix const syncIds = await client.getAllSyncIdsByPrefix({ prefix: hexToBytes("0x2024"), // e.g., all messages from 2024 }); ``` -------------------------------- ### Get Hub Status and Version Source: https://context7.com/farcasterxyz/protocol/llms.txt Retrieves the Hub's protocol version, sync status, nickname, and root trie hash. Useful for health checks and ensuring the Hub is on the expected protocol version before submitting messages. ```typescript const info = await client.getInfo({ dbStats: true }); if (info.isOk()) { const { version, isSynced, nickname, rootHash } = info.value; console.log(`Hub: ${nickname} | Version: ${version} | Synced: ${isSynced}`); console.log(`Trie root: ${rootHash}`); // Hub: "mainnet-hub-1" | Version: "1.9.0" | Synced: true // Trie root: "0xabc123..." } else { console.error("Hub unreachable:", info.error.message); } ``` -------------------------------- ### Get User Data Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves specific user data for a given FID. ```APIDOC ## GET /user_data ### Description Retrieves specific user data for a given FID. ### Method GET ### Endpoint /user_data ### Parameters #### Query Parameters - **fid** (uint64) - Required - The FID to retrieve data for. - **user_data_type** (UserDataType) - Required - The type of user data to retrieve. ``` -------------------------------- ### Get On-Chain Storage Rent Events Source: https://context7.com/farcasterxyz/protocol/llms.txt Retrieves storage rent events for a specific FID to audit storage allocation. This helps track how much storage a user is paying for and when it expires. ```typescript // Fetch storage rent events (to audit storage allocation) const storageEvents = await client.getOnChainEvents({ fid: 8930123n, eventType: protobufs.OnChainEventType.EVENT_TYPE_STORAGE_RENT, }); for (const event of storageEvents.value.events) { const { units, expiry } = event.storageRentEventBody; console.log(`Rented ${units} units, expires at block ${expiry}`); } ``` -------------------------------- ### Subscribe to Real-Time Hub Events Source: https://context7.com/farcasterxyz/protocol/llms.txt Opens a server-sent gRPC stream for HubEvents. Clients can filter by event type and resume from a specific event ID. Use this to get real-time updates on message merges, prunes, and revokes. ```typescript const { HubEventType } = protobufs; const subscription = await client.subscribe({ eventTypes: [ HubEventType.HUB_EVENT_TYPE_MERGE_MESSAGE, HubEventType.HUB_EVENT_TYPE_PRUNE_MESSAGE, HubEventType.HUB_EVENT_TYPE_REVOKE_MESSAGE, ], fromId: 0n, // 0 = start from now; pass a saved event id to resume }); for await (const event of subscription.value) { switch (event.type) { case HubEventType.HUB_EVENT_TYPE_MERGE_MESSAGE: { const msg = event.mergeMessageBody.message; console.log("MERGE", protobufs.MessageType[msg.data.type], "fid:", msg.data.fid); break; } case HubEventType.HUB_EVENT_TYPE_PRUNE_MESSAGE: console.log("PRUNED fid:", event.pruneMessageBody.message.data.fid); break; case HubEventType.HUB_EVENT_TYPE_REVOKE_MESSAGE: console.log("REVOKED fid:", event.revokeMessageBody.message.data.fid); break; } } ``` -------------------------------- ### Verify Fname Ownership Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieve a paginated list of Fname transfer events by making a GET request to the /transfers endpoint. Results can be filtered using query parameters. ```APIDOC ## GET /transfers ### Description Retrieve a paginated list of Fname transfer events to verify ownership. ### Method GET ### Endpoint /transfers ### Query Parameters - **from_id** (id) - Optional - Minimum id for filtering. - **from_ts** (timestamp) - Optional - Minimum timestamp for filtering. - **fid** (fid) - Optional - Filter events by a particular fid. - **name** (username) - Optional - Filter events for a particular name. ### Response #### Success Response (200) - **transfers** (array) - A list of transfer events. - **id** (integer) - Unique identifier for the transfer. - **from** (fid) - The originating fid. - **to** (fid) - The destination fid. - **username** (string) - The fname username. - **timestamp** (uint256) - The timestamp of the transfer. - **owner** (address) - The owner's address. - **server_signature** (string) - EIP-712 signature signed by the server's key. - **user_signature** (string) - Original user-provided signature. ### Response Example ```json { "transfers": [ { "id": 1, "from": 0, "to": 1, "username": "test", "timestamp": 1686680932, "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "server_signature": "0x68a1a565f603b9966f228a38d918c12f166650749359fe41e2755fabe016026b361dd7d5f917c6f8a09241b29085fbaefffb75e443a3851be85c8b53b", "user_signature": "0xf603b9966f228a38d918c12f166650749359fe41e2755fabe016026b361dd7d5f917c6f8a09241b29085fbaefffb75e443a3851be85c8b53b691536d1c" } ] } ``` ``` -------------------------------- ### Query Social Graph Links Source: https://context7.com/farcasterxyz/protocol/llms.txt Fetch information about social connections, such as follows. Supports checking if one FID follows another, retrieving all FIDs a given FID follows, or getting all followers of a specific FID. Use `linkType: "follow"`. ```typescript // Check if fid 8930123 follows fid 999 const link = await client.getLink({ fid: 8930123n, linkType: "follow", targetFid: 999n, }); // link.isOk() && link.value → they do follow ``` ```typescript // Get all accounts that fid 8930123 follows const following = await client.getLinksByFid({ fid: 8930123n, linkType: "follow", pageSize: 100, reverse: true, }); ``` ```typescript // Get all followers of fid 999 const followers = await client.getLinksByTarget({ targetFid: 999n, linkType: "follow", pageSize: 100, }); console.log(`${followers.value.messages.length} followers`); ``` -------------------------------- ### Get Nameserver Signer Address Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieve the public address of the nameserver's signer keypair by making a GET request to the /signer endpoint. ```APIDOC ## GET /signer ### Description Retrieve the public address for the nameserver's signer. ### Method GET ### Endpoint /signer ### Response #### Success Response (200) - **address** (string) - The public address of the server's signer. ### Response Example ```json { "address": "" } ``` ``` -------------------------------- ### Allocate Storage with StorageRegistry Source: https://context7.com/farcasterxyz/protocol/llms.txt Rent storage units for an fid using the StorageRegistry contract to ensure sufficient space for messages. Query current storage limits via Hub gRPC after onchain rent. ```Solidity IStorageRegistry(0x00000000fcCe7f938e7aE6D3c335bD6a1a7c593D).rent{value: price}(fid, 1); ``` ```JSON // GetCurrentStorageLimitsByFid returns StorageLimitsResponse: // { // limits: [ // { store_type: STORE_TYPE_CASTS, limit: 5000 }, // { store_type: STORE_TYPE_REACTIONS, limit: 2500 }, // { store_type: STORE_TYPE_LINKS, limit: 2500 }, // { store_type: STORE_TYPE_USER_DATA, limit: 50 }, // { store_type: STORE_TYPE_VERIFICATIONS, limit: 25 }, // { store_type: STORE_TYPE_USERNAME_PROOFS, limit: 5 } // ] // } ``` -------------------------------- ### Get Signer Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves signer information for a given FID and signer address. ```APIDOC ## GET /signer ### Description Retrieves signer information for a given FID and signer address. ### Method GET ### Endpoint /signer ### Parameters #### Query Parameters - **fid** (uint64) - Required - The FID to retrieve signer information for. - **signer** (bytes) - Required - The signer address. ``` -------------------------------- ### Get On-Chain Events Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves on-chain events for a given FID and event type. Supports pagination. ```APIDOC ## GET /on_chain_event ### Description Retrieves on-chain events for a given FID and event type. Supports pagination. ### Method GET ### Endpoint /on_chain_event ### Parameters #### Query Parameters - **fid** (uint64) - Required - The FID to retrieve events for. - **event_type** (OnChainEventType) - Required - The type of on-chain event. - **page_size** (uint32) - Optional - The number of results to return per page. - **page_token** (bytes) - Optional - The token for the next page of results. - **reverse** (bool) - Optional - Whether to return results in reverse order. ``` -------------------------------- ### UsernameProof Source: https://context7.com/farcasterxyz/protocol/llms.txt This method allows users to prove ownership of an fname (e.g., `alice`) or ENS name (e.g., `alice.eth`) for a given fid. The fname server re-validates proofs daily; if the name is transferred away, the proof is automatically revoked. ```APIDOC ## UsernameProof ### Description A `UsernameProof` proves ownership of an fname (e.g., `alice`) or ENS name (e.g., `alice.eth`) for a given fid. The fname server re-validates proofs daily; if the name is transferred away, the proof is automatically revoked. ### Registering an fname (REST API) **Method:** POST **Endpoint:** `https://fnames.farcaster.xyz/transfers` **Request Body:** ```json { "from": 0, // 0 = new registration "to": 8930123, // target fid "name": "alice", // must match /^[a-z0-9][a-z0-9-]{0,15}$/ "timestamp": , "owner": "0xCustodyAddress", "signature": "0x" } ``` **Response Example:** ```json { "id": 42, "from": 0, "to": 8930123, "username": "alice", "timestamp": , ... } ``` ### Verifying fname ownership (REST API) **Method:** GET **Endpoint:** `https://fnames.farcaster.xyz/transfers?name=&fid=` **Response Example:** ```json { "transfers": [ { "server_signature": "", ... } ] } ``` ### Look up current signer (nameserver public key) (REST API) **Method:** GET **Endpoint:** `https://fnames.farcaster.xyz/signer` **Response Example:** ```json { "address": "0x" } ``` ``` -------------------------------- ### Get Links by FID Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves links associated with a given FID. Supports filtering by link type and pagination. ```APIDOC ## GET /links/fid ### Description Retrieves links associated with a given FID. Supports filtering by link type and pagination. ### Method GET ### Endpoint /links/fid ### Parameters #### Query Parameters - **fid** (uint64) - Required - The FID to retrieve links for. - **link_type** (string) - Optional - The type of link to filter by. - **page_size** (uint32) - Optional - The number of results to return per page. - **page_token** (bytes) - Optional - The token for the next page of results. - **reverse** (bool) - Optional - Whether to return results in reverse order. ``` -------------------------------- ### Verification Methods Source: https://context7.com/farcasterxyz/protocol/llms.txt Methods for fetching Ethereum address verifications associated with a user's FID. ```APIDOC ## GetVerification ### Description Fetches a specific Ethereum address verification for a given user (FID). ### Method `getVerification` ### Parameters - **fid** (bigint) - Required - The FID of the user. - **address** (Uint8Array) - Required - The Ethereum address to check for verification. ### Request Example ```typescript const verification = await client.getVerification({ fid: 8930123n, address: hexToBytes("0xEthAddress"), }); ``` ## GetVerificationsByFid ### Description Fetches all verified Ethereum addresses associated with a user's FID. ### Method `getVerificationsByFid` ### Parameters - **fid** (bigint) - Required - The FID of the user. ### Request Example ```typescript const verifications = await client.getVerificationsByFid({ fid: 8930123n }); // Process verifications.value.messages ``` ``` -------------------------------- ### Get Links by Target FID Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Retrieves links where a given FID is the target. Supports filtering by link type and pagination. ```APIDOC ## GET /links/target ### Description Retrieves links where a given FID is the target. Supports filtering by link type and pagination. ### Method GET ### Endpoint /links/target ### Parameters #### Query Parameters - **target_fid** (uint64) - Required - The target FID. - **link_type** (string) - Optional - The type of link to filter by. - **page_size** (uint32) - Optional - The number of results to return per page. - **page_token** (bytes) - Optional - The token for the next page of results. - **reverse** (bool) - Optional - Whether to return results in reverse order. ``` -------------------------------- ### User Data Methods Source: https://context7.com/farcasterxyz/protocol/llms.txt Methods for fetching profile fields for a user, either a specific field or all fields. ```APIDOC ## GetUserData ### Description Fetches a specific user data field for a given user (FID). ### Method `getUserData` ### Parameters - **fid** (bigint) - Required - The FID of the user. - **userDataType** (UserDataType) - Required - The type of user data to fetch (e.g., DISPLAY_NAME, PFP, BIO). ### Request Example ```typescript const displayName = await client.getUserData({ fid: 8930123n, userDataType: protobufs.UserDataType.USER_DATA_TYPE_DISPLAY, }); // displayName.value.data.userDataBody.value ``` ## GetUserDataByFid ### Description Fetches all profile fields for a given user (FID). ### Method `getUserDataByFid` ### Parameters - **fid** (bigint) - Required - The FID of the user. ### Request Example ```typescript const profile = await client.getUserDataByFid({ fid: 8930123n }); // Process profile.value.messages ``` ``` -------------------------------- ### Reaction Retrieval Methods Source: https://context7.com/farcasterxyz/protocol/llms.txt Methods for fetching specific reactions or paginated lists of reactions by author or target. ```APIDOC ## GetReaction ### Description Fetches a specific reaction made by a user on a target cast. ### Method `getReaction` ### Parameters - **fid** (bigint) - Required - The FID of the user who made the reaction. - **reactionType** (ReactionType) - Required - The type of reaction (e.g., LIKE, RECAST). - **targetCastId** (object) - Required - The ID of the cast being reacted to. - **fid** (bigint) - Required - The FID of the target cast's author. - **hash** (Uint8Array) - Required - The hash of the target cast. ### Request Example ```typescript const reaction = await client.getReaction({ fid: 8930123n, reactionType: protobufs.ReactionType.REACTION_TYPE_LIKE, targetCastId: { fid: 1n, hash: hexToBytes("0x...") }, }); ``` ## GetReactionsByFid ### Description Fetches a paginated list of reactions made by a specific user. ### Method `getReactionsByFid` ### Parameters - **fid** (bigint) - Required - The FID of the user making the reactions. - **reactionType** (ReactionType) - Required - The type of reactions to fetch (e.g., LIKE, RECAST). - **pageSize** (number) - Optional - The number of reactions to return per page. - **reverse** (boolean) - Optional - If true, returns reactions in reverse chronological order. ### Request Example ```typescript const likes = await client.getReactionsByFid({ fid: 8930123n, reactionType: protobufs.ReactionType.REACTION_TYPE_LIKE, pageSize: 100, reverse: true, }); ``` ## GetReactionsByTarget ### Description Fetches a paginated list of all reactions (likes and recasts) on a specific target cast. ### Method `getReactionsByTarget` ### Parameters - **targetCastId** (object) - Required - The ID of the cast being reacted to. - **fid** (bigint) - Required - The FID of the target cast's author. - **hash** (Uint8Array) - Required - The hash of the target cast. - **pageSize** (number) - Optional - The number of reactions to return per page. ### Request Example ```typescript const reactions = await client.getReactionsByTarget({ targetCastId: { fid: 1n, hash: hexToBytes("0x...") }, pageSize: 100, }); ``` ``` -------------------------------- ### Verification Add/Remove Body Structures (Protobuf) Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Defines the protobuf structures for adding and removing Ethereum address verifications. VerificationAddEthAddressBody includes the address, signature, block hash, and verification type, while VerificationRemoveBody only contains the address to be removed. ```protobuf message VerificationAddEthAddressBody { bytes address = 1; // Ethereum address being verified bytes eth_signature = 2; // Signature produced by the user's Ethereum address bytes block_hash = 3; // Hash of the latest Ethereum block when the signature was produced uint32 verification_type = 4; // Verification type ID, EOA or contract uint32 chain_id = 5; // Chain ID of the verification claim, for contract verifications } message VerificationRemoveBody { bytes address = 1; // Address of the Verification to remove } ``` -------------------------------- ### Get On-Chain Signer Events by FID Source: https://context7.com/farcasterxyz/protocol/llms.txt Fetches signer addition and removal events for a specific Farcaster ID (FID). Useful for auditing signer keys and their history. ```typescript // Fetch signer events for a specific fid const signerEvents = await client.getOnChainSignersByFid({ fid: 8930123n }); for (const event of signerEvents.value.events) { const { key, eventType } = event.signerEventBody; console.log( protobufs.SignerEventType[eventType], Buffer.from(key).toString("hex").slice(0, 16) + "..." ); } // SIGNER_EVENT_TYPE_ADD → abcdef012345... // SIGNER_EVENT_TYPE_REMOVE → abcdef012345... ``` -------------------------------- ### Create CastAdd and CastRemove Messages Source: https://context7.com/farcasterxyz/protocol/llms.txt Demonstrates creating CastAdd messages with mentions and embeds, and CastRemove messages to tombstone previous casts. CastRemove takes precedence over CastAdd for the same hash. ```typescript // CastAdd: reply to an existing cast with a mention const castAdd = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_CAST_ADD, fid: 8930123n, timestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), network: protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET, castAddBody: { text: " welcome to Farcaster!", // mention occupies byte position 0 mentions: [1n], // fid 1 = @farcaster mentionsPositions: [0], parentCastId: { fid: 1n, hash: hexToBytes("0x...parenthash"), }, embeds: [{ url: "https://farcaster.xyz" }], }, }); // CastRemove: tombstone a previous cast const castRemove = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_CAST_REMOVE, fid: 8930123n, timestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), network: protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET, castRemoveBody: { targetHash: hexToBytes("0x...4448"), // hash of the CastAdd to remove }, }); // Conflict rule: CastRemove always beats CastAdd for the same target hash // CRDT limit: 5,000 casts per storage unit (LWW eviction by timestamp-hash order) ``` -------------------------------- ### Get IdRegistry On-Chain Event Source: https://context7.com/farcasterxyz/protocol/llms.txt Fetches the IdRegistry on-chain event for a specific FID, primarily to retrieve the custody address. Useful for verifying identity registrations and ownership. ```typescript // Fetch IdRegistry registration event const idEvent = await client.getIdRegistryOnChainEvent({ fid: 8930123n }); console.log( "Custody:", Buffer.from(idEvent.value.idRegisterEventBody.to).toString("hex") ); ``` -------------------------------- ### Build and Submit a Farcaster Message Source: https://context7.com/farcasterxyz/protocol/llms.txt Constructs a CastAdd message, serializes, hashes, and signs it, then submits it to a Farcaster Hub. Requires @farcaster/protobufs and @noble/curves libraries. ```typescript import * as protobufs from "@farcaster/protobufs"; import { blake3 } from "@noble/hashes/blake3"; import { ed25519 } from "@noble/curves/ed25519"; const fid = 8930123n; const network = protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET; // Build MessageData const data = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_CAST_ADD, fid: fid, timestamp: Math.floor(Date.now() / 1000) - 1609459200, // Farcaster epoch: Jan 1 2021 network: network, castAddBody: { text: "Hello Farcaster!", mentions: [], mentionsPositions: [], embeds: [], }, }); // Serialize, hash, and sign const dataBytes = protobufs.MessageData.encode(data).finish(); const hash = blake3(dataBytes, { dkLen: 20 }); // 160-bit digest const signerPrivateKey = ed25519.utils.randomPrivateKey(); const signature = ed25519.sign(hash, signerPrivateKey); const message = protobufs.Message.create({ data, hash, hashScheme: protobufs.HashScheme.HASH_SCHEME_BLAKE3, signature, signatureScheme: protobufs.SignatureScheme.SIGNATURE_SCHEME_ED25519, signer: ed25519.getPublicKey(signerPrivateKey), }); // Submit to Hub const client = getHubRpcClient("hub.example.com:2283"); const result = await client.submitMessage(message); // On success: result is the echoed Message with server-confirmed hash ``` -------------------------------- ### Nameserver Signer Public Address Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Response from a GET request to the /signer endpoint, providing the public address of the nameserver's signer keypair. This address is used for counter-signing messages. ```json { "address": "" // Public address for the server's signer } ``` -------------------------------- ### Protobuf Definition for UserNameProof Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Defines the structure for username proof messages, including types, names, owners, signatures, and FIDs. ```protobuf enum UserNameType { USERNAME_TYPE_NONE = 0; USERNAME_TYPE_FNAME = 1; USERNAME_TYPE_ENS_L1 = 2; } message UserNameProofBody { uint64 timestamp = 1; bytes name = 2; bytes owner = 3; bytes signature = 4; uint64 fid = 5; UserNameType type = 6; } ``` -------------------------------- ### Protobuf Definition for User Data Body Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Defines the structure for user metadata, including type and value. Used for adding user profile information. ```protobuf message UserDataBody { UserDataType type = 1; string value = 2; } enum UserDataType { USER_DATA_TYPE_NONE = 0; USER_DATA_TYPE_PFP = 1; // Profile Picture URL USER_DATA_TYPE_DISPLAY = 2; // Display Name USER_DATA_TYPE_BIO = 3; // Bio USER_DATA_TYPE_URL = 5; // Homepage URL USER_DATA_TYPE_USERNAME = 6; // Preferred username } ``` -------------------------------- ### Get All Messages by Sync IDs Source: https://context7.com/farcasterxyz/protocol/llms.txt Retrieves the actual messages corresponding to a list of Sync IDs. This is the final step in out-of-band reconciliation after identifying missing messages via diff sync. ```typescript // Fetch the actual messages for those Sync IDs const messages = await client.getAllMessagesBySyncIds({ syncIds: syncIds.value.syncIds, }); console.log(`Fetched ${messages.value.messages.length} missing messages`); ``` -------------------------------- ### Fname Transfer Event Schema Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Schema for events returned by a GET request to the /transfers endpoint, which lists username transfer events. Includes original user and server signatures for verification. ```json { "transfers": [ { "id": 1, "from": 0, "to": 1, "username": "test", "timestamp": 1686680932, "owner": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", // EIP-712 signature signed by the server's key "server_signature": "0x68a1a565f603b9966f228a38d918c12f166650749359fe41e2755fabe016026b361dd7d5f917c6f8a09241b29085fbaefffb75e443a3851be85c8b53b", // Original user provided signature "user_signature": "0xf603b9966f228a38d918c12f166650749359fe41e2755fabe016026b361dd7d5f917c6f8a09241b29085fbaefffb75e443a3851be85c8b53b691536d1c", }, // ... ] } ``` -------------------------------- ### Hub Service gRPC Endpoints for Diff Sync Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md Defines the gRPC service for hub synchronization, enabling clients to fetch diffs and sync IDs. ```protobuf service HubService { rpc GetInfo(HubInfoRequest) returns (HubInfoResponse); rpc GetAllSyncIdsByPrefix(TrieNodePrefix) returns (SyncIds); rpc GetAllMessagesBySyncIds(SyncIds) returns (MessagesResponse); rpc GetSyncMetadataByPrefix(TrieNodePrefix) returns (TrieNodeMetadataResponse); rpc GetSyncSnapshotByPrefix(TrieNodePrefix) returns (TrieNodeSnapshotResponse); } message HubInfoRequest { bool db_stats = 1; } message HubInfoResponse { string version = 1; bool is_synced = 2; string nickname = 3; string root_hash = 4; } message SyncIds { repeated bytes sync_ids = 1; } message TrieNodeMetadataResponse { bytes prefix = 1; uint64 num_messages = 2; string hash = 3; repeated TrieNodeMetadataResponse children = 4; } message TrieNodeSnapshotResponse { bytes prefix = 1; repeated string excluded_hashes = 2; uint64 num_messages = 3; string root_hash = 4; } message TrieNodePrefix { bytes prefix = 1; } ``` -------------------------------- ### Diff Sync RPC Endpoints Source: https://github.com/farcasterxyz/protocol/blob/main/docs/SPECIFICATION.md gRPC endpoints for enabling diff synchronization between Farcaster Hubs. ```APIDOC ## HubService Diff Sync RPCs ### Description Provides methods for Hubs to synchronize data using a diff-based approach. ### Service `HubService` ### Methods - **GetInfo**: Retrieves information about the Hub, optionally including database statistics. - **GetAllSyncIdsByPrefix**: Fetches all sync IDs within a given trie node prefix. - **GetAllMessagesBySyncIds**: Retrieves all messages corresponding to a list of sync IDs. - **GetSyncMetadataByPrefix**: Gets metadata for a trie node prefix, including message count and children. - **GetSyncSnapshotByPrefix**: Retrieves a snapshot of sync data for a given trie node prefix. ``` -------------------------------- ### Farcaster Authentication Flow Source: https://github.com/farcasterxyz/protocol/blob/main/docs/OVERVIEW.md Illustrates the authentication process where a user's key pair signs messages, which can then be signed by delegated signers. This ensures message integrity and self-authentication. ```mermaid graph LR Custody([Address Key Pair]) --> |Signature|SignerA1([Signer Key Pair]) SignerA1 --> |Signature|CastC[Hello World!] SignerA1 --> |Signature|CastD[It's Alice!] ``` -------------------------------- ### Add/Remove Links (Follows) Between Users Source: https://context7.com/farcasterxyz/protocol/llms.txt Use LinkAdd to follow another user and LinkRemove to unfollow. The 'follow' link type is used for social graph connections. An optional displayTimestamp can be provided. Conflict key is (fid, link_type, target_fid), with remove-wins at equal timestamps. CRDT limit is 2,500 links per storage unit. ```typescript // Follow another user (fid 999) const followAdd = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_LINK_ADD, fid: 8930123n, timestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), network: protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET, linkBody: { type: "follow", // max 8 bytes targetFid: 999n, displayTimestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), }, }); // Unfollow const followRemove = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_LINK_REMOVE, fid: 8930123n, timestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), network: protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET, linkBody: { type: "follow", targetFid: 999n, }, }); // Conflict key: (fid, link_type, target_fid) — LWW, remove-wins at equal timestamp // CRDT limit: 2,500 links per storage unit ``` -------------------------------- ### Add User Data (Profile Metadata) Source: https://context7.com/farcasterxyz/protocol/llms.txt Use UserDataAdd to set profile fields like display name, profile picture URL, or username. There is no remove operation; fields are cleared by setting an empty value. Conflict key is (fid, user_data_type), using LWW. CRDT limit is 50 entries per storage unit. ```typescript // Set display name const setDisplayName = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_USER_DATA_ADD, fid: 8930123n, timestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), network: protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET, userDataBody: { type: protobufs.UserDataType.USER_DATA_TYPE_DISPLAY, value: "Alice", // max 32 bytes }, }); // Set profile picture const setPfp = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_USER_DATA_ADD, fid: 8930123n, timestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), network: protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET, userDataBody: { type: protobufs.UserDataType.USER_DATA_TYPE_PFP, value: "https://example.com/alice.png", // max 256 bytes }, }); // Set preferred username (must map to a valid fname owned by this fid) const setUsername = protobufs.MessageData.create({ type: protobufs.MessageType.MESSAGE_TYPE_USER_DATA_ADD, fid: 8930123n, timestamp: toFarcasterTimestamp(Math.floor(Date.now() / 1000)), network: protobufs.FarcasterNetwork.FARCASTER_NETWORK_MAINNET, userDataBody: { type: protobufs.UserDataType.USER_DATA_TYPE_USERNAME, value: "alice", // must be a valid fname or ENS name owned by fid }, }); // Conflict key: (fid, user_data_type) — LWW; CRDT limit: 50 entries per storage unit ``` -------------------------------- ### Subscribe to Real-Time Event Stream Source: https://context7.com/farcasterxyz/protocol/llms.txt Opens a server-sent gRPC stream of HubEvents. Clients can filter by event type and resume from a specific event ID. ```APIDOC ## Subscribe — Real-Time Event Stream ### Description Opens a server-sent gRPC stream of `HubEvent`s. Clients can filter by event type and resume from a specific event ID to avoid replaying the full history. ### Method `client.subscribe` ### Parameters #### Request Body - **eventTypes** (Array) - Required - Types of events to subscribe to. - **fromId** (bigint) - Optional - Event ID to resume from. `0n` starts from now. ### Request Example ```typescript const subscription = await client.subscribe({ eventTypes: [ HubEventType.HUB_EVENT_TYPE_MERGE_MESSAGE, HubEventType.HUB_EVENT_TYPE_PRUNE_MESSAGE, HubEventType.HUB_EVENT_TYPE_REVOKE_MESSAGE, ], fromId: 0n, }); ``` ### Response #### Success Response - **value** (AsyncIterableIterator) - An iterator yielding HubEvent objects. ### Response Example ```typescript for await (const event of subscription.value) { switch (event.type) { case HubEventType.HUB_EVENT_TYPE_MERGE_MESSAGE: { const msg = event.mergeMessageBody.message; console.log("MERGE", protobufs.MessageType[msg.data.type], "fid:", msg.data.fid); break; } case HubEventType.HUB_EVENT_TYPE_PRUNE_MESSAGE: console.log("PRUNED fid:", event.pruneMessageBody.message.data.fid); break; case HubEventType.HUB_EVENT_TYPE_REVOKE_MESSAGE: console.log("REVOKED fid:", event.revokeMessageBody.message.data.fid); break; } } ``` ```