UNPKG

@standard-crypto/farcaster-js-neynar

Version:

A tool for interacting with Farcaster via Neynar APIs.

296 lines 11.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.NeynarV2APIClient = void 0; const index_js_1 = require("./openapi/index.js"); const axios_1 = __importStar(require("axios")); const logger_js_1 = require("../logger.js"); const utils_js_1 = require("../utils.js"); const BASE_PATH = 'https://api.neynar.com/v2'; class NeynarV2APIClient { logger; apis; /** * Instantiates a NeynarV1APIClient * * Note: A Wallet must be provided if the API client is to mint new AuthTokens */ constructor(apiKey, { logger = logger_js_1.silentLogger, axiosInstance, } = {}) { this.logger = logger; if (apiKey === '') { throw new Error('Attempt to use an authenticated API method without first providing an api key'); } if (axiosInstance === undefined) { axiosInstance = axios_1.default.create(); } axiosInstance.defaults.decompress = true; axiosInstance.interceptors.response.use((response) => response, (error) => { if (NeynarV2APIClient.isApiErrorResponse(error)) { const apiErrors = error.response.data; this.logger.warn(`API errors: ${JSON.stringify(apiErrors)}`); } throw error; }); const config = new index_js_1.Configuration({ basePath: BASE_PATH, apiKey: apiKey, }); this.apis = { signer: new index_js_1.SignerApi(config, undefined, axiosInstance), feed: new index_js_1.FeedApi(config, undefined, axiosInstance), cast: new index_js_1.CastApi(config, undefined, axiosInstance), user: new index_js_1.UserApi(config, undefined, axiosInstance), reaction: new index_js_1.ReactionApi(config, undefined, axiosInstance), follow: new index_js_1.FollowsApi(config, 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. */ static isApiErrorResponse( // eslint-disable-next-line @typescript-eslint/no-explicit-any error) { if (!(error instanceof axios_1.AxiosError)) return false; return (error.response?.data !== undefined && 'message' in error.response.data); } /** * Fetches an existing Signer. See [Neynar documentation](https://docs.neynar.com/reference/get-signer) * for more details. * */ async fetchSigner(signerUuid) { try { const response = await this.apis.signer.signer({ signerUuid }); return response.data; } catch (error) { if (NeynarV2APIClient.isApiErrorResponse(error)) { const status = error.response.status; if (status === 404) { return null; } } throw error; } } /** * Creates and registers a Signer for an fid. See Neynar documentation[1](https://docs.neynar.com/reference/create-signer),[2](https://docs.neynar.com/reference/register-app-fid) * for more details. */ async createSigner(developerMnemonic, deadline) { const custodyAddress = (0, utils_js_1.mnemonicToAddress)(developerMnemonic); const userResponse = await this.apis.user.lookupUserByCustodyAddress({ custodyAddress }); const developerFid = userResponse.data.user.fid; const createSignerResponse = await this.apis.signer.createSigner(); const signer = createSignerResponse.data; // default deadline is 24 hours const defaultDeadline = Math.floor(Date.now() / 1000) + 86400; // create signature const signature = await (0, utils_js_1.generateSignature)(signer.public_key, developerFid, developerMnemonic, deadline ?? defaultDeadline); const request = { registerSignerKeyReqBody: { signer_uuid: signer.signer_uuid, app_fid: developerFid, deadline: deadline ?? defaultDeadline, signature: signature, }, }; const response = await this.apis.signer.registerSignedKey(request); return response.data; } /** * Get reverse chronological feed for a user based on their follow graph. See [Neynar documentation](https://docs.neynar.com/reference/get-feed) */ async *fetchFeed(fid, options) { let cursor; while (true) { const response = await this.apis.feed.feed({ feedType: options?.feedType ?? 'following', filterType: options?.filterType, fid: fid, fids: options?.fids, parentUrl: options?.parentUrl, cursor: cursor, limit: options?.pageSize, }); // yield current page of casts yield* response.data.casts; // prep for next page if (response.data.next.cursor === null) { break; } cursor = response.data.next.cursor; } } /** * Gets information about an individual cast. See [Neynar documentation](https://docs.neynar.com/reference/get-cast) */ async fetchCast(castHash) { try { const response = await this.apis.cast.cast({ type: index_js_1.CastParamType.Hash, identifier: castHash, }); return response.data.cast; } catch (error) { if (NeynarV2APIClient.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/get-array-of-casts) */ async fetchCasts(castHashes) { try { const response = await this.apis.cast.casts({ casts: castHashes.join(','), }); return response.data.result.casts; } catch (error) { if (NeynarV2APIClient.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-a-cast) */ async publishCast(signerUuid, text, options) { const request = { 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-a-cast) */ async deleteCast(signerUuid, castHash) { const body = { signer_uuid: signerUuid, target_hash: castHash, }; await this.apis.cast.deleteCast({ deleteCastReqBody: body }); } /** * Search for Usernames. See [Neynar documentation](https://docs.neynar.com/reference/search-usernames) */ async searchUsernames(query, viewerFid) { const response = await this.apis.user.userSearch({ q: query, viewerFid: viewerFid, }); return response.data.result.users; } /** * Update User Profile. See [Neynar documentation](https://docs.neynar.com/reference/update-user-profile) */ async updateUserProfile(signerUuid, updates) { const response = await this.apis.user.updateUser({ updateUserReqBody: { signer_uuid: signerUuid, bio: updates.bio, pfp_url: updates.pfp_url, url: updates.url, username: updates.username, display_name: updates.display_name, }, }); return response.data; } /** * React to a cast. See [Neynar documentation](https://docs.neynar.com/reference/post-a-reaction) */ async reactToCast(signerUuid, reaction, castHash) { const body = { signer_uuid: signerUuid, reaction_type: reaction === 'like' ? index_js_1.ReactionType.Like : index_js_1.ReactionType.Recast, 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-a-reaction) */ async removeReactionToCast(signerUuid, reaction, castHash) { const body = { signer_uuid: signerUuid, reaction_type: reaction === 'like' ? index_js_1.ReactionType.Like : index_js_1.ReactionType.Recast, target: castHash, }; const response = await this.apis.reaction.deleteReaction({ reactionReqBody: body, }); return response.data; } /** * Follow users. See [Neynar documentation](https://docs.neynar.com/reference/follow-a-user) */ async followUsers(signerUuid, fids) { const body = { signer_uuid: signerUuid, target_fids: fids, }; const response = await this.apis.user.followUser({ followReqBody: body }); return response.data; } /** * Unfollow users. See [Neynar documentation](https://docs.neynar.com/reference/unfollow-a-user) */ async unfollowUsers(signerUuid, fids) { const body = { signer_uuid: signerUuid, target_fids: fids, }; const response = await this.apis.user.unfollowUser({ followReqBody: body, }); return response.data; } } exports.NeynarV2APIClient = NeynarV2APIClient; //# sourceMappingURL=NeynarV2APIClient.js.map