Skip to content

About Swap API

The Definitive Swap API provides a simple interface to swap tokens. This guide demonstrates how to set up and execute a token swap using the API.

Swap Tokens in Five Steps

  1. Get an API Key
  2. Prepare the Pre Hash
  3. Sign the Request
  4. Generate A Quote
  5. Submit Request

Step 1: Get an API Key

Before you begin, obtain your API credentials from Definitive. Follow these steps:

  • Visit the Getting Started page for instructions.
  • Generate your API key and secret.
  • Store them securely, for example, in a .env file:
API_KEY=your_api_key_here
API_SECRET=your_api_secret_here

Additionally, you could use AuthHelpers to streamline this process.

Step 2: Prepare the Pre Hash

To secure your request, you must create a "prehash" string that incorporates the HTTP method, path, query parameters, timestamp, and headers. The prehash format is:

${method}:${path}?${queryParamsString}:${timestamp}:${sortedHeaders}${bodyString};

Below is an example function to generate this prehash in JavaScript:

// if you're using typescript we recommend copying this method directly
function preparePrehash({
  method,
  timestamp,
  path,
  queryParams,
  headers,
  body,
}: PrehashParams) {
  const filtered = Object.entries(headers).filter(([key]) =>
    key.toLowerCase().startsWith("x-definitive-")
  );
 
// ensure that the headers are sorted for consistency
  const sortedHeaders = filtered
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([key, value]) => `${key}:${JSON.stringify(value)}`)
    .join(",");
 
  // only pass x-definitive-api-key and x-definitive-timestamp
  if (filtered.length > 2) {
    throw new Error("Headers are too long - are you adding a new header?");
  }
 
  // stringify the query params eg. 'key=value&key2=value2'
  const queryParamsString = new URLSearchParams(queryParams).toString();
  
  // Use an empty string if no body is provided
  const bodyString = body ?? "";
 
  return `${method}:${path}?${queryParamsString}:${timestamp}:${sortedHeaders}${bodyString}`;
}
 
const timestamp = Date.now().toString();
 
// generate the message to be signed
const message = preparePrehash({
  method: "POST",
  path: "/v1/orders",
  timestamp,
  headers: {
    "x-definitive-api-key": apiKey,
    "x-definitive-timestamp": timestamp,
  },
  queryParams: {},
});

Step 3: Sign the Request

After generating the prehash message, sign it using your API secret. Remove the dpks_ prefix from your API secret (if present) and create an HMAC using SHA-256.

/**
* Signs a message using HMAC SHA256.
*/
function signMessage(message) {
  return crypto.createHmac("sha256", signingSecret)
    .update(message)
    .digest("hex");
}

Step 4: Generate the Quote

These orders will be scoped to the portfolio for which you created the keys. It is necessary to generate the quote in order to submit a valid request.

async function generateQuote() {
  const method = "POST";
  const path = "/v1/trade/quote";
  const timestamp = Date.now().toString();
 
  const headers = {
    "x-definitive-api-key": apiKey,
    "x-definitive-timestamp": timestamp,
    "Content-Type": "application/json"
  };
 
  // Replace these addresses with valid tokens for your trade.
  const quoteRequest = {
    type: "market",     // "market", "limit", or "twap"
    chain: "base",  // example chain; change if needed
    from: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // e.g., USDC on base
    to: "0x4200000000000000000000000000000000000006",   // e.g., WETH on base
    qty: "10.00",     // trade quantity
    orderSide: "sell",  // "buy" or "sell"
    slippageTolerance: "0.01", // 1% slippage tolerance
    maxPriceImpact: "0.05"     // 5% maximum price impact
  };
 
  const bodyString = JSON.stringify(quoteRequest);
 
  // Prepare a prehash message using the current parameters.
  const prehashMessage = preparePrehash({
    method,
    path,
    timestamp,
    headers,
    queryParams: {},
    body: bodyString
  });

Step 5: Submit the Request

Now that we have the ability to generate a prehash, sign the message, and generate a quote: we are ready to submit a request.

async function submitTradeFromQuote() {
  try {
    const quoteResponse = await generateQuote();
    if (!quoteResponse || !quoteResponse.quote) {
      throw new Error("Invalid quote response.");
    }
    // Merge the quote and metadata objects into one payload.
    const tradePayload = {
      ...quoteResponse.quote,
      ...quoteResponse.metadata
    };
    console.log("Using Trade Payload:", tradePayload);
    const orderResponse = await submitTrade(tradePayload);
    console.log("Order Response:", orderResponse);
  } catch (error) {
    console.error("Error in submitting trade from quote:", error);
  }
}

Now, if you call submitTradeFromQuote() it will generate a quote and submit it. Please make sure you are using the correct parameters to prevent any accidental swaps.

Key Takeaways

  • Generating The Prehash
  • Signing the Message
  • Generating a Quote
  • Submitting the Request