refactor to make kebab-case (almost) entirely an Icepick thing rather than a thing per-interface
This commit is contained in:
parent
d7e61b4ae1
commit
a18282d107
|
@ -106,29 +106,24 @@ impl std::fmt::Display for Cluster {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct GetBlockhash {
|
||||
cluster: Option<Cluster>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct GenerateWallet {
|
||||
account: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct GetWalletAddress {}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct GetTokenInfo {
|
||||
token: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Transfer {
|
||||
amount: String,
|
||||
to_address: String,
|
||||
|
@ -140,7 +135,6 @@ pub struct Transfer {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct CreateTokenAccount {
|
||||
funder_address: Option<String>,
|
||||
wallet_address: String,
|
||||
|
@ -148,7 +142,6 @@ pub struct CreateTokenAccount {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct TransferToken {
|
||||
amount: String,
|
||||
token_address: String,
|
||||
|
@ -162,19 +155,16 @@ pub struct TransferToken {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Sign {
|
||||
blockhash: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Broadcast {
|
||||
cluster: Option<Cluster>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
pub struct Request {
|
||||
// NOTE: Can't use the proper XPrv type from Keyfork because Solana's a big stinky
|
||||
// and adds in its own derivation constructs that cause type conflicts.
|
||||
|
@ -188,7 +178,7 @@ pub struct Request {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(tag = "operation", content = "values", rename_all = "kebab-case")]
|
||||
#[serde(tag = "operation", content = "values")]
|
||||
pub enum Operation {
|
||||
GetBlockhash(GetBlockhash),
|
||||
GenerateWallet(GenerateWallet),
|
||||
|
@ -406,14 +396,16 @@ impl Module for Solana {
|
|||
let client = solana_rpc_client::rpc_client::RpcClient::new(cluster_url);
|
||||
let response = client.get_latest_blockhash().unwrap();
|
||||
Ok(serde_json::json!({
|
||||
"blob": response.to_string(),
|
||||
"blob": {
|
||||
"blockhash": response.to_string(),
|
||||
},
|
||||
}))
|
||||
}
|
||||
Operation::GenerateWallet(GenerateWallet { account }) => {
|
||||
let account = u32::from_str(account.as_deref().unwrap_or("0")).unwrap();
|
||||
Ok(serde_json::json!({
|
||||
"blob": null,
|
||||
"derivation-accounts": [(account | 1 << 31)],
|
||||
"blob": {},
|
||||
"derivation_accounts": [(account | 1 << 31)],
|
||||
}))
|
||||
}
|
||||
Operation::GetWalletAddress(_) => {
|
||||
|
@ -422,7 +414,9 @@ impl Module for Solana {
|
|||
let keypair = Self::keypair_from_bytes(key);
|
||||
let pubkey = keypair.pubkey();
|
||||
Ok(serde_json::json!({
|
||||
"blob": pubkey.to_string(),
|
||||
"blob": {
|
||||
"pubkey": pubkey.to_string(),
|
||||
}
|
||||
}))
|
||||
}
|
||||
Operation::GetTokenInfo(GetTokenInfo { token }) => {
|
||||
|
@ -442,7 +436,8 @@ impl Module for Solana {
|
|||
}
|
||||
}),
|
||||
None => serde_json::json!({
|
||||
"blob": null,
|
||||
"blob": {},
|
||||
"error": "key was not found!",
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
@ -499,8 +494,10 @@ impl Module for Solana {
|
|||
requested_accounts.push(*account | 1 << 31);
|
||||
}
|
||||
Ok(serde_json::json!({
|
||||
"blob": transaction,
|
||||
"derivation-accounts": requested_accounts,
|
||||
"blob": {
|
||||
"transaction": transaction,
|
||||
},
|
||||
"derivation_accounts": requested_accounts,
|
||||
}))
|
||||
}
|
||||
Operation::CreateTokenAccount(CreateTokenAccount {
|
||||
|
@ -528,8 +525,10 @@ impl Module for Solana {
|
|||
let transaction = solana_sdk::transaction::Transaction::new_unsigned(message);
|
||||
#[allow(clippy::identity_op)]
|
||||
Ok(serde_json::json!({
|
||||
"blob": transaction,
|
||||
"derivation-accounts": [0u32 | 1 << 31],
|
||||
"blob": {
|
||||
"transaction": transaction,
|
||||
},
|
||||
"derivation_accounts": [0u32 | 1 << 31],
|
||||
}))
|
||||
}
|
||||
Operation::TransferToken(TransferToken {
|
||||
|
@ -619,14 +618,19 @@ impl Module for Solana {
|
|||
|
||||
#[allow(clippy::identity_op)]
|
||||
Ok(serde_json::json!({
|
||||
"blob": transaction,
|
||||
"derivation-accounts": [0u32 | 1 << 31],
|
||||
"blob": {
|
||||
"transaction": transaction,
|
||||
},
|
||||
"derivation_accounts": [0u32 | 1 << 31],
|
||||
}))
|
||||
}
|
||||
Operation::Sign(Sign { blockhash }) => {
|
||||
let blob = request.blob.expect("passed in instruction blob");
|
||||
let transaction = request
|
||||
.blob
|
||||
.and_then(|b| b.get("transaction").cloned())
|
||||
.expect("was given transaction");
|
||||
let mut transaction: solana_sdk::transaction::Transaction =
|
||||
serde_json::from_value(blob).expect("valid message blob");
|
||||
serde_json::from_value(transaction).expect("valid message blob");
|
||||
let keys = request
|
||||
.derived_keys
|
||||
.unwrap_or_default()
|
||||
|
@ -639,16 +643,21 @@ impl Module for Solana {
|
|||
.try_sign(&keys, hash)
|
||||
.expect("not enough keys provided");
|
||||
Ok(serde_json::json!({
|
||||
"blob": transaction,
|
||||
"blob": {
|
||||
"transaction": transaction,
|
||||
}
|
||||
}))
|
||||
}
|
||||
Operation::Broadcast(Broadcast { cluster }) => {
|
||||
let cluster = cluster.unwrap_or(Cluster::MainnetBeta);
|
||||
let cluster_url = format!("https://api.{cluster}.solana.com");
|
||||
|
||||
let blob = request.blob.expect("passed in instruction blob");
|
||||
let transaction = request
|
||||
.blob
|
||||
.and_then(|b| b.get("transaction").cloned())
|
||||
.expect("was given transaction");
|
||||
let transaction: solana_sdk::transaction::Transaction =
|
||||
serde_json::from_value(blob).expect("valid message blob");
|
||||
serde_json::from_value(transaction).expect("valid message blob");
|
||||
transaction.verify().expect("invalid signatures");
|
||||
let client = solana_rpc_client::rpc_client::RpcClient::new(cluster_url);
|
||||
let _simulated_response = client.simulate_transaction(&transaction).unwrap();
|
||||
|
|
|
@ -124,7 +124,7 @@ pub fn do_cli_thing() {
|
|||
|
||||
let derivation_accounts = cli_input
|
||||
.as_ref()
|
||||
.and_then(|json| json.get("derivation-accounts"));
|
||||
.and_then(|json| json.get("derivation_accounts"));
|
||||
|
||||
let matches = icepick_command.get_matches();
|
||||
if let Some((module, matches)) = matches.subcommand() {
|
||||
|
@ -134,44 +134,77 @@ pub fn do_cli_thing() {
|
|||
.find(|(name, ..)| *name == module)
|
||||
.and_then(|(.., operations)| operations.iter().find(|o| o.name == subcommand))
|
||||
{
|
||||
let mut args = std::collections::HashMap::<&String, Option<&String>>::with_capacity(
|
||||
let mut args = std::collections::HashMap::<String, Option<&String>>::with_capacity(
|
||||
operation.arguments.len(),
|
||||
);
|
||||
for arg in &operation.arguments {
|
||||
args.insert(&arg.name, matches.get_one::<String>(&arg.name));
|
||||
args.insert(
|
||||
arg.name.replace('-', "_"),
|
||||
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 (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");
|
||||
.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 = 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, .. }) => {
|
||||
keyforkd_models::Response::Derivation(
|
||||
keyfork_derive_util::request::DerivationResponse { data, .. },
|
||||
) => {
|
||||
derived_keys.push(data.to_vec());
|
||||
},
|
||||
}
|
||||
_ => panic!("Unexpected response"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// in the event this is not PascalCase, this would be false.
|
||||
// we set this to true to capitalize the first character.
|
||||
let mut last_char_was_dash = true;
|
||||
let subcommand = subcommand
|
||||
.chars()
|
||||
.filter_map(|c| {
|
||||
if last_char_was_dash {
|
||||
last_char_was_dash = false;
|
||||
return Some(c.to_ascii_uppercase());
|
||||
}
|
||||
if c == '-' {
|
||||
last_char_was_dash = true;
|
||||
None
|
||||
} else {
|
||||
Some(c)
|
||||
}
|
||||
})
|
||||
.collect::<String>();
|
||||
let json = serde_json::json!({
|
||||
"operation": subcommand,
|
||||
"values": args,
|
||||
"derived-keys": derived_keys,
|
||||
"derived_keys": derived_keys,
|
||||
"blob": blob,
|
||||
});
|
||||
let bin = commands
|
||||
|
|
|
@ -11,7 +11,7 @@ printf "%s" "Amount of token to transfer: "
|
|||
read token_amount
|
||||
|
||||
echo "Acquiring blockhash..."
|
||||
blockhash="$(icepick sol get-blockhash --cluster devnet | jq -r .blob)"
|
||||
blockhash="$(icepick sol get-blockhash --cluster devnet | jq -r .blob.blockhash)"
|
||||
|
||||
echo "Saving information to file"
|
||||
|
||||
|
|
Loading…
Reference in New Issue