penumbra_sdk_custody/soft_kms/
config.rs1use crate::policy::AuthPolicy;
2use penumbra_sdk_keys::keys::SpendKey;
3use serde::{Deserialize, Serialize};
4use serde_with::DisplayFromStr;
5
6#[serde_as]
11#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
12pub struct Config {
13 #[serde_as(as = "DisplayFromStr")]
14 pub spend_key: SpendKey,
15 #[serde(default, skip_serializing_if = "is_default")]
16 pub auth_policy: Vec<AuthPolicy>,
17}
18
19impl From<SpendKey> for Config {
20 fn from(spend_key: SpendKey) -> Self {
21 Self {
22 spend_key,
23 auth_policy: Default::default(),
24 }
25 }
26}
27
28fn is_default<T: Default + Eq>(value: &T) -> bool {
36 *value == T::default()
37}
38
39#[cfg(test)]
40mod tests {
41 use penumbra_sdk_keys::keys::{Bip44Path, SeedPhrase};
42
43 use crate::policy::PreAuthorizationPolicy;
44
45 use super::*;
46
47 #[test]
48 fn toml_config_round_trip() {
49 let seed_phrase = SeedPhrase::generate(rand_core::OsRng);
50 let spend_key = SpendKey::from_seed_phrase_bip44(seed_phrase, &Bip44Path::new(0));
51
52 let pak = ed25519_consensus::SigningKey::new(rand_core::OsRng);
53 let pvk = pak.verification_key();
54
55 let auth_policy = vec![
56 AuthPolicy::OnlyIbcRelay,
57 AuthPolicy::DestinationAllowList {
58 allowed_destination_addresses: vec![
59 spend_key
60 .incoming_viewing_key()
61 .payment_address(Default::default())
62 .0,
63 ],
64 },
65 AuthPolicy::PreAuthorization(PreAuthorizationPolicy::Ed25519 {
66 required_signatures: 1,
67 allowed_signers: vec![pvk],
68 }),
69 ];
70
71 let example = Config {
72 spend_key: spend_key.clone(),
73 auth_policy,
74 };
75
76 let encoded = toml::to_string_pretty(&example).unwrap();
77 println!("{encoded}");
78 let example2 = toml::from_str(&encoded).unwrap();
79 assert_eq!(example, example2);
80
81 println!("---");
82
83 let example3 = Config::from(spend_key);
84 println!("{}", toml::to_string_pretty(&example3).unwrap());
85 }
86}