bittensor-cli 8.3.0__py3-none-any.whl → 8.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bittensor_cli/__init__.py +1 -1
- bittensor_cli/cli.py +17 -7
- bittensor_cli/src/__init__.py +13 -9
- bittensor_cli/src/bittensor/async_substrate_interface.py +24 -30
- bittensor_cli/src/bittensor/extrinsics/registration.py +19 -23
- bittensor_cli/src/bittensor/extrinsics/root.py +3 -9
- bittensor_cli/src/bittensor/extrinsics/transfer.py +2 -5
- bittensor_cli/src/bittensor/subtensor_interface.py +5 -24
- bittensor_cli/src/bittensor/utils.py +60 -7
- bittensor_cli/src/commands/root.py +6 -24
- bittensor_cli/src/commands/stake/children_hotkeys.py +5 -9
- bittensor_cli/src/commands/stake/stake.py +6 -18
- bittensor_cli/src/commands/subnets.py +4 -10
- bittensor_cli/src/commands/sudo.py +6 -8
- bittensor_cli/src/commands/wallets.py +28 -22
- {bittensor_cli-8.3.0.dist-info → bittensor_cli-8.4.0.dist-info}/METADATA +3 -3
- bittensor_cli-8.4.0.dist-info/RECORD +31 -0
- {bittensor_cli-8.3.0.dist-info → bittensor_cli-8.4.0.dist-info}/WHEEL +1 -1
- bittensor_cli-8.3.0.dist-info/RECORD +0 -31
- {bittensor_cli-8.3.0.dist-info → bittensor_cli-8.4.0.dist-info}/entry_points.txt +0 -0
- {bittensor_cli-8.3.0.dist-info → bittensor_cli-8.4.0.dist-info}/top_level.txt +0 -0
bittensor_cli/__init__.py
CHANGED
bittensor_cli/cli.py
CHANGED
@@ -7,6 +7,7 @@ import os.path
|
|
7
7
|
import re
|
8
8
|
import ssl
|
9
9
|
import sys
|
10
|
+
import traceback
|
10
11
|
from pathlib import Path
|
11
12
|
from typing import Coroutine, Optional
|
12
13
|
from dataclasses import fields
|
@@ -57,7 +58,7 @@ except ImportError:
|
|
57
58
|
pass
|
58
59
|
|
59
60
|
|
60
|
-
__version__ = "8.
|
61
|
+
__version__ = "8.4.0"
|
61
62
|
|
62
63
|
|
63
64
|
_core_version = re.match(r"^\d+\.\d+\.\d+", __version__).group(0)
|
@@ -126,8 +127,6 @@ class Options:
|
|
126
127
|
use_password = typer.Option(
|
127
128
|
True,
|
128
129
|
help="Set this to `True` to protect the generated Bittensor key with a password.",
|
129
|
-
is_flag=True,
|
130
|
-
flag_value=False,
|
131
130
|
)
|
132
131
|
public_hex_key = typer.Option(None, help="The public key in hex format.")
|
133
132
|
ss58_address = typer.Option(
|
@@ -840,6 +839,7 @@ class CLIManager:
|
|
840
839
|
return result
|
841
840
|
except (ConnectionRefusedError, ssl.SSLError):
|
842
841
|
err_console.print(f"Unable to connect to the chain: {self.subtensor}")
|
842
|
+
verbose_console.print(traceback.format_exc())
|
843
843
|
except (
|
844
844
|
ConnectionClosed,
|
845
845
|
SubstrateRequestException,
|
@@ -847,6 +847,10 @@ class CLIManager:
|
|
847
847
|
) as e:
|
848
848
|
if isinstance(e, SubstrateRequestException):
|
849
849
|
err_console.print(str(e))
|
850
|
+
verbose_console.print(traceback.format_exc())
|
851
|
+
except Exception as e:
|
852
|
+
err_console.print(f"An unknown error has occurred: {e}")
|
853
|
+
verbose_console.print(traceback.format_exc())
|
850
854
|
finally:
|
851
855
|
if initiated is False:
|
852
856
|
asyncio.create_task(cmd).cancel()
|
@@ -1837,8 +1841,6 @@ class CLIManager:
|
|
1837
1841
|
use_password: bool = typer.Option(
|
1838
1842
|
False, # Overriden to False
|
1839
1843
|
help="Set to 'True' to protect the generated Bittensor key with a password.",
|
1840
|
-
is_flag=True,
|
1841
|
-
flag_value=True,
|
1842
1844
|
),
|
1843
1845
|
quiet: bool = Options.quiet,
|
1844
1846
|
verbose: bool = Options.verbose,
|
@@ -1895,8 +1897,6 @@ class CLIManager:
|
|
1895
1897
|
use_password: bool = typer.Option(
|
1896
1898
|
False, # Overriden to False
|
1897
1899
|
help="Set to 'True' to protect the generated Bittensor key with a password.",
|
1898
|
-
is_flag=True,
|
1899
|
-
flag_value=True,
|
1900
1900
|
),
|
1901
1901
|
quiet: bool = Options.quiet,
|
1902
1902
|
verbose: bool = Options.verbose,
|
@@ -3904,6 +3904,16 @@ class CLIManager:
|
|
3904
3904
|
)
|
3905
3905
|
param_name = hyperparam_list[choice - 1]
|
3906
3906
|
|
3907
|
+
if param_name in ["alpha_high", "alpha_low"]:
|
3908
|
+
param_name = "alpha_values"
|
3909
|
+
low_val = FloatPrompt.ask(
|
3910
|
+
"Enter the new value for [dark_orange]alpha_low[/dark_orange]"
|
3911
|
+
)
|
3912
|
+
high_val = FloatPrompt.ask(
|
3913
|
+
"Enter the new value for [dark_orange]alpha_high[/dark_orange]"
|
3914
|
+
)
|
3915
|
+
param_value = f"{low_val},{high_val}"
|
3916
|
+
|
3907
3917
|
if not param_value:
|
3908
3918
|
param_value = Prompt.ask(
|
3909
3919
|
f"Enter the new value for [dark_orange]{param_name}[/dark_orange] in the VALUE column format"
|
bittensor_cli/src/__init__.py
CHANGED
@@ -318,28 +318,32 @@ NETWORK_EXPLORER_MAP = {
|
|
318
318
|
|
319
319
|
|
320
320
|
HYPERPARAMS = {
|
321
|
-
"
|
321
|
+
"rho": "sudo_set_rho",
|
322
|
+
"kappa": "sudo_set_kappa",
|
323
|
+
"immunity_period": "sudo_set_immunity_period",
|
324
|
+
"min_allowed_weights": "sudo_set_min_allowed_weights",
|
325
|
+
"max_weights_limit": "sudo_set_max_weight_limit",
|
326
|
+
"tempo": "sudo_set_tempo",
|
322
327
|
"min_difficulty": "sudo_set_min_difficulty",
|
323
328
|
"max_difficulty": "sudo_set_max_difficulty",
|
324
329
|
"weights_version": "sudo_set_weights_version_key",
|
325
330
|
"weights_rate_limit": "sudo_set_weights_set_rate_limit",
|
326
|
-
"
|
327
|
-
"immunity_period": "sudo_set_immunity_period",
|
328
|
-
"min_allowed_weights": "sudo_set_min_allowed_weights",
|
331
|
+
"adjustment_interval": "sudo_set_adjustment_interval",
|
329
332
|
"activity_cutoff": "sudo_set_activity_cutoff",
|
330
|
-
"
|
331
|
-
"network_pow_registration_allowed": "sudo_set_network_pow_registration_allowed",
|
333
|
+
"target_regs_per_interval": "sudo_set_target_registrations_per_interval",
|
332
334
|
"min_burn": "sudo_set_min_burn",
|
333
335
|
"max_burn": "sudo_set_max_burn",
|
336
|
+
"bonds_moving_avg": "sudo_set_bonds_moving_average",
|
337
|
+
"max_regs_per_block": "sudo_set_max_registrations_per_block",
|
338
|
+
"serving_rate_limit": "sudo_set_serving_rate_limit",
|
339
|
+
"max_validators": "sudo_set_max_allowed_validators",
|
334
340
|
"adjustment_alpha": "sudo_set_adjustment_alpha",
|
335
|
-
"rho": "sudo_set_rho",
|
336
|
-
"kappa": "sudo_set_kappa",
|
337
341
|
"difficulty": "sudo_set_difficulty",
|
338
|
-
"bonds_moving_avg": "sudo_set_bonds_moving_average",
|
339
342
|
"commit_reveal_weights_interval": "sudo_set_commit_reveal_weights_interval",
|
340
343
|
"commit_reveal_weights_enabled": "sudo_set_commit_reveal_weights_enabled",
|
341
344
|
"alpha_values": "sudo_set_alpha_values",
|
342
345
|
"liquid_alpha_enabled": "sudo_set_liquid_alpha_enabled",
|
346
|
+
"registration_allowed": "sudo_set_network_registration_allowed",
|
343
347
|
}
|
344
348
|
|
345
349
|
# Help Panels for cli help
|
@@ -4,22 +4,28 @@ import random
|
|
4
4
|
from collections import defaultdict
|
5
5
|
from dataclasses import dataclass
|
6
6
|
from hashlib import blake2b
|
7
|
-
from typing import Optional, Any, Union, Callable, Awaitable, cast
|
7
|
+
from typing import Optional, Any, Union, Callable, Awaitable, cast, TYPE_CHECKING
|
8
8
|
|
9
|
-
from bt_decode import PortableRegistry, decode as decode_by_type_string, MetadataV15
|
10
9
|
from async_property import async_property
|
10
|
+
from bt_decode import PortableRegistry, decode as decode_by_type_string, MetadataV15
|
11
|
+
from bittensor_wallet import Keypair
|
11
12
|
from scalecodec import GenericExtrinsic
|
12
13
|
from scalecodec.base import ScaleBytes, ScaleType, RuntimeConfigurationObject
|
13
14
|
from scalecodec.type_registry import load_type_registry_preset
|
14
15
|
from scalecodec.types import GenericCall
|
15
|
-
from bittensor_wallet import Keypair
|
16
16
|
from substrateinterface.exceptions import (
|
17
17
|
SubstrateRequestException,
|
18
18
|
ExtrinsicNotFound,
|
19
19
|
BlockNotFound,
|
20
20
|
)
|
21
21
|
from substrateinterface.storage import StorageKey
|
22
|
-
import
|
22
|
+
from websockets.asyncio.client import connect
|
23
|
+
from websockets.exceptions import ConnectionClosed
|
24
|
+
|
25
|
+
from bittensor_cli.src.bittensor.utils import hex_to_bytes
|
26
|
+
|
27
|
+
if TYPE_CHECKING:
|
28
|
+
from websockets.asyncio.client import ClientConnection
|
23
29
|
|
24
30
|
ResultHandler = Callable[[dict, Any], Awaitable[tuple[dict, bool]]]
|
25
31
|
|
@@ -433,7 +439,7 @@ class RuntimeCache:
|
|
433
439
|
self.block_hashes[block_hash] = runtime
|
434
440
|
|
435
441
|
def retrieve(
|
436
|
-
self, block: Optional[int], block_hash: Optional[str]
|
442
|
+
self, block: Optional[int] = None, block_hash: Optional[str] = None
|
437
443
|
) -> Optional["Runtime"]:
|
438
444
|
if block is not None:
|
439
445
|
return self.blocks.get(block)
|
@@ -624,7 +630,7 @@ class Websocket:
|
|
624
630
|
# TODO allow setting max concurrent connections and rpc subscriptions per connection
|
625
631
|
# TODO reconnection logic
|
626
632
|
self.ws_url = ws_url
|
627
|
-
self.ws: Optional[
|
633
|
+
self.ws: Optional["ClientConnection"] = None
|
628
634
|
self.id = 0
|
629
635
|
self.max_subscriptions = max_subscriptions
|
630
636
|
self.max_connections = max_connections
|
@@ -646,15 +652,12 @@ class Websocket:
|
|
646
652
|
self._exit_task.cancel()
|
647
653
|
if not self._initialized:
|
648
654
|
self._initialized = True
|
649
|
-
await
|
655
|
+
self.ws = await asyncio.wait_for(
|
656
|
+
connect(self.ws_url, **self._options), timeout=10
|
657
|
+
)
|
650
658
|
self._receiving_task = asyncio.create_task(self._start_receiving())
|
651
659
|
return self
|
652
660
|
|
653
|
-
async def _connect(self):
|
654
|
-
self.ws = await asyncio.wait_for(
|
655
|
-
websockets.connect(self.ws_url, **self._options), timeout=10
|
656
|
-
)
|
657
|
-
|
658
661
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
659
662
|
async with self._lock:
|
660
663
|
self._in_use -= 1
|
@@ -695,9 +698,7 @@ class Websocket:
|
|
695
698
|
|
696
699
|
async def _recv(self) -> None:
|
697
700
|
try:
|
698
|
-
response = json.loads(
|
699
|
-
await cast(websockets.WebSocketClientProtocol, self.ws).recv()
|
700
|
-
)
|
701
|
+
response = json.loads(await self.ws.recv())
|
701
702
|
async with self._lock:
|
702
703
|
self._open_subscriptions -= 1
|
703
704
|
if "id" in response:
|
@@ -706,7 +707,7 @@ class Websocket:
|
|
706
707
|
self._received[response["params"]["subscription"]] = response
|
707
708
|
else:
|
708
709
|
raise KeyError(response)
|
709
|
-
except
|
710
|
+
except ConnectionClosed:
|
710
711
|
raise
|
711
712
|
except KeyError as e:
|
712
713
|
raise e
|
@@ -717,7 +718,7 @@ class Websocket:
|
|
717
718
|
await self._recv()
|
718
719
|
except asyncio.CancelledError:
|
719
720
|
pass
|
720
|
-
except
|
721
|
+
except ConnectionClosed:
|
721
722
|
# TODO try reconnect, but only if it's needed
|
722
723
|
raise
|
723
724
|
|
@@ -734,7 +735,7 @@ class Websocket:
|
|
734
735
|
try:
|
735
736
|
await self.ws.send(json.dumps({**payload, **{"id": original_id}}))
|
736
737
|
return original_id
|
737
|
-
except
|
738
|
+
except ConnectionClosed:
|
738
739
|
raise
|
739
740
|
|
740
741
|
async def retrieve(self, item_id: int) -> Optional[dict]:
|
@@ -775,7 +776,6 @@ class AsyncSubstrateInterface:
|
|
775
776
|
chain_endpoint,
|
776
777
|
options={
|
777
778
|
"max_size": 2**32,
|
778
|
-
"read_limit": 2**16,
|
779
779
|
"write_limit": 2**16,
|
780
780
|
},
|
781
781
|
)
|
@@ -1135,7 +1135,7 @@ class AsyncSubstrateInterface:
|
|
1135
1135
|
-------
|
1136
1136
|
StorageKey
|
1137
1137
|
"""
|
1138
|
-
|
1138
|
+
await self.init_runtime(block_hash=block_hash)
|
1139
1139
|
|
1140
1140
|
return StorageKey.create_from_storage_function(
|
1141
1141
|
pallet,
|
@@ -1555,7 +1555,7 @@ class AsyncSubstrateInterface:
|
|
1555
1555
|
self,
|
1556
1556
|
response: dict,
|
1557
1557
|
subscription_id: Union[int, str],
|
1558
|
-
value_scale_type: Optional[str],
|
1558
|
+
value_scale_type: Optional[str] = None,
|
1559
1559
|
storage_item: Optional[ScaleType] = None,
|
1560
1560
|
runtime: Optional[Runtime] = None,
|
1561
1561
|
result_handler: Optional[ResultHandler] = None,
|
@@ -1769,7 +1769,6 @@ class AsyncSubstrateInterface:
|
|
1769
1769
|
call_params = {}
|
1770
1770
|
|
1771
1771
|
await self.init_runtime(block_hash=block_hash)
|
1772
|
-
|
1773
1772
|
call = self.runtime_config.create_scale_object(
|
1774
1773
|
type_string="Call", metadata=self.metadata
|
1775
1774
|
)
|
@@ -2087,7 +2086,8 @@ class AsyncSubstrateInterface:
|
|
2087
2086
|
|
2088
2087
|
:return: The signed Extrinsic
|
2089
2088
|
"""
|
2090
|
-
|
2089
|
+
if not self.metadata:
|
2090
|
+
await self.init_runtime()
|
2091
2091
|
|
2092
2092
|
# Check requirements
|
2093
2093
|
if not isinstance(call, GenericCall):
|
@@ -2140,7 +2140,6 @@ class AsyncSubstrateInterface:
|
|
2140
2140
|
extrinsic = self.runtime_config.create_scale_object(
|
2141
2141
|
type_string="Extrinsic", metadata=self.metadata
|
2142
2142
|
)
|
2143
|
-
|
2144
2143
|
value = {
|
2145
2144
|
"account_id": f"0x{keypair.public_key.hex()}",
|
2146
2145
|
"signature": f"0x{signature.hex()}",
|
@@ -2158,9 +2157,7 @@ class AsyncSubstrateInterface:
|
|
2158
2157
|
signature_cls = self.runtime_config.get_decoder_class("ExtrinsicSignature")
|
2159
2158
|
if issubclass(signature_cls, self.runtime_config.get_decoder_class("Enum")):
|
2160
2159
|
value["signature_version"] = signature_version
|
2161
|
-
|
2162
2160
|
extrinsic.encode(value)
|
2163
|
-
|
2164
2161
|
return extrinsic
|
2165
2162
|
|
2166
2163
|
async def get_chain_finalised_head(self):
|
@@ -2564,10 +2561,7 @@ class AsyncSubstrateInterface:
|
|
2564
2561
|
item_key = None
|
2565
2562
|
|
2566
2563
|
try:
|
2567
|
-
|
2568
|
-
item_bytes = bytes.fromhex(item[1][2:])
|
2569
|
-
except ValueError:
|
2570
|
-
item_bytes = bytes.fromhex(item[1])
|
2564
|
+
item_bytes = hex_to_bytes(item[1])
|
2571
2565
|
|
2572
2566
|
item_value = await self.decode_scale(
|
2573
2567
|
type_string=value_type,
|
@@ -18,9 +18,7 @@ import typing
|
|
18
18
|
from typing import Optional
|
19
19
|
import subprocess
|
20
20
|
|
21
|
-
import backoff
|
22
21
|
from bittensor_wallet import Wallet
|
23
|
-
from bittensor_wallet.errors import KeyFileError
|
24
22
|
from Crypto.Hash import keccak
|
25
23
|
import numpy as np
|
26
24
|
from rich.prompt import Confirm
|
@@ -37,6 +35,8 @@ from bittensor_cli.src.bittensor.utils import (
|
|
37
35
|
get_human_readable,
|
38
36
|
print_verbose,
|
39
37
|
print_error,
|
38
|
+
unlock_key,
|
39
|
+
hex_to_bytes,
|
40
40
|
)
|
41
41
|
|
42
42
|
if typing.TYPE_CHECKING:
|
@@ -687,7 +687,7 @@ async def run_faucet_extrinsic(
|
|
687
687
|
tpb: int = 256,
|
688
688
|
num_processes: Optional[int] = None,
|
689
689
|
update_interval: Optional[int] = None,
|
690
|
-
log_verbose: bool =
|
690
|
+
log_verbose: bool = True,
|
691
691
|
max_successes: int = 3,
|
692
692
|
) -> tuple[bool, str]:
|
693
693
|
r"""Runs a continual POW to get a faucet of TAO on the test net.
|
@@ -726,10 +726,8 @@ async def run_faucet_extrinsic(
|
|
726
726
|
return False, "Requires torch"
|
727
727
|
|
728
728
|
# Unlock coldkey
|
729
|
-
|
730
|
-
|
731
|
-
except KeyFileError:
|
732
|
-
return False, "There was an error unlocking your coldkey"
|
729
|
+
if not (unlock_status := unlock_key(wallet, print_out=False)).success:
|
730
|
+
return False, unlock_status.message
|
733
731
|
|
734
732
|
# Get previous balance.
|
735
733
|
old_balance = await subtensor.get_balance(wallet.coldkeypub.ss58_address)
|
@@ -737,8 +735,12 @@ async def run_faucet_extrinsic(
|
|
737
735
|
# Attempt rolling registration.
|
738
736
|
attempts = 1
|
739
737
|
successes = 1
|
738
|
+
pow_result: Optional[POWSolution]
|
740
739
|
while True:
|
741
740
|
try:
|
741
|
+
account_nonce = await subtensor.substrate.get_account_nonce(
|
742
|
+
wallet.coldkey.ss58_address
|
743
|
+
)
|
742
744
|
pow_result = None
|
743
745
|
while pow_result is None or await pow_result.is_stale(subtensor=subtensor):
|
744
746
|
# Solve latest POW.
|
@@ -747,7 +749,7 @@ async def run_faucet_extrinsic(
|
|
747
749
|
if prompt:
|
748
750
|
err_console.print("CUDA is not available.")
|
749
751
|
return False, "CUDA is not available."
|
750
|
-
pow_result
|
752
|
+
pow_result = await create_pow(
|
751
753
|
subtensor,
|
752
754
|
wallet,
|
753
755
|
-1,
|
@@ -760,7 +762,7 @@ async def run_faucet_extrinsic(
|
|
760
762
|
log_verbose=log_verbose,
|
761
763
|
)
|
762
764
|
else:
|
763
|
-
pow_result
|
765
|
+
pow_result = await create_pow(
|
764
766
|
subtensor,
|
765
767
|
wallet,
|
766
768
|
-1,
|
@@ -780,7 +782,7 @@ async def run_faucet_extrinsic(
|
|
780
782
|
},
|
781
783
|
)
|
782
784
|
extrinsic = await subtensor.substrate.create_signed_extrinsic(
|
783
|
-
call=call, keypair=wallet.coldkey
|
785
|
+
call=call, keypair=wallet.coldkey, nonce=account_nonce
|
784
786
|
)
|
785
787
|
response = await subtensor.substrate.submit_extrinsic(
|
786
788
|
extrinsic,
|
@@ -865,7 +867,7 @@ async def _check_for_newest_block_and_update(
|
|
865
867
|
block_number, difficulty, block_hash = await _get_block_with_retry(
|
866
868
|
subtensor=subtensor, netuid=netuid
|
867
869
|
)
|
868
|
-
block_bytes =
|
870
|
+
block_bytes = hex_to_bytes(block_hash)
|
869
871
|
|
870
872
|
update_curr_block(
|
871
873
|
curr_diff,
|
@@ -972,7 +974,7 @@ async def _block_solver(
|
|
972
974
|
subtensor=subtensor, netuid=netuid
|
973
975
|
)
|
974
976
|
|
975
|
-
block_bytes =
|
977
|
+
block_bytes = hex_to_bytes(block_hash)
|
976
978
|
old_block_number = block_number
|
977
979
|
# Set to current block
|
978
980
|
_update_curr_block(
|
@@ -1247,11 +1249,9 @@ def _terminate_workers_and_wait_for_exit(
|
|
1247
1249
|
worker.terminate()
|
1248
1250
|
|
1249
1251
|
|
1250
|
-
# TODO verify this works with async
|
1251
|
-
@backoff.on_exception(backoff.constant, Exception, interval=1, max_tries=3)
|
1252
1252
|
async def _get_block_with_retry(
|
1253
1253
|
subtensor: "SubtensorInterface", netuid: int
|
1254
|
-
) -> tuple[int, int,
|
1254
|
+
) -> tuple[int, int, str]:
|
1255
1255
|
"""
|
1256
1256
|
Gets the current block number, difficulty, and block hash from the substrate node.
|
1257
1257
|
|
@@ -1263,10 +1263,9 @@ async def _get_block_with_retry(
|
|
1263
1263
|
:raises Exception: If the block hash is None.
|
1264
1264
|
:raises ValueError: If the difficulty is None.
|
1265
1265
|
"""
|
1266
|
-
|
1267
|
-
block_hash =
|
1268
|
-
|
1269
|
-
) # TODO check if I need to do all this
|
1266
|
+
block = await subtensor.substrate.get_block()
|
1267
|
+
block_hash = block["header"]["hash"]
|
1268
|
+
block_number = block["header"]["number"]
|
1270
1269
|
try:
|
1271
1270
|
difficulty = (
|
1272
1271
|
1_000_000
|
@@ -1639,10 +1638,7 @@ async def swap_hotkey_extrinsic(
|
|
1639
1638
|
)
|
1640
1639
|
return False
|
1641
1640
|
|
1642
|
-
|
1643
|
-
wallet.unlock_coldkey()
|
1644
|
-
except KeyFileError:
|
1645
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
1641
|
+
if not unlock_key(wallet).success:
|
1646
1642
|
return False
|
1647
1643
|
|
1648
1644
|
if prompt:
|
@@ -21,7 +21,6 @@ import time
|
|
21
21
|
from typing import Union, List, TYPE_CHECKING
|
22
22
|
|
23
23
|
from bittensor_wallet import Wallet, Keypair
|
24
|
-
from bittensor_wallet.errors import KeyFileError
|
25
24
|
import numpy as np
|
26
25
|
from numpy.typing import NDArray
|
27
26
|
from rich.prompt import Confirm
|
@@ -37,6 +36,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
37
36
|
u16_normalized_float,
|
38
37
|
print_verbose,
|
39
38
|
format_error_message,
|
39
|
+
unlock_key,
|
40
40
|
)
|
41
41
|
|
42
42
|
if TYPE_CHECKING:
|
@@ -306,10 +306,7 @@ async def root_register_extrinsic(
|
|
306
306
|
the response is `True`.
|
307
307
|
"""
|
308
308
|
|
309
|
-
|
310
|
-
wallet.unlock_coldkey()
|
311
|
-
except KeyFileError:
|
312
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
309
|
+
if not unlock_key(wallet).success:
|
313
310
|
return False
|
314
311
|
|
315
312
|
print_verbose(f"Checking if hotkey ({wallet.hotkey_str}) is registered on root")
|
@@ -427,10 +424,7 @@ async def set_root_weights_extrinsic(
|
|
427
424
|
err_console.print("Your hotkey is not registered to the root network")
|
428
425
|
return False
|
429
426
|
|
430
|
-
|
431
|
-
wallet.unlock_coldkey()
|
432
|
-
except KeyFileError:
|
433
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
427
|
+
if not unlock_key(wallet).success:
|
434
428
|
return False
|
435
429
|
|
436
430
|
# First convert types.
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import asyncio
|
2
2
|
|
3
3
|
from bittensor_wallet import Wallet
|
4
|
-
from bittensor_wallet.errors import KeyFileError
|
5
4
|
from rich.prompt import Confirm
|
6
5
|
from substrateinterface.exceptions import SubstrateRequestException
|
7
6
|
|
@@ -16,6 +15,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
16
15
|
get_explorer_url_for_network,
|
17
16
|
is_valid_bittensor_address_or_public_key,
|
18
17
|
print_error,
|
18
|
+
unlock_key,
|
19
19
|
)
|
20
20
|
|
21
21
|
|
@@ -115,10 +115,7 @@ async def transfer_extrinsic(
|
|
115
115
|
return False
|
116
116
|
console.print(f"[dark_orange]Initiating transfer on network: {subtensor.network}")
|
117
117
|
# Unlock wallet coldkey.
|
118
|
-
|
119
|
-
wallet.unlock_coldkey()
|
120
|
-
except KeyFileError:
|
121
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
118
|
+
if not unlock_key(wallet).success:
|
122
119
|
return False
|
123
120
|
|
124
121
|
# Check balance.
|
@@ -35,6 +35,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
35
35
|
err_console,
|
36
36
|
decode_hex_identity_dict,
|
37
37
|
validate_chain_endpoint,
|
38
|
+
hex_to_bytes,
|
38
39
|
)
|
39
40
|
|
40
41
|
|
@@ -213,12 +214,7 @@ class SubtensorInterface:
|
|
213
214
|
block_hash=block_hash,
|
214
215
|
)
|
215
216
|
if hex_bytes_result is not None:
|
216
|
-
|
217
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
218
|
-
except ValueError:
|
219
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
220
|
-
|
221
|
-
return DelegateInfo.list_from_vec_u8(bytes_result)
|
217
|
+
return DelegateInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
222
218
|
else:
|
223
219
|
return []
|
224
220
|
|
@@ -254,12 +250,7 @@ class SubtensorInterface:
|
|
254
250
|
if hex_bytes_result is None:
|
255
251
|
return []
|
256
252
|
|
257
|
-
|
258
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
259
|
-
except ValueError:
|
260
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
261
|
-
|
262
|
-
return StakeInfo.list_from_vec_u8(bytes_result)
|
253
|
+
return StakeInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
263
254
|
|
264
255
|
async def get_stake_for_coldkey_and_hotkey(
|
265
256
|
self, hotkey_ss58: str, coldkey_ss58: str, block_hash: Optional[str]
|
@@ -654,12 +645,7 @@ class SubtensorInterface:
|
|
654
645
|
if hex_bytes_result is None:
|
655
646
|
return []
|
656
647
|
|
657
|
-
|
658
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
659
|
-
except ValueError:
|
660
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
661
|
-
|
662
|
-
return NeuronInfoLite.list_from_vec_u8(bytes_result)
|
648
|
+
return NeuronInfoLite.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
663
649
|
|
664
650
|
async def neuron_for_uid(
|
665
651
|
self, uid: Optional[int], netuid: int, block_hash: Optional[str] = None
|
@@ -988,12 +974,7 @@ class SubtensorInterface:
|
|
988
974
|
if hex_bytes_result is None:
|
989
975
|
return []
|
990
976
|
|
991
|
-
|
992
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
993
|
-
else:
|
994
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
995
|
-
|
996
|
-
return SubnetHyperparameters.from_vec_u8(bytes_result)
|
977
|
+
return SubnetHyperparameters.from_vec_u8(hex_to_bytes(hex_bytes_result))
|
997
978
|
|
998
979
|
async def get_vote_data(
|
999
980
|
self,
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import ast
|
2
|
+
from collections import namedtuple
|
2
3
|
import math
|
3
4
|
import os
|
4
5
|
import sqlite3
|
@@ -9,7 +10,7 @@ from urllib.parse import urlparse
|
|
9
10
|
|
10
11
|
from bittensor_wallet import Wallet, Keypair
|
11
12
|
from bittensor_wallet.utils import SS58_FORMAT
|
12
|
-
from bittensor_wallet.errors import KeyFileError
|
13
|
+
from bittensor_wallet.errors import KeyFileError, PasswordError
|
13
14
|
from bittensor_wallet import utils
|
14
15
|
from jinja2 import Template
|
15
16
|
from markupsafe import Markup
|
@@ -35,6 +36,8 @@ console = Console()
|
|
35
36
|
err_console = Console(stderr=True)
|
36
37
|
verbose_console = Console(quiet=True)
|
37
38
|
|
39
|
+
UnlockStatus = namedtuple("UnlockStatus", ["success", "message"])
|
40
|
+
|
38
41
|
|
39
42
|
def print_console(message: str, colour: str, title: str, console: Console):
|
40
43
|
console.print(
|
@@ -238,11 +241,14 @@ def get_hotkey_wallets_for_wallet(
|
|
238
241
|
def get_coldkey_wallets_for_path(path: str) -> list[Wallet]:
|
239
242
|
"""Gets all wallets with coldkeys from a given path"""
|
240
243
|
wallet_path = Path(path).expanduser()
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
244
|
+
try:
|
245
|
+
wallets = [
|
246
|
+
Wallet(name=directory.name, path=path)
|
247
|
+
for directory in wallet_path.iterdir()
|
248
|
+
if directory.is_dir()
|
249
|
+
]
|
250
|
+
except FileNotFoundError:
|
251
|
+
wallets = []
|
246
252
|
return wallets
|
247
253
|
|
248
254
|
|
@@ -575,7 +581,7 @@ def decode_hex_identity_dict(info_dictionary) -> dict[str, Any]:
|
|
575
581
|
def get_decoded(data: str) -> str:
|
576
582
|
"""Decodes a hex-encoded string."""
|
577
583
|
try:
|
578
|
-
return
|
584
|
+
return hex_to_bytes(data).decode()
|
579
585
|
except UnicodeDecodeError:
|
580
586
|
print(f"Could not decode: {key}: {item}")
|
581
587
|
|
@@ -974,3 +980,50 @@ def retry_prompt(
|
|
974
980
|
return var
|
975
981
|
else:
|
976
982
|
err_console.print(rejection_text)
|
983
|
+
|
984
|
+
|
985
|
+
def unlock_key(
|
986
|
+
wallet: Wallet, unlock_type="cold", print_out: bool = True
|
987
|
+
) -> "UnlockStatus":
|
988
|
+
"""
|
989
|
+
Attempts to decrypt a wallet's coldkey or hotkey
|
990
|
+
Args:
|
991
|
+
wallet: a Wallet object
|
992
|
+
unlock_type: the key type, 'cold' or 'hot'
|
993
|
+
print_out: whether to print out the error message to the err_console
|
994
|
+
|
995
|
+
Returns: UnlockStatus for success status of unlock, with error message if unsuccessful
|
996
|
+
|
997
|
+
"""
|
998
|
+
if unlock_type == "cold":
|
999
|
+
unlocker = "unlock_coldkey"
|
1000
|
+
elif unlock_type == "hot":
|
1001
|
+
unlocker = "unlock_hotkey"
|
1002
|
+
else:
|
1003
|
+
raise ValueError(
|
1004
|
+
f"Invalid unlock type provided: {unlock_type}. Must be 'cold' or 'hot'."
|
1005
|
+
)
|
1006
|
+
try:
|
1007
|
+
getattr(wallet, unlocker)()
|
1008
|
+
return UnlockStatus(True, "")
|
1009
|
+
except PasswordError:
|
1010
|
+
err_msg = f"The password used to decrypt your {unlock_type.capitalize()}key Keyfile is invalid."
|
1011
|
+
if print_out:
|
1012
|
+
err_console.print(f":cross_mark: [red]{err_msg}[/red]")
|
1013
|
+
return UnlockStatus(False, err_msg)
|
1014
|
+
except KeyFileError:
|
1015
|
+
err_msg = f"{unlock_type.capitalize()}key Keyfile is corrupt, non-writable, or non-readable, or non-existent."
|
1016
|
+
if print_out:
|
1017
|
+
err_console.print(f":cross_mark: [red]{err_msg}[/red]")
|
1018
|
+
return UnlockStatus(False, err_msg)
|
1019
|
+
|
1020
|
+
|
1021
|
+
def hex_to_bytes(hex_str: str) -> bytes:
|
1022
|
+
"""
|
1023
|
+
Converts a hex-encoded string into bytes. Handles 0x-prefixed and non-prefixed hex-encoded strings.
|
1024
|
+
"""
|
1025
|
+
if hex_str.startswith("0x"):
|
1026
|
+
bytes_result = bytes.fromhex(hex_str[2:])
|
1027
|
+
else:
|
1028
|
+
bytes_result = bytes.fromhex(hex_str)
|
1029
|
+
return bytes_result
|
@@ -3,7 +3,6 @@ import json
|
|
3
3
|
from typing import Optional, TYPE_CHECKING
|
4
4
|
|
5
5
|
from bittensor_wallet import Wallet
|
6
|
-
from bittensor_wallet.errors import KeyFileError
|
7
6
|
import numpy as np
|
8
7
|
from numpy.typing import NDArray
|
9
8
|
from rich import box
|
@@ -42,6 +41,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
42
41
|
ss58_to_vec_u8,
|
43
42
|
update_metadata_table,
|
44
43
|
group_subnets,
|
44
|
+
unlock_key,
|
45
45
|
)
|
46
46
|
|
47
47
|
if TYPE_CHECKING:
|
@@ -280,10 +280,7 @@ async def burned_register_extrinsic(
|
|
280
280
|
finalization/inclusion, the response is `True`.
|
281
281
|
"""
|
282
282
|
|
283
|
-
|
284
|
-
wallet.unlock_coldkey()
|
285
|
-
except KeyFileError:
|
286
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
283
|
+
if not unlock_key(wallet).success:
|
287
284
|
return False
|
288
285
|
|
289
286
|
with console.status(
|
@@ -537,10 +534,7 @@ async def delegate_extrinsic(
|
|
537
534
|
delegate_string = "delegate" if delegate else "undelegate"
|
538
535
|
|
539
536
|
# Decrypt key
|
540
|
-
|
541
|
-
wallet.unlock_coldkey()
|
542
|
-
except KeyFileError:
|
543
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
537
|
+
if not unlock_key(wallet).success:
|
544
538
|
return False
|
545
539
|
|
546
540
|
print_verbose("Checking if hotkey is a delegate")
|
@@ -1098,11 +1092,7 @@ async def senate_vote(
|
|
1098
1092
|
return False
|
1099
1093
|
|
1100
1094
|
# Unlock the wallet.
|
1101
|
-
|
1102
|
-
wallet.unlock_hotkey()
|
1103
|
-
wallet.unlock_coldkey()
|
1104
|
-
except KeyFileError:
|
1105
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
1095
|
+
if not unlock_key(wallet).success and unlock_key(wallet, "hot").success:
|
1106
1096
|
return False
|
1107
1097
|
|
1108
1098
|
console.print(f"Fetching proposals in [dark_orange]network: {subtensor.network}")
|
@@ -1322,11 +1312,7 @@ async def set_take(wallet: Wallet, subtensor: SubtensorInterface, take: float) -
|
|
1322
1312
|
|
1323
1313
|
console.print(f"Setting take on [dark_orange]network: {subtensor.network}")
|
1324
1314
|
# Unlock the wallet.
|
1325
|
-
|
1326
|
-
wallet.unlock_hotkey()
|
1327
|
-
wallet.unlock_coldkey()
|
1328
|
-
except KeyFileError:
|
1329
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
1315
|
+
if not unlock_key(wallet).success and unlock_key(wallet, "hot").success:
|
1330
1316
|
return False
|
1331
1317
|
|
1332
1318
|
result_ = await _do_set_take()
|
@@ -1724,11 +1710,7 @@ async def nominate(wallet: Wallet, subtensor: SubtensorInterface, prompt: bool):
|
|
1724
1710
|
|
1725
1711
|
console.print(f"Nominating on [dark_orange]network: {subtensor.network}")
|
1726
1712
|
# Unlock the wallet.
|
1727
|
-
|
1728
|
-
wallet.unlock_hotkey()
|
1729
|
-
wallet.unlock_coldkey()
|
1730
|
-
except KeyFileError:
|
1731
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
1713
|
+
if not unlock_key(wallet).success and unlock_key(wallet, "hot").success:
|
1732
1714
|
return False
|
1733
1715
|
|
1734
1716
|
print_verbose(f"Checking hotkey ({wallet.hotkey_str}) is a delegate")
|
@@ -2,7 +2,6 @@ import asyncio
|
|
2
2
|
from typing import Optional
|
3
3
|
|
4
4
|
from bittensor_wallet import Wallet
|
5
|
-
from bittensor_wallet.errors import KeyFileError
|
6
5
|
from rich.prompt import Confirm, Prompt, IntPrompt
|
7
6
|
from rich.table import Table
|
8
7
|
from rich.text import Text
|
@@ -19,6 +18,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
19
18
|
u64_to_float,
|
20
19
|
is_valid_ss58_address,
|
21
20
|
format_error_message,
|
21
|
+
unlock_key,
|
22
22
|
)
|
23
23
|
|
24
24
|
|
@@ -72,10 +72,8 @@ async def set_children_extrinsic(
|
|
72
72
|
return False, "Operation Cancelled"
|
73
73
|
|
74
74
|
# Decrypt coldkey.
|
75
|
-
|
76
|
-
|
77
|
-
except KeyFileError:
|
78
|
-
return False, "There was an error unlocking your coldkey."
|
75
|
+
if not (unlock_status := unlock_key(wallet, print_out=False)).success:
|
76
|
+
return False, unlock_status.message
|
79
77
|
|
80
78
|
with console.status(
|
81
79
|
f":satellite: {operation} on [white]{subtensor.network}[/white] ..."
|
@@ -158,10 +156,8 @@ async def set_childkey_take_extrinsic(
|
|
158
156
|
return False, "Operation Cancelled"
|
159
157
|
|
160
158
|
# Decrypt coldkey.
|
161
|
-
|
162
|
-
|
163
|
-
except KeyFileError:
|
164
|
-
return False, "There was an error unlocking your coldkey."
|
159
|
+
if not (unlock_status := unlock_key(wallet, print_out=False)).success:
|
160
|
+
return False, unlock_status.message
|
165
161
|
|
166
162
|
with console.status(
|
167
163
|
f":satellite: Setting childkey take on [white]{subtensor.network}[/white] ..."
|
@@ -7,7 +7,6 @@ from contextlib import suppress
|
|
7
7
|
from typing import TYPE_CHECKING, Optional, Sequence, Union, cast
|
8
8
|
|
9
9
|
from bittensor_wallet import Wallet
|
10
|
-
from bittensor_wallet.errors import KeyFileError
|
11
10
|
from rich.prompt import Confirm
|
12
11
|
from rich.table import Table, Column
|
13
12
|
import typer
|
@@ -28,6 +27,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
28
27
|
render_tree,
|
29
28
|
u16_normalized_float,
|
30
29
|
validate_coldkey_presence,
|
30
|
+
unlock_key,
|
31
31
|
)
|
32
32
|
|
33
33
|
if TYPE_CHECKING:
|
@@ -103,10 +103,7 @@ async def add_stake_extrinsic(
|
|
103
103
|
"""
|
104
104
|
|
105
105
|
# Decrypt keys,
|
106
|
-
|
107
|
-
wallet.unlock_coldkey()
|
108
|
-
except KeyFileError:
|
109
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
106
|
+
if not unlock_key(wallet).success:
|
110
107
|
return False
|
111
108
|
|
112
109
|
# Default to wallet's own hotkey if the value is not passed.
|
@@ -310,10 +307,7 @@ async def add_stake_multiple_extrinsic(
|
|
310
307
|
return True
|
311
308
|
|
312
309
|
# Decrypt coldkey.
|
313
|
-
|
314
|
-
wallet.unlock_coldkey()
|
315
|
-
except KeyFileError:
|
316
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
310
|
+
if not unlock_key(wallet).success:
|
317
311
|
return False
|
318
312
|
|
319
313
|
with console.status(
|
@@ -491,11 +485,8 @@ async def unstake_extrinsic(
|
|
491
485
|
:return: success: `True` if extrinsic was finalized or included in the block. If we did not wait for
|
492
486
|
finalization/inclusion, the response is `True`.
|
493
487
|
"""
|
494
|
-
# Decrypt
|
495
|
-
|
496
|
-
wallet.unlock_coldkey()
|
497
|
-
except KeyFileError:
|
498
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
488
|
+
# Decrypt coldkey
|
489
|
+
if not unlock_key(wallet).success:
|
499
490
|
return False
|
500
491
|
|
501
492
|
if hotkey_ss58 is None:
|
@@ -663,10 +654,7 @@ async def unstake_multiple_extrinsic(
|
|
663
654
|
return True
|
664
655
|
|
665
656
|
# Unlock coldkey.
|
666
|
-
|
667
|
-
wallet.unlock_coldkey()
|
668
|
-
except KeyFileError:
|
669
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
657
|
+
if not unlock_key(wallet).success:
|
670
658
|
return False
|
671
659
|
|
672
660
|
with console.status(
|
@@ -5,7 +5,6 @@ from textwrap import dedent
|
|
5
5
|
from typing import TYPE_CHECKING, Optional, cast
|
6
6
|
|
7
7
|
from bittensor_wallet import Wallet
|
8
|
-
from bittensor_wallet.errors import KeyFileError
|
9
8
|
from rich.prompt import Confirm
|
10
9
|
from rich.table import Column, Table
|
11
10
|
|
@@ -28,6 +27,8 @@ from bittensor_cli.src.bittensor.utils import (
|
|
28
27
|
millify,
|
29
28
|
render_table,
|
30
29
|
update_metadata_table,
|
30
|
+
unlock_key,
|
31
|
+
hex_to_bytes,
|
31
32
|
)
|
32
33
|
|
33
34
|
if TYPE_CHECKING:
|
@@ -100,10 +101,7 @@ async def register_subnetwork_extrinsic(
|
|
100
101
|
):
|
101
102
|
return False
|
102
103
|
|
103
|
-
|
104
|
-
wallet.unlock_coldkey()
|
105
|
-
except KeyFileError:
|
106
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
104
|
+
if not unlock_key(wallet).success:
|
107
105
|
return False
|
108
106
|
|
109
107
|
with console.status(":satellite: Registering subnet...", spinner="earth"):
|
@@ -158,12 +156,8 @@ async def subnets_list(
|
|
158
156
|
hex_bytes_result = await subtensor.query_runtime_api(
|
159
157
|
runtime_api="SubnetInfoRuntimeApi", method="get_subnets_info", params=[]
|
160
158
|
)
|
161
|
-
try:
|
162
|
-
bytes_result = bytes.fromhex(hex_bytes_result[2:])
|
163
|
-
except ValueError:
|
164
|
-
bytes_result = bytes.fromhex(hex_bytes_result)
|
165
159
|
|
166
|
-
return SubnetInfo.list_from_vec_u8(
|
160
|
+
return SubnetInfo.list_from_vec_u8(hex_to_bytes(hex_bytes_result))
|
167
161
|
|
168
162
|
if not reuse_last:
|
169
163
|
subnets: list[SubnetInfo]
|
@@ -2,7 +2,6 @@ import asyncio
|
|
2
2
|
from typing import TYPE_CHECKING, Union
|
3
3
|
|
4
4
|
from bittensor_wallet import Wallet
|
5
|
-
from bittensor_wallet.errors import KeyFileError
|
6
5
|
from rich import box
|
7
6
|
from rich.table import Column, Table
|
8
7
|
|
@@ -14,6 +13,7 @@ from bittensor_cli.src.bittensor.utils import (
|
|
14
13
|
print_error,
|
15
14
|
print_verbose,
|
16
15
|
normalize_hyperparameters,
|
16
|
+
unlock_key,
|
17
17
|
)
|
18
18
|
|
19
19
|
if TYPE_CHECKING:
|
@@ -101,10 +101,7 @@ async def set_hyperparameter_extrinsic(
|
|
101
101
|
)
|
102
102
|
return False
|
103
103
|
|
104
|
-
|
105
|
-
wallet.unlock_coldkey()
|
106
|
-
except KeyFileError:
|
107
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
104
|
+
if not unlock_key(wallet).success:
|
108
105
|
return False
|
109
106
|
|
110
107
|
extrinsic = HYPERPARAMS.get(parameter)
|
@@ -181,19 +178,20 @@ async def sudo_set_hyperparameter(
|
|
181
178
|
|
182
179
|
normalized_value: Union[str, bool]
|
183
180
|
if param_name in [
|
184
|
-
"
|
181
|
+
"registration_allowed",
|
185
182
|
"network_pow_registration_allowed",
|
186
183
|
"commit_reveal_weights_enabled",
|
187
184
|
"liquid_alpha_enabled",
|
188
185
|
]:
|
189
|
-
normalized_value = param_value.lower() in ["true", "1"]
|
186
|
+
normalized_value = param_value.lower() in ["true", "True", "1"]
|
190
187
|
else:
|
191
188
|
normalized_value = param_value
|
192
189
|
|
193
190
|
is_allowed_value, value = allowed_value(param_name, normalized_value)
|
194
191
|
if not is_allowed_value:
|
195
192
|
err_console.print(
|
196
|
-
f"Hyperparameter {param_name} value is not within bounds.
|
193
|
+
f"Hyperparameter [dark_orange]{param_name}[/dark_orange] value is not within bounds. "
|
194
|
+
f"Value is {normalized_value} but must be {value}"
|
197
195
|
)
|
198
196
|
return
|
199
197
|
|
@@ -15,23 +15,19 @@ from bittensor_wallet.keyfile import Keyfile
|
|
15
15
|
from fuzzywuzzy import fuzz
|
16
16
|
from rich import box
|
17
17
|
from rich.align import Align
|
18
|
-
from rich.prompt import Confirm
|
18
|
+
from rich.prompt import Confirm
|
19
19
|
from rich.table import Column, Table
|
20
20
|
from rich.tree import Tree
|
21
21
|
from rich.padding import Padding
|
22
22
|
from rich.prompt import IntPrompt
|
23
|
-
from scalecodec import ScaleBytes
|
24
|
-
import scalecodec
|
25
23
|
import typer
|
26
24
|
|
27
|
-
from bittensor_cli.src import TYPE_REGISTRY
|
28
25
|
from bittensor_cli.src.bittensor import utils
|
29
26
|
from bittensor_cli.src.bittensor.balances import Balance
|
30
27
|
from bittensor_cli.src.bittensor.chain_data import (
|
31
28
|
DelegateInfo,
|
32
29
|
NeuronInfoLite,
|
33
30
|
StakeInfo,
|
34
|
-
custom_rpc_type_registry,
|
35
31
|
decode_account_id,
|
36
32
|
)
|
37
33
|
from bittensor_cli.src.bittensor.extrinsics.registration import (
|
@@ -46,7 +42,6 @@ from bittensor_cli.src.bittensor.utils import (
|
|
46
42
|
RAO_PER_TAO,
|
47
43
|
console,
|
48
44
|
convert_blocks_to_time,
|
49
|
-
decode_scale_bytes,
|
50
45
|
err_console,
|
51
46
|
print_error,
|
52
47
|
print_verbose,
|
@@ -55,6 +50,8 @@ from bittensor_cli.src.bittensor.utils import (
|
|
55
50
|
is_valid_ss58_address,
|
56
51
|
validate_coldkey_presence,
|
57
52
|
retry_prompt,
|
53
|
+
unlock_key,
|
54
|
+
hex_to_bytes,
|
58
55
|
)
|
59
56
|
|
60
57
|
|
@@ -659,8 +656,13 @@ async def overview(
|
|
659
656
|
neurons
|
660
657
|
)
|
661
658
|
|
659
|
+
has_alerts = False
|
662
660
|
alerts_table = Table(show_header=True, header_style="bold magenta")
|
663
661
|
alerts_table.add_column("🥩 alert!")
|
662
|
+
alerts_table.add_row(
|
663
|
+
"[bold]Detected the following stake(s) associated with coldkey(s) that are not linked to any local hotkeys:[/bold]"
|
664
|
+
)
|
665
|
+
alerts_table.add_row("")
|
664
666
|
|
665
667
|
coldkeys_to_check = []
|
666
668
|
ck_stakes = await subtensor.get_total_stake_for_coldkey(
|
@@ -683,12 +685,23 @@ async def overview(
|
|
683
685
|
if difference == 0:
|
684
686
|
continue # We have all our stake registered.
|
685
687
|
|
688
|
+
has_alerts = True
|
686
689
|
coldkeys_to_check.append(coldkey_wallet)
|
687
690
|
alerts_table.add_row(
|
688
|
-
"
|
689
|
-
abs(difference),
|
691
|
+
"[light_goldenrod2]{}[/light_goldenrod2] stake associated with coldkey [bright_magenta]{}[/bright_magenta] (ss58: [bright_magenta]{}[/bright_magenta])".format(
|
692
|
+
abs(difference),
|
693
|
+
coldkey_wallet.name,
|
694
|
+
coldkey_wallet.coldkeypub.ss58_address,
|
690
695
|
)
|
691
696
|
)
|
697
|
+
if has_alerts:
|
698
|
+
alerts_table.add_row("")
|
699
|
+
alerts_table.add_row(
|
700
|
+
"[bold yellow]Note:[/bold yellow] This stake might be delegated, staked to another user's hotkey, or associated with a hotkey not present in your wallet."
|
701
|
+
)
|
702
|
+
alerts_table.add_row(
|
703
|
+
"You can find out more by executing `[bold]btcli wallet inspect[/bold]` command."
|
704
|
+
)
|
692
705
|
|
693
706
|
if coldkeys_to_check:
|
694
707
|
# We have some stake that is not with a registered hotkey.
|
@@ -742,7 +755,7 @@ async def overview(
|
|
742
755
|
grid = Table.grid(pad_edge=True)
|
743
756
|
|
744
757
|
# If there are any alerts, add them to the grid
|
745
|
-
if
|
758
|
+
if has_alerts:
|
746
759
|
grid.add_row(alerts_table)
|
747
760
|
|
748
761
|
# Add title
|
@@ -1175,7 +1188,7 @@ def _process_neurons_for_netuids(
|
|
1175
1188
|
:return: netuids mapped to decoded neurons
|
1176
1189
|
"""
|
1177
1190
|
all_results = [
|
1178
|
-
(netuid, NeuronInfoLite.list_from_vec_u8(
|
1191
|
+
(netuid, NeuronInfoLite.list_from_vec_u8(hex_to_bytes(result)))
|
1179
1192
|
if result
|
1180
1193
|
else (netuid, [])
|
1181
1194
|
for netuid, result in netuids_with_all_neurons_hex_bytes
|
@@ -1616,10 +1629,7 @@ async def set_id(
|
|
1616
1629
|
print_error(f":cross_mark: This wallet doesn't own subnet {subnet_netuid}.")
|
1617
1630
|
return False
|
1618
1631
|
|
1619
|
-
|
1620
|
-
wallet.unlock_coldkey()
|
1621
|
-
except KeyFileError:
|
1622
|
-
err_console.print("Error decrypting coldkey (possibly incorrect password)")
|
1632
|
+
if not unlock_key(wallet).success:
|
1623
1633
|
return False
|
1624
1634
|
|
1625
1635
|
with console.status(
|
@@ -1719,18 +1729,14 @@ async def check_coldkey_swap(wallet: Wallet, subtensor: SubtensorInterface):
|
|
1719
1729
|
|
1720
1730
|
async def sign(wallet: Wallet, message: str, use_hotkey: str):
|
1721
1731
|
"""Sign a message using the provided wallet or hotkey."""
|
1722
|
-
|
1723
|
-
try:
|
1724
|
-
wallet.unlock_coldkey()
|
1725
|
-
except KeyFileError:
|
1726
|
-
err_console.print(
|
1727
|
-
":cross_mark: [red]Keyfile is corrupt, non-writable, non-readable or the password used to decrypt is "
|
1728
|
-
"invalid[/red]:[bold white]\n [/bold white]"
|
1729
|
-
)
|
1730
1732
|
if not use_hotkey:
|
1733
|
+
if not unlock_key(wallet).success:
|
1734
|
+
return False
|
1731
1735
|
keypair = wallet.coldkey
|
1732
1736
|
print_verbose(f"Signing using coldkey: {wallet.name}")
|
1733
1737
|
else:
|
1738
|
+
if not unlock_key(wallet, "hot").success:
|
1739
|
+
return False
|
1734
1740
|
keypair = wallet.hotkey
|
1735
1741
|
print_verbose(f"Signing using hotkey: {wallet.hotkey_str}")
|
1736
1742
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: bittensor-cli
|
3
|
-
Version: 8.
|
3
|
+
Version: 8.4.0
|
4
4
|
Summary: Bittensor CLI
|
5
5
|
Home-page: https://github.com/opentensor/btcli
|
6
6
|
Author: bittensor.com
|
@@ -40,8 +40,8 @@ Requires-Dist: rich~=13.7
|
|
40
40
|
Requires-Dist: scalecodec==1.2.11
|
41
41
|
Requires-Dist: substrate-interface~=1.7.9
|
42
42
|
Requires-Dist: typer~=0.12
|
43
|
-
Requires-Dist: websockets>=
|
44
|
-
Requires-Dist: bittensor-wallet>=2.
|
43
|
+
Requires-Dist: websockets>=14.1
|
44
|
+
Requires-Dist: bittensor-wallet>=2.1.3
|
45
45
|
Requires-Dist: bt-decode==0.2.0a0
|
46
46
|
Provides-Extra: cuda
|
47
47
|
Requires-Dist: cubit>=1.1.0; extra == "cuda"
|
@@ -0,0 +1,31 @@
|
|
1
|
+
bittensor_cli/__init__.py,sha256=0dDE_gb7wXMgoxy5mCs0B4IjiojCNSEiBmyJTyKwCTg,1217
|
2
|
+
bittensor_cli/cli.py,sha256=1C9xRsNq3CZHEsYcvw50IemjLxQ7olSljX6wK1WwK6g,170025
|
3
|
+
bittensor_cli/doc_generation_helper.py,sha256=GexqjEIKulWg84hpNBEchJ840oOgOi7DWpt447nsdNI,91
|
4
|
+
bittensor_cli/src/__init__.py,sha256=1_hTPLBqA6gV8HTL-v0_RVTPt7TQJEJEv-TIw9f79OE,12055
|
5
|
+
bittensor_cli/src/bittensor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
+
bittensor_cli/src/bittensor/async_substrate_interface.py,sha256=o7Pe_Nxsys8aPm_xsih2xR8ArhZrUu9yYobf8qBvT5s,103185
|
7
|
+
bittensor_cli/src/bittensor/balances.py,sha256=102mg1iiliLSLx-EocQseWGHiWzRqcBBM-MRoObOdKo,10075
|
8
|
+
bittensor_cli/src/bittensor/chain_data.py,sha256=IsHWjmhJbTvud2i3IM1sfmBHP82VxNHC1iFDAtlLgXc,26490
|
9
|
+
bittensor_cli/src/bittensor/minigraph.py,sha256=17AjEA75MO7ez_NekOJSaAz6ARjPt99QG_7E1RJ_u_k,8891
|
10
|
+
bittensor_cli/src/bittensor/networking.py,sha256=pZLMs8YXpZzDMLXWMBb_Bj6TVkm_q9khyY-lnbwVMuE,462
|
11
|
+
bittensor_cli/src/bittensor/subtensor_interface.py,sha256=_99AjukDm7ijEwQUA6TXctZFrj9IRuOzJdheKNmbZ5s,42775
|
12
|
+
bittensor_cli/src/bittensor/utils.py,sha256=60h45hRVTaLhhOOTHmNurY3wHb0Jpt9pIhS3joVM7d4,35505
|
13
|
+
bittensor_cli/src/bittensor/extrinsics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
+
bittensor_cli/src/bittensor/extrinsics/registration.py,sha256=87L7xs64beu0htRaiykaJcYLyRmxoFzF5PFNumNuhcw,59010
|
15
|
+
bittensor_cli/src/bittensor/extrinsics/root.py,sha256=huycqHbSTFBNIhQ846MuBqwBEtQCSVDW3y3yPAqPzeU,19121
|
16
|
+
bittensor_cli/src/bittensor/extrinsics/transfer.py,sha256=yC5oKgoKAXszMzfrof3GbeGppESUMgSqJFFGOMMALuc,8686
|
17
|
+
bittensor_cli/src/bittensor/templates/table.j2,sha256=P2EFiksnO1cQsB8zjK6hVJwUryHTsLslzRE0YtobAV8,10601
|
18
|
+
bittensor_cli/src/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
+
bittensor_cli/src/commands/root.py,sha256=hohGfh7w9Lu7z264rbmFkwRCStyZrtdBZVMt20RwiqA,62186
|
20
|
+
bittensor_cli/src/commands/subnets.py,sha256=_M2EJLdHaLBN04C22A-Xn6weN-3j5dU5frLe6W5Q2rs,33175
|
21
|
+
bittensor_cli/src/commands/sudo.py,sha256=sr4hW27EwW_O7lz0fwPLN3xRpVKNsdBasETIbGDhkb0,8209
|
22
|
+
bittensor_cli/src/commands/wallets.py,sha256=BuPJiEDOpHuGRx3zekU2QkFQjFpCUP-Kdk4opS5YfWo,60678
|
23
|
+
bittensor_cli/src/commands/weights.py,sha256=UHakAMTNqRkg_fkiyebbZAT9T3UEf93MmdbFgPSbqUw,16520
|
24
|
+
bittensor_cli/src/commands/stake/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
+
bittensor_cli/src/commands/stake/children_hotkeys.py,sha256=j239HdawvHp9rTbIx9MI9v9hkaKbA5OaN_cIQISkHdw,28606
|
26
|
+
bittensor_cli/src/commands/stake/stake.py,sha256=7TyFtL5wnXvGvD-GckNrNTRdcu3RewAfx_JfEekugFU,56147
|
27
|
+
bittensor_cli-8.4.0.dist-info/METADATA,sha256=XJctL-W1oJCDVKEvsDOrEG_oh6t8ycRPeXudbVaQ174,6788
|
28
|
+
bittensor_cli-8.4.0.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
29
|
+
bittensor_cli-8.4.0.dist-info/entry_points.txt,sha256=hBTLGLbVxmAKy69XSKaUZvjTCmyEzDGZKq4S8UOto8I,49
|
30
|
+
bittensor_cli-8.4.0.dist-info/top_level.txt,sha256=DvgvXpmTtI_Q1BbDZMlK90LFcGFCreN1daViEPV2iFw,14
|
31
|
+
bittensor_cli-8.4.0.dist-info/RECORD,,
|
@@ -1,31 +0,0 @@
|
|
1
|
-
bittensor_cli/__init__.py,sha256=O5T0sSkvfCnlXbdjLguIp-4w1jd6Bmb-TXgQINZD1uo,1217
|
2
|
-
bittensor_cli/cli.py,sha256=tMJBqFba9L267Ghl8Af228_MIR8h7nHfYrmN1Tz3xR8,169461
|
3
|
-
bittensor_cli/doc_generation_helper.py,sha256=GexqjEIKulWg84hpNBEchJ840oOgOi7DWpt447nsdNI,91
|
4
|
-
bittensor_cli/src/__init__.py,sha256=9hFSqapIynZbrjc9YHl2wARkPdk4pV5P5zLSvn-EbqM,11856
|
5
|
-
bittensor_cli/src/bittensor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
|
-
bittensor_cli/src/bittensor/async_substrate_interface.py,sha256=EcvAoQcyDa_Sm8Ne-SNtMm8lUkZmkzDto1VUvqG0rlg,103271
|
7
|
-
bittensor_cli/src/bittensor/balances.py,sha256=102mg1iiliLSLx-EocQseWGHiWzRqcBBM-MRoObOdKo,10075
|
8
|
-
bittensor_cli/src/bittensor/chain_data.py,sha256=IsHWjmhJbTvud2i3IM1sfmBHP82VxNHC1iFDAtlLgXc,26490
|
9
|
-
bittensor_cli/src/bittensor/minigraph.py,sha256=17AjEA75MO7ez_NekOJSaAz6ARjPt99QG_7E1RJ_u_k,8891
|
10
|
-
bittensor_cli/src/bittensor/networking.py,sha256=pZLMs8YXpZzDMLXWMBb_Bj6TVkm_q9khyY-lnbwVMuE,462
|
11
|
-
bittensor_cli/src/bittensor/subtensor_interface.py,sha256=cwbRhS5qV0Jmref5Qe7rsuDy8ssrRqdObKHvaeGeoOc,43373
|
12
|
-
bittensor_cli/src/bittensor/utils.py,sha256=cvtej2aKix_EEU5FBeBCd3vIEZSt44R0dCidny7zyoA,33663
|
13
|
-
bittensor_cli/src/bittensor/extrinsics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
-
bittensor_cli/src/bittensor/extrinsics/registration.py,sha256=xrEdN_gbL6fFNh-tZRwgB-Xpb8fUer1nSd3Xr5f7x9g,59202
|
15
|
-
bittensor_cli/src/bittensor/extrinsics/root.py,sha256=RZEQv6QVDAQDjuX_vgjOMsatYvHpA3MW8zueiL6jxlE,19376
|
16
|
-
bittensor_cli/src/bittensor/extrinsics/transfer.py,sha256=ZqbUcaGVENFP0nviLj914lJXcQ_bHpUpyudPlrmSCzw,8830
|
17
|
-
bittensor_cli/src/bittensor/templates/table.j2,sha256=P2EFiksnO1cQsB8zjK6hVJwUryHTsLslzRE0YtobAV8,10601
|
18
|
-
bittensor_cli/src/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
-
bittensor_cli/src/commands/root.py,sha256=MiNdEg2SCPYv4Q_8aSgGn_9Giotv-k5JEnwgjrDA09A,62753
|
20
|
-
bittensor_cli/src/commands/subnets.py,sha256=0tf3DhdCmvIQA_64gFTfhk9spOA9PHSn4NUsswjbY0U,33445
|
21
|
-
bittensor_cli/src/commands/sudo.py,sha256=lpmZBT2xoAcERQNjJN__6nBmFUNcbXFTdNvl3S_T5Cg,8310
|
22
|
-
bittensor_cli/src/commands/wallets.py,sha256=lHuChXL9n4esIktENZjffdVnNKaFQaBhtuIHvunqrvs,60286
|
23
|
-
bittensor_cli/src/commands/weights.py,sha256=UHakAMTNqRkg_fkiyebbZAT9T3UEf93MmdbFgPSbqUw,16520
|
24
|
-
bittensor_cli/src/commands/stake/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
-
bittensor_cli/src/commands/stake/children_hotkeys.py,sha256=3FapotpWGbE_i6RELt0Sqlk5Bvao4Sd3tQibLS13nKQ,28667
|
26
|
-
bittensor_cli/src/commands/stake/stake.py,sha256=lGLMWdE3RVmYcr57pMwKljQI8vRX3WFRltmXWHdnKy8,56622
|
27
|
-
bittensor_cli-8.3.0.dist-info/METADATA,sha256=5SilMKuTyLT2Y6r_zi1Gh3kFJWSzWUQvidQQADezkfs,6788
|
28
|
-
bittensor_cli-8.3.0.dist-info/WHEEL,sha256=eOLhNAGa2EW3wWl_TU484h7q1UNgy0JXjjoqKoxAAQc,92
|
29
|
-
bittensor_cli-8.3.0.dist-info/entry_points.txt,sha256=hBTLGLbVxmAKy69XSKaUZvjTCmyEzDGZKq4S8UOto8I,49
|
30
|
-
bittensor_cli-8.3.0.dist-info/top_level.txt,sha256=DvgvXpmTtI_Q1BbDZMlK90LFcGFCreN1daViEPV2iFw,14
|
31
|
-
bittensor_cli-8.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|