@silentswap/react 0.0.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/README.md +48 -0
- package/dist/contexts/AssetsContext.d.ts +24 -0
- package/dist/contexts/AssetsContext.js +83 -0
- package/dist/contexts/BalancesContext.d.ts +28 -0
- package/dist/contexts/BalancesContext.js +533 -0
- package/dist/contexts/OrdersContext.d.ts +53 -0
- package/dist/contexts/OrdersContext.js +240 -0
- package/dist/contexts/PricesContext.d.ts +12 -0
- package/dist/contexts/PricesContext.js +109 -0
- package/dist/contexts/SilentSwapContext.d.ts +58 -0
- package/dist/contexts/SilentSwapContext.js +205 -0
- package/dist/hooks/silent/orderTrackingWebSocketManager.d.ts +48 -0
- package/dist/hooks/silent/orderTrackingWebSocketManager.js +284 -0
- package/dist/hooks/silent/solana-transaction.d.ts +60 -0
- package/dist/hooks/silent/solana-transaction.js +236 -0
- package/dist/hooks/silent/useAuth.d.ts +90 -0
- package/dist/hooks/silent/useAuth.js +269 -0
- package/dist/hooks/silent/useBridgeExecution.d.ts +39 -0
- package/dist/hooks/silent/useBridgeExecution.js +877 -0
- package/dist/hooks/silent/useOrderSigning.d.ts +34 -0
- package/dist/hooks/silent/useOrderSigning.js +133 -0
- package/dist/hooks/silent/useOrderTracking.d.ts +174 -0
- package/dist/hooks/silent/useOrderTracking.js +524 -0
- package/dist/hooks/silent/useQuoteCalculation.d.ts +50 -0
- package/dist/hooks/silent/useQuoteCalculation.js +331 -0
- package/dist/hooks/silent/useQuoteFetching.d.ts +18 -0
- package/dist/hooks/silent/useQuoteFetching.js +54 -0
- package/dist/hooks/silent/useRefund.d.ts +26 -0
- package/dist/hooks/silent/useRefund.js +134 -0
- package/dist/hooks/silent/useSilentClient.d.ts +16 -0
- package/dist/hooks/silent/useSilentClient.js +32 -0
- package/dist/hooks/silent/useSilentOrders.d.ts +174 -0
- package/dist/hooks/silent/useSilentOrders.js +73 -0
- package/dist/hooks/silent/useSilentQuote.d.ts +88 -0
- package/dist/hooks/silent/useSilentQuote.js +381 -0
- package/dist/hooks/silent/useWallet.d.ts +76 -0
- package/dist/hooks/silent/useWallet.js +203 -0
- package/dist/hooks/useAssetPrice.d.ts +8 -0
- package/dist/hooks/useAssetPrice.js +47 -0
- package/dist/hooks/useContacts.d.ts +52 -0
- package/dist/hooks/useContacts.js +259 -0
- package/dist/hooks/useEgressEstimates.d.ts +32 -0
- package/dist/hooks/useEgressEstimates.js +230 -0
- package/dist/hooks/useHiddenSwapFees.d.ts +22 -0
- package/dist/hooks/useHiddenSwapFees.js +81 -0
- package/dist/hooks/useOrderEstimates.d.ts +37 -0
- package/dist/hooks/useOrderEstimates.js +393 -0
- package/dist/hooks/useOutputAssetInfo.d.ts +12 -0
- package/dist/hooks/useOutputAssetInfo.js +38 -0
- package/dist/hooks/usePrices.d.ts +60 -0
- package/dist/hooks/usePrices.js +188 -0
- package/dist/hooks/useQuote.d.ts +73 -0
- package/dist/hooks/useQuote.js +507 -0
- package/dist/hooks/useResetSwapForm.d.ts +16 -0
- package/dist/hooks/useResetSwapForm.js +68 -0
- package/dist/hooks/useSlippageUsd.d.ts +11 -0
- package/dist/hooks/useSlippageUsd.js +19 -0
- package/dist/hooks/useSolanaAdapter.d.ts +15 -0
- package/dist/hooks/useSolanaAdapter.js +55 -0
- package/dist/hooks/useStatus.d.ts +25 -0
- package/dist/hooks/useStatus.js +60 -0
- package/dist/hooks/useSwap.d.ts +67 -0
- package/dist/hooks/useSwap.js +285 -0
- package/dist/hooks/useTransaction.d.ts +119 -0
- package/dist/hooks/useTransaction.js +353 -0
- package/dist/hooks/useTransactionAddress.d.ts +11 -0
- package/dist/hooks/useTransactionAddress.js +26 -0
- package/dist/hooks/useUsdValue.d.ts +7 -0
- package/dist/hooks/useUsdValue.js +19 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +41 -0
- package/dist/stories/SilentSwapOverview.stories.d.ts +10 -0
- package/dist/stories/SilentSwapOverview.stories.js +364 -0
- package/dist/stories/useAuth.stories.d.ts +6 -0
- package/dist/stories/useAuth.stories.js +55 -0
- package/dist/stories/useSilentClient.stories.d.ts +9 -0
- package/dist/stories/useSilentClient.stories.js +39 -0
- package/dist/stories/useSilentOrders.stories.d.ts +1 -0
- package/dist/stories/useSilentOrders.stories.js +1 -0
- package/dist/stories/useSilentQuote.stories.d.ts +6 -0
- package/dist/stories/useSilentQuote.stories.js +267 -0
- package/dist/stories/useTransaction.stories.d.ts +6 -0
- package/dist/stories/useTransaction.stories.js +121 -0
- package/dist/utils/formatters.d.ts +33 -0
- package/dist/utils/formatters.js +82 -0
- package/package.json +67 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { useCallback, useState, useEffect, useRef } from 'react';
|
|
2
|
+
import { createSignInMessage, createEip712DocForOrder, createEip712DocForWalletGeneration, loadCachedAuth, saveAuth, clearAuth, normalizeAddress, } from '@silentswap/sdk';
|
|
3
|
+
/**
|
|
4
|
+
* React hook for SilentSwap authentication with full SIWE flow
|
|
5
|
+
*
|
|
6
|
+
* This hook provides:
|
|
7
|
+
* - SIWE authentication with nonce management
|
|
8
|
+
* - Automatic auth caching and restoration
|
|
9
|
+
* - Sign-in message creation and signing
|
|
10
|
+
* - Auth state management
|
|
11
|
+
* - Auto-authentication when dependencies are available
|
|
12
|
+
*
|
|
13
|
+
* @param options - Configuration options for authentication
|
|
14
|
+
* @returns Object with authentication state and methods
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { useAuth, useSilentClient } from '@silentswap/react';
|
|
19
|
+
* import { useWalletClient, useAccount } from 'wagmi';
|
|
20
|
+
*
|
|
21
|
+
* function MyComponent() {
|
|
22
|
+
* const { address } = useAccount();
|
|
23
|
+
* const { data: walletClient } = useWalletClient();
|
|
24
|
+
* const client = useSilentClient({ config: { /* ... *\/ } }).client;
|
|
25
|
+
*
|
|
26
|
+
* const {
|
|
27
|
+
* auth,
|
|
28
|
+
* isAuthenticated,
|
|
29
|
+
* signIn,
|
|
30
|
+
* signOut,
|
|
31
|
+
* isLoading,
|
|
32
|
+
* error
|
|
33
|
+
* } = useAuth({
|
|
34
|
+
* client,
|
|
35
|
+
* address,
|
|
36
|
+
* walletClient: walletClient as any,
|
|
37
|
+
* autoAuthenticate: true,
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* return (
|
|
41
|
+
* <div>
|
|
42
|
+
* {isLoading && <div>Authenticating...</div>}
|
|
43
|
+
* {error && <div>Error: {error.message}</div>}
|
|
44
|
+
*
|
|
45
|
+
* {isAuthenticated() ? (
|
|
46
|
+
* <div>
|
|
47
|
+
* <p>Authenticated as {auth?.address}</p>
|
|
48
|
+
* <button onClick={signOut}>Sign Out</button>
|
|
49
|
+
* </div>
|
|
50
|
+
* ) : (
|
|
51
|
+
* <button onClick={signIn} disabled={isLoading}>
|
|
52
|
+
* Sign In with Ethereum
|
|
53
|
+
* </button>
|
|
54
|
+
* )}
|
|
55
|
+
* </div>
|
|
56
|
+
* );
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function useAuth({ client, address, walletClient, domain = typeof window !== 'undefined' ? window.location.host : undefined, autoAuthenticate = false, } = {}) {
|
|
61
|
+
const [auth, setAuth] = useState(null);
|
|
62
|
+
const [nonce, setNonce] = useState(null);
|
|
63
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
64
|
+
const [isAutoAuthenticating, setIsAutoAuthenticating] = useState(false);
|
|
65
|
+
const [error, setError] = useState(null);
|
|
66
|
+
// Track if auto-authentication has been attempted to prevent duplicate calls
|
|
67
|
+
const hasAutoAuthenticatedRef = useRef(false);
|
|
68
|
+
// Normalize address
|
|
69
|
+
const normalizedAddress = address ? normalizeAddress(address) : null;
|
|
70
|
+
/**
|
|
71
|
+
* Load cached authentication
|
|
72
|
+
*/
|
|
73
|
+
const loadCachedAuthCallback = useCallback(() => {
|
|
74
|
+
if (!normalizedAddress)
|
|
75
|
+
return null;
|
|
76
|
+
return loadCachedAuth(normalizedAddress);
|
|
77
|
+
}, [normalizedAddress]);
|
|
78
|
+
/**
|
|
79
|
+
* Save authentication to cache
|
|
80
|
+
*/
|
|
81
|
+
const saveAuthCallback = useCallback((authData) => {
|
|
82
|
+
if (!normalizedAddress)
|
|
83
|
+
return;
|
|
84
|
+
saveAuth(normalizedAddress, authData);
|
|
85
|
+
}, [normalizedAddress]);
|
|
86
|
+
/**
|
|
87
|
+
* Create SIWE sign-in message
|
|
88
|
+
*/
|
|
89
|
+
const createSignInMessageCallback = useCallback((address, nonce, domain) => {
|
|
90
|
+
return createSignInMessage(address, nonce, domain);
|
|
91
|
+
}, []);
|
|
92
|
+
/**
|
|
93
|
+
* Create EIP-712 document for order
|
|
94
|
+
*/
|
|
95
|
+
const createEip712DocForOrderCallback = useCallback((quoteResponse) => {
|
|
96
|
+
return createEip712DocForOrder(quoteResponse);
|
|
97
|
+
}, []);
|
|
98
|
+
/**
|
|
99
|
+
* Create EIP-712 document for wallet generation
|
|
100
|
+
*/
|
|
101
|
+
const createEip712DocForWalletGenerationCallback = useCallback((scope, token) => {
|
|
102
|
+
return createEip712DocForWalletGeneration(scope, token);
|
|
103
|
+
}, []);
|
|
104
|
+
/**
|
|
105
|
+
* Get nonce from server
|
|
106
|
+
*/
|
|
107
|
+
const getNonce = useCallback(async () => {
|
|
108
|
+
if (!client) {
|
|
109
|
+
throw new Error('Client required for nonce request');
|
|
110
|
+
}
|
|
111
|
+
if (!normalizedAddress) {
|
|
112
|
+
throw new Error('Address required for nonce request');
|
|
113
|
+
}
|
|
114
|
+
setError(null);
|
|
115
|
+
try {
|
|
116
|
+
const [error, response] = await client.nonce(normalizedAddress);
|
|
117
|
+
if (error) {
|
|
118
|
+
throw new Error(`Failed to get nonce: ${error.error}`);
|
|
119
|
+
}
|
|
120
|
+
const nonceValue = response.nonce;
|
|
121
|
+
setNonce(nonceValue);
|
|
122
|
+
return nonceValue;
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
const error = err instanceof Error ? err : new Error('Failed to fetch nonce');
|
|
126
|
+
setError(error);
|
|
127
|
+
throw error;
|
|
128
|
+
}
|
|
129
|
+
}, [client, normalizedAddress]);
|
|
130
|
+
/**
|
|
131
|
+
* Perform SIWE authentication
|
|
132
|
+
*/
|
|
133
|
+
const authenticate = useCallback(async () => {
|
|
134
|
+
if (!client) {
|
|
135
|
+
throw new Error('Client required for authentication');
|
|
136
|
+
}
|
|
137
|
+
if (!normalizedAddress) {
|
|
138
|
+
throw new Error('Address required for authentication');
|
|
139
|
+
}
|
|
140
|
+
if (!walletClient) {
|
|
141
|
+
throw new Error('Wallet client required for authentication');
|
|
142
|
+
}
|
|
143
|
+
setIsLoading(true);
|
|
144
|
+
setError(null);
|
|
145
|
+
try {
|
|
146
|
+
// Get nonce if we don't have one
|
|
147
|
+
let nonceValue = nonce;
|
|
148
|
+
if (!nonceValue) {
|
|
149
|
+
nonceValue = await getNonce();
|
|
150
|
+
}
|
|
151
|
+
// Create SIWE message
|
|
152
|
+
const siweMessage = createSignInMessageCallback(normalizedAddress, nonceValue, domain);
|
|
153
|
+
// Sign the message
|
|
154
|
+
const signature = await walletClient.signMessage({
|
|
155
|
+
account: normalizedAddress,
|
|
156
|
+
message: siweMessage.message,
|
|
157
|
+
});
|
|
158
|
+
// Authenticate with server
|
|
159
|
+
const [authError, authResponse] = await client.authenticate({
|
|
160
|
+
siwe: {
|
|
161
|
+
message: siweMessage.message,
|
|
162
|
+
signature: signature,
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
if (authError || !authResponse) {
|
|
166
|
+
throw new Error(`Authentication failed: ${authError?.error}`);
|
|
167
|
+
}
|
|
168
|
+
// Cache the auth response
|
|
169
|
+
saveAuthCallback(authResponse);
|
|
170
|
+
// Update state
|
|
171
|
+
setAuth(authResponse);
|
|
172
|
+
return authResponse;
|
|
173
|
+
}
|
|
174
|
+
catch (err) {
|
|
175
|
+
const error = err instanceof Error ? err : new Error('Authentication failed');
|
|
176
|
+
setError(error);
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
finally {
|
|
180
|
+
setIsLoading(false);
|
|
181
|
+
}
|
|
182
|
+
}, [client, normalizedAddress, walletClient, nonce, getNonce, createSignInMessageCallback, domain, saveAuthCallback]);
|
|
183
|
+
/**
|
|
184
|
+
* Sign in (alias for authenticate for convenience)
|
|
185
|
+
*/
|
|
186
|
+
const signIn = useCallback(async () => {
|
|
187
|
+
return authenticate();
|
|
188
|
+
}, [authenticate]);
|
|
189
|
+
/**
|
|
190
|
+
* Sign out and clear auth
|
|
191
|
+
*/
|
|
192
|
+
const signOut = useCallback(() => {
|
|
193
|
+
if (!normalizedAddress)
|
|
194
|
+
return;
|
|
195
|
+
clearAuth(normalizedAddress);
|
|
196
|
+
setAuth(null);
|
|
197
|
+
setNonce(null);
|
|
198
|
+
setError(null);
|
|
199
|
+
setIsAutoAuthenticating(false);
|
|
200
|
+
// Reset auto-authentication flag
|
|
201
|
+
hasAutoAuthenticatedRef.current = false;
|
|
202
|
+
}, [normalizedAddress]);
|
|
203
|
+
/**
|
|
204
|
+
* Check if user is authenticated
|
|
205
|
+
*/
|
|
206
|
+
const isAuthenticated = useCallback(() => {
|
|
207
|
+
return auth !== null && auth.authExpires > Date.now();
|
|
208
|
+
}, [auth]);
|
|
209
|
+
// Load cached auth on mount
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
if (normalizedAddress && !auth && !isLoading) {
|
|
212
|
+
const cachedAuth = loadCachedAuthCallback();
|
|
213
|
+
if (cachedAuth) {
|
|
214
|
+
setAuth(cachedAuth);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}, [normalizedAddress, auth, isLoading, loadCachedAuthCallback]);
|
|
218
|
+
// Auto-authenticate when dependencies are available
|
|
219
|
+
useEffect(() => {
|
|
220
|
+
// Skip if already authenticated, loading, has error, or already attempted
|
|
221
|
+
if (!autoAuthenticate ||
|
|
222
|
+
!normalizedAddress ||
|
|
223
|
+
!walletClient ||
|
|
224
|
+
auth ||
|
|
225
|
+
isLoading ||
|
|
226
|
+
isAutoAuthenticating ||
|
|
227
|
+
error ||
|
|
228
|
+
hasAutoAuthenticatedRef.current) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
// Check if cached auth exists and is valid
|
|
232
|
+
const cachedAuth = loadCachedAuthCallback();
|
|
233
|
+
if (cachedAuth && cachedAuth.authExpires > Date.now()) {
|
|
234
|
+
setAuth(cachedAuth);
|
|
235
|
+
hasAutoAuthenticatedRef.current = true;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
// Mark as in progress and attempt authentication
|
|
239
|
+
setIsAutoAuthenticating(true);
|
|
240
|
+
authenticate()
|
|
241
|
+
.then(() => {
|
|
242
|
+
hasAutoAuthenticatedRef.current = true;
|
|
243
|
+
})
|
|
244
|
+
.catch((err) => {
|
|
245
|
+
console.error('Auto-authentication failed:', err);
|
|
246
|
+
})
|
|
247
|
+
.finally(() => {
|
|
248
|
+
setIsAutoAuthenticating(false);
|
|
249
|
+
});
|
|
250
|
+
}, [autoAuthenticate, normalizedAddress, walletClient, auth, isLoading, isAutoAuthenticating, error, authenticate, loadCachedAuthCallback]);
|
|
251
|
+
return {
|
|
252
|
+
// State
|
|
253
|
+
auth,
|
|
254
|
+
nonce,
|
|
255
|
+
isLoading: isLoading || isAutoAuthenticating,
|
|
256
|
+
error,
|
|
257
|
+
// Sign-in message creation
|
|
258
|
+
createSignInMessage: createSignInMessageCallback,
|
|
259
|
+
// EIP-712 document creation
|
|
260
|
+
createEip712DocForOrder: createEip712DocForOrderCallback,
|
|
261
|
+
createEip712DocForWalletGeneration: createEip712DocForWalletGenerationCallback,
|
|
262
|
+
// Authentication methods
|
|
263
|
+
getNonce,
|
|
264
|
+
authenticate,
|
|
265
|
+
signIn,
|
|
266
|
+
signOut,
|
|
267
|
+
isAuthenticated,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { Hex, WalletClient } from 'viem';
|
|
2
|
+
import type { Connector } from 'wagmi';
|
|
3
|
+
import type { DepositParams } from '@silentswap/sdk';
|
|
4
|
+
import type { SolanaWalletConnector, SolanaConnection } from './solana-transaction.js';
|
|
5
|
+
/**
|
|
6
|
+
* Result from executing a bridge transaction
|
|
7
|
+
*/
|
|
8
|
+
export interface BridgeExecutionResult {
|
|
9
|
+
/** Transaction hash of the deposit on Avalanche */
|
|
10
|
+
depositTxHash: Hex;
|
|
11
|
+
/** Selected bridge provider */
|
|
12
|
+
provider: 'relay' | 'debridge';
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Hook for executing bridge transactions (Solana → Avalanche or EVM → Avalanche)
|
|
16
|
+
*
|
|
17
|
+
* This hook handles the complete bridge execution flow:
|
|
18
|
+
* - Solving for optimal USDC amount (if not provided)
|
|
19
|
+
* - Fetching quotes from both relay.link and deBridge
|
|
20
|
+
* - Selecting the best provider based on rates
|
|
21
|
+
* - Executing bridge transactions (Solana or EVM)
|
|
22
|
+
* - Monitoring bridge status until deposit arrives
|
|
23
|
+
*
|
|
24
|
+
* Supports both Solana and EVM source chains, automatically selecting
|
|
25
|
+
* the best bridge provider (relay.link or deBridge) based on rates.
|
|
26
|
+
*
|
|
27
|
+
* @param walletClient - Wallet client for EVM transactions
|
|
28
|
+
* @param connector - Wagmi connector for chain switching
|
|
29
|
+
* @param solanaConnector - Solana wallet connector (required for Solana swaps)
|
|
30
|
+
* @param solanaConnection - Solana RPC connection (required for Solana swaps)
|
|
31
|
+
* @param solanaRpcUrl - Optional Solana RPC URL
|
|
32
|
+
* @param setCurrentStep - Callback to set current step message
|
|
33
|
+
* @param onStatus - Optional status update callback
|
|
34
|
+
* @returns Functions for executing bridge transactions
|
|
35
|
+
*/
|
|
36
|
+
export declare function useBridgeExecution(walletClient: WalletClient | undefined, connector: Connector | undefined, solanaConnector: SolanaWalletConnector | undefined, solanaConnection: SolanaConnection | undefined, solanaRpcUrl: string | undefined, setCurrentStep: (step: string) => void, depositorAddress: Hex, onStatus?: (status: string) => void): {
|
|
37
|
+
executeSolanaBridge: (sourceAsset: string, sourceAmount: string, usdcAmount: string | undefined, solanaSenderAddress: string, evmSignerAddress: `0x${string}`, depositParams?: DepositParams<`${bigint}`>) => Promise<BridgeExecutionResult>;
|
|
38
|
+
executeEvmBridge: (sourceChainId: number, sourceTokenAddress: string, sourceAmount: string, usdcAmount: string | undefined, depositParams: DepositParams<`${bigint}`>, evmSignerAddress: `0x${string}`, evmSenderAddress?: `0x${string}`, provider?: "relay" | "debridge") => Promise<BridgeExecutionResult>;
|
|
39
|
+
};
|