@ic-reactor/core 2.0.0 → 3.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/client.d.ts +161 -0
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/client.js +499 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/display/helper.d.ts +10 -0
  6. package/dist/display/helper.d.ts.map +1 -0
  7. package/dist/display/helper.js +67 -0
  8. package/dist/display/helper.js.map +1 -0
  9. package/dist/display/index.d.ts +4 -0
  10. package/dist/display/index.d.ts.map +1 -0
  11. package/dist/display/index.js +4 -0
  12. package/dist/display/index.js.map +1 -0
  13. package/dist/display/types.d.ts +31 -0
  14. package/dist/display/types.d.ts.map +1 -0
  15. package/dist/display/types.js +2 -0
  16. package/dist/display/types.js.map +1 -0
  17. package/dist/display/visitor.d.ts +28 -0
  18. package/dist/display/visitor.d.ts.map +1 -0
  19. package/dist/display/visitor.js +318 -0
  20. package/dist/display/visitor.js.map +1 -0
  21. package/dist/display-reactor.d.ts +245 -0
  22. package/dist/display-reactor.d.ts.map +1 -0
  23. package/dist/display-reactor.js +331 -0
  24. package/dist/display-reactor.js.map +1 -0
  25. package/dist/errors/index.d.ts +118 -0
  26. package/dist/errors/index.d.ts.map +1 -0
  27. package/dist/errors/index.js +204 -0
  28. package/dist/errors/index.js.map +1 -0
  29. package/dist/index.d.ts +9 -8
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +9 -47
  32. package/dist/index.js.map +1 -0
  33. package/dist/reactor.d.ts +133 -0
  34. package/dist/reactor.d.ts.map +1 -0
  35. package/dist/reactor.js +325 -0
  36. package/dist/reactor.js.map +1 -0
  37. package/dist/types/client.d.ts +89 -0
  38. package/dist/types/client.d.ts.map +1 -0
  39. package/dist/types/client.js +2 -0
  40. package/dist/types/client.js.map +1 -0
  41. package/dist/types/index.d.ts +6 -0
  42. package/dist/types/index.d.ts.map +1 -0
  43. package/dist/types/index.js +6 -0
  44. package/dist/types/index.js.map +1 -0
  45. package/dist/types/reactor.d.ts +117 -0
  46. package/dist/types/reactor.d.ts.map +1 -0
  47. package/dist/types/reactor.js +2 -0
  48. package/dist/types/reactor.js.map +1 -0
  49. package/dist/types/result.d.ts +48 -0
  50. package/dist/types/result.d.ts.map +1 -0
  51. package/dist/types/result.js +2 -0
  52. package/dist/types/result.js.map +1 -0
  53. package/dist/types/transform.d.ts +7 -0
  54. package/dist/types/transform.d.ts.map +1 -0
  55. package/dist/types/transform.js +2 -0
  56. package/dist/types/transform.js.map +1 -0
  57. package/dist/types/variant.d.ts +18 -0
  58. package/dist/types/variant.d.ts.map +1 -0
  59. package/dist/types/variant.js +2 -0
  60. package/dist/types/variant.js.map +1 -0
  61. package/dist/utils/agent.d.ts +30 -1
  62. package/dist/utils/agent.d.ts.map +1 -0
  63. package/dist/utils/agent.js +118 -16
  64. package/dist/utils/agent.js.map +1 -0
  65. package/dist/utils/candid.d.ts +39 -1
  66. package/dist/utils/candid.d.ts.map +1 -0
  67. package/dist/utils/candid.js +76 -16
  68. package/dist/utils/candid.js.map +1 -0
  69. package/dist/utils/constants.d.ts +3 -4
  70. package/dist/utils/constants.d.ts.map +1 -0
  71. package/dist/utils/constants.js +7 -11
  72. package/dist/utils/constants.js.map +1 -0
  73. package/dist/utils/helper.d.ts +16 -39
  74. package/dist/utils/helper.d.ts.map +1 -0
  75. package/dist/utils/helper.js +53 -155
  76. package/dist/utils/helper.js.map +1 -0
  77. package/dist/utils/index.d.ts +4 -5
  78. package/dist/utils/index.d.ts.map +1 -0
  79. package/dist/utils/index.js +5 -49
  80. package/dist/utils/index.js.map +1 -0
  81. package/dist/utils/polling.d.ts +176 -0
  82. package/dist/utils/polling.d.ts.map +1 -0
  83. package/dist/utils/polling.js +170 -0
  84. package/dist/utils/polling.js.map +1 -0
  85. package/dist/version.d.ts +5 -0
  86. package/dist/version.d.ts.map +1 -0
  87. package/dist/version.js +5 -0
  88. package/dist/version.js.map +1 -0
  89. package/package.json +65 -39
  90. package/LICENSE.md +0 -8
  91. package/README.md +0 -283
  92. package/dist/classes/actor/index.d.ts +0 -34
  93. package/dist/classes/actor/index.js +0 -245
  94. package/dist/classes/actor/types.d.ts +0 -113
  95. package/dist/classes/actor/types.js +0 -2
  96. package/dist/classes/adapter/index.d.ts +0 -19
  97. package/dist/classes/adapter/index.js +0 -140
  98. package/dist/classes/adapter/types.d.ts +0 -14
  99. package/dist/classes/adapter/types.js +0 -2
  100. package/dist/classes/agent/index.d.ts +0 -36
  101. package/dist/classes/agent/index.js +0 -218
  102. package/dist/classes/agent/types.d.ts +0 -87
  103. package/dist/classes/agent/types.js +0 -2
  104. package/dist/classes/index.d.ts +0 -3
  105. package/dist/classes/index.js +0 -19
  106. package/dist/classes/types.d.ts +0 -15
  107. package/dist/classes/types.js +0 -20
  108. package/dist/createActorManager.d.ts +0 -12
  109. package/dist/createActorManager.js +0 -17
  110. package/dist/createAgentManager.d.ts +0 -12
  111. package/dist/createAgentManager.js +0 -17
  112. package/dist/createCandidAdapter.d.ts +0 -11
  113. package/dist/createCandidAdapter.js +0 -16
  114. package/dist/createReactorCore.d.ts +0 -10
  115. package/dist/createReactorCore.js +0 -112
  116. package/dist/createReactorStore.d.ts +0 -11
  117. package/dist/createReactorStore.js +0 -31
  118. package/dist/types.d.ts +0 -96
  119. package/dist/types.js +0 -17
  120. package/dist/utils/hash.d.ts +0 -12
  121. package/dist/utils/hash.js +0 -70
  122. package/dist/utils/principal.d.ts +0 -1
  123. package/dist/utils/principal.js +0 -17
@@ -0,0 +1,161 @@
1
+ import type { Identity } from "@icp-sdk/core/agent";
2
+ import type { AuthClientLoginOptions } from "@icp-sdk/auth/client";
3
+ import type { ClientManagerParameters, AgentState, AuthState } from "./types/client";
4
+ import type { Principal } from "@icp-sdk/core/principal";
5
+ import type { QueryClient } from "@tanstack/react-query";
6
+ import { HttpAgent } from "@icp-sdk/core/agent";
7
+ /**
8
+ * ClientManager is a central class for managing the Internet Computer (IC) agent and authentication state.
9
+ *
10
+ * It initializes the agent (connecting to local or mainnet), handles authentication via AuthClient,
11
+ * and integrates with TanStack Query's QueryClient for state management.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { ClientManager } from "@ic-reactor/core";
16
+ * import { QueryClient } from "@tanstack/react-query";
17
+ *
18
+ * const queryClient = new QueryClient();
19
+ * const clientManager = new ClientManager({
20
+ * queryClient,
21
+ * withLocalEnv: true, // Use local replica
22
+ * });
23
+ *
24
+ * await clientManager.initialize();
25
+ * ```
26
+ */
27
+ export declare class ClientManager {
28
+ #private;
29
+ /**
30
+ * The TanStack QueryClient used for managing cached canister data and invalidating queries on identity changes.
31
+ */
32
+ queryClient: QueryClient;
33
+ /**
34
+ * Current state of the HttpAgent, including initialization status, network, and error information.
35
+ */
36
+ agentState: AgentState;
37
+ /**
38
+ * Current authentication state, including the active identity, authentication progress, and errors.
39
+ */
40
+ authState: AuthState;
41
+ private initPromise?;
42
+ private authPromise?;
43
+ /**
44
+ * Creates a new instance of ClientManager.
45
+ *
46
+ * @param parameters - Configuration options for the agent and network environment.
47
+ */
48
+ constructor({ port, withLocalEnv, withProcessEnv, agentOptions, queryClient, authClient, }: ClientManagerParameters);
49
+ /**
50
+ * Orchestrates the complete initialization of the ClientManager.
51
+ * This method awaits the agent's core initialization (e.g., fetching root keys)
52
+ * and triggers the authentication (session restoration) in the background.
53
+ *
54
+ * @returns A promise that resolves to the ClientManager instance when core initialization is complete.
55
+ */
56
+ initialize(): Promise<this>;
57
+ /**
58
+ * Specifically initializes the HttpAgent.
59
+ * On local networks, this includes fetching the root key for certificate verification.
60
+ *
61
+ * @returns A promise that resolves when the agent is fully initialized.
62
+ */
63
+ initializeAgent(): Promise<void>;
64
+ private authModuleMissing;
65
+ /**
66
+ * Attempts to initialize the authentication client and restore a previous session.
67
+ *
68
+ * If an `AuthClient` is already initialized (passed in constructor or previously created),
69
+ * it uses that instance. Otherwise, it dynamically imports the `@icp-sdk/auth` module
70
+ * and creates a new AuthClient.
71
+ *
72
+ * If the module is missing and no client is provided, it fails gracefully by marking authentication as unavailable.
73
+ *
74
+ * @returns A promise that resolves to the restored Identity, or undefined if auth fails or is unavailable.
75
+ */
76
+ authenticate: () => Promise<Identity | undefined>;
77
+ /**
78
+ * Triggers the login flow using the Internet Identity provider.
79
+ *
80
+ * @param loginOptions - Options for the login flow, including identity provider and callbacks.
81
+ * @throws An error if the authentication module is not installed.
82
+ */
83
+ login: (loginOptions?: AuthClientLoginOptions) => Promise<void>;
84
+ /**
85
+ * Logs out the user and reverts the agent to an anonymous identity.
86
+ *
87
+ * @throws An error if the authentication module is not installed.
88
+ */
89
+ logout: () => Promise<void>;
90
+ /**
91
+ * The underlying HttpAgent managed by this class.
92
+ */
93
+ get agent(): HttpAgent;
94
+ /**
95
+ * The host URL of the current IC agent.
96
+ */
97
+ get agentHost(): URL | undefined;
98
+ /**
99
+ * The hostname of the current IC agent.
100
+ */
101
+ get agentHostName(): string;
102
+ /**
103
+ * Returns true if the agent is connecting to a local environment.
104
+ */
105
+ get isLocal(): boolean;
106
+ /**
107
+ * Returns the current network type ('ic' or 'local').
108
+ */
109
+ get network(): "local" | "remote" | "ic";
110
+ /**
111
+ * Returns the current user's Principal identity.
112
+ */
113
+ getUserPrincipal(): Promise<Principal>;
114
+ /**
115
+ * Registers a canister ID that this agent will interact with.
116
+ * This is used for informational purposes and network detection.
117
+ */
118
+ registerCanisterId(canisterId: string, name?: string): void;
119
+ /**
120
+ * Returns a list of all canister IDs registered with this agent.
121
+ */
122
+ connectedCanisterIds(): string[];
123
+ /**
124
+ * Get the subnet ID for a canister.
125
+ */
126
+ getSubnetIdFromCanister(canisterId: string): Promise<Principal>;
127
+ /**
128
+ * Sync time with a specific subnet.
129
+ */
130
+ syncTimeWithSubnet(subnetId: Principal): Promise<void>;
131
+ private getDefaultIdentityProvider;
132
+ /**
133
+ * Subscribes to identity changes (e.g., after login/logout).
134
+ * @param callback - Function called with the new identity.
135
+ * @returns An unsubscribe function.
136
+ */
137
+ subscribe(callback: (identity: Identity) => void): () => void;
138
+ /**
139
+ * Subscribes to changes in the agent's initialization state.
140
+ * @param callback - Function called with the updated agent state.
141
+ * @returns An unsubscribe function.
142
+ */
143
+ subscribeAgentState(callback: (state: AgentState) => void): () => void;
144
+ /**
145
+ * Subscribes to changes in the authentication state.
146
+ * @param callback - Function called with the updated authentication state.
147
+ * @returns An unsubscribe function.
148
+ */
149
+ subscribeAuthState(callback: (state: AuthState) => void): () => void;
150
+ /**
151
+ * Replaces the current agent's identity and invalidates TanStack queries.
152
+ * @param identity - The new identity to use.
153
+ */
154
+ updateAgent(identity: Identity): void;
155
+ private notifySubscribers;
156
+ private notifyAgentStateSubscribers;
157
+ private notifyAuthStateSubscribers;
158
+ private updateAgentState;
159
+ private updateAuthState;
160
+ }
161
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,EAAc,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,KAAK,EACV,uBAAuB,EACvB,UAAU,EACV,SAAS,EACV,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAQ/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,aAAa;;IAQxB;;OAEG;IACI,WAAW,EAAE,WAAW,CAAA;IAC/B;;OAEG;IACI,UAAU,EAAE,UAAU,CAAA;IAC7B;;OAEG;IACI,SAAS,EAAE,SAAS,CAAA;IAE3B,OAAO,CAAC,WAAW,CAAC,CAAe;IACnC,OAAO,CAAC,WAAW,CAAC,CAA+B;IAEnD;;;;OAIG;gBACS,EACV,IAAW,EACX,YAAY,EACZ,cAAc,EACd,YAAiB,EACjB,WAAW,EACX,UAAU,GACX,EAAE,uBAAuB;IAkD1B;;;;;;OAMG;IACU,UAAU;IAMvB;;;;;OAKG;IACU,eAAe;IAuC5B,OAAO,CAAC,iBAAiB,CAAQ;IAEjC;;;;;;;;;;OAUG;IACI,YAAY,QAAa,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CA2D5D;IAED;;;;;OAKG;IACI,KAAK,GAAU,eAAe,sBAAsB,mBAqD1D;IAED;;;;OAIG;IACI,MAAM,sBAiBZ;IAED;;OAEG;IACH,IAAI,KAAK,cAER;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,GAAG,GAAG,SAAS,CAE/B;IAED;;OAEG;IACH,IAAI,aAAa,WAEhB;IAED;;OAEG;IACH,IAAI,OAAO,YAEV;IAED;;OAEG;IACH,IAAI,OAAO,8BAGV;IAED;;OAEG;IACI,gBAAgB;IAIvB;;;OAGG;IACI,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAiBlE;;OAEG;IACI,oBAAoB,IAAI,MAAM,EAAE;IAIvC;;OAEG;IACI,uBAAuB,CAAC,UAAU,EAAE,MAAM;IAIjD;;OAEG;IACI,kBAAkB,CAAC,QAAQ,EAAE,SAAS;IAI7C,OAAO,CAAC,0BAA0B;IAQlC;;;;OAIG;IACI,SAAS,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI;IASvD;;;;OAIG;IACI,mBAAmB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;IAShE;;;;OAIG;IACI,kBAAkB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI;IAS9D;;;OAGG;IACI,WAAW,CAAC,QAAQ,EAAE,QAAQ;IAwBrC,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,2BAA2B;IAInC,OAAO,CAAC,0BAA0B;IAIlC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,eAAe;CAKxB"}
package/dist/client.js ADDED
@@ -0,0 +1,499 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _ClientManager_agent, _ClientManager_authClient, _ClientManager_identitySubscribers, _ClientManager_agentStateSubscribers, _ClientManager_authStateSubscribers, _ClientManager_targetCanisterIds;
13
+ import { HttpAgent } from "@icp-sdk/core/agent";
14
+ import { IC_HOST_NETWORK_URI, IC_INTERNET_IDENTITY_PROVIDER, LOCAL_INTERNET_IDENTITY_PROVIDER, } from "./utils/constants";
15
+ import { getNetworkByHostname, getProcessEnvNetwork } from "./utils/helper";
16
+ /**
17
+ * ClientManager is a central class for managing the Internet Computer (IC) agent and authentication state.
18
+ *
19
+ * It initializes the agent (connecting to local or mainnet), handles authentication via AuthClient,
20
+ * and integrates with TanStack Query's QueryClient for state management.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * import { ClientManager } from "@ic-reactor/core";
25
+ * import { QueryClient } from "@tanstack/react-query";
26
+ *
27
+ * const queryClient = new QueryClient();
28
+ * const clientManager = new ClientManager({
29
+ * queryClient,
30
+ * withLocalEnv: true, // Use local replica
31
+ * });
32
+ *
33
+ * await clientManager.initialize();
34
+ * ```
35
+ */
36
+ export class ClientManager {
37
+ /**
38
+ * Creates a new instance of ClientManager.
39
+ *
40
+ * @param parameters - Configuration options for the agent and network environment.
41
+ */
42
+ constructor({ port = 4943, withLocalEnv, withProcessEnv, agentOptions = {}, queryClient, authClient, }) {
43
+ _ClientManager_agent.set(this, void 0);
44
+ _ClientManager_authClient.set(this, void 0);
45
+ _ClientManager_identitySubscribers.set(this, []);
46
+ _ClientManager_agentStateSubscribers.set(this, []);
47
+ _ClientManager_authStateSubscribers.set(this, []);
48
+ _ClientManager_targetCanisterIds.set(this, new Set()
49
+ /**
50
+ * The TanStack QueryClient used for managing cached canister data and invalidating queries on identity changes.
51
+ */
52
+ );
53
+ /**
54
+ * The TanStack QueryClient used for managing cached canister data and invalidating queries on identity changes.
55
+ */
56
+ Object.defineProperty(this, "queryClient", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: void 0
61
+ });
62
+ /**
63
+ * Current state of the HttpAgent, including initialization status, network, and error information.
64
+ */
65
+ Object.defineProperty(this, "agentState", {
66
+ enumerable: true,
67
+ configurable: true,
68
+ writable: true,
69
+ value: void 0
70
+ });
71
+ /**
72
+ * Current authentication state, including the active identity, authentication progress, and errors.
73
+ */
74
+ Object.defineProperty(this, "authState", {
75
+ enumerable: true,
76
+ configurable: true,
77
+ writable: true,
78
+ value: void 0
79
+ });
80
+ Object.defineProperty(this, "initPromise", {
81
+ enumerable: true,
82
+ configurable: true,
83
+ writable: true,
84
+ value: void 0
85
+ });
86
+ Object.defineProperty(this, "authPromise", {
87
+ enumerable: true,
88
+ configurable: true,
89
+ writable: true,
90
+ value: void 0
91
+ });
92
+ Object.defineProperty(this, "authModuleMissing", {
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true,
96
+ value: false
97
+ });
98
+ /**
99
+ * Attempts to initialize the authentication client and restore a previous session.
100
+ *
101
+ * If an `AuthClient` is already initialized (passed in constructor or previously created),
102
+ * it uses that instance. Otherwise, it dynamically imports the `@icp-sdk/auth` module
103
+ * and creates a new AuthClient.
104
+ *
105
+ * If the module is missing and no client is provided, it fails gracefully by marking authentication as unavailable.
106
+ *
107
+ * @returns A promise that resolves to the restored Identity, or undefined if auth fails or is unavailable.
108
+ */
109
+ Object.defineProperty(this, "authenticate", {
110
+ enumerable: true,
111
+ configurable: true,
112
+ writable: true,
113
+ value: async () => {
114
+ if (this.authState.isAuthenticated) {
115
+ return this.authState.identity || undefined;
116
+ }
117
+ if (this.authPromise) {
118
+ return this.authPromise;
119
+ }
120
+ if (this.authModuleMissing) {
121
+ return undefined;
122
+ }
123
+ this.authPromise = (async () => {
124
+ if (typeof window !== "undefined") {
125
+ console.info(`%cic-reactor:%c Authenticating...`, "color: #3b82f6; font-weight: bold", "color: inherit", {
126
+ network: this.network,
127
+ authClient: __classPrivateFieldGet(this, _ClientManager_authClient, "f") ? "Shared Instance" : "Dynamic Import",
128
+ });
129
+ }
130
+ this.updateAuthState({ isAuthenticating: true });
131
+ try {
132
+ if (!__classPrivateFieldGet(this, _ClientManager_authClient, "f")) {
133
+ const authModule = await import("@icp-sdk/auth/client").catch(() => {
134
+ this.authModuleMissing = true;
135
+ return null;
136
+ });
137
+ if (!authModule) {
138
+ this.authModuleMissing = true;
139
+ this.updateAuthState({ isAuthenticating: false });
140
+ return undefined;
141
+ }
142
+ const { AuthClient } = authModule;
143
+ __classPrivateFieldSet(this, _ClientManager_authClient, await AuthClient.create(), "f");
144
+ }
145
+ const identity = __classPrivateFieldGet(this, _ClientManager_authClient, "f").getIdentity();
146
+ this.updateAgent(identity);
147
+ this.updateAuthState({
148
+ identity,
149
+ isAuthenticated: !identity.getPrincipal().isAnonymous(),
150
+ isAuthenticating: false,
151
+ });
152
+ return identity;
153
+ }
154
+ catch (error) {
155
+ this.updateAuthState({ error: error, isAuthenticating: false });
156
+ console.error("Authentication failed:", error);
157
+ throw error;
158
+ }
159
+ finally {
160
+ this.authPromise = undefined;
161
+ }
162
+ })();
163
+ return this.authPromise;
164
+ }
165
+ });
166
+ /**
167
+ * Triggers the login flow using the Internet Identity provider.
168
+ *
169
+ * @param loginOptions - Options for the login flow, including identity provider and callbacks.
170
+ * @throws An error if the authentication module is not installed.
171
+ */
172
+ Object.defineProperty(this, "login", {
173
+ enumerable: true,
174
+ configurable: true,
175
+ writable: true,
176
+ value: async (loginOptions) => {
177
+ try {
178
+ // Ensure agent is initialized before login
179
+ if (!this.agentState.isInitialized) {
180
+ await this.initializeAgent();
181
+ }
182
+ if (!__classPrivateFieldGet(this, _ClientManager_authClient, "f")) {
183
+ await this.authenticate();
184
+ }
185
+ if (!__classPrivateFieldGet(this, _ClientManager_authClient, "f")) {
186
+ throw new Error("Authentication module is missing or failed to initialize. To use login, please install the auth package: npm install @icp-sdk/auth");
187
+ }
188
+ this.updateAuthState({ isAuthenticating: true, error: undefined });
189
+ // Auto-detect identity provider based on network if not provided
190
+ const identityProvider = loginOptions?.identityProvider || this.getDefaultIdentityProvider();
191
+ await __classPrivateFieldGet(this, _ClientManager_authClient, "f").login({
192
+ ...loginOptions,
193
+ identityProvider,
194
+ onSuccess: () => {
195
+ const identity = __classPrivateFieldGet(this, _ClientManager_authClient, "f").getIdentity();
196
+ if (identity) {
197
+ this.updateAgent(identity);
198
+ this.updateAuthState({
199
+ identity,
200
+ isAuthenticated: true,
201
+ isAuthenticating: false,
202
+ });
203
+ }
204
+ ;
205
+ loginOptions?.onSuccess?.();
206
+ },
207
+ onError: (error) => {
208
+ this.updateAuthState({
209
+ error: new Error(error),
210
+ isAuthenticating: false,
211
+ });
212
+ loginOptions?.onError?.(error);
213
+ },
214
+ });
215
+ }
216
+ catch (error) {
217
+ this.updateAuthState({
218
+ error: error,
219
+ isAuthenticating: false,
220
+ });
221
+ throw error;
222
+ }
223
+ }
224
+ });
225
+ /**
226
+ * Logs out the user and reverts the agent to an anonymous identity.
227
+ *
228
+ * @throws An error if the authentication module is not installed.
229
+ */
230
+ Object.defineProperty(this, "logout", {
231
+ enumerable: true,
232
+ configurable: true,
233
+ writable: true,
234
+ value: async () => {
235
+ if (!__classPrivateFieldGet(this, _ClientManager_authClient, "f")) {
236
+ throw new Error("Authentication module is missing or failed to initialize. To use logout, please install the auth package: npm install @icp-sdk/auth");
237
+ }
238
+ this.updateAuthState({ isAuthenticating: true, error: undefined });
239
+ await __classPrivateFieldGet(this, _ClientManager_authClient, "f").logout();
240
+ const identity = __classPrivateFieldGet(this, _ClientManager_authClient, "f").getIdentity();
241
+ if (identity) {
242
+ this.updateAgent(identity);
243
+ this.updateAuthState({
244
+ identity,
245
+ isAuthenticated: false,
246
+ isAuthenticating: false,
247
+ });
248
+ }
249
+ }
250
+ });
251
+ this.queryClient = queryClient;
252
+ this.agentState = {
253
+ isInitialized: false,
254
+ isInitializing: false,
255
+ error: undefined,
256
+ network: undefined,
257
+ isLocalhost: false,
258
+ };
259
+ this.authState = {
260
+ identity: null,
261
+ isAuthenticating: false,
262
+ isAuthenticated: false,
263
+ error: undefined,
264
+ };
265
+ if (withProcessEnv) {
266
+ const processNetwork = getProcessEnvNetwork();
267
+ if (processNetwork === "ic") {
268
+ agentOptions.host = IC_HOST_NETWORK_URI;
269
+ }
270
+ else if (processNetwork === "local") {
271
+ agentOptions.host =
272
+ typeof process !== "undefined" && process.env.IC_HOST
273
+ ? process.env.IC_HOST
274
+ : `http://127.0.0.1:${port}`;
275
+ }
276
+ }
277
+ else if (withLocalEnv) {
278
+ agentOptions.host = `http://127.0.0.1:${port}`;
279
+ }
280
+ else {
281
+ agentOptions.host = agentOptions.host ?? IC_HOST_NETWORK_URI;
282
+ }
283
+ __classPrivateFieldSet(this, _ClientManager_agent, HttpAgent.createSync(agentOptions), "f");
284
+ this.updateAgentState({ isLocalhost: this.isLocal });
285
+ if (authClient) {
286
+ __classPrivateFieldSet(this, _ClientManager_authClient, authClient, "f");
287
+ const identity = __classPrivateFieldGet(this, _ClientManager_authClient, "f").getIdentity();
288
+ this.updateAgent(identity);
289
+ this.authState = {
290
+ identity,
291
+ isAuthenticated: !identity.getPrincipal().isAnonymous(),
292
+ isAuthenticating: false,
293
+ error: undefined,
294
+ };
295
+ }
296
+ }
297
+ /**
298
+ * Orchestrates the complete initialization of the ClientManager.
299
+ * This method awaits the agent's core initialization (e.g., fetching root keys)
300
+ * and triggers the authentication (session restoration) in the background.
301
+ *
302
+ * @returns A promise that resolves to the ClientManager instance when core initialization is complete.
303
+ */
304
+ async initialize() {
305
+ await this.initializeAgent();
306
+ this.authenticate();
307
+ return this;
308
+ }
309
+ /**
310
+ * Specifically initializes the HttpAgent.
311
+ * On local networks, this includes fetching the root key for certificate verification.
312
+ *
313
+ * @returns A promise that resolves when the agent is fully initialized.
314
+ */
315
+ async initializeAgent() {
316
+ if (this.agentState.isInitialized) {
317
+ return;
318
+ }
319
+ if (this.agentState.isInitializing) {
320
+ return this.initPromise;
321
+ }
322
+ this.initPromise = (async () => {
323
+ this.updateAgentState({ isInitializing: true });
324
+ if (typeof window !== "undefined") {
325
+ console.info(`%cic-reactor:%c Initializing agent for ${this.network} network`, "color: #3b82f6; font-weight: bold", "color: inherit", {
326
+ host: this.agentHost?.toString(),
327
+ isLocal: this.isLocal,
328
+ });
329
+ }
330
+ try {
331
+ if (this.isLocal) {
332
+ await __classPrivateFieldGet(this, _ClientManager_agent, "f").fetchRootKey();
333
+ }
334
+ this.updateAgentState({ isInitialized: true, isInitializing: false });
335
+ }
336
+ catch (error) {
337
+ this.updateAgentState({
338
+ error: error,
339
+ isInitializing: false,
340
+ });
341
+ this.initPromise = undefined;
342
+ throw error;
343
+ }
344
+ })();
345
+ return this.initPromise;
346
+ }
347
+ /**
348
+ * The underlying HttpAgent managed by this class.
349
+ */
350
+ get agent() {
351
+ return __classPrivateFieldGet(this, _ClientManager_agent, "f");
352
+ }
353
+ /**
354
+ * The host URL of the current IC agent.
355
+ */
356
+ get agentHost() {
357
+ return __classPrivateFieldGet(this, _ClientManager_agent, "f").host;
358
+ }
359
+ /**
360
+ * The hostname of the current IC agent.
361
+ */
362
+ get agentHostName() {
363
+ return this.agentHost?.hostname || "";
364
+ }
365
+ /**
366
+ * Returns true if the agent is connecting to a local environment.
367
+ */
368
+ get isLocal() {
369
+ return this.network !== "ic";
370
+ }
371
+ /**
372
+ * Returns the current network type ('ic' or 'local').
373
+ */
374
+ get network() {
375
+ const hostname = this.agentHostName;
376
+ return getNetworkByHostname(hostname);
377
+ }
378
+ /**
379
+ * Returns the current user's Principal identity.
380
+ */
381
+ getUserPrincipal() {
382
+ return __classPrivateFieldGet(this, _ClientManager_agent, "f").getPrincipal();
383
+ }
384
+ /**
385
+ * Registers a canister ID that this agent will interact with.
386
+ * This is used for informational purposes and network detection.
387
+ */
388
+ registerCanisterId(canisterId, name) {
389
+ if (typeof window !== "undefined") {
390
+ const actorName = name || canisterId;
391
+ console.info(`%cic-reactor:%c Adding actor ${actorName}`, "color: #3b82f6; font-weight: bold", "color: inherit", {
392
+ network: this.network,
393
+ canisterId,
394
+ ...(name && { name }),
395
+ });
396
+ }
397
+ __classPrivateFieldGet(this, _ClientManager_targetCanisterIds, "f").add(canisterId);
398
+ }
399
+ /**
400
+ * Returns a list of all canister IDs registered with this agent.
401
+ */
402
+ connectedCanisterIds() {
403
+ return Array.from(__classPrivateFieldGet(this, _ClientManager_targetCanisterIds, "f"));
404
+ }
405
+ /**
406
+ * Get the subnet ID for a canister.
407
+ */
408
+ getSubnetIdFromCanister(canisterId) {
409
+ return __classPrivateFieldGet(this, _ClientManager_agent, "f").getSubnetIdFromCanister(canisterId);
410
+ }
411
+ /**
412
+ * Sync time with a specific subnet.
413
+ */
414
+ syncTimeWithSubnet(subnetId) {
415
+ return __classPrivateFieldGet(this, _ClientManager_agent, "f").syncTimeWithSubnet(subnetId);
416
+ }
417
+ getDefaultIdentityProvider() {
418
+ if (this.isLocal) {
419
+ return LOCAL_INTERNET_IDENTITY_PROVIDER;
420
+ }
421
+ else {
422
+ return IC_INTERNET_IDENTITY_PROVIDER;
423
+ }
424
+ }
425
+ /**
426
+ * Subscribes to identity changes (e.g., after login/logout).
427
+ * @param callback - Function called with the new identity.
428
+ * @returns An unsubscribe function.
429
+ */
430
+ subscribe(callback) {
431
+ __classPrivateFieldGet(this, _ClientManager_identitySubscribers, "f").push(callback);
432
+ return () => {
433
+ __classPrivateFieldSet(this, _ClientManager_identitySubscribers, __classPrivateFieldGet(this, _ClientManager_identitySubscribers, "f").filter((sub) => sub !== callback), "f");
434
+ };
435
+ }
436
+ /**
437
+ * Subscribes to changes in the agent's initialization state.
438
+ * @param callback - Function called with the updated agent state.
439
+ * @returns An unsubscribe function.
440
+ */
441
+ subscribeAgentState(callback) {
442
+ __classPrivateFieldGet(this, _ClientManager_agentStateSubscribers, "f").push(callback);
443
+ return () => {
444
+ __classPrivateFieldSet(this, _ClientManager_agentStateSubscribers, __classPrivateFieldGet(this, _ClientManager_agentStateSubscribers, "f").filter((sub) => sub !== callback), "f");
445
+ };
446
+ }
447
+ /**
448
+ * Subscribes to changes in the authentication state.
449
+ * @param callback - Function called with the updated authentication state.
450
+ * @returns An unsubscribe function.
451
+ */
452
+ subscribeAuthState(callback) {
453
+ __classPrivateFieldGet(this, _ClientManager_authStateSubscribers, "f").push(callback);
454
+ return () => {
455
+ __classPrivateFieldSet(this, _ClientManager_authStateSubscribers, __classPrivateFieldGet(this, _ClientManager_authStateSubscribers, "f").filter((sub) => sub !== callback), "f");
456
+ };
457
+ }
458
+ /**
459
+ * Replaces the current agent's identity and invalidates TanStack queries.
460
+ * @param identity - The new identity to use.
461
+ */
462
+ updateAgent(identity) {
463
+ if (typeof window !== "undefined") {
464
+ console.info(`%cic-reactor:%c Updating agent identity`, "color: #3b82f6; font-weight: bold", "color: inherit", {
465
+ principal: identity.getPrincipal().toText(),
466
+ });
467
+ }
468
+ // Cancel all queries for connected canisters to prevent race conditions
469
+ // with the old identity
470
+ this.connectedCanisterIds().forEach((canisterId) => {
471
+ this.queryClient.cancelQueries({
472
+ queryKey: [canisterId],
473
+ });
474
+ });
475
+ __classPrivateFieldGet(this, _ClientManager_agent, "f").replaceIdentity(identity);
476
+ this.notifySubscribers(identity);
477
+ this.queryClient.invalidateQueries();
478
+ }
479
+ notifySubscribers(identity) {
480
+ __classPrivateFieldGet(this, _ClientManager_identitySubscribers, "f").forEach((sub) => sub(identity));
481
+ }
482
+ notifyAgentStateSubscribers(state) {
483
+ __classPrivateFieldGet(this, _ClientManager_agentStateSubscribers, "f").forEach((sub) => sub(state));
484
+ }
485
+ notifyAuthStateSubscribers(state) {
486
+ __classPrivateFieldGet(this, _ClientManager_authStateSubscribers, "f").forEach((sub) => sub(state));
487
+ }
488
+ updateAgentState(newState) {
489
+ this.agentState = { ...this.agentState, ...newState };
490
+ this.notifyAgentStateSubscribers(this.agentState);
491
+ }
492
+ updateAuthState(newState) {
493
+ console.debug("Updating Auth State:", newState);
494
+ this.authState = { ...this.authState, ...newState };
495
+ this.notifyAuthStateSubscribers(this.authState);
496
+ }
497
+ }
498
+ _ClientManager_agent = new WeakMap(), _ClientManager_authClient = new WeakMap(), _ClientManager_identitySubscribers = new WeakMap(), _ClientManager_agentStateSubscribers = new WeakMap(), _ClientManager_authStateSubscribers = new WeakMap(), _ClientManager_targetCanisterIds = new WeakMap();
499
+ //# sourceMappingURL=client.js.map