@0xmonaco/react 0.8.7 → 0.8.10
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/coverage.d.ts +85 -0
- package/dist/coverage.js +85 -0
- package/dist/hooks/useAuth/types.d.ts +16 -11
- package/dist/hooks/useAuth/useAuth.js +12 -17
- package/dist/hooks/useTokenLifecycle/useTokenLifecycle.js +2 -2
- package/dist/hooks/useTrade/types.d.ts +6 -27
- package/dist/hooks/useTrade/useTrade.js +0 -6
- package/dist/utils/tokenStorage.d.ts +7 -3
- package/dist/utils/tokenStorage.js +15 -11
- package/package.json +3 -3
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** operationId → the @0xmonaco/react hook that covers it. */
|
|
2
|
+
export declare const COVERED: {
|
|
3
|
+
add_position_margin: string;
|
|
4
|
+
attach_position_tp_sl: string;
|
|
5
|
+
batch_cancel_all: string;
|
|
6
|
+
batch_cancel_all_by_pair: string;
|
|
7
|
+
batch_cancel_orders: string;
|
|
8
|
+
batch_create_orders: string;
|
|
9
|
+
batch_replace_orders: string;
|
|
10
|
+
cancel_conditional_order: string;
|
|
11
|
+
cancel_order: string;
|
|
12
|
+
close_position: string;
|
|
13
|
+
create_challenge: string;
|
|
14
|
+
create_order: string;
|
|
15
|
+
get_candles: string;
|
|
16
|
+
get_funding_state: string;
|
|
17
|
+
get_index_price: string;
|
|
18
|
+
get_mark_price: string;
|
|
19
|
+
get_market_metadata: string;
|
|
20
|
+
get_open_interest: string;
|
|
21
|
+
get_order_by_id: string;
|
|
22
|
+
get_orderbook_snapshot: string;
|
|
23
|
+
get_orders: string;
|
|
24
|
+
get_perp_market_config: string;
|
|
25
|
+
get_perp_market_summary: string;
|
|
26
|
+
get_position: string;
|
|
27
|
+
get_position_risk: string;
|
|
28
|
+
get_trades: string;
|
|
29
|
+
get_user_balance_by_asset: string;
|
|
30
|
+
get_user_balances: string;
|
|
31
|
+
get_user_movements: string;
|
|
32
|
+
get_user_profile: string;
|
|
33
|
+
get_withdrawal: string;
|
|
34
|
+
initiate_withdrawal: string;
|
|
35
|
+
list_conditional_orders: string;
|
|
36
|
+
list_funding_history: string;
|
|
37
|
+
list_position_history: string;
|
|
38
|
+
list_positions: string;
|
|
39
|
+
list_trading_pairs: string;
|
|
40
|
+
reduce_position_margin: string;
|
|
41
|
+
refresh_session: string;
|
|
42
|
+
replace_order: string;
|
|
43
|
+
revoke_session: string;
|
|
44
|
+
simulate_fees: string;
|
|
45
|
+
};
|
|
46
|
+
/** operationId → reason it is intentionally not covered by @0xmonaco/react. */
|
|
47
|
+
export declare const INTENTIONALLY_EXCLUDED: {
|
|
48
|
+
authenticate_backend: string;
|
|
49
|
+
create_delegated_session: string;
|
|
50
|
+
create_sub_account_limit: string;
|
|
51
|
+
delete_sub_account_limit: string;
|
|
52
|
+
get_application_config: string;
|
|
53
|
+
get_application_stats: string;
|
|
54
|
+
get_available_collateral: string;
|
|
55
|
+
get_margin_account_movements: string;
|
|
56
|
+
get_margin_account_summary: string;
|
|
57
|
+
get_portfolio_chart: string;
|
|
58
|
+
get_portfolio_stats: string;
|
|
59
|
+
get_screener: string;
|
|
60
|
+
get_sub_account_limits: string;
|
|
61
|
+
get_trade_by_id: string;
|
|
62
|
+
get_trading_pair_by_id: string;
|
|
63
|
+
get_user_trades: string;
|
|
64
|
+
health_check: string;
|
|
65
|
+
list_application_balances: string;
|
|
66
|
+
list_application_movements: string;
|
|
67
|
+
list_application_orders: string;
|
|
68
|
+
list_application_users: string;
|
|
69
|
+
list_delegated_agent_owners: string;
|
|
70
|
+
list_delegated_agents: string;
|
|
71
|
+
list_funding_payments: string;
|
|
72
|
+
list_margin_accounts: string;
|
|
73
|
+
list_sub_accounts_with_balances: string;
|
|
74
|
+
mint_tokens: string;
|
|
75
|
+
revoke_delegated_agent: string;
|
|
76
|
+
simulate_auto_margin_order_risk: string;
|
|
77
|
+
simulate_order_risk: string;
|
|
78
|
+
submit_whitelist: string;
|
|
79
|
+
transfer_collateral_from_margin_account: string;
|
|
80
|
+
transfer_collateral_to_auto_margin_account: string;
|
|
81
|
+
transfer_collateral_to_margin_account: string;
|
|
82
|
+
update_sub_account_limit: string;
|
|
83
|
+
upsert_delegated_agent: string;
|
|
84
|
+
verify_signature: string;
|
|
85
|
+
};
|
package/dist/coverage.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/** operationId → the @0xmonaco/react hook that covers it. */
|
|
2
|
+
export const COVERED = {
|
|
3
|
+
add_position_margin: "usePositions",
|
|
4
|
+
attach_position_tp_sl: "usePositions",
|
|
5
|
+
batch_cancel_all: "useTrade",
|
|
6
|
+
batch_cancel_all_by_pair: "useTrade",
|
|
7
|
+
batch_cancel_orders: "useTrade",
|
|
8
|
+
batch_create_orders: "useTrade",
|
|
9
|
+
batch_replace_orders: "useTrade",
|
|
10
|
+
cancel_conditional_order: "useTrade",
|
|
11
|
+
cancel_order: "useTrade",
|
|
12
|
+
close_position: "usePositions",
|
|
13
|
+
create_challenge: "useAuth",
|
|
14
|
+
create_order: "useTrade",
|
|
15
|
+
get_candles: "useMarket",
|
|
16
|
+
get_funding_state: "useMarket",
|
|
17
|
+
get_index_price: "useMarket",
|
|
18
|
+
get_mark_price: "useMarket",
|
|
19
|
+
get_market_metadata: "useMarket",
|
|
20
|
+
get_open_interest: "useMarket",
|
|
21
|
+
get_order_by_id: "useTrade",
|
|
22
|
+
get_orderbook_snapshot: "useOrderbook",
|
|
23
|
+
get_orders: "useTrade",
|
|
24
|
+
get_perp_market_config: "useMarket",
|
|
25
|
+
get_perp_market_summary: "useMarket",
|
|
26
|
+
get_position: "usePositions",
|
|
27
|
+
get_position_risk: "usePositions",
|
|
28
|
+
get_trades: "useTradeFeed",
|
|
29
|
+
get_user_balance_by_asset: "useProfile",
|
|
30
|
+
get_user_balances: "useUserBalances",
|
|
31
|
+
get_user_movements: "useUserMovements",
|
|
32
|
+
get_user_profile: "useProfile",
|
|
33
|
+
get_withdrawal: "useVault (retryWithdrawal)",
|
|
34
|
+
initiate_withdrawal: "useVault (withdraw)",
|
|
35
|
+
list_conditional_orders: "useTrade",
|
|
36
|
+
list_funding_history: "useMarket",
|
|
37
|
+
list_position_history: "usePositions",
|
|
38
|
+
list_positions: "usePositions",
|
|
39
|
+
list_trading_pairs: "useMarket",
|
|
40
|
+
reduce_position_margin: "usePositions",
|
|
41
|
+
refresh_session: "useAuth",
|
|
42
|
+
replace_order: "useTrade",
|
|
43
|
+
revoke_session: "useAuth",
|
|
44
|
+
simulate_fees: "useFees",
|
|
45
|
+
};
|
|
46
|
+
/** operationId → reason it is intentionally not covered by @0xmonaco/react. */
|
|
47
|
+
export const INTENTIONALLY_EXCLUDED = {
|
|
48
|
+
authenticate_backend: "Backend auth is header-based via setServerKey()/the x-server-key header, not an endpoint method (MON-1486).",
|
|
49
|
+
create_delegated_session: "Delegated-agent management is an automation/agent surface, not a UI workflow; no React hook.",
|
|
50
|
+
create_sub_account_limit: "Sub-account administration; no React hook.",
|
|
51
|
+
delete_sub_account_limit: "Sub-account administration; no React hook.",
|
|
52
|
+
get_application_config: "Application/backend (server-key) admin endpoint; not a user-wallet React workflow.",
|
|
53
|
+
get_application_stats: "Application/backend (server-key) admin endpoint; not a user-wallet React workflow.",
|
|
54
|
+
get_available_collateral: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
55
|
+
get_margin_account_movements: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
56
|
+
get_margin_account_summary: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
57
|
+
get_portfolio_chart: "Portfolio analytics endpoint; no React hook yet.",
|
|
58
|
+
get_portfolio_stats: "Portfolio analytics endpoint; no React hook yet.",
|
|
59
|
+
get_screener: "Market lookup available via the core client / list+symbol hooks; no dedicated React hook.",
|
|
60
|
+
get_sub_account_limits: "Sub-account administration; no React hook.",
|
|
61
|
+
get_trade_by_id: "Trade-history lookup with a core client method but no dedicated React hook yet.",
|
|
62
|
+
get_trading_pair_by_id: "Market lookup available via the core client / list+symbol hooks; no dedicated React hook.",
|
|
63
|
+
get_user_trades: "Trade-history lookup with a core client method but no dedicated React hook yet.",
|
|
64
|
+
health_check: "Infrastructure liveness probe (GET /health); not part of the data SDK surface.",
|
|
65
|
+
list_application_balances: "Application/backend (server-key) admin endpoint; not a user-wallet React workflow.",
|
|
66
|
+
list_application_movements: "Application/backend (server-key) admin endpoint; not a user-wallet React workflow.",
|
|
67
|
+
list_application_orders: "Application/backend (server-key) admin endpoint; not a user-wallet React workflow.",
|
|
68
|
+
list_application_users: "Application/backend (server-key) admin endpoint; not a user-wallet React workflow.",
|
|
69
|
+
list_delegated_agent_owners: "Delegated-agent management is an automation/agent surface, not a UI workflow; no React hook.",
|
|
70
|
+
list_delegated_agents: "Delegated-agent management is an automation/agent surface, not a UI workflow; no React hook.",
|
|
71
|
+
list_funding_payments: "Perps funding-payment history; no React hook yet.",
|
|
72
|
+
list_margin_accounts: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
73
|
+
list_sub_accounts_with_balances: "Sub-account administration; no React hook.",
|
|
74
|
+
mint_tokens: "Test-net faucet; no React hook (use the MCP/core faucet path).",
|
|
75
|
+
revoke_delegated_agent: "Delegated-agent management is an automation/agent surface, not a UI workflow; no React hook.",
|
|
76
|
+
simulate_auto_margin_order_risk: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
77
|
+
simulate_order_risk: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
78
|
+
submit_whitelist: "Whitelist submission; no React hook.",
|
|
79
|
+
transfer_collateral_from_margin_account: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
80
|
+
transfer_collateral_to_auto_margin_account: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
81
|
+
transfer_collateral_to_margin_account: "Margin-account management/collateral/simulation endpoint; no React hook yet.",
|
|
82
|
+
update_sub_account_limit: "Sub-account administration; no React hook.",
|
|
83
|
+
upsert_delegated_agent: "Delegated-agent management is an automation/agent surface, not a UI workflow; no React hook.",
|
|
84
|
+
verify_signature: "Auth verification runs inside login()/authenticate(); useAuth does not expose verifySignature as its own hook method.",
|
|
85
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AuthState, ChallengeResponse,
|
|
1
|
+
import type { AuthState, ChallengeResponse, SessionRefreshResponse } from "@0xmonaco/types";
|
|
2
2
|
import type { AuthenticationStatus } from "../../provider";
|
|
3
3
|
export interface UseAuthState {
|
|
4
4
|
/** Current authentication status */
|
|
@@ -6,25 +6,30 @@ export interface UseAuthState {
|
|
|
6
6
|
}
|
|
7
7
|
export interface UseAuthReturn extends UseAuthState {
|
|
8
8
|
/**
|
|
9
|
-
* Complete authentication flow.
|
|
9
|
+
* Complete authentication flow. Generates a session keypair, has the wallet
|
|
10
|
+
* authorize it, and returns the AuthState (including the session keypair).
|
|
10
11
|
* @param options - Optional configuration
|
|
11
12
|
* @param options.connectWebSocket - Auto-connect all authenticated WebSocket channels after login (currently Orders) (default: false)
|
|
12
13
|
*/
|
|
13
14
|
login: (options?: {
|
|
14
15
|
connectWebSocket?: boolean;
|
|
15
16
|
}) => Promise<AuthState>;
|
|
16
|
-
/** Logout user and clear state. Revokes the
|
|
17
|
+
/** Logout user and clear state. Revokes the session on the server. */
|
|
17
18
|
logout: () => Promise<void>;
|
|
18
|
-
/** Refresh
|
|
19
|
+
/** Refresh the current session, extending its expiry. */
|
|
19
20
|
refreshAuth: () => Promise<AuthState>;
|
|
20
21
|
/** Sign a challenge message with the connected wallet. */
|
|
21
22
|
signChallenge: (message: string) => Promise<string>;
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Create an authentication challenge for the given address, binding the
|
|
25
|
+
* provided session public key. Advanced/manual flow — most callers should
|
|
26
|
+
* use `login`/`authenticate`, which manage the keypair for you.
|
|
27
|
+
*/
|
|
28
|
+
createChallenge: (address: string, sessionPublicKey: string) => Promise<ChallengeResponse>;
|
|
29
|
+
/** Complete authentication with signature. Returns the AuthState. */
|
|
25
30
|
authenticate: () => Promise<AuthState>;
|
|
26
|
-
/**
|
|
27
|
-
|
|
28
|
-
/** Revoke the current session
|
|
29
|
-
|
|
31
|
+
/** Extend the current session's expiry (signed with the active session key). */
|
|
32
|
+
refreshSession: () => Promise<SessionRefreshResponse>;
|
|
33
|
+
/** Revoke the current session on the server. */
|
|
34
|
+
revokeSession: () => Promise<void>;
|
|
30
35
|
}
|
|
@@ -65,14 +65,16 @@ export const useAuth = () => {
|
|
|
65
65
|
throw new Error("Message is required and cannot be empty");
|
|
66
66
|
return await sdk.auth.signChallenge(message);
|
|
67
67
|
}, [sdk]);
|
|
68
|
-
const createChallenge = useCallback(async (address) => {
|
|
68
|
+
const createChallenge = useCallback(async (address, sessionPublicKey) => {
|
|
69
69
|
if (!sdk)
|
|
70
70
|
throw new Error("SDK not available");
|
|
71
71
|
if (!address?.trim())
|
|
72
72
|
throw new Error("Address is required and cannot be empty");
|
|
73
|
+
if (!sessionPublicKey?.trim())
|
|
74
|
+
throw new Error("Session public key is required and cannot be empty");
|
|
73
75
|
if (!clientId?.trim())
|
|
74
76
|
throw new Error("Client ID is required and cannot be empty");
|
|
75
|
-
return await sdk.auth.createChallenge(address, clientId);
|
|
77
|
+
return await sdk.auth.createChallenge(address, clientId, sessionPublicKey);
|
|
76
78
|
}, [sdk, clientId]);
|
|
77
79
|
const authenticate = useCallback(async () => {
|
|
78
80
|
if (!sdk)
|
|
@@ -84,26 +86,19 @@ export const useAuth = () => {
|
|
|
84
86
|
const result = await sdk.auth.authenticate(clientId);
|
|
85
87
|
const authenticated = sdk.isAuthenticated();
|
|
86
88
|
setAuthenticationStatus(authenticated ? AuthenticationStatus.AUTHENTICATED : AuthenticationStatus.UNAUTHENTICATED);
|
|
87
|
-
return
|
|
88
|
-
accessToken: result.accessToken,
|
|
89
|
-
refreshToken: result.refreshToken,
|
|
90
|
-
expiresAt: result.expiresAt,
|
|
91
|
-
user: result.user,
|
|
92
|
-
};
|
|
89
|
+
return result;
|
|
93
90
|
}
|
|
94
91
|
catch (error) {
|
|
95
92
|
setAuthenticationStatus(AuthenticationStatus.UNAUTHENTICATED);
|
|
96
93
|
throw error;
|
|
97
94
|
}
|
|
98
95
|
}, [sdk, clientId, setAuthenticationStatus]);
|
|
99
|
-
const
|
|
96
|
+
const refreshSession = useCallback(async () => {
|
|
100
97
|
if (!sdk)
|
|
101
98
|
throw new Error("SDK not available");
|
|
102
|
-
if (!token?.trim())
|
|
103
|
-
throw new Error("Refresh token is required and cannot be empty");
|
|
104
99
|
setAuthenticationStatus(AuthenticationStatus.AUTHENTICATING);
|
|
105
100
|
try {
|
|
106
|
-
const result = await sdk.auth.
|
|
101
|
+
const result = await sdk.auth.refreshSession();
|
|
107
102
|
const authenticated = sdk.isAuthenticated();
|
|
108
103
|
setAuthenticationStatus(authenticated ? AuthenticationStatus.AUTHENTICATED : AuthenticationStatus.UNAUTHENTICATED);
|
|
109
104
|
return result;
|
|
@@ -113,12 +108,12 @@ export const useAuth = () => {
|
|
|
113
108
|
throw error;
|
|
114
109
|
}
|
|
115
110
|
}, [sdk, setAuthenticationStatus]);
|
|
116
|
-
const
|
|
111
|
+
const revokeSession = useCallback(async () => {
|
|
117
112
|
if (!sdk)
|
|
118
113
|
throw new Error("SDK not available");
|
|
119
114
|
setAuthenticationStatus(AuthenticationStatus.AUTHENTICATING);
|
|
120
115
|
try {
|
|
121
|
-
await sdk.auth.
|
|
116
|
+
await sdk.auth.revokeSession();
|
|
122
117
|
const authenticated = sdk.isAuthenticated();
|
|
123
118
|
setAuthenticationStatus(authenticated ? AuthenticationStatus.AUTHENTICATED : AuthenticationStatus.UNAUTHENTICATED);
|
|
124
119
|
}
|
|
@@ -133,10 +128,10 @@ export const useAuth = () => {
|
|
|
133
128
|
// Primary auth actions
|
|
134
129
|
login,
|
|
135
130
|
logout,
|
|
136
|
-
//
|
|
131
|
+
// Session management
|
|
137
132
|
refreshAuth,
|
|
138
|
-
|
|
139
|
-
|
|
133
|
+
refreshSession,
|
|
134
|
+
revokeSession,
|
|
140
135
|
// Low-level auth functions
|
|
141
136
|
authenticate,
|
|
142
137
|
signChallenge,
|
|
@@ -53,8 +53,8 @@ export const useTokenLifecycle = (sdk, config = {}) => {
|
|
|
53
53
|
return refreshPromiseRef.current;
|
|
54
54
|
}
|
|
55
55
|
const currentAuthState = currentAuthStateRef.current;
|
|
56
|
-
if (!currentAuthState
|
|
57
|
-
console.warn("No
|
|
56
|
+
if (!currentAuthState) {
|
|
57
|
+
console.warn("No active session available for refresh");
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
60
|
const refreshPromise = (async () => {
|
|
@@ -1,35 +1,13 @@
|
|
|
1
|
-
import type { BatchCancelOrdersResponse, BatchCreateOrderParams, BatchCreateOrdersResponse, BatchReplaceOrderParams, BatchReplaceOrdersResponse, CancelConditionalOrderResponse, CancelOrderResponse,
|
|
1
|
+
import type { BatchCancelOrdersResponse, BatchCreateOrderParams, BatchCreateOrdersResponse, BatchReplaceOrderParams, BatchReplaceOrdersResponse, CancelConditionalOrderResponse, CancelOrderResponse, CreateOrderResponse, GetOrderResponse, GetPaginatedOrdersParams, GetPaginatedOrdersResponse, ListConditionalOrdersParams, ListConditionalOrdersResponse, OrderSide, ReplaceOrderResponse, TradingAPI } from "@0xmonaco/types";
|
|
2
|
+
type PlaceLimitOrderOptions = NonNullable<Parameters<TradingAPI["placeLimitOrder"]>[4]>;
|
|
3
|
+
type PlaceMarketOrderOptions = NonNullable<Parameters<TradingAPI["placeMarketOrder"]>[3]>;
|
|
2
4
|
export interface UseTradeReturn {
|
|
3
5
|
/** Place a limit order */
|
|
4
|
-
placeLimitOrder: (tradingPairId: string, side: OrderSide, quantity: string, price: string, options?:
|
|
5
|
-
tradingMode?: TradingMode;
|
|
6
|
-
useMasterBalance?: boolean;
|
|
7
|
-
expirationDate?: string;
|
|
8
|
-
timeInForce?: TimeInForce;
|
|
9
|
-
marginAccountId?: string;
|
|
10
|
-
strategyKey?: string;
|
|
11
|
-
positionSide?: PositionSide;
|
|
12
|
-
leverage?: string;
|
|
13
|
-
reduceOnly?: boolean;
|
|
14
|
-
takeProfit?: ParentTpSlLegParams;
|
|
15
|
-
stopLoss?: ParentTpSlLegParams;
|
|
16
|
-
}) => Promise<CreateOrderResponse>;
|
|
6
|
+
placeLimitOrder: (tradingPairId: string, side: OrderSide, quantity: string, price: string, options?: PlaceLimitOrderOptions) => Promise<CreateOrderResponse>;
|
|
17
7
|
/** Place a market order */
|
|
18
|
-
placeMarketOrder: (tradingPairId: string, side: OrderSide, quantity: string, options?:
|
|
19
|
-
tradingMode?: TradingMode;
|
|
20
|
-
slippageTolerance?: number;
|
|
21
|
-
marginAccountId?: string;
|
|
22
|
-
strategyKey?: string;
|
|
23
|
-
positionSide?: PositionSide;
|
|
24
|
-
leverage?: string;
|
|
25
|
-
reduceOnly?: boolean;
|
|
26
|
-
takeProfit?: ParentTpSlLegParams;
|
|
27
|
-
stopLoss?: ParentTpSlLegParams;
|
|
28
|
-
}) => Promise<CreateOrderResponse>;
|
|
8
|
+
placeMarketOrder: (tradingPairId: string, side: OrderSide, quantity: string, options?: PlaceMarketOrderOptions) => Promise<CreateOrderResponse>;
|
|
29
9
|
/** Cancel an existing order */
|
|
30
10
|
cancelOrder: (orderId: string) => Promise<CancelOrderResponse>;
|
|
31
|
-
/** Create a standalone conditional TP/SL order */
|
|
32
|
-
createConditionalOrder: (params: CreateConditionalOrderParams) => Promise<CreateConditionalOrderResponse>;
|
|
33
11
|
/** Cancel an active conditional TP/SL order */
|
|
34
12
|
cancelConditionalOrder: (conditionalOrderId: string) => Promise<CancelConditionalOrderResponse>;
|
|
35
13
|
/** List conditional TP/SL orders */
|
|
@@ -53,3 +31,4 @@ export interface UseTradeReturn {
|
|
|
53
31
|
/** Get a single order by ID */
|
|
54
32
|
getOrder: (orderId: string) => Promise<GetOrderResponse>;
|
|
55
33
|
}
|
|
34
|
+
export {};
|
|
@@ -39,11 +39,6 @@ export const useTrade = () => {
|
|
|
39
39
|
throw new Error("Order ID is required and cannot be empty");
|
|
40
40
|
return await sdk.trading.cancelOrder(orderId);
|
|
41
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
42
|
const cancelConditionalOrder = useCallback(async (conditionalOrderId) => {
|
|
48
43
|
if (!sdk)
|
|
49
44
|
throw new Error("SDK not available");
|
|
@@ -117,7 +112,6 @@ export const useTrade = () => {
|
|
|
117
112
|
placeMarketOrder,
|
|
118
113
|
// Order management
|
|
119
114
|
cancelOrder,
|
|
120
|
-
createConditionalOrder,
|
|
121
115
|
cancelConditionalOrder,
|
|
122
116
|
listConditionalOrders,
|
|
123
117
|
batchCancel,
|
|
@@ -2,14 +2,18 @@ import type { AuthState } from "@0xmonaco/types";
|
|
|
2
2
|
/**
|
|
3
3
|
* Save auth state to localStorage
|
|
4
4
|
*
|
|
5
|
-
* @security This function stores
|
|
6
|
-
* which is accessible to any JavaScript running on the
|
|
5
|
+
* @security This function stores the session keypair (including the private
|
|
6
|
+
* key) in localStorage, which is accessible to any JavaScript running on the
|
|
7
|
+
* page. This is the same XSS exposure as the previous JWT-based scheme — an
|
|
8
|
+
* attacker who can read localStorage can act as the user until the session
|
|
9
|
+
* expires either way.
|
|
7
10
|
*
|
|
8
11
|
* Security recommendations:
|
|
9
12
|
* - Implement Content Security Policy (CSP) headers to mitigate XSS risks
|
|
10
13
|
* - Sanitize all user input to prevent XSS vulnerabilities
|
|
11
14
|
* - Consider the tradeoffs: localStorage provides persistence across sessions but sacrifices XSS protection
|
|
12
|
-
* - For
|
|
15
|
+
* - For higher-security requirements, back the session key with a
|
|
16
|
+
* non-extractable WebCrypto key (out of scope for this default helper)
|
|
13
17
|
*
|
|
14
18
|
* @param authState - The authentication state to persist
|
|
15
19
|
*/
|
|
@@ -5,22 +5,26 @@ const STORAGE_KEY = "monaco_auth_state";
|
|
|
5
5
|
/**
|
|
6
6
|
* Save auth state to localStorage
|
|
7
7
|
*
|
|
8
|
-
* @security This function stores
|
|
9
|
-
* which is accessible to any JavaScript running on the
|
|
8
|
+
* @security This function stores the session keypair (including the private
|
|
9
|
+
* key) in localStorage, which is accessible to any JavaScript running on the
|
|
10
|
+
* page. This is the same XSS exposure as the previous JWT-based scheme — an
|
|
11
|
+
* attacker who can read localStorage can act as the user until the session
|
|
12
|
+
* expires either way.
|
|
10
13
|
*
|
|
11
14
|
* Security recommendations:
|
|
12
15
|
* - Implement Content Security Policy (CSP) headers to mitigate XSS risks
|
|
13
16
|
* - Sanitize all user input to prevent XSS vulnerabilities
|
|
14
17
|
* - Consider the tradeoffs: localStorage provides persistence across sessions but sacrifices XSS protection
|
|
15
|
-
* - For
|
|
18
|
+
* - For higher-security requirements, back the session key with a
|
|
19
|
+
* non-extractable WebCrypto key (out of scope for this default helper)
|
|
16
20
|
*
|
|
17
21
|
* @param authState - The authentication state to persist
|
|
18
22
|
*/
|
|
19
23
|
export function saveAuthState(authState) {
|
|
20
24
|
try {
|
|
21
25
|
const data = JSON.stringify({
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
sessionPublicKey: authState.sessionPublicKey,
|
|
27
|
+
sessionPrivateKey: authState.sessionPrivateKey,
|
|
24
28
|
expiresAt: authState.expiresAt,
|
|
25
29
|
user: authState.user,
|
|
26
30
|
});
|
|
@@ -41,10 +45,10 @@ export function loadAuthState() {
|
|
|
41
45
|
return null;
|
|
42
46
|
const parsed = JSON.parse(data);
|
|
43
47
|
// Validate required fields and types
|
|
44
|
-
if (typeof parsed.
|
|
45
|
-
parsed.
|
|
46
|
-
typeof parsed.
|
|
47
|
-
parsed.
|
|
48
|
+
if (typeof parsed.sessionPublicKey !== "string" ||
|
|
49
|
+
parsed.sessionPublicKey.length === 0 ||
|
|
50
|
+
typeof parsed.sessionPrivateKey !== "string" ||
|
|
51
|
+
parsed.sessionPrivateKey.length === 0 ||
|
|
48
52
|
typeof parsed.expiresAt !== "number" ||
|
|
49
53
|
!Number.isFinite(parsed.expiresAt) ||
|
|
50
54
|
parsed.expiresAt <= 0 ||
|
|
@@ -58,8 +62,8 @@ export function loadAuthState() {
|
|
|
58
62
|
return null;
|
|
59
63
|
}
|
|
60
64
|
return {
|
|
61
|
-
|
|
62
|
-
|
|
65
|
+
sessionPublicKey: parsed.sessionPublicKey,
|
|
66
|
+
sessionPrivateKey: parsed.sessionPrivateKey,
|
|
63
67
|
expiresAt: parsed.expiresAt,
|
|
64
68
|
user: parsed.user,
|
|
65
69
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xmonaco/react",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.10",
|
|
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": "0.8.
|
|
24
|
-
"@0xmonaco/types": "0.8.
|
|
23
|
+
"@0xmonaco/core": "0.8.10",
|
|
24
|
+
"@0xmonaco/types": "0.8.10"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/react": "^19.1.12",
|