hotstuff-python-sdk 0.0.1b1__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/apis/info.py ADDED
@@ -0,0 +1,291 @@
1
+ """Info API client."""
2
+ from typing import Optional, Any, List
3
+ import importlib
4
+
5
+ GM = importlib.import_module("hotstuff.methods.info.global")
6
+ AM = importlib.import_module("hotstuff.methods.info.account")
7
+ VM = importlib.import_module("hotstuff.methods.info.vault")
8
+ EM = importlib.import_module("hotstuff.methods.info.explorer")
9
+
10
+
11
+ class InfoClient:
12
+ """Client for querying market data and account information."""
13
+
14
+ def __init__(self, transport):
15
+ """
16
+ Initialize InfoClient.
17
+
18
+ Args:
19
+ transport: The transport layer to use
20
+ """
21
+ self.transport = transport
22
+
23
+ # Global Info Endpoints
24
+
25
+ async def oracle(
26
+ self, params: GM.OracleParams, signal: Optional[Any] = None
27
+ ) -> GM.OracleResponse:
28
+ """Get oracle prices."""
29
+ request = {"method": "oracle", "params": params.model_dump()}
30
+ response = await self.transport.request("info", request, signal)
31
+ return GM.OracleResponse.model_validate(response)
32
+
33
+ async def supported_collateral(
34
+ self, params: GM.SupportedCollateralParams, signal: Optional[Any] = None
35
+ ) -> List[GM.SupportedCollateral]:
36
+ """Get supported collateral."""
37
+ request = {"method": "supportedCollateral", "params": params.model_dump()}
38
+ response = await self.transport.request("info", request, signal)
39
+ return [GM.SupportedCollateral.model_validate(item) for item in response]
40
+
41
+ async def instruments(
42
+ self, params: GM.InstrumentsParams, signal: Optional[Any] = None
43
+ ) -> GM.InstrumentsResponse:
44
+ """Get all instruments."""
45
+ request = {"method": "instruments", "params": params.model_dump()}
46
+ response = await self.transport.request("info", request, signal)
47
+ return GM.InstrumentsResponse.model_validate(response)
48
+
49
+ async def ticker(
50
+ self, params: GM.TickerParams, signal: Optional[Any] = None
51
+ ) -> List[GM.Ticker]:
52
+ """Get ticker for a specific symbol."""
53
+ request = {"method": "ticker", "params": params.model_dump()}
54
+ response = await self.transport.request("info", request, signal)
55
+ return [GM.Ticker.model_validate(item) for item in response]
56
+
57
+ async def orderbook(
58
+ self, params: GM.OrderbookParams, signal: Optional[Any] = None
59
+ ) -> GM.OrderbookResponse:
60
+ """Get orderbook with depth."""
61
+ request = {"method": "orderbook", "params": params.model_dump()}
62
+ response = await self.transport.request("info", request, signal)
63
+ return GM.OrderbookResponse.model_validate(response)
64
+
65
+ async def trades(
66
+ self, params: GM.TradesParams, signal: Optional[Any] = None
67
+ ) -> List[GM.Trade]:
68
+ """Get recent trades."""
69
+ request = {"method": "trades", "params": params.model_dump()}
70
+ response = await self.transport.request("info", request, signal)
71
+ return [GM.Trade.model_validate(item) for item in response]
72
+
73
+ async def mids(
74
+ self, params: GM.MidsParams, signal: Optional[Any] = None
75
+ ) -> List[GM.Mid]:
76
+ """Get mid prices for all instruments."""
77
+ request = {"method": "mids", "params": params.model_dump()}
78
+ response = await self.transport.request("info", request, signal)
79
+ return [GM.Mid.model_validate(item) for item in response]
80
+
81
+ async def bbo(
82
+ self, params: GM.BBOParams, signal: Optional[Any] = None
83
+ ) -> List[GM.BBO]:
84
+ """Get best bid/offer."""
85
+ request = {"method": "bbo", "params": params.model_dump()}
86
+ response = await self.transport.request("info", request, signal)
87
+ return [GM.BBO.model_validate(item) for item in response]
88
+
89
+ async def chart(
90
+ self, params: GM.ChartParams, signal: Optional[Any] = None
91
+ ) -> List[GM.ChartPoint]:
92
+ """Get chart data (candles or funding)."""
93
+ # Convert from_ to "from" for API
94
+ params_dict = params.model_dump(by_alias=True)
95
+ request = {"method": "chart", "params": params_dict}
96
+ response = await self.transport.request("info", request, signal)
97
+ return [GM.ChartPoint.model_validate(item) for item in response]
98
+
99
+ # Account Info Endpoints
100
+
101
+ async def open_orders(
102
+ self, params: AM.OpenOrdersParams, signal: Optional[Any] = None
103
+ ) -> AM.OpenOrdersResponse:
104
+ """Get open orders."""
105
+ request = {"method": "openOrders", "params": params.model_dump()}
106
+ response = await self.transport.request("info", request, signal)
107
+ if isinstance(response, dict) and "data" in response:
108
+ response = {"orders": response["data"]}
109
+ return AM.OpenOrdersResponse.model_validate(response)
110
+
111
+ async def positions(
112
+ self, params: AM.PositionsParams, signal: Optional[Any] = None
113
+ ) -> AM.PositionsResponse:
114
+ """Get current positions."""
115
+ request = {"method": "positions", "params": params.model_dump()}
116
+ response = await self.transport.request("info", request, signal)
117
+ return AM.PositionsResponse.model_validate(response)
118
+
119
+ async def account_summary(
120
+ self, params: AM.AccountSummaryParams, signal: Optional[Any] = None
121
+ ) -> AM.AccountSummaryResponse:
122
+ """Get account summary."""
123
+ request = {"method": "accountSummary", "params": params.model_dump()}
124
+ response = await self.transport.request("info", request, signal)
125
+ return AM.AccountSummaryResponse.model_validate(response)
126
+
127
+ async def referral_summary(
128
+ self, params: AM.ReferralSummaryParams, signal: Optional[Any] = None
129
+ ) -> AM.ReferralSummaryResponse:
130
+ """Get referral summary."""
131
+ request = {"method": "referralSummary", "params": params.model_dump()}
132
+ response = await self.transport.request("info", request, signal)
133
+ return AM.ReferralSummaryResponse.model_validate(response)
134
+
135
+ async def user_fee_info(
136
+ self, params: AM.UserFeeInfoParams, signal: Optional[Any] = None
137
+ ) -> AM.UserFeeInfoResponse:
138
+ """Get user fee information."""
139
+ request = {"method": "userFees", "params": params.model_dump()}
140
+ response = await self.transport.request("info", request, signal)
141
+ return AM.UserFeeInfoResponse.model_validate(response)
142
+
143
+ async def account_history(
144
+ self, params: AM.AccountHistoryParams, signal: Optional[Any] = None
145
+ ) -> AM.AccountHistoryResponse:
146
+ """Get account history."""
147
+ request = {"method": "accountHistory", "params": params.model_dump()}
148
+ response = await self.transport.request("info", request, signal)
149
+ return AM.AccountHistoryResponse.model_validate(response)
150
+
151
+ async def order_history(
152
+ self, params: AM.OrderHistoryParams, signal: Optional[Any] = None
153
+ ) -> AM.OrderHistoryResponse:
154
+ """Get order history."""
155
+ request = {"method": "orderHistory", "params": params.model_dump(by_alias=True)}
156
+ response = await self.transport.request("info", request, signal)
157
+ return AM.OrderHistoryResponse.model_validate(response)
158
+
159
+ async def trade_history(
160
+ self, params: AM.TradeHistoryParams, signal: Optional[Any] = None
161
+ ) -> AM.TradeHistoryResponse:
162
+ """Get trade history (fills)."""
163
+ request = {"method": "fills", "params": params.model_dump(by_alias=True)}
164
+ response = await self.transport.request("info", request, signal)
165
+ return AM.TradeHistoryResponse.model_validate(response)
166
+
167
+ async def funding_history(
168
+ self, params: AM.FundingHistoryParams, signal: Optional[Any] = None
169
+ ) -> AM.FundingHistoryResponse:
170
+ """Get funding history."""
171
+ request = {"method": "fundingHistory", "params": params.model_dump()}
172
+ response = await self.transport.request("info", request, signal)
173
+ return AM.FundingHistoryResponse.model_validate(response)
174
+
175
+ async def transfer_history(
176
+ self, params: AM.TransferHistoryParams, signal: Optional[Any] = None
177
+ ) -> AM.TransferHistoryResponse:
178
+ """Get transfer history."""
179
+ request = {"method": "transferHistory", "params": params.model_dump()}
180
+ response = await self.transport.request("info", request, signal)
181
+ return AM.TransferHistoryResponse.model_validate(response)
182
+
183
+ async def instrument_leverage(
184
+ self, params: AM.InstrumentLeverageParams, signal: Optional[Any] = None
185
+ ) -> AM.InstrumentLeverageResponse:
186
+ """Get instrument leverage settings."""
187
+ request = {"method": "instrumentLeverage", "params": params.model_dump()}
188
+ response = await self.transport.request("info", request, signal)
189
+ return AM.InstrumentLeverageResponse.model_validate(response)
190
+
191
+ async def get_referral_info(
192
+ self, params: AM.ReferralInfoParams, signal: Optional[Any] = None
193
+ ) -> AM.ReferralInfoResponse:
194
+ """Get referral info."""
195
+ request = {"method": "referralInfo", "params": params.model_dump()}
196
+ response = await self.transport.request("info", request, signal)
197
+ return AM.ReferralInfoResponse.model_validate(response)
198
+
199
+ async def sub_accounts_list(
200
+ self, params: AM.SubAccountsListParams, signal: Optional[Any] = None
201
+ ) -> AM.SubAccountsListResponse:
202
+ """Get sub-accounts list."""
203
+ request = {"method": "subAccountsList", "params": params.model_dump()}
204
+ response = await self.transport.request("info", request, signal)
205
+ return AM.SubAccountsListResponse.model_validate(response)
206
+
207
+ async def agents(
208
+ self, params: AM.AgentsParams, signal: Optional[Any] = None
209
+ ) -> AM.AgentsResponse:
210
+ """Get agents."""
211
+ request = {"method": "allAgents", "params": params.model_dump()}
212
+ response = await self.transport.request("info", request, signal)
213
+ if isinstance(response, list):
214
+ return [AM.Agent.model_validate(item) for item in response]
215
+ return AM.AgentsResponse.model_validate(response)
216
+
217
+ async def user_balance(
218
+ self, params: AM.UserBalanceInfoParams, signal: Optional[Any] = None
219
+ ) -> AM.UserBalanceInfoResponse:
220
+ """Get user balance."""
221
+ request = {"method": "userBalance", "params": params.model_dump()}
222
+ response = await self.transport.request("info", request, signal)
223
+ return AM.UserBalanceInfoResponse.model_validate(response)
224
+
225
+ async def account_info(
226
+ self, params: AM.AccountInfoParams, signal: Optional[Any] = None
227
+ ) -> AM.AccountInfoResponse:
228
+ """Get account info."""
229
+ request = {"method": "accountInfo", "params": params.model_dump(by_alias=True)}
230
+ response = await self.transport.request("info", request, signal)
231
+ return AM.AccountInfoResponse.model_validate(response)
232
+
233
+ # Vault Info Endpoints
234
+
235
+ async def vaults(
236
+ self, params: VM.VaultsParams, signal: Optional[Any] = None
237
+ ) -> VM.VaultsResponse:
238
+ """Get all vaults."""
239
+ request = {"method": "vaults", "params": params.model_dump()}
240
+ response = await self.transport.request("info", request, signal)
241
+ return VM.VaultsResponse.model_validate(response)
242
+
243
+ async def sub_vaults(
244
+ self, params: VM.SubVaultsParams, signal: Optional[Any] = None
245
+ ) -> VM.SubVaultsResponse:
246
+ """Get sub-vaults for a specific vault."""
247
+ request = {"method": "subVaults", "params": params.model_dump()}
248
+ response = await self.transport.request("info", request, signal)
249
+ return VM.SubVaultsResponse.model_validate(response)
250
+
251
+ async def vault_balances(
252
+ self, params: VM.VaultBalancesParams, signal: Optional[Any] = None
253
+ ) -> VM.VaultBalancesResponse:
254
+ """Get vault balances."""
255
+ request = {"method": "vaultBalance", "params": params.model_dump()}
256
+ response = await self.transport.request("info", request, signal)
257
+ return VM.VaultBalancesResponse.model_validate(response)
258
+
259
+ # Explorer Info Endpoints
260
+
261
+ async def blocks(
262
+ self, params: EM.BlocksParams, signal: Optional[Any] = None
263
+ ) -> EM.BlocksResponse:
264
+ """Get recent blocks."""
265
+ request = {"method": "blocks", "params": params.model_dump()}
266
+ response = await self.transport.request("explorer", request, signal)
267
+ return EM.BlocksResponse.model_validate(response)
268
+
269
+ async def block_details(
270
+ self, params: EM.BlockDetailsParams, signal: Optional[Any] = None
271
+ ) -> EM.BlockDetailsResponse:
272
+ """Get specific block details."""
273
+ request = {"method": "block", "params": params.model_dump()}
274
+ response = await self.transport.request("explorer", request, signal)
275
+ return EM.BlockDetailsResponse.model_validate(response)
276
+
277
+ async def transactions(
278
+ self, params: EM.TransactionsParams, signal: Optional[Any] = None
279
+ ) -> EM.TransactionsResponse:
280
+ """Get recent transactions."""
281
+ request = {"method": "transactions", "params": params.model_dump()}
282
+ response = await self.transport.request("explorer", request, signal)
283
+ return EM.TransactionsResponse.model_validate(response)
284
+
285
+ async def transaction_details(
286
+ self, params: EM.TransactionDetailsParams, signal: Optional[Any] = None
287
+ ) -> EM.TransactionDetailsResponse:
288
+ """Get specific transaction details."""
289
+ request = {"method": "transaction", "params": params.model_dump()}
290
+ response = await self.transport.request("explorer", request, signal)
291
+ return EM.TransactionDetailsResponse.model_validate(response)
@@ -0,0 +1,278 @@
1
+ """Subscription API client for real-time data."""
2
+ from typing import Callable, Dict, Any
3
+ import importlib
4
+
5
+ SM = importlib.import_module("hotstuff.methods.subscription.global")
6
+
7
+
8
+ class SubscriptionClient:
9
+ """Client for subscribing to real-time data streams."""
10
+
11
+ def __init__(self, transport):
12
+ """
13
+ Initialize SubscriptionClient.
14
+
15
+ Args:
16
+ transport: The WebSocket transport layer to use
17
+ """
18
+ self.transport = transport
19
+
20
+ # Market Subscriptions
21
+
22
+ async def ticker(
23
+ self,
24
+ params: SM.TickerSubscriptionParams,
25
+ listener: Callable
26
+ ) -> Dict[str, Any]:
27
+ """
28
+ Subscribe to ticker updates.
29
+
30
+ Args:
31
+ params: Subscription parameters (symbol)
32
+ listener: Callback function for updates
33
+
34
+ Returns:
35
+ Subscription object with unsubscribe method
36
+ """
37
+ return await self.transport.subscribe("ticker", params.model_dump(), listener)
38
+
39
+ async def mids(
40
+ self,
41
+ params: SM.MidsSubscriptionParams,
42
+ listener: Callable
43
+ ) -> Dict[str, Any]:
44
+ """
45
+ Subscribe to mid prices.
46
+
47
+ Args:
48
+ params: Subscription parameters (symbol)
49
+ listener: Callback function for updates
50
+
51
+ Returns:
52
+ Subscription object with unsubscribe method
53
+ """
54
+ return await self.transport.subscribe("mids", params.model_dump(), listener)
55
+
56
+ async def bbo(
57
+ self,
58
+ params: SM.BBOSubscriptionParams,
59
+ listener: Callable
60
+ ) -> Dict[str, Any]:
61
+ """
62
+ Subscribe to best bid/offer.
63
+
64
+ Args:
65
+ params: Subscription parameters (symbol)
66
+ listener: Callback function for updates
67
+
68
+ Returns:
69
+ Subscription object with unsubscribe method
70
+ """
71
+ return await self.transport.subscribe("bbo", params.model_dump(), listener)
72
+
73
+ async def orderbook(
74
+ self,
75
+ params: SM.OrderbookSubscriptionParams,
76
+ listener: Callable
77
+ ) -> Dict[str, Any]:
78
+ """
79
+ Subscribe to orderbook updates.
80
+
81
+ Args:
82
+ params: Subscription parameters (instrument_id)
83
+ listener: Callback function for updates
84
+
85
+ Returns:
86
+ Subscription object with unsubscribe method
87
+ """
88
+ # Convert to format expected by API (both instrumentId and symbol)
89
+ params_dict = params.model_dump()
90
+ params_dict["symbol"] = params_dict["instrument_id"]
91
+ return await self.transport.subscribe("orderbook", params_dict, listener)
92
+
93
+ async def trade(
94
+ self,
95
+ params: SM.TradeSubscriptionParams,
96
+ listener: Callable
97
+ ) -> Dict[str, Any]:
98
+ """
99
+ Subscribe to trades.
100
+
101
+ Args:
102
+ params: Subscription parameters (instrument_id)
103
+ listener: Callback function for updates
104
+
105
+ Returns:
106
+ Subscription object with unsubscribe method
107
+ """
108
+ # Convert to format expected by API (both instrumentId and symbol)
109
+ params_dict = params.model_dump()
110
+ params_dict["symbol"] = params_dict["instrument_id"]
111
+ return await self.transport.subscribe("trade", params_dict, listener)
112
+
113
+ async def index(
114
+ self,
115
+ listener: Callable
116
+ ) -> Dict[str, Any]:
117
+ """
118
+ Subscribe to index prices.
119
+
120
+ Args:
121
+ listener: Callback function for updates
122
+
123
+ Returns:
124
+ Subscription object with unsubscribe method
125
+ """
126
+ return await self.transport.subscribe("index", {}, listener)
127
+
128
+ async def chart(
129
+ self,
130
+ params: SM.ChartSubscriptionParams,
131
+ listener: Callable
132
+ ) -> Dict[str, Any]:
133
+ """
134
+ Subscribe to chart updates.
135
+
136
+ Args:
137
+ params: Subscription parameters (symbol, chart_type, resolution)
138
+ listener: Callback function for updates
139
+
140
+ Returns:
141
+ Subscription object with unsubscribe method
142
+ """
143
+ return await self.transport.subscribe("chart", params.model_dump(), listener)
144
+
145
+ # Account Subscriptions
146
+
147
+ async def account_order_updates(
148
+ self,
149
+ params: SM.AccountOrderUpdatesParams,
150
+ listener: Callable
151
+ ) -> Dict[str, Any]:
152
+ """
153
+ Subscribe to order updates.
154
+
155
+ Args:
156
+ params: Subscription parameters (address)
157
+ listener: Callback function for updates
158
+
159
+ Returns:
160
+ Subscription object with unsubscribe method
161
+ """
162
+ # Convert to format expected by API (both address and user)
163
+ params_dict = params.model_dump()
164
+ params_dict["user"] = params_dict["address"]
165
+ return await self.transport.subscribe("accountOrderUpdates", params_dict, listener)
166
+
167
+ async def account_balance_updates(
168
+ self,
169
+ params: SM.AccountBalanceUpdatesParams,
170
+ listener: Callable
171
+ ) -> Dict[str, Any]:
172
+ """
173
+ Subscribe to balance updates.
174
+
175
+ Args:
176
+ params: Subscription parameters (address)
177
+ listener: Callback function for updates
178
+
179
+ Returns:
180
+ Subscription object with unsubscribe method
181
+ """
182
+ # Convert to format expected by API (both address and user)
183
+ params_dict = params.model_dump()
184
+ params_dict["user"] = params_dict["address"]
185
+ return await self.transport.subscribe("accountBalanceUpdates", params_dict, listener)
186
+
187
+ async def positions(
188
+ self,
189
+ params: SM.PositionsSubscriptionParams,
190
+ listener: Callable
191
+ ) -> Dict[str, Any]:
192
+ """
193
+ Subscribe to position updates.
194
+
195
+ Args:
196
+ params: Subscription parameters (address)
197
+ listener: Callback function for updates
198
+
199
+ Returns:
200
+ Subscription object with unsubscribe method
201
+ """
202
+ # Convert to format expected by API (both address and user)
203
+ params_dict = params.model_dump()
204
+ params_dict["user"] = params_dict["address"]
205
+ return await self.transport.subscribe("positions", params_dict, listener)
206
+
207
+ async def fills(
208
+ self,
209
+ params: SM.FillsSubscriptionParams,
210
+ listener: Callable
211
+ ) -> Dict[str, Any]:
212
+ """
213
+ Subscribe to fills.
214
+
215
+ Args:
216
+ params: Subscription parameters (address)
217
+ listener: Callback function for updates
218
+
219
+ Returns:
220
+ Subscription object with unsubscribe method
221
+ """
222
+ # Convert to format expected by API (both address and user)
223
+ params_dict = params.model_dump()
224
+ params_dict["user"] = params_dict["address"]
225
+ return await self.transport.subscribe("fills", params_dict, listener)
226
+
227
+ async def account_summary(
228
+ self,
229
+ params: SM.AccountSummarySubscriptionParams,
230
+ listener: Callable
231
+ ) -> Dict[str, Any]:
232
+ """
233
+ Subscribe to account summary.
234
+
235
+ Args:
236
+ params: Subscription parameters (user)
237
+ listener: Callback function for updates
238
+
239
+ Returns:
240
+ Subscription object with unsubscribe method
241
+ """
242
+ return await self.transport.subscribe("accountSummary", params.model_dump(), listener)
243
+
244
+ # Explorer Subscriptions
245
+
246
+ async def blocks(
247
+ self,
248
+ params: SM.BlocksSubscriptionParams,
249
+ listener: Callable
250
+ ) -> Dict[str, Any]:
251
+ """
252
+ Subscribe to new blocks.
253
+
254
+ Args:
255
+ params: Subscription parameters
256
+ listener: Callback function for updates
257
+
258
+ Returns:
259
+ Subscription object with unsubscribe method
260
+ """
261
+ return await self.transport.subscribe("blocks", params.model_dump(), listener)
262
+
263
+ async def transactions(
264
+ self,
265
+ params: SM.TransactionsSubscriptionParams,
266
+ listener: Callable
267
+ ) -> Dict[str, Any]:
268
+ """
269
+ Subscribe to new transactions.
270
+
271
+ Args:
272
+ params: Subscription parameters
273
+ listener: Callback function for updates
274
+
275
+ Returns:
276
+ Subscription object with unsubscribe method
277
+ """
278
+ return await self.transport.subscribe("transactions", params.model_dump(), listener)
@@ -0,0 +1,10 @@
1
+ """Method types organized by category."""
2
+ from hotstuff.methods import info as InfoMethods
3
+ from hotstuff.methods import exchange as ExchangeMethods
4
+ from hotstuff.methods import subscription as SubscriptionMethods
5
+
6
+ __all__ = [
7
+ "InfoMethods",
8
+ "ExchangeMethods",
9
+ "SubscriptionMethods",
10
+ ]
@@ -0,0 +1,14 @@
1
+ """Exchange method types organized by category."""
2
+ from hotstuff.methods.exchange import trading as TradingExchangeMethods
3
+ from hotstuff.methods.exchange import account as AccountExchangeMethods
4
+ from hotstuff.methods.exchange import collateral as CollateralExchangeMethods
5
+ from hotstuff.methods.exchange import vault as VaultExchangeMethods
6
+ from hotstuff.methods.exchange.op_codes import EXCHANGE_OP_CODES
7
+
8
+ __all__ = [
9
+ "TradingExchangeMethods",
10
+ "AccountExchangeMethods",
11
+ "CollateralExchangeMethods",
12
+ "VaultExchangeMethods",
13
+ "EXCHANGE_OP_CODES",
14
+ ]