@0xmonaco/react 1.0.38 → 1.0.39

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.
@@ -1,23 +1,37 @@
1
1
  import type { AuthState } from "@0xmonaco/types";
2
+ /**
3
+ * Configuration for the session lifecycle hook.
4
+ *
5
+ * The `persistTokens` field name is a retained legacy compatibility name; it
6
+ * persists the ed25519 session key (the `AuthState`), not any JWT or bearer
7
+ * credential.
8
+ */
2
9
  export interface TokenLifecycleConfig {
3
- /** Enable automatic token refresh (default: true) */
10
+ /** Enable automatic session refresh before expiry (default: true) */
4
11
  autoRefresh?: boolean;
5
- /** Enable token persistence in localStorage (default: true) */
12
+ /** Persist the session in localStorage so it survives reloads (default: true) */
6
13
  persistTokens?: boolean;
7
- /** Buffer time in seconds before token expiry to trigger refresh (default: 300 = 5 minutes) */
14
+ /** Buffer time in seconds before session expiry to trigger a refresh (default: 300 = 5 minutes) */
8
15
  refreshBufferSeconds?: number;
9
- /** Callback when token refresh fails */
16
+ /** Callback when a session refresh fails */
10
17
  onRefreshError?: (error: Error) => void;
11
- /** Callback when token is refreshed successfully */
18
+ /** Callback when the session is refreshed successfully */
12
19
  onRefreshSuccess?: (authState: AuthState) => void;
13
20
  }
21
+ /**
22
+ * Return shape of the session lifecycle hook.
23
+ *
24
+ * The `initializeTokens`, `clearTokens`, `refreshTokens`, and `isTokenExpired`
25
+ * member names are retained legacy compatibility names; they all act on the
26
+ * session key.
27
+ */
14
28
  export interface UseTokenLifecycleReturn {
15
- /** Initialize token lifecycle with auth state */
29
+ /** Start managing a session from an auth state (persists it and schedules auto-refresh) */
16
30
  initializeTokens: (authState: AuthState) => void;
17
- /** Clear tokens and stop lifecycle management */
31
+ /** Stop managing the session, cancel scheduled refreshes, and clear persistence */
18
32
  clearTokens: () => void;
19
- /** Manually trigger token refresh */
33
+ /** Manually extend the session's expiry now */
20
34
  refreshTokens: () => Promise<AuthState | null>;
21
- /** Check if token is expired or near expiry */
35
+ /** Whether the session is expired or within the refresh buffer of expiry */
22
36
  isTokenExpired: (authState: AuthState | null) => boolean;
23
37
  }
@@ -1,11 +1,23 @@
1
1
  import type { MonacoSDK } from "@0xmonaco/core";
2
2
  import type { TokenLifecycleConfig, UseTokenLifecycleReturn } from "./types";
3
3
  /**
4
- * Hook for managing token lifecycle including automatic refresh and persistence
4
+ * Hook for managing the authenticated session lifecycle, including automatic
5
+ * refresh and persistence.
6
+ *
7
+ * Monaco authenticates with a wallet-authorized ed25519 session key (the
8
+ * `AuthState` returned by `login()`), not a JWT or bearer credential. This hook
9
+ * extends that session's expiry via `sdk.refreshAuth()` and persists the
10
+ * resulting `AuthState`; there is no separate access or refresh credential.
11
+ *
12
+ * The exported members and config fields listed here — `useTokenLifecycle`,
13
+ * `TokenLifecycleConfig`, `persistTokens`, `initializeTokens`, `clearTokens`,
14
+ * `refreshTokens`, `isTokenExpired`, and the like — are retained legacy
15
+ * compatibility names kept stable for existing consumers; they all operate on
16
+ * the session key.
5
17
  *
6
18
  * @param sdk - Monaco SDK instance
7
- * @param config - Configuration options for token lifecycle
8
- * @returns Token lifecycle management functions
19
+ * @param config - Configuration options for the session lifecycle
20
+ * @returns Session lifecycle management functions
9
21
  *
10
22
  * @example
11
23
  * ```tsx
@@ -13,7 +25,7 @@ import type { TokenLifecycleConfig, UseTokenLifecycleReturn } from "./types";
13
25
  * autoRefresh: true,
14
26
  * persistTokens: true,
15
27
  * refreshBufferSeconds: 300, // 5 minutes
16
- * onRefreshError: (error) => console.error('Token refresh failed:', error),
28
+ * onRefreshError: (error) => console.error('Session refresh failed:', error),
17
29
  * });
18
30
  * ```
19
31
  */
@@ -2,11 +2,23 @@ import { useCallback, useEffect, useMemo, useRef } from "react";
2
2
  import { clearAuthState, getTimeUntilExpiry, isTokenExpired, saveAuthState } from "../../utils";
3
3
  import { validateRefreshBuffer } from "./utils";
4
4
  /**
5
- * Hook for managing token lifecycle including automatic refresh and persistence
5
+ * Hook for managing the authenticated session lifecycle, including automatic
6
+ * refresh and persistence.
7
+ *
8
+ * Monaco authenticates with a wallet-authorized ed25519 session key (the
9
+ * `AuthState` returned by `login()`), not a JWT or bearer credential. This hook
10
+ * extends that session's expiry via `sdk.refreshAuth()` and persists the
11
+ * resulting `AuthState`; there is no separate access or refresh credential.
12
+ *
13
+ * The exported members and config fields listed here — `useTokenLifecycle`,
14
+ * `TokenLifecycleConfig`, `persistTokens`, `initializeTokens`, `clearTokens`,
15
+ * `refreshTokens`, `isTokenExpired`, and the like — are retained legacy
16
+ * compatibility names kept stable for existing consumers; they all operate on
17
+ * the session key.
6
18
  *
7
19
  * @param sdk - Monaco SDK instance
8
- * @param config - Configuration options for token lifecycle
9
- * @returns Token lifecycle management functions
20
+ * @param config - Configuration options for the session lifecycle
21
+ * @returns Session lifecycle management functions
10
22
  *
11
23
  * @example
12
24
  * ```tsx
@@ -14,7 +26,7 @@ import { validateRefreshBuffer } from "./utils";
14
26
  * autoRefresh: true,
15
27
  * persistTokens: true,
16
28
  * refreshBufferSeconds: 300, // 5 minutes
17
- * onRefreshError: (error) => console.error('Token refresh failed:', error),
29
+ * onRefreshError: (error) => console.error('Session refresh failed:', error),
18
30
  * });
19
31
  * ```
20
32
  */
@@ -61,7 +73,7 @@ export const useTokenLifecycle = (sdk, config = {}) => {
61
73
  try {
62
74
  // Re-check SDK in case it became null during async operations
63
75
  if (!sdk) {
64
- console.warn("SDK became null during token refresh");
76
+ console.warn("SDK became null during session refresh");
65
77
  return null;
66
78
  }
67
79
  const newAuthState = await sdk.refreshAuth();
@@ -75,7 +87,7 @@ export const useTokenLifecycle = (sdk, config = {}) => {
75
87
  }
76
88
  catch (error) {
77
89
  const err = error instanceof Error ? error : new Error(String(error));
78
- console.error("Failed to refresh tokens:", err);
90
+ console.error("Failed to refresh session:", err);
79
91
  if (persistTokens) {
80
92
  clearAuthState();
81
93
  }
@@ -75,21 +75,17 @@ export function useUserMovements(options = {}) {
75
75
  sdk.profile
76
76
  .getPaginatedUserMovements({ pageSize: requestLimit, entryType, transactionType, assetId })
77
77
  .then(async (response) => {
78
- // Combine latest_movements (from the live engine cache) with movements (from PostgreSQL)
79
- // latest_movements contains real-time data that may not yet be in PostgreSQL
80
- // Deduplicate by id, preferring latest_movements (newer data)
81
- const latestMovements = (response.latest_movements || []).map((m) => ledgerMovementToEvent(m, userId));
78
+ // Deduplicate the paginated movements by id, keeping the first occurrence.
82
79
  const historicalMovements = response.movements.map((m) => ledgerMovementToEvent(m, userId));
83
- // Merge: latest_movements first, then historical, deduplicated by id
84
80
  const seenIds = new Set();
85
- const mergedMovements = [];
86
- for (const movement of [...latestMovements, ...historicalMovements]) {
81
+ const dedupedMovements = [];
82
+ for (const movement of historicalMovements) {
87
83
  if (!seenIds.has(movement.data.id)) {
88
84
  seenIds.add(movement.data.id);
89
- mergedMovements.push(movement);
85
+ dedupedMovements.push(movement);
90
86
  }
91
87
  }
92
- setMovements(mergedMovements.slice(0, sliceSize));
88
+ setMovements(dedupedMovements.slice(0, sliceSize));
93
89
  // Subscribe to WebSocket movement updates after initial data is loaded
94
90
  // This prevents race conditions where WS events could be overwritten by REST response
95
91
  try {
@@ -27,21 +27,16 @@ export function useUserOrders(maxOrders = 50) {
27
27
  pageSize: maxOrders,
28
28
  pageToken: "",
29
29
  });
30
- // Combine latest_orders (from the live engine cache) with orders (from PostgreSQL)
31
- // latest_orders contains real-time data that may not yet be in PostgreSQL
32
- // Deduplicate by id, preferring latest_orders (newer data)
33
- const latestOrders = response.latest_orders || [];
34
- const historicalOrders = response.orders;
35
- // Merge: latest_orders first, then historical, deduplicated by id
30
+ // Deduplicate the paginated orders by id, keeping the first occurrence.
36
31
  const seenIds = new Set();
37
- const mergedOrders = [];
38
- for (const order of [...latestOrders, ...historicalOrders]) {
32
+ const dedupedOrders = [];
33
+ for (const order of response.orders) {
39
34
  if (!seenIds.has(order.id)) {
40
35
  seenIds.add(order.id);
41
- mergedOrders.push(order);
36
+ dedupedOrders.push(order);
42
37
  }
43
38
  }
44
- setOrders(mergedOrders.slice(0, maxOrders));
39
+ setOrders(dedupedOrders.slice(0, maxOrders));
45
40
  }
46
41
  catch (err) {
47
42
  setError(err instanceof Error ? err : new Error(String(err)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xmonaco/react",
3
- "version": "1.0.38",
3
+ "version": "1.0.39",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,8 +20,8 @@
20
20
  "lint": "biome lint ."
21
21
  },
22
22
  "dependencies": {
23
- "@0xmonaco/core": "1.0.38",
24
- "@0xmonaco/types": "1.0.38"
23
+ "@0xmonaco/core": "1.0.39",
24
+ "@0xmonaco/types": "1.0.39"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@types/react": "^19.1.12",