dfns_sdk_rs/api/staking/
delegated_client.rs

1// @dfns-sdk-rs/src/api/staking/delegated_client.rs
2
3use super::types::*;
4use crate::{
5    client::{
6        base_auth_api::{
7            BaseAuthApi, CreateUserActionChallengeRequest, SignUserActionChallengeRequest,
8        },
9        delegated_api_client::DfnsDelegatedApiClientOptions,
10    },
11    error::DfnsError,
12    signer::UserActionChallenge,
13    utils::{
14        fetch::{simple_fetch, FetchOptions, HttpMethod},
15        url::{build_path_and_query, PathAndQueryParams},
16    },
17};
18use serde_json::json;
19use std::collections::HashMap;
20
21pub struct DelegatedStakingClient {
22    api_options: DfnsDelegatedApiClientOptions,
23}
24
25impl DelegatedStakingClient {
26    pub fn new(api_options: DfnsDelegatedApiClientOptions) -> Self {
27        Self { api_options }
28    }
29
30    pub async fn create_stake_init(
31        &self,
32        request: CreateStakeRequest,
33    ) -> Result<UserActionChallenge, DfnsError> {
34        let path = build_path_and_query(
35            "/staking/stakes",
36            &PathAndQueryParams {
37                path: HashMap::new(),
38                query: HashMap::new(),
39            },
40        );
41
42        BaseAuthApi::create_user_action_challenge(
43            CreateUserActionChallengeRequest {
44                user_action_http_method: HttpMethod::POST,
45                user_action_http_path: path,
46                user_action_payload: serde_json::to_string(&request.body)?,
47                user_action_server_kind: "Api".to_string(),
48            },
49            self.api_options.base.clone(),
50        )
51        .await
52    }
53
54    pub async fn create_stake_complete(
55        &self,
56        request: CreateStakeRequest,
57        signed_challenge: SignUserActionChallengeRequest,
58    ) -> Result<CreateStakeResponse, DfnsError> {
59        let path = build_path_and_query(
60            "/staking/stakes",
61            &PathAndQueryParams {
62                path: HashMap::new(),
63                query: HashMap::new(),
64            },
65        );
66
67        let user_action = BaseAuthApi::sign_user_action_challenge(
68            signed_challenge,
69            self.api_options.base.clone(),
70        )
71        .await?
72        .user_action;
73
74        let mut headers = HashMap::new();
75        headers.insert("x-dfns-useraction".to_string(), user_action);
76
77        simple_fetch(
78            &path,
79            FetchOptions {
80                method: HttpMethod::POST,
81                headers: Some(headers),
82                body: Some(json!(request.body)),
83                api_options: self.api_options.base.clone(),
84            },
85        )
86        .await
87    }
88
89    pub async fn create_stake_action_init(
90        &self,
91        request: CreateStakeActionRequest,
92    ) -> Result<UserActionChallenge, DfnsError> {
93        let path = build_path_and_query(
94            "/staking/stakes/:stakeId/actions",
95            &PathAndQueryParams {
96                path: {
97                    let mut map = HashMap::new();
98                    map.insert("stakeId".to_string(), request.stake_id.clone());
99                    map
100                },
101                query: HashMap::new(),
102            },
103        );
104
105        BaseAuthApi::create_user_action_challenge(
106            CreateUserActionChallengeRequest {
107                user_action_http_method: HttpMethod::POST,
108                user_action_http_path: path,
109                user_action_payload: serde_json::to_string(&request.body)?,
110                user_action_server_kind: "Api".to_string(),
111            },
112            self.api_options.base.clone(),
113        )
114        .await
115    }
116
117    pub async fn create_stake_action_complete(
118        &self,
119        request: CreateStakeActionRequest,
120        signed_challenge: SignUserActionChallengeRequest,
121    ) -> Result<CreateStakeActionResponse, DfnsError> {
122        let path = build_path_and_query(
123            "/staking/stakes/:stakeId/actions",
124            &PathAndQueryParams {
125                path: {
126                    let mut map = HashMap::new();
127                    map.insert("stakeId".to_string(), request.stake_id.clone());
128                    map
129                },
130                query: HashMap::new(),
131            },
132        );
133
134        let user_action = BaseAuthApi::sign_user_action_challenge(
135            signed_challenge,
136            self.api_options.base.clone(),
137        )
138        .await?
139        .user_action;
140
141        let mut headers = HashMap::new();
142        headers.insert("x-dfns-useraction".to_string(), user_action);
143
144        simple_fetch(
145            &path,
146            FetchOptions {
147                method: HttpMethod::POST,
148                headers: Some(headers),
149                body: Some(json!(request.body)),
150                api_options: self.api_options.base.clone(),
151            },
152        )
153        .await
154    }
155
156    pub async fn get_stake_rewards(
157        &self,
158        request: GetStakeRewardsRequest,
159    ) -> Result<GetStakeRewardsResponse, DfnsError> {
160        let path = build_path_and_query(
161            "/staking/stakes/:stakeId/rewards",
162            &PathAndQueryParams {
163                path: {
164                    let mut map = HashMap::new();
165                    map.insert("stakeId".to_string(), request.stake_id.clone());
166                    map
167                },
168                query: HashMap::new(),
169            },
170        );
171
172        simple_fetch(
173            &path,
174            FetchOptions {
175                method: HttpMethod::GET,
176                headers: None,
177                body: None,
178                api_options: self.api_options.base.clone(),
179            },
180        )
181        .await
182    }
183
184    pub async fn list_stake_actions(
185        &self,
186        stake_id: String,
187        request: Option<ListStakeActionsRequest>,
188    ) -> Result<ListStakeActionsResponse, DfnsError> {
189        let path = build_path_and_query(
190            "/staking/stakes/:stakeId/actions",
191            &PathAndQueryParams {
192                path: {
193                    let mut map = HashMap::new();
194                    map.insert("stakeId".to_string(), stake_id);
195                    map
196                },
197                query: request
198                    .and_then(|r| r.query)
199                    .map(|q| {
200                        let mut map = HashMap::new();
201                        if let Some(limit) = q.limit {
202                            map.insert("limit".to_string(), limit.to_string());
203                        }
204                        if let Some(token) = q.pagination_token {
205                            map.insert("paginationToken".to_string(), token);
206                        }
207                        map
208                    })
209                    .unwrap_or_default(),
210            },
211        );
212
213        simple_fetch(
214            &path,
215            FetchOptions {
216                method: HttpMethod::GET,
217                headers: None,
218                body: None,
219                api_options: self.api_options.base.clone(),
220            },
221        )
222        .await
223    }
224
225    pub async fn list_stakes(
226        &self,
227        request: Option<ListStakesRequest>,
228    ) -> Result<ListStakesResponse, DfnsError> {
229        let path = build_path_and_query(
230            "/staking/stakes",
231            &PathAndQueryParams {
232                path: HashMap::new(),
233                query: request
234                    .and_then(|r| r.query)
235                    .map(|q| {
236                        let mut map = HashMap::new();
237                        if let Some(limit) = q.limit {
238                            map.insert("limit".to_string(), limit.to_string());
239                        }
240                        if let Some(token) = q.pagination_token {
241                            map.insert("paginationToken".to_string(), token);
242                        }
243                        map
244                    })
245                    .unwrap_or_default(),
246            },
247        );
248
249        simple_fetch(
250            &path,
251            FetchOptions {
252                method: HttpMethod::GET,
253                headers: None,
254                body: None,
255                api_options: self.api_options.base.clone(),
256            },
257        )
258        .await
259    }
260}