@@ -10,15 +10,24 @@ use serde_json;
1010use std:: time:: Duration ;
1111use thiserror:: Error ;
1212
13-
1413use crate :: { auth:: ThirdwebAuth , error:: SerializableReqwestError } ;
15- use engine_aa_types:: { VersionedUserOp , UserOpError , compute_user_op_v06_hash, compute_user_op_v07_hash} ;
14+ use engine_aa_types:: {
15+ UserOpError , VersionedUserOp , compute_user_op_v06_hash, compute_user_op_v07_hash,
16+ } ;
1617
1718/// Authentication token for IAW operations
1819pub type AuthToken = String ;
1920
2021/// Error types for IAW operations
21- #[ derive( Error , Debug , Clone , serde:: Serialize , serde:: Deserialize , schemars:: JsonSchema , utoipa:: ToSchema ) ]
22+ #[ derive(
23+ Error ,
24+ Debug ,
25+ Clone ,
26+ serde:: Serialize ,
27+ serde:: Deserialize ,
28+ schemars:: JsonSchema ,
29+ utoipa:: ToSchema ,
30+ ) ]
2231#[ serde( tag = "type" , rename_all = "SCREAMING_SNAKE_CASE" ) ]
2332pub enum IAWError {
2433 #[ error( "API error: {0}" ) ]
@@ -99,13 +108,11 @@ pub struct SignUserOpData {
99108 pub signature : String ,
100109}
101110
102-
103-
104111/// Client for interacting with the IAW (In-App Wallet) service
105112#[ derive( Clone ) ]
106113pub struct IAWClient {
107- _base_url : String ,
108- _http_client : reqwest:: Client ,
114+ base_url : String ,
115+ http_client : reqwest:: Client ,
109116}
110117
111118impl IAWClient {
@@ -123,19 +130,16 @@ impl IAWClient {
123130 . map_err ( IAWError :: from) ?;
124131
125132 Ok ( Self {
126- _base_url : base_url. into ( ) ,
127- _http_client : http_client,
133+ base_url : base_url. into ( ) ,
134+ http_client,
128135 } )
129136 }
130137
131138 /// Create a new IAWClient with a custom HTTP client
132- pub fn with_http_client (
133- base_url : impl Into < String > ,
134- http_client : reqwest:: Client ,
135- ) -> Self {
139+ pub fn with_http_client ( base_url : impl Into < String > , http_client : reqwest:: Client ) -> Self {
136140 Self {
137- _base_url : base_url. into ( ) ,
138- _http_client : http_client,
141+ base_url : base_url. into ( ) ,
142+ http_client,
139143 }
140144 }
141145
@@ -151,14 +155,17 @@ impl IAWClient {
151155 ) -> Result < SignMessageData , IAWError > {
152156 // Get ThirdwebAuth headers for billing/authentication
153157 let mut headers = thirdweb_auth. to_header_map ( ) ?;
154-
158+
155159 // Add IAW service authentication
156160 headers. insert (
157161 "Authorization" ,
158- reqwest:: header:: HeaderValue :: from_str ( & format ! ( "Bearer embedded-wallet-token:{}" , auth_token) )
159- . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
162+ reqwest:: header:: HeaderValue :: from_str ( & format ! (
163+ "Bearer embedded-wallet-token:{}" ,
164+ auth_token
165+ ) )
166+ . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
160167 ) ;
161-
168+
162169 // Add content type
163170 headers. insert (
164171 "Content-Type" ,
@@ -182,8 +189,9 @@ impl IAWClient {
182189 } ) ;
183190
184191 // Make the request to IAW service
185- let url = format ! ( "{}/api/v1/enclave-wallet/sign-message" , self . _base_url) ;
186- let response = self . _http_client
192+ let url = format ! ( "{}/api/v1/enclave-wallet/sign-message" , self . base_url) ;
193+ let response = self
194+ . http_client
187195 . post ( & url)
188196 . headers ( headers)
189197 . json ( & payload)
@@ -194,13 +202,16 @@ impl IAWClient {
194202 return Err ( IAWError :: ApiError ( format ! (
195203 "Failed to sign message - {} {}" ,
196204 response. status( ) ,
197- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
205+ response
206+ . status( )
207+ . canonical_reason( )
208+ . unwrap_or( "Unknown error" )
198209 ) ) ) ;
199210 }
200211
201212 // Parse the response
202213 let signed_response: serde_json:: Value = response. json ( ) . await ?;
203-
214+
204215 // Extract just the signature as requested
205216 let signature = signed_response
206217 . get ( "signature" )
@@ -222,14 +233,17 @@ impl IAWClient {
222233 ) -> Result < SignTypedDataData , IAWError > {
223234 // Get ThirdwebAuth headers for billing/authentication
224235 let mut headers = thirdweb_auth. to_header_map ( ) ?;
225-
236+
226237 // Add IAW service authentication
227238 headers. insert (
228239 "Authorization" ,
229- reqwest:: header:: HeaderValue :: from_str ( & format ! ( "Bearer embedded-wallet-token:{}" , auth_token) )
230- . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
240+ reqwest:: header:: HeaderValue :: from_str ( & format ! (
241+ "Bearer embedded-wallet-token:{}" ,
242+ auth_token
243+ ) )
244+ . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
231245 ) ;
232-
246+
233247 // Add content type
234248 headers. insert (
235249 "Content-Type" ,
@@ -240,8 +254,9 @@ impl IAWClient {
240254 let payload = serde_json:: json!( typed_data) ;
241255
242256 // Make the request to IAW service
243- let url = format ! ( "{}/api/v1/enclave-wallet/sign-typed-data" , self . _base_url) ;
244- let response = self . _http_client
257+ let url = format ! ( "{}/api/v1/enclave-wallet/sign-typed-data" , self . base_url) ;
258+ let response = self
259+ . http_client
245260 . post ( & url)
246261 . headers ( headers)
247262 . json ( & payload)
@@ -252,13 +267,16 @@ impl IAWClient {
252267 return Err ( IAWError :: ApiError ( format ! (
253268 "Failed to sign typed data - {} {}" ,
254269 response. status( ) ,
255- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
270+ response
271+ . status( )
272+ . canonical_reason( )
273+ . unwrap_or( "Unknown error" )
256274 ) ) ) ;
257275 }
258276
259277 // Parse the response
260278 let signed_response: serde_json:: Value = response. json ( ) . await ?;
261-
279+
262280 // Extract just the signature as requested
263281 let signature = signed_response
264282 . get ( "signature" )
@@ -279,14 +297,17 @@ impl IAWClient {
279297 ) -> Result < SignTransactionData , IAWError > {
280298 // Get ThirdwebAuth headers for billing/authentication
281299 let mut headers = thirdweb_auth. to_header_map ( ) ?;
282-
300+
283301 // Add IAW service authentication
284302 headers. insert (
285303 "Authorization" ,
286- reqwest:: header:: HeaderValue :: from_str ( & format ! ( "Bearer embedded-wallet-token:{}" , auth_token) )
287- . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
304+ reqwest:: header:: HeaderValue :: from_str ( & format ! (
305+ "Bearer embedded-wallet-token:{}" ,
306+ auth_token
307+ ) )
308+ . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
288309 ) ;
289-
310+
290311 // Add content type
291312 headers. insert (
292313 "Content-Type" ,
@@ -299,8 +320,9 @@ impl IAWClient {
299320 } ) ;
300321
301322 // Make the request to IAW service
302- let url = format ! ( "{}/api/v1/enclave-wallet/sign-transaction" , self . _base_url) ;
303- let response = self . _http_client
323+ let url = format ! ( "{}/api/v1/enclave-wallet/sign-transaction" , self . base_url) ;
324+ let response = self
325+ . http_client
304326 . post ( & url)
305327 . headers ( headers)
306328 . json ( & payload)
@@ -311,13 +333,16 @@ impl IAWClient {
311333 return Err ( IAWError :: ApiError ( format ! (
312334 "Failed to sign transaction - {} {}" ,
313335 response. status( ) ,
314- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
336+ response
337+ . status( )
338+ . canonical_reason( )
339+ . unwrap_or( "Unknown error" )
315340 ) ) ) ;
316341 }
317342
318343 // Parse the response
319344 let signed_response: serde_json:: Value = response. json ( ) . await ?;
320-
345+
321346 // Extract just the signature as requested
322347 let signature = signed_response
323348 . get ( "signature" )
@@ -339,14 +364,17 @@ impl IAWClient {
339364 ) -> Result < SignAuthorizationData , IAWError > {
340365 // Get ThirdwebAuth headers for billing/authentication
341366 let mut headers = thirdweb_auth. to_header_map ( ) ?;
342-
367+
343368 // Add IAW service authentication
344369 headers. insert (
345370 "Authorization" ,
346- reqwest:: header:: HeaderValue :: from_str ( & format ! ( "Bearer embedded-wallet-token:{}" , auth_token) )
347- . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
371+ reqwest:: header:: HeaderValue :: from_str ( & format ! (
372+ "Bearer embedded-wallet-token:{}" ,
373+ auth_token
374+ ) )
375+ . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
348376 ) ;
349-
377+
350378 // Add content type
351379 headers. insert (
352380 "Content-Type" ,
@@ -361,8 +389,9 @@ impl IAWClient {
361389 } ) ;
362390
363391 // Make the request to IAW service
364- let url = format ! ( "{}/api/v1/enclave-wallet/sign-authorization" , self . _base_url) ;
365- let response = self . _http_client
392+ let url = format ! ( "{}/api/v1/enclave-wallet/sign-authorization" , self . base_url) ;
393+ let response = self
394+ . http_client
366395 . post ( & url)
367396 . headers ( headers)
368397 . json ( & payload)
@@ -373,18 +402,24 @@ impl IAWClient {
373402 return Err ( IAWError :: ApiError ( format ! (
374403 "Failed to sign authorization - {} {}" ,
375404 response. status( ) ,
376- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
405+ response
406+ . status( )
407+ . canonical_reason( )
408+ . unwrap_or( "Unknown error" )
377409 ) ) ) ;
378410 }
379411
380412 // Parse the response
381413 let signed_response: serde_json:: Value = response. json ( ) . await ?;
382-
414+
383415 // Extract the signed authorization from the response
384416 let signed_authorization: SignedAuthorization = serde_json:: from_value (
385- signed_response. get ( "signedAuthorization" )
386- . ok_or_else ( || IAWError :: ApiError ( "No signedAuthorization in response" . to_string ( ) ) ) ?
387- . clone ( )
417+ signed_response
418+ . get ( "signedAuthorization" )
419+ . ok_or_else ( || {
420+ IAWError :: ApiError ( "No signedAuthorization in response" . to_string ( ) )
421+ } ) ?
422+ . clone ( ) ,
388423 ) ?;
389424
390425 Ok ( SignAuthorizationData {
@@ -404,26 +439,25 @@ impl IAWClient {
404439 ) -> Result < SignUserOpData , IAWError > {
405440 // Compute the userop hash based on version
406441 let hash = match & userop {
407- VersionedUserOp :: V0_6 ( op) => {
408- compute_user_op_v06_hash ( op, entrypoint, chain_id) ?
409- }
410- VersionedUserOp :: V0_7 ( op) => {
411- compute_user_op_v07_hash ( op, entrypoint, chain_id) ?
412- }
442+ VersionedUserOp :: V0_6 ( op) => compute_user_op_v06_hash ( op, entrypoint, chain_id) ?,
443+ VersionedUserOp :: V0_7 ( op) => compute_user_op_v07_hash ( op, entrypoint, chain_id) ?,
413444 } ;
414-
445+
415446 let userop_hash = format ! ( "0x{}" , hex:: encode( hash. as_slice( ) ) ) ;
416447 tracing:: info!( "Computed userop hash: {}" , userop_hash) ;
417448 // Get ThirdwebAuth headers for billing/authentication
418449 let mut headers = thirdweb_auth. to_header_map ( ) ?;
419-
450+
420451 // Add IAW service authentication
421452 headers. insert (
422453 "Authorization" ,
423- reqwest:: header:: HeaderValue :: from_str ( & format ! ( "Bearer embedded-wallet-token:{}" , auth_token) )
424- . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
454+ reqwest:: header:: HeaderValue :: from_str ( & format ! (
455+ "Bearer embedded-wallet-token:{}" ,
456+ auth_token
457+ ) )
458+ . map_err ( |_| IAWError :: AuthError ( "Invalid auth token format" . to_string ( ) ) ) ?,
425459 ) ;
426-
460+
427461 // Add content type
428462 headers. insert (
429463 "Content-Type" ,
@@ -436,13 +470,14 @@ impl IAWClient {
436470 "message" : userop_hash,
437471 "isRaw" : true ,
438472 "chainId" : chain_id,
439- "originalMessage" : serde_json:: to_string( & userop) . unwrap ( ) ,
473+ "originalMessage" : serde_json:: to_string( & userop) . map_err ( |e| IAWError :: SerializationError { message : e . to_string ( ) } ) ? ,
440474 }
441475 } ) ;
442476
443477 // Make the request to IAW service with explicit timeout
444- let url = format ! ( "{}/api/v1/enclave-wallet/sign-message" , self . _base_url) ;
445- let response = self . _http_client
478+ let url = format ! ( "{}/api/v1/enclave-wallet/sign-message" , self . base_url) ;
479+ let response = self
480+ . http_client
446481 . post ( & url)
447482 . headers ( headers)
448483 . json ( & payload)
@@ -453,13 +488,16 @@ impl IAWClient {
453488 return Err ( IAWError :: ApiError ( format ! (
454489 "Failed to sign userop - {} {}" ,
455490 response. status( ) ,
456- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
491+ response
492+ . status( )
493+ . canonical_reason( )
494+ . unwrap_or( "Unknown error" )
457495 ) ) ) ;
458496 }
459497
460498 // Parse the response
461499 let signed_response: serde_json:: Value = response. json ( ) . await ?;
462-
500+
463501 // Extract just the signature as requested
464502 let signature = signed_response
465503 . get ( "signature" )
0 commit comments