Step-By-Step: Fetching DeFi Token Prices

Getting real-time token price data for your Web3 / DeFi project is a cinch with the Portals API.

June 11, 2024

Accurate and real-time token prices are essential for developers building DeFi applications or managing portfolios. The Portals API provides a powerful solution to access this data easily and efficiently, with a breadth of assets surpassing DefiLlama & CoinGecko.

In this post, we'll demonstrate how to use the Portals API to fetch token prices with Axios & TypeScript.

What is the Portals API?

Imagine a user-friendly DeFi API with straightforward endpoints delivering comprehensive data, with which a single query can fetch balances across all networks, or returns every single asset associated with a DeFi platform. That's the Portals API. In a single integration, the API allows you to inject your app with coverage of thousands of tokens & DeFi assets across 9 EVMs & hundreds of protocols from Aave to Yearn and everything in between.  

And the best part? Most devs can start building with Portals API in under 30 minutes!
Let's get started.

Setting Up Your Environment

First, let's set up a TypeScript project. If you don't have TypeScript installed, you can do so by running:

[js]

npm install -g typescript

[/js]


Next, create a new directory for your project and initialize a new Node.js project:

[sh]

mkdir defi-token-prices
cd defi-token-prices
npm init -y

[/sh]


Now, install Axios and TypeScript:

[sh]

npm install axios
npm install --save-dev typescript @types/node @types/axios

[/sh]


Create a tsconfig.json file in the root directory to configure Typescript:

[js]

{
 "compilerOptions": {
   "target": "ES6",
   "module": "commonjs",
   "strict": true,
   "esModuleInterop": true,
   "skipLibCheck": true,
   "forceConsistentCasingInFileNames": true},
 "include": ["src"]
}

[/js]


Passing the API Key

The Portals API requires authentication via an API key for the data endpoints, which must be included in the request headers. Here’s how you can pass the API key using Axios.

- First, obtain your API key from the Portals API dashboard.
- Then, update your TypeScript script to include the API key in the headers.

If you don’t have an API key yet, you can get one from here: https://build.portals.fi/dashboard

Storing the API Key in an Environment Variable

It's a good practice to store sensitive information like API keys in environment variables instead of hardcoding them in your source code. This makes your application more secure and easier to manage. Here's how:

Install dotenv package

  1. Install the dotenv package to help load environment variables from a .env file into process.env.
  2. npm install dotenv

Create a .env file

  1. Create a .env file in the root of your project and add your API key:
  2. PORTALS_API_KEY=your_api_key_here


Load the environment variable in your script

  1. Update your TypeScript script to load the API key from the environment variable.


Example cURL Request

Here's an example cURL request for reference:

[sh]

curl --location --request GET '<https://api.portals.fi/v2/tokens?search=eth&platforms=native&networks=ethereum>' --header 'Authorization: [YOUR_API_KEY]'

[/sh]


Writing the TypeScript Script

Step 1: Set Up Axios and Define Interfaces

Create a file named fetchTokenPrices.ts and start by importing Axios and defining your interfaces:

[ts]

import axios from 'axios';
import * as dotenv from "dotenv";

dotenv.config(); // Load environment variables
const BASE_URL = 'https://api.portals.fi/v2/tokens'; // Define the base URL for the Portals API

// Define an interface for the token price response
interface TokenPrice {
 key: string;
 name: string;
 decimals: number;
 symbol: string;
 price: number;
 address: string;
 platform: string;
 network: string;
 liquidity: number;
 image: string;
 totalSupply: string;
 addresses: Record<string, string>;
}

[/ts]


Step 2: Configure Axios with the API Key

Next, configure Axios to include the API key in the headers:

[js]

// Retrieve the API key from environment variables
const API_KEY = process.env.PORTALS_API_KEY;

// Configure Axios with the API key
const axiosInstance = axios.create({
 headers: {
   'Authorization': API_KEY,
 },
});

[/js]


Step 3: Fetch Token Prices

Now we can write functions to fetch the price of multiple tokens at the same time.


Function to Fetch Multiple Token Prices

[ts]

// Function to fetch prices for multiple tokens
const fetchMultipleTokenPrices = async (tokenIds: string[]): Promise<TokenPrice[]> => {
 try {
   const response = await axiosInstance.get(BASE_URL, {
     params: {
       sortBy: 'liquidity',
       sortDirection: 'desc',
       limit: 250,
       ids: tokenIds.join(',')
     }
   });
   return response.data.tokens.map((tokenData: any) => ({
     key: tokenData.key,
     name: tokenData.name,
     decimals: tokenData.decimals,
     symbol: tokenData.symbol,
     price: tokenData.price,
     address: tokenData.address,
     platform: tokenData.platform,
     network: tokenData.network,
     liquidity: tokenData.liquidity,
     image: tokenData.image,
     totalSupply: tokenData.totalSupply,
     addresses: tokenData.addresses,
   }));
 } catch (error) {
   console.error(`Error fetching token prices: ${error}`);
   return [];
 }
};

[/ts]


Step 4: Example Usage

Finally, let's create an example usage to fetch prices for your selection of tokens:

[ts]

// Example usage
const main = async () => {
 const tokenIds = [
   'ethereum:0x6b175474e89094c44da98b954eedeac495271d0f', // DAI on Ethereum
   'ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC on Ethereum
   'bsc:0xe9e7cea3dedca5984780bafc599bd69add087d56', // BUSD on BSC
 ];

 const tokenPrices = await fetchMultipleTokenPrices(tokenIds);
 console.log('Token Prices:', tokenPrices);
};

main();

[/ts]


Running the Script

To run the script, compile it to JavaScript using TypeScript and then execute it with Node.js:

[sh]

tsc
node dist/fetchTokenPrices.js

[/sh]


You should see an output with the prices of the specified tokens.
If not, re-read the instructions carefully.

Full Code

Here's the complete code for reference:

[ts]

import axios from 'axios';
import * as dotenv from "dotenv";

dotenv.config(); // Load environment variables

// Define the base URL for the Portals API
const BASE_URL = '<https://api.portals.fi/v2/tokens>';

// Define an interface for the token price response
interface TokenPrice {
 key: string;
 name: string;
 decimals: number;
 symbol: string;
 price: number;
 address: string;
 platform: string;
 network: string;
 liquidity: number;
 image: string;
 totalSupply: string;
 addresses: Record<string, string>;
}

// Retrieve the API key from environment variables
const API_KEY = process.env.PORTALS_API_KEY;

// Configure Axios with the API key
const axiosInstance = axios.create({
 headers: {
   'Authorization': API_KEY,
 },
});

// Function to fetch prices for multiple tokens
const fetchMultipleTokenPrices = async (tokenIds: string[]): Promise<TokenPrice[]> => {
 try {
   const response = await axiosInstance.get(BASE_URL, {
     params: {
       sortBy: 'liquidity',
       sortDirection: 'desc',
       limit: 250,
       ids: tokenIds.join(',')
     }
   });
   return response.data.tokens.map((tokenData: any) => ({
     key: tokenData.key,
     name: tokenData.name,
     decimals: tokenData.decimals,
     symbol: tokenData.symbol,
     price: tokenData.price,
     address: tokenData.address,
     platform: tokenData.platform,
     network: tokenData.network,
     liquidity: tokenData.liquidity,
     image: tokenData.image,
     totalSupply: tokenData.totalSupply,
     addresses: tokenData.addresses,
   }));
 } catch (error) {
   console.error(`Error fetching token prices: ${error}`);
   return [];
 }
};

// Example usage
const main = async () => {
 const tokenIds = [
   'ethereum:0x6b175474e89094c44da98b954eedeac495271d0f', // DAI on Ethereum
   'ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48', // USDC on Ethereum
   'bsc:0xe9e7cea3dedca5984780bafc599bd69add087d56', // BUSD on BSC
 ];

 const tokenPrices = await fetchMultipleTokenPrices(tokenIds);
 console.log('Token Prices:', tokenPrices);
};

main();

[/ts]


Congratulations!

Fetching real-time data of your DeFi tokens of choice is made as straightforward as possible using the Portals API, Axios & TypeScript. This approach ensures type safety and makes it easy to handle asynchronous operations.

Still having trouble? Join like-minded developers and API users on our official Discord: https://discord.gg/JKDYTXN8hm

Of course, it doesn't stop there; leveraging the Portals API, you can access a wealth of DeFi data and integrate it into your applications seamlessly. We'll be releasing further Step By Step walkthroughs regularly, ensuring the DeFi dev community can rely on Portals for their data and Swap/Zap functionalities while prioritizing their own innovations.

Stay tuned for more tutorials on how to leverage the power of DeFi with the Portals API!