hyperliquid 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +21 -2
- data/CHANGELOG.md +24 -4
- data/CLAUDE.md +202 -0
- data/README.md +184 -7
- data/example.rb +131 -28
- data/lib/hyperliquid/cloid.rb +102 -0
- data/lib/hyperliquid/constants.rb +1 -0
- data/lib/hyperliquid/exchange.rb +410 -0
- data/lib/hyperliquid/signing/eip712.rb +56 -0
- data/lib/hyperliquid/signing/signer.rb +122 -0
- data/lib/hyperliquid/version.rb +1 -1
- data/lib/hyperliquid.rb +33 -5
- data/test_integration.rb +255 -0
- metadata +35 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 789cad57e75566edeaeb09a8437763d716caa6978c8a2ed9322623eb223c40a7
|
|
4
|
+
data.tar.gz: f2e68884aedf2f33cf4b66d811e02fe1f3fdaf4e1b77793b29b64b52934773ad
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 271fd73adff54d249d4ca2bf2b9f16aacdba8519ea0891e36b2315781019e231ddc158e2a0caeb401d2b43c3cf34f5cee68a0f1c15b183f41f2a1363a98af05b
|
|
7
|
+
data.tar.gz: 8b0c7fe1e353bdd6aa01d745708c0dfd7b3909bd95185c88ce9cd7fa93204535cccea04f47ad22d786f068c6e3f2cee77a69ce81df6aa1615e700743248e35fa
|
data/.rubocop.yml
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
AllCops:
|
|
2
2
|
NewCops: enable
|
|
3
3
|
TargetRubyVersion: 3.4.3
|
|
4
|
+
SuggestExtensions: false
|
|
5
|
+
Exclude:
|
|
6
|
+
- 'test_*.rb' # Exclude ad-hoc integration test scripts
|
|
7
|
+
- 'vendor/**/*' # Exclude vendored gems (CI bundles here)
|
|
4
8
|
|
|
5
9
|
# Allow longer methods for complex logic
|
|
6
10
|
Metrics/MethodLength:
|
|
@@ -14,7 +18,22 @@ Metrics/AbcSize:
|
|
|
14
18
|
Metrics/ClassLength:
|
|
15
19
|
Enabled: false
|
|
16
20
|
|
|
17
|
-
# Allow longer blocks in specs - this is normal for tests
|
|
21
|
+
# Allow longer blocks in specs and gemspec - this is normal for tests and gem configs
|
|
18
22
|
Metrics/BlockLength:
|
|
19
23
|
Exclude:
|
|
20
|
-
- 'spec/**/*'
|
|
24
|
+
- 'spec/**/*'
|
|
25
|
+
- '*.gemspec'
|
|
26
|
+
|
|
27
|
+
# Exchange API methods require many parameters
|
|
28
|
+
Metrics/ParameterLists:
|
|
29
|
+
Exclude:
|
|
30
|
+
- 'lib/hyperliquid/exchange.rb'
|
|
31
|
+
|
|
32
|
+
# Allow higher complexity for order type conversion logic
|
|
33
|
+
Metrics/CyclomaticComplexity:
|
|
34
|
+
Exclude:
|
|
35
|
+
- 'lib/hyperliquid/exchange.rb'
|
|
36
|
+
|
|
37
|
+
Metrics/PerceivedComplexity:
|
|
38
|
+
Exclude:
|
|
39
|
+
- 'lib/hyperliquid/exchange.rb'
|
data/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,33 @@
|
|
|
1
1
|
## [Ruby Hyperliquid SDK Changelog]
|
|
2
2
|
|
|
3
|
-
## [0.
|
|
3
|
+
## [0.4.0] - 2025-01-27
|
|
4
4
|
|
|
5
|
-
-
|
|
5
|
+
- Add Exchange API for authenticated write operations (trading)
|
|
6
|
+
- Order placement: `order`, `bulk_orders`, `market_order`
|
|
7
|
+
- Order cancellation: `cancel`, `cancel_by_cloid`, `bulk_cancel`, `bulk_cancel_by_cloid`
|
|
8
|
+
- Trigger orders (stop loss / take profit) support
|
|
9
|
+
- Vault trading support via optional `vault_address` parameter
|
|
10
|
+
- Order expiration support via `expires_after` parameter
|
|
11
|
+
- Add EIP-712 signing infrastructure matching official Python SDK
|
|
12
|
+
- Phantom agent signing scheme
|
|
13
|
+
- Full parity with Python SDK signature generation
|
|
14
|
+
- Add new dependencies: `eth` (~> 0.5), `msgpack` (~> 1.7)
|
|
15
|
+
- SDK now accepts optional `private_key` and `expires_after` parameters
|
|
6
16
|
|
|
7
|
-
## [0.
|
|
17
|
+
## [0.3.0] - 2025-09-24
|
|
8
18
|
|
|
9
|
-
-
|
|
19
|
+
- Full parity with all Hyperliquid Info APIs
|
|
20
|
+
- All Info APIs implemented
|
|
21
|
+
- Code, tests, and docs reflect structure of official Hyperliquid API documentation
|
|
10
22
|
|
|
11
23
|
## [0.2.0] - 2025-09-24
|
|
12
24
|
|
|
13
25
|
- Add info endpoints for user spot data
|
|
26
|
+
|
|
27
|
+
## [0.1.1] - 2025-09-23
|
|
28
|
+
|
|
29
|
+
- Fixed retry logic, make retry logic disabled by default
|
|
30
|
+
|
|
31
|
+
## [0.1.0] - 2025-08-21
|
|
32
|
+
|
|
33
|
+
- Initial release which includes info endpoints for market and user perps data
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This is a Ruby SDK for the Hyperliquid decentralized exchange API. The current version (0.4.0) supports both **read operations** (Info API) and **authenticated write operations** (Exchange API) for trading.
|
|
8
|
+
|
|
9
|
+
**Target Ruby Version**: 3.4.0+
|
|
10
|
+
|
|
11
|
+
## Development Commands
|
|
12
|
+
|
|
13
|
+
### Running Tests
|
|
14
|
+
```bash
|
|
15
|
+
# Run all tests
|
|
16
|
+
rake spec
|
|
17
|
+
|
|
18
|
+
# Run tests and linting together (default rake task)
|
|
19
|
+
rake
|
|
20
|
+
|
|
21
|
+
# Run a single test file
|
|
22
|
+
bundle exec rspec spec/hyperliquid/cloid_spec.rb
|
|
23
|
+
|
|
24
|
+
# Run a specific test by line number
|
|
25
|
+
bundle exec rspec spec/hyperliquid/cloid_spec.rb:62
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Linting
|
|
29
|
+
```bash
|
|
30
|
+
# Run RuboCop linter
|
|
31
|
+
rake rubocop
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Interactive Console
|
|
35
|
+
```bash
|
|
36
|
+
# Open an interactive console with the SDK loaded
|
|
37
|
+
bin/console
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Example Script
|
|
41
|
+
```bash
|
|
42
|
+
# Run the example usage script
|
|
43
|
+
ruby example.rb
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Integration Testing (Testnet)
|
|
47
|
+
```bash
|
|
48
|
+
# Run the testnet integration test (requires private key)
|
|
49
|
+
# Get testnet funds from: https://app.hyperliquid-testnet.xyz
|
|
50
|
+
HYPERLIQUID_PRIVATE_KEY=0x... ruby test_integration.rb
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The integration test executes real trades on testnet:
|
|
54
|
+
1. Spot market roundtrip (buy/sell PURR/USDC)
|
|
55
|
+
2. Spot limit order (place and cancel)
|
|
56
|
+
3. Perp market roundtrip (long/close BTC)
|
|
57
|
+
4. Perp limit order (place short, cancel)
|
|
58
|
+
|
|
59
|
+
### Setup
|
|
60
|
+
```bash
|
|
61
|
+
# Install dependencies
|
|
62
|
+
bin/setup
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Architecture
|
|
66
|
+
|
|
67
|
+
### Core Components
|
|
68
|
+
|
|
69
|
+
**Hyperliquid::SDK** (`lib/hyperliquid.rb`)
|
|
70
|
+
- Main entry point created via `Hyperliquid.new(testnet:, timeout:, retry_enabled:, private_key:, expires_after:)`
|
|
71
|
+
- Manages environment selection (mainnet vs testnet)
|
|
72
|
+
- Exposes the `info` API client (always available)
|
|
73
|
+
- Exposes the `exchange` API client (when `private_key` provided)
|
|
74
|
+
|
|
75
|
+
**Hyperliquid::Client** (`lib/hyperliquid/client.rb`)
|
|
76
|
+
- Low-level HTTP client built on Faraday
|
|
77
|
+
- Handles all POST requests to the Hyperliquid API
|
|
78
|
+
- Manages retry logic (disabled by default, opt-in via `retry_enabled: true`)
|
|
79
|
+
- Converts HTTP errors into typed exceptions
|
|
80
|
+
|
|
81
|
+
**Hyperliquid::Info** (`lib/hyperliquid/info.rb`)
|
|
82
|
+
- High-level API client for all Info endpoints (read-only)
|
|
83
|
+
- Organized into three sections:
|
|
84
|
+
1. **General Info**: Market data, user orders, fills, rate limits, portfolios, referrals, fees, staking
|
|
85
|
+
2. **Perpetuals**: Perp DEXs, metadata, user state, funding rates, open interest
|
|
86
|
+
3. **Spot**: Spot tokens, balances, deploy auctions, token details
|
|
87
|
+
- All methods accept user wallet addresses and return parsed JSON responses
|
|
88
|
+
|
|
89
|
+
**Hyperliquid::Exchange** (`lib/hyperliquid/exchange.rb`)
|
|
90
|
+
- High-level API client for Exchange endpoints (authenticated write operations)
|
|
91
|
+
- Order placement: `order`, `bulk_orders`, `market_order`
|
|
92
|
+
- Order cancellation: `cancel`, `cancel_by_cloid`, `bulk_cancel`, `bulk_cancel_by_cloid`
|
|
93
|
+
- Supports trigger orders (stop loss / take profit)
|
|
94
|
+
- Supports vault trading via `vault_address` parameter
|
|
95
|
+
- Caches asset metadata for efficient lookups
|
|
96
|
+
|
|
97
|
+
**Hyperliquid::Signing::Signer** (`lib/hyperliquid/signing/signer.rb`)
|
|
98
|
+
- EIP-712 signature generation using phantom agent scheme
|
|
99
|
+
- Matches official Python SDK signing algorithm exactly
|
|
100
|
+
- Supports vault address and expiration in signature
|
|
101
|
+
|
|
102
|
+
**Hyperliquid::Signing::EIP712** (`lib/hyperliquid/signing/eip712.rb`)
|
|
103
|
+
- EIP-712 domain and type definitions
|
|
104
|
+
- L1 chain ID (1337) and source identifiers ('a' mainnet, 'b' testnet)
|
|
105
|
+
|
|
106
|
+
**Hyperliquid::Cloid** (`lib/hyperliquid/cloid.rb`)
|
|
107
|
+
- Type-safe client order ID class
|
|
108
|
+
- Validates 16-byte hex format (0x + 32 hex characters)
|
|
109
|
+
- Factory methods: `from_int`, `from_str`, `from_uuid`, `random`
|
|
110
|
+
|
|
111
|
+
**Hyperliquid::Constants** (`lib/hyperliquid/constants.rb`)
|
|
112
|
+
- API URLs for mainnet and testnet
|
|
113
|
+
- Endpoint paths (`/info`, `/exchange`)
|
|
114
|
+
- Default timeout values
|
|
115
|
+
|
|
116
|
+
**Hyperliquid::Errors** (`lib/hyperliquid/errors.rb`)
|
|
117
|
+
- Typed exception hierarchy for API errors
|
|
118
|
+
- Base class: `Hyperliquid::Error`
|
|
119
|
+
- Specific errors: `ClientError`, `ServerError`, `AuthenticationError`, `RateLimitError`, `BadRequestError`, `NotFoundError`, `TimeoutError`, `NetworkError`
|
|
120
|
+
|
|
121
|
+
### API Request Pattern
|
|
122
|
+
|
|
123
|
+
**Info API (read-only):**
|
|
124
|
+
1. SDK method called (e.g., `sdk.info.all_mids`)
|
|
125
|
+
2. Info class builds request body with `type` field (e.g., `{ type: 'allMids' }`)
|
|
126
|
+
3. Client POSTs JSON body to `/info` endpoint
|
|
127
|
+
4. Client parses response and handles errors
|
|
128
|
+
5. Parsed JSON returned to caller
|
|
129
|
+
|
|
130
|
+
**Exchange API (authenticated):**
|
|
131
|
+
1. SDK method called (e.g., `sdk.exchange.order(...)`)
|
|
132
|
+
2. Exchange class builds action payload with order/cancel details
|
|
133
|
+
3. Signer generates EIP-712 signature over msgpack-encoded action
|
|
134
|
+
4. Exchange POSTs signed payload to `/exchange` endpoint
|
|
135
|
+
5. Client parses response and handles errors
|
|
136
|
+
6. Parsed JSON returned to caller
|
|
137
|
+
|
|
138
|
+
### Testing
|
|
139
|
+
|
|
140
|
+
- Uses RSpec for testing
|
|
141
|
+
- WebMock for HTTP mocking
|
|
142
|
+
- Spec helper configures WebMock to reset between tests
|
|
143
|
+
- Test files mirror source structure in `spec/`
|
|
144
|
+
|
|
145
|
+
### Code Style
|
|
146
|
+
|
|
147
|
+
RuboCop configuration (`.rubocop.yml`):
|
|
148
|
+
- Targets Ruby 3.4.0+
|
|
149
|
+
- Allows longer methods (max 50 lines) for complex logic
|
|
150
|
+
- Disables class length checks (Info/Exchange classes implement many endpoints)
|
|
151
|
+
- Excludes block length checks for specs
|
|
152
|
+
- Enables NewCops by default
|
|
153
|
+
|
|
154
|
+
## Key Implementation Details
|
|
155
|
+
|
|
156
|
+
### Retry Logic
|
|
157
|
+
- **Disabled by default** for predictable behavior in time-sensitive trading
|
|
158
|
+
- When enabled: max 2 retries, 0.5s base interval, exponential backoff (2x), ±50% randomness
|
|
159
|
+
- Retries on: connection failures, timeouts, 429 (rate limit), 5xx errors
|
|
160
|
+
|
|
161
|
+
### API Endpoints
|
|
162
|
+
- Info requests POST to `/info` endpoint
|
|
163
|
+
- Exchange requests POST to `/exchange` endpoint
|
|
164
|
+
- Request body includes `type` field indicating the operation
|
|
165
|
+
|
|
166
|
+
### Time Parameters
|
|
167
|
+
- All timestamps are in **milliseconds** (not seconds)
|
|
168
|
+
- Methods with time ranges support optional `end_time` parameter
|
|
169
|
+
- `expires_after` is an absolute timestamp in milliseconds
|
|
170
|
+
|
|
171
|
+
### Signature Generation (Python SDK Parity)
|
|
172
|
+
The signing implementation matches the official Python SDK exactly:
|
|
173
|
+
- **Action hash**: `keccak256(msgpack(action) + nonce(8B BE) + vault_flag + [vault_addr] + [expires_flag + expires_after])`
|
|
174
|
+
- **Phantom agent**: `{ source: 'a'|'b', connectionId: action_hash }`
|
|
175
|
+
- **EIP-712 signature** over phantom agent with Exchange domain
|
|
176
|
+
|
|
177
|
+
### Float to Wire Format
|
|
178
|
+
Numeric values are converted to strings matching Python SDK `float_to_wire`:
|
|
179
|
+
- 8 decimal precision
|
|
180
|
+
- Rounding tolerance validation (1e-12)
|
|
181
|
+
- Trailing zero normalization (no scientific notation)
|
|
182
|
+
|
|
183
|
+
### Market Order Price Calculation
|
|
184
|
+
Market orders use Python SDK `_slippage_price` algorithm:
|
|
185
|
+
- Apply slippage to mid price
|
|
186
|
+
- Round to 5 significant figures
|
|
187
|
+
- Round to asset-specific decimal places: `(6 for perp, 8 for spot) - szDecimals`
|
|
188
|
+
|
|
189
|
+
### Client Order IDs (Cloid)
|
|
190
|
+
- Must be 16 bytes in hex format: `0x` + 32 hex characters
|
|
191
|
+
- Use `Hyperliquid::Cloid` class for type safety and validation
|
|
192
|
+
- Factory methods: `from_int(n)`, `from_str(s)`, `from_uuid(uuid)`, `random`
|
|
193
|
+
|
|
194
|
+
## Development Workflow
|
|
195
|
+
|
|
196
|
+
1. Make changes to library code in `lib/hyperliquid/`
|
|
197
|
+
2. Add/update tests in `spec/`
|
|
198
|
+
3. Run tests: `rake spec`
|
|
199
|
+
4. Run linter: `rake rubocop`
|
|
200
|
+
5. Test in console: `bin/console`
|
|
201
|
+
6. Run example script: `ruby example.rb`
|
|
202
|
+
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A Ruby SDK for interacting with the Hyperliquid decentralized exchange API.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The SDK supports both read operations (Info API) and authenticated write operations (Exchange API) for trading.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -27,14 +27,23 @@ Or install it yourself as:
|
|
|
27
27
|
```ruby
|
|
28
28
|
require 'hyperliquid'
|
|
29
29
|
|
|
30
|
-
# Create SDK instance (mainnet by default)
|
|
30
|
+
# Create SDK instance for read-only operations (mainnet by default)
|
|
31
31
|
sdk = Hyperliquid.new
|
|
32
32
|
|
|
33
33
|
# Or use testnet
|
|
34
34
|
testnet_sdk = Hyperliquid.new(testnet: true)
|
|
35
35
|
|
|
36
|
-
# Access the Info API
|
|
36
|
+
# Access the Info API (read operations)
|
|
37
37
|
info = sdk.info
|
|
38
|
+
|
|
39
|
+
# For trading operations, provide a private key
|
|
40
|
+
trading_sdk = Hyperliquid.new(
|
|
41
|
+
testnet: true,
|
|
42
|
+
private_key: ENV['HYPERLIQUID_PRIVATE_KEY']
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Access the Exchange API (write operations)
|
|
46
|
+
exchange = trading_sdk.exchange
|
|
38
47
|
```
|
|
39
48
|
|
|
40
49
|
### Supported APIs
|
|
@@ -287,6 +296,155 @@ details = sdk.info.token_details("0x00000000000000000000000000000000")
|
|
|
287
296
|
# => { "name" => "TEST", "maxSupply" => "...", "midPx" => "...", ... }
|
|
288
297
|
```
|
|
289
298
|
|
|
299
|
+
#### Exchange Methods (Trading)
|
|
300
|
+
|
|
301
|
+
**Note:** Exchange methods require initializing the SDK with a `private_key`.
|
|
302
|
+
|
|
303
|
+
- `order(coin:, is_buy:, size:, limit_px:, ...)` - Place a single limit order
|
|
304
|
+
- `bulk_orders(orders:, grouping:, ...)` - Place multiple orders in a batch
|
|
305
|
+
- `market_order(coin:, is_buy:, size:, slippage:, ...)` - Place a market order with slippage
|
|
306
|
+
- `cancel(coin:, oid:, ...)` - Cancel an order by order ID
|
|
307
|
+
- `cancel_by_cloid(coin:, cloid:, ...)` - Cancel an order by client order ID
|
|
308
|
+
- `bulk_cancel(cancels:, ...)` - Cancel multiple orders by order ID
|
|
309
|
+
- `bulk_cancel_by_cloid(cancels:, ...)` - Cancel multiple orders by client order ID
|
|
310
|
+
- `address` - Get the wallet address associated with the private key
|
|
311
|
+
|
|
312
|
+
All exchange methods support an optional `vault_address:` parameter for vault trading.
|
|
313
|
+
|
|
314
|
+
##### Examples: Exchange (Trading)
|
|
315
|
+
|
|
316
|
+
```ruby
|
|
317
|
+
# Initialize SDK with private key for trading
|
|
318
|
+
sdk = Hyperliquid.new(
|
|
319
|
+
testnet: true,
|
|
320
|
+
private_key: ENV['HYPERLIQUID_PRIVATE_KEY']
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
# Get wallet address
|
|
324
|
+
address = sdk.exchange.address
|
|
325
|
+
# => "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
|
|
326
|
+
|
|
327
|
+
# Place a limit buy order
|
|
328
|
+
result = sdk.exchange.order(
|
|
329
|
+
coin: 'BTC',
|
|
330
|
+
is_buy: true,
|
|
331
|
+
size: '0.01',
|
|
332
|
+
limit_px: '95000',
|
|
333
|
+
order_type: { limit: { tif: 'Gtc' } } # Good-til-canceled (default)
|
|
334
|
+
)
|
|
335
|
+
# => { "status" => "ok", "response" => { "type" => "order", "data" => { "statuses" => [...] } } }
|
|
336
|
+
|
|
337
|
+
# Place a limit sell order with client order ID
|
|
338
|
+
cloid = Hyperliquid::Cloid.from_int(123) # Or Cloid.random
|
|
339
|
+
result = sdk.exchange.order(
|
|
340
|
+
coin: 'ETH',
|
|
341
|
+
is_buy: false,
|
|
342
|
+
size: '0.5',
|
|
343
|
+
limit_px: '3500',
|
|
344
|
+
cloid: cloid
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
# Place a market order (IoC with slippage)
|
|
348
|
+
result = sdk.exchange.market_order(
|
|
349
|
+
coin: 'BTC',
|
|
350
|
+
is_buy: true,
|
|
351
|
+
size: '0.01',
|
|
352
|
+
slippage: 0.03 # 3% slippage tolerance (default: 5%)
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
# Place multiple orders at once
|
|
356
|
+
orders = [
|
|
357
|
+
{ coin: 'BTC', is_buy: true, size: '0.01', limit_px: '94000' },
|
|
358
|
+
{ coin: 'BTC', is_buy: false, size: '0.01', limit_px: '96000' }
|
|
359
|
+
]
|
|
360
|
+
result = sdk.exchange.bulk_orders(orders: orders)
|
|
361
|
+
|
|
362
|
+
# Cancel an order by order ID
|
|
363
|
+
oid = result.dig('response', 'data', 'statuses', 0, 'resting', 'oid')
|
|
364
|
+
sdk.exchange.cancel(coin: 'BTC', oid: oid)
|
|
365
|
+
|
|
366
|
+
# Cancel an order by client order ID
|
|
367
|
+
sdk.exchange.cancel_by_cloid(coin: 'ETH', cloid: cloid)
|
|
368
|
+
|
|
369
|
+
# Cancel multiple orders by order ID
|
|
370
|
+
cancels = [
|
|
371
|
+
{ coin: 'BTC', oid: 12345 },
|
|
372
|
+
{ coin: 'ETH', oid: 12346 }
|
|
373
|
+
]
|
|
374
|
+
sdk.exchange.bulk_cancel(cancels: cancels)
|
|
375
|
+
|
|
376
|
+
# Cancel multiple orders by client order ID
|
|
377
|
+
cloid_cancels = [
|
|
378
|
+
{ coin: 'BTC', cloid: Hyperliquid::Cloid.from_int(1) },
|
|
379
|
+
{ coin: 'ETH', cloid: Hyperliquid::Cloid.from_int(2) }
|
|
380
|
+
]
|
|
381
|
+
sdk.exchange.bulk_cancel_by_cloid(cancels: cloid_cancels)
|
|
382
|
+
|
|
383
|
+
# Vault trading (trade on behalf of a vault)
|
|
384
|
+
vault_address = '0x...'
|
|
385
|
+
sdk.exchange.order(
|
|
386
|
+
coin: 'BTC',
|
|
387
|
+
is_buy: true,
|
|
388
|
+
size: '1.0',
|
|
389
|
+
limit_px: '95000',
|
|
390
|
+
vault_address: vault_address
|
|
391
|
+
)
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
**Order Types:**
|
|
395
|
+
- `{ limit: { tif: 'Gtc' } }` - Good-til-canceled (default)
|
|
396
|
+
- `{ limit: { tif: 'Ioc' } }` - Immediate-or-cancel
|
|
397
|
+
- `{ limit: { tif: 'Alo' } }` - Add-liquidity-only (post-only)
|
|
398
|
+
|
|
399
|
+
**Trigger Orders (Stop Loss / Take Profit):**
|
|
400
|
+
```ruby
|
|
401
|
+
# Stop loss: Sell when price drops to trigger level
|
|
402
|
+
sdk.exchange.order(
|
|
403
|
+
coin: 'BTC',
|
|
404
|
+
is_buy: false,
|
|
405
|
+
size: '0.1',
|
|
406
|
+
limit_px: '89900',
|
|
407
|
+
order_type: {
|
|
408
|
+
trigger: {
|
|
409
|
+
trigger_px: 90_000,
|
|
410
|
+
is_market: true, # Execute as market order when triggered
|
|
411
|
+
tpsl: 'sl' # Stop loss
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
# Take profit: Sell when price rises to trigger level
|
|
417
|
+
sdk.exchange.order(
|
|
418
|
+
coin: 'BTC',
|
|
419
|
+
is_buy: false,
|
|
420
|
+
size: '0.1',
|
|
421
|
+
limit_px: '100100',
|
|
422
|
+
order_type: {
|
|
423
|
+
trigger: {
|
|
424
|
+
trigger_px: 100_000,
|
|
425
|
+
is_market: false, # Execute as limit order when triggered
|
|
426
|
+
tpsl: 'tp' # Take profit
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
)
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Client Order IDs (Cloid):**
|
|
433
|
+
```ruby
|
|
434
|
+
# Create from integer (zero-padded to 16 bytes)
|
|
435
|
+
cloid = Hyperliquid::Cloid.from_int(42)
|
|
436
|
+
# => "0x0000000000000000000000000000002a"
|
|
437
|
+
|
|
438
|
+
# Create from hex string
|
|
439
|
+
cloid = Hyperliquid::Cloid.from_str('0x1234567890abcdef1234567890abcdef')
|
|
440
|
+
|
|
441
|
+
# Create from UUID
|
|
442
|
+
cloid = Hyperliquid::Cloid.from_uuid('550e8400-e29b-41d4-a716-446655440000')
|
|
443
|
+
|
|
444
|
+
# Generate random
|
|
445
|
+
cloid = Hyperliquid::Cloid.random
|
|
446
|
+
```
|
|
447
|
+
|
|
290
448
|
### Configuration
|
|
291
449
|
|
|
292
450
|
```ruby
|
|
@@ -296,12 +454,31 @@ sdk = Hyperliquid.new(timeout: 60)
|
|
|
296
454
|
# Enable retry logic for handling transient failures (default: disabled)
|
|
297
455
|
sdk = Hyperliquid.new(retry_enabled: true)
|
|
298
456
|
|
|
457
|
+
# Enable trading with a private key
|
|
458
|
+
sdk = Hyperliquid.new(private_key: ENV['HYPERLIQUID_PRIVATE_KEY'])
|
|
459
|
+
|
|
460
|
+
# Set global order expiration (orders expire after this timestamp)
|
|
461
|
+
expires_at_ms = (Time.now.to_f * 1000).to_i + 30_000 # 30 seconds from now
|
|
462
|
+
sdk = Hyperliquid.new(
|
|
463
|
+
private_key: ENV['HYPERLIQUID_PRIVATE_KEY'],
|
|
464
|
+
expires_after: expires_at_ms
|
|
465
|
+
)
|
|
466
|
+
|
|
299
467
|
# Combine multiple configuration options
|
|
300
|
-
sdk = Hyperliquid.new(
|
|
468
|
+
sdk = Hyperliquid.new(
|
|
469
|
+
testnet: true,
|
|
470
|
+
timeout: 60,
|
|
471
|
+
retry_enabled: true,
|
|
472
|
+
private_key: ENV['HYPERLIQUID_PRIVATE_KEY'],
|
|
473
|
+
expires_after: expires_at_ms
|
|
474
|
+
)
|
|
301
475
|
|
|
302
476
|
# Check which environment you're using
|
|
303
477
|
sdk.testnet? # => false
|
|
304
478
|
sdk.base_url # => "https://api.hyperliquid.xyz"
|
|
479
|
+
|
|
480
|
+
# Check if exchange is available (private_key was provided)
|
|
481
|
+
sdk.exchange # => nil if no private_key, Hyperliquid::Exchange instance otherwise
|
|
305
482
|
```
|
|
306
483
|
|
|
307
484
|
#### Retry Configuration
|
|
@@ -380,11 +557,11 @@ rake rubocop
|
|
|
380
557
|
|
|
381
558
|
## Roadmap
|
|
382
559
|
|
|
383
|
-
The
|
|
560
|
+
The SDK now supports both Info API (read) and Exchange API (trading). Future versions will include:
|
|
384
561
|
|
|
385
|
-
- Trading API (place orders, cancel orders, etc.)
|
|
386
562
|
- WebSocket support for real-time data
|
|
387
|
-
-
|
|
563
|
+
- Additional exchange operations (leverage, margin adjustments, transfers)
|
|
564
|
+
- Advanced trading features (TWAP, etc.)
|
|
388
565
|
|
|
389
566
|
## Contributing
|
|
390
567
|
|