LogoLogo
  • ☠️Introduction
    • What is Clipper?
    • How Clipper Makes Money for LPs
    • How LPs Earn from Arbitrage
    • Clipper's Benchmark: No Impermanent Loss
      • Clipper vs. CPMMs vs. HODLing
      • Appendix: Math
    • Why Clipper Has Better Trading Prices
    • DAO Protocol Fees
    • DAO Governance
  • ⚔️How to Use Clipper
    • Liquidity Pools
      • Depositing & Withdrawing
      • Farming Pools
    • Trading
    • Community Adventures
    • FAQs
  • 🪙Governance Token
    • Community Governance
    • ⛵SAIL Primer
      • Clipper Fundamentals
      • DEX Market Structure
      • SAIL Supply & Circulation
      • SAIL Farming
      • veSAIL
      • Token Listings
  • 🏴‍☠️Disclaimers & Technical
    • Audits
    • Smart Contracts
      • Subgraph
        • Entities
        • Queries
    • Integrating with Clipper RFQ
      • Introduction
      • Guides
        • How to use clipper RFQ API?
        • Estimate Clipper Prices
        • Interacting with the Clipper Exchange contracts
        • Integration Examples
          • Swap Native token → Shorttail
          • Swap Shorttail → Native token
          • Swap Shorttail → Shorttail
          • Complete Swap Flow
      • API Reference
        • API v2
          • Overview
          • Pool v2
          • Quote v2
        • API v1
          • Overview
          • Pool
          • Quote
          • Sign
      • Troubleshooting & FAQs
    • Terms of Service
    • Privacy Policy
  • ⛵Come Aboard
    • Discord
    • Twitter
    • Github
Powered by GitBook
On this page

Was this helpful?

  1. Disclaimers & Technical
  2. Integrating with Clipper RFQ
  3. Guides

How to use clipper RFQ API?

PreviousGuidesNextEstimate Clipper Prices

Last updated 1 month ago

Was this helpful?

Clipper's Formula Market Maker (FMM) is implemented similar to a typical Request For Quotes (RFQ) system. In an , you first ask our offchain server to quote a transaction price, specifying the buy and sell tokens and either a target input or output amount. You then have a short amount of time to accept that quote, and receive back a signed certificate from our offchain server. Then, you must pass that transaction and signed certificate to our onchain smart contracts to execute the swap.

Clipper supports a “send, then swap" modality and is designed to be as simple as possible to chain within a larger set of transactions, or to automate trading with bots.

It's essential to obtain the credentials in order to proceed with the guide for API usage. Please reach out to us to acquire the necessary credentials for API access, please refer to the section to know details.

You can see the supported networks

  1. Get exchange address and asset information.

const fetch = require('node-fetch');

const chainId = 137;  // You can use a different network. Look for our supported networks
const fieldset = 'offchain-data';
const authorizationHeader = 'YXBpLXVzZXI6dXNlci1wYXNz';  // This is a placeholder 

const requestOptions = {
  method: 'GET',
  headers: {
    'x-api-key': authorizationHeader,
    'Content-Type': 'application/json'
  }
};

const response = await fetch(`https://api.clipper.exchange/rfq/pool?chain_id=${chainId}&fieldset=${fieldset}`, requestOptions);
const data = await response.json();
console.log(data);

The API response will look like the following (some fields omitted):

{
    "pool": {
        "chain_id": 137,
        "address": "0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8",
        "num_assets": 2,
        "k": 0.115,
        "time_in_seconds": 60,
        "default_time_in_seconds": 60,
        "swaps_enabled": true
    },
    "assets": [
        {
            "name": "USDC",
            "address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
            "price_in_usd": 1.0,
            "listing_weight": 178
        },
        {
            "name": "DAI",
            "address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
            "price_in_usd": 1.0,
            "listing_weight": 250
        }
    ],
    "pairs": [
        {
            "assets": [
                "USDC",
                "DAI"
            ],
            "fee_in_basis_points": 6.0
        }
    ],
    "pool_type": "offchain"
}

💡 You can include the query param time_in_seconds to the GET call if you intend to get quotes for values other than the default_time_in_seconds for a chain. As you lower the time you will see lower fees (and therefore better prices).

  1. Request a quote

const fetch = require('node-fetch');

const params = {
  output_asset_symbol: 'USDC',
  input_asset_symbol: 'DAI',
  chain_id: 137,  // Should be set to the appropriate chain ID. Polygon is 137.
  input_amount: '2000000000000000000', // XOR: output_amount: '2000000000000000000'
  time_in_seconds: 30. // A good suggestion for Polygon is 30 seconds. As this value increases, the quote will get worse for the user.
};

const authorizationHeader = 'YXBpLXVzZXI6dXNlci1wYXNz';  // This is a placeholder 

const requestOptions = {
  method: 'POST',
  headers: {
    'x-api-key': authorizationHeader,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(params)
};

const response = await fetch('https://api.clipper.exchange/rfq/quote', requestOptions);
const data = await response.json();
console.log(data);

input_asset_symbol and output_asset_symbol should correspond to the asset name returned from the /rfq/poolcall in the step 1.

The API response will look like the following (some fields omitted):

{
    "id": "320d255f-5864-4245-927c-fa4951121ee8",
    "must_accept_by": "2023-09-01 18:10:36.629117+00:00",
    "good_until": 1693591896,
    "chain_id": 137,
    "input_amount": "2000000000000000000",
    "output_amount": "2000000",
    "input_value_in_usd": 2.0,
    "output_value_in_usd": 2.0,
    "rate": 1.0,
    "input_asset_address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
    "output_asset_address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174"
}

For assets like ETH and MATIC Clipper exchange uses the wrapped version of these assets, a distinction made clear and unambiguous by the inclusion of the contract addresses in the response.

  1. Sign the quote

Our quotes are firm. If a signed order make it onchain by the good_until time it will generally be honored as explicitly written. Note that, on some chains, if other orders frontrun the signed quote it may be rejected - this is a security precaution to prevent sybil attacks.

const fetch = require('node-fetch');

const params = {
  quote_id: "590d7956-c7cc-45da-83ed-23f6901f74e9",  // id we get get in first step
  destination_address: "0x5901920A7b8cb1Bba39220FAC138Ffb3800dD212",  // it will receive the output token
  sender_address: "0x5901920A7b8cb1Bba39220FAC138Ffb3800dD212". // Optional: it is for DEX aggregator partners that are using their own smart contract
};

const authorizationHeader = 'YXBpLXVzZXI6dXNlci1wYXNz';  // This is a placeholder

const requestOptions = {
  method: 'POST',
  headers: {
    'x-api-key': authorizationHeader,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(params)
};

const response = await fetch('https://api.clipper.exchange/rfq/sign', requestOptions);
const data = await response.json();
console.log(data);

The API response will look like the following:

{
    "chain_id": 137,
    "input_asset_address": "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
    "output_asset_address": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
    "input_amount": "2000000000000000000",
    "output_amount": "2000000",
    "good_until": "627710173538668076417607179014705162363943960351250641945575434764",
    "destination_address": "0xab83Af831dfb4028EBFd3fFA74A828a4d5DCaAC5",
    "signature": {
        "v": 28,
        "r": "0x8a866d67003c32bf9b4bd40f6abf1fe939a288ad2199f967c108d4e73ecb6916",
        "s": "0x4c9b1219a35139c5f7ce58452fb3d3c8fdff27c7dd3af055fbbdfd30ef0a0a20"
    },
    "clipper_exchange_address": "0x6Bfce69d1Df30FD2B2C8e478EDEC9dAa643Ae3B8"
}
  1. Send the transaction

Using ether.js

import ethers from "ethers";
import exchangeAbi from "./exchangeAbi.json";

async function executeSwap(signResponse) {
  const provider = new ethers.providers.JsonRpcProvider(process.env.RPC_URL);
  const exchangeContract = new ethers.Contract(
    signResponse.clipper_exchange_address,
    exchangeAbi,
    provider
  );
  // Any 32 bytes identifier
  const auxData = "0x00000000000000000000000000000000000000000000000000";

  const result = await exchangeContract.swap(
    signResponse.input_asset_address,
    signResponse.output_asset_address,
    signResponse.input_amount,
    signResponse.outputAmount,
    signRespose.good_until,
    signResponse.destination_address,
    [signResponse.signature.v, signResponse.signature.r, signResponse.signature.s],
    auxData
  )

💡 To obtain more details about the endpoint, its parameters, and the response, please refer to the API Reference in the section.

You should estimate clipper prices using the offchain state information for better performance. Review the section to know more about it.

💡 To obtain more details about the endpoint, its parameters, and the response, please refer to the API Reference in the section.

Only members of the Clipper Community and DEX aggregator partners can get their quotes signed. If you're building a DEX aggregator, please reach out to the team on for access (MNDA required).

If you want to get the bytes representation of the swap to be sent directly to the pool contract you can review our

💡 To obtain more details about the endpoint, its parameters, and the response, please refer to the API Reference in the section

💡 You can review the guide to know more ways of interact with Clipper. You can also review code examples in the section

You can find a complete swap flow example

🏴‍☠️
pool
Estimate Clipper Prices
quote
Discord
sign
Interacting with the Clipper Exchange
Integration Examples
here
Authorization
calldata swap feature
RFQ architecture
here
19KB
exchangeAbi.json