gmsol_sdk/js/instructions/
create_shift.rs1use std::collections::HashSet;
2
3use gmsol_solana_utils::{AtomicGroup, IntoAtomicGroup, ParallelGroup};
4use serde::{Deserialize, Serialize};
5use tsify_next::Tsify;
6use wasm_bindgen::prelude::*;
7
8use crate::{
9 builders::{shift::CreateShift, token::PrepareTokenAccounts, user::PrepareUser, StoreProgram},
10 js::instructions::BuildTransactionOptions,
11 serde::StringPubkey,
12};
13
14use super::{TransactionGroup, TransactionGroupOptions};
15
16#[derive(Debug, Serialize, Deserialize, Tsify, Clone)]
17#[tsify(into_wasm_abi, from_wasm_abi)]
18pub struct CreateShiftParamsJs {
19 pub from_market_token: StringPubkey,
20 pub to_market_token: StringPubkey,
21 #[serde(default)]
22 pub receiver: Option<StringPubkey>,
23 #[serde(default)]
24 pub from_market_token_amount: Option<u128>,
25 #[serde(default)]
26 pub min_to_market_token_amount: Option<u128>,
27 #[serde(default)]
28 pub skip_to_market_token_ata_creation: Option<bool>,
29}
30
31#[derive(Debug, Serialize, Deserialize, Tsify)]
32#[tsify(into_wasm_abi, from_wasm_abi)]
33pub struct CreateShiftOptions {
34 pub recent_blockhash: String,
35 pub payer: StringPubkey,
36 #[serde(default)]
37 pub program: Option<StoreProgram>,
38 #[serde(default)]
39 pub compute_unit_price_micro_lamports: Option<u64>,
40 #[serde(default)]
41 pub compute_unit_min_priority_lamports: Option<u64>,
42 #[serde(default)]
43 pub transaction_group: TransactionGroupOptions,
44}
45
46#[wasm_bindgen]
47pub struct CreateShiftsBuilder {
48 payer: StringPubkey,
49 tokens: HashSet<StringPubkey>,
50 groups: Vec<AtomicGroup>,
51 transaction_group: TransactionGroupOptions,
52 build: BuildTransactionOptions,
53}
54
55#[wasm_bindgen]
56pub fn create_shifts_builder(
57 shifts: Vec<CreateShiftParamsJs>,
58 options: CreateShiftOptions,
59) -> crate::Result<CreateShiftsBuilder> {
60 let mut tokens = HashSet::default();
61 let mut groups: Vec<AtomicGroup> = Vec::with_capacity(shifts.len());
62
63 for params in shifts.into_iter() {
64 tokens.insert(params.to_market_token);
65
66 let program = options.program.clone().unwrap_or_default();
67 let builder = CreateShift::builder()
68 .program(program)
69 .payer(options.payer)
70 .from_market_token(params.from_market_token)
71 .to_market_token(params.to_market_token)
72 .from_market_token_amount(
73 params
74 .from_market_token_amount
75 .unwrap_or_default()
76 .try_into()?,
77 )
78 .min_to_market_token_amount(
79 params
80 .min_to_market_token_amount
81 .unwrap_or_default()
82 .try_into()?,
83 )
84 .skip_to_market_token_ata_creation(
85 params.skip_to_market_token_ata_creation.unwrap_or_default(),
86 );
87
88 let built = if let Some(r) = params.receiver {
89 builder.receiver(r).build()
90 } else {
91 builder.build()
92 };
93
94 let ag = built.into_atomic_group(&())?;
95 groups.push(ag);
96 }
97
98 Ok(CreateShiftsBuilder {
99 payer: options.payer,
100 tokens,
101 groups,
102 transaction_group: options.transaction_group,
103 build: BuildTransactionOptions {
104 recent_blockhash: options.recent_blockhash,
105 compute_unit_price_micro_lamports: options.compute_unit_price_micro_lamports,
106 compute_unit_min_priority_lamports: options.compute_unit_min_priority_lamports,
107 },
108 })
109}
110
111#[wasm_bindgen]
112impl CreateShiftsBuilder {
113 pub fn build_with_options(
114 self,
115 transaction_group: Option<TransactionGroupOptions>,
116 build: Option<BuildTransactionOptions>,
117 ) -> crate::Result<TransactionGroup> {
118 let mut group = transaction_group.unwrap_or(self.transaction_group).build();
119
120 let prepare_user = PrepareUser::builder()
121 .payer(self.payer)
122 .build()
123 .into_atomic_group(&())?;
124
125 let prepare_tokens = PrepareTokenAccounts::builder()
126 .owner(self.payer)
127 .payer(self.payer)
128 .tokens(self.tokens)
129 .build()
130 .into_atomic_group(&())?;
131
132 let build = build.unwrap_or(self.build);
133 TransactionGroup::new(
134 group
135 .add(prepare_user)?
136 .add(prepare_tokens)?
137 .add(self.groups.into_iter().collect::<ParallelGroup>())?
138 .optimize(false),
139 &build.recent_blockhash,
140 build.compute_unit_price_micro_lamports,
141 build.compute_unit_min_priority_lamports,
142 )
143 }
144}
145
146#[wasm_bindgen]
147pub fn create_shifts(
148 shifts: Vec<CreateShiftParamsJs>,
149 options: CreateShiftOptions,
150) -> crate::Result<TransactionGroup> {
151 create_shifts_builder(shifts, options)?.build_with_options(None, None)
152}