snarkos_cli/commands/developer/
transfer_private.rs1use super::{DEFAULT_ENDPOINT, Developer};
17use crate::{
18 commands::StoreFormat,
19 helpers::args::{parse_private_key, prepare_endpoint},
20};
21use snarkvm::{
22 console::network::Network,
23 ledger::store::helpers::memory::BlockMemory,
24 prelude::{
25 Address,
26 Locator,
27 VM,
28 Value,
29 query::Query,
30 store::{ConsensusStore, helpers::memory::ConsensusMemory},
31 },
32};
33
34use aleo_std::StorageMode;
35use anyhow::Result;
36use clap::{Parser, builder::NonEmptyStringValueParser};
37use std::str::FromStr;
38use ureq::http::Uri;
39use zeroize::Zeroize;
40
41#[derive(Debug, Parser)]
43#[clap(
44 group(clap::ArgGroup::new("mode").required(true).multiple(false))
45)]
46pub struct TransferPrivate {
47 #[clap(long)]
49 input_record: String,
50 #[clap(long)]
52 recipient: String,
53 #[clap(long)]
55 amount: u64,
56 #[clap(short = 'p', long, group = "key", value_parser=NonEmptyStringValueParser::default())]
58 private_key: Option<String>,
59 #[clap(long, group = "key", value_parser=NonEmptyStringValueParser::default())]
61 private_key_file: Option<String>,
62 #[clap(long, group = "key")]
64 dev_key: Option<u16>,
65 #[clap(short, long, default_value=DEFAULT_ENDPOINT)]
67 endpoint: Uri,
68 #[clap(long)]
70 priority_fee: u64,
71 #[clap(long)]
73 fee_record: String,
74 #[clap(short, long, group = "mode")]
76 broadcast: Option<Option<Uri>>,
77 #[clap(short, long, group = "mode")]
79 dry_run: bool,
80 #[clap(long, group = "mode")]
82 store: Option<String>,
83 #[clap(long, value_enum, default_value_t = StoreFormat::Bytes, requires="store")]
86 store_format: StoreFormat,
87 #[clap(long, requires = "broadcast")]
89 wait: bool,
90 #[clap(long, default_value_t = 60, requires = "wait")]
92 timeout: u64,
93}
94
95impl Drop for TransferPrivate {
96 fn drop(&mut self) {
98 self.private_key.zeroize();
99 }
100}
101
102impl TransferPrivate {
103 pub fn parse<N: Network>(self) -> Result<String> {
105 let endpoint = prepare_endpoint(self.endpoint.clone())?;
106
107 let query = Query::<N, BlockMemory<N>>::from(endpoint.clone());
109
110 let recipient = Address::<N>::from_str(&self.recipient)?;
112
113 let private_key = parse_private_key(self.private_key.clone(), self.private_key_file.clone(), self.dev_key)?;
115 println!("📦 Creating private transfer of {} microcredits to {}...\n", self.amount, recipient);
116
117 let transaction = {
119 let rng = &mut rand::thread_rng();
121
122 let store = ConsensusStore::<N, ConsensusMemory<N>>::open(StorageMode::Production)?;
124
125 let vm = VM::from(store)?;
127
128 let fee_record = Developer::parse_record(&private_key, &self.fee_record)?;
130 let priority_fee = self.priority_fee;
131
132 let input_record = Developer::parse_record(&private_key, &self.input_record)?;
134 let inputs = [
135 Value::Record(input_record),
136 Value::from_str(&format!("{recipient}"))?,
137 Value::from_str(&format!("{}u64", self.amount))?,
138 ];
139
140 vm.execute(
142 &private_key,
143 ("credits.aleo", "transfer_private"),
144 inputs.iter(),
145 Some(fee_record),
146 priority_fee,
147 Some(&query),
148 rng,
149 )?
150 };
151 let locator = Locator::<N>::from_str("credits.aleo/transfer_private")?;
152 println!("✅ Created private transfer of {} microcredits to {}\n", &self.amount, recipient);
153
154 Developer::handle_transaction(
156 &endpoint,
157 &self.broadcast,
158 self.dry_run,
159 &self.store,
160 self.store_format,
161 self.wait,
162 self.timeout,
163 transaction,
164 locator.to_string(),
165 )
166 }
167}