How to get enriched token balances

Whether you’re building a wallet, investing from smart contracts, or building out tax-solutions, accessing high-quality financial-accounting data is critical to ensuring you’re accurately capturing both yours and your users activity and performance.
With OpenPool’s API’s you can seamlessly access comprehensive contract & wallet accounting and reporting data for all your applications

This article will walk through how you can pull in token balances and performance for a given address(es). With these requests, you will be able to see extremely detailed financial-accounting breakdowns and summaries that include fields such as cost-basis, realized, and unrealized P&L to help power what you’re building.

Before we get started

You will need an API key to start making requests, so let’s first generate one from the OpenPool Dev Portal:

  1. Visit the Dev Portal at https://dev.openpool.co/

  2. Sign up or log in to your account

Untitled
  1. Create a Project and give it a name

Untitled

Awesome! Now that we have this covered, we’ll need to register the 0x address before you can start making any API calls. We covered this in a separate article and you can find [here] or in the docs.

Retrieving Enriched Balances & Performance

The endpoints for accessing balances & performances for addresses are broken into three main asset classes:

  • Tokens
  • NFTs
  • DeFi

These requests are all straightforward GET requests that use query parameters to specify the 0x addresses, and timeframes a request should be made for.

Let’s go through each of them and start setting up requests!

Token Balances

Summary and breakdown

This endpoint returns Current Token Balance, Cost, and Performance data for one or more registered wallets, including Price, Balance, Value, Cost Basis, Realized PnL, and Unrealized PnL.

  • For multiple wallets, the total Current Token Balance and Performance data for the group of wallets queried will be returned in addition to Current Token Balance and Performance for each individual token.
  • Real-time token Prices are sourced from 4 reputable sources, ensuring completeness in pricing coverage.
  • Cost Basis is inclusive of gas fees paid in the transaction. Cost Basis methodology can be selected using the cost_method parameter
  • Realized PnL represents potential tax realization events as defined in the U.S. For Realized PnL, data is available for multiple time periods (D, W, M, 3M, YTD, 1YR, Max). The desired period is selected using the period param.

Making Requests

For this example, we’ll be using Javascript to set up and make this request

First, let’s get our request URL

const baseUrl = 'https://api.openpool.co/wallet/balance/'

Now let’s set up the request headers

  • Make sure you store your API key as an environment variable for security purposes.
const headers = {
    accept: 'application/json',
    'X-API-KEY': process.env.OPENPOOL_API_KEY
  }

Now, let’s specify the addresses and timeframes for our request

  • This process will be done through the use of query parameters appended to the request url that are defined as wallet (for addresses), and period (for timeframes)
  • Addresses used here must be hexadecimal 0x strings
  • For example, to filter by address we’d utilize an address query param like so:
const addressToSearch = '0x59a5493513ba2378ed57ae5ecfb8a027e9d80365'

const baseUrlWithAddress = `https://api.openpool.co/wallet/balance/?wallet=${addressToSearch}`
  • To look up multiple addresses, we’d just use a comma-separated string for the respective addresses:
const address1ToSearch = '0x59a5493513ba2378ed57ae5ecfb8a027e9d80365'
const address2ToSearch = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'

const stringOfCommaSeperatedAddresses = `${address1ToSearch}, ${address2ToSearch}`

const baseUrlWithAddresses = `https://api.openpool.co/wallet/balance/?wallet=`${stringOfCommaSeperatedAddresses}`
  • The default timeframe is set to One Week, and if we want to change that filter, we’d structure the request as:
const addressToSearch = '0x59a5493513ba2378ed57ae5ecfb8a027e9d80365'
const timeframe = 'YTD'

const baseUrlWithAddress = `https://api.openpool.co/wallet/balance/?wallet=${addressToSearch}&period=${timeframe}`

Now that we have all this down, let’s put together our request

  • In practice, you will likely want to use a more robust validation check here for the address
const retrieveTokenBalancesAndPerformance = async (address: string, timeframe = "W") => {
  if (!address || typeof address !== 'string' || address && typeof address === 'string' && !address.includes('0x')) {
    throw new Error('A valid address is required for making requests');
    return
  }
  try {
     let request = `https://api.openpool.co/wallet/balance/?wallet=${address}&period=${timeframe}`
     const headers = {
       accept: 'application/json',
      'X-API-KEY': '<YOUR_API_KEY>'
     }
    const requestOptions = {
      method: 'GET',
      headers: headers
    };

    const response = await fetch(url, requestOptions)
    const parsedResponse = await response.json()
    return parsedResponse
  }
  catch(e){
      console.error(`The error trying to retrieve address balances`, ${e})
  }
}

Reading from the response

When you receive a successful response, you will receive back an Object with two properties:

  • Data: An array of objects representing the enriched balance positions that has the following shape:
[
    {
      "balance": 90.8199,
      "token": {
        "id": 6178,
        "asset": {
          "id": 2,
          "name": "Ethereum",
          "symbol": "ETH",
          "slug": "ethereum",
          "image_url": "https://cdn.openpool.co/static/assets/ethereum.png"
        },
        "blockchain": {
          "id": 12,
          "name": "Ethereum",
          "slug": "ethereum",
          "image_url": "https://openpool.s3.amazonaws.com/landingImages/eth.png"
        },
        "token_id": "0x0000000000000000000000000000000000000000_12",
        "address": "0x0000000000000000000000000000000000000000",
        "decimals": 18
      },
      "price": 1807.0349999999999,
      "value": 164114.7379965,
      "pnl": {
        "total_realized": -64311.17902073,
        "unrealized": 45829.99203749998
      },
      "delta": {
        "total_realized": 0,
        "price": 1895.2301480548908,
        "pct_change": -4.653532350432865,
        "period": "M"
      }
    },
  ],
  • Summary: An object comprised of a summary view of financial accounting metrics such as its Cost-Basis, and P&L
{
    "total_fees_usd": -31560.67759719,
    "total_realized_fees": -690.37367984,
    "total_inflows": 6467174.63225595,
    "total_outflows": -6175784.37202448,
    "total_value": 227163.7824816275,
    "total_basis": 239201.29528499994,
    "total_unrealized_pnl": -14226.842011364379,
    "total_realized": -48408.06556556,
    "total_delta_realized_pnl": 0
  }

Next Steps

Look at that, we can now get enriched token balances and performance for any app or report we’d want to build. Up next we’ll move on to covering how to pull enriched DeFi balances and performance data!