extern crate alloc;
use alloc::vec;
use miden_processor::crypto::random::RandomCoin;
use miden_protocol::account::{Account, AccountBuilder, AccountId, AccountType, AssetCallbackFlag};
use miden_protocol::asset::{Asset, AssetAmount, FungibleAsset};
use miden_protocol::note::{Note, NoteTag, NoteType};
use miden_protocol::transaction::ExecutedTransaction;
use miden_protocol::{Felt, Word};
use miden_standards::account::access::Authority;
use miden_standards::account::faucets::{FungibleFaucet, TokenName};
use miden_standards::account::policies::{BurnPolicy, MintPolicy, TokenPolicyManager};
use miden_standards::account::wallets::BasicWallet;
use miden_standards::note::{MintNote, MintNoteStorage, P2idNote};
use miden_testing::{AccountState, Auth, MockChainBuilder};
pub(crate) fn add_faucet_with_wallet(builder: &mut MockChainBuilder) -> anyhow::Result<Account> {
let faucet = FungibleFaucet::builder()
.name(TokenName::new("OTH")?)
.symbol("OTH".try_into()?)
.decimals(8)
.max_supply(AssetAmount::new(1_000_000)?)
.build()?;
let account_builder = AccountBuilder::new([44u8; 32])
.account_type(AccountType::Public)
.with_asset_callbacks(AssetCallbackFlag::Disabled)
.with_component(faucet)
.with_component(BasicWallet)
.with_component(Authority::AuthControlled)
.with_components(
TokenPolicyManager::builder()
.active_mint_policy(MintPolicy::allow_all())
.active_burn_policy(BurnPolicy::allow_all())
.build(),
);
builder.add_account_from_builder(Auth::IncrNonce, account_builder, AccountState::Exists)
}
pub(crate) struct MintNoteFixture {
pub note: Note,
pub asset: FungibleAsset,
pub recipient_digest: Word,
}
pub(crate) fn build_mint_note(
sender: AccountId,
faucet_id: AccountId,
target: AccountId,
amount: u64,
rng_seed: u32,
) -> anyhow::Result<MintNoteFixture> {
let asset = FungibleAsset::new(faucet_id, amount)?;
let tag = NoteTag::with_account_target(target);
let output_note = Note::from(
P2idNote::builder()
.sender(faucet_id)
.target(target)
.assets(vec![asset])
.note_type(NoteType::Private)
.serial_number(Word::default())
.build()?,
);
let recipient_digest = output_note.recipient().digest();
let mut rng = RandomCoin::new([Felt::from(rng_seed); 4].into());
let note: Note = MintNote::builder()
.sender(sender)
.mint_storage(MintNoteStorage::new_fungible_private(recipient_digest, asset, tag))
.generate_serial_number(&mut rng)
.build()?
.into();
Ok(MintNoteFixture { note, asset, recipient_digest })
}
pub(crate) fn assert_minted_note(
executed: &ExecutedTransaction,
mint: &MintNoteFixture,
) -> anyhow::Result<()> {
assert_eq!(executed.output_notes().num_notes(), 1);
let note = executed.output_notes().get_note(0);
assert_eq!(note.recipient_digest(), mint.recipient_digest);
let expected_asset: Asset = mint.asset.into();
assert_eq!(note.assets().num_assets(), 1);
assert_eq!(note.assets().iter().next(), Some(&expected_asset));
Ok(())
}