diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/.gitignore b/crates/iota-e2e-tests/tests/abstract_account/authenticate/.gitignore new file mode 100644 index 00000000000..a007feab071 --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/.gitignore @@ -0,0 +1 @@ +build/* diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/Move.toml b/crates/iota-e2e-tests/tests/abstract_account/authenticate/Move.toml new file mode 100644 index 00000000000..a5b368736fe --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/Move.toml @@ -0,0 +1,13 @@ +[package] +name = "authenticate" +edition = "2024" + +[dependencies] +Iota = { local = "../../../../iota-framework/packages/iota-framework" } + +[addresses] +authenticate = "0x0" + +[dev-dependencies] + +[dev-addresses] diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/object.move b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/object.move new file mode 100644 index 00000000000..1e8c6563166 --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/object.move @@ -0,0 +1,32 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module authenticate::object; + +use iota::auth_context::AuthContext; + +// Object + +public struct Object has key, store { + id: iota::object::UID, +} + +// PASS +public fun immutable_ref( + _object: &Object, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +#[allow(lint(share_owned))] +public fun by_value(object: Object, _auth_ctx: &AuthContext, _ctx: &TxContext) { + transfer::public_share_object(object); +} + +// FAIL +public fun by_mutable_ref( + _object: &mut Object, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/option.move b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/option.move new file mode 100644 index 00000000000..54e75844324 --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/option.move @@ -0,0 +1,179 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module authenticate::option; + +use iota::auth_context::AuthContext; + +public struct Object has key, store { + id: iota::object::UID, +} + +#[allow(unused_field)] +public struct ObjectTemplated has copy, drop, store { + t: T, +} + +#[allow(unused_field)] +public struct NonObjectTemplated has copy, drop, store { + t: T, +} + +public struct NonObject has copy, drop, store {} + +// Option + +// PASS +public fun primitive_immutable_reference( + _arg: &Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun primitive_mutable_reference( + _arg: &mut Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// PASS +public fun primitive_by_value(_arg: Option, _auth_ctx: &AuthContext, _ctx: &TxContext) {} + +// FAIL +public fun non_object_immutable_ref( + _arg: &Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun non_object_mutable_ref( + _arg: &mut Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun non_object_by_value( + _arg: Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// Option and object + +// PASS +public fun object_immutable_ref( + _objects: &Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun object_mutable_ref( + _objects: &mut Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +#[allow(lint(share_owned))] +public fun object_by_value(objects: Option, _auth_ctx: &AuthContext, _ctx: &TxContext) { + objects.do!(|object| transfer::public_share_object(object)); +} + +// Option and template + +// error[E06001]: unused value without 'drop' +//public fun template_non_object_by_value( +// _arg: Option, +// _auth_ctx: &AuthContext, +// _ctx: &TxContext, +//) {} + +// PASS +public fun template_non_object_immutable_ref( + _arg: &Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun template_non_object_mutable_ref( + _arg: &mut Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_non_object_by_value( + _arg: Option>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// PASS +public fun templated_non_object_immutable_ref( + _arg: &Option>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_non_object_mutable_ref( + _arg: &mut Option>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// Option, template and object + +// PASS +public fun template_object_immutable_reference( + _objects: &Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun template_object_by_value( + objects: Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) { + objects.do!(|object| transfer::public_share_object(object)); +} + +// FAIL +public fun template_object_mutable_reference( + _objects: &mut Option, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// PASS +public fun templated_object_immutable_ref( + _objects: &Option>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_object_by_value( + objects: Option>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) { + objects.do!(|object| { + let ObjectTemplated { t } = object; + transfer::public_share_object(t); + }); +} + +// FAIL +public fun templated_object_mutable_ref( + _objects: &mut Option>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/signature.move b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/signature.move new file mode 100644 index 00000000000..6585d243797 --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/signature.move @@ -0,0 +1,43 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module authenticate::signature; + +use iota::auth_context::AuthContext; + +// PASS +public fun minimally_viable_auth_function(_auth_ctx: &AuthContext, _ctx: &TxContext) {} + +// FAIL +#[allow(unused_function)] +fun has_to_be_public_auth_function(_auth_ctx: &AuthContext, _ctx: &TxContext) {} + +// FAIL +public fun at_least_two_args(_ctx: &TxContext) {} + +// FAIL +public fun auth_context_cant_be_value(_auth_ctx: AuthContext, _ctx: &TxContext) {} + +// FAIL +public fun auth_context_cant_be_mutable_ref(_auth_ctx: &mut AuthContext, _ctx: &TxContext) {} + +// FAIL +public fun tx_context_cant_be_value(_auth_ctx: &AuthContext, _ctx: TxContext) {} + +// FAIL +public fun tx_context_cant_be_mutable_ref(_auth_ctx: &AuthContext, _ctx: &mut TxContext) {} + +// FAIL +public fun auth_context_isnt_struct(_auth_ctx: u64, _ctx: &TxContext) {} + +// FAIL +public fun tx_context_isnt_struct(_auth_ctx: &AuthContext, _ctx: u64) {} + +// PASS +public fun arg_value(_val: u8, _auth_ctx: &AuthContext, _ctx: &TxContext) {} + +// PASS +public fun arg_mutable_value(mut _val: u8, _auth_ctx: &AuthContext, _ctx: &TxContext) {} + +// FAIL +public fun with_signer(_s: signer, _auth_ctx: &AuthContext, _ctx: &TxContext) {} diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/template.move b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/template.move new file mode 100644 index 00000000000..e2ee45f8cbd --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/template.move @@ -0,0 +1,99 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module authenticate::template; + +use iota::auth_context::AuthContext; + +public struct Object has key, store { + id: iota::object::UID, +} + +// Template + +#[allow(unused_field)] +public struct NonObjectTemplated has copy, drop, store { + t: T, +} + +// PASS +public fun primitive( + _arg: T, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// PASS +public fun templated_non_object_immutable_ref( + _arg: &NonObjectTemplated, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_non_object_mutable_ref( + _arg: &mut NonObjectTemplated, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_non_object_by_value( + _arg: NonObjectTemplated, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// Template and object + +// PASS +public fun object_immutable_ref( + _object: &T, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun object_by_value( + object: T, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) { + transfer::public_share_object(object); +} + +// FAIL +public fun object_mutable_ref( + _object: &mut T, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +#[allow(unused_field)] +public struct ObjectTemplated has copy, drop, store { + t: T, +} + +// PASS +public fun templated_object_immutable_ref( + _object: &ObjectTemplated, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_object_by_value( + object: ObjectTemplated, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) { + let ObjectTemplated { t } = object; + transfer::public_share_object(t); +} + +// FAIL +public fun templated_object_mutable_ref( + _object: &mut ObjectTemplated, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/vector.move b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/vector.move new file mode 100644 index 00000000000..84ceb51b844 --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/sources/vector.move @@ -0,0 +1,179 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +module authenticate::vector; + +use iota::auth_context::AuthContext; + +public struct Object has key, store { + id: iota::object::UID, +} + +#[allow(unused_field)] +public struct ObjectTemplated has copy, drop, store { + t: T, +} + +#[allow(unused_field)] +public struct NonObjectTemplated has copy, drop, store { + t: T, +} + +public struct NonObject has copy, drop, store {} + +// Vector + +// PASS +public fun primitive_immutable_reference( + _arg: &vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun primitive_mutable_reference( + _arg: &mut vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// PASS +public fun primitive_by_value(_arg: vector, _auth_ctx: &AuthContext, _ctx: &TxContext) {} + +// PASS +public fun non_object_immutable_ref( + _arg: &vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun non_object_mutable_ref( + _arg: &mut vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun non_object_by_value( + _arg: vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// Vector and object + +// PASS +public fun object_immutable_ref( + _objects: &vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun object_mutable_ref( + _objects: &mut vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +#[allow(lint(share_owned))] +public fun object_by_value(objects: vector, _auth_ctx: &AuthContext, _ctx: &TxContext) { + objects.do!(|object| transfer::public_share_object(object)); +} + +// Vector and template + +// error[E06001]: unused value without 'drop' +//public fun template_non_object_by_value( +// _arg: vector, +// _auth_ctx: &AuthContext, +// _ctx: &TxContext, +//) {} + +// PASS +public fun template_non_object_immutable_ref( + _arg: &vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun template_non_object_mutable_ref( + _arg: &mut vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_non_object_by_value( + _arg: vector>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// PASS +public fun templated_non_object_immutable_ref( + _arg: &vector>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_non_object_mutable_ref( + _arg: &mut vector>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// Vector, template and object + +// PASS +public fun template_object_immutable_reference( + _objects: &vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun template_object_by_value( + objects: vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) { + objects.do!(|object| transfer::public_share_object(object)); +} + +// FAIL +public fun template_object_mutable_reference( + _objects: &mut vector, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// PASS +public fun templated_object_immutable_ref( + _objects: &vector>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} + +// FAIL +public fun templated_object_by_value( + objects: vector>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) { + objects.do!(|object| { + let ObjectTemplated { t } = object; + transfer::public_share_object(t); + }); +} + +// FAIL +public fun templated_object_mutable_ref( + _objects: &mut vector>, + _auth_ctx: &AuthContext, + _ctx: &TxContext, +) {} diff --git a/crates/iota-e2e-tests/tests/abstract_account/authenticate/tests/authenticate_tests.move b/crates/iota-e2e-tests/tests/abstract_account/authenticate/tests/authenticate_tests.move new file mode 100644 index 00000000000..e1398c15b7a --- /dev/null +++ b/crates/iota-e2e-tests/tests/abstract_account/authenticate/tests/authenticate_tests.move @@ -0,0 +1,6 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +/* +The verifier cannot be tested through move unit tests, using account::create_auth_info. +*/ diff --git a/crates/iota-e2e-tests/tests/authenticate_verifier_tests.rs b/crates/iota-e2e-tests/tests/authenticate_verifier_tests.rs new file mode 100644 index 00000000000..744d7ec0109 --- /dev/null +++ b/crates/iota-e2e-tests/tests/authenticate_verifier_tests.rs @@ -0,0 +1,285 @@ +// Copyright (c) 2025 IOTA Stiftung +// SPDX-License-Identifier: Apache-2.0 + +//! Abstract Account verifier tests +//! +//! The tests in this module are meant to test the +//! `account::create_auth_info_v1` native function ,`iota-execution/latest/ +//! iota-verifier/src/account_auth_verifier.rs` verifier and the +//! `iota-execution/latest/iota-move-natives/src/raw_module_loader/mod.rs`in an +//! e2e environment. + +use iota_test_transaction_builder::publish_package; +use iota_types::{ + IOTA_FRAMEWORK_ADDRESS, + base_types::{ObjectID, ObjectRef}, + effects::{TransactionEffects, TransactionEvents}, + transaction::CallArg, +}; +use move_core_types::account_address::AccountAddress; +use test_cluster::{TestCluster, TestClusterBuilder}; + +macro_rules! use_crates { + () => { + use iota_macros::sim_test; + use iota_types::effects::TransactionEffectsAPI; + + use super::TestEnvironment; + }; +} + +/// Generate `simtest` tests for each `move module`. +/// +/// To use the macro: +/// tests_in_module(; pass::{+}? +/// fail::{+}?) pattern should be used. +/// Either the `pass` or `fail` section can be omitted, but not both. +/// +/// This macro collection helps remove the need to individually write out the +/// simtests. The generated code will look likes so: +/// ``` +/// { +/// pass { +/// #[sim_test] +/// async fn { ... } +/// ... +/// } +/// fail { +/// #[sim_test] +/// async fn { ... } +/// ... +/// } +/// } +/// ``` +/// With this module hierarchy we remove the possibility for test_name +/// collisions and can refer to each test case as one could find it in the +/// relevant source. E.x.: +/// ``` +/// tests_in_module!( +/// object; +/// pass::{ +/// immutable_ref +/// } +/// ) +/// ``` +/// The test can be found in the `object` move module and its name is +/// `immutable_ref`. +macro_rules! tests_in_module { + ($module_name:ident; pass::{$($function_name_p:ident),+ $(,)?}) => { + mod $module_name { + use_crates!(); + + gen_simtest_expect_pass![$($module_name::$function_name_p),+]; + } + }; + ($module_name:ident; fail::{$($function_name_f:ident),+ $(,)?}) => { + mod $module_name { + use_crates!(); + + gen_simtest_expect_fail![$($module_name::$function_name_f),+]; + } + }; + ($module_name:ident; pass::{$($function_name_p:ident),+ $(,)?} fail::{$($function_name_f:ident),+ $(,)?}) => { + mod $module_name { + use_crates!(); + + gen_simtest_expect_pass![$($module_name::$function_name_p),+]; + gen_simtest_expect_fail![$($module_name::$function_name_f),+]; + } + }; +} + +macro_rules! gen_simtest_expect_pass { + () => {}; + ($module_name: ident::$function_name: ident) => { + #[sim_test] + async fn $function_name() { + let env = TestEnvironment::new().await; + let (effects, _) = env + .create_auth_info_using(stringify!($module_name), stringify!($function_name)) + .await + .unwrap(); + assert!(effects.status().is_ok()); + } + }; + ($module_name: ident::$function_name: ident, $($module_name_n: ident::$function_name_n: ident),+) => { + gen_simtest_expect_pass![$module_name::$function_name]; + gen_simtest_expect_pass![$($module_name_n::$function_name_n),+]; + } +} + +macro_rules! gen_simtest_expect_fail { + () => {}; + ($module_name: ident::$function_name: ident) => { + #[sim_test] + async fn $function_name() { + let env = TestEnvironment::new().await; + let (effects, _) = env + .create_auth_info_using("signature", "at_least_two_args") + .await + .unwrap(); + assert!(effects.status().is_err()); + } + }; + ($module_name: ident::$function_name: ident, $($module_name_n: ident::$function_name_n: ident),+) => { + gen_simtest_expect_fail![$module_name::$function_name]; + gen_simtest_expect_fail![$($module_name_n::$function_name_n),+]; + } +} + +tests_in_module!( +object; +pass::{ + immutable_ref +} +fail::{ + by_value, + by_mutable_ref +}); + +tests_in_module!( +option; +pass::{ + primitive_immutable_reference, + primitive_by_value, + // non_object_immutable_ref, + object_immutable_ref, + template_non_object_immutable_ref, + templated_non_object_immutable_ref, + template_object_immutable_reference, + templated_object_immutable_ref +} +fail::{ + primitive_mutable_reference, + non_object_mutable_ref, + non_object_by_value, + object_mutable_ref, + object_by_value, + template_non_object_mutable_ref, + templated_non_object_by_value, + templated_non_object_mutable_ref, + template_object_by_value, + template_object_mutable_reference, + templated_object_by_value, + templated_object_mutable_ref +}); + +tests_in_module!( +signature; +pass::{ + minimally_viable_auth_function, + arg_value, + arg_mutable_value +} +fail::{ + has_to_be_public_auth_function, + at_least_two_args, + auth_context_cant_be_value, + auth_context_cant_be_mutable_ref, + tx_context_cant_be_value, + tx_context_cant_be_mutable_ref, + auth_context_isnt_struct, + tx_context_isnt_struct, + with_signer +}); + +tests_in_module!( +template; +pass::{ + primitive, + templated_non_object_immutable_ref, + object_immutable_ref, + templated_object_immutable_ref, +} +fail::{ + templated_non_object_mutable_ref, + templated_non_object_by_value, + object_by_value, + object_mutable_ref, + templated_object_by_value, + templated_object_mutable_ref +}); + +tests_in_module!( +vector; +pass::{ + primitive_immutable_reference, + primitive_by_value, + non_object_immutable_ref, + object_immutable_ref, + template_non_object_immutable_ref, + templated_non_object_immutable_ref, + template_object_immutable_reference, + templated_object_immutable_ref, +} +fail::{ + primitive_mutable_reference, + non_object_mutable_ref, + non_object_by_value, + object_mutable_ref, + object_by_value, + template_non_object_mutable_ref, + templated_non_object_by_value, + templated_non_object_mutable_ref, + template_object_by_value, + template_object_mutable_reference, + templated_object_by_value, + templated_object_mutable_ref +}); + +struct TestEnvironment { + cluster: TestCluster, + package_id: ObjectID, +} + +impl TestEnvironment { + async fn new() -> Self { + let cluster = TestClusterBuilder::new().build().await; + + let package_id = publish_move_package(&cluster).await.0; + + Self { + cluster, + package_id, + } + } + + async fn create_auth_info_using( + &self, + module_name: &str, + function_name: &str, + ) -> anyhow::Result<(TransactionEffects, TransactionEvents)> { + let arguments = vec![ + CallArg::Pure(bcs::to_bytes(&Into::::into(self.package_id)).unwrap()), + CallArg::Pure(bcs::to_bytes(module_name.as_bytes()).unwrap()), + CallArg::Pure(bcs::to_bytes(function_name.as_bytes()).unwrap()), + ]; + + let transaction_data = self + .cluster + .test_transaction_builder() + .await + .move_call( + IOTA_FRAMEWORK_ADDRESS.into(), + "account", + "create_auth_info_v1", + arguments, + ) + .build(); + + let transaction = self.cluster.wallet.sign_transaction(&transaction_data); + self.cluster + .execute_transaction_return_raw_effects(transaction) + .await + } +} + +async fn publish_move_package(test_cluster: &TestCluster) -> ObjectRef { + let path = [ + env!("CARGO_MANIFEST_DIR"), + "tests/abstract_account/authenticate", + ] + .iter() + .collect(); + publish_package(&test_cluster.wallet, path).await +} diff --git a/crates/iota-framework/packages/iota-framework/sources/account.move b/crates/iota-framework/packages/iota-framework/sources/account.move index 29e7d724c2a..5c29a922c20 100644 --- a/crates/iota-framework/packages/iota-framework/sources/account.move +++ b/crates/iota-framework/packages/iota-framework/sources/account.move @@ -27,6 +27,8 @@ public struct AuthenticatorInfoV1 has copy, drop, store { /// function defined in package B version 2. /// Refiring to an `authenticate` function with `create_auth_info_v1` is a strictly runtime dependency and /// it does not collide with any compile time restrictions. +/// +/// This function cannot be used in `move unit tests` as there is no mechanism to refer to the package being tested. public fun create_auth_info_v1( package: address, module_name: ascii::String, diff --git a/crates/iota-types/src/auth_context.rs b/crates/iota-types/src/auth_context.rs index 3ecefccfdf9..a749acfcc17 100644 --- a/crates/iota-types/src/auth_context.rs +++ b/crates/iota-types/src/auth_context.rs @@ -140,7 +140,7 @@ impl Serialize for AuthContext { "type_arguments", &m.type_arguments .iter() - .map(|ty| TypeName::from(ty)) + .map(TypeName::from) .collect::>(), )?; s.serialize_field("arguments", &m.arguments)?; @@ -149,7 +149,7 @@ impl Serialize for AuthContext { Command::MakeMoveVec(ty_opt, vals) => { let mut s = serializer.serialize_tuple_variant("Command", 5, "MakeMoveVec", 2)?; - s.serialize_field(&ty_opt.as_ref().map(|ty| TypeName::from(ty)))?; + s.serialize_field(&ty_opt.as_ref().map(TypeName::from))?; s.serialize_field(vals)?; s.end() }