gmsol_sdk/client/ops/
competition.rs

1use std::ops::Deref;
2
3use gmsol_programs::gmsol_competition::{
4    client::{accounts, args},
5    ID,
6};
7use gmsol_solana_utils::transaction_builder::TransactionBuilder;
8use solana_sdk::{pubkey::Pubkey, signer::Signer, system_program};
9
10/// Operations for competition.
11pub trait CompetitionOps<C> {
12    /// Initialzie a competition.
13    fn initialize_competition(&self, params: &CompetitionParams) -> TransactionBuilder<C, Pubkey>;
14
15    /// Create participant account idempotently.
16    fn create_participant_idempotent(
17        &self,
18        competition: &Pubkey,
19        trader: Option<&Pubkey>,
20    ) -> TransactionBuilder<C, Pubkey>;
21
22    /// Close a participant account.
23    fn close_participant(&self, competition: &Pubkey) -> TransactionBuilder<C>;
24}
25
26impl<C: Deref<Target = impl Signer> + Clone> CompetitionOps<C> for crate::Client<C> {
27    fn initialize_competition(&self, params: &CompetitionParams) -> TransactionBuilder<C, Pubkey> {
28        let payer = self.payer();
29        let competition = crate::pda::find_competition_address(&payer, params.start_time, &ID).0;
30        self.program(ID)
31            .transaction()
32            .output(competition)
33            .anchor_args(args::InitializeCompetition::from(params.clone()))
34            .anchor_accounts(accounts::InitializeCompetition {
35                payer,
36                competition,
37                system_program: system_program::ID,
38            })
39    }
40
41    fn create_participant_idempotent(
42        &self,
43        competition: &Pubkey,
44        trader: Option<&Pubkey>,
45    ) -> TransactionBuilder<C, Pubkey> {
46        let payer = self.payer();
47        let trader = trader.copied().unwrap_or(payer);
48        let participant = crate::pda::find_participant_address(competition, &trader, &ID).0;
49        self.program(ID)
50            .transaction()
51            .output(participant)
52            .anchor_args(args::CreateParticipantIdempotent {})
53            .anchor_accounts(accounts::CreateParticipantIdempotent {
54                payer,
55                competition: *competition,
56                participant,
57                trader,
58                system_program: system_program::ID,
59            })
60    }
61
62    fn close_participant(&self, competition: &Pubkey) -> TransactionBuilder<C> {
63        let trader = self.payer();
64        let participant = crate::pda::find_participant_address(competition, &trader, &ID).0;
65        self.program(ID)
66            .transaction()
67            .anchor_args(args::CloseParticipant {})
68            .anchor_accounts(accounts::CloseParticipant {
69                trader,
70                competition: *competition,
71                participant,
72            })
73    }
74}
75
76/// Competition Params.
77#[derive(Debug, Clone, typed_builder::TypedBuilder)]
78pub struct CompetitionParams {
79    start_time: i64,
80    end_time: i64,
81    volume_threshold: u128,
82    extension_duration: i64,
83    extension_cap: i64,
84    only_count_increase: bool,
85    volume_merge_window: i64,
86}
87
88impl From<CompetitionParams> for args::InitializeCompetition {
89    fn from(params: CompetitionParams) -> Self {
90        let CompetitionParams {
91            start_time,
92            end_time,
93            volume_threshold,
94            extension_duration,
95            extension_cap,
96            only_count_increase,
97            volume_merge_window,
98        } = params;
99        Self {
100            start_time,
101            end_time,
102            volume_threshold,
103            extension_duration,
104            extension_cap,
105            only_count_increase,
106            volume_merge_window,
107        }
108    }
109}