How to get enriched DeFi balances

Whether you’re a 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 DeFi 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
  2. Sign up or log in to your account
  1. Create a Project and give it a name


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

These requests are all straightforward GET requests that utilize query parameters to specify the given addresses and timeframes a request should be made for.

Now that we have that covered, let’s go through each of them and start setting up requests!

DeFi Balances

This endpoint returns the DeFi Protocol name, Liquidity Pool/DeFi Strategy Name, Token Balance staked/lent/used in DeFi activities, and DeFi Position (like LP tokens received). It also returns any Income Accrual earned over the 24-hour period immediately preceding the query.

  • The DeFi Strategy object taxonomy is as follows:
  • Strategy Name
  • Strategy Activity (Staking, Borrowing, etc)
  • Position Type is the type of position within the DeFi strategy:
  • Supplied (farming position)
  • Claimable (reward)
  • LP token (liquid staking token)
  • Income Accrual/Rewards is shown in the native token and is always for the last 24 hour period.
  • You may submit one or more wallet addresses in this query. For multiple wallet addresses, the response will return the DeFi data points outlined above by protocol and then by DeFi Strategy.
  • OpenPool currently supports 22 DeFi protocols including:
  1. Aave v2
  2. Abracadabra
  3. Apecoin
  4. Aura Finance
  5. Balancer v1
  6. Balancer v2
  7. Bancor v3
  8. Convex
  9. Curve
  10. Hop V1
  11. Lido
  12. LooksRare
  13. Maple
  14. Sushiswap Bentobox
  15. Sushiswap Kashi
  16. Stargate
  17. Synapse
  18. Synthetix
  19. Uniswap v2
  20. Uniswap v3
  21. Verse
  22. Yearn

Need a different protocol? Let us know at

These requests are all straightforward GET requests that utilize query parameters to specify the given addresses and timeframes a request should be made for.

Now that we have that covered, let’s go through each of them and start setting up requests!

Making Requests

For this example, we’ll be utilizing Javascript to set up and make this request. This process will follow the same steps we took before for getting the token balances

First let’s get our request url

const baseUrl = ''

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

Let’s now specify the addresses and timeframes for a given 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 = `${addressToSearch}`
  • To lookup 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 = ``${stringOfCommaSeperatedAddresses}`
  • The default timeframe is set to be 1 Week, and if we want to change that filter, we’d structure the request as:
const addressToSearch = '0x59a5493513ba2378ed57ae5ecfb8a027e9d80365'
const timeframe = 'YTD'
const baseUrlWithAddress = `${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 retrieveDeFiBalancesAndPerformance = 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');
  try {
     let request = `${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
      console.error(`The error trying to retrieve NFT 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 protocol positions and metadata that has the following shape:
      "protocol": "looks-rare",
      "balance": 4491.9811,
      "token": {
        "id": 663,
        "asset": {
          "id": 241,
          "name": "LooksRare",
          "symbol": "LOOKS",
          "slug": "looksrare",
          "image_url": ""
        "blockchain": {
          "id": 12,
          "name": "Ethereum",
          "slug": "ethereum",
          "image_url": ""
        "token_id": "0xf4d2888d29d722226fafa5d9b24f9164c092421e_12",
        "address": "0xf4d2888d29d722226fafa5d9b24f9164c092421e",
        "decimals": 18
      "strategy": {
        "name": "LOOKS",
        "type": "Staking",
        "protocol": {
          "id": 17,
          "name": "Looks Rare",
          "slug": "looks-rare",
          "image_url": ""
      "delta": {
        "period": "M",
        "price": 0.115582,
        "pct_change": -16.506058182927774
      "accrual": {
        "balance": 0,
        "accrual": null,
        "pct_change": null,
        "value_change": null,
        "period": "D"
      "price": 0.09650396783100842,
      "value": 433.49399957189786
  • Summary: An object comprised of a summary view of the staked balances and its 24-hour accrual
    "total_value": 4432.507080029978,
    "total_24h_accrual": 0

Next Steps

Now we can retrieve detailed financial-accounting protocol balances and performance values! Next up we’ll cover how to pull enriched NFT balances and performance data.