Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
848dd19
feat: add last admin capability prevention of deletion
itsyaasir Feb 14, 2026
763bea2
feat: allow lint for abort_without_constant in capability_component_t…
itsyaasir Feb 16, 2026
7df0efd
feat: implement explicit destruction and revocation for initial admin…
itsyaasir Feb 16, 2026
819f796
feat: add Prettier configuration and update Move.lock dependencies
itsyaasir Feb 16, 2026
5b0ab43
Merge branch 'main' into feat/emit-events-for-capabilities
itsyaasir Feb 17, 2026
dc2c566
feat: Add drop capability to TimeLock enum for improved resource mana…
itsyaasir Feb 24, 2026
7c12271
feat: Enhance RoleMap documentation and clarify initial admin role pr…
itsyaasir Mar 3, 2026
6c457b1
feat: Update role_map to use assert_capability_valid and enhance Time…
itsyaasir Mar 3, 2026
bb710f5
feat: Update role change events to separate role creation, removal, a…
itsyaasir Mar 3, 2026
bd55db0
feat: Simplify CapabilityDestroyed struct and update event emission f…
itsyaasir Mar 3, 2026
04a8b53
Merge pull request #104 from iotaledger/feat/improvements-and-fixes
itsyaasir Mar 3, 2026
23225ad
Merge branch 'main' into feat/tf-compoenents-dev
chrisgitiota Mar 4, 2026
e651819
RoleMap with generic role-data argument (#100)
chrisgitiota Mar 9, 2026
05ddef6
Merge branch 'main' into feat/tf-compoenents-dev
chrisgitiota Mar 17, 2026
9579d8a
Feat: `revoked_capabilities` list for TfComponents RoleMap (#108)
chrisgitiota Mar 19, 2026
ad6f4d8
chore: publish components move package
itsyaasir Mar 24, 2026
43bc4e1
chore: add tf component id to the trait
itsyaasir Mar 26, 2026
5af85c1
Merge pull request #110 from iotaledger/feat/tf-components-package
itsyaasir Mar 27, 2026
2cbbedc
chore: bump up msrv
itsyaasir Mar 27, 2026
c3e2c63
Preserve tf components package id in wasm core client bridge
itsyaasir Mar 30, 2026
3c21bc8
Fix V2 dynamic field param name
itsyaasir Mar 30, 2026
62a160d
chore: deploy tf components to testnet
itsyaasir Mar 30, 2026
41271da
Merge branch 'main' into feat/tf-compoenents-dev
chrisgitiota Mar 31, 2026
c010c8e
fix: re-export iota_move types from rpc_types
itsyaasir Apr 1, 2026
eb08514
Merge branch 'main' into feat/tf-compoenents-dev
itsyaasir Apr 29, 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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ edition = "2021"
homepage = "https://www.iota.org"
license = "Apache-2.0"
repository = "https://github.com/iotaledger/product-core.rs"
rust-version = "1.70"
rust-version = "1.80"

[workspace]
resolver = "2"
Expand Down
1 change: 1 addition & 0 deletions bindings/wasm/iota_interaction_ts/lib/core_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { TransactionSigner } from "~iota_interaction_ts";
export interface CoreClientReadOnly {
packageId(): string;
packageHistory(): string[];
tfComponentsPackageId(): string | undefined;
network(): string;
iotaClient(): IotaClient;
}
Expand Down
3 changes: 3 additions & 0 deletions bindings/wasm/iota_interaction_ts/src/core_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ extern "C" {
#[wasm_bindgen(method, js_name = packageHistory)]
pub fn package_history(this: &WasmCoreClientReadOnly) -> Vec<String>;

#[wasm_bindgen(method, js_name = tfComponentsPackageId)]
pub fn tf_components_package_id(this: &WasmCoreClientReadOnly) -> Option<String>;

#[wasm_bindgen(method, js_name = network)]
pub fn network(this: &WasmCoreClientReadOnly) -> String;

Expand Down
1 change: 1 addition & 0 deletions components_move/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
build/*
8 changes: 8 additions & 0 deletions components_move/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"tabWidth": 4,
"printWidth": 100,
"useModuleLabel": true,
"autoGroupImports": "package",
"enableErrorDebug": false,
"wrapComments": false
}
10 changes: 10 additions & 0 deletions components_move/Move.history.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"aliases": {
"testnet": "2304aa97"
},
"envs": {
"testnet": [
"0x098767e6cd008f341847ad68089300375a274899b1c718e8cf8f5d57f96e8607"
]
}
}
20 changes: 14 additions & 6 deletions components_move/Move.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[move]
version = 3
manifest_digest = "172E6E9D27DFB64487EDC62DB907AD3642D5693302E78F3727A67B53C44DAD6C"
manifest_digest = "4E219538E560B52E657002599823A7F5794C484FDEB0EA7DE93DD860C8821C44"
deps_digest = "F9B494B64F0615AED0E98FC12A85B85ECD2BC5185C22D30E7F67786BB52E507C"
dependencies = [
{ id = "Iota", name = "Iota" },
Expand All @@ -13,15 +13,15 @@ dependencies = [

[[move.package]]
id = "Iota"
source = { git = "https://github.com/iotaledger/iota.git", rev = "4698c6723208e052a00c74602d2c8dc0efffe5de", subdir = "crates/iota-framework/packages/iota-framework" }
source = { git = "https://github.com/iotaledger/iota.git", rev = "e694e2ee8f2f9f0b9b03b843a24ff0f7bcff2930", subdir = "crates/iota-framework/packages/iota-framework" }

dependencies = [
{ id = "MoveStdlib", name = "MoveStdlib" },
]

[[move.package]]
id = "IotaSystem"
source = { git = "https://github.com/iotaledger/iota.git", rev = "4698c6723208e052a00c74602d2c8dc0efffe5de", subdir = "crates/iota-framework/packages/iota-system" }
source = { git = "https://github.com/iotaledger/iota.git", rev = "e694e2ee8f2f9f0b9b03b843a24ff0f7bcff2930", subdir = "crates/iota-framework/packages/iota-system" }

dependencies = [
{ id = "Iota", name = "Iota" },
Expand All @@ -30,18 +30,26 @@ dependencies = [

[[move.package]]
id = "MoveStdlib"
source = { git = "https://github.com/iotaledger/iota.git", rev = "4698c6723208e052a00c74602d2c8dc0efffe5de", subdir = "crates/iota-framework/packages/move-stdlib" }
source = { git = "https://github.com/iotaledger/iota.git", rev = "e694e2ee8f2f9f0b9b03b843a24ff0f7bcff2930", subdir = "crates/iota-framework/packages/move-stdlib" }

[[move.package]]
id = "Stardust"
source = { git = "https://github.com/iotaledger/iota.git", rev = "4698c6723208e052a00c74602d2c8dc0efffe5de", subdir = "crates/iota-framework/packages/stardust" }
source = { git = "https://github.com/iotaledger/iota.git", rev = "e694e2ee8f2f9f0b9b03b843a24ff0f7bcff2930", subdir = "crates/iota-framework/packages/stardust" }

dependencies = [
{ id = "Iota", name = "Iota" },
{ id = "MoveStdlib", name = "MoveStdlib" },
]

[move.toolchain-version]
compiler-version = "1.14.1"
compiler-version = "1.19.1"
edition = "2024.beta"
flavor = "iota"

[env]

[env.testnet]
chain-id = "2304aa97"
original-published-id = "0x098767e6cd008f341847ad68089300375a274899b1c718e8cf8f5d57f96e8607"
latest-published-id = "0x098767e6cd008f341847ad68089300375a274899b1c718e8cf8f5d57f96e8607"
published-version = "1"
128 changes: 106 additions & 22 deletions components_move/examples/counter/sources/counter.move
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright (c) 2026 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

/// Simple shared counter to demonstrate role_mao::RoleMap integration
/// Simple shared counter to demonstrate role_map::RoleMap integration
/// It also demonstrates how to use the generic role-data argument of the RoleMap
/// to implement time-based permissions by storing a weekday in the role data
/// and checking if the current day matches the stored weekday in the permission check.
#[test_only]
module tf_components::counter;

Expand All @@ -11,13 +14,63 @@ use tf_components::counter_permission::{Self as permission, CounterPermission};
use tf_components::role_map;

#[error]
const EPermissionDenied: vector<u8> =
b"The role associated with the provided capability does not have the required permission";
const EWeekDayMismatch: vector<u8> =
b"The role associated with the provided capability is restricted to a specific weekday which does not match the current weekday";

public enum Weekday has copy, drop, store {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday,
}

public fun weekday_to_u8(self: &Weekday): u8 {
match (self) {
Weekday::Monday => 0,
Weekday::Tuesday => 1,
Weekday::Wednesday => 2,
Weekday::Thursday => 3,
Weekday::Friday => 4,
Weekday::Saturday => 5,
Weekday::Sunday => 6,
}
}

public fun monday(): Weekday {
Weekday::Monday
}

public fun tuesday(): Weekday {
Weekday::Tuesday
}

public fun wednesday(): Weekday {
Weekday::Wednesday
}

public fun thursday(): Weekday {
Weekday::Thursday
}

public fun friday(): Weekday {
Weekday::Friday
}

public fun saturday(): Weekday {
Weekday::Saturday
}

public fun sunday(): Weekday {
Weekday::Sunday
}

public struct Counter has key {
id: UID,
value: u64,
access: role_map::RoleMap<CounterPermission>,
access: role_map::RoleMap<CounterPermission, Weekday>,
}

public fun create(ctx: &mut TxContext): (Capability, ID) {
Expand Down Expand Up @@ -76,29 +129,60 @@ public fun create(ctx: &mut TxContext): (Capability, ID) {
(admin_cap, counter_id)
}

public fun increment(counter: &mut Counter, cap: &Capability, clock: &Clock, ctx: &TxContext) {
assert!(
counter
.access
.is_capability_valid(
cap,
&permission::increment_counter(),
clock,
ctx,
),
EPermissionDenied,
public fun increment(self: &mut Counter, cap: &Capability, clock: &Clock, ctx: &TxContext) {
self.assert_capability_valid(
cap,
&permission::increment_counter(),
clock,
ctx,
);
self.value = self.value + 1;
}

public fun assert_capability_valid(
self: &Counter,
cap: &Capability,
permission: &CounterPermission,
clock: &Clock,
ctx: &TxContext,
): bool {
self.access.assert_capability_valid(
cap,
permission,
clock,
ctx
);
counter.value = counter.value + 1;
let role_data_option = self.access.get_role_data(cap.role());
if (role_data_option.is_some_and!(|required_weekday| {
let current_weekday = to_weekday(clock);
weekday_to_u8(required_weekday) != current_weekday
})) {
assert!(false, EWeekDayMismatch);
};
true
}

public fun access(self: &Counter): &role_map::RoleMap<CounterPermission, Weekday> {
&self.access
}

public fun access(counter: &Counter): &role_map::RoleMap<CounterPermission> {
&counter.access
public fun access_mut(self: &mut Counter): &mut role_map::RoleMap<CounterPermission, Weekday> {
&mut self.access
}

public fun access_mut(counter: &mut Counter): &mut role_map::RoleMap<CounterPermission> {
&mut counter.access
public fun value(self: &Counter): u64 {
self.value
}

public fun value(counter: &Counter): u64 {
counter.value
/// Returns the day of the week (0 = Monday, 1 = Tuesday, ..., 6 = Sunday)
/// based on a millisecond Unix timestamp.
/// The Unix epoch (timestamp 0) was a Thursday (day index 3).
public fun to_weekday(clock: &Clock): u8 {
let timestamp_ms = clock.timestamp_ms();
let ms_per_day: u64 = 86_400_000; // 24 * 60 * 60 * 1000
let day_count = timestamp_ms / ms_per_day;
// Unix epoch is Thursday. If Monday = 0, then Thursday = 3.
// So we add 3 to shift the epoch day to Thursday, then mod 7.
let weekday = ((day_count + 3) % 7) as u8;
weekday
}
Loading
Loading