gmsol_sdk/builders/
position.rs1use gmsol_programs::gmsol_store::client::{accounts, args};
2use gmsol_solana_utils::{AtomicGroup, IntoAtomicGroup, ProgramExt};
3use typed_builder::TypedBuilder;
4
5use crate::serde::StringPubkey;
6
7use super::StoreProgram;
8
9#[cfg_attr(js, derive(tsify_next::Tsify))]
11#[cfg_attr(js, tsify(from_wasm_abi))]
12#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
13#[derive(Debug, Clone, TypedBuilder)]
14pub struct CloseEmptyPosition {
15 #[cfg_attr(serde, serde(default))]
17 #[builder(default)]
18 pub program: StoreProgram,
19 #[builder(setter(into))]
21 pub payer: StringPubkey,
22 #[builder(setter(into))]
24 pub position: StringPubkey,
25}
26
27impl IntoAtomicGroup for CloseEmptyPosition {
28 type Hint = ();
29
30 fn into_atomic_group(
31 self,
32 _hint: &Self::Hint,
33 ) -> gmsol_solana_utils::Result<gmsol_solana_utils::AtomicGroup> {
34 let owner = self.payer.0;
35
36 let ix = self
37 .program
38 .anchor_instruction(args::CloseEmptyPosition {})
39 .anchor_accounts(
40 accounts::CloseEmptyPosition {
41 owner,
42 store: self.program.store.0,
43 position: self.position.0,
44 },
45 false,
46 )
47 .build();
48
49 Ok(AtomicGroup::with_instructions(&owner, [ix]))
50 }
51}
52
53#[cfg(test)]
54mod tests {
55 use gmsol_solana_utils::transaction_builder::default_before_sign;
56 use solana_sdk::pubkey::Pubkey;
57
58 use super::*;
59
60 #[test]
61 fn close_empty_position() -> crate::Result<()> {
62 CloseEmptyPosition::builder()
63 .payer(Pubkey::new_unique())
64 .position(Pubkey::new_unique())
65 .build()
66 .into_atomic_group(&())?
67 .partially_signed_transaction_with_blockhash_and_options(
68 Default::default(),
69 Default::default(),
70 None,
71 default_before_sign,
72 )?;
73
74 Ok(())
75 }
76}