Skip to main content

miden_standards/note/
burn.rs

1use miden_protocol::account::AccountId;
2use miden_protocol::assembly::Path;
3use miden_protocol::asset::Asset;
4use miden_protocol::crypto::rand::FeltRng;
5use miden_protocol::errors::NoteError;
6use miden_protocol::note::{
7    Note,
8    NoteAssets,
9    NoteAttachments,
10    NoteRecipient,
11    NoteScript,
12    NoteScriptRoot,
13    NoteStorage,
14    NoteTag,
15    NoteType,
16    PartialNoteMetadata,
17};
18use miden_protocol::utils::sync::LazyLock;
19
20use crate::StandardsLib;
21
22// NOTE SCRIPT
23// ================================================================================================
24
25/// Path to the BURN note script procedure in the standards library.
26const BURN_SCRIPT_PATH: &str = "::miden::standards::notes::burn::main";
27
28// Initialize the BURN note script only once
29static BURN_SCRIPT: LazyLock<NoteScript> = LazyLock::new(|| {
30    let standards_lib = StandardsLib::default();
31    let path = Path::new(BURN_SCRIPT_PATH);
32    NoteScript::from_library_reference(standards_lib.as_ref(), path)
33        .expect("Standards library contains BURN note script procedure")
34});
35
36// BURN NOTE
37// ================================================================================================
38
39/// TODO: add docs
40pub struct BurnNote;
41
42impl BurnNote {
43    // CONSTANTS
44    // --------------------------------------------------------------------------------------------
45
46    /// Expected number of storage items of the BURN note.
47    pub const NUM_STORAGE_ITEMS: usize = 0;
48
49    // PUBLIC ACCESSORS
50    // --------------------------------------------------------------------------------------------
51
52    /// Returns the script of the BURN note.
53    pub fn script() -> NoteScript {
54        BURN_SCRIPT.clone()
55    }
56
57    /// Returns the BURN note script root.
58    pub fn script_root() -> NoteScriptRoot {
59        BURN_SCRIPT.root()
60    }
61
62    // BUILDERS
63    // --------------------------------------------------------------------------------------------
64
65    /// Generates a BURN note - a note that instructs a faucet to burn a fungible asset.
66    ///
67    /// This script enables the creation of a PUBLIC note that, when consumed by a fungible
68    /// faucet, will burn the fungible assets contained in the note. The compiled call targets
69    /// `fungible::receive_and_burn`.
70    ///
71    /// BURN notes are always PUBLIC for network execution.
72    ///
73    /// The passed-in `rng` is used to generate a serial number for the note. The note's tag
74    /// is automatically set to the faucet's account ID for proper routing.
75    ///
76    /// # Parameters
77    /// - `sender`: The account ID of the note creator
78    /// - `faucet_id`: The account ID of the faucet that will burn the assets
79    /// - `fungible_asset`: The fungible asset to be burned
80    /// - `attachment`: The [`NoteAttachments`] of the BURN note
81    /// - `rng`: Random number generator for creating the serial number
82    ///
83    /// # Errors
84    /// Returns an error if note creation fails.
85    pub fn create<R: FeltRng>(
86        sender: AccountId,
87        faucet_id: AccountId,
88        fungible_asset: Asset,
89        attachments: NoteAttachments,
90        rng: &mut R,
91    ) -> Result<Note, NoteError> {
92        let note_script = Self::script();
93        let serial_num = rng.draw_word();
94
95        // BURN notes are always public
96        let note_type = NoteType::Public;
97
98        let inputs = NoteStorage::new(vec![])?;
99        let tag = NoteTag::with_account_target(faucet_id);
100
101        let metadata = PartialNoteMetadata::new(sender, note_type).with_tag(tag);
102        let assets = NoteAssets::new(vec![fungible_asset])?; // BURN notes contain the asset to burn
103        let recipient = NoteRecipient::new(serial_num, note_script, inputs);
104
105        Ok(Note::with_attachments(assets, metadata, recipient, attachments))
106    }
107}