hotstuff-python-sdk 0.0.1b1__py3-none-any.whl → 0.0.1b3__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.
@@ -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: Literal["tp", "sl", ""]
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
- orders: List[OpenOrder] = Field(..., description="List of open orders")
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 PositionsResponse(BaseModel):
95
- """Positions response."""
96
- pass
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
- pass
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
- pass
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
@@ -1,249 +1,65 @@
1
- """Global info method types."""
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
- bridge_chain_type: int
29
- bridge_chain_id: int
30
- token_address: str
31
- bridge_contract_address: str
32
- enabled: bool
33
-
34
-
35
- class WeightTier(BaseModel):
36
- """Weight tier configuration."""
37
- amount: int
38
- weight: int
39
-
40
-
41
- class CollRisk(BaseModel):
42
- """Collateral risk configuration."""
43
- weight_tiers: List[WeightTier]
44
- max_margin_cap: int
45
- stale_price_guard_weight: int
46
-
47
-
48
- class SupportedCollateral(BaseModel):
49
- """Supported collateral information."""
50
- id: int
51
- symbol: str
52
- name: str
53
- decimals: int
54
- default_coll_weight: int
55
- price_index: str
56
- type: int
57
- bridge_by_chain: List[BridgeByChain]
58
- coll_risk: List[CollRisk]
59
- withdrawal_fee: int
60
- added_at_block: int
61
-
62
-
63
- # Instruments Method
64
- class InstrumentsParams(BaseModel):
65
- """Parameters for instruments query."""
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