Skip to main content

dydx/indexer/rest/
types.rs

1use bigdecimal::BigDecimal;
2use chrono::{DateTime, Utc};
3use derive_more::{Display, From};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7use crate::indexer::types::*;
8
9/// REST Indexer response error.
10#[derive(Deserialize)]
11#[serde(rename_all = "camelCase")]
12#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
13pub struct ResponseError {
14    /// Errors.
15    pub errors: Vec<ErrorMsg>,
16}
17
18/// REST Indexer error message.
19#[derive(Deserialize)]
20#[serde(rename_all = "camelCase")]
21#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
22pub struct ErrorMsg {
23    /// Message.
24    pub msg: String,
25    /// Parameter.
26    pub param: String,
27    /// Location.
28    pub location: String,
29}
30
31/// Profit and loss tick id.
32#[derive(Deserialize, Debug, Clone, From, Display, PartialEq, Eq, PartialOrd, Ord, Hash)]
33pub struct PnlTickId(pub String);
34
35/// PnL tick resolution.
36#[derive(
37    Deserialize, Serialize, Debug, Clone, Copy, From, Display, PartialEq, Eq, PartialOrd, Ord, Hash,
38)]
39#[serde(rename_all = "lowercase")]
40pub enum PnlTickInterval {
41    /// Hour.
42    Hour,
43    /// Day.
44    Day,
45}
46
47/// Transfer id.
48#[derive(
49    Serialize, Deserialize, Debug, Clone, From, Display, PartialEq, Eq, PartialOrd, Ord, Hash,
50)]
51pub struct TransferId(pub String);
52
53/// Period to aggregate rewards over.
54#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
55#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
56pub enum TradingRewardAggregationPeriod {
57    /// Day.
58    Daily,
59    /// Week.
60    Weekly,
61    /// Month.
62    Monthly,
63}
64
65/// Sparkline time period.
66#[derive(Serialize, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
67#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
68pub enum SparklineTimePeriod {
69    /// 1 day.
70    OneDay,
71    /// 7 days.
72    SevenDays,
73}
74
75/// Fundings response.
76#[derive(Deserialize, Debug, Clone)]
77#[serde(rename_all = "camelCase")]
78#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
79pub struct HistoricalFundingResponse {
80    /// List of fundings
81    pub historical_funding: Vec<HistoricalFundingResponseObject>,
82}
83
84/// Funding response.
85#[derive(Deserialize, Debug, Clone)]
86#[serde(rename_all = "camelCase")]
87#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
88pub struct HistoricalFundingResponseObject {
89    /// Market ticker.
90    pub ticker: Ticker,
91    /// Time.
92    pub effective_at: DateTime<Utc>,
93    /// Block height.
94    pub effective_at_height: Height,
95    /// Price.
96    pub price: Price,
97    /// Funding rate.
98    pub rate: BigDecimal,
99}
100
101/// Sparkline response.
102pub type SparklineResponseObject = HashMap<Ticker, Vec<BigDecimal>>;
103
104/// Indexer server time.
105#[derive(Deserialize, Debug, Clone)]
106#[serde(rename_all = "camelCase")]
107#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
108pub struct TimeResponse {
109    /// Time (UTC).
110    pub iso: DateTime<Utc>,
111    /// Unix epoch.
112    pub epoch: f64,
113}
114
115/// Compliance response.
116#[derive(Deserialize, Debug, Clone)]
117#[serde(rename_all = "camelCase")]
118#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
119pub struct ComplianceResponse {
120    /// Whether the address is restricted.
121    pub restricted: bool,
122    /// Reason.
123    pub reason: Option<String>,
124}
125
126/// Compliance status.
127#[derive(Deserialize, Debug, Clone)]
128#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
129pub enum ComplianceStatus {
130    /// Compliant.
131    Compliant,
132    /// First strike close only.
133    FirstStrikeCloseOnly,
134    /// First strike.
135    FirstStrike,
136    /// Close only.
137    CloseOnly,
138    /// Blocked.
139    Blocked,
140}
141
142/// Compliance reason.
143#[derive(Deserialize, Debug, Clone)]
144#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
145pub enum ComplianceReason {
146    /// Manual.
147    Manual,
148    /// US geo.
149    UsGeo,
150    /// CA geo.
151    CaGeo,
152    /// GB geo.
153    GbGeo,
154    /// Sanctioned geo.
155    SanctionedGeo,
156    /// Compliance provider.
157    ComplianceProvider,
158}
159
160/// Compliance response v2.
161#[derive(Deserialize, Debug, Clone)]
162#[serde(rename_all = "camelCase")]
163#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
164pub struct ComplianceV2Response {
165    /// Status.
166    pub status: ComplianceStatus,
167    /// Reason.
168    pub reason: Option<ComplianceReason>,
169    /// Updated at.
170    pub updated_at: Option<DateTime<Utc>>,
171}
172
173/// Address response.
174#[derive(Deserialize, Debug, Clone)]
175#[serde(rename_all = "camelCase")]
176#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
177pub struct AddressResponse {
178    /// List of all subaccounts.
179    pub subaccounts: Vec<SubaccountResponseObject>,
180    /// Total rewards.
181    pub total_trading_rewards: BigDecimal,
182}
183
184/// Subaccount response.
185#[derive(Deserialize, Debug, Clone)]
186#[serde(rename_all = "camelCase")]
187#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
188pub struct SubaccountResponse {
189    /// Subaccount.
190    pub subaccount: SubaccountResponseObject,
191}
192
193/// Parent subaccount response.
194#[derive(Deserialize, Debug, Clone)]
195#[serde(rename_all = "camelCase")]
196#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
197pub struct ParentSubaccountResponse {
198    /// Subaccount.
199    pub subaccount: ParentSubaccountResponseObject,
200}
201
202/// Asset positions response.
203#[derive(Deserialize, Debug, Clone)]
204#[serde(rename_all = "camelCase")]
205#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
206pub struct AssetPositionResponse {
207    /// Asset positions.
208    pub positions: Vec<AssetPositionResponseObject>,
209}
210
211/// Perpetual positions response.
212#[derive(Deserialize, Debug, Clone)]
213#[serde(rename_all = "camelCase")]
214#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
215pub struct PerpetualPositionResponse {
216    /// Perpetual positions.
217    pub positions: Vec<PerpetualPositionResponseObject>,
218}
219
220/// Pagination request.
221#[derive(Serialize, Default, Debug, Clone)]
222#[serde(rename_all = "camelCase")]
223#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
224pub struct PaginationRequest {
225    /// Limit.
226    pub limit: Option<u32>,
227    /// Offset.
228    pub offset: Option<u32>,
229}
230
231/// Affiliate metadata response.
232#[derive(Deserialize, Debug, Clone)]
233#[serde(rename_all = "camelCase")]
234#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
235pub struct AffiliateMetadataResponse {
236    /// Referral code.
237    pub referral_code: String,
238    /// Is volume eligible.
239    pub is_volume_eligible: bool,
240    /// Is affiliate.
241    pub is_affiliate: bool,
242}
243
244/// Affiliate address response.
245#[derive(Deserialize, Debug, Clone)]
246#[serde(rename_all = "camelCase")]
247#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
248pub struct AffiliateAddressResponse {
249    /// Address.
250    pub address: Address,
251}
252
253/// Affiliate snapshot response.
254#[derive(Deserialize, Debug, Clone)]
255#[serde(rename_all = "camelCase")]
256#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
257pub struct AffiliateSnapshotResponse {
258    /// Affiliate list.
259    pub affiliate_list: Vec<AffiliateSnapshotResponseObject>,
260    /// Total.
261    pub total: u32,
262    /// Current offset.
263    pub current_offset: u32,
264}
265
266/// Affiliate snapshot response object.
267#[derive(Deserialize, Debug, Clone)]
268#[serde(rename_all = "camelCase")]
269#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
270pub struct AffiliateSnapshotResponseObject {
271    /// Affiliate address.
272    pub affiliate_address: Address,
273    /// Affiliate referral code.
274    pub affiliate_referral_code: String,
275    /// Affiliate earnings.
276    pub affiliate_earnings: BigDecimal,
277    /// Affiliate referred trades.
278    pub affiliate_referred_trades: u32,
279    /// Affiliate total referred fees.
280    pub affiliate_total_referred_fees: BigDecimal,
281    /// Affiliate referred users.
282    pub affiliate_referred_users: u32,
283    /// Affiliate referred net protocol earnings.
284    pub affiliate_referred_net_protocol_earnings: BigDecimal,
285    /// Affiliate referred total volume.
286    pub affiliate_referred_total_volume: BigDecimal,
287    /// Affiliate referred maker fees.
288    pub affiliate_referred_maker_fees: BigDecimal,
289    /// Affiliate referred taker fees.
290    pub affiliate_referred_taker_fees: BigDecimal,
291    /// Affiliate referred maker rebates.
292    pub affiliate_referred_maker_rebates: BigDecimal,
293}
294
295/// Affiliate total volume response.
296#[derive(Deserialize, Debug, Clone)]
297#[serde(rename_all = "camelCase")]
298#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
299pub struct AffiliateTotalVolumeResponse {
300    /// Total volume.
301    pub total_volume: Option<BigDecimal>,
302}
303
304/// Pagination response.
305#[derive(Deserialize, Debug, Clone)]
306#[serde(rename_all = "camelCase")]
307#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
308pub struct PaginationResponse {
309    /// Page size.
310    pub page_size: Option<u32>,
311    /// Total results.
312    pub total_results: Option<u32>,
313    /// Offset.
314    pub offset: Option<u32>,
315}
316
317/// Transfers response.
318#[derive(Deserialize, Debug, Clone)]
319#[serde(rename_all = "camelCase")]
320#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
321pub struct TransferResponse {
322    /// List of transfers.
323    pub transfers: Vec<TransferResponseObject>,
324    /// Pagination.
325    #[serde(flatten)]
326    pub pagination: PaginationResponse,
327}
328
329/// Parent subaccount transfer response.
330#[derive(Deserialize, Debug, Clone)]
331#[serde(rename_all = "camelCase")]
332#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
333pub struct ParentSubaccountTransferResponse {
334    /// List of transfers.
335    pub transfers: Vec<ParentSubaccountTransferResponseObject>,
336}
337
338/// Trader search response.
339#[derive(Deserialize, Debug, Clone)]
340#[serde(rename_all = "camelCase")]
341#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
342pub struct TraderSearchResponse {
343    /// Result.
344    pub result: Option<TraderSearchResponseObject>,
345}
346
347/// Trader search response object.
348#[derive(Deserialize, Debug, Clone)]
349#[serde(rename_all = "camelCase")]
350#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
351pub struct TraderSearchResponseObject {
352    /// Address.
353    pub address: Address,
354    /// Subaccount number.
355    pub subaccount_number: SubaccountNumber,
356    /// Subaccount id.
357    pub subaccount_id: SubaccountId,
358    /// Username.
359    pub username: String,
360}
361
362/// Transfer between response.
363#[derive(Deserialize, Debug, Clone)]
364#[serde(rename_all = "camelCase")]
365#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
366pub struct TransferBetweenResponse {
367    /// List of transfers.
368    pub transfers_subset: Vec<TransferResponseObject>,
369    /// Total net transfers.
370    pub total_net_transfers: BigDecimal,
371    /// Pagination.
372    #[serde(flatten)]
373    pub pagination: PaginationResponse,
374}
375
376/// Funding payment response.
377#[derive(Deserialize, Debug, Clone)]
378#[serde(rename_all = "camelCase")]
379#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
380pub struct FundingPaymentResponse {
381    /// List of funding payments.
382    pub funding_payments: Vec<FundingPaymentResponseObject>,
383    /// Pagination.
384    #[serde(flatten)]
385    pub pagination: PaginationResponse,
386}
387
388/// Funding payment response object.
389#[derive(Deserialize, Debug, Clone)]
390#[serde(rename_all = "camelCase")]
391#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
392pub struct FundingPaymentResponseObject {
393    /// Time (UTC).
394    pub created_at: DateTime<Utc>,
395    /// Block height.
396    pub created_at_height: Height,
397    /// Perpetual id.
398    pub perpetual_id: String,
399    /// Ticker.
400    pub ticker: Ticker,
401    /// Oracle price.
402    pub oracle_price: BigDecimal,
403    /// Size.
404    pub size: BigDecimal,
405    /// Side.
406    pub side: FundingOrderSide,
407    /// Rate.
408    pub rate: BigDecimal,
409    /// Payment.
410    pub payment: BigDecimal,
411    /// Subaccount number.
412    pub subaccount_number: SubaccountNumber,
413    /// Funding index.
414    pub funding_index: String,
415}
416
417/// Funding order side.
418#[derive(Deserialize, Debug, Clone)]
419#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
420pub enum FundingOrderSide {
421    /// Long.
422    Long,
423    /// Short.
424    Short,
425}
426
427/// Transfer response.
428/// T is the type of the sender and recipient.
429#[derive(Deserialize, Debug, Clone)]
430#[serde(rename_all = "camelCase")]
431#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
432pub struct TransferResponseObject {
433    /// Transfer id.
434    pub id: TransferId,
435    /// Sender of transfer.
436    pub sender: Account,
437    /// Recipient of transfer.
438    pub recipient: Account,
439    /// Size of transfer.
440    pub size: BigDecimal,
441    /// Time (UTC).
442    pub created_at: DateTime<Utc>,
443    /// Block height.
444    pub created_at_height: Height,
445    /// Token symbol.
446    pub symbol: Symbol,
447    /// Transfer type.
448    #[serde(rename = "type")]
449    pub transfer_type: TransferType,
450    /// Transfer transaction hash.
451    pub transaction_hash: String,
452}
453
454/// Parent subaccount transfer response object.
455#[derive(Deserialize, Debug, Clone)]
456#[serde(rename_all = "camelCase")]
457#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
458pub struct ParentSubaccountTransferResponseObject {
459    /// Transfer id.
460    pub id: TransferId,
461    /// Sender of transfer.
462    pub sender: AccountWithParentSubaccountNumber,
463    /// Recipient of transfer.
464    pub recipient: AccountWithParentSubaccountNumber,
465    /// Size of transfer.
466    pub size: BigDecimal,
467    /// Time (UTC).
468    pub created_at: DateTime<Utc>,
469    /// Block height.
470    pub created_at_height: Height,
471    /// Token symbol.
472    pub symbol: Symbol,
473    /// Transfer type.
474    #[serde(rename = "type")]
475    pub transfer_type: TransferType,
476    /// Transfer transaction hash.
477    pub transaction_hash: String,
478}
479
480/// Orders list response.
481pub type ListOrdersResponse = Vec<OrderResponseObject>;
482
483/// Fills response.
484#[derive(Deserialize, Debug, Clone)]
485#[serde(rename_all = "camelCase")]
486#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
487pub struct FillResponse {
488    /// List of fills.
489    pub fills: Vec<FillResponseObject>,
490}
491
492/// Fill response.
493#[derive(Deserialize, Debug, Clone)]
494#[serde(rename_all = "camelCase")]
495#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
496pub struct FillResponseObject {
497    /// Fill id.
498    pub id: FillId,
499    /// Side (buy/sell).
500    pub side: OrderSide,
501    /// Liquidity.
502    pub liquidity: Liquidity,
503    /// Fill type.
504    #[serde(rename = "type")]
505    pub fill_type: FillType,
506    /// Market ticker.
507    pub market: Ticker,
508    /// Market type.
509    pub market_type: MarketType,
510    /// Price.
511    pub price: Price,
512    /// Size.
513    pub size: BigDecimal,
514    /// Fee.
515    pub fee: BigDecimal,
516    /// Affiliate rev share.
517    pub affiliate_rev_share: BigDecimal,
518    /// Time (UTC).
519    pub created_at: DateTime<Utc>,
520    /// Block height.
521    pub created_at_height: Height,
522    /// Order id.
523    pub order_id: Option<OrderId>,
524    /// Client metadata.
525    pub client_metadata: Option<ClientMetadata>,
526    /// Subaccount number.
527    pub subaccount_number: SubaccountNumber,
528    /// Builder fee.
529    pub builder_fee: Option<BigDecimal>,
530    /// Builder address.
531    pub builder_address: Option<Address>,
532    /// Order router address.
533    pub order_router_address: Option<Address>,
534    /// Order router fee.
535    pub order_router_fee: Option<BigDecimal>,
536}
537
538/// Profit and loss reports.
539#[derive(Deserialize, Debug, Clone)]
540#[serde(rename_all = "camelCase")]
541#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
542pub struct HistoricalPnlResponse {
543    /// List of PnL reports.
544    pub historical_pnl: Vec<PnlTicksResponseObject>,
545}
546
547/// Profit and loss report.
548#[derive(Deserialize, Debug, Clone)]
549#[serde(rename_all = "camelCase")]
550#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
551pub struct PnlTicksResponseObject {
552    /// Block height.
553    pub block_height: Height,
554    /// Time (UTC).
555    pub block_time: DateTime<Utc>,
556    /// Time (UTC).
557    pub created_at: DateTime<Utc>,
558    /// Equity.
559    pub equity: BigDecimal,
560    /// Total PnL.
561    pub total_pnl: BigDecimal,
562    /// Net transfers.
563    pub net_transfers: BigDecimal,
564}
565
566/// Trading rewards reports.
567#[derive(Deserialize, Debug, Clone)]
568#[serde(rename_all = "camelCase")]
569#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
570pub struct HistoricalBlockTradingRewardsResponse {
571    /// List of reports.
572    pub rewards: Vec<HistoricalBlockTradingReward>,
573}
574
575/// Trading rewards report.
576#[derive(Deserialize, Debug, Clone)]
577#[serde(rename_all = "camelCase")]
578#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
579pub struct HistoricalBlockTradingReward {
580    /// Trading reward amount.
581    pub trading_reward: BigDecimal,
582    /// Block height.
583    pub created_at_height: Height,
584    /// Time (UTC).
585    pub created_at: DateTime<Utc>,
586}
587
588/// Trading rewards aggregation reports.
589#[derive(Deserialize, Debug, Clone)]
590#[serde(rename_all = "camelCase")]
591#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
592pub struct HistoricalTradingRewardAggregationsResponse {
593    /// List of reports.
594    pub rewards: Vec<HistoricalTradingRewardAggregation>,
595}
596
597/// Trading rewards aggregation report.
598#[derive(Deserialize, Debug, Clone)]
599#[serde(rename_all = "camelCase")]
600#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
601pub struct HistoricalTradingRewardAggregation {
602    /// Trading reward amount.
603    pub trading_reward: BigDecimal,
604    /// Block height.
605    pub started_at_height: Height,
606    /// Time (UTC).
607    pub started_at: DateTime<Utc>,
608    /// Block height.
609    pub ended_at_height: Option<Height>,
610    /// Time (UTC).
611    pub ended_at: Option<DateTime<Utc>>,
612    /// Aggregation period.
613    pub period: TradingRewardAggregationPeriod,
614}
615
616/// MegaVault Profit and loss reports.
617#[derive(Deserialize, Debug, Clone)]
618#[serde(rename_all = "camelCase")]
619#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
620pub struct MegaVaultHistoricalPnlResponse {
621    /// List of PnL reports.
622    pub megavault_pnl: Vec<PnlTicksResponseObject>,
623}
624
625/// MegaVault Profit and loss reports.
626#[derive(Deserialize, Debug, Clone)]
627#[serde(rename_all = "camelCase")]
628#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
629pub struct MegaVaultPositionResponse {
630    /// List MegaVault positions.
631    pub positions: Vec<VaultPosition>,
632}
633
634/// Vaults profit and loss reports.
635#[derive(Deserialize, Debug, Clone)]
636#[serde(rename_all = "camelCase")]
637#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
638pub struct VaultsHistoricalPnLResponse {
639    /// List of PnL reports.
640    pub vaults_pnl: Vec<VaultHistoricalPnl>,
641}
642
643/// Vault Profit and loss reports.
644#[derive(Deserialize, Debug, Clone)]
645#[serde(rename_all = "camelCase")]
646#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
647pub struct VaultHistoricalPnl {
648    /// Associated ticker.
649    pub ticker: String,
650    /// List of PnL reports.
651    pub historical_pnl: Vec<PnlTicksResponseObject>,
652}
653
654/// Vault position.
655#[derive(Deserialize, Debug, Clone)]
656#[serde(rename_all = "camelCase")]
657#[cfg_attr(any(test, feature = "strict-serde"), serde(deny_unknown_fields))]
658pub struct VaultPosition {
659    /// Associated ticker.
660    pub ticker: String,
661    /// Asset position.
662    pub asset_position: Option<AssetPositionResponseObject>,
663    /// Perpetual position.
664    pub perpetual_position: Option<PerpetualPositionResponseObject>,
665    /// Equity.
666    pub equity: BigDecimal,
667}