âŦ‡ī¸Fetchers

The main goal of a Fetcher is to send back a list of PortfolioElement which represent any type of position of a user.

The Fetcher receive an address, scan the blockchain and send back all positions hold by this address.

A Fetcher is entitled to one specific network/chain.

When do you need to use a Fetcher ?

Some protocols do not need any fetcher, an AMM with classic pools for instance might only need a Job which will fetch the price of each LP and store it in the cache.

We recommend checking other examples of Fetcher to understand how they should be used.

Here is a non-exhaustive of data type they could retrieve :

  • Get all Concentrated Liquidity Positions of a user from an AMM

  • Get all deposits and loans of a user on a Lending protocol

  • Get all listed NFTs for a user on a marketplace

  • Get all locked/staked assets in a protocol

How to create a Fetcher

To create a job you have to run the following command :

npx nx generate @sonarwatch/portfolio-plugins:fetcher --fetcherName=myFetcherName --pluginId=myPluginName

The terminal will ask you to enter a network, this is not definitive as you can change it afterwards if needed but here are the available networks :

  • solana

  • ethereum

  • polygon

  • sui

  • aptos

  • sei

  • bitcoin

You should now see a new file called <myJobName>Fetcher.ts in your plugin folder.

Once a Fetcher is created, to be able to test it you need to add it inside your index.ts file like this :

import myFetcher from './<myFetcherName>Fetcher.ts';

export const fetchers: Fetcher[] = [myFetcher];

Remember : in order to test your fetchers, you have to also import your fetchers inside the main index.ts file, more info here

How to run a fetcher

Once you've implemented the logic of your fetcher, you can run it with the following command :

npx nx run plugins:run-fetcher myPluginName-myFetcher <address>

If your fetcher is retrieving data from the Cache, make sure to run your local Cache first, as explained here

You always need to provide an address to a fetcher.

For any address starting with "0x", your terminal might think you're providing a number.

To avoid this, use \" before and after your address inside a bash terminal, like this :

npx nx run plugins:run-fetcher myPluginName-myFetcher \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\"

A Fetcher should always return an array (empty or not), if your fetcher works you will see something like this being returned in your terminal :

[
  {
    type: 'borrowlend',
    networkId: 'solana',
    platformId: 'solend',
    label: 'Lending',
    value: 0.06856082072779543,
    name: 'Kamino USDH',
    data: {
      borrowedAssets: [],
      borrowedValue: 0,
      borrowedYields: [],
      suppliedAssets: [
        {
          type: 'token',
          networkId: 'solana',
          value: 0.06856082072779543,
          data: {
            address: 'USDH1SM1ojwWUga67PGrgFWUHibbjqMvuMaDkRJTgkX',
            amount: 0.06913401081143303,
            price: 0.991709
          }
        }
      ],
      suppliedValue: 0.06856082072779543,
      suppliedYields: [ [ { apr: 0, apy: 0 } ] ],
      collateralRatio: -1,
      healthRatio: NaN,
      rewardAssets: [],
      value: 0.06856082072779543
    }
  },
  {
    type: 'borrowlend',
    networkId: 'solana',
    platformId: 'solend',
    label: 'Lending',
    value: 0.13373722446687017,
    name: 'Cropper',
    data: {
      borrowedAssets: [],
      borrowedValue: 0,
      borrowedYields: [],
      suppliedAssets: [
        {
          type: 'token',
          networkId: 'solana',
          value: 0.13373722446687017,
          data: {
            address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
            amount: 0.13360362084602417,
            price: 1.001
          }
        }
      ],
      suppliedValue: 0.13373722446687017,
      suppliedYields: [ [ { apr: 0.12323409534345742, apy: 0.1311256602561086 } ] ],
      collateralRatio: -1,
      healthRatio: 1,
      rewardAssets: [],
      value: 0.13373722446687017
    }
  }
]

Now that you know everything about Plugins, Jobs and Fetchers, let's dive into some useful functions that could be of great help during the integration

Last updated