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
@@ -0,0 +1,524 @@
1
+ """
2
+ Error handling utilities for subnet commands.
3
+ Provides user-friendly error messages for all subnet-related errors.
4
+ """
5
+
6
+ from typing import Optional
7
+
8
+ from ...ui.components import HTCLIPanel
9
+ from ...ui.display import HTCLIConsole
10
+
11
+
12
+ def handle_subnet_error(
13
+ error_msg: str,
14
+ subnet_id: Optional[int] = None,
15
+ operation: str = "operation",
16
+ client=None,
17
+ ) -> bool:
18
+ """
19
+ Handle subnet-related errors with user-friendly messages.
20
+
21
+ Args:
22
+ error_msg: The error message from the blockchain
23
+ subnet_id: The subnet ID (if applicable)
24
+ operation: Description of the operation being performed
25
+ client: Optional client instance for fetching additional info
26
+
27
+ Returns:
28
+ bool: True if error was handled, False otherwise
29
+ """
30
+ console = HTCLIConsole()
31
+ subnet_id_str = f" {subnet_id}" if subnet_id is not None else ""
32
+
33
+ # System-level errors (checked first)
34
+ if "Paused" in error_msg and "Subnet" not in error_msg:
35
+ error_panel = HTCLIPanel(
36
+ f"The network is currently paused.\n\n"
37
+ f"⏸️ All transactions are temporarily disabled on the network.\n\n"
38
+ f"💡 Please wait for the network to resume operations.\n"
39
+ f" Check network status or try again later.",
40
+ title="⏸️ Network Paused",
41
+ border_style="htcli.warning",
42
+ highlight=True,
43
+ )
44
+ error_panel.render(console.console)
45
+ return True
46
+
47
+ elif "BadOrigin" in error_msg or ("invalid" in error_msg.lower() and "signature" in error_msg.lower()):
48
+ error_panel = HTCLIPanel(
49
+ f"Invalid transaction signature.\n\n"
50
+ f"💡 This usually means:\n"
51
+ f" - Your wallet is not properly unlocked\n"
52
+ f" - The signing key doesn't match the account\n"
53
+ f" - There's an issue with your wallet configuration\n\n"
54
+ f" Try: htcli wallet unlock to unlock your wallet\n"
55
+ f" Or check your wallet configuration: htcli wallet list",
56
+ title="❌ Invalid Signature",
57
+ border_style="htcli.error",
58
+ highlight=True,
59
+ )
60
+ error_panel.render(console.console)
61
+ return True
62
+
63
+ elif "TxRateLimitExceeded" in error_msg:
64
+ error_panel = HTCLIPanel(
65
+ f"Transaction rate limit exceeded.\n\n"
66
+ f"⏱️ You've exceeded the maximum number of transactions allowed for your account.\n\n"
67
+ f"💡 Wait a moment before submitting another transaction.\n"
68
+ f" Rate limits help prevent spam and ensure network stability.",
69
+ title="⏳ Rate Limit Exceeded",
70
+ border_style="htcli.warning",
71
+ highlight=True,
72
+ )
73
+ error_panel.render(console.console)
74
+ return True
75
+
76
+ # Common errors that apply to most operations
77
+ elif "NotSubnetOwner" in error_msg:
78
+ error_panel = HTCLIPanel(
79
+ f"Only the subnet owner can perform this {operation} on subnet{subnet_id_str}.\n\n"
80
+ f"💡 Make sure you're using the coldkey wallet that owns this subnet.\n"
81
+ f" Use: htcli subnet info --subnet-id{subnet_id_str} to check the owner",
82
+ title="❌ Permission Denied",
83
+ border_style="htcli.error",
84
+ highlight=True,
85
+ )
86
+ error_panel.render(console.console)
87
+ return True
88
+
89
+ elif "InvalidSubnetId" in error_msg:
90
+ error_panel = HTCLIPanel(
91
+ f"Subnet{subnet_id_str} does not exist.\n\n"
92
+ f"💡 Check the subnet ID and try again.\n"
93
+ f" Use: htcli subnet list to see available subnets",
94
+ title="❌ Invalid Subnet ID",
95
+ border_style="htcli.error",
96
+ highlight=True,
97
+ )
98
+ error_panel.render(console.console)
99
+ return True
100
+
101
+ # Pause-specific errors
102
+ elif "SubnetMustBeActive" in error_msg:
103
+ error_panel = HTCLIPanel(
104
+ f"Subnet{subnet_id_str} must be active to pause it.\n\n"
105
+ f"💡 Only active subnets can be paused.\n"
106
+ f" Use: htcli subnet info --subnet-id{subnet_id_str} to check subnet status",
107
+ title="⚠️ Subnet Not Active",
108
+ border_style="htcli.warning",
109
+ highlight=True,
110
+ )
111
+ error_panel.render(console.console)
112
+ return True
113
+
114
+ elif "SubnetPauseCooldownActive" in error_msg:
115
+ error_panel = HTCLIPanel(
116
+ f"Subnet{subnet_id_str} cannot be paused yet due to cooldown period.\n\n"
117
+ f"⏱️ Subnets have a cooldown period after unpausing before they can be paused again.\n\n"
118
+ f"💡 Wait for the cooldown period to expire and try again.",
119
+ title="⏳ Pause Cooldown Active",
120
+ border_style="htcli.warning",
121
+ highlight=True,
122
+ )
123
+ error_panel.render(console.console)
124
+ return True
125
+
126
+ # Unpause-specific errors
127
+ elif "SubnetMustBePaused" in error_msg:
128
+ error_panel = HTCLIPanel(
129
+ f"Subnet{subnet_id_str} must be paused to {operation}.\n\n"
130
+ f"💡 This action requires the subnet to be in a Paused state.\n"
131
+ f" Use: htcli subnet pause --subnet-id{subnet_id_str} to pause it first",
132
+ title="⚠️ Subnet Not Paused",
133
+ border_style="htcli.warning",
134
+ highlight=True,
135
+ )
136
+ error_panel.render(console.console)
137
+ return True
138
+
139
+ # Update name/repo errors
140
+ elif "SubnetNameExist" in error_msg:
141
+ error_panel = HTCLIPanel(
142
+ f"This subnet name is already taken by another subnet.\n\n"
143
+ f"💡 Subnet names must be unique across the network.\n"
144
+ f" Choose a different name and try again.",
145
+ title="❌ Name Already Exists",
146
+ border_style="htcli.error",
147
+ highlight=True,
148
+ )
149
+ error_panel.render(console.console)
150
+ return True
151
+
152
+ elif "SubnetRepoExist" in error_msg:
153
+ error_panel = HTCLIPanel(
154
+ f"This repository URL is already registered to another subnet.\n\n"
155
+ f"💡 Repository URLs must be unique across the network.\n"
156
+ f" Use a different repository URL and try again.",
157
+ title="❌ Repository Already Exists",
158
+ border_style="htcli.error",
159
+ highlight=True,
160
+ )
161
+ error_panel.render(console.console)
162
+ return True
163
+
164
+ # Transfer ownership errors
165
+ elif "NoPendingSubnetOwner" in error_msg:
166
+ error_panel = HTCLIPanel(
167
+ f"No pending ownership transfer exists for subnet{subnet_id_str}.\n\n"
168
+ f"💡 Ownership transfer is a 2-step process:\n"
169
+ f" 1. Current owner initiates transfer: htcli subnet transfer --subnet-id{subnet_id_str} --new-owner <address>\n"
170
+ f" 2. New owner accepts: htcli subnet accept --subnet-id{subnet_id_str}\n\n"
171
+ f" Make sure step 1 was completed first.",
172
+ title="❌ No Pending Transfer",
173
+ border_style="htcli.error",
174
+ highlight=True,
175
+ )
176
+ error_panel.render(console.console)
177
+ return True
178
+
179
+ elif "NotPendingSubnetOwner" in error_msg:
180
+ error_panel = HTCLIPanel(
181
+ f"You are not the pending owner for subnet{subnet_id_str}.\n\n"
182
+ f"💡 Only the address specified in the ownership transfer can accept it.\n"
183
+ f" Make sure you're using the correct coldkey wallet.",
184
+ title="❌ Not Pending Owner",
185
+ border_style="htcli.error",
186
+ highlight=True,
187
+ )
188
+ error_panel.render(console.console)
189
+ return True
190
+
191
+ # Configuration update errors
192
+ elif "InvalidChurnLimit" in error_msg:
193
+ error_panel = HTCLIPanel(
194
+ f"Invalid churn limit value.\n\n"
195
+ f"💡 Churn limit must be within the allowed range (MinChurnLimit to MaxChurnLimit).\n"
196
+ f" Check the network parameters for valid values.",
197
+ title="❌ Invalid Churn Limit",
198
+ border_style="htcli.error",
199
+ highlight=True,
200
+ )
201
+ error_panel.render(console.console)
202
+ return True
203
+
204
+ elif "InvalidRegistrationQueueEpochs" in error_msg:
205
+ error_panel = HTCLIPanel(
206
+ f"Invalid registration queue epochs value.\n\n"
207
+ f"💡 Registration queue epochs must be within the allowed range.\n"
208
+ f" Check the network parameters for valid values.",
209
+ title="❌ Invalid Queue Epochs",
210
+ border_style="htcli.error",
211
+ highlight=True,
212
+ )
213
+ error_panel.render(console.console)
214
+ return True
215
+
216
+ elif "InvalidIdleClassificationEpochs" in error_msg:
217
+ error_panel = HTCLIPanel(
218
+ f"Invalid idle classification epochs value.\n\n"
219
+ f"💡 Idle classification epochs must be within the allowed range.\n"
220
+ f" Check the network parameters for valid values.",
221
+ title="❌ Invalid Idle Epochs",
222
+ border_style="htcli.error",
223
+ highlight=True,
224
+ )
225
+ error_panel.render(console.console)
226
+ return True
227
+
228
+ elif "InvalidIncludedClassificationEpochs" in error_msg:
229
+ error_panel = HTCLIPanel(
230
+ f"Invalid included classification epochs value.\n\n"
231
+ f"💡 Included classification epochs must be within the allowed range.\n"
232
+ f" Check the network parameters for valid values.",
233
+ title="❌ Invalid Included Epochs",
234
+ border_style="htcli.error",
235
+ highlight=True,
236
+ )
237
+ error_panel.render(console.console)
238
+ return True
239
+
240
+ elif "InvalidMaxRegisteredNodes" in error_msg:
241
+ error_panel = HTCLIPanel(
242
+ f"Invalid max registered nodes value.\n\n"
243
+ f"💡 Max registered nodes must be between 1 and 64.\n"
244
+ f" The blockchain enforces a maximum of 64 nodes.",
245
+ title="❌ Invalid Max Nodes",
246
+ border_style="htcli.error",
247
+ highlight=True,
248
+ )
249
+ error_panel.render(console.console)
250
+ return True
251
+
252
+ elif "InvalidMaxSubnetNodePenalties" in error_msg:
253
+ error_panel = HTCLIPanel(
254
+ f"Invalid max node penalties value.\n\n"
255
+ f"💡 Max node penalties must be within the allowed range.\n"
256
+ f" Check MinMaxSubnetNodePenalties and MaxMaxSubnetNodePenalties parameters.",
257
+ title="❌ Invalid Max Penalties",
258
+ border_style="htcli.error",
259
+ highlight=True,
260
+ )
261
+ error_panel.render(console.console)
262
+ return True
263
+
264
+ elif "InvalidSubnetMinStake" in error_msg:
265
+ error_panel = HTCLIPanel(
266
+ f"Invalid minimum stake value.\n\n"
267
+ f"💡 Minimum stake must be between 100-250 TENSOR.\n"
268
+ f" Check the network parameters for valid values.",
269
+ title="❌ Invalid Min Stake",
270
+ border_style="htcli.error",
271
+ highlight=True,
272
+ )
273
+ error_panel.render(console.console)
274
+ return True
275
+
276
+ elif "InvalidSubnetMaxStake" in error_msg:
277
+ error_panel = HTCLIPanel(
278
+ f"Invalid maximum stake value.\n\n"
279
+ f"💡 Maximum stake must be ≤ 1000 TENSOR (NetworkMaxStakeBalance).\n"
280
+ f" Use a lower value and try again.",
281
+ title="❌ Invalid Max Stake",
282
+ border_style="htcli.error",
283
+ highlight=True,
284
+ )
285
+ error_panel.render(console.console)
286
+ return True
287
+
288
+ elif "InvalidSubnetStakeParameters" in error_msg:
289
+ error_panel = HTCLIPanel(
290
+ f"Invalid stake parameters.\n\n"
291
+ f"💡 Minimum stake must be less than or equal to maximum stake.\n"
292
+ f" Adjust your stake parameters to satisfy: min_stake ≤ max_stake",
293
+ title="❌ Invalid Stake Parameters",
294
+ border_style="htcli.error",
295
+ highlight=True,
296
+ )
297
+ error_panel.render(console.console)
298
+ return True
299
+
300
+ elif (
301
+ "InvalidDelegateStakePercentage" in error_msg
302
+ or "InvalidMinDelegateStakePercentage" in error_msg
303
+ ):
304
+ error_panel = HTCLIPanel(
305
+ f"Invalid delegate stake percentage.\n\n"
306
+ f"💡 Delegate stake percentage must be between 5% and 95%.\n"
307
+ f" Use a value in this range (e.g., 20 for 20%).",
308
+ title="❌ Invalid Delegate Percentage",
309
+ border_style="htcli.error",
310
+ highlight=True,
311
+ )
312
+ error_panel.render(console.console)
313
+ return True
314
+
315
+ elif "DelegateStakePercentageUpdateTooSoon" in error_msg:
316
+ error_panel = HTCLIPanel(
317
+ f"Cannot update delegate stake percentage yet.\n\n"
318
+ f"⏱️ There is a cooldown period between delegate stake percentage updates.\n\n"
319
+ f"💡 Wait for the cooldown period to expire and try again.",
320
+ title="⏳ Update Cooldown Active",
321
+ border_style="htcli.warning",
322
+ highlight=True,
323
+ )
324
+ error_panel.render(console.console)
325
+ return True
326
+
327
+ elif "DelegateStakePercentageAbsDiffTooLarge" in error_msg:
328
+ error_panel = HTCLIPanel(
329
+ f"Delegate stake percentage change is too large.\n\n"
330
+ f"💡 The change between current and new percentage exceeds the maximum allowed.\n"
331
+ f" Make smaller incremental changes instead.",
332
+ title="❌ Change Too Large",
333
+ border_style="htcli.error",
334
+ highlight=True,
335
+ )
336
+ error_panel.render(console.console)
337
+ return True
338
+
339
+ # Network pause errors
340
+ elif "SubnetIsPaused" in error_msg:
341
+ error_panel = HTCLIPanel(
342
+ f"Subnet{subnet_id_str} is paused and cannot perform this action.\n\n"
343
+ f"💡 The subnet must be unpaused first.\n"
344
+ f" Use: htcli subnet unpause --subnet-id{subnet_id_str}",
345
+ title="⏸️ Subnet Paused",
346
+ border_style="htcli.warning",
347
+ highlight=True,
348
+ )
349
+ error_panel.render(console.console)
350
+ return True
351
+
352
+ # Registration errors
353
+ elif "MaxSubnets" in error_msg:
354
+ error_panel = HTCLIPanel(
355
+ f"The network has reached maximum subnet capacity.\n\n"
356
+ f"💡 The network can only support a limited number of subnets.\n"
357
+ f" Wait for a subnet slot to become available or check if any subnets can be removed.",
358
+ title="❌ Network at Capacity",
359
+ border_style="htcli.error",
360
+ highlight=True,
361
+ )
362
+ error_panel.render(console.console)
363
+ return True
364
+
365
+ elif "BootnodesEmpty" in error_msg:
366
+ error_panel = HTCLIPanel(
367
+ f"No bootnodes provided for subnet registration.\n\n"
368
+ f"💡 At least one bootnode is required for subnet registration.\n"
369
+ f" Bootnodes are P2P network entry points for subnet nodes.\n"
370
+ f" Provide at least one valid bootnode multiaddr and try again.",
371
+ title="❌ Bootnodes Required",
372
+ border_style="htcli.error",
373
+ highlight=True,
374
+ )
375
+ error_panel.render(console.console)
376
+ return True
377
+
378
+ elif "TooManyBootnodes" in error_msg:
379
+ error_panel = HTCLIPanel(
380
+ f"Too many bootnodes provided.\n\n"
381
+ f"💡 The number of bootnodes exceeds the maximum allowed (MaxBootnodes).\n"
382
+ f" Reduce the number of bootnodes and try again.",
383
+ title="❌ Too Many Bootnodes",
384
+ border_style="htcli.error",
385
+ highlight=True,
386
+ )
387
+ error_panel.render(console.console)
388
+ return True
389
+
390
+ elif "CostGreaterThanMaxCost" in error_msg:
391
+ error_panel = HTCLIPanel(
392
+ f"Registration cost exceeds your maximum cost limit.\n\n"
393
+ f"💡 The current registration cost is higher than the max_cost you specified.\n"
394
+ f" This protects you from unexpected cost increases.\n"
395
+ f" Increase your max_cost parameter or wait for costs to decrease.",
396
+ title="❌ Cost Exceeds Maximum",
397
+ border_style="htcli.error",
398
+ highlight=True,
399
+ )
400
+ error_panel.render(console.console)
401
+ return True
402
+
403
+ elif "NotEnoughBalanceToRegisterSubnet" in error_msg:
404
+ error_panel = HTCLIPanel(
405
+ f"Insufficient balance to register subnet.\n\n"
406
+ f"💡 You don't have enough balance to cover the registration cost.\n"
407
+ f" Ensure your wallet has sufficient funds and try again.\n"
408
+ f" Check your balance: htcli wallet balance",
409
+ title="❌ Insufficient Balance",
410
+ border_style="htcli.error",
411
+ highlight=True,
412
+ )
413
+ error_panel.render(console.console)
414
+ return True
415
+
416
+ elif "NoAvailableSlots" in error_msg:
417
+ error_panel = HTCLIPanel(
418
+ f"No epoch slots available for subnet registration.\n\n"
419
+ f"💡 The network has no available epoch slots for new subnet assignments.\n"
420
+ f" Wait for a slot to become available and try again.",
421
+ title="❌ No Available Slots",
422
+ border_style="htcli.error",
423
+ highlight=True,
424
+ )
425
+ error_panel.render(console.console)
426
+ return True
427
+
428
+ elif "MustUnstakeToRegister" in error_msg:
429
+ error_panel = HTCLIPanel(
430
+ f"You must unstake before registering a subnet.\n\n"
431
+ f"💡 You have existing stake that must be unstaked before registering a new subnet.\n"
432
+ f" Unstake your existing stake first, then try registering again.\n"
433
+ f" Use: htcli stake unstake to remove your stake",
434
+ title="❌ Must Unstake First",
435
+ border_style="htcli.error",
436
+ highlight=True,
437
+ )
438
+ error_panel.render(console.console)
439
+ return True
440
+
441
+ elif "ColdkeyRegistrationWhitelist" in error_msg:
442
+ error_panel = HTCLIPanel(
443
+ f"Your coldkey is not whitelisted for subnet registration.\n\n"
444
+ f"💡 Subnet registration requires whitelisting when enabled.\n"
445
+ f" Contact network administrators to get your coldkey whitelisted.",
446
+ title="❌ Not Whitelisted",
447
+ border_style="htcli.error",
448
+ highlight=True,
449
+ )
450
+ error_panel.render(console.console)
451
+ return True
452
+
453
+ elif "InvalidSubnetRegistrationInitialColdkeys" in error_msg:
454
+ error_panel = HTCLIPanel(
455
+ f"Invalid initial coldkeys configuration.\n\n"
456
+ f"💡 The initial coldkeys must meet minimum requirements:\n"
457
+ f" - Each coldkey must have at least 1 registration slot\n"
458
+ f" - Total number of coldkeys must be >= MinSubnetNodes\n"
459
+ f" Check your initial_coldkeys configuration and try again.",
460
+ title="❌ Invalid Initial Coldkeys",
461
+ border_style="htcli.error",
462
+ highlight=True,
463
+ )
464
+ error_panel.render(console.console)
465
+ return True
466
+
467
+ elif "CouldNotConvertToBalance" in error_msg:
468
+ error_panel = HTCLIPanel(
469
+ f"Balance conversion failed.\n\n"
470
+ f"💡 Failed to convert u128 value to BalanceOf type.\n"
471
+ f" This usually indicates an overflow or invalid value.\n"
472
+ f" Check your input values and try again.",
473
+ title="❌ Conversion Error",
474
+ border_style="htcli.error",
475
+ highlight=True,
476
+ )
477
+ error_panel.render(console.console)
478
+ return True
479
+
480
+ # Activation errors
481
+ elif "SubnetActivatedAlready" in error_msg:
482
+ error_panel = HTCLIPanel(
483
+ f"Subnet{subnet_id_str} is already activated.\n\n"
484
+ f"💡 This subnet is already in Active or Paused state.\n"
485
+ f" Only subnets in Registered state can be activated.\n"
486
+ f" Check subnet status: htcli subnet info --subnet-id{subnet_id_str}",
487
+ title="⚠️ Already Activated",
488
+ border_style="htcli.warning",
489
+ highlight=True,
490
+ )
491
+ error_panel.render(console.console)
492
+ return True
493
+
494
+ elif "MinSubnetRegistrationEpochsNotMet" in error_msg:
495
+ error_panel = HTCLIPanel(
496
+ f"Too early to activate subnet{subnet_id_str}.\n\n"
497
+ f"⏱️ The minimum registration epochs requirement has not been met yet.\n\n"
498
+ f"💡 Subnets must wait for MinSubnetRegistrationEpochs after registration\n"
499
+ f" before they can attempt activation.\n"
500
+ f" Wait for the minimum period to pass and try again.",
501
+ title="⏳ Too Early to Activate",
502
+ border_style="htcli.warning",
503
+ highlight=True,
504
+ )
505
+ error_panel.render(console.console)
506
+ return True
507
+
508
+ elif "SubnetActivationConditionsNotMetYet" in error_msg:
509
+ error_panel = HTCLIPanel(
510
+ f"Subnet{subnet_id_str} activation conditions not met yet.\n\n"
511
+ f"💡 The subnet is still in the registration period but doesn't meet activation requirements:\n"
512
+ f" - Minimum active nodes (MinSubnetNodes)\n"
513
+ f" - Minimum delegate stake balance\n"
514
+ f" - Minimum subnet reputation\n\n"
515
+ f" You can retry activation once these conditions are met.\n"
516
+ f" Add more nodes or delegate stake and try again.",
517
+ title="⚠️ Activation Conditions Not Met",
518
+ border_style="htcli.warning",
519
+ highlight=True,
520
+ )
521
+ error_panel.render(console.console)
522
+ return True
523
+
524
+ return False # Error not handled by this function