defuse_core/intents/
account.rs

1use std::borrow::Cow;
2
3use defuse_crypto::PublicKey;
4use near_sdk::{AccountIdRef, CryptoHash, near};
5
6use crate::{
7    Result,
8    accounts::{AccountEvent, PublicKeyEvent},
9    engine::{Engine, Inspector, State},
10    events::DefuseEvent,
11    intents::MaybeIntentEvent,
12};
13
14use super::ExecutableIntent;
15
16#[near(serializers = [borsh, json])]
17#[derive(Debug, Clone)]
18/// Given an account id, the user can add public keys. The added public keys can sign
19/// intents on behalf of these accounts, even to add new ones.
20/// Warning: Implicit account ids, by default, have their corresponding public keys added.
21/// Meaning: For a leaked private key, whose implicit account id had been used in intents,
22/// the user must manually rotate the underlying public key within intents, too.
23pub struct AddPublicKey {
24    pub public_key: PublicKey,
25}
26
27impl ExecutableIntent for AddPublicKey {
28    #[inline]
29    fn execute_intent<S, I>(
30        self,
31        signer_id: &AccountIdRef,
32        engine: &mut Engine<S, I>,
33        intent_hash: CryptoHash,
34    ) -> Result<()>
35    where
36        S: State,
37        I: Inspector,
38    {
39        engine
40            .state
41            .add_public_key(signer_id.to_owned(), self.public_key)?;
42
43        engine
44            .inspector
45            .on_event(DefuseEvent::PublicKeyAdded(MaybeIntentEvent::new_intent(
46                AccountEvent::new(
47                    Cow::Borrowed(signer_id),
48                    PublicKeyEvent {
49                        public_key: Cow::Borrowed(&self.public_key),
50                    },
51                ),
52                intent_hash,
53            )));
54        Ok(())
55    }
56}
57
58#[near(serializers = [borsh, json])]
59#[derive(Debug, Clone)]
60/// Remove the public key associated with a given account. See `AddPublicKey`.
61pub struct RemovePublicKey {
62    pub public_key: PublicKey,
63}
64
65impl ExecutableIntent for RemovePublicKey {
66    #[inline]
67    fn execute_intent<S, I>(
68        self,
69        signer_id: &AccountIdRef,
70        engine: &mut Engine<S, I>,
71        intent_hash: CryptoHash,
72    ) -> crate::Result<()>
73    where
74        S: State,
75        I: Inspector,
76    {
77        engine
78            .state
79            .remove_public_key(signer_id.to_owned(), self.public_key)?;
80        engine
81            .inspector
82            .on_event(DefuseEvent::PublicKeyRemoved(MaybeIntentEvent::new_intent(
83                AccountEvent::new(
84                    Cow::Borrowed(signer_id),
85                    PublicKeyEvent {
86                        public_key: Cow::Borrowed(&self.public_key),
87                    },
88                ),
89                intent_hash,
90            )));
91        Ok(())
92    }
93}
94
95#[near(serializers = [borsh, json])]
96#[derive(Debug, Clone)]
97pub struct SetAuthByPredecessorId {
98    pub enabled: bool,
99}
100
101impl ExecutableIntent for SetAuthByPredecessorId {
102    fn execute_intent<S, I>(
103        self,
104        signer_id: &AccountIdRef,
105        engine: &mut Engine<S, I>,
106        intent_hash: CryptoHash,
107    ) -> Result<()>
108    where
109        S: State,
110        I: Inspector,
111    {
112        let toggled = engine
113            .state
114            .set_auth_by_predecessor_id(signer_id.to_owned(), self.enabled)?;
115
116        if toggled {
117            engine
118                .inspector
119                .on_event(DefuseEvent::SetAuthByPredecessorId(
120                    MaybeIntentEvent::new_intent(
121                        AccountEvent::new(Cow::Borrowed(signer_id), Cow::Borrowed(&self)),
122                        intent_hash,
123                    ),
124                ));
125        }
126
127        Ok(())
128    }
129}