useSilentQuote
The useSilentQuote hook provides a high-level API for getting quotes and executing complete Silent Swap transactions. It handles the full flow from quote to execution, including authorization signing, order creation, and transaction execution.
Import
import { useSilentQuote, useSilentClient, useAuth, useWallet } from '@silentswap/react';
import { useAccount, useWalletClient } from 'wagmi';
import { DeliveryMethod, caip19FungibleEvmToken, FacilitatorKeyType, PublicKeyArgGroups } from '@silentswap/sdk';Basic Usage
import {
useSilentQuote,
useSilentClient,
useAuth,
useWallet
} from '@silentswap/react';
import { useAccount, useWalletClient } from 'wagmi';
import { DeliveryMethod, caip19FungibleEvmToken, FacilitatorKeyType, PublicKeyArgGroups } from '@silentswap/sdk';
function SwapComponent() {
const { address, connector } = useAccount();
const { data: walletClient } = useWalletClient();
const { client } = useSilentClient({ config: { /* ... */ } });
const { auth } = useAuth({ client, address: address!, walletClient });
const { wallet } = useWallet({ address: address!, auth, walletClient, connector });
const {
getQuote,
executeSwap,
quote,
isLoading,
currentStep,
error,
} = useSilentQuote({
client,
address: address!,
walletClient: walletClient as any,
connector,
facilitatorGroup: wallet?.accounts[0]?.group(),
bridgeProvider: 'relay',
onStatus: (status) => console.log('Status:', status),
});
const handleGetQuote = async () => {
// Generate facilitator group
const facilitatorGroup = await wallet?.accounts[0]?.group();
const viewer = await facilitatorGroup.viewer();
const { publicKeyBytes: viewerPk } = viewer.exportPublicKey('*', FacilitatorKeyType.SECP256K1);
const groupPks = await facilitatorGroup.exportPublicKeys(1, PublicKeyArgGroups.GENERIC);
// Get quote
const quoteResult = await getQuote({
signer: address!,
viewer: viewerPk,
outputs: [{
method: DeliveryMethod.SNIP,
asset: caip19FungibleEvmToken(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
value: '1000000',
recipient: address!,
facilitatorPublicKeys: groupPks[0],
}],
});
if (quoteResult) {
console.log('Quote ID:', quoteResult.quoteId);
}
};
const handleExecuteSwap = async () => {
if (!quote) return;
const result = await executeSwap({
quote,
sourceAsset: 'eip155:43114/erc20:0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
sourceAmount: '1000000',
senderContactId: `caip10:eip155:*:${address}`,
});
if (result) {
console.log('Swap completed:', result.orderId);
}
};
return (
<div>
{isLoading && <div>{currentStep || 'Processing...'}</div>}
{error && <div>Error: {error.message}</div>}
<button onClick={handleGetQuote} disabled={isLoading}>
Get Quote
</button>
{quote && (
<button onClick={handleExecuteSwap} disabled={isLoading}>
Execute Swap
</button>
)}
</div>
);
}API Reference
Options
interface useSilentQuoteOptions {
/** SilentSwap client instance */
client: SilentSwapClient;
/** User's EVM address */
address: `0x${string}`;
/** Wallet client for signing operations */
walletClient?: WalletClient;
/** Wagmi connector */
connector?: Connector;
/** Facilitator group for the swap */
facilitatorGroup?: HdFacilitatorGroup;
/** Bridge provider to use for cross-chain swaps */
bridgeProvider?: BridgeProvider;
/** Status update callback */
onStatus?: (status: string) => void;
}Return Value
interface useSilentQuoteReturn {
// State
isLoading: boolean;
currentStep: string;
quote: QuoteResponse | null;
error: Error | null;
// Methods
getQuote: (request: QuoteRequest) => Promise<QuoteResponse | null>;
executeSwap: (params: ExecuteSwapParams) => Promise<SwapResult | null>;
clearQuote: () => void;
}
interface ExecuteSwapParams {
/** Quote to execute */
quote: QuoteResponse;
/** Source asset CAIP-19 identifier */
sourceAsset: string;
/** Source amount */
sourceAmount: string;
/** Contact ID of the sender */
senderContactId: string;
/** Allowance target address (for ERC-20 approvals) */
allowanceTarget?: `0x${string}`;
/** Bridge provider override */
bridgeProvider?: BridgeProvider;
}
interface SwapResult {
orderId: string;
viewingAuth: string;
depositTransaction: SwapTransaction;
bridgeTransaction?: SwapTransaction;
}Complete Swap Flow
The executeSwap method handles the complete swap flow:
- Sign Authorizations - Sign all required authorization instructions
- Create Order - Submit order with signed quote and authorizations
- Execute Deposit - Send deposit transaction
- Bridge (if needed) - Execute bridge transaction for cross-chain swaps
- Return Result - Return order ID and transaction hashes
Getting a Quote
const { getQuote } = useSilentQuote({
client,
address: address!,
walletClient,
facilitatorGroup: wallet?.accounts[0]?.group(),
});
// Generate facilitator group and public keys
const facilitatorGroup = await wallet?.accounts[0]?.group();
const viewer = await facilitatorGroup.viewer();
const { publicKeyBytes: viewerPk } = viewer.exportPublicKey('*', FacilitatorKeyType.SECP256K1);
const groupPks = await facilitatorGroup.exportPublicKeys(
outputs.length,
PublicKeyArgGroups.GENERIC
);
// Get quote
const quote = await getQuote({
signer: address!,
viewer: viewerPk,
outputs: [
{
method: DeliveryMethod.SNIP,
asset: caip19FungibleEvmToken(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
value: '1000000',
recipient: recipientAddress,
facilitatorPublicKeys: groupPks[0],
},
],
});Executing a Swap
const { executeSwap, quote } = useSilentQuote({
client,
address: address!,
walletClient,
facilitatorGroup: wallet?.accounts[0]?.group(),
});
const handleSwap = async () => {
if (!quote) return;
const result = await executeSwap({
quote,
sourceAsset: 'eip155:43114/erc20:0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',
sourceAmount: '1000000',
senderContactId: `caip10:eip155:*:${address}`,
bridgeProvider: 'relay', // Optional override
});
if (result) {
console.log('Order ID:', result.orderId);
console.log('Deposit TX:', result.depositTransaction.hash);
if (result.bridgeTransaction) {
console.log('Bridge TX:', result.bridgeTransaction.hash);
}
}
};Multi-Output Swaps
Support for multiple outputs (splitting one input across multiple recipients):
const quote = await getQuote({
signer: address!,
viewer: viewerPk,
outputs: [
{
method: DeliveryMethod.SNIP,
asset: caip19FungibleEvmToken(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
value: '500000', // 50% of input
recipient: recipient1,
facilitatorPublicKeys: groupPks[0],
},
{
method: DeliveryMethod.SNIP,
asset: caip19FungibleEvmToken(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
value: '500000', // 50% of input
recipient: recipient2,
facilitatorPublicKeys: groupPks[1],
},
],
});Status Updates
Monitor swap progress with status callbacks:
const { executeSwap, currentStep } = useSilentQuote({
client,
address: address!,
walletClient,
facilitatorGroup: wallet?.accounts[0]?.group(),
onStatus: (status) => {
console.log('Swap status:', status);
// Update UI with status
},
});
// currentStep will also be updated automatically
{currentStep && <div>Status: {currentStep}</div>}Bridge Providers
Choose between bridge providers:
// Use Relay.link (default)
const { executeSwap } = useSilentQuote({
client,
address: address!,
walletClient,
facilitatorGroup: wallet?.accounts[0]?.group(),
bridgeProvider: 'relay',
});
// Use deBridge
const { executeSwap } = useSilentQuote({
client,
address: address!,
walletClient,
facilitatorGroup: wallet?.accounts[0]?.group(),
bridgeProvider: 'debridge',
});
// No bridge (direct deposit to Avalanche USDC)
const { executeSwap } = useSilentQuote({
client,
address: address!,
walletClient,
facilitatorGroup: wallet?.accounts[0]?.group(),
bridgeProvider: 'none',
});
// Override per swap
await executeSwap({
quote,
sourceAsset: '...',
sourceAmount: '...',
senderContactId: '...',
bridgeProvider: 'relay', // Override default
});Error Handling
const { getQuote, executeSwap, error } = useSilentQuote({
client,
address: address!,
walletClient,
facilitatorGroup: wallet?.accounts[0]?.group(),
});
const handleSwap = async () => {
try {
const quote = await getQuote(/* ... */);
if (!quote) {
throw new Error('Failed to get quote');
}
const result = await executeSwap({
quote,
sourceAsset: '...',
sourceAmount: '...',
senderContactId: '...',
});
if (!result) {
throw new Error('Swap execution failed');
}
// Success
console.log('Swap completed:', result.orderId);
} catch (err) {
console.error('Swap error:', err);
// Show error to user
}
};
// Display errors
{error && (
<div className="error">
Swap error: {error.message}
</div>
)}Best Practices
- Check Prerequisites - Ensure auth, wallet, and facilitator group are ready
- Handle Loading States - Show progress using
currentStep - Validate Quotes - Check quote exists before executing
- Monitor Status - Use
onStatuscallback for real-time updates - Error Recovery - Provide retry mechanisms for failed swaps
Next Steps
- Learn about order management
- See complete example