smart_account_auth/
impls.rs1#[cfg(feature = "replay")]
2use super::traits::ReplayProtection;
3use core::ops::Deref;
4
5use saa_common::{CredentialError, Identifiable, ensure};
6use crate::{credential::CredentialName, Credential, CredentialData, caller::Caller};
7use crate::traits::CredentialsWrapper;
8
9
10impl From<Caller> for Credential {
11 fn from(c: Caller) -> Self {
12 Credential::Native(c)
13 }
14}
15
16
17impl From<&str> for Credential {
18 fn from(s: &str) -> Self {
19 Caller::from(s).into()
20 }
21}
22
23
24#[cfg(feature = "eth_personal")]
25impl From<saa_auth::ethereum::EthPersonalSign> for Credential {
26 fn from(c: saa_auth::ethereum::EthPersonalSign) -> Self {
27 Credential::EthPersonalSign(c)
28 }
29}
30
31#[cfg(feature = "eth_typed_data")]
32impl From<saa_auth::ethereum::EthTypedData> for Credential {
33 fn from(c: saa_auth::ethereum::EthTypedData) -> Self {
34 Credential::EthTypedData(c)
35 }
36}
37
38
39#[cfg(any(feature = "cosmos_arb", feature = "cosmos_arb_addr"))]
40impl From<saa_auth::cosmos::CosmosArbitrary> for Credential {
41 fn from(c: saa_auth::cosmos::CosmosArbitrary) -> Self {
42 Credential::CosmosArbitrary(c)
43 }
44}
45
46
47#[cfg(feature = "ed25519")]
48impl From<saa_curves::ed25519::Ed25519> for Credential {
49 fn from(c: saa_curves::ed25519::Ed25519) -> Self {
50 Credential::Ed25519(c)
51 }
52}
53
54
55#[cfg(feature = "secp256k1")]
56impl From<saa_curves::secp256k1::Secp256k1> for Credential {
57 fn from(c: saa_curves::secp256k1::Secp256k1) -> Self {
58 Credential::Secp256k1(c)
59 }
60}
61
62#[cfg(feature = "secp256r1")]
63impl From<saa_passkeys::Secp256r1> for Credential {
64 fn from(c: saa_passkeys::Secp256r1) -> Self {
65 Credential::Secp256r1(c)
66 }
67}
68
69
70#[cfg(feature = "passkeys")]
71impl From<saa_passkeys::PasskeyCredential> for Credential {
72 fn from(c: saa_passkeys::PasskeyCredential) -> Self {
73 Credential::Passkey(c)
74 }
75}
76
77
78
79impl Identifiable for Credential {
80 fn cred_id(&self) -> String {
81 self.deref().cred_id()
82 }
83 fn name(&self) -> CredentialName {
84 self.deref().name()
85 }
86}
87
88
89impl Deref for Credential {
90 #[cfg(not(feature = "replay"))]
91 type Target = dyn saa_common::Verifiable;
92 #[cfg(feature = "replay")]
93 type Target = dyn ReplayProtection;
94
95
96 fn deref(&self) -> &Self::Target {
97 match self {
98 Credential::Native(c) => c,
99 #[cfg(feature = "eth_personal")]
100 Credential::EthPersonalSign(c) => c,
101 #[cfg(feature = "eth_typed_data")]
102 Credential::EthTypedData(c) => c,
103 #[cfg(any(feature = "cosmos_arb", feature = "cosmos_arb_addr"))]
104 Credential::CosmosArbitrary(c) => c,
105 #[cfg(feature = "passkeys")]
106 Credential::Passkey(c) => c,
107 #[cfg(feature = "secp256r1")]
108 Credential::Secp256r1(c) => c,
109 #[cfg(feature = "secp256k1")]
110 Credential::Secp256k1(c) => c,
111 #[cfg(feature = "ed25519")]
112 Credential::Ed25519(c) => c,
113 }
114 }
115}
116
117
118
119
120
121
122impl CredentialData {
123 pub(crate) fn validate_logic(
125 &self, sender: &str,
126 records: Option<&Vec<crate::credential::CredentialRecord>>
127 ) -> Result<(), CredentialError> {
128 let iter: Box<dyn Iterator<Item = (String, CredentialName)> + '_> = match records {
130 Some(
131 records
132 ) => Box::new(records.iter().map(|(id, info)| (id.clone(), info.name.clone()))),
133 None => Box::new(self.credentials.iter().map(|c| (c.cred_id(), c.name()))),
134 };
135 let (count, native_count, sender_found) = iter.fold(
137 (0, 0, false),
138 |(count, native_count, sender_found), (id, name)| (
139 count + 1,
140 if name == CredentialName::Native { native_count + 1 } else { native_count },
141 sender_found || id == sender
142 )
143 );
144 ensure!(count > 0, CredentialError::NoCredentials);
145 ensure!(count <= 255, CredentialError::TooManyCredentials(count));
146
147 if let Some(index) = self.primary_index {
148 ensure!(index < count, CredentialError::IndexOutOfBounds(index, count));
149 }
150 if self.use_native.unwrap_or_default() {
151 ensure!(native_count > 0 && sender_found, CredentialError::NoNativeCaller);
152 }
153 if native_count == count {
155 ensure!(sender_found, CredentialError::OnlyCustomNatives);
156 }
157 Ok(())
158 }
159}
160
161
162
163impl CredentialData {
164
165 #[cfg(feature = "utils")]
166 pub fn new(
167 credentials: Vec<Credential>,
168 use_native: Option<bool>,
169 ) -> Self {
170 Self {
171 credentials,
172 use_native,
173 primary_index: None,
174 pre_validate: None,
175 override_primary: None,
176 }
177 }
178
179 pub fn with_native<C: Into::<Caller>> (&self, cal: C) -> Self {
184 if !self.use_native.unwrap_or(false) {
185 return self.clone()
186 }
187 let caller : Caller = cal.into();
188 let mut credentials = self.credentials.clone();
189 match self.cred_index( &caller.0, CredentialName::Native) {
190 Some(index) => credentials[index] = caller.into(),
191 None => credentials.push(caller.into())
192 };
193 Self {
194 credentials,
195 ..self.clone()
196 }
197 }
198
199
200}
201