Skip to content

useSilentOrders

The useSilentOrders hook provides a lower-level API for managing Silent Swap operations. It's useful when you need more control over the order creation process or want to implement custom flows.

Import

import { useSilentOrders, useSilentClient } from '@silentswap/react';

Basic Usage

import { useSilentOrders, useSilentClient } from '@silentswap/react';
import { ENVIRONMENT } from '@silentswap/sdk';
 
function OrdersComponent() {
  const { client } = useSilentClient({
    config: {
      environment: ENVIRONMENT.MAINNET,
    },
  });
 
  const {
    getNonce,
    authenticate,
    getQuote,
    createOrder,
    isLoading,
    error,
  } = useSilentOrders({ client });
 
  // Use methods as needed
  return <div>Orders component</div>;
}

API Reference

Options

interface useSilentOrdersOptions {
  client: SilentSwapClient;
}

Return Value

interface useSilentOrdersReturn {
  // State
  isLoading: boolean;
  error: Error | null;
 
  // Methods
  getNonce: (address: `0x${string}`) => Promise<NonceResponse | null>;
  authenticate: (auth: AuthRequest) => Promise<AuthResponse | null>;
  getQuote: (quote: QuoteRequest) => Promise<QuoteResponse | null>;
  createOrder: (order: OrderRequest) => Promise<OrderResponse | null>;
}

Getting a Nonce

const { getNonce } = useSilentOrders({ client });
 
const handleGetNonce = async () => {
  const nonceResponse = await getNonce('0x1234567890123456789012345678901234567890');
  if (nonceResponse) {
    console.log('Nonce:', nonceResponse.nonce);
  }
};

Authenticating

import { createSignInMessage } from '@silentswap/sdk';
 
const { authenticate, getNonce } = useSilentOrders({ client });
 
const handleAuthenticate = async () => {
  // Get nonce first
  const nonceResponse = await getNonce(address);
  if (!nonceResponse) return;
 
  // Create SIWE message
  const siweMessage = createSignInMessage(
    address,
    nonceResponse.nonce,
    'example.com'
  );
 
  // Sign message with wallet
  const signature = await walletClient.signMessage({
    account: address,
    message: siweMessage.message,
  });
 
  // Authenticate
  const authResponse = await authenticate({
    siwe: {
      message: siweMessage.message,
      signature: signature as `0x${string}`,
    },
  });
 
  if (authResponse) {
    console.log('Authenticated:', authResponse.address);
  }
};

Getting a Quote

import {
  DeliveryMethod,
  caip19FungibleEvmToken,
  FacilitatorKeyType,
  PublicKeyArgGroups,
} from '@silentswap/sdk';
 
const { getQuote } = useSilentOrders({ client });
 
const handleGetQuote = async () => {
  // Generate facilitator group (from useWallet)
  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 quoteResponse = await getQuote({
    signer: address,
    viewer: viewerPk,
    outputs: [{
      method: DeliveryMethod.SNIP,
      asset: caip19FungibleEvmToken(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
      value: '1000000',
      recipient: recipientAddress,
      facilitatorPublicKeys: groupPks[0],
    }],
  });
 
  if (quoteResponse) {
    console.log('Quote ID:', quoteResponse.quoteId);
    console.log('Authorizations:', quoteResponse.authorizations.length);
    console.log('Facilitators:', quoteResponse.facilitators.length);
  }
};

Creating an Order

import { createEip712DocForOrder, createViemSigner } from '@silentswap/sdk';
import type { AuthorizationInstruction } from '@silentswap/sdk';
 
const { createOrder, getQuote } = useSilentOrders({ client });
const { createEip712DocForOrder } = useAuth({ client, address, walletClient });
 
const handleCreateOrder = async () => {
  // Get quote first
  const quoteResponse = await getQuote(/* ... */);
  if (!quoteResponse) return;
 
  // Create signer
  const signer = createViemSigner(
    { address: connectedAddress, type: 'json-rpc' },
    walletClient
  );
 
  // Sign authorizations
  const signedAuths = await Promise.all(
    quoteResponse.authorizations.map(async (auth: AuthorizationInstruction) => ({
      ...auth,
      signature: await (async () => {
        if (auth.type === 'eip3009_deposit') {
          return await signer.signEip712TypedData(auth.eip712);
        }
        throw Error(`Authorization type not implemented: ${auth.type}`);
      })(),
    }))
  );
 
  // Sign the order's EIP-712
  const orderDoc = createEip712DocForOrder(quoteResponse);
  const signedQuote = await signer.signEip712TypedData(orderDoc);
 
  // Approve proxy authorizations
  const facilitatorReplies = await facilitatorGroup.approveProxyAuthorizations(
    quoteResponse.facilitators,
    {
      proxyPublicKey: client.proxyPublicKey,
    }
  );
 
  // Create the order
  const orderResponse = await createOrder({
    quote: quoteResponse.quote,
    quoteId: quoteResponse.quoteId,
    authorizations: signedAuths,
    eip712Domain: orderDoc.domain,
    signature: signedQuote,
    facilitators: facilitatorReplies,
  });
 
  if (orderResponse) {
    console.log('Order ID:', orderResponse.response.orderId);
    // Use orderResponse.transaction to execute the deposit
  }
};

Complete Flow Example

const {
  getNonce,
  authenticate,
  getQuote,
  createOrder,
  isLoading,
  error,
} = useSilentOrders({ client });
 
const handleCompleteFlow = async () => {
  try {
    // 1. Get nonce
    const nonceResponse = await getNonce(address);
    if (!nonceResponse) throw new Error('Failed to get nonce');
 
    // 2. Authenticate
    const siweMessage = createSignInMessage(address, nonceResponse.nonce, 'example.com');
    const signature = await walletClient.signMessage({
      account: address,
      message: siweMessage.message,
    });
    const authResponse = await authenticate({
      siwe: {
        message: siweMessage.message,
        signature: signature as `0x${string}`,
      },
    });
    if (!authResponse) throw new Error('Authentication failed');
 
    // 3. Get quote
    const quoteResponse = await getQuote({
      signer: address,
      viewer: viewerPk,
      outputs: [/* ... */],
    });
    if (!quoteResponse) throw new Error('Failed to get quote');
 
    // 4. Create order
    // ... (sign authorizations, etc.)
    const orderResponse = await createOrder({
      quote: quoteResponse.quote,
      quoteId: quoteResponse.quoteId,
      authorizations: signedAuths,
      eip712Domain: orderDoc.domain,
      signature: signedQuote,
      facilitators: facilitatorReplies,
    });
    if (!orderResponse) throw new Error('Failed to create order');
 
    // 5. Execute transaction
    // Use orderResponse.transaction to send transaction
 
  } catch (err) {
    console.error('Flow error:', err);
  }
};

When to Use

Use useSilentOrders when:

  • You need fine-grained control over the order creation process
  • You want to implement custom authorization flows
  • You're building a custom UI that doesn't fit the standard flow
  • You need to handle errors at each step individually

Use useSilentQuote when:

  • You want a simpler, higher-level API
  • You're building a standard swap interface
  • You want automatic handling of the complete flow

Error Handling

const { getQuote, createOrder, error } = useSilentOrders({ client });
 
const handleOperation = async () => {
  try {
    const quote = await getQuote(/* ... */);
    if (!quote) {
      // Handle quote error
      return;
    }
 
    const order = await createOrder(/* ... */);
    if (!order) {
      // Handle order error
      return;
    }
 
    // Success
  } catch (err) {
    console.error('Operation failed:', err);
  }
};
 
// Display errors
{error && (
  <div className="error">
    Error: {error.message}
  </div>
)}

Best Practices

  1. Error Handling - Check return values for null (indicates error)
  2. Loading States - Use isLoading to show progress
  3. Type Safety - Use TypeScript types for all requests/responses
  4. Validation - Validate inputs before making requests
  5. Caching - Cache quotes and auth responses when appropriate

Next Steps