Skip to content

Commit 77faaa9

Browse files
authored
Merge pull request #158 from opentensor/release/3.1.0
Release/3.1.0
2 parents 9dbf45a + db54a07 commit 77faaa9

File tree

8 files changed

+292
-47
lines changed

8 files changed

+292
-47
lines changed

CHANGELOG.MD

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## 3.1.0 /2025-07-07
4+
5+
## What's Changed
6+
* Add `hotkeypub` to bittensor-wallet by @basfroman in https://github.com/opentensor/btwallet/pull/156
7+
8+
**Full Changelog**: https://github.com/opentensor/btwallet/compare/v3.0.11...v3.1.0
9+
310
## 3.0.11 /2025-06-26
411

512
## What's Changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "bittensor_wallet"
3-
version = "3.0.11"
3+
version = "3.1.0"
44
edition = "2021"
55

66
[lib]

bittensor_wallet/wallet/__init__.pyi

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class Wallet:
5252
def get_coldkey(self, password: Optional[str] = None) -> "Keypair": ...
5353
def get_coldkeypub(self, password: Optional[str] = None) -> "Keypair": ...
5454
def get_hotkey(self, password: Optional[str] = None) -> "Keypair": ...
55+
def get_hotkeypub(self, password: Optional[str] = None) -> "Keypair": ...
5556
def set_coldkey(
5657
self,
5758
keypair: "Keypair",
@@ -74,19 +75,29 @@ class Wallet:
7475
save_hotkey_to_env: bool = False,
7576
hotkey_password: Optional[str] = None,
7677
) -> None: ...
78+
def set_hotkeypub(
79+
self,
80+
keypair: "Keypair",
81+
encrypt: bool = False,
82+
overwrite: bool = False,
83+
) -> None: ...
7784
@property
7885
def coldkey(self) -> "Keypair": ...
7986
@property
8087
def coldkeypub(self) -> "Keypair": ...
8188
@property
8289
def hotkey(self) -> "Keypair": ...
8390
@property
91+
def hotkeypub(self) -> "Keypair": ...
92+
@property
8493
def coldkey_file(self) -> "Keyfile": ...
8594
@property
8695
def coldkeypub_file(self) -> "Keyfile": ...
8796
@property
8897
def hotkey_file(self) -> "Keyfile": ...
8998
@property
99+
def hotkeypub_file(self) -> "Keyfile": ...
100+
@property
90101
def name(self) -> str: ...
91102
@property
92103
def path(self) -> str: ...
@@ -113,6 +124,7 @@ class Wallet:
113124
def unlock_coldkey(self) -> "Keypair": ...
114125
def unlock_coldkeypub(self) -> "Keypair": ...
115126
def unlock_hotkey(self) -> "Keypair": ...
127+
def unlock_hotkeypub(self) -> "Keypair": ...
116128
def new_coldkey(
117129
self,
118130
n_words: Optional[int] = 12,
@@ -177,3 +189,9 @@ class Wallet:
177189
save_hotkey_to_env: Optional[bool] = False,
178190
hotkey_password: Optional[str] = None,
179191
) -> "Wallet": ...
192+
def regenerate_hotkeypub(
193+
self,
194+
ss58_address: Optional[str] = None,
195+
public_key: Optional[bytes] = None,
196+
overwrite: Optional[bool] = False,
197+
) -> "Wallet": ...

src/python_bindings.rs

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ fn bittensor_wallet(module: Bound<'_, PyModule>) -> PyResult<()> {
477477
module.add_class::<PyKeyfile>()?;
478478
module.add_class::<PyKeypair>()?;
479479
module.add_class::<Wallet>()?;
480-
480+
481481
// Add submodules to the main module
482482
register_config_module(&module)?;
483483
register_errors_module(&module)?;
@@ -1000,6 +1000,15 @@ except argparse.ArgumentError:
10001000
Ok(PyKeypair { inner: keypair })
10011001
}
10021002

1003+
#[pyo3(signature = (password=None))]
1004+
fn get_hotkeypub(&self, password: Option<String>) -> PyResult<PyKeypair> {
1005+
let keypair = self
1006+
.inner
1007+
.get_hotkeypub(password)
1008+
.map_err(|e| PyErr::new::<PyKeyFileError, _>(e))?;
1009+
Ok(PyKeypair { inner: keypair })
1010+
}
1011+
10031012
#[pyo3(signature = (keypair, encrypt=true, overwrite=false, save_coldkey_to_env=false, coldkey_password=None))]
10041013
fn set_coldkey(
10051014
&mut self,
@@ -1052,6 +1061,18 @@ except argparse.ArgumentError:
10521061
.map_err(|e| PyErr::new::<PyKeyFileError, _>(e))
10531062
}
10541063

1064+
#[pyo3(signature = (keypair, encrypt=false, overwrite=false))]
1065+
fn set_hotkeypub(
1066+
&mut self,
1067+
keypair: PyKeypair,
1068+
encrypt: bool,
1069+
overwrite: bool,
1070+
) -> PyResult<()> {
1071+
self.inner
1072+
.set_hotkeypub(keypair.inner, encrypt, overwrite)
1073+
.map_err(|e| PyErr::new::<PyKeyFileError, _>(e))
1074+
}
1075+
10551076
// Getters
10561077
#[getter(coldkey)]
10571078
fn coldkey_py_property(&self) -> PyResult<PyKeypair> {
@@ -1077,6 +1098,14 @@ except argparse.ArgumentError:
10771098
Ok(PyKeypair { inner: keypair })
10781099
}
10791100

1101+
#[getter(hotkeypub)]
1102+
fn hotkeypub_py_property(&self) -> PyResult<PyKeypair> {
1103+
let keypair = self.inner.hotkeypub_property().map_err(|e| {
1104+
PyErr::new::<PyKeyFileError, _>(format!("Failed to get hotkeypub: {:?}", e))
1105+
})?;
1106+
Ok(PyKeypair { inner: keypair })
1107+
}
1108+
10801109
#[getter]
10811110
fn coldkey_file(&self) -> PyResult<PyKeyfile> {
10821111
self.inner
@@ -1101,6 +1130,14 @@ except argparse.ArgumentError:
11011130
.map_err(|e| PyErr::new::<PyKeyFileError, _>(e))
11021131
}
11031132

1133+
#[getter]
1134+
fn hotkeypub_file(&self) -> PyResult<PyKeyfile> {
1135+
self.inner
1136+
.hotkeypub_file()
1137+
.map(|inner| PyKeyfile { inner })
1138+
.map_err(|e| PyErr::new::<PyKeyFileError, _>(e))
1139+
}
1140+
11041141
#[getter]
11051142
fn name(&self) -> String {
11061143
self.inner.get_name()
@@ -1218,6 +1255,20 @@ except argparse.ArgumentError:
12181255
})
12191256
}
12201257

1258+
#[pyo3(text_signature = "($self)")]
1259+
fn unlock_hotkeypub(&mut self) -> PyResult<PyKeypair> {
1260+
self.inner
1261+
.unlock_hotkeypub()
1262+
.map(|inner| PyKeypair { inner })
1263+
.map_err(|e| match e {
1264+
KeyFileError::DecryptionError(_) => PyErr::new::<PyPasswordError, _>(format!(
1265+
"Decryption failed: {}",
1266+
e.to_string()
1267+
)),
1268+
_ => PyErr::new::<PyKeyFileError, _>(format!("Failed to unlock hotkey: {:?}", e)),
1269+
})
1270+
}
1271+
12211272
#[pyo3(
12221273
name = "create_new_coldkey",
12231274
signature = (n_words=Some(12), use_password=None, overwrite=None, suppress=None, save_coldkey_to_env=None, coldkey_password=None)
@@ -1377,4 +1428,21 @@ except argparse.ArgumentError:
13771428
inner: self.inner.clone(),
13781429
})
13791430
}
1431+
1432+
#[pyo3(signature = (ss58_address=None, public_key=None, overwrite=None))]
1433+
fn regenerate_hotkeypub(
1434+
&mut self,
1435+
ss58_address: Option<String>,
1436+
public_key: Option<String>,
1437+
overwrite: Option<bool>,
1438+
) -> PyResult<Self> {
1439+
let new_inner_wallet = self
1440+
.inner
1441+
.regenerate_hotkeypub(ss58_address, public_key, overwrite.unwrap_or(false))
1442+
.map_err(|e| PyErr::new::<PyKeyFileError, _>(e))?;
1443+
self.inner = new_inner_wallet;
1444+
Ok(Wallet {
1445+
inner: self.inner.clone(),
1446+
})
1447+
}
13801448
}

0 commit comments

Comments
 (0)