use alloc::vec::Vec;
use miden_objects::account::AccountId;
use miden_objects::asset::Asset;
use miden_objects::block::BlockNumber;
use miden_objects::crypto::rand::FeltRng;
use miden_objects::note::{
Note,
NoteAssets,
NoteDetails,
NoteExecutionHint,
NoteInputs,
NoteMetadata,
NoteRecipient,
NoteTag,
NoteType,
};
use miden_objects::{Felt, NoteError, Word};
use utils::build_swap_tag;
pub mod utils;
mod well_known_note;
pub use well_known_note::{NoteConsumptionStatus, WellKnownNote};
pub fn create_p2id_note<R: FeltRng>(
sender: AccountId,
target: AccountId,
assets: Vec<Asset>,
note_type: NoteType,
aux: Felt,
rng: &mut R,
) -> Result<Note, NoteError> {
let serial_num = rng.draw_word();
let recipient = utils::build_p2id_recipient(target, serial_num)?;
let tag = NoteTag::from_account_id(target);
let metadata = NoteMetadata::new(sender, note_type, tag, NoteExecutionHint::always(), aux)?;
let vault = NoteAssets::new(assets)?;
Ok(Note::new(vault, metadata, recipient))
}
pub fn create_p2ide_note<R: FeltRng>(
sender: AccountId,
target: AccountId,
assets: Vec<Asset>,
reclaim_height: Option<BlockNumber>,
timelock_height: Option<BlockNumber>,
note_type: NoteType,
aux: Felt,
rng: &mut R,
) -> Result<Note, NoteError> {
let serial_num = rng.draw_word();
let recipient =
utils::build_p2ide_recipient(target, reclaim_height, timelock_height, serial_num)?;
let tag = NoteTag::from_account_id(target);
let execution_hint = match timelock_height {
Some(height) => NoteExecutionHint::after_block(height)?,
None => NoteExecutionHint::always(),
};
let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
let vault = NoteAssets::new(assets)?;
Ok(Note::new(vault, metadata, recipient))
}
pub fn create_swap_note<R: FeltRng>(
sender: AccountId,
offered_asset: Asset,
requested_asset: Asset,
swap_note_type: NoteType,
swap_note_aux: Felt,
payback_note_type: NoteType,
payback_note_aux: Felt,
rng: &mut R,
) -> Result<(Note, NoteDetails), NoteError> {
if requested_asset == offered_asset {
return Err(NoteError::other("requested asset same as offered asset"));
}
let note_script = WellKnownNote::SWAP.script();
let payback_serial_num = rng.draw_word();
let payback_recipient = utils::build_p2id_recipient(sender, payback_serial_num)?;
let payback_recipient_word: Word = payback_recipient.digest();
let requested_asset_word: Word = requested_asset.into();
let payback_tag = NoteTag::from_account_id(sender);
let inputs = NoteInputs::new(vec![
requested_asset_word[0],
requested_asset_word[1],
requested_asset_word[2],
requested_asset_word[3],
payback_recipient_word[0],
payback_recipient_word[1],
payback_recipient_word[2],
payback_recipient_word[3],
NoteExecutionHint::always().into(),
payback_note_type.into(),
payback_note_aux,
payback_tag.into(),
])?;
let tag = build_swap_tag(swap_note_type, &offered_asset, &requested_asset)?;
let serial_num = rng.draw_word();
let metadata =
NoteMetadata::new(sender, swap_note_type, tag, NoteExecutionHint::always(), swap_note_aux)?;
let assets = NoteAssets::new(vec![offered_asset])?;
let recipient = NoteRecipient::new(serial_num, note_script, inputs);
let note = Note::new(assets, metadata, recipient);
let payback_assets = NoteAssets::new(vec![requested_asset])?;
let payback_note = NoteDetails::new(payback_assets, payback_recipient);
Ok((note, payback_note))
}
pub fn create_mint_note<R: FeltRng>(
faucet_id: AccountId,
sender: AccountId,
target_recipient: Word,
output_note_tag: Felt,
amount: Felt,
aux: Felt,
output_note_aux: Felt,
rng: &mut R,
) -> Result<Note, NoteError> {
let note_script = WellKnownNote::MINT.script();
let serial_num = rng.draw_word();
let note_type = NoteType::Public;
let output_note_type = NoteType::Private;
let execution_hint = NoteExecutionHint::always();
let inputs = NoteInputs::new(vec![
target_recipient[0],
target_recipient[1],
target_recipient[2],
target_recipient[3],
execution_hint.into(),
output_note_type.into(),
output_note_aux,
output_note_tag,
amount,
])?;
let tag = NoteTag::from_account_id(faucet_id);
let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
let assets = NoteAssets::new(vec![])?; let recipient = NoteRecipient::new(serial_num, note_script, inputs);
Ok(Note::new(assets, metadata, recipient))
}
pub fn create_burn_note<R: FeltRng>(
sender: AccountId,
faucet_id: AccountId,
fungible_asset: Asset,
aux: Felt,
rng: &mut R,
) -> Result<Note, NoteError> {
let note_script = WellKnownNote::BURN.script();
let serial_num = rng.draw_word();
let note_type = NoteType::Public;
let execution_hint = NoteExecutionHint::always();
let inputs = NoteInputs::new(vec![])?;
let tag = NoteTag::from_account_id(faucet_id);
let metadata = NoteMetadata::new(sender, note_type, tag, execution_hint, aux)?;
let assets = NoteAssets::new(vec![fungible_asset])?; let recipient = NoteRecipient::new(serial_num, note_script, inputs);
Ok(Note::new(assets, metadata, recipient))
}