meshtensor-cli 9.18.1__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 (74) hide show
  1. meshtensor_cli/__init__.py +22 -0
  2. meshtensor_cli/cli.py +10742 -0
  3. meshtensor_cli/doc_generation_helper.py +4 -0
  4. meshtensor_cli/src/__init__.py +1085 -0
  5. meshtensor_cli/src/commands/__init__.py +0 -0
  6. meshtensor_cli/src/commands/axon/__init__.py +0 -0
  7. meshtensor_cli/src/commands/axon/axon.py +132 -0
  8. meshtensor_cli/src/commands/crowd/__init__.py +0 -0
  9. meshtensor_cli/src/commands/crowd/contribute.py +621 -0
  10. meshtensor_cli/src/commands/crowd/contributors.py +200 -0
  11. meshtensor_cli/src/commands/crowd/create.py +783 -0
  12. meshtensor_cli/src/commands/crowd/dissolve.py +219 -0
  13. meshtensor_cli/src/commands/crowd/refund.py +233 -0
  14. meshtensor_cli/src/commands/crowd/update.py +418 -0
  15. meshtensor_cli/src/commands/crowd/utils.py +124 -0
  16. meshtensor_cli/src/commands/crowd/view.py +991 -0
  17. meshtensor_cli/src/commands/governance/__init__.py +0 -0
  18. meshtensor_cli/src/commands/governance/governance.py +794 -0
  19. meshtensor_cli/src/commands/liquidity/__init__.py +0 -0
  20. meshtensor_cli/src/commands/liquidity/liquidity.py +699 -0
  21. meshtensor_cli/src/commands/liquidity/utils.py +202 -0
  22. meshtensor_cli/src/commands/proxy.py +700 -0
  23. meshtensor_cli/src/commands/stake/__init__.py +0 -0
  24. meshtensor_cli/src/commands/stake/add.py +799 -0
  25. meshtensor_cli/src/commands/stake/auto_staking.py +306 -0
  26. meshtensor_cli/src/commands/stake/children_hotkeys.py +865 -0
  27. meshtensor_cli/src/commands/stake/claim.py +770 -0
  28. meshtensor_cli/src/commands/stake/list.py +738 -0
  29. meshtensor_cli/src/commands/stake/move.py +1211 -0
  30. meshtensor_cli/src/commands/stake/remove.py +1466 -0
  31. meshtensor_cli/src/commands/stake/wizard.py +323 -0
  32. meshtensor_cli/src/commands/subnets/__init__.py +0 -0
  33. meshtensor_cli/src/commands/subnets/mechanisms.py +515 -0
  34. meshtensor_cli/src/commands/subnets/price.py +733 -0
  35. meshtensor_cli/src/commands/subnets/subnets.py +2908 -0
  36. meshtensor_cli/src/commands/sudo.py +1294 -0
  37. meshtensor_cli/src/commands/tc/__init__.py +0 -0
  38. meshtensor_cli/src/commands/tc/tc.py +190 -0
  39. meshtensor_cli/src/commands/treasury/__init__.py +0 -0
  40. meshtensor_cli/src/commands/treasury/treasury.py +194 -0
  41. meshtensor_cli/src/commands/view.py +354 -0
  42. meshtensor_cli/src/commands/wallets.py +2311 -0
  43. meshtensor_cli/src/commands/weights.py +467 -0
  44. meshtensor_cli/src/meshtensor/__init__.py +0 -0
  45. meshtensor_cli/src/meshtensor/balances.py +313 -0
  46. meshtensor_cli/src/meshtensor/chain_data.py +1263 -0
  47. meshtensor_cli/src/meshtensor/extrinsics/__init__.py +0 -0
  48. meshtensor_cli/src/meshtensor/extrinsics/mev_shield.py +174 -0
  49. meshtensor_cli/src/meshtensor/extrinsics/registration.py +1861 -0
  50. meshtensor_cli/src/meshtensor/extrinsics/root.py +550 -0
  51. meshtensor_cli/src/meshtensor/extrinsics/serving.py +255 -0
  52. meshtensor_cli/src/meshtensor/extrinsics/transfer.py +239 -0
  53. meshtensor_cli/src/meshtensor/meshtensor_interface.py +2598 -0
  54. meshtensor_cli/src/meshtensor/minigraph.py +254 -0
  55. meshtensor_cli/src/meshtensor/networking.py +12 -0
  56. meshtensor_cli/src/meshtensor/templates/main-filters.j2 +24 -0
  57. meshtensor_cli/src/meshtensor/templates/main-header.j2 +36 -0
  58. meshtensor_cli/src/meshtensor/templates/neuron-details.j2 +111 -0
  59. meshtensor_cli/src/meshtensor/templates/price-multi.j2 +113 -0
  60. meshtensor_cli/src/meshtensor/templates/price-single.j2 +99 -0
  61. meshtensor_cli/src/meshtensor/templates/subnet-details-header.j2 +49 -0
  62. meshtensor_cli/src/meshtensor/templates/subnet-details.j2 +32 -0
  63. meshtensor_cli/src/meshtensor/templates/subnet-metrics.j2 +57 -0
  64. meshtensor_cli/src/meshtensor/templates/subnets-table.j2 +28 -0
  65. meshtensor_cli/src/meshtensor/templates/table.j2 +267 -0
  66. meshtensor_cli/src/meshtensor/templates/view.css +1058 -0
  67. meshtensor_cli/src/meshtensor/templates/view.j2 +43 -0
  68. meshtensor_cli/src/meshtensor/templates/view.js +1053 -0
  69. meshtensor_cli/src/meshtensor/utils.py +2007 -0
  70. meshtensor_cli/version.py +23 -0
  71. meshtensor_cli-9.18.1.dist-info/METADATA +261 -0
  72. meshtensor_cli-9.18.1.dist-info/RECORD +74 -0
  73. meshtensor_cli-9.18.1.dist-info/WHEEL +4 -0
  74. meshtensor_cli-9.18.1.dist-info/entry_points.txt +3 -0
@@ -0,0 +1,323 @@
1
+ """
2
+ Wizard command for guiding users through stake movement operations.
3
+
4
+ This module provides an interactive wizard that helps users understand and select
5
+ the appropriate stake movement command (move, transfer, or swap) based on their needs.
6
+ """
7
+
8
+ import asyncio
9
+ from typing import TYPE_CHECKING, Optional
10
+
11
+ from meshtensor_wallet import Wallet
12
+ from rich.prompt import Prompt
13
+ from rich.table import Table
14
+ from rich.panel import Panel
15
+
16
+ from meshtensor_cli.src import COLOR_PALETTE
17
+ from meshtensor_cli.src.meshtensor.utils import (
18
+ console,
19
+ print_error,
20
+ is_valid_ss58_address,
21
+ get_hotkey_pub_ss58,
22
+ group_subnets,
23
+ get_hotkey_wallets_for_wallet,
24
+ )
25
+ from meshtensor_cli.src.commands.stake.move import (
26
+ stake_move_transfer_selection,
27
+ stake_swap_selection,
28
+ )
29
+
30
+ if TYPE_CHECKING:
31
+ from meshtensor_cli.src.meshtensor.meshtensor_interface import MeshtensorInterface
32
+
33
+
34
+ async def stake_movement_wizard(
35
+ meshtensor: "MeshtensorInterface",
36
+ wallet: Wallet,
37
+ ) -> Optional[dict]:
38
+ """
39
+ Interactive wizard that guides users through stake movement operations.
40
+
41
+ This wizard helps users understand the differences between:
42
+ - move: Move stake between hotkeys (same coldkey)
43
+ - transfer: Transfer stake between coldkeys (same hotkey)
44
+ - swap: Swap stake between subnets (same coldkey-hotkey pair)
45
+
46
+ Args:
47
+ meshtensor: MeshtensorInterface object
48
+ wallet: Wallet object
49
+
50
+ Returns:
51
+ dict: Contains the operation type and parameters needed to execute the operation
52
+ """
53
+
54
+ # Display welcome message and explanation
55
+ console.print("\n")
56
+ console.print(
57
+ Panel(
58
+ "[bold cyan]Stake Movement Wizard[/bold cyan]\n\n"
59
+ "This wizard will help you choose the right stake movement operation.\n"
60
+ "There are three types of stake movements:\n\n"
61
+ "[bold]1. Move[/bold] - Move stake between [blue]hotkeys[/blue] while keeping the same [blue]coldkey[/blue]\n"
62
+ " Example: Moving stake from hotkey A to hotkey B (both owned by your coldkey)\n\n"
63
+ "[bold]2. Transfer[/bold] - Transfer stake between [blue]coldkeys[/blue] while keeping the same [blue]hotkey[/blue]\n"
64
+ " Example: Transferring stake ownership from your coldkey to another coldkey (same hotkey)\n\n"
65
+ "[bold]3. Swap[/bold] - Swap stake between [blue]subnets[/blue] while keeping the same [blue]coldkey-hotkey pair[/blue]\n"
66
+ " Example: Moving stake from subnet 1 to subnet 2 (same wallet and hotkey)\n",
67
+ title="Welcome",
68
+ border_style="cyan",
69
+ )
70
+ )
71
+
72
+ # Ask user what they want to do
73
+ operation_choice = Prompt.ask(
74
+ "\n[bold]What would you like to do?[/bold]",
75
+ choices=["1", "2", "3", "move", "transfer", "swap", "q"],
76
+ default="q",
77
+ )
78
+
79
+ if operation_choice.lower() == "q":
80
+ console.print("[yellow]Wizard cancelled.[/yellow]")
81
+ return None
82
+
83
+ # Normalize choice
84
+ if operation_choice in ["1", "move"]:
85
+ operation = "move"
86
+ operation_name = "Move"
87
+ description = "Move stake between hotkeys (same coldkey)"
88
+ elif operation_choice in ["2", "transfer"]:
89
+ operation = "transfer"
90
+ operation_name = "Transfer"
91
+ description = "Transfer stake between coldkeys (same hotkey)"
92
+ elif operation_choice in ["3", "swap"]:
93
+ operation = "swap"
94
+ operation_name = "Swap"
95
+ description = "Swap stake between subnets (same coldkey-hotkey pair)"
96
+ else:
97
+ print_error("Invalid choice")
98
+ return None
99
+
100
+ console.print(f"\n[bold green]Selected: {operation_name}[/bold green]")
101
+ console.print(f"[dim]{description}[/dim]\n")
102
+
103
+ # Get stakes for the wallet
104
+ with console.status("Retrieving stake information..."):
105
+ stakes, ck_hk_identities, old_identities = await asyncio.gather(
106
+ meshtensor.get_stake_for_coldkey(
107
+ coldkey_ss58=wallet.coldkeypub.ss58_address
108
+ ),
109
+ meshtensor.fetch_coldkey_hotkey_identities(),
110
+ meshtensor.get_delegate_identities(),
111
+ )
112
+
113
+ # Filter stakes with actual amounts
114
+ available_stakes = [s for s in stakes if s.stake.tao > 0]
115
+
116
+ if not available_stakes:
117
+ print_error("You have no stakes available to move.")
118
+ return None
119
+
120
+ # Display available stakes
121
+ _display_available_stakes(available_stakes, ck_hk_identities, old_identities)
122
+
123
+ # Guide user through the specific operation
124
+ if operation == "move":
125
+ return await _guide_move_operation(
126
+ meshtensor, wallet, available_stakes, ck_hk_identities, old_identities
127
+ )
128
+ elif operation == "transfer":
129
+ return await _guide_transfer_operation(
130
+ meshtensor, wallet, available_stakes, ck_hk_identities, old_identities
131
+ )
132
+ elif operation == "swap":
133
+ return await _guide_swap_operation(meshtensor, wallet, available_stakes)
134
+ else:
135
+ raise ValueError(f"Unknown operation: {operation}")
136
+
137
+
138
+ def _display_available_stakes(
139
+ stakes: list,
140
+ ck_hk_identities: dict,
141
+ old_identities: dict,
142
+ ):
143
+ """Display a table of available stakes."""
144
+ # Group stakes by hotkey
145
+ hotkey_stakes = {}
146
+ for stake in stakes:
147
+ hotkey = stake.hotkey_ss58
148
+ if hotkey not in hotkey_stakes:
149
+ hotkey_stakes[hotkey] = {}
150
+ hotkey_stakes[hotkey][stake.netuid] = stake.stake
151
+
152
+ # Get identities
153
+ def get_identity(hotkey_ss58_: str) -> str:
154
+ if hk_identity := ck_hk_identities["hotkeys"].get(hotkey_ss58_):
155
+ return hk_identity.get("identity", {}).get("name", "") or hk_identity.get(
156
+ "display", "~"
157
+ )
158
+ elif old_identity := old_identities.get(hotkey_ss58_):
159
+ return old_identity.display
160
+ return "~"
161
+
162
+ table = Table(
163
+ title=f"\n[{COLOR_PALETTE['GENERAL']['HEADER']}]Your Available Stakes[/{COLOR_PALETTE['GENERAL']['HEADER']}]\n",
164
+ show_edge=False,
165
+ header_style="bold white",
166
+ border_style="bright_black",
167
+ title_justify="center",
168
+ )
169
+
170
+ table.add_column("Hotkey Identity", style=COLOR_PALETTE["GENERAL"]["SUBHEADING"])
171
+ table.add_column("Hotkey Address", style=COLOR_PALETTE["GENERAL"]["HOTKEY"])
172
+ table.add_column("Netuids", style=COLOR_PALETTE["GENERAL"]["NETUID"])
173
+ table.add_column("Total Stake", style=COLOR_PALETTE["STAKE"]["STAKE_AMOUNT"])
174
+
175
+ for hotkey_ss58, netuid_stakes in hotkey_stakes.items():
176
+ identity = get_identity(hotkey_ss58)
177
+ netuids = sorted(netuid_stakes.keys())
178
+ total_stake = sum(
179
+ netuid_stakes.values(), start=stakes[0].stake.__class__.from_tao(0)
180
+ )
181
+
182
+ table.add_row(
183
+ identity,
184
+ f"{hotkey_ss58[:8]}...{hotkey_ss58[-8:]}",
185
+ group_subnets(netuids),
186
+ str(total_stake),
187
+ )
188
+
189
+ console.print(table)
190
+
191
+
192
+ async def _guide_move_operation(
193
+ meshtensor: "MeshtensorInterface",
194
+ wallet: Wallet,
195
+ available_stakes: list,
196
+ ck_hk_identities: dict,
197
+ old_identities: dict,
198
+ ) -> dict:
199
+ """Guide user through move operation."""
200
+ console.print(
201
+ "\n[bold cyan]Move Operation[/bold cyan]\n"
202
+ "You will move stake from one hotkey to another hotkey.\n"
203
+ "Both hotkeys must be owned by the same coldkey (your wallet).\n"
204
+ )
205
+
206
+ try:
207
+ selection = await stake_move_transfer_selection(meshtensor, wallet)
208
+
209
+ # Get available hotkeys for destination
210
+ all_hotkeys = get_hotkey_wallets_for_wallet(wallet=wallet)
211
+ available_hotkeys = [
212
+ (hk.hotkey_str, get_hotkey_pub_ss58(hk)) for hk in all_hotkeys
213
+ ]
214
+
215
+ # Ask for destination hotkey
216
+ console.print("\n[bold]Destination Hotkey[/bold]")
217
+ if available_hotkeys:
218
+ console.print("\nAvailable hotkeys in your wallet:")
219
+ for idx, (name, ss58) in enumerate(available_hotkeys):
220
+ console.print(f" {idx}: {name} ({ss58[:8]}...{ss58[-8:]})")
221
+
222
+ dest_choice = Prompt.ask(
223
+ "\nEnter the [blue]index[/blue] of the destination hotkey, or [blue]SS58 address[/blue]",
224
+ )
225
+
226
+ try:
227
+ dest_idx = int(dest_choice)
228
+ if 0 <= dest_idx < len(available_hotkeys):
229
+ dest_hotkey = available_hotkeys[dest_idx][1]
230
+ else:
231
+ raise ValueError("Invalid index")
232
+ except ValueError:
233
+ # Assume it's an SS58 address
234
+ if is_valid_ss58_address(dest_choice):
235
+ dest_hotkey = dest_choice
236
+ else:
237
+ print_error(
238
+ "Invalid hotkey selection. Please provide a valid index or SS58 address."
239
+ )
240
+ raise ValueError("Invalid destination hotkey")
241
+ else:
242
+ dest_hotkey = Prompt.ask(
243
+ "Enter the [blue]destination hotkey[/blue] SS58 address"
244
+ )
245
+ if not is_valid_ss58_address(dest_hotkey):
246
+ print_error("Invalid SS58 address")
247
+ raise ValueError("Invalid destination hotkey")
248
+
249
+ return {
250
+ "operation": "move",
251
+ "origin_hotkey": selection["origin_hotkey"],
252
+ "origin_netuid": selection["origin_netuid"],
253
+ "destination_netuid": selection["destination_netuid"],
254
+ "destination_hotkey": dest_hotkey,
255
+ "amount": selection["amount"],
256
+ "stake_all": selection["stake_all"],
257
+ }
258
+ except ValueError:
259
+ raise
260
+
261
+
262
+ async def _guide_transfer_operation(
263
+ meshtensor: "MeshtensorInterface",
264
+ wallet: Wallet,
265
+ available_stakes: list,
266
+ ck_hk_identities: dict,
267
+ old_identities: dict,
268
+ ) -> dict:
269
+ """Guide user through transfer operation."""
270
+ console.print(
271
+ "\n[bold cyan]Transfer Operation[/bold cyan]\n"
272
+ "You will transfer stake ownership from one coldkey to another coldkey.\n"
273
+ "The hotkey remains the same, but ownership changes.\n"
274
+ "[yellow]Warning:[/yellow] Make sure the destination coldkey is not a validator hotkey.\n"
275
+ )
276
+
277
+ try:
278
+ selection = await stake_move_transfer_selection(meshtensor, wallet)
279
+
280
+ # Ask for destination coldkey
281
+ console.print("\n[bold]Destination Coldkey[/bold]")
282
+ dest_coldkey = Prompt.ask(
283
+ "Enter the [blue]destination coldkey[/blue] SS58 address or wallet name"
284
+ )
285
+
286
+ # Note: The CLI will handle wallet name resolution if it's not an SS58 address
287
+
288
+ return {
289
+ "operation": "transfer",
290
+ "origin_hotkey": selection["origin_hotkey"],
291
+ "origin_netuid": selection["origin_netuid"],
292
+ "destination_netuid": selection["destination_netuid"],
293
+ "destination_coldkey": dest_coldkey,
294
+ "amount": selection["amount"],
295
+ "stake_all": selection["stake_all"],
296
+ }
297
+ except ValueError:
298
+ raise
299
+
300
+
301
+ async def _guide_swap_operation(
302
+ meshtensor: "MeshtensorInterface",
303
+ wallet: Wallet,
304
+ available_stakes: list,
305
+ ) -> dict:
306
+ """Guide user through swap operation."""
307
+ console.print(
308
+ "\n[bold cyan]Swap Operation[/bold cyan]\n"
309
+ "You will swap stake between subnets.\n"
310
+ "The same coldkey-hotkey pair is used, but stake moves between subnets.\n"
311
+ )
312
+
313
+ try:
314
+ selection = await stake_swap_selection(meshtensor, wallet)
315
+
316
+ return {
317
+ "operation": "swap",
318
+ "origin_netuid": selection["origin_netuid"],
319
+ "destination_netuid": selection["destination_netuid"],
320
+ "amount": selection["amount"],
321
+ }
322
+ except ValueError:
323
+ raise
File without changes