diff --git a/crates/by-chain/icepick-cosmos/src/lib.rs b/crates/by-chain/icepick-cosmos/src/lib.rs index 0556e98..22cbb6c 100644 --- a/crates/by-chain/icepick-cosmos/src/lib.rs +++ b/crates/by-chain/icepick-cosmos/src/lib.rs @@ -28,7 +28,7 @@ pub struct GenerateWallet { #[derive(Serialize, Deserialize, Debug)] pub struct GetWalletAddress { - address_prefix: String, + blockchain_config: coin_denoms::Blockchain, } #[derive(Serialize, Deserialize, Debug)] @@ -324,12 +324,14 @@ impl Module for Cosmos { "derivation_accounts": [(account | 1 << 31)], })) } - Operation::GetWalletAddress(GetWalletAddress { address_prefix }) => { + Operation::GetWalletAddress(GetWalletAddress { blockchain_config }) => { // NOTE: panics if doesn't exist let key = request.derived_keys.unwrap()[0]; let privkey = secp256k1::SigningKey::from_slice(&key).unwrap(); let pubkey = privkey.public_key(); - let sender_account_id = pubkey.account_id(&address_prefix).unwrap(); + let sender_account_id = pubkey + .account_id(&blockchain_config.bech32_config.account_address_prefix) + .unwrap(); Ok(serde_json::json!({ "blob": { "pubkey": sender_account_id, @@ -495,10 +497,7 @@ impl Module for Cosmos { amount: expected_fee as u128, }; - let fee = Fee::from_amount_and_gas( - fee_coin, - expected_gas, - ); + let fee = Fee::from_amount_and_gas(fee_coin, expected_gas); #[allow(clippy::identity_op)] Ok(serde_json::json!({ diff --git a/crates/icepick-workflow/src/lib.rs b/crates/icepick-workflow/src/lib.rs index d9ec259..4a2bf20 100644 --- a/crates/icepick-workflow/src/lib.rs +++ b/crates/icepick-workflow/src/lib.rs @@ -31,6 +31,9 @@ pub struct Workflow { #[serde(default)] pub inputs: Vec, + #[serde(default)] + pub optional_inputs: Vec, + #[serde(rename = "step")] steps: Vec, } @@ -130,7 +133,7 @@ impl Workflow { let Some((algo, path_prefix)) = operation.derivation_configuration() else { return Err(WorkflowError::DerivationConfigurationNotFound(step_type)); }; - derived_keys.extend(derive_keys(&algo, &path_prefix, &derivation_accounts)); + derived_keys.extend(derive_keys(algo, path_prefix, &derivation_accounts)); } derivation_accounts.clear(); diff --git a/crates/icepick/build.rs b/crates/icepick/build.rs index 523d481..b5e5b66 100644 --- a/crates/icepick/build.rs +++ b/crates/icepick/build.rs @@ -1,15 +1,20 @@ use icepick_workflow::Workflow; -use std::{collections::HashMap, path::PathBuf}; +use std::{collections::HashMap, path::{PathBuf, Path}}; fn env_var(var: &'static str) -> String { println!("cargo::rerun-if-env-changed={var}"); std::env::var(var).expect(var) } +fn track_path(path: &Path) { + println!("cargo::rerun-if-changed={}", path.to_str().unwrap()); +} + fn main() { let out_dir = env_var("CARGO_TARGET_DIR"); let crate_dir = env_var("CARGO_MANIFEST_DIR"); let workflows_dir = PathBuf::from(crate_dir).join("workflows"); + track_path(&workflows_dir); let mut workflows_by_module: HashMap> = Default::default(); @@ -40,6 +45,6 @@ fn main() { ); } let out_path = PathBuf::from(out_dir).join("workflows.yaml"); - let out_file = std::fs::File::create(out_path).unwrap(); + let out_file = std::fs::File::create(&out_path).unwrap(); serde_yaml::to_writer(out_file, &workflows_by_module).unwrap(); } diff --git a/crates/icepick/src/cli/workflow.rs b/crates/icepick/src/cli/workflow.rs index dfd341b..fe2f7f0 100644 --- a/crates/icepick/src/cli/workflow.rs +++ b/crates/icepick/src/cli/workflow.rs @@ -88,6 +88,13 @@ pub fn generate_command(workflow: &Workflow) -> clap::Command { "A file containing any inputs not passed on the command line" )); for input in &workflow.inputs { + let arg = clap::Arg::new(input) + .required(true) + .long(input.replace('_', "-")) + .value_name(input.to_uppercase()); + command = command.arg(arg); + } + for input in &workflow.optional_inputs { let arg = clap::Arg::new(input) .required(false) .long(input.replace('_', "-")) @@ -99,6 +106,7 @@ pub fn generate_command(workflow: &Workflow) -> clap::Command { fn load_inputs + Into + std::fmt::Display>( inputs: impl IntoIterator, + optional_inputs: impl IntoIterator, matches: &clap::ArgMatches, ) -> StringMap { let mut map = StringMap::default(); @@ -122,6 +130,21 @@ fn load_inputs + Into + std::fmt::Display>( panic!("Required workflow input was not found: {input}"); } + for input in optional_inputs { + match matches.get_one::(input.as_ref()) { + Some(value) => { + map.insert(input.into(), value.clone()); + continue; + } + None => { + if let Some(value) = input_file.as_ref().and_then(|f| f.get(input.as_ref())) { + map.insert(input.into(), value.clone()); + continue; + } + } + } + } + map } @@ -152,7 +175,7 @@ pub fn handle( modules: Commands, config: &[ModuleConfig], ) { - let inputs = load_inputs(&workflow.inputs, matches); + let inputs = load_inputs(&workflow.inputs, &workflow.optional_inputs, matches); let data: HashMap = inputs .into_iter() .map(|(k, v)| (k, Value::String(v))) @@ -161,13 +184,17 @@ pub fn handle( let operations = load_operations(modules, config); if matches.get_flag("simulate-workflow") { - let reports = workflow.simulate_workflow(data.into_keys().collect(), &operations).expect("Simulation failure"); + let reports = workflow + .simulate_workflow(data.into_keys().collect(), &operations) + .expect("Simulation failure"); for report in reports { println!("{report}"); } return; } - let result = workflow.run_workflow(data, &operations, &derive_keys).expect("Invocation failure"); + let result = workflow + .run_workflow(data, &operations, &derive_keys) + .expect("Invocation failure"); println!("{}", serde_json::to_string(&result).expect("valid JSON")); } diff --git a/crates/icepick/workflows/cosmos/generate-address.yaml b/crates/icepick/workflows/cosmos/generate-address.yaml new file mode 100644 index 0000000..07a44c6 --- /dev/null +++ b/crates/icepick/workflows/cosmos/generate-address.yaml @@ -0,0 +1,20 @@ +name: generate-address +inputs: +- chain_name +optional_inputs: +- account +step: +- type: cosmos-get-chain-info + inputs: + chain_name: chain_name + outputs: + blockchain_config: blockchain_config +- type: cosmos-generate-wallet + inputs: + account: account + blockchain_config: blockchain_config +- type: cosmos-get-wallet-address + inputs: + blockchain_config: blockchain_config + outputs: + pubkey: pubkey diff --git a/crates/icepick/workflows/sol/generate-address.yaml b/crates/icepick/workflows/sol/generate-address.yaml new file mode 100644 index 0000000..c63c627 --- /dev/null +++ b/crates/icepick/workflows/sol/generate-address.yaml @@ -0,0 +1,10 @@ +name: generate-address +optional_inputs: +- account +step: +- type: sol-generate-wallet + inputs: + account: account +- type: sol-get-wallet-address + outputs: + pubkey: pubkey