leo_package/root/
env.rs

1// Copyright (C) 2019-2024 Aleo Systems Inc.
2// This file is part of the Leo library.
3
4// The Leo library is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// The Leo library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
16
17//! The `.env` file.
18use leo_errors::{PackageError, Result};
19use leo_retriever::NetworkName;
20use snarkvm::console::account::PrivateKey;
21
22use snarkvm::prelude::{MainnetV0, Network, TestnetV0};
23
24use serde::Deserialize;
25use std::{borrow::Cow, fmt, fs::File, io::Write, path::Path};
26
27pub static ENV_FILENAME: &str = ".env";
28
29#[derive(Deserialize)]
30pub struct Env<N: Network> {
31    #[serde(bound(deserialize = ""))]
32    private_key: PrivateKey<N>,
33    endpoint: String,
34}
35
36impl<N: Network> Env<N> {
37    pub fn new(private_key: Option<PrivateKey<N>>, endpoint: String) -> Result<Self> {
38        // Initialize an RNG.
39        let rng = &mut rand::thread_rng();
40
41        // Generate a development private key.
42        let private_key = match private_key {
43            Some(private_key) => private_key,
44            None => PrivateKey::<N>::new(rng)?,
45        };
46
47        Ok(Self { private_key, endpoint })
48    }
49
50    pub fn exists_at(path: &Path) -> bool {
51        let mut path = Cow::from(path);
52        if path.is_dir() {
53            path.to_mut().push(ENV_FILENAME);
54        }
55        path.exists()
56    }
57
58    pub fn write_to(self, path: &Path) -> Result<()> {
59        let mut path = Cow::from(path);
60        if path.is_dir() {
61            path.to_mut().push(ENV_FILENAME);
62        }
63
64        let mut file = File::create(&path).map_err(PackageError::io_error_env_file)?;
65        file.write_all(self.to_string().as_bytes()).map_err(PackageError::io_error_env_file)?;
66        Ok(())
67    }
68}
69
70impl<N: Network> fmt::Display for Env<N> {
71    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72        // Get the network name.
73        let network = match N::ID {
74            MainnetV0::ID => NetworkName::MainnetV0,
75            TestnetV0::ID => NetworkName::TestnetV0,
76            _ => unimplemented!("Unsupported network"),
77        };
78        // Write the formatted string.
79        write!(f, "NETWORK={network}\nPRIVATE_KEY={}\nENDPOINT={}\n", self.private_key, self.endpoint)
80    }
81}