npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

0xppl-solana-portfolio

v1.0.0

Published

[![Core NPM Version](https://img.shields.io/npm/v/@sonarwatch/portfolio-core?color=33cd56&label=npm%20core)](https://www.npmjs.com/package/@sonarwatch/portfolio-core) [![Plugins NPM Version](https://img.shields.io/npm/v/@sonarwatch/portfolio-plugins?color

Readme

SonarWatch Portfolio

Core NPM Version Plugins NPM Version

Useful links:

This repository powers SonarWatch website by fetching all DeFi assets for a wallet on multiple chains, it covers:

  • Tokens value
  • NFTs (listed included)
  • LP Tokens value
  • Lending and borrowing amount
  • Spot accounts
  • Native stake accounts
  • many other to come!

How does it works?

Anyone can contribute to this repository to help us cover more protocols and create a better coverage for the user.

This repository is divided in plugins, each plugin can have :

  • Job(s) : they retrieve common data for all users and store it in the Cache
  • Fetcher(s) : they retrieve information for a single user and send back a list of assets

What is a Job ?

A Job will store data into our Cache, those data are usually common data for all users (information about the amounts of a tokens on a lending protocol, liquidity pools prices, etc..)

To add data to the Cache, you will mainly use the following methods on the cache object :

  • Add a price for a specific Token address (token, lp, etc...) : cache.setTokenPriceSource()
  • Add any item : cache.setItem()

Warning If your Job is adding prices for tokens, make sure to verify those prices by :

  1. Running your local cache.
  2. Running your Job, this will add prices into your local cache.
  3. Running the Fetcher wallet-tokens-<networkId>, this will fetch all tokens within the wallet and get the prices from the Cache (local + distant). (see below for commands)

You can create as many Jobs as needed by plugins.

What is a Fetcher ?

A Fetcher is were the logic stand, it usually (not necessarily) recover some data from the Cache, then use it to compute the value of the assets deposited by a user on a protocol.

Some examples of Fetchers :

  • 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
  • etc...

You can create as many Fetchers as needed by plugins, each Fetcher being entitled to a Networkd (Solana, Sui, Aptos etc..).

You always need to provide a user address to run a fetcher.

How to start ?

Setup your environment

  1. Clone this repository.
  2. Run
npm install
  1. Setup your own .env file by running :
cp .env.example .env
  1. If you need a new plugin, run :
npx nx generate @sonarwatch/portfolio-plugins:plugin my-super-protocol
  1. Depending on what you're trying to achieve, either create a Job or a Fetcher (see commands below)

Import your fetchers and jobs

Once you're down writing the logic on your Job or Fetcher :

  1. Add your Job(s) and Fetcher(s) to your index.ts file in your plugin folder
  2. Add your Fetchers and Jobs to the packages\plugins\src\index.ts file

Test your job/fetcher

Before anything, you need to run the Cache on your local network, simply run :

npx nx run plugins:serve-cache

If you are adding a liquidity protocol You're now ready to try your Fetcher or Job by running the following commands :

  • Job :
npx nx run plugins:run-job jobId

Example :

# Run the job mango-banks
npx nx run plugins:run-job mango-banks
  • Fetcher (remember to provide an address):
npx nx run plugins:run-fetcher fetcherId userAddress

Example :

# Run the fetcher mango-collateral on the address Demo...tKG
npx nx run plugins:run-fetcher mango-collateral DemoSX9F2zXfQLtBr56Yr5he15P7viZWsYJpSDAX3tKG

Missing a token price ?

If you need the price of a token but don't find it in the Cache, please submit a PR to our token list repository

Useful commands

Here is a list of useful command that can help you during your integration.

# Getting started
npm install
cp .env.example .env
# Set your RPCs

# Generate a plugin
npx nx generate @sonarwatch/portfolio-plugins:plugin my-super-protocol

# Generator a job
npx nx generate @sonarwatch/portfolio-plugins:job --jobName=myJob --pluginId=my-super-protocol

# Generator a fetcher
npx nx generate @sonarwatch/portfolio-plugins:fetcher --fetcherName=myFetcher --pluginId=my-super-protocol

# Serve cache in background
npx nx run plugins:serve-cache

# Run a job
npx nx run plugins:run-job mango-banks
npx nx run plugins:run-job wallet-tokens-aptos

# Run a fetcher
npx nx run plugins:run-fetcher mango-collateral DemoSX9F2zXfQLtBr56Yr5he15P7viZWsYJpSDAX3tKG
npx nx run plugins:run-fetcher marinade-tickets DemoSX9F2zXfQLtBr56Yr5he15P7viZWsYJpSDAX3tKG
npx nx run plugins:run-fetcher wallet-tokens-aptos \"0xaa3fca2b46efb0c9b63e9c92ee31a28b9f22ca52a36967151416706f2ca138c6\"
npx nx run plugins:run-fetcher wallet-tokens-aptos aa3fca2b46efb0c9b63e9c92ee31a28b9f22ca52a36967151416706f2ca138c6
npx nx run plugins:run-fetcher wallet-tokens-ethereum-top \"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\"
npx nx run plugins:run-fetcher wallet-tokens-ethereum-top d8dA6BF26964aF9D7eEd9e03E53415D37aA96045

# Run a airdrop fetcher
npx nx run plugins:run-airdrop-fetcher drift-airdrop-1 DemoSX9F2zXfQLtBr56Yr5he15P7viZWsYJpSDAX3tKG

Build

npx nx run core:build
npx nx run plugins:build

Deploy

npx nx run core:version --releaseAs=patch
npx nx run plugins:version --releaseAs=patch

npx nx run core:version --releaseAs=minor
npx nx run plugins:version --releaseAs=minor

npm run nx:version