@silentswap/react 0.0.51 → 0.0.53
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/contexts/SilentSwapContext.js +3 -1
- package/dist/hooks/silent/useSilentQuote.d.ts +5 -1
- package/dist/hooks/silent/useSilentQuote.js +59 -5
- package/dist/hooks/usePlatformHealth.d.ts +45 -0
- package/dist/hooks/usePlatformHealth.js +172 -0
- package/dist/hooks/usePlatformHealthMonitor.d.ts +24 -0
- package/dist/hooks/usePlatformHealthMonitor.js +25 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +2 -0
- package/package.json +3 -3
|
@@ -72,7 +72,7 @@ function SilentSwapInnerProvider({ children, client, evmAddress, solAddress, sol
|
|
|
72
72
|
autoAuthenticate: true,
|
|
73
73
|
});
|
|
74
74
|
// Wallet management hook
|
|
75
|
-
const { wallet, generateWallet, refreshWallet, isLoading: walletLoading, } = useWallet({
|
|
75
|
+
const { wallet, generateWallet, refreshWallet, isLoading: walletLoading, error: walletError, } = useWallet({
|
|
76
76
|
client,
|
|
77
77
|
address: evmAddress,
|
|
78
78
|
auth: auth || undefined,
|
|
@@ -121,6 +121,8 @@ function SilentSwapInnerProvider({ children, client, evmAddress, solAddress, sol
|
|
|
121
121
|
setDestinations,
|
|
122
122
|
wallet,
|
|
123
123
|
walletLoading,
|
|
124
|
+
walletError,
|
|
125
|
+
generateWallet,
|
|
124
126
|
walletClient,
|
|
125
127
|
connector,
|
|
126
128
|
solanaConnector,
|
|
@@ -40,6 +40,10 @@ export interface useSilentQuoteOptions {
|
|
|
40
40
|
wallet: SilentSwapWallet | null;
|
|
41
41
|
/** Whether wallet is currently being generated (to prevent swap execution before wallet is ready) */
|
|
42
42
|
walletLoading?: boolean;
|
|
43
|
+
/** Wallet generation error (if previous generation failed) */
|
|
44
|
+
walletError?: Error | null;
|
|
45
|
+
/** Function to generate wallet (for retry on swap execution) */
|
|
46
|
+
generateWallet?: () => Promise<void>;
|
|
43
47
|
/** Facilitator group for the swap, or a function that resolves it */
|
|
44
48
|
/** Status update callback */
|
|
45
49
|
onStatus?: (status: string) => void;
|
|
@@ -87,4 +91,4 @@ export interface ExecuteSwapParams {
|
|
|
87
91
|
/** Optional integrator ID for tracking */
|
|
88
92
|
integratorId?: string;
|
|
89
93
|
}
|
|
90
|
-
export declare function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, wallet, walletLoading, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, getPrice, setDestinations, }: useSilentQuoteOptions): useSilentQuoteReturn;
|
|
94
|
+
export declare function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, wallet, walletLoading, walletError, generateWallet, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, getPrice, setDestinations, }: useSilentQuoteOptions): useSilentQuoteReturn;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useMemo, useState } from 'react';
|
|
1
|
+
import { useCallback, useMemo, useState, useRef, useEffect } from 'react';
|
|
2
2
|
import { hexToBase58, isSolanaAsset, parseEvmCaip19, S_CAIP19_USDC_AVALANCHE, NI_CHAIN_ID_AVALANCHE, getAssetByCaip19, } from '@silentswap/sdk';
|
|
3
3
|
import { getAddress } from 'viem';
|
|
4
4
|
import { BigNumber } from 'bignumber.js';
|
|
@@ -7,7 +7,7 @@ import { useOrderSigning } from './useOrderSigning.js';
|
|
|
7
7
|
import { useBridgeExecution } from './useBridgeExecution.js';
|
|
8
8
|
import { useTransaction } from '../useTransaction.js';
|
|
9
9
|
import { useQuoteCalculation } from './useQuoteCalculation.js';
|
|
10
|
-
export function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, wallet, walletLoading = false, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, getPrice, setDestinations, }) {
|
|
10
|
+
export function useSilentQuote({ client, address, evmAddress, solAddress, walletClient, connector, wallet, walletLoading = false, walletError = null, generateWallet, onStatus, solanaConnector, solanaConnection, solanaRpcUrl, getPrice, setDestinations, }) {
|
|
11
11
|
const [isLoading, setIsLoading] = useState(false);
|
|
12
12
|
const [currentStep, setCurrentStep] = useState('');
|
|
13
13
|
const [quote, setQuote] = useState(null);
|
|
@@ -15,6 +15,18 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
|
|
|
15
15
|
const [orderId, setOrderId] = useState(null);
|
|
16
16
|
const [viewingAuth, setViewingAuth] = useState(null);
|
|
17
17
|
const [isSwapping, setIsSwapping] = useState(false);
|
|
18
|
+
// Use refs to track current wallet state (to avoid stale closure values)
|
|
19
|
+
const walletRef = useRef(wallet);
|
|
20
|
+
const walletLoadingRef = useRef(walletLoading);
|
|
21
|
+
const walletErrorRef = useRef(walletError);
|
|
22
|
+
const generateWalletRef = useRef(generateWallet);
|
|
23
|
+
// Update refs when wallet state changes
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
walletRef.current = wallet;
|
|
26
|
+
walletLoadingRef.current = walletLoading;
|
|
27
|
+
walletErrorRef.current = walletError;
|
|
28
|
+
generateWalletRef.current = generateWallet;
|
|
29
|
+
}, [wallet, walletLoading, walletError, generateWallet]);
|
|
18
30
|
// Normalize address - only normalize EVM addresses
|
|
19
31
|
// Note: For Solana swaps, we still need an EVM address for facilitator operations
|
|
20
32
|
// The address parameter should be EVM for facilitator operations, but can be Solana for quote requests
|
|
@@ -93,9 +105,49 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
|
|
|
93
105
|
if (!walletClient) {
|
|
94
106
|
throw new Error('Wallet client required for swap execution');
|
|
95
107
|
}
|
|
96
|
-
// Check if wallet
|
|
97
|
-
if (
|
|
98
|
-
|
|
108
|
+
// Check if wallet generation previously failed - retry if so
|
|
109
|
+
if (!walletRef.current && walletErrorRef.current && generateWalletRef.current && !walletLoadingRef.current) {
|
|
110
|
+
setCurrentStep('Retrying wallet generation...');
|
|
111
|
+
onStatus?.('Retrying wallet generation...');
|
|
112
|
+
try {
|
|
113
|
+
await generateWalletRef.current();
|
|
114
|
+
// Wait for wallet to be ready after retry (with timeout)
|
|
115
|
+
const maxWaitTime = 30000; // 30 seconds
|
|
116
|
+
const checkInterval = 100; // Check every 100ms
|
|
117
|
+
const startTime = Date.now();
|
|
118
|
+
while (!walletRef.current && Date.now() - startTime < maxWaitTime) {
|
|
119
|
+
await new Promise((resolve) => setTimeout(resolve, checkInterval));
|
|
120
|
+
}
|
|
121
|
+
// If wallet is still not ready after retry, throw error
|
|
122
|
+
if (!walletRef.current) {
|
|
123
|
+
throw new Error('Wallet generation retry completed but wallet is still not available. Please try again.');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
const error = err instanceof Error ? err : new Error('Failed to generate wallet');
|
|
128
|
+
throw new Error(`Wallet generation failed: ${error.message}. Please try again or ensure wallet is connected and authenticated.`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Wait for wallet to be ready if it's being generated
|
|
132
|
+
// Use refs to check current state (avoid stale closure values)
|
|
133
|
+
if (!walletRef.current && walletLoadingRef.current) {
|
|
134
|
+
setCurrentStep('Waiting for wallet generation...');
|
|
135
|
+
onStatus?.('Waiting for wallet generation...');
|
|
136
|
+
// Wait for wallet generation to complete (with timeout)
|
|
137
|
+
const maxWaitTime = 30000; // 30 seconds
|
|
138
|
+
const checkInterval = 100; // Check every 100ms
|
|
139
|
+
const startTime = Date.now();
|
|
140
|
+
while (!walletRef.current && walletLoadingRef.current && Date.now() - startTime < maxWaitTime) {
|
|
141
|
+
await new Promise((resolve) => setTimeout(resolve, checkInterval));
|
|
142
|
+
}
|
|
143
|
+
// If wallet is still not ready after waiting, throw error
|
|
144
|
+
if (!walletRef.current) {
|
|
145
|
+
throw new Error('Wallet is being generated. Please wait for wallet generation to complete before executing swap.');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Final check: wallet must exist for swap execution
|
|
149
|
+
if (!walletRef.current) {
|
|
150
|
+
throw new Error('Wallet is required for swap execution. Please ensure wallet is connected and authenticated.');
|
|
99
151
|
}
|
|
100
152
|
setIsLoading(true);
|
|
101
153
|
setError(null);
|
|
@@ -233,6 +285,8 @@ export function useSilentQuote({ client, address, evmAddress, solAddress, wallet
|
|
|
233
285
|
evmAddress,
|
|
234
286
|
walletClient,
|
|
235
287
|
walletLoading,
|
|
288
|
+
walletError,
|
|
289
|
+
generateWallet,
|
|
236
290
|
solanaConnector,
|
|
237
291
|
signAuthorizations,
|
|
238
292
|
createOrder,
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type PlatformHealthStatus = 'ON' | 'ONLINE' | 'PAUSED' | 'DEPOSITS_PAUSED' | 'OFF' | 'MAINTENANCE' | 'UNKNOWN';
|
|
3
|
+
export type PlatformHealthContextType = {
|
|
4
|
+
platformHealth: PlatformHealthStatus | null;
|
|
5
|
+
maximumDepositUusdc: string | undefined;
|
|
6
|
+
minimumDepositUusdc: string | undefined;
|
|
7
|
+
outputLimit: number | undefined;
|
|
8
|
+
serviceFeeRate: number | undefined;
|
|
9
|
+
overheadUsd: number | undefined;
|
|
10
|
+
formDisabled: boolean;
|
|
11
|
+
trackingDisabled: boolean;
|
|
12
|
+
validateDepositAmount: (usdAmount: string | number) => {
|
|
13
|
+
valid: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
};
|
|
16
|
+
validateOutputCount: (count: number) => {
|
|
17
|
+
valid: boolean;
|
|
18
|
+
error?: string;
|
|
19
|
+
};
|
|
20
|
+
getMinimumDepositUsd: () => number | null;
|
|
21
|
+
getMaximumDepositUsd: () => number | null;
|
|
22
|
+
getServiceFeeRate: () => number | null;
|
|
23
|
+
};
|
|
24
|
+
export type PlatformHealthProviderProps = {
|
|
25
|
+
children: React.ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Optional callback to update form disabled state in app state
|
|
28
|
+
* If not provided, formDisabled will always be false in the context
|
|
29
|
+
*/
|
|
30
|
+
onFormDisabledChange?: (disabled: boolean) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Optional callback to update tracking disabled state in app state
|
|
33
|
+
* If not provided, trackingDisabled will always be false in the context
|
|
34
|
+
*/
|
|
35
|
+
onTrackingDisabledChange?: (disabled: boolean) => void;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Provider that monitors platform health from status API and provides validation functions
|
|
39
|
+
* for deposit amounts, output limits, and service fee rates
|
|
40
|
+
*/
|
|
41
|
+
export declare function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, }: PlatformHealthProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
/**
|
|
43
|
+
* Hook to access platform health context
|
|
44
|
+
*/
|
|
45
|
+
export declare function usePlatformHealthContext(): PlatformHealthContextType;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import React, { createContext, useContext, useEffect, useMemo, useCallback } from 'react';
|
|
4
|
+
import { useStatus } from '../hooks/useStatus.js';
|
|
5
|
+
import { BigNumber } from 'bignumber.js';
|
|
6
|
+
const PlatformHealthContext = createContext(undefined);
|
|
7
|
+
/**
|
|
8
|
+
* Provider that monitors platform health from status API and provides validation functions
|
|
9
|
+
* for deposit amounts, output limits, and service fee rates
|
|
10
|
+
*/
|
|
11
|
+
export function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, }) {
|
|
12
|
+
const { platformHealth: statusPlatformHealth, maximumDepositUusdc, minimumDepositUusdc, outputLimit, serviceFeeRate, overheadUsd, } = useStatus();
|
|
13
|
+
// Normalize platform health status
|
|
14
|
+
const platformHealth = useMemo(() => {
|
|
15
|
+
if (!statusPlatformHealth)
|
|
16
|
+
return null;
|
|
17
|
+
return statusPlatformHealth;
|
|
18
|
+
}, [statusPlatformHealth]);
|
|
19
|
+
// Track disabled states locally for context value
|
|
20
|
+
const [formDisabled, setFormDisabled] = React.useState(false);
|
|
21
|
+
const [trackingDisabled, setTrackingDisabled] = React.useState(false);
|
|
22
|
+
// Update app state based on platform health
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (!platformHealth) {
|
|
25
|
+
// Default to enabled if no platform health info
|
|
26
|
+
const newFormDisabled = false;
|
|
27
|
+
const newTrackingDisabled = false;
|
|
28
|
+
setFormDisabled(newFormDisabled);
|
|
29
|
+
setTrackingDisabled(newTrackingDisabled);
|
|
30
|
+
onFormDisabledChange?.(newFormDisabled);
|
|
31
|
+
onTrackingDisabledChange?.(newTrackingDisabled);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Update app state based on platform health (matching Svelte fees.ts logic)
|
|
35
|
+
let newFormDisabled = false;
|
|
36
|
+
let newTrackingDisabled = false;
|
|
37
|
+
switch (platformHealth) {
|
|
38
|
+
case 'ON':
|
|
39
|
+
case 'ONLINE':
|
|
40
|
+
// Everything enabled
|
|
41
|
+
newFormDisabled = false;
|
|
42
|
+
newTrackingDisabled = false;
|
|
43
|
+
break;
|
|
44
|
+
case 'PAUSED':
|
|
45
|
+
case 'DEPOSITS_PAUSED':
|
|
46
|
+
// Form disabled, tracking still enabled
|
|
47
|
+
newFormDisabled = true;
|
|
48
|
+
newTrackingDisabled = false;
|
|
49
|
+
break;
|
|
50
|
+
case 'OFF':
|
|
51
|
+
case 'MAINTENANCE':
|
|
52
|
+
case 'UNKNOWN':
|
|
53
|
+
default:
|
|
54
|
+
// Both form and tracking disabled
|
|
55
|
+
newFormDisabled = true;
|
|
56
|
+
newTrackingDisabled = true;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
setFormDisabled(newFormDisabled);
|
|
60
|
+
setTrackingDisabled(newTrackingDisabled);
|
|
61
|
+
onFormDisabledChange?.(newFormDisabled);
|
|
62
|
+
onTrackingDisabledChange?.(newTrackingDisabled);
|
|
63
|
+
}, [platformHealth, onFormDisabledChange, onTrackingDisabledChange]);
|
|
64
|
+
// Convert uusdc (micro-USDC) to USDC: 1 USDC = 1,000,000 uusdc
|
|
65
|
+
const getMinimumDepositUsd = useCallback(() => {
|
|
66
|
+
if (!minimumDepositUusdc)
|
|
67
|
+
return null;
|
|
68
|
+
try {
|
|
69
|
+
const uusdc = BigNumber(minimumDepositUusdc);
|
|
70
|
+
// Convert from micro-USDC to USDC (divide by 1e6)
|
|
71
|
+
return uusdc.dividedBy(1000000).toNumber();
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}, [minimumDepositUusdc]);
|
|
77
|
+
const getMaximumDepositUsd = useCallback(() => {
|
|
78
|
+
if (!maximumDepositUusdc)
|
|
79
|
+
return null;
|
|
80
|
+
try {
|
|
81
|
+
const uusdc = BigNumber(maximumDepositUusdc);
|
|
82
|
+
// Convert from micro-USDC to USDC (divide by 1e6)
|
|
83
|
+
return uusdc.dividedBy(1000000).toNumber();
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}, [maximumDepositUusdc]);
|
|
89
|
+
const getServiceFeeRate = useCallback(() => {
|
|
90
|
+
if (!serviceFeeRate)
|
|
91
|
+
return null;
|
|
92
|
+
try {
|
|
93
|
+
return +serviceFeeRate;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}, [serviceFeeRate]);
|
|
99
|
+
// Validate deposit amount against min/max limits
|
|
100
|
+
const validateDepositAmount = useCallback((usdAmount) => {
|
|
101
|
+
const amount = typeof usdAmount === 'string' ? parseFloat(usdAmount) : usdAmount;
|
|
102
|
+
if (isNaN(amount) || amount <= 0) {
|
|
103
|
+
return { valid: false, error: 'Amount must be greater than zero' };
|
|
104
|
+
}
|
|
105
|
+
const minUsd = getMinimumDepositUsd();
|
|
106
|
+
const maxUsd = getMaximumDepositUsd();
|
|
107
|
+
if (minUsd !== null && amount < minUsd) {
|
|
108
|
+
return { valid: false, error: `Minimum deposit is $${minUsd.toFixed(2)}` };
|
|
109
|
+
}
|
|
110
|
+
if (maxUsd !== null && amount > maxUsd) {
|
|
111
|
+
return { valid: false, error: `Maximum deposit is $${maxUsd.toFixed(2)}` };
|
|
112
|
+
}
|
|
113
|
+
return { valid: true };
|
|
114
|
+
}, [getMinimumDepositUsd, getMaximumDepositUsd]);
|
|
115
|
+
// Validate output count against limit
|
|
116
|
+
const validateOutputCount = useCallback((count) => {
|
|
117
|
+
if (outputLimit === null || outputLimit === undefined) {
|
|
118
|
+
// No limit set, allow any count
|
|
119
|
+
return { valid: true };
|
|
120
|
+
}
|
|
121
|
+
if (count < 1) {
|
|
122
|
+
return { valid: false, error: 'At least one output destination is required' };
|
|
123
|
+
}
|
|
124
|
+
if (count > outputLimit) {
|
|
125
|
+
return {
|
|
126
|
+
valid: false,
|
|
127
|
+
error: `Maximum ${outputLimit} output destination${outputLimit === 1 ? '' : 's'} allowed`,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return { valid: true };
|
|
131
|
+
}, [outputLimit]);
|
|
132
|
+
const value = useMemo(() => ({
|
|
133
|
+
platformHealth,
|
|
134
|
+
maximumDepositUusdc,
|
|
135
|
+
minimumDepositUusdc,
|
|
136
|
+
outputLimit: outputLimit ?? undefined,
|
|
137
|
+
serviceFeeRate: serviceFeeRate ?? undefined,
|
|
138
|
+
overheadUsd: overheadUsd ?? undefined,
|
|
139
|
+
formDisabled,
|
|
140
|
+
trackingDisabled,
|
|
141
|
+
validateDepositAmount,
|
|
142
|
+
validateOutputCount,
|
|
143
|
+
getMinimumDepositUsd,
|
|
144
|
+
getMaximumDepositUsd,
|
|
145
|
+
getServiceFeeRate,
|
|
146
|
+
}), [
|
|
147
|
+
platformHealth,
|
|
148
|
+
maximumDepositUusdc,
|
|
149
|
+
minimumDepositUusdc,
|
|
150
|
+
outputLimit,
|
|
151
|
+
serviceFeeRate,
|
|
152
|
+
overheadUsd,
|
|
153
|
+
formDisabled,
|
|
154
|
+
trackingDisabled,
|
|
155
|
+
validateDepositAmount,
|
|
156
|
+
validateOutputCount,
|
|
157
|
+
getMinimumDepositUsd,
|
|
158
|
+
getMaximumDepositUsd,
|
|
159
|
+
getServiceFeeRate,
|
|
160
|
+
]);
|
|
161
|
+
return _jsx(PlatformHealthContext.Provider, { value: value, children: children });
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Hook to access platform health context
|
|
165
|
+
*/
|
|
166
|
+
export function usePlatformHealthContext() {
|
|
167
|
+
const context = useContext(PlatformHealthContext);
|
|
168
|
+
if (context === undefined) {
|
|
169
|
+
throw new Error('usePlatformHealthContext must be used within a PlatformHealthProvider');
|
|
170
|
+
}
|
|
171
|
+
return context;
|
|
172
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type PlatformHealthMonitorProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Component to render when maintenance mode is active
|
|
5
|
+
* Receives `enabled` prop indicating if maintenance mode is active
|
|
6
|
+
*/
|
|
7
|
+
MaintenanceComponent: React.ComponentType<{
|
|
8
|
+
enabled: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Hook that determines if platform is in maintenance mode
|
|
13
|
+
* Returns the maintenance status based on platform health
|
|
14
|
+
*/
|
|
15
|
+
export declare function usePlatformHealthMonitor(): {
|
|
16
|
+
isMaintenanceMode: boolean;
|
|
17
|
+
platformHealth: import("./usePlatformHealth.js").PlatformHealthStatus | null;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Component that renders MaintenanceComponent when platform is down for maintenance
|
|
21
|
+
* Should be mounted at the root level to ensure it runs on every page
|
|
22
|
+
* The actual platform health monitoring is done in PlatformHealthProvider
|
|
23
|
+
*/
|
|
24
|
+
export declare function PlatformHealthMonitor({ MaintenanceComponent }: PlatformHealthMonitorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { usePlatformHealthContext } from './usePlatformHealth.js';
|
|
4
|
+
/**
|
|
5
|
+
* Hook that determines if platform is in maintenance mode
|
|
6
|
+
* Returns the maintenance status based on platform health
|
|
7
|
+
*/
|
|
8
|
+
export function usePlatformHealthMonitor() {
|
|
9
|
+
const { platformHealth } = usePlatformHealthContext();
|
|
10
|
+
// Show maintenance modal when status is 'OFF' or 'MAINTENANCE'
|
|
11
|
+
const isMaintenanceMode = platformHealth === 'OFF' || platformHealth === 'MAINTENANCE' || platformHealth === 'UNKNOWN';
|
|
12
|
+
return {
|
|
13
|
+
isMaintenanceMode,
|
|
14
|
+
platformHealth,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Component that renders MaintenanceComponent when platform is down for maintenance
|
|
19
|
+
* Should be mounted at the root level to ensure it runs on every page
|
|
20
|
+
* The actual platform health monitoring is done in PlatformHealthProvider
|
|
21
|
+
*/
|
|
22
|
+
export function PlatformHealthMonitor({ MaintenanceComponent }) {
|
|
23
|
+
const { isMaintenanceMode } = usePlatformHealthMonitor();
|
|
24
|
+
return _jsx(MaintenanceComponent, { enabled: isMaintenanceMode });
|
|
25
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,10 @@ export { useEgressEstimates } from './hooks/useEgressEstimates.js';
|
|
|
25
25
|
export type { UseEgressEstimatesOptions } from './hooks/useEgressEstimates.js';
|
|
26
26
|
export { useStatus } from './hooks/useStatus.js';
|
|
27
27
|
export type { StatusResponse } from './hooks/useStatus.js';
|
|
28
|
+
export { PlatformHealthProvider, usePlatformHealthContext } from './hooks/usePlatformHealth.js';
|
|
29
|
+
export type { PlatformHealthStatus, PlatformHealthContextType, PlatformHealthProviderProps, } from './hooks/usePlatformHealth.js';
|
|
30
|
+
export { PlatformHealthMonitor, usePlatformHealthMonitor, } from './hooks/usePlatformHealthMonitor.js';
|
|
31
|
+
export type { PlatformHealthMonitorProps } from './hooks/usePlatformHealthMonitor.js';
|
|
28
32
|
export { useHiddenSwapFees } from './hooks/useHiddenSwapFees.js';
|
|
29
33
|
export type { HiddenSwapFees, UseHiddenSwapFeesOptions } from './hooks/useHiddenSwapFees.js';
|
|
30
34
|
export { useSlippageUsd } from './hooks/useSlippageUsd.js';
|
package/dist/index.js
CHANGED
|
@@ -17,6 +17,8 @@ export { usePrices } from './hooks/usePrices.js';
|
|
|
17
17
|
export { useSwap, getSourceAssetCaip19, X_RANGE_SLIDER_MIN_GAP, OUTPUT_LIMIT, DEFAULT_SOURCE_ASSET, DEFAULT_DEST_ASSET, } from './hooks/useSwap.js';
|
|
18
18
|
export { useEgressEstimates } from './hooks/useEgressEstimates.js';
|
|
19
19
|
export { useStatus } from './hooks/useStatus.js';
|
|
20
|
+
export { PlatformHealthProvider, usePlatformHealthContext } from './hooks/usePlatformHealth.js';
|
|
21
|
+
export { PlatformHealthMonitor, usePlatformHealthMonitor, } from './hooks/usePlatformHealthMonitor.js';
|
|
20
22
|
export { useHiddenSwapFees } from './hooks/useHiddenSwapFees.js';
|
|
21
23
|
export { useSlippageUsd } from './hooks/useSlippageUsd.js';
|
|
22
24
|
export { useResetSwapForm } from './hooks/useResetSwapForm.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silentswap/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.53",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@ensdomains/ensjs": "^4.2.0",
|
|
26
|
-
"@silentswap/sdk": "0.0.
|
|
27
|
-
"@silentswap/ui-kit": "0.0.
|
|
26
|
+
"@silentswap/sdk": "0.0.53",
|
|
27
|
+
"@silentswap/ui-kit": "0.0.53",
|
|
28
28
|
"@solana/codecs-strings": "^5.1.0",
|
|
29
29
|
"@solana/kit": "^5.1.0",
|
|
30
30
|
"@solana/rpc": "^5.1.0",
|