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

@meteorwallet/token-data-shared

v0.7.0

Published

Shared interfaces that every Meteor Wallet token data service implements and every consumer reads

Readme

@meteorwallet/token-data-shared

The shared contract for Meteor Wallet token data services: the token data types every service returns, the interfaces every service implements, the HTTP paths and response envelope every service serves — and the HTTP client the wallets call them with.

No runtime dependencies. Runs anywhere modern JavaScript does (browser, React Native, Workers).

Installation

bun add @meteorwallet/token-data-shared

Calling a service

import {
  createTokenDataHttpClient,
  ETokenCategory,
  ETokenListSort,
  ETokenSignalType,
} from "@meteorwallet/token-data-shared";

const tokenData = createTokenDataHttpClient({ baseUrl: "https://tokens.meteorwallet.app" });
const NEAR = { blockchainId: "near", genericNetworkId: "mainnet" } as const;

const trending = await tokenData.listTokens({ ...NEAR, limit: 5 });
// The Top 100's "Meme Coins": that type's slice of Trending (its top 100, in Trending order).
const memes = await tokenData.listTokens({ ...NEAR, limit: 100, category: ETokenCategory.meme });
const gainers = await tokenData.listTokens({ ...NEAR, sort: ETokenListSort.price_change_24h });
const results = await tokenData.listTokens({ ...NEAR, query: "ninu", category: ETokenCategory.meme });
const token = await tokenData.getToken({ ...NEAR, tokenId: "ninu-4.nearlytrade.near" }); // or null
// What the service knows about each of a user's holdings — tracked, blocked, or unknown.
const holdings = await tokenData.getTokens({ ...NEAR, tokenIds: ["wrap.near", "scam.near"] });
// Or let it find them: every token an account holds, with its balance, status and metadata.
const wallet = await tokenData.getAccountTokens({ ...NEAR, accountId: "alice.near" });
const overview = await tokenData.getNetworkOverview(NEAR); // "Total 24H DEX volume on NEAR"

for (const item of trending.items) {
  const tag = item.signals[0]; // the most prominent reason it stands out, if any
  if (tag?.type === ETokenSignalType.new_listing) {
    // "NEW" — tag.value is the pair's age in hours
  }
}
  • Every method accepts { signal } as a second argument (react-query passes one).
  • A service error rejects with a TokenDataError carrying its code (ETokenDataErrorCode); network failures and timeouts reject with upstream_unavailable. getToken resolves null for an unknown token.
  • fetch defaults to the global one; pass your own in environments that need it.
  • listTokens and getNetworkOverview return updatedAt and stale: show "updated N min ago", and de-emphasize figures when stale is true.
  • category narrows any list — the default Trending order, a sort, or a search — to one type; leave it out for everything. Unclassified tokens (category: null) only appear without it.
  • getTokens answers every ID asked about, in order, with a status: tracked (and the token's record in token), blocked (Meteor blocked it: nothing else is said), or unknown (the service knows nothing about it — no lookup is made). The HTTP API takes TOKEN_DATA_MAX_BATCH_SIZE (100) IDs per request; the client splits longer lists and answers them as one. Treat a status you don't recognise like unknown.
  • getAccountTokens finds an account's holdings itself (a chain indexer), and answers each like getTokens, plus its balance (the indexer's, seconds behind the chain; null when it has none on record) and its metadata — for an unknown token, the contract's own, read and cached by the service, null until it has been (a later call fills it). At most 1,000 tokens, tracked ones first. Most of an account's unknown tokens are airdrops nobody chose: listing a holding is the wallet's call — the tracked ones, the ones the user bought, the ones a whitelist knows.

Conventions

  • Decimals are strings. Prices, USD amounts and percentages are TDecimalString ("0.000001234"), never exponent notation. Meme token prices sit far below float precision — parse with a decimal library such as big.js, never Number(), for anything a user sees.
  • Raw amounts are strings in the token's smallest unit (TRawAmountString).
  • Timestamps are Unix epoch milliseconds (TTimestampMs).
  • Missing data is null, never a guess. Every market figure is nullable; a service fills what its sources provide.
  • Networks are { blockchainId, genericNetworkId } — structurally compatible with IBlockchainNetworkTarget from @meteorwallet/core-sdk, so an existing target passes straight in.

Token fields worth knowing

| Field | Meaning | | --- | --- | | trendingRank | Position in the service's Trending order — the team's pinned tokens hold the first places — or null (major token, or too little liquidity, unless pinned). | | signals | Why the token stands out (featured, new_listing, price_surge, top_volume, high_activity), most prominent first, each with the figure behind it. Ignore types you don't know. | | riskFlags | Warn before trading: price_warning (Meteor doubts its price — even a real token's: warn before a purchase), symbol_collision (its symbol belongs to another token — a major's, or one Meteor has marked as the original), duplicate_symbol (another token uses the same symbol with more liquidity), low_liquidity. | | isCanonical | Meteor has settled this as a real token for its symbol (a major, or the team's pick): copies of it are flagged. A symbol can have several (USDC and USDC.e; ETH's two contracts). NEAR itself, asked about as near, is too. | | canonicalToken | With symbol_collision: the original the symbol belongs to — the first, when it has several — when the service knows it: ID, name, symbol, icon. Send the user there ("View the official PEPE"); it passes straight to getToken. null otherwise. | | primaryPair | The pair the market figures come from: "HOOT / wNEAR", createdAt ("Listed 12h ago" — the pair's age, not the token's), url ("View on DexScreener"). | | launchpad | The launch platform, from the contract ID. | | category | meme or project (a project or ecosystem token) — the "Meme Coins" / "Eco Coins" switch. null until the service has classified the token: list it under "All" only. Treat a value you don't recognise like null. | | market.txns24h | Buys and sells. traders24h has no source yet and is always null. |

Untrusted metadata

Every string in metadata — name, symbol, description, links — was written by whoever deployed the token. Services cap lengths and strip control characters, but render them as plain text, never as HTML, and open links as external links. metadata.icon is an https image URL on a third-party host, or null (never a data URI); fall back to your own icon source by contract ID.

Implementing a service

import type { ITokenDataService, ITokenNetworkTarget } from "@meteorwallet/token-data-shared";

export class MyTokenDataService implements ITokenDataService {
  readonly supportedNetworks: readonly ITokenNetworkTarget[] = [
    { blockchainId: "near", genericNetworkId: "mainnet" },
  ];
  // listTokens, getToken, getTokenPriceHistory, getNetworkOverview — resolve `null` for an
  // unknown token, throw a TokenDataError for anything else.
}