diff --git a/package.json b/package.json index 9aedee30..d86a39f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@neynar/nodejs-sdk", - "version": "0.9.1", + "version": "0.10.0", "description": "SDK to interact with Neynar APIs (https://docs.neynar.com/)", "main": "./build/index.js", "types": "./build/index.d.ts", diff --git a/src/neynar-api/neynar-api-client.ts b/src/neynar-api/neynar-api-client.ts index 35ea5233..8f4601ee 100644 --- a/src/neynar-api/neynar-api-client.ts +++ b/src/neynar-api/neynar-api-client.ts @@ -1,20 +1,96 @@ -import { NeynarV1APIClient } from "./neynar-v1-api"; -import { NeynarV2APIClient } from "./neynar-v2-api"; -import { AxiosInstance } from "axios"; +import { + CastApi, + SignerApi, + Signer, + Cast, + CastParamType, + PostCastResponseCast, + DeleteCastReqBody, + ReactionApi, + ReactionReqBody, + ReactionType, + OperationResponse, + BulkFollowResponse, + EmbeddedCast, + Configuration, + ErrorRes, + FeedApi, + UserApi, + CastApiPostCastRequest, + FeedType, + FilterType, + FeedResponse, + SignerApiRegisterSignedKeyRequest, + NotificationsResponse, + NotificationsApi, + FollowsApi, + RelevantFollowersResponse, + UserApiRemoveVerificationRequest, + UserApiAddVerificationRequest, + UserApiFollowRequest, + UserApiUpdateUserRequest, + UserBulk200Response, + UserSearchResponse, +} from "./neynar-v2-api/openapi-farcaster"; + +import { + UserApi as UserApiV1, + CastApi as CastApiV1, + NotificationsApi as NotificationsApiV1, + VerificationApi as VerificationApiV1, + ReactionsApi as ReactionsApiV1, + Configuration as ConfigurationV1, + FollowsApi as FollowsApiV1, + RecentUsersResponse, + UserCastLikeResponse, + User, + Cast as CastV1, + CastsResponse, + RecentCastsResponse, + VerificationResponseResult, + MentionsAndRepliesResponse, + ReactionsAndRecastsResponse, + CastLikesResponse, + CastReactionsResponse, + CastRecasterResponse, + FollowResponse, +} from "./neynar-v1-api/openapi"; + +import { + FetchRelevantMints200Response, + NFTApi, +} from "./neynar-v2-api/openapi-recommendation"; +import axios, { AxiosError, AxiosInstance } from "axios"; import { silentLogger, Logger } from "./common/logger"; +import type { SetRequired } from "type-fest"; + +const BASE_PATH_V1 = "https://api.neynar.com/v1"; +const BASE_PATH_V2 = "https://api.neynar.com/v2"; export class NeynarAPIClient { private readonly logger: Logger; - public readonly clients: { - v1: NeynarV1APIClient; - v2: NeynarV2APIClient; + public readonly apis: { + signer: SignerApi; + user: UserApi; + cast: CastApi; + reaction: ReactionApi; + feed: FeedApi; + notifications: NotificationsApi; + follows: FollowsApi; + nft: NFTApi; + userV1: UserApiV1; + castV1: CastApiV1; + verificationV1: VerificationApiV1; + notificationsV1: NotificationsApiV1; + reactionsV1: ReactionsApiV1; + followsV1: FollowsApiV1; }; /** * Instantiates a NeynarAPIClient * - * Creates NeynarV1APIClient and NeynarV2APIClients + * Creates NeynarAPIClient */ constructor( apiKey: string, @@ -30,9 +106,869 @@ export class NeynarAPIClient { "Attempt to use an authenticated API method without first providing an api key" ); } - this.clients = { - v1: new NeynarV1APIClient(apiKey, { logger, axiosInstance }), - v2: new NeynarV2APIClient(apiKey, { logger, axiosInstance }), + if (axiosInstance === undefined) { + axiosInstance = axios.create(); + } + axiosInstance.defaults.decompress = true; + axiosInstance.interceptors.response.use( + (response) => response, + (error) => { + if (NeynarAPIClient.isApiErrorResponse(error)) { + const apiErrors = error.response.data; + this.logger.warn(`API errors: ${JSON.stringify(apiErrors)}`); + } + throw error; + } + ); + + const config: Configuration = new Configuration({ + basePath: BASE_PATH_V2, + apiKey: apiKey, + }); + + const configV1: ConfigurationV1 = new ConfigurationV1({ + basePath: BASE_PATH_V1, + apiKey: apiKey, + }); + + this.apis = { + signer: new SignerApi(config, undefined, axiosInstance), + user: new UserApi(config, undefined, axiosInstance), + cast: new CastApi(config, undefined, axiosInstance), + reaction: new ReactionApi(config, undefined, axiosInstance), + feed: new FeedApi(config, undefined, axiosInstance), + notifications: new NotificationsApi(config, undefined, axiosInstance), + follows: new FollowsApi(config, undefined, axiosInstance), + nft: new NFTApi(config, undefined, axiosInstance), + userV1: new UserApiV1(configV1, undefined, axiosInstance), + castV1: new CastApiV1(configV1, undefined, axiosInstance), + verificationV1: new VerificationApiV1(configV1, undefined, axiosInstance), + notificationsV1: new NotificationsApiV1( + configV1, + undefined, + axiosInstance + ), + reactionsV1: new ReactionsApiV1(configV1, undefined, axiosInstance), + followsV1: new FollowsApiV1(configV1, undefined, axiosInstance), }; } + + /** + * Utility for parsing errors returned by the Neynar API servers. Returns true + * if the given error is caused by an error response from the server, and + * narrows the type of `error` accordingly. + */ + public static isApiErrorResponse( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + error: any + ): error is SetRequired, "response"> { + if (!(error instanceof AxiosError)) return false; + return ( + error.response?.data !== undefined && "message" in error.response.data + ); + } + + // ============ v1 APIs ============ + + // ------------ User ------------ + + /** + * A list of users in reverse chronological order based on sign up. + * See [Neynar documentation](https://docs.neynar.com/reference/recent-users-v1) + * + */ + public async fetchRecentUsers(options?: { + viewerFid?: number; + limit?: number; + cursor?: string; + }): Promise { + const response = await this.apis.userV1.recentUsers({ + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + /** + * Fetch all likes by a given user. + * See [Neynar documentation](https://docs.neynar.com/reference/user-cast-likes-v1) + * + */ + public async fetchAllCastsLikedByUser( + fid: number, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + const response = await this.apis.userV1.userCastLikes({ + fid: fid, + viewerFid: options?.viewerFid, + limit: options?.limit, + cursor: options?.cursor, + }); + + return response.data; + } + + /** + * Gets the specified user via their FID (if found). + * See [Neynar documentation](https://docs.neynar.com/reference/user-v1) + * + */ + public async lookupUserByFid( + fid: number, + viewerFid?: number + ): Promise { + try { + const response = await this.apis.userV1.user({ fid, viewerFid }); + return response.data.result.user; + } catch (error) { + if (NeynarAPIClient.isApiErrorResponse(error)) { + if (error.response.status === 404) return null; + } + throw error; + } + } + + /** + * Gets the specified user via their username (if found). + * See [Neynar documentation](https://docs.neynar.com/reference/user-by-username-v1) + * + */ + public async lookupUserByUsername( + username: string, + viewerFid?: number + ): Promise { + const response = await this.apis.userV1.userByUsername({ + username, + viewerFid, + }); + // result.user is undefined if not found + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + return response.data.result.user ?? null; + } + + /** + * Gets the custody address for the specified user via their username (if found). + * See [Neynar documentation](https://docs.neynar.com/reference/custody-address-v1) + * + */ + public async fetchCustodyAddressForUser(fid: number): Promise { + const response = await this.apis.userV1.custodyAddress({ fid }); + return response.data.result.custodyAddress; + } + + // ------------ Cast ------------ + + /** + * Fetches a single cast by its hash. + * See [Neynar documentation](https://docs.neynar.com/reference/cast-v1) + * + */ + public async lookUpCastByHash( + hash: string, + options?: { viewerFid?: number } + ): Promise { + const response = await this.apis.castV1.cast({ + hash, + viewerFid: options?.viewerFid, + }); + return response.data.result.cast; + } + + /** + * Gets all casts, including root cast and all replies for a given thread hash. No limit the depth of replies. + * See [Neynar documentation](https://docs.neynar.com/reference/all-casts-in-thread-v1) + * Note that the parent provided by the caller is included in the response. + * + */ + public async fetchAllCastsInThread( + threadParent: CastV1 | { hash: string }, + viewerFid?: number + ): Promise { + const response = await this.apis.castV1.allCastsInThread({ + threadHash: threadParent.hash, + viewerFid: viewerFid, + }); + return response.data.result.casts; + } + + /** + * Gets all casts (including replies and recasts) created by the specified user. + * See [Neynar documentation](https://docs.neynar.com/reference/casts-v1) + * + */ + public async fetchAllCastsCreatedByUser( + fid: number, + options?: { + parentUrl?: string; + viewerFid?: number; + limit?: number; + cursor?: string; + } + ): Promise { + const response = await this.apis.castV1.casts({ + fid: fid, + viewerFid: options?.viewerFid, + parentUrl: options?.parentUrl, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + /** + * Gets recent casts created by the specified user. + * See [Neynar documentation](https://docs.neynar.com/reference/recent-casts-v1) + * + */ + public async fetchRecentCasts(options?: { + viewerFid?: number; + limit?: number; + cursor?: string; + }): Promise { + const response = await this.apis.castV1.recentCasts({ + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + // ------------ Verification ------------ + + /** + * Gets all known verifications of a user. + * See [Neynar documentation](https://docs.neynar.com/reference/verifications-v1) + * + */ + public async fetchUserVerifications( + fid: number + ): Promise { + const response = await this.apis.verificationV1.verifications({ fid }); + return response.data.result; + } + + /** + * Checks if a given Ethereum address has a Farcaster user associated with it. + * Note: if an address is associated with multiple users, the API will return + * the user who most recently published a verification with the address + * (based on when Warpcast received the proof, not a self-reported timestamp). + * See [Neynar documentation](https://docs.neynar.com/reference/user-by-verification-v1) + * + */ + public async lookupUserByVerification(address: string): Promise { + try { + const response = await this.apis.verificationV1.userByVerification({ + address, + }); + return response.data.result.user; + } catch (error) { + if (NeynarAPIClient.isApiErrorResponse(error)) { + const status = error.response.status; + if (status === 404) { + return null; + } + } + throw error; + } + } + + // ------------ Notifications ------------ + + /** + * Gets a list of mentions and replies to the user’s casts in reverse chronological order. + * See [Neynar documentation](https://docs.neynar.com/reference/mentions-and-replies-v1) + * + */ + public async fetchMentionAndReplyNotifications( + fid: number, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + const response = await this.apis.notificationsV1.mentionsAndReplies({ + fid: fid, + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + /** + * Get a list of likes and recasts to the users’s casts in reverse chronological order. + * See [Neynar documentation](https://docs.neynar.com/reference/reactions-and-recasts-v1) + * + */ + public async fetchUserLikesAndRecasts( + fid: number, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + const response = await this.apis.notificationsV1.reactionsAndRecasts({ + fid: fid, + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + // ------------ Reactions ------------ + + /** + * Lists a given cast's likes. + * See [Neynar documentation](https://docs.neynar.com/reference/cast-likes-v1) + * + */ + public async fetchCastLikes( + castOrCastHash: Cast | string, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + let castHash: string; + if (typeof castOrCastHash === "string") { + castHash = castOrCastHash; + } else { + castHash = castOrCastHash.hash; + } + + const response = await this.apis.reactionsV1.castLikes({ + castHash: castHash, + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + /** + * Get All Reactions For a Cast. + * See [Neynar documentation](https://docs.neynar.com/reference/cast-reactions-v1) + * + */ + public async fetchCastReactions( + castOrCastHash: Cast | string, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + let castHash: string; + if (typeof castOrCastHash === "string") { + castHash = castOrCastHash; + } else { + castHash = castOrCastHash.hash; + } + + const response = await this.apis.reactionsV1.castReactions({ + castHash: castHash, + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + /** + * Get the list of users who have recasted a specific cast. + * See [Neynar documentation](https://docs.neynar.com/reference/cast-recasters-v1) + * + */ + public async fetchRecasters( + castOrCastHash: Cast | string, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + let castHash: string; + if (typeof castOrCastHash === "string") { + castHash = castOrCastHash; + } else { + castHash = castOrCastHash.hash; + } + + const response = await this.apis.reactionsV1.castRecasters({ + castHash: castHash, + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + // ------------ Follows ------------ + + /** + * Get all users that follow the specified user. + * See [Neynar documentation](https://docs.neynar.com/reference/followers-v1) + * + */ + public async fetchUserFollowers( + fid: number, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + const response = await this.apis.followsV1.followers({ + fid, + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + /** + * Get all users the specified user is following. + * See [Neynar documentation](https://docs.neynar.com/reference/following-v1) + * + */ + public async fetchUserFollowing( + fid: number, + options?: { viewerFid?: number; limit?: number; cursor?: string } + ): Promise { + const response = await this.apis.followsV1.following({ + fid, + viewerFid: options?.viewerFid, + cursor: options?.cursor, + limit: options?.limit, + }); + + return response.data; + } + + // ============ v2 APIs ============ + + // ------------ Signer ------------ + + /** + * Creates a Signer. + * See [Neynar documentation](https://docs.neynar.com/reference/create-signer) + * + */ + public async createSigner(): Promise { + const response = await this.apis.signer.createSigner(); + return response.data; + } + + /** + * Fetches an existing Signer. + * See [Neynar documentation](https://docs.neynar.com/reference/signer) + * + */ + public async lookupSigner(signerUuid: string): Promise { + const response = await this.apis.signer.signer({ signerUuid }); + return response.data; + } + + /** + * Registers a Signer with an fid. + * See [Neynar documentation](https://docs.neynar.com/reference/register-signed-key) + * + */ + public async registerSigner( + signerUuid: string, + fid: number, + deadline: number, + signature: string + ): Promise { + const request: SignerApiRegisterSignedKeyRequest = { + registerSignerKeyReqBody: { + signer_uuid: signerUuid, + app_fid: fid, + deadline: deadline, + signature: signature, + }, + }; + const response = await this.apis.signer.registerSignedKey(request); + return response.data; + } + + // ------------ User ------------ + + /** + * Removes verification for an eth address for the user. + * See [Neynar documentation](https://docs.neynar.com/reference/remove-verification) + * + */ + public async removeVerification( + signerUuid: string, + address: string + ): Promise { + const request: UserApiRemoveVerificationRequest = { + removeVerificationReqBody: { + signer_uuid: signerUuid, + address, + }, + }; + + const response = await this.apis.user.farcasterUserVerificationDelete( + request + ); + return response.data; + } + + /** + * Adds verification for an eth address for the user + * See [Neynar documentation](https://docs.neynar.com/reference/add-verification) + * + */ + public async addVerification( + signerUuid: string, + address: string, + block_hash: string, + eth_signature: string + ): Promise { + const request: UserApiAddVerificationRequest = { + addVerificationReqBody: { + signer_uuid: signerUuid, + address, + block_hash, + eth_signature, + }, + }; + + const response = await this.apis.user.farcasterUserVerificationPost( + request + ); + return response.data; + } + + /** + * Follow a user. + * See [Neynar documentation](https://docs.neynar.com/reference/follow-user) + * + */ + + public async followUser( + signerUuid: string, + targetFid: number[] + ): Promise { + const request: UserApiFollowRequest = { + followReqBody: { + signer_uuid: signerUuid, + target_fids: targetFid, + }, + }; + + const response = await this.apis.user.followUser(request); + return response.data; + } + + /** + * Unfollow a user + * See [Neynar documentation](https://docs.neynar.com/reference/unfollow-user) + * + */ + public async unfollowUser( + signerUuid: string, + targetFid: number[] + ): Promise { + const request: UserApiFollowRequest = { + followReqBody: { + signer_uuid: signerUuid, + target_fids: targetFid, + }, + }; + const response = await this.apis.user.unfollowUser(request); + return response.data; + } + + /** + * Update user profile + * See [Neynar documentation](https://docs.neynar.com/reference/update-user) + * + */ + public async updateUserProfile( + signerUuid: string, + options?: { + bio?: string; + pfp_url?: string; + url?: string; + username?: string; + display_name?: string; + } + ): Promise { + const request: UserApiUpdateUserRequest = { + updateUserReqBody: { + signer_uuid: signerUuid, + bio: options?.bio, + pfp_url: options?.pfp_url, + url: options?.url, + username: options?.username, + display_name: options?.display_name, + }, + }; + + const response = await this.apis.user.updateUser(request); + return response.data; + } + + /** + * Fetches information about multiple users based on FIDs + * See [Neynar documentation](https://docs.neynar.com/reference/user-bulk) + * + */ + public async fetchUsersInBulk( + fids: string, + viewerFid?: number + ): Promise { + const response = await this.apis.user.userBulk({ fids, viewerFid }); + return response.data; + } + + /** + * Search User + * See [Neynar documentation](https://docs.neynar.com/reference/user-search) + */ + public async searchUser( + q: string, + viewerFid: number + ): Promise { + const response = await this.apis.user.userSearch({ q, viewerFid }); + return response.data; + } + + // ------------ Cast ------------ + + /** + * Gets information about an individual cast by passing in a Warpcast web URL or cast hash + * See [Neynar documentation](https://docs.neynar.com/reference/cast) + * + */ + public async lookUpCastByHashOrWarpcastUrl( + castHashOrUrl: string, + type: CastParamType + ): Promise { + try { + const response = await this.apis.cast.cast({ + type, + identifier: castHashOrUrl, + }); + return response.data.cast; + } catch (error) { + if (NeynarAPIClient.isApiErrorResponse(error)) { + const status = error.response.status; + if (status === 404) { + return null; + } + } + throw error; + } + } + + /** + * Gets information about an array of casts. + * See [Neynar documentation](https://docs.neynar.com/reference/casts) + * + */ + public async fetchBulkCastsByHash( + castHashes: string[] + ): Promise { + try { + const response = await this.apis.cast.casts({ + getCastsReqBody: { + casts: castHashes.map((hash) => ({ hash })), + }, + }); + return response.data.result.casts; + } catch (error) { + if (NeynarAPIClient.isApiErrorResponse(error)) { + const status = error.response.status; + if (status === 404) { + return null; + } + } + throw error; + } + } + + /** + * Publishes a cast for the currently authenticated user. + * See [Neynar documentation](https://docs.neynar.com/reference/post-cast) + * + */ + public async publishCast( + signerUuid: string, + text: string, + options?: { embeds?: EmbeddedCast[]; replyTo?: string } + ): Promise { + const request: CastApiPostCastRequest = { + postCastReqBody: { + signer_uuid: signerUuid, + text: text, + embeds: options?.embeds, + parent: options?.replyTo, + }, + }; + const response = await this.apis.cast.postCast(request); + return response.data.cast; + } + + /** + * Delete a cast. + * See [Neynar documentation](https://docs.neynar.com/reference/delete-cast) + * + */ + public async deleteCast( + signerUuid: string, + castOrCastHash: Cast | string + ): Promise { + let castHash: string; + if (typeof castOrCastHash === "string") { + castHash = castOrCastHash; + } else { + castHash = castOrCastHash.hash; + } + const body: DeleteCastReqBody = { + signer_uuid: signerUuid, + target_hash: castHash, + }; + const response = await this.apis.cast.deleteCast({ + deleteCastReqBody: body, + }); + return response.data; + } + + // ------------ Feed ------------ + + /** + * Get reverse chronological feed page for a user based on their follow graph. + * See [Neynar documentation](https://docs.neynar.com/reference/feed) + * + */ + public async fetchFeedPage( + fid: number, + options?: { + feedType?: FeedType; + filterType?: FilterType; + fids?: string; + parentUrl?: string; + limit?: number; + cursor?: string; + withRecasts?: boolean; + } + ): Promise { + const response = await this.apis.feed.feed({ + fid, + feedType: options?.feedType, + filterType: options?.filterType, + fids: options?.fids, + parentUrl: options?.parentUrl, + cursor: options?.cursor, + limit: options?.limit, + withRecasts: options?.withRecasts, + }); + return response.data; + } + + // ------------ Reaction ------------ + + /** + * React to a cast. + * See [Neynar documentation](https://docs.neynar.com/reference/post-reaction) + * + */ + public async reactToCast( + signerUuid: string, + reaction: ReactionType, + castOrCastHash: Cast | string + ): Promise { + let castHash: string; + if (typeof castOrCastHash === "string") { + castHash = castOrCastHash; + } else { + castHash = castOrCastHash.hash; + } + const body: ReactionReqBody = { + signer_uuid: signerUuid, + reaction_type: reaction, + target: castHash, + }; + const response = await this.apis.reaction.postReaction({ + reactionReqBody: body, + }); + return response.data; + } + + /** + * Remove a reaction to a cast. See [Neynar documentation](https://docs.neynar.com/reference/delete-reaction) + */ + public async removeReactionFromCast( + signerUuid: string, + reaction: ReactionType, + castOrCastHash: Cast | string + ): Promise { + let castHash: string; + if (typeof castOrCastHash === "string") { + castHash = castOrCastHash; + } else { + castHash = castOrCastHash.hash; + } + const body: ReactionReqBody = { + signer_uuid: signerUuid, + reaction_type: reaction, + target: castHash, + }; + const response = await this.apis.reaction.deleteReaction({ + reactionReqBody: body, + }); + return response.data; + } + + // ------------ Notifications ------------ + + /** + * Returns a list of notifications for a specific FID in reverse chronological order. + * See [Neynar documentation](https://docs.neynar.com/reference/notifications) + * + */ + public async fetchAllNotifications( + fid: number, + options?: { cursor?: string; limit?: number } + ): Promise { + const response = await this.apis.notifications.notifications({ + fid, + cursor: options?.cursor, + limit: options?.limit, + }); + return response.data; + } + + // ------------ Follows ------------ + + /** + * Returns a list of relevant followers for a specific FID. + * See [Neynar documentation](https://docs.neynar.com/reference/relevant-followers) + * + */ + public async fetchRelaventFollowers( + targetFid: number, + viewerFid: number + ): Promise { + const response = await this.apis.follows.relevantFollowers({ + targetFid, + viewerFid, + }); + return response.data; + } + + // ------------ Recommendation ------------ + + /** + * Fetches all mint actions relevant for a contract address (and optionally tokenId for ERC1155s) given a user's ethereum address + * See [Neynar documentation](https://docs.neynar.com/reference/fetch-relevant-mints) + * + */ + public async fetchRelevantMints( + address: string, + contractAddress: string, + tokenId?: string + ): Promise { + const response = await this.apis.nft.fetchRelevantMints({ + address, + contractAddress, + tokenId, + }); + return response.data; + } } diff --git a/src/neynar-api/neynar-v2-api/neynar-api-v2-client.ts b/src/neynar-api/neynar-v2-api/neynar-api-v2-client.ts index fd95929d..7b05d693 100644 --- a/src/neynar-api/neynar-v2-api/neynar-api-v2-client.ts +++ b/src/neynar-api/neynar-v2-api/neynar-api-v2-client.ts @@ -305,8 +305,8 @@ export class NeynarV2APIClient { } /** - * Fetches information about multiple users based on FIDs - * See [Neynar documentation](https://docs.neynar.com/reference/user-bulk) + * Search User + * See [Neynar documentation](https://docs.neynar.com/reference/user-search) */ public async searchUser( q: string, @@ -415,7 +415,39 @@ export class NeynarV2APIClient { return response.data; } - // ------------ Rection ------------ + // ------------ Feed ------------ + + /** + * Get reverse chronological feed page for a user based on their follow graph. + * See [Neynar documentation](https://docs.neynar.com/reference/feed) + * + */ + public async fetchFeedPage( + fid: number, + options?: { + feedType?: FeedType; + filterType?: FilterType; + fids?: string; + parentUrl?: string; + limit?: number; + cursor?: string; + withRecasts?: boolean; + } + ): Promise { + const response = await this.apis.feed.feed({ + fid, + feedType: options?.feedType, + filterType: options?.filterType, + fids: options?.fids, + parentUrl: options?.parentUrl, + cursor: options?.cursor, + limit: options?.limit, + withRecasts: options?.withRecasts, + }); + return response.data; + } + + // ------------ Reaction ------------ /** * React to a cast. @@ -469,38 +501,6 @@ export class NeynarV2APIClient { return response.data; } - // ------------ Feed ------------ - - /** - * Get reverse chronological feed page for a user based on their follow graph. - * See [Neynar documentation](https://docs.neynar.com/reference/feed) - * - */ - public async fetchFeedPage( - fid: number, - options?: { - feedType?: FeedType; - filterType?: FilterType; - fids?: string; - parentUrl?: string; - limit?: number; - cursor?: string; - withRecasts?: boolean; - } - ): Promise { - const response = await this.apis.feed.feed({ - fid, - feedType: options?.feedType, - filterType: options?.filterType, - fids: options?.fids, - parentUrl: options?.parentUrl, - cursor: options?.cursor, - limit: options?.limit, - withRecasts: options?.withRecasts, - }); - return response.data; - } - // ------------ Notifications ------------ /**