@@ -96,7 +96,7 @@ pub mod module {
96
96
/// Filters the inner calls for passkey which is set in runtime
97
97
type PasskeyCallFilter : Contains < <Self as Config >:: RuntimeCall > ;
98
98
99
- /// Helper Curreny method for benchmarking
99
+ /// Helper Currency method for benchmarking
100
100
#[ cfg( feature = "runtime-benchmarks" ) ]
101
101
type Currency : Mutate < Self :: AccountId > ;
102
102
}
@@ -123,7 +123,9 @@ pub mod module {
123
123
124
124
#[ pallet:: call]
125
125
impl < T : Config > Pallet < T > {
126
- /// proxy call
126
+ /// Proxies an extrinsic call by changing the origin to `account_id` inside the payload.
127
+ /// Since this is an unsigned extrinsic all the verification checks are performed inside
128
+ /// `validate_unsigned` and `pre_dispatch` hooks.
127
129
#[ pallet:: call_index( 0 ) ]
128
130
#[ pallet:: weight( {
129
131
let dispatch_info = payload. passkey_call. call. get_dispatch_info( ) ;
@@ -159,59 +161,51 @@ pub mod module {
159
161
From < Call < T > > + Dispatchable < Info = DispatchInfo , PostInfo = PostDispatchInfo > ,
160
162
{
161
163
type Call = Call < T > ;
164
+
165
+ /// Validating the regular checks of an extrinsic plus verifying the P256 Passkey signature
166
+ /// The majority of these checks are the same as `SignedExtra` list in defined in runtime
162
167
fn validate_unsigned ( _source : TransactionSource , call : & Self :: Call ) -> TransactionValidity {
163
168
let valid_tx = ValidTransaction :: default ( ) ;
164
169
let payload = Self :: filter_valid_calls ( & call) ?;
165
170
166
- let frame_system_checks =
167
- FrameSystemChecks ( payload. passkey_call . account_id . clone ( ) , call. clone ( ) ) ;
168
- let frame_system_validity = frame_system_checks. validate ( ) ?;
169
-
170
- let signatures_check = PasskeySignatureCheck :: new ( payload. clone ( ) ) ;
171
- let signature_validity = signatures_check. validate ( ) ?;
172
-
173
- let nonce_check = PasskeyNonceCheck :: new ( payload. passkey_call . clone ( ) ) ;
174
- let nonce_validity = nonce_check. validate ( ) ?;
175
-
176
- let tx_charge = ChargeTransactionPayment :: < T > (
171
+ let frame_system_validity =
172
+ FrameSystemChecks ( payload. passkey_call . account_id . clone ( ) , call. clone ( ) )
173
+ . validate ( ) ?;
174
+ let nonce_validity = PasskeyNonceCheck :: new ( payload. passkey_call . clone ( ) ) . validate ( ) ?;
175
+ let weight_validity = PasskeyWeightCheck :: new ( call. clone ( ) ) . validate ( ) ?;
176
+ // this is the last (except for the fee validation check) since it is the heaviest
177
+ let signature_validity = PasskeySignatureCheck :: new ( payload. clone ( ) ) . validate ( ) ?;
178
+ // this should be last since we are not refunding in the case of failure since we didn't
179
+ // have `post_dispatch` implemented this should be the last check executed
180
+ let tx_payment_validity = ChargeTransactionPayment :: < T > (
177
181
payload. passkey_call . account_id . clone ( ) ,
178
182
call. clone ( ) ,
179
- ) ;
180
- let tx_payment_validity = tx_charge. validate ( ) ?;
181
-
182
- let weight_check = PasskeyWeightCheck :: new ( call. clone ( ) ) ;
183
- let weight_validity = weight_check. validate ( ) ?;
183
+ )
184
+ . validate ( ) ?;
184
185
185
186
let valid_tx = valid_tx
186
187
. combine_with ( frame_system_validity)
187
- . combine_with ( signature_validity)
188
188
. combine_with ( nonce_validity)
189
- . combine_with ( tx_payment_validity)
190
- . combine_with ( weight_validity) ;
189
+ . combine_with ( weight_validity)
190
+ . combine_with ( signature_validity)
191
+ . combine_with ( tx_payment_validity) ;
191
192
Ok ( valid_tx)
192
193
}
193
194
195
+ /// Checking and executing a list of operations pre_dispatch
196
+ /// The majority of these checks are the same as `SignedExtra` list in defined in runtime
194
197
fn pre_dispatch ( call : & Self :: Call ) -> Result < ( ) , TransactionValidityError > {
195
198
let payload = Self :: filter_valid_calls ( & call) ?;
196
-
197
- let frame_system_checks =
198
- FrameSystemChecks ( payload. passkey_call . account_id . clone ( ) , call. clone ( ) ) ;
199
- frame_system_checks. pre_dispatch ( ) ?;
200
-
201
- let signatures_check = PasskeySignatureCheck :: new ( payload. clone ( ) ) ;
202
- signatures_check. pre_dispatch ( ) ?;
203
-
204
- let nonce_check = PasskeyNonceCheck :: new ( payload. passkey_call . clone ( ) ) ;
205
- nonce_check. pre_dispatch ( ) ?;
206
-
207
- let tx_charge = ChargeTransactionPayment :: < T > (
208
- payload. passkey_call . account_id . clone ( ) ,
209
- call. clone ( ) ,
210
- ) ;
211
- tx_charge. pre_dispatch ( ) ?;
212
-
213
- let weight_check = PasskeyWeightCheck :: new ( call. clone ( ) ) ;
214
- weight_check. pre_dispatch ( )
199
+ FrameSystemChecks ( payload. passkey_call . account_id . clone ( ) , call. clone ( ) )
200
+ . pre_dispatch ( ) ?;
201
+ PasskeyNonceCheck :: new ( payload. passkey_call . clone ( ) ) . pre_dispatch ( ) ?;
202
+ PasskeyWeightCheck :: new ( call. clone ( ) ) . pre_dispatch ( ) ?;
203
+ // this is the last (except for the fee validation check) since it is the heaviest
204
+ PasskeySignatureCheck :: new ( payload. clone ( ) ) . pre_dispatch ( ) ?;
205
+ // this should be last since we are not refunding in the case of failure since we didn't
206
+ // have `post_dispatch` implemented this should be the last check executed
207
+ ChargeTransactionPayment :: < T > ( payload. passkey_call . account_id . clone ( ) , call. clone ( ) )
208
+ . pre_dispatch ( )
215
209
}
216
210
}
217
211
}
@@ -222,6 +216,7 @@ where
222
216
<T as frame_system:: Config >:: RuntimeCall :
223
217
From < Call < T > > + Dispatchable < Info = DispatchInfo , PostInfo = PostDispatchInfo > ,
224
218
{
219
+ /// Filtering the valid calls and extracting the payload from inside the call
225
220
fn filter_valid_calls ( call : & Call < T > ) -> Result < PasskeyPayload < T > , TransactionValidityError > {
226
221
match call {
227
222
Call :: proxy { payload }
@@ -232,7 +227,7 @@ where
232
227
}
233
228
}
234
229
235
- /// Passkey specific nonce check
230
+ /// Passkey specific nonce check which is a wrapper around `CheckNonce` extension
236
231
#[ derive( Encode , Decode , Clone , TypeInfo ) ]
237
232
#[ scale_info( skip_type_params( T ) ) ]
238
233
struct PasskeyNonceCheck < T : Config > ( pub PasskeyCall < T > ) ;
@@ -266,7 +261,9 @@ where
266
261
}
267
262
}
268
263
269
- /// Passkey signatures check
264
+ /// Passkey signatures check which verifies 2 signatures
265
+ /// 1. Account signature of the P256 public key
266
+ /// 2. Passkey P256 signature of the account public key
270
267
#[ derive( Encode , Decode , Clone , TypeInfo ) ]
271
268
#[ scale_info( skip_type_params( T ) ) ]
272
269
struct PasskeySignatureCheck < T : Config > ( pub PasskeyPayload < T > ) ;
@@ -277,6 +274,14 @@ impl<T: Config> PasskeySignatureCheck<T> {
277
274
}
278
275
279
276
pub fn validate ( & self ) -> TransactionValidity {
277
+ // checking account signature to verify ownership of the account used
278
+ let signed_data = self . 0 . passkey_public_key . clone ( ) ;
279
+ let signature = self . 0 . passkey_call . account_ownership_proof . clone ( ) ;
280
+ let signer = & self . 0 . passkey_call . account_id ;
281
+
282
+ Self :: check_account_signature ( signer, & signed_data. inner ( ) . to_vec ( ) , & signature)
283
+ . map_err ( |_e| TransactionValidityError :: Invalid ( InvalidTransaction :: BadSigner ) ) ?;
284
+
280
285
// checking the passkey signature to ensure access to the passkey
281
286
let p256_signed_data = self . 0 . passkey_call . encode ( ) ;
282
287
let p256_signature = self . 0 . verifiable_passkey_signature . clone ( ) ;
@@ -290,15 +295,7 @@ impl<T: Config> PasskeySignatureCheck<T> {
290
295
_ => TransactionValidityError :: Invalid ( InvalidTransaction :: Custom ( e. into ( ) ) ) ,
291
296
} ) ?;
292
297
293
- // checking account signature to verify ownership of the account used
294
- let signed_data = self . 0 . passkey_public_key . clone ( ) ;
295
- let signature = self . 0 . passkey_call . account_ownership_proof . clone ( ) ;
296
- let signer = & self . 0 . passkey_call . account_id ;
297
-
298
- match Self :: check_account_signature ( signer, & signed_data. inner ( ) . to_vec ( ) , & signature) {
299
- Ok ( _) => Ok ( ValidTransaction :: default ( ) ) ,
300
- Err ( _e) => InvalidTransaction :: BadSigner . into ( ) ,
301
- }
298
+ Ok ( ValidTransaction :: default ( ) )
302
299
}
303
300
304
301
pub fn pre_dispatch ( & self ) -> Result < ( ) , TransactionValidityError > {
0 commit comments