gmsol_sdk/builders/
store_program.rs1use anchor_lang::InstructionData;
2use gmsol_programs::anchor_lang::ToAccountMetas;
3use gmsol_solana_utils::{Program, ProgramExt};
4use solana_sdk::{instruction::Instruction, pubkey::Pubkey};
5use typed_builder::TypedBuilder;
6
7use crate::{pda, serde::StringPubkey};
8
9use super::callback::{Callback, CallbackParams};
10
11pub type NonceBytes = StringPubkey;
13
14#[cfg_attr(js, derive(tsify_next::Tsify))]
16#[cfg_attr(js, tsify(from_wasm_abi, into_wasm_abi))]
17#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
18#[derive(Debug, Clone, TypedBuilder)]
19pub struct StoreProgram {
20 #[builder(setter(into))]
22 pub id: StringPubkey,
23 #[builder(setter(into))]
25 pub store: StringPubkey,
26}
27
28impl anchor_lang::Id for StoreProgram {
29 fn id() -> Pubkey {
30 gmsol_programs::gmsol_store::ID
31 }
32}
33
34impl Default for StoreProgram {
35 fn default() -> Self {
36 use gmsol_programs::gmsol_store::ID;
37 Self {
38 id: ID.into(),
39 store: pda::find_store_address("", &ID).0.into(),
40 }
41 }
42}
43
44impl Program for StoreProgram {
45 fn id(&self) -> &Pubkey {
46 &self.id
47 }
48}
49
50impl StoreProgram {
51 #[deprecated(
53 since = "0.8.0",
54 note = "Use `ProgramExt::anchor_instruction` instead."
55 )]
56 #[allow(deprecated)]
57 pub fn instruction(&self, args: impl InstructionData) -> InstructionBuilder {
58 InstructionBuilder(self.anchor_instruction(args))
59 }
60
61 pub(crate) fn get_callback_params(&self, callback: Option<&Callback>) -> CallbackParams {
62 match callback {
63 Some(callback) => CallbackParams {
64 callback_version: Some(callback.version),
65 callback_authority: Some(self.find_callback_authority_address()),
66 callback_program: Some(callback.program.0),
67 callback_shared_data_account: Some(callback.shared_data.0),
68 callback_partitioned_data_account: Some(callback.partitioned_data.0),
69 },
70 None => CallbackParams::default(),
71 }
72 }
73
74 pub fn find_event_authority_address(&self) -> Pubkey {
76 pda::find_event_authority_address(&self.id).0
77 }
78
79 pub fn find_store_wallet_address(&self) -> Pubkey {
81 pda::find_store_wallet_address(&self.store, &self.id).0
82 }
83
84 pub fn find_order_address(&self, owner: &Pubkey, nonce: &NonceBytes) -> Pubkey {
86 pda::find_order_address(&self.store, owner, &nonce.0.to_bytes(), &self.id).0
87 }
88
89 pub fn find_deposit_address(&self, owner: &Pubkey, nonce: &NonceBytes) -> Pubkey {
91 pda::find_deposit_address(&self.store, owner, &nonce.0.to_bytes(), &self.id).0
92 }
93
94 pub fn find_withdrawal_address(&self, owner: &Pubkey, nonce: &NonceBytes) -> Pubkey {
96 pda::find_withdrawal_address(&self.store, owner, &nonce.0.to_bytes(), &self.id).0
97 }
98
99 pub fn find_shift_address(&self, owner: &Pubkey, nonce: &NonceBytes) -> Pubkey {
101 pda::find_shift_address(&self.store, owner, &nonce.0.to_bytes(), &self.id).0
102 }
103
104 pub fn find_glv_deposit_address(&self, owner: &Pubkey, nonce: &NonceBytes) -> Pubkey {
106 pda::find_glv_deposit_address(&self.store, owner, &nonce.0.to_bytes(), &self.id).0
107 }
108
109 pub fn find_glv_withdrawal_address(&self, owner: &Pubkey, nonce: &NonceBytes) -> Pubkey {
111 pda::find_glv_withdrawal_address(&self.store, owner, &nonce.0.to_bytes(), &self.id).0
112 }
113
114 pub fn find_market_address(&self, market_token: &Pubkey) -> Pubkey {
116 pda::find_market_address(&self.store, market_token, &self.id).0
117 }
118
119 pub fn find_user_address(&self, owner: &Pubkey) -> Pubkey {
121 pda::find_user_address(&self.store, owner, &self.id).0
122 }
123
124 pub fn find_position_address(
126 &self,
127 owner: &Pubkey,
128 market_token: &Pubkey,
129 collateral_token: &Pubkey,
130 is_long: bool,
131 ) -> Pubkey {
132 pda::find_position_address(
133 &self.store,
134 owner,
135 market_token,
136 collateral_token,
137 is_long,
138 &self.id,
139 )
140 .0
141 }
142
143 pub fn find_callback_authority_address(&self) -> Pubkey {
145 crate::pda::find_callback_authority(&self.id).0
146 }
147
148 pub fn find_glv_address(&self, glv_token: &Pubkey) -> Pubkey {
150 crate::pda::find_glv_address(glv_token, &self.id).0
151 }
152}
153
154pub trait StoreProgramIxBuilder {
156 fn store_program(&self) -> &StoreProgram;
158}
159
160#[deprecated(
162 since = "0.8.0",
163 note = "Use `gmsol_sdk::solana_utils::InstructionBuilder` instead."
164)]
165pub struct InstructionBuilder<'a>(gmsol_solana_utils::InstructionBuilder<'a, StoreProgram>);
166
167#[allow(deprecated)]
168impl InstructionBuilder<'_> {
169 pub fn accounts(self, accounts: impl ToAccountMetas, convert_optional: bool) -> Self {
171 Self(self.0.anchor_accounts(accounts, convert_optional))
172 }
173
174 pub fn build(self) -> Instruction {
176 self.0.build()
177 }
178}
179
180#[cfg(test)]
181mod tests {
182 use super::*;
183
184 #[test]
185 fn default_store_program() {
186 let program = StoreProgram::default();
187 assert_eq!(
188 program.store.to_string(),
189 "CTDLvGGXnoxvqLyTpGzdGLg9pD6JexKxKXSV8tqqo8bN"
190 );
191 }
192
193 #[cfg(serde)]
194 #[test]
195 fn serde() {
196 let program = StoreProgram::default();
197 assert_eq!(
198 serde_json::to_string(&program).unwrap(),
199 r#"{"id":"Gmso1uvJnLbawvw7yezdfCDcPydwW2s2iqG3w6MDucLo","store":"CTDLvGGXnoxvqLyTpGzdGLg9pD6JexKxKXSV8tqqo8bN"}"#
200 );
201 }
202}