use std::sync::Arc;
use fedimint_api_client::api::{DynGlobalApi, DynModuleApi};
use fedimint_client_module::module::OutPointRange;
use fedimint_client_module::sm::{ClientSMDatabaseTransaction, DynState, IState};
use fedimint_client_module::transaction::{TransactionBuilder, TxSubmissionStatesSM};
use fedimint_client_module::{
AddStateMachinesResult, IGlobalClientContext, InstancelessDynClientInputBundle,
InstancelessDynClientOutputBundle,
};
use fedimint_core::config::ClientConfig;
use fedimint_core::core::{IntoDynInstance, ModuleInstanceId, ModuleKind, OperationId};
use fedimint_core::module::registry::ModuleDecoderRegistry;
use fedimint_core::util::BoxStream;
use fedimint_core::{apply, async_trait_maybe_send, maybe_add_send_sync};
use fedimint_eventlog::{EventKind, EventPersistence};
use super::Client;
#[derive(Clone, Debug)]
pub(crate) struct ModuleGlobalClientContext {
pub(crate) client: Arc<Client>,
pub(crate) module_instance_id: ModuleInstanceId,
pub(crate) operation: OperationId,
}
#[apply(async_trait_maybe_send!)]
impl IGlobalClientContext for ModuleGlobalClientContext {
fn module_api(&self) -> DynModuleApi {
self.api().with_module(self.module_instance_id)
}
fn api(&self) -> &DynGlobalApi {
&self.client.api
}
fn decoders(&self) -> &ModuleDecoderRegistry {
self.client.decoders()
}
async fn client_config(&self) -> ClientConfig {
self.client.config().await
}
async fn claim_inputs_dyn(
&self,
dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
inputs: InstancelessDynClientInputBundle,
) -> anyhow::Result<OutPointRange> {
let tx_builder =
TransactionBuilder::new().with_inputs(inputs.into_dyn(self.module_instance_id));
self.client
.finalize_and_submit_transaction_inner(
&mut dbtx.global_tx().to_ref_nc(),
self.operation,
tx_builder,
)
.await
}
async fn fund_output_dyn(
&self,
dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
outputs: InstancelessDynClientOutputBundle,
) -> anyhow::Result<OutPointRange> {
let tx_builder =
TransactionBuilder::new().with_outputs(outputs.into_dyn(self.module_instance_id));
self.client
.finalize_and_submit_transaction_inner(
&mut dbtx.global_tx().to_ref_nc(),
self.operation,
tx_builder,
)
.await
}
async fn add_state_machine_dyn(
&self,
dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
sm: Box<maybe_add_send_sync!(dyn IState)>,
) -> AddStateMachinesResult {
let state = DynState::from_parts(self.module_instance_id, sm);
self.client
.executor
.add_state_machines_dbtx(&mut dbtx.global_tx().to_ref_nc(), vec![state])
.await
}
async fn transaction_update_stream(&self) -> BoxStream<TxSubmissionStatesSM> {
self.client.transaction_update_stream(self.operation).await
}
async fn log_event_json(
&self,
dbtx: &mut ClientSMDatabaseTransaction<'_, '_>,
kind: EventKind,
module: Option<(ModuleKind, ModuleInstanceId)>,
payload: serde_json::Value,
persist: EventPersistence,
) {
self.client
.log_event_raw_dbtx(
dbtx.global_tx(),
kind,
module,
serde_json::to_vec(&payload).expect("Serialization can't fail"),
persist,
)
.await;
}
async fn core_api_version(&self) -> fedimint_core::module::ApiVersion {
self.client.core_api_version().await
}
}