Complete private-swap example
This example shows the full EVM path. The UI must render the quote before calling
placeOrder.
import {
AmountOutOfRangeError,
DepositSimulationError,
HttpError,
createSilentSwapClient,
} from '@silentswap/sdk';
import {
createWalletClient,
custom,
parseUnits,
type Address,
} from 'viem';
import { mainnet } from 'viem/chains';
declare const provider: Parameters<typeof custom>[0];
declare const account: Address;
const walletClient = createWalletClient({
account,
chain: mainnet,
transport: custom(provider),
});
const client = createSilentSwapClient({
walletClient,
});
export async function startSwap(): Promise<() => void> {
try {
const quote = await client.quote({
privacy: true,
inputAddress: account,
sourceAsset: 'USDC',
sourceChainId: 1,
outputs: [{
address: '0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC',
chainId: 8453,
amount: parseUnits('25', 6),
}],
});
// Await a real UI review here, then optionally narrate approval.
if (!(await client.hasAllowance(quote))) {
await client.ensureAllowance(quote);
}
const order = await client.placeOrder(quote);
return client.trackOrderViaWebSocket(
order.reference,
(state) => console.log(state.status),
console.error,
);
} catch (error) {
if (error instanceof AmountOutOfRangeError) {
throw new Error(error.message, { cause: error });
}
if (error instanceof DepositSimulationError) {
throw new Error('Nothing was broadcast.', { cause: error });
}
if (error instanceof HttpError) {
throw new Error(`SilentSwap API: HTTP ${error.status}`, { cause: error });
}
throw error;
}
}