@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.
- package/dist/hooks/useTokenLifecycle/types.d.ts +23 -9
- package/dist/hooks/useTokenLifecycle/useTokenLifecycle.d.ts +16 -4
- package/dist/hooks/useTokenLifecycle/useTokenLifecycle.js +18 -6
- package/dist/hooks/useUserMovements/useUserMovements.js +5 -9
- package/dist/hooks/useUserOrders/useUserOrders.js +5 -10
- package/package.json +3 -3
|
@@ -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
|
|
10
|
+
/** Enable automatic session refresh before expiry (default: true) */
|
|
4
11
|
autoRefresh?: boolean;
|
|
5
|
-
/**
|
|
12
|
+
/** Persist the session in localStorage so it survives reloads (default: true) */
|
|
6
13
|
persistTokens?: boolean;
|
|
7
|
-
/** Buffer time in seconds before
|
|
14
|
+
/** Buffer time in seconds before session expiry to trigger a refresh (default: 300 = 5 minutes) */
|
|
8
15
|
refreshBufferSeconds?: number;
|
|
9
|
-
/** Callback when
|
|
16
|
+
/** Callback when a session refresh fails */
|
|
10
17
|
onRefreshError?: (error: Error) => void;
|
|
11
|
-
/** Callback when
|
|
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
|
-
/**
|
|
29
|
+
/** Start managing a session from an auth state (persists it and schedules auto-refresh) */
|
|
16
30
|
initializeTokens: (authState: AuthState) => void;
|
|
17
|
-
/**
|
|
31
|
+
/** Stop managing the session, cancel scheduled refreshes, and clear persistence */
|
|
18
32
|
clearTokens: () => void;
|
|
19
|
-
/** Manually
|
|
33
|
+
/** Manually extend the session's expiry now */
|
|
20
34
|
refreshTokens: () => Promise<AuthState | null>;
|
|
21
|
-
/**
|
|
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
|
|
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
|
|
8
|
-
* @returns
|
|
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('
|
|
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
|
|
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
|
|
9
|
-
* @returns
|
|
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('
|
|
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
|
|
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
|
|
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
|
-
//
|
|
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
|
|
86
|
-
for (const movement of
|
|
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
|
-
|
|
85
|
+
dedupedMovements.push(movement);
|
|
90
86
|
}
|
|
91
87
|
}
|
|
92
|
-
setMovements(
|
|
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
|
-
//
|
|
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
|
|
38
|
-
for (const order of
|
|
32
|
+
const dedupedOrders = [];
|
|
33
|
+
for (const order of response.orders) {
|
|
39
34
|
if (!seenIds.has(order.id)) {
|
|
40
35
|
seenIds.add(order.id);
|
|
41
|
-
|
|
36
|
+
dedupedOrders.push(order);
|
|
42
37
|
}
|
|
43
38
|
}
|
|
44
|
-
setOrders(
|
|
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.
|
|
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.
|
|
24
|
-
"@0xmonaco/types": "1.0.
|
|
23
|
+
"@0xmonaco/core": "1.0.39",
|
|
24
|
+
"@0xmonaco/types": "1.0.39"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/react": "^19.1.12",
|