@ic-reactor/react 3.3.1 → 3.5.0

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.
package/README.md CHANGED
@@ -81,8 +81,8 @@ export function App() {
81
81
 
82
82
  - `createActorHooks(reactor)` for per-canister hooks like `useActorQuery` and
83
83
  `useActorMutation`
84
- - `createAuthHooks(clientManager)` for `useAuth`, `useAgentState`, and
85
- `useUserPrincipal`
84
+ - `createAuthHooks(clientManager)` for `useAuth`, `useAgentState`,
85
+ `useUserPrincipal`, and identity attribute hooks
86
86
  - direct reactor hooks like `useReactorQuery` when you want to pass the reactor
87
87
  instance at call time
88
88
  - factory helpers like `createQuery`, `createSuspenseQuery`,
@@ -134,6 +134,65 @@ const mutation = updateProfile.useMutation({
134
134
  })
135
135
  ```
136
136
 
137
+ ## Identity Attributes / OpenID email and profile values
138
+
139
+ `createAuthHooks(clientManager)` exposes `useIdentityAttributes()` for signed
140
+ identity attributes from `@icp-sdk/auth` v6. Existing `useAuth()`, `login()`,
141
+ `logout()`, and `useUserPrincipal()` consumers keep the same IC Reactor API, but
142
+ the configured auth client must support the v6 constructor/sign-in API.
143
+
144
+ ```tsx
145
+ import { createAuthHooks } from "@ic-reactor/react"
146
+ import { clientManager } from "./reactor"
147
+
148
+ const { useIdentityAttributes } = createAuthHooks(clientManager)
149
+
150
+ function RegisterWithOpenIdProvider() {
151
+ const {
152
+ requestOpenIdAttributes,
153
+ attributes,
154
+ isRequestingAttributes,
155
+ attributeError,
156
+ } = useIdentityAttributes()
157
+
158
+ async function handleProviderLogin() {
159
+ const nonce = await backend.registerBegin()
160
+
161
+ const result = await requestOpenIdAttributes({
162
+ nonce,
163
+ openIdProvider: "microsoft",
164
+ keys: ["email", "name"],
165
+ identityProvider: "https://beta.id.ai/authorize",
166
+ windowOpenerFeatures: popupCenter(),
167
+ })
168
+
169
+ console.log(result.decodedAttributes.email)
170
+ console.log(result.decodedAttributes.name)
171
+
172
+ await backend.registerFinish({
173
+ data: result.signedAttributes.data,
174
+ signature: result.signedAttributes.signature,
175
+ })
176
+ }
177
+
178
+ return (
179
+ <button disabled={isRequestingAttributes} onClick={handleProviderLogin}>
180
+ {attributes?.decodedAttributes.email ??
181
+ attributeError?.message ??
182
+ "Continue with provider"}
183
+ </button>
184
+ )
185
+ }
186
+ ```
187
+
188
+ Use a documented auth provider alias (`"google"`, `"apple"`, or `"microsoft"`)
189
+ or the provider issuer URL your app expects for `openIdProvider`.
190
+
191
+ Frontend decoded `email` and `name` values are for display only. Production flows
192
+ must send `signedAttributes.data` and `signedAttributes.signature` to the backend
193
+ or canister and verify the signature, nonce, origin, timestamp, and requested keys
194
+ before trusting or storing the attributes.
195
+
137
196
  ## Query Result Methods
138
197
 
139
198
  Every object returned by `createQuery`, `createSuspenseQuery`, and their
@@ -1,10 +1,9 @@
1
- import { ClientManager, AgentState } from "@ic-reactor/core";
2
- import { Principal } from "@icp-sdk/core/principal";
3
- import { Identity } from "@icp-sdk/core/agent";
4
- import { AuthClientLoginOptions } from "@icp-sdk/auth/client";
1
+ import { ClientManager, AgentState, ClientManagerSignInOptions, IdentityAttributeResult, RequestIdentityAttributesParameters, RequestOpenIdIdentityAttributesParameters } from "@ic-reactor/core";
2
+ import type { Principal } from "@icp-sdk/core/principal";
3
+ import type { Identity } from "@icp-sdk/core/agent";
5
4
  export interface UseAuthReturn {
6
5
  authenticate: () => Promise<Identity | undefined>;
7
- login: (options?: AuthClientLoginOptions) => Promise<void>;
6
+ login: (options?: ClientManagerSignInOptions) => Promise<void>;
8
7
  logout: (options?: {
9
8
  returnTo?: string;
10
9
  }) => Promise<void>;
@@ -18,6 +17,15 @@ export interface CreateAuthHooksReturn {
18
17
  useAgentState: () => AgentState;
19
18
  useUserPrincipal: () => Principal | null;
20
19
  useAuth: () => UseAuthReturn;
20
+ useIdentityAttributes: () => UseIdentityAttributesReturn;
21
+ }
22
+ export interface UseIdentityAttributesReturn {
23
+ requestAttributes: (params: RequestIdentityAttributesParameters) => Promise<IdentityAttributeResult>;
24
+ requestOpenIdAttributes: (params: RequestOpenIdIdentityAttributesParameters) => Promise<IdentityAttributeResult>;
25
+ attributes: IdentityAttributeResult | null;
26
+ isRequestingAttributes: boolean;
27
+ attributeError: Error | null;
28
+ clearAttributes: () => void;
21
29
  }
22
30
  /**
23
31
  * Create authentication hooks for managing user sessions with Internet Identity.
@@ -1 +1 @@
1
- {"version":3,"file":"createAuthHooks.d.ts","sourceRoot":"","sources":["../src/createAuthHooks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAa,MAAM,kBAAkB,CAAA;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAA;IACjD,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAA;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,UAAU,CAAA;IAC/B,gBAAgB,EAAE,MAAM,SAAS,GAAG,IAAI,CAAA;IACxC,OAAO,EAAE,MAAM,aAAa,CAAA;CAC7B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,aAAa,KAC3B,qBAiGF,CAAA"}
1
+ {"version":3,"file":"createAuthHooks.d.ts","sourceRoot":"","sources":["../src/createAuthHooks.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,aAAa,EACb,UAAU,EAEV,0BAA0B,EAC1B,uBAAuB,EACvB,mCAAmC,EACnC,yCAAyC,EAC1C,MAAM,kBAAkB,CAAA;AACzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAEnD,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAAA;IACjD,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,0BAA0B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9D,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1D,eAAe,EAAE,OAAO,CAAA;IACxB,gBAAgB,EAAE,OAAO,CAAA;IACzB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAA;IAC3B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IACzB,KAAK,EAAE,KAAK,GAAG,SAAS,CAAA;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,UAAU,CAAA;IAC/B,gBAAgB,EAAE,MAAM,SAAS,GAAG,IAAI,CAAA;IACxC,OAAO,EAAE,MAAM,aAAa,CAAA;IAC5B,qBAAqB,EAAE,MAAM,2BAA2B,CAAA;CACzD;AAED,MAAM,WAAW,2BAA2B;IAC1C,iBAAiB,EAAE,CACjB,MAAM,EAAE,mCAAmC,KACxC,OAAO,CAAC,uBAAuB,CAAC,CAAA;IACrC,uBAAuB,EAAE,CACvB,MAAM,EAAE,yCAAyC,KAC9C,OAAO,CAAC,uBAAuB,CAAC,CAAA;IACrC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAA;IAC1C,sBAAsB,EAAE,OAAO,CAAA;IAC/B,cAAc,EAAE,KAAK,GAAG,IAAI,CAAA;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAA;CAC5B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,eAAe,GAC1B,eAAe,aAAa,KAC3B,qBA4JF,CAAA"}
@@ -1,4 +1,4 @@
1
- import { useSyncExternalStore, useEffect, useRef, useMemo } from "react";
1
+ import { useSyncExternalStore, useEffect, useRef, useMemo, useState, useCallback, } from "react";
2
2
  /**
3
3
  * Create authentication hooks for managing user sessions with Internet Identity.
4
4
  *
@@ -85,10 +85,60 @@ export const createAuthHooks = (clientManager) => {
85
85
  const { identity } = useAuthState();
86
86
  return identity ? identity.getPrincipal() : null;
87
87
  };
88
+ const useIdentityAttributes = () => {
89
+ const [attributes, setAttributes] = useState(null);
90
+ const [isRequestingAttributes, setIsRequestingAttributes] = useState(false);
91
+ const [attributeError, setAttributeError] = useState(null);
92
+ const requestAttributes = useCallback(async (params) => {
93
+ setIsRequestingAttributes(true);
94
+ setAttributeError(null);
95
+ try {
96
+ const result = await clientManager.requestIdentityAttributes(params);
97
+ setAttributes(result);
98
+ return result;
99
+ }
100
+ catch (error) {
101
+ setAttributeError(error);
102
+ throw error;
103
+ }
104
+ finally {
105
+ setIsRequestingAttributes(false);
106
+ }
107
+ }, []);
108
+ const requestOpenIdAttributes = useCallback(async (params) => {
109
+ setIsRequestingAttributes(true);
110
+ setAttributeError(null);
111
+ try {
112
+ const result = await clientManager.requestOpenIdIdentityAttributes(params);
113
+ setAttributes(result);
114
+ return result;
115
+ }
116
+ catch (error) {
117
+ setAttributeError(error);
118
+ throw error;
119
+ }
120
+ finally {
121
+ setIsRequestingAttributes(false);
122
+ }
123
+ }, []);
124
+ const clearAttributes = useCallback(() => {
125
+ setAttributes(null);
126
+ setAttributeError(null);
127
+ }, []);
128
+ return {
129
+ requestAttributes,
130
+ requestOpenIdAttributes,
131
+ attributes,
132
+ isRequestingAttributes,
133
+ attributeError,
134
+ clearAttributes,
135
+ };
136
+ };
88
137
  return {
89
138
  useAuth,
90
139
  useAgentState,
91
140
  useUserPrincipal,
141
+ useIdentityAttributes,
92
142
  };
93
143
  };
94
144
  //# sourceMappingURL=createAuthHooks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"createAuthHooks.js","sourceRoot":"","sources":["../src/createAuthHooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAuBxE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,aAA4B,EACL,EAAE;IACzB;;;OAGG;IACH,MAAM,aAAa,GAAG,GAAe,EAAE,CACrC,oBAAoB,CAClB,CAAC,QAAQ,EAAE,EAAE,CAAC,aAAa,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EACzD,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU;IAC9B,kDAAkD;IAClD,GAAG,EAAE,CAAC,aAAa,CAAC,UAAU,CAC/B,CAAA;IAEH;;;OAGG;IACH,MAAM,YAAY,GAAG,GAAc,EAAE,CACnC,oBAAoB,CAClB,CAAC,QAAQ,EAAE,EAAE,CAAC,aAAa,CAAC,kBAAkB,CAAC,QAAQ,CAAC,EACxD,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS;IAC7B,kDAAkD;IAClD,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,CAC9B,CAAA;IAEH;;;;;;;;;;;;;;;;;OAiBG;IACH,MAAM,OAAO,GAAG,GAAkB,EAAE;QAClC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,aAAa,CAAA;QACrD,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,KAAK,EAAE,GAC1D,YAAY,EAAE,CAAA;QAEhB,8DAA8D;QAC9D,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;QAEpC,6DAA6D;QAC7D,SAAS,CAAC,GAAG,EAAE;YACb,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC5B,cAAc,CAAC,OAAO,GAAG,IAAI,CAAA;gBAC7B,aAAa,CAAC,UAAU,EAAE,CAAA;YAC5B,CAAC;QACH,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,MAAM,SAAS,GAAG,OAAO,CACvB,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EACjD,CAAC,QAAQ,CAAC,CACX,CAAA;QAED,OAAO;YACL,YAAY;YACZ,KAAK;YACL,MAAM;YACN,eAAe;YACf,gBAAgB;YAChB,SAAS;YACT,QAAQ;YACR,KAAK;SACN,CAAA;IACH,CAAC,CAAA;IAED;;;;;;;;;;OAUG;IACH,MAAM,gBAAgB,GAAG,GAAqB,EAAE;QAC9C,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,CAAA;QACnC,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IAClD,CAAC,CAAA;IAED,OAAO;QACL,OAAO;QACP,aAAa;QACb,gBAAgB;KACjB,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"createAuthHooks.js","sourceRoot":"","sources":["../src/createAuthHooks.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ic-reactor/react",
3
- "version": "3.3.1",
3
+ "version": "3.5.0",
4
4
  "description": "IC Reactor React Library",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -42,29 +42,35 @@
42
42
  "author": "Behrad Deylami",
43
43
  "license": "MIT",
44
44
  "dependencies": {
45
- "@ic-reactor/core": "^3.3.1"
45
+ "@ic-reactor/core": "^3.5.0"
46
46
  },
47
47
  "peerDependencies": {
48
+ "@icp-sdk/auth": "^6.0.0",
48
49
  "@tanstack/react-query": "^5.0.0",
49
50
  "react": ">=18.0.0",
50
51
  "react-dom": ">=18.0.0"
51
52
  },
53
+ "peerDependenciesMeta": {
54
+ "@icp-sdk/auth": {
55
+ "optional": true
56
+ }
57
+ },
52
58
  "devDependencies": {
53
- "@icp-sdk/auth": "^5.0.0",
54
- "@icp-sdk/core": "^5.2.1",
55
- "@size-limit/preset-small-lib": "^12.0.1",
56
- "@tanstack/react-query": "^5.96.2",
59
+ "@icp-sdk/auth": "^6.0.0",
60
+ "@icp-sdk/core": "^5.3.1",
61
+ "@size-limit/preset-small-lib": "^12.1.0",
62
+ "@tanstack/react-query": "^5.100.5",
57
63
  "@testing-library/dom": "^10.4.1",
58
64
  "@testing-library/jest-dom": "^6.9.1",
59
65
  "@testing-library/react": "^16.3.2",
60
66
  "@types/react": "^19.2.14",
61
67
  "@types/react-dom": "^19.2.3",
62
68
  "fake-indexeddb": "^6.2.5",
63
- "jsdom": "^29.0.1",
64
- "react": "^19.2.4",
65
- "react-dom": "^19.2.4",
66
- "size-limit": "^12.0.1",
67
- "vitest": "^4.1.2"
69
+ "jsdom": "^29.1.0",
70
+ "react": "^19.2.5",
71
+ "react-dom": "^19.2.5",
72
+ "size-limit": "^12.1.0",
73
+ "vitest": "^4.1.5"
68
74
  },
69
75
  "size-limit": [
70
76
  {
@@ -1,12 +1,26 @@
1
- import { useSyncExternalStore, useEffect, useRef, useMemo } from "react"
2
- import { ClientManager, AgentState, AuthState } from "@ic-reactor/core"
3
- import { Principal } from "@icp-sdk/core/principal"
4
- import { Identity } from "@icp-sdk/core/agent"
5
- import { AuthClientLoginOptions } from "@icp-sdk/auth/client"
1
+ import {
2
+ useSyncExternalStore,
3
+ useEffect,
4
+ useRef,
5
+ useMemo,
6
+ useState,
7
+ useCallback,
8
+ } from "react"
9
+ import {
10
+ ClientManager,
11
+ AgentState,
12
+ AuthState,
13
+ ClientManagerSignInOptions,
14
+ IdentityAttributeResult,
15
+ RequestIdentityAttributesParameters,
16
+ RequestOpenIdIdentityAttributesParameters,
17
+ } from "@ic-reactor/core"
18
+ import type { Principal } from "@icp-sdk/core/principal"
19
+ import type { Identity } from "@icp-sdk/core/agent"
6
20
 
7
21
  export interface UseAuthReturn {
8
22
  authenticate: () => Promise<Identity | undefined>
9
- login: (options?: AuthClientLoginOptions) => Promise<void>
23
+ login: (options?: ClientManagerSignInOptions) => Promise<void>
10
24
  logout: (options?: { returnTo?: string }) => Promise<void>
11
25
  isAuthenticated: boolean
12
26
  isAuthenticating: boolean
@@ -19,6 +33,20 @@ export interface CreateAuthHooksReturn {
19
33
  useAgentState: () => AgentState
20
34
  useUserPrincipal: () => Principal | null
21
35
  useAuth: () => UseAuthReturn
36
+ useIdentityAttributes: () => UseIdentityAttributesReturn
37
+ }
38
+
39
+ export interface UseIdentityAttributesReturn {
40
+ requestAttributes: (
41
+ params: RequestIdentityAttributesParameters
42
+ ) => Promise<IdentityAttributeResult>
43
+ requestOpenIdAttributes: (
44
+ params: RequestOpenIdIdentityAttributesParameters
45
+ ) => Promise<IdentityAttributeResult>
46
+ attributes: IdentityAttributeResult | null
47
+ isRequestingAttributes: boolean
48
+ attributeError: Error | null
49
+ clearAttributes: () => void
22
50
  }
23
51
 
24
52
  /**
@@ -129,9 +157,68 @@ export const createAuthHooks = (
129
157
  return identity ? identity.getPrincipal() : null
130
158
  }
131
159
 
160
+ const useIdentityAttributes = (): UseIdentityAttributesReturn => {
161
+ const [attributes, setAttributes] =
162
+ useState<IdentityAttributeResult | null>(null)
163
+ const [isRequestingAttributes, setIsRequestingAttributes] = useState(false)
164
+ const [attributeError, setAttributeError] = useState<Error | null>(null)
165
+
166
+ const requestAttributes = useCallback(
167
+ async (params: RequestIdentityAttributesParameters) => {
168
+ setIsRequestingAttributes(true)
169
+ setAttributeError(null)
170
+ try {
171
+ const result = await clientManager.requestIdentityAttributes(params)
172
+ setAttributes(result)
173
+ return result
174
+ } catch (error) {
175
+ setAttributeError(error as Error)
176
+ throw error
177
+ } finally {
178
+ setIsRequestingAttributes(false)
179
+ }
180
+ },
181
+ []
182
+ )
183
+
184
+ const requestOpenIdAttributes = useCallback(
185
+ async (params: RequestOpenIdIdentityAttributesParameters) => {
186
+ setIsRequestingAttributes(true)
187
+ setAttributeError(null)
188
+ try {
189
+ const result =
190
+ await clientManager.requestOpenIdIdentityAttributes(params)
191
+ setAttributes(result)
192
+ return result
193
+ } catch (error) {
194
+ setAttributeError(error as Error)
195
+ throw error
196
+ } finally {
197
+ setIsRequestingAttributes(false)
198
+ }
199
+ },
200
+ []
201
+ )
202
+
203
+ const clearAttributes = useCallback(() => {
204
+ setAttributes(null)
205
+ setAttributeError(null)
206
+ }, [])
207
+
208
+ return {
209
+ requestAttributes,
210
+ requestOpenIdAttributes,
211
+ attributes,
212
+ isRequestingAttributes,
213
+ attributeError,
214
+ clearAttributes,
215
+ }
216
+ }
217
+
132
218
  return {
133
219
  useAuth,
134
220
  useAgentState,
135
221
  useUserPrincipal,
222
+ useIdentityAttributes,
136
223
  }
137
224
  }