Skip to content

Commit

Permalink
[fix] Use user home directory for wallet path (#59)
Browse files Browse the repository at this point in the history
* Updates local -> environment vars in changelog

* closes GH #51 (#56)

* [fix] Use userhome for default wallet path ~ (#57)

* use userhome for default path ~

* bump ver

* expand path on init and use as _path

---------

Co-authored-by: ibraheem-opentensor <[email protected]>
Co-authored-by: ibraheem-opentensor <[email protected]>
Co-authored-by: Cameron Fairchild <[email protected]>
  • Loading branch information
4 people authored Nov 7, 2024
1 parent 708e140 commit f420553
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 43 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## What's Changed

* Add the ability to use local variables to store hot/coldkey passwords by @roman-opentensor in https://github.com/opentensor/btwallet/pull/46
* Add the ability to use environment variables to store hot/coldkey passwords by @roman-opentensor in https://github.com/opentensor/btwallet/pull/46
* fix/roman/fix-config-parsing by @roman-opentensor in https://github.com/opentensor/btwallet/pull/47

**Full Changelog**: https://github.com/opentensor/btwallet/compare/v2.0.1...v2.0.2
Expand Down
12 changes: 11 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bittensor_wallet"
version = "2.0.0"
version = "2.0.3"
edition = "2021"

[lib]
Expand All @@ -27,6 +27,7 @@ base64 = "0.22.1"
scrypt = "0.11.0"
pkcs8 = "0.10.2"
schnorrkel = "0.11.4"
shellexpand = "3.1.0"

[features]
extension-module = ["pyo3/extension-module"]
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "bittensor-wallet"
version = "2.0.2"
version = "2.0.3"
description = ""
readme = "README.md"
license = {file = "LICENSE"}
Expand Down
2 changes: 1 addition & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
pub const BT_WALLET_NAME: &str = "default";
pub const BT_WALLET_HOTKEY: &str = "default";
pub const BT_WALLET_PATH: &str = ".bittensor/wallets/";
pub const BT_WALLET_PATH: &str = "~/.bittensor/wallets/";
24 changes: 12 additions & 12 deletions src/keyfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use std::env;
use std::fs;
use std::io::{Read, Write};
use std::os::unix::fs::PermissionsExt;
use std::path::Path;
use std::path::PathBuf;
use std::str::from_utf8;

use ansible_vault::{decrypt_vault, encrypt_vault};
Expand Down Expand Up @@ -515,6 +515,7 @@ fn decrypt_password(data: String, key: String) -> String {
#[pyclass(subclass)]
pub struct Keyfile {
path: String,
_path: PathBuf,
name: String,
should_save_to_env: bool,
}
Expand All @@ -524,10 +525,11 @@ impl Keyfile {
#[new]
#[pyo3(signature = (path, name=None, should_save_to_env=false))]
pub fn new(path: String, name: Option<String>, should_save_to_env: bool) -> PyResult<Self> {
let path = expand_tilde(&path);
let expanded_path: PathBuf = PathBuf::from(expand_tilde(&path));
let name = name.unwrap_or_else(|| "Keyfile".to_string());
Ok(Keyfile {
path,
_path: expanded_path,
name,
should_save_to_env,
})
Expand Down Expand Up @@ -649,9 +651,7 @@ impl Keyfile {

/// Creates directories for the path if they do not exist.
pub fn make_dirs(&self) -> PyResult<()> {
// convert String to Path
let path: &Path = self.path.as_ref();
if let Some(directory) = path.parent() {
if let Some(directory) = self._path.parent() {
// check if the dir is exit already
if !directory.exists() {
// create the dir if not
Expand All @@ -666,7 +666,7 @@ impl Keyfile {
/// Returns:
/// readable (bool): ``True`` if the file is readable.
pub fn exists_on_device(&self) -> PyResult<bool> {
Ok(Path::new(&self.path).exists())
Ok(self._path.exists())
}

/// Returns ``True`` if the file under path is readable.
Expand All @@ -677,7 +677,7 @@ impl Keyfile {
}

// get file metadata
let metadata = fs::metadata(&self.path).map_err(|e| {
let metadata = fs::metadata(&self._path).map_err(|e| {
PyErr::new::<PyIOError, _>(format!("Failed to get metadata for file: {}.", e))
})?;

Expand All @@ -699,7 +699,7 @@ impl Keyfile {
}

// get file metadata
let metadata = fs::metadata(&self.path).map_err(|e| {
let metadata = fs::metadata(&self._path).map_err(|e| {
PyErr::new::<PyIOError, _>(format!("Failed to get metadata for file: {}", e))
})?;

Expand Down Expand Up @@ -989,7 +989,7 @@ impl Keyfile {
}

// open and read the file
let mut file = fs::File::open(&self.path)
let mut file = fs::File::open(&self._path)
.map_err(|e| PyErr::new::<PyOSError, _>(format!("Failed to open file: {}.", e)))?;
let mut data_vec = Vec::new();
file.read_to_end(&mut data_vec)
Expand Down Expand Up @@ -1025,7 +1025,7 @@ impl Keyfile {
.write(true)
.create(true)
.truncate(true) // cleanup if rewrite
.open(&self.path)
.open(&self._path)
.map_err(|e| PyErr::new::<PyIOError, _>(format!("Failed to open file: {}.", e)))?;

// write data
Expand All @@ -1034,9 +1034,9 @@ impl Keyfile {
.map_err(|e| PyErr::new::<PyIOError, _>(format!("Failed to write to file: {}.", e)))?;

// set permissions
let mut permissions = fs::metadata(&self.path)?.permissions();
let mut permissions = fs::metadata(&self._path)?.permissions();
permissions.set_mode(0o600); // just for owner
fs::set_permissions(&self.path, permissions).map_err(|e| {
fs::set_permissions(&self._path, permissions).map_err(|e| {
PyErr::new::<PyPermissionError, _>(format!("Failed to set permissions: {}.", e))
})?;
Ok(())
Expand Down
40 changes: 14 additions & 26 deletions src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use pyo3::types::{IntoPyDict, PyString, PyType};

use colored::Colorize;
use std::env;
use std::path::PathBuf;

use crate::config::Config;
use crate::constants::{BT_WALLET_HOTKEY, BT_WALLET_NAME, BT_WALLET_PATH};
Expand All @@ -12,10 +13,6 @@ use crate::keyfile::Keyfile;
use crate::keypair::Keypair;
use crate::utils::{self, is_valid_bittensor_address_or_public_key};

use dirs::home_dir;

type PyRuntimeError = KeyFileError;

/// Display the mnemonic and a warning message to keep the mnemonic safe.
#[pyfunction]
#[pyo3(signature = (mnemonic, key_type))]
Expand Down Expand Up @@ -65,6 +62,8 @@ pub struct Wallet {
pub path: String,
pub hotkey: String,

_path: PathBuf,

_coldkey: Option<Keypair>,
_coldkeypub: Option<Keypair>,
_hotkey: Option<Keypair>,
Expand Down Expand Up @@ -132,17 +131,18 @@ impl Wallet {
path
} else if let Some(conf_path) = conf_path {
conf_path
.strip_prefix("~/")
.unwrap_or(&conf_path)
.to_string()
} else {
BT_WALLET_PATH.to_string()
};

let expanded_path: PathBuf = PathBuf::from(shellexpand::tilde(&final_path).to_string());

Ok(Wallet {
name: final_name,
hotkey: final_hotkey,
path: final_path,
path: final_path.clone(),

_path: expanded_path,

_coldkey: None,
_coldkeypub: None,
Expand All @@ -152,14 +152,14 @@ impl Wallet {

fn __str__(&self) -> PyResult<String> {
Ok(format!(
"Wallet (Name: '{:}', Hotkey: '{:}', Path: '~/{:}')",
"Wallet (Name: '{:}', Hotkey: '{:}', Path: '{:}')",
self.name, self.hotkey, self.path
))
}

fn __repr__(&self) -> PyResult<String> {
Ok(format!(
"name: '{:}', hotkey: '{:}', path: '~/{:}'",
"name: '{:}', hotkey: '{:}', path: '{:}'",
self.name, self.hotkey, self.path
))
}
Expand Down Expand Up @@ -389,12 +389,8 @@ except argparse.ArgumentError:
/// Created Hot Keyfile for Keypair
#[pyo3(signature = (save_hotkey_to_env=false))]
pub fn create_hotkey_file(&self, save_hotkey_to_env: bool) -> PyResult<Keyfile> {
// get home dir
let home = home_dir()
.ok_or_else(|| PyErr::new::<PyRuntimeError, _>("Failed to get user home directory."))?;

// concatenate wallet path
let wallet_path = home.join(&self.path).join(&self.name);
let wallet_path = self._path.join(&self.name);

// concatenate hotkey path
let hotkey_path = wallet_path.join("hotkeys").join(&self.hotkey);
Expand All @@ -415,12 +411,8 @@ except argparse.ArgumentError:
/// Created Cold Keyfile for Keypair
#[pyo3(signature = (save_coldkey_to_env=false))]
pub fn create_coldkey_file(&self, save_coldkey_to_env: bool) -> PyResult<Keyfile> {
// get home dir
let home = home_dir()
.ok_or_else(|| PyErr::new::<PyRuntimeError, _>("Failed to get user home directory."))?;

// concatenate wallet path
let wallet_path = home.join(&self.path).join(&self.name);
let wallet_path = PathBuf::from(&self._path).join(&self.name);

// concatenate coldkey path
let coldkey_path = wallet_path.join("coldkey");
Expand All @@ -434,12 +426,8 @@ except argparse.ArgumentError:
/// Property that returns the coldkeypub file.
#[getter]
pub fn coldkeypub_file(&self) -> PyResult<Keyfile> {
// get home dir
let home = home_dir()
.ok_or_else(|| PyErr::new::<PyRuntimeError, _>("Failed to get user home directory."))?;

// concatenate wallet path
let wallet_path = home.join(&self.path).join(&self.name);
let wallet_path = self._path.join(&self.name);

// concatenate hotkey path
let coldkeypub_path = wallet_path.join("coldkeypub.txt");
Expand Down Expand Up @@ -834,7 +822,7 @@ except argparse.ArgumentError:

let keypair = Keypair::new(ss58_address, public_key, None, 42, None, 1)?;

self.set_coldkeypub(keypair, overwrite, false, py)?;
self.set_coldkeypub(keypair, false, overwrite, py)?;
Ok(self.clone())
}

Expand Down

0 comments on commit f420553

Please sign in to comment.