ClientManager
Defined in: core/src/client.ts:170
ClientManager is a central class for managing the Internet Computer (IC) agent.
It initializes the agent (connecting to local or mainnet) and integrates with TanStack Query’s QueryClient for state management. Use this as a singleton shared by all reactors in an app.
Examples
Section titled “Examples”import { ClientManager } from "@ic-reactor/core";import { QueryClient } from "@tanstack/query-core";
const queryClient = new QueryClient();const clientManager = new ClientManager({ queryClient, agentOptions: { host: "http://127.0.0.1:4943" },});
await clientManager.initialize();// Reuse the same ClientManager across multiple canisters. `canisterId` is// required in Node, where the constructor otherwise throws; a browser page// may omit it only where the ic_env cookie is trusted (a local replica, or// `allowEnvConfig: true`).const backend = new Reactor<BackendService>({ clientManager, idlFactory: backendIdl, name: "backend", canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",})const ledger = new Reactor<LedgerService>({ clientManager, idlFactory: ledgerIdl, name: "ledger", canisterId: "ryjl3-tyaaa-aaaaa-aaaba-cai",})Constructors
Section titled “Constructors”Constructor
Section titled “Constructor”new ClientManager(
parameters):ClientManager
Defined in: core/src/client.ts:214
Creates a new instance of ClientManager.
Parameters
Section titled “Parameters”parameters
Section titled “parameters”Configuration options for the agent and network environment.
Returns
Section titled “Returns”ClientManager
Properties
Section titled “Properties”queryClient
Section titled “queryClient”queryClient:
QueryClient
Defined in: core/src/client.ts:202
The TanStack QueryClient used for managing cached canister data and invalidating queries on identity changes.
agentState
Section titled “agentState”agentState:
AgentState
Defined in: core/src/client.ts:206
Current state of the HttpAgent, including initialization status, network, and error information.
Accessors
Section titled “Accessors”Get Signature
Section titled “Get Signature”get agent():
HttpAgent
Defined in: core/src/client.ts:489
The underlying HttpAgent managed by this class.
Returns
Section titled “Returns”HttpAgent
agentHost
Section titled “agentHost”Get Signature
Section titled “Get Signature”get agentHost():
URL|undefined
Defined in: core/src/client.ts:496
The host URL of the current IC agent.
Returns
Section titled “Returns”URL | undefined
agentHostName
Section titled “agentHostName”Get Signature
Section titled “Get Signature”get agentHostName():
string
Defined in: core/src/client.ts:503
The hostname of the current IC agent.
Returns
Section titled “Returns”string
trustsEnvConfig
Section titled “trustsEnvConfig”Get Signature
Section titled “Get Signature”get trustsEnvConfig():
boolean
Defined in: core/src/client.ts:523
Whether the configuration carried by the ic_env cookie may be trusted for
this agent’s host.
true when BOTH the agent host and the page origin are unambiguously a
local replica (loopback, localhost and its subdomains), or when the
caller passed allowEnvConfig. The page counts because the page is what
decides who can write the cookie. A Codespaces or Gitpod domain shares its
parent with other users’ workspaces, so it needs allowEnvConfig.
Every consumer of that cookie reads this one decision, so the root key, the
Internet Identity provider and a reactor’s canister ID cannot disagree
about whether the environment is trustworthy.
The deprecated allowEnvRootKey is not enough on its own: it granted the
root key alone, and is honoured for the root key alone.
Returns
Section titled “Returns”boolean
explicitRootKey
Section titled “explicitRootKey”Get Signature
Section titled “Get Signature”get explicitRootKey():
Uint8Array<ArrayBufferLike> |undefined
Defined in: core/src/client.ts:533
The root key the caller passed as agentOptions.rootKey, which the agent
keeps: on a local host initializeAgent does not replace it with
the key the host serves. undefined when none was passed, also when the
agent took one from the ic_env cookie.
Returns
Section titled “Returns”Uint8Array<ArrayBufferLike> | undefined
isLocal
Section titled “isLocal”Get Signature
Section titled “Get Signature”get isLocal():
boolean
Defined in: core/src/client.ts:540
Returns true if the agent is connecting to a local environment.
Returns
Section titled “Returns”boolean
network
Section titled “network”Get Signature
Section titled “Get Signature”get network():
"local"|"remote"|"ic"
Defined in: core/src/client.ts:547
Returns the current network type (‘ic’ or ‘local’).
Returns
Section titled “Returns”"local" | "remote" | "ic"
identity
Section titled “identity”Get Signature
Section titled “Get Signature”get identity():
Identity|undefined
Defined in: core/src/client.ts:559
The identity currently installed on the agent, if one was set explicitly.
Calls capture this at submit time and pass it back on every request they make, so a sign-in or sign-out part-way through cannot re-sign a request that is already in flight.
Returns
Section titled “Returns”Identity | undefined
Methods
Section titled “Methods”initialize()
Section titled “initialize()”initialize():
Promise<ClientManager>
Defined in: core/src/client.ts:380
Orchestrates the complete initialization of the ClientManager. This method awaits the agent’s core initialization (e.g., fetching root keys) Authentication session restoration is handled by AuthenticationManager.
Returns
Section titled “Returns”Promise<ClientManager>
A promise that resolves to the ClientManager instance when core initialization is complete.
initializeAgent()
Section titled “initializeAgent()”initializeAgent():
Promise<void>
Defined in: core/src/client.ts:399
Specifically initializes the HttpAgent.
On local networks, this includes fetching the root key for certificate verification.
That covers every host whose network isn’t "ic", Codespaces and Gitpod
included. The fetched key replaces the key the agent holds: one from the
ic_env cookie, or mainnet’s when shouldFetchRootKey is false.
A key passed as agentOptions.rootKey is kept instead: nothing is
fetched, so /api/v2/status is not requested and need not be reachable,
and the agent verifies against that key before and after this call alike.
On a mainnet host nothing is fetched either way.
Returns
Section titled “Returns”Promise<void>
A promise that resolves when the agent is fully initialized.
getUserPrincipal()
Section titled “getUserPrincipal()”getUserPrincipal():
Promise<Principal>
Defined in: core/src/client.ts:566
Returns the current user’s Principal identity.
Returns
Section titled “Returns”Promise<Principal>
registerCanisterId()
Section titled “registerCanisterId()”registerCanisterId(
canisterId,name?):void
Defined in: core/src/client.ts:574
Registers a canister ID that this agent will interact with. This is used for informational purposes and network detection.
Parameters
Section titled “Parameters”canisterId
Section titled “canisterId”string
string
Returns
Section titled “Returns”void
connectedCanisterIds()
Section titled “connectedCanisterIds()”connectedCanisterIds():
string[]
Defined in: core/src/client.ts:597
Returns a list of all canister IDs registered with this agent.
Returns
Section titled “Returns”string[]
getSubnetIdFromCanister()
Section titled “getSubnetIdFromCanister()”getSubnetIdFromCanister(
canisterId):Promise<Principal>
Defined in: core/src/client.ts:604
Get the subnet ID for a canister.
Parameters
Section titled “Parameters”canisterId
Section titled “canisterId”string
Returns
Section titled “Returns”Promise<Principal>
syncTimeWithSubnet()
Section titled “syncTimeWithSubnet()”syncTimeWithSubnet(
subnetId):Promise<void>
Defined in: core/src/client.ts:611
Sync time with a specific subnet.
Parameters
Section titled “Parameters”subnetId
Section titled “subnetId”Principal
Returns
Section titled “Returns”Promise<void>
subscribe()
Section titled “subscribe()”subscribe(
callback): () =>void
Defined in: core/src/client.ts:627
Subscribes to identity changes (e.g., after login/logout).
Callbacks run in the order they subscribed, after the agent already holds
the new identity. A callback that throws does not stop the others; the
first error is rethrown from updateAgent once they have all run. When a
callback itself calls updateAgent, the identity that replaced this one
is the last each callback hears.
Parameters
Section titled “Parameters”callback
Section titled “callback”(identity) => void
Function called with the new identity.
Returns
Section titled “Returns”An unsubscribe function.
() => void
subscribeAgentState()
Section titled “subscribeAgentState()”subscribeAgentState(
callback): () =>void
Defined in: core/src/client.ts:650
Subscribes to changes in the agent’s initialization state.
Delivery works as for subscribe: every callback runs even when one throws, and a newer state set from inside a callback is the last state each callback hears.
Parameters
Section titled “Parameters”callback
Section titled “callback”(state) => void
Function called with the updated agent state.
Returns
Section titled “Returns”An unsubscribe function.
() => void
updateAgent()
Section titled “updateAgent()”updateAgent(
identity):void
Defined in: core/src/client.ts:688
Installs identity on the agent, cleans the cached queries of every
registered canister when the principal changes, and notifies identity
subscribers.
Query keys carry no principal, so on a switch to another principal (signing in, signing out, switching users) the cache is swept: queries in flight are cancelled, inactive entries are removed, and the rest are invalidated, so mounted queries refetch as the new principal.
When identity has the principal already installed (a renewed delegation,
a sign-in while signed in, an identity attribute request), the cached
answers are already that principal’s and are kept: nothing is cancelled or
removed, and no query that succeeded refetches. Only queries whose last
fetch failed are invalidated, since the old identity may be why they
failed (an expired delegation, or one not valid for that canister), and
so is a query whose fetch was in flight and fails afterwards. The first
call after construction always sweeps.
The comparison sees only the principal. An identity that changes what a
canister is told under the same principal, such as an AttributesIdentity
adding signed sender_info to each request, keeps answers computed
without it. After installing or removing one, invalidate the affected
queries yourself, e.g. with reactor.invalidateQueries().
Parameters
Section titled “Parameters”identity
Section titled “identity”Identity
The new identity to use.
Returns
Section titled “Returns”void
fetchAcrossIdentitySwitch()
Section titled “fetchAcrossIdentitySwitch()”fetchAcrossIdentitySwitch<
T>(fetch):Promise<T>
Defined in: core/src/client.ts:893
Runs fetch, a fetch of a registered canister’s query through
queryClient, and runs it again when the principal switches while
it runs.
updateAgent cancels those queries when the principal changes, so an
answer fetched for the previous principal never reaches the cache. A
query with a mounted observer refetches afterwards. An imperative fetch
has no observer: TanStack rejects its promise with a CancelledError,
which is neither a CallError nor a CanisterError, or, when the entry
held data before the fetch began, resolves it with that data, which is
the previous principal’s. Through this method it resolves with the
answer for the identity installed now, as a mounted query would show; the
previous identity’s answer is still never cached.
Reactor.fetchQuery, and with it the query factories’ fetch(), runs
through here. Wrap any other fetch of a canister query the same way.
Whatever fetch settles with while the principal stays is passed on as
is, including a cancellation from queryClient.cancelQueries(). After
three runs again, each overtaken by another switch, it rejects with a
CallError whose cause is what the last run settled with, if it
rejected, so the loop always ends and never returns an answer that may
be another principal’s.
Type Parameters
Section titled “Type Parameters”T
Parameters
Section titled “Parameters”() => Promise<T>
Starts the fetch. It is called once per run, so it has to start a fetch each time rather than return one promise it kept.
Returns
Section titled “Returns”Promise<T>
What fetch resolved with.
Example
Section titled “Example”const pages = await clientManager.fetchAcrossIdentitySwitch(() => clientManager.queryClient.fetchInfiniteQuery(options))