@standard-crypto/farcaster-js-hub-rest
Version:
A tool for interacting with the REST API of any Farcaster hub.
904 lines • 34.4 kB
JavaScript
"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.HubRestAPIClient = exports.DEFAULT_HUB_URL = void 0;
const axios_1 = __importStar(require("axios"));
const logger_js_1 = require("./logger.js");
const index_js_1 = require("./openapi/index.js");
const core_1 = require("@farcaster/core");
const utils_js_1 = require("./utils.js");
exports.DEFAULT_HUB_URL = 'https://nemes.farcaster.xyz:2281';
class HubRestAPIClient {
logger;
apis;
/**
* Instantiates a HubRestAPIClient
*/
constructor({ axiosInstance, hubUrl = exports.DEFAULT_HUB_URL, logger = logger_js_1.silentLogger, } = {}) {
this.logger = logger;
if (axiosInstance === undefined) {
axiosInstance = axios_1.default.create();
}
axiosInstance.defaults.decompress = true;
axiosInstance.interceptors.response.use((response) => response, (error) => {
if (HubRestAPIClient.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: hubUrl });
this.apis = {
casts: new index_js_1.CastsApi(config, undefined, axiosInstance),
info: new index_js_1.InfoApi(config, undefined, axiosInstance),
links: new index_js_1.LinksApi(config, undefined, axiosInstance),
reactions: new index_js_1.ReactionsApi(config, undefined, axiosInstance),
userData: new index_js_1.UserDataApi(config, undefined, axiosInstance),
fids: new index_js_1.FIDsApi(config, undefined, axiosInstance),
storage: new index_js_1.StorageApi(config, undefined, axiosInstance),
submitMessage: new index_js_1.SubmitMessageApi(config, undefined, axiosInstance),
usernames: new index_js_1.UsernamesApi(config, undefined, axiosInstance),
verifications: new index_js_1.VerificationsApi(config, undefined, axiosInstance),
onChainEvents: new index_js_1.OnChainEventsApi(config, undefined, axiosInstance),
hubEvents: new index_js_1.HubEventsApi(config, undefined, axiosInstance),
validateMessage: new index_js_1.ValidateMessageApi(config, undefined, axiosInstance),
};
}
/**
* Takes in a hex private key or Signer object and returns a Signer object.
* If the input is a hex private key, it will be converted to a Signer object.
*
* @param signer The signer's hex private key or Signer object
*/
formatSigner(signer) {
if (typeof signer === 'string') {
return (0, utils_js_1.hexToSigner)(signer);
}
return signer;
}
/**
* Get the Hub's info.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/info.html#info)
*/
async getHubInfo({ includeDbStats = false, } = {}) {
const response = await this.apis.info.getInfo({ dbstats: includeDbStats });
return response.data;
}
/**
* Submits a Cast.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param cast The cast to submit
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async submitCast(cast, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
const castAdd = {
text: cast.text,
embeds: cast.embeds ?? [],
embedsDeprecated: cast.embedsDeprecated ?? [],
mentions: cast.mentions ?? [],
mentionsPositions: cast.mentionsPositions ?? [],
parentUrl: cast.parentUrl,
};
if (cast.parentCastId !== undefined) {
const parentHashBytes = (0, core_1.hexStringToBytes)(cast.parentCastId.hash);
const parentFid = cast.parentCastId.fid;
parentHashBytes.match(bytes => {
castAdd.parentCastId = {
fid: parentFid,
hash: bytes,
};
}, (err) => {
throw err;
});
}
const msg = await (0, core_1.makeCastAdd)(castAdd, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Deletes a Cast.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param castHash The hash of the cast to delete
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async removeCast(castHash, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
const targetHashBytes = (0, core_1.hexStringToBytes)(castHash);
if (targetHashBytes.isErr()) {
throw targetHashBytes.error;
}
const castToRemove = { targetHash: targetHashBytes.value };
const msg = await (0, core_1.makeCastRemove)(castToRemove, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Submits a Link. Used to follow users.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param link The link to submit
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async submitLink(link, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
const msg = await (0, core_1.makeLinkAdd)(link, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Follows a User. Wraps submitLink.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param targetFid The FID of the user to follow
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async followUser(targetFid, fid, signer) {
return await this.submitLink({ type: 'follow', targetFid: targetFid }, fid, this.formatSigner(signer));
}
/**
* Removes a Link. Used to unfollow users
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param link The link to remove
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async removeLink(link, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
const msg = await (0, core_1.makeLinkRemove)(link, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Un-follows a User. Wraps removeLink.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param targetFid The FID of the user to unfollow
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async unfollowUser(targetFid, fid, signer) {
return await this.removeLink({ type: 'follow', targetFid: targetFid }, fid, this.formatSigner(signer));
}
/**
* Submits a Reaction. Used to like or recast.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param reaction The reaction to submit
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async submitReaction(reaction, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
let castId;
let targetUrl;
if ('hash' in reaction.target && 'fid' in reaction.target) {
const targetHashBytes = (0, core_1.hexStringToBytes)(reaction.target.hash);
if (targetHashBytes.isErr()) {
throw targetHashBytes.error;
}
castId = { fid: reaction.target.fid, hash: targetHashBytes.value };
}
else {
targetUrl = reaction.target.url;
}
const reactionAdd = {
type: reaction.type === 'like'
? core_1.ReactionType.LIKE
: core_1.ReactionType.RECAST,
targetCastId: castId,
targetUrl: targetUrl,
};
const msg = await (0, core_1.makeReactionAdd)(reactionAdd, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Removes a Reaction. Used to un-like or un-recast.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param reaction The reaction to remove
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async removeReaction(reaction, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
let castId;
let targetUrl;
if ('hash' in reaction.target && 'fid' in reaction.target) {
const targetHashBytes = (0, core_1.hexStringToBytes)(reaction.target.hash);
if (targetHashBytes.isErr()) {
throw targetHashBytes.error;
}
castId = { fid: reaction.target.fid, hash: targetHashBytes.value };
}
else {
targetUrl = reaction.target.url;
}
const reactionRemove = {
type: reaction.type === 'like'
? core_1.ReactionType.LIKE
: core_1.ReactionType.RECAST,
targetCastId: castId,
targetUrl: targetUrl,
};
const msg = await (0, core_1.makeReactionRemove)(reactionRemove, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Submits a Verification.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param verification The verification to submit
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async submitVerification(verification, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
const verificationSigner = (0, utils_js_1.eip712SignerFromMnemonicOrPrivateKey)(verification.verifiedAddressMnemonicOrPrivateKey);
const addressBytes = await verificationSigner.getSignerKey();
if (addressBytes.isErr()) {
throw addressBytes.error;
}
const latestBlockHashBytes = (0, core_1.hexStringToBytes)(await (0, utils_js_1.getLatestBlock)());
if (latestBlockHashBytes.isErr()) {
throw latestBlockHashBytes.error;
}
const claim = await (0, core_1.makeVerificationAddressClaim)(fid, addressBytes.value, core_1.FarcasterNetwork[verification.network], latestBlockHashBytes.value, core_1.Protocol.ETHEREUM);
if (claim.isErr()) {
throw claim.error;
}
const ethSignResult = await verificationSigner.signVerificationEthAddressClaim(claim.value);
if (ethSignResult.isErr()) {
throw ethSignResult.error;
}
const verificationAdd = {
address: addressBytes.value,
claimSignature: ethSignResult.value,
blockHash: latestBlockHashBytes.value,
verificationType: verification.verificationType === 'EOA' ? 0 : 1,
chainId: verification.chainId,
protocol: core_1.Protocol.ETHEREUM,
};
const msg = await (0, core_1.makeVerificationAddEthAddress)(verificationAdd, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Removes a Verification.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/submitmessage.html#submitmessage)
* @param address The address to remove the verification for
* @param fid The FID of the signer
* @param signer The signer's hex private key or Signer object
*/
async removeVerification(address, fid, signer) {
const dataOptions = {
fid: fid,
network: 1,
};
const addressBytes = (0, core_1.hexStringToBytes)(address);
if (addressBytes.isErr()) {
throw addressBytes.error;
}
const msg = await (0, core_1.makeVerificationRemove)({ address: addressBytes.value, protocol: core_1.Protocol.ETHEREUM }, dataOptions, this.formatSigner(signer));
if (msg.isErr()) {
throw msg.error;
}
const messageBytes = Buffer.from(core_1.Message.encode(msg.value).finish());
const response = await this.apis.submitMessage.submitMessage({
body: messageBytes,
});
return response.data;
}
/**
* Get a cast by its FID and Hash.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/casts.html#castbyid)
* @param fid The FID of the cast's creator
* @param hash The hash of the cast
*/
async getCastById({ fid, hash }) {
try {
const response = await this.apis.casts.getCastById({ fid, hash });
return response.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Fetch all casts for authored by an FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/casts.html#castsbyfid)
* @param fid The FID of the cast's creator
* @param options
*/
async *listCastsByFid(fid, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.casts.listCastsByFid({
fid,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Fetch all casts that mention an FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/casts.html#castsbymention)
* @param fid The FID that is mentioned in a cast
* @param options
*/
async *listCastsByMention(fid, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.casts.listCastsByMention({
...options,
fid,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Fetch all casts by parent cast's FID and Hash OR by the parent's URL.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/casts.html#castsbyparent)
* @param parent
* @param options
*/
async *listCastsByParent(parent, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.casts.listCastsByParent({
...parent,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get a reaction by its created FID and target Cast.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/reactions.html#reactionbyid)
* @param id The source and target of the reaction, and the reaction type
* @returns
*/
async getReactionById(id) {
try {
const result = await this.apis.reactions.getReactionById(id);
return result.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Get all reactions by an FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/reactions.html#reactionsbyfid)
* @param fid The FID of the reaction's creator
* @param reactionType The type of reaction
* @param options
*/
async *listReactionsByFid(fid, reactionType, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.reactions.listReactionsByFid({
fid,
reactionType,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get all reactions to a cast.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/reactions.html#reactionsbycast)
* @param targetFid The FID of the cast's creator
* @param targetHash The hash of the cast
* @param reactionType The type of reaction
* @param options
*/
async *listReactionsByCast(targetFid, targetHash, reactionType, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.reactions.listReactionsByCast({
targetFid,
targetHash,
reactionType,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get all reactions to cast's target URL.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/reactions.html#reactionsbytarget)
* @param url The URL of the parent cast
* @param reactionType The type of reaction
* @param options
*/
async *listReactionsByTarget(url, reactionType, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.reactions.listReactionsByTarget({
url,
reactionType,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get a link by its FID and target FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/links.html#linkbyid)
* @param sourceFid The FID of the link's creator
* @param targetFid The FID of the link's target
*/
async getLinkById(sourceFid, targetFid) {
try {
const result = await this.apis.links.getLinkById({
fid: sourceFid,
targetFid,
linkType: index_js_1.LinkType.Follow,
});
return result.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Get all links from a source FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/links.html#linksbyfid)
* @param fid The FID of the link's originator
* @param options
*/
async *listLinksByFid(fid, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.links.listLinksByFid({
fid,
linkType: index_js_1.LinkType.Follow,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get all links to a target FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/links.html#linksbytargetfid)
* @param targetFid
* @param options
*/
async *listLinksByTargetFid(targetFid, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.links.listLinksByTargetFid({
targetFid,
linkType: index_js_1.LinkType.Follow,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get a specific type of UserData for a FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/userdata.html#userdatabyfid)
* @param fid The FID that's being requested
* @param userDataType The type of UserData requested
* @returns
*/
async getSpecificUserDataByFid(fid, userDataType) {
try {
const response = await this.apis.userData.getUserDataByFid({
fid,
userDataType,
});
return response.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Get all UserData for a FID. Returns an empty iterator if FID has no user data or does not exist.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/userdata.html#userdatabyfid)
* @param fid The FID that's being requested
* @returns
*/
async *listAllUserDataByFid(fid, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.userData.getUserDataByFid({
fid,
...options,
pageToken,
});
// yield current page
const data = response.data;
yield* data.messages;
// prep for next page
if (data.nextPageToken === '') {
break;
}
pageToken = data.nextPageToken;
}
}
/**
* Get a list of all the FIDs.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/fids.html#fids)
* @param options
*/
async *listFids(options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.fids.listFids({
...options,
pageToken,
});
// yield current page
yield* response.data.fids;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get an FID's storage limits.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/storagelimits.html#storagelimitsbyfid)
* @param fid The FID that's being requested
* @returns
*/
async getStorageLimitsByFid(fid) {
const response = await this.apis.storage.getStorageLimitsByFid({ fid });
return response.data.limits;
}
/**
* Get an proof for a username by the Farcaster username.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/usernameproof.html#usernameproofbyname)
* @param username The Farcaster username or ENS address
* @returns
*/
async getUsernameProof(username) {
try {
const response = await this.apis.usernames.getUsernameProof({
name: username,
});
return response.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Get a list of proofs provided by an FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/usernameproof.html#usernameproofsbyfid)
* @param fid The FID being requested
* @returns
*/
async listUsernameProofsForFid(fid) {
const response = await this.apis.usernames.listUsernameProofsByFid({ fid });
return response.data.proofs;
}
/**
* Get a list of verifications provided by an FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/verification.html)
* @param fid The FID being requested
* @param options The optional ETH address to filter by
*/
async *listVerificationsByFid(fid, options) {
let pageToken;
while (true) {
// fetch one page
const response = await this.apis.verifications.listVerificationsByFid({
fid,
...options,
pageToken,
});
// yield current page
yield* response.data.messages;
// prep for next page
if (response.data.nextPageToken === '') {
break;
}
pageToken = response.data.nextPageToken;
}
}
/**
* Get a list of on-chain events by an FID.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/onchain.html#onchaineventsbyfid)
* @param fid The FID being requested
* @param eventType The event type being requested
* @returns
*/
async listOnChainEventsByFid(fid, eventType) {
const response = await this.apis.onChainEvents.listOnChainEventsByFid({
fid,
eventType,
});
return response.data.events;
}
/**
* Get a specific on-chain signer event by FID and signer.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/onchain.html#onchainsignersbyfid)
* @param fid The FID being requested
* @param signer The key of signer
* @returns
*/
async getOnChainSignerEventBySigner(fid, signer) {
try {
const response = await this.apis.onChainEvents.listOnChainSignersByFid({
fid,
signer,
});
return response.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Get a specific on-chain ID registration event by address.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/onchain.html#onchainidregistryeventbyaddress)
* @param address The ETH address being requested
* @returns
*/
async getOnChainIdRegistryEventByAddress(address) {
try {
const response = await this.apis.onChainEvents.getOnChainIdRegistrationByAddress({
address,
});
return response.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Get a hub event by its Id.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/events.html#eventbyid)
* @param eventId The Hub Id of the event
* @returns
*/
async getHubEventById(eventId) {
try {
const response = await this.apis.hubEvents.getEventById({
eventId,
});
return response.data;
}
catch (err) {
if (HubRestAPIClient.isApiErrorResponse(err) &&
err.response.data.errCode === 'not_found') {
return null;
}
throw err;
}
}
/**
* Get a page of Hub events.
* See [farcaster documentation](https://www.thehubble.xyz/docs/httpapi/events.html#events)
* @param fromEventId An optional Hub Id to start getting events from.
*/
async *listHubEvents(fromEventId) {
while (true) {
// fetch one page
const response = await this.apis.hubEvents.listEvents({
fromEventId,
});
// yield current page
if (response.data.events.length === 0) {
break;
}
yield* response.data.events;
// prep for next page
fromEventId = response.data.nextPageEventId;
}
}
/**
* Validate a signed protobuf-serialized message with the Hub.
* This can be used to verify that the hub will consider the message valid.
* Or to validate message that cannot be submitted (e.g. Frame actions).
* See [farcaster documentation](https://github.com/farcasterxyz/hub-monorepo/blob/main/apps/hubble/www/docs/docs/httpapi/message.md#validatemessage)
* @param encodedMessage A signed protobuf-serialized message to validate.
*/
async validateMessage(encodedMessage) {
let encodedMessageHex = encodedMessage;
if (encodedMessage.startsWith('0x')) {
encodedMessageHex = encodedMessage.slice(2);
}
const messageBytes = Buffer.from(encodedMessageHex, 'hex');
const response = await this.apis.validateMessage.validateMessage({ body: messageBytes });
return response.data;
}
/**
* Utility for parsing errors returned by a hub's REST API server. 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 && 'errCode' in error.response.data);
}
}
exports.HubRestAPIClient = HubRestAPIClient;
//# sourceMappingURL=hubRestApiClient.js.map