fix(hyperliquid): bump go-hyperliquid v0.26 -> v0.36 to dodge spot-meta panic

go-hyperliquid v0.26.0 crashed at startup with

    panic: runtime error: index out of range [479] with length 464
    github.com/sonirico/go-hyperliquid.NewInfo (info.go:75)
    NewExchange -> NewHyperliquidTrader -> AutoTrader.NewAutoTrader
    -> TraderManager.LoadTradersFromStore -> main.main

The library's NewInfo built the spot-asset map by indexing
`spotMeta.Tokens[spotInfo.Tokens[0]]` directly, but Hyperliquid recently
added spot tokens whose Tokens[0] value (a logical token *index*, not an
array position) was larger than the Tokens slice length. With every
restart the backend panicked before the API server bound, so the
frontend's `/api/*` proxy got connection refused on every poll and the
dashboard rendered "全是 error" toasts.

v0.36 fixes the panic by building `tokensByIndex map[int]SpotTokenInfo`
and looking up by logical index instead of position. Adopting v0.36
required two small adaptations to our wrapper:

  - trader/hyperliquid/trader.go: NewExchange grew an extra `perpDexs
    *MixedArray` argument. Passing `nil` keeps the existing
    "auto-fetch on first use" behavior.
  - trader/hyperliquid/trader_sync.go: `Info.NameToAsset(coin) int` was
    renamed to `Info.CoinToAsset(coin) (int, bool)` with an `ok` flag.
    refreshMetaIfNeeded now treats `!ok || assetID == 0` as "needs
    refresh" (the same semantic as the old `assetID == 0`).

Verified: backend rebuilds cleanly, container is healthy, all
Hyperliquid traders load, AI cycles execute, and Hyperliquid order
sync receives the full historical trade window.
This commit is contained in:
tinkle-community
2026-05-30 01:48:11 +08:00
parent b15c2da3a9
commit 7f0a9f0749
4 changed files with 44 additions and 34 deletions

View File

@@ -133,15 +133,21 @@ func NewHyperliquidTrader(privateKeyHex string, walletAddr string, testnet bool,
ctx := context.Background()
// Create Exchange client (Exchange includes Info functionality)
// Create Exchange client (Exchange includes Info functionality).
// v0.36 signature: ctx, privateKey, baseURL, meta, vaultAddr, accountAddr,
// spotMeta, perpDexs, ...opts. nil values are auto-fetched on first use.
// v0.36 fixed the spot-meta indexing panic that crashed earlier versions
// when Hyperliquid added new spot tokens whose Tokens[0] index pointed
// past the Tokens array end.
exchange := hyperliquid.NewExchange(
ctx,
privateKey,
apiURL,
nil, // Meta will be fetched automatically
nil, // Meta fetched automatically
"", // vault address (empty for personal account)
walletAddr, // wallet address
nil, // SpotMeta will be fetched automatically
nil, // SpotMeta fetched automatically
nil, // perpDexs — fetched automatically
)
logger.Infof("✓ Hyperliquid trader initialized successfully (testnet=%v, wallet=%s)", testnet, walletAddr)

View File

@@ -11,10 +11,14 @@ import (
"time"
)
// refreshMetaIfNeeded refreshes meta information when invalid (triggered when Asset ID is 0)
// refreshMetaIfNeeded refreshes meta information when invalid (triggered when Asset ID is 0).
//
// NOTE: go-hyperliquid v0.27 renamed `NameToAsset(coin) int` to
// `CoinToAsset(coin) (int, bool)` — the second return is `ok` for whether
// the coin exists in the meta cache. We treat `!ok` (or zero asset for a
// perp) as "need refresh" the same way the old code did.
func (t *HyperliquidTrader) refreshMetaIfNeeded(coin string) error {
assetID := t.exchange.Info().NameToAsset(coin)
if assetID != 0 {
if assetID, ok := t.exchange.Info().CoinToAsset(coin); ok && assetID != 0 {
return nil // Meta is normal, no refresh needed
}
@@ -34,8 +38,8 @@ func (t *HyperliquidTrader) refreshMetaIfNeeded(coin string) error {
logger.Infof("✅ Meta information refreshed, contains %d assets", len(meta.Universe))
// Verify Asset ID after refresh
assetID = t.exchange.Info().NameToAsset(coin)
if assetID == 0 {
assetID, ok := t.exchange.Info().CoinToAsset(coin)
if !ok || assetID == 0 {
return fmt.Errorf("❌ Even after refreshing Meta, Asset ID for %s is still 0. Possible reasons:\n"+
" 1. This coin is not listed on Hyperliquid\n"+
" 2. Coin name is incorrect (should be BTC not BTCUSDT)\n"+