@silentswap/sdk 0.1.3 → 0.1.41
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/chain.d.ts +13 -0
- package/dist/chain.js +72 -8
- package/package.json +1 -1
package/dist/chain.d.ts
CHANGED
|
@@ -13,6 +13,19 @@ import type { Connector } from 'wagmi';
|
|
|
13
13
|
export declare function ensureChain(chainId: number, walletClient: WalletClient, connector: Connector, options?: {
|
|
14
14
|
required?: boolean;
|
|
15
15
|
}): Promise<WalletClient>;
|
|
16
|
+
/**
|
|
17
|
+
* Ping the WalletConnect session to ensure the relay WebSocket is alive.
|
|
18
|
+
* Browsers cannot detect stale WebSockets (no ping/pong frames), so a signing
|
|
19
|
+
* request sent on a dead socket silently vanishes. Pinging first forces
|
|
20
|
+
* the relay to reconnect if the connection dropped.
|
|
21
|
+
*
|
|
22
|
+
* @param connector - The wagmi connector (must be WalletConnect)
|
|
23
|
+
* @returns true if ping succeeded, false if it failed or connector is not WalletConnect
|
|
24
|
+
*/
|
|
25
|
+
export declare function pingWalletConnectSession(connector: {
|
|
26
|
+
type: string;
|
|
27
|
+
getProvider: () => Promise<unknown>;
|
|
28
|
+
}): Promise<boolean>;
|
|
16
29
|
/**
|
|
17
30
|
* Create a public client with RPC fallback configuration
|
|
18
31
|
*
|
package/dist/chain.js
CHANGED
|
@@ -13,6 +13,13 @@ import { H_RPCS } from './rpc.js';
|
|
|
13
13
|
*/
|
|
14
14
|
export async function ensureChain(chainId, walletClient, connector, options) {
|
|
15
15
|
const required = options?.required ?? true;
|
|
16
|
+
console.log('[ensureChain] called', {
|
|
17
|
+
targetChainId: chainId,
|
|
18
|
+
required,
|
|
19
|
+
connectorName: connector.name,
|
|
20
|
+
connectorType: connector.type,
|
|
21
|
+
walletClientChain: walletClient.chain?.id,
|
|
22
|
+
});
|
|
16
23
|
// Check current chain
|
|
17
24
|
let currentChainId;
|
|
18
25
|
try {
|
|
@@ -22,35 +29,92 @@ export async function ensureChain(chainId, walletClient, connector, options) {
|
|
|
22
29
|
// If we can't get chain ID, assume we need to switch
|
|
23
30
|
currentChainId = -1;
|
|
24
31
|
}
|
|
32
|
+
console.log('[ensureChain] currentChainId:', currentChainId, 'targetChainId:', chainId, 'needsSwitch:', currentChainId !== chainId);
|
|
25
33
|
if (currentChainId !== chainId) {
|
|
34
|
+
let switchSucceeded = false;
|
|
26
35
|
try {
|
|
27
36
|
// Try to switch chain
|
|
37
|
+
console.log('[ensureChain] attempting switchChain ...', { hasSwitchChain: !!connector.switchChain });
|
|
28
38
|
await connector.switchChain?.({ chainId });
|
|
39
|
+
switchSucceeded = true;
|
|
40
|
+
console.log('[ensureChain] switchChain succeeded');
|
|
29
41
|
}
|
|
30
42
|
catch (switchError) {
|
|
43
|
+
console.warn('[ensureChain] switchChain failed', {
|
|
44
|
+
error: switchError instanceof Error ? switchError.message : switchError,
|
|
45
|
+
required,
|
|
46
|
+
});
|
|
31
47
|
if (required) {
|
|
32
48
|
throw new Error(`Failed to switch to chain ${chainId}`);
|
|
33
49
|
}
|
|
34
50
|
// Non-required: chain switch failed (e.g. Trust Wallet via WalletConnect
|
|
35
|
-
// doesn't support programmatic chain switching).
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
|
|
51
|
+
// doesn't support programmatic chain switching). Still recreate the
|
|
52
|
+
// walletClient from the provider so the WalletConnect transport is fresh
|
|
53
|
+
// — TrustWallet silently drops signTypedData when the client's chain scope
|
|
54
|
+
// doesn't match its active session chain.
|
|
39
55
|
}
|
|
40
|
-
//
|
|
56
|
+
// Always recreate walletClient from the provider after a chain change attempt.
|
|
41
57
|
// Critical for WalletConnect: the old walletClient's chain scope (e.g. eip155:43114)
|
|
42
|
-
// doesn't match the
|
|
43
|
-
// by the mobile wallet.
|
|
58
|
+
// doesn't match the active chain, so signing requests get silently dropped
|
|
59
|
+
// by the mobile wallet. This applies both after a successful switch AND a failed
|
|
60
|
+
// one — the provider's internal state may still have updated even if switchChain threw.
|
|
61
|
+
console.log('[ensureChain] recreating walletClient from provider ...', { switchSucceeded });
|
|
44
62
|
const provider = await connector.getProvider();
|
|
45
63
|
const chain = getChainById(chainId);
|
|
46
|
-
|
|
64
|
+
const newClient = createWalletClient({
|
|
47
65
|
account: walletClient.account,
|
|
48
66
|
chain,
|
|
49
67
|
transport: custom(provider),
|
|
50
68
|
});
|
|
69
|
+
console.log('[ensureChain] new walletClient created', {
|
|
70
|
+
chainId: newClient.chain?.id,
|
|
71
|
+
account: newClient.account?.address,
|
|
72
|
+
});
|
|
73
|
+
return newClient;
|
|
51
74
|
}
|
|
75
|
+
console.log('[ensureChain] already on correct chain, returning existing walletClient');
|
|
52
76
|
return walletClient;
|
|
53
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Ping the WalletConnect session to ensure the relay WebSocket is alive.
|
|
80
|
+
* Browsers cannot detect stale WebSockets (no ping/pong frames), so a signing
|
|
81
|
+
* request sent on a dead socket silently vanishes. Pinging first forces
|
|
82
|
+
* the relay to reconnect if the connection dropped.
|
|
83
|
+
*
|
|
84
|
+
* @param connector - The wagmi connector (must be WalletConnect)
|
|
85
|
+
* @returns true if ping succeeded, false if it failed or connector is not WalletConnect
|
|
86
|
+
*/
|
|
87
|
+
export async function pingWalletConnectSession(connector) {
|
|
88
|
+
if (connector.type !== 'walletConnect')
|
|
89
|
+
return true; // Not WC, nothing to ping
|
|
90
|
+
try {
|
|
91
|
+
const provider = await connector.getProvider();
|
|
92
|
+
const topic = provider?.session?.topic;
|
|
93
|
+
// Try both paths: Reown (provider.client) and legacy WC (provider.signer.client)
|
|
94
|
+
const signClient = provider?.client?.ping ? provider.client : provider?.signer?.client;
|
|
95
|
+
if (!topic || !signClient?.ping) {
|
|
96
|
+
console.log('[pingWC] no session or sign client, skipping ping', {
|
|
97
|
+
hasTopic: !!topic,
|
|
98
|
+
hasClient: !!provider?.client,
|
|
99
|
+
hasClientPing: !!provider?.client?.ping,
|
|
100
|
+
hasSigner: !!provider?.signer,
|
|
101
|
+
hasSignerClient: !!provider?.signer?.client,
|
|
102
|
+
});
|
|
103
|
+
return true; // Can't ping, assume ok
|
|
104
|
+
}
|
|
105
|
+
console.log('[pingWC] pinging session ...');
|
|
106
|
+
await Promise.race([
|
|
107
|
+
signClient.ping({ topic }),
|
|
108
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('WC ping timeout')), 5000)),
|
|
109
|
+
]);
|
|
110
|
+
console.log('[pingWC] ping OK');
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
catch (err) {
|
|
114
|
+
console.warn('[pingWC] ping failed, session may be stale:', err.message);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
54
118
|
/**
|
|
55
119
|
* Create a public client with RPC fallback configuration
|
|
56
120
|
*
|