@silentswap/react 0.1.0 → 0.1.2
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.
|
@@ -193,6 +193,11 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
|
|
|
193
193
|
return amountStr;
|
|
194
194
|
});
|
|
195
195
|
const outputs = destinations.map((dest, idx) => {
|
|
196
|
+
// Validate destination asset exists in the asset registry
|
|
197
|
+
// This prevents invalid CAIP-19 identifiers (e.g. erc20 with zero address) from reaching the quote API
|
|
198
|
+
if (!getAssetByCaip19(dest.asset)) {
|
|
199
|
+
throw new Error(`Unknown destination asset: ${dest.asset}. Asset not found in registry.`);
|
|
200
|
+
}
|
|
196
201
|
const isDestSolana = isSolanaAsset(dest.asset);
|
|
197
202
|
const isDestBitcoin = isBitcoinAsset(dest.asset);
|
|
198
203
|
let asset;
|
|
@@ -272,6 +277,14 @@ export function useQuoteCalculation({ address, evmAddress, wallet, depositorAddr
|
|
|
272
277
|
// - Using isEvmNativeToken() would incorrectly try to construct erc20:null
|
|
273
278
|
const isNative = destParsed.isNative;
|
|
274
279
|
const destChainId = destParsed.chainId;
|
|
280
|
+
// Reject ERC-20 tokens with the zero address — the zero address is not a valid
|
|
281
|
+
// ERC-20 contract. Native tokens should use slip44 namespace instead.
|
|
282
|
+
if (!isNative &&
|
|
283
|
+
destParsed.tokenAddress &&
|
|
284
|
+
/^0x0+$/.test(destParsed.tokenAddress)) {
|
|
285
|
+
throw new Error(`Invalid ERC-20 token address for destination ${idx}: zero address is not a valid token. ` +
|
|
286
|
+
`Use slip44 namespace for native tokens (e.g. eip155:${destChainId}/slip44:60).`);
|
|
287
|
+
}
|
|
275
288
|
asset = isNative
|
|
276
289
|
? dest.asset
|
|
277
290
|
: caip19FungibleEvmToken(destChainId, destParsed.tokenAddress);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
export type PlatformHealthStatus = 'ON' | 'ONLINE' | 'PAUSED' | 'DEPOSITS_PAUSED' | 'OFF' | 'MAINTENANCE' | 'UNKNOWN';
|
|
3
|
-
export declare const MAX_DEPOSIT_USD = 25000;
|
|
4
3
|
export type PlatformHealthContextType = {
|
|
5
4
|
platformHealth: PlatformHealthStatus | null;
|
|
6
5
|
maximumDepositUusdc: string | undefined;
|
|
@@ -14,6 +13,8 @@ export type PlatformHealthContextType = {
|
|
|
14
13
|
storage: Record<string, string> | undefined;
|
|
15
14
|
formDisabled: boolean;
|
|
16
15
|
trackingDisabled: boolean;
|
|
16
|
+
/** Effective maximum deposit in USD (min of admin cap and platform API cap), or null if no cap. */
|
|
17
|
+
effectiveMaxDepositUsd: number | null;
|
|
17
18
|
validateDepositAmount: (usdAmount: string | number) => {
|
|
18
19
|
valid: boolean;
|
|
19
20
|
error?: string;
|
|
@@ -43,13 +44,19 @@ export type PlatformHealthProviderProps = {
|
|
|
43
44
|
* If not provided, trackingDisabled will always be false in the context
|
|
44
45
|
*/
|
|
45
46
|
onTrackingDisabledChange?: (disabled: boolean) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Optional maximum deposit amount in USD, typically fetched from admin dashboard settings.
|
|
49
|
+
* If not provided (undefined), no frontend cap is enforced — only the platform
|
|
50
|
+
* API's own maximumDepositUusdc limit applies.
|
|
51
|
+
*/
|
|
52
|
+
maxDepositUsd?: number;
|
|
46
53
|
};
|
|
47
54
|
/**
|
|
48
55
|
* Provider that monitors platform health from SilentSwapContext (which calls useStatus
|
|
49
56
|
* once with proId) and provides validation functions for deposit amounts, output limits,
|
|
50
57
|
* and service fee rates.
|
|
51
58
|
*/
|
|
52
|
-
export declare function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, }: PlatformHealthProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
export declare function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, maxDepositUsd, }: PlatformHealthProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
53
60
|
/**
|
|
54
61
|
* Hook to access platform health context
|
|
55
62
|
*/
|
|
@@ -3,14 +3,13 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import React, { createContext, useContext, useEffect, useMemo, useCallback } from 'react';
|
|
4
4
|
import { useSilentSwap } from '../contexts/SilentSwapContext.js';
|
|
5
5
|
import { BigNumber } from 'bignumber.js';
|
|
6
|
-
export const MAX_DEPOSIT_USD = 25000;
|
|
7
6
|
const PlatformHealthContext = createContext(undefined);
|
|
8
7
|
/**
|
|
9
8
|
* Provider that monitors platform health from SilentSwapContext (which calls useStatus
|
|
10
9
|
* once with proId) and provides validation functions for deposit amounts, output limits,
|
|
11
10
|
* and service fee rates.
|
|
12
11
|
*/
|
|
13
|
-
export function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, }) {
|
|
12
|
+
export function PlatformHealthProvider({ children, onFormDisabledChange, onTrackingDisabledChange, maxDepositUsd, }) {
|
|
14
13
|
// Consume status data from parent SilentSwapContext instead of calling useStatus again
|
|
15
14
|
const { status } = useSilentSwap();
|
|
16
15
|
const { platformHealth: statusPlatformHealth, maximumDepositUusdc, minimumDepositUusdc, outputLimit, serviceFeeRate, overheadUsd, identity, volume, liquidity, storage, } = status;
|
|
@@ -98,6 +97,13 @@ export function PlatformHealthProvider({ children, onFormDisabledChange, onTrack
|
|
|
98
97
|
return 0.01;
|
|
99
98
|
return rate;
|
|
100
99
|
}, [serviceFeeRate]);
|
|
100
|
+
// Compute effective max deposit: min of admin cap and platform API cap, or null if neither is set
|
|
101
|
+
const effectiveMaxDepositUsd = useMemo(() => {
|
|
102
|
+
const platformMax = getMaximumDepositUsd();
|
|
103
|
+
if (maxDepositUsd != null && platformMax != null)
|
|
104
|
+
return Math.min(maxDepositUsd, platformMax);
|
|
105
|
+
return maxDepositUsd ?? platformMax ?? null;
|
|
106
|
+
}, [maxDepositUsd, getMaximumDepositUsd]);
|
|
101
107
|
// Validate deposit amount against min/max limits
|
|
102
108
|
const validateDepositAmount = useCallback((usdAmount) => {
|
|
103
109
|
const amount = typeof usdAmount === 'string' ? parseFloat(usdAmount) : usdAmount;
|
|
@@ -105,15 +111,14 @@ export function PlatformHealthProvider({ children, onFormDisabledChange, onTrack
|
|
|
105
111
|
return { valid: false, error: 'Amount must be greater than zero' };
|
|
106
112
|
}
|
|
107
113
|
const minUsd = getMinimumDepositUsd();
|
|
108
|
-
const maxUsd = Math.min(MAX_DEPOSIT_USD, getMaximumDepositUsd() ?? MAX_DEPOSIT_USD);
|
|
109
114
|
if (minUsd !== null && amount < minUsd) {
|
|
110
115
|
return { valid: false, error: `Minimum value is $${minUsd.toFixed(2)}` };
|
|
111
116
|
}
|
|
112
|
-
if (
|
|
113
|
-
return { valid: false, error: `Maximum value is $${
|
|
117
|
+
if (effectiveMaxDepositUsd !== null && amount > effectiveMaxDepositUsd) {
|
|
118
|
+
return { valid: false, error: `Maximum value is $${effectiveMaxDepositUsd.toFixed(2)}` };
|
|
114
119
|
}
|
|
115
120
|
return { valid: true };
|
|
116
|
-
}, [getMinimumDepositUsd,
|
|
121
|
+
}, [getMinimumDepositUsd, effectiveMaxDepositUsd]);
|
|
117
122
|
// Validate output count against limit
|
|
118
123
|
const validateOutputCount = useCallback((count) => {
|
|
119
124
|
if (outputLimit === null || outputLimit === undefined) {
|
|
@@ -144,6 +149,7 @@ export function PlatformHealthProvider({ children, onFormDisabledChange, onTrack
|
|
|
144
149
|
storage,
|
|
145
150
|
formDisabled,
|
|
146
151
|
trackingDisabled,
|
|
152
|
+
effectiveMaxDepositUsd,
|
|
147
153
|
validateDepositAmount,
|
|
148
154
|
validateOutputCount,
|
|
149
155
|
getMinimumDepositUsd,
|
|
@@ -162,6 +168,7 @@ export function PlatformHealthProvider({ children, onFormDisabledChange, onTrack
|
|
|
162
168
|
storage,
|
|
163
169
|
formDisabled,
|
|
164
170
|
trackingDisabled,
|
|
171
|
+
effectiveMaxDepositUsd,
|
|
165
172
|
validateDepositAmount,
|
|
166
173
|
validateOutputCount,
|
|
167
174
|
getMinimumDepositUsd,
|
package/dist/hooks/useSwap.js
CHANGED
|
@@ -194,11 +194,17 @@ const useSwapStore = create()(persist((set, get) => ({
|
|
|
194
194
|
return false;
|
|
195
195
|
},
|
|
196
196
|
updateDestinationAsset: (index, asset) => {
|
|
197
|
+
const assetStr = String(asset);
|
|
198
|
+
// Validate that the asset CAIP-19 exists in the registry
|
|
199
|
+
if (!getAssetByCaip19(assetStr)) {
|
|
200
|
+
console.warn(`[useSwap] Ignoring unknown destination asset: ${assetStr}`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
197
203
|
set((state) => {
|
|
198
204
|
return {
|
|
199
205
|
destinations: state.destinations.map((dest, idx) => idx === index
|
|
200
206
|
? {
|
|
201
|
-
asset:
|
|
207
|
+
asset: assetStr,
|
|
202
208
|
contact: String(dest.contact),
|
|
203
209
|
amount: '',
|
|
204
210
|
priceUsd: dest.priceUsd,
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,6 @@ export { useStatus } from './hooks/useStatus.js';
|
|
|
29
29
|
export type { StatusResponse, UseStatusOptions } from './hooks/useStatus.js';
|
|
30
30
|
export { PlatformHealthProvider, usePlatformHealthContext } from './hooks/usePlatformHealth.js';
|
|
31
31
|
export type { PlatformHealthStatus, PlatformHealthContextType, PlatformHealthProviderProps, } from './hooks/usePlatformHealth.js';
|
|
32
|
-
export { MAX_DEPOSIT_USD } from './hooks/usePlatformHealth.js';
|
|
33
32
|
export { PlatformHealthMonitor, usePlatformHealthMonitor, } from './hooks/usePlatformHealthMonitor.js';
|
|
34
33
|
export type { PlatformHealthMonitorProps } from './hooks/usePlatformHealthMonitor.js';
|
|
35
34
|
export { useHiddenSwapFees } from './hooks/useHiddenSwapFees.js';
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,6 @@ export { useSwap, getSourceAssetCaip19, X_RANGE_SLIDER_MIN_GAP, OUTPUT_LIMIT, DE
|
|
|
19
19
|
export { useEgressEstimates } from './hooks/useEgressEstimates.js';
|
|
20
20
|
export { useStatus } from './hooks/useStatus.js';
|
|
21
21
|
export { PlatformHealthProvider, usePlatformHealthContext } from './hooks/usePlatformHealth.js';
|
|
22
|
-
export { MAX_DEPOSIT_USD } from './hooks/usePlatformHealth.js';
|
|
23
22
|
export { PlatformHealthMonitor, usePlatformHealthMonitor, } from './hooks/usePlatformHealthMonitor.js';
|
|
24
23
|
export { useHiddenSwapFees } from './hooks/useHiddenSwapFees.js';
|
|
25
24
|
export { useSlippageUsd } from './hooks/useSlippageUsd.js';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silentswap/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@bigmi/core": "^0.6.5",
|
|
26
26
|
"@ensdomains/ensjs": "^4.2.0",
|
|
27
|
-
"@silentswap/sdk": "0.1.
|
|
28
|
-
"@silentswap/ui-kit": "0.1.
|
|
27
|
+
"@silentswap/sdk": "0.1.2",
|
|
28
|
+
"@silentswap/ui-kit": "0.1.2",
|
|
29
29
|
"@solana/codecs-strings": "^5.1.0",
|
|
30
30
|
"@solana/kit": "^5.1.0",
|
|
31
31
|
"@solana/rpc": "^5.1.0",
|