Skip to main content

Overview

The Quotes API enables you to request price quotes for chain-abstracted swaps, execute those quotes, and monitor their execution status. This is the core API for performing token swaps in the OneBalance system.

API Methods

getQuote

Request a quote for swapping tokens across chains.
quotesApi.getQuote(request: QuoteRequest): Promise<Quote>

Parameters

request
QuoteRequest
required
The quote request object containing source and destination details

Returns

Quote
object
A quote object containing all information needed to execute the swap

Example

import { quotesApi } from '@/lib/api/quotes';
import type { QuoteRequest } from '@/lib/types/quote';

const quoteRequest: QuoteRequest = {
  from: {
    account: {
      sessionAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
      adminAddress: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb',
      accountAddress: '0x1234567890abcdef1234567890abcdef12345678'
    },
    asset: {
      assetId: 'ob:usdc'
    },
    amount: '1000000' // 1 USDC (6 decimals)
  },
  to: {
    asset: {
      assetId: 'ob:eth'
    }
  }
};

const quote = await quotesApi.getQuote(quoteRequest);
console.log('Quote ID:', quote.id);
console.log('Expected output:', quote.destinationToken.amount);

executeQuote

Execute a signed quote to perform the swap.
quotesApi.executeQuote(quote: Quote): Promise<any>
Before calling this function, you must sign the quote’s chain operations using the user’s wallet. The quote parameter should include signed userOp signatures.

Parameters

quote
Quote
required
The quote object with signed user operations. This should be the same quote returned from getQuote(), but with signatures added to each chain operation.

Returns

response
any
Execution confirmation response from the server

Example

import { quotesApi } from '@/lib/api/quotes';
import { signQuote } from '@/lib/utils/privySigningUtils';

// First, get a quote
const quote = await quotesApi.getQuote(quoteRequest);

// Check if quote is still valid
const expirationTime = parseInt(quote.expirationTimestamp) * 1000;
if (Date.now() > expirationTime) {
  throw new Error('Quote has expired');
}

// Sign the quote with user's wallet
const signedQuote = await signQuote(quote, embeddedWallet);

// Execute the signed quote
await quotesApi.executeQuote(signedQuote);

console.log('Quote executed successfully!');

getQuoteStatus

Check the execution status of a quote.
quotesApi.getQuoteStatus(quoteId: string): Promise<QuoteStatus>
This endpoint should be polled periodically after executing a quote to monitor transaction progress across chains.

Parameters

quoteId
string
required
The unique identifier of the quote to check (from quote.id)

Returns

QuoteStatus
object
Current status and transaction details

Example

import { quotesApi } from '@/lib/api/quotes';

// Start polling after executing a quote
const pollStatus = async (quoteId: string) => {
  const interval = setInterval(async () => {
    try {
      const status = await quotesApi.getQuoteStatus(quoteId);
      
      console.log('Status:', status.status);
      console.log('Origin txs:', status.originChainOperations);
      
      if (status.status === 'COMPLETED') {
        clearInterval(interval);
        console.log('Swap completed!');
        console.log('Explorer:', status.destinationChainOperations[0]?.explorerUrl);
      } else if (status.status === 'FAILED') {
        clearInterval(interval);
        console.error('Swap failed');
      }
    } catch (error) {
      console.error('Error checking status:', error);
      clearInterval(interval);
    }
  }, 1000); // Poll every 1 second
};

pollStatus(quote.id);

Complete Workflow Example

Here’s a complete example showing how to request, execute, and monitor a swap:
import { quotesApi } from '@/lib/api/quotes';
import { signQuote } from '@/lib/utils/privySigningUtils';
import type { QuoteRequest } from '@/lib/types/quote';

// Step 1: Create a quote request
const quoteRequest: QuoteRequest = {
  from: {
    account: {
      sessionAddress: walletAddress,
      adminAddress: walletAddress,
      accountAddress: smartAccountAddress
    },
    asset: { assetId: 'ob:usdc' },
    amount: '100000000' // 100 USDC
  },
  to: {
    asset: { assetId: 'ob:eth' }
  }
};

// Step 2: Get the quote
const quote = await quotesApi.getQuote(quoteRequest);
console.log('Quote received:', quote.id);
console.log('Will receive:', quote.destinationToken.amount, 'ETH');

// Step 3: Sign and execute
const signedQuote = await signQuote(quote, wallet);
await quotesApi.executeQuote(signedQuote);
console.log('Quote executed, monitoring status...');

// Step 4: Poll for status
const checkStatus = setInterval(async () => {
  const status = await quotesApi.getQuoteStatus(quote.id);
  
  if (status.status === 'COMPLETED' || status.status === 'FAILED') {
    clearInterval(checkStatus);
    console.log('Final status:', status.status);
  }
}, 2000);

Error Handling

try {
  const quote = await quotesApi.getQuote(request);
} catch (error) {
  if (error instanceof Error) {
    console.error('Failed to get quote:', error.message);
    // Handle specific error cases
    if (error.message.includes('insufficient balance')) {
      // Show balance error to user
    } else if (error.message.includes('unsupported asset')) {
      // Show asset error to user
    }
  }
}

Best Practices

Check Expiration

Always validate that expirationTimestamp hasn’t passed before executing a quote

Poll Efficiently

Poll status every 1-2 seconds after execution, and stop when status is terminal (COMPLETED/FAILED)

Handle Errors

Implement proper error handling for network failures and transaction rejections

Show Progress

Display transaction hashes and explorer links to users for transparency

Build docs developers (and LLMs) love