Skip to main content

cougr_core/accounts/
signer.rs

1use soroban_sdk::{Address, Env};
2
3use super::error::AccountError;
4use super::intent::{IntentProofKind, IntentSigner, SignedIntent};
5use super::secp256r1_auth::{verify_secp256r1, Secp256r1Storage};
6
7/// Base signer verification interface for the account kernel.
8pub trait AccountSigner {
9    fn verify(
10        &self,
11        env: &Env,
12        account: &Address,
13        intent: &SignedIntent,
14    ) -> Result<(), AccountError>;
15}
16
17/// Direct owner signer backed by Soroban `require_auth`.
18pub 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
35/// Session signer used for explicit session intents.
36pub 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
52/// Passkey signer backed by stored secp256r1 keys.
53pub 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}