@nekofar/warpcast
Version:
TypeScript client for interacting with Warpcast APIs
2,044 lines (2,043 loc) • 511 kB
text/typescript
import { FetchOptions, ResponseType, ofetch } from "ofetch";
import { z } from "zod";
//#region src/client/core/auth.gen.d.ts
type AuthToken = string | undefined;
interface Auth {
/**
* Which part of the request do we use to send the auth?
*
* @default 'header'
*/
in?: "header" | "query" | "cookie";
/**
* Header or query parameter name.
*
* @default 'Authorization'
*/
name?: string;
scheme?: "basic" | "bearer";
type: "apiKey" | "http";
}
//#endregion
//#region src/client/core/pathSerializer.gen.d.ts
interface SerializerOptions<T> {
/**
* @default true
*/
explode: boolean;
style: T;
}
type ArrayStyle = "form" | "spaceDelimited" | "pipeDelimited";
type ObjectStyle = "form" | "deepObject";
//#endregion
//#region src/client/core/bodySerializer.gen.d.ts
type QuerySerializer = (query: Record<string, unknown>) => string;
type BodySerializer = (body: any) => any;
type QuerySerializerOptionsObject = {
allowReserved?: boolean;
array?: Partial<SerializerOptions<ArrayStyle>>;
object?: Partial<SerializerOptions<ObjectStyle>>;
};
type QuerySerializerOptions = QuerySerializerOptionsObject & {
/**
* Per-parameter serialization overrides. When provided, these settings
* override the global array/object settings for specific parameter names.
*/
parameters?: Record<string, QuerySerializerOptionsObject>;
};
declare const formDataBodySerializer: {
bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T) => FormData;
};
declare const jsonBodySerializer: {
bodySerializer: <T>(body: T) => string;
};
declare const urlSearchParamsBodySerializer: {
bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(body: T) => string;
};
//#endregion
//#region src/client/core/params.gen.d.ts
type Slot = "body" | "headers" | "path" | "query";
type Field = {
in: Exclude<Slot, "body">;
/**
* Field name. This is the name we want the user to see and use.
*/
key: string;
/**
* Field mapped name. This is the name we want to use in the request.
* If omitted, we use the same value as `key`.
*/
map?: string;
} | {
in: Extract<Slot, "body">;
/**
* Key isn't required for bodies.
*/
key?: string;
map?: string;
} | {
/**
* Field name. This is the name we want the user to see and use.
*/
key: string;
/**
* Field mapped name. This is the name we want to use in the request.
* If `in` is omitted, `map` aliases `key` to the transport layer.
*/
map: Slot;
};
interface Fields {
allowExtra?: Partial<Record<Slot, boolean>>;
args?: ReadonlyArray<Field>;
}
type FieldsConfig = ReadonlyArray<Field | Fields>;
interface Params {
body: unknown;
headers: Record<string, unknown>;
path: Record<string, unknown>;
query: Record<string, unknown>;
}
declare const buildClientParams: (args: ReadonlyArray<unknown>, fields: FieldsConfig) => Params;
//#endregion
//#region src/client/core/queryKeySerializer.gen.d.ts
/**
* JSON-friendly union that mirrors what Pinia Colada can hash.
*/
type JsonValue = null | string | number | boolean | JsonValue[] | {
[key: string]: JsonValue;
};
/**
* Normalizes any accepted value into a JSON-friendly shape for query keys.
*/
declare const serializeQueryKeyValue: (value: unknown) => JsonValue | undefined;
//#endregion
//#region src/client/core/types.gen.d.ts
type HttpMethod = "connect" | "delete" | "get" | "head" | "options" | "patch" | "post" | "put" | "trace";
type Client$1<RequestFn$1 = never, Config$2 = unknown, MethodFn$1 = never, BuildUrlFn$1 = never, SseFn$1 = never> = {
/**
* Returns the final request URL.
*/
buildUrl: BuildUrlFn$1;
getConfig: () => Config$2;
request: RequestFn$1;
setConfig: (config: Config$2) => Config$2;
} & { [K in HttpMethod]: MethodFn$1 } & ([SseFn$1] extends [never] ? {
sse?: never;
} : {
sse: { [K in HttpMethod]: SseFn$1 };
});
interface Config$1 {
/**
* Auth token or a function returning auth token. The resolved value will be
* added to the request payload as defined by its `security` array.
*/
auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
/**
* A function for serializing request body parameter. By default,
* {@link JSON.stringify()} will be used.
*/
bodySerializer?: BodySerializer | null;
/**
* An object containing any HTTP headers that you want to pre-populate your
* `Headers` object with.
*
* {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
*/
headers?: RequestInit["headers"] | Record<string, string | number | boolean | (string | number | boolean)[] | null | undefined | unknown>;
/**
* The request method.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
*/
method?: Uppercase<HttpMethod>;
/**
* A function for serializing request query parameters. By default, arrays
* will be exploded in form style, objects will be exploded in deepObject
* style, and reserved characters are percent-encoded.
*
* This method will have no effect if the native `paramsSerializer()` Axios
* API function is used.
*
* {@link https://swagger.io/docs/specification/serialization/#query View examples}
*/
querySerializer?: QuerySerializer | QuerySerializerOptions;
/**
* A function validating request data. This is useful if you want to ensure
* the request conforms to the desired shape, so it can be safely sent to
* the server.
*/
requestValidator?: (data: unknown) => Promise<unknown>;
/**
* A function transforming response data before it's returned. This is useful
* for post-processing data, e.g. converting ISO strings into Date objects.
*/
responseTransformer?: (data: unknown) => Promise<unknown>;
/**
* A function validating response data. This is useful if you want to ensure
* the response conforms to the desired shape, so it can be safely passed to
* the transformers and returned to the user.
*/
responseValidator?: (data: unknown) => Promise<unknown>;
}
//#endregion
//#region src/client/core/serverSentEvents.gen.d.ts
type ServerSentEventsOptions<TData = unknown> = Omit<RequestInit, "method"> & Pick<Config$1, "method" | "responseTransformer" | "responseValidator"> & {
/**
* Fetch API implementation. You can use this option to provide a custom
* fetch instance.
*
* @default globalThis.fetch
*/
fetch?: typeof fetch;
/**
* Implementing clients can call request interceptors inside this hook.
*/
onRequest?: (url: string, init: RequestInit) => Promise<Request>;
/**
* Callback invoked when a network or parsing error occurs during streaming.
*
* This option applies only if the endpoint returns a stream of events.
*
* @param error The error that occurred.
*/
onSseError?: (error: unknown) => void;
/**
* Callback invoked when an event is streamed from the server.
*
* This option applies only if the endpoint returns a stream of events.
*
* @param event Event streamed from the server.
* @returns Nothing (void).
*/
onSseEvent?: (event: StreamEvent<TData>) => void;
serializedBody?: RequestInit["body"];
/**
* Default retry delay in milliseconds.
*
* This option applies only if the endpoint returns a stream of events.
*
* @default 3000
*/
sseDefaultRetryDelay?: number;
/**
* Maximum number of retry attempts before giving up.
*/
sseMaxRetryAttempts?: number;
/**
* Maximum retry delay in milliseconds.
*
* Applies only when exponential backoff is used.
*
* This option applies only if the endpoint returns a stream of events.
*
* @default 30000
*/
sseMaxRetryDelay?: number;
/**
* Optional sleep function for retry backoff.
*
* Defaults to using `setTimeout`.
*/
sseSleepFn?: (ms: number) => Promise<void>;
url: string;
};
interface StreamEvent<TData = unknown> {
data: TData;
event?: string;
id?: string;
retry?: number;
}
type ServerSentEventsResult<TData = unknown, TReturn = void, TNext = unknown> = {
stream: AsyncGenerator<TData extends Record<string, unknown> ? TData[keyof TData] : TData, TReturn, TNext>;
};
//#endregion
//#region src/client/client/utils.gen.d.ts
declare const mergeHeaders: (...headers: Array<Required<Config>["headers"] | undefined>) => Headers;
type ErrInterceptor<Err, Res, Req, Options$2> = (error: Err, response: Res, request: Req, options: Options$2) => Err | Promise<Err>;
type ReqInterceptor<Req, Options$2> = (request: Req, options: Options$2) => Req | Promise<Req>;
type ResInterceptor<Res, Req, Options$2> = (response: Res, request: Req, options: Options$2) => Res | Promise<Res>;
declare class Interceptors<Interceptor> {
fns: Array<Interceptor | null>;
clear(): void;
eject(id: number | Interceptor): void;
exists(id: number | Interceptor): boolean;
getInterceptorIndex(id: number | Interceptor): number;
update(id: number | Interceptor, fn: Interceptor): number | Interceptor | false;
use(fn: Interceptor): number;
}
interface Middleware<Req, Res, Err, Options$2> {
error: Interceptors<ErrInterceptor<Err, Res, Req, Options$2>>;
request: Interceptors<ReqInterceptor<Req, Options$2>>;
response: Interceptors<ResInterceptor<Res, Req, Options$2>>;
}
declare const createConfig: <T extends ClientOptions = ClientOptions>(override?: Config<Omit<ClientOptions, keyof T> & T>) => Config<Omit<ClientOptions, keyof T> & T>;
//#endregion
//#region src/client/client/types.gen.d.ts
type ResponseStyle = "data" | "fields";
interface Config<T extends ClientOptions = ClientOptions> extends Omit<RequestInit, "body" | "headers" | "method">, Config$1 {
/**
* HTTP(S) agent configuration (Node.js only). Passed through to ofetch.
*/
agent?: FetchOptions["agent"];
/**
* Base URL for all requests made by this client.
*/
baseUrl?: T["baseUrl"];
/**
* Node-only proxy/agent options.
*/
dispatcher?: FetchOptions["dispatcher"];
/**
* Fetch API implementation. Used for SSE streaming. You can use this option
* to provide a custom fetch instance.
*
* @default globalThis.fetch
*/
fetch?: typeof fetch;
/**
* Controls the native ofetch behaviour that throws `FetchError` when
* `response.ok === false`. We default to suppressing it to match the fetch
* client semantics and let `throwOnError` drive the outcome.
*/
ignoreResponseError?: FetchOptions["ignoreResponseError"];
/**
* Please don't use the Fetch client for Next.js applications. The `next`
* options won't have any effect.
*
* Install {@link https://www.npmjs.com/package/@hey-api/client-next `@hey-api/client-next`} instead.
*/
next?: never;
/**
* Custom ofetch instance created via `ofetch.create()`. If provided, it will
* be used for requests instead of the default `ofetch` export.
*/
ofetch?: typeof ofetch;
/**
* ofetch hook called before a request is sent.
*/
onRequest?: FetchOptions["onRequest"];
/**
* ofetch hook called when a request fails before receiving a response
* (e.g., network errors or aborted requests).
*/
onRequestError?: FetchOptions["onRequestError"];
/**
* ofetch hook called after a successful response is received and parsed.
*/
onResponse?: FetchOptions["onResponse"];
/**
* ofetch hook called when the response indicates an error (non-ok status)
* or when response parsing fails.
*/
onResponseError?: FetchOptions["onResponseError"];
/**
* Return the response data parsed in a specified format. By default, `auto`
* will infer the appropriate method from the `Content-Type` response header.
* You can override this behavior with any of the {@link Body} methods.
* Select `stream` if you don't want to parse response data at all.
*
* @default 'auto'
*/
parseAs?: "arrayBuffer" | "auto" | "blob" | "formData" | "json" | "stream" | "text";
/** Custom response parser (ofetch). */
parseResponse?: FetchOptions["parseResponse"];
/**
* Should we return only data or multiple fields (data, error, response, etc.)?
*
* @default 'fields'
*/
responseStyle?: ResponseStyle;
/**
* ofetch responseType override. If provided, it will be passed directly to
* ofetch and take precedence over `parseAs`.
*/
responseType?: ResponseType;
/**
* Automatically retry failed requests.
*/
retry?: FetchOptions["retry"];
/**
* Delay (in ms) between retry attempts.
*/
retryDelay?: FetchOptions["retryDelay"];
/**
* HTTP status codes that should trigger a retry.
*/
retryStatusCodes?: FetchOptions["retryStatusCodes"];
/**
* Throw an error instead of returning it in the response?
*
* @default false
*/
throwOnError?: T["throwOnError"];
/**
* Abort the request after the given milliseconds.
*/
timeout?: number;
}
interface RequestOptions<TData = unknown, TResponseStyle extends ResponseStyle = "fields", ThrowOnError extends boolean = boolean, Url extends string = string> extends Config<{
responseStyle: TResponseStyle;
throwOnError: ThrowOnError;
}>, Pick<ServerSentEventsOptions<TData>, "onSseError" | "onSseEvent" | "sseDefaultRetryDelay" | "sseMaxRetryAttempts" | "sseMaxRetryDelay"> {
/**
* Any body that you want to add to your request.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#body}
*/
body?: unknown;
path?: Record<string, unknown>;
query?: Record<string, unknown>;
/**
* Security mechanism(s) to use for the request.
*/
security?: ReadonlyArray<Auth>;
url: Url;
}
interface ResolvedRequestOptions<TResponseStyle extends ResponseStyle = "fields", ThrowOnError extends boolean = boolean, Url extends string = string> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
serializedBody?: string;
}
type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = "fields"> = ThrowOnError extends true ? Promise<TResponseStyle extends "data" ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : {
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
request: Request;
response: Response;
}> : Promise<TResponseStyle extends "data" ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({
data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
error: undefined;
} | {
data: undefined;
error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
}) & {
request: Request;
response: Response;
}>;
interface ClientOptions {
baseUrl?: string;
responseStyle?: ResponseStyle;
throwOnError?: boolean;
}
type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields">(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, "method">) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
type SseFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields">(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, "method">) => Promise<ServerSentEventsResult<TData, TError>>;
type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = "fields">(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, "method"> & Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, "method">) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
type BuildUrlFn = <TData extends {
body?: unknown;
path?: Record<string, unknown>;
query?: Record<string, unknown>;
url: string;
}>(options: TData & Options<TData>) => string;
type Client = Client$1<RequestFn, Config, MethodFn, BuildUrlFn, SseFn> & {
interceptors: Middleware<Request, Response, unknown, ResolvedRequestOptions>;
};
/**
* The `createClientConfig()` function will be called on client initialization
* and the returned object will become the client's initial configuration.
*
* You may want to initialize your client this way instead of calling
* `setConfig()`. This is useful for example if you're using Next.js
* to ensure your client always has the correct values.
*/
type CreateClientConfig<T extends ClientOptions = ClientOptions> = (override?: Config<ClientOptions & T>) => Config<Required<ClientOptions> & T>;
interface TDataShape {
body?: unknown;
headers?: unknown;
path?: unknown;
query?: unknown;
url: string;
}
type OmitKeys<T, K$1> = Pick<T, Exclude<keyof T, K$1>>;
type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = "fields"> = OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, "body" | "path" | "query" | "url"> & ([TData] extends [never] ? unknown : Omit<TData, "url">);
//#endregion
//#region src/client/client/client.gen.d.ts
declare const createClient: (config?: Config) => Client;
//#endregion
//#region src/client/types.gen.d.ts
type ProfilePicture = {
url?: string;
verified?: boolean;
};
type Bio = {
text?: string;
mentions?: Array<unknown>;
channelMentions?: Array<unknown>;
};
type Location = {
placeId?: string;
description?: string;
};
type Profile = {
bio?: Bio;
location?: Location;
};
type ViewerContext = {
following?: boolean;
followedBy?: boolean;
enableNotifications?: boolean;
canSendDirectCasts?: boolean;
hasUploadedInboxKeys?: boolean;
};
type User = {
fid: number;
username: string;
displayName: string;
pfp?: ProfilePicture;
profile?: Profile;
followerCount?: number;
followingCount?: number;
viewerContext?: ViewerContext;
};
type OnboardingState = {
id?: string;
email?: string;
user?: User;
hasOnboarding?: boolean;
hasConfirmedEmail?: boolean;
handledConnectAddress?: boolean;
canRegisterUsername?: boolean;
needsRegistrationPayment?: boolean;
hasFid?: boolean;
hasFname?: boolean;
hasDelegatedSigner?: boolean;
hasSetupProfile?: boolean;
hasCompletedRegistration?: boolean;
hasStorage?: boolean;
handledPushNotificationsNudge?: boolean;
handledContactsNudge?: boolean;
handledInterestsNudge?: boolean;
hasValidPaidInvite?: boolean;
hasWarpcastWalletAddress?: boolean;
hasPhone?: boolean;
needsPhone?: boolean;
sponsoredRegisterEligible?: boolean;
geoRestricted?: boolean;
};
type OnboardingStateResponse = {
result?: {
state?: OnboardingState;
};
};
/**
* Generic 400 Bad Request error for simple error messages
*/
type GenericBadRequestError = {
errors: Array<{
/**
* Error message describing the issue
*/
message: string;
}>;
};
type ErrorResponse = {
errors?: Array<{
/**
* Error message describing the issue
*/
message?: string;
}>;
};
type UserWithExtras = User & {
connectedAccounts?: Array<unknown>;
};
type UserExtras = {
fid?: number;
custodyAddress?: string;
ethWallets?: Array<string>;
solanaWallets?: Array<string>;
walletLabels?: Array<{
address?: string;
labels?: Array<string>;
}>;
v2?: boolean;
publicSpamLabel?: string;
};
type UserByFidResponse = {
result?: {
user?: UserWithExtras;
collectionsOwned?: Array<unknown>;
extras?: UserExtras;
};
};
/**
* Represents a single validation error
*/
type ValidationError = {
/**
* JSON Pointer to the part of the request that failed validation
*/
instancePath: string;
/**
* JSON Schema path that was violated
*/
schemaPath: string;
/**
* The JSON Schema keyword that failed
*/
keyword: string;
/**
* Additional parameters describing the validation error
*/
params?: {
[key: string]: unknown;
};
/**
* Human-readable error description
*/
message: string;
};
/**
* Standard 400 Bad Request error response
*/
type BadRequestError = {
/**
* Array of validation errors
*/
errors: Array<ValidationError>;
};
type DirectCastMessageReaction = {
/**
* Emoji used for the reaction
*/
reaction: string;
/**
* Number of users who reacted with this emoji
*/
count: number;
/**
* Emoji used for the reaction (legacy field)
*/
emoji?: string;
/**
* List of Farcaster IDs who reacted
*/
userFids?: Array<number>;
};
type DirectCastMessageViewerContext = {
/**
* Whether this is the last read message
*/
isLastReadMessage?: boolean;
/**
* Whether the message is focused
*/
focused?: boolean;
/**
* User's reactions to this message
*/
reactions?: Array<string>;
};
type DirectCastMessage = {
/**
* ID of the conversation this message belongs to
*/
conversationId: string;
/**
* Farcaster ID of the message sender
*/
senderFid: number;
/**
* Unique identifier for the message
*/
messageId: string;
/**
* Server timestamp when message was sent (Unix milliseconds)
*/
serverTimestamp: bigint;
/**
* Type of the message
*/
type: "text" | "image" | "reaction" | "link" | "group_membership_addition" | "pin_message" | "message_ttl_change";
/**
* Content of the message
*/
message: string;
/**
* Whether the message contains mentions
*/
hasMention: boolean;
/**
* List of reactions to the message
*/
reactions: Array<DirectCastMessageReaction>;
/**
* Whether the message is pinned
*/
isPinned: boolean;
/**
* Whether the message is deleted
*/
isDeleted: boolean;
senderContext: User;
viewerContext?: DirectCastMessageViewerContext;
inReplyTo?: DirectCastMessage;
metadata?: DirectCastMessageMetadata;
actionTargetUserContext?: User;
/**
* Whether the message was sent programmatically
*/
isProgrammatic?: boolean;
/**
* List of mentions in the message
*/
mentions?: Array<DirectCastMessageMention>;
};
type DirectCastMessageMetadata = {
/**
* Cast metadata if message contains cast references
*/
casts?: Array<{
[key: string]: unknown;
}>;
/**
* URL metadata if message contains links
*/
urls?: Array<{
[key: string]: unknown;
}>;
/**
* Media metadata if message contains media
*/
medias?: Array<{
[key: string]: unknown;
}>;
};
type DirectCastMessageMention = {
user: User;
/**
* Starting index of the mention in the message text
*/
textIndex: number;
/**
* Length of the mention text
*/
length: number;
};
type DirectCastConversationViewerContext = {
/**
* Access level for the conversation
*/
access?: "read-write" | "read-only";
/**
* Category of the conversation
*/
category?: string;
/**
* Whether the conversation is archived
*/
archived?: boolean;
/**
* Timestamp of last read (Unix milliseconds)
*/
lastReadAt?: bigint;
/**
* Whether the conversation is muted
*/
muted?: boolean;
/**
* Whether the conversation is manually marked as unread
*/
manuallyMarkedUnread?: boolean;
/**
* Whether the conversation is pinned
*/
pinned?: boolean;
/**
* Number of unread messages
*/
unreadCount?: number;
/**
* Number of unread mentions
*/
unreadMentionsCount?: number;
/**
* The other participant in a 1:1 conversation
*/
counterParty?: User;
/**
* Tag associated with the conversation
*/
tag?: string;
};
type DirectCastConversation = {
/**
* Unique identifier for the conversation
*/
conversationId: string;
/**
* Name of the conversation (for group conversations)
*/
name?: string;
/**
* Description of the conversation
*/
description?: string;
/**
* URL of the conversation photo
*/
photoUrl?: string;
/**
* List of admin Farcaster IDs
*/
adminFids: Array<number>;
/**
* List of removed Farcaster IDs
*/
removedFids?: Array<number>;
/**
* List of conversation participants
*/
participants?: Array<User>;
/**
* Timestamp of last read time (Unix milliseconds)
*/
lastReadTime: bigint;
/**
* Timestamp of viewer's last read time (Unix milliseconds)
*/
selfLastReadTime?: bigint;
/**
* List of pinned messages in the conversation
*/
pinnedMessages?: Array<DirectCastMessage>;
/**
* Whether the conversation has pinned messages
*/
hasPinnedMessages?: boolean;
/**
* Whether this is a group conversation
*/
isGroup: boolean;
/**
* Whether the conversation is collection token gated
*/
isCollectionTokenGated?: boolean;
/**
* Number of active participants in the conversation
*/
activeParticipantsCount?: number;
/**
* Message time-to-live in days, or "Infinity" for no expiration
*/
messageTTLDays?: number | "Infinity";
/**
* Timestamp when conversation was created (Unix milliseconds)
*/
createdAt: bigint;
/**
* Number of unread messages
*/
unreadCount?: number;
/**
* Whether the conversation is muted
*/
muted?: boolean;
/**
* Whether the conversation has mentions
*/
hasMention?: boolean;
lastMessage?: DirectCastMessage;
viewerContext: DirectCastConversationViewerContext;
};
type DirectCastInboxResult = {
/**
* Whether user has archived conversations
*/
hasArchived: boolean;
/**
* Whether user has unread conversation requests
*/
hasUnreadRequests: boolean;
/**
* Total number of conversation requests
*/
requestsCount: number;
conversations: Array<DirectCastConversation>;
};
type PaginationCursor = {
/**
* Base64 encoded cursor for pagination
*/
cursor?: string;
[key: string]: unknown | string | undefined;
};
type DirectCastInboxResponse = {
result: DirectCastInboxResult;
next?: PaginationCursor;
};
type CastAction = {
id?: string;
name?: string;
octicon?: string;
actionUrl?: string;
action?: {
actionType?: string;
postUrl?: string;
};
};
type UserAppContextResponse = {
result?: {
context?: {
canAddLinks?: boolean;
showConnectedApps?: boolean;
signerRequestsEnabled?: boolean;
prompts?: Array<unknown>;
adminForChannelKeys?: Array<string>;
modOfChannelKeys?: Array<string>;
memberOfChannelKeys?: Array<string>;
canEditAllChannels?: boolean;
canUploadVideo?: boolean;
statsigEnabled?: boolean;
shouldPromptForPushNotifications?: boolean;
shouldPromptForUserFollowsSyncContacts?: boolean;
castActions?: Array<CastAction>;
canAddCastAction?: boolean;
enabledCastAction?: CastAction;
notificationTabsV2?: Array<{
id?: string;
name?: string;
}>;
enabledVideoAutoplay?: boolean;
regularCastByteLimit?: number;
longCastByteLimit?: number;
newUserStatus?: {
[key: string]: unknown;
};
country?: string;
higherClientEventSamplingRateEnabled?: boolean;
};
};
};
type UserPreferencesResponse = {
result?: {
preferences?: {
[key: string]: unknown;
};
};
};
type Channel = {
type?: string;
key?: string;
name?: string;
imageUrl?: string;
fastImageUrl?: string;
feeds?: Array<{
name?: string;
type?: string;
}>;
description?: string;
followerCount?: number;
memberCount?: number;
showCastSourceLabels?: boolean;
showCastTags?: boolean;
sectionRank?: number;
subscribable?: boolean;
publicCasting?: boolean;
inviteCode?: string;
headerImageUrl?: string;
headerAction?: {
title?: string;
target?: string;
};
headerActionMetadata?: {
[key: string]: unknown;
};
viewerContext?: {
following?: boolean;
isMember?: boolean;
hasUnseenItems?: boolean;
favoritePosition?: number;
activityRank?: number;
canCast?: boolean;
};
};
type HighlightedChannelsResponse = {
result?: {
channels?: Array<Channel>;
viewerContext?: {
defaultFeed?: string;
};
};
};
type ImageEmbed = {
type?: "image";
url?: string;
sourceUrl?: string;
media?: {
version?: string;
width?: number;
height?: number;
staticRaster?: string;
mimeType?: string;
};
alt?: string;
};
type UrlEmbed = {
type: "url";
openGraph: {
url: string;
sourceUrl?: string;
title?: string;
description?: string;
domain?: string;
image?: string;
useLargeImage?: boolean;
};
};
type VideoEmbed = {
type?: "video";
};
type Recaster = {
fid?: number;
username?: string;
displayName?: string;
recastHash?: string;
};
type Cast = {
/**
* Unique hash identifier for the cast
*/
hash: string;
/**
* Hash identifier for the thread this cast belongs to
*/
threadHash?: string;
/**
* Hash identifier of the parent cast (if this is a reply)
*/
parentHash?: string;
parentSource?: {
type?: "url";
url?: string;
};
author: User;
/**
* The text content of the cast
*/
text: string;
/**
* Unix timestamp in milliseconds
*/
timestamp: bigint;
mentions?: Array<User>;
embeds?: {
images?: Array<ImageEmbed>;
urls?: Array<UrlEmbed>;
videos?: Array<VideoEmbed>;
unknowns?: Array<{
[key: string]: unknown;
}>;
processedCastText?: string;
groupInvites?: Array<{
[key: string]: unknown;
}>;
};
replies: {
count: number;
};
reactions: {
count: number;
};
recasts: {
count: number;
recasters?: Array<Recaster>;
};
watches: {
count: number;
};
recast?: boolean;
tags?: Array<{
type?: string;
id?: string;
name?: string;
imageUrl?: string;
}>;
quoteCount?: number;
combinedRecastCount?: number;
channel?: {
key?: string;
name?: string;
imageUrl?: string;
authorContext?: {
role?: string;
restricted?: boolean;
banned?: boolean;
};
authorRole?: string;
};
viewerContext?: {
reacted?: boolean;
recast?: boolean;
bookmarked?: boolean;
};
};
type FeedItemsResponse = {
result: {
items: Array<{
id: string;
timestamp: number;
cast: Cast;
otherParticipants?: Array<User>;
}>;
latestMainCastTimestamp?: number;
feedTopSeenAtTimestamp?: number;
replaceFeed: boolean;
};
};
type GenericResponse = {
result: {
[key: string]: unknown;
};
};
type UserResponse = GenericResponse & {
result: {
user?: UserWithExtras;
collectionsOwned?: Array<{
[key: string]: unknown;
}>;
extras?: UserExtras;
};
};
type PaginatedResponse = {
result: {
[key: string]: unknown;
};
next?: PaginationCursor;
};
type SuggestedUsersResponse = PaginatedResponse & {
result?: {
users?: Array<{
[key: string]: unknown;
}>;
};
};
type FavoriteFramesResponse = {
result: {
frames: Array<{
[key: string]: unknown;
}>;
};
};
type ChannelStreaksResponse = {
result: {
[key: string]: unknown;
};
};
type UnseenCountsResponse = {
result: {
notificationsCount?: number;
notificationTabs?: Array<{
tab: string;
unseenCount: number;
}>;
inboxCount?: number;
channelFeeds?: Array<{
channelKey: string;
feedType: string;
hasNewItems: boolean;
}>;
warpTransactionCount?: number;
};
};
type UserThreadCastsResponse = {
result: {
casts: Array<{
[key: string]: unknown;
}>;
};
};
type ChannelFollowersYouKnowResponse = {
result: {
users: Array<{
[key: string]: unknown;
}>;
totalCount: number;
};
};
type SuccessResponse = GenericResponse & {
result?: {
/**
* Whether the operation was successful
*/
success: boolean;
};
};
type NotificationsResponse = {
result: {
/**
* Notification items for the requested tab.
*/
notifications: Array<{
/**
* Notification identifier.
*/
id: string;
/**
* Notification type.
*/
type: "channel-pinned-cast" | "channel-role-invite" | "new-cast-in-channel" | "cast-mention" | "cast-quote" | "cast-reaction" | "cast-reply" | "dormant-user-new-cast" | "follow" | "mini-app" | "new-article" | "new-cast" | "recast";
/**
* Latest activity timestamp (ms).
*/
latestTimestamp: bigint;
/**
* Number of items represented by this notification.
*/
totalItemCount: number;
/**
* Sample items for this notification; structure varies by type.
*/
previewItems: Array<{
[key: string]: unknown;
}>;
/**
* Whether the notification is unread.
*/
isUnread: boolean;
/**
* Additional notification-specific fields.
*/
metadata?: {
[key: string]: unknown;
};
}>;
next?: PaginationCursor;
};
};
type DirectCastConversationResponse = GenericResponse & {
result?: {
conversation: DirectCastConversation;
};
};
type DirectCastConversationCategorizationRequest = {
/**
* ID of the conversation to categorize
*/
conversationId: string;
/**
* Category to assign to the conversation
*/
category: string;
};
type DirectCastConversationMessagesResponse = PaginatedResponse & {
result?: {
messages: Array<DirectCastMessage>;
};
};
type DirectCastConversationMessageTtlRequest = {
/**
* ID of the conversation to set message TTL for
*/
conversationId: string;
/**
* Time to live for messages in days
*/
ttl: number;
};
type DirectCastConversationNotificationsRequest = {
/**
* ID of the conversation to update notification settings for
*/
conversationId: string;
/**
* Whether to mute notifications for this conversation
*/
muted: boolean;
};
type DirectCastSendRequest = {
/**
* ID of the conversation to send the message to
*/
conversationId: string;
/**
* Array of Farcaster IDs of message recipients
*/
recipientFids: Array<number>;
/**
* Unique identifier for the message
*/
messageId: string;
/**
* Type of the message
*/
type: "text" | "image" | "reaction" | "link";
/**
* Content of the message
*/
message: string;
/**
* ID of the message this is replying to (optional)
*/
inReplyToId?: string;
};
type DirectCastManuallyMarkUnreadRequest = {
/**
* ID of the conversation to mark as unread
*/
conversationId: string;
};
type DirectCastMessageReactionRequest = {
/**
* ID of the conversation containing the message
*/
conversationId: string;
/**
* ID of the message to react to
*/
messageId: string;
/**
* Emoji reaction to add or remove
*/
reaction: string;
};
type DirectCastPinConversationRequest = {
/**
* ID of the conversation to pin
*/
conversationId: string;
};
type DiscoverChannelsResponse = GenericResponse & {
result?: {
channels?: Array<{
[key: string]: unknown;
}>;
};
};
type InvitesAvailableResponse = GenericResponse & {
result?: {
/**
* Total number of invites allocated to the user
*/
allocatedInvitesCount: number;
/**
* Number of invites currently available to send
*/
availableInvitesCount: number;
};
};
type SponsoredInvitesResponse = GenericResponse & {
result?: {
invites?: Array<{
[key: string]: unknown;
}>;
};
[key: string]: unknown | {
invites?: Array<{
[key: string]: unknown;
}>;
} | undefined;
};
type RewardsLeaderboardResponse = {
result: {
leaderboard: {
type: string;
users: Array<{
user?: {
[key: string]: unknown;
};
score?: number;
rank?: number;
}>;
};
};
};
type RewardsScoresResponse = {
result: {
scores: Array<{
type?: string;
user?: {
[key: string]: unknown;
};
allTimeScore?: number;
currentPeriodScore?: number;
previousPeriodScore?: number;
}>;
};
};
type RewardsMetadataResponse = {
result: {
metadata?: {
type: string;
lastUpdateTimestamp: bigint;
currentPeriodStartTimestamp: bigint;
currentPeriodEndTimestamp: bigint;
tiers?: Array<{
[key: string]: unknown;
}>;
proportionalPayout?: {
numWinners?: number;
totalRewardCents?: number;
};
};
};
};
type BookmarkedCast = {
[key: string]: unknown;
};
type BookmarkedCastsResponse = {
result: {
bookmarks?: Array<BookmarkedCast>;
};
};
type StarterPack = {
/**
* Unique identifier for the starter pack
*/
id: string;
creator?: User;
/**
* Display name of the starter pack
*/
name?: string;
/**
* Description of the starter pack
*/
description?: string;
/**
* URL for OG image preview
*/
openGraphImageUrl?: string;
/**
* Number of items in the starter pack
*/
itemCount?: number;
/**
* Items contained in the starter pack
*/
items?: Array<{
[key: string]: unknown;
}>;
/**
* Labels/tags for the starter pack
*/
labels?: Array<string>;
[key: string]: unknown | string | User | number | Array<{
[key: string]: unknown;
}> | Array<string> | undefined;
};
type StarterPacksResponse = {
result: {
starterPacks: Array<StarterPack>;
};
};
type StarterPackResponse = {
result: {
starterPack: StarterPack;
};
};
type StarterPackUpdateRequest = {
/**
* Unique identifier for the starter pack to update
*/
id: string;
/**
* Display name of the starter pack
*/
name: string;
/**
* Description of the starter pack
*/
description: string;
/**
* List of FIDs included in the starter pack
*/
fids: Array<number>;
/**
* Labels/tags for the starter pack
*/
labels: Array<string>;
};
type StarterPackUsersResponse = {
result: {
users: Array<User>;
};
};
type ChannelResponse = {
result: {
channel?: Channel;
};
};
type ChannelUsersResponse = {
result: {
users?: Array<User>;
};
};
type UsersResponse = {
result: {
users: Array<User>;
};
};
type UsersWithCountResponse = {
result: {
users: Array<User>;
totalCount: number;
};
};
type FrameApp = {
[key: string]: unknown;
};
type FrameAppsResponse = {
result?: {
frames?: Array<FrameApp>;
};
};
/**
* Context information for the viewer
*/
type MiniAppViewerContext = {
[key: string]: unknown;
};
type MiniApp = {
/**
* The domain of the mini app
*/
domain?: string;
/**
* The name of the mini app
*/
name?: string;
/**
* URL to the mini app's icon
*/
iconUrl?: string;
/**
* The home URL of the mini app
*/
homeUrl?: string;
author?: User;
/**
* Whether the mini app supports notifications
*/
supportsNotifications?: boolean;
/**
* Unique identifier for the mini app
*/
id?: string;
/**
* Short identifier for the mini app
*/
shortId?: string;
/**
* URL to the mini app's main image
*/
imageUrl?: string;
/**
* Title for the action button
*/
buttonTitle?: string;
/**
* URL to the splash screen image
*/
splashImageUrl?: string;
/**
* Background color for the splash screen
*/
splashBackgroundColor?: string;
/**
* URL for sharing casts
*/
castShareUrl?: string;
/**
* Subtitle of the mini app
*/
subtitle?: string;
/**
* Description of the mini app
*/
description?: string;
/**
* Tagline of the mini app
*/
tagline?: string;
/**
* URL to the hero image
*/
heroImageUrl?: string;
/**
* Primary category of the mini app
*/
primaryCategory?: string;
/**
* Tags associated with the mini app
*/
tags?: Array<string>;
/**
* URLs to screenshot images
*/
screenshotUrls?: Array<string>;
/**
* Whether the mini app should be indexed
*/
noindex?: boolean;
/**
* Open Graph title
*/
ogTitle?: string;
/**
* Open Graph description
*/
ogDescription?: string;
/**
* Open Graph image URL
*/
ogImageUrl?: string;
/**
* Required capabilities for the mini app
*/
requiredCapabilities?: Array<string>;
/**
* Required blockchain chains
*/
requiredChains?: Array<string>;
viewerContext?: MiniAppViewerContext;
};
type RankedMiniApp = {
/**
* Current rank of the mini app
*/
rank?: number;
miniApp?: MiniApp;
/**
* Change in rank over the last 72 hours
*/
rank72hChange?: number;
};
type TopMiniAppsResponse = {
result?: {
miniApps?: Array<RankedMiniApp>;
next?: PaginationCursor;
};
};
type VerifiedAddress = {
fid?: number;
address?: string;
timestamp?: number;
version?: string;
protocol?: string;
isPrimary?: boolean;
labels?: Array<string>;
};
type MutedKeywordProperties = {
channels?: boolean;
frames?: boolean;
notifications?: boolean;
};
type MutedKeyword = {
keyword: string;
properties: MutedKeywordProperties;
};
type MutedKeywordsResponse = {
success: boolean;
result: {
keywords: Array<string>;
mutedKeywords: Array<MutedKeyword>;
};
};
type CastHashResponse = {
result: {
castHash?: string;
};
};
type AttachEmbedsResponse = {
result: {
[key: string]: unknown;
};
};
type CastRecastersResponse = {
result: {
users?: Array<User>;
};
};
type CastQuote = {
hash?: string;
threadHash?: string;
parentSource?: {
type?: string;
url?: string;
};
author?: User;
text?: string;
timestamp?: number;
};
type CastQuotesResponse = {
result: {
quotes?: Array<CastQuote>;
};
};
type UserResponseUserResponse = {
result: {
user: User;
};
};
type SearchChannelsResponse = {
result?: {
channels?: Array<Channel>;
};
};
type DraftsResponse = {
result?: {
drafts?: Array<unknown>;
};
};
type DraftCast = {
text?: string;
embeds?: Array<unknown>;
};
type Draft = {
draftId?: string;
casts?: Array<DraftCast>;
};
type DraftCreatedResponse = {
result?: {
draft?: Draft;
};
};
type CastCreatedResponse = {
result?: {
cast?: Cast;
};
};
type RawChannel = {
id?: string;
url?: string;
name?: string;
description?: string;
descriptionMentions?: Array<number>;
descriptionMentionsPositions?: Array<number>;
imageUrl?: string;
headerImageUrl?: string;
leadFid?: number;
moderatorFids?: Array<number>;
createdAt?: number;
followerCount?: number;
memberCount?: number;
pinnedCastHash?: string;
publicCasting?: boolean;
externalLink?: {
title?: string;
url?: string;
};
};
type ChannelListResponse = {
result?: {
channels?: Array<RawChannel>;
};
};
type RawChannelResponse = {
result?: {
channel?: RawChannel;
};
};
type ChannelFollower = {
fid?: number;
followedAt?: number;
};
type ChannelFollowersResponse = PaginatedResponse & {
result?: {
users?: Array<ChannelFollower>;
};
};
type ChannelFollowStatus = {
following?: boolean;
followedAt?: number;
};
type ChannelFollowStatusResponse = {
result?: ChannelFollowStatus;
};
type Action = {
name?: string;
icon?: string;
description?: string;
aboutUrl?: string;
imageUrl?: string;
actionUrl?: string;
action?: {
actionType?: "post" | "get" | "put" | "delete";
postUrl?: string;
};
};
type Winner = {
/**
* The fid of the winner
*/
fid?: number;
/**
* The domain of the winner
*/
domain?: string;
/**
* The name of the frame (mini app)
*/
frameName?: string;
/**
* The score of the winner
*/
score?: number;
/**
* The rank of the winner
*/
rank?: number;
/**
* The reward amount in cents
*/
rewardCents?: number;
/**
* The wallet address of the winner (optional)
*/
walletAddress?: string;
};
type Frame = {
domain?: string;
name?: string;
iconUrl?: string;
homeUrl?: string;
splashImageUrl?: string;
splashBackgroundColor?: string;
buttonTitle?: string | null;
imageUrl?: string | null;
supportsNotifications?: boolean;
viewerContext?: {
[key: string]: unknown;
};
author?: User;
};
type AppsByAuthorResponse = {
result?: {
frames?: Array<Frame>;
};
};
type ApiKey = {
/**
* Unique identifier for the API key
*/
id: string;
/**
* Timestamp when the API key was created (in milliseconds since epoch)
*/
createdAt: bigint;
/**
* Timestamp when the API key expires (in milliseconds since epoch)
*/
expiresAt: bigint;
/**
* Timestamp when the API key was revoked, if applicable (in milliseconds since epoch)
*/
revokedAt?: string | null;
/**
* Short identifier tag for the API key
*/
tag: string;
/**
* User-provided description of the API key's purpose
*/
description: string;
};
type DirectCastSendResponse = SuccessResponse;
type DirectCastConversationCategorizationResponse = SuccessResponse;
type DirectCastConversationNotificationsResponse = SuccessResponse;
type DirectCastConversationMessageTtlResponse = SuccessResponse;
type DirectCastMessageReactionResponse = SuccessResponse;
/**
* The user's FID (Farcaster ID)
*/
type FidParam = number;
/**
* Maximum number of items to return
*/
type LimitParam = number;
/**
* Base64 encoded cursor for pagination
*/
type CursorParam = string;
type GetUserOnboardingStateData = {
body?: never;
path?: never;
query?: never;
url: "/v2/onboarding-state";
};
type GetUserOnboardingStateErrors = {
/**
* Missing or invalid authorization header
*/
400: GenericBadRequestError;
/**
* Authentication is required or failed
*/
401: ErrorResponse;
/**
* Too many requests - rate limit exceeded
*/
429: ErrorResponse;
};
type GetUserOnboardingStateError = GetUserOnboardingStateErrors[keyof GetUserOnboardingStateErrors];
type GetUserOnboardingStateResponses = {
/**
* Successful retrieval of onboarding state
*/
200: OnboardingStateResponse;
};
type GetUserOnboardingStateResponse = GetUserOnboardingStateResponses[keyof GetUserOnboardingStateResponses];
type GetUserByFidData = {
body?: never;
path?: never;
query: {
/**
* The user's FID (Farcaster ID)
*/
fid: number;
};
url: "/v2/user-by-fid";
};
type GetUserByFidErrors = {
/**
* Bad request - validation errors or malformed request
*/
400: BadRequestError;
/**
* Authentication is required or failed
*/
401: ErrorResponse;
/**
* The specified resource was not found
*/
404: ErrorResponse;
};
type GetUserByFidError = GetUserByFidErrors[keyof GetUserByFidErrors];
type GetUserByFidResponses = {
/**
* Successful retrieval of user by fid
*/
200: UserByFidResponse;
};
type GetUserByFidResponse = GetUserByFidResponses[keyof GetUserByFidResponses];
type GetDirectCastInboxData = {
body?: never;
path?: never;
query?: {
/**
* Maximum number of items to return
*/
limit?: number;
/**
* Category of conversations to retrieve
*/
category?: "default" | "requests" | "spam";
/**
* Filter for conversations (e.g., unread, all)
*/
filter?: "unread" | "group" | "1-1";
/**
* Base64 encoded cursor for pagination
*/
cursor?: string;
};
url: "/v2/direct-cast-inbox";
};
type GetDirectCastInboxErrors = {
/**
* Bad request - validation errors or malformed request
*/
400: BadRequestError;
/**
* Authentication is required or failed
*/
401: ErrorResponse;
/**
* Too many requests - rate limit exceeded
*/
429: ErrorResponse;
};
type GetDirectCastInboxError = GetDirectCastInboxErrors[keyof GetDirectCastInboxErrors];
type GetDirectCastInboxResponses = {
/**
* Successful retrieval of direct cast inbox
*/
200: DirectCastInboxResponse;
};
type GetDirectCastInboxResponse = GetDirectCastInboxResponses[keyof GetDirectCastInboxResponses];
type GetUserAppContextData = {
body?: never;
path?: never;
query?: never;
url: "/v2/user-app-context";
};
type GetUserAppContextErrors = {
/**
* Authentication is required or failed
*/
401: ErrorResponse;
};
type GetUserAppContextError = GetUserAppContextErrors[keyof GetUserAppContextErrors];
type GetUserAppContextResponses = {
/**
* Successful retrieval of user app context
*/
200: UserAppContextResponse;
};
type GetUserAppContextResponse = GetUserAppContextResponses[keyof GetUserAppContextResponses];
type GetUserPreferencesData = {
body?: never;
path?: never;
query?: never;
url: "/v2/user-preferences";
};
type GetUserPreferencesErrors = {
/**
* Authentication is required or failed
*/
401: ErrorResponse;
/**
* Too many requests - rate limit exceeded
*/
429: ErrorResponse;
};
type GetUserPreferencesError = GetUserPreferencesErrors[keyof GetUserPreferencesErrors];
type GetUserPreferencesResponses = {
/**
* Successful retrieval of user preferences
*/
200: UserPreferencesResponse;
};
type GetUserPreferencesResponse = GetUserPreferencesResponses[keyof GetUserPreferencesResponses];
type GetHighlightedChannelsData = {
body?: never;
path?: never;
query?: never;
url: "/v2/highlighted-channels";
};
type GetHighlightedChannelsErrors = {
/**
* Authentication is required or failed
*/
401: ErrorResponse;
};
type GetHighlightedChannelsError = GetHighlightedChannelsErrors[keyof GetHighlightedChannelsErrors];
type GetHighlightedChannelsResponses = {
/**
* Successful retrieval of highlighted channels
*/
200: HighlightedChannelsResponse;
};
type GetHighlightedChannelsResponse = GetHighlightedChannelsResponses[keyof GetHighlightedChannelsResponses];
type GetFeedItemsData = {
body: {
/**
* Identifier for the specific feed
*/
feedKey: string;
/**
* Type of feed to retrieve
*/
feedType: string;
/**
* Only return items older than this timestamp (ms)
*/
olderThan?: bigint;
/**
* Latest main cast timestamp used for pagination (ms)
*/
latestMainCastTimestamp?: bigint;
/**
* List of item ID prefixes to exclude from the response
*/
excludeItemIdPrefixes?: Array<string>;
/**
* View events for casts (can be empty array)
*/
castViewEvents?: