@0xmonaco/react 0.7.6 → 0.7.7

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 (109) hide show
  1. package/package.json +3 -3
  2. package/dist/hooks/index.d.ts +0 -15
  3. package/dist/hooks/index.js +0 -15
  4. package/dist/hooks/useAuth/index.d.ts +0 -2
  5. package/dist/hooks/useAuth/index.js +0 -1
  6. package/dist/hooks/useAuth/types.d.ts +0 -30
  7. package/dist/hooks/useAuth/types.js +0 -0
  8. package/dist/hooks/useAuth/useAuth.d.ts +0 -2
  9. package/dist/hooks/useAuth/useAuth.js +0 -145
  10. package/dist/hooks/useFees/index.d.ts +0 -2
  11. package/dist/hooks/useFees/index.js +0 -1
  12. package/dist/hooks/useFees/types.d.ts +0 -5
  13. package/dist/hooks/useFees/types.js +0 -0
  14. package/dist/hooks/useFees/useFees.d.ts +0 -2
  15. package/dist/hooks/useFees/useFees.js +0 -14
  16. package/dist/hooks/useMarket/index.d.ts +0 -2
  17. package/dist/hooks/useMarket/index.js +0 -1
  18. package/dist/hooks/useMarket/types.d.ts +0 -30
  19. package/dist/hooks/useMarket/types.js +0 -0
  20. package/dist/hooks/useMarket/useMarket.d.ts +0 -2
  21. package/dist/hooks/useMarket/useMarket.js +0 -92
  22. package/dist/hooks/useMonaco/index.d.ts +0 -2
  23. package/dist/hooks/useMonaco/index.js +0 -1
  24. package/dist/hooks/useMonaco/types.d.ts +0 -13
  25. package/dist/hooks/useMonaco/types.js +0 -0
  26. package/dist/hooks/useMonaco/useMonaco.d.ts +0 -2
  27. package/dist/hooks/useMonaco/useMonaco.js +0 -13
  28. package/dist/hooks/useOHLCV/index.d.ts +0 -2
  29. package/dist/hooks/useOHLCV/index.js +0 -2
  30. package/dist/hooks/useOHLCV/types.d.ts +0 -29
  31. package/dist/hooks/useOHLCV/types.js +0 -0
  32. package/dist/hooks/useOHLCV/useOHLCV.d.ts +0 -11
  33. package/dist/hooks/useOHLCV/useOHLCV.js +0 -76
  34. package/dist/hooks/useOrderbook/index.d.ts +0 -2
  35. package/dist/hooks/useOrderbook/index.js +0 -1
  36. package/dist/hooks/useOrderbook/types.d.ts +0 -27
  37. package/dist/hooks/useOrderbook/types.js +0 -0
  38. package/dist/hooks/useOrderbook/useOrderbook.d.ts +0 -3
  39. package/dist/hooks/useOrderbook/useOrderbook.js +0 -31
  40. package/dist/hooks/usePositions/index.d.ts +0 -2
  41. package/dist/hooks/usePositions/index.js +0 -1
  42. package/dist/hooks/usePositions/types.d.ts +0 -11
  43. package/dist/hooks/usePositions/types.js +0 -0
  44. package/dist/hooks/usePositions/usePositions.d.ts +0 -2
  45. package/dist/hooks/usePositions/usePositions.js +0 -65
  46. package/dist/hooks/useProfile/index.d.ts +0 -2
  47. package/dist/hooks/useProfile/index.js +0 -1
  48. package/dist/hooks/useProfile/types.d.ts +0 -23
  49. package/dist/hooks/useProfile/types.js +0 -0
  50. package/dist/hooks/useProfile/useProfile.d.ts +0 -2
  51. package/dist/hooks/useProfile/useProfile.js +0 -128
  52. package/dist/hooks/useTokenLifecycle/index.d.ts +0 -2
  53. package/dist/hooks/useTokenLifecycle/index.js +0 -1
  54. package/dist/hooks/useTokenLifecycle/types.d.ts +0 -23
  55. package/dist/hooks/useTokenLifecycle/types.js +0 -0
  56. package/dist/hooks/useTokenLifecycle/useTokenLifecycle.d.ts +0 -20
  57. package/dist/hooks/useTokenLifecycle/useTokenLifecycle.js +0 -125
  58. package/dist/hooks/useTokenLifecycle/utils.d.ts +0 -7
  59. package/dist/hooks/useTokenLifecycle/utils.js +0 -15
  60. package/dist/hooks/useTrade/index.d.ts +0 -2
  61. package/dist/hooks/useTrade/index.js +0 -1
  62. package/dist/hooks/useTrade/types.d.ts +0 -49
  63. package/dist/hooks/useTrade/types.js +0 -0
  64. package/dist/hooks/useTrade/useTrade.d.ts +0 -2
  65. package/dist/hooks/useTrade/useTrade.js +0 -132
  66. package/dist/hooks/useTradeFeed/index.d.ts +0 -2
  67. package/dist/hooks/useTradeFeed/index.js +0 -2
  68. package/dist/hooks/useTradeFeed/types.d.ts +0 -14
  69. package/dist/hooks/useTradeFeed/types.js +0 -0
  70. package/dist/hooks/useTradeFeed/useTradeFeed.d.ts +0 -12
  71. package/dist/hooks/useTradeFeed/useTradeFeed.js +0 -32
  72. package/dist/hooks/useUserBalances/index.d.ts +0 -2
  73. package/dist/hooks/useUserBalances/index.js +0 -2
  74. package/dist/hooks/useUserBalances/types.d.ts +0 -18
  75. package/dist/hooks/useUserBalances/types.js +0 -0
  76. package/dist/hooks/useUserBalances/useUserBalances.d.ts +0 -9
  77. package/dist/hooks/useUserBalances/useUserBalances.js +0 -171
  78. package/dist/hooks/useUserMovements/index.d.ts +0 -2
  79. package/dist/hooks/useUserMovements/index.js +0 -2
  80. package/dist/hooks/useUserMovements/types.d.ts +0 -23
  81. package/dist/hooks/useUserMovements/types.js +0 -0
  82. package/dist/hooks/useUserMovements/useUserMovements.d.ts +0 -18
  83. package/dist/hooks/useUserMovements/useUserMovements.js +0 -122
  84. package/dist/hooks/useUserOrders/index.d.ts +0 -2
  85. package/dist/hooks/useUserOrders/index.js +0 -2
  86. package/dist/hooks/useUserOrders/types.d.ts +0 -18
  87. package/dist/hooks/useUserOrders/types.js +0 -0
  88. package/dist/hooks/useUserOrders/useUserOrders.d.ts +0 -11
  89. package/dist/hooks/useUserOrders/useUserOrders.js +0 -191
  90. package/dist/hooks/useVault/index.d.ts +0 -2
  91. package/dist/hooks/useVault/index.js +0 -1
  92. package/dist/hooks/useVault/types.d.ts +0 -15
  93. package/dist/hooks/useVault/types.js +0 -0
  94. package/dist/hooks/useVault/useVault.d.ts +0 -2
  95. package/dist/hooks/useVault/useVault.js +0 -66
  96. package/dist/index.d.ts +0 -3
  97. package/dist/index.js +0 -3
  98. package/dist/provider/MonacoProvider.d.ts +0 -3
  99. package/dist/provider/MonacoProvider.js +0 -142
  100. package/dist/provider/TradeFeedProvider.d.ts +0 -22
  101. package/dist/provider/TradeFeedProvider.js +0 -143
  102. package/dist/provider/index.d.ts +0 -3
  103. package/dist/provider/index.js +0 -3
  104. package/dist/provider/types.d.ts +0 -49
  105. package/dist/provider/types.js +0 -9
  106. package/dist/utils/index.d.ts +0 -1
  107. package/dist/utils/index.js +0 -1
  108. package/dist/utils/tokenStorage.d.ts +0 -38
  109. package/dist/utils/tokenStorage.js +0 -102
@@ -1,132 +0,0 @@
1
- import { useCallback } from "react";
2
- import { useMonacoSDK } from "../useMonaco";
3
- export const useTrade = () => {
4
- const { sdk } = useMonacoSDK();
5
- const placeLimitOrder = useCallback(async (tradingPairId, side, quantity, price, options) => {
6
- if (!sdk)
7
- throw new Error("SDK not available");
8
- if (!tradingPairId?.trim())
9
- throw new Error("Trading pair ID is required and cannot be empty");
10
- if (!side)
11
- throw new Error("Order side is required");
12
- if (!quantity?.trim())
13
- throw new Error("Quantity is required and cannot be empty");
14
- if (!price?.trim())
15
- throw new Error("Price is required and cannot be empty");
16
- if (Number(quantity) <= 0)
17
- throw new Error("Quantity must be greater than 0");
18
- if (Number(price) <= 0)
19
- throw new Error("Price must be greater than 0");
20
- return await sdk.trading.placeLimitOrder(tradingPairId, side, quantity, price, options);
21
- }, [sdk]);
22
- const placeMarketOrder = useCallback(async (tradingPairId, side, quantity, options) => {
23
- if (!sdk)
24
- throw new Error("SDK not available");
25
- if (!tradingPairId?.trim())
26
- throw new Error("Trading pair ID is required and cannot be empty");
27
- if (!side)
28
- throw new Error("Order side is required");
29
- if (!quantity?.trim())
30
- throw new Error("Quantity is required and cannot be empty");
31
- if (Number(quantity) <= 0)
32
- throw new Error("Quantity must be greater than 0");
33
- return await sdk.trading.placeMarketOrder(tradingPairId, side, quantity, options);
34
- }, [sdk]);
35
- const cancelOrder = useCallback(async (orderId) => {
36
- if (!sdk)
37
- throw new Error("SDK not available");
38
- if (!orderId?.trim())
39
- throw new Error("Order ID is required and cannot be empty");
40
- return await sdk.trading.cancelOrder(orderId);
41
- }, [sdk]);
42
- const createConditionalOrder = useCallback(async (params) => {
43
- if (!sdk)
44
- throw new Error("SDK not available");
45
- return await sdk.trading.createConditionalOrder(params);
46
- }, [sdk]);
47
- const cancelConditionalOrder = useCallback(async (conditionalOrderId) => {
48
- if (!sdk)
49
- throw new Error("SDK not available");
50
- if (!conditionalOrderId?.trim())
51
- throw new Error("Conditional order ID is required and cannot be empty");
52
- return await sdk.trading.cancelConditionalOrder(conditionalOrderId);
53
- }, [sdk]);
54
- const listConditionalOrders = useCallback(async (params) => {
55
- if (!sdk)
56
- throw new Error("SDK not available");
57
- return await sdk.trading.listConditionalOrders(params);
58
- }, [sdk]);
59
- const batchCancel = useCallback(async (orderIds) => {
60
- if (!sdk)
61
- throw new Error("SDK not available");
62
- return await sdk.trading.batchCancel(orderIds);
63
- }, [sdk]);
64
- const batchCancelAll = useCallback(async (tradingPairId) => {
65
- if (!sdk)
66
- throw new Error("SDK not available");
67
- return await sdk.trading.batchCancelAll(tradingPairId);
68
- }, [sdk]);
69
- const replaceOrder = useCallback(async (orderId, newOrder) => {
70
- if (!sdk)
71
- throw new Error("SDK not available");
72
- if (!orderId?.trim())
73
- throw new Error("Order ID is required and cannot be empty");
74
- if (!newOrder)
75
- throw new Error("New order object is required");
76
- // Validate quantity only if provided
77
- if (newOrder.quantity !== undefined) {
78
- if (!newOrder.quantity?.trim())
79
- throw new Error("Quantity cannot be empty");
80
- if (Number(newOrder.quantity) <= 0)
81
- throw new Error("Quantity must be greater than 0");
82
- }
83
- // Validate price only if provided
84
- if (newOrder.price !== undefined) {
85
- if (!newOrder.price?.trim())
86
- throw new Error("Price cannot be empty");
87
- if (Number(newOrder.price) <= 0)
88
- throw new Error("Price must be a valid positive number");
89
- }
90
- return await sdk.trading.replaceOrder(orderId, newOrder);
91
- }, [sdk]);
92
- const batchCreate = useCallback(async (orders) => {
93
- if (!sdk)
94
- throw new Error("SDK not available");
95
- return await sdk.trading.batchCreate(orders);
96
- }, [sdk]);
97
- const batchReplace = useCallback(async (orders) => {
98
- if (!sdk)
99
- throw new Error("SDK not available");
100
- return await sdk.trading.batchReplace(orders);
101
- }, [sdk]);
102
- const getPaginatedOrders = useCallback(async (params) => {
103
- if (!sdk)
104
- throw new Error("SDK not available");
105
- return await sdk.trading.getPaginatedOrders(params);
106
- }, [sdk]);
107
- const getOrder = useCallback(async (orderId) => {
108
- if (!sdk)
109
- throw new Error("SDK not available");
110
- if (!orderId?.trim())
111
- throw new Error("Order ID is required and cannot be empty");
112
- return await sdk.trading.getOrder(orderId);
113
- }, [sdk]);
114
- return {
115
- // Order placement
116
- placeLimitOrder,
117
- placeMarketOrder,
118
- // Order management
119
- cancelOrder,
120
- createConditionalOrder,
121
- cancelConditionalOrder,
122
- listConditionalOrders,
123
- batchCancel,
124
- batchCancelAll,
125
- replaceOrder,
126
- batchCreate,
127
- batchReplace,
128
- // Order queries
129
- getPaginatedOrders,
130
- getOrder,
131
- };
132
- };
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useTradeFeed } from "./useTradeFeed";
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useTradeFeed } from "./useTradeFeed";
@@ -1,14 +0,0 @@
1
- import type { TradeEvent } from "@0xmonaco/types";
2
- /**
3
- * Return type for the useTradeFeed hook
4
- */
5
- export interface UseTradeFeedReturn {
6
- /** Array of trade events from WebSocket and REST API */
7
- trades: TradeEvent[];
8
- /** Whether currently subscribed to a market. Will be false if the SDK is not yet initialized. */
9
- subscribed: boolean;
10
- /** Whether the initial trades are being fetched */
11
- fetchingInitialState: boolean;
12
- /** Any error that occurred during connection or subscription */
13
- error: Error | null;
14
- }
File without changes
@@ -1,12 +0,0 @@
1
- import type { UseTradeFeedReturn } from "./types";
2
- /**
3
- * Hook for subscribing to real-time trade events via WebSocket (public)
4
- *
5
- * Subscriptions are shared at the provider level - multiple components using the same
6
- * tradingPairId will share both the WebSocket connection and the trade state.
7
- * Initial trades are fetched only once when the first component subscribes.
8
- * The last 50 trades are kept in state (this limit is fixed and not configurable).
9
- *
10
- * @param tradingPairId - The trading pair UUID to subscribe to
11
- */
12
- export declare function useTradeFeed(tradingPairId: string): UseTradeFeedReturn;
@@ -1,32 +0,0 @@
1
- import { useEffect } from "react";
2
- import { MAX_TRADES, useTradeFeedContext } from "../../provider";
3
- import { useMonacoSDK } from "../useMonaco";
4
- /**
5
- * Hook for subscribing to real-time trade events via WebSocket (public)
6
- *
7
- * Subscriptions are shared at the provider level - multiple components using the same
8
- * tradingPairId will share both the WebSocket connection and the trade state.
9
- * Initial trades are fetched only once when the first component subscribes.
10
- * The last 50 trades are kept in state (this limit is fixed and not configurable).
11
- *
12
- * @param tradingPairId - The trading pair UUID to subscribe to
13
- */
14
- export function useTradeFeed(tradingPairId) {
15
- const { sdk } = useMonacoSDK();
16
- const { subscribe, subscriptions } = useTradeFeedContext();
17
- const subscription = subscriptions.get(tradingPairId);
18
- useEffect(() => {
19
- if (!sdk?.ws || !sdk?.trades || !tradingPairId) {
20
- return;
21
- }
22
- const fetchInitialTrades = () => sdk.trades.getTrades(tradingPairId, { page_size: MAX_TRADES });
23
- const subscribeToWs = (handler) => sdk.ws.trades(tradingPairId, handler);
24
- return subscribe(tradingPairId, fetchInitialTrades, subscribeToWs);
25
- }, [sdk?.ws, sdk?.trades, tradingPairId, subscribe]);
26
- return {
27
- trades: subscription?.trades ?? [],
28
- subscribed: subscription?.subscribed ?? false,
29
- fetchingInitialState: subscription?.fetchingInitialState ?? false,
30
- error: subscription?.error ?? null,
31
- };
32
- }
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useUserBalances } from "./useUserBalances";
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useUserBalances } from "./useUserBalances";
@@ -1,18 +0,0 @@
1
- import type { AccountBalance } from "@0xmonaco/types";
2
- /**
3
- * Return type for the useUserBalances hook
4
- */
5
- export interface UseUserBalancesReturn {
6
- /** Array of user balances, updated in real-time via WebSocket */
7
- balances: AccountBalance[];
8
- /** Whether initial data is being loaded */
9
- loading: boolean;
10
- /** Whether currently subscribed to balances channel */
11
- subscribed: boolean;
12
- /** Any error that occurred during connection or subscription */
13
- error: Error | null;
14
- /** Clear the current error state */
15
- clearError: () => void;
16
- /** Manually refresh balances from REST API */
17
- refresh: () => Promise<void>;
18
- }
File without changes
@@ -1,9 +0,0 @@
1
- import type { UseUserBalancesReturn } from "./types";
2
- /**
3
- * Hook for subscribing to real-time user balance updates via WebSocket (authenticated)
4
- *
5
- * Fetches initial balances from the REST API, then subscribes to real-time updates.
6
- * Requires authentication - the user must be logged in with a valid JWT token.
7
- * User is identified on the backend via the JWT token.
8
- */
9
- export declare function useUserBalances(): UseUserBalancesReturn;
@@ -1,171 +0,0 @@
1
- import { useCallback, useEffect, useState } from "react";
2
- import { useMonacoSDK } from "../useMonaco";
3
- /**
4
- * Update an AccountBalance with data from a WebSocket balance event
5
- */
6
- function updateBalanceFromEvent(balance, event) {
7
- const totalBalance = totalBalanceFromEvent(balance, event);
8
- return {
9
- ...balance,
10
- available_balance: event.data.available,
11
- available_balance_raw: event.data.availableRaw,
12
- locked_balance: event.data.locked,
13
- locked_balance_raw: event.data.lockedRaw,
14
- total_balance: totalBalance,
15
- };
16
- }
17
- function parseDecimal(value) {
18
- const match = value.trim().match(/^(-?)(\d+)(?:\.(\d+))?$/);
19
- if (!match)
20
- return null;
21
- const [, sign, whole, fractional = ""] = match;
22
- const digits = `${whole}${fractional}`.replace(/^0+(?=\d)/, "");
23
- const parsed = BigInt(digits || "0");
24
- return {
25
- value: sign === "-" ? -parsed : parsed,
26
- scale: fractional.length,
27
- };
28
- }
29
- function pow10(exponent) {
30
- return 10n ** BigInt(exponent);
31
- }
32
- function toScale(value, scale) {
33
- return value.value * pow10(scale - value.scale);
34
- }
35
- function formatDecimal(value, scale) {
36
- const sign = value < 0n ? "-" : "";
37
- const absolute = value < 0n ? -value : value;
38
- if (scale === 0)
39
- return `${sign}${absolute.toString()}`;
40
- const padded = absolute.toString().padStart(scale + 1, "0");
41
- const whole = padded.slice(0, -scale);
42
- const fractional = padded.slice(-scale).replace(/0+$/, "");
43
- return fractional ? `${sign}${whole}.${fractional}` : `${sign}${whole}`;
44
- }
45
- function decimalSum(...values) {
46
- const parsed = values.map(parseDecimal);
47
- if (parsed.some((value) => value === null))
48
- return null;
49
- const decimals = parsed;
50
- const scale = Math.max(...decimals.map((value) => value.scale));
51
- const sum = decimals.reduce((total, value) => total + toScale(value, scale), 0n);
52
- return formatDecimal(sum, scale);
53
- }
54
- function decimalDifference(left, ...right) {
55
- return decimalSum(left, ...right.map((value) => (value.startsWith("-") ? value.slice(1) : `-${value}`)));
56
- }
57
- function decimalGreaterThanZero(value) {
58
- const parsed = parseDecimal(value);
59
- return parsed ? parsed.value > 0n : false;
60
- }
61
- function totalBalanceFromEvent(balance, event) {
62
- if (event.data.reason === "margin_transfer_in" || event.data.reason === "margin_transfer_out") {
63
- return event.data.total;
64
- }
65
- const eventExtraTotal = decimalDifference(event.data.total, event.data.available, event.data.locked);
66
- if (eventExtraTotal && decimalGreaterThanZero(eventExtraTotal)) {
67
- return event.data.total;
68
- }
69
- const previousMarginTotal = decimalDifference(balance.total_balance, balance.available_balance, balance.locked_balance);
70
- if (!previousMarginTotal || !decimalGreaterThanZero(previousMarginTotal)) {
71
- return event.data.total;
72
- }
73
- return decimalSum(event.data.total, previousMarginTotal) ?? event.data.total;
74
- }
75
- /**
76
- * Hook for subscribing to real-time user balance updates via WebSocket (authenticated)
77
- *
78
- * Fetches initial balances from the REST API, then subscribes to real-time updates.
79
- * Requires authentication - the user must be logged in with a valid JWT token.
80
- * User is identified on the backend via the JWT token.
81
- */
82
- export function useUserBalances() {
83
- const { sdk } = useMonacoSDK();
84
- const [balances, setBalances] = useState([]);
85
- const [loading, setLoading] = useState(false);
86
- const [error, setError] = useState(null);
87
- const [subscribed, setSubscribed] = useState(false);
88
- const clearError = useCallback(() => setError(null), []);
89
- const fetchBalances = useCallback(async () => {
90
- if (!sdk?.profile)
91
- return;
92
- setLoading(true);
93
- try {
94
- const response = await sdk.profile.getUserBalances();
95
- setBalances(response.balances);
96
- }
97
- catch (err) {
98
- setError(err instanceof Error ? err : new Error(String(err)));
99
- }
100
- finally {
101
- setLoading(false);
102
- }
103
- }, [sdk?.profile]);
104
- const refresh = useCallback(async () => {
105
- await fetchBalances();
106
- }, [fetchBalances]);
107
- useEffect(() => {
108
- if (!sdk?.ws || !sdk?.profile) {
109
- setSubscribed(false);
110
- return;
111
- }
112
- setBalances([]);
113
- setError(null);
114
- setLoading(true);
115
- // Fetch initial balances via REST API, then subscribe to WebSocket updates
116
- let unsubscribe;
117
- let cancelled = false;
118
- fetchBalances()
119
- .then(() => {
120
- // Bail out if effect was cleaned up before fetch resolved
121
- if (cancelled)
122
- return;
123
- // Subscribe to WebSocket balance updates after initial data is loaded
124
- try {
125
- unsubscribe = sdk.ws.balances((event) => {
126
- let needsRefresh = false;
127
- setBalances((prev) => {
128
- // Find by token address and update (case-insensitive for addresses)
129
- const existingIndex = prev.findIndex((b) => b.token.toLowerCase() === event.data.tokenAddress.toLowerCase());
130
- const existingBalance = prev[existingIndex];
131
- if (existingIndex >= 0 && existingBalance) {
132
- // Update existing balance
133
- const updatedBalance = updateBalanceFromEvent(existingBalance, event);
134
- const newBalances = [...prev];
135
- newBalances[existingIndex] = updatedBalance;
136
- return newBalances;
137
- }
138
- // New token - flag for refresh outside the updater
139
- needsRefresh = true;
140
- return prev;
141
- });
142
- // Refresh outside the state updater to keep it pure
143
- if (needsRefresh && !cancelled) {
144
- fetchBalances().catch((err) => {
145
- if (!cancelled) {
146
- setError(err instanceof Error ? err : new Error(String(err)));
147
- }
148
- });
149
- }
150
- });
151
- setSubscribed(true);
152
- }
153
- catch (err) {
154
- setError(err instanceof Error ? err : new Error(String(err)));
155
- setSubscribed(false);
156
- }
157
- })
158
- .catch((err) => {
159
- if (cancelled)
160
- return;
161
- setError(err instanceof Error ? err : new Error(String(err)));
162
- setLoading(false);
163
- });
164
- return () => {
165
- cancelled = true;
166
- unsubscribe?.();
167
- setSubscribed(false);
168
- };
169
- }, [sdk?.ws, sdk?.profile, fetchBalances]);
170
- return { balances, loading, subscribed, error, clearError, refresh };
171
- }
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useUserMovements } from "./useUserMovements";
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useUserMovements } from "./useUserMovements";
@@ -1,23 +0,0 @@
1
- import type { GetUserMovementsParams, UserMovementEvent } from "@0xmonaco/types";
2
- /**
3
- * Options for the useUserMovements hook
4
- */
5
- export interface UseUserMovementsOptions extends Omit<GetUserMovementsParams, "page"> {
6
- /** Maximum number of movements to keep in state (default: 50) */
7
- maxMovements?: number;
8
- }
9
- /**
10
- * Return type for the useUserMovements hook
11
- */
12
- export interface UseUserMovementsReturn {
13
- /** Array of user movement events from WebSocket */
14
- movements: UserMovementEvent[];
15
- /** Whether initial data is being loaded */
16
- loading: boolean;
17
- /** Whether currently subscribed to movements channel */
18
- subscribed: boolean;
19
- /** Any error that occurred during connection or subscription */
20
- error: Error | null;
21
- /** Clear the current error state */
22
- clearError: () => void;
23
- }
File without changes
@@ -1,18 +0,0 @@
1
- import type { UseUserMovementsOptions, UseUserMovementsReturn } from "./types";
2
- /**
3
- * Hook for subscribing to real-time user movement events via WebSocket (authenticated)
4
- *
5
- * Fetches initial movements from the REST API, then subscribes to real-time updates.
6
- * Requires authentication - the user must be logged in with a valid JWT token.
7
- * User is identified on the backend via the JWT token.
8
- *
9
- * Re-fetches movements whenever filter options change.
10
- *
11
- * @param options - Optional filter and pagination options
12
- * @param options.maxMovements - Maximum number of movements to keep in state (default: 50)
13
- * @param options.page_size - Number of items per page for the API call (default: maxMovements)
14
- * @param options.entry_type - Filter by entry type (CREDIT, DEBIT, LOCK, UNLOCK, FEE)
15
- * @param options.transaction_type - Filter by transaction type (DEPOSIT, WITHDRAWAL, TRADE, etc.)
16
- * @param options.asset_id - Filter by asset ID (UUID)
17
- */
18
- export declare function useUserMovements(options?: UseUserMovementsOptions): UseUserMovementsReturn;
@@ -1,122 +0,0 @@
1
- import { useCallback, useEffect, useState } from "react";
2
- import { useMonacoContext } from "../../provider";
3
- import { useMonacoSDK } from "../useMonaco";
4
- /**
5
- * Convert a LedgerMovement from the REST API to a UserMovementEvent format
6
- */
7
- function ledgerMovementToEvent(movement, userId) {
8
- return {
9
- eventType: "movement",
10
- userId,
11
- data: {
12
- id: movement.id,
13
- entryType: movement.entry_type,
14
- transactionType: movement.transaction_type,
15
- tokenAddress: movement.token,
16
- symbol: movement.symbol ?? undefined,
17
- decimals: movement.decimals,
18
- amount: movement.amount,
19
- amountRaw: movement.amount_raw,
20
- balanceBefore: movement.balance_before ?? undefined,
21
- balanceBeforeRaw: movement.balance_before_raw ?? undefined,
22
- balanceAfter: movement.balance_after ?? undefined,
23
- balanceAfterRaw: movement.balance_after_raw ?? undefined,
24
- lockedBefore: movement.locked_before ?? undefined,
25
- lockedBeforeRaw: movement.locked_before_raw ?? undefined,
26
- lockedAfter: movement.locked_after ?? undefined,
27
- lockedAfterRaw: movement.locked_after_raw ?? undefined,
28
- referenceId: movement.reference_id ?? undefined,
29
- referenceType: movement.reference_type ?? undefined,
30
- description: movement.description ?? undefined,
31
- txHash: movement.tx_hash ?? undefined,
32
- createdAt: movement.created_at ?? undefined,
33
- },
34
- };
35
- }
36
- /**
37
- * Hook for subscribing to real-time user movement events via WebSocket (authenticated)
38
- *
39
- * Fetches initial movements from the REST API, then subscribes to real-time updates.
40
- * Requires authentication - the user must be logged in with a valid JWT token.
41
- * User is identified on the backend via the JWT token.
42
- *
43
- * Re-fetches movements whenever filter options change.
44
- *
45
- * @param options - Optional filter and pagination options
46
- * @param options.maxMovements - Maximum number of movements to keep in state (default: 50)
47
- * @param options.page_size - Number of items per page for the API call (default: maxMovements)
48
- * @param options.entry_type - Filter by entry type (CREDIT, DEBIT, LOCK, UNLOCK, FEE)
49
- * @param options.transaction_type - Filter by transaction type (DEPOSIT, WITHDRAWAL, TRADE, etc.)
50
- * @param options.asset_id - Filter by asset ID (UUID)
51
- */
52
- export function useUserMovements(options = {}) {
53
- const { sdk } = useMonacoSDK();
54
- const { authenticationStatus } = useMonacoContext();
55
- const { maxMovements = 50, page_size, entry_type, transaction_type, asset_id } = options;
56
- const [movements, setMovements] = useState([]);
57
- const [loading, setLoading] = useState(false);
58
- const [error, setError] = useState(null);
59
- const [subscribed, setSubscribed] = useState(false);
60
- const clearError = useCallback(() => setError(null), []);
61
- const sliceSize = Number.isFinite(maxMovements) && maxMovements > 0 ? maxMovements : 50;
62
- const requestLimit = page_size ?? Math.min(Math.max(Math.round(sliceSize), 1), 100);
63
- // Derive userId reactively — authenticationStatus changes on login/logout, triggering a re-render
64
- const userId = authenticationStatus === "authenticated" ? sdk?.getAuthState()?.user.id : undefined;
65
- useEffect(() => {
66
- if (!sdk?.ws || !sdk?.profile || !userId) {
67
- setSubscribed(false);
68
- return;
69
- }
70
- setMovements([]);
71
- setError(null);
72
- setLoading(true);
73
- // Fetch initial movements via REST API, then subscribe to WebSocket updates
74
- let unsubscribe;
75
- sdk.profile
76
- .getPaginatedUserMovements({ page_size: requestLimit, entry_type, transaction_type, asset_id })
77
- .then(async (response) => {
78
- // Combine latest_movements (from Redis) 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));
82
- const historicalMovements = response.movements.map((m) => ledgerMovementToEvent(m, userId));
83
- // Merge: latest_movements first, then historical, deduplicated by id
84
- const seenIds = new Set();
85
- const mergedMovements = [];
86
- for (const movement of [...latestMovements, ...historicalMovements]) {
87
- if (!seenIds.has(movement.data.id)) {
88
- seenIds.add(movement.data.id);
89
- mergedMovements.push(movement);
90
- }
91
- }
92
- setMovements(mergedMovements.slice(0, sliceSize));
93
- // Subscribe to WebSocket movement updates after initial data is loaded
94
- // This prevents race conditions where WS events could be overwritten by REST response
95
- try {
96
- unsubscribe = sdk.ws.movements((event) => {
97
- setMovements((prev) => {
98
- // Deduplicate by id and keep newest first
99
- const exists = prev.some((movement) => movement.data.id === event.data.id);
100
- if (exists) {
101
- // Update existing movement
102
- return prev.map((movement) => (movement.data.id === event.data.id ? event : movement));
103
- }
104
- return [event, ...prev].slice(0, sliceSize);
105
- });
106
- });
107
- setSubscribed(true);
108
- }
109
- catch (err) {
110
- setError(err instanceof Error ? err : new Error(String(err)));
111
- setSubscribed(false);
112
- }
113
- })
114
- .catch((err) => setError(err instanceof Error ? err : new Error(String(err))))
115
- .finally(() => setLoading(false));
116
- return () => {
117
- unsubscribe?.();
118
- setSubscribed(false);
119
- };
120
- }, [sdk?.ws, sdk?.profile, userId, sliceSize, requestLimit, entry_type, transaction_type, asset_id]);
121
- return { movements, loading, subscribed, error, clearError };
122
- }
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useUserOrders } from "./useUserOrders";
@@ -1,2 +0,0 @@
1
- export * from "./types";
2
- export { useUserOrders } from "./useUserOrders";
@@ -1,18 +0,0 @@
1
- import type { Order } from "@0xmonaco/types";
2
- /**
3
- * Return type for the useUserOrders hook
4
- */
5
- export interface UseUserOrdersReturn {
6
- /** Array of user orders (merged from REST API and WebSocket updates) */
7
- orders: Order[];
8
- /** Whether initial data is being loaded */
9
- loading: boolean;
10
- /** Whether currently subscribed to orders channel */
11
- subscribed: boolean;
12
- /** Any error that occurred during connection or subscription */
13
- error: Error | null;
14
- /** Clear the current error state */
15
- clearError: () => void;
16
- /** Manually refresh orders from REST API */
17
- refresh: () => Promise<void>;
18
- }
File without changes
@@ -1,11 +0,0 @@
1
- import type { UseUserOrdersReturn } from "./types";
2
- /**
3
- * Hook for subscribing to real-time user order events via WebSocket (authenticated)
4
- *
5
- * Fetches initial orders from the REST API, then subscribes to real-time updates.
6
- * Requires authentication - the user must be logged in with a valid JWT token.
7
- * User is identified on the backend via the JWT token.
8
- *
9
- * @param maxOrders - Maximum number of orders to keep in state (default: 50)
10
- */
11
- export declare function useUserOrders(maxOrders?: number): UseUserOrdersReturn;