Skip to content

docs: note that spot_meta_and_asset_ctxs returns two non-parallel lists - #309

Open
massimiliano1991 wants to merge 1 commit into
hyperliquid-dex:masterfrom
massimiliano1991:docs-spot-ctxs-not-parallel
Open

docs: note that spot_meta_and_asset_ctxs returns two non-parallel lists#309
massimiliano1991 wants to merge 1 commit into
hyperliquid-dex:masterfrom
massimiliano1991:docs-spot-ctxs-not-parallel

Conversation

@massimiliano1991

Copy link
Copy Markdown

Closes #308.

spot_meta_and_asset_ctxs() returns two lists that are not parallel, and the docstring
lays them out adjacently. This adds a Note: saying so, with the correct pairing. No
behaviour change — docstring only.

The fact, re-measured on mainnet today (2026-08-10)

universe   324 entries
assetCtxs  715 entries
aligned by position :  71
aligned by index    : 324   <- universe[i]["index"]

Why it deserves a line rather than being obvious

Positions 0-70 line up. Everything you are likely to eyeball while testing is inside the
aligned region, so zipping the two lists looks correct and then silently returns a
different asset's prices. The first divergence:

universe[71] = @72 (index 72)   zip -> markPx 1.0   correct -> 0.72847

The perp sibling meta_and_asset_ctxs() is parallel (232 vs 232), so the natural
intuition carries over from perps and is wrong for spot. The SDK already encodes the
distinction in Info.__init__ — perps use enumerate(meta["universe"]), spot uses
spot_info["index"] + 10000 — so the knowledge is in the codebase, just not where a
caller of this method reads.

Reproduce (no keys, no install)

import json, urllib.request
def info(b):
    r = urllib.request.Request("https://api.hyperliquid.xyz/info",
        data=json.dumps(b).encode(), headers={"Content-Type": "application/json"})
    return json.loads(urllib.request.urlopen(r).read())

meta, ctxs = info({"type": "spotMetaAndAssetCtxs"})
uni = meta["universe"]
print(len(uni), len(ctxs))                                                # 324 715
print(sum(1 for i, e in enumerate(uni) if ctxs[i]["coin"] == e["name"]))  #  71  by position
print(sum(1 for e in uni if ctxs[e["index"]]["coin"] == e["name"]))       # 324  by index

Happy to trim the note if it reads long — the pairing line is the part that matters.

universe (324) and assetCtxs (715) are not parallel; pair them through the
universe entry's own `index` field. Positions 0-70 line up, which hides the
mismatch during casual testing and returns another asset's prices past that
point. The perp sibling meta_and_asset_ctxs() IS parallel, so the intuition
does not carry over.

Docstring only, no behaviour change. Closes hyperliquid-dex#308.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Docs: spotMetaAndAssetCtxs arrays are not parallel (320 vs 711) — and positions 0-70 line up, which hides it

1 participant