gmsol_sdk/client/ops/
store.rs

1use std::{ops::Deref, sync::Arc};
2
3use gmsol_programs::gmsol_store::client::{accounts, args};
4use gmsol_solana_utils::transaction_builder::TransactionBuilder;
5use solana_sdk::{pubkey::Pubkey, signer::Signer, system_program};
6
7/// Operations for store account.
8pub trait StoreOps<C> {
9    /// Initialize [`Store`](gmsol_programs::gmsol_store::accounts::Store) account.
10    fn initialize_store<S: Signer + 'static>(
11        &self,
12        key: &str,
13        authority: Option<S>,
14        receiver: Option<S>,
15        holding: Option<S>,
16    ) -> TransactionBuilder<C>;
17
18    /// Transfer store authority.
19    fn transfer_store_authority(
20        &self,
21        store: &Pubkey,
22        new_authority: &Pubkey,
23    ) -> TransactionBuilder<C>;
24
25    /// Accept store authority.
26    fn accept_store_authority(&self, store: &Pubkey) -> TransactionBuilder<C>;
27
28    /// Transfer receiver.
29    fn transfer_receiver(&self, store: &Pubkey, new_receiver: &Pubkey) -> TransactionBuilder<C>;
30
31    /// Set new token map.
32    fn set_token_map(&self, store: &Pubkey, token_map: &Pubkey) -> TransactionBuilder<C>;
33
34    /// Initialize callback authority.
35    fn initialize_callback_authority(&self) -> TransactionBuilder<C>;
36
37    /// Update last restarted slot.
38    fn update_last_restarted_slot(&self, store: &Pubkey) -> TransactionBuilder<C>;
39}
40
41impl<C: Deref<Target = impl Signer> + Clone> StoreOps<C> for crate::Client<C> {
42    fn initialize_store<S2: Signer + 'static>(
43        &self,
44        key: &str,
45        authority: Option<S2>,
46        receiver: Option<S2>,
47        holding: Option<S2>,
48    ) -> TransactionBuilder<C> {
49        let store = self.find_store_address(key);
50        let authority_address = authority.as_ref().map(|s| s.pubkey());
51        let receiver_address = receiver.as_ref().map(|s| s.pubkey());
52        let holding_address = holding.as_ref().map(|s| s.pubkey());
53        let mut rpc = self
54            .store_transaction()
55            .anchor_accounts(accounts::Initialize {
56                payer: self.payer(),
57                authority: authority_address,
58                receiver: receiver_address,
59                holding: holding_address,
60                store,
61                system_program: system_program::ID,
62            })
63            .anchor_args(args::Initialize {
64                key: key.to_string(),
65            });
66
67        for signer in authority.into_iter().chain(receiver).chain(holding) {
68            rpc = rpc.owned_signer(Arc::new(signer));
69        }
70
71        rpc
72    }
73
74    fn transfer_store_authority(
75        &self,
76        store: &Pubkey,
77        next_authority: &Pubkey,
78    ) -> TransactionBuilder<C> {
79        self.store_transaction()
80            .anchor_args(args::TransferStoreAuthority {})
81            .anchor_accounts(accounts::TransferStoreAuthority {
82                authority: self.payer(),
83                store: *store,
84                next_authority: *next_authority,
85            })
86    }
87
88    fn accept_store_authority(&self, store: &Pubkey) -> TransactionBuilder<C> {
89        self.store_transaction()
90            .anchor_args(args::AcceptStoreAuthority {})
91            .anchor_accounts(accounts::AcceptStoreAuthority {
92                next_authority: self.payer(),
93                store: *store,
94            })
95    }
96
97    fn transfer_receiver(&self, store: &Pubkey, new_receiver: &Pubkey) -> TransactionBuilder<C> {
98        self.store_transaction()
99            .anchor_args(args::TransferReceiver {})
100            .anchor_accounts(accounts::TransferReceiver {
101                authority: self.payer(),
102                store: *store,
103                next_receiver: *new_receiver,
104            })
105    }
106
107    fn set_token_map(&self, store: &Pubkey, token_map: &Pubkey) -> TransactionBuilder<C> {
108        self.store_transaction()
109            .anchor_args(args::SetTokenMap {})
110            .anchor_accounts(accounts::SetTokenMap {
111                authority: self.payer(),
112                store: *store,
113                token_map: *token_map,
114            })
115    }
116
117    fn initialize_callback_authority(&self) -> TransactionBuilder<C> {
118        self.store_transaction()
119            .anchor_args(args::InitializeCallbackAuthority {})
120            .anchor_accounts(accounts::InitializeCallbackAuthority {
121                payer: self.payer(),
122                callback_authority: self.find_callback_authority_address(),
123                system_program: system_program::ID,
124            })
125    }
126
127    fn update_last_restarted_slot(&self, store: &Pubkey) -> TransactionBuilder<C> {
128        let authority = self.payer();
129        self.store_transaction()
130            .anchor_args(args::UpdateLastRestartedSlot {})
131            .anchor_accounts(accounts::UpdateLastRestartedSlot {
132                authority,
133                store: *store,
134            })
135    }
136}