@silentswap/sdk 0.0.21 → 0.0.22

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/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export type { SilentSwapClientConfig, SilentSwapClient, } from './client.js';
2
2
  export type * from './types/api.js';
3
- export type { Caip19 } from './types/core.js';
3
+ export type { Caip19, SignInMessage } from './types/core.js';
4
4
  export type { EvmSigner } from './types/sdk.js';
5
5
  export * from './order.js';
6
6
  export * from './caip19.js';
@@ -10,3 +10,11 @@ export * from './gateway-abi.js';
10
10
  export { createHdFacilitatorGroupFromEntropy, exportSecretMnemonicFromEntropy, type HdFacilitatorGroup, } from './hd-facilitator-group.js';
11
11
  export { createSignInMessage, createEip712DocForOrder, createEip712DocForWalletGeneration, } from './sdk.js';
12
12
  export { createViemSigner, parseTransactionRequestForViem, } from './signer-adapters/viem.js';
13
+ export * from './bridge.js';
14
+ export * from './quote-utils.js';
15
+ export * from './transaction-utils.js';
16
+ export * from './wallet.js';
17
+ export * from './storage.js';
18
+ export * from './chain.js';
19
+ export * from './constants.js';
20
+ export * from './assets.js';
package/dist/index.js CHANGED
@@ -6,3 +6,11 @@ export * from './gateway-abi.js';
6
6
  export { createHdFacilitatorGroupFromEntropy, exportSecretMnemonicFromEntropy, } from './hd-facilitator-group.js';
7
7
  export { createSignInMessage, createEip712DocForOrder, createEip712DocForWalletGeneration, } from './sdk.js';
8
8
  export { createViemSigner, parseTransactionRequestForViem, } from './signer-adapters/viem.js';
9
+ export * from './bridge.js';
10
+ export * from './quote-utils.js';
11
+ export * from './transaction-utils.js';
12
+ export * from './wallet.js';
13
+ export * from './storage.js';
14
+ export * from './chain.js';
15
+ export * from './constants.js';
16
+ export * from './assets.js';
@@ -0,0 +1,75 @@
1
+ import type { BridgeProvider, RelayQuoteResponse, DeBridgeOrderResponse } from './bridge.js';
2
+ /**
3
+ * Estimate sample for retention rate interpolation
4
+ */
5
+ export interface EstimateSample {
6
+ /** USD baseline value for this sample */
7
+ baseline: number;
8
+ /** Retention rate (0-1) - how much value is retained after fees */
9
+ retention: number;
10
+ /** Bridge source that provided this sample */
11
+ source: BridgeProvider | 'none';
12
+ }
13
+ /**
14
+ * Estimate for a given direction (ingress or egress)
15
+ */
16
+ export interface Estimate {
17
+ /** Gas fee in USD for this direction */
18
+ gasFee: number;
19
+ /** Array of samples for retention rate interpolation */
20
+ samples: EstimateSample[];
21
+ }
22
+ /**
23
+ * Quote metrics calculated from provider responses
24
+ */
25
+ export interface QuoteMetrics {
26
+ retention: number;
27
+ feeUsd: number;
28
+ slippage: number;
29
+ time: number;
30
+ txCount: number;
31
+ }
32
+ /**
33
+ * Quote result with all necessary information
34
+ */
35
+ export interface BridgeQuoteResult {
36
+ /** Selected bridge provider */
37
+ provider: BridgeProvider;
38
+ /** Output amount in destination token units (as string) */
39
+ outputAmount: string;
40
+ /** Input amount required in source token units (as string) */
41
+ inputAmount: string;
42
+ /** Total fee in USD */
43
+ feeUsd: number;
44
+ /** Price slippage/impact percentage */
45
+ slippage: number;
46
+ /** Estimated time in seconds */
47
+ estimatedTime: number;
48
+ /** Retention rate (how much value is retained after fees, 0-1) */
49
+ retentionRate: number;
50
+ /** Number of transactions required */
51
+ txCount: number;
52
+ /** Raw response from the provider */
53
+ rawResponse: RelayQuoteResponse | DeBridgeOrderResponse;
54
+ }
55
+ /**
56
+ * Calculate metrics from a Relay.link quote response
57
+ */
58
+ export declare function calculateRelayMetrics(relayQuote: RelayQuoteResponse): QuoteMetrics;
59
+ /**
60
+ * Calculate metrics from a deBridge quote response
61
+ */
62
+ export declare function calculateDebridgeMetrics(debridgeQuote: DeBridgeOrderResponse): QuoteMetrics;
63
+ /**
64
+ * Select the best quote from multiple providers based on retention rate
65
+ */
66
+ export declare function selectBestQuote(relayQuote: RelayQuoteResponse | null, debridgeQuote: DeBridgeOrderResponse | null, srcAmount: string): BridgeQuoteResult;
67
+ /**
68
+ * Interpolate retention rate from samples
69
+ */
70
+ export declare function interpolateSamples(samples: EstimateSample[], usdValue: number, marginHi?: number): number;
71
+ /**
72
+ * Get quote for cross-chain swap from multiple providers
73
+ * This is the core logic shared between React and Vue
74
+ */
75
+ export declare function getBridgeQuote(srcChainId: number, srcToken: string, srcAmount: string, dstChainId: number, dstToken: string, userAddress: `0x${string}`, signal?: AbortSignal): Promise<BridgeQuoteResult>;
@@ -0,0 +1,185 @@
1
+ import BigNumber from 'bignumber.js';
2
+ import { fetchRelayQuote, fetchDebridgeOrder, } from './bridge.js';
3
+ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
4
+ /**
5
+ * Calculate metrics from a Relay.link quote response
6
+ */
7
+ export function calculateRelayMetrics(relayQuote) {
8
+ const usdIn = relayQuote.details.currencyIn.amountUsd;
9
+ const usdOut = relayQuote.details.currencyOut.amountUsd;
10
+ return {
11
+ retention: BigNumber(usdOut).div(usdIn).toNumber(),
12
+ feeUsd: Number(relayQuote.fees.relayerGas?.amountUsd || relayQuote.fees.gas?.amountUsd || '0'),
13
+ slippage: Number(relayQuote.details.totalImpact?.percent || '0') * 100,
14
+ time: relayQuote.details.timeEstimate || 300,
15
+ txCount: relayQuote.steps?.length || 1,
16
+ };
17
+ }
18
+ /**
19
+ * Calculate metrics from a deBridge quote response
20
+ */
21
+ export function calculateDebridgeMetrics(debridgeQuote) {
22
+ const usdIn = debridgeQuote.estimation.srcChainTokenIn.approximateUsdValue;
23
+ const usdOut = debridgeQuote.estimation.dstChainTokenOut.approximateUsdValue;
24
+ return {
25
+ retention: BigNumber(usdOut).div(usdIn).toNumber(),
26
+ feeUsd: debridgeQuote.estimation.costDetails
27
+ ?.reduce((sum, detail) => sum + Number(detail.payload?.feeApproximateUsdValue || 0), 0) || 0,
28
+ slippage: 100 * (1 - usdOut / usdIn),
29
+ time: debridgeQuote.order?.approximateFulfillmentDelay || 600,
30
+ txCount: 2, // DeBridge typically requires 2 txs
31
+ };
32
+ }
33
+ /**
34
+ * Select the best quote from multiple providers based on retention rate
35
+ */
36
+ export function selectBestQuote(relayQuote, debridgeQuote, srcAmount) {
37
+ // Calculate metrics for each provider
38
+ const relayMetrics = relayQuote ? calculateRelayMetrics(relayQuote) : null;
39
+ const debridgeMetrics = debridgeQuote ? calculateDebridgeMetrics(debridgeQuote) : null;
40
+ // Both providers failed
41
+ if (!relayQuote && !debridgeQuote) {
42
+ throw new Error('All quote providers failed');
43
+ }
44
+ // Determine best provider based on retention rate
45
+ let bestProvider;
46
+ let bestQuote;
47
+ let bestMetrics;
48
+ if (!relayQuote || (debridgeMetrics && debridgeMetrics.retention > (relayMetrics?.retention || 0))) {
49
+ bestProvider = 'debridge';
50
+ bestQuote = debridgeQuote;
51
+ bestMetrics = debridgeMetrics;
52
+ }
53
+ else {
54
+ bestProvider = 'relay';
55
+ bestQuote = relayQuote;
56
+ bestMetrics = relayMetrics;
57
+ }
58
+ // Extract output amount
59
+ const outputAmount = bestProvider === 'relay'
60
+ ? bestQuote.details.currencyOut.amount
61
+ : bestQuote.estimation.dstChainTokenOut.amount;
62
+ return {
63
+ provider: bestProvider,
64
+ outputAmount: outputAmount || '0',
65
+ inputAmount: srcAmount,
66
+ feeUsd: bestMetrics.feeUsd,
67
+ slippage: bestMetrics.slippage,
68
+ estimatedTime: bestMetrics.time,
69
+ retentionRate: bestMetrics.retention,
70
+ txCount: bestMetrics.txCount,
71
+ rawResponse: bestQuote,
72
+ };
73
+ }
74
+ /**
75
+ * Interpolate retention rate from samples
76
+ */
77
+ export function interpolateSamples(samples, usdValue, marginHi = Infinity) {
78
+ if (samples.length === 0) {
79
+ throw new Error('No samples provided');
80
+ }
81
+ let lo = samples[0];
82
+ let hi = samples[samples.length - 1];
83
+ // Less than or equal to lo
84
+ if (usdValue <= lo.baseline) {
85
+ return lo.retention;
86
+ }
87
+ // Greater than or equal to hi
88
+ if (usdValue >= hi.baseline) {
89
+ // Exclusive hi with margin check
90
+ if (usdValue > hi.baseline + marginHi) {
91
+ throw new Error(`Value ${usdValue} exceeds maximum ${hi.baseline} by more than margin ${marginHi}`);
92
+ }
93
+ return hi.retention;
94
+ }
95
+ // In range - find bracketing samples
96
+ for (let i = 0; i < samples.length; i++) {
97
+ const sample = samples[i];
98
+ // Exact match
99
+ if (sample.baseline === usdValue) {
100
+ return sample.retention;
101
+ }
102
+ // Target is greater than sample
103
+ if (usdValue > sample.baseline) {
104
+ lo = sample;
105
+ }
106
+ else {
107
+ // Target is lower than sample
108
+ hi = sample;
109
+ break;
110
+ }
111
+ }
112
+ // Linear interpolation
113
+ const deltaY = hi.retention - lo.retention;
114
+ const deltaX = hi.baseline - lo.baseline;
115
+ return ((usdValue - lo.baseline) / deltaX) * deltaY + lo.retention;
116
+ }
117
+ /**
118
+ * Get quote for cross-chain swap from multiple providers
119
+ * This is the core logic shared between React and Vue
120
+ */
121
+ export async function getBridgeQuote(srcChainId, srcToken, srcAmount, dstChainId, dstToken, userAddress, signal) {
122
+ // Normalize addresses
123
+ const srcTokenNorm = srcToken === '0x0' || srcToken === '0x0000000000000000000000000000000000000000'
124
+ ? ZERO_ADDRESS
125
+ : srcToken;
126
+ const dstTokenNorm = dstToken === '0x0' || dstToken === '0x0000000000000000000000000000000000000000'
127
+ ? ZERO_ADDRESS
128
+ : dstToken;
129
+ // Fetch quotes from both providers in parallel
130
+ const [relayResult, debridgeResult] = await Promise.allSettled([
131
+ // Relay.link quote
132
+ (async () => {
133
+ try {
134
+ const quote = await fetchRelayQuote({
135
+ user: userAddress,
136
+ referrer: 'silentswap',
137
+ originChainId: srcChainId,
138
+ destinationChainId: dstChainId,
139
+ originCurrency: srcTokenNorm,
140
+ destinationCurrency: dstTokenNorm,
141
+ amount: srcAmount,
142
+ tradeType: 'EXACT_INPUT',
143
+ }, signal);
144
+ return quote;
145
+ }
146
+ catch (err) {
147
+ if (err instanceof Error && err.name !== 'AbortError') {
148
+ console.warn('Relay quote failed:', err);
149
+ }
150
+ return null;
151
+ }
152
+ })(),
153
+ // deBridge quote
154
+ (async () => {
155
+ try {
156
+ const quote = await fetchDebridgeOrder({
157
+ srcChainId,
158
+ srcChainTokenIn: srcTokenNorm,
159
+ srcChainTokenInAmount: srcAmount,
160
+ dstChainId,
161
+ dstChainTokenOut: dstTokenNorm,
162
+ dstChainTokenOutAmount: 'auto',
163
+ prependOperatingExpenses: true,
164
+ }, signal);
165
+ return quote;
166
+ }
167
+ catch (err) {
168
+ if (err instanceof Error && err.name !== 'AbortError') {
169
+ console.warn('DeBridge quote failed:', err);
170
+ }
171
+ return null;
172
+ }
173
+ })(),
174
+ ]);
175
+ const relayQuote = relayResult.status === 'fulfilled' ? relayResult.value : null;
176
+ const debridgeQuote = debridgeResult.status === 'fulfilled' ? debridgeResult.value : null;
177
+ // Select best quote
178
+ const result = selectBestQuote(relayQuote, debridgeQuote, srcAmount);
179
+ console.info(`Selected ${result.provider} for quote:`, {
180
+ retention: result.retentionRate,
181
+ feeUsd: result.feeUsd,
182
+ time: result.estimatedTime,
183
+ });
184
+ return result;
185
+ }
@@ -0,0 +1,74 @@
1
+ import type { AuthResponse } from './types/api.js';
2
+ /**
3
+ * Storage key prefix for authentication data
4
+ */
5
+ export declare const STORAGE_KEY_AUTH_PREFIX = "silentswap:auth:";
6
+ /**
7
+ * Storage key prefix for wallet data
8
+ */
9
+ export declare const STORAGE_KEY_WALLET_PREFIX = "silentswap:signer:";
10
+ /**
11
+ * Get storage key for authentication data
12
+ *
13
+ * @param address - The user's EVM address
14
+ * @returns The storage key for the auth data
15
+ */
16
+ export declare function getAuthStorageKey(address: `0x${string}`): string;
17
+ /**
18
+ * Get storage key for wallet data
19
+ *
20
+ * @param address - The user's EVM address
21
+ * @returns The storage key for the wallet data
22
+ */
23
+ export declare function getWalletStorageKey(address: `0x${string}`): string;
24
+ /**
25
+ * Load cached authentication data
26
+ *
27
+ * @param address - The user's EVM address
28
+ * @returns The cached auth response or null if not found/expired
29
+ */
30
+ export declare function loadCachedAuth(address: `0x${string}`): AuthResponse | null;
31
+ /**
32
+ * Save authentication data to cache
33
+ *
34
+ * @param address - The user's EVM address
35
+ * @param authData - The authentication response to cache
36
+ */
37
+ export declare function saveAuth(address: `0x${string}`, authData: AuthResponse): void;
38
+ /**
39
+ * Clear cached authentication data
40
+ *
41
+ * @param address - The user's EVM address
42
+ */
43
+ export declare function clearAuth(address: `0x${string}`): void;
44
+ /**
45
+ * Save wallet data to sessionStorage
46
+ *
47
+ * @param address - The user's EVM address
48
+ * @param walletData - The wallet data to cache
49
+ * @param expirationMs - Expiration time in milliseconds from now
50
+ */
51
+ export declare function saveWalletData(address: `0x${string}`, walletData: {
52
+ entropy: string;
53
+ accounts: {
54
+ nonce: number;
55
+ }[];
56
+ }, expirationMs?: number): void;
57
+ /**
58
+ * Load cached wallet data from sessionStorage
59
+ *
60
+ * @param address - The user's EVM address
61
+ * @returns The cached wallet data or null if not found/expired
62
+ */
63
+ export declare function loadWalletData(address: `0x${string}`): {
64
+ entropy: string;
65
+ accounts: {
66
+ nonce: number;
67
+ }[];
68
+ } | null;
69
+ /**
70
+ * Clear cached wallet data
71
+ *
72
+ * @param address - The user's EVM address
73
+ */
74
+ export declare function clearWalletData(address: `0x${string}`): void;
@@ -0,0 +1,161 @@
1
+ import { getAddress } from 'viem';
2
+ /**
3
+ * Storage key prefix for authentication data
4
+ */
5
+ export const STORAGE_KEY_AUTH_PREFIX = 'silentswap:auth:';
6
+ /**
7
+ * Storage key prefix for wallet data
8
+ */
9
+ export const STORAGE_KEY_WALLET_PREFIX = 'silentswap:signer:';
10
+ /**
11
+ * Get storage key for authentication data
12
+ *
13
+ * @param address - The user's EVM address
14
+ * @returns The storage key for the auth data
15
+ */
16
+ export function getAuthStorageKey(address) {
17
+ return `${STORAGE_KEY_AUTH_PREFIX}${getAddress(address)}`;
18
+ }
19
+ /**
20
+ * Get storage key for wallet data
21
+ *
22
+ * @param address - The user's EVM address
23
+ * @returns The storage key for the wallet data
24
+ */
25
+ export function getWalletStorageKey(address) {
26
+ return `${STORAGE_KEY_WALLET_PREFIX}${getAddress(address)}`;
27
+ }
28
+ /**
29
+ * Load cached authentication data
30
+ *
31
+ * @param address - The user's EVM address
32
+ * @returns The cached auth response or null if not found/expired
33
+ */
34
+ export function loadCachedAuth(address) {
35
+ const normalizedAddress = getAddress(address);
36
+ try {
37
+ const storageKey = getAuthStorageKey(normalizedAddress);
38
+ const cachedData = typeof localStorage !== 'undefined' ? localStorage.getItem(storageKey) : null;
39
+ if (!cachedData)
40
+ return null;
41
+ const cachedAuth = JSON.parse(cachedData);
42
+ // Check if auth is still valid
43
+ if (cachedAuth.authExpires && cachedAuth.authExpires > Date.now()) {
44
+ return cachedAuth;
45
+ }
46
+ else {
47
+ // Remove expired auth
48
+ if (typeof localStorage !== 'undefined') {
49
+ localStorage.removeItem(storageKey);
50
+ }
51
+ return null;
52
+ }
53
+ }
54
+ catch (err) {
55
+ console.warn('Failed to load cached auth:', err);
56
+ return null;
57
+ }
58
+ }
59
+ /**
60
+ * Save authentication data to cache
61
+ *
62
+ * @param address - The user's EVM address
63
+ * @param authData - The authentication response to cache
64
+ */
65
+ export function saveAuth(address, authData) {
66
+ const normalizedAddress = getAddress(address);
67
+ try {
68
+ const storageKey = getAuthStorageKey(normalizedAddress);
69
+ if (typeof localStorage !== 'undefined') {
70
+ localStorage.setItem(storageKey, JSON.stringify(authData));
71
+ }
72
+ }
73
+ catch (err) {
74
+ console.warn('Failed to save auth:', err);
75
+ }
76
+ }
77
+ /**
78
+ * Clear cached authentication data
79
+ *
80
+ * @param address - The user's EVM address
81
+ */
82
+ export function clearAuth(address) {
83
+ const normalizedAddress = getAddress(address);
84
+ const storageKey = getAuthStorageKey(normalizedAddress);
85
+ if (typeof localStorage !== 'undefined') {
86
+ localStorage.removeItem(storageKey);
87
+ }
88
+ }
89
+ /**
90
+ * Save wallet data to sessionStorage
91
+ *
92
+ * @param address - The user's EVM address
93
+ * @param walletData - The wallet data to cache
94
+ * @param expirationMs - Expiration time in milliseconds from now
95
+ */
96
+ export function saveWalletData(address, walletData, expirationMs = 24 * 60 * 60 * 1000 // 24 hours
97
+ ) {
98
+ const normalizedAddress = getAddress(address);
99
+ try {
100
+ const storageKey = getWalletStorageKey(normalizedAddress);
101
+ const data = {
102
+ ...walletData,
103
+ expiration: Date.now() + expirationMs,
104
+ };
105
+ if (typeof sessionStorage !== 'undefined') {
106
+ sessionStorage.setItem(storageKey, JSON.stringify(data));
107
+ }
108
+ }
109
+ catch (err) {
110
+ console.warn('Failed to save wallet data:', err);
111
+ }
112
+ }
113
+ /**
114
+ * Load cached wallet data from sessionStorage
115
+ *
116
+ * @param address - The user's EVM address
117
+ * @returns The cached wallet data or null if not found/expired
118
+ */
119
+ export function loadWalletData(address) {
120
+ const normalizedAddress = getAddress(address);
121
+ try {
122
+ const storageKey = getWalletStorageKey(normalizedAddress);
123
+ const sessionData = typeof sessionStorage !== 'undefined'
124
+ ? sessionStorage.getItem(storageKey)
125
+ : null;
126
+ if (!sessionData)
127
+ return null;
128
+ const cached = JSON.parse(sessionData);
129
+ // Check expiration
130
+ if (cached.expiration <= Date.now()) {
131
+ if (typeof sessionStorage !== 'undefined') {
132
+ sessionStorage.removeItem(storageKey);
133
+ }
134
+ return null;
135
+ }
136
+ return {
137
+ entropy: cached.entropy,
138
+ accounts: cached.accounts,
139
+ };
140
+ }
141
+ catch (err) {
142
+ console.warn('Failed to load wallet data:', err);
143
+ if (typeof sessionStorage !== 'undefined') {
144
+ const storageKey = getWalletStorageKey(normalizedAddress);
145
+ sessionStorage.removeItem(storageKey);
146
+ }
147
+ return null;
148
+ }
149
+ }
150
+ /**
151
+ * Clear cached wallet data
152
+ *
153
+ * @param address - The user's EVM address
154
+ */
155
+ export function clearWalletData(address) {
156
+ const normalizedAddress = getAddress(address);
157
+ const storageKey = getWalletStorageKey(normalizedAddress);
158
+ if (typeof sessionStorage !== 'undefined') {
159
+ sessionStorage.removeItem(storageKey);
160
+ }
161
+ }
@@ -0,0 +1,19 @@
1
+ import type { Hex, WalletClient } from 'viem';
2
+ import type { Connector } from 'wagmi';
3
+ import type { BridgeProvider, BridgeQuote, BridgeTransaction, BridgeStatus } from './bridge.js';
4
+ /**
5
+ * Create transaction execution wrapper for framework-agnostic bridge execution
6
+ */
7
+ export declare function createTransactionExecutor(walletClient: WalletClient, connector: Connector): (tx: BridgeTransaction) => Promise<Hex>;
8
+ /**
9
+ * Create chain switching wrapper
10
+ */
11
+ export declare function createChainSwitcher(walletClient: WalletClient, connector: Connector): (chainId: number) => Promise<void>;
12
+ /**
13
+ * Execute a bridge transaction (framework-agnostic)
14
+ */
15
+ export declare function executeBridgeTransaction(quote: BridgeQuote, walletClient: WalletClient, connector: Connector, setStep: (step: string) => void): Promise<BridgeStatus>;
16
+ /**
17
+ * Get bridge status (framework-agnostic)
18
+ */
19
+ export declare function getBridgeStatus(requestId: string, provider: BridgeProvider): Promise<BridgeStatus>;
@@ -0,0 +1,85 @@
1
+ import { executeRelayBridge, executeDebridgeBridge, getRelayStatus, getDebridgeStatus, } from './bridge.js';
2
+ /**
3
+ * Create transaction execution wrapper for framework-agnostic bridge execution
4
+ */
5
+ export function createTransactionExecutor(walletClient, connector) {
6
+ return async (tx) => {
7
+ // Switch to the correct chain if needed
8
+ let currentChainId;
9
+ try {
10
+ currentChainId = await walletClient.getChainId();
11
+ }
12
+ catch {
13
+ currentChainId = -1;
14
+ }
15
+ if (currentChainId !== tx.chainId) {
16
+ try {
17
+ await connector.switchChain?.({ chainId: tx.chainId });
18
+ }
19
+ catch (switchError) {
20
+ throw new Error(`Failed to switch to chain ${tx.chainId}`);
21
+ }
22
+ }
23
+ // Send transaction
24
+ const hash = await walletClient.sendTransaction({
25
+ account: walletClient.account,
26
+ chain: null,
27
+ to: tx.to,
28
+ value: BigInt(tx.value),
29
+ data: tx.data,
30
+ gas: tx.gasLimit ? BigInt(tx.gasLimit) : undefined,
31
+ });
32
+ return hash;
33
+ };
34
+ }
35
+ /**
36
+ * Create chain switching wrapper
37
+ */
38
+ export function createChainSwitcher(walletClient, connector) {
39
+ return async (chainId) => {
40
+ // Check current chain
41
+ let currentChainId;
42
+ try {
43
+ currentChainId = await walletClient?.getChainId() || -1;
44
+ }
45
+ catch {
46
+ currentChainId = -1;
47
+ }
48
+ if (currentChainId !== chainId) {
49
+ try {
50
+ await connector.switchChain?.({ chainId });
51
+ }
52
+ catch (switchError) {
53
+ throw new Error(`Failed to switch to chain ${chainId}`);
54
+ }
55
+ }
56
+ };
57
+ }
58
+ /**
59
+ * Execute a bridge transaction (framework-agnostic)
60
+ */
61
+ export async function executeBridgeTransaction(quote, walletClient, connector, setStep) {
62
+ const executeTransaction = createTransactionExecutor(walletClient, connector);
63
+ const switchChain = createChainSwitcher(walletClient, connector);
64
+ switch (quote.provider) {
65
+ case 'relay':
66
+ return await executeRelayBridge(quote, executeTransaction, switchChain, setStep);
67
+ case 'debridge':
68
+ return await executeDebridgeBridge(quote, executeTransaction, switchChain, setStep);
69
+ default:
70
+ throw new Error(`Unsupported bridge provider: ${quote.provider}`);
71
+ }
72
+ }
73
+ /**
74
+ * Get bridge status (framework-agnostic)
75
+ */
76
+ export async function getBridgeStatus(requestId, provider) {
77
+ switch (provider) {
78
+ case 'relay':
79
+ return await getRelayStatus(requestId);
80
+ case 'debridge':
81
+ return await getDebridgeStatus(requestId);
82
+ default:
83
+ throw new Error(`Unsupported bridge provider: ${provider}`);
84
+ }
85
+ }
@@ -0,0 +1,18 @@
1
+ import { type Hex } from 'viem';
2
+ /**
3
+ * Query the number of deposits made by a user to the Gateway contract
4
+ *
5
+ * @param userAddress - The user's EVM address
6
+ * @returns The number of deposits made by the user
7
+ */
8
+ export declare function queryDepositCount(userAddress: `0x${string}`): Promise<bigint>;
9
+ /**
10
+ * Generate phony deposit proxy calldata for testing/estimation purposes
11
+ * This creates a valid calldata structure without actual signature data
12
+ *
13
+ * @param signerAddress - The signer's EVM address (or zero address for anonymous)
14
+ * @param approvalExpiration - Timestamp when approval expires (default: 12 hours from now)
15
+ * @param duration - Duration of the deposit in seconds (default: 7 days)
16
+ * @returns Encoded calldata for depositProxy2 function
17
+ */
18
+ export declare function createPhonyDepositCalldata(signerAddress?: `0x${string}`, approvalExpiration?: bigint, duration?: bigint): Hex;