cougr_core/accounts/
signer.rs1use soroban_sdk::{Address, Env};
2
3use super::error::AccountError;
4use super::intent::{IntentProofKind, IntentSigner, SignedIntent};
5use super::secp256r1_auth::{verify_secp256r1, Secp256r1Storage};
6
7pub trait AccountSigner {
9 fn verify(
10 &self,
11 env: &Env,
12 account: &Address,
13 intent: &SignedIntent,
14 ) -> Result<(), AccountError>;
15}
16
17pub struct DirectAuthSigner;
19
20impl AccountSigner for DirectAuthSigner {
21 fn verify(
22 &self,
23 _env: &Env,
24 account: &Address,
25 intent: &SignedIntent,
26 ) -> Result<(), AccountError> {
27 if intent.signer.kind != IntentSigner::Direct {
28 return Err(AccountError::SignerMismatch);
29 }
30 account.require_auth();
31 Ok(())
32 }
33}
34
35pub struct SessionAuthSigner;
37
38impl AccountSigner for SessionAuthSigner {
39 fn verify(
40 &self,
41 _env: &Env,
42 _account: &Address,
43 intent: &SignedIntent,
44 ) -> Result<(), AccountError> {
45 if intent.signer.kind != IntentSigner::Session {
46 return Err(AccountError::SignerMismatch);
47 }
48 Ok(())
49 }
50}
51
52pub struct Secp256r1PasskeySigner;
54
55impl AccountSigner for Secp256r1PasskeySigner {
56 fn verify(
57 &self,
58 env: &Env,
59 account: &Address,
60 intent: &SignedIntent,
61 ) -> Result<(), AccountError> {
62 if intent.signer.kind != IntentSigner::Passkey {
63 return Err(AccountError::SignerMismatch);
64 }
65 if intent.proof.kind != IntentProofKind::Secp256r1 {
66 return Err(AccountError::InvalidSignature);
67 }
68 let key = Secp256r1Storage::find_by_label(env, account, &intent.signer.label)
69 .ok_or(AccountError::SignerNotRegistered)?;
70 let message = intent.action_hash.to_bytes();
71 verify_secp256r1(env, &key.public_key, &message, &intent.proof.signature)
72 }
73}