### 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;
}
}
```
```