Skip to content

getSilentSwapOrders

The getSilentSwapOrders composable provides reactive state management for Silent Swap operations including authentication, quotes, and order creation.

Import

import { getSilentSwapOrders, getSilentSwapClient } from '@silentswap/vue';

Basic Usage

<script setup lang="ts">
import { getSilentSwapOrders, getSilentSwapClient } from '@silentswap/vue';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const { client } = getSilentSwapClient({
  config: {
    environment: ENVIRONMENT.MAINNET,
  },
});
 
const {
  isLoading,
  error,
  getNonce,
  authenticate,
  getQuote,
  createOrder,
} = getSilentSwapOrders({ client });
</script>
 
<template>
  <div>
    <div v-if="isLoading">Loading...</div>
    <div v-if="error">Error: {{ error.message }}</div>
    <!-- Your UI here -->
  </div>
</template>

API Reference

Options

interface GetSilentSwapOrdersOptions {
  client: SilentSwapClient;
}

Return Value

interface GetSilentSwapOrdersReturn {
  // State (reactive)
  isLoading: Readonly<Ref<boolean>>;
  error: Readonly<Ref<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

<script setup lang="ts">
import { ref } from 'vue';
import { getSilentSwapOrders, getSilentSwapClient } from '@silentswap/vue';
import { useAccount } from 'wagmi';
 
const { address } = useAccount();
const { client } = getSilentSwapClient({ config: { /* ... */ } });
const { getNonce, isLoading, error } = getSilentSwapOrders({ client });
 
const nonce = ref<string | null>(null);
 
const handleGetNonce = async () => {
  const nonceResponse = await getNonce(address.value!);
  if (nonceResponse) {
    nonce.value = nonceResponse.nonce;
  }
};
</script>
 
<template>
  <div>
    <button @click="handleGetNonce" :disabled="isLoading">
      Get Nonce
    </button>
    <div v-if="nonce">Nonce: {{ nonce }}</div>
    <div v-if="error">Error: {{ error.message }}</div>
  </div>
</template>

Authenticating

<script setup lang="ts">
import { ref } from 'vue';
import { getSilentSwapOrders, getSilentSwapAuth, getSilentSwapClient } from '@silentswap/vue';
import { useAccount, useSignMessage } from 'wagmi';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const { address } = useAccount();
const { signMessageAsync } = useSignMessage();
 
const { client } = getSilentSwapClient({
  config: {
    environment: ENVIRONMENT.MAINNET,
  },
});
 
const { getNonce, authenticate } = getSilentSwapOrders({ client });
const { createSignInMessage } = getSilentSwapAuth();
 
const authResult = ref<any>(null);
 
const handleAuthenticate = async () => {
  // Get nonce
  const nonceResponse = await getNonce(address.value!);
  if (!nonceResponse) return;
 
  // Create SIWE message
  const message = createSignInMessage(
    address.value!,
    nonceResponse.nonce,
    'example.com'
  );
 
  // Sign message
  const signature = await signMessageAsync({ message });
 
  // Authenticate
  const result = await authenticate({
    siwe: {
      message,
      signature: signature as `0x${string}`,
    },
  });
 
  if (result) {
    authResult.value = result;
    console.log('Authenticated:', result.address);
  }
};
</script>
 
<template>
  <div>
    <button @click="handleAuthenticate">Sign In</button>
    <div v-if="authResult">
      <p>Authenticated as: {{ authResult.address }}</p>
    </div>
  </div>
</template>

Getting a Quote

<script setup lang="ts">
import { ref } from 'vue';
import { getSilentSwapOrders, getSilentSwapClient } from '@silentswap/vue';
import { 
  DeliveryMethod, 
  caip19FungibleEvmToken, 
  FacilitatorKeyType, 
  PublicKeyArgGroups 
} from '@silentswap/sdk';
import { ENVIRONMENT } from '@silentswap/sdk';
 
const { client } = getSilentSwapClient({ config: { /* ... */ } });
const { getQuote, isLoading, error } = getSilentSwapOrders({ client });
 
const quote = ref<any>(null);
 
const handleGetQuote = async () => {
  // Generate facilitator group (you would get this from wallet generation)
  // 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);
 
  const quoteResult = await getQuote({
    signer: '0x...' as `0x${string}`,
    viewer: new Uint8Array(65), // viewerPk
    outputs: [{
      method: DeliveryMethod.SNIP,
      asset: caip19FungibleEvmToken(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'),
      value: '1000000' as `${bigint}`,
      recipient: '0x...' as `0x${string}`,
      facilitatorPublicKeys: new Uint8Array(65), // groupPks[0]
    }],
  });
 
  if (quoteResult) {
    quote.value = quoteResult;
    console.log('Quote ID:', quoteResult.quoteId);
  }
};
</script>
 
<template>
  <div>
    <button @click="handleGetQuote" :disabled="isLoading">
      Get Quote
    </button>
    <div v-if="quote">
      <p>Quote ID: {{ quote.quoteId }}</p>
      <p>Authorizations: {{ quote.authorizations.length }}</p>
    </div>
    <div v-if="error">Error: {{ error.message }}</div>
  </div>
</template>

Creating an Order

<script setup lang="ts">
import { ref } from 'vue';
import { getSilentSwapOrders, getSilentSwapAuth, getSilentSwapClient } from '@silentswap/vue';
import { useSignTypedData } from 'wagmi';
import type { QuoteResponse } from '@silentswap/sdk';
 
const { signTypedDataAsync } = useSignTypedData();
const { client } = getSilentSwapClient({ config: { /* ... */ } });
const { getQuote, createOrder } = getSilentSwapOrders({ client });
const { createEip712DocForOrder } = getSilentSwapAuth();
 
const order = ref<any>(null);
const quote = ref<QuoteResponse | null>(null);
 
const handleCreateOrder = async () => {
  // Get quote first (simplified - you'd have the full quote flow)
  // const quoteResult = await getQuote(/* ... */);
  // if (!quoteResult) return;
  // quote.value = quoteResult;
 
  if (!quote.value) return;
 
  // Create EIP-712 document
  const orderDoc = createEip712DocForOrder(quote.value);
 
  // Sign the document
  const signature = await signTypedDataAsync(orderDoc);
 
  // Create order
  const orderResult = await createOrder({
    quote: quote.value.quote,
    quoteId: quote.value.quoteId,
    authorizations: [], // You'd sign these separately
    eip712Domain: orderDoc.domain,
    signature,
    facilitators: [], // You'd generate these from facilitator group
  });
 
  if (orderResult) {
    order.value = orderResult;
    console.log('Order created:', orderResult.response.orderId);
  }
};
</script>
 
<template>
  <div>
    <button @click="handleCreateOrder">Create Order</button>
    <div v-if="order">
      <p>Order ID: {{ order.response.orderId }}</p>
    </div>
  </div>
</template>

Reactive State

The composable provides reactive state that automatically updates:

<script setup lang="ts">
import { watch } from 'vue';
import { getSilentSwapOrders, getSilentSwapClient } from '@silentswap/vue';
 
const { client } = getSilentSwapClient({ config: { /* ... */ } });
const { isLoading, error } = getSilentSwapOrders({ client });
 
// Watch for loading state changes
watch(isLoading, (loading) => {
  if (loading) {
    console.log('Operation in progress...');
  } else {
    console.log('Operation completed');
  }
});
 
// Watch for errors
watch(error, (err) => {
  if (err) {
    console.error('Error occurred:', err.message);
  }
});
</script>

Error Handling

<script setup lang="ts">
import { ref } from 'vue';
import { getSilentSwapOrders, getSilentSwapClient } from '@silentswap/vue';
 
const { client } = getSilentSwapClient({ config: { /* ... */ } });
const { getQuote, error, isLoading } = getSilentSwapOrders({ client });
 
const handleGetQuote = async () => {
  try {
    const quote = await getQuote(/* ... */);
    if (!quote) {
      // Handle null return (indicates error)
      console.error('Failed to get quote');
      return;
    }
    // Success
    console.log('Quote received:', quote);
  } catch (err) {
    // Handle exception
    console.error('Quote error:', err);
  }
};
</script>
 
<template>
  <div>
    <button @click="handleGetQuote" :disabled="isLoading">
      Get Quote
    </button>
    <div v-if="error" class="error">
      Error: {{ error.message }}
    </div>
  </div>
</template>

Best Practices

  1. Check Return Values - Always check for null returns (indicates error)
  2. Use Reactive State - Leverage isLoading and error for UI updates
  3. Error Recovery - Provide retry mechanisms for failed operations
  4. Type Safety - Use TypeScript types for all requests/responses
  5. Watch State - Use Vue's watch to react to state changes

Next Steps