@ic-reactor/core
@ic-reactor/core is the framework-agnostic foundation of IC Reactor. It gives
you the runtime building blocks for agent management, identity wiring,
TanStack Query integration, and typed canister interaction without depending on
React.
When to Use This Package
Section titled “When to Use This Package”- You need
ClientManager,Reactor, orDisplayReactorin non-React code. - You want to use IC Reactor in loaders, services, scripts, or framework adapters.
- You are building your own abstractions on top of IC Reactor’s runtime layer.
Installation
Section titled “Installation”pnpm add @ic-reactor/core @icp-sdk/core @tanstack/query-coreWhat’s Included
Section titled “What’s Included”Quick Start
Section titled “Quick Start”import { ClientManager, Reactor } from "@ic-reactor/core"import { QueryClient } from "@tanstack/query-core"import { idlFactory, type _SERVICE } from "./declarations/backend"
const queryClient = new QueryClient()const clientManager = new ClientManager({ queryClient,})
await clientManager.initialize()
const backend = new Reactor<_SERVICE>({ clientManager, idlFactory, name: "backend",})
const greeting = await backend.fetchQuery({ functionName: "greet", args: ["World"],})Retry Classification
Section titled “Retry Classification”Whether a failed call is worth retrying is decided by what failed, and most
failures are deterministic. @ic-reactor/core exports the classification
(@ic-reactor/react re-exports both functions):
import { reactorRetry, isRetryableReactorError } from "@ic-reactor/core"import { QueryClient } from "@tanstack/query-core"
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: reactorRetry } },})isRetryableReactorError(error) returns true only for a CallError whose
cause is an agent-level fault — a transport, protocol, or certificate failure,
or a SysTransient/SysUnknown replica rejection. A canister Err variant
(CanisterError), a ValidationError, a Candid encode failure (no request
was ever made), and a decode failure on the reply are never retryable:
identical input — or the identical reply — produces the identical failure.
Within agent errors the bias is toward retrying — an unrecognized kind, or a
rejection whose code cannot be read, still retries, so an unfamiliar
transport-level fault is never silently made fatal.
reactorRetry(failureCount, error) is a ready-made TanStack Query retry
predicate on top of it — up to 3 retries (4 attempts in total) for retryable
errors, none otherwise, and always false on the server so a failed prefetch
keeps failing fast. defineReactor in @ic-reactor/react already installs it
as the query default on the QueryClient it creates; a QueryClient you
construct yourself opts in as shown above.
Identity Attributes
Section titled “Identity Attributes”Identity attributes are not part of @ic-reactor/core.
IdentityAttributesManager in @ic-reactor/react requests
signed OpenID identity attributes through @icp-sdk/auth v8:
import { AuthenticationManager, IdentityAttributesManager, identityAttributeKeys,} from "@ic-reactor/react"
const authentication = new AuthenticationManager({ clientManager })const identityAttributes = new IdentityAttributesManager(authentication)
const result = await identityAttributes.requestOpenId({ // Pass the nonce as a callback: awaiting it first ends the user gesture // and the browser blocks the Internet Identity window. nonce: () => backend.callMethod({ functionName: "register_begin" }), openIdProvider: "microsoft", keys: ["email", "name"],})
await backend.callMethod({ functionName: "register_finish", args: [ { data: result.signedAttributes.data, signature: result.signedAttributes.signature, }, ],})Use openIdProvider: "google", "apple", "microsoft", or a provider issuer
URL. For lower-level requests, build scoped keys with identityAttributeKeys()
and pass them to identityAttributes.request().
See Also
Section titled “See Also”- @ic-reactor/react — React bindings built on top of this package
- Authentication — Internet Identity and identity attributes
- React Setup — End-to-end React integration guide
- @ic-reactor/candid — Dynamic runtime Candid support