hotstuff-python-sdk 0.0.1b2__py3-none-any.whl → 0.0.1b4__py3-none-any.whl
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.
- hotstuff/__init__.py +73 -3
- hotstuff/apis/exchange.py +15 -14
- hotstuff/apis/info.py +7 -7
- hotstuff/apis/subscription.py +9 -22
- hotstuff/exceptions.py +72 -0
- hotstuff/methods/exchange/account.py +1 -23
- hotstuff/methods/exchange/collateral.py +2 -24
- hotstuff/methods/exchange/trading.py +47 -16
- hotstuff/methods/exchange/vault.py +2 -24
- hotstuff/methods/info/account.py +54 -32
- hotstuff/methods/info/global.py +65 -249
- hotstuff/methods/info/market.py +256 -0
- hotstuff/methods/subscription/channels.py +200 -0
- hotstuff/methods/subscription/global.py +55 -200
- hotstuff/transports/http.py +36 -6
- hotstuff/utils/__init__.py +4 -1
- hotstuff/utils/signing.py +59 -22
- {hotstuff_python_sdk-0.0.1b2.dist-info → hotstuff_python_sdk-0.0.1b4.dist-info}/METADATA +564 -158
- hotstuff_python_sdk-0.0.1b4.dist-info/RECORD +38 -0
- hotstuff_python_sdk-0.0.1b2.dist-info/RECORD +0 -35
- {hotstuff_python_sdk-0.0.1b2.dist-info → hotstuff_python_sdk-0.0.1b4.dist-info}/LICENSE +0 -0
- {hotstuff_python_sdk-0.0.1b2.dist-info → hotstuff_python_sdk-0.0.1b4.dist-info}/WHEEL +0 -0
hotstuff/methods/info/account.py
CHANGED
|
@@ -1,30 +1,8 @@
|
|
|
1
1
|
"""Account info method types."""
|
|
2
2
|
from typing import List, Literal, Optional, Annotated
|
|
3
3
|
from pydantic import BaseModel, Field, ConfigDict, field_validator, RootModel
|
|
4
|
-
from eth_utils import is_address, to_checksum_address
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
def validate_ethereum_address(value: str) -> str:
|
|
8
|
-
"""
|
|
9
|
-
Validate and normalize an Ethereum address.
|
|
10
|
-
|
|
11
|
-
Args:
|
|
12
|
-
value: The address string to validate
|
|
13
|
-
|
|
14
|
-
Returns:
|
|
15
|
-
Checksummed address string
|
|
16
|
-
|
|
17
|
-
Raises:
|
|
18
|
-
ValueError: If the address is invalid
|
|
19
|
-
"""
|
|
20
|
-
if not isinstance(value, str):
|
|
21
|
-
raise ValueError(f"Address must be a string, got {type(value)}")
|
|
22
|
-
|
|
23
|
-
if not is_address(value):
|
|
24
|
-
raise ValueError(f"Invalid Ethereum address: {value}")
|
|
25
|
-
|
|
26
|
-
# Return checksummed address (EIP-55)
|
|
27
|
-
return to_checksum_address(value)
|
|
5
|
+
from hotstuff.utils.address import validate_ethereum_address
|
|
28
6
|
|
|
29
7
|
|
|
30
8
|
# Type alias for validated Ethereum addresses (similar to viem's Address type)
|
|
@@ -54,6 +32,8 @@ class OpenOrdersParams(BaseModel):
|
|
|
54
32
|
|
|
55
33
|
class OpenOrder(BaseModel):
|
|
56
34
|
"""Open order information."""
|
|
35
|
+
model_config = ConfigDict(extra='allow')
|
|
36
|
+
|
|
57
37
|
order_id: int
|
|
58
38
|
user: str
|
|
59
39
|
instrument_id: int
|
|
@@ -65,17 +45,28 @@ class OpenOrder(BaseModel):
|
|
|
65
45
|
state: Literal["open", "filled", "cancelled", "triggered"]
|
|
66
46
|
cloid: str
|
|
67
47
|
tif: Literal["GTC", "IOC", "FOK"]
|
|
68
|
-
tpsl:
|
|
69
|
-
trigger_px: str
|
|
70
|
-
trigger_price: Optional[str] = None
|
|
48
|
+
tpsl: Optional[str] = None # Can be "tp", "sl", or ""
|
|
49
|
+
trigger_px: Optional[str] = None
|
|
50
|
+
trigger_price: Optional[str] = None # Alternative field name
|
|
71
51
|
post_only: bool
|
|
72
52
|
reduce_only: bool
|
|
53
|
+
is_market: Optional[bool] = None # Optional market order flag
|
|
54
|
+
grouping: Optional[str] = None # Optional grouping
|
|
73
55
|
timestamp: str
|
|
74
56
|
|
|
75
57
|
|
|
76
58
|
class OpenOrdersResponse(BaseModel):
|
|
77
59
|
"""Open orders response."""
|
|
78
|
-
|
|
60
|
+
model_config = ConfigDict(extra='allow')
|
|
61
|
+
|
|
62
|
+
orders: List[OpenOrder] = Field(default_factory=list, description="List of open orders")
|
|
63
|
+
# Pagination fields (optional)
|
|
64
|
+
page: Optional[int] = None
|
|
65
|
+
limit: Optional[int] = None
|
|
66
|
+
total_count: Optional[int] = Field(None, alias="totalCount")
|
|
67
|
+
total_pages: Optional[int] = Field(None, alias="totalPages")
|
|
68
|
+
has_next: Optional[bool] = Field(None, alias="hasNext")
|
|
69
|
+
has_prev: Optional[bool] = Field(None, alias="hasPrev")
|
|
79
70
|
|
|
80
71
|
|
|
81
72
|
# Positions Method
|
|
@@ -91,9 +82,28 @@ class PositionsParams(BaseModel):
|
|
|
91
82
|
return validate_ethereum_address(v)
|
|
92
83
|
|
|
93
84
|
|
|
94
|
-
class
|
|
95
|
-
"""
|
|
96
|
-
|
|
85
|
+
class Position(BaseModel):
|
|
86
|
+
"""Individual position information."""
|
|
87
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
88
|
+
|
|
89
|
+
user: str
|
|
90
|
+
instrument_id: int = Field(alias="instrumentId")
|
|
91
|
+
instrument: str
|
|
92
|
+
side: Literal["LONG", "SHORT"]
|
|
93
|
+
size: str
|
|
94
|
+
entry_price: str = Field(alias="entryPrice")
|
|
95
|
+
mark_price: Optional[str] = Field(None, alias="markPrice")
|
|
96
|
+
margin: str
|
|
97
|
+
unrealized_pnl: str = Field(alias="unrealizedPnl")
|
|
98
|
+
realized_pnl: Optional[str] = Field(None, alias="realizedPnl")
|
|
99
|
+
liquidation_price: Optional[str] = Field(None, alias="liquidationPrice")
|
|
100
|
+
leverage: Optional[str] = None
|
|
101
|
+
margin_type: Optional[str] = Field(None, alias="marginType")
|
|
102
|
+
updated_at: Optional[int] = Field(None, alias="updatedAt")
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Note: positions endpoint returns List[Position] directly, not wrapped in PositionsResponse
|
|
106
|
+
PositionsResponse = List[Position]
|
|
97
107
|
|
|
98
108
|
|
|
99
109
|
# Account Summary Method
|
|
@@ -131,7 +141,13 @@ class ReferralSummaryParams(BaseModel):
|
|
|
131
141
|
|
|
132
142
|
class ReferralSummaryResponse(BaseModel):
|
|
133
143
|
"""Referral summary response."""
|
|
134
|
-
|
|
144
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
145
|
+
|
|
146
|
+
referral_code: Optional[str] = Field(None, alias="referralCode")
|
|
147
|
+
total_referrals: Optional[int] = Field(None, alias="totalReferrals")
|
|
148
|
+
total_volume: Optional[str] = Field(None, alias="totalVolume")
|
|
149
|
+
total_rewards: Optional[str] = Field(None, alias="totalRewards")
|
|
150
|
+
tier: Optional[str] = None
|
|
135
151
|
|
|
136
152
|
|
|
137
153
|
# User Fee Info Method
|
|
@@ -148,7 +164,13 @@ class UserFeeInfoParams(BaseModel):
|
|
|
148
164
|
|
|
149
165
|
class UserFeeInfoResponse(BaseModel):
|
|
150
166
|
"""User fee info response."""
|
|
151
|
-
|
|
167
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
168
|
+
|
|
169
|
+
maker_fee: Optional[str] = Field(None, alias="makerFee")
|
|
170
|
+
taker_fee: Optional[str] = Field(None, alias="takerFee")
|
|
171
|
+
volume_tier: Optional[str] = Field(None, alias="volumeTier")
|
|
172
|
+
trading_volume_30d: Optional[str] = Field(None, alias="tradingVolume30d")
|
|
173
|
+
discount: Optional[str] = None
|
|
152
174
|
|
|
153
175
|
|
|
154
176
|
# Account History Method
|
hotstuff/methods/info/global.py
CHANGED
|
@@ -1,249 +1,65 @@
|
|
|
1
|
-
"""Global info method types.
|
|
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
|
-
type: Literal["perps", "spot", "all"] = Field(..., description="Instrument type filter")
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
class MarginTier(BaseModel):
|
|
70
|
-
"""Margin tier configuration."""
|
|
71
|
-
notional_usd_threshold: str
|
|
72
|
-
max_leverage: int
|
|
73
|
-
mmr: float # Can be fractional
|
|
74
|
-
mmd: int
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
class PerpInstrument(BaseModel):
|
|
78
|
-
"""Perpetual instrument information."""
|
|
79
|
-
id: int
|
|
80
|
-
name: str
|
|
81
|
-
price_index: str
|
|
82
|
-
lot_size: float # Can be fractional (e.g., 1e-05)
|
|
83
|
-
tick_size: float # Can be fractional (e.g., 0.1, 1e-06)
|
|
84
|
-
settlement_currency: int
|
|
85
|
-
only_isolated: bool
|
|
86
|
-
max_leverage: int
|
|
87
|
-
delisted: bool
|
|
88
|
-
min_notional_usd: int
|
|
89
|
-
margin_tiers: List[MarginTier]
|
|
90
|
-
listed_at_block_timestamp: int
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
class SpotInstrument(BaseModel):
|
|
94
|
-
"""Spot instrument information."""
|
|
95
|
-
id: int
|
|
96
|
-
name: str
|
|
97
|
-
price_index: str
|
|
98
|
-
lot_size: int
|
|
99
|
-
tick_size: float # Can be fractional (e.g., 0.0001)
|
|
100
|
-
base_asset: int
|
|
101
|
-
quote_asset: int
|
|
102
|
-
stable_pair: bool
|
|
103
|
-
min_size_in_quote_asset: int
|
|
104
|
-
listed_at_block_timestamp: int
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
class InstrumentsResponse(BaseModel):
|
|
108
|
-
"""Instruments response."""
|
|
109
|
-
perps: List[PerpInstrument]
|
|
110
|
-
spot: List[SpotInstrument]
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
# Ticker Method
|
|
114
|
-
class TickerParams(BaseModel):
|
|
115
|
-
"""Parameters for ticker query."""
|
|
116
|
-
symbol: str = Field(..., description="Trading pair symbol")
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
class Ticker(BaseModel):
|
|
120
|
-
"""Ticker information."""
|
|
121
|
-
type: Literal["perp", "spot"]
|
|
122
|
-
symbol: str
|
|
123
|
-
mark_price: str
|
|
124
|
-
mid_price: str
|
|
125
|
-
index_price: str
|
|
126
|
-
best_bid_price: str
|
|
127
|
-
best_ask_price: str
|
|
128
|
-
best_bid_size: str
|
|
129
|
-
best_ask_size: str
|
|
130
|
-
funding_rate: str
|
|
131
|
-
open_interest: str
|
|
132
|
-
volume_24h: str
|
|
133
|
-
change_24h: str
|
|
134
|
-
max_trading_price: str
|
|
135
|
-
min_trading_price: str
|
|
136
|
-
last_updated: int
|
|
137
|
-
last_price: str
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
# Orderbook Method
|
|
141
|
-
class OrderbookParams(BaseModel):
|
|
142
|
-
"""Parameters for orderbook query."""
|
|
143
|
-
symbol: str = Field(..., description="Trading pair symbol")
|
|
144
|
-
depth: Optional[int] = Field(None, description="Orderbook depth")
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
class OrderbookLevel(BaseModel):
|
|
148
|
-
"""Orderbook level (bid/ask)."""
|
|
149
|
-
price: str # API may return int/float, but we store as string for precision
|
|
150
|
-
size: str # API may return int/float, but we store as string for precision
|
|
151
|
-
|
|
152
|
-
@field_validator('price', mode='before')
|
|
153
|
-
@classmethod
|
|
154
|
-
def convert_price_to_string(cls, v: Union[str, int, float]) -> str:
|
|
155
|
-
"""Convert numeric price to string."""
|
|
156
|
-
if not isinstance(v, str):
|
|
157
|
-
return str(v)
|
|
158
|
-
return v
|
|
159
|
-
|
|
160
|
-
@field_validator('size', mode='before')
|
|
161
|
-
@classmethod
|
|
162
|
-
def convert_size_to_string(cls, v: Union[str, int, float]) -> str:
|
|
163
|
-
"""Convert numeric size to string."""
|
|
164
|
-
if not isinstance(v, str):
|
|
165
|
-
return str(v)
|
|
166
|
-
return v
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
class OrderbookResponse(BaseModel):
|
|
170
|
-
"""Orderbook response."""
|
|
171
|
-
bids: List[OrderbookLevel]
|
|
172
|
-
asks: List[OrderbookLevel]
|
|
173
|
-
instrument_name: str
|
|
174
|
-
timestamp: int
|
|
175
|
-
sequence_number: int
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
# Trades Method
|
|
179
|
-
class TradesParams(BaseModel):
|
|
180
|
-
"""Parameters for trades query."""
|
|
181
|
-
symbol: str = Field(..., description="Trading pair symbol")
|
|
182
|
-
limit: Optional[int] = Field(None, description="Number of trades to return")
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
class Trade(BaseModel):
|
|
186
|
-
"""Trade information."""
|
|
187
|
-
instrument_id: int
|
|
188
|
-
instrument: str
|
|
189
|
-
trade_id: int
|
|
190
|
-
tx_hash: str
|
|
191
|
-
side: Literal["b", "s"]
|
|
192
|
-
price: str
|
|
193
|
-
size: str
|
|
194
|
-
maker: str
|
|
195
|
-
taker: str
|
|
196
|
-
timestamp: str
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
# Mids Method
|
|
200
|
-
class MidsParams(BaseModel):
|
|
201
|
-
"""Parameters for mids query."""
|
|
202
|
-
pass
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
class Mid(BaseModel):
|
|
206
|
-
"""Mid price information."""
|
|
207
|
-
symbol: str
|
|
208
|
-
mid_price: str
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
# BBO Method
|
|
212
|
-
class BBOParams(BaseModel):
|
|
213
|
-
"""Parameters for best bid/offer query."""
|
|
214
|
-
symbol: str = Field(..., description="Trading pair symbol")
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
class BBO(BaseModel):
|
|
218
|
-
"""Best bid/offer information."""
|
|
219
|
-
symbol: str
|
|
220
|
-
best_bid_price: str
|
|
221
|
-
best_ask_price: str
|
|
222
|
-
best_bid_size: str
|
|
223
|
-
best_ask_size: str
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
# Chart Method
|
|
227
|
-
SupportedChartResolutions = Literal["1", "5", "15", "60", "240", "1D", "1W"]
|
|
228
|
-
SupportedChartTypes = Literal["mark", "ltp", "index"]
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
class ChartParams(BaseModel):
|
|
232
|
-
"""Parameters for chart data query."""
|
|
233
|
-
model_config = ConfigDict(populate_by_name=True)
|
|
234
|
-
|
|
235
|
-
symbol: str = Field(..., description="Trading pair symbol")
|
|
236
|
-
resolution: SupportedChartResolutions = Field(..., description="Chart resolution")
|
|
237
|
-
from_: int = Field(..., alias="from", description="Start timestamp")
|
|
238
|
-
to: int = Field(..., description="End timestamp")
|
|
239
|
-
chart_type: SupportedChartTypes = Field(..., description="Chart type")
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
class ChartPoint(BaseModel):
|
|
243
|
-
"""Chart data point."""
|
|
244
|
-
open: float
|
|
245
|
-
high: float
|
|
246
|
-
low: float
|
|
247
|
-
close: float
|
|
248
|
-
volume: float
|
|
249
|
-
time: int
|
|
1
|
+
"""Global info method types.
|
|
2
|
+
|
|
3
|
+
DEPRECATED: This module is deprecated. Import from hotstuff.methods.info.market instead.
|
|
4
|
+
This module exists for backward compatibility only.
|
|
5
|
+
"""
|
|
6
|
+
# Re-export everything from market.py for backward compatibility
|
|
7
|
+
from hotstuff.methods.info.market import (
|
|
8
|
+
OracleParams,
|
|
9
|
+
OracleResponse,
|
|
10
|
+
SupportedCollateralParams,
|
|
11
|
+
BridgeByChain,
|
|
12
|
+
WeightTier,
|
|
13
|
+
CollRisk,
|
|
14
|
+
SupportedCollateral,
|
|
15
|
+
InstrumentsParams,
|
|
16
|
+
MarginTier,
|
|
17
|
+
PerpInstrument,
|
|
18
|
+
SpotInstrument,
|
|
19
|
+
InstrumentsResponse,
|
|
20
|
+
TickerParams,
|
|
21
|
+
Ticker,
|
|
22
|
+
OrderbookParams,
|
|
23
|
+
OrderbookLevel,
|
|
24
|
+
OrderbookResponse,
|
|
25
|
+
TradesParams,
|
|
26
|
+
Trade,
|
|
27
|
+
MidsParams,
|
|
28
|
+
Mid,
|
|
29
|
+
BBOParams,
|
|
30
|
+
BBO,
|
|
31
|
+
SupportedChartResolutions,
|
|
32
|
+
SupportedChartTypes,
|
|
33
|
+
ChartParams,
|
|
34
|
+
ChartPoint,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
__all__ = [
|
|
38
|
+
"OracleParams",
|
|
39
|
+
"OracleResponse",
|
|
40
|
+
"SupportedCollateralParams",
|
|
41
|
+
"BridgeByChain",
|
|
42
|
+
"WeightTier",
|
|
43
|
+
"CollRisk",
|
|
44
|
+
"SupportedCollateral",
|
|
45
|
+
"InstrumentsParams",
|
|
46
|
+
"MarginTier",
|
|
47
|
+
"PerpInstrument",
|
|
48
|
+
"SpotInstrument",
|
|
49
|
+
"InstrumentsResponse",
|
|
50
|
+
"TickerParams",
|
|
51
|
+
"Ticker",
|
|
52
|
+
"OrderbookParams",
|
|
53
|
+
"OrderbookLevel",
|
|
54
|
+
"OrderbookResponse",
|
|
55
|
+
"TradesParams",
|
|
56
|
+
"Trade",
|
|
57
|
+
"MidsParams",
|
|
58
|
+
"Mid",
|
|
59
|
+
"BBOParams",
|
|
60
|
+
"BBO",
|
|
61
|
+
"SupportedChartResolutions",
|
|
62
|
+
"SupportedChartTypes",
|
|
63
|
+
"ChartParams",
|
|
64
|
+
"ChartPoint",
|
|
65
|
+
]
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"""Market info method types (public/global market data)."""
|
|
2
|
+
from typing import List, Literal, Optional, Union
|
|
3
|
+
from pydantic import BaseModel, Field, ConfigDict, field_validator
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Oracle Method
|
|
7
|
+
class OracleParams(BaseModel):
|
|
8
|
+
"""Parameters for oracle price query."""
|
|
9
|
+
symbol: str = Field(..., description="Symbol to get oracle price for")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class OracleResponse(BaseModel):
|
|
13
|
+
"""Oracle price response."""
|
|
14
|
+
symbol: str
|
|
15
|
+
index_price: str
|
|
16
|
+
ext_mark_price: str
|
|
17
|
+
updated_at: int
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# Supported Collateral Method
|
|
21
|
+
class SupportedCollateralParams(BaseModel):
|
|
22
|
+
"""Parameters for supported collateral query."""
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class BridgeByChain(BaseModel):
|
|
27
|
+
"""Bridge chain configuration."""
|
|
28
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
29
|
+
|
|
30
|
+
bridge_chain_type: int = Field(alias="bridgeChainType")
|
|
31
|
+
bridge_chain_id: int = Field(alias="bridgeChainId")
|
|
32
|
+
token_address: str = Field(alias="tokenAddress")
|
|
33
|
+
bridge_contract_address: str = Field(alias="bridgeContractAddress")
|
|
34
|
+
enabled: bool
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class WeightTier(BaseModel):
|
|
38
|
+
"""Weight tier configuration."""
|
|
39
|
+
model_config = ConfigDict(extra='allow')
|
|
40
|
+
|
|
41
|
+
amount: float # Can be large numbers as float
|
|
42
|
+
weight: float # Can be fractional
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class CollRisk(BaseModel):
|
|
46
|
+
"""Collateral risk configuration."""
|
|
47
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
48
|
+
|
|
49
|
+
weight_tiers: Optional[List[WeightTier]] = Field(default=None, alias="weightTiers")
|
|
50
|
+
max_margin_cap: Optional[float] = Field(default=None, alias="maxMarginCap")
|
|
51
|
+
stale_price_guard_weight: Optional[float] = Field(default=None, alias="stalePriceGuardWeight")
|
|
52
|
+
enabled: Optional[bool] = None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class SupportedCollateral(BaseModel):
|
|
56
|
+
"""Supported collateral information."""
|
|
57
|
+
model_config = ConfigDict(populate_by_name=True, extra='allow')
|
|
58
|
+
|
|
59
|
+
id: int
|
|
60
|
+
symbol: str
|
|
61
|
+
name: str
|
|
62
|
+
decimals: int
|
|
63
|
+
default_coll_weight: Optional[float] = Field(default=None, alias="defaultCollWeight")
|
|
64
|
+
price_index: Optional[str] = Field(default=None, alias="priceIndex")
|
|
65
|
+
type: Optional[int] = None
|
|
66
|
+
bridge_by_chain: Optional[List[BridgeByChain]] = Field(default=None, alias="bridgeByChain")
|
|
67
|
+
coll_risk: Optional[CollRisk] = Field(default=None, alias="collRisk")
|
|
68
|
+
withdrawal_fee: Optional[int] = Field(default=None, alias="withdrawalFee")
|
|
69
|
+
added_at_block: Optional[int] = Field(default=None, alias="addedAtBlock")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Instruments Method
|
|
73
|
+
class InstrumentsParams(BaseModel):
|
|
74
|
+
"""Parameters for instruments query."""
|
|
75
|
+
type: Literal["perps", "spot", "all"] = Field(..., description="Instrument type filter")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class MarginTier(BaseModel):
|
|
79
|
+
"""Margin tier configuration."""
|
|
80
|
+
notional_usd_threshold: str
|
|
81
|
+
max_leverage: int
|
|
82
|
+
mmr: float
|
|
83
|
+
mmd: int
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class PerpInstrument(BaseModel):
|
|
87
|
+
"""Perpetual instrument information."""
|
|
88
|
+
id: int
|
|
89
|
+
name: str
|
|
90
|
+
price_index: str
|
|
91
|
+
lot_size: float
|
|
92
|
+
tick_size: float
|
|
93
|
+
settlement_currency: int
|
|
94
|
+
only_isolated: bool
|
|
95
|
+
max_leverage: int
|
|
96
|
+
delisted: bool
|
|
97
|
+
min_notional_usd: int
|
|
98
|
+
margin_tiers: List[MarginTier]
|
|
99
|
+
listed_at_block_timestamp: int
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class SpotInstrument(BaseModel):
|
|
103
|
+
"""Spot instrument information."""
|
|
104
|
+
id: int
|
|
105
|
+
name: str
|
|
106
|
+
price_index: str
|
|
107
|
+
lot_size: int
|
|
108
|
+
tick_size: float
|
|
109
|
+
base_asset: int
|
|
110
|
+
quote_asset: int
|
|
111
|
+
stable_pair: bool
|
|
112
|
+
min_size_in_quote_asset: int
|
|
113
|
+
listed_at_block_timestamp: int
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class InstrumentsResponse(BaseModel):
|
|
117
|
+
"""Instruments response."""
|
|
118
|
+
perps: List[PerpInstrument]
|
|
119
|
+
spot: List[SpotInstrument]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# Ticker Method
|
|
123
|
+
class TickerParams(BaseModel):
|
|
124
|
+
"""Parameters for ticker query."""
|
|
125
|
+
symbol: str = Field(..., description="Trading pair symbol")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class Ticker(BaseModel):
|
|
129
|
+
"""Ticker information."""
|
|
130
|
+
model_config = ConfigDict(extra='allow')
|
|
131
|
+
|
|
132
|
+
type: Optional[str] = None
|
|
133
|
+
symbol: str
|
|
134
|
+
mark_price: str
|
|
135
|
+
mid_price: str
|
|
136
|
+
index_price: str
|
|
137
|
+
best_bid_price: str
|
|
138
|
+
best_ask_price: str
|
|
139
|
+
best_bid_size: str
|
|
140
|
+
best_ask_size: str
|
|
141
|
+
funding_rate: Optional[str] = None
|
|
142
|
+
open_interest: Optional[str] = None
|
|
143
|
+
volume_24h: str
|
|
144
|
+
change_24h: str
|
|
145
|
+
max_trading_price: Optional[str] = None
|
|
146
|
+
min_trading_price: Optional[str] = None
|
|
147
|
+
last_updated: int
|
|
148
|
+
last_price: Optional[str] = None
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
# Orderbook Method
|
|
152
|
+
class OrderbookParams(BaseModel):
|
|
153
|
+
"""Parameters for orderbook query."""
|
|
154
|
+
symbol: str = Field(..., description="Trading pair symbol")
|
|
155
|
+
depth: Optional[int] = Field(None, description="Orderbook depth")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
class OrderbookLevel(BaseModel):
|
|
159
|
+
"""Orderbook level (bid/ask)."""
|
|
160
|
+
price: str
|
|
161
|
+
size: str
|
|
162
|
+
|
|
163
|
+
@field_validator('price', mode='before')
|
|
164
|
+
@classmethod
|
|
165
|
+
def convert_price_to_string(cls, v: Union[str, int, float]) -> str:
|
|
166
|
+
"""Convert numeric price to string."""
|
|
167
|
+
return str(v) if not isinstance(v, str) else v
|
|
168
|
+
|
|
169
|
+
@field_validator('size', mode='before')
|
|
170
|
+
@classmethod
|
|
171
|
+
def convert_size_to_string(cls, v: Union[str, int, float]) -> str:
|
|
172
|
+
"""Convert numeric size to string."""
|
|
173
|
+
return str(v) if not isinstance(v, str) else v
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class OrderbookResponse(BaseModel):
|
|
177
|
+
"""Orderbook response."""
|
|
178
|
+
bids: List[OrderbookLevel]
|
|
179
|
+
asks: List[OrderbookLevel]
|
|
180
|
+
instrument_name: str
|
|
181
|
+
timestamp: int
|
|
182
|
+
sequence_number: int
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# Trades Method
|
|
186
|
+
class TradesParams(BaseModel):
|
|
187
|
+
"""Parameters for trades query."""
|
|
188
|
+
symbol: str = Field(..., description="Trading pair symbol")
|
|
189
|
+
limit: Optional[int] = Field(None, description="Number of trades to return")
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
class Trade(BaseModel):
|
|
193
|
+
"""Trade information."""
|
|
194
|
+
instrument_id: int
|
|
195
|
+
instrument: str
|
|
196
|
+
trade_id: int
|
|
197
|
+
tx_hash: str
|
|
198
|
+
side: Literal["b", "s"]
|
|
199
|
+
price: str
|
|
200
|
+
size: str
|
|
201
|
+
maker: str
|
|
202
|
+
taker: str
|
|
203
|
+
timestamp: str
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
# Mids Method
|
|
207
|
+
class MidsParams(BaseModel):
|
|
208
|
+
"""Parameters for mids query."""
|
|
209
|
+
pass
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
class Mid(BaseModel):
|
|
213
|
+
"""Mid price information."""
|
|
214
|
+
symbol: str
|
|
215
|
+
mid_price: str
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
# BBO Method
|
|
219
|
+
class BBOParams(BaseModel):
|
|
220
|
+
"""Parameters for best bid/offer query."""
|
|
221
|
+
symbol: str = Field(..., description="Trading pair symbol")
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
class BBO(BaseModel):
|
|
225
|
+
"""Best bid/offer information."""
|
|
226
|
+
symbol: str
|
|
227
|
+
best_bid_price: str
|
|
228
|
+
best_ask_price: str
|
|
229
|
+
best_bid_size: str
|
|
230
|
+
best_ask_size: str
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# Chart Method
|
|
234
|
+
SupportedChartResolutions = Literal["1", "5", "15", "60", "240", "1D", "1W"]
|
|
235
|
+
SupportedChartTypes = Literal["mark", "ltp", "index"]
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
class ChartParams(BaseModel):
|
|
239
|
+
"""Parameters for chart data query."""
|
|
240
|
+
model_config = ConfigDict(populate_by_name=True)
|
|
241
|
+
|
|
242
|
+
symbol: str = Field(..., description="Trading pair symbol")
|
|
243
|
+
resolution: SupportedChartResolutions = Field(..., description="Chart resolution")
|
|
244
|
+
from_: int = Field(..., alias="from", description="Start timestamp")
|
|
245
|
+
to: int = Field(..., description="End timestamp")
|
|
246
|
+
chart_type: SupportedChartTypes = Field(..., description="Chart type")
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class ChartPoint(BaseModel):
|
|
250
|
+
"""Chart data point."""
|
|
251
|
+
open: float
|
|
252
|
+
high: float
|
|
253
|
+
low: float
|
|
254
|
+
close: float
|
|
255
|
+
volume: float
|
|
256
|
+
time: int
|