Skip to main content

miden_standards/note/
mint_inputs.rs

1use alloc::vec::Vec;
2
3use miden_protocol::errors::NoteError;
4use miden_protocol::note::{NoteAttachment, NoteInputs, NoteRecipient};
5use miden_protocol::{Felt, MAX_INPUTS_PER_NOTE, Word};
6
7/// Represents the different input formats for MINT notes.
8/// - Private: Creates a private output note using a precomputed recipient digest (12 MINT note
9///   inputs)
10/// - Public: Creates a public output note by providing script root, serial number, and
11///   variable-length inputs (16+ MINT note inputs: 16 fixed + variable number of output note
12///   inputs)
13#[derive(Debug, Clone, PartialEq, Eq)]
14pub enum MintNoteInputs {
15    Private {
16        recipient_digest: Word,
17        amount: Felt,
18        tag: Felt,
19        attachment: NoteAttachment,
20    },
21    Public {
22        recipient: NoteRecipient,
23        amount: Felt,
24        tag: Felt,
25        attachment: NoteAttachment,
26    },
27}
28
29impl MintNoteInputs {
30    pub fn new_private(recipient_digest: Word, amount: Felt, tag: Felt) -> Self {
31        Self::Private {
32            recipient_digest,
33            amount,
34            tag,
35            attachment: NoteAttachment::default(),
36        }
37    }
38
39    pub fn new_public(
40        recipient: NoteRecipient,
41        amount: Felt,
42        tag: Felt,
43    ) -> Result<Self, NoteError> {
44        // Calculate total number of inputs that will be created:
45        // 16 fixed inputs (tag, amount, attachment_kind, attachment_scheme, ATTACHMENT,
46        // SCRIPT_ROOT, SERIAL_NUM) + variable recipient inputs length
47        const FIXED_PUBLIC_INPUTS: usize = 16;
48        let total_inputs = FIXED_PUBLIC_INPUTS + recipient.inputs().num_values() as usize;
49
50        if total_inputs > MAX_INPUTS_PER_NOTE {
51            return Err(NoteError::TooManyInputs(total_inputs));
52        }
53
54        Ok(Self::Public {
55            recipient,
56            amount,
57            tag,
58            attachment: NoteAttachment::default(),
59        })
60    }
61
62    /// Overwrites the [`NoteAttachment`] of the note inputs.
63    pub fn with_attachment(self, attachment: NoteAttachment) -> Self {
64        match self {
65            MintNoteInputs::Private {
66                recipient_digest,
67                amount,
68                tag,
69                attachment: _,
70            } => MintNoteInputs::Private {
71                recipient_digest,
72                amount,
73                tag,
74                attachment,
75            },
76            MintNoteInputs::Public { recipient, amount, tag, attachment: _ } => {
77                MintNoteInputs::Public { recipient, amount, tag, attachment }
78            },
79        }
80    }
81}
82
83impl From<MintNoteInputs> for NoteInputs {
84    fn from(mint_inputs: MintNoteInputs) -> Self {
85        match mint_inputs {
86            MintNoteInputs::Private {
87                recipient_digest,
88                amount,
89                tag,
90                attachment,
91            } => {
92                let attachment_scheme = Felt::from(attachment.attachment_scheme().as_u32());
93                let attachment_kind = Felt::from(attachment.attachment_kind().as_u8());
94                let attachment = attachment.content().to_word();
95
96                let mut input_values = Vec::with_capacity(12);
97                input_values.extend_from_slice(&[tag, amount, attachment_kind, attachment_scheme]);
98                input_values.extend_from_slice(attachment.as_elements());
99                input_values.extend_from_slice(recipient_digest.as_elements());
100                NoteInputs::new(input_values)
101                    .expect("number of inputs should not exceed max inputs")
102            },
103            MintNoteInputs::Public { recipient, amount, tag, attachment } => {
104                let attachment_scheme = Felt::from(attachment.attachment_scheme().as_u32());
105                let attachment_kind = Felt::from(attachment.attachment_kind().as_u8());
106                let attachment = attachment.content().to_word();
107
108                let mut input_values = vec![tag, amount, attachment_kind, attachment_scheme];
109                input_values.extend_from_slice(attachment.as_elements());
110                input_values.extend_from_slice(recipient.script().root().as_elements());
111                input_values.extend_from_slice(recipient.serial_num().as_elements());
112                input_values.extend_from_slice(recipient.inputs().values());
113                NoteInputs::new(input_values)
114                    .expect("number of inputs should not exceed max inputs")
115            },
116        }
117    }
118}