Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions hyperliquid/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,24 @@ def __init__(
self.asset_to_sz_decimals = {}

# spot assets start at 10000
# Build index-based token lookup to handle cases where token indices don't match array positions
# Fixes issue #275: https://github.com/hyperliquid-dex/hyperliquid-python-sdk/issues/275
token_by_index = {token["index"]: token for token in spot_meta["tokens"]}

for spot_info in spot_meta["universe"]:
asset = spot_info["index"] + 10000
self.coin_to_asset[spot_info["name"]] = asset
self.name_to_coin[spot_info["name"]] = spot_info["name"]
base, quote = spot_info["tokens"]
base_info = spot_meta["tokens"][base]
quote_info = spot_meta["tokens"][quote]
self.asset_to_sz_decimals[asset] = base_info["szDecimals"]
name = f'{base_info["name"]}/{quote_info["name"]}'
if name not in self.name_to_coin:
self.name_to_coin[name] = spot_info["name"]
base_idx, quote_idx = spot_info["tokens"]
# Use index-based lookup instead of array position to avoid IndexError
# when testnet API returns malformed spot_meta with token indices exceeding array bounds
base_info = token_by_index.get(base_idx)
quote_info = token_by_index.get(quote_idx)
if base_info is not None and quote_info is not None:
self.asset_to_sz_decimals[asset] = base_info["szDecimals"]
name = f'{base_info["name"]}/{quote_info["name"]}'
if name not in self.name_to_coin:
self.name_to_coin[name] = spot_info["name"]

perp_dex_to_offset = {"": 0}
if perp_dexs is None:
Expand Down