@coin-communities/sdk/react-query ships hook bindings around every operation in the SDK Reference, plus a queryKeys factory for cache invalidation and prefetching. The entry also re-exports configureApi and the api namespace, so it's the only import path most React apps need.

@tanstack/react-query (v5+) is a peer dependency.


Setup

bun add @coin-communities/sdk @tanstack/react-query

Wrap your app in a QueryClientProvider and configure the SDK once at boot:

import { configureApi } from '@coin-communities/sdk/react-query';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
 
configureApi({
  baseUrl: 'https://api.coin-communities.xyz',
  auth: () => getToken(),
});
 
const queryClient = new QueryClient();
 
export function App({ children }: { children: React.ReactNode }) {
  return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}

Conventions

  • Read operations (GET) are exposed as useXxx() hooks returning UseQueryResult<TData, TError>.
  • Write operations (POST / PUT / DELETE) are exposed as useXxx() hooks returning UseMutationResult<TData, TError, TVars>.
  • Hooks accept the standard React Query options object as their last argument (onSuccess, onError, select, enabled, …) — query/mutation keys and functions are managed for you.
  • Mutations that target a single resource (e.g. useRotateApiKey) take the resource id as the mutation variable rather than an options object.
  • Hooks scoped to a community (useMessages, usePostMessage, …) take tokenAddress as the first positional argument.

Hook catalog

Diagnostics

HookWrapsKind
useHealth(opts?)api.health()query
usePing(opts?)api.ping()query

Business — Auth

HookWrapsKind
useMe(opts?)api.me()query
useLogin(opts?)api.login()mutation (LoginRequest)
useLogout(opts?)api.logout()mutation (void)
useRegister(opts?)api.register()mutation (RegisterRequest)
useVerifyEmail(opts?)api.verifyEmail()mutation (VerifyEmailRequest)
useResendVerification(opts?)api.resendVerification()mutation (ResendVerificationRequest)
useForgotPassword(opts?)api.forgotPassword()mutation (ForgotPasswordRequest)
useResetPassword(opts?)api.resetPassword()mutation (ResetPasswordRequest)
useRefreshToken(opts?)api.refreshToken()mutation (RefreshTokenRequest)

Business — API Keys

HookWrapsKind
useApiKeys(opts?)api.getApiKeys()query
useCreateApiKey(opts?)api.createApiKey()mutation (CreateApiKeyRequest)
useRotateApiKey(opts?)api.rotateApiKey()mutation (id: string)
useRevokeApiKey(opts?)api.revokeApiKey()mutation (id: string)

Business — Callbacks

HookWrapsKind
useCallbacks(opts?)api.listCallbacks()query
useAddCallback(opts?)api.addCallback()mutation (AddCallbackRequest)
useRemoveCallback(opts?)api.removeCallback()mutation (id: string)

Business — Members

HookWrapsKind
useMembers(opts?)api.getMembers()query
useAddMember(opts?)api.addMember()mutation (AddMemberRequest)
useRemoveMember(opts?)api.deleteMember()mutation (id: string)

Business — Logs

HookWrapsKind
useLogs(params?, opts?)api.getLogs()query

Communities

HookWrapsKind
useCommunity(tokenAddress, opts?)api.getCommunity()query
useMessages(tokenAddress, query?, opts?)api.getMessages()query
useMessagesPublic(tokenAddress, query?, opts?)api.getMessagesPublic()query
usePostMessage(tokenAddress, opts?)api.postMessage()mutation (PostMessageRequest)
useLikeMessage(tokenAddress, opts?)api.likeMessage()mutation (messageId: string)
useUnlikeMessage(tokenAddress, opts?)api.unlikeMessage()mutation (messageId: string)
useLikeCount(tokenAddress, messageId, opts?)api.getLikeCount()query
useReportMessage(tokenAddress, opts?)api.reportMessage()mutation (ReportMessageRequest & { messageId })

Community media

HookWrapsKind
useUploadCommunityMedia(opts?)api.uploadCommunityMedia()mutation (UploadMediaRequest)
useMediaProviders(opts?)api.getMediaProviders()query

Chains & Feed

HookWrapsKind
useSupportedChains(opts?)api.getSupportedChains()query
useTopCommunities(query?, opts?)api.getTopCommunities()query
useFeed(opts?)api.getFeed()query
useFeedPublic(opts?)api.getFeedPublic()query

Users

HookWrapsKind
useUser(opts?)api.userMe()query
useUpdateUsername(opts?)api.updateUsername()mutation (UpdateUsernameRequest)
useUploadPfp(opts?)api.uploadPfp()mutation (UploadPfpRequest)

Wallets

HookWrapsKind
useWallets(opts?)api.getWallets()query
useWalletChallenge(opts?)api.walletChallenge()mutation (WalletChallengeRequest)
useLinkWallet(opts?)api.linkWallet()mutation (LinkWalletRequest)
useUnlinkWallet(opts?)api.unlinkWallet()mutation (id: string)

Twitter

HookWrapsKind
useTwitterAuthUrl(query, opts?)api.twitterAuthUrl()query
useTwitterCallback(opts?)api.twitterCallback()mutation (TwitterCallbackRequest)
useTwitterChallengeExchange(opts?)api.twitterChallengeExchange()mutation (TwitterChallengeExchangeRequest)

User Social Graph

HookWrapsKind
useUserProfile(userId, opts?)api.getUserProfile()query
useUserFollowers(userId, params?, opts?)api.getFollowers()query
useUserFollowing(userId, params?, opts?)api.getFollowing()query
useFollowUser(opts?)api.followUser()mutation (userId: string) — auto-invalidates profile + follow lists
useUnfollowUser(opts?)api.unfollowUser()mutation (userId: string) — auto-invalidates profile + follow lists

Message Replies

HookWrapsKind
useMessageReplies(tokenAddress, messageId, params?, opts?)api.getReplies()query
usePostReply(tokenAddress, messageId, opts?)api.postReply()mutation (PostMessageRequest) — auto-invalidates replies list

Community Members

HookWrapsKind
useCommunityMembers(tokenAddress, params?, opts?)api.getCommunityMembers()query
useWsTicket(tokenAddress, opts?)api.getWsTicket()mutation

Realtime

useCommunityEvents is not a query hook — it manages a WebSocket subscription via CommunityRealtimeClient. See the SDK Reference — Realtime section.

import { useCommunityEvents } from '@coin-communities/sdk/react-query';
import { api } from '@coin-communities/sdk';
 
useCommunityEvents(tokenAddress, {
  auth: async () => {
    const { data } = await api.getWsTicket({ path: { token_address: tokenAddress } });
    return data?.ticket ?? null;
  },
  onMessage: (event) => { /* new message */ },
  onLike:    (event) => { /* like update */ },
});

Business — API Key Origins

HookWrapsKind
useApiKeyOrigins(apiKeyId, opts?)api.listApiKeyOrigins()query
useAddApiKeyOrigin(opts?)api.addApiKeyOrigin()mutation (AddApiKeyOriginVariables) — auto-invalidates origins list
useRemoveApiKeyOrigin(opts?)api.removeApiKeyOrigin()mutation (RemoveApiKeyOriginVariables) — auto-invalidates origins list

queryKeys factory

queryKeys is a stable, typed object literal that exposes the cache key for every query the hooks use. Reach for it when you want to invalidate, prefetch, or read cache entries directly.

import { queryKeys } from '@coin-communities/sdk/react-query';
 
queryKeys.health;                                                    // ['health']
queryKeys.ping;                                                      // ['ping']
queryKeys.auth.me;                                                   // ['auth', 'me']
queryKeys.apiKeys.all;                                               // ['apiKeys']
queryKeys.apiKeys.list();                                            // ['apiKeys', 'list']
queryKeys.apiKeyOrigins.all;                                         // ['apiKeyOrigins']
queryKeys.apiKeyOrigins.list(apiKeyId);                              // ['apiKeyOrigins', apiKeyId, 'list']
queryKeys.callbacks.all;                                             // ['callbacks']
queryKeys.members.all;                                               // ['members']
queryKeys.logs.list({ from: '...' });                                // ['logs', 'list', params]
queryKeys.feed;                                                      // ['feed']
queryKeys.feedPublic;                                                // ['feed', 'public']
queryKeys.user.me;                                                   // ['user', 'me']
queryKeys.user.wallets;                                              // ['user', 'wallets']
queryKeys.user.profile(userId);                                      // ['user', userId, 'profile']
queryKeys.user.followers(userId, params?);                           // ['user', userId, 'followers', params]
queryKeys.user.following(userId, params?);                           // ['user', userId, 'following', params]
queryKeys.community.all;                                             // ['community']
queryKeys.community.detail(tokenAddress);                            // ['community', tokenAddress]
queryKeys.community.messages(tokenAddress, q);                       // ['community', tokenAddress, 'messages', q]
queryKeys.community.likeCount(tokenAddress, mid);                    // ['community', tokenAddress, 'messages', mid, 'likes']
queryKeys.community.replies(tokenAddress, messageId, params?);       // ['community', tokenAddress, 'messages', messageId, 'replies', params]
queryKeys.community.members(tokenAddress, params?);                  // ['community', tokenAddress, 'members', params]
queryKeys.media.providers;                                           // ['media', 'providers']
queryKeys.chains.supported;                                          // ['chains', 'supported']
queryKeys.twitter.authUrl(query);                                    // ['twitter', 'auth-url', query]

The *.all keys are deliberately broad — pass them to queryClient.invalidateQueries({ queryKey }) to refresh every variant of a resource at once.


Mutation variable types

AddApiKeyOriginVariables

Variables accepted by useAddApiKeyOrigin.

interface AddApiKeyOriginVariables {
  apiKeyId: string;
  origin: string;
}
  • apiKeyId (string) — the API key to add the origin to.
  • origin (string) — the origin to allow (e.g. 'https://app.example.com').

RemoveApiKeyOriginVariables

Variables accepted by useRemoveApiKeyOrigin.

interface RemoveApiKeyOriginVariables {
  apiKeyId: string;
  originId: string;
}
  • apiKeyId (string) — the API key that owns the origin entry.
  • originId (string) — the id of the ApiKeyOrigin entry to remove.

End-to-end example

A list-and-create flow that invalidates the list cache after a successful mutation:

import {
  queryKeys,
  useApiKeys,
  useCreateApiKey,
} from '@coin-communities/sdk/react-query';
import { useQueryClient } from '@tanstack/react-query';
 
export function ApiKeysList() {
  const qc = useQueryClient();
  const keys = useApiKeys();
  const create = useCreateApiKey({
    onSuccess: () => qc.invalidateQueries({ queryKey: queryKeys.apiKeys.all }),
  });
 
  if (keys.isLoading) return <p>Loading…</p>;
  if (keys.isError) return <p>Failed to load API keys.</p>;
 
  return (
    <>
      <ul>{keys.data?.map((k) => <li key={k.id}>{k.name}</li>)}</ul>
      <button
        type="button"
        disabled={create.isPending}
        onClick={() => create.mutate({ name: 'CI key' })}
      >
        Create key
      </button>
    </>
  );
}