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