1use 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}