@silentswap/sdk 0.1.53 → 0.1.54

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/wallet.d.ts CHANGED
@@ -1,9 +1,15 @@
1
1
  import { type Hex } from 'viem';
2
2
  /**
3
- * Query the number of deposits made by a user to the Gateway contract
3
+ * Query the number of deposits made by a user to the Gateway contract.
4
+ *
5
+ * Tries each fallback RPC in order and returns on the first success. viem's
6
+ * built-in `fallback` transport sometimes treats WebKit's "Load failed"
7
+ * (CORS / TLS) errors as non-retryable and stops on the first URL, so we
8
+ * loop manually here to guarantee every endpoint gets a real attempt.
4
9
  *
5
10
  * @param userAddress - The user's EVM address
6
11
  * @returns The number of deposits made by the user
12
+ * @throws The last error encountered if every fallback RPC failed
7
13
  */
8
14
  export declare function queryDepositCount(userAddress: `0x${string}`, s0xGatewayAddress: Hex): Promise<bigint>;
9
15
  /**
package/dist/wallet.js CHANGED
@@ -1,47 +1,116 @@
1
1
  import { createPublicClient, http, encodeFunctionData } from 'viem';
2
2
  import { avalanche } from 'viem/chains';
3
3
  import { normalizeAddress } from './address.js';
4
+ import { H_RPCS } from './rpc.js';
4
5
  /**
5
- * Query the number of deposits made by a user to the Gateway contract
6
+ * Avalanche C-chain public RPC endpoints tried in order by {@link queryDepositCount}.
7
+ *
8
+ * The viem default (`https://api.avax.network/ext/bc/C/rpc`) is blocked by
9
+ * CORS / TLS restrictions in some in-app browsers (notably MetaMask mobile's
10
+ * in-app WebView on iOS), which causes `queryDepositCount` to fail with
11
+ * "HTTP request failed ... Load failed" before the signing step is even
12
+ * reached. We try a list of known CORS-friendly public RPCs and return the
13
+ * first successful response.
14
+ *
15
+ * Ordering rationale:
16
+ * - PublicNode first: most reliable CORS behaviour for in-app browsers.
17
+ * - meowrpc / 1rpc / Ankr: secondary CORS-enabled public endpoints.
18
+ * - api.avax.network last: preserves the previous default as a final try
19
+ * for environments where the CDN-fronted endpoints might be geoblocked.
20
+ */
21
+ const AVALANCHE_FALLBACK_RPCS = [
22
+ H_RPCS[avalanche.id],
23
+ 'https://avalanche-c-chain-rpc.publicnode.com',
24
+ 'https://avax.meowrpc.com',
25
+ 'https://1rpc.io/avax/c',
26
+ 'https://rpc.ankr.com/avalanche',
27
+ 'https://api.avax.network/ext/bc/C/rpc',
28
+ ];
29
+ const SIGNER_COUNTS_ABI = [
30
+ {
31
+ inputs: [
32
+ {
33
+ internalType: 'address',
34
+ name: '',
35
+ type: 'address',
36
+ },
37
+ ],
38
+ name: 'signerCounts',
39
+ outputs: [
40
+ {
41
+ internalType: 'uint256',
42
+ name: '',
43
+ type: 'uint256',
44
+ },
45
+ ],
46
+ stateMutability: 'view',
47
+ type: 'function',
48
+ },
49
+ ];
50
+ const QUERY_TIMEOUT_MS = 8_000;
51
+ /**
52
+ * Race a promise against a timeout so a hung fetch (no CORS preflight
53
+ * response, dead TCP socket) doesn't block the whole fallback loop.
54
+ */
55
+ async function withTimeout(promise, ms, label) {
56
+ let timer;
57
+ try {
58
+ return await Promise.race([
59
+ promise,
60
+ new Promise((_, reject) => {
61
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
62
+ }),
63
+ ]);
64
+ }
65
+ finally {
66
+ if (timer)
67
+ clearTimeout(timer);
68
+ }
69
+ }
70
+ /**
71
+ * Query the number of deposits made by a user to the Gateway contract.
72
+ *
73
+ * Tries each fallback RPC in order and returns on the first success. viem's
74
+ * built-in `fallback` transport sometimes treats WebKit's "Load failed"
75
+ * (CORS / TLS) errors as non-retryable and stops on the first URL, so we
76
+ * loop manually here to guarantee every endpoint gets a real attempt.
6
77
  *
7
78
  * @param userAddress - The user's EVM address
8
79
  * @returns The number of deposits made by the user
80
+ * @throws The last error encountered if every fallback RPC failed
9
81
  */
10
82
  export async function queryDepositCount(userAddress, s0xGatewayAddress) {
11
83
  const normalizedAddress = normalizeAddress(userAddress);
12
- // Create a public client for Avalanche
13
- const publicClient = createPublicClient({
14
- chain: avalanche,
15
- transport: http(),
16
- });
17
- // Query the signerCounts function on the Gateway contract
18
- const depositCount = await publicClient.readContract({
19
- address: s0xGatewayAddress,
20
- abi: [
21
- {
22
- inputs: [
23
- {
24
- internalType: 'address',
25
- name: '',
26
- type: 'address',
27
- },
28
- ],
29
- name: 'signerCounts',
30
- outputs: [
31
- {
32
- internalType: 'uint256',
33
- name: '',
34
- type: 'uint256',
35
- },
36
- ],
37
- stateMutability: 'view',
38
- type: 'function',
39
- },
40
- ],
41
- functionName: 'signerCounts',
42
- args: [normalizedAddress],
43
- });
44
- return depositCount;
84
+ let lastError;
85
+ for (const rpcUrl of AVALANCHE_FALLBACK_RPCS) {
86
+ try {
87
+ const publicClient = createPublicClient({
88
+ chain: avalanche,
89
+ transport: http(rpcUrl, {
90
+ // Disable viem's internal retry — we're doing our own
91
+ // fallback loop and don't want compounding delays.
92
+ retryCount: 0,
93
+ timeout: QUERY_TIMEOUT_MS,
94
+ }),
95
+ });
96
+ const depositCount = await withTimeout(publicClient.readContract({
97
+ address: s0xGatewayAddress,
98
+ abi: SIGNER_COUNTS_ABI,
99
+ functionName: 'signerCounts',
100
+ args: [normalizedAddress],
101
+ }), QUERY_TIMEOUT_MS, `queryDepositCount(${rpcUrl})`);
102
+ return depositCount;
103
+ }
104
+ catch (err) {
105
+ lastError = err;
106
+ // eslint-disable-next-line no-console
107
+ console.warn(`[queryDepositCount] ${rpcUrl} failed:`, err instanceof Error ? err.message : err);
108
+ // Try the next RPC
109
+ }
110
+ }
111
+ throw lastError instanceof Error
112
+ ? new Error(`All Avalanche RPC endpoints failed. Last error: ${lastError.message}`)
113
+ : new Error('All Avalanche RPC endpoints failed');
45
114
  }
46
115
  // Nil data constants for phony deposit calldata
47
116
  const NIL_DATA_32 = '0x0000000000000000000000000000000000000000000000000000000000000000';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@silentswap/sdk",
3
3
  "type": "module",
4
- "version": "0.1.53",
4
+ "version": "0.1.54",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
7
7
  "files": [