@@ -10,15 +10,24 @@ use serde_json;
10
10
use std:: time:: Duration ;
11
11
use thiserror:: Error ;
12
12
13
-
14
13
use 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
+ } ;
16
17
17
18
/// Authentication token for IAW operations
18
19
pub type AuthToken = String ;
19
20
20
21
/// 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
+ ) ]
22
31
#[ serde( tag = "type" , rename_all = "SCREAMING_SNAKE_CASE" ) ]
23
32
pub enum IAWError {
24
33
#[ error( "API error: {0}" ) ]
@@ -99,13 +108,11 @@ pub struct SignUserOpData {
99
108
pub signature : String ,
100
109
}
101
110
102
-
103
-
104
111
/// Client for interacting with the IAW (In-App Wallet) service
105
112
#[ derive( Clone ) ]
106
113
pub struct IAWClient {
107
- _base_url : String ,
108
- _http_client : reqwest:: Client ,
114
+ base_url : String ,
115
+ http_client : reqwest:: Client ,
109
116
}
110
117
111
118
impl IAWClient {
@@ -123,19 +130,16 @@ impl IAWClient {
123
130
. map_err ( IAWError :: from) ?;
124
131
125
132
Ok ( Self {
126
- _base_url : base_url. into ( ) ,
127
- _http_client : http_client,
133
+ base_url : base_url. into ( ) ,
134
+ http_client,
128
135
} )
129
136
}
130
137
131
138
/// 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 {
136
140
Self {
137
- _base_url : base_url. into ( ) ,
138
- _http_client : http_client,
141
+ base_url : base_url. into ( ) ,
142
+ http_client,
139
143
}
140
144
}
141
145
@@ -151,14 +155,17 @@ impl IAWClient {
151
155
) -> Result < SignMessageData , IAWError > {
152
156
// Get ThirdwebAuth headers for billing/authentication
153
157
let mut headers = thirdweb_auth. to_header_map ( ) ?;
154
-
158
+
155
159
// Add IAW service authentication
156
160
headers. insert (
157
161
"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 ( ) ) ) ?,
160
167
) ;
161
-
168
+
162
169
// Add content type
163
170
headers. insert (
164
171
"Content-Type" ,
@@ -182,8 +189,9 @@ impl IAWClient {
182
189
} ) ;
183
190
184
191
// 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
187
195
. post ( & url)
188
196
. headers ( headers)
189
197
. json ( & payload)
@@ -194,13 +202,16 @@ impl IAWClient {
194
202
return Err ( IAWError :: ApiError ( format ! (
195
203
"Failed to sign message - {} {}" ,
196
204
response. status( ) ,
197
- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
205
+ response
206
+ . status( )
207
+ . canonical_reason( )
208
+ . unwrap_or( "Unknown error" )
198
209
) ) ) ;
199
210
}
200
211
201
212
// Parse the response
202
213
let signed_response: serde_json:: Value = response. json ( ) . await ?;
203
-
214
+
204
215
// Extract just the signature as requested
205
216
let signature = signed_response
206
217
. get ( "signature" )
@@ -222,14 +233,17 @@ impl IAWClient {
222
233
) -> Result < SignTypedDataData , IAWError > {
223
234
// Get ThirdwebAuth headers for billing/authentication
224
235
let mut headers = thirdweb_auth. to_header_map ( ) ?;
225
-
236
+
226
237
// Add IAW service authentication
227
238
headers. insert (
228
239
"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 ( ) ) ) ?,
231
245
) ;
232
-
246
+
233
247
// Add content type
234
248
headers. insert (
235
249
"Content-Type" ,
@@ -240,8 +254,9 @@ impl IAWClient {
240
254
let payload = serde_json:: json!( typed_data) ;
241
255
242
256
// 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
245
260
. post ( & url)
246
261
. headers ( headers)
247
262
. json ( & payload)
@@ -252,13 +267,16 @@ impl IAWClient {
252
267
return Err ( IAWError :: ApiError ( format ! (
253
268
"Failed to sign typed data - {} {}" ,
254
269
response. status( ) ,
255
- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
270
+ response
271
+ . status( )
272
+ . canonical_reason( )
273
+ . unwrap_or( "Unknown error" )
256
274
) ) ) ;
257
275
}
258
276
259
277
// Parse the response
260
278
let signed_response: serde_json:: Value = response. json ( ) . await ?;
261
-
279
+
262
280
// Extract just the signature as requested
263
281
let signature = signed_response
264
282
. get ( "signature" )
@@ -279,14 +297,17 @@ impl IAWClient {
279
297
) -> Result < SignTransactionData , IAWError > {
280
298
// Get ThirdwebAuth headers for billing/authentication
281
299
let mut headers = thirdweb_auth. to_header_map ( ) ?;
282
-
300
+
283
301
// Add IAW service authentication
284
302
headers. insert (
285
303
"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 ( ) ) ) ?,
288
309
) ;
289
-
310
+
290
311
// Add content type
291
312
headers. insert (
292
313
"Content-Type" ,
@@ -299,8 +320,9 @@ impl IAWClient {
299
320
} ) ;
300
321
301
322
// 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
304
326
. post ( & url)
305
327
. headers ( headers)
306
328
. json ( & payload)
@@ -311,13 +333,16 @@ impl IAWClient {
311
333
return Err ( IAWError :: ApiError ( format ! (
312
334
"Failed to sign transaction - {} {}" ,
313
335
response. status( ) ,
314
- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
336
+ response
337
+ . status( )
338
+ . canonical_reason( )
339
+ . unwrap_or( "Unknown error" )
315
340
) ) ) ;
316
341
}
317
342
318
343
// Parse the response
319
344
let signed_response: serde_json:: Value = response. json ( ) . await ?;
320
-
345
+
321
346
// Extract just the signature as requested
322
347
let signature = signed_response
323
348
. get ( "signature" )
@@ -339,14 +364,17 @@ impl IAWClient {
339
364
) -> Result < SignAuthorizationData , IAWError > {
340
365
// Get ThirdwebAuth headers for billing/authentication
341
366
let mut headers = thirdweb_auth. to_header_map ( ) ?;
342
-
367
+
343
368
// Add IAW service authentication
344
369
headers. insert (
345
370
"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 ( ) ) ) ?,
348
376
) ;
349
-
377
+
350
378
// Add content type
351
379
headers. insert (
352
380
"Content-Type" ,
@@ -361,8 +389,9 @@ impl IAWClient {
361
389
} ) ;
362
390
363
391
// 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
366
395
. post ( & url)
367
396
. headers ( headers)
368
397
. json ( & payload)
@@ -373,18 +402,24 @@ impl IAWClient {
373
402
return Err ( IAWError :: ApiError ( format ! (
374
403
"Failed to sign authorization - {} {}" ,
375
404
response. status( ) ,
376
- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
405
+ response
406
+ . status( )
407
+ . canonical_reason( )
408
+ . unwrap_or( "Unknown error" )
377
409
) ) ) ;
378
410
}
379
411
380
412
// Parse the response
381
413
let signed_response: serde_json:: Value = response. json ( ) . await ?;
382
-
414
+
383
415
// Extract the signed authorization from the response
384
416
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 ( ) ,
388
423
) ?;
389
424
390
425
Ok ( SignAuthorizationData {
@@ -404,26 +439,25 @@ impl IAWClient {
404
439
) -> Result < SignUserOpData , IAWError > {
405
440
// Compute the userop hash based on version
406
441
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) ?,
413
444
} ;
414
-
445
+
415
446
let userop_hash = format ! ( "0x{}" , hex:: encode( hash. as_slice( ) ) ) ;
416
447
tracing:: info!( "Computed userop hash: {}" , userop_hash) ;
417
448
// Get ThirdwebAuth headers for billing/authentication
418
449
let mut headers = thirdweb_auth. to_header_map ( ) ?;
419
-
450
+
420
451
// Add IAW service authentication
421
452
headers. insert (
422
453
"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 ( ) ) ) ?,
425
459
) ;
426
-
460
+
427
461
// Add content type
428
462
headers. insert (
429
463
"Content-Type" ,
@@ -436,13 +470,14 @@ impl IAWClient {
436
470
"message" : userop_hash,
437
471
"isRaw" : true ,
438
472
"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 ( ) } ) ? ,
440
474
}
441
475
} ) ;
442
476
443
477
// 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
446
481
. post ( & url)
447
482
. headers ( headers)
448
483
. json ( & payload)
@@ -453,13 +488,16 @@ impl IAWClient {
453
488
return Err ( IAWError :: ApiError ( format ! (
454
489
"Failed to sign userop - {} {}" ,
455
490
response. status( ) ,
456
- response. status( ) . canonical_reason( ) . unwrap_or( "Unknown error" )
491
+ response
492
+ . status( )
493
+ . canonical_reason( )
494
+ . unwrap_or( "Unknown error" )
457
495
) ) ) ;
458
496
}
459
497
460
498
// Parse the response
461
499
let signed_response: serde_json:: Value = response. json ( ) . await ?;
462
-
500
+
463
501
// Extract just the signature as requested
464
502
let signature = signed_response
465
503
. get ( "signature" )
0 commit comments