forked from sonirico/go-hyperliquid
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexchange.go
More file actions
94 lines (82 loc) · 1.85 KB
/
exchange.go
File metadata and controls
94 lines (82 loc) · 1.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package hyperliquid
import (
"crypto/ecdsa"
"encoding/json"
"time"
)
type Exchange struct {
client *Client
privateKey *ecdsa.PrivateKey
vault string
accountAddr string
info *Info
expiresAfter *int64
}
func NewExchange(
privateKey *ecdsa.PrivateKey,
baseURL string,
meta *Meta,
vaultAddr, accountAddr string,
spotMeta *SpotMeta,
) *Exchange {
return &Exchange{
client: NewClient(baseURL),
privateKey: privateKey,
vault: vaultAddr,
accountAddr: accountAddr,
info: NewInfo(baseURL, true, meta, spotMeta),
}
}
// executeAction executes an action and unmarshals the response into the given result
func (e *Exchange) executeAction(action any, result any) error {
timestamp := time.Now().UnixMilli()
sig, err := SignL1Action(
e.privateKey,
action,
e.vault,
timestamp,
e.expiresAfter,
e.client.baseURL == MainnetAPIURL,
)
if err != nil {
return err
}
resp, err := e.postAction(action, sig, timestamp)
if err != nil {
return err
}
if err := json.Unmarshal(resp, result); err != nil {
return err
}
return nil
}
func (e *Exchange) postAction(
action any,
signature SignatureResult,
nonce int64,
) ([]byte, error) {
payload := map[string]any{
"action": action,
"nonce": nonce,
"signature": signature,
}
if e.vault != "" {
// Handle vault address based on action type
if actionMap, ok := action.(map[string]any); ok {
if actionMap["type"] != "usdClassTransfer" {
payload["vaultAddress"] = e.vault
} else {
payload["vaultAddress"] = nil
}
} else {
// For struct types, we need to use reflection or type assertion
// For now, assume it's not usdClassTransfer
payload["vaultAddress"] = e.vault
}
}
// Add expiration time if set
if e.expiresAfter != nil {
payload["expiresAfter"] = *e.expiresAfter
}
return e.client.post("/exchange", payload)
}