@silentswap/react 0.0.98 → 0.1.1
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 +0 -1
- package/dist/hooks/silent/useQuoteCalculation.js +13 -0
- package/dist/hooks/silent/useWallet.js +12 -0
- package/dist/hooks/usePlatformHealth.d.ts +1 -1
- package/dist/hooks/usePlatformHealth.js +1 -1
- package/dist/hooks/useSwap.js +7 -1
- package/package.json +3 -3
|
@@ -261,7 +261,6 @@ function SilentSwapInnerProvider({ children, client, evmAddress, solAddress, bit
|
|
|
261
261
|
export function SilentSwapProvider({ children, client, evmAddress, solAddress, connector, isConnected, solanaConnector, solanaConnection, bitcoinConnector, bitcoinConnection, environment = ENVIRONMENT.STAGING, baseUrl, solanaRpcUrl, walletClient, bitcoinAddress, bitcoinRpcUrl, proId, requestWalletConnect, forceBridgeProvider, }) {
|
|
262
262
|
const config = useMemo(() => {
|
|
263
263
|
const computedBaseUrl = baseUrl ?? ENVIRONMENT_CONFIGS[environment].baseUrl;
|
|
264
|
-
console.log('[SilentSwapProvider] Creating config:', { environment, baseUrl, computedBaseUrl });
|
|
265
264
|
return {
|
|
266
265
|
environment,
|
|
267
266
|
baseUrl: computedBaseUrl,
|
|
@@ -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);
|
|
@@ -46,6 +46,10 @@ export function useWallet({ client, address, auth, walletClient, connector, allD
|
|
|
46
46
|
const [wallet, setWallet] = useState(null);
|
|
47
47
|
const [isLoading, setIsLoading] = useState(false);
|
|
48
48
|
const [error, setError] = useState(null);
|
|
49
|
+
// Synchronous guard to prevent concurrent generateWallet calls.
|
|
50
|
+
// React state (isLoading) is async/batched, so multiple callers can see
|
|
51
|
+
// isLoading=false in the same tick and both trigger signTypedData prompts.
|
|
52
|
+
const isGeneratingRef = useRef(false);
|
|
49
53
|
// Normalize address
|
|
50
54
|
const normalizedAddress = address ? getAddress(address) : null;
|
|
51
55
|
/**
|
|
@@ -112,6 +116,12 @@ export function useWallet({ client, address, auth, walletClient, connector, allD
|
|
|
112
116
|
if (!normalizedAddress) {
|
|
113
117
|
throw new Error('Address required for wallet generation');
|
|
114
118
|
}
|
|
119
|
+
// Synchronous guard: prevent concurrent calls from racing through
|
|
120
|
+
// before React state (isLoading) has a chance to update
|
|
121
|
+
if (isGeneratingRef.current) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
isGeneratingRef.current = true;
|
|
115
125
|
setIsLoading(true);
|
|
116
126
|
setError(null);
|
|
117
127
|
try {
|
|
@@ -163,6 +173,7 @@ export function useWallet({ client, address, auth, walletClient, connector, allD
|
|
|
163
173
|
throw error;
|
|
164
174
|
}
|
|
165
175
|
finally {
|
|
176
|
+
isGeneratingRef.current = false;
|
|
166
177
|
setIsLoading(false);
|
|
167
178
|
}
|
|
168
179
|
}, [normalizedAddress, getCachedWallet, queryDepositCount, generateEntropy, allDeposits, connector, client.s0xGatewayAddress]);
|
|
@@ -180,6 +191,7 @@ export function useWallet({ client, address, auth, walletClient, connector, allD
|
|
|
180
191
|
*/
|
|
181
192
|
const refreshWallet = useCallback(async () => {
|
|
182
193
|
clearWallet();
|
|
194
|
+
isGeneratingRef.current = false;
|
|
183
195
|
await generateWallet();
|
|
184
196
|
}, [clearWallet, generateWallet]);
|
|
185
197
|
// Clear wallet when address changes (e.g. user switched from MetaMask to Phantom)
|
|
@@ -1,6 +1,6 @@
|
|
|
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 =
|
|
3
|
+
export declare const MAX_DEPOSIT_USD = 25000;
|
|
4
4
|
export type PlatformHealthContextType = {
|
|
5
5
|
platformHealth: PlatformHealthStatus | null;
|
|
6
6
|
maximumDepositUusdc: string | undefined;
|
|
@@ -3,7 +3,7 @@ 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 =
|
|
6
|
+
export const MAX_DEPOSIT_USD = 25000;
|
|
7
7
|
const PlatformHealthContext = createContext(undefined);
|
|
8
8
|
/**
|
|
9
9
|
* Provider that monitors platform health from SilentSwapContext (which calls useStatus
|
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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@silentswap/react",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.1.1",
|
|
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.
|
|
28
|
-
"@silentswap/ui-kit": "0.
|
|
27
|
+
"@silentswap/sdk": "0.1.1",
|
|
28
|
+
"@silentswap/ui-kit": "0.1.1",
|
|
29
29
|
"@solana/codecs-strings": "^5.1.0",
|
|
30
30
|
"@solana/kit": "^5.1.0",
|
|
31
31
|
"@solana/rpc": "^5.1.0",
|