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,736 @@
1
+ """
2
+ Stake command module - RPC-based operations.
3
+ """
4
+
5
+ from textwrap import dedent
6
+ from typing import Optional
7
+
8
+ import typer
9
+
10
+ from .handlers import (
11
+ add_stake_handler,
12
+ claim_handler,
13
+ delegate_add_handler,
14
+ delegate_donate_handler,
15
+ delegate_remove_handler,
16
+ delegate_swap_handler,
17
+ delegate_transfer_handler,
18
+ get_coldkey_stakes_handler,
19
+ get_delegate_stakes_handler,
20
+ get_node_delegate_stakes_handler,
21
+ remove_stake_handler,
22
+ swap_node_to_subnet_handler,
23
+ swap_queue_update_handler,
24
+ swap_subnet_to_node_handler,
25
+ swap_subnet_to_validator_handler,
26
+ swap_validator_to_subnet_handler,
27
+ verify_proof_of_stake_handler,
28
+ )
29
+
30
+ app = typer.Typer(name="stake", help="Staking operations")
31
+
32
+
33
+ def _option_value(value):
34
+ return None if isinstance(value, typer.models.OptionInfo) else value
35
+
36
+
37
+ ADD_STAKE_HELP = dedent("""\
38
+ Add stake to your node (direct staking - requires hotkey ownership).
39
+
40
+ \b
41
+ Usage:
42
+ - htcli stake add --subnet-id 1 --amount 100
43
+ - htcli stake add --subnet-id 1 --node-id 2 --amount 100
44
+ - htcli stake add --subnet-id 1 --hotkey-address 0x... --amount 100
45
+
46
+ \b
47
+ Note:
48
+ Use --node-id OR --hotkey-address, not both.
49
+ """)
50
+
51
+ REMOVE_STAKE_HELP = dedent("""\
52
+ Remove stake from your node (direct staking).
53
+
54
+ \b
55
+ Note:
56
+ Use --hotkey (wallet name) OR --hotkey-address (0x...), not both.
57
+ """)
58
+
59
+ DELEGATE_ADD_HELP = dedent("""\
60
+ Add delegate stake to a subnet, validator, or specific node.
61
+
62
+ \b
63
+ Usage:
64
+ - Subnet: htcli stake delegate-add --subnet-id 1 --amount 100
65
+ - Validator: htcli stake delegate-add --validator-id 7 --amount 100
66
+ - Node: htcli stake delegate-add --subnet-id 1 --node-id 5 --amount 100
67
+ """)
68
+
69
+ DELEGATE_REMOVE_HELP = dedent("""\
70
+ Remove delegate stake from a subnet, validator, or specific node.
71
+
72
+ \b
73
+ Usage:
74
+ - Subnet: htcli stake delegate-remove --subnet-id 1 --shares 1000
75
+ - Validator: htcli stake delegate-remove --validator-id 7 --shares 1000
76
+ - Node: htcli stake delegate-remove --subnet-id 1 --node-id 5 --shares 1000
77
+ """)
78
+
79
+ DELEGATE_SWAP_HELP = dedent("""\
80
+ Swap delegate stake between subnets, validators, or nodes.
81
+
82
+ \b
83
+ Usage:
84
+ - Subnet: htcli stake delegate-swap --from-subnet-id 1 --to-subnet-id 2 --shares 1000
85
+ - Validator: htcli stake delegate-swap --from-validator-id 7 --to-validator-id 8 --shares 1000
86
+ - Node: htcli stake delegate-swap --from-subnet-id 1 --from-node-id 5 --to-subnet-id 2 --to-node-id 3 --shares 1000
87
+ """)
88
+
89
+ DELEGATE_TRANSFER_HELP = dedent("""\
90
+ Transfer delegate stake to another account.
91
+
92
+ \b
93
+ Usage:
94
+ - Subnet: htcli stake delegate-transfer --subnet-id 1 --to-account 0x... --shares 1000
95
+ - Validator: htcli stake delegate-transfer --validator-id 7 --to-account 0x... --shares 1000
96
+ - Node: htcli stake delegate-transfer --subnet-id 1 --node-id 5 --to-account 0x... --shares 1000
97
+ """)
98
+
99
+ DELEGATE_DONATE_HELP = dedent("""\
100
+ Donate delegate stake to subnet treasury, validator pool, or node pool.
101
+
102
+ \b
103
+ Usage:
104
+ - Subnet: htcli stake delegate-donate --subnet-id 1 --amount 100
105
+ - Validator: htcli stake delegate-donate --validator-id 7 --amount 100
106
+ - Node: htcli stake delegate-donate --subnet-id 1 --node-id 5 --amount 100
107
+ """)
108
+
109
+ LIST_DELEGATE_HELP = dedent("""\
110
+ List delegate stake information for an account.
111
+
112
+ \b
113
+ Usage:
114
+ - Subnet delegate: htcli stake list-delegate --account 0x...
115
+ - Node delegate: htcli stake list-delegate --account 0x... --node-id 5
116
+ """)
117
+
118
+
119
+ # ============================================================================
120
+ # DIRECT STAKING COMMANDS (Owner-only, require hotkey ownership)
121
+ # ============================================================================
122
+
123
+
124
+ @app.command("add", help=ADD_STAKE_HELP)
125
+ def add_stake(
126
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
127
+ node_id: Optional[int] = typer.Option(
128
+ None, "--node-id", help="Node ID (hotkey fetched automatically)"
129
+ ),
130
+ hotkey_address: Optional[str] = typer.Option(
131
+ None,
132
+ "--hotkey-address",
133
+ help="Hotkey address (0x...) - alternative to --node-id",
134
+ ),
135
+ amount: Optional[float] = typer.Option(None, "--amount", help="Amount in TENSOR"),
136
+ coldkey: Optional[str] = typer.Option(
137
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
138
+ ),
139
+ ):
140
+ """Add stake to your node."""
141
+ add_stake_handler(subnet_id, node_id, hotkey_address, amount, coldkey)
142
+
143
+
144
+ @app.command("remove", help=REMOVE_STAKE_HELP)
145
+ def remove_stake(
146
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
147
+ hotkey: Optional[str] = typer.Option(
148
+ None, "--hotkey", help="Hotkey wallet name (resolved under coldkey)"
149
+ ),
150
+ hotkey_address: Optional[str] = typer.Option(
151
+ None,
152
+ "--hotkey-address",
153
+ help="Hotkey address (0x...) - alternative to --hotkey",
154
+ ),
155
+ amount: Optional[float] = typer.Option(None, "--amount", help="Amount in TENSOR"),
156
+ coldkey: Optional[str] = typer.Option(
157
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
158
+ ),
159
+ ):
160
+ """Remove stake from your node."""
161
+ # Resolve hotkey: prefer hotkey_address if provided, otherwise use hotkey (wallet name)
162
+ resolved_hotkey = hotkey_address if hotkey_address else hotkey
163
+ remove_stake_handler(subnet_id, resolved_hotkey, amount, coldkey)
164
+
165
+
166
+ @app.command("claim")
167
+ def claim_unbondings(
168
+ coldkey: Optional[str] = typer.Option(
169
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
170
+ ),
171
+ yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt"),
172
+ ):
173
+ """Claim all unbonded tokens after unbonding period."""
174
+ claim_handler(coldkey, yes)
175
+
176
+
177
+ # ============================================================================
178
+ # UNIFIED DELEGATE STAKING COMMANDS
179
+ # Use --node-id to target a specific node, otherwise targets the subnet
180
+ # ============================================================================
181
+
182
+
183
+ @app.command("delegate-add", help=DELEGATE_ADD_HELP)
184
+ def delegate_add(
185
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
186
+ node_id: Optional[int] = typer.Option(
187
+ None, "--node-id", help="Node ID (for node-level delegation)"
188
+ ),
189
+ validator_id: Optional[int] = typer.Option(
190
+ None, "--validator-id", help="Validator ID (for validator-level delegation)"
191
+ ),
192
+ amount: Optional[float] = typer.Option(None, "--amount", help="Amount in TENSOR"),
193
+ coldkey: Optional[str] = typer.Option(
194
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
195
+ ),
196
+ ):
197
+ """Add delegate stake to a subnet, validator, or specific node."""
198
+ delegate_add_handler(
199
+ subnet_id=subnet_id,
200
+ node_id=node_id,
201
+ stake_amount=amount,
202
+ coldkey=coldkey,
203
+ validator_id=validator_id,
204
+ )
205
+
206
+
207
+ @app.command("node-delegate-add")
208
+ def node_delegate_add(
209
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
210
+ node_id: Optional[int] = typer.Option(
211
+ None, "--node-id", help="Node ID (for node-level delegation)"
212
+ ),
213
+ amount: Optional[float] = typer.Option(None, "--amount", help="Amount in TENSOR"),
214
+ coldkey: Optional[str] = typer.Option(
215
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
216
+ ),
217
+ ):
218
+ """Backward-compatible alias for adding node delegate stake."""
219
+ delegate_add_handler(subnet_id, node_id, amount, coldkey)
220
+
221
+
222
+ @app.command("delegate-remove", help=DELEGATE_REMOVE_HELP)
223
+ def delegate_remove(
224
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
225
+ node_id: Optional[int] = typer.Option(
226
+ None, "--node-id", help="Node ID (for node-level removal)"
227
+ ),
228
+ validator_id: Optional[int] = typer.Option(
229
+ None, "--validator-id", help="Validator ID (for validator-level removal)"
230
+ ),
231
+ shares: Optional[int] = typer.Option(
232
+ None, "--shares", help="Number of shares to remove"
233
+ ),
234
+ coldkey: Optional[str] = typer.Option(
235
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
236
+ ),
237
+ ):
238
+ """Remove delegate stake from a subnet, validator, or specific node."""
239
+ delegate_remove_handler(
240
+ subnet_id=subnet_id,
241
+ node_id=node_id,
242
+ shares_to_remove=shares,
243
+ coldkey=coldkey,
244
+ validator_id=validator_id,
245
+ )
246
+
247
+
248
+ @app.command("node-delegate-remove")
249
+ def node_delegate_remove(
250
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
251
+ node_id: Optional[int] = typer.Option(
252
+ None, "--node-id", help="Node ID (for node-level removal)"
253
+ ),
254
+ shares: Optional[int] = typer.Option(
255
+ None, "--shares", help="Number of shares to remove"
256
+ ),
257
+ coldkey: Optional[str] = typer.Option(
258
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
259
+ ),
260
+ ):
261
+ """Backward-compatible alias for removing node delegate stake."""
262
+ delegate_remove_handler(subnet_id, node_id, shares, coldkey)
263
+
264
+
265
+ @app.command("validator-delegate-add")
266
+ def validator_delegate_add(
267
+ validator_id: Optional[int] = typer.Option(
268
+ None, "--validator-id", help="Validator ID to delegate to"
269
+ ),
270
+ amount: Optional[float] = typer.Option(None, "--amount", help="Amount in TENSOR"),
271
+ coldkey: Optional[str] = typer.Option(
272
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
273
+ ),
274
+ ):
275
+ """Add delegate stake to a validator."""
276
+ delegate_add_handler(
277
+ stake_amount=amount,
278
+ coldkey=coldkey,
279
+ validator_id=validator_id,
280
+ )
281
+
282
+
283
+ @app.command("validator-delegate-remove")
284
+ def validator_delegate_remove(
285
+ validator_id: Optional[int] = typer.Option(
286
+ None, "--validator-id", help="Validator ID to remove delegate stake from"
287
+ ),
288
+ shares: Optional[int] = typer.Option(
289
+ None, "--shares", help="Number of shares to remove"
290
+ ),
291
+ coldkey: Optional[str] = typer.Option(
292
+ None, "--coldkey", help="Coldkey wallet name to sign the transaction"
293
+ ),
294
+ ):
295
+ """Remove delegate stake from a validator."""
296
+ delegate_remove_handler(
297
+ shares_to_remove=shares,
298
+ coldkey=coldkey,
299
+ validator_id=validator_id,
300
+ )
301
+
302
+
303
+ @app.command("delegate-swap", help=DELEGATE_SWAP_HELP)
304
+ def delegate_swap(
305
+ from_subnet_id: Optional[int] = typer.Option(
306
+ None, "--from-subnet-id", help="Source subnet ID"
307
+ ),
308
+ from_node_id: Optional[int] = typer.Option(
309
+ None, "--from-node-id", help="Source node ID (for node-level swap)"
310
+ ),
311
+ from_validator_id: Optional[int] = typer.Option(
312
+ None, "--from-validator-id", help="Source validator ID"
313
+ ),
314
+ to_subnet_id: Optional[int] = typer.Option(
315
+ None, "--to-subnet-id", help="Destination subnet ID"
316
+ ),
317
+ to_node_id: Optional[int] = typer.Option(
318
+ None, "--to-node-id", help="Destination node ID (for node-level swap)"
319
+ ),
320
+ to_validator_id: Optional[int] = typer.Option(
321
+ None, "--to-validator-id", help="Destination validator ID"
322
+ ),
323
+ shares: Optional[int] = typer.Option(
324
+ None, "--shares", help="Number of shares to swap"
325
+ ),
326
+ coldkey: Optional[str] = typer.Option(
327
+ None, "--coldkey", help="Coldkey wallet to sign with"
328
+ ),
329
+ ):
330
+ """Swap delegate stake between subnets, validators, or nodes."""
331
+ delegate_swap_handler(
332
+ from_subnet_id=from_subnet_id,
333
+ from_node_id=from_node_id,
334
+ to_subnet_id=to_subnet_id,
335
+ to_node_id=to_node_id,
336
+ shares=shares,
337
+ coldkey=coldkey,
338
+ from_validator_id=_option_value(from_validator_id),
339
+ to_validator_id=_option_value(to_validator_id),
340
+ )
341
+
342
+
343
+ @app.command("node-delegate-swap")
344
+ def node_delegate_swap(
345
+ from_subnet_id: Optional[int] = typer.Option(
346
+ None, "--from-subnet-id", help="Source subnet ID"
347
+ ),
348
+ from_node_id: Optional[int] = typer.Option(
349
+ None, "--from-node-id", help="Source node ID"
350
+ ),
351
+ to_subnet_id: Optional[int] = typer.Option(
352
+ None, "--to-subnet-id", help="Destination subnet ID"
353
+ ),
354
+ to_node_id: Optional[int] = typer.Option(
355
+ None, "--to-node-id", help="Destination node ID"
356
+ ),
357
+ shares: Optional[int] = typer.Option(
358
+ None, "--shares", help="Number of shares to swap"
359
+ ),
360
+ coldkey: Optional[str] = typer.Option(
361
+ None, "--coldkey", help="Coldkey wallet to sign with"
362
+ ),
363
+ ):
364
+ """Backward-compatible alias for swapping node delegate stake."""
365
+ delegate_swap_handler(
366
+ from_subnet_id, from_node_id, to_subnet_id, to_node_id, shares, coldkey
367
+ )
368
+
369
+
370
+ @app.command("delegate-transfer", help=DELEGATE_TRANSFER_HELP)
371
+ def delegate_transfer(
372
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
373
+ node_id: Optional[int] = typer.Option(
374
+ None, "--node-id", help="Node ID (for node-level transfer)"
375
+ ),
376
+ validator_id: Optional[int] = typer.Option(
377
+ None, "--validator-id", help="Validator ID (for validator-level transfer)"
378
+ ),
379
+ to_account: Optional[str] = typer.Option(
380
+ None, "--to-account", help="Destination account (0x...)"
381
+ ),
382
+ shares: Optional[int] = typer.Option(
383
+ None, "--shares", help="Number of shares to transfer"
384
+ ),
385
+ coldkey: Optional[str] = typer.Option(
386
+ None, "--coldkey", help="Coldkey wallet to sign with"
387
+ ),
388
+ ):
389
+ """Transfer delegate stake to another account."""
390
+ delegate_transfer_handler(
391
+ subnet_id=subnet_id,
392
+ node_id=node_id,
393
+ to_account=to_account,
394
+ shares=shares,
395
+ coldkey=coldkey,
396
+ validator_id=_option_value(validator_id),
397
+ )
398
+
399
+
400
+ @app.command("validator-delegate-swap")
401
+ def validator_delegate_swap(
402
+ from_validator_id: Optional[int] = typer.Option(
403
+ None, "--from-validator-id", help="Source validator ID"
404
+ ),
405
+ to_validator_id: Optional[int] = typer.Option(
406
+ None, "--to-validator-id", help="Destination validator ID"
407
+ ),
408
+ shares: Optional[int] = typer.Option(
409
+ None, "--shares", help="Number of shares to swap"
410
+ ),
411
+ coldkey: Optional[str] = typer.Option(
412
+ None, "--coldkey", help="Coldkey wallet to sign with"
413
+ ),
414
+ ):
415
+ """Swap delegate stake between validators."""
416
+ delegate_swap_handler(
417
+ shares=shares,
418
+ coldkey=coldkey,
419
+ from_validator_id=from_validator_id,
420
+ to_validator_id=to_validator_id,
421
+ )
422
+
423
+
424
+ @app.command("validator-delegate-transfer")
425
+ def validator_delegate_transfer(
426
+ validator_id: Optional[int] = typer.Option(
427
+ None, "--validator-id", help="Validator ID"
428
+ ),
429
+ to_account: Optional[str] = typer.Option(
430
+ None, "--to-account", help="Destination account (0x...)"
431
+ ),
432
+ shares: Optional[int] = typer.Option(
433
+ None, "--shares", help="Number of shares to transfer"
434
+ ),
435
+ coldkey: Optional[str] = typer.Option(
436
+ None, "--coldkey", help="Coldkey wallet to sign with"
437
+ ),
438
+ ):
439
+ """Transfer validator delegate stake to another account."""
440
+ delegate_transfer_handler(
441
+ to_account=to_account,
442
+ shares=shares,
443
+ coldkey=coldkey,
444
+ validator_id=validator_id,
445
+ )
446
+
447
+
448
+ @app.command("node-delegate-transfer")
449
+ def node_delegate_transfer(
450
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
451
+ node_id: Optional[int] = typer.Option(None, "--node-id", help="Node ID"),
452
+ to_account: Optional[str] = typer.Option(
453
+ None, "--to-account", help="Destination account (0x...)"
454
+ ),
455
+ shares: Optional[int] = typer.Option(
456
+ None, "--shares", help="Number of shares to transfer"
457
+ ),
458
+ coldkey: Optional[str] = typer.Option(
459
+ None, "--coldkey", help="Coldkey wallet to sign with"
460
+ ),
461
+ ):
462
+ """Backward-compatible alias for transferring node delegate stake."""
463
+ delegate_transfer_handler(subnet_id, node_id, to_account, shares, coldkey)
464
+
465
+
466
+ @app.command("delegate-donate", help=DELEGATE_DONATE_HELP)
467
+ def delegate_donate(
468
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
469
+ node_id: Optional[int] = typer.Option(
470
+ None, "--node-id", help="Node ID (for node-level donation)"
471
+ ),
472
+ validator_id: Optional[int] = typer.Option(
473
+ None, "--validator-id", help="Validator ID (for validator-level donation)"
474
+ ),
475
+ amount: Optional[float] = typer.Option(
476
+ None, "--amount", help="Donation amount in TENSOR"
477
+ ),
478
+ coldkey: Optional[str] = typer.Option(
479
+ None, "--coldkey", help="Coldkey wallet to sign with"
480
+ ),
481
+ ):
482
+ """Donate delegate stake to subnet treasury, validator pool, or node pool."""
483
+ delegate_donate_handler(
484
+ subnet_id=subnet_id,
485
+ node_id=node_id,
486
+ amount=amount,
487
+ coldkey=coldkey,
488
+ validator_id=_option_value(validator_id),
489
+ )
490
+
491
+
492
+ @app.command("validator-delegate-donate")
493
+ def validator_delegate_donate(
494
+ validator_id: Optional[int] = typer.Option(
495
+ None, "--validator-id", help="Validator ID"
496
+ ),
497
+ amount: Optional[float] = typer.Option(
498
+ None, "--amount", help="Donation amount in TENSOR"
499
+ ),
500
+ coldkey: Optional[str] = typer.Option(
501
+ None, "--coldkey", help="Coldkey wallet to sign with"
502
+ ),
503
+ ):
504
+ """Donate delegate stake to a validator delegate pool."""
505
+ delegate_donate_handler(
506
+ amount=amount,
507
+ coldkey=coldkey,
508
+ validator_id=validator_id,
509
+ )
510
+
511
+
512
+ @app.command("node-delegate-donate")
513
+ def node_delegate_donate(
514
+ subnet_id: Optional[int] = typer.Option(None, "--subnet-id", help="Subnet ID"),
515
+ node_id: Optional[int] = typer.Option(None, "--node-id", help="Node ID"),
516
+ amount: Optional[float] = typer.Option(
517
+ None, "--amount", help="Donation amount in TENSOR"
518
+ ),
519
+ coldkey: Optional[str] = typer.Option(
520
+ None, "--coldkey", help="Coldkey wallet to sign with"
521
+ ),
522
+ ):
523
+ """Backward-compatible alias for donating node delegate stake."""
524
+ delegate_donate_handler(subnet_id, node_id, amount, coldkey)
525
+
526
+
527
+ # ============================================================================
528
+ # CROSS-TYPE SWAP COMMANDS (Convert between node and subnet delegate)
529
+ # ============================================================================
530
+
531
+
532
+ @app.command("swap-node-to-subnet")
533
+ def swap_node_to_subnet(
534
+ from_subnet_id: Optional[int] = typer.Option(
535
+ None, "--from-subnet-id", help="Source subnet ID"
536
+ ),
537
+ from_node_id: Optional[int] = typer.Option(
538
+ None, "--from-node-id", help="Source node ID"
539
+ ),
540
+ to_subnet_id: Optional[int] = typer.Option(
541
+ None, "--to-subnet-id", help="Destination subnet ID"
542
+ ),
543
+ shares: Optional[int] = typer.Option(None, "--shares", help="Shares to convert"),
544
+ coldkey: Optional[str] = typer.Option(
545
+ None, "--coldkey", help="Coldkey wallet to sign with"
546
+ ),
547
+ ):
548
+ """
549
+ Convert node delegate stake to subnet delegate stake.
550
+
551
+ This operation swaps stake from a specific node's delegate pool to the general subnet delegate pool.
552
+ """
553
+ swap_node_to_subnet_handler(
554
+ from_subnet_id, from_node_id, to_subnet_id, shares, coldkey
555
+ )
556
+
557
+
558
+ @app.command("swap-subnet-to-node")
559
+ def swap_subnet_to_node(
560
+ from_subnet_id: Optional[int] = typer.Option(
561
+ None, "--from-subnet-id", help="Source subnet ID"
562
+ ),
563
+ to_subnet_id: Optional[int] = typer.Option(
564
+ None, "--to-subnet-id", help="Destination subnet ID"
565
+ ),
566
+ to_node_id: Optional[int] = typer.Option(
567
+ None, "--to-node-id", help="Destination node ID"
568
+ ),
569
+ shares: Optional[int] = typer.Option(None, "--shares", help="Shares to convert"),
570
+ coldkey: Optional[str] = typer.Option(
571
+ None, "--coldkey", help="Coldkey wallet to sign with"
572
+ ),
573
+ ):
574
+ """
575
+ Convert subnet delegate stake to node delegate stake.
576
+
577
+ This operation swaps stake from the general subnet delegate pool to a specific node's delegate pool.
578
+ """
579
+ swap_subnet_to_node_handler(
580
+ from_subnet_id, to_subnet_id, to_node_id, shares, coldkey
581
+ )
582
+
583
+
584
+ @app.command("swap-validator-to-subnet")
585
+ def swap_validator_to_subnet(
586
+ from_validator_id: Optional[int] = typer.Option(
587
+ None, "--from-validator-id", help="Source validator ID"
588
+ ),
589
+ to_subnet_id: Optional[int] = typer.Option(
590
+ None, "--to-subnet-id", help="Destination subnet ID"
591
+ ),
592
+ shares: Optional[int] = typer.Option(None, "--shares", help="Shares to convert"),
593
+ coldkey: Optional[str] = typer.Option(
594
+ None, "--coldkey", help="Coldkey wallet to sign with"
595
+ ),
596
+ ):
597
+ """Convert validator delegate stake to subnet delegate stake."""
598
+ swap_validator_to_subnet_handler(
599
+ from_validator_id=from_validator_id,
600
+ to_subnet_id=to_subnet_id,
601
+ shares_to_swap=shares,
602
+ coldkey=coldkey,
603
+ )
604
+
605
+
606
+ @app.command("swap-subnet-to-validator")
607
+ def swap_subnet_to_validator(
608
+ from_subnet_id: Optional[int] = typer.Option(
609
+ None, "--from-subnet-id", help="Source subnet ID"
610
+ ),
611
+ to_validator_id: Optional[int] = typer.Option(
612
+ None, "--to-validator-id", help="Destination validator ID"
613
+ ),
614
+ shares: Optional[int] = typer.Option(None, "--shares", help="Shares to convert"),
615
+ coldkey: Optional[str] = typer.Option(
616
+ None, "--coldkey", help="Coldkey wallet to sign with"
617
+ ),
618
+ ):
619
+ """Convert subnet delegate stake to validator delegate stake."""
620
+ swap_subnet_to_validator_handler(
621
+ from_subnet_id=from_subnet_id,
622
+ to_validator_id=to_validator_id,
623
+ shares_to_swap=shares,
624
+ coldkey=coldkey,
625
+ )
626
+
627
+
628
+ @app.command("swap-update")
629
+ def swap_queue_update(
630
+ queue_id: Optional[int] = typer.Option(None, "--queue-id", help="Queue entry ID"),
631
+ new_call_json: Optional[str] = typer.Option(
632
+ None,
633
+ "--new-call-json",
634
+ help='Replacement call JSON (e.g. {"type":"SwapToNodeDelegateStake","to_subnet_id":1,"to_subnet_node_id":2})',
635
+ ),
636
+ coldkey: Optional[str] = typer.Option(
637
+ None, "--coldkey", help="Coldkey wallet to sign with"
638
+ ),
639
+ ):
640
+ """Update a queued swap entry."""
641
+ swap_queue_update_handler(queue_id, new_call_json, coldkey)
642
+
643
+
644
+ # ============================================================================
645
+ # QUERY COMMANDS (RPC-based, read-only)
646
+ # ============================================================================
647
+
648
+
649
+ @app.command("list")
650
+ def list_stakes(
651
+ coldkey: Optional[str] = typer.Option(
652
+ None, "--coldkey", help="Coldkey address to get stakes for"
653
+ ),
654
+ ):
655
+ """List all stake information for a coldkey (direct, delegate, and node delegate)."""
656
+ get_coldkey_stakes_handler(coldkey)
657
+
658
+
659
+ @app.command("coldkey")
660
+ def coldkey_stakes(
661
+ coldkey: Optional[str] = typer.Option(
662
+ None, "--coldkey", help="Coldkey address to get stakes for"
663
+ ),
664
+ ):
665
+ """Backward-compatible alias for listing all stake information for a coldkey."""
666
+ get_coldkey_stakes_handler(coldkey)
667
+
668
+
669
+ @app.command("list-delegate", help=LIST_DELEGATE_HELP)
670
+ def list_delegate_stakes(
671
+ account: Optional[str] = typer.Option(
672
+ None, "--account", help="Account address to query"
673
+ ),
674
+ subnet_id: Optional[int] = typer.Option(
675
+ None, "--subnet-id", help="Filter by subnet ID"
676
+ ),
677
+ node_id: Optional[int] = typer.Option(
678
+ None, "--node-id", help="Filter by node ID (shows node delegate stakes)"
679
+ ),
680
+ ):
681
+ """List delegate stake information for an account."""
682
+ if node_id is not None:
683
+ # Query node delegate stakes
684
+ get_node_delegate_stakes_handler(account)
685
+ else:
686
+ # Query subnet delegate stakes
687
+ get_delegate_stakes_handler(account)
688
+
689
+
690
+ @app.command("delegate")
691
+ def delegate_stakes(
692
+ account: Optional[str] = typer.Argument(None, help="Account address to query"),
693
+ ):
694
+ """Backward-compatible alias for listing delegate stakes for an account."""
695
+ get_delegate_stakes_handler(account)
696
+
697
+
698
+ @app.command("node-delegate")
699
+ def node_delegate_stakes(
700
+ account: Optional[str] = typer.Option(
701
+ None, "--account", help="Account address to query"
702
+ ),
703
+ ):
704
+ """Backward-compatible alias for listing node delegate stakes for an account."""
705
+ get_node_delegate_stakes_handler(account)
706
+
707
+
708
+ @app.command("verify-proof")
709
+ def verify_proof_of_stake(
710
+ subnet_id: Optional[int] = typer.Option(
711
+ None, "--subnet-id", help="Subnet ID to check"
712
+ ),
713
+ peer_id: Optional[str] = typer.Option(None, "--peer-id", help="Peer ID to verify"),
714
+ min_class: Optional[int] = typer.Option(
715
+ None, "--min-class", help="Minimum required class (0-3)"
716
+ ),
717
+ ):
718
+ """Verify proof of stake for a peer in a subnet."""
719
+ verify_proof_of_stake_handler(subnet_id, peer_id, min_class)
720
+
721
+
722
+ @app.command("verify")
723
+ def verify_proof_of_stake_alias(
724
+ subnet_id: Optional[int] = typer.Option(
725
+ None, "--subnet-id", help="Subnet ID to check"
726
+ ),
727
+ peer_id: Optional[str] = typer.Option(None, "--peer-id", help="Peer ID to verify"),
728
+ min_class: Optional[int] = typer.Option(
729
+ None, "--min-class", help="Minimum required class (0-3)"
730
+ ),
731
+ ):
732
+ """Backward-compatible alias for proof-of-stake verification."""
733
+ verify_proof_of_stake_handler(subnet_id, peer_id, min_class)
734
+
735
+
736
+ __all__ = ["app"]