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

@earnforge/sdk

v1.1.0

Published

Typed SDK for the LI.FI Earn API — vault discovery, risk scoring, yield strategies, and deposit quoting, with every documented and undocumented API quirk handled by default

Readme

@earnforge/sdk

Typed SDK for the LI.FI Earn API — vault discovery, risk scoring, yield strategies, and deposit/withdrawal quoting.

npm i @earnforge/sdk

Quick start

The Earn Data API requires an API key as of April 2026. Create one at portal.li.fi.

import { createEarnForge, riskScore, isFlagged } from '@earnforge/sdk'

const forge = createEarnForge({ apiKey: process.env.LIFI_API_KEY })

for await (const vault of forge.vaults.listAll({ chainId: 8453 })) {
  if (isFlagged(vault)) continue // LI.FI flagged ~10% of vaults as suspect
  const risk = riskScore(vault)
  console.log(vault.name, vault.analytics.apy.total, risk.label, risk.flags)
}

Auto-pagination, rate limiting, retry, caching, and every quirk below are handled for you.

Why this exists

The Earn API has a number of behaviours that are easy to get wrong, several of which contradict LI.FI's own documentation. Verified against 703 live vaults (9 Aug 2026):

| Behaviour | What bites you | |---|---| | APY is a percentage (4.63 = 4.63%) | The OpenAPI spec, quickstart and schema docs all say decimal. Following the quickstart's * 100 overstates every APY 100×. | | tvl.usd is a number | It used to be a string, and the spec still says string. parseTvl() accepts either. | | Auth is mandatory | earn.li.fi hard-401s, while LI.FI's API reference still says no key is required. That's true only for li.quest. | | Protocol ids are unversioned | ?protocol=morpho-v1 returns 200 with zero results — a stale slug fails silently. | | nextCursor is absent on the last page | Not null, not empty. A nullable-only schema rejects the final page. | | apy.reward is three-valued | null / 0 / positive, and the split varies within a protocol. Collapsing null to 0 loses real signal. | | Unknown query params are ignored | Sending minTvl instead of minTvlUsd returns the whole fleet, silently unfiltered. | | verificationStatus is undocumented | Present on every vault, flags ~10% of the fleet. In no spec or changelog. | | caps, timeLock, kyc, lpTokens | Documented in the OpenAPI spec; sent by zero vaults. |

What's in it

DiscoverylistVaults, listAllVaults (async iterator), getVault, getVaultBySlug, listChains, listProtocols, getPortfolio.

Risk scoring — a composite 0–10 score across seven dimensions: TVL, APY stability, protocol maturity, redeemability, asset type, LI.FI's verificationStatus, and reward dependency. Returns a flags[] array of human-readable concerns. Calibrated so no flagged vault can score ≥ 8, which means none can be labelled low risk.

const { score, label, breakdown, flags } = riskScore(vault)
// score: 4.5, label: 'high'
// flags: ['flagged by LI.FI verification: zero_apy', 'withdrawals unavailable']

Strategy presetsconservative, max-apy, diversified, risk-adjusted. All exclude verification-flagged vaults; conservative also excludes il-risk tags.

Portfolio allocationsuggest() produces a risk-adjusted allocation with chain-diversification limits. Flagged vaults are excluded unless you pass includeFlagged: true.

ExecutionbuildDepositQuote, buildRedeemQuote, checkAllowance, buildApprovalTx, preflight, optimizeGasRoutes.

EnrichmentgetApyHistory matches vaults to DeFiLlama pools by project + chain + underlying token + TVL proximity, covering ~97% of the fleet.

Drift detectiondetectDrift() compares three sources: the live API, the published OpenAPI spec, and our schema. It reports which pair disagrees, so a LI.FI documentation bug is distinguishable from our own.

const report = await detectDrift()
console.log(formatDriftReport(report))

Notes

  • ESM-first with a CJS build. "type": "module".
  • Zod schemas are generated from real API responses, never from documentation — see the table above for why.
  • Rate limiting defaults to 100 req/min. LI.FI enforces this as RPM × 120 over a two-hour rolling window.

License

Apache-2.0