diff --git a/config.go b/config.go index 9b7856b..3c28c3c 100644 --- a/config.go +++ b/config.go @@ -56,7 +56,8 @@ type Config struct { // HyperLiquid API HLPrivateKey string // ed25519 private key hex - HLAddress string // wallet address + HLAddress string // main account address + HLAPIAddress string // API wallet address (signer, auto-derived if empty) } // jsonConfig maps config.json fields (non-secret defaults checked into git). @@ -157,6 +158,7 @@ func LoadConfig() *Config { HLPrivateKey: getEnv("HL_PRIVATE_KEY", ""), HLAddress: getEnv("HL_ADDRESS", ""), + HLAPIAddress: getEnv("HL_API_ADDRESS", ""), } } diff --git a/exchange/hyperliquid_trade.go b/exchange/hyperliquid_trade.go index b78156f..2752042 100644 --- a/exchange/hyperliquid_trade.go +++ b/exchange/hyperliquid_trade.go @@ -39,6 +39,7 @@ type HLSignedAction struct { Action HLOrderAction `json:"action"` Nonce int64 `json:"nonce"` Signature string `json:"signature"` + Address string `json:"address"` // API wallet address (signer) VaultAddress string `json:"vaultAddress,omitempty"` } @@ -51,12 +52,13 @@ type HLOrderResponse struct { type HyperLiquidTrade struct { PrivateKey ed25519.PrivateKey Address string + APIAddress string // API wallet address (signer), derived from private key client *http.Client lastNonce int64 nonceMu sync.Mutex // protect lastNonce++ (Issue #4) } -func NewHyperLiquidTrade(privateKeyHex, address string) (*HyperLiquidTrade, error) { +func NewHyperLiquidTrade(privateKeyHex, mainAddress, apiAddress string) (*HyperLiquidTrade, error) { if privateKeyHex == "" { return &HyperLiquidTrade{client: &http.Client{Timeout: 10 * time.Second}}, nil } @@ -81,9 +83,17 @@ func NewHyperLiquidTrade(privateKeyHex, address string) (*HyperLiquidTrade, erro return nil, fmt.Errorf("invalid private key length: %d (expected 32 or %d)", len(keyBytes), ed25519.PrivateKeySize) } + // If apiAddress not provided, derive from private key + if apiAddress == "" { + privKey := ed25519.PrivateKey(keyBytes) + pubKey := privKey.Public().(ed25519.PublicKey) + apiAddress = "0x" + hex.EncodeToString(pubKey) + } + return &HyperLiquidTrade{ PrivateKey: ed25519.PrivateKey(keyBytes), - Address: address, + Address: mainAddress, + APIAddress: apiAddress, client: &http.Client{Timeout: 10 * time.Second}, }, nil } @@ -130,6 +140,7 @@ func (h *HyperLiquidTrade) PlaceMarketOrder(coin, side, sz string) (string, erro Action: action, Nonce: nonce, Signature: sig, + Address: h.APIAddress, } bodyJSON, _ := json.Marshal(signed) diff --git a/trader.go b/trader.go index c3168c8..0d0a1af 100644 --- a/trader.go +++ b/trader.go @@ -191,7 +191,7 @@ func NewTrader(cfg *Config, database *db.DB) *Trader { if cfg.BitgetAPIKey != "" { bt = exchange.NewBitgetTrade(cfg.BitgetAPIKey, cfg.BitgetAPISecret, cfg.BitgetPassphrase) } - hl, _ := exchange.NewHyperLiquidTrade(cfg.HLPrivateKey, cfg.HLAddress) + hl, _ := exchange.NewHyperLiquidTrade(cfg.HLPrivateKey, cfg.HLAddress, cfg.HLAPIAddress) t := &Trader{ cfg: cfg,