Skip to main content

defuse_core/intents/
account.rs

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