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
File without changes
@@ -0,0 +1,190 @@
1
+ """
2
+ Technical Committee (TC) commands for meshcli.
3
+
4
+ Provides commands for interacting with the elected Technical Committee:
5
+ - List current TC members
6
+ - List TC election candidates
7
+ - Vote in TC elections
8
+ """
9
+
10
+ import asyncio
11
+ import json
12
+ from typing import TYPE_CHECKING, Optional
13
+
14
+ from meshtensor_wallet import Wallet
15
+ from rich import box
16
+ from rich.table import Column, Table
17
+
18
+ from meshtensor_cli.src.meshtensor.utils import (
19
+ confirm_action,
20
+ console,
21
+ print_error,
22
+ print_success,
23
+ unlock_key,
24
+ json_console,
25
+ print_extrinsic_id,
26
+ )
27
+
28
+ if TYPE_CHECKING:
29
+ from meshtensor_cli.src.meshtensor.meshtensor_interface import MeshtensorInterface
30
+
31
+
32
+ # ============================================================================
33
+ # meshcli tc members
34
+ # ============================================================================
35
+
36
+ async def tc_members(
37
+ subtensor: "MeshtensorInterface",
38
+ quiet: bool = False,
39
+ verbose: bool = False,
40
+ output_json: bool = False,
41
+ ):
42
+ """List current Technical Committee members."""
43
+
44
+ try:
45
+ members = await subtensor.substrate.query(
46
+ module="TechnicalMembership",
47
+ storage_function="Members",
48
+ )
49
+
50
+ member_list = members.value if members else []
51
+
52
+ if output_json:
53
+ json_console.print_json(json.dumps({"members": member_list}, default=str))
54
+ return
55
+
56
+ if not member_list:
57
+ console.print("[dim]No Technical Committee members found.[/dim]")
58
+ return
59
+
60
+ console.print(f"\n[bold]Technical Committee Members ({len(member_list)})[/bold]")
61
+
62
+ table = Table(
63
+ Column("#", style="bold"),
64
+ Column("Account", style="cyan"),
65
+ title=f"TC Members (adaptive size: {len(member_list)} seats)",
66
+ box=box.ROUNDED,
67
+ )
68
+
69
+ for i, member in enumerate(member_list, 1):
70
+ account_str = str(member)
71
+ table.add_row(str(i), account_str)
72
+
73
+ console.print(table)
74
+
75
+ # Show adaptive sizing info
76
+ if len(member_list) <= 5:
77
+ console.print("[dim]Current phase: 5 seats (initial)[/dim]")
78
+ elif len(member_list) <= 7:
79
+ console.print("[dim]Current phase: 7 seats (network growth)[/dim]")
80
+ else:
81
+ console.print("[dim]Current phase: 9 seats (mature network)[/dim]")
82
+
83
+ except Exception as e:
84
+ print_error(f"Error fetching TC members: {e}")
85
+
86
+
87
+ # ============================================================================
88
+ # meshcli tc candidates
89
+ # ============================================================================
90
+
91
+ async def tc_candidates(
92
+ subtensor: "MeshtensorInterface",
93
+ quiet: bool = False,
94
+ verbose: bool = False,
95
+ output_json: bool = False,
96
+ ):
97
+ """List TC election candidates."""
98
+
99
+ try:
100
+ candidates = await subtensor.substrate.query(
101
+ module="Elections",
102
+ storage_function="Candidates",
103
+ )
104
+
105
+ candidate_list = candidates.value if candidates else []
106
+
107
+ if output_json:
108
+ json_console.print_json(
109
+ json.dumps({"candidates": candidate_list}, default=str)
110
+ )
111
+ return
112
+
113
+ if not candidate_list:
114
+ console.print("[dim]No TC election candidates found.[/dim]")
115
+ return
116
+
117
+ table = Table(
118
+ Column("#", style="bold"),
119
+ Column("Candidate", style="cyan"),
120
+ Column("Deposit", style="yellow"),
121
+ title="TC Election Candidates",
122
+ box=box.ROUNDED,
123
+ )
124
+
125
+ for i, (candidate, deposit) in enumerate(candidate_list, 1):
126
+ table.add_row(
127
+ str(i),
128
+ str(candidate),
129
+ f"{deposit / 1e9:.4f} MESH" if isinstance(deposit, (int, float)) else str(deposit),
130
+ )
131
+
132
+ console.print(table)
133
+
134
+ except Exception as e:
135
+ print_error(f"Error fetching TC candidates: {e}")
136
+
137
+
138
+ # ============================================================================
139
+ # meshcli tc vote
140
+ # ============================================================================
141
+
142
+ async def tc_vote(
143
+ subtensor: "MeshtensorInterface",
144
+ wallet: Wallet,
145
+ candidates: list[str],
146
+ stake: float,
147
+ quiet: bool = False,
148
+ verbose: bool = False,
149
+ ):
150
+ """Vote in a TC election."""
151
+
152
+ stake_raw = int(stake * 1e9)
153
+
154
+ if not quiet:
155
+ console.print(f"\n[bold]Voting in TC Election[/bold]")
156
+ console.print(f" Candidates: {len(candidates)}")
157
+ for c in candidates:
158
+ console.print(f" - {c[:16]}...")
159
+ console.print(f" Stake: {stake} MESH")
160
+
161
+ if not confirm_action("Cast TC election vote?"):
162
+ return
163
+
164
+ if not unlock_key(wallet):
165
+ return
166
+
167
+ try:
168
+ call = await subtensor.substrate.compose_call(
169
+ call_module="Elections",
170
+ call_function="vote",
171
+ call_params={
172
+ "votes": candidates,
173
+ "value": stake_raw,
174
+ },
175
+ )
176
+
177
+ extrinsic = await subtensor.substrate.create_signed_extrinsic(
178
+ call=call, keypair=wallet.coldkey
179
+ )
180
+ response = await subtensor.substrate.submit_extrinsic(
181
+ extrinsic, wait_for_inclusion=True
182
+ )
183
+
184
+ if response.is_success:
185
+ print_success(f"TC election vote cast for {len(candidates)} candidate(s)")
186
+ print_extrinsic_id(response)
187
+ else:
188
+ print_error(f"Failed to vote: {response.error_message}")
189
+ except Exception as e:
190
+ print_error(f"Error voting in TC election: {e}")
File without changes
@@ -0,0 +1,194 @@
1
+ """
2
+ Treasury commands for meshcli.
3
+
4
+ Provides commands for interacting with the Meshtensor on-chain treasury:
5
+ - Submit treasury spend proposals
6
+ - List active proposals
7
+ - View treasury balance
8
+ """
9
+
10
+ import asyncio
11
+ import json
12
+ from typing import TYPE_CHECKING, Optional
13
+
14
+ from meshtensor_wallet import Wallet
15
+ from rich import box
16
+ from rich.table import Column, Table
17
+
18
+ from meshtensor_cli.src.meshtensor.utils import (
19
+ confirm_action,
20
+ console,
21
+ print_error,
22
+ print_success,
23
+ unlock_key,
24
+ json_console,
25
+ print_extrinsic_id,
26
+ )
27
+
28
+ if TYPE_CHECKING:
29
+ from meshtensor_cli.src.meshtensor.meshtensor_interface import MeshtensorInterface
30
+
31
+
32
+ # ============================================================================
33
+ # meshcli treasury propose
34
+ # ============================================================================
35
+
36
+ async def treasury_propose(
37
+ subtensor: "MeshtensorInterface",
38
+ wallet: Wallet,
39
+ value: float,
40
+ beneficiary: str,
41
+ description: str = "",
42
+ quiet: bool = False,
43
+ verbose: bool = False,
44
+ ):
45
+ """Submit a treasury spend proposal."""
46
+
47
+ value_raw = int(value * 1e9) # Convert MESH to meshlet
48
+
49
+ if not quiet:
50
+ console.print(f"\n[bold]Submitting Treasury Proposal[/bold]")
51
+ console.print(f" Amount: {value} MESH ({value_raw} meshlet)")
52
+ console.print(f" Beneficiary: {beneficiary}")
53
+ if description:
54
+ console.print(f" Description: {description}")
55
+
56
+ if not confirm_action("Submit this treasury proposal?"):
57
+ return
58
+
59
+ if not unlock_key(wallet):
60
+ return
61
+
62
+ try:
63
+ call = await subtensor.substrate.compose_call(
64
+ call_module="Treasury",
65
+ call_function="propose_spend",
66
+ call_params={
67
+ "value": value_raw,
68
+ "beneficiary": beneficiary,
69
+ },
70
+ )
71
+
72
+ extrinsic = await subtensor.substrate.create_signed_extrinsic(
73
+ call=call, keypair=wallet.coldkey
74
+ )
75
+ response = await subtensor.substrate.submit_extrinsic(
76
+ extrinsic, wait_for_inclusion=True
77
+ )
78
+
79
+ if response.is_success:
80
+ print_success(f"Treasury proposal submitted: {value} MESH to {beneficiary[:8]}...{beneficiary[-8:]}")
81
+ print_extrinsic_id(response)
82
+ else:
83
+ print_error(f"Failed to submit proposal: {response.error_message}")
84
+ except Exception as e:
85
+ print_error(f"Error submitting treasury proposal: {e}")
86
+
87
+
88
+ # ============================================================================
89
+ # meshcli treasury list
90
+ # ============================================================================
91
+
92
+ async def treasury_list(
93
+ subtensor: "MeshtensorInterface",
94
+ quiet: bool = False,
95
+ verbose: bool = False,
96
+ output_json: bool = False,
97
+ ):
98
+ """List active treasury proposals."""
99
+
100
+ try:
101
+ proposals = await subtensor.substrate.query_map(
102
+ module="Treasury",
103
+ storage_function="Proposals",
104
+ )
105
+
106
+ results = []
107
+ async for proposal_id, proposal_info in proposals:
108
+ pid = proposal_id.value if hasattr(proposal_id, "value") else proposal_id
109
+ data = proposal_info.value if hasattr(proposal_info, "value") else proposal_info
110
+ results.append({
111
+ "id": pid,
112
+ "proposer": data.get("proposer", "Unknown"),
113
+ "value": data.get("value", 0),
114
+ "beneficiary": data.get("beneficiary", "Unknown"),
115
+ "bond": data.get("bond", 0),
116
+ })
117
+
118
+ if output_json:
119
+ json_console.print_json(json.dumps(results, default=str))
120
+ return
121
+
122
+ if not results:
123
+ console.print("[dim]No active treasury proposals.[/dim]")
124
+ return
125
+
126
+ table = Table(
127
+ Column("ID", style="bold"),
128
+ Column("Value (MESH)", style="green"),
129
+ Column("Beneficiary", style="cyan"),
130
+ Column("Bond (MESH)", style="yellow"),
131
+ title="Active Treasury Proposals",
132
+ box=box.ROUNDED,
133
+ )
134
+
135
+ for p in sorted(results, key=lambda x: x["id"]):
136
+ table.add_row(
137
+ str(p["id"]),
138
+ f"{p['value'] / 1e9:.4f}",
139
+ str(p["beneficiary"])[:16] + "...",
140
+ f"{p['bond'] / 1e9:.4f}",
141
+ )
142
+
143
+ console.print(table)
144
+
145
+ except Exception as e:
146
+ print_error(f"Error listing treasury proposals: {e}")
147
+
148
+
149
+ # ============================================================================
150
+ # meshcli treasury balance
151
+ # ============================================================================
152
+
153
+ async def treasury_balance(
154
+ subtensor: "MeshtensorInterface",
155
+ quiet: bool = False,
156
+ verbose: bool = False,
157
+ output_json: bool = False,
158
+ ):
159
+ """Show the treasury balance."""
160
+
161
+ try:
162
+ # Query treasury account balance
163
+ # The treasury account is derived from the PalletId
164
+ treasury_account = await subtensor.substrate.query(
165
+ module="Treasury",
166
+ storage_function="Pot",
167
+ )
168
+
169
+ balance = treasury_account.value if treasury_account else 0
170
+
171
+ # Also query the governance reward pool
172
+ gov_pool = await subtensor.substrate.query(
173
+ module="MeshtensorGovernance",
174
+ storage_function="GovernanceRewardPool",
175
+ )
176
+
177
+ gov_balance = gov_pool.value if gov_pool else 0
178
+
179
+ if output_json:
180
+ data = {
181
+ "treasury_balance": balance,
182
+ "treasury_balance_mesh": balance / 1e9,
183
+ "governance_reward_pool": gov_balance,
184
+ "governance_reward_pool_mesh": gov_balance / 1e9,
185
+ }
186
+ json_console.print_json(json.dumps(data))
187
+ return
188
+
189
+ console.print(f"\n[bold]Treasury Status[/bold]")
190
+ console.print(f" Treasury Balance: [green]{balance / 1e9:.4f} MESH[/green]")
191
+ console.print(f" Governance Reward Pool: [yellow]{gov_balance / 1e9:.4f} MESH[/yellow]")
192
+
193
+ except Exception as e:
194
+ print_error(f"Error fetching treasury balance: {e}")