Skip to main content

gmsol_sdk/js/instructions/
mod.rs

1use std::{collections::HashMap, sync::Arc};
2
3use crate::{
4    serde::StringPubkey,
5    solana_utils::transaction_group::TransactionGroupOptions as SdkTransactionGroupOptions,
6};
7use gmsol_solana_utils::{
8    instruction_group::ComputeBudgetOptions, signer::TransactionSigners,
9    transaction_builder::default_before_sign,
10};
11use serde::{Deserialize, Serialize};
12use solana_sdk::{signature::NullSigner, transaction::VersionedTransaction};
13use tsify_next::Tsify;
14use wasm_bindgen::prelude::wasm_bindgen;
15
16/// Create order.
17pub mod create_order;
18
19/// Close order.
20pub mod close_order;
21
22/// Update order.
23pub mod update_order;
24
25/// Create deposit.
26pub mod create_deposit;
27
28/// Create withdrawal.
29pub mod create_withdrawal;
30
31/// Create shift.
32pub mod create_shift;
33
34/// Create GLV deposit.
35pub mod create_glv_deposit;
36
37/// Create GLV withdrawal.
38pub mod create_glv_withdrawal;
39
40/// A JS version transaction group options.
41#[derive(Debug, Serialize, Deserialize, Tsify, Default)]
42#[tsify(from_wasm_abi)]
43pub struct TransactionGroupOptions {
44    #[serde(default)]
45    max_transaction_size: Option<usize>,
46    #[serde(default)]
47    max_instructions_per_tx: Option<usize>,
48    #[serde(default)]
49    luts: HashMap<StringPubkey, Vec<StringPubkey>>,
50    #[serde(default)]
51    memo: Option<String>,
52}
53
54impl<'a> From<&'a TransactionGroupOptions> for SdkTransactionGroupOptions {
55    fn from(value: &'a TransactionGroupOptions) -> Self {
56        let mut options = SdkTransactionGroupOptions::default();
57        if let Some(size) = value.max_transaction_size {
58            options.max_transaction_size = size;
59        }
60        if let Some(num) = value.max_instructions_per_tx {
61            options.max_instructions_per_tx = num;
62        }
63        options.memo = value.memo.clone();
64        options
65    }
66}
67
68impl TransactionGroupOptions {
69    pub(crate) fn build(&self) -> gmsol_solana_utils::TransactionGroup {
70        gmsol_solana_utils::TransactionGroup::with_options_and_luts(
71            self.into(),
72            self.luts
73                .iter()
74                .map(|(pubkey, addresses)| {
75                    (**pubkey, addresses.iter().map(|pubkey| **pubkey).collect())
76                })
77                .collect(),
78        )
79    }
80}
81
82/// A JS binding for compiled transaction group.
83#[wasm_bindgen]
84pub struct TransactionGroup(Vec<Vec<VersionedTransaction>>);
85
86/// Serialized transaction group.
87#[derive(Serialize, Deserialize, Tsify)]
88#[tsify(into_wasm_abi)]
89pub struct SerializedTransactionGroup(Vec<Vec<Vec<u8>>>);
90
91#[wasm_bindgen]
92impl TransactionGroup {
93    /// Returns serialized transaciton group.
94    pub fn serialize(&self) -> crate::Result<SerializedTransactionGroup> {
95        let serialized = self
96            .0
97            .iter()
98            .map(|batch| {
99                batch
100                    .iter()
101                    .map(|txn| Ok(bincode::serialize(txn)?))
102                    .collect::<crate::Result<Vec<_>>>()
103            })
104            .collect::<crate::Result<Vec<_>>>()?;
105        Ok(SerializedTransactionGroup(serialized))
106    }
107}
108
109/// Build transaction options.
110#[derive(Debug, Serialize, Deserialize, Tsify)]
111#[tsify(into_wasm_abi, from_wasm_abi)]
112pub struct BuildTransactionOptions {
113    recent_blockhash: String,
114    #[serde(default)]
115    compute_unit_price_micro_lamports: Option<u64>,
116    #[serde(default)]
117    compute_unit_min_priority_lamports: Option<u64>,
118}
119
120impl TransactionGroup {
121    fn new(
122        group: &gmsol_solana_utils::TransactionGroup,
123        recent_blockhash: &str,
124        compute_unit_price_micro_lamports: Option<u64>,
125        compute_unit_min_priority_lamports: Option<u64>,
126    ) -> crate::Result<Self> {
127        let signers = empty_signers();
128        let transactions = group
129            .to_transactions_with_options(
130                &signers,
131                recent_blockhash.parse().map_err(crate::Error::custom)?,
132                true,
133                ComputeBudgetOptions {
134                    without_compute_budget: false,
135                    compute_unit_price_micro_lamports,
136                    compute_unit_min_priority_lamports,
137                },
138                default_before_sign,
139            )
140            .map(|res| res.map_err(crate::Error::from))
141            .collect::<crate::Result<Vec<_>>>()?;
142        Ok(Self(transactions))
143    }
144}
145
146fn empty_signers() -> TransactionSigners<Arc<NullSigner>> {
147    Default::default()
148}