add key derivation
This commit is contained in:
parent
40467ce13d
commit
10cda7824c
|
@ -1046,7 +1046,9 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"clap",
|
||||
"icepick-module",
|
||||
"keyfork-derive-util",
|
||||
"keyforkd-client",
|
||||
"keyforkd-models",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.3",
|
||||
|
|
|
@ -167,7 +167,7 @@ impl Module for Solana {
|
|||
match (&fee_payer, &fee_payer_address) {
|
||||
(Some(payer), Some(address)) => {
|
||||
// Use the provided account
|
||||
Some((payer.clone(), Pubkey::from_str_const(address)))
|
||||
Some((u32::from_str(payer).unwrap(), Pubkey::from_str(address).unwrap()))
|
||||
}
|
||||
(None, None) => {
|
||||
// Use the transaction account
|
||||
|
@ -185,19 +185,23 @@ impl Module for Solana {
|
|||
&hash,
|
||||
);
|
||||
let transaction = solana_sdk::transaction::Transaction::new_unsigned(message);
|
||||
let mut required_derivation_indices = vec![];
|
||||
// TODO: error handling from_str
|
||||
let from_account = from_account.and_then(|a| u32::from_str(&a).ok()).unwrap_or(0);
|
||||
required_derivation_indices.push(from_account);
|
||||
let mut requested_accounts = vec![];
|
||||
requested_accounts.push(from_account | 1 << 31);
|
||||
if let Some((account, _)) = &payer_account_and_pk {
|
||||
requested_accounts.push(*account | 1 << 31);
|
||||
}
|
||||
Ok(serde_json::json!({
|
||||
"blob": transaction,
|
||||
"derivation-accounts": requested_accounts,
|
||||
}))
|
||||
}
|
||||
Operation::Sign(Sign {}) => {
|
||||
let blob = request.blob.expect("passed in instruction blob");
|
||||
let transaction: solana_sdk::transaction::Transaction =
|
||||
serde_json::from_value(blob).expect("valid message blob");
|
||||
dbg!(transaction);
|
||||
let keys = request.derived_keys.unwrap_or_default();
|
||||
Ok(serde_json::json!({
|
||||
"blob": []
|
||||
}))
|
||||
|
|
|
@ -6,7 +6,9 @@ edition = "2021"
|
|||
[dependencies]
|
||||
clap = { version = "4.5.20", features = ["cargo", "derive", "string"] }
|
||||
icepick-module = { version = "0.1.0", path = "../icepick-module" }
|
||||
keyfork-derive-util = { version = "0.2.1", registry = "distrust" }
|
||||
keyforkd-client = { version = "0.2.1", registry = "distrust" }
|
||||
keyforkd-models = { version = "0.2.0", registry = "distrust" }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
thiserror = "2.0.3"
|
||||
|
|
|
@ -18,7 +18,33 @@ pub fn get_command(bin_name: &str) -> (&str, Vec<&str>) {
|
|||
struct ModuleConfig {
|
||||
name: String,
|
||||
command_name: Option<String>,
|
||||
derivation_prefix: String,
|
||||
algorithm: keyfork_derive_util::request::DerivationAlgorithm,
|
||||
#[serde(with = "serde_derivation")]
|
||||
derivation_prefix: keyfork_derive_util::DerivationPath,
|
||||
}
|
||||
|
||||
mod serde_derivation {
|
||||
use keyfork_derive_util::DerivationPath;
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn serialize<S>(p: &DerivationPath, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let path = p.to_string();
|
||||
serializer.serialize_str(&path)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<DerivationPath, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
use serde::de::Error;
|
||||
String::deserialize(deserializer).and_then(|string| {
|
||||
DerivationPath::from_str(&string).map_err(|e| Error::custom(e.to_string()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
|
@ -45,7 +71,10 @@ pub fn do_cli_thing() {
|
|||
// and coin_bin otherwise wouldn't live long enough
|
||||
for module in &config.modules {
|
||||
let module_name = &module.name;
|
||||
let bin = module.command_name.clone().unwrap_or_else(|| format!("icepick-{module_name}"));
|
||||
let bin = module
|
||||
.command_name
|
||||
.clone()
|
||||
.unwrap_or_else(|| format!("icepick-{module_name}"));
|
||||
let (command, args) = get_command(&bin);
|
||||
let mut child = Command::new(command)
|
||||
.args(args)
|
||||
|
@ -93,6 +122,10 @@ pub fn do_cli_thing() {
|
|||
}
|
||||
let blob = cli_input.as_ref().and_then(|json| json.get("blob"));
|
||||
|
||||
let derivation_accounts = cli_input
|
||||
.as_ref()
|
||||
.and_then(|json| json.get("derivation-accounts"));
|
||||
|
||||
let matches = icepick_command.get_matches();
|
||||
if let Some((module, matches)) = matches.subcommand() {
|
||||
if let Some((subcommand, matches)) = matches.subcommand() {
|
||||
|
@ -107,19 +140,50 @@ pub fn do_cli_thing() {
|
|||
for arg in &operation.arguments {
|
||||
args.insert(&arg.name, matches.get_one::<String>(&arg.name));
|
||||
}
|
||||
|
||||
let (algo, path) = config.modules.iter().find_map(|fmodule| {
|
||||
if fmodule.name == module {
|
||||
return Some((fmodule.algorithm.clone(), fmodule.derivation_prefix.clone()))
|
||||
}
|
||||
None
|
||||
}).unwrap();
|
||||
|
||||
let mut derived_keys: Vec<Vec<u8>> = vec![];
|
||||
if let Some(accounts) = derivation_accounts {
|
||||
let accounts: Vec<keyfork_derive_util::DerivationIndex> =
|
||||
serde_json::from_value(accounts.clone())
|
||||
.expect("valid derivation-accounts");
|
||||
let mut client =
|
||||
keyforkd_client::Client::discover_socket().expect("keyforkd started");
|
||||
for account in accounts {
|
||||
let request = keyfork_derive_util::request::DerivationRequest::new(algo.clone(), &path.clone().chain_push(account));
|
||||
let request = keyforkd_models::Request::Derivation(request);
|
||||
let response = client.request(&request).expect("valid derivation");
|
||||
match response {
|
||||
keyforkd_models::Response::Derivation(keyfork_derive_util::request::DerivationResponse { data, .. }) => {
|
||||
derived_keys.push(data.to_vec());
|
||||
},
|
||||
_ => panic!("Unexpected response"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let json = serde_json::json!({
|
||||
"operation": subcommand,
|
||||
"values": args,
|
||||
"derived-keys": [],
|
||||
"derived-keys": derived_keys,
|
||||
"blob": blob,
|
||||
});
|
||||
let bin = commands.iter().find_map(|(fmodule, fcommand, _)| {
|
||||
if fmodule == module {
|
||||
Some(fcommand)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}).expect("previously found module should exist in new search");
|
||||
let bin = commands
|
||||
.iter()
|
||||
.find_map(|(fmodule, fcommand, _)| {
|
||||
if fmodule == module {
|
||||
Some(fcommand)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.expect("previously found module should exist in new search");
|
||||
let (command, args) = get_command(bin);
|
||||
let mut child = Command::new(command)
|
||||
.args(args)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
[[module]]
|
||||
name = "sol"
|
||||
derivation_prefix = "m/44'/501'"
|
||||
algorithm = "Ed25519"
|
||||
|
|
Loading…
Reference in New Issue