miden_lib/note/
well_known_note.rs1use miden_objects::{
2 Digest,
3 assembly::{ProcedureName, QualifiedProcedureName},
4 note::{Note, NoteScript},
5 utils::{Deserializable, sync::LazyLock},
6 vm::Program,
7};
8
9use crate::account::{
10 components::basic_wallet_library,
11 interface::{AccountComponentInterface, AccountInterface},
12};
13
14static P2ID_SCRIPT: LazyLock<NoteScript> = LazyLock::new(|| {
19 let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/P2ID.masb"));
20 let program = Program::read_from_bytes(bytes).expect("Shipped P2ID script is well-formed");
21 NoteScript::new(program)
22});
23
24static P2IDR_SCRIPT: LazyLock<NoteScript> = LazyLock::new(|| {
26 let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/P2IDR.masb"));
27 let program = Program::read_from_bytes(bytes).expect("Shipped P2IDR script is well-formed");
28 NoteScript::new(program)
29});
30
31static SWAP_SCRIPT: LazyLock<NoteScript> = LazyLock::new(|| {
33 let bytes = include_bytes!(concat!(env!("OUT_DIR"), "/assets/note_scripts/SWAP.masb"));
34 let program = Program::read_from_bytes(bytes).expect("Shipped SWAP script is well-formed");
35 NoteScript::new(program)
36});
37
38fn p2id() -> NoteScript {
40 P2ID_SCRIPT.clone()
41}
42
43fn p2id_root() -> Digest {
45 P2ID_SCRIPT.root()
46}
47
48fn p2idr() -> NoteScript {
50 P2IDR_SCRIPT.clone()
51}
52
53fn p2idr_root() -> Digest {
55 P2IDR_SCRIPT.root()
56}
57
58fn swap() -> NoteScript {
60 SWAP_SCRIPT.clone()
61}
62
63fn swap_root() -> Digest {
65 SWAP_SCRIPT.root()
66}
67
68pub enum WellKnownNote {
73 P2ID,
74 P2IDR,
75 SWAP,
76}
77
78impl WellKnownNote {
79 pub fn from_note(note: &Note) -> Option<Self> {
82 let note_script_root = note.script().root();
83
84 if note_script_root == p2id_root() {
85 return Some(Self::P2ID);
86 }
87 if note_script_root == p2idr_root() {
88 return Some(Self::P2IDR);
89 }
90 if note_script_root == swap_root() {
91 return Some(Self::SWAP);
92 }
93
94 None
95 }
96
97 pub fn script(&self) -> NoteScript {
99 match self {
100 Self::P2ID => p2id(),
101 Self::P2IDR => p2idr(),
102 Self::SWAP => swap(),
103 }
104 }
105
106 pub fn script_root(&self) -> Digest {
108 match self {
109 Self::P2ID => p2id_root(),
110 Self::P2IDR => p2idr_root(),
111 Self::SWAP => swap_root(),
112 }
113 }
114
115 pub fn is_compatible_with(&self, account_interface: &AccountInterface) -> bool {
118 if account_interface.components().contains(&AccountComponentInterface::BasicWallet) {
119 return true;
120 }
121
122 let interface_proc_digests = account_interface.get_procedure_digests();
123 match self {
124 Self::P2ID | &Self::P2IDR => {
125 let receive_asset_proc_name = QualifiedProcedureName::new(
129 Default::default(),
130 ProcedureName::new("receive_asset").unwrap(),
131 );
132 let node_id = basic_wallet_library().get_export_node_id(&receive_asset_proc_name);
133 let receive_asset_digest = basic_wallet_library().mast_forest()[node_id].digest();
134
135 interface_proc_digests.contains(&receive_asset_digest)
136 },
137 Self::SWAP => {
138 basic_wallet_library()
142 .mast_forest()
143 .procedure_digests()
144 .all(|proc_digest| interface_proc_digests.contains(&proc_digest))
145 },
146 }
147 }
148}