DEV Community

Cover image for Building a Token Vibe Checker Agent with OnChainOS
Harish Kotra (he/him)
Harish Kotra (he/him)

Posted on

Building a Token Vibe Checker Agent with OnChainOS

How I built a CLI agent that runs a full background check on any crypto token and rates it 1–10 in under 200 lines of TypeScript.


The Idea

Every day, thousands of tokens launch onchain. Most are scams, rugs, or honeypots. Before you ape into any token, you need answers:

  • Has the dev rugged before?
  • Is the supply bundled/sniped?
  • Are the top 10 holders controlling too much?
  • What's the cluster concentration risk?

I wanted a single command that answers all of these — an agent you run in your terminal that gives you a clear 1–10 "vibe score" before you trade.

Why OnChainOS?

OnChainOS by OKX exposes a rich set of Market APIs that provide exactly this data:

  • Token advanced-info — risk control level, dev reputation, bundle/sniper holdings
  • Cluster overview — holder concentration, rug pull probability, new wallet percentage
  • Price info — market cap, liquidity, holders, 24h trading volume
  • Token Dev Info (pump.fun) — how many tokens this dev created vs rugged
  • Token Bundle Info — bundler detection for newly launched tokens
  • Similar tokens — other tokens by the same dev

All of this is accessible via a single REST API with HMAC-SHA256 authentication.

Architecture

┌──────────────┐     ┌──────────────────────────────────────────┐
│   index.ts   │────▶│              client.ts                   │
│  CLI entry   │     │  Promise.all (6 parallel OnChainOS API   │
│  (args/help) │     │  calls with HMAC-SHA256 auth)            │
└──────────────┘     └──────────────────┬───────────────────────┘
                                        ▼
                             ┌──────────────────────┐
                             │     scorer.ts         │
                             │  Weighted 9-metric    │
                             │  algorithm → 1-10     │
                             └──────────┬───────────┘
                                        ▼
                             ┌──────────────────────┐
                             │    display.ts         │
                             │  picocolors + bars +  │
                             │  emoji verdict        │
                             └──────────────────────┘
Enter fullscreen mode Exit fullscreen mode

The Scoring Algorithm

The score is computed from 9 weighted metrics. Each metric is scored 1–10 using thresholds derived from common DeFi security heuristics:

// Weight distribution
const METRICS = [
  { name: "Risk Level",       weight: 20, source: "riskControlLevel" },
  { name: "Dev Reputation",   weight: 20, source: "rugCount / totalTokens" },
  { name: "Bundled Supply",   weight: 10, source: "bundleHoldingPercent" },
  { name: "Sniper Holdings",  weight: 10, source: "sniperHoldingPercent" },
  { name: "Concentration",    weight: 10, source: "cluster level" },
  { name: "Rug Pull Prob",    weight: 10, source: "rugPullPercent" },
  { name: "Top 10 Holders",   weight: 10, source: "top10HoldPercent" },
  { name: "Dev Holdings",     weight: 5,  source: "devHoldingPercent" },
  { name: "New Wallet %",     weight: 5,  source: "holderNewAddressPercent" },
];
Enter fullscreen mode Exit fullscreen mode

For each metric, we define thresholds that determine the score:

// Example: Top 10 Holder % scoring
const top10Thresholds: [number, number][] = [
  [10, 10],   // ≤10% → perfect score
  [20, 8],    // ≤20% → good
  [30, 6],    // ≤30% → moderate
  [50, 4],    // ≤50% → concerning
  [70, 2],    // ≤70% → bad
];            // >70% → 0
Enter fullscreen mode Exit fullscreen mode

The final score is (weightedSum / totalWeight) * 10.

HMAC-SHA256 Authentication

The OnChainOS API uses a custom HMAC-SHA256 signing scheme. Each request needs:

export function getHeaders(auth, method, requestPath, bodyOrQuery) {
  const timestamp = new Date().toISOString().slice(0, -5) + "Z";
  const message = timestamp + method + requestPath + bodyOrQuery;
  const signature = crypto.createHmac("sha256", auth.secretKey)
    .update(message).digest("base64");

  return {
    "OK-ACCESS-KEY":    auth.apiKey,
    "OK-ACCESS-SIGN":   signature,
    "OK-ACCESS-TIMESTAMP": timestamp,
    "OK-ACCESS-PASSPHRASE": auth.passphrase,
    "OK-ACCESS-PROJECT": auth.projectId,
  };
}
Enter fullscreen mode Exit fullscreen mode

Key gotcha: the timestamp format must match the official JS example — without milliseconds (.slice(0, -5) + "Z").

Parallel API Calls

All 6 endpoint calls fire in parallel using Promise.all, making the total check take only as long as the slowest endpoint (~300-500ms):

const [priceInfo, advancedInfo, clusterInfo] = await Promise.all([
  postJson("dex/market/price-info", [...]);
  getJson("dex/market/token/advanced-info", {...});
  getJson("dex/market/token/cluster/overview", {...});
]);
Enter fullscreen mode Exit fullscreen mode

For meme-token chains (Solana, BSC), we additionally query memepump-specific endpoints for dev reputation and bundle detection.

CLI Output

The display module uses picocolors (a 2KB zero-dep alternative to chalk) for color-coded output:

  • 🟢 Green (score ≥ 8) — "Solid vibes"
  • 🟡 Yellow (score ≥ 6) — "Decent, some caution"
  • 🟠 Orange (score ≥ 4) — "Risky"
  • 🔴 Red (score < 4) — "High risk"

Each metric gets a visual bar:

Risk Level:       LOW     ████████░░  8/10
Top 10 Holders:   9.59%   ██████████ 10/10
Enter fullscreen mode Exit fullscreen mode

What I Learned

  1. Parallelism mattersPromise.all over 6 endpoints cut response time from ~1.5s to ~400ms
  2. HMAC gotchas — timestamp format discrepancies between the docs examples caused auth failures. Stick with the code examples, not the prose.
  3. Not all endpoints work everywhere — memepump endpoints only work on Solana/BSC/TRON. Handle gracefully.
  4. TypeScript pays off — 10+ API response interfaces caught 3 field name typos before runtime
  5. Picocolors > Chalk — for CLI tools, 2KB vs 20KB makes a real difference

Ideas to Extend

  • WebSocket mode — subscribe to the OnChainOS signal channel for real-time alerts on new tokens, then auto-score them
  • Auto-trade agent — combine the vibe checker with the OnChainOS DEX Swap API: score ≥ 7? Execute a buy
  • Telegram bot — wrap the CLI in a bot for on-the-go token research
  • Dashboard — log scores to SQLite and build a Svelte dashboard showing trends over time

Try It Yourself

git clone https://github.com/harishkotra/token-vibe.git
cd token-vibe
npm install
cp .env.example .env
# Fill in your OKX API keys
npx tsx src/index.ts -t 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 -c 1
Enter fullscreen mode Exit fullscreen mode

Get your free API keys at OKX Developer Portal.

Code and more: https://www.dailybuild.xyz/project/165-token-vibe

Top comments (0)