Standard Notes
Standard notes are prebuilt note scripts from miden-standards. They cover common asset flows and network-account administration before builders need custom note scripts.
Use the Rust APIs to construct standard notes in client or transaction-building code. The scripts themselves are MASM modules, so direct MASM authors can inspect or import the same standard scripts when they need exact procedure behavior.
Which note should I use?
| Note | Use it when | Rust type | MASM module |
|---|---|---|---|
| P2ID | You are sending assets to a specific account ID. | P2idNote | miden::standards::notes::p2id |
| P2IDE | You are sending to a specific account ID with a timelock and/or reclaim path. | P2ideNote | miden::standards::notes::p2ide |
| SWAP | You are offering one asset and requiring a specific asset in return. | SwapNote | miden::standards::notes::swap |
| PSWAP | You need a partially fillable swap note. | PswapNote | miden::standards::notes::pswap |
| MINT | You are requesting that a network faucet mint an asset and create a delivery note. | MintNote | miden::standards::notes::mint |
| BURN | A faucet is burning an asset returned through a note. | BurnNote | miden::standards::notes::burn |
| UPGRADE | An authorized owner or role holder is replacing a deployed network account's code. | UpgradeNote | miden::standards::notes::upgrade |
For the note model itself, start with What are Notes?. This page focuses on how the standards fit into builder workflows.
use miden_protocol::Word;
use miden_protocol::account::{
AccountId, AccountIdVersion, AccountType, AssetCallbackFlag,
};
use miden_protocol::asset::{Asset, FungibleAsset};
use miden_protocol::crypto::rand::RandomCoin;
use miden_protocol::note::{Note, NoteType};
use miden_standards::note::P2idNote;
fn dummy_account(byte: u8, account_type: AccountType) -> AccountId {
let mut bytes = [0; 15];
bytes[0] = byte;
AccountId::dummy(
bytes,
AccountIdVersion::Version1,
account_type,
AssetCallbackFlag::Disabled,
)
}
fn create_p2id_note() -> Result<(), Box<dyn std::error::Error>> {
let sender = dummy_account(1, AccountType::Public);
let target = dummy_account(2, AccountType::Public);
let faucet_id = dummy_account(3, AccountType::Public);
let asset: Asset = FungibleAsset::new(faucet_id, 100)?.into();
let mut rng = RandomCoin::new(Word::from([1, 2, 3, 4u32]));
let note: Note = P2idNote::builder()
.sender(sender)
.target(target)
.asset(asset)
.note_type(NoteType::Public)
.generate_serial_number(&mut rng)
.build()?
.into();
assert_eq!(note.metadata().sender(), sender);
Ok(())
}
AccountId::dummy is available with the protocol crate's testing feature
and keeps this example self-contained. Production code should use account IDs
created or retrieved through the client.
Account requirements
Standard notes assume the consuming account exposes the procedures the note script calls.
| Note | Consuming account needs |
|---|---|
| P2ID / P2IDE | BasicWallet, exposing receive_asset. |
| SWAP / PSWAP | BasicWallet and NoteCreator, exposing receive_asset, move_asset_to_note, and create_note. |
| MINT | A network faucet exposing CodeInspection::has_procedure and a fungible or non-fungible mint_and_send procedure. |
| BURN | The issuing faucet exposing CodeInspection::has_procedure and a fungible or non-fungible receive_and_burn procedure. |
| UPGRADE | A deployed public network account with UpgradeManager, owner- or role-controlled Authority, and the upgrade script in both its note allowlist and fee schedule. |
If you write a custom wallet or faucet component, test it against the standard notes you expect it to consume.
PSWAP output sealing
PSWAP validates and seals the payback P2ID note. For a partial fill, it also validates and seals the remainder PSWAP note. Each output must hold exactly the expected assets. A later note or transaction script cannot add assets or attachments to a sealed output. Create a separate output note for anything extra.
Asset callbacks run before sealing. A callback that adds an asset or increases the expected balance makes the fill fail with PSWAP output was altered before sealing. Public attachments added before sealing remain part of the final note ID. Attempts to modify either output after sealing fail with sealed output notes cannot be modified.
Network-account upgrades
UpgradeNote carries the new code in public attachments and calls the target's UpgradeManager. The target must already exist and preserve its storage layout when replacing its code. Follow Upgrade a network account for authority, allowlist, fees, attachment limits, and a Rust example. Exhaustive matches on StandardNote must include StandardNote::UPGRADE.
Attachments and execution hints
Standard notes can use attachments and execution hints to help clients and indexers route notes and decide when a note might be consumable.
| Helper | Use it for |
|---|---|
StandardNoteAttachment | Identifiers for standard attachment schemes. |
NetworkAccountTarget | Attaching network-account targeting data to notes. |
AccountTargetNetworkNote | Wrapping notes known to target network accounts. |
NetworkNoteExt | Convenience helpers for network-targeted notes. |
NoteExecutionHint | Encoding when clients should attempt note execution. |
Execution hints do not replace note-script checks. The note script still enforces consumption rules during transaction execution.
Rust and MASM entry points
Rust constructors are the usual way to create standard notes in client-side code. Direct MASM authors should use the standard note modules as the source of truth for stack effects and script behavior.
The Rust types live under miden_standards::note. The MASM scripts live under miden::standards::notes::*.
Related pages
- Standard Note Types - more detail on P2ID, P2IDE, and SWAP
- Output Notes - creating output notes from transactions
- Note Scripts - writing custom note scripts
miden-standardsnote source - current implementation