|
15 | 15 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
16 | 16 | # DEALINGS IN THE SOFTWARE.
|
17 | 17 |
|
18 |
| -from urllib.parse import urlparse |
19 | 18 | import ast
|
| 19 | +from collections import namedtuple |
20 | 20 | import hashlib
|
21 | 21 | from typing import Any, Literal, Union, Optional, TYPE_CHECKING
|
| 22 | +from urllib.parse import urlparse |
22 | 23 |
|
23 | 24 | import scalecodec
|
24 | 25 | from bittensor_wallet import Keypair
|
25 | 26 | from substrateinterface.utils import ss58
|
26 | 27 |
|
27 | 28 | from bittensor.core.settings import SS58_FORMAT
|
28 | 29 | from bittensor.utils.btlogging import logging
|
| 30 | +from bittensor_wallet.errors import KeyFileError, PasswordError |
29 | 31 | from .registration import torch, use_torch
|
30 | 32 | from .version import version_checking, check_version, VersionCheckError
|
31 | 33 |
|
32 | 34 | if TYPE_CHECKING:
|
33 | 35 | from bittensor.utils.async_substrate_interface import AsyncSubstrateInterface
|
34 | 36 | from substrateinterface import SubstrateInterface
|
| 37 | + from bittensor_wallet import Wallet |
35 | 38 |
|
36 | 39 | RAOPERTAO = 1e9
|
37 | 40 | U16_MAX = 65535
|
38 | 41 | U64_MAX = 18446744073709551615
|
39 | 42 |
|
40 | 43 |
|
| 44 | +UnlockStatus = namedtuple("UnlockStatus", ["success", "message"]) |
| 45 | + |
| 46 | + |
41 | 47 | def ss58_to_vec_u8(ss58_address: str) -> list[int]:
|
42 | 48 | ss58_bytes: bytes = ss58_address_to_bytes(ss58_address)
|
43 | 49 | encoded_address: list[int] = [int(byte) for byte in ss58_bytes]
|
@@ -370,3 +376,30 @@ def validate_chain_endpoint(endpoint_url: str) -> tuple[bool, str]:
|
370 | 376 | if not parsed.netloc:
|
371 | 377 | return False, "Invalid URL passed as the endpoint"
|
372 | 378 | return True, ""
|
| 379 | + |
| 380 | + |
| 381 | +def unlock_key(wallet: "Wallet", unlock_type="coldkey") -> "UnlockStatus": |
| 382 | + """ |
| 383 | + Attempts to decrypt a wallet's coldkey or hotkey |
| 384 | + Args: |
| 385 | + wallet: a Wallet object |
| 386 | + unlock_type: the key type, 'coldkey' or 'hotkey' |
| 387 | + Returns: UnlockStatus for success status of unlock, with error message if unsuccessful |
| 388 | + """ |
| 389 | + if unlock_type == "coldkey": |
| 390 | + unlocker = "unlock_coldkey" |
| 391 | + elif unlock_type == "hotkey": |
| 392 | + unlocker = "unlock_hotkey" |
| 393 | + else: |
| 394 | + raise ValueError( |
| 395 | + f"Invalid unlock type provided: {unlock_type}. Must be 'coldkey' or 'hotkey'." |
| 396 | + ) |
| 397 | + try: |
| 398 | + getattr(wallet, unlocker)() |
| 399 | + return UnlockStatus(True, "") |
| 400 | + except PasswordError: |
| 401 | + err_msg = f"The password used to decrypt your {unlock_type.capitalize()} keyfile is invalid." |
| 402 | + return UnlockStatus(False, err_msg) |
| 403 | + except KeyFileError: |
| 404 | + err_msg = f"{unlock_type.capitalize()} keyfile is corrupt, non-writable, or non-readable, or non-existent." |
| 405 | + return UnlockStatus(False, err_msg) |
0 commit comments