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.
Files changed (140) hide show
  1. htcli-1.1.0.dist-info/METADATA +509 -0
  2. htcli-1.1.0.dist-info/RECORD +140 -0
  3. htcli-1.1.0.dist-info/WHEEL +4 -0
  4. htcli-1.1.0.dist-info/entry_points.txt +2 -0
  5. htcli-1.1.0.dist-info/licenses/LICENSE +21 -0
  6. src/__init__.py +0 -0
  7. src/htcli/__init__.py +5 -0
  8. src/htcli/client/__init__.py +338 -0
  9. src/htcli/client/extrinsics/__init__.py +26 -0
  10. src/htcli/client/extrinsics/base.py +487 -0
  11. src/htcli/client/extrinsics/consensus.py +79 -0
  12. src/htcli/client/extrinsics/governance.py +714 -0
  13. src/htcli/client/extrinsics/identity.py +490 -0
  14. src/htcli/client/extrinsics/node.py +1054 -0
  15. src/htcli/client/extrinsics/overwatch.py +401 -0
  16. src/htcli/client/extrinsics/staking.py +1504 -0
  17. src/htcli/client/extrinsics/subnet.py +2218 -0
  18. src/htcli/client/extrinsics/validator.py +203 -0
  19. src/htcli/client/extrinsics/wallet.py +323 -0
  20. src/htcli/client/offchain/__init__.py +10 -0
  21. src/htcli/client/offchain/backup.py +385 -0
  22. src/htcli/client/offchain/config.py +541 -0
  23. src/htcli/client/offchain/wallet.py +839 -0
  24. src/htcli/client/rpc/__init__.py +20 -0
  25. src/htcli/client/rpc/chain.py +568 -0
  26. src/htcli/client/rpc/node.py +783 -0
  27. src/htcli/client/rpc/overwatch.py +680 -0
  28. src/htcli/client/rpc/staking.py +216 -0
  29. src/htcli/client/rpc/subnet.py +2104 -0
  30. src/htcli/client/rpc/wallet.py +912 -0
  31. src/htcli/commands/__init__.py +31 -0
  32. src/htcli/commands/chain/__init__.py +66 -0
  33. src/htcli/commands/chain/display.py +204 -0
  34. src/htcli/commands/chain/handlers.py +260 -0
  35. src/htcli/commands/config/__init__.py +158 -0
  36. src/htcli/commands/config/display.py +353 -0
  37. src/htcli/commands/config/handlers.py +347 -0
  38. src/htcli/commands/config/prompts.py +357 -0
  39. src/htcli/commands/consensus/__init__.py +61 -0
  40. src/htcli/commands/consensus/handlers.py +100 -0
  41. src/htcli/commands/governance/__init__.py +49 -0
  42. src/htcli/commands/governance/handlers.py +81 -0
  43. src/htcli/commands/node/__init__.py +304 -0
  44. src/htcli/commands/node/display.py +749 -0
  45. src/htcli/commands/node/error_handling.py +470 -0
  46. src/htcli/commands/node/handlers.py +844 -0
  47. src/htcli/commands/node/prompts.py +346 -0
  48. src/htcli/commands/overwatch/__init__.py +219 -0
  49. src/htcli/commands/overwatch/display.py +396 -0
  50. src/htcli/commands/overwatch/error_handling.py +276 -0
  51. src/htcli/commands/overwatch/handlers.py +443 -0
  52. src/htcli/commands/overwatch/prompts.py +359 -0
  53. src/htcli/commands/stake/__init__.py +736 -0
  54. src/htcli/commands/stake/display.py +1103 -0
  55. src/htcli/commands/stake/error_handling.py +425 -0
  56. src/htcli/commands/stake/handlers.py +1902 -0
  57. src/htcli/commands/stake/prompts.py +1080 -0
  58. src/htcli/commands/subnet/__init__.py +639 -0
  59. src/htcli/commands/subnet/display.py +801 -0
  60. src/htcli/commands/subnet/error_handling.py +524 -0
  61. src/htcli/commands/subnet/handlers.py +2855 -0
  62. src/htcli/commands/subnet/prompts.py +1225 -0
  63. src/htcli/commands/validator/__init__.py +192 -0
  64. src/htcli/commands/validator/display.py +54 -0
  65. src/htcli/commands/validator/handlers.py +340 -0
  66. src/htcli/commands/wallet/__init__.py +546 -0
  67. src/htcli/commands/wallet/display.py +806 -0
  68. src/htcli/commands/wallet/error_handling.py +210 -0
  69. src/htcli/commands/wallet/handlers.py +3040 -0
  70. src/htcli/commands/wallet/prompts.py +1518 -0
  71. src/htcli/config.py +184 -0
  72. src/htcli/dependencies.py +186 -0
  73. src/htcli/errors/__init__.py +63 -0
  74. src/htcli/errors/base.py +141 -0
  75. src/htcli/errors/display.py +20 -0
  76. src/htcli/errors/handlers.py +710 -0
  77. src/htcli/main.py +343 -0
  78. src/htcli/models/__init__.py +21 -0
  79. src/htcli/models/enums/enum_types.py +35 -0
  80. src/htcli/models/errors.py +103 -0
  81. src/htcli/models/requests/__init__.py +197 -0
  82. src/htcli/models/requests/config.py +70 -0
  83. src/htcli/models/requests/consensus.py +19 -0
  84. src/htcli/models/requests/governance.py +38 -0
  85. src/htcli/models/requests/identity.py +51 -0
  86. src/htcli/models/requests/key.py +22 -0
  87. src/htcli/models/requests/node.py +91 -0
  88. src/htcli/models/requests/overwatch.py +64 -0
  89. src/htcli/models/requests/staking.py +580 -0
  90. src/htcli/models/requests/subnet.py +195 -0
  91. src/htcli/models/requests/validator.py +139 -0
  92. src/htcli/models/requests/wallet.py +118 -0
  93. src/htcli/models/responses/__init__.py +147 -0
  94. src/htcli/models/responses/base.py +18 -0
  95. src/htcli/models/responses/chain.py +39 -0
  96. src/htcli/models/responses/config.py +58 -0
  97. src/htcli/models/responses/identity.py +102 -0
  98. src/htcli/models/responses/overwatch.py +51 -0
  99. src/htcli/models/responses/staking.py +502 -0
  100. src/htcli/models/responses/subnet.py +856 -0
  101. src/htcli/models/responses/wallet.py +185 -0
  102. src/htcli/ui/__init__.py +87 -0
  103. src/htcli/ui/colors.py +309 -0
  104. src/htcli/ui/components/__init__.py +60 -0
  105. src/htcli/ui/components/panels.py +174 -0
  106. src/htcli/ui/components/progress.py +166 -0
  107. src/htcli/ui/components/spinners.py +92 -0
  108. src/htcli/ui/components/tables.py +809 -0
  109. src/htcli/ui/components/trees.py +721 -0
  110. src/htcli/ui/display.py +336 -0
  111. src/htcli/ui/prompts.py +870 -0
  112. src/htcli/utils/__init__.py +76 -0
  113. src/htcli/utils/blockchain/__init__.py +75 -0
  114. src/htcli/utils/blockchain/formatting.py +368 -0
  115. src/htcli/utils/blockchain/patches.py +286 -0
  116. src/htcli/utils/blockchain/peer_id.py +186 -0
  117. src/htcli/utils/blockchain/staking.py +448 -0
  118. src/htcli/utils/blockchain/type_registry.py +1373 -0
  119. src/htcli/utils/blockchain/validation.py +179 -0
  120. src/htcli/utils/cache.py +613 -0
  121. src/htcli/utils/constants.py +38 -0
  122. src/htcli/utils/legacy/__init__.py +12 -0
  123. src/htcli/utils/legacy/colors.py +311 -0
  124. src/htcli/utils/legacy/crypto.py +1176 -0
  125. src/htcli/utils/legacy/formatting.py +452 -0
  126. src/htcli/utils/legacy/interactive.py +306 -0
  127. src/htcli/utils/legacy/subnet_manifest.py +265 -0
  128. src/htcli/utils/legacy/validation.py +488 -0
  129. src/htcli/utils/logging.py +183 -0
  130. src/htcli/utils/network/__init__.py +20 -0
  131. src/htcli/utils/network/subnet.py +344 -0
  132. src/htcli/utils/prompts.py +27 -0
  133. src/htcli/utils/scale_codec.py +155 -0
  134. src/htcli/utils/validation/__init__.py +57 -0
  135. src/htcli/utils/validation/prompt_validators.py +267 -0
  136. src/htcli/utils/wallet/__init__.py +65 -0
  137. src/htcli/utils/wallet/auth.py +151 -0
  138. src/htcli/utils/wallet/core.py +1069 -0
  139. src/htcli/utils/wallet/crypto.py +1615 -0
  140. src/htcli/utils/wallet/migration.py +159 -0
src/htcli/main.py ADDED
@@ -0,0 +1,343 @@
1
+ """
2
+ Main CLI entry point for the Hypertensor CLI.
3
+ """
4
+
5
+ import inspect
6
+ import signal
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ import click
11
+ import typer
12
+ from rich.align import Align
13
+ from rich.console import Console
14
+ from rich.text import Text
15
+ from typer.core import TyperArgument, TyperGroup
16
+
17
+ from . import __version__
18
+ from .ui.display import get_console, print_error, print_warning
19
+
20
+
21
+ def _patch_click_make_metavar_compat() -> None:
22
+ """Patch Click 8.2+ metavar signature for Typer 0.15 compatibility."""
23
+ signature = inspect.signature(click.core.Parameter.make_metavar)
24
+ if "ctx" not in signature.parameters:
25
+ if "ctx" not in inspect.signature(TyperArgument.make_metavar).parameters:
26
+ return
27
+ else:
28
+ original_make_metavar = click.core.Parameter.make_metavar
29
+
30
+ def compat_make_metavar(self, ctx=None):
31
+ if ctx is None:
32
+ ctx = click.Context(click.Command(self.name or "htcli"))
33
+ return original_make_metavar(self, ctx)
34
+
35
+ click.core.Parameter.make_metavar = compat_make_metavar
36
+
37
+ if "ctx" not in inspect.signature(TyperArgument.make_metavar).parameters:
38
+
39
+ def compat_typer_argument_make_metavar(self, ctx=None):
40
+ if self.metavar is not None:
41
+ return self.metavar
42
+ if ctx is None:
43
+ ctx = click.Context(click.Command(self.name or "htcli"))
44
+ var = (self.name or "").upper()
45
+ if not self.required:
46
+ var = f"[{var}]"
47
+ type_var = self.type.get_metavar(param=self, ctx=ctx)
48
+ if type_var:
49
+ var += f":{type_var}"
50
+ if self.nargs != 1:
51
+ var += "..."
52
+ return var
53
+
54
+ TyperArgument.make_metavar = compat_typer_argument_make_metavar
55
+
56
+
57
+ _patch_click_make_metavar_compat()
58
+
59
+
60
+ # Set up global exception handler for KeyboardInterrupt
61
+ def _handle_keyboard_interrupt_exception(exc_type, exc_value, exc_traceback):
62
+ """Handle unhandled KeyboardInterrupt exceptions with a clean message."""
63
+ if exc_type is KeyboardInterrupt:
64
+ get_console().print()
65
+ print_warning("Operation cancelled")
66
+ sys.exit(130) # Standard exit code for SIGINT (Ctrl+C)
67
+ else:
68
+ # For other exceptions, use default handler
69
+ sys.__excepthook__(exc_type, exc_value, exc_traceback)
70
+
71
+
72
+ # Set up signal handler for Ctrl+C at the earliest possible point
73
+ def _handle_keyboard_interrupt(signum, frame):
74
+ """Handle Ctrl+C gracefully with a clean message."""
75
+ get_console().print()
76
+ print_warning("Operation cancelled")
77
+ sys.exit(130) # Standard exit code for SIGINT (Ctrl+C)
78
+
79
+
80
+ # Register signal handler for SIGINT (Ctrl+C)
81
+ signal.signal(signal.SIGINT, _handle_keyboard_interrupt)
82
+
83
+ # Set up global exception hook to catch unhandled KeyboardInterrupt
84
+ sys.excepthook = _handle_keyboard_interrupt_exception
85
+
86
+ try:
87
+ from .commands import (
88
+ chain_app,
89
+ config_app,
90
+ consensus_app,
91
+ governance_app,
92
+ node_app,
93
+ overwatch_app,
94
+ stake_app,
95
+ subnet_app,
96
+ validator_app,
97
+ wallet_app,
98
+ )
99
+ from .config import apply_network_profile, load_config
100
+ from .dependencies import set_config
101
+ from .utils.logging import get_logger, setup_logging
102
+ except KeyboardInterrupt:
103
+ # Handle Ctrl+C during imports
104
+ get_console().print()
105
+ print_warning("Operation cancelled")
106
+ sys.exit(130)
107
+
108
+ # ASCII art banner for HTCLI
109
+ BANNER = """
110
+ ██╗ ██╗████████╗ ██████╗██╗ ██╗
111
+ ██║ ██║╚══██╔══╝██╔════╝██║ ██║
112
+ ███████║ ██║ ██║ ██║ ██║
113
+ ██╔══██║ ██║ ██║ ██║ ██║
114
+ ██║ ██║ ██║ ╚██████╗███████╗██║
115
+ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝
116
+ """
117
+
118
+ TAGLINE = "Hypertensor Blockchain CLI - Your Gateway to Decentralized AI"
119
+
120
+ console = Console()
121
+
122
+ # Initialize logging
123
+ logger = get_logger(__name__)
124
+
125
+
126
+ def get_ascii_art():
127
+ """Return ASCII art for the CLI (legacy function for compatibility)."""
128
+ return BANNER
129
+
130
+
131
+ def show_banner():
132
+ """Display the styled ASCII art banner with gradient colors."""
133
+ banner_lines = BANNER.strip().split("\n")
134
+ # Gradient from bright cyan through blue to purple
135
+ colors = ["bright_cyan", "cyan", "blue", "bright_blue", "magenta", "bright_magenta"]
136
+
137
+ styled_banner = Text()
138
+ for i, line in enumerate(banner_lines):
139
+ color = colors[i % len(colors)]
140
+ styled_banner.append(line + "\n", style=color)
141
+
142
+ console.print(Align.center(styled_banner))
143
+ console.print(Align.center(Text(TAGLINE, style="italic bright_yellow")))
144
+ console.print()
145
+
146
+
147
+ class BannerGroup(TyperGroup):
148
+ """Custom Typer group that shows banner before help output."""
149
+
150
+ def format_help(self, ctx, formatter):
151
+ # Show banner before help
152
+ show_banner()
153
+ super().format_help(ctx, formatter)
154
+
155
+
156
+ app = typer.Typer(
157
+ name="htcli",
158
+ help="Hypertensor Blockchain CLI - Manage subnets, wallets, and chain operations.",
159
+ add_completion=True,
160
+ rich_markup_mode=None,
161
+ no_args_is_help=False,
162
+ cls=BannerGroup,
163
+ )
164
+
165
+ # Global configuration
166
+ config = None
167
+
168
+
169
+ @app.callback(invoke_without_command=True)
170
+ def main(
171
+ config_file: Path | None = typer.Option(
172
+ None, "--config", "-c", help="Configuration file path"
173
+ ),
174
+ endpoint: str | None = typer.Option(
175
+ None, "--endpoint", "-e", help="Blockchain endpoint"
176
+ ),
177
+ subtensor_network: str | None = typer.Option(
178
+ None,
179
+ "--subtensor.network",
180
+ "--subtensor-network",
181
+ help="Compatibility network selector (main, test, local)",
182
+ ),
183
+ verbose: bool = typer.Option(False, "--verbose", "-v", help="Verbose output"),
184
+ output_format: str = typer.Option(
185
+ "table", "--format", "-f", help="Output format (table/json/csv)"
186
+ ),
187
+ version: bool = typer.Option(
188
+ False,
189
+ "--version",
190
+ help="Show the htcli version and exit.",
191
+ is_eager=True,
192
+ ),
193
+ ):
194
+ """Hypertensor Blockchain CLI - Manage subnets, wallets, and chain operations."""
195
+ global config
196
+
197
+ if version:
198
+ console.print(f"htcli v{__version__}")
199
+ console.print("Developed by ShiftLayer LLC")
200
+ raise typer.Exit()
201
+
202
+ # Initialize logging based on verbosity
203
+ log_level = "DEBUG" if verbose else "INFO"
204
+ setup_logging(
205
+ level=log_level, enable_console_logging=False
206
+ ) # Disable console logging to avoid interfering with CLI output
207
+
208
+ logger.info(f"HTCLI starting with log level: {log_level}")
209
+
210
+ # Show beautiful welcome screen when no command is provided
211
+ import sys
212
+
213
+ # Skip config loading for help commands to avoid hanging
214
+ is_help = "--help" in sys.argv or "-h" in sys.argv
215
+
216
+ if len(sys.argv) == 1:
217
+ from rich.panel import Panel
218
+ from rich.table import Table
219
+
220
+ # Display styled banner
221
+ show_banner()
222
+
223
+ # Create a beautiful welcome panel
224
+ welcome_text = Text()
225
+ welcome_text.append("Welcome to ", style="bold white")
226
+ welcome_text.append("Hypertensor CLI", style="bold cyan")
227
+ welcome_text.append(
228
+ "\nYour gateway to the Hypertensor blockchain ecosystem",
229
+ style="italic dim",
230
+ )
231
+
232
+ welcome_panel = Panel(
233
+ welcome_text,
234
+ title="[bold cyan]HTCLI[/bold cyan]",
235
+ border_style="cyan",
236
+ padding=(1, 2),
237
+ )
238
+
239
+ console.print(welcome_panel)
240
+ console.print()
241
+
242
+ # Create command categories table
243
+ table = Table(
244
+ title="[bold cyan]Available Commands[/bold cyan]",
245
+ show_header=True,
246
+ header_style="bold magenta",
247
+ )
248
+ table.add_column("Category", style="cyan", no_wrap=True)
249
+ table.add_column("Description", style="white")
250
+ table.add_column("Example", style="dim")
251
+
252
+ table.add_row("config", "Configuration management", "htcli config init")
253
+ table.add_row("subnet", "Subnet operations", "htcli subnet list")
254
+ table.add_row("node", "Node management", "htcli node register --subnet-id 1")
255
+ table.add_row(
256
+ "stake",
257
+ "Staking operations",
258
+ "htcli stake add --subnet-id 1 --amount 100",
259
+ )
260
+ table.add_row("wallet", "Wallet management", "htcli wallet generate-coldkey")
261
+ table.add_row(
262
+ "validator",
263
+ "Validator operations",
264
+ "htcli validator register --hotkey 0x...",
265
+ )
266
+ table.add_row("chain", "Chain & network operations", "htcli chain info")
267
+ table.add_row(
268
+ "consensus",
269
+ "Consensus operations",
270
+ "htcli consensus propose --subnet 1 --data 0x123",
271
+ )
272
+
273
+ console.print(table)
274
+ console.print()
275
+
276
+ # Quick tips section
277
+ tips_panel = Panel(
278
+ "[bold yellow]Quick Tips:[/bold yellow]\n"
279
+ "• [bold cyan]🔑 Setup Keys:[/bold cyan] htcli wallet generate-coldkey --name my-wallet\n"
280
+ "• [bold cyan]Check Identity:[/bold cyan] htcli wallet identity --help\n"
281
+ "• [bold cyan]Filter Assets:[/bold cyan] Use command filters such as --coldkey where supported\n"
282
+ "• [bold cyan]Get Help:[/bold cyan] Use --help with any command\n"
283
+ "• [bold cyan]JSON Output:[/bold cyan] Use global --format json before the command group",
284
+ title="[bold yellow]💡 Getting Started[/bold yellow]",
285
+ border_style="yellow",
286
+ )
287
+
288
+ console.print(tips_panel)
289
+ raise typer.Exit()
290
+
291
+ # Load configuration only if not a help command (help commands don't need config)
292
+ if not is_help:
293
+ config = load_config(config_file)
294
+
295
+ if subtensor_network:
296
+ try:
297
+ config = apply_network_profile(config, subtensor_network)
298
+ except ValueError as e:
299
+ print_error(str(e))
300
+ raise typer.Exit(1) from e
301
+
302
+ # Override endpoint if provided
303
+ if endpoint:
304
+ config.network.endpoint = endpoint
305
+
306
+ # Set global options
307
+ config.output.verbose = verbose
308
+ config.output.format = output_format
309
+
310
+ # Store config globally for lazy client initialization
311
+ # Client will be initialized only when needed for blockchain operations
312
+ set_config(config)
313
+
314
+
315
+ # Include the main command groups with new folder-based structure
316
+ app.add_typer(wallet_app, name="wallet", help="Wallet and key management")
317
+ app.add_typer(subnet_app, name="subnet", help="Subnet operations")
318
+ app.add_typer(stake_app, name="stake", help="Staking operations and management")
319
+ app.add_typer(chain_app, name="chain", help="Chain operations")
320
+ app.add_typer(node_app, name="node", help="Node management operations")
321
+ app.add_typer(config_app, name="config", help="Configuration management")
322
+ app.add_typer(overwatch_app, name="overwatch", help="Overwatch node operations")
323
+ app.add_typer(consensus_app, name="consensus", help="Consensus operations")
324
+ app.add_typer(governance_app, name="governance", help="Governance operations")
325
+ app.add_typer(validator_app, name="validator", help="Validator operations")
326
+
327
+
328
+ if __name__ == "__main__":
329
+ try:
330
+ app()
331
+ except KeyboardInterrupt:
332
+ # User pressed Ctrl+C - exit cleanly with a friendly message
333
+ get_console().print()
334
+ print_warning("Operation cancelled")
335
+ sys.exit(130) # Standard exit code for SIGINT (Ctrl+C)
336
+ except Exception as e:
337
+ # For any other unexpected errors during app initialization
338
+ # (typer should handle most errors, but this is a safety net)
339
+ logger.error(f"Unexpected error in main: {e}", exc_info=True)
340
+ get_console().print()
341
+ print_error("An unexpected error occurred")
342
+ get_console().print(f"[dim]{str(e)}[/dim]")
343
+ sys.exit(1)
@@ -0,0 +1,21 @@
1
+ """
2
+ HTCLI Models Package.
3
+
4
+ This package contains all Pydantic models for requests, responses, and errors.
5
+ Models are organized into separate folders for better maintainability.
6
+ """
7
+
8
+ # Import all request models
9
+ # Import error models (keep existing structure)
10
+ from .errors import *
11
+ from .requests import *
12
+
13
+ # Import all response models
14
+ from .responses import *
15
+
16
+ # Re-export everything for backward compatibility
17
+ __all__ = [
18
+ # All request models are exported from requests package
19
+ # All response models are exported from responses package
20
+ # All error models are exported from errors package
21
+ ]
@@ -0,0 +1,35 @@
1
+ from enum import Enum, IntEnum
2
+
3
+
4
+ class KeyType(IntEnum):
5
+ """Supported key types for subnet registration."""
6
+
7
+ RSA = 0
8
+ ED25519 = 1
9
+ SECP256K1 = 2
10
+ ECDSA = 3
11
+
12
+
13
+ class VoteType(str, Enum):
14
+ """Vote types for proposals."""
15
+
16
+ YAY = "Yay"
17
+ NAY = "Nay"
18
+
19
+
20
+ class SubnetState(str, Enum):
21
+ """Subnet state enumeration."""
22
+
23
+ REGISTERED = "Registered"
24
+ ACTIVE = "Active"
25
+ PAUSED = "Paused"
26
+
27
+
28
+ class SubnetNodeClass(str, Enum):
29
+ """Subnet node class enumeration."""
30
+
31
+ REGISTERED = "Registered"
32
+ IDLE = "Idle"
33
+ INCLUDED = "Included"
34
+ VALIDATOR = "Validator"
35
+ DEACTIVATED = "Deactivated"
@@ -0,0 +1,103 @@
1
+ """
2
+ Pydantic models for error structures.
3
+ """
4
+
5
+ from typing import Any, Optional
6
+
7
+ from pydantic import BaseModel, Field
8
+
9
+
10
+ class ErrorResponse(BaseModel):
11
+ """Standard error response model."""
12
+
13
+ success: bool = Field(False, description="Always false for errors")
14
+ error: str = Field(..., description="Error type")
15
+ message: str = Field(..., description="Human-readable error message")
16
+ code: int = Field(..., description="Error code")
17
+ details: Optional[dict[str, Any]] = Field(
18
+ None, description="Optional error details"
19
+ )
20
+ timestamp: str = Field(..., description="ISO timestamp")
21
+
22
+
23
+ class ValidationError(BaseModel):
24
+ """Validation error model."""
25
+
26
+ field: str = Field(..., description="Field name")
27
+ value: Any = Field(..., description="Invalid value")
28
+ constraint: str = Field(..., description="Constraint that was violated")
29
+
30
+
31
+ class NetworkError(BaseModel):
32
+ """Network error model."""
33
+
34
+ endpoint: str = Field(..., description="Failed endpoint")
35
+ status_code: Optional[int] = Field(None, description="HTTP status code")
36
+ timeout: bool = Field(False, description="Whether the error was due to timeout")
37
+
38
+
39
+ class RPCError(BaseModel):
40
+ """RPC error model."""
41
+
42
+ method: str = Field(..., description="RPC method that failed")
43
+ params: Optional[dict[str, Any]] = Field(None, description="RPC parameters")
44
+ error_code: Optional[int] = Field(None, description="RPC error code")
45
+
46
+
47
+ class BusinessLogicError(BaseModel):
48
+ """Business logic error model."""
49
+
50
+ operation: str = Field(..., description="Operation that failed")
51
+ reason: str = Field(..., description="Reason for failure")
52
+ recoverable: bool = Field(True, description="Whether the error is recoverable")
53
+
54
+
55
+ # Error code ranges
56
+ ERROR_CODES = {
57
+ "AuthenticationFailed": (1001, 1999),
58
+ "ValidationError": (2001, 2999),
59
+ "NetworkError": (3001, 3999),
60
+ "RPCError": (4001, 4999),
61
+ "BusinessLogicError": (5001, 5999),
62
+ "SubnetError": (6001, 6999),
63
+ "StakingError": (7001, 7999),
64
+ "ValidationError": (8001, 8999),
65
+ "GovernanceError": (9001, 9999),
66
+ }
67
+
68
+ # Specific error codes
69
+ SPECIFIC_ERROR_CODES = {
70
+ # Subnet errors
71
+ "INVALID_SUBNET_PATH": 1001,
72
+ "INSUFFICIENT_MEMORY": 1002,
73
+ "INVALID_REGISTRATION_PERIOD": 1003,
74
+ "DUPLICATE_SUBNET_PATH": 1004,
75
+ "INSUFFICIENT_BALANCE_FOR_REGISTRATION": 1005,
76
+ "SUBNET_NOT_FOUND": 2001,
77
+ "SUBNET_ALREADY_ACTIVATED": 2002,
78
+ "INSUFFICIENT_NODES_FOR_ACTIVATION": 2003,
79
+ "REGISTRATION_PERIOD_NOT_COMPLETED": 2004,
80
+ # Node errors
81
+ "SUBNET_NOT_ACTIVATED": 4002,
82
+ "NODE_ALREADY_EXISTS": 4003,
83
+ "INVALID_PEER_ID_FORMAT": 4004,
84
+ "INSUFFICIENT_STAKE_FOR_NODE": 4005,
85
+ # Staking errors
86
+ "NODE_NOT_FOUND": 5002,
87
+ "INSUFFICIENT_BALANCE": 5003,
88
+ "INVALID_STAKE_AMOUNT": 5004,
89
+ "STAKE_LIMIT_EXCEEDED": 5005,
90
+ "INSUFFICIENT_STAKE_TO_REMOVE": 6002,
91
+ "STAKE_STILL_IN_UNBONDING_PERIOD": 6003,
92
+ # Validation errors
93
+ "SUBNET_NOT_ACTIVE": 7002,
94
+ "INVALID_VALIDATION_DATA": 7003,
95
+ "VALIDATION_RATE_LIMIT_EXCEEDED": 7004,
96
+ # Governance errors
97
+ "INVALID_PROPOSAL_DATA": 8003,
98
+ "INSUFFICIENT_STAKE_FOR_PROPOSAL": 8004,
99
+ "PROPOSAL_NOT_FOUND": 9001,
100
+ "INVALID_VOTE_TYPE": 9002,
101
+ "ALREADY_VOTED": 9003,
102
+ "VOTING_PERIOD_ENDED": 9004,
103
+ }
@@ -0,0 +1,197 @@
1
+ """
2
+ Request models for HTCLI.
3
+ """
4
+
5
+ # Wallet-related requests
6
+ # Config-related requests
7
+ from .config import (
8
+ ConfigEditRequest,
9
+ ConfigGetRequest,
10
+ ConfigInitRequest,
11
+ ConfigPathRequest,
12
+ ConfigSetRequest,
13
+ ConfigShowRequest,
14
+ ConfigValidateRequest,
15
+ )
16
+
17
+ # Governance-related requests
18
+ from .governance import (
19
+ GovernanceCollectiveRemoveOverwatchNodeRequest,
20
+ GovernanceCollectiveRemoveSubnetNodeRequest,
21
+ GovernanceCollectiveRemoveSubnetRequest,
22
+ GovernanceParameterUpdateRequest,
23
+ GovernancePauseRequest,
24
+ GovernanceUnpauseRequest,
25
+ )
26
+
27
+ # Identity-related requests
28
+ from .identity import (
29
+ IdentityAcceptRequest,
30
+ IdentityRegisterRequest,
31
+ IdentityRemoveRequest,
32
+ )
33
+
34
+ # Key-related requests
35
+ from .key import KeyGenerateRequest, KeyImportRequest
36
+
37
+ # Node-related requests
38
+ from .node import (
39
+ SubnetNodeActivateRequest,
40
+ SubnetNodeBootnodeUpdateRequest,
41
+ SubnetNodePauseRequest,
42
+ SubnetNodePeerIdUpdateRequest,
43
+ SubnetNodeReactivateRequest,
44
+ SubnetNodeRegisterRequest,
45
+ SubnetNodeRemoveRequest,
46
+ SubnetNodeUpdateRequest,
47
+ )
48
+
49
+ # Overwatch-related requests
50
+ from .overwatch import (
51
+ OverwatchNodeAnyoneRemoveRequest,
52
+ OverwatchNodePeerIdUpdateRequest,
53
+ OverwatchNodeRegisterRequest,
54
+ OverwatchNodeRemoveRequest,
55
+ )
56
+
57
+ # Staking-related requests
58
+ from .staking import (
59
+ ClaimUnbondingsRequest,
60
+ DelegateStakeAddRequest,
61
+ DelegateStakeDonateRequest,
62
+ DelegateStakeRemoveRequest,
63
+ DelegateStakeSwapRequest,
64
+ DelegateStakeTransferRequest,
65
+ NodeDelegateStakeAddRequest,
66
+ NodeDelegateStakeDonateRequest,
67
+ NodeDelegateStakeRemoveRequest,
68
+ NodeDelegateStakeSwapRequest,
69
+ NodeDelegateStakeTransferRequest,
70
+ OverwatchStakeAddRequest,
71
+ OverwatchStakeRemoveRequest,
72
+ StakeAddRequest,
73
+ StakeRemoveRequest,
74
+ StakeSwapFromNodeToSubnetRequest,
75
+ StakeSwapFromSubnetToNodeRequest,
76
+ StakeSwapFromSubnetToValidatorRequest,
77
+ StakeSwapFromValidatorToSubnetRequest,
78
+ StakeSwapQueueUpdateRequest,
79
+ ValidatorDelegateStakeAddRequest,
80
+ ValidatorDelegateStakeDonateRequest,
81
+ ValidatorDelegateStakeRemoveRequest,
82
+ ValidatorDelegateStakeSwapRequest,
83
+ ValidatorDelegateStakeTransferRequest,
84
+ )
85
+
86
+ # Subnet-related requests
87
+ from .subnet import (
88
+ SubnetActivateRequest,
89
+ SubnetConfigUpdateRequest,
90
+ SubnetOwnershipAcceptRequest,
91
+ SubnetOwnershipTransferRequest,
92
+ SubnetRegisterRequest,
93
+ SubnetRemoveRequest,
94
+ SubnetUpdateRequest,
95
+ )
96
+
97
+ # Validator-related requests
98
+ from .validator import (
99
+ ValidatorColdkeyUpdateRequest,
100
+ ValidatorDelegateAccountUpdateRequest,
101
+ ValidatorDelegateRewardRateUpdateRequest,
102
+ ValidatorHotkeyUpdateRequest,
103
+ ValidatorIdentityUpdateRequest,
104
+ ValidatorRegisterRequest,
105
+ )
106
+ from .wallet import (
107
+ PreseededWalletRequest,
108
+ WalletBalanceRequest,
109
+ WalletCreateRequest,
110
+ WalletDeleteRequest,
111
+ WalletRestoreRequest,
112
+ WalletTransferRequest,
113
+ WalletUpdateRequest,
114
+ )
115
+
116
+ __all__ = [
117
+ # Wallet requests
118
+ "WalletCreateRequest",
119
+ "WalletRestoreRequest",
120
+ "WalletUpdateRequest",
121
+ "WalletDeleteRequest",
122
+ "WalletTransferRequest",
123
+ "WalletBalanceRequest",
124
+ "PreseededWalletRequest",
125
+ # Staking requests
126
+ "StakeAddRequest",
127
+ "StakeRemoveRequest",
128
+ "ClaimUnbondingsRequest",
129
+ "DelegateStakeAddRequest",
130
+ "DelegateStakeRemoveRequest",
131
+ "DelegateStakeTransferRequest",
132
+ "DelegateStakeSwapRequest",
133
+ "DelegateStakeDonateRequest",
134
+ "ValidatorDelegateStakeAddRequest",
135
+ "ValidatorDelegateStakeRemoveRequest",
136
+ "ValidatorDelegateStakeTransferRequest",
137
+ "ValidatorDelegateStakeSwapRequest",
138
+ "ValidatorDelegateStakeDonateRequest",
139
+ "NodeDelegateStakeAddRequest",
140
+ "NodeDelegateStakeRemoveRequest",
141
+ "NodeDelegateStakeTransferRequest",
142
+ "NodeDelegateStakeSwapRequest",
143
+ "NodeDelegateStakeDonateRequest",
144
+ "StakeSwapFromNodeToSubnetRequest",
145
+ "StakeSwapFromSubnetToNodeRequest",
146
+ "StakeSwapFromValidatorToSubnetRequest",
147
+ "StakeSwapFromSubnetToValidatorRequest",
148
+ "StakeSwapQueueUpdateRequest",
149
+ "OverwatchStakeAddRequest",
150
+ "OverwatchStakeRemoveRequest",
151
+ # Identity requests
152
+ "IdentityRegisterRequest",
153
+ "IdentityAcceptRequest",
154
+ "IdentityRemoveRequest",
155
+ # Governance requests
156
+ "GovernancePauseRequest",
157
+ "GovernanceUnpauseRequest",
158
+ "GovernanceCollectiveRemoveSubnetRequest",
159
+ "GovernanceCollectiveRemoveSubnetNodeRequest",
160
+ "GovernanceCollectiveRemoveOverwatchNodeRequest",
161
+ "GovernanceParameterUpdateRequest",
162
+ # Node requests
163
+ "SubnetNodeRegisterRequest",
164
+ "SubnetNodeActivateRequest",
165
+ "SubnetNodePauseRequest",
166
+ "SubnetNodeReactivateRequest",
167
+ "SubnetNodeRemoveRequest",
168
+ "SubnetNodeUpdateRequest",
169
+ "SubnetNodePeerIdUpdateRequest",
170
+ "SubnetNodeBootnodeUpdateRequest",
171
+ # Subnet requests
172
+ "SubnetRegisterRequest",
173
+ "SubnetActivateRequest",
174
+ "SubnetRemoveRequest",
175
+ "SubnetUpdateRequest",
176
+ "SubnetConfigUpdateRequest",
177
+ "SubnetOwnershipTransferRequest",
178
+ "SubnetOwnershipAcceptRequest",
179
+ # Validator requests
180
+ "ValidatorRegisterRequest",
181
+ "ValidatorDelegateRewardRateUpdateRequest",
182
+ "ValidatorDelegateAccountUpdateRequest",
183
+ "ValidatorHotkeyUpdateRequest",
184
+ "ValidatorColdkeyUpdateRequest",
185
+ "ValidatorIdentityUpdateRequest",
186
+ # Config requests
187
+ "ConfigInitRequest",
188
+ "ConfigShowRequest",
189
+ "ConfigSetRequest",
190
+ "ConfigGetRequest",
191
+ "ConfigValidateRequest",
192
+ "ConfigPathRequest",
193
+ "ConfigEditRequest",
194
+ # Key requests
195
+ "KeyGenerateRequest",
196
+ "KeyImportRequest",
197
+ ]