Build more with QuickNode - New pricing plans and a free tier! Read the press release

Interacting with 0x API using JavaScript

March 23, 2022

Overview

We have seen tremendous growth in trade volume in DEXs. With many of these coming to the market, it is tough to decide which DEX to choose when you want to swap your token for another. That's where 0x and its APIs come into the picture. It helps us to fetch the DEX with the best price quote. This will give a much better output for the number of tokens we want to swap, which you will eventually see towards the end. So, make sure to follow through till the end.

Prerequisite:
1. Terminal
2. Node
3. Code Editor
4. Curious mind

What is a DEX?

A Decentralised EXchanges, popularly known as DEX, is a crucial part of the blockchain ecosystem. It is a decentralized marketplace that connects cryptocurrency buyers and sellers in a peer-to-peer fashion without involving any controlling/central authority. Some of the popular DEX in the space are UniSwap, SuhiSwap, and PancakeSwap. Smart contracts power every DEX to operate in a deterministic and unstoppable manner. DEXs has gained popularity and has seen a massive surge in numbers because they are permissionless. In any Centralised Exchange, you will have to verify your identity through KYC, and the exchange is in control of your private key. So, if the organization gets hacked or freezes your account, your funds will be gone forever. But in a DEX, a user is in control of the private key. The only limiting factor is the security flaw in the contract. Any good DEX would audit their contract from multiple agencies to make sure they are less prone to attacks. So in case, you want to swap your ETH for some DAI, you can easily do that using a DEX. 

Heart of DEX→AMM

Automated Market Maker or AMM drives the DEX. AMM, at its core, uses a mathematical formula that decides the price for a pair of tokens and facilitates the trading of tokens. It helps in quoting the exchange rate for two assets and allows anyone to build the market for the duo by providing liquidity, i.e., become a market maker. For example, Uniswap uses x*y=k as AMM. Here x is the quantity of one token, and y is the quantity of another token. Now, the product of both tokens should be constant, which is denoted by k.  Ideally, no matter how many tokens are added or removed, it will balance out to keep the product steady. Other functionalities come into the picture, including swapping, liquidity mining, and many more.

About 0X

Following the official docs:

0x is a protocol that facilitates the peer-to-peer exchange of Ethereum-based assets. The protocol serves as an open standard and common building block for any developer needing exchange functionality.

0x is one of its kind that enables peer-to-peer trading in the traditional book order method. Book orders are a standard trading method that matches buyers and sellers based on the price they quote. Though it is a feasible and trendy option for a centralized exchange, it becomes a very costly and time-consuming affair for a DEX. Every transaction and smart contract interaction would consume gas, aka money. 0x promises to get rid of this pain point by taking some of the procedures off-chain. This would save a lot of money for the participants and the procedure would be much faster. In a nutshell, a trade initiation takes place off-chain, and the settlement is done on-chain, which makes the dream of a frictionless decentralized order book a reality.

The key participants in the protocols are Makers, Takers, and Relayers. Makers are the market entity that initiates a trade, while Takers are entities that fulfill the transaction. In between is the Relayers that connects Makers and Takers, which again keeps a record of all off-chain settlements. Let's say Maker wants to swap Token A for Token B. It would go like this:

1. Maker approves the 0x contract to access their balance of Token A and initiates an order to exchange it for Token B. Maker signs the transaction with its private key, converting the order into a **message format** that is ready to be transmitted to off-chain channels.
2. The Maker broadcasts it over Relayer. 0x has an explorer page that lists the Relayers. 
3. A Taker, who wants to fill the order, approves the 0x contract to access their balance of Token B.
4. The Taker filled the order by submitting it to the 0x contract on the Ethereum blockchain.
5. The Relayer receives fees in the form of XRZ, which is the native token of 0x.

0x is a next-generation DEX that lets developers leverage its open software to build Dapps and projects around it. 0x has developer-friendly resources and provides support to develop projects on top of 0x. This way, 0x is a lucrative choice among both business people and developers. 0x believes in the motto that any ownable assets can be tokenized, i.e., represented as a token in the blockchain. This means that soon, your house can be defined as a token in blockchain and can be traded in a decentralized fashion without involving an intermediary like a lawyer or brokerage firm. 0x is evolving and aiming to fulfill such needs.

Code

Now, we will leverage the APIs provided by 0x to build an application that will assist us in finding the best DEX to swap our token.

Installation

1.  For that, create a folder named ZRX_Swap.  Inside the folder, open your terminal and enter:

code

Copy
npm init -y

2. Now open the folder in your favorite editor. For this article, we will be using VS Code editor. Now, run the following command to open the folder in VS editor:

code

Copy
code .

3.We will need to install a package called qs. For that:

code

Copy
npm install qs --save

4.Now, we also need to install a package called axios. It will help us to call the 0x API. For that:

code

Copy
npm install axios --save

Writing the code

Create a file called index.js which will house our main code. In this, we will fetch the best quotation sent by 0x, and we will separately try to fetch the same from UniSwapV3. This highlights that we can either go for a specific exchange of our choice or let 0x decide the best one for us. Copy and paste the following code in the file:

code

Copy
const { default: axios } = require('axios')
const qs = require('qs')
const params = {
  buyToken: 'DAI',
  sellToken: 'ETH',
  sellAmount: 0.05 * Math.pow(10, 18).toString(), // Always denominated in wei
}
const URL = 'https://api.0x.org/swap/v1/quote?'

//Get Default Quote
const getDefaultQuote = async () => {
  let response
  try {
    response = await axios.get(`${URL}${qs.stringify(params)}`)
  } catch (err) {
    console.error(err)
  }
  console.log("Default Quote")
  console.log("%O",response.data)
  console.log("%O",response.data.sources)

}

//Get Quote from a specific DEX
const getUniSwapV3Quote = async (inputToken, outputToken, value) => {
  const exchangeList = 'Uniswap_V3'
  const params = {
    buyToken: 'DAI',
    sellToken: 'ETH',
    sellAmount: 0.05 * Math.pow(10, 18).toString(), // Always denominated in wei
    includedSources: exchangeList,
  }
  let response
  try {
    response = await axios.get(
      `${URL}${qs.stringify(params)}`,
    )
  } catch (err) {
    console.error(err)
  }
  console.log("Uniswap Quote",)
  console.log("%O",response.data)
  console.log("%O",response.data.sources)
}

getDefaultQuote()
getUniSwapV3Quote()

Line1: We are importing axios, a popular node module for making HTTPS request.

Line2: Next, we are importing qs which is mainly used for formatting our query string for our API to work.

Line3-7: We are creating an object that contains details about:

1. The token we want to sell. In this case, it is Ethers.
2. The token we want to buy. So, we will buy some DAI.
3. The amount of token you want to sell. In this case, we are selling 0.005 Ether or 0.005 * 10^8 Wei.

Line8: We are storing the base URL in a variable.

Line11: We define a function that would fetch us the best price quotation by 0x for the given pair.

Line12:We are defining a variable to store the response we got from the API.

Line13:Start of the try block.

Line14:We are calling the API using axios. In the get parameter, we are passing the base URL and the formatted query object. We are storing the output in the response variable.

Line15-17:End of the try block. We have a catch block to log any error from API.

Line18-21: We are displaying the quotation for the pair of tokens and the source from which we are getting them.

Line 24-41: We are following the same procedure as above except that we are passing an additional field i.e. includedSources in the params object, which contains the DEXs name from which we want to fetch the quote. In this case, we want to fetch the quotation from UniSwapV3.

Line 43-44: We are calling the above functions to see their output.

Now, in the terminal, run:

code

Copy
node index

Output

You should see an output similar to the ones below:

1. For Default Quote

code

Copy
Default Quote
{
  chainId: 1,
  price: '1813.2127887520304968',
  guaranteedPrice: '1795.0806608645101918',
  to: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
  data: '0xd9627aa400000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000011c37937e080000000000000000000000000000000000000000000000000007c8f09c066034caf00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f869584cd0000000000000000000000001000000000000000000000000000000000000011000000000000000000000000000000000000000000000083951146f160f5b444',
  value: '5000000000000000',
  gas: '136000',
  estimatedGas: '136000',
  gasPrice: '59000000000',
  protocolFee: '0',
  minimumProtocolFee: '0',
  buyTokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f',
  sellTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
  buyAmount: '9066063943760152484',
  sellAmount: '5000000000000000',
  sources: [
    { name: '0x', proportion: '0' },
    { name: 'Uniswap', proportion: '0' },
    { name: 'Uniswap_V2', proportion: '0' },
    { name: 'Eth2Dai', proportion: '0' },
    { name: 'Kyber', proportion: '0' },
    { name: 'Curve', proportion: '0' },
    { name: 'Balancer', proportion: '0' },
    { name: 'Balancer_V2', proportion: '0' },
    { name: 'Bancor', proportion: '0' },
    { name: 'mStable', proportion: '0' },
    { name: 'Mooniswap', proportion: '0' },
    { name: 'Swerve', proportion: '0' },
    { name: 'SnowSwap', proportion: '0' },
    { name: 'SuiSwap', proportion: '1' },
    { name: 'Shell', proportion: '0' },
    { name: 'MultiHop', proportion: '0' },
    { name: 'DODO', proportion: '0' },
    { name: 'DODO_V2', proportion: '0' },
    { name: 'CREAM', proportion: '0' },
    { name: 'LiquidityProvider', proportion: '0' },
    { name: 'CryptoCom', proportion: '0' },
    { name: 'Linkswap', proportion: '0' },
    { name: 'Lido', proportion: '0' },
    { name: 'MakerPsm', proportion: '0' },
    { name: 'KyberDMM', proportion: '0' },
    { name: 'Smoothy', proportion: '0' },
    { name: 'Component', proportion: '0' },
    { name: 'Saddle', proportion: '0' },
    { name: 'xSigma', proportion: '0' },
    { name: 'Uniswap_V3', proportion: '0' },
    { name: 'Curve_V2', proportion: '0' },
    { name: 'ShibaSwap', proportion: '0' }
  ],
  orders: [
    {
      makerToken: '0x6b175474e89094c44da98b954eedeac495271d0f',
      takerToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
      makerAmount: '9066063943760152484',
      takerAmount: '5000000000000000',
      fillData: [Object],
      source: 'SuiSwap',
      sourcePathId: '0x2ea41c4f046aa0e743deb854fb95d19a4c011243a12d190f8a22cf14e974c86b',
      type: 0
    }
  ],
  allowanceTarget: '0x0000000000000000000000000000000000000000',
  sellTokenToEthRate: '1',
  buyTokenToEthRate: '1813.2096453862199738'
}
[
  { name: '0x', proportion: '0' },
  { name: 'Uniswap', proportion: '0' },
  { name: 'Uniswap_V2', proportion: '0' },
  { name: 'Eth2Dai', proportion: '0' },
  { name: 'Kyber', proportion: '0' },
  { name: 'Curve', proportion: '0' },
  { name: 'Balancer', proportion: '0' },
  { name: 'Balancer_V2', proportion: '0' },
  { name: 'Bancor', proportion: '0' },
  { name: 'mStable', proportion: '0' },
  { name: 'Mooniswap', proportion: '0' },
  { name: 'Swerve', proportion: '0' },
  { name: 'SnowSwap', proportion: '0' },
  { name: 'SuiSwap', proportion: '1' },
  { name: 'Shell', proportion: '0' },
  { name: 'MultiHop', proportion: '0' },
  { name: 'DODO', proportion: '0' },
  { name: 'DODO_V2', proportion: '0' },
  { name: 'CREAM', proportion: '0' },
  { name: 'LiquidityProvider', proportion: '0' },
  { name: 'CryptoCom', proportion: '0' },
  { name: 'Linkswap', proportion: '0' },
  { name: 'Lido', proportion: '0' },
  { name: 'MakerPsm', proportion: '0' },
  { name: 'KyberDMM', proportion: '0' },
  { name: 'Smoothy', proportion: '0' },
  { name: 'Component', proportion: '0' },
  { name: 'Saddle', proportion: '0' },
  { name: 'xSigma', proportion: '0' },
  { name: 'Uniswap_V3', proportion: '0' },
  { name: 'Curve_V2', proportion: '0' },
  { name: 'ShibaSwap', proportion: '0' }
]

2. For UniSwapV3 Quote

code

Copy
UniswapV3 Quote
{
  chainId: 1,
  price: '1819.24780097598123892',
  guaranteedPrice: '1801.05532296622142652',
  to: '0xdef1c0ded9bec7f1a1670819833240f027b25eff',
  data: '0x3598d8ab0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000004e1bbb1b11f673a5e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002bc02aaa39b223fe8d0a0e5c4f27ead9083c756cc20001f46b175474e89094c44da98b954eedeac495271d0f000000000000000000000000000000000000000000869584cd00000000000000000000000010000000000000000000000000000000000000110000000000000000000000000000000000000000000000c2bfe11f3560f5b443',
  value: '50000000000000000',
  gas: '151000',
  estimatedGas: '151000',
  gasPrice: '59000000000',
  protocolFee: '0',
  minimumProtocolFee: '0',
  buyTokenAddress: '0x6b175474e89094c44da98b954eedeac495271d0f',
  sellTokenAddress: '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee',
  buyAmount: '90962390048799061946',
  sellAmount: '50000000000000000',
  sources: [
    { name: '0x', proportion: '0' },
    { name: 'Uniswap', proportion: '0' },
    { name: 'Uniswap_V2', proportion: '0' },
    { name: 'Eth2Dai', proportion: '0' },
    { name: 'Kyber', proportion: '0' },
    { name: 'Curve', proportion: '0' },
    { name: 'Balancer', proportion: '0' },
    { name: 'Balancer_V2', proportion: '0' },
    { name: 'Bancor', proportion: '0' },
    { name: 'mStable', proportion: '0' },
    { name: 'Mooniswap', proportion: '0' },
    { name: 'Swerve', proportion: '0' },
    { name: 'SnowSwap', proportion: '0' },
    { name: 'SuiSwap', proportion: '0' },
    { name: 'Shell', proportion: '0' },
    { name: 'MultiHop', proportion: '0' },
    { name: 'DODO', proportion: '0' },
    { name: 'DODO_V2', proportion: '0' },
    { name: 'CREAM', proportion: '0' },
    { name: 'LiquidityProvider', proportion: '0' },
    { name: 'CryptoCom', proportion: '0' },
    { name: 'Linkswap', proportion: '0' },
    { name: 'Lido', proportion: '0' },
    { name: 'MakerPsm', proportion: '0' },
    { name: 'KyberDMM', proportion: '0' },
    { name: 'Smoothy', proportion: '0' },
    { name: 'Component', proportion: '0' },
    { name: 'Saddle', proportion: '0' },
    { name: 'xSigma', proportion: '0' },
    { name: 'Uniswap_V3', proportion: '1' },
    { name: 'Curve_V2', proportion: '0' },
    { name: 'ShibaSwap', proportion: '0' }
  ],
  orders: [
    {
      makerToken: '0x6b175474e89094c44da98b954eedeac495271d0f',
      takerToken: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2',
      makerAmount: '90962390048799061946',
      takerAmount: '50000000000000000',
      fillData: [Object],
      source: 'Uniswap_V3',
      sourcePathId: '0xfe215f0d81d8367ed86f2044b4b354d556f564f8bcb5bfec85fa07c54f31015c',
      type: 0
    }
  ],
  allowanceTarget: '0x0000000000000000000000000000000000000000',
  sellTokenToEthRate: '1',
  buyTokenToEthRate: '1813.2096453862199738'
}
[
  { name: '0x', proportion: '0' },
  { name: 'Uniswap', proportion: '0' },
  { name: 'Uniswap_V2', proportion: '0' },
  { name: 'Eth2Dai', proportion: '0' },
  { name: 'Kyber', proportion: '0' },
  { name: 'Curve', proportion: '0' },
  { name: 'Balancer', proportion: '0' },
  { name: 'Balancer_V2', proportion: '0' },
  { name: 'Bancor', proportion: '0' },
  { name: 'mStable', proportion: '0' },
  { name: 'Mooniswap', proportion: '0' },
  { name: 'Swerve', proportion: '0' },
  { name: 'SnowSwap', proportion: '0' },
  { name: 'SuiSwap', proportion: '0' },
  { name: 'Shell', proportion: '0' },
  { name: 'MultiHop', proportion: '0' },
  { name: 'DODO', proportion: '0' },
  { name: 'DODO_V2', proportion: '0' },
  { name: 'CREAM', proportion: '0' },
  { name: 'LiquidityProvider', proportion: '0' },
  { name: 'CryptoCom', proportion: '0' },
  { name: 'Linkswap', proportion: '0' },
  { name: 'Lido', proportion: '0' },
  { name: 'MakerPsm', proportion: '0' },
  { name: 'KyberDMM', proportion: '0' },
  { name: 'Smoothy', proportion: '0' },
  { name: 'Component', proportion: '0' },
  { name: 'Saddle', proportion: '0' },
  { name: 'xSigma', proportion: '0' },
  { name: 'Uniswap_V3', proportion: '1' },
  { name: 'Curve_V2', proportion: '0' },
  { name: 'ShibaSwap', proportion: '0' }
]

Here are some things to look for:

1. price: It gives us the best price for the token pair, which doesn't involve slippage rate
2. guranteedPrice: It gives us the price for the pair in case there is a large slippage rate. API will revert the call if this price isn't met.
3. buyAmount: The amount of token we will get in Wei.
4. sellAmount: The amount of token we sold in Wei.
5. sources: It gives us the proportion in which the amount is split among different DEXs. We are getting the whole amount from a single DEXs, so we have a proportion of 1 for both cases. 

If you observe closely, you can see that you are getting higher buyAmount from SushiSwap compared UniswapV3. Now, you can swap our ETH for DAI in SushiSwap for a higher amount of DAI. It is recommended that you try out different token pairs and compare default quotes with your favorite DEX. Here is list of DEXs that you can pass in the params:
    0x
    Uniswap
    Uniswap_V2
    Eth2Dai
    Kyber
    Curve
    Balancer
    Balancer_V2
    Bancor
    mStable
    Mooniswap
    Swerve
    SnowSwap
    SushiSwap
    Shell
    MultiHop
    DODO
    DODO_V2
    CREAM
    LiquidityProvider
    CryptoCom
    Linkswap
    Lido
    MakerPsm
    KyberDMM
    Smoothy
    Component
    Saddle
    xSigma
    Uniswap_V3
    Curve_V2
    ShibaSwap

If you want to get quotes from multiple DEXs, you can specify them in the includedSources separted by commas. So, if you want to fetch from SushiSwap and UniSwapV3, you can specify it as:

code

Copy
const exchangeList = 'Uniswap_V3,SushiSwap'
  const params = {
    buyToken: 'DAI',
    sellToken: 'ETH',
    sellAmount: 0.05 * Math.pow(10, 18).toString(), // Always denominated in wei
    includedSources: exchangeList,
  }

Conclusion

We were able to get the best price quotation for a pair of tokens using 0x API. We didn't have to go through all the DEXs, compare the quote to fetch the best quote, and make a trade. Instead, we leveraged the API to fetch the best price quote. This can be a base upon which you can build an arbitrage bot. You can go through the official documentation to build your next innovative project.

Subscribe to our newsletter for more articles and guides on Ethereum. If you have any feedback, feel free to reach out to us via Twitter. You can always chat with us on our Discord community server, featuring some of the coolest developers you’ll ever meet :)

Related articles 12

How to Interact with Uniswap using Javascript
Apr 12, 2022

Uniswap is one of the most discussed and important projects in the DeFi space. It’s a pretty popular project for many reasons - in this guide, we will learn how to interact with the Uniswap smart contracts using a JavaScript library called

Continue reading
How to setup a Chainlink node
Apr 12, 2022

Smart-contracts are the heart and soul of all the development happening on the Ethereum blockchain, and as more and more people develop on Ethereum, smart contracts are becoming more complex.Sometimes a smart contract wants information about the real world, like...

Continue reading
How to Access Bitcoin Mempool
Apr 12, 2022

Bitcoin is the father of blockchain technology. With Bitcoin started a new era of blockchain and decentralization. Bitcoin enabled everyone to make the peer-to-peer transactions they enjoy today; this guide will teach you how to get these transactions from the Bitcoin...

Continue reading
How to Make a Flash Loan using Aave
Dec 27, 2021

Aave, previously known as ETHLender, has catapulted to the forefront of the DeFi space. Aave was the first in the space to come up with the idea of a Flash Loan. Before flash loans, you would have to stake an over-collateralized...

Continue reading
Cómo realizar un Préstamo Flash en Aave
Jan 10, 2022

Aave, anteriormente conocido como ETHLender, se ha catapultado hacia la delantera en el espacio DeFi. Aave fue el primero de todos en aparecer con la idea de los Prestamos Flash. Antes de los Préstamos Flash, tenías que tener...

Continue reading
How to access Ethereum Mempool
Apr 12, 2022

On Ethereum, when a transaction is sent, before being added to a block, it resides in what is called a Mempool. To receive information about this transaction, the Mempool must be queried. This guide will demonstrate how to query a node’s mempool using QuickNode Ethereum...

Continue reading
How to Listen For Newly Minted Tokens on PancakeSwap
Apr 12, 2022

Hello reader! Today we will be diving into details about making a bot that buys newly minted tokens on the PancakeSwap DEX. Today may be your first time making a trading bot or using the BSC network, and that is okay! By the time you have read through and completed this...

Continue reading
How to Swap Tokens on Uniswap with Ethers.js
Apr 12, 2022

Not all users interact via the front-end UI when trading tokens on a decentralized exchange. Some users (or entities) trade programmatically via a smart contract or server-side scripts. This guide will demonstrate how to swap tokens on Uniswap using Javascript and the...

Continue reading