diff --git a/Cargo.lock b/Cargo.lock index 409bb7e20..6e2bb66f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2755,6 +2755,12 @@ dependencies = [ "serde", ] +[[package]] +name = "build_const" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ae4235e6dac0694637c763029ecea1a2ec9e4e06ec2729bd21ba4d9c863eb7" + [[package]] name = "bumpalo" version = "3.16.0" @@ -5444,6 +5450,16 @@ dependencies = [ "serde", ] +[[package]] +name = "fs4" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8640e34b88f7652208ce9e88b1a37a2ae95227d84abec377ccd3c5cfeb141ed4" +dependencies = [ + "rustix 1.0.3", + "windows-sys 0.59.0", +] + [[package]] name = "funty" version = "2.0.0" @@ -6791,7 +6807,7 @@ checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" dependencies = [ "arbitrary", "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.16.0", "serde", "serde_core", ] @@ -7306,7 +7322,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -13097,7 +13113,7 @@ dependencies = [ "tokio", "toml_edit 0.23.7", "uuid 1.16.0", - "zip", + "zip 4.6.1", "zip-extract", ] @@ -14080,12 +14096,13 @@ dependencies = [ [[package]] name = "svm-rs" -version = "0.5.22" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909e8ff825120cd2b34ceb236ab72e2a7f74b1d3a86c247936c8ff7a80c5d408" +checksum = "039f8b5327f4c4c94384ad8596cc62fb23f58ef5e5d940945757b627fa56d0c2" dependencies = [ "const-hex", "dirs 6.0.0", + "fs4", "reqwest 0.12.24", "semver 1.0.26", "serde", @@ -14094,15 +14111,16 @@ dependencies = [ "tempfile", "thiserror 2.0.17", "url", - "zip", + "zip 2.3.0", ] [[package]] name = "svm-rs-builds" -version = "0.5.22" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ebe77b200f965e8dbec3ef1d8337e974179ca1ecaa9fc28f67288d6b438159" +checksum = "05723cae9acea48e97af3357b25cf0079277bf2ab54405fd3dd62258caae1a48" dependencies = [ + "build_const", "const-hex", "semver 1.0.26", "serde_json", @@ -15160,6 +15178,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "strum 0.26.3", + "strum_macros 0.26.4", "test-case", "tiny-hderive", "url", @@ -16483,7 +16502,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -17160,6 +17179,23 @@ dependencies = [ "syn 2.0.100", ] +[[package]] +name = "zip" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e9a772a54b54236b9b744aaaf8d7be01b4d6e99725523cb82cb32d1c81b1d7" +dependencies = [ + "arbitrary", + "crc32fast", + "crossbeam-utils", + "displaydoc", + "flate2", + "indexmap 2.11.4", + "memchr", + "thiserror 2.0.17", + "zopfli", +] + [[package]] name = "zip" version = "4.6.1" @@ -17182,7 +17218,7 @@ checksum = "7fa5b9958fd0b5b685af54f2c3fa21fca05fe295ebaf3e77b6d24d96c4174037" dependencies = [ "log 0.4.27", "thiserror 2.0.17", - "zip", + "zip 4.6.1", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 30cd949ec..2994ccd7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,6 @@ members = [ "crates/txtx-addon-kit", "crates/txtx-cloud", "crates/txtx-lsp", - "crates/txtx-supervisor-ui", "crates/txtx-serve", "addons/bitcoin", "addons/evm", @@ -46,3 +45,6 @@ txtx-addon-network-svm = { path = "addons/svm/core" } txtx-addon-telegram = { path = "addons/telegram" } txtx-addon-sp1 = { path = "addons/sp1" } uuid = { version = "1.15.1", features = ["v4", "serde", "js"] } + +[alias] +build-cli = "build --package txtx-cli --no-default-features --features cli" diff --git a/addons/bitcoin/src/functions/mod.rs b/addons/bitcoin/src/functions/mod.rs index 093642b85..31856ffea 100644 --- a/addons/bitcoin/src/functions/mod.rs +++ b/addons/bitcoin/src/functions/mod.rs @@ -1,6 +1,7 @@ use txtx_addon_kit::types::{ diagnostics::Diagnostic, functions::{arg_checker_with_ctx, fn_diag_with_ctx, FunctionSpecification}, + namespace::Namespace, types::Value, }; @@ -8,12 +9,12 @@ use crate::constants::NAMESPACE; pub mod opcodes; -pub fn arg_checker(fn_spec: &FunctionSpecification, args: &Vec) -> Result<(), Diagnostic> { - let checker = arg_checker_with_ctx(NAMESPACE.to_string()); +pub fn arg_checker(fn_spec: &FunctionSpecification, args: &[Value]) -> Result<(), Diagnostic> { + let checker = arg_checker_with_ctx(Namespace::from(NAMESPACE)); checker(fn_spec, args) } pub fn to_diag(fn_spec: &FunctionSpecification, e: String) -> Diagnostic { - let error_fn = fn_diag_with_ctx(NAMESPACE.to_string()); + let error_fn = fn_diag_with_ctx(Namespace::from(NAMESPACE)); error_fn(fn_spec, e) } diff --git a/addons/bitcoin/src/functions/opcodes/bitwise_logic.rs b/addons/bitcoin/src/functions/opcodes/bitwise_logic.rs index 455ac7811..5fbb2cbd4 100644 --- a/addons/bitcoin/src/functions/opcodes/bitwise_logic.rs +++ b/addons/bitcoin/src/functions/opcodes/bitwise_logic.rs @@ -35,7 +35,7 @@ impl FunctionImplementation for EqualVerify { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -43,7 +43,7 @@ impl FunctionImplementation for EqualVerify { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result { Ok(BitcoinValue::opcode(BitcoinOpcode::OpEqualVerify.get_code())) } diff --git a/addons/bitcoin/src/functions/opcodes/constants.rs b/addons/bitcoin/src/functions/opcodes/constants.rs index 132c7c459..9996c0fe6 100644 --- a/addons/bitcoin/src/functions/opcodes/constants.rs +++ b/addons/bitcoin/src/functions/opcodes/constants.rs @@ -95,7 +95,7 @@ impl FunctionImplementation for OpZero { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -103,7 +103,7 @@ impl FunctionImplementation for OpZero { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result { Ok(BitcoinValue::opcode(BitcoinOpcode::Op0.get_code())) } @@ -115,7 +115,7 @@ impl FunctionImplementation for PushData { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -123,7 +123,7 @@ impl FunctionImplementation for PushData { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let expected_bytes_length = args.get(0).unwrap().as_integer().unwrap(); @@ -165,7 +165,7 @@ impl FunctionImplementation for PushData1 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -173,7 +173,7 @@ impl FunctionImplementation for PushData1 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let expected_bytes_length = args.get(0).unwrap().as_integer().unwrap(); diff --git a/addons/bitcoin/src/functions/opcodes/crypto.rs b/addons/bitcoin/src/functions/opcodes/crypto.rs index b298a0b49..983e5dd84 100644 --- a/addons/bitcoin/src/functions/opcodes/crypto.rs +++ b/addons/bitcoin/src/functions/opcodes/crypto.rs @@ -55,7 +55,7 @@ impl FunctionImplementation for Hash160 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -63,7 +63,7 @@ impl FunctionImplementation for Hash160 { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result { Ok(BitcoinValue::opcode(BitcoinOpcode::OpHash160.get_code())) } @@ -75,7 +75,7 @@ impl FunctionImplementation for CheckSig { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -83,7 +83,7 @@ impl FunctionImplementation for CheckSig { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result { Ok(BitcoinValue::opcode(BitcoinOpcode::OpCheckSig.get_code())) } diff --git a/addons/bitcoin/src/functions/opcodes/stack.rs b/addons/bitcoin/src/functions/opcodes/stack.rs index f529262a6..4f24b4834 100644 --- a/addons/bitcoin/src/functions/opcodes/stack.rs +++ b/addons/bitcoin/src/functions/opcodes/stack.rs @@ -33,7 +33,7 @@ impl FunctionImplementation for Dup { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -41,7 +41,7 @@ impl FunctionImplementation for Dup { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result { Ok(BitcoinValue::opcode(BitcoinOpcode::OpDup.get_code())) } diff --git a/addons/evm/src/commands/actions/call_contract.rs b/addons/evm/src/commands/actions/call_contract.rs index a0cbfe359..cf1cff828 100644 --- a/addons/evm/src/commands/actions/call_contract.rs +++ b/addons/evm/src/commands/actions/call_contract.rs @@ -30,10 +30,11 @@ use crate::commands::actions::check_confirmations::CheckEvmConfirmations; use crate::commands::actions::sign_transaction::SignEvmTransaction; use crate::constants::{ ABI_ENCODED_RESULT, ADDRESS_ABI_MAP, CONTRACT_ABI, CONTRACT_ADDRESS, RESULT, RPC_API_URL, + TX_HASH, }; use crate::rpc::EvmRpc; use crate::typing::{DECODED_LOG_OUTPUT, EVM_ADDRESS, EVM_SIM_RESULT, RAW_LOG_OUTPUT}; -use txtx_addon_kit::constants::TX_HASH; +use txtx_addon_kit::constants::SignerKey; use super::{get_expected_address, get_signer_did}; @@ -231,14 +232,14 @@ impl CommandImplementation for SignEvmContractCall { let auth_context = auth_context.clone(); let future = async move { - use txtx_addon_kit::constants::META_DESCRIPTION; + use txtx_addon_kit::constants::DocumentationKey; use crate::{commands::actions::get_meta_description, constants::CHAIN_ID}; let mut actions = Actions::none(); let mut signer_state = signers.pop_signer_state(&signer_did).unwrap(); if let Some(_) = - signer_state.get_scoped_value(&construct_did.value().to_string(), TX_HASH) + signer_state.get_scoped_value(&construct_did.value().to_string(), SignerKey::TxHash) { return Ok((signers, signer_state, Actions::none())); } @@ -297,7 +298,7 @@ impl CommandImplementation for SignEvmContractCall { let mut values = values.clone(); values.insert(TRANSACTION_PAYLOAD_BYTES, payload.clone()); - values.insert(META_DESCRIPTION, Value::string(meta_description)); + values.insert(DocumentationKey::MetaDescription, Value::string(meta_description)); signer_state.insert_scoped_value( &construct_did.to_string(), @@ -387,7 +388,7 @@ impl CommandImplementation for SignEvmContractCall { Err(err) => return Err(err), }; result.append(&mut res_signing); - values.insert(TX_HASH, result.outputs.get(TX_HASH).unwrap().clone()); + values.insert(SignerKey::TxHash, result.outputs.get(SignerKey::TxHash.as_ref()).unwrap().clone()); let mut res = match CheckEvmConfirmations::run_execution( &construct_did, @@ -431,7 +432,7 @@ impl CommandImplementation for SignEvmContractCall { let future = async move { let mut result = CommandExecutionResult::new(); - result.outputs.insert(TX_HASH.to_string(), inputs.get_value(TX_HASH).unwrap().clone()); + result.outputs.insert(SignerKey::TxHash.to_string(), inputs.get_value(SignerKey::TxHash).unwrap().clone()); let call_result = outputs.get_expected_value(RESULT)?; result.outputs.insert(RESULT.to_string(), call_result.clone()); diff --git a/addons/evm/src/commands/actions/check_confirmations.rs b/addons/evm/src/commands/actions/check_confirmations.rs index f2ef0843f..8d0b22717 100644 --- a/addons/evm/src/commands/actions/check_confirmations.rs +++ b/addons/evm/src/commands/actions/check_confirmations.rs @@ -11,6 +11,7 @@ use txtx_addon_kit::types::{ types::Type, }; use txtx_addon_kit::uuid::Uuid; +use txtx_addon_kit::constants::SignerKey; use crate::constants::{DEFAULT_CONFIRMATIONS_NUMBER, RPC_API_URL}; @@ -175,7 +176,7 @@ impl CommandImplementation for CheckEvmConfirmations { return return_synchronous_result(Ok(result)); } - let tx_hash_bytes = inputs.get_expected_buffer_bytes(TX_HASH)?; + let tx_hash_bytes = inputs.get_expected_buffer_bytes(SignerKey::TxHash)?; let rpc_api_url = inputs.get_expected_string(RPC_API_URL)?.to_owned(); let progress_symbol = ["|", "/", "-", "\\", "|", "/", "-", "\\"]; diff --git a/addons/evm/src/commands/actions/deploy_contract.rs b/addons/evm/src/commands/actions/deploy_contract.rs index 80d3a1eb8..c17dea9d0 100644 --- a/addons/evm/src/commands/actions/deploy_contract.rs +++ b/addons/evm/src/commands/actions/deploy_contract.rs @@ -54,7 +54,7 @@ use super::check_confirmations::CheckEvmConfirmations; use super::sign_transaction::SignEvmTransaction; use super::{get_common_tx_params_from_args, get_expected_address, get_signer_did}; -use txtx_addon_kit::constants::TX_HASH; +use txtx_addon_kit::constants::SignerKey; lazy_static! { pub static ref DEPLOY_CONTRACT: PreCommandSpecification = { @@ -329,7 +329,7 @@ impl CommandImplementation for DeployContract { let mut actions = Actions::none(); let mut signer_state = signers.pop_signer_state(&signer_did).unwrap(); if let Some(_) = - signer_state.get_scoped_value(&construct_did.value().to_string(), TX_HASH) + signer_state.get_scoped_value(&construct_did.value().to_string(), SignerKey::TxHash) { return Ok((signers, signer_state, Actions::none())); } @@ -444,8 +444,8 @@ impl CommandImplementation for DeployContract { let mut values = values.clone(); values.insert(TRANSACTION_PAYLOAD_BYTES, payload); if let Some(meta_description) = meta_description { - use txtx_addon_kit::constants::META_DESCRIPTION; - values.insert(META_DESCRIPTION, Value::string(meta_description)); + use txtx_addon_kit::constants::DocumentationKey; + values.insert(DocumentationKey::MetaDescription, Value::string(meta_description)); } signers.push_signer_state(signer_state); @@ -559,7 +559,7 @@ impl CommandImplementation for DeployContract { }; result.append(&mut res_signing); - values.insert(TX_HASH, result.outputs.get(TX_HASH).unwrap().clone()); + values.insert(SignerKey::TxHash, result.outputs.get(SignerKey::TxHash.as_ref()).unwrap().clone()); (signers, signer_state) } else { @@ -613,8 +613,8 @@ impl CommandImplementation for DeployContract { // If the deployment is done through create2, it could have already been deployed, // which means we don't have a tx_hash - if let Some(tx_hash) = inputs.get_value(TX_HASH) { - result.insert(TX_HASH, tx_hash.clone()); + if let Some(tx_hash) = inputs.get_value(SignerKey::TxHash) { + result.insert(SignerKey::TxHash.as_ref(), tx_hash.clone()); }; if let Some(impl_contract_address) = outputs.get_value(IMPL_CONTRACT_ADDRESS) { diff --git a/addons/evm/src/commands/actions/send_eth.rs b/addons/evm/src/commands/actions/send_eth.rs index 653ca6222..986f690dd 100644 --- a/addons/evm/src/commands/actions/send_eth.rs +++ b/addons/evm/src/commands/actions/send_eth.rs @@ -27,7 +27,7 @@ use crate::commands::actions::sign_transaction::SignEvmTransaction; use crate::constants::RPC_API_URL; use crate::rpc::EvmRpc; use crate::typing::EVM_ADDRESS; -use txtx_addon_kit::constants::TX_HASH; +use txtx_addon_kit::constants::SignerKey; use super::get_signer_did; @@ -183,14 +183,14 @@ impl CommandImplementation for SendEth { let auth_context = auth_context.clone(); let future = async move { - use txtx_addon_kit::constants::META_DESCRIPTION; + use txtx_addon_kit::constants::DocumentationKey; use crate::commands::actions::get_meta_description; let mut actions = Actions::none(); let mut signer_state = signers.pop_signer_state(&signer_did).unwrap(); if let Some(_) = - signer_state.get_scoped_value(&construct_did.value().to_string(), TX_HASH) + signer_state.get_scoped_value(&construct_did.value().to_string(), SignerKey::TxHash) { return Ok((signers, signer_state, Actions::none())); } @@ -210,7 +210,7 @@ impl CommandImplementation for SendEth { let mut values = values.clone(); values.insert(TRANSACTION_PAYLOAD_BYTES, payload.clone()); - values.insert(META_DESCRIPTION, Value::string(meta_description)); + values.insert(DocumentationKey::MetaDescription, Value::string(meta_description)); signer_state.insert_scoped_value( &construct_did.to_string(), @@ -281,7 +281,7 @@ impl CommandImplementation for SendEth { Err(err) => return Err(err), }; result.append(&mut res_signing); - values.insert(TX_HASH, result.outputs.get(TX_HASH).unwrap().clone()); + values.insert(SignerKey::TxHash, result.outputs.get(SignerKey::TxHash.as_ref()).unwrap().clone()); let mut res = match CheckEvmConfirmations::run_execution( &construct_did, @@ -325,7 +325,7 @@ impl CommandImplementation for SendEth { let future = async move { let mut result = CommandExecutionResult::new(); - result.outputs.insert(TX_HASH.to_string(), inputs.get_value(TX_HASH).unwrap().clone()); + result.outputs.insert(SignerKey::TxHash.to_string(), inputs.get_value(SignerKey::TxHash).unwrap().clone()); let mut res = CheckEvmConfirmations::build_background_task( &construct_did, &spec, diff --git a/addons/evm/src/commands/actions/sign_transaction.rs b/addons/evm/src/commands/actions/sign_transaction.rs index 0a179564a..9361c87e1 100644 --- a/addons/evm/src/commands/actions/sign_transaction.rs +++ b/addons/evm/src/commands/actions/sign_transaction.rs @@ -19,11 +19,12 @@ use txtx_addon_kit::types::{ signers::SignersState, types::RunbookSupervisionContext, ConstructDid, }; -use crate::constants::{ACTION_ITEM_CHECK_FEE, ACTION_ITEM_CHECK_NONCE, ALREADY_DEPLOYED}; +use crate::constants::ALREADY_DEPLOYED; +use txtx_addon_kit::constants::ActionItemKey; use crate::constants::SECRET_KEY_WALLET_UNSIGNED_TRANSACTION_BYTES; use crate::typing::EvmValue; -use txtx_addon_kit::constants::TX_HASH; +use txtx_addon_kit::constants::SignerKey; use super::get_signer_did; @@ -120,23 +121,23 @@ impl CommandImplementation for SignEvmTransaction { let auth_ctx = auth_ctx.clone(); let future = async move { - use txtx_addon_kit::constants::{DESCRIPTION, META_DESCRIPTION}; + use txtx_addon_kit::constants::DocumentationKey; let mut actions = Actions::none(); let mut signer_state = signers.pop_signer_state(&signer_did).unwrap(); if let Some(_) = - signer_state.get_scoped_value(&construct_did.value().to_string(), TX_HASH) + signer_state.get_scoped_value(&construct_did.value().to_string(), SignerKey::TxHash) { return Ok((signers, signer_state, Actions::none())); } let description = - values.get_expected_string(DESCRIPTION).ok().and_then(|d| Some(d.to_string())); + values.get_expected_string(DocumentationKey::Description).ok().and_then(|d| Some(d.to_string())); let markdown = values .get_markdown(&auth_ctx) .map_err(|diag| (signers.clone(), signer_state.clone(), diag))?; let meta_description = - values.get_expected_string(META_DESCRIPTION).ok().and_then(|d| Some(d.to_string())); + values.get_expected_string(DocumentationKey::MetaDescription).ok().and_then(|d| Some(d.to_string())); let already_deployed = signer_state .get_scoped_bool(&construct_did.to_string(), ALREADY_DEPLOYED) @@ -149,7 +150,7 @@ impl CommandImplementation for SignEvmTransaction { actions.push_sub_group(description.clone(), vec![]); } } else { - use txtx_addon_kit::constants::SIGNATURE_APPROVED; + use txtx_addon_kit::constants::SignerKey; let transaction_request_bytes = values .get_expected_buffer_bytes(TRANSACTION_PAYLOAD_BYTES) @@ -203,14 +204,14 @@ impl CommandImplementation for SignEvmTransaction { let mut action_items = vec![]; let already_signed = signer_state - .get_scoped_bool(&construct_did.to_string(), SIGNATURE_APPROVED) + .get_scoped_bool(&construct_did.to_string(), SignerKey::SignatureApproved) .unwrap_or(false); if !already_signed { action_items.push( ReviewInputRequest::new("", &Value::integer(transaction.nonce().into())) .to_action_type() - .to_request(&instance_name, ACTION_ITEM_CHECK_NONCE) + .to_request(&instance_name, ActionItemKey::CheckNonce) .with_construct_did(&construct_did) .with_meta_description("Check transaction nonce"), ); @@ -230,7 +231,7 @@ impl CommandImplementation for SignEvmTransaction { action_items.push( ReviewInputRequest::new("", &Value::string(formatted_cost)) .to_action_type() - .to_request(&instance_name, ACTION_ITEM_CHECK_FEE) + .to_request(&instance_name, ActionItemKey::CheckFee) .with_meta_description("Check transaction cost (Wei)") .with_construct_did(&construct_did), ); @@ -280,7 +281,7 @@ impl CommandImplementation for SignEvmTransaction { .get_scoped_bool(&construct_did.to_string(), ALREADY_DEPLOYED) .unwrap_or(false); if let Some(tx_hash) = - signer_state.get_scoped_value(&construct_did.value().to_string(), TX_HASH) + signer_state.get_scoped_value(&construct_did.value().to_string(), SignerKey::TxHash) { let mut result = CommandExecutionResult::new(); if !already_deployed { @@ -292,7 +293,7 @@ impl CommandImplementation for SignEvmTransaction { ) })?; let tx_hash = EvmValue::tx_hash(tx_hash_bytes); - result.outputs.insert(TX_HASH.into(), tx_hash.clone()); + result.outputs.insert(SignerKey::TxHash.to_string(), tx_hash.clone()); } return return_synchronous_ok(signers, signer_state, result); } diff --git a/addons/evm/src/constants.rs b/addons/evm/src/constants.rs index c50b5a635..b040ce575 100644 --- a/addons/evm/src/constants.rs +++ b/addons/evm/src/constants.rs @@ -87,15 +87,6 @@ pub const DEFAULT_CREATE2_SALT: &str = pub const EMPTY_CREATE2_SALT: &str = "0x0000000000000000000000000000000000000000000000000000000000000000"; -// Actions items keys -pub const ACTION_ITEM_CHECK_BALANCE: &str = "check_balance"; -pub const ACTION_ITEM_CHECK_ADDRESS: &str = "check_address"; -pub const ACTION_ITEM_CHECK_NONCE: &str = "check_nonce"; -pub const ACTION_ITEM_CHECK_FEE: &str = "check_fee"; -pub const ACTION_ITEM_PROVIDE_PUBLIC_KEY: &str = "provide_public_key"; -pub const ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION: &str = "provide_signed_transaction"; -pub const ACTION_ITEM_SEND_TRANSACTION: &str = "send_transaction"; -pub const ACTION_OPEN_MODAL: &str = "open_modal"; // Default contracts pub const DEFAULT_CREATE2_FACTORY_ADDRESS: &str = "0x4e59b44847b379578588920cA78FbF26c0B4956C"; diff --git a/addons/evm/src/functions.rs b/addons/evm/src/functions.rs index bd10c46eb..955f5cb30 100644 --- a/addons/evm/src/functions.rs +++ b/addons/evm/src/functions.rs @@ -17,6 +17,7 @@ use txtx_addon_kit::{ types::{ diagnostics::Diagnostic, functions::{FunctionImplementation, FunctionSpecification}, + namespace::Namespace, types::{ObjectType, Type, Value}, AuthorizationContext, }, @@ -44,12 +45,12 @@ use crate::{ }; const INFURA_API_KEY: &str = ""; -pub fn arg_checker(fn_spec: &FunctionSpecification, args: &Vec) -> Result<(), Diagnostic> { - let checker = arg_checker_with_ctx(NAMESPACE.to_string()); +pub fn arg_checker(fn_spec: &FunctionSpecification, args: &[Value]) -> Result<(), Diagnostic> { + let checker = arg_checker_with_ctx(Namespace::from(NAMESPACE)); checker(fn_spec, args) } pub fn to_diag(fn_spec: &FunctionSpecification, e: String) -> Diagnostic { - let error_fn = fn_diag_with_ctx(NAMESPACE.to_string()); + let error_fn = fn_diag_with_ctx(Namespace::from(NAMESPACE)); error_fn(fn_spec, e) } @@ -434,7 +435,7 @@ impl FunctionImplementation for EncodeEvmAddress { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -442,7 +443,7 @@ impl FunctionImplementation for EncodeEvmAddress { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let entry = match args.get(0) { Some(Value::String(val)) => val.clone(), @@ -465,7 +466,7 @@ impl FunctionImplementation for EvmZeroAddress { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -473,7 +474,7 @@ impl FunctionImplementation for EvmZeroAddress { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; Ok(EvmValue::address(&Address::ZERO)) @@ -486,7 +487,7 @@ impl FunctionImplementation for AbiEncode { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -494,7 +495,7 @@ impl FunctionImplementation for AbiEncode { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let array = args.get(0).unwrap().as_array().unwrap(); @@ -521,7 +522,7 @@ impl FunctionImplementation for EncodeToAbiType { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -529,7 +530,7 @@ impl FunctionImplementation for EncodeToAbiType { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let value = args.get(0).unwrap(); @@ -583,7 +584,7 @@ impl FunctionImplementation for EncodeEvmBytes32 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -591,7 +592,7 @@ impl FunctionImplementation for EncodeEvmBytes32 { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let bytes = match args.get(0) { Some(Value::String(val)) => B256::from_hex(&val).map_err(|e| { @@ -619,7 +620,7 @@ impl FunctionImplementation for EncodeEvmBytes { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -627,7 +628,7 @@ impl FunctionImplementation for EncodeEvmBytes { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let bytes = match args.get(0).unwrap() { @@ -650,7 +651,7 @@ impl FunctionImplementation for EncodeEvmUint32 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -658,7 +659,7 @@ impl FunctionImplementation for EncodeEvmUint32 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let value = args.get(0).unwrap().as_integer().unwrap(); @@ -673,7 +674,7 @@ impl FunctionImplementation for EncodeEvmUint256 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -681,7 +682,7 @@ impl FunctionImplementation for EncodeEvmUint256 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let value = args.get(0).unwrap(); @@ -707,7 +708,7 @@ impl FunctionImplementation for EncodeEvmUint8 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -715,7 +716,7 @@ impl FunctionImplementation for EncodeEvmUint8 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let value = args.get(0).unwrap().as_integer().unwrap(); @@ -730,7 +731,7 @@ impl FunctionImplementation for EncodeEvmChain { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -738,7 +739,7 @@ impl FunctionImplementation for EncodeEvmChain { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let chain = match args.get(0) { Some(Value::String(chain_name)) => { @@ -790,7 +791,7 @@ impl FunctionImplementation for GetFoundryDeploymentArtifacts { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -798,7 +799,7 @@ impl FunctionImplementation for GetFoundryDeploymentArtifacts { fn run( fn_spec: &FunctionSpecification, auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let contract_name = args.get(0).unwrap().as_string().unwrap(); @@ -895,7 +896,7 @@ impl FunctionImplementation for GetHardhatDeploymentArtifacts { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -903,7 +904,7 @@ impl FunctionImplementation for GetHardhatDeploymentArtifacts { fn run( fn_spec: &FunctionSpecification, auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let contract_name = args.get(0).unwrap().as_string().unwrap(); @@ -983,7 +984,7 @@ impl FunctionImplementation for CreateInitCode { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -991,7 +992,7 @@ impl FunctionImplementation for CreateInitCode { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let prefix = "command 'evm::create_init_code'"; @@ -1048,7 +1049,7 @@ impl FunctionImplementation for EncodeFunctionCall { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -1056,7 +1057,7 @@ impl FunctionImplementation for EncodeFunctionCall { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let function_name = args.get(0).unwrap().as_string().unwrap(); @@ -1101,7 +1102,7 @@ impl FunctionImplementation for GenerateCreate2Address { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -1109,7 +1110,7 @@ impl FunctionImplementation for GenerateCreate2Address { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let prefix = "command 'evm::create2'"; let salt = match args.get(0) { diff --git a/addons/evm/src/signers/common.rs b/addons/evm/src/signers/common.rs index 6d2ee4910..7f7596ec4 100644 --- a/addons/evm/src/signers/common.rs +++ b/addons/evm/src/signers/common.rs @@ -9,16 +9,15 @@ use txtx_addon_kit::{ stores::ValueStore, types::Value, ConstructDid, + namespace::Namespace, }, }; use crate::{ - constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_CHECK_BALANCE, ACTION_ITEM_PROVIDE_PUBLIC_KEY, - DEFAULT_MESSAGE, NAMESPACE, - }, + constants::{DEFAULT_MESSAGE, NAMESPACE}, rpc::EvmRpc, }; +use txtx_addon_kit::constants::ActionItemKey; pub async fn get_additional_actions_for_address( expected_address: &Option
, @@ -52,9 +51,9 @@ pub async fn get_additional_actions_for_address( check_expectation_action_uuid: Some(signer_did.clone()), message: DEFAULT_MESSAGE.to_string(), network_id: chain_id.to_string(), - namespace: NAMESPACE.to_string(), + namespace: Namespace::from(NAMESPACE), }) - .to_request(instance_name, ACTION_ITEM_PROVIDE_PUBLIC_KEY) + .to_request(instance_name, ActionItemKey::ProvidePublicKey) .with_construct_did(signer_did) .with_some_description(description) .with_meta_description(&format!("Connect wallet '{instance_name}'")) @@ -67,7 +66,7 @@ pub async fn get_additional_actions_for_address( action_items.push( ReviewInputRequest::new("", &Value::string(expected_address.to_string())) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_ADDRESS) + .to_request(instance_name, ActionItemKey::CheckAddress) .with_construct_did(signer_did) .with_meta_description(&format!("Check '{}' expected address", instance_name)) .with_some_description(Some("".into())), @@ -91,7 +90,7 @@ pub async fn get_additional_actions_for_address( }; let check_balance = ReviewInputRequest::new("", &value) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_BALANCE) + .to_request(instance_name, ActionItemKey::CheckBalance) .with_construct_did(signer_did) .with_meta_description(&format!("Check '{}' signer balance", instance_name)) .with_some_description(Some("".into())) @@ -102,7 +101,7 @@ pub async fn get_additional_actions_for_address( if do_request_balance { let check_balance = ReviewInputRequest::new("", &Value::string("N/A".to_string())) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_BALANCE) + .to_request(instance_name, ActionItemKey::CheckBalance) .with_construct_did(signer_did) .with_meta_description(&format!("Check '{}' signer balance", instance_name)) .with_some_description(Some("".into())); diff --git a/addons/evm/src/signers/secret_key.rs b/addons/evm/src/signers/secret_key.rs index 6313a9203..cef189736 100644 --- a/addons/evm/src/signers/secret_key.rs +++ b/addons/evm/src/signers/secret_key.rs @@ -3,7 +3,7 @@ use alloy::primitives::Address; use alloy_rpc_types::TransactionRequest; use std::collections::HashMap; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::SIGNATURE_APPROVED; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::frontend::{ ActionItemStatus, ProvideSignedTransactionRequest, ReviewInputRequest, @@ -27,10 +27,10 @@ use txtx_addon_kit::types::{ use crate::codec::crypto::field_bytes_to_secret_key_signer; use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, CHAIN_ID, - FORMATTED_TRANSACTION, NAMESPACE, RPC_API_URL, SECRET_KEY_WALLET_UNSIGNED_TRANSACTION_BYTES, + CHAIN_ID, FORMATTED_TRANSACTION, NAMESPACE, RPC_API_URL, SECRET_KEY_WALLET_UNSIGNED_TRANSACTION_BYTES, TX_HASH, }; +use txtx_addon_kit::constants::ActionItemKey; use crate::rpc::EvmWalletRpc; use crate::typing::EvmValue; use txtx_addon_kit::types::signers::return_synchronous_actions; @@ -128,7 +128,7 @@ impl SignerImplementation for EvmSecretKeySigner { _is_balance_check_required: bool, _is_public_key_required: bool, ) -> SignerActionsFutureResult { - use txtx_addon_kit::constants::DESCRIPTION; + use txtx_addon_kit::constants::DocumentationKey; use crate::{ codec::crypto::{mnemonic_to_secret_key_signer, secret_key_to_secret_key_signer}, @@ -140,7 +140,7 @@ impl SignerImplementation for EvmSecretKeySigner { if signer_state.get_value(PUBLIC_KEYS).is_some() { return return_synchronous_actions(Ok((signers, signer_state, actions))); } - let description = values.get_string(DESCRIPTION).map(|d| d.to_string()); + let description = values.get_string(DocumentationKey::Description).map(|d| d.to_string()); let markdown = values .get_markdown(auth_ctx) .map_err(|d| (signers.clone(), signer_state.clone(), d))?; @@ -175,7 +175,7 @@ impl SignerImplementation for EvmSecretKeySigner { None, vec![ReviewInputRequest::new("", &Value::string(expected_address.to_string())) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_ADDRESS) + .to_request(instance_name, ActionItemKey::CheckAddress) .with_construct_did(construct_did) .with_some_description(description.clone()) .with_meta_description(&format!("Check {} expected address", instance_name)) @@ -228,7 +228,7 @@ impl SignerImplementation for EvmSecretKeySigner { ) -> Result { let actions = if supervision_context.review_input_values { let construct_did_str = &construct_did.to_string(); - if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SIGNATURE_APPROVED) { + if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SignerKey::SignatureApproved) { return Ok((signers, signer_state, Actions::none())); } @@ -251,7 +251,7 @@ impl SignerImplementation for EvmSecretKeySigner { .only_approval_needed() .formatted_payload(formatted_payload) .to_action_type() - .to_request(title, ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION) + .to_request(title, ActionItemKey::ProvideSignedTransaction) .with_construct_did(construct_did) .with_some_description(description.clone()) .with_some_meta_description(meta_description.clone()) @@ -326,7 +326,7 @@ impl SignerImplementation for EvmSecretKeySigner { (signers.clone(), signer_state.clone(), diagnosed_error!("{}", e.to_string())) })?; - result.outputs.insert(TX_HASH.to_string(), EvmValue::tx_hash(tx_hash.to_vec())); + result.outputs.insert(SignerKey::TxHash.to_string(), EvmValue::tx_hash(tx_hash.to_vec())); Ok((signers, signer_state, result)) }; diff --git a/addons/evm/src/signers/web_wallet.rs b/addons/evm/src/signers/web_wallet.rs index fabc69763..95baa8705 100644 --- a/addons/evm/src/signers/web_wallet.rs +++ b/addons/evm/src/signers/web_wallet.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::TX_HASH; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::frontend::{ ActionItemRequestUpdate, ActionItemStatus, Actions, BlockEvent, ReviewInputRequest, @@ -22,12 +22,12 @@ use txtx_addon_kit::types::{ use txtx_addon_kit::types::{AuthorizationContext, ConstructDid}; use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_PROVIDE_PUBLIC_KEY, ACTION_ITEM_SEND_TRANSACTION, ALREADY_DEPLOYED, CHAIN_ID, CHECKED_ADDRESS, CHECKED_COST_PROVISION, CHECKED_PUBLIC_KEY, CONTRACT_ADDRESS, EXPECTED_ADDRESS, FETCHED_BALANCE, FETCHED_NONCE, FORMATTED_TRANSACTION, NAMESPACE, PUBLIC_KEYS, REQUESTED_STARTUP_DATA, RPC_API_URL, WEB_WALLET_UNSIGNED_TRANSACTION_BYTES, }; +use txtx_addon_kit::constants::ActionItemKey; lazy_static! { pub static ref EVM_WEB_WALLET: SignerSpecification = { @@ -108,7 +108,7 @@ impl SignerImplementation for EvmWebWallet { is_balance_check_required: bool, is_public_key_required: bool, ) -> SignerActionsFutureResult { - use txtx_addon_kit::constants::{DESCRIPTION, PROVIDE_PUBLIC_KEY_ACTION_RESULT}; + use txtx_addon_kit::constants::{DocumentationKey, SignerKey}; use crate::{ codec::{ @@ -150,13 +150,13 @@ impl SignerImplementation for EvmWebWallet { .get_expected_string(RPC_API_URL) .map_err(|e| (signers.clone(), signer_state.clone(), e))? .to_owned(); - let description = values.get_string(DESCRIPTION).map(|d| d.to_string()); + let description = values.get_string(DocumentationKey::Description).map(|d| d.to_string()); let markdown = values .get_markdown(auth_ctx) .map_err(|d| (signers.clone(), signer_state.clone(), d))?; if let Ok(ref signed_message_hex) = - values.get_expected_string(PROVIDE_PUBLIC_KEY_ACTION_RESULT) + values.get_expected_string(ActionItemKey::ProvidePublicKey) { let public_key_bytes = public_key_from_signed_message(&DEFAULT_MESSAGE, signed_message_hex).map_err( @@ -180,7 +180,7 @@ impl SignerImplementation for EvmWebWallet { } else { let update = ActionItemRequestUpdate::from_context( &signer_did, - ACTION_ITEM_CHECK_ADDRESS, + ActionItemKey::CheckAddress, ) .set_status(status_update.clone()); actions.push_action_item_update(update); @@ -195,7 +195,7 @@ impl SignerImplementation for EvmWebWallet { signer_state.insert("signer_address", Value::string(evm_address.to_string())); } let update = - ActionItemRequestUpdate::from_context(&signer_did, ACTION_ITEM_PROVIDE_PUBLIC_KEY) + ActionItemRequestUpdate::from_context(&signer_did, ActionItemKey::ProvidePublicKey) .set_status(status_update); actions.push_action_item_update(update); @@ -280,7 +280,7 @@ impl SignerImplementation for EvmWebWallet { _auth_ctx: &AuthorizationContext, ) -> Result { let construct_did_str = &construct_did.to_string(); - if let Some(_) = signer_state.get_scoped_value(&construct_did_str, TX_HASH) { + if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SignerKey::TxHash) { return Ok((signers, signer_state, Actions::none())); } @@ -290,7 +290,7 @@ impl SignerImplementation for EvmWebWallet { let actions = if already_deployed { // the tx hash won't actually be used in the path where the contract is already deployed, but we need // this value set in order to prevent re-adding the same action item every time we get to this fn - signer_state.insert_scoped_value(&construct_did_str, TX_HASH, Value::null()); + signer_state.insert_scoped_value(&construct_did_str, SignerKey::TxHash, Value::null()); let contract_address = signer_state .get_scoped_value(&construct_did.to_string(), CONTRACT_ADDRESS) @@ -299,7 +299,7 @@ impl SignerImplementation for EvmWebWallet { let request = ReviewInputRequest::new("", contract_address) .force_execution() .to_action_type() - .to_request(title, "action_item_review_deployed_contract") + .to_request(title, ActionItemKey::ReviewDeployedContract) .with_construct_did(construct_did) .with_some_description(description.clone()) .with_some_meta_description(meta_description.clone()); @@ -345,7 +345,7 @@ impl SignerImplementation for EvmWebWallet { .check_expectation_action_uuid(construct_did) .formatted_payload(formatted_payload) .to_action_type() - .to_request(title, ACTION_ITEM_SEND_TRANSACTION) + .to_request(title, ActionItemKey::SendTransaction) .with_construct_did(construct_did) .with_some_description(description.clone()) .with_some_meta_description(meta_description.clone()) @@ -374,8 +374,8 @@ impl SignerImplementation for EvmWebWallet { ) -> SignerSignFutureResult { let mut result = CommandExecutionResult::new(); let key = construct_did.to_string(); - if let Some(signed_transaction) = signer_state.get_scoped_value(&key, TX_HASH) { - result.outputs.insert(TX_HASH.into(), signed_transaction.clone()); + if let Some(signed_transaction) = signer_state.get_scoped_value(&key, SignerKey::TxHash) { + result.outputs.insert(SignerKey::TxHash.to_string(), signed_transaction.clone()); } return_synchronous_result(Ok((signers, signer_state, result))) diff --git a/addons/stacks/src/commands/actions/broadcast_transaction.rs b/addons/stacks/src/commands/actions/broadcast_transaction.rs index 41c9abaf3..94e91bf65 100644 --- a/addons/stacks/src/commands/actions/broadcast_transaction.rs +++ b/addons/stacks/src/commands/actions/broadcast_transaction.rs @@ -164,7 +164,7 @@ impl CommandImplementation for BroadcastStacksTransaction { _cloud_service_context: &Option, ) -> CommandExecutionFutureResult { use txtx_addon_kit::{ - constants::SIGNED_TRANSACTION_BYTES, types::frontend::ProgressBarStatusColor, + constants::SignerKey::SignedTransactionBytes, types::frontend::ProgressBarStatusColor, }; use crate::{ @@ -187,7 +187,7 @@ impl CommandImplementation for BroadcastStacksTransaction { let network_id = args.get_expected_string(NETWORK_ID)?.to_owned(); - let transaction_bytes = args.get_expected_buffer_bytes(SIGNED_TRANSACTION_BYTES)?; + let transaction_bytes = args.get_expected_buffer_bytes(SignerKey::SignedTransactionBytes)?; let rpc_api_url = args.get_expected_string(RPC_API_URL)?.to_owned(); let rpc_api_auth_token = diff --git a/addons/stacks/src/commands/actions/call_contract.rs b/addons/stacks/src/commands/actions/call_contract.rs index b1b47013d..d65c68595 100644 --- a/addons/stacks/src/commands/actions/call_contract.rs +++ b/addons/stacks/src/commands/actions/call_contract.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::SIGNED_TRANSACTION_BYTES; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::types::cloud_interface::CloudServiceContext; use txtx_addon_kit::types::signers::SignerActionsFutureResult; use txtx_addon_kit::types::stores::ValueStore; @@ -323,8 +323,8 @@ impl CommandImplementation for SendContractCall { }; args.insert( - SIGNED_TRANSACTION_BYTES, - res_signing.outputs.get(SIGNED_TRANSACTION_BYTES).unwrap().clone(), + SignerKey::SignedTransactionBytes, + res_signing.outputs.get(SignerKey::SignedTransactionBytes.as_ref()).unwrap().clone(), ); let mut res = match BroadcastStacksTransaction::run_execution( &construct_did, diff --git a/addons/stacks/src/commands/actions/deploy_contract.rs b/addons/stacks/src/commands/actions/deploy_contract.rs index 3b6cf72d8..d016ab03e 100644 --- a/addons/stacks/src/commands/actions/deploy_contract.rs +++ b/addons/stacks/src/commands/actions/deploy_contract.rs @@ -10,7 +10,7 @@ use clarity_repl::repl::{ use std::collections::{BTreeMap, HashMap}; use std::future; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::SIGNED_TRANSACTION_BYTES; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::types::cloud_interface::CloudServiceContext; use txtx_addon_kit::types::commands::{ CommandInputsEvaluationResult, InputsPostProcessingFutureResult, @@ -566,14 +566,14 @@ impl CommandImplementation for StacksDeployContract { Err(err) => return Err(err), }; - let signed_transaction = res_signing.outputs.get(SIGNED_TRANSACTION_BYTES).unwrap(); + let signed_transaction = res_signing.outputs.get(SignerKey::SignedTransactionBytes.as_ref()).unwrap(); let signed_transaction_bytes = signed_transaction.clone().expect_buffer_bytes(); let transaction = StacksTransaction::consensus_deserialize(&mut &signed_transaction_bytes[..]) .unwrap(); let sender_address = transaction.origin_address().to_string(); - values.insert(SIGNED_TRANSACTION_BYTES, signed_transaction.clone()); + values.insert(SignerKey::SignedTransactionBytes, signed_transaction.clone()); let mut res = match BroadcastStacksTransaction::run_execution( &construct_did, diff --git a/addons/stacks/src/commands/actions/send_stx.rs b/addons/stacks/src/commands/actions/send_stx.rs index c0f315155..a04fe8697 100644 --- a/addons/stacks/src/commands/actions/send_stx.rs +++ b/addons/stacks/src/commands/actions/send_stx.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::SIGNED_TRANSACTION_BYTES; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::types::cloud_interface::CloudServiceContext; use txtx_addon_kit::types::signers::SignerActionsFutureResult; use txtx_addon_kit::types::stores::ValueStore; @@ -228,8 +228,8 @@ impl CommandImplementation for SendStxTransfer { }; values.insert( - SIGNED_TRANSACTION_BYTES, - res_signing.outputs.get(SIGNED_TRANSACTION_BYTES).unwrap().clone(), + SignerKey::SignedTransactionBytes, + res_signing.outputs.get(SignerKey::SignedTransactionBytes.as_ref()).unwrap().clone(), ); let mut res = match BroadcastStacksTransaction::run_execution( &construct_did, diff --git a/addons/stacks/src/commands/actions/sign_transaction.rs b/addons/stacks/src/commands/actions/sign_transaction.rs index d54b083c0..c3ec3df4e 100644 --- a/addons/stacks/src/commands/actions/sign_transaction.rs +++ b/addons/stacks/src/commands/actions/sign_transaction.rs @@ -10,7 +10,7 @@ use clarity::util::secp256k1::MessageSignature; use clarity::vm::{ClarityName, ContractName}; use clarity_repl::clarity::address::AddressHashMode; use std::collections::HashMap; -use txtx_addon_kit::constants::SIGNED_TRANSACTION_BYTES; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::types::commands::{ CommandExecutionResult, CommandImplementation, PreCommandSpecification, }; @@ -143,7 +143,7 @@ impl CommandImplementation for SignStacksTransaction { signers_instances: &HashMap, mut signers: SignersState, ) -> SignerActionsFutureResult { - use txtx_addon_kit::constants::SIGNATURE_APPROVED; + use txtx_addon_kit::constants::SignerKey; use crate::constants::{ ACTION_ITEM_CHECK_FEE, ACTION_ITEM_CHECK_NONCE, FORMATTED_TRANSACTION, @@ -162,10 +162,10 @@ impl CommandImplementation for SignStacksTransaction { let mut actions = Actions::none(); let mut signer_state = signers.pop_signer_state(&signer_did).unwrap(); if signer_state - .get_scoped_value(&construct_did.to_string(), SIGNED_TRANSACTION_BYTES) + .get_scoped_value(&construct_did.to_string(), SignerKey::SignedTransactionBytes) .is_some() || signer_state - .get_scoped_value(&construct_did.to_string(), SIGNATURE_APPROVED) + .get_scoped_value(&construct_did.to_string(), SignerKey::SignatureApproved) .is_some() { return Ok((signers, signer_state, Actions::none())); @@ -280,11 +280,11 @@ impl CommandImplementation for SignStacksTransaction { let signer_did = get_signer_did(args).unwrap(); let signer_state = signers.pop_signer_state(&signer_did).unwrap(); - if let Ok(signed_transaction_bytes) = args.get_expected_value(SIGNED_TRANSACTION_BYTES) { + if let Ok(signed_transaction_bytes) = args.get_expected_value(SignerKey::SignedTransactionBytes) { let mut result = CommandExecutionResult::new(); result .outputs - .insert(SIGNED_TRANSACTION_BYTES.into(), signed_transaction_bytes.clone()); + .insert(SignerKey::SignedTransactionBytes, signed_transaction_bytes.clone()); return return_synchronous_ok(signers, signer_state, result); } diff --git a/addons/stacks/src/constants.rs b/addons/stacks/src/constants.rs index 8cc4036f8..4e156e83d 100644 --- a/addons/stacks/src/constants.rs +++ b/addons/stacks/src/constants.rs @@ -33,10 +33,4 @@ pub const DEFAULT_MESSAGE: &str = pub const DEFAULT_CLARINET_MANIFEST_PATH: &str = "Clarinet.toml"; // Actions items keys -pub const ACTION_ITEM_CHECK_BALANCE: &str = "check_balance"; -pub const ACTION_ITEM_CHECK_ADDRESS: &str = "check_address"; -pub const ACTION_ITEM_CHECK_NONCE: &str = "check_nonce"; -pub const ACTION_ITEM_CHECK_FEE: &str = "check_fee"; -pub const ACTION_ITEM_PROVIDE_PUBLIC_KEY: &str = "provide_public_key"; -pub const ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION: &str = "provide_signed_transaction"; pub const ACTION_OPEN_MODAL: &str = "open_modal"; diff --git a/addons/stacks/src/signers/mod.rs b/addons/stacks/src/signers/mod.rs index 8d047ecec..5396b1ab1 100644 --- a/addons/stacks/src/signers/mod.rs +++ b/addons/stacks/src/signers/mod.rs @@ -19,7 +19,7 @@ use web_wallet::STACKS_WEB_WALLET; use crate::{ constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_CHECK_BALANCE, ACTION_ITEM_PROVIDE_PUBLIC_KEY, + ActionItemKey::CheckAddress, ActionItemKey::CheckBalance, ActionItemKey::ProvidePublicKey, DEFAULT_MESSAGE, }, rpc::StacksRpc, @@ -59,7 +59,7 @@ pub async fn get_addition_actions_for_address( network_id: network_id.into(), namespace: "stacks".to_string(), }), - ACTION_ITEM_PROVIDE_PUBLIC_KEY, + ActionItemKey::ProvidePublicKey, )); } @@ -72,7 +72,7 @@ pub async fn get_addition_actions_for_address( ActionItemStatus::Todo, ReviewInputRequest::new("", &Value::string(expected_address.to_owned())) .to_action_type(), - ACTION_ITEM_CHECK_ADDRESS, + ActionItemKey::CheckAddress, )) } if do_request_balance { @@ -95,7 +95,7 @@ pub async fn get_addition_actions_for_address( None, action_status, ReviewInputRequest::new("", &value).to_action_type(), - ACTION_ITEM_CHECK_BALANCE, + ActionItemKey::CheckBalance, ); action_items.push(check_balance); } @@ -107,7 +107,7 @@ pub async fn get_addition_actions_for_address( None, ActionItemStatus::Todo, ReviewInputRequest::new("", &Value::string("N/A".to_string())).to_action_type(), - ACTION_ITEM_CHECK_BALANCE, + ActionItemKey::CheckBalance, ); action_items.push(check_balance); } diff --git a/addons/stacks/src/signers/multisig.rs b/addons/stacks/src/signers/multisig.rs index 3229d45a5..56527eb22 100644 --- a/addons/stacks/src/signers/multisig.rs +++ b/addons/stacks/src/signers/multisig.rs @@ -3,7 +3,7 @@ use clarity::types::chainstate::StacksAddress; use clarity::util::secp256k1::Secp256k1PublicKey; use clarity::{codec::StacksMessageCodec, util::secp256k1::MessageSignature}; use std::collections::{HashMap, VecDeque}; -use txtx_addon_kit::constants::{SIGNATURE_SKIPPABLE, SIGNED_TRANSACTION_BYTES}; +use txtx_addon_kit::constants::{SignerKey}; use txtx_addon_kit::types::commands::{CommandExecutionResult, CommandSpecification}; use txtx_addon_kit::types::types::RunbookSupervisionContext; @@ -33,7 +33,7 @@ use txtx_addon_kit::types::{ use txtx_addon_kit::types::{ConstructDid, Did}; use crate::constants::{ - ACTION_ITEM_CHECK_BALANCE, ACTION_ITEM_PROVIDE_PUBLIC_KEY, ACTION_OPEN_MODAL, CHECKED_ADDRESS, + ActionItemKey::CheckBalance, ActionItemKey::ProvidePublicKey, ACTION_OPEN_MODAL, CHECKED_ADDRESS, CHECKED_PUBLIC_KEY, FORMATTED_TRANSACTION, IS_SIGNABLE, NETWORK_ID, PUBLIC_KEYS, REQUIRED_SIGNATURE_COUNT, RPC_API_URL, }; @@ -176,7 +176,7 @@ impl SignerImplementation for StacksConnect { modal_uuid: modal.uuid.clone(), title: "OPEN ASSISTANT".into(), }), - ACTION_ITEM_PROVIDE_PUBLIC_KEY, + ActionItemKey::ProvidePublicKey, )]; let ref mut res = get_addition_actions_for_address( &expected_address, @@ -288,7 +288,7 @@ impl SignerImplementation for StacksConnect { actions.push_action_item_update( ActionItemRequestUpdate::from_context( &root_construct_did, - ACTION_ITEM_CHECK_BALANCE, + ActionItemKey::CheckBalance, ) .set_type(ReviewInputRequest::new("", &value).to_action_type()) .set_status(status_update), @@ -297,7 +297,7 @@ impl SignerImplementation for StacksConnect { actions.push_action_item_update( ActionItemRequestUpdate::from_context( &root_construct_did, - ACTION_ITEM_PROVIDE_PUBLIC_KEY, + ActionItemKey::ProvidePublicKey, ) .set_status(ActionItemStatus::Success(Some(stacks_address))), ); @@ -332,7 +332,7 @@ impl SignerImplementation for StacksConnect { signers_instances: &HashMap, progress_tx: &channel::Sender, ) -> SignerActivateFutureResult { - use txtx_addon_kit::constants::PROVIDE_PUBLIC_KEY_ACTION_RESULT; + use txtx_addon_kit::constants::SignerKey; let values = values.clone(); let public_key = signer_state @@ -387,7 +387,7 @@ impl SignerImplementation for StacksConnect { signer_state.insert("signers", Value::array(signers_uuids.clone())); result.outputs.insert("signers".into(), Value::array(signers_uuids)); - result.outputs.insert(PROVIDE_PUBLIC_KEY_ACTION_RESULT.into(), public_key.clone()); + result.outputs.insert(ActionItemKey::ProvidePublicKey.to_string(), public_key.clone()); result.outputs.insert("address".into(), address.clone()); Ok((signers, signer_state, result)) @@ -470,7 +470,7 @@ impl SignerImplementation for StacksConnect { signer_state.insert_scoped_value( &origin_uuid.value().to_string(), - SIGNED_TRANSACTION_BYTES, + SignerKey::SignedTransactionBytes, Value::string(txtx_addon_kit::hex::encode(signed_tx_bytes)), ); // we know that there are no pending actions because we're in all_signed, @@ -552,12 +552,12 @@ impl SignerImplementation for StacksConnect { use crate::typing::StacksValue; if let Some(signed_transaction_bytes) = signer_state - .get_scoped_value(&origin_uuid.value().to_string(), SIGNED_TRANSACTION_BYTES) + .get_scoped_value(&origin_uuid.value().to_string(), SignerKey::SignedTransactionBytes) { let mut result = CommandExecutionResult::new(); result .outputs - .insert(SIGNED_TRANSACTION_BYTES.into(), signed_transaction_bytes.clone()); + .insert(SignerKey::SignedTransactionBytes, signed_transaction_bytes.clone()); return Ok(Box::pin(future::ready(Ok((signers, signer_state, result))))); } @@ -635,7 +635,7 @@ impl SignerImplementation for StacksConnect { transaction.verify().unwrap(); - result.outputs.insert(SIGNED_TRANSACTION_BYTES.into(), transaction_bytes); + result.outputs.insert(SignerKey::SignedTransactionBytes.to_string(), transaction_bytes); Ok((signers, signer_state, result)) }; @@ -702,7 +702,7 @@ fn generate_ordered_multisig_payloads( let this_signer_state = signers.get_signer_state(&this_signer_uuid).unwrap(); let stored_signature = - this_signer_state.get_scoped_value(origin_uuid, SIGNED_TRANSACTION_BYTES); + this_signer_state.get_scoped_value(origin_uuid, SignerKey::SignedTransactionBytes); // along the way, track how many signers have completed signatures signature_count += stored_signature // if we have a signature for this signer, check if it's null. if null, this signer was skipped so don't add it to our count @@ -806,7 +806,7 @@ fn extract_auth_field_from_signer_state( multisig_signer_idx: usize, origin_uuid: &str, ) -> Result { - let field = match signer_state.get_scoped_value(origin_uuid, SIGNED_TRANSACTION_BYTES) { + let field = match signer_state.get_scoped_value(origin_uuid, SignerKey::SignedTransactionBytes) { Some(&Value::Null) | None => { let stacks_public_key = expect_stacks_public_key(signer_state, CHECKED_PUBLIC_KEY)?; TransactionAuthField::PublicKey(stacks_public_key) @@ -857,12 +857,12 @@ fn set_signer_states( // if this signer has a signature stored and it is null, the user skipped this signature let this_signer_skipped = signing_command_state - .get_scoped_value(origin_uuid, SIGNED_TRANSACTION_BYTES) + .get_scoped_value(origin_uuid, SignerKey::SignedTransactionBytes) .and_then(|v| Some(v.as_null().is_some())) .unwrap_or(false); // if this signer has a signature stored and it _isn't_ null, we have a real signature and weren't skipped let this_signer_signed = signing_command_state - .get_scoped_value(origin_uuid, SIGNED_TRANSACTION_BYTES) + .get_scoped_value(origin_uuid, SignerKey::SignedTransactionBytes) .and_then(|v| Some(v.as_null().is_none())) .unwrap_or(false); @@ -870,7 +870,7 @@ fn set_signer_states( if this_signer_signed || this_signer_skipped { signing_command_state.insert_scoped_value( &origin_uuid, - SIGNATURE_SKIPPABLE, + SignerKey::SignatureSkippable, Value::bool(false), ); @@ -886,7 +886,7 @@ fn set_signer_states( let eligible_signers_after_this_signer = signer_count - next_signer_idx; signing_command_state.insert_scoped_value( &origin_uuid, - SIGNATURE_SKIPPABLE, + SignerKey::SignatureSkippable, Value::bool( previous_signer_action_completed && (eligible_signers_after_this_signer >= remaining_signatures_required), diff --git a/addons/stacks/src/signers/secret_key.rs b/addons/stacks/src/signers/secret_key.rs index be4079d9b..850c3ad53 100644 --- a/addons/stacks/src/signers/secret_key.rs +++ b/addons/stacks/src/signers/secret_key.rs @@ -4,7 +4,7 @@ use crate::codec::crypto::{compute_keypair, sign_message, sign_transaction}; use txtx_addon_kit::channel; use txtx_addon_kit::constants::{ - SIGNATURE_APPROVED, SIGNATURE_SKIPPABLE, SIGNED_MESSAGE_BYTES, SIGNED_TRANSACTION_BYTES, + SignerKey::SignatureApproved, SignerKey::SignatureSkippable, SIGNED_MESSAGE_BYTES, SignerKey::SignedTransactionBytes, }; use txtx_addon_kit::crypto::secret_key_from_bytes; use txtx_addon_kit::types::commands::CommandExecutionResult; @@ -26,7 +26,7 @@ use txtx_addon_kit::types::{ }; use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, CHECKED_ADDRESS, + ActionItemKey::CheckAddress, ActionItemKey::ProvideSignedTransaction, CHECKED_ADDRESS, FORMATTED_TRANSACTION, IS_SIGNABLE, MESSAGE_BYTES, }; use txtx_addon_kit::types::signers::return_synchronous_actions; @@ -179,7 +179,7 @@ impl SignerImplementation for StacksSecretKey { ActionItemStatus::Todo, ReviewInputRequest::new("", &Value::string(expected_address.to_string())) .to_action_type(), - ACTION_ITEM_CHECK_ADDRESS, + ActionItemKey::CheckAddress, )], ); } @@ -216,7 +216,7 @@ impl SignerImplementation for StacksSecretKey { ) -> Result { let actions = if supervision_context.review_input_values { let construct_did_str = &construct_did.to_string(); - if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SIGNATURE_APPROVED) { + if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SignerKey::SignatureApproved) { return Ok((signers, signer_state, Actions::none())); } @@ -234,7 +234,7 @@ impl SignerImplementation for StacksSecretKey { false => ActionItemStatus::Blocked, }; let skippable = signer_state - .get_scoped_value(&construct_did_str, SIGNATURE_SKIPPABLE) + .get_scoped_value(&construct_did_str, SignerKey::SignatureSkippable) .and_then(|v| v.as_bool()) .unwrap_or(false); @@ -257,7 +257,7 @@ impl SignerImplementation for StacksSecretKey { .only_approval_needed() .formatted_payload(formatted_payload) .to_action_type(), - ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, + ActionItemKey::ProvideSignedTransaction, ); Actions::append_item( request, @@ -303,7 +303,7 @@ impl SignerImplementation for StacksSecretKey { })?; result.outputs.insert( - SIGNED_TRANSACTION_BYTES.into(), + SignerKey::SignedTransactionBytes, StacksValue::transaction(signed_transaction_bytes), ); } else { diff --git a/addons/stacks/src/signers/web_wallet.rs b/addons/stacks/src/signers/web_wallet.rs index 8cd55bf04..15bdb4235 100644 --- a/addons/stacks/src/signers/web_wallet.rs +++ b/addons/stacks/src/signers/web_wallet.rs @@ -4,7 +4,7 @@ use clarity::address::AddressHashMode; use clarity::types::chainstate::StacksAddress; use clarity::util::secp256k1::Secp256k1PublicKey; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::{SIGNATURE_SKIPPABLE, SIGNED_TRANSACTION_BYTES}; +use txtx_addon_kit::constants::{SignerKey}; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::frontend::{ ActionItemRequest, ActionItemRequestUpdate, ActionItemStatus, Actions, BlockEvent, @@ -25,8 +25,8 @@ use txtx_addon_kit::types::{ }; use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_PROVIDE_PUBLIC_KEY, - ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, CHECKED_ADDRESS, CHECKED_COST_PROVISION, + ActionItemKey::CheckAddress, ActionItemKey::ProvidePublicKey, + ActionItemKey::ProvideSignedTransaction, CHECKED_ADDRESS, CHECKED_COST_PROVISION, CHECKED_PUBLIC_KEY, EXPECTED_ADDRESS, FETCHED_BALANCE, FETCHED_NONCE, FORMATTED_TRANSACTION, IS_SIGNABLE, NETWORK_ID, PUBLIC_KEYS, REQUESTED_STARTUP_DATA, RPC_API_URL, }; @@ -98,7 +98,7 @@ impl SignerImplementation for StacksWebWallet { is_balance_check_required: bool, is_public_key_required: bool, ) -> SignerActionsFutureResult { - use txtx_addon_kit::constants::PROVIDE_PUBLIC_KEY_ACTION_RESULT; + use txtx_addon_kit::constants::SignerKey; use crate::constants::RPC_API_AUTH_TOKEN; @@ -135,7 +135,7 @@ impl SignerImplementation for StacksWebWallet { .to_owned(); if let Ok(public_key_bytes) = - values.get_expected_buffer_bytes(PROVIDE_PUBLIC_KEY_ACTION_RESULT) + values.get_expected_buffer_bytes(ActionItemKey::ProvidePublicKey) { let version = if network_id.eq("mainnet") { clarity_repl::clarity::address::C32_ADDRESS_VERSION_MAINNET_SINGLESIG @@ -169,7 +169,7 @@ impl SignerImplementation for StacksWebWallet { } else { let update = ActionItemRequestUpdate::from_context( &signer_did, - ACTION_ITEM_CHECK_ADDRESS, + ActionItemKey::CheckAddress, ) .set_status(status_update.clone()); actions.push_action_item_update(update); @@ -183,7 +183,7 @@ impl SignerImplementation for StacksWebWallet { signer_state.insert(CHECKED_ADDRESS, Value::string(stx_address)); } let update = - ActionItemRequestUpdate::from_context(&signer_did, ACTION_ITEM_PROVIDE_PUBLIC_KEY) + ActionItemRequestUpdate::from_context(&signer_did, ActionItemKey::ProvidePublicKey) .set_status(status_update); actions.push_action_item_update(update); @@ -272,7 +272,7 @@ impl SignerImplementation for StacksWebWallet { _supervision_context: &RunbookSupervisionContext, ) -> Result { let construct_did_str = &construct_did.to_string(); - if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SIGNED_TRANSACTION_BYTES) + if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SignerKey::SignedTransactionBytes) { return Ok((signers, signer_state, Actions::none())); } @@ -292,7 +292,7 @@ impl SignerImplementation for StacksWebWallet { }; let skippable = signer_state - .get_scoped_value(&construct_did_str, SIGNATURE_SKIPPABLE) + .get_scoped_value(&construct_did_str, SignerKey::SignatureSkippable) .and_then(|v| v.as_bool()) .unwrap_or(false); let expected_signer_address = signer_state.get_string(CHECKED_ADDRESS); @@ -316,7 +316,7 @@ impl SignerImplementation for StacksWebWallet { .check_expectation_action_uuid(construct_did) .formatted_payload(formatted_payload) .to_action_type(), - ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, + ActionItemKey::ProvideSignedTransaction, ); Ok(( signers, @@ -342,9 +342,9 @@ impl SignerImplementation for StacksWebWallet { let mut result = CommandExecutionResult::new(); let key = construct_did.to_string(); if let Some(signed_transaction) = - signer_state.get_scoped_value(&key, SIGNED_TRANSACTION_BYTES) + signer_state.get_scoped_value(&key, SignerKey::SignedTransactionBytes) { - result.outputs.insert(SIGNED_TRANSACTION_BYTES.into(), signed_transaction.clone()); + result.outputs.insert(SignerKey::SignedTransactionBytes.to_string(), signed_transaction.clone()); } return_synchronous_result(Ok((signers, signer_state, result))) diff --git a/addons/svm/core/src/codec/send_transaction.rs b/addons/svm/core/src/codec/send_transaction.rs index 9492bd3e5..be5ea4ad5 100644 --- a/addons/svm/core/src/codec/send_transaction.rs +++ b/addons/svm/core/src/codec/send_transaction.rs @@ -5,7 +5,7 @@ use solana_client::rpc_config::RpcSendTransactionConfig; use solana_commitment_config::{CommitmentConfig, CommitmentLevel}; use solana_transaction::Transaction; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::SIGNED_TRANSACTION_BYTES; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::commands::{CommandExecutionFutureResult, CommandSpecification}; use txtx_addon_kit::types::diagnostics::Diagnostic; @@ -49,9 +49,9 @@ pub fn send_transaction_background_task( let is_deployment = inputs.get_bool(IS_DEPLOYMENT).unwrap_or(false); let signed_transaction_value = if is_deployment { - inputs.get_value(SIGNED_TRANSACTION_BYTES).unwrap() + inputs.get_value(SignerKey::SignedTransactionBytes).unwrap() } else { - outputs.get_value(SIGNED_TRANSACTION_BYTES).unwrap() + outputs.get_value(SignerKey::SignedTransactionBytes).unwrap() }; let commitment_config = CommitmentConfig { diff --git a/addons/svm/core/src/commands/deploy_program.rs b/addons/svm/core/src/commands/deploy_program.rs index 5bf345346..39eeddd33 100644 --- a/addons/svm/core/src/commands/deploy_program.rs +++ b/addons/svm/core/src/commands/deploy_program.rs @@ -7,11 +7,7 @@ use solana_client::rpc_client::RpcClient; use solana_commitment_config::CommitmentConfig; use solana_pubkey::Pubkey; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::{ - DESCRIPTION, META_DESCRIPTION, NESTED_CONSTRUCT_COUNT, NESTED_CONSTRUCT_DID, - NESTED_CONSTRUCT_INDEX, RUNBOOK_COMPLETE_ADDITIONAL_INFO, SIGNATURE_APPROVED, - SIGNED_TRANSACTION_BYTES, -}; +use txtx_addon_kit::constants::{DocumentationKey, NestedConstructKey, RunbookKey, SignerKey}; use txtx_addon_kit::futures::future; use txtx_addon_kit::indexmap::IndexMap; use txtx_addon_kit::types::cloud_interface::{CloudService, CloudServiceContext}; @@ -39,8 +35,9 @@ use crate::codec::idl::IdlRef; use crate::codec::send_transaction::send_transaction_background_task; use crate::codec::utils::cheatcode_deploy_program; use crate::codec::{DeploymentTransaction, ProgramArtifacts, UpgradeableProgramDeployer}; +use txtx_addon_kit::constants::ActionItemKey; use crate::constants::{ - ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, AUTHORITY, AUTO_EXTEND, BUFFER_ACCOUNT_PUBKEY, + AUTHORITY, AUTO_EXTEND, BUFFER_ACCOUNT_PUBKEY, CHECKED_PUBLIC_KEY, COMMITMENT_LEVEL, DEPLOYMENT_TRANSACTIONS, DEPLOYMENT_TRANSACTION_TYPE, DO_AWAIT_CONFIRMATION, EPHEMERAL_AUTHORITY_SECRET_KEY, FORMATTED_TRANSACTION, INITIAL_EXPECTED_DEPLOYMENT_TRANSACTIONS_COUNT, INSTANT_SURFNET_DEPLOYMENT, IS_DEPLOYMENT, @@ -502,7 +499,7 @@ impl CommandImplementation for DeployProgram { DeploymentTransaction::transaction_type_from_value(transaction_value) .map_err(|e| (signers.clone(), authority_signer_state.clone(), e))?; - value_store.insert(NESTED_CONSTRUCT_DID, Value::string(new_did.to_string())); + value_store.insert(NestedConstructKey::NestedConstructDid, Value::string(new_did.to_string())); value_store.insert_scoped_value( &new_did.to_string(), @@ -541,12 +538,12 @@ impl CommandImplementation for DeployProgram { ); value_store.insert_scoped_value( &new_did.to_string(), - NESTED_CONSTRUCT_INDEX, + NestedConstructKey::NestedConstructIndex, Value::integer(cursor as i128), ); value_store.insert_scoped_value( &new_did.to_string(), - NESTED_CONSTRUCT_COUNT, + NestedConstructKey::NestedConstructCount, Value::integer(transaction_count as i128), ); res.push((new_did, value_store)); @@ -565,7 +562,7 @@ impl CommandImplementation for DeployProgram { signers: SignersState, auth_context: &txtx_addon_kit::types::AuthorizationContext, ) -> SignerActionsFutureResult { - let nested_construct_did = values.get_expected_construct_did(NESTED_CONSTRUCT_DID).unwrap(); + let nested_construct_did = values.get_expected_construct_did(NestedConstructKey::NestedConstructDid).unwrap(); let transaction = values.get_scoped_value(&nested_construct_did.to_string(), TRANSACTION_BYTES).unwrap(); @@ -597,7 +594,7 @@ impl CommandImplementation for DeployProgram { _ => false, } { if authority_signer_state - .get_scoped_value(&&nested_construct_did.to_string(), SIGNATURE_APPROVED) + .get_scoped_value(&&nested_construct_did.to_string(), SignerKey::SignatureApproved) .is_some() || !supervision_context.review_input_values { @@ -608,7 +605,7 @@ impl CommandImplementation for DeployProgram { Err(diag) => return Err((signers, authority_signer_state, diag)), }; let description = - values.get_expected_string(DESCRIPTION).ok().and_then(|d| Some(d.to_string())); + values.get_expected_string(DocumentationKey::Description).ok().and_then(|d| Some(d.to_string())); let request = ProvideSignedTransactionRequest::new( &authority_signer_did.0, &Value::null(), @@ -619,7 +616,7 @@ impl CommandImplementation for DeployProgram { .formatted_payload(Some(&Value::string("The program binary will be written to the program data address.".into()))) .only_approval_needed() .to_action_type() - .to_request(instance_name, ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION) + .to_request(instance_name, ActionItemKey::ProvideSignedTransaction) .with_construct_did(&nested_construct_did) .with_some_description(description) .with_meta_description("The `surfnet_setAccount` cheatcode will be used to instantly deploy the program without sending any transactions."); @@ -673,7 +670,7 @@ impl CommandImplementation for DeployProgram { })?; if let Some((formatted_transaction, meta_description)) = formatted_transaction { values.insert(FORMATTED_TRANSACTION, formatted_transaction); - values.insert(META_DESCRIPTION, Value::string(meta_description)); + values.insert(DocumentationKey::MetaDescription, Value::string(meta_description)); } let res = check_signed_executability( &nested_construct_did, @@ -725,10 +722,10 @@ impl CommandImplementation for DeployProgram { } let nested_construct_did = - values.get_expected_construct_did(NESTED_CONSTRUCT_DID).unwrap(); + values.get_expected_construct_did(NestedConstructKey::NestedConstructDid).unwrap(); let nested_construct_index = values - .get_scoped_integer(&nested_construct_did.to_string(), NESTED_CONSTRUCT_INDEX) + .get_scoped_integer(&nested_construct_did.to_string(), NestedConstructKey::NestedConstructIndex) .unwrap(); authority_signer_state.insert_scoped_value( &construct_did.to_string(), @@ -785,7 +782,7 @@ impl CommandImplementation for DeployProgram { })?; result.outputs.insert( - format!("{}:{}", &nested_construct_did.to_string(), SIGNED_TRANSACTION_BYTES), + format!("{}:{}", &nested_construct_did.to_string(), SignerKey::SignedTransactionBytes), transaction_value.clone(), ); @@ -805,12 +802,12 @@ impl CommandImplementation for DeployProgram { Err(err) => return Err(err), }; - let some_signed_transaction_value = signin_res.outputs.remove(SIGNED_TRANSACTION_BYTES); + let some_signed_transaction_value = signin_res.outputs.remove(SignerKey::SignedTransactionBytes.as_ref()); result.append(&mut signin_res); if let Some(signed_transaction_value) = some_signed_transaction_value { result.outputs.insert( - format!("{}:{}", &nested_construct_did.to_string(), SIGNED_TRANSACTION_BYTES), + format!("{}:{}", &nested_construct_did.to_string(), SignerKey::SignedTransactionBytes), signed_transaction_value, ); } @@ -840,17 +837,17 @@ impl CommandImplementation for DeployProgram { let future = async move { let nested_construct_did = - inputs.get_expected_construct_did(NESTED_CONSTRUCT_DID).unwrap(); + inputs.get_expected_construct_did(NestedConstructKey::NestedConstructDid).unwrap(); let transaction_value = inputs .get_scoped_value(&nested_construct_did.to_string(), TRANSACTION_BYTES) .unwrap() .clone(); let transaction_index = inputs - .get_scoped_integer(&nested_construct_did.to_string(), NESTED_CONSTRUCT_INDEX) + .get_scoped_integer(&nested_construct_did.to_string(), NestedConstructKey::NestedConstructIndex) .unwrap(); let transaction_count = inputs - .get_scoped_integer(&nested_construct_did.to_string(), NESTED_CONSTRUCT_COUNT) + .get_scoped_integer(&nested_construct_did.to_string(), NestedConstructKey::NestedConstructCount) .unwrap(); let program_id = SvmValue::to_pubkey(&outputs.get_value(PROGRAM_ID).unwrap()).unwrap(); @@ -898,7 +895,7 @@ impl CommandImplementation for DeployProgram { let Some(signed_transaction_value) = inputs .get_scoped_value( &nested_construct_did.to_string(), - SIGNED_TRANSACTION_BYTES, + SignerKey::SignedTransactionBytes, ) .cloned() else { @@ -906,7 +903,7 @@ impl CommandImplementation for DeployProgram { }; inputs.insert(IS_DEPLOYMENT, Value::bool(true)); - inputs.insert(SIGNED_TRANSACTION_BYTES, signed_transaction_value.clone()); + inputs.insert(SignerKey::SignedTransactionBytes, signed_transaction_value.clone()); inputs.insert( COMMITMENT_LEVEL, Value::string(deployment_transaction.commitment_level.to_string()), @@ -1054,7 +1051,7 @@ impl CommandImplementation for DeployProgram { } if is_squads_authority { result.outputs.insert( - RUNBOOK_COMPLETE_ADDITIONAL_INFO.into(), + RunbookKey::RunbookCompleteAdditionalInfo.to_string(), RunbookCompleteAdditionalInfo::new( construct_did, instance_name, diff --git a/addons/svm/core/src/commands/deploy_subraph.rs b/addons/svm/core/src/commands/deploy_subraph.rs index a68454e58..11714858e 100644 --- a/addons/svm/core/src/commands/deploy_subraph.rs +++ b/addons/svm/core/src/commands/deploy_subraph.rs @@ -180,7 +180,7 @@ impl CommandImplementation for DeployProgram { _progress_tx: &txtx_addon_kit::channel::Sender, _auth_ctx: &txtx_addon_kit::types::AuthorizationContext, ) -> CommandExecutionFutureResult { - use txtx_addon_kit::{constants::DESCRIPTION, types::commands::return_synchronous_ok}; + use txtx_addon_kit::{constants::DocumentationKey, types::commands::return_synchronous_ok}; use crate::{ constants::{ @@ -215,7 +215,7 @@ impl CommandImplementation for DeployProgram { .map_err(|e| diagnosed_error!("{e}"))?; let subgraph_name = values.get_string(SUBGRAPH_NAME).and_then(|s| Some(s.to_string())); - let description = values.get_string(DESCRIPTION).and_then(|s| Some(s.to_string())); + let description = values.get_string(DocumentationKey::Description).and_then(|s| Some(s.to_string())); let subgraph_request = SubgraphRequest::parse_value_store_v0( subgraph_name, diff --git a/addons/svm/core/src/commands/sign_transaction.rs b/addons/svm/core/src/commands/sign_transaction.rs index b721b8292..88f4a6e4a 100644 --- a/addons/svm/core/src/commands/sign_transaction.rs +++ b/addons/svm/core/src/commands/sign_transaction.rs @@ -6,9 +6,9 @@ use crate::typing::SvmValue; use crate::utils::build_transaction_from_svm_value; use solana_signature::Signature; use std::collections::HashMap; -use txtx_addon_kit::constants::META_DESCRIPTION; -use txtx_addon_kit::constants::SIGNED_TRANSACTION_BYTES; -use txtx_addon_kit::constants::THIRD_PARTY_SIGNATURE_STATUS; +use txtx_addon_kit::constants::DocumentationKey; +use txtx_addon_kit::constants::SignerKey; +use txtx_addon_kit::constants::RunbookKey; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::diagnostics::Diagnostic; use txtx_addon_kit::types::frontend::Actions; @@ -37,7 +37,7 @@ pub fn check_signed_executability( mut signers: SignersState, auth_context: &AuthorizationContext, ) -> Result { - use txtx_addon_kit::constants::{DESCRIPTION, SIGNATURE_APPROVED}; +use txtx_addon_kit::constants::{DocumentationKey, SignerKey}; use crate::constants::FORMATTED_TRANSACTION; @@ -51,10 +51,10 @@ pub fn check_signed_executability( let mut actions = Actions::none(); let description = - values.get_expected_string(DESCRIPTION).ok().and_then(|d| Some(d.to_string())); + values.get_expected_string(DocumentationKey::Description).ok().and_then(|d| Some(d.to_string())); let markdown_res = values.get_markdown(&auth_context); let meta_description = - values.get_expected_string(META_DESCRIPTION).ok().and_then(|d| Some(d.to_string())); + values.get_expected_string(DocumentationKey::MetaDescription).ok().and_then(|d| Some(d.to_string())); let signers_dids_with_instances = get_signers_and_instance(&values, &signers_instances).unwrap(); @@ -65,10 +65,10 @@ pub fn check_signed_executability( let mut signer_state = signers.get_signer_state(&signer_did).unwrap().clone(); let signer_already_signed = signer_state - .get_scoped_value(&construct_did.to_string(), SIGNED_TRANSACTION_BYTES) + .get_scoped_value(&construct_did.to_string(), SignerKey::SignedTransactionBytes) .is_some(); let signer_already_approved = - signer_state.get_scoped_value(&construct_did.to_string(), SIGNATURE_APPROVED).is_some(); + signer_state.get_scoped_value(&construct_did.to_string(), SignerKey::SignatureApproved).is_some(); if !signer_already_signed && !signer_already_approved { let payload = values.get_value(TRANSACTION_BYTES).unwrap().clone(); @@ -180,11 +180,11 @@ pub fn run_signed_execution( ) { Ok(res) => match res.await { Ok((new_signers, new_signer_state, results)) => { - if results.outputs.get(THIRD_PARTY_SIGNATURE_STATUS).is_some() { + if results.outputs.get(RunbookKey::ThirdPartySignatureStatus.as_ref()).is_some() { return Ok((new_signers, new_signer_state, results)); } - if let Some(fully_signed_tx) = results.outputs.get(SIGNED_TRANSACTION_BYTES) + if let Some(fully_signed_tx) = results.outputs.get(SignerKey::SignedTransactionBytes.as_ref()) { let fully_signed_tx = build_transaction_from_svm_value(fully_signed_tx) .map_err(|e| (new_signers.clone(), new_signer_state.clone(), e))?; @@ -275,7 +275,7 @@ pub fn run_signed_execution( ) })?; result.outputs.insert( - SIGNED_TRANSACTION_BYTES.into(), + SignerKey::SignedTransactionBytes.to_string(), SvmValue::transaction(&combined_transaction).map_err(|e| { (new_signers.clone(), new_signer_state.clone(), e) })?, diff --git a/addons/svm/core/src/commands/srs/create_class.rs b/addons/svm/core/src/commands/srs/create_class.rs index 0a6f0989b..065f94b01 100644 --- a/addons/svm/core/src/commands/srs/create_class.rs +++ b/addons/svm/core/src/commands/srs/create_class.rs @@ -14,7 +14,7 @@ use solana_pubkey::Pubkey; use solana_sdk_ids::system_program; use solana_transaction::Transaction; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::META_DESCRIPTION; +use txtx_addon_kit::constants::DocumentationKey; use txtx_addon_kit::types::cloud_interface::CloudServiceContext; use txtx_addon_kit::types::commands::{ CommandExecutionFutureResult, CommandExecutionResult, CommandImplementation, @@ -402,7 +402,7 @@ impl CommandImplementation for ProcessInstructions { let mut args = args.clone(); args.insert(TRANSACTION_BYTES, transaction); args.insert(FORMATTED_TRANSACTION, formatted_transaction); - args.insert(META_DESCRIPTION, Value::string(meta_description)); + args.insert(DocumentationKey::MetaDescription, Value::string(meta_description)); signers.push_signer_state(signer_state); let res = check_signed_executability( diff --git a/addons/svm/core/src/commands/srs/create_record.rs b/addons/svm/core/src/commands/srs/create_record.rs index b392be945..31ef8ca20 100644 --- a/addons/svm/core/src/commands/srs/create_record.rs +++ b/addons/svm/core/src/commands/srs/create_record.rs @@ -15,7 +15,7 @@ use std::collections::HashMap; use std::future; use std::ops::Deref; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::META_DESCRIPTION; +use txtx_addon_kit::constants::DocumentationKey; use txtx_addon_kit::types::cloud_interface::CloudServiceContext; use txtx_addon_kit::types::commands::{ CommandExecutionFutureResult, CommandExecutionResult, CommandImplementation, @@ -522,7 +522,7 @@ impl CommandImplementation for ProcessInstructions { Value::array(signer_dids.iter().map(|d| Value::string(d.to_string())).collect()), ); args.insert(FORMATTED_TRANSACTION, formatted_transaction); - args.insert(META_DESCRIPTION, Value::string(meta_description)); + args.insert(DocumentationKey::MetaDescription, Value::string(meta_description)); signers.push_signer_state(owner_signer_state); let res = check_signed_executability( diff --git a/addons/svm/core/src/constants.rs b/addons/svm/core/src/constants.rs index b0c8e7215..89924dcc4 100644 --- a/addons/svm/core/src/constants.rs +++ b/addons/svm/core/src/constants.rs @@ -87,11 +87,6 @@ pub const SUBGRAPH_ENDPOINT_URL: &str = "subgraph_endpoint_url"; pub const DO_INCLUDE_TOKEN: &str = "do_include_token"; // Actions items keys -pub const ACTION_ITEM_CHECK_BALANCE: &str = "check_balance"; -pub const ACTION_ITEM_CHECK_ADDRESS: &str = "check_address"; -pub const ACTION_ITEM_PROVIDE_PUBLIC_KEY: &str = "provide_public_key"; -pub const ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION: &str = "provide_signed_transaction"; -pub const ACTION_ITEM_PROVIDE_SIGNED_SQUAD_TRANSACTION: &str = "provide_signed_squad_transaction"; // Subgraph endpoints pub const MAINNET_SUBGRAPH_ENDPOINT: &str = "https://svm-cloud-api.txtx.run/v1/subgraphs"; diff --git a/addons/svm/core/src/functions.rs b/addons/svm/core/src/functions.rs index 1b33f1201..0cc9bb0fa 100644 --- a/addons/svm/core/src/functions.rs +++ b/addons/svm/core/src/functions.rs @@ -11,6 +11,7 @@ use txtx_addon_kit::types::{ functions::{ arg_checker_with_ctx, fn_diag_with_ctx, FunctionImplementation, FunctionSpecification, }, + namespace::Namespace, types::{ObjectType, Type, Value}, AuthorizationContext, }; @@ -36,12 +37,12 @@ pub fn lamports_to_sol(lamports: u64) -> f64 { lamports as f64 / LAMPORTS_PER_SOL_F64 } -pub fn arg_checker(fn_spec: &FunctionSpecification, args: &Vec) -> Result<(), Diagnostic> { - let checker = arg_checker_with_ctx(NAMESPACE.to_string()); +pub fn arg_checker(fn_spec: &FunctionSpecification, args: &[Value]) -> Result<(), Diagnostic> { + let checker = arg_checker_with_ctx(Namespace::from(NAMESPACE)); checker(fn_spec, args) } pub fn to_diag(fn_spec: &FunctionSpecification, e: T) -> Diagnostic { - let error_fn = fn_diag_with_ctx(NAMESPACE.to_string()); + let error_fn = fn_diag_with_ctx(Namespace::from(NAMESPACE)); error_fn(fn_spec, e.to_string()) } @@ -435,7 +436,7 @@ impl FunctionImplementation for SystemProgramId { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -443,7 +444,7 @@ impl FunctionImplementation for SystemProgramId { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; Ok(SvmValue::pubkey(system_program::id().to_bytes().to_vec())) @@ -454,7 +455,7 @@ impl FunctionImplementation for DefaultPubkey { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -462,7 +463,7 @@ impl FunctionImplementation for DefaultPubkey { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; Ok(SvmValue::pubkey(Pubkey::default().to_bytes().to_vec())) @@ -473,7 +474,7 @@ impl FunctionImplementation for GetInstructionDataFromIdl { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -481,7 +482,7 @@ impl FunctionImplementation for GetInstructionDataFromIdl { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; // let idl_bytes = &args.get(0).unwrap().as_addon_data().unwrap().bytes; @@ -513,7 +514,7 @@ impl FunctionImplementation for GetInstructionDataFromIdlPath { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -521,7 +522,7 @@ impl FunctionImplementation for GetInstructionDataFromIdlPath { fn run( fn_spec: &FunctionSpecification, auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let idl_path_str = args.get(0).unwrap().as_string().unwrap(); @@ -550,7 +551,7 @@ impl FunctionImplementation for GetProgramFromAnchorProject { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -558,7 +559,7 @@ impl FunctionImplementation for GetProgramFromAnchorProject { fn run( fn_spec: &FunctionSpecification, auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let program_name = args.get(0).unwrap().as_string().unwrap(); @@ -617,7 +618,7 @@ impl FunctionImplementation for GetProgramFromNativeProject { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -625,7 +626,7 @@ impl FunctionImplementation for GetProgramFromNativeProject { fn run( fn_spec: &FunctionSpecification, auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let program_name = args.get(0).unwrap().as_string().unwrap(); @@ -691,7 +692,7 @@ impl FunctionImplementation for SolToLamports { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -699,7 +700,7 @@ impl FunctionImplementation for SolToLamports { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let sol = args.get(0).unwrap(); @@ -731,7 +732,7 @@ impl FunctionImplementation for LamportsToSol { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -739,7 +740,7 @@ impl FunctionImplementation for LamportsToSol { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let lamports = args.get(0).unwrap().as_uint().unwrap().map_err(|e| to_diag(fn_spec, e))?; @@ -754,7 +755,7 @@ impl FunctionImplementation for FindPda { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -762,7 +763,7 @@ impl FunctionImplementation for FindPda { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let program_id = SvmValue::to_pubkey(args.get(0).unwrap()) @@ -791,7 +792,7 @@ impl FunctionImplementation for GetAssociatedTokenAccount { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -799,7 +800,7 @@ impl FunctionImplementation for GetAssociatedTokenAccount { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let wallet_address = SvmValue::to_pubkey(args.get(0).unwrap()).map_err(|e| { @@ -831,7 +832,7 @@ impl FunctionImplementation for CreateTokenAccountInstruction { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -839,7 +840,7 @@ impl FunctionImplementation for CreateTokenAccountInstruction { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let funding_address = SvmValue::to_pubkey(args.get(0).unwrap()).map_err(|e| { @@ -877,7 +878,7 @@ impl FunctionImplementation for SvmU64 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -885,7 +886,7 @@ impl FunctionImplementation for SvmU64 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let value = args.get(0).unwrap().as_uint().unwrap().map_err(|e| to_diag(fn_spec, e))?; @@ -897,7 +898,7 @@ impl FunctionImplementation for SvmI64 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -905,7 +906,7 @@ impl FunctionImplementation for SvmI64 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let value = args.get(0).unwrap().as_integer().unwrap(); diff --git a/addons/svm/core/src/signers/mod.rs b/addons/svm/core/src/signers/mod.rs index 58744ba21..68e16af66 100644 --- a/addons/svm/core/src/signers/mod.rs +++ b/addons/svm/core/src/signers/mod.rs @@ -13,15 +13,15 @@ use txtx_addon_kit::types::{ ActionItemRequest, ActionItemRequestType, ActionItemStatus, ProvidePublicKeyRequest, ReviewInputRequest, }, + namespace::Namespace, signers::SignerSpecification, types::Value, ConstructDid, }; use web_wallet::SVM_WEB_WALLET; -use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_CHECK_BALANCE, ACTION_ITEM_PROVIDE_PUBLIC_KEY, NAMESPACE, -}; +use txtx_addon_kit::constants::ActionItemKey; +use crate::constants::NAMESPACE; lazy_static! { pub static ref SIGNERS: Vec = @@ -52,9 +52,9 @@ pub async fn get_additional_actions_for_address( check_expectation_action_uuid: Some(signer_did.clone()), message: "".to_string(), network_id: network_id.into(), - namespace: NAMESPACE.to_string(), + namespace: Namespace::from(NAMESPACE), }) - .to_request(instance_name, ACTION_ITEM_PROVIDE_PUBLIC_KEY) + .to_request(instance_name, ActionItemKey::ProvidePublicKey) .with_construct_did(signer_did) .with_some_description(description) .with_meta_description(&format!("Connect wallet '{instance_name}'")) @@ -68,7 +68,7 @@ pub async fn get_additional_actions_for_address( action_items.push( ReviewInputRequest::new("", &Value::string(expected_address.to_string())) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_ADDRESS) + .to_request(instance_name, ActionItemKey::CheckAddress) .with_construct_did(signer_did) .with_some_description(Some("".into())) .with_meta_description(&format!( @@ -138,7 +138,7 @@ async fn get_check_balance_action( Some( ReviewInputRequest::new("", &value) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_BALANCE) + .to_request(instance_name, ActionItemKey::CheckBalance) .with_construct_did(signer_did) .with_meta_description(&format!("Check '{}' signer balance", instance_name)) .with_some_description(Some("".into())) diff --git a/addons/svm/core/src/signers/secret_key.rs b/addons/svm/core/src/signers/secret_key.rs index 757745a9a..7040965fc 100644 --- a/addons/svm/core/src/signers/secret_key.rs +++ b/addons/svm/core/src/signers/secret_key.rs @@ -5,7 +5,7 @@ use solana_commitment_config::{CommitmentConfig, CommitmentLevel}; use solana_keypair::Keypair; use solana_transaction::Transaction; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::{SIGNATURE_APPROVED, SIGNATURE_SKIPPABLE}; +use txtx_addon_kit::constants::{SignerKey}; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::frontend::{ ActionItemStatus, ProvideSignedTransactionRequest, ReviewInputRequest, @@ -27,8 +27,9 @@ use txtx_addon_kit::types::{ use txtx_addon_network_svm_types::SvmValue; use crate::codec::DeploymentTransaction; +use txtx_addon_kit::constants::ActionItemKey; use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, ADDRESS, CHECKED_ADDRESS, + ADDRESS, CHECKED_ADDRESS, CHECKED_PUBLIC_KEY, COMMITMENT_LEVEL, FORMATTED_TRANSACTION, IS_DEPLOYMENT, IS_SIGNABLE, NAMESPACE, NETWORK_ID, PARTIALLY_SIGNED_TRANSACTION_BYTES, PREVIOUSLY_SIGNED_BLOCKHASH, PUBLIC_KEY, RPC_API_URL, SECRET_KEY, TRANSACTION_BYTES, @@ -137,14 +138,14 @@ impl SignerImplementation for SvmSecretKey { }; use solana_keypair::Keypair; use solana_signer::Signer; - use txtx_addon_kit::{constants::DESCRIPTION, crypto::secret_key_bytes_from_mnemonic}; + use txtx_addon_kit::{constants::DocumentationKey, crypto::secret_key_bytes_from_mnemonic}; let mut actions = Actions::none(); if signer_state.get_value(CHECKED_PUBLIC_KEY).is_some() { return return_synchronous_actions(Ok((signers, signer_state, actions))); } - let description = values.get_string(DESCRIPTION).map(|d| d.to_string()); + let description = values.get_string(DocumentationKey::Description).map(|d| d.to_string()); let markdown = values .get_markdown(auth_ctx) .map_err(|d| (signers.clone(), signer_state.clone(), d))?; @@ -242,7 +243,7 @@ impl SignerImplementation for SvmSecretKey { None, vec![ReviewInputRequest::new("", &public_key_value) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_ADDRESS) + .to_request(instance_name, ActionItemKey::CheckAddress) .with_construct_did(construct_did) .with_some_description(description) .with_meta_description(&format!("Check {} expected address", instance_name)) @@ -298,7 +299,7 @@ impl SignerImplementation for SvmSecretKey { let actions = if supervision_context.review_input_values { let construct_did_str = &construct_did.to_string(); - if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SIGNATURE_APPROVED) { + if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SignerKey::SignatureApproved) { return Ok((signers, signer_state, Actions::none())); } @@ -316,7 +317,7 @@ impl SignerImplementation for SvmSecretKey { false => ActionItemStatus::Blocked, }; let skippable = signer_state - .get_scoped_value(&construct_did_str, SIGNATURE_SKIPPABLE) + .get_scoped_value(&construct_did_str, SignerKey::SignatureSkippable) .and_then(|v| v.as_bool()) .unwrap_or(false); let formatted_payload = @@ -333,7 +334,7 @@ impl SignerImplementation for SvmSecretKey { .formatted_payload(formatted_payload) .only_approval_needed() .to_action_type() - .to_request(title, ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION) + .to_request(title, ActionItemKey::ProvideSignedTransaction) .with_construct_did(construct_did) .with_some_description(description.clone()) .with_some_meta_description(meta_description.clone()) diff --git a/addons/svm/core/src/signers/squads.rs b/addons/svm/core/src/signers/squads.rs index 2cd135cd2..4f845fb98 100644 --- a/addons/svm/core/src/signers/squads.rs +++ b/addons/svm/core/src/signers/squads.rs @@ -4,9 +4,7 @@ use solana_client::rpc_client::RpcClient; use solana_signature::Signature; use solana_transaction::Transaction; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::{ - META_DESCRIPTION, SIGNED_TRANSACTION_BYTES, THIRD_PARTY_SIGNATURE_STATUS, -}; +use txtx_addon_kit::constants::{DocumentationKey, RunbookKey, SignerKey}; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::frontend::{ ActionItemStatus, ReviewInputRequest, VerifyThirdPartySignatureRequest, @@ -26,7 +24,7 @@ use txtx_addon_kit::types::{ types::{Type, Value}, }; use txtx_addon_kit::{ - constants::ACTION_ITEM_CHECK_BALANCE, types::frontend::ActionItemRequestUpdate, + constants::ActionItemKey, types::frontend::ActionItemRequestUpdate, }; use txtx_addon_network_svm_types::SVM_PUBKEY; @@ -35,7 +33,7 @@ use crate::codec::squads::SquadsMultisig; use crate::codec::ui_encode::get_formatted_transaction_meta_description; use crate::commands::sign_transaction::{check_signed_executability, run_signed_execution}; use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_PROVIDE_SIGNED_SQUAD_TRANSACTION, ADDRESS, + ADDRESS, CHECKED_ADDRESS, CHECKED_PUBLIC_KEY, FORMATTED_TRANSACTION, INITIATOR, IS_DEPLOYMENT, IS_SIGNABLE, MULTISIG_ACCOUNT_ADDRESS, MULTISIG_ACCOUNT_PUBLIC_KEY, NAMESPACE, NETWORK_ID, PAYER, PUBLIC_KEY, RPC_API_URL, SIGNATURE, SIGNERS, SQUADS_MULTISIG, TRANSACTION_BYTES, @@ -179,7 +177,7 @@ impl SignerImplementation for SvmSecretKey { is_balance_check_required: bool, is_public_key_required: bool, ) -> SignerActionsFutureResult { - use txtx_addon_kit::constants::{DESCRIPTION, IS_BALANCE_CHECKED}; +use txtx_addon_kit::constants::{ActionItemKey, DocumentationKey}; use txtx_addon_kit::types::signers::consolidate_signer_result; use crate::constants::{ @@ -268,7 +266,7 @@ impl SignerImplementation for SvmSecretKey { )); }; - let is_balance_checked = signer_state.get_bool(IS_BALANCE_CHECKED); + let is_balance_checked = signer_state.get_bool(SignerKey::IsBalanceChecked); let rpc_api_url = values .get_expected_string(RPC_API_URL) .map_err(|e| (signers.clone(), signer_state.clone(), e))? @@ -283,7 +281,7 @@ impl SignerImplementation for SvmSecretKey { let vault_pubkey_value = SvmValue::pubkey(vault_pubkey.to_bytes().to_vec()); let vault_pubkey_string_value = Value::string(vault_pubkey.to_string()); let multisig_value = squad.to_value(); - let description = values.get_string(DESCRIPTION).map(|d| d.to_string()); + let description = values.get_string(DocumentationKey::Description).map(|d| d.to_string()); let markdown = values .get_markdown(auth_ctx) .map_err(|d| (signers.clone(), signer_state.clone(), d))?; @@ -300,14 +298,14 @@ impl SignerImplementation for SvmSecretKey { signer_state.insert(PAYER, Value::string(payer_did.to_string())); } let update = - ActionItemRequestUpdate::from_context(&construct_did, ACTION_ITEM_CHECK_ADDRESS) + ActionItemRequestUpdate::from_context(&construct_did, ActionItemKey::CheckAddress) .set_status(ActionItemStatus::Success(Some(vault_pubkey.to_string()))); consolidated_actions.push_action_item_update(update); } else { action_items.push( ReviewInputRequest::new("", &vault_pubkey_string_value) .to_action_type() - .to_request(instance_name, ACTION_ITEM_CHECK_ADDRESS) + .to_request(instance_name, ActionItemKey::CheckAddress) .with_construct_did(construct_did) .with_some_description(description) .with_meta_description(&format!( @@ -323,7 +321,7 @@ impl SignerImplementation for SvmSecretKey { consolidated_actions.push_action_item_update( ActionItemRequestUpdate::from_context( &construct_did, - ACTION_ITEM_CHECK_BALANCE, + ActionItemKey::CheckBalance, ) .set_status(ActionItemStatus::Success(None)), ); @@ -332,7 +330,7 @@ impl SignerImplementation for SvmSecretKey { consolidated_actions.push_action_item_update( ActionItemRequestUpdate::from_context( &construct_did, - ACTION_ITEM_CHECK_BALANCE, + ActionItemKey::CheckBalance, ) .set_status(ActionItemStatus::Todo), ); @@ -500,7 +498,7 @@ impl SignerImplementation for SvmSecretKey { ); let third_party_signature_status = signer_state - .get_scoped_value(&construct_did.to_string(), THIRD_PARTY_SIGNATURE_STATUS) + .get_scoped_value(&construct_did.to_string(), RunbookKey::ThirdPartySignatureStatus) .and_then(|v| v.as_third_party_signature_status()); let rpc_api_url = values @@ -610,7 +608,7 @@ impl SignerImplementation for SvmSecretKey { let values = { let mut values = values.clone(); values.insert( - META_DESCRIPTION, + DocumentationKey::MetaDescription, Value::string(get_formatted_transaction_meta_description( &vec!["This transaction will create a Squads proposal.".into()], &signers_dids, @@ -683,7 +681,7 @@ impl SignerImplementation for SvmSecretKey { .check_expectation_action_uuid(construct_did) .formatted_payload(formatted_payload) .to_action_type() - .to_request(instance_name, ACTION_ITEM_PROVIDE_SIGNED_SQUAD_TRANSACTION) + .to_request(instance_name, ActionItemKey::ProvideSignedSquadTransaction) .with_construct_did(construct_did) .with_some_description(description.clone()) .with_some_meta_description(meta_description.clone()) @@ -704,7 +702,7 @@ impl SignerImplementation for SvmSecretKey { actions.push_action_item_update( ActionItemRequestUpdate::from_context( &construct_did, - ACTION_ITEM_PROVIDE_SIGNED_SQUAD_TRANSACTION, + txtx_addon_kit::constants::ActionItemKey::ProvideSignedSquadTransaction, ) .set_status(ActionItemStatus::Todo), ); @@ -757,7 +755,7 @@ impl SignerImplementation for SvmSecretKey { actions.push_action_item_update( ActionItemRequestUpdate::from_context( &construct_did, - ACTION_ITEM_PROVIDE_SIGNED_SQUAD_TRANSACTION, + txtx_addon_kit::constants::ActionItemKey::ProvideSignedSquadTransaction, ) .set_status(ActionItemStatus::Success(None)), ); @@ -769,7 +767,7 @@ impl SignerImplementation for SvmSecretKey { actions.push_action_item_update( ActionItemRequestUpdate::from_context( &construct_did, - ACTION_ITEM_PROVIDE_SIGNED_SQUAD_TRANSACTION, + txtx_addon_kit::constants::ActionItemKey::ProvideSignedSquadTransaction, ) .set_status(ActionItemStatus::Todo), ); @@ -811,7 +809,7 @@ impl SignerImplementation for SvmSecretKey { let rpc_client = RpcClient::new(rpc_api_url); let third_party_signature_status = signer_state - .get_scoped_value(&construct_did.to_string(), THIRD_PARTY_SIGNATURE_STATUS) + .get_scoped_value(&construct_did.to_string(), RunbookKey::ThirdPartySignatureStatus) .and_then(|v| v.as_third_party_signature_status()); // The squads signer will have multiple passes through `check_signability` and `sign`. The enum variants are @@ -842,7 +840,7 @@ impl SignerImplementation for SvmSecretKey { signer_state.insert_scoped_value( &construct_did.to_string(), - THIRD_PARTY_SIGNATURE_STATUS, + RunbookKey::ThirdPartySignatureStatus, Value::third_party_signature_initialized(), ); signers.push_signer_state(signer_state); @@ -858,7 +856,7 @@ impl SignerImplementation for SvmSecretKey { }; result.insert( - THIRD_PARTY_SIGNATURE_STATUS, + RunbookKey::ThirdPartySignatureStatus.as_ref(), Value::third_party_signature_initialized(), ); @@ -872,7 +870,7 @@ impl SignerImplementation for SvmSecretKey { signer_state, CommandExecutionResult::from([ ( - THIRD_PARTY_SIGNATURE_STATUS, + RunbookKey::ThirdPartySignatureStatus, Value::third_party_signature_check_requested(), ), // (SIGNED_TRANSACTION_BYTES, Value::null()), @@ -890,8 +888,8 @@ impl SignerImplementation for SvmSecretKey { signers, signer_state, CommandExecutionResult::from([ - (THIRD_PARTY_SIGNATURE_STATUS, Value::third_party_signature_approved()), - (SIGNED_TRANSACTION_BYTES, Value::null()), + (RunbookKey::ThirdPartySignatureStatus.as_ref(), Value::third_party_signature_approved()), + (SignerKey::SignedTransactionBytes.as_ref(), Value::null()), (SIGNATURE, Value::string(signature)), ]), )); diff --git a/addons/svm/core/src/signers/web_wallet.rs b/addons/svm/core/src/signers/web_wallet.rs index 8fc5306be..9896a01ee 100644 --- a/addons/svm/core/src/signers/web_wallet.rs +++ b/addons/svm/core/src/signers/web_wallet.rs @@ -5,7 +5,7 @@ use solana_commitment_config::CommitmentConfig; use solana_signature::Signature; use solana_transaction::Transaction; use txtx_addon_kit::channel; -use txtx_addon_kit::constants::{SIGNATURE_SKIPPABLE, SIGNED_TRANSACTION_BYTES}; +use txtx_addon_kit::constants::{SignerKey}; use txtx_addon_kit::types::commands::CommandExecutionResult; use txtx_addon_kit::types::frontend::{ ActionItemRequestUpdate, ActionItemStatus, Actions, BlockEvent, ProvideSignedTransactionRequest, @@ -25,9 +25,9 @@ use txtx_addon_kit::types::{ use txtx_addon_kit::types::{AuthorizationContext, ConstructDid}; use crate::codec::{transaction_is_fully_signed, DeploymentTransaction}; +use txtx_addon_kit::constants::ActionItemKey; use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_PROVIDE_PUBLIC_KEY, - ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION, ADDRESS, CHECKED_ADDRESS, CHECKED_PUBLIC_KEY, + ADDRESS, CHECKED_ADDRESS, CHECKED_PUBLIC_KEY, EXPECTED_ADDRESS, FORMATTED_TRANSACTION, IS_DEPLOYMENT, IS_SIGNABLE, NAMESPACE, NETWORK_ID, PARTIALLY_SIGNED_TRANSACTION_BYTES, PUBLIC_KEY, REQUESTED_STARTUP_DATA, RPC_API_URL, TRANSACTION_BYTES, UPDATED_PARTIALLY_SIGNED_TRANSACTION, @@ -99,13 +99,10 @@ impl SignerImplementation for SvmWebWallet { _is_public_key_required: bool, ) -> SignerActionsFutureResult { use crate::{codec::public_key_from_str, constants::NETWORK_ID}; - use txtx_addon_kit::constants::{ - ACTION_ITEM_CHECK_BALANCE, DESCRIPTION, IS_BALANCE_CHECKED, - PROVIDE_PUBLIC_KEY_ACTION_RESULT, - }; + use txtx_addon_kit::constants::{ActionItemKey, DocumentationKey, SignerKey}; let checked_public_key = signer_state.get_expected_string(CHECKED_PUBLIC_KEY); - let is_balance_checked = signer_state.get_bool(IS_BALANCE_CHECKED); + let is_balance_checked = signer_state.get_bool(SignerKey::IsBalanceChecked); let values = values.clone(); let expected_address = values @@ -126,7 +123,7 @@ impl SignerImplementation for SvmWebWallet { .get_expected_string(RPC_API_URL) .map_err(|e| (signers.clone(), signer_state.clone(), e))? .to_owned(); - let description = values.get_string(DESCRIPTION).map(|d| d.to_string()); + let description = values.get_string(DocumentationKey::Description).map(|d| d.to_string()); let markdown = values .get_markdown(auth_ctx) .map_err(|d| (signers.clone(), signer_state.clone(), d))?; @@ -137,7 +134,7 @@ impl SignerImplementation for SvmWebWallet { .to_owned(); let (mut actions, connected_public_key) = if let Ok(public_key_bytes) = - values.get_expected_string(PROVIDE_PUBLIC_KEY_ACTION_RESULT) + values.get_expected_string(ActionItemKey::ProvidePublicKey) { let sol_address = public_key_from_str(&public_key_bytes) .map_err(|e| (signers.clone(), signer_state.clone(), e))?; @@ -156,7 +153,7 @@ impl SignerImplementation for SvmWebWallet { } else { let update = ActionItemRequestUpdate::from_context( &signer_did, - ACTION_ITEM_CHECK_ADDRESS, + ActionItemKey::CheckAddress, ) .set_status(status_update.clone()); actions.push_action_item_update(update); @@ -169,7 +166,7 @@ impl SignerImplementation for SvmWebWallet { do_request_public_key = false; } let update = - ActionItemRequestUpdate::from_context(&signer_did, ACTION_ITEM_PROVIDE_PUBLIC_KEY) + ActionItemRequestUpdate::from_context(&signer_did, ActionItemKey::ProvidePublicKey) .set_status(status_update); actions.push_action_item_update(update); @@ -187,13 +184,13 @@ impl SignerImplementation for SvmWebWallet { match is_balance_checked { Some(true) => { actions.push_action_item_update( - ActionItemRequestUpdate::from_context(&signer_did, ACTION_ITEM_CHECK_BALANCE) + ActionItemRequestUpdate::from_context(&signer_did, ActionItemKey::CheckBalance) .set_status(ActionItemStatus::Success(None)), ); } Some(false) => { actions.push_action_item_update( - ActionItemRequestUpdate::from_context(&signer_did, ACTION_ITEM_CHECK_BALANCE) + ActionItemRequestUpdate::from_context(&signer_did, ActionItemKey::CheckBalance) .set_status(ActionItemStatus::Todo), ); } @@ -272,7 +269,7 @@ impl SignerImplementation for SvmWebWallet { ) -> Result { let construct_did_str = &construct_did.to_string(); signer_state.insert_scoped_value(&construct_did_str, TRANSACTION_BYTES, payload.clone()); - if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SIGNED_TRANSACTION_BYTES) + if let Some(_) = signer_state.get_scoped_value(&construct_did_str, SignerKey::SignedTransactionBytes) { return Ok((signers, signer_state, Actions::none())); } @@ -292,7 +289,7 @@ impl SignerImplementation for SvmWebWallet { }; let skippable = signer_state - .get_scoped_value(&construct_did_str, SIGNATURE_SKIPPABLE) + .get_scoped_value(&construct_did_str, SignerKey::SignatureSkippable) .and_then(|v| v.as_bool()) .unwrap_or(false); let expected_signer_address = signer_state.get_string(CHECKED_ADDRESS); @@ -311,7 +308,7 @@ impl SignerImplementation for SvmWebWallet { .check_expectation_action_uuid(construct_did) .formatted_payload(formatted_payload) .to_action_type() - .to_request(title, ACTION_ITEM_PROVIDE_SIGNED_TRANSACTION) + .to_request(title, ActionItemKey::ProvideSignedTransaction) .with_construct_did(construct_did) .with_some_description(description.clone()) .with_some_meta_description(meta_description.clone()) @@ -343,7 +340,7 @@ impl SignerImplementation for SvmWebWallet { // value signed (partially, maybe) by the supervisor let signed_transaction_value = - signer_state.remove_scoped_value(&construct_did.to_string(), SIGNED_TRANSACTION_BYTES); + signer_state.remove_scoped_value(&construct_did.to_string(), SignerKey::SignedTransactionBytes); let supervisor_signed_tx = if let Some(signed_transaction_value) = signed_transaction_value { diff --git a/branch-changes.txt b/branch-changes.txt new file mode 100644 index 000000000..ed23b5261 --- /dev/null +++ b/branch-changes.txt @@ -0,0 +1,124 @@ +Branch: feat/addon-kit-factor +Description: Type-safe constant enums refactoring +Rebased onto: main (2025-12-12) + +================================================================================ +SUMMARY +================================================================================ + +This branch replaces string constants throughout the codebase with type-safe +enums using Strum derives (AsRefStr, Display, EnumString, IntoStaticStr). +This provides compile-time safety, better IDE support, and eliminates typo bugs. + +================================================================================ +COMMITS (20 total) +================================================================================ + +Foundation (txtx-addon-kit): +1. Add Strum traits to Type enum and structured FunctionError +2. Replace string namespaces with Namespace enum +3. Apply idiomatic Rust patterns to function APIs +4. Extract type compatibility logic into dedicated module +5. Derive Display for DiagnosticLevel using Strum +6. Replace string constants with type-safe enums (SignerKey, ActionItemKey, etc.) +7. Replace internal_key string field with ActionItemKey enum +8. Add enum variants and Ord traits to constants + +Migration: +9. Migrate txtx-core to type-safe constant enums +10. Fix Namespace type conversions in txtx-cli +11. Migrate txtx-cloud and txtx-gql to type-safe constant enums +12. Migrate bitcoin addon to type-safe function signatures +13. Migrate evm addon to type-safe constant enums +14. Migrate stacks addon to type-safe constant enums +15. Migrate svm addon to type-safe constant enums + +Cleanup: +16. Update Cargo dependency versions +17. Eliminate DRY violation in Diagnostic constructors +18. Remove redundant per-variant attributes from ActionItemKey +19. Improve ValueStore API ergonomics with impl AsRef and impl ToString +20. Fix post-rebase integration with validation infrastructure + +================================================================================ +KEY CHANGES +================================================================================ + +New Enums in txtx-addon-kit/src/constants.rs: +- SignerKey: SignedMessageBytes, SignedTransactionBytes, TxHash, SignatureApproved +- ActionItemKey: CheckAddress, CheckBalance, CheckInput, ProvideInput, etc. +- DocumentationKey: Description, DependsOn, MetaDescription, Markdown, MarkdownFilepath +- ConditionKey: PreCondition, PostCondition +- RunbookKey: ThirdPartySignatureStatus, RunbookCompleteAdditionalInfo +- NestedConstructKey: NestedConstructIndex + +New Modules: +- txtx-addon-kit/src/types/function_errors.rs - Structured FunctionError type +- txtx-addon-kit/src/types/namespace.rs - Namespace enum +- txtx-addon-kit/src/types/type_compatibility.rs - Type compatibility logic + +API Changes: +- ValueStore methods accept impl AsRef and impl ToString +- ActionItem.internal_key changed from String to ActionItemKey enum +- Function signatures use structured error types + +================================================================================ +REBASE CONFLICT RESOLUTION STRATEGY +================================================================================ + +Rebased 19 commits onto main which had 17 new commits including: +- Linter command feature +- Validation infrastructure (new validation module) +- SVM fixes and improvements +- EVM nonce manager removal + +Key Conflicts Resolved: + +1. crates/txtx-addon-kit/src/types/types.rs + - Main changed Type::Null to Type::Null(Option>) + - Resolution: Keep main's parameterized Null, update all pattern matches + from Type::Null to Type::Null(_) + +2. crates/txtx-addon-kit/src/constants.rs + - Main added DEPENDS_ON, PRE_CONDITION, POST_CONDITION string constants + - Branch rewrote entire file to use enums + - Resolution: Keep branch's enum structure, add new variants: + * DocumentationKey::DependsOn + * ConditionKey::PreCondition, ConditionKey::PostCondition + +3. crates/txtx-addon-kit/src/types/mod.rs + - Main added: construct_type, typed_block, diagnostic_types modules + - Branch added: function_errors, namespace, type_compatibility modules + - Resolution: Keep all module declarations from both branches + +4. crates/txtx-core/src/lib.rs + - Main added: pub mod validation + - Branch changed: constant imports to enum imports + - Resolution: Keep both changes + +5. addons/evm/src/signers/*.rs + - Main removed nonce tracking (behavioral change) + - Branch added type-safe enum conversions + - Resolution: Accept main's nonce removal + apply branch's enum changes + +6. crates/txtx-addon-kit/src/types/diagnostics.rs + - Main added re-exports from diagnostic_types + - Branch added DRY with_level constructor + - Resolution: Keep both, fix incomplete Default impl + +Post-Rebase Integration Fixes: +- validation_helpers.rs: Convert string constants to enum usage +- tests/mod.rs: Fix ActionItemKey enum comparison +- deploy_program.rs: Use NestedConstructKey enum +- Cargo.toml: Remove duplicate strum dependency + +================================================================================ +TESTING +================================================================================ + +All tests pass after rebase: +- txtx-core: 66 tests passed +- txtx-cli: 42 tests passed + +Build command: cargo build --package txtx-cli --no-default-features --features cli +Test command: cargo test --package txtx-cli --no-default-features --features cli diff --git a/crates/txtx-addon-kit/Cargo.toml b/crates/txtx-addon-kit/Cargo.toml index 350326754..ce9c289a9 100644 --- a/crates/txtx-addon-kit/Cargo.toml +++ b/crates/txtx-addon-kit/Cargo.toml @@ -39,6 +39,7 @@ libsecp256k1 = { version = "0.7.0" } keccak-hash = "0.11.0" dirs = "5.0.1" dyn-clone = "1" +strum_macros = "0.26" [dev-dependencies] test-case = "3.3" diff --git a/crates/txtx-addon-kit/src/constants.rs b/crates/txtx-addon-kit/src/constants.rs index ae5839bde..88507dbd5 100644 --- a/crates/txtx-addon-kit/src/constants.rs +++ b/crates/txtx-addon-kit/src/constants.rs @@ -1,27 +1,79 @@ -// Signers -pub const SIGNED_MESSAGE_BYTES: &str = "signed_message_bytes"; -pub const SIGNED_TRANSACTION_BYTES: &str = "signed_transaction_bytes"; -pub const TX_HASH: &str = "tx_hash"; -pub const SIGNATURE_APPROVED: &str = "signature_approved"; -pub const SIGNATURE_SKIPPABLE: &str = "signature_skippable"; -pub const PROVIDE_PUBLIC_KEY_ACTION_RESULT: &str = "provide_public_key_action_result"; -pub const NESTED_CONSTRUCT_DID: &str = "nested_construct_did"; -pub const NESTED_CONSTRUCT_INDEX: &str = "nested_construct_index"; -pub const NESTED_CONSTRUCT_COUNT: &str = "nested_construct_count"; -pub const DESCRIPTION: &str = "description"; -pub const DEPENDS_ON: &str = "depends_on"; -pub const META_DESCRIPTION: &str = "meta_description"; -pub const MARKDOWN: &str = "markdown"; -pub const MARKDOWN_FILEPATH: &str = "markdown_filepath"; -pub const PRE_CONDITION: &str = "pre_condition"; -pub const POST_CONDITION: &str = "post_condition"; +use serde::{Deserialize, Serialize}; +use strum_macros::{AsRefStr, Display, EnumString, IntoStaticStr}; -pub const ACTION_ITEM_CHECK_ADDRESS: &str = "check_address"; -pub const CHECKED_ADDRESS: &str = "checked_address"; -pub const ACTION_ITEM_CHECK_BALANCE: &str = "check_balance"; -pub const IS_BALANCE_CHECKED: &str = "is_balance_checked"; -pub const ACTION_ITEM_BEGIN_FLOW: &str = "begin_flow"; -pub const RE_EXECUTE_COMMAND: &str = "re_execute_command"; +/// Keys related to signer operations and signatures +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, AsRefStr, Display, EnumString, IntoStaticStr)] +#[strum(serialize_all = "snake_case")] +pub enum SignerKey { + SignedMessageBytes, + SignedTransactionBytes, + TxHash, + SignatureApproved, + SignatureSkippable, + ProvidePublicKeyActionResult, + IsBalanceChecked, +} -pub const THIRD_PARTY_SIGNATURE_STATUS: &str = "third_party_signature_status"; -pub const RUNBOOK_COMPLETE_ADDITIONAL_INFO: &str = "runbook_complete_additional_info"; +/// Keys related to action items +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, AsRefStr, Display, EnumString, IntoStaticStr)] +#[strum(serialize_all = "snake_case")] +#[serde(rename_all = "snake_case")] +pub enum ActionItemKey { + CheckAddress, + CheckedAddress, + CheckBalance, + IsBalanceChecked, + CheckNonce, + CheckFee, + CheckOutput, + ProvidePublicKey, + ProvideSignedTransaction, + ProvideSignedSquadTransaction, + SendTransaction, + ReviewDeployedContract, + Env, + Genesis, + ValidateBlock, + BeginFlow, + ReExecuteCommand, + Diagnostic, + Output, + ProvideInput, + CheckInput, +} + +/// Keys related to nested constructs +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, AsRefStr, Display, EnumString, IntoStaticStr)] +#[strum(serialize_all = "snake_case")] +pub enum NestedConstructKey { + NestedConstructDid, + NestedConstructIndex, + NestedConstructCount, +} + +/// Keys related to documentation and metadata +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, AsRefStr, Display, EnumString, IntoStaticStr)] +#[strum(serialize_all = "snake_case")] +pub enum DocumentationKey { + Description, + DependsOn, + MetaDescription, + Markdown, + MarkdownFilepath, +} + +/// Keys related to conditions (pre/post) +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, AsRefStr, Display, EnumString, IntoStaticStr)] +#[strum(serialize_all = "snake_case")] +pub enum ConditionKey { + PreCondition, + PostCondition, +} + +/// Keys related to runbook execution +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, AsRefStr, Display, EnumString, IntoStaticStr)] +#[strum(serialize_all = "snake_case")] +pub enum RunbookKey { + ThirdPartySignatureStatus, + RunbookCompleteAdditionalInfo, +} diff --git a/crates/txtx-addon-kit/src/types/commands/execution_conditions/post_conditions.rs b/crates/txtx-addon-kit/src/types/commands/execution_conditions/post_conditions.rs index c6812f604..8e78d0a60 100644 --- a/crates/txtx-addon-kit/src/types/commands/execution_conditions/post_conditions.rs +++ b/crates/txtx-addon-kit/src/types/commands/execution_conditions/post_conditions.rs @@ -1,5 +1,5 @@ use crate::{ - constants::RE_EXECUTE_COMMAND, + constants::ActionItemKey, indoc, types::{commands::CommandExecutionResult, frontend::LogDispatcher, types::ObjectProperty}, }; @@ -149,10 +149,10 @@ pub fn evaluate_post_conditions( execution_results .outputs .insert(POST_CONDITION_ATTEMPTS.into(), Value::Integer(attempts + 1)); - execution_results.outputs.insert(RE_EXECUTE_COMMAND.into(), Value::bool(true)); + execution_results.outputs.insert(ActionItemKey::ReExecuteCommand.as_ref().into(), Value::bool(true)); return Ok(PostConditionEvaluationResult::Retry(post_condition.backoff)); } else { - execution_results.outputs.entry(RE_EXECUTE_COMMAND.into()).and_modify(|v| { + execution_results.outputs.entry(ActionItemKey::ReExecuteCommand.as_ref().into()).and_modify(|v| { *v = Value::bool(false); }); } @@ -193,7 +193,7 @@ pub fn evaluate_post_conditions( PostConditionBehavior::Continue => {} } } else { - execution_results.outputs.entry(RE_EXECUTE_COMMAND.into()).and_modify(|v| { + execution_results.outputs.entry(ActionItemKey::ReExecuteCommand.as_ref().into()).and_modify(|v| { *v = Value::bool(false); }); } diff --git a/crates/txtx-addon-kit/src/types/commands/mod.rs b/crates/txtx-addon-kit/src/types/commands/mod.rs index 6db9a881d..5b59a6592 100644 --- a/crates/txtx-addon-kit/src/types/commands/mod.rs +++ b/crates/txtx-addon-kit/src/types/commands/mod.rs @@ -17,10 +17,7 @@ use hcl_edit::{expr::Expression, structure::Block, Span}; use indexmap::IndexMap; use crate::{ - constants::{ - DESCRIPTION, MARKDOWN, MARKDOWN_FILEPATH, RUNBOOK_COMPLETE_ADDITIONAL_INFO, - SIGNED_MESSAGE_BYTES, SIGNED_TRANSACTION_BYTES, - }, + constants::{DocumentationKey, RunbookKey, SignerKey}, helpers::hcl::{ collect_constructs_references_from_expression, visit_optional_untyped_attribute, }, @@ -37,6 +34,7 @@ use super::{ ActionItemResponseType, ActionItemStatus, Actions, BlockEvent, ProvideInputRequest, ProvidedInputResponse, ReviewedInputResponse, }, + namespace::Namespace, signers::{ consolidate_nested_execution_result, consolidate_signer_activate_future_result, consolidate_signer_future_result, return_synchronous, PrepareSignedNestedExecutionResult, @@ -110,7 +108,7 @@ impl CommandExecutionResult { pub fn runbook_complete_additional_info(&self) -> Option { self.outputs - .get(RUNBOOK_COMPLETE_ADDITIONAL_INFO) + .get(RunbookKey::RunbookCompleteAdditionalInfo.as_ref()) .and_then(|i| i.as_runbook_complete_additional_info()) } } @@ -399,7 +397,7 @@ impl CommandSpecification { pub fn default_inputs() -> Vec { vec![ CommandInput { - name: DESCRIPTION.into(), + name: DocumentationKey::Description.as_ref().into(), documentation: "Allows you to describe and comment steps of your runbook".into(), typing: Type::string(), optional: true, @@ -411,7 +409,7 @@ impl CommandSpecification { self_referencing: false, }, CommandInput { - name: MARKDOWN.into(), + name: DocumentationKey::Markdown.as_ref().into(), documentation: "Allows you to describe and comment steps of your runbook with in-line markdown".into(), typing: Type::string(), optional: true, @@ -423,7 +421,7 @@ impl CommandSpecification { self_referencing: false, }, CommandInput { - name: MARKDOWN_FILEPATH.into(), + name: DocumentationKey::MarkdownFilepath.as_ref().into(), documentation: "Allows you to describe and comment steps of your runbook with a reference to a markdown file in the filesystem".into(), typing: Type::string(), optional: true, @@ -685,7 +683,7 @@ pub struct CommandInstance { pub name: String, pub block: Block, pub package_id: PackageId, - pub namespace: String, + pub namespace: Namespace, pub typing: CommandInstanceType, } pub enum CommandExecutionStatus { @@ -908,13 +906,13 @@ impl CommandInstance { ActionItemResponseType::ProvideSignedTransaction(response) => { match &response.signed_transaction_bytes { Some(bytes) => values - .insert(SIGNED_TRANSACTION_BYTES, Value::string(bytes.clone())), - None => values.insert(SIGNED_TRANSACTION_BYTES, Value::null()), + .insert(SignerKey::SignedTransactionBytes.as_ref(), Value::string(bytes.clone())), + None => values.insert(SignerKey::SignedTransactionBytes.as_ref(), Value::null()), } } ActionItemResponseType::ProvideSignedMessage(response) => { values.insert( - SIGNED_MESSAGE_BYTES, + SignerKey::SignedMessageBytes.as_ref(), Value::string(response.signed_message_bytes.clone()), ); } @@ -1508,7 +1506,7 @@ pub fn add_ctx_to_diag( command_type: String, matcher: String, command_instance_name: String, - namespace: String, + namespace: Namespace, ) -> impl Fn(&Diagnostic) -> Diagnostic { let diag_with_command_ctx = move |diag: &Diagnostic| -> Diagnostic { let mut diag = diag.clone(); diff --git a/crates/txtx-addon-kit/src/types/diagnostics.rs b/crates/txtx-addon-kit/src/types/diagnostics.rs index 4cdf72f22..fb524b2ce 100644 --- a/crates/txtx-addon-kit/src/types/diagnostics.rs +++ b/crates/txtx-addon-kit/src/types/diagnostics.rs @@ -1,6 +1,7 @@ use std::{fmt::Display, ops::Range}; use hcl_edit::{expr::Expression, structure::Block}; +use serde::{Deserialize, Serialize}; use crate::helpers::fs::FileLocation; @@ -27,7 +28,34 @@ pub struct Diagnostic { pub parent_diagnostic: Option>, } +impl Default for Diagnostic { + fn default() -> Self { + Self { + level: DiagnosticLevel::Error, + message: String::new(), + code: None, + span: None, + span_range: None, + location: None, + file: None, + line: None, + column: None, + context: None, + related_locations: Vec::new(), + documentation: None, + suggestion: None, + example: None, + parent_diagnostic: None, + } + } +} + impl Diagnostic { + /// Create a diagnostic with the specified level and message + pub fn with_level(level: DiagnosticLevel, message: String) -> Self { + Self { message, level, ..Default::default() } + } + pub fn error_from_expression( _block: &Block, _expr: Option<&Expression>, @@ -53,63 +81,15 @@ impl Diagnostic { } pub fn error_from_string(message: String) -> Diagnostic { - Diagnostic { - level: DiagnosticLevel::Error, - message, - code: None, - span: None, - span_range: None, - location: None, - file: None, - line: None, - column: None, - context: None, - related_locations: Vec::new(), - documentation: None, - suggestion: None, - example: None, - parent_diagnostic: None, - } + Self::with_level(DiagnosticLevel::Error, message) } pub fn warning_from_string(message: String) -> Diagnostic { - Diagnostic { - level: DiagnosticLevel::Warning, - message, - code: None, - span: None, - span_range: None, - location: None, - file: None, - line: None, - column: None, - context: None, - related_locations: Vec::new(), - documentation: None, - suggestion: None, - example: None, - parent_diagnostic: None, - } + Self::with_level(DiagnosticLevel::Warning, message) } pub fn note_from_string(message: String) -> Diagnostic { - Diagnostic { - level: DiagnosticLevel::Note, - message, - code: None, - span: None, - span_range: None, - location: None, - file: None, - line: None, - column: None, - context: None, - related_locations: Vec::new(), - documentation: None, - suggestion: None, - example: None, - parent_diagnostic: None, - } + Self::with_level(DiagnosticLevel::Note, message) } // Builder methods diff --git a/crates/txtx-addon-kit/src/types/embedded_runbooks/mod.rs b/crates/txtx-addon-kit/src/types/embedded_runbooks/mod.rs index 84c2a2089..f10ba6eb2 100644 --- a/crates/txtx-addon-kit/src/types/embedded_runbooks/mod.rs +++ b/crates/txtx-addon-kit/src/types/embedded_runbooks/mod.rs @@ -10,6 +10,7 @@ use super::{ PreConditionEvaluatableInput, }, diagnostics::Diagnostic, + namespace::Namespace, package::Package, signers::{SignerInstance, SignersState}, stores::ValueStore, @@ -246,7 +247,7 @@ pub struct EmbeddedRunbookValueInputSpecification { pub struct EmbeddedRunbookSignerInputSpecification { pub name: String, pub documentation: String, - pub namespace: String, + pub namespace: Namespace, } pub type SignerName = String; diff --git a/crates/txtx-addon-kit/src/types/frontend.rs b/crates/txtx-addon-kit/src/types/frontend.rs index c10ca7873..c5aab7cb0 100644 --- a/crates/txtx-addon-kit/src/types/frontend.rs +++ b/crates/txtx-addon-kit/src/types/frontend.rs @@ -1,13 +1,14 @@ use std::{borrow::BorrowMut, collections::BTreeMap, fmt::Display}; use crate::{ - constants::ACTION_ITEM_BEGIN_FLOW, + constants::ActionItemKey, types::{stores::AddonDefaults, types::RunbookCompleteAdditionalInfo}, }; use super::{ block_id::BlockId, diagnostics::Diagnostic, + namespace::Namespace, types::{Type, Value}, ConstructDid, Did, }; @@ -118,8 +119,8 @@ impl LogEvent { pub fn namespace(&self) -> &str { match self { - LogEvent::Static(event) => &event.namespace, - LogEvent::Transient(event) => &event.namespace, + LogEvent::Static(event) => event.namespace.as_str(), + LogEvent::Transient(event) => event.namespace.as_str(), } } } @@ -130,7 +131,7 @@ pub struct StaticLogEvent { pub level: LogLevel, pub uuid: Uuid, pub details: LogDetails, - pub namespace: String, + pub namespace: Namespace, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -154,7 +155,7 @@ pub struct TransientLogEvent { pub level: LogLevel, pub uuid: Uuid, pub status: TransientLogEventStatus, - pub namespace: String, + pub namespace: Namespace, } impl TransientLogEvent { @@ -186,7 +187,7 @@ impl TransientLogEvent { uuid: Uuid, summary: impl ToString, message: impl ToString, - namespace: impl ToString, + namespace: impl Into, ) -> Self { TransientLogEvent { level: LogLevel::Info, @@ -195,7 +196,7 @@ impl TransientLogEvent { message: message.to_string(), summary: summary.to_string(), }), - namespace: namespace.to_string(), + namespace: namespace.into(), } } @@ -203,7 +204,7 @@ impl TransientLogEvent { uuid: Uuid, summary: impl ToString, message: impl ToString, - namespace: impl ToString, + namespace: impl Into, ) -> Self { TransientLogEvent { level: LogLevel::Info, @@ -212,7 +213,7 @@ impl TransientLogEvent { message: message.to_string(), summary: summary.to_string(), }), - namespace: namespace.to_string(), + namespace: namespace.into(), } } @@ -220,7 +221,7 @@ impl TransientLogEvent { uuid: Uuid, summary: impl ToString, message: impl ToString, - namespace: impl ToString, + namespace: impl Into, ) -> Self { TransientLogEvent { level: LogLevel::Error, @@ -229,19 +230,19 @@ impl TransientLogEvent { message: message.to_string(), summary: summary.to_string(), }), - namespace: namespace.to_string(), + namespace: namespace.into(), } } } pub struct LogDispatcher { uuid: Uuid, - namespace: String, + namespace: Namespace, tx: channel::Sender, } impl LogDispatcher { pub fn new(uuid: Uuid, namespace: &str, tx: &channel::Sender) -> Self { - LogDispatcher { uuid, namespace: format!("txtx::{}", namespace), tx: tx.clone() } + LogDispatcher { uuid, namespace: Namespace::custom(format!("txtx::{}", namespace)), tx: tx.clone() } } fn log_static(&self, level: LogLevel, summary: impl ToString, message: impl ToString) { @@ -307,7 +308,7 @@ impl BlockEvent { pub fn static_log( level: LogLevel, uuid: Uuid, - namespace: String, + namespace: Namespace, summary: impl ToString, message: impl ToString, ) -> Self { @@ -443,7 +444,7 @@ pub struct ActionItemRequestUpdate { #[derive(Debug, Clone, Serialize)] pub enum ActionItemRequestUpdateIdentifier { Id(BlockId), - ConstructDidWithKey((ConstructDid, String)), + ConstructDidWithKey((ConstructDid, ActionItemKey)), } impl ActionItemRequestUpdate { @@ -454,11 +455,11 @@ impl ActionItemRequestUpdate { action_type: None, } } - pub fn from_context(construct_did: &ConstructDid, internal_key: &str) -> Self { + pub fn from_context(construct_did: &ConstructDid, internal_key: ActionItemKey) -> Self { ActionItemRequestUpdate { id: ActionItemRequestUpdateIdentifier::ConstructDidWithKey(( construct_did.clone(), - internal_key.to_string(), + internal_key, )), action_status: None, action_type: None, @@ -743,7 +744,7 @@ impl ErrorPanelData { let mut action = ActionItemRequestType::DisplayErrorLog(DisplayErrorLogRequest { diagnostic: diag.clone(), }) - .to_request("", "diagnostic") + .to_request("", ActionItemKey::Diagnostic) .with_status(ActionItemStatus::Error(diag.clone())); action.index = (i + 1) as u16; @@ -917,13 +918,13 @@ pub struct ActionItemRequest { pub markdown: Option, pub action_status: ActionItemStatus, pub action_type: ActionItemRequestType, - pub internal_key: String, + pub internal_key: ActionItemKey, } impl ActionItemRequest { fn new( construct_instance_name: &str, - internal_key: &str, + internal_key: ActionItemKey, action_type: ActionItemRequestType, ) -> Self { let mut req = ActionItemRequest { @@ -936,7 +937,7 @@ impl ActionItemRequest { markdown: None, action_status: ActionItemStatus::Todo, action_type, - internal_key: internal_key.to_string(), + internal_key, }; req.recompute_id(); req @@ -1117,7 +1118,7 @@ impl Actions { name: flow_name.to_string(), description: flow_description.clone(), }) - .to_request("", ACTION_ITEM_BEGIN_FLOW) + .to_request("", ActionItemKey::BeginFlow) .with_status(ActionItemStatus::Success(None))], allow_batch_completion: false, }], @@ -1552,7 +1553,7 @@ impl ActionItemRequestType { pub fn to_request( self, construct_instance_name: &str, - internal_key: &str, + internal_key: ActionItemKey, ) -> ActionItemRequest { ActionItemRequest::new(construct_instance_name, internal_key, self) } @@ -1989,7 +1990,7 @@ impl InputOption { pub struct ProvidePublicKeyRequest { pub check_expectation_action_uuid: Option, pub message: String, - pub namespace: String, + pub namespace: Namespace, pub network_id: String, } @@ -2003,7 +2004,7 @@ pub struct ProvideSignedTransactionRequest { pub only_approval_needed: bool, pub payload: Value, pub formatted_payload: Option, - pub namespace: String, + pub namespace: Namespace, pub network_id: String, } @@ -2016,7 +2017,7 @@ impl ProvideSignedTransactionRequest { skippable: false, payload: payload.clone(), formatted_payload: None, - namespace: namespace.to_string(), + namespace: namespace.into(), network_id: network_id.to_string(), only_approval_needed: false, } @@ -2057,7 +2058,7 @@ impl ProvideSignedTransactionRequest { pub struct VerifyThirdPartySignatureRequest { pub check_expectation_action_uuid: Option, pub signer_uuid: ConstructDid, - pub namespace: String, + pub namespace: Namespace, pub network_id: String, pub signer_name: String, pub third_party_name: String, @@ -2082,7 +2083,7 @@ impl VerifyThirdPartySignatureRequest { signer_name: signer_name.to_string(), third_party_name: third_party_name.to_string(), url: url.to_string(), - namespace: namespace.to_string(), + namespace: namespace.into(), network_id: network_id.to_string(), payload: payload.clone(), formatted_payload: None, @@ -2112,7 +2113,7 @@ pub struct SendTransactionRequest { pub expected_signer_address: Option, pub payload: Value, pub formatted_payload: Option, - pub namespace: String, + pub namespace: Namespace, pub network_id: String, } @@ -2124,7 +2125,7 @@ impl SendTransactionRequest { expected_signer_address: None, payload: payload.clone(), formatted_payload: None, - namespace: namespace.to_string(), + namespace: namespace.into(), network_id: network_id.to_string(), } } @@ -2155,7 +2156,7 @@ pub struct ProvideSignedMessageRequest { pub check_expectation_action_uuid: Option, pub signer_uuid: ConstructDid, pub message: Value, - pub namespace: String, + pub namespace: Namespace, pub network_id: String, } @@ -2312,3 +2313,65 @@ impl SupervisorAddonData { Self { addon_name: addon_name.to_string(), rpc_api_url } } } + +#[cfg(test)] +mod tests { + use super::*; + use serde_json; + + #[test] + fn test_action_item_request_serialization_compatibility() { + // Test that ActionItemRequest with ActionItemKey enum serializes correctly + let request = ActionItemRequest::new( + "test-action", + ActionItemKey::CheckAddress, + ActionItemRequestType::ValidateModal, + ); + + let json = serde_json::to_string(&request).unwrap(); + let parsed: serde_json::Value = serde_json::from_str(&json).unwrap(); + + // Verify the internal_key is serialized as "check_address" string + assert_eq!( + parsed["internalKey"].as_str().unwrap(), + "check_address", + "ActionItemKey::CheckAddress should serialize to \"check_address\"" + ); + + // Test deserialization back to the struct + let deserialized: ActionItemRequest = serde_json::from_str(&json).unwrap(); + assert_eq!( + deserialized.internal_key, + ActionItemKey::CheckAddress, + "Should deserialize back to the correct enum variant" + ); + } + + #[test] + fn test_action_item_key_all_variants() { + // Test all ActionItemKey variants serialize to their expected string values + let test_cases = vec![ + (ActionItemKey::CheckAddress, "check_address"), + (ActionItemKey::CheckedAddress, "checked_address"), + (ActionItemKey::CheckBalance, "check_balance"), + (ActionItemKey::IsBalanceChecked, "is_balance_checked"), + (ActionItemKey::BeginFlow, "begin_flow"), + (ActionItemKey::ReExecuteCommand, "re_execute_command"), + (ActionItemKey::Diagnostic, "diagnostic"), + ]; + + for (key, expected) in test_cases { + let json = serde_json::to_string(&key).unwrap(); + let parsed: serde_json::Value = serde_json::from_str(&json).unwrap(); + assert_eq!( + parsed.as_str().unwrap(), + expected, + "ActionItemKey::{:?} should serialize to \"{}\"", key, expected + ); + + // Test round-trip + let deserialized: ActionItemKey = serde_json::from_str(&json).unwrap(); + assert_eq!(deserialized, key, "Should deserialize back to the same variant"); + } + } +} diff --git a/crates/txtx-addon-kit/src/types/function_errors.rs b/crates/txtx-addon-kit/src/types/function_errors.rs new file mode 100644 index 000000000..09bf8736d --- /dev/null +++ b/crates/txtx-addon-kit/src/types/function_errors.rs @@ -0,0 +1,155 @@ +use std::fmt; + +use super::diagnostics::Diagnostic; +use super::namespace::Namespace; +use super::types::Type; + +/// Structured error types for function execution and validation (owned version) +#[derive(Debug, Clone)] +pub enum FunctionError { + MissingArgument { + namespace: Namespace, + function: String, + position: usize, + name: String, + }, + TypeMismatch { + namespace: Namespace, + function: String, + position: usize, + name: String, + expected: Vec, + found: Type, + }, + ExecutionError { + namespace: Namespace, + function: String, + message: String, + }, +} + +/// Borrowing version for creating errors without allocation +#[derive(Debug)] +pub enum FunctionErrorRef<'a> { + MissingArgument { + namespace: &'a str, + function: &'a str, + position: usize, + name: &'a str, + }, + TypeMismatch { + namespace: &'a str, + function: &'a str, + position: usize, + name: &'a str, + expected: &'a [Type], + found: &'a Type, + }, + ExecutionError { + namespace: &'a str, + function: &'a str, + message: &'a str, + }, +} + +impl fmt::Display for FunctionError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FunctionError::MissingArgument { namespace, function, position, name } => { + write!( + f, + "function '{}::{}' missing required argument #{} ({})", + namespace, function, position, name + ) + } + FunctionError::TypeMismatch { namespace, function, position, name, expected, found } => { + let expected_types = expected + .iter() + .map(|t| t.to_string()) + .collect::>() + .join(","); + write!( + f, + "function '{}::{}' argument #{} ({}) should be of type ({}), found {}", + namespace, function, position, name, expected_types, found + ) + } + FunctionError::ExecutionError { namespace, function, message } => { + write!(f, "function '{}::{}': {}", namespace, function, message) + } + } + } +} + +impl<'a> fmt::Display for FunctionErrorRef<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + FunctionErrorRef::MissingArgument { namespace, function, position, name } => { + write!( + f, + "function '{}::{}' missing required argument #{} ({})", + namespace, function, position, name + ) + } + FunctionErrorRef::TypeMismatch { namespace, function, position, name, expected, found } => { + let expected_types = expected + .iter() + .map(|t| t.to_string()) + .collect::>() + .join(","); + write!( + f, + "function '{}::{}' argument #{} ({}) should be of type ({}), found {}", + namespace, function, position, name, expected_types, found + ) + } + FunctionErrorRef::ExecutionError { namespace, function, message } => { + write!(f, "function '{}::{}': {}", namespace, function, message) + } + } + } +} + +impl<'a> From> for FunctionError { + fn from(err: FunctionErrorRef<'a>) -> Self { + match err { + FunctionErrorRef::MissingArgument { namespace, function, position, name } => { + FunctionError::MissingArgument { + namespace: namespace.into(), + function: function.to_string(), + position, + name: name.to_string(), + } + } + FunctionErrorRef::TypeMismatch { namespace, function, position, name, expected, found } => { + FunctionError::TypeMismatch { + namespace: namespace.into(), + function: function.to_string(), + position, + name: name.to_string(), + expected: expected.to_vec(), + found: found.clone(), + } + } + FunctionErrorRef::ExecutionError { namespace, function, message } => { + FunctionError::ExecutionError { + namespace: namespace.into(), + function: function.to_string(), + message: message.to_string(), + } + } + } + } +} + +impl From for Diagnostic { + fn from(err: FunctionError) -> Self { + Diagnostic::error_from_string(err.to_string()) + } +} + +impl<'a> From> for Diagnostic { + fn from(err: FunctionErrorRef<'a>) -> Self { + Diagnostic::error_from_string(err.to_string()) + } +} \ No newline at end of file diff --git a/crates/txtx-addon-kit/src/types/functions.rs b/crates/txtx-addon-kit/src/types/functions.rs index 27f94fb11..df049ab9c 100644 --- a/crates/txtx-addon-kit/src/types/functions.rs +++ b/crates/txtx-addon-kit/src/types/functions.rs @@ -1,5 +1,8 @@ use super::{ diagnostics::Diagnostic, + function_errors::FunctionErrorRef, + namespace::Namespace, + type_compatibility::TypeChecker, types::{Type, Value}, AuthorizationContext, }; @@ -31,100 +34,70 @@ pub struct FunctionSpecification { } type FunctionRunner = - fn(&FunctionSpecification, &AuthorizationContext, &Vec) -> Result; + fn(&FunctionSpecification, &AuthorizationContext, &[Value]) -> Result; type FunctionChecker = - fn(&FunctionSpecification, &AuthorizationContext, &Vec) -> Result; + fn(&FunctionSpecification, &AuthorizationContext, &[Type]) -> Result; pub trait FunctionImplementation { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result; fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result; } pub fn fn_diag_with_ctx( - namespace: String, + namespace: Namespace, ) -> impl Fn(&FunctionSpecification, String) -> Diagnostic { let fn_diag_with_ctx = move |fn_spec: &FunctionSpecification, e: String| -> Diagnostic { - Diagnostic::error_from_string(format!("function '{}::{}': {}", namespace, fn_spec.name, e)) + FunctionErrorRef::ExecutionError { + namespace: namespace.as_str(), + function: &fn_spec.name, + message: &e, + } + .into() }; return fn_diag_with_ctx; } pub fn arg_checker_with_ctx( - namespace: String, -) -> impl Fn(&FunctionSpecification, &Vec) -> Result<(), Diagnostic> { - let fn_checker = - move |fn_spec: &FunctionSpecification, args: &Vec| -> Result<(), Diagnostic> { - for (i, input) in fn_spec.inputs.iter().enumerate() { - if !input.optional { - if let Some(arg) = args.get(i) { - let mut has_type_match = false; - for typing in input.typing.iter() { - let arg_type = arg.get_type(); - // special case if both are addons: we don't want to be so strict that - // we check the addon id here - if let Type::Addon(_) = arg_type { - if let Type::Addon(_) = typing { - has_type_match = true; - break; - } - } - // special case for empty arrays - if let Type::Array(_) = arg_type { - if arg.expect_array().len() == 0 { - has_type_match = true; - break; - } - } - // we don't have an "any" type, so if the array is of type null, we won't check types - if let Type::Array(inner) = typing { - if let Type::Null(_) = **inner { - has_type_match = true; - break; - } - } - if arg_type.eq(typing) { - has_type_match = true; - break; - } - } - if !has_type_match { - let expected_types = input - .typing - .iter() - .map(|t| t.to_string()) - .collect::>() - .join(","); - return Err(Diagnostic::error_from_string(format!( - "function '{}::{}' argument #{} ({}) should be of type ({}), found {}", - namespace, - fn_spec.name, - i + 1, - input.name, - expected_types, - arg.get_type().to_string() - ))); - } - } else { - return Err(Diagnostic::error_from_string(format!( - "function '{}::{}' missing required argument #{} ({})", - namespace, - fn_spec.name, - i + 1, - input.name, - ))); - } + namespace: Namespace, +) -> impl Fn(&FunctionSpecification, &[Value]) -> Result<(), Diagnostic> { + move |fn_spec, args| { + for (i, input) in fn_spec.inputs.iter().enumerate() { + if input.optional { + continue; + } + + let arg = args.get(i).ok_or_else(|| { + Diagnostic::from(FunctionErrorRef::MissingArgument { + namespace: namespace.as_str(), + function: &fn_spec.name, + position: i + 1, + name: &input.name, + }) + })?; + + let type_matches = TypeChecker::matches_any(arg, &input.typing); + + if !type_matches { + return Err(FunctionErrorRef::TypeMismatch { + namespace: namespace.as_str(), + function: &fn_spec.name, + position: i + 1, + name: &input.name, + expected: &input.typing, + found: &arg.get_type(), } + .into()); } - Ok(()) - }; - return fn_checker; + } + Ok(()) + } } diff --git a/crates/txtx-addon-kit/src/types/mod.rs b/crates/txtx-addon-kit/src/types/mod.rs index ebd92bc5c..9d9418f86 100644 --- a/crates/txtx-addon-kit/src/types/mod.rs +++ b/crates/txtx-addon-kit/src/types/mod.rs @@ -29,10 +29,13 @@ pub use diagnostic_types::{DiagnosticLevel, DiagnosticSpan, RelatedLocation}; pub mod embedded_runbooks; pub mod frontend; +pub mod function_errors; pub mod functions; +pub mod namespace; pub mod package; pub mod signers; pub mod stores; +pub mod type_compatibility; pub mod types; pub const CACHED_NONCE: &str = "cached_nonce"; diff --git a/crates/txtx-addon-kit/src/types/namespace.rs b/crates/txtx-addon-kit/src/types/namespace.rs new file mode 100644 index 000000000..1fbd5438f --- /dev/null +++ b/crates/txtx-addon-kit/src/types/namespace.rs @@ -0,0 +1,130 @@ +use serde::{Deserialize, Serialize}; +use std::fmt; +use strum_macros::{AsRefStr, Display as StrumDisplay, EnumString, IntoStaticStr}; + +/// Namespace types for txtx addons and functions +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] +#[serde(untagged)] +pub enum Namespace { + /// Well-known standard namespace + WellKnown(WellKnownNamespace), + /// Custom addon namespace + Custom(String), +} + +/// Well-known namespaces that have special meaning in txtx +#[derive( + Debug, + Clone, + Copy, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + Serialize, + Deserialize, + AsRefStr, + StrumDisplay, + EnumString, + IntoStaticStr, +)] +#[strum(serialize_all = "lowercase")] +#[serde(rename_all = "lowercase")] +pub enum WellKnownNamespace { + /// Standard library namespace + Std, +} + +impl Namespace { + /// Create a standard namespace + pub fn std() -> Self { + Namespace::WellKnown(WellKnownNamespace::Std) + } + + /// Create a custom namespace + pub fn custom(name: impl Into) -> Self { + Namespace::Custom(name.into()) + } + + /// Get the string representation of the namespace + pub fn as_str(&self) -> &str { + match self { + Namespace::WellKnown(wk) => wk.as_ref(), + Namespace::Custom(s) => s.as_str(), + } + } + + /// Check if this is the standard namespace + pub fn is_std(&self) -> bool { + matches!(self, Namespace::WellKnown(WellKnownNamespace::Std)) + } +} + +impl fmt::Display for Namespace { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl From for Namespace { + fn from(s: String) -> Self { + match s.as_str() { + "std" => Namespace::std(), + _ => Namespace::Custom(s), + } + } +} + +impl From<&str> for Namespace { + fn from(s: &str) -> Self { + match s { + "std" => Namespace::std(), + _ => Namespace::Custom(s.to_string()), + } + } +} + +impl From<&String> for Namespace { + fn from(s: &String) -> Self { + Namespace::from(s.as_str()) + } +} + +impl From<&Namespace> for Namespace { + fn from(ns: &Namespace) -> Self { + ns.clone() + } +} + +impl AsRef for Namespace { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +// Allow comparison with &str +impl PartialEq<&str> for Namespace { + fn eq(&self, other: &&str) -> bool { + self.as_str() == *other + } +} + +impl PartialEq for &str { + fn eq(&self, other: &Namespace) -> bool { + *self == other.as_str() + } +} + +// Allow comparison with String +impl PartialEq for Namespace { + fn eq(&self, other: &String) -> bool { + self.as_str() == other.as_str() + } +} + +impl PartialEq for String { + fn eq(&self, other: &Namespace) -> bool { + self.as_str() == other.as_str() + } +} \ No newline at end of file diff --git a/crates/txtx-addon-kit/src/types/signers.rs b/crates/txtx-addon-kit/src/types/signers.rs index 287800b5f..0071e48c8 100644 --- a/crates/txtx-addon-kit/src/types/signers.rs +++ b/crates/txtx-addon-kit/src/types/signers.rs @@ -1,7 +1,4 @@ -use crate::constants::{ - ACTION_ITEM_CHECK_ADDRESS, ACTION_ITEM_CHECK_BALANCE, CHECKED_ADDRESS, IS_BALANCE_CHECKED, - PROVIDE_PUBLIC_KEY_ACTION_RESULT, -}; +use crate::constants::{ActionItemKey, SignerKey}; use crate::helpers::hcl::visit_optional_untyped_attribute; use crate::types::stores::ValueStore; use futures::future; @@ -13,6 +10,7 @@ use super::{ commands::{ CommandExecutionResult, CommandInput, CommandInputsEvaluationResult, CommandOutput, }, + namespace::Namespace, diagnostics::Diagnostic, frontend::{ ActionItemRequest, ActionItemResponse, ActionItemResponseType, Actions, BlockEvent, @@ -314,7 +312,7 @@ pub struct SignerInstance { pub name: String, pub block: Block, pub package_id: PackageId, - pub namespace: String, + pub namespace: Namespace, } impl SignerInstance { @@ -384,7 +382,7 @@ impl SignerInstance { match payload { ActionItemResponseType::ProvidePublicKey(update) => { values.insert( - PROVIDE_PUBLIC_KEY_ACTION_RESULT, + SignerKey::ProvidePublicKeyActionResult.as_ref(), Value::string(update.public_key.clone()), ); } @@ -396,22 +394,26 @@ impl SignerInstance { if let Some(signer_did) = &request.construct_did { let mut signer_state = signers.pop_signer_state(signer_did).unwrap(); - if request.internal_key == ACTION_ITEM_CHECK_ADDRESS { - if response.value_checked { - let data = request - .action_type - .as_review_input() - .expect("review input action item"); + match request.internal_key { + ActionItemKey::CheckAddress => { + if response.value_checked { + let data = request + .action_type + .as_review_input() + .expect("review input action item"); + signer_state.insert( + ActionItemKey::CheckedAddress.as_ref(), + Value::string(data.value.to_string()), + ); + } + } + ActionItemKey::CheckBalance => { signer_state.insert( - CHECKED_ADDRESS, - Value::string(data.value.to_string()), + ActionItemKey::IsBalanceChecked.as_ref(), + Value::bool(response.value_checked), ); } - } else if request.internal_key == ACTION_ITEM_CHECK_BALANCE { - signer_state.insert( - IS_BALANCE_CHECKED, - Value::bool(response.value_checked), - ); + _ => {} // Handle other cases } signers.push_signer_state(signer_state); } diff --git a/crates/txtx-addon-kit/src/types/stores.rs b/crates/txtx-addon-kit/src/types/stores.rs index e1deff418..a7ca7cf5d 100644 --- a/crates/txtx-addon-kit/src/types/stores.rs +++ b/crates/txtx-addon-kit/src/types/stores.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use indexmap::IndexMap; use crate::{ - constants::{MARKDOWN, MARKDOWN_FILEPATH, THIRD_PARTY_SIGNATURE_STATUS}, + constants::{DocumentationKey, RunbookKey}, types::{types::ThirdPartySignatureStatus, AuthorizationContext}, }; @@ -111,7 +111,8 @@ impl ValueStore { } // Expected values: if both inputs/defaults yield an error, we should return the input's Diagnostic - pub fn get_expected_value(&self, key: &str) -> Result<&Value, Diagnostic> { + pub fn get_expected_value(&self, key: impl AsRef) -> Result<&Value, Diagnostic> { + let key = key.as_ref(); match self.inputs.get_expected_value(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_value(key).or(Err(e)), @@ -119,7 +120,8 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_construct_did(&self, key: &str) -> Result { + pub fn get_expected_construct_did(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); match self.inputs.get_expected_construct_did(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_construct_did(key).or(Err(e)), @@ -127,7 +129,8 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_string(&self, key: &str) -> Result<&str, Diagnostic> { + pub fn get_expected_string(&self, key: impl AsRef) -> Result<&str, Diagnostic> { + let key = key.as_ref(); match self.inputs.get_expected_string(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_string(key).or(Err(e)), @@ -135,7 +138,8 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_integer(&self, key: &str) -> Result { + pub fn get_expected_integer(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); match self.inputs.get_expected_integer(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_integer(key).or(Err(e)), @@ -143,14 +147,16 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_uint(&self, key: &str) -> Result { + pub fn get_expected_uint(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); match self.inputs.get_expected_uint(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_uint(key).or(Err(e)), } .map_err(|e| e) } - pub fn get_expected_bool(&self, key: &str) -> Result { + pub fn get_expected_bool(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); match self.inputs.get_expected_bool(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_bool(key).or(Err(e)), @@ -158,7 +164,8 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_array(&self, key: &str) -> Result<&Vec, Diagnostic> { + pub fn get_expected_array(&self, key: impl AsRef) -> Result<&Vec, Diagnostic> { + let key = key.as_ref(); match self.inputs.get_expected_array(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_array(key).or(Err(e)), @@ -166,7 +173,8 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_map(&self, key: &str) -> Result<&Vec, Diagnostic> { + pub fn get_expected_map(&self, key: impl AsRef) -> Result<&Vec, Diagnostic> { + let key = key.as_ref(); match self.inputs.get_expected_map(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_map(key).or(Err(e)), @@ -174,7 +182,8 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_object(&self, key: &str) -> Result, Diagnostic> { + pub fn get_expected_object(&self, key: impl AsRef) -> Result, Diagnostic> { + let key = key.as_ref(); match self.inputs.get_expected_object(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_object(key).or(Err(e)), @@ -182,7 +191,8 @@ impl ValueStore { .map_err(|e| e) } - pub fn get_expected_buffer_bytes(&self, key: &str) -> Result, Diagnostic> { + pub fn get_expected_buffer_bytes(&self, key: impl AsRef) -> Result, Diagnostic> { + let key = key.as_ref(); match self.inputs.get_expected_buffer_bytes(key) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_buffer_bytes(key).or(Err(e)), @@ -191,21 +201,25 @@ impl ValueStore { } // Optional values - pub fn get_string(&self, key: &str) -> Option<&str> { + pub fn get_string(&self, key: impl AsRef) -> Option<&str> { + let key = key.as_ref(); self.inputs.get_string(key).or(self.defaults.get_string(key)) } - pub fn get_value(&self, key: &str) -> Option<&Value> { + pub fn get_value(&self, key: impl AsRef) -> Option<&Value> { + let key = key.as_ref(); self.inputs.get_value(key).or(self.defaults.get_value(key)) } - pub fn get_uint(&self, key: &str) -> Result, String> { + pub fn get_uint(&self, key: impl AsRef) -> Result, String> { + let key = key.as_ref(); self.inputs .get_uint(key) .map_or_else(|_| self.defaults.get_uint(key).map_err(|e| e), |val| Ok(val)) } - pub fn get_u8(&self, key: &str) -> Result, String> { + pub fn get_u8(&self, key: impl AsRef) -> Result, String> { + let key = key.as_ref(); self.inputs .get_integer(key) .or(self.defaults.get_integer(key)) @@ -215,7 +229,8 @@ impl ValueStore { .transpose() } - pub fn get_bool(&self, key: &str) -> Option { + pub fn get_bool(&self, key: impl AsRef) -> Option { + let key = key.as_ref(); self.inputs.get_bool(key).or(self.defaults.get_bool(key)) } @@ -225,11 +240,13 @@ impl ValueStore { .or(self.defaults.get_third_party_signature_status()) } - pub fn get_integer(&self, key: &str) -> Option { + pub fn get_integer(&self, key: impl AsRef) -> Option { + let key = key.as_ref(); self.inputs.get_integer(key).or(self.defaults.get_integer(key)) } - pub fn get_i64(&self, key: &str) -> Result, Diagnostic> { + pub fn get_i64(&self, key: impl AsRef) -> Result, Diagnostic> { + let key = key.as_ref(); self.inputs .get_integer(key) .or(self.defaults.get_integer(key)) @@ -239,40 +256,47 @@ impl ValueStore { .transpose() } - pub fn get_array(&self, key: &str) -> Option<&Box>> { + pub fn get_array(&self, key: impl AsRef) -> Option<&Box>> { + let key = key.as_ref(); self.inputs.get_array(key).or(self.defaults.get_array(key)) } - pub fn get_map(&self, key: &str) -> Option<&Box>> { + pub fn get_map(&self, key: impl AsRef) -> Option<&Box>> { + let key = key.as_ref(); self.inputs.get_map(key).or(self.defaults.get_map(key)) } - pub fn get_object(&self, key: &str) -> Option<&IndexMap> { + pub fn get_object(&self, key: impl AsRef) -> Option<&IndexMap> { + let key = key.as_ref(); self.inputs.get_object(key).or(self.defaults.get_object(key)) } // Scoped values - pub fn insert_scoped_value(&mut self, scope: &str, key: &str, value: Value) { - self.inputs.insert(&format!("{}:{}", scope, key), value); + pub fn insert_scoped_value(&mut self, scope: &str, key: impl ToString, value: Value) { + self.inputs.insert(format!("{}:{}", scope, key.to_string()), value); } - pub fn clear_scoped_value(&mut self, scope: &str, key: &str) { + pub fn clear_scoped_value(&mut self, scope: &str, key: impl AsRef) { + let key = key.as_ref(); self.inputs.store.swap_remove(&format!("{}:{}", scope, key)); } - pub fn remove_scoped_value(&mut self, scope: &str, key: &str) -> Option { + pub fn remove_scoped_value(&mut self, scope: &str, key: impl AsRef) -> Option { + let key = key.as_ref(); self.inputs.store.shift_remove(&format!("{}:{}", scope, key)) } - pub fn get_scoped_value(&self, scope: &str, key: &str) -> Option<&Value> { + pub fn get_scoped_value(&self, scope: &str, key: impl AsRef) -> Option<&Value> { + let key = key.as_ref(); self.inputs.get_value(&format!("{}:{}", scope, key)) } - pub fn get_scoped_integer(&self, scope: &str, key: &str) -> Option { + pub fn get_scoped_integer(&self, scope: &str, key: impl AsRef) -> Option { + let key = key.as_ref(); self.inputs.get_integer(&format!("{}:{}", scope, key)) } - pub fn get_scoped_bool(&self, scope: &str, key: &str) -> Option { + pub fn get_scoped_bool(&self, scope: &str, key: impl AsRef) -> Option { if let Some(Value::Bool(bool)) = self.get_scoped_value(scope, key) { Some(*bool) } else { @@ -280,7 +304,8 @@ impl ValueStore { } } - pub fn get_expected_scoped_value(&self, scope: &str, key: &str) -> Result<&Value, Diagnostic> { + pub fn get_expected_scoped_value(&self, scope: &str, key: impl AsRef) -> Result<&Value, Diagnostic> { + let key = key.as_ref(); match self.inputs.get_expected_value(&format!("{}:{}", scope, key)) { Ok(val) => Ok(val), Err(e) => self.defaults.get_expected_value(&format!("{}:{}", scope, key)).or(Err(e)), @@ -307,16 +332,18 @@ impl ValueStore { self.inputs.clear_autoincrementable_nonce(); } - pub fn set_autoincrementable_nonce(&mut self, key: &str, initial_value: u64) { + pub fn set_autoincrementable_nonce(&mut self, key: impl AsRef, initial_value: u64) { + let key = key.as_ref(); self.inputs.set_autoincrementable_nonce(key, initial_value); } - pub fn get_autoincremented_nonce(&mut self, key: &str) -> Option { + pub fn get_autoincremented_nonce(&mut self, key: impl AsRef) -> Option { + let key = key.as_ref(); self.inputs.get_autoincremented_nonce(key) } // General helpers - pub fn insert(&mut self, key: &str, value: Value) { + pub fn insert(&mut self, key: impl ToString, value: Value) { self.inputs.insert(key, value); } @@ -327,7 +354,8 @@ impl ValueStore { pub fn len(&self) -> usize { self.inputs.len() } - pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> { + pub fn get_mut(&mut self, key: impl AsRef) -> Option<&mut Value> { + let key = key.as_ref(); self.inputs.get_mut(key) } @@ -346,10 +374,10 @@ impl ValueStore { ) -> Result, Diagnostic> { let markdown = self .inputs - .get_value(MARKDOWN) + .get_value(DocumentationKey::Markdown.as_ref()) .and_then(|v| v.as_string().map(|s| s.to_string())) .or_else(|| { - self.defaults.get_value(MARKDOWN).and_then(|v| v.as_string().map(|s| s.to_string())) + self.defaults.get_value(DocumentationKey::Markdown.as_ref()).and_then(|v| v.as_string().map(|s| s.to_string())) }); if markdown.is_some() { @@ -358,8 +386,8 @@ impl ValueStore { let Some(markdown_filepath) = self .inputs - .get_string(MARKDOWN_FILEPATH) - .or_else(|| self.defaults.get_string(MARKDOWN_FILEPATH)) + .get_string(DocumentationKey::MarkdownFilepath.as_ref()) + .or_else(|| self.defaults.get_string(DocumentationKey::MarkdownFilepath.as_ref())) else { return Ok(None); }; @@ -396,13 +424,14 @@ impl AddonDefaults { pub fn new(key: &str) -> AddonDefaults { AddonDefaults { store: ValueMap::new(), name: key.to_string(), uuid: Did::zero() } } - pub fn insert(&mut self, key: &str, value: Value) { + pub fn insert(&mut self, key: impl ToString, value: Value) { self.store.insert(key, value); } pub fn iter(&self) -> indexmap::map::Iter { self.store.iter() } - pub fn contains_key(&self, key: &str) -> bool { + pub fn contains_key(&self, key: impl AsRef) -> bool { + let key = key.as_ref(); self.store.contains_key(key) } } @@ -428,7 +457,8 @@ impl ValueMap { self } - pub fn get_expected_value(&self, key: &str) -> Result<&Value, Diagnostic> { + pub fn get_expected_value(&self, key: impl AsRef) -> Result<&Value, Diagnostic> { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve value '{}'", @@ -438,7 +468,8 @@ impl ValueMap { Ok(value) } - pub fn get_expected_bool(&self, key: &str) -> Result { + pub fn get_expected_bool(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve bool '{}'", @@ -454,13 +485,15 @@ impl ValueMap { Ok(value) } - pub fn get_expected_construct_did(&self, key: &str) -> Result { + pub fn get_expected_construct_did(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); let value = self.get_expected_string(key)?; let construct_did = ConstructDid::from_hex_string(value); Ok(construct_did) } - pub fn get_expected_string(&self, key: &str) -> Result<&str, Diagnostic> { + pub fn get_expected_string(&self, key: impl AsRef) -> Result<&str, Diagnostic> { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve string '{}'", @@ -476,7 +509,8 @@ impl ValueMap { Ok(value) } - pub fn get_expected_array(&self, key: &str) -> Result<&Vec, Diagnostic> { + pub fn get_expected_array(&self, key: impl AsRef) -> Result<&Vec, Diagnostic> { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve array '{}'", @@ -492,7 +526,8 @@ impl ValueMap { Ok(value) } - pub fn get_expected_map(&self, key: &str) -> Result<&Vec, Diagnostic> { + pub fn get_expected_map(&self, key: impl AsRef) -> Result<&Vec, Diagnostic> { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string( format!("unable to retrieve map '{}'", key,), @@ -507,7 +542,8 @@ impl ValueMap { Ok(value) } - pub fn get_expected_object(&self, key: &str) -> Result, Diagnostic> { + pub fn get_expected_object(&self, key: impl AsRef) -> Result, Diagnostic> { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve object '{}'", @@ -523,7 +559,8 @@ impl ValueMap { Ok(result.clone()) } - pub fn get_expected_integer(&self, key: &str) -> Result { + pub fn get_expected_integer(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve integer '{}'", @@ -539,7 +576,8 @@ impl ValueMap { Ok(value) } - pub fn get_expected_uint(&self, key: &str) -> Result { + pub fn get_expected_uint(&self, key: impl AsRef) -> Result { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve uint '{}'", @@ -560,7 +598,8 @@ impl ValueMap { }) } - pub fn get_expected_buffer_bytes(&self, key: &str) -> Result, Diagnostic> { + pub fn get_expected_buffer_bytes(&self, key: impl AsRef) -> Result, Diagnostic> { + let key = key.as_ref(); let Some(value) = self.store.get(key) else { return Err(Diagnostic::error_from_string(format!( "unable to retrieve buffer '{}'", @@ -589,11 +628,12 @@ impl ValueMap { Ok(bytes) } - pub fn get_scoped_value(&self, scope: &str, key: &str) -> Option<&Value> { + pub fn get_scoped_value(&self, scope: &str, key: impl AsRef) -> Option<&Value> { + let key = key.as_ref(); self.store.get(&format!("{}:{}", scope, key)) } - pub fn get_scoped_bool(&self, scope: &str, key: &str) -> Option { + pub fn get_scoped_bool(&self, scope: &str, key: impl AsRef) -> Option { if let Some(Value::Bool(bool)) = self.get_scoped_value(scope, key) { Some(*bool) } else { @@ -605,7 +645,8 @@ impl ValueMap { self.store.swap_remove(&format!("{}:autoincrement", CACHED_NONCE)); } - pub fn set_autoincrementable_nonce(&mut self, key: &str, initial_value: u64) { + pub fn set_autoincrementable_nonce(&mut self, key: impl AsRef, initial_value: u64) { + let key = key.as_ref(); self.store.insert( format!("{}:autoincrement", CACHED_NONCE), Value::integer((initial_value + 1).into()), @@ -614,7 +655,8 @@ impl ValueMap { .insert(format!("{}:{}", CACHED_NONCE, key), Value::integer(initial_value.into())); } - pub fn get_autoincremented_nonce(&mut self, key: &str) -> Option { + pub fn get_autoincremented_nonce(&mut self, key: impl AsRef) -> Option { + let key = key.as_ref(); let value = match self.store.get(&format!("{}:{}", CACHED_NONCE, key)) { None => match self.store.get(&format!("{}:autoincrement", CACHED_NONCE)) { None => return None, @@ -638,48 +680,56 @@ impl ValueMap { Some(value) } - pub fn get_value(&self, key: &str) -> Option<&Value> { + pub fn get_value(&self, key: impl AsRef) -> Option<&Value> { + let key = key.as_ref(); self.store.get(key) } - pub fn get_uint(&self, key: &str) -> Result, String> { + pub fn get_uint(&self, key: impl AsRef) -> Result, String> { + let key = key.as_ref(); self.store.get(key).map(|v| v.expect_uint()).transpose() } - pub fn get_integer(&self, key: &str) -> Option { + pub fn get_integer(&self, key: impl AsRef) -> Option { + let key = key.as_ref(); self.store.get(key).and_then(|v| v.as_integer()) } - pub fn get_string(&self, key: &str) -> Option<&str> { + pub fn get_string(&self, key: impl AsRef) -> Option<&str> { + let key = key.as_ref(); self.store.get(key).and_then(|v| v.as_string()) } - pub fn get_bool(&self, key: &str) -> Option { + pub fn get_bool(&self, key: impl AsRef) -> Option { + let key = key.as_ref(); self.store.get(key).and_then(|v| v.as_bool()) } pub fn get_third_party_signature_status(&self) -> Option { self.store - .get(THIRD_PARTY_SIGNATURE_STATUS) + .get(RunbookKey::ThirdPartySignatureStatus.as_ref()) .and_then(|v| v.as_third_party_signature_status()) } - pub fn get_array(&self, key: &str) -> Option<&Box>> { + pub fn get_array(&self, key: impl AsRef) -> Option<&Box>> { + let key = key.as_ref(); self.store.get(key).and_then(|v| v.as_array()) } - pub fn get_map(&self, key: &str) -> Option<&Box>> { + pub fn get_map(&self, key: impl AsRef) -> Option<&Box>> { + let key = key.as_ref(); self.store.get(key).and_then(|v| v.as_array()) } - pub fn get_object(&self, key: &str) -> Option<&IndexMap> { + pub fn get_object(&self, key: impl AsRef) -> Option<&IndexMap> { + let key = key.as_ref(); self.store.get(key).and_then(|v| v.as_object()) } - pub fn insert_scoped_value(&mut self, scope: &str, key: &str, value: Value) { - self.store.insert(format!("{}:{}", scope, key), value); + pub fn insert_scoped_value(&mut self, scope: &str, key: impl ToString, value: Value) { + self.store.insert(format!("{}:{}", scope, key.to_string()), value); } - pub fn insert(&mut self, key: &str, value: Value) { + pub fn insert(&mut self, key: impl ToString, value: Value) { self.store.insert(key.to_string(), value); } @@ -690,10 +740,12 @@ impl ValueMap { pub fn len(&self) -> usize { self.store.len() } - pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> { + pub fn get_mut(&mut self, key: impl AsRef) -> Option<&mut Value> { + let key = key.as_ref(); self.store.get_mut(key) } - pub fn contains_key(&self, key: &str) -> bool { + pub fn contains_key(&self, key: impl AsRef) -> bool { + let key = key.as_ref(); self.store.contains_key(key) } } diff --git a/crates/txtx-addon-kit/src/types/type_compatibility.rs b/crates/txtx-addon-kit/src/types/type_compatibility.rs new file mode 100644 index 000000000..c5b932af2 --- /dev/null +++ b/crates/txtx-addon-kit/src/types/type_compatibility.rs @@ -0,0 +1,83 @@ +use super::types::{Type, Value}; + +/// Type compatibility checking for txtx types +pub struct TypeChecker; + +impl TypeChecker { + /// Check if a value matches any of the expected types + pub fn matches_any(value: &Value, expected_types: &[Type]) -> bool { + expected_types.iter().any(|expected| Self::matches(value, expected)) + } + + /// Check if a value matches a specific type + pub fn matches(value: &Value, expected_type: &Type) -> bool { + match (value.get_type(), expected_type) { + // Both are addons - any addon matches any addon type + // We don't check the specific addon ID for flexibility + (Type::Addon(_), Type::Addon(_)) => true, + + // Empty arrays match any array type + (Type::Array(_), _) if value.expect_array().is_empty() => true, + + // Array with null inner type accepts any array + // This is our "any array" pattern + (_, Type::Array(inner)) if matches!(**inner, Type::Null(_)) => true, + + // Otherwise require exact type match + (actual_type, expected) => actual_type.eq(expected), + } + } + + /// Check if two types are compatible (for type checking without values) + pub fn types_compatible(actual: &Type, expected: &Type) -> bool { + match (actual, expected) { + // Any addon type matches any other addon type + (Type::Addon(_), Type::Addon(_)) => true, + + // Array with null inner type accepts any array + (Type::Array(_), Type::Array(inner)) if matches!(**inner, Type::Null(_)) => true, + + // Otherwise require exact match + _ => actual == expected, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_addon_compatibility() { + let value = Value::addon(vec![1, 2, 3], "addon1"); + let addon_type = Type::Addon("addon2".to_string()); + + assert!(TypeChecker::matches(&value, &addon_type)); + } + + #[test] + fn test_empty_array_compatibility() { + let value = Value::array(vec![]); + let array_type = Type::Array(Box::new(Type::String)); + + assert!(TypeChecker::matches(&value, &array_type)); + } + + #[test] + fn test_any_array_compatibility() { + let value = Value::array(vec![Value::string("test".to_string())]); + let any_array_type = Type::Array(Box::new(Type::Null(None))); + + assert!(TypeChecker::matches(&value, &any_array_type)); + } + + #[test] + fn test_exact_type_match() { + let value = Value::string("test".to_string()); + let string_type = Type::String; + let int_type = Type::Integer; + + assert!(TypeChecker::matches(&value, &string_type)); + assert!(!TypeChecker::matches(&value, &int_type)); + } +} \ No newline at end of file diff --git a/crates/txtx-addon-kit/src/types/types.rs b/crates/txtx-addon-kit/src/types/types.rs index 6dd664925..3932393e2 100644 --- a/crates/txtx-addon-kit/src/types/types.rs +++ b/crates/txtx-addon-kit/src/types/types.rs @@ -8,13 +8,14 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use serde_json::{Map, Value as JsonValue}; use std::collections::VecDeque; use std::fmt::{self, Debug}; +use strum_macros::Display as StrumDisplay; use crate::helpers::hcl::{ collect_constructs_references_from_block, collect_constructs_references_from_expression, visit_optional_untyped_attribute, }; use crate::types::frontend::{LogDetails, LogEvent, StaticLogEvent}; -use crate::types::ConstructDid; +use crate::types::{namespace::Namespace, ConstructDid}; use super::diagnostics::Diagnostic; use super::{Did, EvaluatableInput}; @@ -255,6 +256,7 @@ impl RunbookCompleteAdditionalInfo { impl Into> for RunbookCompleteAdditionalInfo { fn into(self) -> Vec { + let namespace: Namespace = self.construct_name.into(); self.details .split("\n") .filter_map(|line| { @@ -269,7 +271,7 @@ impl Into> for RunbookCompleteAdditionalInfo { summary: self.title.clone(), }, uuid: self.construct_did.as_uuid(), - namespace: self.construct_name.clone(), + namespace: namespace.clone(), })) } }) @@ -1021,17 +1023,26 @@ impl fmt::Debug for AddonData { } } -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Debug, Eq, PartialEq, Hash, StrumDisplay)] pub enum Type { + #[strum(serialize = "bool")] Bool, Null(Option>), + #[strum(serialize = "integer")] Integer, + #[strum(serialize = "float")] Float, + #[strum(serialize = "string")] String, + #[strum(serialize = "buffer")] Buffer, + #[strum(to_string = "object")] Object(ObjectDefinition), + #[strum(to_string = "addon({0})")] Addon(String), + #[strum(to_string = "array[{0}]")] Array(Box), + #[strum(to_string = "map")] Map(ObjectDefinition), } @@ -1275,6 +1286,7 @@ impl Type { } } +// Custom to_string() needed because Null has a parameterized inner type impl Type { pub fn to_string(&self) -> String { match self { diff --git a/crates/txtx-cli/Cargo.toml b/crates/txtx-cli/Cargo.toml index 3570ffe69..07f875162 100644 --- a/crates/txtx-cli/Cargo.toml +++ b/crates/txtx-cli/Cargo.toml @@ -61,7 +61,7 @@ thiserror = "1.0" strum = { version = "0.26", features = ["derive"] } [features] -default = ["cli", "supervisor_ui"] +default = ["cli"] cli = ["clap", "clap_generate", "ctrlc", "hiro-system-kit/log"] supervisor_ui = ["txtx-supervisor-ui"] txtx_serve = ["txtx-serve"] diff --git a/crates/txtx-cli/src/cli/runbooks/mod.rs b/crates/txtx-cli/src/cli/runbooks/mod.rs index e85dcebc9..c2006c821 100644 --- a/crates/txtx-cli/src/cli/runbooks/mod.rs +++ b/crates/txtx-cli/src/cli/runbooks/mod.rs @@ -1231,7 +1231,7 @@ fn handle_log_event( persist_log( &message, &summary, - &static_log_event.namespace, + static_log_event.namespace.as_ref(), &static_log_event.level, &log_filter, true, @@ -1249,7 +1249,7 @@ fn handle_log_event( pb.enable_steady_tick(Duration::from_millis(80)); pb.set_message(format!("{} {}", yellow!(&summary), message)); active_spinners.insert(log.uuid, pb); - persist_log(&message, &summary, &log.namespace, &log.level, &log_filter, false); + persist_log(&message, &summary, log.namespace.as_ref(), &log.level, &log_filter, false); } } TransientLogEventStatus::Success(LogDetails { summary, message }) => { @@ -1260,7 +1260,7 @@ fn handle_log_event( println!("{}", msg); } - persist_log(&message, &summary, &log.namespace, &log.level, &log_filter, false); + persist_log(&message, &summary, log.namespace.as_ref(), &log.level, &log_filter, false); } TransientLogEventStatus::Failure(LogDetails { summary, message }) => { let msg = format!("{} {}: {}", red!("x"), red!(&summary), message); @@ -1269,7 +1269,7 @@ fn handle_log_event( } else { println!("{}", msg); } - persist_log(&message, &summary, &log.namespace, &log.level, &log_filter, false); + persist_log(&message, &summary, log.namespace.as_ref(), &log.level, &log_filter, false); } }, } diff --git a/crates/txtx-cloud/src/publish.rs b/crates/txtx-cloud/src/publish.rs index 59ecc631f..3bf56eff8 100644 --- a/crates/txtx-cloud/src/publish.rs +++ b/crates/txtx-cloud/src/publish.rs @@ -210,7 +210,7 @@ impl CloudServiceRunbookDocumentation { signers.push(CloudServiceSignerDocumentation { name: signer.name.clone(), description: Some(signer.documentation.clone()), - namespace: signer.namespace.clone(), + namespace: signer.namespace.to_string(), }); } } diff --git a/crates/txtx-core/src/constants.rs b/crates/txtx-core/src/constants.rs index 75e28f531..c8befa04b 100644 --- a/crates/txtx-core/src/constants.rs +++ b/crates/txtx-core/src/constants.rs @@ -1,7 +1 @@ pub const NAMESPACE: &str = "std"; - -// Action item keys -pub const ACTION_ITEM_ENV: &str = "env"; -pub const ACTION_ITEM_GENESIS: &str = "genesis"; -pub const ACTION_ITEM_CHECK_OUTPUT: &str = "check_output"; -pub const ACTION_ITEM_VALIDATE_BLOCK: &str = "validate_block"; diff --git a/crates/txtx-core/src/eval/mod.rs b/crates/txtx-core/src/eval/mod.rs index 01cf5aa1a..c5f72c8c8 100644 --- a/crates/txtx-core/src/eval/mod.rs +++ b/crates/txtx-core/src/eval/mod.rs @@ -4,17 +4,14 @@ use crate::runbook::{ RuntimeContext, }; use crate::types::{ConstructType, RunbookExecutionContext, RunbookSources}; -use kit::constants::{RE_EXECUTE_COMMAND, THIRD_PARTY_SIGNATURE_STATUS}; +use kit::constants::{ActionItemKey, RunbookKey}; use kit::types::commands::{ ConstructInstance, PostConditionEvaluationResult, PreConditionEvaluationResult, }; use kit::types::types::ObjectDefinition; use std::collections::{BTreeMap, HashMap, HashSet}; use std::fmt::Display; -use txtx_addon_kit::constants::{ - SIGNATURE_APPROVED, SIGNATURE_SKIPPABLE, SIGNED_MESSAGE_BYTES, SIGNED_TRANSACTION_BYTES, - TX_HASH, -}; +use txtx_addon_kit::constants::SignerKey; use txtx_addon_kit::hcl::structure::Block as HclBlock; use txtx_addon_kit::helpers::hcl::visit_optional_untyped_attribute; use txtx_addon_kit::indexmap::IndexMap; @@ -323,12 +320,12 @@ impl Display for EvaluationPassResult { fn should_skip_construct_evaluation(execution_result: &CommandExecutionResult) -> bool { // Check if the execution result indicates that the construct should be skipped let has_re_execute_command = - execution_result.outputs.get(RE_EXECUTE_COMMAND).and_then(|v| v.as_bool()).unwrap_or(false); + execution_result.outputs.get(ActionItemKey::ReExecuteCommand.as_ref()).and_then(|v| v.as_bool()).unwrap_or(false); let is_third_party_signed_construct_not_yet_signed_by_third_party = { let third_party_val = execution_result .outputs - .get(THIRD_PARTY_SIGNATURE_STATUS) + .get(RunbookKey::ThirdPartySignatureStatus.as_ref()) .map(|v| v.expect_third_party_signature()); let is_action_signed_by_third_party = third_party_val.is_some(); let is_third_party_sign_complete = @@ -347,7 +344,7 @@ fn should_retry_construct_evaluation(execution_result: &CommandExecutionResult) let is_third_party_signed_construct_not_yet_signed_by_third_party = { let third_party_val = execution_result .outputs - .get(THIRD_PARTY_SIGNATURE_STATUS) + .get(RunbookKey::ThirdPartySignatureStatus.as_ref()) .map(|v| v.expect_third_party_signature()); let is_action_signed_by_third_party = third_party_val.is_some(); let is_third_party_sign_check_requested = @@ -1563,7 +1560,7 @@ pub fn update_signer_instances_from_action_response( Some(bytes) => { signer_state.insert_scoped_value( &did, - SIGNED_TRANSACTION_BYTES, + SignerKey::SignedTransactionBytes, Value::string(bytes.clone()), ); } @@ -1571,20 +1568,20 @@ pub fn update_signer_instances_from_action_response( Some(true) => { signer_state.insert_scoped_value( &did, - SIGNATURE_APPROVED, + SignerKey::SignatureApproved, Value::bool(true), ); } Some(false) => {} None => { let skippable = signer_state - .get_scoped_value(&did, SIGNATURE_SKIPPABLE) + .get_scoped_value(&did, SignerKey::SignatureSkippable) .and_then(|v| v.as_bool()) .unwrap_or(false); if skippable { signer_state.insert_scoped_value( &did, - SIGNED_TRANSACTION_BYTES, + SignerKey::SignedTransactionBytes, Value::null(), ); } @@ -1601,7 +1598,7 @@ pub fn update_signer_instances_from_action_response( let did = &construct_did.to_string(); signer_state.insert_scoped_value( &did, - TX_HASH, + SignerKey::TxHash, Value::string(response.transaction_hash.clone()), ); @@ -1614,7 +1611,7 @@ pub fn update_signer_instances_from_action_response( { signer_state.insert_scoped_value( &construct_did.value().to_string(), - SIGNED_MESSAGE_BYTES, + SignerKey::SignedMessageBytes, Value::string(response.signed_message_bytes.clone()), ); signers.push_signer_state(signer_state.clone()); @@ -1629,7 +1626,7 @@ pub fn update_signer_instances_from_action_response( // can handle accordingly signer_state.insert_scoped_value( &construct_did.value().to_string(), - THIRD_PARTY_SIGNATURE_STATUS, + RunbookKey::ThirdPartySignatureStatus, Value::third_party_signature_check_requested(), ); signers.push_signer_state(signer_state.clone()); diff --git a/crates/txtx-core/src/lib.rs b/crates/txtx-core/src/lib.rs index ad6603429..84f3c7f09 100644 --- a/crates/txtx-core/src/lib.rs +++ b/crates/txtx-core/src/lib.rs @@ -28,16 +28,12 @@ use ::std::thread::sleep; use ::std::time::Duration; use crate::runbook::flow_context::FlowContext; -use constants::ACTION_ITEM_ENV; -use constants::ACTION_ITEM_GENESIS; -use constants::ACTION_ITEM_VALIDATE_BLOCK; use eval::run_constructs_evaluation; use eval::run_signers_evaluation; -use kit::constants::ACTION_ITEM_CHECK_BALANCE; use runbook::get_source_context_for_diagnostic; use tokio::sync::broadcast::error::TryRecvError; use txtx_addon_kit::channel::Sender; -use txtx_addon_kit::constants::ACTION_ITEM_CHECK_ADDRESS; +use txtx_addon_kit::constants::ActionItemKey; use txtx_addon_kit::hcl::Span; use txtx_addon_kit::types::block_id::BlockId; use txtx_addon_kit::types::commands::CommandExecutionResult; @@ -68,7 +64,7 @@ lazy_static! { pub static ref SET_ENV_ACTION: ActionItemRequest =ActionItemRequestType::PickInputOption(PickInputOptionRequest { options: vec![], selected: InputOption::default(), - }).to_request("", ACTION_ITEM_ENV) + }).to_request("", ActionItemKey::Env) .with_meta_description("Select the environment to target") .with_status(ActionItemStatus::Success(None)) ; @@ -384,7 +380,7 @@ pub async fn start_supervised_runbook_runloop( vec![ActionItemRequestType::ValidateBlock(ValidateBlockData::new( validated_blocks, )) - .to_request("Validate", ACTION_ITEM_VALIDATE_BLOCK)], + .to_request("Validate", ActionItemKey::ValidateBlock)], ); } @@ -451,8 +447,8 @@ pub async fn start_supervised_runbook_runloop( // but they need to confirm it in the supervisor. when it is confirmed, we need to // reprocess the signers if let Some(request) = action_item_requests.get(&action_item_id) { - if request.internal_key == ACTION_ITEM_CHECK_ADDRESS - || request.internal_key == ACTION_ITEM_CHECK_BALANCE + if request.internal_key == ActionItemKey::CheckAddress + || request.internal_key == ActionItemKey::CheckBalance { process_signers_action_item_response( runbook, @@ -696,7 +692,7 @@ pub async fn build_genesis_panel( options: input_options, selected: selected_option, }) - .to_request("", ACTION_ITEM_ENV) + .to_request("", ActionItemKey::Env) .with_meta_description("Select the environment to target") .with_status(ActionItemStatus::Success(None)); @@ -722,7 +718,7 @@ pub async fn build_genesis_panel( let validate_action = ActionItemRequestType::ValidateBlock(ValidateBlockData::new(validated_blocks)) - .to_request("start runbook", ACTION_ITEM_GENESIS); + .to_request("start runbook", ActionItemKey::Genesis); actions.push_sub_group(None, vec![validate_action]); diff --git a/crates/txtx-core/src/runbook/embedded_runbook/mod.rs b/crates/txtx-core/src/runbook/embedded_runbook/mod.rs index 8b63babee..32e2d1562 100644 --- a/crates/txtx-core/src/runbook/embedded_runbook/mod.rs +++ b/crates/txtx-core/src/runbook/embedded_runbook/mod.rs @@ -9,6 +9,7 @@ use txtx_addon_kit::types::commands::DependencyExecutionResultCache; use txtx_addon_kit::types::diagnostics::Diagnostic; use txtx_addon_kit::types::embedded_runbooks::EmbeddedRunbookStatefulExecutionContext; use txtx_addon_kit::types::stores::ValueStore; +use txtx_addon_kit::types::namespace::Namespace; use txtx_addon_kit::types::PackageId; use txtx_addon_kit::types::{ commands::CommandExecutionResult, embedded_runbooks::EmbeddedRunbookInstance, @@ -178,7 +179,7 @@ impl EmbeddingRunbookContext { for (_, addon_instance) in execution_context.addon_instances.iter() { let existing_addon_defaults = workspace_context .addons_defaults - .get(&(addon_instance.package_id.did(), addon_instance.addon_id.to_string())) + .get(&(addon_instance.package_id.did(), Namespace::from(addon_instance.addon_id.to_string()))) .cloned(); let defaults = runtime_context .generate_addon_defaults_from_block( @@ -197,7 +198,7 @@ impl EmbeddingRunbookContext { )) })?; workspace_context.addons_defaults.insert( - (addon_instance.package_id.did(), addon_instance.addon_id.to_string()), + (addon_instance.package_id.did(), Namespace::from(&addon_instance.addon_id)), defaults, ); } diff --git a/crates/txtx-core/src/runbook/embedded_runbook/publishable.rs b/crates/txtx-core/src/runbook/embedded_runbook/publishable.rs index 6996fb97e..1b4e99a49 100644 --- a/crates/txtx-core/src/runbook/embedded_runbook/publishable.rs +++ b/crates/txtx-core/src/runbook/embedded_runbook/publishable.rs @@ -10,6 +10,7 @@ use txtx_addon_kit::types::embedded_runbooks::{ EmbeddedRunbookStaticExecutionContext, EmbeddedRunbookStaticWorkspaceContext, SignerName, }; use txtx_addon_kit::types::stores::ValueStore; +use txtx_addon_kit::types::namespace::Namespace; use txtx_addon_kit::types::AddonInstance; use txtx_addon_kit::types::{ConstructDid, ConstructId, PackageId, RunbookId}; @@ -409,7 +410,7 @@ impl PublishableCommandInstance { name: self.name.clone(), block: block.clone(), package_id: self.package_id.clone(), - namespace: self.namespace.clone(), + namespace: Namespace::from(&self.namespace), typing: CommandInstanceType::Variable, }, CommandInstanceType::Output => CommandInstance { @@ -417,7 +418,7 @@ impl PublishableCommandInstance { name: self.name.clone(), block: block.clone(), package_id: self.package_id.clone(), - namespace: self.namespace.clone(), + namespace: Namespace::from(&self.namespace), typing: CommandInstanceType::Output, }, CommandInstanceType::Action(command_id) => { @@ -452,7 +453,7 @@ impl PublishableCommandInstance { name: self.name.clone(), block: block.clone(), package_id: self.package_id.clone(), - namespace: self.namespace.clone(), + namespace: Namespace::from(&self.namespace), typing: CommandInstanceType::Module, }, CommandInstanceType::Addon => todo!(), @@ -463,7 +464,7 @@ impl PublishableCommandInstance { pub fn from_command_instance(command_instance: &CommandInstance) -> Self { Self { package_id: command_instance.package_id.clone(), - namespace: command_instance.namespace.clone(), + namespace: command_instance.namespace.to_string(), typing: command_instance.typing.clone(), name: command_instance.name.clone(), hcl: RawHclContent::from_block(&command_instance.block), diff --git a/crates/txtx-core/src/runbook/execution_context.rs b/crates/txtx-core/src/runbook/execution_context.rs index e0fe176c7..98d99f778 100644 --- a/crates/txtx-core/src/runbook/execution_context.rs +++ b/crates/txtx-core/src/runbook/execution_context.rs @@ -1,4 +1,4 @@ -use kit::constants::DESCRIPTION; +use kit::constants::{ActionItemKey, DocumentationKey}; use kit::types::commands::ConstructInstance; use kit::types::frontend::DisplayErrorLogRequest; use kit::types::AuthorizationContext; @@ -157,7 +157,7 @@ impl RunbookExecutionContext { action_items: &mut IndexMap>, auth_context: &AuthorizationContext, ) -> LoopEvaluationResult { - if command_instance.specification.name.to_lowercase().eq("output") { + if command_instance.specification.name.to_lowercase().eq(ActionItemKey::Output.as_ref()) { let Some(execution_result) = self.commands_execution_results.get(&construct_did) else { return LoopEvaluationResult::Continue; }; @@ -172,7 +172,7 @@ impl RunbookExecutionContext { }; let description = - input_evaluations.inputs.get_string(DESCRIPTION).and_then(|d| Some(d.to_string())); + input_evaluations.inputs.get_string(DocumentationKey::Description).and_then(|d| Some(d.to_string())); let markdown = match input_evaluations.inputs.get_markdown(&auth_context) { Ok(md) => md, Err(e) => { @@ -184,7 +184,7 @@ impl RunbookExecutionContext { e.message ), }) - .to_request(&command_instance.name, "output") + .to_request(&command_instance.name, ActionItemKey::Output) .with_construct_did(construct_did), ); None @@ -197,7 +197,7 @@ impl RunbookExecutionContext { description: description.clone(), value: value.clone(), }) - .to_request(&command_instance.name, "output") + .to_request(&command_instance.name, ActionItemKey::Output) .with_construct_did(construct_did) .with_some_description(description) .with_some_markdown(markdown), diff --git a/crates/txtx-core/src/runbook/flow_context.rs b/crates/txtx-core/src/runbook/flow_context.rs index eb12cc9ee..b310ba2ae 100644 --- a/crates/txtx-core/src/runbook/flow_context.rs +++ b/crates/txtx-core/src/runbook/flow_context.rs @@ -115,7 +115,7 @@ impl FlowContext { pub fn index_flow_input(&mut self, key: &str, value: Value, package_id: &PackageId) { let construct_id = self.workspace_context.index_flow_input(key, package_id, &mut self.graph_context); - self.evaluated_inputs.insert(key.into(), value.clone()); + self.evaluated_inputs.insert(key.to_string(), value.clone()); // self.graph_context.index_top_level_input(&construct_did); let mut result = CommandExecutionResult::new(); result.outputs.insert("value".into(), value); diff --git a/crates/txtx-core/src/runbook/runtime_context.rs b/crates/txtx-core/src/runbook/runtime_context.rs index 63bd53cf5..55fa7ddbc 100644 --- a/crates/txtx-core/src/runbook/runtime_context.rs +++ b/crates/txtx-core/src/runbook/runtime_context.rs @@ -17,6 +17,7 @@ use txtx_addon_kit::{ }, diagnostics::Diagnostic, functions::FunctionSpecification, + namespace::Namespace, signers::{SignerInstance, SignerSpecification}, types::Value, AuthorizationContext, ConstructDid, ContractSourceTransform, Did, PackageDid, PackageId, @@ -94,7 +95,7 @@ impl RuntimeContext { let inputs_simulation_results = runbook_execution_context.commands_inputs_evaluation_results.get(did); grouped_commands - .entry(command_instance.namespace.clone()) + .entry(command_instance.namespace.to_string()) .and_modify(|e: &mut _| { e.push((did.clone(), command_instance, inputs_simulation_results)) }) @@ -245,7 +246,7 @@ impl RuntimeContext { let existing_addon_defaults = runbook_workspace_context .addons_defaults - .get(&(package_id.did(), addon_id.clone())) + .get(&(package_id.did(), Namespace::from(addon_id.clone()))) .cloned(); let addon_defaults = self .generate_addon_defaults_from_block( @@ -261,7 +262,7 @@ impl RuntimeContext { runbook_workspace_context .addons_defaults - .insert((package_id.did(), addon_id.clone()), addon_defaults); + .insert((package_id.did(), Namespace::from(addon_id.clone())), addon_defaults); } _ => {} } @@ -622,7 +623,7 @@ impl AddonConstructFactory { block: block.clone(), package_id: package_id.clone(), typing, - namespace: namespace.to_string(), + namespace: Namespace::from(namespace), }; Ok(command_instance) } @@ -649,7 +650,7 @@ impl AddonConstructFactory { specification: signer_spec.clone(), block: block.clone(), package_id: package_id.clone(), - namespace: namespace.to_string(), + namespace: Namespace::from(namespace), }) } } diff --git a/crates/txtx-core/src/runbook/workspace_context.rs b/crates/txtx-core/src/runbook/workspace_context.rs index d12fb1f1d..77840a053 100644 --- a/crates/txtx-core/src/runbook/workspace_context.rs +++ b/crates/txtx-core/src/runbook/workspace_context.rs @@ -22,6 +22,7 @@ use txtx_addon_kit::types::package::Package; use txtx_addon_kit::types::signers::SignerInstance; use txtx_addon_kit::types::stores::AddonDefaults; use txtx_addon_kit::types::types::Value; +use txtx_addon_kit::types::namespace::Namespace; use txtx_addon_kit::types::AddonInstance; use txtx_addon_kit::types::{ConstructDid, ConstructId, Did, PackageDid, PackageId, RunbookId}; use crate::types::ConstructType; @@ -52,7 +53,7 @@ pub struct RunbookWorkspaceContext { /// Lookup: Retrieve a value given an environment variable construct did pub top_level_inputs_values: BTreeMap, /// Lookup: Retrieve an addon's defaults given a package and addon id - pub addons_defaults: HashMap<(PackageDid, String), AddonDefaults>, + pub addons_defaults: HashMap<(PackageDid, Namespace), AddonDefaults>, std_defaults: AddonDefaults, } @@ -70,7 +71,7 @@ impl RunbookWorkspaceContext { } } - pub fn get_addon_defaults(&self, key: &(PackageDid, String)) -> &AddonDefaults { + pub fn get_addon_defaults(&self, key: &(PackageDid, Namespace)) -> &AddonDefaults { self.addons_defaults.get(key).unwrap_or(&self.std_defaults) } @@ -83,7 +84,7 @@ impl RunbookWorkspaceContext { .into_iter() .map(|((package_did, addon_id), defaults)| { let mut addon_defaults_values = IndexMap::from([( - addon_id, + addon_id.to_string(), defaults .store .store @@ -500,7 +501,7 @@ impl RunbookWorkspaceContext { name: construct_name.clone(), block: block.clone(), package_id: package_id.clone(), - namespace: construct_name.clone(), + namespace: Namespace::from(&construct_name), typing: CommandInstanceType::Module, }) } @@ -512,7 +513,7 @@ impl RunbookWorkspaceContext { name: construct_name.clone(), block: block.clone(), package_id: package_id.clone(), - namespace: construct_name.clone(), + namespace: Namespace::from(&construct_name), typing: CommandInstanceType::Variable, }) } @@ -533,7 +534,7 @@ impl RunbookWorkspaceContext { name: construct_name.clone(), block: block.clone(), package_id: package_id.clone(), - namespace: construct_name.clone(), + namespace: Namespace::from(&construct_name), typing: CommandInstanceType::Output, }) } @@ -640,7 +641,7 @@ impl RunbookWorkspaceContext { { let addon_defaults = self.get_addon_defaults(&( addon_instance.package_id.did(), - addon_instance.addon_id.clone(), + Namespace::from(addon_instance.addon_id.clone()), )); for input_name in input_names { if let Some(value) = addon_defaults.store.get_value(&input_name) { diff --git a/crates/txtx-core/src/std/commands/mod.rs b/crates/txtx-core/src/std/commands/mod.rs index 425bc25ae..b343c0b34 100644 --- a/crates/txtx-core/src/std/commands/mod.rs +++ b/crates/txtx-core/src/std/commands/mod.rs @@ -1,6 +1,6 @@ pub mod actions; -use kit::constants::DESCRIPTION; +use kit::constants::DocumentationKey; use kit::types::AuthorizationContext; use txtx_addon_kit::types::commands::return_synchronous_result; use txtx_addon_kit::types::frontend::{ActionItemRequestType, ProvideInputRequest}; @@ -23,7 +23,7 @@ use txtx_addon_kit::{ }, }; -use crate::constants::ACTION_ITEM_CHECK_OUTPUT; +use txtx_addon_kit::constants::ActionItemKey; pub fn new_module_specification() -> CommandSpecification { let command = define_command! { @@ -171,7 +171,7 @@ impl CommandImplementation for Variable { } let title = instance_name; - let description = values.get_string(DESCRIPTION).and_then(|d| Some(d.to_string())); + let description = values.get_string(DocumentationKey::Description).and_then(|d| Some(d.to_string())); let markdown = values.get_markdown(&auth_context)?; let is_editable = values.get_bool("editable").unwrap_or(false); @@ -181,7 +181,7 @@ impl CommandImplementation for Variable { input_name: "value".into(), typing: value.get_type(), }) - .to_request(title, "provide_input") + .to_request(title, ActionItemKey::ProvideInput) .with_some_description(description) .with_construct_did(construct_did) .with_some_markdown(markdown) @@ -189,7 +189,7 @@ impl CommandImplementation for Variable { if supervision_context.review_input_values { ReviewInputRequest::new("value", &value) .to_action_type() - .to_request(title, "check_input") + .to_request(title, ActionItemKey::CheckInput) .with_some_description(description) .with_construct_did(construct_did) .with_some_markdown(markdown) @@ -278,7 +278,7 @@ impl CommandImplementation for Output { auth_context: &AuthorizationContext, ) -> Result { let value = args.get_expected_value("value")?; - let description = args.get_string(DESCRIPTION).and_then(|d| Some(d.to_string())); + let description = args.get_string(DocumentationKey::Description).and_then(|d| Some(d.to_string())); let markdown = args.get_markdown(&auth_context)?; let actions = Actions::new_sub_group_of_items( None, @@ -287,7 +287,7 @@ impl CommandImplementation for Output { description: None, value: value.clone(), }) - .to_request(instance_name, ACTION_ITEM_CHECK_OUTPUT) + .to_request(instance_name, ActionItemKey::CheckOutput) .with_construct_did(construct_did) .with_some_description(description) .with_some_markdown(markdown)], diff --git a/crates/txtx-core/src/std/functions/assertions.rs b/crates/txtx-core/src/std/functions/assertions.rs index 23e6ccc41..d87299967 100644 --- a/crates/txtx-core/src/std/functions/assertions.rs +++ b/crates/txtx-core/src/std/functions/assertions.rs @@ -181,7 +181,7 @@ impl FunctionImplementation for AssertEq { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -189,7 +189,7 @@ impl FunctionImplementation for AssertEq { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let left = &args[0]; @@ -212,7 +212,7 @@ impl FunctionImplementation for AssertNe { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -220,7 +220,7 @@ impl FunctionImplementation for AssertNe { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let left = &args[0]; @@ -243,7 +243,7 @@ impl FunctionImplementation for AssertGt { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -251,7 +251,7 @@ impl FunctionImplementation for AssertGt { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let left = &args[0]; @@ -311,7 +311,7 @@ impl FunctionImplementation for AssertGte { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -319,7 +319,7 @@ impl FunctionImplementation for AssertGte { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let left = &args[0]; @@ -379,7 +379,7 @@ impl FunctionImplementation for AssertLt { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -387,7 +387,7 @@ impl FunctionImplementation for AssertLt { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let left = &args[0]; @@ -447,7 +447,7 @@ impl FunctionImplementation for AssertLte { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -455,7 +455,7 @@ impl FunctionImplementation for AssertLte { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let left = &args[0]; diff --git a/crates/txtx-core/src/std/functions/base58.rs b/crates/txtx-core/src/std/functions/base58.rs index 97fafe656..3004f9904 100644 --- a/crates/txtx-core/src/std/functions/base58.rs +++ b/crates/txtx-core/src/std/functions/base58.rs @@ -39,7 +39,7 @@ impl FunctionImplementation for Base58Encode { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -47,7 +47,7 @@ impl FunctionImplementation for Base58Encode { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let hex = args.get(0).unwrap().to_string(); diff --git a/crates/txtx-core/src/std/functions/base64.rs b/crates/txtx-core/src/std/functions/base64.rs index 2f92f2eff..b399b977d 100644 --- a/crates/txtx-core/src/std/functions/base64.rs +++ b/crates/txtx-core/src/std/functions/base64.rs @@ -39,7 +39,7 @@ impl FunctionImplementation for Base64Decode { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -47,7 +47,7 @@ impl FunctionImplementation for Base64Decode { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let encoded = args.get(0).unwrap().expect_string(); let decoded = general_purpose::STANDARD.decode(encoded).map_err(|e| { diff --git a/crates/txtx-core/src/std/functions/crypto.rs b/crates/txtx-core/src/std/functions/crypto.rs index 979841830..6827f1648 100644 --- a/crates/txtx-core/src/std/functions/crypto.rs +++ b/crates/txtx-core/src/std/functions/crypto.rs @@ -42,7 +42,7 @@ impl FunctionImplementation for Secp256k1Recover { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -50,7 +50,7 @@ impl FunctionImplementation for Secp256k1Recover { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { use libsecp256k1::{recover, Message, RecoveryId, Signature}; diff --git a/crates/txtx-core/src/std/functions/hash.rs b/crates/txtx-core/src/std/functions/hash.rs index 9f0d4f944..fac19e637 100644 --- a/crates/txtx-core/src/std/functions/hash.rs +++ b/crates/txtx-core/src/std/functions/hash.rs @@ -91,7 +91,7 @@ impl FunctionImplementation for Ripemd160 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -99,7 +99,7 @@ impl FunctionImplementation for Ripemd160 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(value) = args.get(0) else { return Err(diagnosed_error!("{}: expected 1 argument, got 0", fn_spec.name)); @@ -117,7 +117,7 @@ impl FunctionImplementation for Sha256 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -125,7 +125,7 @@ impl FunctionImplementation for Sha256 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(value) = args.get(0) else { return Err(diagnosed_error!("{}: expected 1 argument, got 0", fn_spec.name)); @@ -143,7 +143,7 @@ impl FunctionImplementation for Keccak256 { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -151,7 +151,7 @@ impl FunctionImplementation for Keccak256 { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let value = args.get(0).unwrap().as_string().unwrap().to_string(); diff --git a/crates/txtx-core/src/std/functions/hex.rs b/crates/txtx-core/src/std/functions/hex.rs index 37c780c9b..66b0a0748 100644 --- a/crates/txtx-core/src/std/functions/hex.rs +++ b/crates/txtx-core/src/std/functions/hex.rs @@ -38,7 +38,7 @@ impl FunctionImplementation for EncodeHex { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -46,7 +46,7 @@ impl FunctionImplementation for EncodeHex { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let input = args.get(0).unwrap().expect_string(); let hex = txtx_addon_kit::hex::encode(input); diff --git a/crates/txtx-core/src/std/functions/json.rs b/crates/txtx-core/src/std/functions/json.rs index a92225b35..b601e1b9f 100644 --- a/crates/txtx-core/src/std/functions/json.rs +++ b/crates/txtx-core/src/std/functions/json.rs @@ -49,7 +49,7 @@ impl FunctionImplementation for JsonQuery { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -57,7 +57,7 @@ impl FunctionImplementation for JsonQuery { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let input_str = args.get(0).unwrap().encode_to_string(); diff --git a/crates/txtx-core/src/std/functions/list.rs b/crates/txtx-core/src/std/functions/list.rs index e61f4899e..08c6a6314 100644 --- a/crates/txtx-core/src/std/functions/list.rs +++ b/crates/txtx-core/src/std/functions/list.rs @@ -42,7 +42,7 @@ impl FunctionImplementation for Index { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -50,7 +50,7 @@ impl FunctionImplementation for Index { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Value::Array(list) = args.get(0).unwrap() else { panic!("index function requires list for first input") diff --git a/crates/txtx-core/src/std/functions/mod.rs b/crates/txtx-core/src/std/functions/mod.rs index 98f977003..8c1d7a544 100644 --- a/crates/txtx-core/src/std/functions/mod.rs +++ b/crates/txtx-core/src/std/functions/mod.rs @@ -11,17 +11,18 @@ use txtx_addon_kit::types::functions::FunctionSpecification; use txtx_addon_kit::types::{ diagnostics::Diagnostic, functions::{arg_checker_with_ctx, fn_diag_with_ctx}, + namespace::Namespace, types::Value, }; use crate::constants::NAMESPACE; -pub fn arg_checker(fn_spec: &FunctionSpecification, args: &Vec) -> Result<(), Diagnostic> { - let checker = arg_checker_with_ctx(NAMESPACE.to_string()); +pub fn arg_checker(fn_spec: &FunctionSpecification, args: &[Value]) -> Result<(), Diagnostic> { + let checker = arg_checker_with_ctx(Namespace::from(NAMESPACE)); checker(fn_spec, args) } pub fn to_diag(fn_spec: &FunctionSpecification, e: String) -> Diagnostic { - let error_fn = fn_diag_with_ctx(NAMESPACE.to_string()); + let error_fn = fn_diag_with_ctx(Namespace::from(NAMESPACE)); error_fn(fn_spec, e) } diff --git a/crates/txtx-core/src/std/functions/operators.rs b/crates/txtx-core/src/std/functions/operators.rs index 81c5ad336..b6fb7f5f9 100644 --- a/crates/txtx-core/src/std/functions/operators.rs +++ b/crates/txtx-core/src/std/functions/operators.rs @@ -394,7 +394,7 @@ impl FunctionImplementation for UnaryNegInteger { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -402,7 +402,7 @@ impl FunctionImplementation for UnaryNegInteger { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result { unimplemented!() } @@ -413,7 +413,7 @@ impl FunctionImplementation for UnaryNotBool { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -421,7 +421,7 @@ impl FunctionImplementation for UnaryNotBool { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Value], ) -> Result { unimplemented!() } @@ -432,7 +432,7 @@ impl FunctionImplementation for BinaryAndBool { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -440,7 +440,7 @@ impl FunctionImplementation for BinaryAndBool { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Bool(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Bool(rhs)) = args.get(1) else { unreachable!() }; @@ -453,7 +453,7 @@ impl FunctionImplementation for BinaryOrBool { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -461,7 +461,7 @@ impl FunctionImplementation for BinaryOrBool { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Bool(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Bool(rhs)) = args.get(1) else { unreachable!() }; @@ -474,7 +474,7 @@ impl FunctionImplementation for BinaryDivSignedInteger { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -482,7 +482,7 @@ impl FunctionImplementation for BinaryDivSignedInteger { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -499,7 +499,7 @@ impl FunctionImplementation for BinaryEq { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -507,7 +507,7 @@ impl FunctionImplementation for BinaryEq { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let lhs = args.get(0).unwrap(); @@ -521,7 +521,7 @@ impl FunctionImplementation for BinaryGreater { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -529,7 +529,7 @@ impl FunctionImplementation for BinaryGreater { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -542,7 +542,7 @@ impl FunctionImplementation for BinaryGreaterEq { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -550,7 +550,7 @@ impl FunctionImplementation for BinaryGreaterEq { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -563,7 +563,7 @@ impl FunctionImplementation for BinaryLess { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -571,7 +571,7 @@ impl FunctionImplementation for BinaryLess { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -584,7 +584,7 @@ impl FunctionImplementation for BinaryLessEq { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -592,7 +592,7 @@ impl FunctionImplementation for BinaryLessEq { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -605,7 +605,7 @@ impl FunctionImplementation for BinaryNotEq { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -613,7 +613,7 @@ impl FunctionImplementation for BinaryNotEq { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -626,7 +626,7 @@ impl FunctionImplementation for BinaryMinus { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -634,7 +634,7 @@ impl FunctionImplementation for BinaryMinus { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -647,7 +647,7 @@ impl FunctionImplementation for BinaryModulo { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -655,7 +655,7 @@ impl FunctionImplementation for BinaryModulo { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; @@ -668,7 +668,7 @@ impl FunctionImplementation for BinaryMul { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -676,7 +676,7 @@ impl FunctionImplementation for BinaryMul { fn run( fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { arg_checker(fn_spec, args)?; let lhs = args.get(0).unwrap().as_integer().unwrap(); @@ -690,7 +690,7 @@ impl FunctionImplementation for BinaryPlus { fn check_instantiability( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - _args: &Vec, + _args: &[Type], ) -> Result { unimplemented!() } @@ -698,7 +698,7 @@ impl FunctionImplementation for BinaryPlus { fn run( _fn_spec: &FunctionSpecification, _auth_ctx: &AuthorizationContext, - args: &Vec, + args: &[Value], ) -> Result { let Some(Value::Integer(lhs)) = args.get(0) else { unreachable!() }; let Some(Value::Integer(rhs)) = args.get(1) else { unreachable!() }; diff --git a/crates/txtx-core/src/tests/mod.rs b/crates/txtx-core/src/tests/mod.rs index adc7115e4..fce373311 100644 --- a/crates/txtx-core/src/tests/mod.rs +++ b/crates/txtx-core/src/tests/mod.rs @@ -1,3 +1,4 @@ +use txtx_addon_kit::constants::ActionItemKey; use txtx_addon_kit::types::{ frontend::{ ActionItemResponse, ActionItemResponseType, ActionItemStatus, ProvidedInputResponse, @@ -55,8 +56,8 @@ fn test_ab_c_runbook_no_env() { let input_a_action = &inputs_panel_data.groups[0].sub_groups[0].action_items[0]; let input_b_action = &inputs_panel_data.groups[0].sub_groups[0].action_items[1]; - assert_eq!(&input_a_action.internal_key, "check_input"); - assert_eq!(&input_b_action.internal_key, "provide_input"); + assert_eq!(input_a_action.internal_key, ActionItemKey::CheckInput); + assert_eq!(input_b_action.internal_key, ActionItemKey::ProvideInput); // review input a and expect action item update harness.send_and_expect_action_item_update( diff --git a/crates/txtx-core/src/validation/hcl_validator/validation_helpers.rs b/crates/txtx-core/src/validation/hcl_validator/validation_helpers.rs index 689f69b3b..ddbf31ac6 100644 --- a/crates/txtx-core/src/validation/hcl_validator/validation_helpers.rs +++ b/crates/txtx-core/src/validation/hcl_validator/validation_helpers.rs @@ -4,9 +4,7 @@ //! phase (block_processors) and the validation phase (visitor). use std::collections::HashMap; -use txtx_addon_kit::constants::{ - DEPENDS_ON, DESCRIPTION, MARKDOWN, MARKDOWN_FILEPATH, POST_CONDITION, PRE_CONDITION, -}; +use txtx_addon_kit::constants::{ConditionKey, DocumentationKey}; use crate::kit::types::commands::CommandSpecification; use super::visitor::ValidationError; @@ -57,8 +55,10 @@ pub fn validate_action( /// Check if an attribute is an inherited property pub fn is_inherited_property(attr_name: &str) -> bool { - matches!( - attr_name, - MARKDOWN | MARKDOWN_FILEPATH | DESCRIPTION | DEPENDS_ON | PRE_CONDITION | POST_CONDITION - ) + attr_name == DocumentationKey::Markdown.as_ref() + || attr_name == DocumentationKey::MarkdownFilepath.as_ref() + || attr_name == DocumentationKey::Description.as_ref() + || attr_name == DocumentationKey::DependsOn.as_ref() + || attr_name == ConditionKey::PreCondition.as_ref() + || attr_name == ConditionKey::PostCondition.as_ref() } diff --git a/crates/txtx-gql/src/types/block.rs b/crates/txtx-gql/src/types/block.rs index c87409da3..00d724557 100644 --- a/crates/txtx-gql/src/types/block.rs +++ b/crates/txtx-gql/src/types/block.rs @@ -291,7 +291,7 @@ impl GqlActionItemRequest { } pub fn internal_key(&self) -> String { - self.action_item.internal_key.clone() + self.action_item.internal_key.to_string() } pub fn description(&self) -> Option {