fedimint_client/client/
global_ctx.rs

1use std::sync::Arc;
2
3use fedimint_api_client::api::{DynGlobalApi, DynModuleApi};
4use fedimint_client_module::module::OutPointRange;
5use fedimint_client_module::sm::{ClientSMDatabaseTransaction, DynState, IState};
6use fedimint_client_module::transaction::{TransactionBuilder, TxSubmissionStatesSM};
7use fedimint_client_module::{
8    AddStateMachinesResult, IGlobalClientContext, InstancelessDynClientInputBundle,
9    InstancelessDynClientOutputBundle,
10};
11use fedimint_core::config::ClientConfig;
12use fedimint_core::core::{IntoDynInstance, ModuleInstanceId, ModuleKind, OperationId};
13use fedimint_core::module::registry::ModuleDecoderRegistry;
14use fedimint_core::util::BoxStream;
15use fedimint_core::{apply, async_trait_maybe_send, maybe_add_send_sync};
16use fedimint_eventlog::EventKind;
17
18use super::Client;
19
20/// Global state given to a specific client module and state. It is aware inside
21/// which module instance and operation it is used and to avoid module being
22/// aware of their instance id etc.
23#[derive(Clone, Debug)]
24pub(crate) struct ModuleGlobalClientContext {
25    pub(crate) client: Arc<Client>,
26    pub(crate) module_instance_id: ModuleInstanceId,
27    pub(crate) operation: OperationId,
28}
29
30#[apply(async_trait_maybe_send!)]
31impl IGlobalClientContext for ModuleGlobalClientContext {
32    fn module_api(&self) -> DynModuleApi {
33        self.api().with_module(self.module_instance_id)
34    }
35
36    fn api(&self) -> &DynGlobalApi {
37        &self.client.api
38    }
39
40    fn decoders(&self) -> &ModuleDecoderRegistry {
41        self.client.decoders()
42    }
43
44    async fn client_config(&self) -> ClientConfig {
45        self.client.config().await
46    }
47
48    async fn claim_inputs_dyn(
49        &self,
50        dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
51        inputs: InstancelessDynClientInputBundle,
52    ) -> anyhow::Result<OutPointRange> {
53        let tx_builder =
54            TransactionBuilder::new().with_inputs(inputs.into_dyn(self.module_instance_id));
55
56        self.client
57            .finalize_and_submit_transaction_inner(
58                &mut dbtx.global_tx().to_ref_nc(),
59                self.operation,
60                tx_builder,
61            )
62            .await
63    }
64
65    async fn fund_output_dyn(
66        &self,
67        dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
68        outputs: InstancelessDynClientOutputBundle,
69    ) -> anyhow::Result<OutPointRange> {
70        let tx_builder =
71            TransactionBuilder::new().with_outputs(outputs.into_dyn(self.module_instance_id));
72
73        self.client
74            .finalize_and_submit_transaction_inner(
75                &mut dbtx.global_tx().to_ref_nc(),
76                self.operation,
77                tx_builder,
78            )
79            .await
80    }
81
82    async fn add_state_machine_dyn(
83        &self,
84        dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
85        sm: Box<maybe_add_send_sync!(dyn IState)>,
86    ) -> AddStateMachinesResult {
87        let state = DynState::from_parts(self.module_instance_id, sm);
88
89        self.client
90            .executor
91            .add_state_machines_dbtx(&mut dbtx.global_tx().to_ref_nc(), vec![state])
92            .await
93    }
94
95    async fn transaction_update_stream(&self) -> BoxStream<TxSubmissionStatesSM> {
96        self.client.transaction_update_stream(self.operation).await
97    }
98
99    async fn log_event_json(
100        &self,
101        dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
102        kind: EventKind,
103        module: Option<(ModuleKind, ModuleInstanceId)>,
104        payload: serde_json::Value,
105        persist: bool,
106    ) {
107        self.client
108            .log_event_raw_dbtx(
109                dbtx.global_tx(),
110                kind,
111                module,
112                serde_json::to_vec(&payload).expect("Serialization can't fail"),
113                persist,
114            )
115            .await;
116    }
117}