Skip to content

Bug: Hyperliquid SPOT API: @notation pairs have misleading/opaque naming #101

@PrathmeshRanjan

Description

@PrathmeshRanjan

Hyperliquid SPOT API: @Notation pairs have misleading/opaque naming

The Hyperliquid SPOT API returns pair names using @number notation (e.g., @145, @156, @161), but these names don't match the actual underlying token pairs. This makes it difficult to:

  1. Identify which pairs these represent
  2. Match SPOT pairs between database storage and API responses
  3. Understand what assets are actually being traded

Code to Reproduce

import { Hyperliquid } from '@nktkas/hyperliquid';

const client = new Hyperliquid();

async function investigateSpotPairs() {
  const [spotMeta, spotAssetCtxs] = await client.infoClient.spotMetaAndAssetCtxs();
  
  console.log(`Total SPOT pairs: ${spotMeta.universe.length}`);
  console.log(`Total tokens: ${spotMeta.tokens.length}\n`);
  
  // Show top pairs by volume with actual token names
  const topPairs = spotMeta.universe
    .map((p, idx) => {
      const assetCtx = spotAssetCtxs[idx];
      const baseToken = spotMeta.tokens.find(t => t.index === p.tokens[0]);
      const quoteToken = spotMeta.tokens.find(t => t.index === p.tokens[1]);
      
      return {
        pairName: p.name,              // API returns this
        actualSymbol: `${baseToken?.name}/${quoteToken?.name}`, // What it actually is
        baseAsset: baseToken?.name,
        quoteAsset: quoteToken?.name,
        volume: parseFloat(assetCtx?.dayNtlVlm || '0'),
        price: parseFloat(assetCtx?.midPx || assetCtx?.markPx || '0'),
      };
    })
    .filter(p => p.volume > 0)
    .sort((a, b) => b.volume - a.volume)
    .slice(0, 10);
  
  console.log('Top 10 SPOT pairs by volume:\n');
  topPairs.forEach((p, idx) => {
    console.log(`${idx + 1}. API Name: "${p.pairName}" -> Actual: ${p.actualSymbol}`);
    console.log(`   Price: $${p.price.toLocaleString()}, Volume: $${p.volume.toLocaleString()}\n`);
  });
}

investigateSpotPairs();

Actual Output (as of 2025-12-31)

Top 10 SPOT pairs by volume:

1. API Name: "@145" -> Actual: VORTX/USDC (should be BTC/USDC)
   Price: $88,563.5, Volume: $70,700,244

2. API Name: "@109" -> Actual: WOW/USDC (should be HYPE/USDC)
   Price: $25.828, Volume: $38,796,441

3. API Name: "@156" -> Actual: USOL/USDC (should be ETH/USDC)
   Price: $2,975.05, Volume: $8,648,178

4. API Name: "@161" -> Actual: PRFI/USDC (should be SOL/USDC)
   Price: $125.92, Volume: $6,701,855

5. API Name: "@224" -> Actual: UWLD/USDC
   Price: $0.17588, Volume: $2,882,144

6. API Name: "@246" -> Actual: IZEC/USDC
   Price: $0.99996, Volume: $2,656,106

7. API Name: "@174" -> Actual: ANON/USDC
   Price: $0.999155, Volume: $2,071,988

8. API Name: "@192" -> Actual: ANZ/USDC
   Price: $4,324.6, Volume: $1,988,151

9. API Name: "@170" -> Actual: PEG/USDC
   Price: $0.28535, Volume: $1,977,673

10. API Name: "@155" -> Actual: QUANT/USDC
    Price: $0.998415, Volume: $1,651,996

The Problem

Notice that:

  • @145 is actually VORTX/USDC
  • @156 is actually USOL/USDC
  • @161 is actually PRFI/USDC

The @number notation does not indicate what the underlying assets are.

Environment

  • @nktkas/hyperliquid version: 0.25.4 (specified in package.json as ^0.25.4)
  • Runtime environment and its version: Bun 1.3.0

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions