Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
9a73293
chore: fix `TransactionAuthenticator::get_signature()` docs
bobbinth Dec 14, 2025
534aa0e
chore: fix lints
bobbinth Dec 14, 2025
b351216
test: simplify codebuilder creation (#2175)
igamigo Dec 15, 2025
26f67f1
feat: Add From<&ExecutedTransaction> for TransactionHeader impl (#2178)
sergerad Dec 15, 2025
8d70adc
chore: update protocol library docs (#2179)
PhilippGackstatter Dec 15, 2025
2d6e5a0
refactor: add `SlotName` to `StorageSlotHeader` (#2160)
Farukest Dec 15, 2025
822c6a0
test: move tx header test logic (#2181)
sergerad Dec 15, 2025
8bb2058
ci: improve dependency control & runner disk space (#2133)
huitseeker Dec 16, 2025
c0c1e3e
chore: refactor `AccountStorageDelta` to use `StorageSlotDelta` (#2182)
PhilippGackstatter Dec 17, 2025
ac944ef
refactor: Implement component schemas (#2193)
igamigo Dec 19, 2025
da7a823
chore: migrate to the VM v0.20.0 (#2158)
Fumuran Dec 20, 2025
67884c3
chore: prepare split into protocol and standards (#2184)
PhilippGackstatter Dec 20, 2025
55909b4
chore: move protocol components from `miden-lib` to `miden-objects` (…
PhilippGackstatter Dec 20, 2025
c8aad1b
feat: rename `miden-objects` into `miden-protocol` and `miden-lib` in…
PhilippGackstatter Dec 20, 2025
e6f0573
feat: add `Clone` to `NoteConsumptionStatus` (#2209)
juan518munoz Dec 24, 2025
0c26f2a
refactor: rm `OLD_MAP_ROOT` from return of `set_map_item` (#2194)
partylikeits1983 Dec 26, 2025
dee1d48
feat: follow-ups from #2193 (#2207)
igamigo Dec 30, 2025
b4ac3da
feat: implement ownership management for network fungible faucet
afa7789 Jan 6, 2026
4fb098b
chore: restore stack manipulation
mmagician Jan 7, 2026
3d90813
refactor: simplify ownership error handling and clean up unused proce…
afa7789 Jan 8, 2026
07fee30
feat: add renounce ownership functionality to network fungible faucet
afa7789 Jan 8, 2026
65c50a4
Update crates/miden-standards/asm/standards/utils/access/ownable.masm
afa7789 Jan 8, 2026
2a96753
chore: fix based on PR review.
afa7789 Jan 8, 2026
ca83cc2
feat: implement ownership management functionality in ownable module …
afa7789 Jan 9, 2026
1edb039
fix: update stack handling in transfer_ownership procedure for proper…
afa7789 Jan 10, 2026
0aa6d68
test: add unit test for get_owner procedure in network fungible faucet
afa7789 Jan 13, 2026
8d74f6d
refactor: clean up ownable module documentation and error constants, …
afa7789 Jan 14, 2026
79be861
feat: add ownable standard module for component ownership management …
afa7789 Jan 15, 2026
18a7d27
feat:import constants directly instead of getter procedures (#2221)
PoulavBhowmick03 Jan 6, 2026
bc34aa3
fix: ensure cargo-msrv is properly installed for MSRV check (#2234)
huitseeker Jan 6, 2026
1512add
feat: add AccountId::parse() for hex and bech32 formats (#2223)
Farukest Jan 6, 2026
7421546
chore: organize `miden-standards` (#2227)
mmagician Jan 7, 2026
17b76f9
refactor: close gap in account memory layout (#2190)
PivasDesant Jan 8, 2026
34392ae
chore: add error messages to asserts (#2239)
mmagician Jan 8, 2026
f696d29
feat: move standard note scripts into standard library (#2255)
Farukest Jan 12, 2026
c430514
chore: move MSRV check from PR CI to release workflows (#2233)
huitseeker Jan 13, 2026
49377cd
feat: Read foreign account inputs and witnesses from transaction inpu…
sergerad Jan 13, 2026
b680282
feat: insert unpadded note inputs into `advice_inputs` (#2232)
mmagician Jan 13, 2026
c25d8f6
feat: Refactor `NoteTag` to contain an arbitrary `u32` (#2219)
PhilippGackstatter Jan 15, 2026
a6a83ee
feat: add tx kernel support for `NoteAttachment` (#2249)
PhilippGackstatter Jan 15, 2026
1f66663
feat: add `output_not_set_attachment` kernel API (#2252)
PhilippGackstatter Jan 15, 2026
1978e6b
feat: introduce standard `NetworkAccountTarget` attachment (#2257)
PhilippGackstatter Jan 15, 2026
8e47927
chore: Remove `aux` and `execution_hint` parameters from `output_note…
PhilippGackstatter Jan 15, 2026
166d8c0
chore: rename `NoteAttachmentType` and `NoteAttachmentContentType` (#…
PhilippGackstatter Jan 15, 2026
83dc36d
feat: add ownable standard module for component ownership management …
afa7789 Jan 15, 2026
fdfbfb5
refactor: simplify note creation by replacing auxiliary parameters wi…
afa7789 Jan 15, 2026
1d1bdf3
chore(cargo): fixing lint issues.
afa7789 Jan 15, 2026
c8bcbfe
Merge branch 'next' into openzeppelin/ownable
afa7789 Jan 15, 2026
1229dc0
Merge branch 'next' into openzeppelin/ownable
afa7789 Jan 16, 2026
d122730
Update crates/miden-standards/asm/standards/access/ownable.masm
afa7789 Jan 16, 2026
ac2374c
Update crates/miden-standards/asm/standards/access/ownable.masm
afa7789 Jan 16, 2026
196a491
Update crates/miden-standards/asm/standards/access/ownable.masm
afa7789 Jan 16, 2026
b3ae5f8
chore: Refactor error handling in faucet tests to use ERR_SENDER_NOT_…
afa7789 Jan 16, 2026
5428d53
chore: lint fix
afa7789 Jan 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
- [BREAKING] Introduce `NoteAttachment` as part of `NoteMetadata` and remove `aux` and `execution_hint` ([#2249](https://github.com/0xMiden/miden-base/pull/2249), [#2252](https://github.com/0xMiden/miden-base/pull/2252), [#2260](https://github.com/0xMiden/miden-base/pull/2260)).
- [BREAKING] Introduce `NoteAttachment` as part of `NoteMetadata` and remove `aux` and `execution_hint` ([#2249](https://github.com/0xMiden/miden-base/pull/2249), [#2252](https://github.com/0xMiden/miden-base/pull/2252), [#2260](https://github.com/0xMiden/miden-base/pull/2260), [#2268](https://github.com/0xMiden/miden-base/pull/2268), [#2279](https://github.com/0xMiden/miden-base/pull/2279)).
- Introduce standard `NetworkAccountTarget` attachment for use in network transactions which replaces `NoteTag::NetworkAccount` ([#2257](https://github.com/0xMiden/miden-base/pull/2257)).
- Added `miden::standards::access::ownable` standard module for component ownership management, and integrated it into the `network_fungible` faucet (including new tests). ([#2228](https://github.com/0xMiden/miden-base/pull/2228)).

### Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@

pub use ::miden::standards::faucets::network_fungible::distribute
pub use ::miden::standards::faucets::network_fungible::burn
pub use ::miden::standards::faucets::network_fungible::transfer_ownership
pub use ::miden::standards::faucets::network_fungible::renounce_ownership
175 changes: 175 additions & 0 deletions crates/miden-standards/asm/standards/access/ownable.masm
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# miden::standards::access::ownable
#
# Provides ownership management functionality for account components.
# This template can be imported and used by any component that needs owner controls.

use miden::protocol::active_account
use miden::protocol::account_id
use miden::protocol::active_note
use miden::protocol::native_account

# CONSTANTS
# ================================================================================================

# The slot in this component's storage layout where the owner config is stored.
const OWNER_CONFIG_SLOT = word("miden::standards::access::ownable::owner_config")

# ZERO_ADDRESS word (all zeros) used to represent no owner
# Format: [prefix=0, suffix=0, 0, 0] as stored in account storage
const ZERO_ADDRESS = [0, 0, 0, 0]

# ERRORS
# ================================================================================================

const ERR_SENDER_NOT_OWNER = "note sender is not the owner"

# INTERNAL PROCEDURES
# ================================================================================================

#! Returns the owner AccountId from storage.
#!
#! Inputs: []
#! Outputs: [owner_prefix, owner_suffix]
#!
#! Where:
#! - owner_{prefix, suffix} are the prefix and suffix felts of the owner AccountId.
proc owner
push.OWNER_CONFIG_SLOT[0..2] exec.active_account::get_item
# => [owner_prefix, owner_suffix, 0, 0]

# Storage format in memory: [0, 0, suffix, prefix] (word[0], word[1], word[2], word[3])
# mem_loadw_be loads big-endian (reversed), so stack gets: [prefix, suffix, 0, 0]
# Stack: [owner_prefix (pos 0), owner_suffix (pos 1), 0 (pos 2), 0 (pos 3)]
# We want: [owner_prefix, owner_suffix]
# Move zeros to top using movup, then drop them
movup.2
# => [0, owner_prefix, owner_suffix, 0] (moves element at pos 2 to pos 0)

movup.3
# => [0, 0, owner_prefix, owner_suffix] (moves element at pos 3 to pos 0)

drop drop
# => [owner_prefix, owner_suffix]
end

#! Checks if the given account ID is the owner of this component.
#!
#! Inputs: [account_id_prefix, account_id_suffix]
#! Outputs: [is_owner]
#!
#! Where:
#! - account_id_{prefix, suffix} are the prefix and suffix felts of the AccountId to check.
#! - is_owner is 1 if the account is the owner, 0 otherwise.
proc is_owner

exec.owner
# => [owner_prefix, owner_suffix, account_id_prefix, account_id_suffix]

exec.account_id::is_equal
# => [is_owner]

end

# PUBLIC INTERFACE
# ================================================================================================

#! Checks if the note sender is the owner and panics if not.
#!
#! Inputs: []
#! Outputs: []
#!
#! Panics if:
#! - the note sender is not the owner.
pub proc verify_owner
exec.active_note::get_sender
# => [sender_prefix, sender_suffix]

exec.is_owner
# => [is_owner]

assert.err=ERR_SENDER_NOT_OWNER
# => []
end

#! Returns the owner AccountId.
#!
#! Inputs: [pad(16)]
#! Outputs: [owner_prefix, owner_suffix, pad(14)]
#!
#! Where:
#! - owner_{prefix, suffix} are the prefix and suffix felts of the owner AccountId.
#!
#! Invocation: call
pub proc get_owner
exec.owner
# => [owner_prefix, owner_suffix, pad(14)]
end

#! Transfers ownership to a new account.
#!
#! Can only be called by the current owner.
#!
#! Inputs: [new_owner_prefix, new_owner_suffix, pad(14)]
#! Outputs: [pad(16)]
#!
#! Where:
#! - new_owner_{prefix, suffix} are the prefix and suffix felts of the new owner AccountId.
#!
#! Panics if:
#! - the note sender is not the owner.
#!
#! Invocation: call
pub proc transfer_ownership
# Check that the caller is the owner
exec.verify_owner
# => [new_owner_prefix, new_owner_suffix, pad(14)]

push.0 movdn.2 push.0 movdn.2
# => [new_owner_prefix, new_owner_suffix, 0, 0, pad(14)]

push.OWNER_CONFIG_SLOT[0..2]
# => [slot_prefix, slot_suffix, new_owner_prefix, new_owner_suffix, 0, 0, pad(14)]

exec.native_account::set_item
# => [OLD_OWNER_WORD, pad(14)]

# When the stack has 16 elements, dropw will shift in zeros from the right,
# resulting in [pad(16)]. So dropw is sufficient here.
dropw
# => [pad(16)]
end

#! Renounces ownership, leaving the component without an owner.
#!
#! Can only be called by the current owner.
#!
#! Inputs: [pad(16)]
#! Outputs: [pad(16)]
#!
#! Panics if:
#! - the note sender is not the owner.
#!
#! Invocation: call
#!
#! Important Note!
#! This feature allows the owner to relinquish administrative privileges, a common pattern
#! after an initial stage with centralized administration is over. Once ownership is renounced,
#! the component becomes permanently ownerless and cannot be managed by any account.
pub proc renounce_ownership
exec.verify_owner
# => [pad(16)]

# ---- Push ZERO_ADDRESS to storage ----
push.ZERO_ADDRESS
# => [0, 0, 0, 0, pad(16)]

push.OWNER_CONFIG_SLOT[0..2]
# => [slot_prefix, slot_suffix, 0, 0, 0, 0, pad(16)]

exec.native_account::set_item
# => [OLD_OWNER_WORD, pad(16)]

dropw
# => [pad(16)]
end

67 changes: 39 additions & 28 deletions crates/miden-standards/asm/standards/faucets/network_fungible.masm
Original file line number Diff line number Diff line change
@@ -1,38 +1,52 @@
use miden::protocol::active_account
use miden::protocol::account_id
use miden::protocol::active_note
use miden::standards::faucets
use miden::standards::faucets::basic_fungible
use miden::standards::access::ownable

# CONSTANTS
# PUBLIC INTERFACE
# ================================================================================================

# The slot in this component's storage layout where the owner config is stored.
const OWNER_CONFIG_SLOT=word("miden::standards::network_fungible_faucet::owner_config")
# OWNER MANAGEMENT
# ------------------------------------------------------------------------------------------------

# ERRORS
const ERR_ONLY_OWNER_CAN_MINT="note sender is not the owner of the faucet who can mint assets"

#! Checks if the note sender is the owner of this faucet.
#! Returns the owner AccountId.
#!
#! Inputs: []
#! Outputs: [is_owner]
#! Outputs: [owner_prefix, owner_suffix, pad(14)]
#!
#! Where:
#! - is_owner is 1 if the sender is the owner, 0 otherwise.
proc is_owner
push.OWNER_CONFIG_SLOT[0..2] exec.active_account::get_item
# => [owner_prefix, owner_suffix, 0, 0]
#! Invocation: call
pub use ownable::get_owner

exec.active_note::get_sender
# => [sender_prefix, sender_suffix, owner_prefix, owner_suffix, 0, 0]
#! Transfers ownership to a new account.
#!
#! Can only be called by the current owner.
#!
#! Inputs: [new_owner_prefix, new_owner_suffix, pad(14)]
#! Outputs: [pad(16)]
#!
#! Where:
#! - new_owner_{prefix, suffix} are the prefix and suffix felts of the new owner AccountId.
#!
#! Panics if:
#! - the note sender is not the owner.
#!
#! Invocation: call
pub use ownable::transfer_ownership

exec.account_id::is_equal
# => [are_equal, 0, 0]
#! Renounces ownership, leaving the component without an owner.
#!
#! Can only be called by the current owner.
#!
#! Inputs: [pad(16)]
#! Outputs: [pad(16)]
#!
#! Panics if:
#! - the note sender is not the owner.
#!
#! Invocation: call
pub use ownable::renounce_ownership

movdn.2 drop drop
# => [is_owner]
end
# ASSET DISTRIBUTION
# ------------------------------------------------------------------------------------------------

#! Distributes freshly minted fungible assets to the provided recipient.
#!
Expand All @@ -55,11 +69,8 @@ end
#!
#! Invocation: call
pub proc distribute
exec.is_owner
# => [is_owner, amount, tag, note_type, RECIPIENT, pad(9)]

assert.err=ERR_ONLY_OWNER_CAN_MINT
# => [amount, tag, note_type, RECIPIENT, pad(9)]
exec.ownable::verify_owner
# => [amount, tag, aux, note_type, execution_hint, RECIPIENT, pad(7)]

exec.faucets::distribute
# => [note_idx, pad(15)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ procedure_digest!(
);

static OWNER_CONFIG_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
StorageSlotName::new("miden::standards::network_fungible_faucet::owner_config")
StorageSlotName::new("miden::standards::access::ownable::owner_config")
.expect("storage slot name should be valid")
});

Expand Down
6 changes: 3 additions & 3 deletions crates/miden-standards/src/errors/standards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ pub const ERR_MALFORMED_MULTISIG_CONFIG: MasmError = MasmError::from_static_str(
/// Error Message: "MINT script expects exactly 12 inputs for private or 16+ inputs for public output notes"
pub const ERR_MINT_WRONG_NUMBER_OF_INPUTS: MasmError = MasmError::from_static_str("MINT script expects exactly 12 inputs for private or 16+ inputs for public output notes");

/// Error Message: "note sender is not the owner of the faucet who can mint assets"
pub const ERR_ONLY_OWNER_CAN_MINT: MasmError = MasmError::from_static_str("note sender is not the owner of the faucet who can mint assets");

/// Error Message: "failed to reclaim P2IDE note because the reclaiming account is not the sender"
pub const ERR_P2IDE_RECLAIM_ACCT_IS_NOT_SENDER: MasmError = MasmError::from_static_str("failed to reclaim P2IDE note because the reclaiming account is not the sender");
/// Error Message: "P2IDE reclaim is disabled"
Expand All @@ -40,6 +37,9 @@ pub const ERR_P2ID_TARGET_ACCT_MISMATCH: MasmError = MasmError::from_static_str(
/// Error Message: "P2ID note expects exactly 2 note inputs"
pub const ERR_P2ID_WRONG_NUMBER_OF_INPUTS: MasmError = MasmError::from_static_str("P2ID note expects exactly 2 note inputs");

/// Error Message: "note sender is not the owner"
pub const ERR_SENDER_NOT_OWNER: MasmError = MasmError::from_static_str("note sender is not the owner");

/// Error Message: "SWAP script requires exactly 1 note asset"
pub const ERR_SWAP_WRONG_NUMBER_OF_ASSETS: MasmError = MasmError::from_static_str("SWAP script requires exactly 1 note asset");
/// Error Message: "SWAP script expects exactly 16 note inputs"
Expand Down
Loading