11use alloy:: {
22 hex:: FromHex ,
33 primitives:: { Address , Bytes , ChainId } ,
4- rpc:: types:: { PackedUserOperation , UserOperation } ,
54} ;
6- use serde:: { Deserialize , Serialize } ;
5+ use thirdweb_core:: iaw:: IAWClient ;
6+ use types_core:: UserOpVersion ;
77use vault_sdk:: VaultClient ;
88use vault_types:: {
99 enclave:: encrypted:: eoa:: StructuredMessageInput ,
@@ -12,16 +12,10 @@ use vault_types::{
1212
1313use crate :: { credentials:: SigningCredential , error:: EngineError } ;
1414
15- #[ derive( Debug , Clone , Serialize , Deserialize ) ]
16- #[ serde( untagged) ]
17- pub enum UserOpVersion {
18- V0_6 ( UserOperation ) ,
19- V0_7 ( PackedUserOperation ) ,
20- }
21-
2215#[ derive( Clone ) ]
2316pub struct UserOpSigner {
2417 pub vault_client : VaultClient ,
18+ pub iaw_client : IAWClient ,
2519}
2620
2721pub struct UserOpSignerParams {
@@ -32,49 +26,47 @@ pub struct UserOpSignerParams {
3226 pub chain_id : ChainId ,
3327}
3428
35- impl UserOpVersion {
36- fn to_vault_input ( & self , entrypoint : Address ) -> StructuredMessageInput {
37- match self {
38- UserOpVersion :: V0_6 ( userop) => {
39- StructuredMessageInput :: UserOperationV06Input ( UserOperationV06Input {
40- call_data : userop. call_data . clone ( ) ,
41- init_code : userop. init_code . clone ( ) ,
42- nonce : userop. nonce ,
43- pre_verification_gas : userop. pre_verification_gas ,
44- max_fee_per_gas : userop. max_fee_per_gas ,
45- verification_gas_limit : userop. verification_gas_limit ,
46- sender : userop. sender ,
47- paymaster_and_data : userop. paymaster_and_data . clone ( ) ,
48- signature : userop. signature . clone ( ) ,
49- call_gas_limit : userop. call_gas_limit ,
50- max_priority_fee_per_gas : userop. max_priority_fee_per_gas ,
51- entrypoint,
52- } )
53- }
54- UserOpVersion :: V0_7 ( userop) => {
55- StructuredMessageInput :: UserOperationV07Input ( UserOperationV07Input {
56- call_data : userop. call_data . clone ( ) ,
57- nonce : userop. nonce ,
58- pre_verification_gas : userop. pre_verification_gas ,
59- max_fee_per_gas : userop. max_fee_per_gas ,
60- verification_gas_limit : userop. verification_gas_limit ,
61- sender : userop. sender ,
62- paymaster_data : userop. paymaster_data . clone ( ) . unwrap_or_default ( ) ,
63- factory : userop. factory . unwrap_or_default ( ) ,
64- factory_data : userop. factory_data . clone ( ) . unwrap_or_default ( ) ,
65- paymaster_post_op_gas_limit : userop
66- . paymaster_post_op_gas_limit
67- . unwrap_or_default ( ) ,
68- paymaster_verification_gas_limit : userop
69- . paymaster_verification_gas_limit
70- . unwrap_or_default ( ) ,
71- signature : userop. signature . clone ( ) ,
72- call_gas_limit : userop. call_gas_limit ,
73- max_priority_fee_per_gas : userop. max_priority_fee_per_gas ,
74- paymaster : userop. paymaster . unwrap_or_default ( ) ,
75- entrypoint,
76- } )
77- }
29+ fn userop_to_vault_input ( userop : & UserOpVersion , entrypoint : Address ) -> StructuredMessageInput {
30+ match userop {
31+ UserOpVersion :: V0_6 ( userop) => {
32+ StructuredMessageInput :: UserOperationV06Input ( UserOperationV06Input {
33+ call_data : userop. call_data . clone ( ) ,
34+ init_code : userop. init_code . clone ( ) ,
35+ nonce : userop. nonce ,
36+ pre_verification_gas : userop. pre_verification_gas ,
37+ max_fee_per_gas : userop. max_fee_per_gas ,
38+ verification_gas_limit : userop. verification_gas_limit ,
39+ sender : userop. sender ,
40+ paymaster_and_data : userop. paymaster_and_data . clone ( ) ,
41+ signature : userop. signature . clone ( ) ,
42+ call_gas_limit : userop. call_gas_limit ,
43+ max_priority_fee_per_gas : userop. max_priority_fee_per_gas ,
44+ entrypoint,
45+ } )
46+ }
47+ UserOpVersion :: V0_7 ( userop) => {
48+ StructuredMessageInput :: UserOperationV07Input ( UserOperationV07Input {
49+ call_data : userop. call_data . clone ( ) ,
50+ nonce : userop. nonce ,
51+ pre_verification_gas : userop. pre_verification_gas ,
52+ max_fee_per_gas : userop. max_fee_per_gas ,
53+ verification_gas_limit : userop. verification_gas_limit ,
54+ sender : userop. sender ,
55+ paymaster_data : userop. paymaster_data . clone ( ) . unwrap_or_default ( ) ,
56+ factory : userop. factory . unwrap_or_default ( ) ,
57+ factory_data : userop. factory_data . clone ( ) . unwrap_or_default ( ) ,
58+ paymaster_post_op_gas_limit : userop
59+ . paymaster_post_op_gas_limit
60+ . unwrap_or_default ( ) ,
61+ paymaster_verification_gas_limit : userop
62+ . paymaster_verification_gas_limit
63+ . unwrap_or_default ( ) ,
64+ signature : userop. signature . clone ( ) ,
65+ call_gas_limit : userop. call_gas_limit ,
66+ max_priority_fee_per_gas : userop. max_priority_fee_per_gas ,
67+ paymaster : userop. paymaster . unwrap_or_default ( ) ,
68+ entrypoint,
69+ } )
7870 }
7971 }
8072}
@@ -88,7 +80,7 @@ impl UserOpSigner {
8880 . sign_structured_message (
8981 auth_method. clone ( ) ,
9082 params. signer_address ,
91- params. userop . to_vault_input ( params. entrypoint ) ,
83+ userop_to_vault_input ( & params. userop , params. entrypoint ) ,
9284 Some ( params. chain_id ) ,
9385 )
9486 . await
@@ -103,11 +95,23 @@ impl UserOpSigner {
10395 }
10496 } ) ?)
10597 }
106- SigningCredential :: Iaw { auth_token : _, thirdweb_auth : _ } => {
107- // IAW doesn't support UserOp signing yet
108- Err ( EngineError :: ValidationError {
109- message : "IAW service does not support UserOperation signing" . to_string ( ) ,
110- } )
98+ SigningCredential :: Iaw { auth_token, thirdweb_auth } => {
99+ let result = self . iaw_client . sign_userop (
100+ auth_token. clone ( ) ,
101+ thirdweb_auth. clone ( ) ,
102+ params. userop ,
103+ params. entrypoint ,
104+ params. signer_address ,
105+ params. chain_id ,
106+ ) . await . map_err ( |e| EngineError :: ValidationError {
107+ message : format ! ( "Failed to sign userop: {}" , e) ,
108+ } ) ?;
109+
110+ Ok ( Bytes :: from_hex ( & result. signature ) . map_err ( |_| {
111+ EngineError :: ValidationError {
112+ message : "Bad signature received from IAW" . to_string ( ) ,
113+ }
114+ } ) ?)
111115 }
112116 }
113117 }
0 commit comments