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

@three-ws/intel

v0.1.1

Published

Token sentiment + market intelligence in one import. Sentiment pulse, aixbt narrative intel, momentum-ranked project scans, and live Solana token snapshots — the three.ws intelligence SDK.

Readme


@three-ws/intel is the official client for the three.ws market intelligence surface — four reads that tell you what a token is worth, what people are saying about it, and where attention is flowing. It wraps four live endpoints: a deterministic sentiment pulse over pump.fun commentary, the aixbt narrative intel feed, momentum-ranked project scans, and a real-time Solana token snapshot (price, volume, holders, metadata). The sentiment endpoint is public and key-free; the aixbt and snapshot lanes are exposed as paid MCP tools settled in USDC over x402. It pairs with @three-ws/forge — Forge makes assets, Intel reads the market they trade into.

Why

Reading a token means stitching together five providers — pump.fun comments, Jupiter price, Dexscreener volume, Solana RPC holder distribution, and a narrative source — then normalizing five different payload shapes, handling each one's rate limits, and scoring sentiment yourself. Intel does that once:

  • One import, four reads. sentiment(mint), intel(query), projects(), snapshot(mint) — each a single call returning a stable, normalized shape.
  • Real data, no fakes. Every field comes from a live source. If a provider is unreachable, the field is null so you see the gap — never a fabricated number.
  • Sentiment that's reproducible. The pulse uses a deterministic lexicon scorer, not an opaque model, so the same comments always yield the same score.
  • Narrative + momentum in one place. The aixbt bridge surfaces what's being said (intel) and what's spiking (projects) without you holding an aixbt key — it stays server-side.

This is the SDK twin of the 3D Studio MCP server — the same sentiment_pulse, aixbt_intel, aixbt_projects, and pump_snapshot tools, exposed as plain functions instead of MCP calls.

Install

npm install @three-ws/intel

Zero runtime dependencies. Works in Node 18+ and the browser (uses fetch). To auto-pay the paid lanes (aixbt + snapshot), add @three-ws/x402-fetch.

Quick start

The sentiment lane is public — no key, no wallet:

import { sentiment } from '@three-ws/intel';

const pulse = await sentiment('FeMbDoX7R1Psc4GEcvJdsbNbZA3bfztcyDCatJVJpump'); // $THREE

console.log(pulse.overall.score);   // → 0.42  (range -1 … 1)
console.log(pulse.overall.posPct);  // → 58
console.log(pulse.breakdown.pumpfun.count); // comments scored

A fuller read — narrative, momentum, and an on-chain snapshot together:

import { intel, projects, snapshot } from '@three-ws/intel';

const narrative = await intel({ chain: 'solana', limit: 10 });
const hot       = await projects({ chain: 'solana', limit: 10 });
const market    = await snapshot('THREEsynthetic1111111111111111111111111111');

console.log(narrative.intel[0].description);  // what's being said
console.log(hot.projects[0].scores.spiking);  // momentum rank
console.log(market.priceUsd, market.holders.topHolderCount);

Fold your own signals (e.g. X cashtag posts you collected) into the pulse:

const pulse = await sentiment('FeMbDoX7R1Psc4GEcvJdsbNbZA3bfztcyDCatJVJpump', {
  limit: 150,
  extraTexts: ['$THREE volume ripping today', 'best 3D agent stack on Solana'],
});
console.log(pulse.breakdown.extra.score); // score of just your snippets

API

sentiment(mint, options?) → Promise<SentimentPulse>

Real-time sentiment pulse for a Solana token. Pulls recent pump.fun comments via frontend-api-v3, optionally folds in caller-supplied snippets, and scores the combined stream with the three.ws deterministic lexicon. Wraps POST /api/social/sentiment-pulse. Public — no key required.

Options

| Option | Type | Default | Notes | |---|---|---|---| | limit | number | 100 | Max pump.fun comments to fetch + score (1–200). | | extraTexts | string[] | [] | Up to 200 extra snippets (≤2000 chars each) to score alongside. |

Returns SentimentPulse

| Field | Type | Notes | |---|---|---| | ok | true | Present on success. | | token | string | The mint you queried. | | overall | Score | Combined score over comments + extras. | | breakdown.pumpfun | Score | Just the pump.fun comments (or { error, count: 0 } if the source failed). | | breakdown.extra | Score | Just your extraTexts. | | sources | object | { pumpfun, pumpfunCount, extraCount }. | | fetchedAt | string | ISO timestamp. |

A Score is { score, posPct, negPct, neuPct, count, examples }score runs -1 … 1, the *Pct fields sum to 100, and examples carries { pos, neg } representative lines.

intel(query?) → Promise<IntelFeed>

aixbt narrative intelligence feed — recent intel items detected across crypto. Wraps GET /api/aixbt/intel. Paid via the aixbt_intel MCP tool ($0.01).

Query

| Field | Type | Default | Notes | |---|---|---|---| | limit | number | 20 | Items to return (1–100; the bridge caps the upstream call at 50). | | category | string | — | Filter to one aixbt intel category. | | chain | string | — | Filter to a chain, e.g. solana, base, ethereum. |

Returns { intel: IntelItem[], pagination }, where each IntelItem is { category, description, detected_at, reinforced_at, observations, official_source, project, ticker, source }.

projects(query?) → Promise<ProjectScan>

aixbt momentum scan — projects ranked by spiking / climbing / active scores, with market metrics and recent intel per project. Wraps GET /api/aixbt/projects. Paid via the aixbt_projects MCP tool ($0.01).

Query

| Field | Type | Default | Notes | |---|---|---|---| | limit | number | 20 | Projects to return (1–100; upstream capped at 50). | | page | number | 1 | Page of the ranked list (1–100). | | names | string | — | Comma-separated names/tickers to filter to. | | chain | string | — | Filter to a chain. |

Returns { projects: Project[], pagination }. Each Project:

| Field | Type | Notes | |---|---|---| | id / name / ticker | string | Identity. | | x_handle | string \| null | Project X handle. | | address / chain | string \| null | Primary token address + chain. | | scores | { spiking, climbing, active } | aixbt momentum scores. | | trajectory | string \| null | Spiking/climbing trajectory note. | | market | { price_usd, market_cap, volume_24h, change_24h } | Live metrics (null where unavailable). | | intel | IntelItem[] | Up to 10 recent intel items for the project. | | categories | string[] | CoinGecko categories. |

snapshot(mint) → Promise<TokenSnapshot>

Live market snapshot for any Solana SPL or pump.fun token. Generic plumbing — it takes whatever mint you pass at runtime. Wraps the pump_snapshot MCP tool. Paid ($0.005).

Returns TokenSnapshot

| Field | Type | Notes | |---|---|---| | token | string | The mint. | | priceUsd | number \| null | USD price (Jupiter, falling back to Dexscreener). | | priceSource | 'jupiter' \| 'dexscreener' \| null | Which source priced it. | | price | object | Jupiter detail: { usdPrice, priceChange24hPct, liquidityUsd, decimals, blockId }. | | volume24h | object | Dexscreener: { volume24hUsd, dex, pairAddress, url, marketCapUsd, … }. | | meta | object | pump.fun metadata: { name, symbol, imageUrl, creator, marketCapUsd, … }. | | holders | object | { topHolderCount, topHolders[] } from Solana RPC getTokenLargestAccounts. | | helius | object \| null | Supply/decimals/price from Helius DAS when HELIUS_API_KEY is set. | | image | string \| null | Token image. | | sources | object | The exact upstream URLs each field came from. | | fetchedAt | string | ISO timestamp. |

How it works

Four independent reads, each fronting a normalized aggregate. The aixbt key and all provider keys live server-side — the SDK never holds them.

  sentiment(mint) ─▶ POST /api/social/sentiment-pulse
                       └─ pump.fun frontend-api-v3 replies → lexicon scorer

  intel(query)    ─▶ GET  /api/aixbt/intel ─┐
  projects(query) ─▶ GET  /api/aixbt/projects ┴─▶ aixbt REST v2 (key server-side)

  snapshot(mint)  ─▶ pump_snapshot (x402) ─┬─ Jupiter Lite      → price
                                           ├─ Dexscreener       → volume + pair
                                           ├─ pump.fun api-v3    → name/image/mcap
                                           ├─ Solana RPC         → top holders
                                           └─ Helius DAS (opt)   → exact supply
  • Sentiment is deterministic: the same comments always produce the same score. The pulse fetches the most recent batch from pump.fun and scores positive/negative term matches — no model, no randomness.
  • Narrative + momentum ride the three.ws ⇄ aixbt bridge. aixbt wraps its reads as { status, data, pagination }; the bridge unwraps and normalizes them into the lean shapes above so an upstream change never ripples into your code.
  • Snapshot fans out to five sources in parallel and stitches the results. Price has a built-in fallback (Jupiter → Dexscreener) so the single most important field has two independent backers.

Pricing & payment

The sentiment lane is genuinely free — it relies only on public pump.fun data and an in-repo scorer. The aixbt and snapshot lanes are flat per-call prices, quoted in USDC and settled exact on Solana mainnet over x402:

| Call | Tool | Price | Lane | |---|---|---|---| | sentiment() | sentiment_pulse | free over the public endpoint¹ | pump.fun + lexicon | | intel() | aixbt_intel | $0.01 USDC | aixbt bridge | | projects() | aixbt_projects | $0.01 USDC | aixbt bridge | | snapshot() | pump_snapshot | $0.005 USDC | multi-provider |

¹ The sentiment_pulse MCP tool is priced at $0.003 USDC for agent callers; the underlying POST /api/social/sentiment-pulse HTTP endpoint this SDK targets is public and key-free. Pair with @three-ws/x402-fetch to automate the 402 settlement on the paid calls.

Errors & edge cases

Every state is designed — a missing key or an unreachable provider returns a typed state, never a crash or a fake number.

| State | HTTP | Where | Meaning & recovery | |---|---|---|---| | validation_error | 400 | sentiment | token isn't a base58 mint, or body is malformed. Fix the input. | | aixbt_not_configured | 503 | intel / projects | Deployment has no AIXBT_API_KEY. Response carries a setup hint pointing at the aixbt key pass. | | aixbt_unauthorized | 401/403 | intel / projects | aixbt rejected the key. Rotate it. | | aixbt_rate_limited | 429 | intel / projects | aixbt throttled the bridge. Back off and retry. | | aixbt_upstream_error | 502/504 | intel / projects | aixbt was unreachable or errored. Retry. | | invalid_mint | — | snapshot | token isn't a valid Solana pubkey. Fix it. | | payment_required | 402 | intel / projects / snapshot | Paid lane with no x402 payment. Attach a payer (see Pricing). | | field = null | 200 | snapshot | A provider was unreachable. The field is null and sources shows which one — partial data, never fabricated. |

In the sentiment pulse, a pump.fun failure doesn't fail the whole call: breakdown.pumpfun becomes { error, count: 0 } and the overall score reflects whatever did resolve (e.g. just your extraTexts). Branch on it in your UI.

Examples

Agent decision gate — read sentiment + momentum before acting:

import { sentiment, projects } from '@three-ws/intel';

const mint = 'FeMbDoX7R1Psc4GEcvJdsbNbZA3bfztcyDCatJVJpump'; // $THREE
const [pulse, scan] = await Promise.all([
  sentiment(mint),
  projects({ chain: 'solana', limit: 5 }),
]);

const bullish = pulse.overall.score > 0.2 && pulse.overall.count >= 20;
const trending = scan.projects.some((p) => (p.scores.spiking ?? 0) > 0.8);
if (bullish && trending) console.log('signal: attention + positive chatter');

Dashboard tile — render a live token card in the browser:

<script type="module">
  import { snapshot, sentiment } from '@three-ws/intel';

  const mint = 'THREEsynthetic1111111111111111111111111111';
  const [m, s] = await Promise.all([snapshot(mint), sentiment(mint)]);

  document.querySelector('#card').innerHTML = `
    <h3>${m.meta?.name ?? 'Token'} · ${m.meta?.symbol ?? '—'}</h3>
    <p>$${m.priceUsd ?? '—'} · vol $${m.volume24h?.volume24hUsd ?? '—'}</p>
    <p>sentiment ${Math.round(s.overall.posPct)}% positive
       (${s.overall.count} comments)</p>`;
</script>

Narrative monitor — poll the intel feed for a category:

import { intel } from '@three-ws/intel';

const feed = await intel({ category: 'partnership', limit: 15 });
for (const item of feed.intel) {
  if (item.official_source) console.log(`[${item.ticker}] ${item.description}`);
}

Related