pcli/command/view/
address.rs1use anyhow::Result;
2use base64::Engine;
3use rand_core::OsRng;
4use std::str::FromStr;
5
6use penumbra_sdk_keys::{keys::AddressIndex, Address, FullViewingKey};
7
8#[derive(Debug, clap::Parser)]
9pub struct AddressCmd {
10 #[clap(default_value = "0")]
12 address_or_index: String,
13 #[clap(short, long)]
15 ephemeral: bool,
16 #[clap(long)]
18 base64: bool,
19 #[clap(long)]
21 transparent: bool,
22 #[clap(long)]
24 fvk: bool,
25 #[clap(long)]
27 from_fvk: Option<String>,
28}
29
30impl AddressCmd {
31 pub fn offline(&self) -> bool {
33 true
34 }
35
36 pub fn exec(&self, fvk: &FullViewingKey) -> Result<()> {
37 let index: Result<u32, _> = self.address_or_index.parse();
38
39 if let Ok(index) = index {
40 let (address, _dtk) = match self.ephemeral {
43 false => fvk.incoming().payment_address(index.into()),
44 true => fvk.incoming().ephemeral_address(OsRng, index.into()),
45 };
46
47 if self.base64 {
48 println!(
49 "{}",
50 base64::engine::general_purpose::STANDARD.encode(address.to_vec()),
51 );
52 } else if self.transparent {
53 if index != 0 {
54 return Err(anyhow::anyhow!(
55 "warning: index must be 0 to use transparent address encoding"
56 ));
57 }
58 println!("{}", fvk.incoming().transparent_address());
59 } else {
60 if self.fvk {
61 eprintln!("🔥 CAUTION: POSSESSION OF THE FOLLOWING FULL VIEWING KEY WILL");
62 eprintln!("🔥 PROVIDE VISIBILITY TO ALL ACTIVITY ON ITS ASSOCIATED ACCOUNTS.");
63 eprintln!("🔥 DISTRIBUTE WITH CARE!");
64 eprintln!("");
65 println!("{}", fvk);
66 } else if let Some(fvk) = &self.from_fvk {
67 let (address, _) = FullViewingKey::payment_address(
68 &FullViewingKey::from_str(&fvk[..])?,
69 AddressIndex::new(0),
70 );
71
72 println!("{}", address);
73 } else {
74 println!("{}", address);
75 }
76 };
77 } else {
78 let address: Address = self
81 .address_or_index
82 .parse()
83 .map_err(|_| anyhow::anyhow!("Provided address is invalid."))?;
84
85 match fvk.address_index(&address) {
86 Some(address_index) => println!(
87 "Address is viewable with this full viewing key. Account index is {0}. {1}",
88 address_index.account,
89 match address_index.randomizer != [0u8; 12] {
90 true => "Address is an IBC deposit address.",
91 false => "",
92 }
93 ),
94 None => println!("Address is not viewable with this full viewing key."),
95 }
96 }
97
98 Ok(())
99 }
100}