Skip to main content

WPAXG Swap Integration

This guide walks through integrating the WPAXG swap REST API into your application.
Currently only available via REST API.

Prerequisites

  • A Paxos Labs API key
  • An Optimism RPC endpoint
  • A wallet library (viem, ethers, wagmi, etc.)

Getting a Swap Quote

Request a quote by calling the /v1/wpaxg/swapQuotes endpoint:
const response = await fetch(
  'https://api.paxoslabs.com/v1/wpaxg/swapQuotes?' + new URLSearchParams({
    chainId: '10',
    offerAsset: '0x5cb5c4d5e8b184a364534bc688da0553ccf8f484', // WPAXG
    wantAsset: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',  // USDC
    offerAmount: '1000000000000000000', // 1 WPAXG in wei
    userAddress: '0x...', // User's wallet address
  }),
  {
    headers: {
      'x-api-key': 'pxl_<public_id>_<secret>',
    },
  }
);

const quote = await response.json();

Response Structure

The quote response includes:
interface SwapQuoteResponse {
  transaction: {
    to: string;      // Contract to send the transaction to
    data: string;    // Encoded swap calldata
    value: string;   // ETH value (usually "0" for token swaps)
    gas: string;     // Estimated gas limit
    gasPrice: string; // Suggested gas price
  };
  buyAmount: string;        // Expected output amount
  minBuyAmount: string;     // Minimum output (with slippage)
  allowanceTarget: string;  // Address to approve tokens to
  currentAllowance?: string; // User's current allowance (if any)
}

Handling Token Approvals

Before executing the swap, ensure the user has approved sufficient tokens:
import { erc20Abi } from 'viem';

// Check if approval is needed
const needsApproval = BigInt(quote.currentAllowance ?? '0') < BigInt(offerAmount);

if (needsApproval) {
  // Request approval
  const approveTx = await walletClient.writeContract({
    address: offerAsset,
    abi: erc20Abi,
    functionName: 'approve',
    args: [quote.allowanceTarget, offerAmount],
  });

  // Wait for approval confirmation
  await publicClient.waitForTransactionReceipt({ hash: approveTx });
}

Executing the Swap

Once approved, execute the swap using the provided calldata:
const swapTx = await walletClient.sendTransaction({
  to: quote.transaction.to,
  data: quote.transaction.data,
  value: BigInt(quote.transaction.value),
  gas: BigInt(quote.transaction.gas),
});

const receipt = await publicClient.waitForTransactionReceipt({ hash: swapTx });

Using Permit2 Authorization

For gasless approvals, use the permit2 auth method:
const response = await fetch(
  'https://api.paxoslabs.com/v1/wpaxg/swapQuotes?' + new URLSearchParams({
    chainId: '10',
    offerAsset: '0x5cb5c4d5e8b184a364534bc688da0553ccf8f484',
    wantAsset: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85',
    offerAmount: '1000000000000000000',
    userAddress: '0x...',
    authMethod: 'permit2', // Use Permit2
  }),
  {
    headers: {
      'x-api-key': 'pxl_<public_id>_<secret>',
    },
  }
);

const quote = await response.json();

// The response includes EIP-712 typed data for signing
if (quote.permit2) {
  const signature = await walletClient.signTypedData({
    domain: quote.permit2.eip712.domain,
    types: quote.permit2.eip712.types,
    primaryType: quote.permit2.eip712.primaryType,
    message: quote.permit2.eip712.message,
  });

  // Include signature when executing the swap
  // (implementation depends on your setup)
}

Error Handling

The API returns standard HTTP error codes:
StatusDescription
400Invalid parameters or insufficient liquidity
503DEX aggregator temporarily unavailable
Example error response:
{
  "error": {
    "code": 400,
    "message": "No liquidity available for this swap. Try a smaller amount or different token pair.",
    "status": "INVALID_ARGUMENT"
  }
}
Always validate the minBuyAmount before executing to protect against slippage. Consider showing users the expected output and allowing them to set slippage tolerance.