htcli 1.1.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.
- htcli-1.1.0.dist-info/METADATA +509 -0
- htcli-1.1.0.dist-info/RECORD +140 -0
- htcli-1.1.0.dist-info/WHEEL +4 -0
- htcli-1.1.0.dist-info/entry_points.txt +2 -0
- htcli-1.1.0.dist-info/licenses/LICENSE +21 -0
- src/__init__.py +0 -0
- src/htcli/__init__.py +5 -0
- src/htcli/client/__init__.py +338 -0
- src/htcli/client/extrinsics/__init__.py +26 -0
- src/htcli/client/extrinsics/base.py +487 -0
- src/htcli/client/extrinsics/consensus.py +79 -0
- src/htcli/client/extrinsics/governance.py +714 -0
- src/htcli/client/extrinsics/identity.py +490 -0
- src/htcli/client/extrinsics/node.py +1054 -0
- src/htcli/client/extrinsics/overwatch.py +401 -0
- src/htcli/client/extrinsics/staking.py +1504 -0
- src/htcli/client/extrinsics/subnet.py +2218 -0
- src/htcli/client/extrinsics/validator.py +203 -0
- src/htcli/client/extrinsics/wallet.py +323 -0
- src/htcli/client/offchain/__init__.py +10 -0
- src/htcli/client/offchain/backup.py +385 -0
- src/htcli/client/offchain/config.py +541 -0
- src/htcli/client/offchain/wallet.py +839 -0
- src/htcli/client/rpc/__init__.py +20 -0
- src/htcli/client/rpc/chain.py +568 -0
- src/htcli/client/rpc/node.py +783 -0
- src/htcli/client/rpc/overwatch.py +680 -0
- src/htcli/client/rpc/staking.py +216 -0
- src/htcli/client/rpc/subnet.py +2104 -0
- src/htcli/client/rpc/wallet.py +912 -0
- src/htcli/commands/__init__.py +31 -0
- src/htcli/commands/chain/__init__.py +66 -0
- src/htcli/commands/chain/display.py +204 -0
- src/htcli/commands/chain/handlers.py +260 -0
- src/htcli/commands/config/__init__.py +158 -0
- src/htcli/commands/config/display.py +353 -0
- src/htcli/commands/config/handlers.py +347 -0
- src/htcli/commands/config/prompts.py +357 -0
- src/htcli/commands/consensus/__init__.py +61 -0
- src/htcli/commands/consensus/handlers.py +100 -0
- src/htcli/commands/governance/__init__.py +49 -0
- src/htcli/commands/governance/handlers.py +81 -0
- src/htcli/commands/node/__init__.py +304 -0
- src/htcli/commands/node/display.py +749 -0
- src/htcli/commands/node/error_handling.py +470 -0
- src/htcli/commands/node/handlers.py +844 -0
- src/htcli/commands/node/prompts.py +346 -0
- src/htcli/commands/overwatch/__init__.py +219 -0
- src/htcli/commands/overwatch/display.py +396 -0
- src/htcli/commands/overwatch/error_handling.py +276 -0
- src/htcli/commands/overwatch/handlers.py +443 -0
- src/htcli/commands/overwatch/prompts.py +359 -0
- src/htcli/commands/stake/__init__.py +736 -0
- src/htcli/commands/stake/display.py +1103 -0
- src/htcli/commands/stake/error_handling.py +425 -0
- src/htcli/commands/stake/handlers.py +1902 -0
- src/htcli/commands/stake/prompts.py +1080 -0
- src/htcli/commands/subnet/__init__.py +639 -0
- src/htcli/commands/subnet/display.py +801 -0
- src/htcli/commands/subnet/error_handling.py +524 -0
- src/htcli/commands/subnet/handlers.py +2855 -0
- src/htcli/commands/subnet/prompts.py +1225 -0
- src/htcli/commands/validator/__init__.py +192 -0
- src/htcli/commands/validator/display.py +54 -0
- src/htcli/commands/validator/handlers.py +340 -0
- src/htcli/commands/wallet/__init__.py +546 -0
- src/htcli/commands/wallet/display.py +806 -0
- src/htcli/commands/wallet/error_handling.py +210 -0
- src/htcli/commands/wallet/handlers.py +3040 -0
- src/htcli/commands/wallet/prompts.py +1518 -0
- src/htcli/config.py +184 -0
- src/htcli/dependencies.py +186 -0
- src/htcli/errors/__init__.py +63 -0
- src/htcli/errors/base.py +141 -0
- src/htcli/errors/display.py +20 -0
- src/htcli/errors/handlers.py +710 -0
- src/htcli/main.py +343 -0
- src/htcli/models/__init__.py +21 -0
- src/htcli/models/enums/enum_types.py +35 -0
- src/htcli/models/errors.py +103 -0
- src/htcli/models/requests/__init__.py +197 -0
- src/htcli/models/requests/config.py +70 -0
- src/htcli/models/requests/consensus.py +19 -0
- src/htcli/models/requests/governance.py +38 -0
- src/htcli/models/requests/identity.py +51 -0
- src/htcli/models/requests/key.py +22 -0
- src/htcli/models/requests/node.py +91 -0
- src/htcli/models/requests/overwatch.py +64 -0
- src/htcli/models/requests/staking.py +580 -0
- src/htcli/models/requests/subnet.py +195 -0
- src/htcli/models/requests/validator.py +139 -0
- src/htcli/models/requests/wallet.py +118 -0
- src/htcli/models/responses/__init__.py +147 -0
- src/htcli/models/responses/base.py +18 -0
- src/htcli/models/responses/chain.py +39 -0
- src/htcli/models/responses/config.py +58 -0
- src/htcli/models/responses/identity.py +102 -0
- src/htcli/models/responses/overwatch.py +51 -0
- src/htcli/models/responses/staking.py +502 -0
- src/htcli/models/responses/subnet.py +856 -0
- src/htcli/models/responses/wallet.py +185 -0
- src/htcli/ui/__init__.py +87 -0
- src/htcli/ui/colors.py +309 -0
- src/htcli/ui/components/__init__.py +60 -0
- src/htcli/ui/components/panels.py +174 -0
- src/htcli/ui/components/progress.py +166 -0
- src/htcli/ui/components/spinners.py +92 -0
- src/htcli/ui/components/tables.py +809 -0
- src/htcli/ui/components/trees.py +721 -0
- src/htcli/ui/display.py +336 -0
- src/htcli/ui/prompts.py +870 -0
- src/htcli/utils/__init__.py +76 -0
- src/htcli/utils/blockchain/__init__.py +75 -0
- src/htcli/utils/blockchain/formatting.py +368 -0
- src/htcli/utils/blockchain/patches.py +286 -0
- src/htcli/utils/blockchain/peer_id.py +186 -0
- src/htcli/utils/blockchain/staking.py +448 -0
- src/htcli/utils/blockchain/type_registry.py +1373 -0
- src/htcli/utils/blockchain/validation.py +179 -0
- src/htcli/utils/cache.py +613 -0
- src/htcli/utils/constants.py +38 -0
- src/htcli/utils/legacy/__init__.py +12 -0
- src/htcli/utils/legacy/colors.py +311 -0
- src/htcli/utils/legacy/crypto.py +1176 -0
- src/htcli/utils/legacy/formatting.py +452 -0
- src/htcli/utils/legacy/interactive.py +306 -0
- src/htcli/utils/legacy/subnet_manifest.py +265 -0
- src/htcli/utils/legacy/validation.py +488 -0
- src/htcli/utils/logging.py +183 -0
- src/htcli/utils/network/__init__.py +20 -0
- src/htcli/utils/network/subnet.py +344 -0
- src/htcli/utils/prompts.py +27 -0
- src/htcli/utils/scale_codec.py +155 -0
- src/htcli/utils/validation/__init__.py +57 -0
- src/htcli/utils/validation/prompt_validators.py +267 -0
- src/htcli/utils/wallet/__init__.py +65 -0
- src/htcli/utils/wallet/auth.py +151 -0
- src/htcli/utils/wallet/core.py +1069 -0
- src/htcli/utils/wallet/crypto.py +1615 -0
- src/htcli/utils/wallet/migration.py +159 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Config-related response models.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ConfigInitResponse(BaseModel):
|
|
11
|
+
"""Response model for config initialization."""
|
|
12
|
+
|
|
13
|
+
config_path: str = Field(..., description="Configuration file path")
|
|
14
|
+
created: bool = Field(..., description="Whether config was created")
|
|
15
|
+
message: str = Field(..., description="Initialization message")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ConfigShowResponse(BaseModel):
|
|
19
|
+
"""Response model for config show."""
|
|
20
|
+
|
|
21
|
+
config_data: dict[str, Any] = Field(..., description="Config data")
|
|
22
|
+
config_path: str = Field(..., description="Config file path")
|
|
23
|
+
exists: bool = Field(..., description="Whether config file exists")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ConfigValidateResponse(BaseModel):
|
|
27
|
+
"""Response model for config validation."""
|
|
28
|
+
|
|
29
|
+
config_path: str = Field(..., description="Configuration file path")
|
|
30
|
+
valid: bool = Field(..., description="Configuration validation status")
|
|
31
|
+
errors: list[str] = Field(default=[], description="Validation errors")
|
|
32
|
+
message: str = Field(..., description="Validation result message")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ConfigSetResponse(BaseModel):
|
|
36
|
+
"""Response model for config set."""
|
|
37
|
+
|
|
38
|
+
config_path: str = Field(..., description="Configuration file path")
|
|
39
|
+
key: str = Field(..., description="Configuration key")
|
|
40
|
+
old_value: Any = Field(..., description="Previous value")
|
|
41
|
+
new_value: Any = Field(..., description="New value")
|
|
42
|
+
message: str = Field(..., description="Result message")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class ConfigGetResponse(BaseModel):
|
|
46
|
+
"""Response model for config get."""
|
|
47
|
+
|
|
48
|
+
key: str = Field(..., description="Configuration key")
|
|
49
|
+
value: Any = Field(..., description="Configuration value")
|
|
50
|
+
value_type: str = Field(..., description="Value type")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class ConfigPathResponse(BaseModel):
|
|
54
|
+
"""Response model for config path."""
|
|
55
|
+
|
|
56
|
+
config_path: str = Field(..., description="Configuration file path")
|
|
57
|
+
exists: bool = Field(..., description="Whether config file exists")
|
|
58
|
+
absolute_path: str = Field(..., description="Absolute path to config file")
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Identity-related response models.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, Field, field_validator
|
|
8
|
+
from scalecodec.base import RuntimeConfiguration, ScaleBytes
|
|
9
|
+
from substrateinterface.base import load_type_registry_preset
|
|
10
|
+
|
|
11
|
+
from .base import BaseResponse
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class IdentityInfo(BaseModel):
|
|
15
|
+
"""Identity information structure with validation matching Rust ColdkeyIdentityData."""
|
|
16
|
+
|
|
17
|
+
coldkey: str = Field(..., description="Coldkey account ID")
|
|
18
|
+
hotkey: str = Field(..., description="Hotkey account ID")
|
|
19
|
+
name: bytes = Field(..., description="Identity name")
|
|
20
|
+
url: bytes = Field(default=b"", description="Identity URL")
|
|
21
|
+
image: bytes = Field(default=b"", description="Identity image URL")
|
|
22
|
+
discord: bytes = Field(default=b"", description="Discord handle")
|
|
23
|
+
x: bytes = Field(default=b"", description="X (Twitter) handle")
|
|
24
|
+
telegram: bytes = Field(default=b"", description="Telegram handle")
|
|
25
|
+
github: bytes = Field(default=b"", description="GitHub URL")
|
|
26
|
+
hugging_face: bytes = Field(default=b"", description="Hugging Face URL")
|
|
27
|
+
description: bytes = Field(default=b"", description="Identity description")
|
|
28
|
+
misc: bytes = Field(default=b"", description="Miscellaneous information")
|
|
29
|
+
|
|
30
|
+
@field_validator(
|
|
31
|
+
"name",
|
|
32
|
+
"url",
|
|
33
|
+
"image",
|
|
34
|
+
"discord",
|
|
35
|
+
"x",
|
|
36
|
+
"telegram",
|
|
37
|
+
"github",
|
|
38
|
+
"hugging_face",
|
|
39
|
+
"description",
|
|
40
|
+
"misc",
|
|
41
|
+
)
|
|
42
|
+
def validate_bytes_not_empty(cls, v):
|
|
43
|
+
"""Ensure byte fields are not None."""
|
|
44
|
+
if v is None:
|
|
45
|
+
return b""
|
|
46
|
+
return v
|
|
47
|
+
|
|
48
|
+
@classmethod
|
|
49
|
+
def from_scale_bytes(
|
|
50
|
+
cls, data: bytes, coldkey: str = "", hotkey: str = ""
|
|
51
|
+
) -> "IdentityInfo":
|
|
52
|
+
"""Decode from SCALE bytes using scalecodec."""
|
|
53
|
+
if not ScaleBytes:
|
|
54
|
+
raise ImportError("scalecodec is required for decoding")
|
|
55
|
+
|
|
56
|
+
# Load type registry
|
|
57
|
+
type_registry = load_type_registry_preset("substrate-node-template")
|
|
58
|
+
|
|
59
|
+
# Create runtime configuration
|
|
60
|
+
runtime_config = RuntimeConfiguration()
|
|
61
|
+
runtime_config.update_type_registry(type_registry)
|
|
62
|
+
|
|
63
|
+
# Decode the data (ColdkeyIdentityData structure)
|
|
64
|
+
obj = runtime_config.create_scale_object(
|
|
65
|
+
"ColdkeyIdentityData", ScaleBytes(data)
|
|
66
|
+
)
|
|
67
|
+
obj.decode()
|
|
68
|
+
|
|
69
|
+
return cls(
|
|
70
|
+
coldkey=coldkey,
|
|
71
|
+
hotkey=hotkey,
|
|
72
|
+
name=obj["name"],
|
|
73
|
+
url=obj["url"],
|
|
74
|
+
image=obj["image"],
|
|
75
|
+
discord=obj["discord"],
|
|
76
|
+
x=obj["x"],
|
|
77
|
+
telegram=obj["telegram"],
|
|
78
|
+
github=obj["github"],
|
|
79
|
+
hugging_face=obj["hugging_face"],
|
|
80
|
+
description=obj["description"],
|
|
81
|
+
misc=obj["misc"],
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class IdentityRegisterResponse(BaseResponse):
|
|
86
|
+
"""Response model for identity registration."""
|
|
87
|
+
|
|
88
|
+
identity_name: Optional[str] = Field(None, description="Registered identity name")
|
|
89
|
+
coldkey: Optional[str] = Field(None, description="Coldkey account ID")
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class IdentityRemoveResponse(BaseResponse):
|
|
93
|
+
"""Response model for identity removal."""
|
|
94
|
+
|
|
95
|
+
identity_name: Optional[str] = Field(None, description="Removed identity name")
|
|
96
|
+
coldkey: Optional[str] = Field(None, description="Coldkey account ID")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class IdentityAcceptResponse(BaseResponse):
|
|
100
|
+
"""Response model for identity acceptance."""
|
|
101
|
+
|
|
102
|
+
identity: Optional[str] = Field(None, description="Accepted identity data")
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field, field_validator
|
|
4
|
+
from scalecodec import ScaleBytes
|
|
5
|
+
from scalecodec.base import RuntimeConfiguration
|
|
6
|
+
from scalecodec.type_registry import load_type_registry_preset
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OverwatchNodeInfo(BaseModel):
|
|
10
|
+
"""Overwatch node information structure matching Rust OverwatchNodeInfo with validation."""
|
|
11
|
+
|
|
12
|
+
overwatch_node_id: int = Field(..., description="Overwatch node ID", ge=0)
|
|
13
|
+
coldkey: str = Field(..., description="Coldkey account ID")
|
|
14
|
+
hotkey: str = Field(..., description="Hotkey account ID")
|
|
15
|
+
peer_ids: dict[int, bytes] = Field(default_factory=dict, description="Peer IDs by subnet")
|
|
16
|
+
penalties: int = Field(default=0, description="Penalties", ge=0)
|
|
17
|
+
stake_balance: int = Field(default=0, description="Stake balance in wei", ge=0)
|
|
18
|
+
reputation: Optional[dict[str, Any]] = Field(None, description="Reputation data")
|
|
19
|
+
|
|
20
|
+
@field_validator("peer_ids")
|
|
21
|
+
def validate_peer_ids(cls, v):
|
|
22
|
+
"""Ensure peer IDs are valid."""
|
|
23
|
+
if v is None:
|
|
24
|
+
return {}
|
|
25
|
+
return v
|
|
26
|
+
|
|
27
|
+
@classmethod
|
|
28
|
+
def from_scale_bytes(cls, data: bytes) -> "OverwatchNodeInfo":
|
|
29
|
+
"""Decode from SCALE bytes using scalecodec."""
|
|
30
|
+
if not ScaleBytes:
|
|
31
|
+
raise ImportError("scalecodec is required for decoding")
|
|
32
|
+
|
|
33
|
+
# Load type registry
|
|
34
|
+
type_registry = load_type_registry_preset("substrate-node-template")
|
|
35
|
+
|
|
36
|
+
# Create runtime configuration
|
|
37
|
+
runtime_config = RuntimeConfiguration()
|
|
38
|
+
runtime_config.update_type_registry(type_registry)
|
|
39
|
+
|
|
40
|
+
# Decode the data
|
|
41
|
+
obj = runtime_config.create_scale_object("OverwatchNodeInfo", ScaleBytes(data))
|
|
42
|
+
obj.decode()
|
|
43
|
+
|
|
44
|
+
return cls(
|
|
45
|
+
overwatch_node_id=obj["overwatch_node_id"],
|
|
46
|
+
coldkey=obj["coldkey"],
|
|
47
|
+
hotkey=obj["hotkey"],
|
|
48
|
+
peer_ids=list(obj["peer_ids"]),
|
|
49
|
+
penalties=obj["penalties"],
|
|
50
|
+
reputation=obj["reputation"],
|
|
51
|
+
)
|