decibel-python-sdk 0.1.0__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.
Files changed (53) hide show
  1. decibel/__init__.py +247 -0
  2. decibel/_base.py +726 -0
  3. decibel/_constants.py +164 -0
  4. decibel/_fee_pay.py +301 -0
  5. decibel/_gas_price_manager.py +262 -0
  6. decibel/_order_status.py +138 -0
  7. decibel/_order_types.py +109 -0
  8. decibel/_pagination.py +82 -0
  9. decibel/_subaccount_types.py +43 -0
  10. decibel/_transaction_builder.py +325 -0
  11. decibel/_utils.py +432 -0
  12. decibel/_version.py +1 -0
  13. decibel/abi/__init__.py +23 -0
  14. decibel/abi/__main__.py +4 -0
  15. decibel/abi/_registry.py +89 -0
  16. decibel/abi/_types.py +55 -0
  17. decibel/abi/generate.py +183 -0
  18. decibel/abi/json/netna.json +2417 -0
  19. decibel/abi/json/testnet.json +2919 -0
  20. decibel/admin.py +868 -0
  21. decibel/py.typed +0 -0
  22. decibel/read/__init__.py +279 -0
  23. decibel/read/_account_overview.py +119 -0
  24. decibel/read/_base.py +137 -0
  25. decibel/read/_candlesticks.py +97 -0
  26. decibel/read/_delegations.py +32 -0
  27. decibel/read/_leaderboard.py +64 -0
  28. decibel/read/_market_contexts.py +35 -0
  29. decibel/read/_market_depth.py +81 -0
  30. decibel/read/_market_prices.py +100 -0
  31. decibel/read/_market_trades.py +81 -0
  32. decibel/read/_markets.py +146 -0
  33. decibel/read/_portfolio_chart.py +48 -0
  34. decibel/read/_trading_points.py +36 -0
  35. decibel/read/_types.py +136 -0
  36. decibel/read/_user_active_twaps.py +70 -0
  37. decibel/read/_user_bulk_orders.py +73 -0
  38. decibel/read/_user_fund_history.py +49 -0
  39. decibel/read/_user_funding_history.py +45 -0
  40. decibel/read/_user_notifications.py +87 -0
  41. decibel/read/_user_open_orders.py +91 -0
  42. decibel/read/_user_order_history.py +101 -0
  43. decibel/read/_user_positions.py +84 -0
  44. decibel/read/_user_subaccounts.py +35 -0
  45. decibel/read/_user_trade_history.py +77 -0
  46. decibel/read/_user_twap_history.py +32 -0
  47. decibel/read/_vaults.py +218 -0
  48. decibel/read/_ws.py +245 -0
  49. decibel/write/__init__.py +1949 -0
  50. decibel/write/_types.py +190 -0
  51. decibel_python_sdk-0.1.0.dist-info/METADATA +255 -0
  52. decibel_python_sdk-0.1.0.dist-info/RECORD +53 -0
  53. decibel_python_sdk-0.1.0.dist-info/WHEEL +4 -0
decibel/py.typed ADDED
File without changes
@@ -0,0 +1,279 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from aptos_sdk.async_client import RestClient
6
+
7
+ from ._account_overview import (
8
+ AccountOverview,
9
+ AccountOverviewReader,
10
+ AccountOverviewWsMessage,
11
+ VolumeWindow,
12
+ )
13
+ from ._base import ReaderDeps
14
+ from ._candlesticks import (
15
+ Candlestick,
16
+ CandlestickInterval,
17
+ CandlesticksReader,
18
+ CandlestickWsMessage,
19
+ )
20
+ from ._delegations import Delegation, DelegationsReader
21
+ from ._leaderboard import (
22
+ LeaderboardItem,
23
+ LeaderboardReader,
24
+ LeaderboardResponse,
25
+ LeaderboardSortKey,
26
+ )
27
+ from ._market_contexts import MarketContext, MarketContextsReader
28
+ from ._market_depth import (
29
+ MarketDepth,
30
+ MarketDepthAggregationSize,
31
+ MarketDepthReader,
32
+ MarketDepthWsMessage,
33
+ MarketOrder,
34
+ )
35
+ from ._market_prices import (
36
+ AllMarketPricesWsMessage,
37
+ MarketPrice,
38
+ MarketPricesReader,
39
+ MarketPriceWsMessage,
40
+ )
41
+ from ._market_trades import (
42
+ MarketTrade,
43
+ MarketTradesReader,
44
+ MarketTradesResponse,
45
+ MarketTradeWsMessage,
46
+ )
47
+ from ._markets import (
48
+ MarketMode,
49
+ MarketModeConfig,
50
+ MarketsReader,
51
+ PerpMarket,
52
+ PerpMarketConfig,
53
+ SzPrecision,
54
+ )
55
+ from ._portfolio_chart import (
56
+ PortfolioChartItem,
57
+ PortfolioChartReader,
58
+ PortfolioChartTimeRange,
59
+ PortfolioChartType,
60
+ )
61
+ from ._trading_points import (
62
+ OwnerTradingPoints,
63
+ SubaccountPoints,
64
+ TradingPointsReader,
65
+ )
66
+ from ._types import (
67
+ ActivateVaultArgs,
68
+ AssetType,
69
+ BalanceTable,
70
+ CollateralBalanceSheet,
71
+ CreateVaultArgs,
72
+ CrossedPosition,
73
+ DepositToVaultArgs,
74
+ GlobalAccountsState,
75
+ GlobalAccountsStateV1,
76
+ LiquidationConfigV1,
77
+ PerpPosition,
78
+ Precision,
79
+ Store,
80
+ StoreExtendRef,
81
+ WithdrawFromVaultArgs,
82
+ )
83
+ from ._user_active_twaps import (
84
+ TwapStatus,
85
+ UserActiveTwap,
86
+ UserActiveTwapsReader,
87
+ UserActiveTwapsWsMessage,
88
+ )
89
+ from ._user_bulk_orders import (
90
+ UserBulkOrder,
91
+ UserBulkOrdersReader,
92
+ UserBulkOrderWsMessage,
93
+ )
94
+ from ._user_fund_history import (
95
+ FundMovementType,
96
+ UserFund,
97
+ UserFundHistoryReader,
98
+ UserFundHistoryResponse,
99
+ )
100
+ from ._user_funding_history import (
101
+ UserFunding,
102
+ UserFundingHistoryReader,
103
+ UserFundingHistoryResponse,
104
+ )
105
+ from ._user_notifications import (
106
+ NotificationMetadata,
107
+ NotificationType,
108
+ UserNotificationsReader,
109
+ UserNotificationWsMessage,
110
+ )
111
+ from ._user_open_orders import (
112
+ UserOpenOrder,
113
+ UserOpenOrdersReader,
114
+ UserOpenOrdersResponse,
115
+ UserOpenOrdersWsMessage,
116
+ )
117
+ from ._user_order_history import (
118
+ UserOrder,
119
+ UserOrderHistoryReader,
120
+ UserOrders,
121
+ UserOrdersWsMessage,
122
+ )
123
+ from ._user_positions import (
124
+ UserPosition,
125
+ UserPositionsReader,
126
+ UserPositionsWsMessage,
127
+ )
128
+ from ._user_subaccounts import UserSubaccount, UserSubaccountsReader
129
+ from ._user_trade_history import (
130
+ UserTrade,
131
+ UserTradeAction,
132
+ UserTradeHistoryReader,
133
+ UserTradesResponse,
134
+ UserTradesWsMessage,
135
+ )
136
+ from ._user_twap_history import UserTwapHistoryReader, UserTwapHistoryResponse
137
+ from ._vaults import (
138
+ UserOwnedVault,
139
+ UserOwnedVaultsResponse,
140
+ UserPerformanceOnVault,
141
+ Vault,
142
+ VaultDeposit,
143
+ VaultsReader,
144
+ VaultsResponse,
145
+ VaultType,
146
+ VaultWithdrawal,
147
+ )
148
+ from ._ws import DecibelWsSubscription, Unsubscribe
149
+
150
+ if TYPE_CHECKING:
151
+ from collections.abc import Callable
152
+
153
+ from .._constants import DecibelConfig
154
+
155
+
156
+ class DecibelReadDex:
157
+ def __init__(
158
+ self,
159
+ config: DecibelConfig,
160
+ *,
161
+ api_key: str | None = None,
162
+ on_ws_error: Callable[[Exception], None] | None = None,
163
+ ) -> None:
164
+ aptos = RestClient(config.fullnode_url)
165
+ ws = DecibelWsSubscription(config, api_key, on_ws_error)
166
+ deps = ReaderDeps(config=config, ws=ws, aptos=aptos, api_key=api_key)
167
+
168
+ self.ws = ws
169
+ self.account_overview = AccountOverviewReader(deps)
170
+ self.candlesticks = CandlesticksReader(deps)
171
+ self.delegations = DelegationsReader(deps)
172
+ self.leaderboard = LeaderboardReader(deps)
173
+ self.markets = MarketsReader(deps)
174
+ self.market_prices = MarketPricesReader(deps)
175
+ self.market_depth = MarketDepthReader(deps)
176
+ self.market_trades = MarketTradesReader(deps)
177
+ self.market_contexts = MarketContextsReader(deps)
178
+ self.portfolio_chart = PortfolioChartReader(deps)
179
+ self.user_positions = UserPositionsReader(deps)
180
+ self.user_open_orders = UserOpenOrdersReader(deps)
181
+ self.user_order_history = UserOrderHistoryReader(deps)
182
+ self.user_trade_history = UserTradeHistoryReader(deps)
183
+ self.user_bulk_orders = UserBulkOrdersReader(deps)
184
+ self.user_subaccounts = UserSubaccountsReader(deps)
185
+ self.user_fund_history = UserFundHistoryReader(deps)
186
+ self.user_funding_history = UserFundingHistoryReader(deps)
187
+ self.user_active_twaps = UserActiveTwapsReader(deps)
188
+ self.user_twap_history = UserTwapHistoryReader(deps)
189
+ self.user_notifications = UserNotificationsReader(deps)
190
+ self.vaults = VaultsReader(deps)
191
+ self.trading_points = TradingPointsReader(deps)
192
+
193
+
194
+ __all__ = [
195
+ "AccountOverview",
196
+ "AccountOverviewWsMessage",
197
+ "ActivateVaultArgs",
198
+ "AllMarketPricesWsMessage",
199
+ "AssetType",
200
+ "BalanceTable",
201
+ "Candlestick",
202
+ "CandlestickInterval",
203
+ "CandlestickWsMessage",
204
+ "CollateralBalanceSheet",
205
+ "CreateVaultArgs",
206
+ "CrossedPosition",
207
+ "DecibelReadDex",
208
+ "Delegation",
209
+ "DepositToVaultArgs",
210
+ "FundMovementType",
211
+ "GlobalAccountsState",
212
+ "GlobalAccountsStateV1",
213
+ "LeaderboardItem",
214
+ "LeaderboardResponse",
215
+ "LeaderboardSortKey",
216
+ "LiquidationConfigV1",
217
+ "MarketContext",
218
+ "MarketDepth",
219
+ "MarketDepthAggregationSize",
220
+ "MarketDepthWsMessage",
221
+ "MarketMode",
222
+ "MarketModeConfig",
223
+ "MarketOrder",
224
+ "MarketPrice",
225
+ "MarketPriceWsMessage",
226
+ "MarketTrade",
227
+ "MarketTradesResponse",
228
+ "MarketTradeWsMessage",
229
+ "NotificationMetadata",
230
+ "NotificationType",
231
+ "OwnerTradingPoints",
232
+ "PerpMarket",
233
+ "PerpMarketConfig",
234
+ "PerpPosition",
235
+ "PortfolioChartItem",
236
+ "PortfolioChartTimeRange",
237
+ "PortfolioChartType",
238
+ "Precision",
239
+ "Store",
240
+ "StoreExtendRef",
241
+ "SubaccountPoints",
242
+ "SzPrecision",
243
+ "TradingPointsReader",
244
+ "TwapStatus",
245
+ "Unsubscribe",
246
+ "UserActiveTwap",
247
+ "UserActiveTwapsWsMessage",
248
+ "UserBulkOrder",
249
+ "UserBulkOrderWsMessage",
250
+ "UserFund",
251
+ "UserFundHistoryResponse",
252
+ "UserFunding",
253
+ "UserFundingHistoryResponse",
254
+ "UserNotificationWsMessage",
255
+ "UserOpenOrder",
256
+ "UserOpenOrdersResponse",
257
+ "UserOpenOrdersWsMessage",
258
+ "UserOrder",
259
+ "UserOrders",
260
+ "UserOrdersWsMessage",
261
+ "UserOwnedVault",
262
+ "UserOwnedVaultsResponse",
263
+ "UserPerformanceOnVault",
264
+ "UserPosition",
265
+ "UserPositionsWsMessage",
266
+ "UserSubaccount",
267
+ "UserTrade",
268
+ "UserTradeAction",
269
+ "UserTradesResponse",
270
+ "UserTradesWsMessage",
271
+ "UserTwapHistoryResponse",
272
+ "Vault",
273
+ "VaultDeposit",
274
+ "VaultsResponse",
275
+ "VaultType",
276
+ "VaultWithdrawal",
277
+ "VolumeWindow",
278
+ "WithdrawFromVaultArgs",
279
+ ]
@@ -0,0 +1,119 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import StrEnum
4
+ from typing import TYPE_CHECKING
5
+
6
+ from pydantic import BaseModel, ConfigDict
7
+
8
+ from ._base import BaseReader
9
+
10
+ if TYPE_CHECKING:
11
+ from collections.abc import Awaitable, Callable
12
+
13
+ from ._ws import Unsubscribe
14
+
15
+ __all__ = [
16
+ "AccountOverview",
17
+ "AccountOverviewReader",
18
+ "AccountOverviewWsMessage",
19
+ "VolumeWindow",
20
+ ]
21
+
22
+
23
+ class VolumeWindow(StrEnum):
24
+ SEVEN_DAYS = "7d"
25
+ FOURTEEN_DAYS = "14d"
26
+ THIRTY_DAYS = "30d"
27
+ NINETY_DAYS = "90d"
28
+
29
+
30
+ class AccountOverview(BaseModel):
31
+ model_config = ConfigDict(populate_by_name=True)
32
+
33
+ perp_equity_balance: float
34
+ unrealized_pnl: float
35
+ unrealized_funding_cost: float
36
+ cross_margin_ratio: float
37
+ maintenance_margin: float
38
+ cross_account_leverage_ratio: float | None
39
+ volume: float | None
40
+ net_deposits: float | None = None
41
+ all_time_return: float | None
42
+ pnl_90d: float | None
43
+ sharpe_ratio: float | None
44
+ max_drawdown: float | None
45
+ weekly_win_rate_12w: float | None
46
+ average_cash_position: float | None
47
+ average_leverage: float | None
48
+ cross_account_position: float
49
+ total_margin: float
50
+ usdc_cross_withdrawable_balance: float
51
+ usdc_isolated_withdrawable_balance: float
52
+ realized_pnl: float | None
53
+ liquidation_fees_paid: float | None
54
+ liquidation_losses: float | None
55
+
56
+
57
+ class _AccountOverviewWs(BaseModel):
58
+ model_config = ConfigDict(populate_by_name=True)
59
+
60
+ perp_equity_balance: float
61
+ unrealized_pnl: float
62
+ unrealized_funding_cost: float
63
+ cross_margin_ratio: float
64
+ maintenance_margin: float
65
+ cross_account_leverage_ratio: float | None
66
+ net_deposits: float | None = None
67
+ all_time_return: float | None
68
+ pnl_90d: float | None
69
+ sharpe_ratio: float | None
70
+ max_drawdown: float | None
71
+ weekly_win_rate_12w: float | None
72
+ average_cash_position: float | None
73
+ average_leverage: float | None
74
+ cross_account_position: float
75
+ total_margin: float
76
+ usdc_cross_withdrawable_balance: float
77
+ usdc_isolated_withdrawable_balance: float
78
+ realized_pnl: float | None
79
+ liquidation_fees_paid: float | None
80
+ liquidation_losses: float | None
81
+
82
+
83
+ class AccountOverviewWsMessage(BaseModel):
84
+ model_config = ConfigDict(populate_by_name=True)
85
+
86
+ account_overview: _AccountOverviewWs
87
+
88
+
89
+ class AccountOverviewReader(BaseReader):
90
+ async def get_by_addr(
91
+ self,
92
+ *,
93
+ sub_addr: str,
94
+ volume_window: VolumeWindow | None = None,
95
+ include_performance: bool = False,
96
+ ) -> AccountOverview:
97
+ params: dict[str, str] = {"account": sub_addr}
98
+ if volume_window is not None:
99
+ params["volume_window"] = volume_window.value
100
+ if include_performance:
101
+ params["include_performance"] = "true"
102
+
103
+ response, _, _ = await self.get_request(
104
+ model=AccountOverview,
105
+ url=f"{self.config.trading_http_url}/api/v1/account_overviews",
106
+ params=params,
107
+ )
108
+ return response
109
+
110
+ def subscribe_by_addr(
111
+ self,
112
+ sub_addr: str,
113
+ on_data: (
114
+ Callable[[AccountOverviewWsMessage], None]
115
+ | Callable[[AccountOverviewWsMessage], Awaitable[None]]
116
+ ),
117
+ ) -> Unsubscribe:
118
+ topic = f"account_overview:{sub_addr}"
119
+ return self.ws.subscribe(topic, AccountOverviewWsMessage, on_data)
decibel/read/_base.py ADDED
@@ -0,0 +1,137 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import TYPE_CHECKING, Any, TypeVar
5
+
6
+ from pydantic import BaseModel
7
+
8
+ from .._utils import (
9
+ get_request,
10
+ get_request_sync,
11
+ patch_request,
12
+ patch_request_sync,
13
+ post_request,
14
+ post_request_sync,
15
+ )
16
+
17
+ if TYPE_CHECKING:
18
+ from aptos_sdk.async_client import RestClient
19
+
20
+ from .._constants import DecibelConfig
21
+ from ._ws import DecibelWsSubscription
22
+
23
+ __all__ = [
24
+ "ReaderDeps",
25
+ "BaseReader",
26
+ ]
27
+
28
+ T = TypeVar("T", bound=BaseModel)
29
+
30
+
31
+ @dataclass
32
+ class ReaderDeps:
33
+ config: DecibelConfig
34
+ ws: DecibelWsSubscription
35
+ aptos: RestClient
36
+ api_key: str | None = None
37
+
38
+
39
+ class BaseReader:
40
+ def __init__(self, deps: ReaderDeps) -> None:
41
+ self._deps = deps
42
+
43
+ @property
44
+ def config(self) -> DecibelConfig:
45
+ return self._deps.config
46
+
47
+ @property
48
+ def ws(self) -> DecibelWsSubscription:
49
+ return self._deps.ws
50
+
51
+ @property
52
+ def aptos(self) -> RestClient:
53
+ return self._deps.aptos
54
+
55
+ async def get_request(
56
+ self,
57
+ model: type[T],
58
+ url: str,
59
+ *,
60
+ params: dict[str, Any] | None = None,
61
+ ) -> tuple[T, int, str]:
62
+ return await get_request(
63
+ model=model,
64
+ url=url,
65
+ params=params,
66
+ api_key=self._deps.api_key,
67
+ )
68
+
69
+ async def post_request(
70
+ self,
71
+ model: type[T],
72
+ url: str,
73
+ *,
74
+ body: Any | None = None,
75
+ ) -> tuple[T, int, str]:
76
+ return await post_request(
77
+ model=model,
78
+ url=url,
79
+ body=body,
80
+ api_key=self._deps.api_key,
81
+ )
82
+
83
+ async def patch_request(
84
+ self,
85
+ model: type[T],
86
+ url: str,
87
+ *,
88
+ body: Any | None = None,
89
+ ) -> tuple[T, int, str]:
90
+ return await patch_request(
91
+ model=model,
92
+ url=url,
93
+ body=body,
94
+ api_key=self._deps.api_key,
95
+ )
96
+
97
+ def get_request_sync(
98
+ self,
99
+ model: type[T],
100
+ url: str,
101
+ *,
102
+ params: dict[str, Any] | None = None,
103
+ ) -> tuple[T, int, str]:
104
+ return get_request_sync(
105
+ model=model,
106
+ url=url,
107
+ params=params,
108
+ api_key=self._deps.api_key,
109
+ )
110
+
111
+ def post_request_sync(
112
+ self,
113
+ model: type[T],
114
+ url: str,
115
+ *,
116
+ body: Any | None = None,
117
+ ) -> tuple[T, int, str]:
118
+ return post_request_sync(
119
+ model=model,
120
+ url=url,
121
+ body=body,
122
+ api_key=self._deps.api_key,
123
+ )
124
+
125
+ def patch_request_sync(
126
+ self,
127
+ model: type[T],
128
+ url: str,
129
+ *,
130
+ body: Any | None = None,
131
+ ) -> tuple[T, int, str]:
132
+ return patch_request_sync(
133
+ model=model,
134
+ url=url,
135
+ body=body,
136
+ api_key=self._deps.api_key,
137
+ )
@@ -0,0 +1,97 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import StrEnum
4
+ from typing import TYPE_CHECKING
5
+
6
+ from pydantic import BaseModel, ConfigDict, Field, RootModel
7
+
8
+ from .._utils import get_market_addr
9
+ from ._base import BaseReader
10
+
11
+ if TYPE_CHECKING:
12
+ from collections.abc import Awaitable, Callable
13
+
14
+ from ._ws import Unsubscribe
15
+
16
+ __all__ = [
17
+ "Candlestick",
18
+ "CandlestickInterval",
19
+ "CandlesticksReader",
20
+ "CandlestickWsMessage",
21
+ ]
22
+
23
+
24
+ class CandlestickInterval(StrEnum):
25
+ ONE_MINUTE = "1m"
26
+ FIVE_MINUTES = "5m"
27
+ FIFTEEN_MINUTES = "15m"
28
+ THIRTY_MINUTES = "30m"
29
+ ONE_HOUR = "1h"
30
+ TWO_HOURS = "2h"
31
+ FOUR_HOURS = "4h"
32
+ EIGHT_HOURS = "8h"
33
+ TWELVE_HOURS = "12h"
34
+ ONE_DAY = "1d"
35
+ THREE_DAYS = "3d"
36
+ ONE_WEEK = "1w"
37
+ ONE_MONTH = "1mo"
38
+
39
+
40
+ class Candlestick(BaseModel):
41
+ model_config = ConfigDict(populate_by_name=True)
42
+
43
+ time_end: int = Field(alias="T")
44
+ close: float = Field(alias="c")
45
+ high: float = Field(alias="h")
46
+ interval: str = Field(alias="i")
47
+ low: float = Field(alias="l")
48
+ open_price: float = Field(alias="o")
49
+ time_start: int = Field(alias="t")
50
+ volume: float = Field(alias="v")
51
+
52
+
53
+ class _CandlesticksList(RootModel[list[Candlestick]]):
54
+ pass
55
+
56
+
57
+ class CandlestickWsMessage(BaseModel):
58
+ model_config = ConfigDict(populate_by_name=True)
59
+
60
+ candle: Candlestick
61
+
62
+
63
+ class CandlesticksReader(BaseReader):
64
+ async def get_by_name(
65
+ self,
66
+ market_name: str,
67
+ *,
68
+ interval: CandlestickInterval,
69
+ start_time: int,
70
+ end_time: int,
71
+ ) -> list[Candlestick]:
72
+ market_addr = get_market_addr(market_name, self.config.deployment.perp_engine_global)
73
+
74
+ response, _, _ = await self.get_request(
75
+ model=_CandlesticksList,
76
+ url=f"{self.config.trading_http_url}/api/v1/candlesticks",
77
+ params={
78
+ "market": market_addr,
79
+ "interval": interval.value,
80
+ "startTime": str(start_time),
81
+ "endTime": str(end_time),
82
+ },
83
+ )
84
+ return response.root
85
+
86
+ def subscribe_by_name(
87
+ self,
88
+ market_name: str,
89
+ interval: CandlestickInterval,
90
+ on_data: (
91
+ Callable[[CandlestickWsMessage], None]
92
+ | Callable[[CandlestickWsMessage], Awaitable[None]]
93
+ ),
94
+ ) -> Unsubscribe:
95
+ market_addr = get_market_addr(market_name, self.config.deployment.perp_engine_global)
96
+ topic = f"market_candlestick:{market_addr}:{interval.value}"
97
+ return self.ws.subscribe(topic, CandlestickWsMessage, on_data)
@@ -0,0 +1,32 @@
1
+ from __future__ import annotations
2
+
3
+ from pydantic import BaseModel, ConfigDict, RootModel
4
+
5
+ from ._base import BaseReader
6
+
7
+ __all__ = [
8
+ "Delegation",
9
+ "DelegationsReader",
10
+ ]
11
+
12
+
13
+ class Delegation(BaseModel):
14
+ model_config = ConfigDict(populate_by_name=True)
15
+
16
+ delegated_account: str
17
+ permission_type: str
18
+ expiration_time_s: float | None
19
+
20
+
21
+ class _DelegationsList(RootModel[list[Delegation]]):
22
+ pass
23
+
24
+
25
+ class DelegationsReader(BaseReader):
26
+ async def get_all(self, *, sub_addr: str) -> list[Delegation]:
27
+ response, _, _ = await self.get_request(
28
+ model=_DelegationsList,
29
+ url=f"{self.config.trading_http_url}/api/v1/delegations",
30
+ params={"subaccount": sub_addr},
31
+ )
32
+ return response.root