oxarchive 0.4.0__tar.gz → 0.4.2__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oxarchive
3
- Version: 0.4.0
3
+ Version: 0.4.2
4
4
  Summary: Official Python SDK for 0xarchive - Hyperliquid Historical Data API
5
5
  Project-URL: Homepage, https://0xarchive.io
6
6
  Project-URL: Documentation, https://0xarchive.io/docs/sdks
@@ -41,7 +41,7 @@ Official Python SDK for [0xarchive](https://0xarchive.io) - Historical Market Da
41
41
 
42
42
  Supports multiple exchanges:
43
43
  - **Hyperliquid** - Perpetuals data from April 2023
44
- - **Lighter.xyz** - Perpetuals data with orderbook reconstruction
44
+ - **Lighter.xyz** - Perpetuals data (August 2025+ for fills, Jan 2026+ for OB, OI, Funding Rate)
45
45
 
46
46
  ## Installation
47
47
 
@@ -187,17 +187,47 @@ result = await client.hyperliquid.trades.alist("ETH", start=..., end=...)
187
187
  ### Instruments
188
188
 
189
189
  ```python
190
- # List all trading instruments
190
+ # List all trading instruments (Hyperliquid)
191
191
  instruments = client.hyperliquid.instruments.list()
192
192
 
193
193
  # Get specific instrument details
194
194
  btc = client.hyperliquid.instruments.get("BTC")
195
+ print(f"BTC size decimals: {btc.sz_decimals}")
195
196
 
196
197
  # Async versions
197
198
  instruments = await client.hyperliquid.instruments.alist()
198
199
  btc = await client.hyperliquid.instruments.aget("BTC")
199
200
  ```
200
201
 
202
+ #### Lighter.xyz Instruments
203
+
204
+ Lighter instruments have a different schema with additional fields for fees, market IDs, and minimum order amounts:
205
+
206
+ ```python
207
+ # List Lighter instruments (returns LighterInstrument, not Instrument)
208
+ lighter_instruments = client.lighter.instruments.list()
209
+
210
+ # Get specific Lighter instrument
211
+ eth = client.lighter.instruments.get("ETH")
212
+ print(f"ETH taker fee: {eth.taker_fee}")
213
+ print(f"ETH maker fee: {eth.maker_fee}")
214
+ print(f"ETH market ID: {eth.market_id}")
215
+ print(f"ETH min base amount: {eth.min_base_amount}")
216
+
217
+ # Async versions
218
+ lighter_instruments = await client.lighter.instruments.alist()
219
+ eth = await client.lighter.instruments.aget("ETH")
220
+ ```
221
+
222
+ **Key differences:**
223
+ | Field | Hyperliquid (`Instrument`) | Lighter (`LighterInstrument`) |
224
+ |-------|---------------------------|------------------------------|
225
+ | Symbol | `name` | `symbol` |
226
+ | Size decimals | `sz_decimals` | `size_decimals` |
227
+ | Fee info | Not available | `taker_fee`, `maker_fee`, `liquidation_fee` |
228
+ | Market ID | Not available | `market_id` |
229
+ | Min amounts | Not available | `min_base_amount`, `min_quote_amount` |
230
+
201
231
  ### Funding Rates
202
232
 
203
233
  ```python
@@ -450,7 +480,7 @@ Full type hint support with Pydantic models:
450
480
 
451
481
  ```python
452
482
  from oxarchive import Client
453
- from oxarchive.types import OrderBook, Trade, Instrument, FundingRate, OpenInterest
483
+ from oxarchive.types import OrderBook, Trade, Instrument, LighterInstrument, FundingRate, OpenInterest
454
484
  from oxarchive.resources.trades import CursorResponse
455
485
 
456
486
  client = Client(api_key="ox_your_api_key")
@@ -4,7 +4,7 @@ Official Python SDK for [0xarchive](https://0xarchive.io) - Historical Market Da
4
4
 
5
5
  Supports multiple exchanges:
6
6
  - **Hyperliquid** - Perpetuals data from April 2023
7
- - **Lighter.xyz** - Perpetuals data with orderbook reconstruction
7
+ - **Lighter.xyz** - Perpetuals data (August 2025+ for fills, Jan 2026+ for OB, OI, Funding Rate)
8
8
 
9
9
  ## Installation
10
10
 
@@ -150,17 +150,47 @@ result = await client.hyperliquid.trades.alist("ETH", start=..., end=...)
150
150
  ### Instruments
151
151
 
152
152
  ```python
153
- # List all trading instruments
153
+ # List all trading instruments (Hyperliquid)
154
154
  instruments = client.hyperliquid.instruments.list()
155
155
 
156
156
  # Get specific instrument details
157
157
  btc = client.hyperliquid.instruments.get("BTC")
158
+ print(f"BTC size decimals: {btc.sz_decimals}")
158
159
 
159
160
  # Async versions
160
161
  instruments = await client.hyperliquid.instruments.alist()
161
162
  btc = await client.hyperliquid.instruments.aget("BTC")
162
163
  ```
163
164
 
165
+ #### Lighter.xyz Instruments
166
+
167
+ Lighter instruments have a different schema with additional fields for fees, market IDs, and minimum order amounts:
168
+
169
+ ```python
170
+ # List Lighter instruments (returns LighterInstrument, not Instrument)
171
+ lighter_instruments = client.lighter.instruments.list()
172
+
173
+ # Get specific Lighter instrument
174
+ eth = client.lighter.instruments.get("ETH")
175
+ print(f"ETH taker fee: {eth.taker_fee}")
176
+ print(f"ETH maker fee: {eth.maker_fee}")
177
+ print(f"ETH market ID: {eth.market_id}")
178
+ print(f"ETH min base amount: {eth.min_base_amount}")
179
+
180
+ # Async versions
181
+ lighter_instruments = await client.lighter.instruments.alist()
182
+ eth = await client.lighter.instruments.aget("ETH")
183
+ ```
184
+
185
+ **Key differences:**
186
+ | Field | Hyperliquid (`Instrument`) | Lighter (`LighterInstrument`) |
187
+ |-------|---------------------------|------------------------------|
188
+ | Symbol | `name` | `symbol` |
189
+ | Size decimals | `sz_decimals` | `size_decimals` |
190
+ | Fee info | Not available | `taker_fee`, `maker_fee`, `liquidation_fee` |
191
+ | Market ID | Not available | `market_id` |
192
+ | Min amounts | Not available | `min_base_amount`, `min_quote_amount` |
193
+
164
194
  ### Funding Rates
165
195
 
166
196
  ```python
@@ -413,7 +443,7 @@ Full type hint support with Pydantic models:
413
443
 
414
444
  ```python
415
445
  from oxarchive import Client
416
- from oxarchive.types import OrderBook, Trade, Instrument, FundingRate, OpenInterest
446
+ from oxarchive.types import OrderBook, Trade, Instrument, LighterInstrument, FundingRate, OpenInterest
417
447
  from oxarchive.resources.trades import CursorResponse
418
448
 
419
449
  client = Client(api_key="ox_your_api_key")
@@ -27,6 +27,7 @@ from .types import (
27
27
  OrderBook,
28
28
  Trade,
29
29
  Instrument,
30
+ LighterInstrument,
30
31
  FundingRate,
31
32
  OpenInterest,
32
33
  OxArchiveError,
@@ -63,7 +64,7 @@ except ImportError:
63
64
  OxArchiveWs = None # type: ignore
64
65
  WsOptions = None # type: ignore
65
66
 
66
- __version__ = "0.4.0"
67
+ __version__ = "0.4.2"
67
68
 
68
69
  __all__ = [
69
70
  # Client
@@ -78,6 +79,7 @@ __all__ = [
78
79
  "OrderBook",
79
80
  "Trade",
80
81
  "Instrument",
82
+ "LighterInstrument",
81
83
  "FundingRate",
82
84
  "OpenInterest",
83
85
  "OxArchiveError",
@@ -90,7 +90,7 @@ class Client:
90
90
  """Hyperliquid exchange data (orderbook, trades, funding, OI from April 2023)"""
91
91
 
92
92
  self.lighter = LighterClient(self._http)
93
- """Lighter.xyz exchange data (orderbook reconstructed from checkpoints + deltas)"""
93
+ """Lighter.xyz exchange data (August 2025+)"""
94
94
 
95
95
  # Legacy resource namespaces (deprecated - use client.hyperliquid.* instead)
96
96
  # These will be removed in v2.0
@@ -7,6 +7,7 @@ from .resources import (
7
7
  OrderBookResource,
8
8
  TradesResource,
9
9
  InstrumentsResource,
10
+ LighterInstrumentsResource,
10
11
  FundingResource,
11
12
  OpenInterestResource,
12
13
  )
@@ -49,12 +50,13 @@ class LighterClient:
49
50
  Lighter.xyz exchange client.
50
51
 
51
52
  Access Lighter.xyz market data through the 0xarchive API.
52
- Lighter orderbooks are reconstructed from checkpoint + delta data.
53
53
 
54
54
  Example:
55
55
  >>> client = oxarchive.Client(api_key="...")
56
56
  >>> orderbook = client.lighter.orderbook.get("BTC")
57
57
  >>> trades = client.lighter.trades.list("ETH", start=..., end=...)
58
+ >>> instruments = client.lighter.instruments.list()
59
+ >>> print(f"ETH taker fee: {instruments[0].taker_fee}")
58
60
  """
59
61
 
60
62
  def __init__(self, http: HttpClient):
@@ -62,13 +64,13 @@ class LighterClient:
62
64
  base_path = "/v1/lighter"
63
65
 
64
66
  self.orderbook = OrderBookResource(http, base_path)
65
- """Order book data (reconstructed from checkpoints + deltas)"""
67
+ """Order book data (L2 snapshots)"""
66
68
 
67
69
  self.trades = TradesResource(http, base_path)
68
70
  """Trade/fill history"""
69
71
 
70
- self.instruments = InstrumentsResource(http, base_path)
71
- """Trading instruments metadata"""
72
+ self.instruments = LighterInstrumentsResource(http, base_path)
73
+ """Trading instruments metadata (returns LighterInstrument with fees, min amounts, etc.)"""
72
74
 
73
75
  self.funding = FundingResource(http, base_path)
74
76
  """Funding rates"""
@@ -2,7 +2,7 @@
2
2
 
3
3
  from .orderbook import OrderBookResource
4
4
  from .trades import TradesResource
5
- from .instruments import InstrumentsResource
5
+ from .instruments import InstrumentsResource, LighterInstrumentsResource
6
6
  from .funding import FundingResource
7
7
  from .openinterest import OpenInterestResource
8
8
 
@@ -10,6 +10,7 @@ __all__ = [
10
10
  "OrderBookResource",
11
11
  "TradesResource",
12
12
  "InstrumentsResource",
13
+ "LighterInstrumentsResource",
13
14
  "FundingResource",
14
15
  "OpenInterestResource",
15
16
  ]
@@ -0,0 +1,110 @@
1
+ """Instruments API resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..http import HttpClient
6
+ from ..types import Instrument, LighterInstrument
7
+
8
+
9
+ class InstrumentsResource:
10
+ """
11
+ Instruments API resource.
12
+
13
+ Example:
14
+ >>> # List all instruments
15
+ >>> instruments = client.instruments.list()
16
+ >>>
17
+ >>> # Get specific instrument
18
+ >>> btc = client.instruments.get("BTC")
19
+ """
20
+
21
+ def __init__(self, http: HttpClient, base_path: str = "/v1"):
22
+ self._http = http
23
+ self._base_path = base_path
24
+
25
+ def list(self) -> list[Instrument]:
26
+ """
27
+ List all available trading instruments.
28
+
29
+ Returns:
30
+ List of instruments
31
+ """
32
+ data = self._http.get(f"{self._base_path}/instruments")
33
+ return [Instrument.model_validate(item) for item in data["data"]]
34
+
35
+ async def alist(self) -> list[Instrument]:
36
+ """Async version of list()."""
37
+ data = await self._http.aget(f"{self._base_path}/instruments")
38
+ return [Instrument.model_validate(item) for item in data["data"]]
39
+
40
+ def get(self, coin: str) -> Instrument:
41
+ """
42
+ Get a specific instrument by coin symbol.
43
+
44
+ Args:
45
+ coin: The coin symbol (e.g., 'BTC', 'ETH')
46
+
47
+ Returns:
48
+ Instrument details
49
+ """
50
+ data = self._http.get(f"{self._base_path}/instruments/{coin.upper()}")
51
+ return Instrument.model_validate(data["data"])
52
+
53
+ async def aget(self, coin: str) -> Instrument:
54
+ """Async version of get()."""
55
+ data = await self._http.aget(f"{self._base_path}/instruments/{coin.upper()}")
56
+ return Instrument.model_validate(data["data"])
57
+
58
+
59
+ class LighterInstrumentsResource:
60
+ """
61
+ Lighter.xyz Instruments API resource.
62
+
63
+ Lighter instruments have a different schema than Hyperliquid with more
64
+ detailed market configuration including fees and minimum amounts.
65
+
66
+ Example:
67
+ >>> # List all Lighter instruments
68
+ >>> instruments = client.lighter.instruments.list()
69
+ >>>
70
+ >>> # Get specific instrument
71
+ >>> btc = client.lighter.instruments.get("BTC")
72
+ >>> print(f"Taker fee: {btc.taker_fee}")
73
+ """
74
+
75
+ def __init__(self, http: HttpClient, base_path: str = "/v1/lighter"):
76
+ self._http = http
77
+ self._base_path = base_path
78
+
79
+ def list(self) -> list[LighterInstrument]:
80
+ """
81
+ List all available Lighter trading instruments.
82
+
83
+ Returns:
84
+ List of Lighter instruments with full market configuration
85
+ """
86
+ data = self._http.get(f"{self._base_path}/instruments")
87
+ return [LighterInstrument.model_validate(item) for item in data["data"]]
88
+
89
+ async def alist(self) -> list[LighterInstrument]:
90
+ """Async version of list()."""
91
+ data = await self._http.aget(f"{self._base_path}/instruments")
92
+ return [LighterInstrument.model_validate(item) for item in data["data"]]
93
+
94
+ def get(self, coin: str) -> LighterInstrument:
95
+ """
96
+ Get a specific Lighter instrument by coin symbol.
97
+
98
+ Args:
99
+ coin: The coin symbol (e.g., 'BTC', 'ETH')
100
+
101
+ Returns:
102
+ Lighter instrument details with full market configuration
103
+ """
104
+ data = self._http.get(f"{self._base_path}/instruments/{coin.upper()}")
105
+ return LighterInstrument.model_validate(data["data"])
106
+
107
+ async def aget(self, coin: str) -> LighterInstrument:
108
+ """Async version of get()."""
109
+ data = await self._http.aget(f"{self._base_path}/instruments/{coin.upper()}")
110
+ return LighterInstrument.model_validate(data["data"])
@@ -140,7 +140,7 @@ class Trade(BaseModel):
140
140
 
141
141
 
142
142
  class Instrument(BaseModel):
143
- """Trading instrument specification."""
143
+ """Trading instrument specification (Hyperliquid)."""
144
144
 
145
145
  model_config = {"populate_by_name": True}
146
146
 
@@ -163,6 +163,53 @@ class Instrument(BaseModel):
163
163
  """Whether the instrument is currently tradeable."""
164
164
 
165
165
 
166
+ class LighterInstrument(BaseModel):
167
+ """Trading instrument specification (Lighter.xyz).
168
+
169
+ Lighter instruments have a different schema than Hyperliquid with more
170
+ detailed market configuration including fees and minimum amounts.
171
+ """
172
+
173
+ symbol: str
174
+ """Instrument symbol (e.g., BTC, ETH)."""
175
+
176
+ market_id: int
177
+ """Unique market identifier."""
178
+
179
+ market_type: str
180
+ """Market type (e.g., 'perp')."""
181
+
182
+ status: str
183
+ """Market status (e.g., 'active')."""
184
+
185
+ taker_fee: float
186
+ """Taker fee rate (e.g., 0.0005 = 0.05%)."""
187
+
188
+ maker_fee: float
189
+ """Maker fee rate (e.g., 0.0002 = 0.02%)."""
190
+
191
+ liquidation_fee: float
192
+ """Liquidation fee rate."""
193
+
194
+ min_base_amount: float
195
+ """Minimum order size in base currency."""
196
+
197
+ min_quote_amount: float
198
+ """Minimum order size in quote currency."""
199
+
200
+ size_decimals: int
201
+ """Size decimal precision."""
202
+
203
+ price_decimals: int
204
+ """Price decimal precision."""
205
+
206
+ quote_decimals: int
207
+ """Quote currency decimal precision."""
208
+
209
+ is_active: bool
210
+ """Whether the instrument is currently tradeable."""
211
+
212
+
166
213
  # =============================================================================
167
214
  # Funding Types
168
215
  # =============================================================================
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "oxarchive"
7
- version = "0.4.0"
7
+ version = "0.4.2"
8
8
  description = "Official Python SDK for 0xarchive - Hyperliquid Historical Data API"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -1,56 +0,0 @@
1
- """Instruments API resource."""
2
-
3
- from __future__ import annotations
4
-
5
- from ..http import HttpClient
6
- from ..types import Instrument
7
-
8
-
9
- class InstrumentsResource:
10
- """
11
- Instruments API resource.
12
-
13
- Example:
14
- >>> # List all instruments
15
- >>> instruments = client.instruments.list()
16
- >>>
17
- >>> # Get specific instrument
18
- >>> btc = client.instruments.get("BTC")
19
- """
20
-
21
- def __init__(self, http: HttpClient, base_path: str = "/v1"):
22
- self._http = http
23
- self._base_path = base_path
24
-
25
- def list(self) -> list[Instrument]:
26
- """
27
- List all available trading instruments.
28
-
29
- Returns:
30
- List of instruments
31
- """
32
- data = self._http.get(f"{self._base_path}/instruments")
33
- return [Instrument.model_validate(item) for item in data["data"]]
34
-
35
- async def alist(self) -> list[Instrument]:
36
- """Async version of list()."""
37
- data = await self._http.aget(f"{self._base_path}/instruments")
38
- return [Instrument.model_validate(item) for item in data["data"]]
39
-
40
- def get(self, coin: str) -> Instrument:
41
- """
42
- Get a specific instrument by coin symbol.
43
-
44
- Args:
45
- coin: The coin symbol (e.g., 'BTC', 'ETH')
46
-
47
- Returns:
48
- Instrument details
49
- """
50
- data = self._http.get(f"{self._base_path}/instruments/{coin.upper()}")
51
- return Instrument.model_validate(data["data"])
52
-
53
- async def aget(self, coin: str) -> Instrument:
54
- """Async version of get()."""
55
- data = await self._http.aget(f"{self._base_path}/instruments/{coin.upper()}")
56
- return Instrument.model_validate(data["data"])
File without changes
File without changes