cw_auth_types/sessions/
actions.rs

1
2use saa_schema::saa_type;
3use saa_schema::strum::{IntoDiscriminant};
4use saa_schema::strum_macros::{AsRefStr, Display, EnumIter, EnumString};
5
6use smart_account_auth::cosmwasm_std::Env;
7use smart_account_auth::{Session, SessionInfo};
8use smart_account_auth::{msgs::DerivableMsg};
9use smart_account_auth::msgs::{SignedDataMsg, Action, AllowedActions, ActionDerivation};
10use crate::{errors::SessionError};
11
12
13
14#[saa_type]
15pub enum ActionMsg<M> {
16    Native(M),
17    Signed(SignedDataMsg)
18}
19
20
21
22#[saa_type]
23pub struct CreateSession {
24    pub allowed_actions     :      AllowedActions,
25    pub session_info        :      SessionInfo,
26}
27
28
29#[saa_type]
30pub struct CreateSessionFromMsg<M : DerivableMsg> {
31    pub message             :      M,
32    pub derivation          :      Option<ActionDerivation>,
33    pub session_info        :      SessionInfo,
34}
35
36
37
38
39#[saa_type]
40pub struct WithSessionMsg<M> {
41    pub message             :      ActionMsg<M>,
42    pub session_key         :      String,
43}
44
45
46#[saa_type]
47pub struct RevokeKeyMsg {
48    pub session_key         :      String,
49}
50
51
52
53
54#[saa_type]
55pub enum SessionActionMsg<M : DerivableMsg> {
56    CreateSession(CreateSession),
57    CreateSessionFromMsg(CreateSessionFromMsg<M>),
58    WithSessionKey(WithSessionMsg<M>),
59    RevokeSession(RevokeKeyMsg),
60}
61
62
63
64
65#[derive(AsRefStr, EnumString, EnumIter, PartialEq, Display)]
66#[strum(serialize_all = "snake_case")]
67pub enum SessionActionName {
68    SessionActions,
69    CreateSession,
70    CreateSessionFromMsg,
71    WithSessionKey,
72    RevokeSession,
73}
74
75
76
77
78pub trait SessionActionsMatch : DerivableMsg  {
79    fn match_actions(&self) -> Option<SessionActionMsg<Self>>;
80}
81
82
83
84
85
86
87
88impl<M : DerivableMsg> IntoDiscriminant for SessionActionMsg<M> {
89    type Discriminant = SessionActionName;
90    fn discriminant(&self) -> Self::Discriminant {
91        match self {
92            SessionActionMsg::CreateSession(_) => SessionActionName::CreateSession,
93            SessionActionMsg::CreateSessionFromMsg(_) => SessionActionName::CreateSessionFromMsg,
94            SessionActionMsg::WithSessionKey(_) => SessionActionName::WithSessionKey,
95            SessionActionMsg::RevokeSession(_) => SessionActionName::RevokeSession,
96        }
97    }
98    
99}
100
101
102
103impl core::fmt::Display for CreateSession {
104    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
105        write!(f, "create_session")
106    }
107}
108
109impl AsRef<str> for CreateSession {
110    fn as_ref(&self) -> &str {
111        "create_session"
112    }
113}   
114
115
116impl<M : DerivableMsg> core::fmt::Display for CreateSessionFromMsg<M> {
117    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
118        write!(f, "create_session_from_msg")
119    }
120    
121}
122impl<M : DerivableMsg> AsRef<str> for CreateSessionFromMsg<M> {
123    fn as_ref(&self) -> &str {
124        "create_session_from_msg"
125    }
126}
127
128
129impl IntoDiscriminant for CreateSession {
130    type Discriminant = SessionActionName;
131    fn discriminant(&self) -> Self::Discriminant {
132        SessionActionName::CreateSession
133    }
134}
135impl<M : DerivableMsg> IntoDiscriminant for CreateSessionFromMsg<M> {
136    type Discriminant = SessionActionName;
137    fn discriminant(&self) -> Self::Discriminant {
138        SessionActionName::CreateSessionFromMsg
139    }
140}
141
142
143
144
145
146
147impl CreateSession {
148    pub fn to_session(
149        &self, 
150        env: &Env
151    ) -> Result<Session, SessionError> {
152        
153        let (
154            granter,
155            grantee, 
156            expiration, 
157            actions
158        ) = self.session_info.checked_params(env, Some(&self.allowed_actions))?;
159
160        Ok(Session {
161            actions,
162            expiration,
163            grantee,
164            granter,
165            nonce: 0,
166        })
167    }
168}
169
170
171
172impl<M: DerivableMsg> CreateSessionFromMsg<M> {
173
174    pub fn to_session(
175        &self, 
176        env: &Env
177    ) -> Result<Session, SessionError> {
178        let (
179            granter, 
180            grantee, 
181            expiration, 
182            _
183        ) = self.session_info.checked_params(env, None)?;
184        
185        let method = self.derivation.clone().unwrap_or_default();
186        let action = Action::new(&self.message, method)
187            .map_err(|_| SessionError::InvalidActions)?;
188
189        Ok(Session {
190            actions: AllowedActions::Include(vec![action]),
191            expiration,
192            grantee,
193            granter,
194            nonce: 0,
195        })
196    }
197}
198