@ic-reactor/react 0.4.1 → 0.4.3

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
@@ -37,11 +37,12 @@ import { createReActor } from "@ic-reactor/react"
37
37
 
38
38
  type Actor = typeof actor
39
39
 
40
- export const { useActorStore, useQueryCall } = createReActor<Actor>({
41
- canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",
42
- idlFactory,
43
- host: "https://localhost:4943",
44
- })
40
+ export const { useActorStore, useAuthClient, useQueryCall } =
41
+ createReActor<Actor>({
42
+ canisterId: "rrkah-fqaaa-aaaaa-aaaaq-cai",
43
+ idlFactory,
44
+ host: "https://localhost:4943",
45
+ })
45
46
  ```
46
47
 
47
48
  Then, use the `useQueryCall` hook to call your canister method:
@@ -54,7 +55,11 @@ const Balance = ({ principal }) => {
54
55
  const { call, data, loading, error } = useQueryCall({
55
56
  functionName: "get_balance",
56
57
  args: [principal],
57
- callOnMount: true,
58
+ refetchInterval: 1000,
59
+ refetchOnMount: true,
60
+ onLoading: () => console.log("Loading..."),
61
+ onSuccess: (data) => console.log("Success!", data),
62
+ onError: (error) => console.log("Error!", error),
58
63
  })
59
64
 
60
65
  return (
@@ -72,6 +77,61 @@ const Balance = ({ principal }) => {
72
77
  export default Balance
73
78
  ```
74
79
 
80
+ ## Authentication
81
+
82
+ `@ic-reactor/react` provides a custom hook for managing authentication with the IC blockchain. To use it, first create an authentication declaration file:
83
+
84
+ ```jsx
85
+ // Login.tsx
86
+ import { useAuthClient } from "./store"
87
+
88
+ const Login = () => {
89
+ const {
90
+ login,
91
+ logout,
92
+ loginLoading,
93
+ loginError,
94
+ identity,
95
+ authenticating,
96
+ authenticated,
97
+ } = useAuthClient()
98
+
99
+ return (
100
+ <div>
101
+ <h2>Login:</h2>
102
+ <div>
103
+ {loginLoading && <div>Loading...</div>}
104
+ {loginError ? <div>{JSON.stringify(loginError)}</div> : null}
105
+ {identity && <div>{identity.getPrincipal().toText()}</div>}
106
+ </div>
107
+ {authenticated ? (
108
+ <div>
109
+ <button onClick={() => logout()}>Logout</button>
110
+ </div>
111
+ ) : (
112
+ <div>
113
+ <button
114
+ onClick={() =>
115
+ login({
116
+ identityProvider:
117
+ process.env.DFX_NETWORK === "ic"
118
+ ? "https://identity.ic0.app/#authorize"
119
+ : "http://rdmx6-jaaaa-aaaaa-aaadq-cai.localhost:4943/#authorize",
120
+ })
121
+ }
122
+ disabled={authenticating}
123
+ >
124
+ Login
125
+ </button>
126
+ </div>
127
+ )}
128
+ </div>
129
+ )
130
+ }
131
+
132
+ export default Login
133
+ ```
134
+
75
135
  ## API Reference
76
136
 
77
137
  The library provides various hooks and utilities for interacting with IC actors:
@@ -1,10 +1,11 @@
1
1
  import type { AuthClientLoginOptions } from "@dfinity/auth-client";
2
2
  import type { AgentManager } from "@ic-reactor/store";
3
+ import { AuthArgs } from "../types";
3
4
  export type AuthHooks = ReturnType<typeof getAuthHooks>;
4
5
  export declare const getAuthHooks: (agentManager: AgentManager) => {
5
6
  useAgentManager: () => AgentManager;
6
7
  useAuthStore: () => import("@ic-reactor/store").AgentAuthState;
7
- useAuthClient: () => {
8
+ useAuthClient: ({ onAuthentication, onAuthenticationSuccess, onAuthenticationFailure, onLogin, onLoginSuccess, onLoginError, onLoggedOut, }?: AuthArgs) => {
8
9
  authClient: import("@dfinity/auth-client").AuthClient | null;
9
10
  authenticated: boolean;
10
11
  authenticating: boolean;
@@ -13,7 +13,7 @@ exports.getAuthHooks = void 0;
13
13
  const react_1 = require("react");
14
14
  const zustand_1 = require("zustand");
15
15
  const getAuthHooks = (agentManager) => {
16
- const { authenticate, authStore } = agentManager;
16
+ const { authenticate: authenticator, authStore, isLocalEnv } = agentManager;
17
17
  const useAgentManager = () => {
18
18
  return agentManager;
19
19
  };
@@ -21,35 +21,63 @@ const getAuthHooks = (agentManager) => {
21
21
  const authState = (0, zustand_1.useStore)(authStore, (state) => state);
22
22
  return authState;
23
23
  };
24
- const useAuthClient = () => {
24
+ const useAuthClient = ({ onAuthentication, onAuthenticationSuccess, onAuthenticationFailure, onLogin, onLoginSuccess, onLoginError, onLoggedOut, } = {}) => {
25
25
  const [loginLoading, setLoginLoading] = (0, react_1.useState)(false);
26
26
  const [loginError, setLoginError] = (0, react_1.useState)(null);
27
27
  const { authClient, authenticated, authenticating, identity } = useAuthStore();
28
- const login = (options) => __awaiter(void 0, void 0, void 0, function* () {
28
+ const authenticate = (0, react_1.useCallback)(() => __awaiter(void 0, void 0, void 0, function* () {
29
+ onAuthentication === null || onAuthentication === void 0 ? void 0 : onAuthentication();
30
+ authenticator()
31
+ .then((identity) => {
32
+ onAuthenticationSuccess === null || onAuthenticationSuccess === void 0 ? void 0 : onAuthenticationSuccess(identity);
33
+ })
34
+ .catch((e) => {
35
+ onAuthenticationFailure === null || onAuthenticationFailure === void 0 ? void 0 : onAuthenticationFailure(e);
36
+ });
37
+ }), [
38
+ authenticator,
39
+ onAuthentication,
40
+ onAuthenticationSuccess,
41
+ onAuthenticationFailure,
42
+ ]);
43
+ const login = (0, react_1.useCallback)((options) => __awaiter(void 0, void 0, void 0, function* () {
29
44
  setLoginLoading(true);
30
45
  setLoginError(null);
46
+ onLogin === null || onLogin === void 0 ? void 0 : onLogin();
31
47
  try {
32
- yield (authClient === null || authClient === void 0 ? void 0 : authClient.login(Object.assign(Object.assign({}, options), { onSuccess: () => __awaiter(void 0, void 0, void 0, function* () {
48
+ if (!authClient) {
49
+ throw new Error("Auth client not initialized");
50
+ }
51
+ yield authClient.login(Object.assign(Object.assign({ identityProvider: isLocalEnv
52
+ ? "https://identity.ic0.app/#authorize"
53
+ : "http://rdmx6-jaaaa-aaaaa-aaadq-cai.localhost:4943/#authorize" }, options), { onSuccess: () => __awaiter(void 0, void 0, void 0, function* () {
33
54
  var _a;
34
55
  setLoginLoading(false);
35
56
  yield authenticate();
36
57
  (_a = options === null || options === void 0 ? void 0 : options.onSuccess) === null || _a === void 0 ? void 0 : _a.call(options);
58
+ onLoginSuccess === null || onLoginSuccess === void 0 ? void 0 : onLoginSuccess();
37
59
  }), onError: (e) => {
38
60
  var _a;
39
61
  setLoginError(e);
40
62
  setLoginLoading(false);
41
63
  (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, e);
42
- } })));
64
+ onLoginError === null || onLoginError === void 0 ? void 0 : onLoginError(e);
65
+ } }));
43
66
  }
44
67
  catch (e) {
45
68
  setLoginLoading(false);
46
69
  setLoginError(e);
70
+ onLoginError === null || onLoginError === void 0 ? void 0 : onLoginError(e);
47
71
  }
48
- });
49
- const logout = (options) => __awaiter(void 0, void 0, void 0, function* () {
50
- yield (authClient === null || authClient === void 0 ? void 0 : authClient.logout(options));
72
+ }), [authClient, onLogin, onLoginSuccess, onLoginError, isLocalEnv]);
73
+ const logout = (0, react_1.useCallback)((options) => __awaiter(void 0, void 0, void 0, function* () {
74
+ if (!authClient) {
75
+ throw new Error("Auth client not initialized");
76
+ }
77
+ yield authClient.logout(options);
51
78
  yield authenticate();
52
- });
79
+ onLoggedOut === null || onLoggedOut === void 0 ? void 0 : onLoggedOut();
80
+ }), [authClient, onLoggedOut]);
53
81
  (0, react_1.useEffect)(() => {
54
82
  if (!authClient && !authenticating) {
55
83
  authenticate();
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export * from "./context/actor";
7
7
  export declare const createReActor: <A extends unknown>({ isLocalEnv, ...options }: CreateReActorOptions) => ActorHooks<A> & {
8
8
  useAgentManager: () => import("@ic-reactor/store").AgentManager;
9
9
  useAuthStore: () => import("@ic-reactor/store").AgentAuthState;
10
- useAuthClient: () => {
10
+ useAuthClient: ({ onAuthentication, onAuthenticationSuccess, onAuthenticationFailure, onLogin, onLoginSuccess, onLoginError, onLoggedOut, }?: import("./types").AuthArgs) => {
11
11
  authClient: import("@dfinity/auth-client").AuthClient | null;
12
12
  authenticated: boolean;
13
13
  authenticating: boolean;
package/dist/types.d.ts CHANGED
@@ -1,6 +1,15 @@
1
- import type { ExtractActorMethodArgs, ExtractActorMethodReturnType, ServiceMethodType } from "@ic-reactor/store";
1
+ import type { ExtractActorMethodArgs, ExtractActorMethodReturnType, Identity, ServiceMethodType } from "@ic-reactor/store";
2
2
  export type * from "@ic-reactor/store";
3
3
  export type * from "@ic-reactor/store/dist/actor/types";
4
+ export type AuthArgs = {
5
+ onAuthentication?: () => void;
6
+ onAuthenticationSuccess?: (identity: Identity) => void;
7
+ onAuthenticationFailure?: (error: Error | unknown | null) => void;
8
+ onLoginSuccess?: () => void;
9
+ onLoginError?: (error: Error | unknown | null) => void;
10
+ onLogin?: () => void;
11
+ onLoggedOut?: () => void;
12
+ };
4
13
  export type ActorCallArgs<A, M extends keyof A> = {
5
14
  functionName: M & string;
6
15
  args?: ExtractActorMethodArgs<A[M]>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ic-reactor/react",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "A React library for interacting with Dfinity actors",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  "node": ">=10"
36
36
  },
37
37
  "dependencies": {
38
- "@ic-reactor/store": "^0.4.1",
38
+ "@ic-reactor/store": "^0.4.3",
39
39
  "zustand-utils": "^1.3"
40
40
  },
41
41
  "peerDependencies": {
@@ -48,5 +48,5 @@
48
48
  "react": ">=16.8",
49
49
  "zustand": "4.4"
50
50
  },
51
- "gitHead": "1086988151f4b52e95db045856a125b847d66639"
51
+ "gitHead": "b7de729b76ac8e1db098bf2eadf975cfb4a57fa2"
52
52
  }