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}