miden_agglayer/
claim_note.rs1use alloc::string::ToString;
2use alloc::vec;
3use alloc::vec::Vec;
4
5use miden_core::{Felt, Word};
6use miden_protocol::account::AccountId;
7use miden_protocol::crypto::SequentialCommit;
8use miden_protocol::crypto::rand::FeltRng;
9use miden_protocol::errors::NoteError;
10use miden_protocol::note::{Note, NoteAssets, NoteMetadata, NoteRecipient, NoteStorage, NoteType};
11use miden_standards::note::{NetworkAccountTarget, NoteExecutionHint};
12
13use crate::utils::Keccak256Output;
14use crate::{EthAddress, EthAmount, GlobalIndex, MetadataHash, claim_script};
15
16pub type SmtNode = Keccak256Output;
21
22pub type ExitRoot = Keccak256Output;
24
25pub type LeafValue = Keccak256Output;
27
28pub type CgiChainHash = Keccak256Output;
30
31#[derive(Clone)]
34pub struct ProofData {
35 pub smt_proof_local_exit_root: [SmtNode; 32],
37 pub smt_proof_rollup_exit_root: [SmtNode; 32],
39 pub global_index: GlobalIndex,
41 pub mainnet_exit_root: ExitRoot,
43 pub rollup_exit_root: ExitRoot,
45}
46
47impl SequentialCommit for ProofData {
48 type Commitment = Word;
49
50 fn to_elements(&self) -> Vec<Felt> {
51 const PROOF_DATA_ELEMENT_COUNT: usize = 536; let mut elements = Vec::with_capacity(PROOF_DATA_ELEMENT_COUNT);
53
54 for node in self.smt_proof_local_exit_root.iter() {
56 elements.extend(node.to_elements());
57 }
58
59 for node in self.smt_proof_rollup_exit_root.iter() {
60 elements.extend(node.to_elements());
61 }
62
63 elements.extend(self.global_index.to_elements());
65
66 elements.extend(self.mainnet_exit_root.to_elements());
68 elements.extend(self.rollup_exit_root.to_elements());
69
70 elements
71 }
72}
73
74#[derive(Clone)]
77pub struct LeafData {
78 pub origin_network: u32,
80 pub origin_token_address: EthAddress,
82 pub destination_network: u32,
84 pub destination_address: EthAddress,
86 pub amount: EthAmount,
88 pub metadata_hash: MetadataHash,
90}
91
92impl SequentialCommit for LeafData {
93 type Commitment = Word;
94
95 fn to_elements(&self) -> Vec<Felt> {
96 const LEAF_DATA_ELEMENT_COUNT: usize = 32; let mut elements = Vec::with_capacity(LEAF_DATA_ELEMENT_COUNT);
98
99 elements.push(Felt::ZERO);
103
104 let origin_network = u32::from_le_bytes(self.origin_network.to_be_bytes());
106 elements.push(Felt::from(origin_network));
107
108 elements.extend(self.origin_token_address.to_elements());
110
111 let destination_network = u32::from_le_bytes(self.destination_network.to_be_bytes());
113 elements.push(Felt::from(destination_network));
114
115 elements.extend(self.destination_address.to_elements());
117
118 elements.extend(self.amount.to_elements());
120
121 elements.extend(self.metadata_hash.to_elements());
123
124 elements.extend(vec![Felt::ZERO; 3]);
126
127 elements
128 }
129}
130
131#[derive(Clone)]
136pub struct ClaimNoteStorage {
137 pub proof_data: ProofData,
139 pub leaf_data: LeafData,
141 pub miden_claim_amount: Felt,
143}
144
145impl TryFrom<ClaimNoteStorage> for NoteStorage {
146 type Error = NoteError;
147
148 fn try_from(storage: ClaimNoteStorage) -> Result<Self, Self::Error> {
149 let mut claim_storage = Vec::with_capacity(569);
152
153 claim_storage.extend(storage.proof_data.to_elements());
154 claim_storage.extend(storage.leaf_data.to_elements());
155 claim_storage.push(storage.miden_claim_amount);
156
157 NoteStorage::new(claim_storage)
158 }
159}
160
161pub fn create_claim_note<R: FeltRng>(
177 storage: ClaimNoteStorage,
178 target_bridge_id: AccountId,
179 sender_account_id: AccountId,
180 rng: &mut R,
181) -> Result<Note, NoteError> {
182 let note_storage = NoteStorage::try_from(storage.clone())?;
183
184 let attachment = NetworkAccountTarget::new(target_bridge_id, NoteExecutionHint::Always)
185 .map_err(|e| NoteError::other(e.to_string()))?
186 .into();
187
188 let metadata =
189 NoteMetadata::new(sender_account_id, NoteType::Public).with_attachment(attachment);
190
191 let recipient = NoteRecipient::new(rng.draw_word(), claim_script(), note_storage);
192 let assets = NoteAssets::new(vec![])?;
193
194 Ok(Note::new(assets, metadata, recipient))
195}