use core::fmt;
use miden_protocol::account::AccountId;
use miden_protocol::asset::AssetAmount;
use miden_protocol::crypto::rand::FeltRng;
use miden_protocol::errors::NoteError;
use miden_protocol::note::{Note, NoteScript, NoteScriptRoot};
use miden_standards::note::config::MinBurnAmountConfigNote;
use crate::account::xreserve::MIN_BURN_SIZE_FLOOR;
#[derive(Debug)]
#[non_exhaustive]
pub enum XReserveMinBurnAmountNoteError {
MinBurnAmountTooSmall { min_burn_amount: u64 },
Note(NoteError),
}
impl fmt::Display for XReserveMinBurnAmountNoteError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::MinBurnAmountTooSmall { min_burn_amount } => write!(
f,
"refusing to build a note that sets the burn floor to {min_burn_amount}, below \
the floor {MIN_BURN_SIZE_FLOOR}; a zero floor would admit zero-amount burn notes"
),
Self::Note(_) => {
write!(f, "the standard min-burn-amount config note could not be built")
},
}
}
}
impl core::error::Error for XReserveMinBurnAmountNoteError {
fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
match self {
Self::Note(source) => Some(source),
Self::MinBurnAmountTooSmall { .. } => None,
}
}
}
impl From<NoteError> for XReserveMinBurnAmountNoteError {
fn from(source: NoteError) -> Self {
Self::Note(source)
}
}
pub struct XReserveMinBurnAmountNote;
#[bon::bon]
impl XReserveMinBurnAmountNote {
pub fn script() -> NoteScript {
MinBurnAmountConfigNote::script()
}
pub fn script_root() -> NoteScriptRoot {
MinBurnAmountConfigNote::script_root()
}
#[builder]
pub fn new<R: FeltRng>(
sender: AccountId,
target: AccountId,
min_burn_amount: AssetAmount,
generate_serial_number: &mut R,
) -> Result<Note, XReserveMinBurnAmountNoteError> {
if min_burn_amount.as_u64() < MIN_BURN_SIZE_FLOOR {
return Err(XReserveMinBurnAmountNoteError::MinBurnAmountTooSmall {
min_burn_amount: min_burn_amount.as_u64(),
});
}
let note = MinBurnAmountConfigNote::builder()
.sender(sender)
.target(target)
.min_burn_amount(min_burn_amount)
.generate_serial_number(generate_serial_number)
.build()
.map_err(XReserveMinBurnAmountNoteError::Note)?;
Ok(Note::from(note))
}
}