use alloc::{
format,
string::{String, ToString},
vec::Vec,
};
use mls_rs::client_builder::MlsConfig;
use mls_rs::time::MlsTime;
use mls_rs::Client;
use mls_rs_core::mls_rs_codec::MlsEncode;
use offline_protocol_core::WIRE_VERSION_V1;
use offline_protocol_sealed::{
KeyPackagePayload, CTRL_SIGN_V2, LEAF_KEY_PACKAGE_LIFETIME,
LEAF_KEY_PACKAGE_NOT_BEFORE_BACKDATE_SECONDS, MLS_ENVELOPE_COMPACT_V1,
};
use crate::error::{LeafError, Result};
pub(crate) struct Minted {
pub(crate) data: Vec<u8>,
pub(crate) reference: String,
}
pub(crate) fn mint(client: &Client<impl MlsConfig>, now_unix_secs: u64) -> Result<Minted> {
let not_before = now_unix_secs.saturating_sub(LEAF_KEY_PACKAGE_NOT_BEFORE_BACKDATE_SECONDS);
let message = client
.generate_key_package_message(
Default::default(),
Default::default(),
Some(MlsTime::from(not_before)),
)
.map_err(|e| LeafError::Mls(format!("cannot generate a key package: {e:?}")))?;
let reference = message
.key_package_reference(&crate::identity::suite_provider()?)
.map_err(|e| LeafError::Mls(format!("cannot reference the key package: {e:?}")))?
.ok_or_else(|| LeafError::Mls(String::from("generated message is not a key package")))?;
let data = message
.into_key_package()
.ok_or_else(|| LeafError::Mls(String::from("generated message is not a key package")))?
.mls_encode_to_vec()
.map_err(|e| LeafError::Mls(format!("cannot encode the key package: {e:?}")))?;
Ok(Minted {
data,
reference: crate::adapters::hex(&reference),
})
}
pub(crate) fn payload(
user_id: &str,
key_package_data: Vec<u8>,
session_reset: bool,
) -> KeyPackagePayload {
KeyPackagePayload {
user_id: user_id.to_string(),
key_package_data,
remaining_lifetime_ms: LEAF_KEY_PACKAGE_LIFETIME
.as_millis()
.try_into()
.unwrap_or(u64::MAX),
timestamp_ms: 0,
session_reset,
wire_versions: alloc::vec![WIRE_VERSION_V1],
env_versions: alloc::vec![MLS_ENVELOPE_COMPACT_V1],
rich_versions: Vec::new(),
data_versions: Vec::new(),
ctrl_versions: alloc::vec![CTRL_SIGN_V2],
svc_versions: Vec::new(),
ack_versions: Vec::new(),
nostr_pubkey: None,
}
}