Files
nofx/scripts/test_lighter_orders.go

169 lines
5.0 KiB
Go

//go:build ignore
// Test script to verify Lighter API authentication
// Run: go run scripts/test_lighter_orders.go
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"os"
"time"
lighterClient "github.com/elliottech/lighter-go/client"
lighterHTTP "github.com/elliottech/lighter-go/client/http"
)
func main() {
// Configuration - update these values
walletAddr := os.Getenv("LIGHTER_WALLET")
apiKeyPrivateKey := os.Getenv("LIGHTER_API_KEY")
if walletAddr == "" || apiKeyPrivateKey == "" {
fmt.Println("Usage: LIGHTER_WALLET=0x... LIGHTER_API_KEY=... go run scripts/test_lighter_orders.go")
fmt.Println("Environment variables required:")
fmt.Println(" LIGHTER_WALLET - Ethereum wallet address")
fmt.Println(" LIGHTER_API_KEY - API key private key (40 bytes hex)")
os.Exit(1)
}
fmt.Println("=== Lighter API Test ===")
fmt.Printf("Wallet: %s\n\n", walletAddr)
baseURL := "https://mainnet.zklighter.elliot.ai"
chainID := uint32(304)
client := &http.Client{Timeout: 30 * time.Second}
// Step 1: Get account info (no auth required)
fmt.Println("1. Getting account info...")
accountIndex, err := getAccountIndex(client, baseURL, walletAddr)
if err != nil {
fmt.Printf(" FAILED: %v\n", err)
os.Exit(1)
}
fmt.Printf(" OK: account_index = %d\n\n", accountIndex)
// Step 2: Create TxClient and generate auth token
fmt.Println("2. Creating TxClient and generating auth token...")
httpClient := lighterHTTP.NewClient(baseURL)
txClient, err := lighterClient.NewTxClient(httpClient, apiKeyPrivateKey, accountIndex, 0, chainID)
if err != nil {
fmt.Printf(" FAILED: %v\n", err)
os.Exit(1)
}
authToken, err := txClient.GetAuthToken(time.Now().Add(1 * time.Hour))
if err != nil {
fmt.Printf(" FAILED: %v\n", err)
os.Exit(1)
}
fmt.Printf(" OK: auth token generated\n\n")
// Step 3: Test GetActiveOrders with auth query parameter (NEW method)
fmt.Println("3. Testing GetActiveOrders with auth query parameter (FIXED)...")
encodedAuth := url.QueryEscape(authToken)
endpoint := fmt.Sprintf("%s/api/v1/accountActiveOrders?account_index=%d&market_id=0&auth=%s",
baseURL, accountIndex, encodedAuth)
resp, err := client.Get(endpoint)
if err != nil {
fmt.Printf(" FAILED: %v\n", err)
os.Exit(1)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result map[string]interface{}
json.Unmarshal(body, &result)
if code, ok := result["code"].(float64); ok && code == 200 {
orders := result["orders"].([]interface{})
fmt.Printf(" OK: Retrieved %d orders\n", len(orders))
if len(orders) > 0 {
fmt.Println(" Sample orders:")
for i, o := range orders {
if i >= 3 {
fmt.Printf(" ... and %d more\n", len(orders)-3)
break
}
order := o.(map[string]interface{})
fmt.Printf(" - ID: %v, Price: %v, Side: %v\n",
order["order_id"], order["price"], order["is_ask"])
}
}
} else {
fmt.Printf(" FAILED: %s\n", string(body))
fmt.Println("\n Possible causes:")
fmt.Println(" - API key not registered on-chain")
fmt.Println(" - API key private key incorrect")
fmt.Println(" - Account index mismatch")
os.Exit(1)
}
// Step 4: Test GetActiveOrders with Authorization header (OLD method - for comparison)
fmt.Println("\n4. Testing GetActiveOrders with Authorization header (OLD method)...")
endpoint2 := fmt.Sprintf("%s/api/v1/accountActiveOrders?account_index=%d&market_id=0",
baseURL, accountIndex)
req, _ := http.NewRequest("GET", endpoint2, nil)
req.Header.Set("Authorization", authToken)
req.Header.Set("Content-Type", "application/json")
resp2, err := client.Do(req)
if err != nil {
fmt.Printf(" FAILED: %v\n", err)
} else {
defer resp2.Body.Close()
body2, _ := io.ReadAll(resp2.Body)
var result2 map[string]interface{}
json.Unmarshal(body2, &result2)
if code, ok := result2["code"].(float64); ok && code == 200 {
orders := result2["orders"].([]interface{})
fmt.Printf(" OK: Retrieved %d orders (both methods work!)\n", len(orders))
} else {
fmt.Printf(" FAILED: %s\n", string(body2))
fmt.Println(" ^ This is expected - Authorization header doesn't work consistently")
}
}
fmt.Println("\n=== TEST COMPLETE ===")
fmt.Println("If test 3 passed, the fix is working correctly.")
}
func getAccountIndex(client *http.Client, baseURL, walletAddr string) (int64, error) {
endpoint := fmt.Sprintf("%s/api/v1/account?by=l1_address&value=%s", baseURL, walletAddr)
resp, err := client.Get(endpoint)
if err != nil {
return 0, err
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var result struct {
Code int `json:"code"`
Accounts []struct {
AccountIndex int64 `json:"account_index"`
} `json:"accounts"`
SubAccounts []struct {
AccountIndex int64 `json:"account_index"`
} `json:"sub_accounts"`
}
if err := json.Unmarshal(body, &result); err != nil {
return 0, fmt.Errorf("failed to parse: %w", err)
}
if len(result.Accounts) > 0 {
return result.Accounts[0].AccountIndex, nil
}
if len(result.SubAccounts) > 0 {
return result.SubAccounts[0].AccountIndex, nil
}
return 0, fmt.Errorf("no account found")
}