Skip to main content
Version: 0.17 (unstable)

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?​

NoteUse it whenRust typeMASM module
P2IDYou are sending assets to a specific account ID.P2idNotemiden::standards::notes::p2id
P2IDEYou are sending to a specific account ID with a timelock and/or reclaim path.P2ideNotemiden::standards::notes::p2ide
SWAPYou are offering one asset and requiring a specific asset in return.SwapNotemiden::standards::notes::swap
PSWAPYou need a partially fillable swap note.PswapNotemiden::standards::notes::pswap
MINTYou are requesting that a network faucet mint an asset and create a delivery note.MintNotemiden::standards::notes::mint
BURNA faucet is burning an asset returned through a note.BurnNotemiden::standards::notes::burn
UPGRADEAn authorized owner or role holder is replacing a deployed network account's code.UpgradeNotemiden::standards::notes::upgrade

For the note model itself, start with What are Notes?. This page focuses on how the standards fit into builder workflows.

Create a public P2ID note
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.

NoteConsuming account needs
P2ID / P2IDEBasicWallet, exposing receive_asset.
SWAP / PSWAPBasicWallet and NoteCreator, exposing receive_asset, move_asset_to_note, and create_note.
MINTA network faucet exposing CodeInspection::has_procedure and a fungible or non-fungible mint_and_send procedure.
BURNThe issuing faucet exposing CodeInspection::has_procedure and a fungible or non-fungible receive_and_burn procedure.
UPGRADEA 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.

HelperUse it for
StandardNoteAttachmentIdentifiers for standard attachment schemes.
NetworkAccountTargetAttaching network-account targeting data to notes.
AccountTargetNetworkNoteWrapping notes known to target network accounts.
NetworkNoteExtConvenience helpers for network-targeted notes.
NoteExecutionHintEncoding 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::*.