Skip to main content

primitivo_macro/
lib.rs

1pub mod ownership;
2pub mod pausable;
3
4pub use ownership::*;
5pub use pausable::*;
6
7#[macro_export]
8macro_rules! generate_ownership_transfer_accounts {
9    (
10        state_ty = $state_ty:ident,
11        state_account = $state_account:ident,
12        propose_ctx = $propose_ctx:ident,
13        accept_ctx = $accept_ctx:ident,
14        cancel_ctx = $cancel_ctx:ident
15    ) => {
16        #[derive(Accounts)]
17        pub struct $propose_ctx<'info> {
18            #[account(mut)]
19            pub owner: Signer<'info>,
20
21            #[account(
22                mut,
23                constraint = $state_account.ownership.owner == owner.key() @ primitivo_macro::OwnershipError::NotOwner,
24            )]
25            pub $state_account: Account<'info, $state_ty>,
26        }
27
28        #[derive(Accounts)]
29        pub struct $accept_ctx<'info> {
30            #[account(mut)]
31            pub pending_owner: Signer<'info>,
32
33            #[account(
34                mut,
35                constraint = $state_account.ownership.pending_owner == pending_owner.key() @ primitivo_macro::OwnershipError::InvalidPendingOwner,
36            )]
37            pub $state_account: Account<'info, $state_ty>,
38        }
39
40        #[derive(Accounts)]
41        pub struct $cancel_ctx<'info> {
42            #[account(mut)]
43            pub owner: Signer<'info>,
44
45            #[account(
46                mut,
47                constraint = $state_account.ownership.owner == owner.key() @ primitivo_macro::OwnershipError::NotOwner,
48            )]
49            pub $state_account: Account<'info, $state_ty>,
50        }
51    };
52}
53
54#[macro_export]
55macro_rules! generate_ownership_transfer_handlers {
56    (
57        propose_fn = $propose_fn:ident,
58        accept_fn = $accept_fn:ident,
59        cancel_fn = $cancel_fn:ident,
60        propose_ctx = $propose_ctx:ident,
61        accept_ctx = $accept_ctx:ident,
62        cancel_ctx = $cancel_ctx:ident,
63        state_account = $state_account:ident
64    ) => {
65        pub fn $propose_fn(
66            ctx: Context<$propose_ctx>,
67            new_owner: Pubkey,
68            accept_window_secs: i64,
69        ) -> Result<()> {
70            let now_ts = Clock::get()?.unix_timestamp;
71            ctx.accounts.$state_account.ownership.propose_transfer(
72                ctx.accounts.owner.key(),
73                new_owner,
74                now_ts,
75                accept_window_secs,
76            )?;
77            Ok(())
78        }
79
80        pub fn $accept_fn(
81            ctx: Context<$accept_ctx>,
82        ) -> Result<()> {
83            let now_ts = Clock::get()?.unix_timestamp;
84            ctx.accounts.$state_account.ownership.accept_transfer(
85                ctx.accounts.pending_owner.key(),
86                now_ts,
87            )?;
88            Ok(())
89        }
90
91        pub fn $cancel_fn(
92            ctx: Context<$cancel_ctx>,
93        ) -> Result<()> {
94            ctx.accounts
95                .$state_account
96                .ownership
97                .cancel_transfer(ctx.accounts.owner.key())?;
98            Ok(())
99        }
100    };
101}
102
103#[macro_export]
104macro_rules! generate_pausable_accounts {
105    (
106        state_ty = $state_ty:ident,
107        state_account = $state_account:ident,
108        pause_ctx = $pause_ctx:ident,
109        unpause_ctx = $unpause_ctx:ident
110    ) => {
111        #[derive(Accounts)]
112        pub struct $pause_ctx<'info> {
113            #[account(mut)]
114            pub owner: Signer<'info>,
115
116            #[account(
117                mut,
118                constraint = $state_account.ownership.owner == owner.key() @ primitivo_macro::PausableError::NotOwner,
119            )]
120            pub $state_account: Account<'info, $state_ty>,
121        }
122
123        #[derive(Accounts)]
124        pub struct $unpause_ctx<'info> {
125            #[account(mut)]
126            pub owner: Signer<'info>,
127
128            #[account(
129                mut,
130                constraint = $state_account.ownership.owner == owner.key() @ primitivo_macro::PausableError::NotOwner,
131            )]
132            pub $state_account: Account<'info, $state_ty>,
133        }
134    };
135}
136
137#[macro_export]
138macro_rules! generate_pausable_handlers {
139    (
140        pause_fn = $pause_fn:ident,
141        unpause_fn = $unpause_fn:ident,
142        pause_ctx = $pause_ctx:ident,
143        unpause_ctx = $unpause_ctx:ident,
144        state_account = $state_account:ident
145    ) => {
146        pub fn $pause_fn(
147            ctx: Context<$pause_ctx>,
148        ) -> Result<()> {
149            let owner = ctx.accounts.owner.key();
150            let owner_of_state = ctx.accounts.$state_account.ownership.owner;
151            let state = &mut ctx.accounts.$state_account;
152            state.pausable.pause(owner_of_state, owner)?;
153            Ok(())
154        }
155
156        pub fn $unpause_fn(
157            ctx: Context<$unpause_ctx>,
158        ) -> Result<()> {
159            let owner = ctx.accounts.owner.key();
160            let owner_of_state = ctx.accounts.$state_account.ownership.owner;
161            let state = &mut ctx.accounts.$state_account;
162            state.pausable.unpause(owner_of_state, owner)?;
163            Ok(())
164        }
165    };
166}
167
168#[macro_export]
169macro_rules! require_not_paused {
170    ($ctx:expr, $state_account:ident) => {
171        $ctx.accounts.$state_account.pausable.require_not_paused()?;
172    };
173}