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.
- meshtensor_cli/__init__.py +22 -0
- meshtensor_cli/cli.py +10742 -0
- meshtensor_cli/doc_generation_helper.py +4 -0
- meshtensor_cli/src/__init__.py +1085 -0
- meshtensor_cli/src/commands/__init__.py +0 -0
- meshtensor_cli/src/commands/axon/__init__.py +0 -0
- meshtensor_cli/src/commands/axon/axon.py +132 -0
- meshtensor_cli/src/commands/crowd/__init__.py +0 -0
- meshtensor_cli/src/commands/crowd/contribute.py +621 -0
- meshtensor_cli/src/commands/crowd/contributors.py +200 -0
- meshtensor_cli/src/commands/crowd/create.py +783 -0
- meshtensor_cli/src/commands/crowd/dissolve.py +219 -0
- meshtensor_cli/src/commands/crowd/refund.py +233 -0
- meshtensor_cli/src/commands/crowd/update.py +418 -0
- meshtensor_cli/src/commands/crowd/utils.py +124 -0
- meshtensor_cli/src/commands/crowd/view.py +991 -0
- meshtensor_cli/src/commands/governance/__init__.py +0 -0
- meshtensor_cli/src/commands/governance/governance.py +794 -0
- meshtensor_cli/src/commands/liquidity/__init__.py +0 -0
- meshtensor_cli/src/commands/liquidity/liquidity.py +699 -0
- meshtensor_cli/src/commands/liquidity/utils.py +202 -0
- meshtensor_cli/src/commands/proxy.py +700 -0
- meshtensor_cli/src/commands/stake/__init__.py +0 -0
- meshtensor_cli/src/commands/stake/add.py +799 -0
- meshtensor_cli/src/commands/stake/auto_staking.py +306 -0
- meshtensor_cli/src/commands/stake/children_hotkeys.py +865 -0
- meshtensor_cli/src/commands/stake/claim.py +770 -0
- meshtensor_cli/src/commands/stake/list.py +738 -0
- meshtensor_cli/src/commands/stake/move.py +1211 -0
- meshtensor_cli/src/commands/stake/remove.py +1466 -0
- meshtensor_cli/src/commands/stake/wizard.py +323 -0
- meshtensor_cli/src/commands/subnets/__init__.py +0 -0
- meshtensor_cli/src/commands/subnets/mechanisms.py +515 -0
- meshtensor_cli/src/commands/subnets/price.py +733 -0
- meshtensor_cli/src/commands/subnets/subnets.py +2908 -0
- meshtensor_cli/src/commands/sudo.py +1294 -0
- meshtensor_cli/src/commands/tc/__init__.py +0 -0
- meshtensor_cli/src/commands/tc/tc.py +190 -0
- meshtensor_cli/src/commands/treasury/__init__.py +0 -0
- meshtensor_cli/src/commands/treasury/treasury.py +194 -0
- meshtensor_cli/src/commands/view.py +354 -0
- meshtensor_cli/src/commands/wallets.py +2311 -0
- meshtensor_cli/src/commands/weights.py +467 -0
- meshtensor_cli/src/meshtensor/__init__.py +0 -0
- meshtensor_cli/src/meshtensor/balances.py +313 -0
- meshtensor_cli/src/meshtensor/chain_data.py +1263 -0
- meshtensor_cli/src/meshtensor/extrinsics/__init__.py +0 -0
- meshtensor_cli/src/meshtensor/extrinsics/mev_shield.py +174 -0
- meshtensor_cli/src/meshtensor/extrinsics/registration.py +1861 -0
- meshtensor_cli/src/meshtensor/extrinsics/root.py +550 -0
- meshtensor_cli/src/meshtensor/extrinsics/serving.py +255 -0
- meshtensor_cli/src/meshtensor/extrinsics/transfer.py +239 -0
- meshtensor_cli/src/meshtensor/meshtensor_interface.py +2598 -0
- meshtensor_cli/src/meshtensor/minigraph.py +254 -0
- meshtensor_cli/src/meshtensor/networking.py +12 -0
- meshtensor_cli/src/meshtensor/templates/main-filters.j2 +24 -0
- meshtensor_cli/src/meshtensor/templates/main-header.j2 +36 -0
- meshtensor_cli/src/meshtensor/templates/neuron-details.j2 +111 -0
- meshtensor_cli/src/meshtensor/templates/price-multi.j2 +113 -0
- meshtensor_cli/src/meshtensor/templates/price-single.j2 +99 -0
- meshtensor_cli/src/meshtensor/templates/subnet-details-header.j2 +49 -0
- meshtensor_cli/src/meshtensor/templates/subnet-details.j2 +32 -0
- meshtensor_cli/src/meshtensor/templates/subnet-metrics.j2 +57 -0
- meshtensor_cli/src/meshtensor/templates/subnets-table.j2 +28 -0
- meshtensor_cli/src/meshtensor/templates/table.j2 +267 -0
- meshtensor_cli/src/meshtensor/templates/view.css +1058 -0
- meshtensor_cli/src/meshtensor/templates/view.j2 +43 -0
- meshtensor_cli/src/meshtensor/templates/view.js +1053 -0
- meshtensor_cli/src/meshtensor/utils.py +2007 -0
- meshtensor_cli/version.py +23 -0
- meshtensor_cli-9.18.1.dist-info/METADATA +261 -0
- meshtensor_cli-9.18.1.dist-info/RECORD +74 -0
- meshtensor_cli-9.18.1.dist-info/WHEEL +4 -0
- meshtensor_cli-9.18.1.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,865 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from meshtensor_wallet import Wallet
|
|
6
|
+
from rich.prompt import IntPrompt, FloatPrompt
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
from rich.text import Text
|
|
9
|
+
from async_substrate_interface.errors import SubstrateRequestException
|
|
10
|
+
|
|
11
|
+
from meshtensor_cli.src.meshtensor.balances import Balance
|
|
12
|
+
from meshtensor_cli.src.meshtensor.meshtensor_interface import MeshtensorInterface
|
|
13
|
+
from meshtensor_cli.src.meshtensor.utils import (
|
|
14
|
+
confirm_action,
|
|
15
|
+
console,
|
|
16
|
+
print_error,
|
|
17
|
+
float_to_u16,
|
|
18
|
+
float_to_u64,
|
|
19
|
+
print_success,
|
|
20
|
+
u16_to_float,
|
|
21
|
+
u64_to_float,
|
|
22
|
+
is_valid_ss58_address,
|
|
23
|
+
format_error_message,
|
|
24
|
+
unlock_key,
|
|
25
|
+
json_console,
|
|
26
|
+
get_hotkey_pub_ss58,
|
|
27
|
+
print_extrinsic_id,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async def get_childkey_completion_block(
|
|
32
|
+
meshtensor: MeshtensorInterface, netuid: int
|
|
33
|
+
) -> tuple[int, int]:
|
|
34
|
+
"""
|
|
35
|
+
Calculates the block at which the childkey set request will complete
|
|
36
|
+
"""
|
|
37
|
+
bh = await meshtensor.substrate.get_chain_head()
|
|
38
|
+
blocks_since_last_step_query = meshtensor.query(
|
|
39
|
+
"MeshtensorModule", "BlocksSinceLastStep", params=[netuid], block_hash=bh
|
|
40
|
+
)
|
|
41
|
+
tempo_query = meshtensor.get_hyperparameter(
|
|
42
|
+
param_name="Tempo", netuid=netuid, block_hash=bh
|
|
43
|
+
)
|
|
44
|
+
block_number, blocks_since_last_step, tempo = await asyncio.gather(
|
|
45
|
+
meshtensor.substrate.get_block_number(block_hash=bh),
|
|
46
|
+
blocks_since_last_step_query,
|
|
47
|
+
tempo_query,
|
|
48
|
+
)
|
|
49
|
+
cooldown = block_number + 7200
|
|
50
|
+
blocks_left_in_tempo = tempo - blocks_since_last_step
|
|
51
|
+
next_tempo = block_number + blocks_left_in_tempo
|
|
52
|
+
next_epoch_after_cooldown = (cooldown - next_tempo) % (tempo + 1) + cooldown
|
|
53
|
+
return block_number, next_epoch_after_cooldown
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def set_children_extrinsic(
|
|
57
|
+
meshtensor: "MeshtensorInterface",
|
|
58
|
+
wallet: Wallet,
|
|
59
|
+
hotkey: str,
|
|
60
|
+
netuid: int,
|
|
61
|
+
proxy: Optional[str],
|
|
62
|
+
children_with_proportions: list[tuple[float, str]],
|
|
63
|
+
wait_for_inclusion: bool = True,
|
|
64
|
+
wait_for_finalization: bool = False,
|
|
65
|
+
prompt: bool = False,
|
|
66
|
+
decline: bool = False,
|
|
67
|
+
quiet: bool = False,
|
|
68
|
+
) -> tuple[bool, str, Optional[str]]:
|
|
69
|
+
"""
|
|
70
|
+
Sets children hotkeys with proportions assigned from the parent.
|
|
71
|
+
|
|
72
|
+
:param: meshtensor: Meshtensor endpoint to use.
|
|
73
|
+
:param: wallet: Meshtensor wallet object.
|
|
74
|
+
:param: hotkey: Parent hotkey.
|
|
75
|
+
:param: children_with_proportions: Children hotkeys.
|
|
76
|
+
:param: netuid: Unique identifier of for the subnet.
|
|
77
|
+
:param: wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, or returns
|
|
78
|
+
`False` if the extrinsic fails to enter the block within the timeout.
|
|
79
|
+
:param: wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning `
|
|
80
|
+
`True`, or returns `False` if the extrinsic fails to be finalized within the timeout.
|
|
81
|
+
:param: prompt: If `True`, the call waits for confirmation from the user before proceeding.
|
|
82
|
+
|
|
83
|
+
:return: A tuple containing a success flag, an optional error message, and the extrinsic identifier
|
|
84
|
+
"""
|
|
85
|
+
# Check if all children are being revoked
|
|
86
|
+
all_revoked = len(children_with_proportions) == 0
|
|
87
|
+
|
|
88
|
+
operation = "Revoking all child hotkeys" if all_revoked else "Setting child hotkeys"
|
|
89
|
+
|
|
90
|
+
# Ask before moving on.
|
|
91
|
+
if prompt:
|
|
92
|
+
if all_revoked:
|
|
93
|
+
if not confirm_action(
|
|
94
|
+
f"Do you want to revoke all children hotkeys for hotkey {hotkey} on netuid {netuid}?",
|
|
95
|
+
decline=decline,
|
|
96
|
+
quiet=quiet,
|
|
97
|
+
):
|
|
98
|
+
return False, "Operation Cancelled", None
|
|
99
|
+
else:
|
|
100
|
+
if not confirm_action(
|
|
101
|
+
"Do you want to set children hotkeys:\n[bold white]{}[/bold white]?".format(
|
|
102
|
+
"\n".join(
|
|
103
|
+
f" {child[1]}: {child[0]}"
|
|
104
|
+
for child in children_with_proportions
|
|
105
|
+
)
|
|
106
|
+
),
|
|
107
|
+
decline=decline,
|
|
108
|
+
quiet=quiet,
|
|
109
|
+
):
|
|
110
|
+
return False, "Operation Cancelled", None
|
|
111
|
+
|
|
112
|
+
# Decrypt coldkey.
|
|
113
|
+
if not (unlock_status := unlock_key(wallet, print_out=False)).success:
|
|
114
|
+
return False, unlock_status.message, ""
|
|
115
|
+
|
|
116
|
+
with console.status(
|
|
117
|
+
f":satellite: {operation} on [white]{meshtensor.network}[/white] ..."
|
|
118
|
+
):
|
|
119
|
+
if not all_revoked:
|
|
120
|
+
normalized_children = prepare_child_proportions(children_with_proportions)
|
|
121
|
+
else:
|
|
122
|
+
normalized_children = []
|
|
123
|
+
|
|
124
|
+
call = await meshtensor.substrate.compose_call(
|
|
125
|
+
call_module="MeshtensorModule",
|
|
126
|
+
call_function="set_children",
|
|
127
|
+
call_params={
|
|
128
|
+
"hotkey": hotkey,
|
|
129
|
+
"children": normalized_children,
|
|
130
|
+
"netuid": netuid,
|
|
131
|
+
},
|
|
132
|
+
)
|
|
133
|
+
success, error_message, ext_receipt = await meshtensor.sign_and_send_extrinsic(
|
|
134
|
+
call, wallet, wait_for_inclusion, wait_for_finalization, proxy=proxy
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
if not wait_for_finalization and not wait_for_inclusion:
|
|
138
|
+
return (
|
|
139
|
+
True,
|
|
140
|
+
f"Not waiting for finalization or inclusion. {operation} initiated.",
|
|
141
|
+
None,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
if success:
|
|
145
|
+
ext_id = await ext_receipt.get_extrinsic_identifier()
|
|
146
|
+
await print_extrinsic_id(ext_receipt)
|
|
147
|
+
modifier = "included"
|
|
148
|
+
if wait_for_finalization:
|
|
149
|
+
print_success("Finalized")
|
|
150
|
+
modifier = "finalized"
|
|
151
|
+
return True, f"{operation} successfully {modifier}.", ext_id
|
|
152
|
+
else:
|
|
153
|
+
print_error(f"Failed: {error_message}")
|
|
154
|
+
return False, error_message, None
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
async def set_childkey_take_extrinsic(
|
|
158
|
+
meshtensor: "MeshtensorInterface",
|
|
159
|
+
wallet: Wallet,
|
|
160
|
+
hotkey: str,
|
|
161
|
+
netuid: int,
|
|
162
|
+
take: float,
|
|
163
|
+
proxy: Optional[str] = None,
|
|
164
|
+
wait_for_inclusion: bool = True,
|
|
165
|
+
wait_for_finalization: bool = False,
|
|
166
|
+
prompt: bool = True,
|
|
167
|
+
decline: bool = False,
|
|
168
|
+
quiet: bool = False,
|
|
169
|
+
) -> tuple[bool, str, Optional[str]]:
|
|
170
|
+
"""
|
|
171
|
+
Sets childkey take.
|
|
172
|
+
|
|
173
|
+
:param: meshtensor: Meshtensor endpoint to use.
|
|
174
|
+
:param: wallet: Meshtensor wallet object.
|
|
175
|
+
:param: hotkey: Child hotkey.
|
|
176
|
+
:param: take: Childkey Take value.
|
|
177
|
+
:param: netuid: Unique identifier of for the subnet.
|
|
178
|
+
:param: proxy: Optional proxy to use to make this extrinsic submission.
|
|
179
|
+
:param: wait_for_inclusion: If set, waits for the extrinsic to enter a block before returning `True`, or returns
|
|
180
|
+
`False` if the extrinsic fails to enter the block within the timeout.
|
|
181
|
+
:param: wait_for_finalization: If set, waits for the extrinsic to be finalized on the chain before returning `
|
|
182
|
+
`True`, or returns `False` if the extrinsic fails to be finalized within the timeout.
|
|
183
|
+
:param: prompt: If `True`, the call waits for confirmation from the user before proceeding.
|
|
184
|
+
|
|
185
|
+
:return: A tuple containing a success flag, an optional error message, and an optional extrinsic identifier
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
# Ask before moving on.
|
|
189
|
+
if prompt:
|
|
190
|
+
if not confirm_action(
|
|
191
|
+
f"Do you want to set childkey take to: [bold white]{take * 100}%[/bold white]?",
|
|
192
|
+
decline=decline,
|
|
193
|
+
quiet=quiet,
|
|
194
|
+
):
|
|
195
|
+
return False, "Operation Cancelled", None
|
|
196
|
+
|
|
197
|
+
# Decrypt coldkey.
|
|
198
|
+
if not (unlock_status := unlock_key(wallet, print_out=False)).success:
|
|
199
|
+
return False, unlock_status.message, None
|
|
200
|
+
|
|
201
|
+
with console.status(
|
|
202
|
+
f":satellite: Setting childkey take on [white]{meshtensor.network}[/white] ..."
|
|
203
|
+
):
|
|
204
|
+
try:
|
|
205
|
+
if 0 <= take <= 0.18:
|
|
206
|
+
take_u16 = float_to_u16(take)
|
|
207
|
+
else:
|
|
208
|
+
return False, "Invalid take value", None
|
|
209
|
+
|
|
210
|
+
call = await meshtensor.substrate.compose_call(
|
|
211
|
+
call_module="MeshtensorModule",
|
|
212
|
+
call_function="set_childkey_take",
|
|
213
|
+
call_params={
|
|
214
|
+
"hotkey": hotkey,
|
|
215
|
+
"take": take_u16,
|
|
216
|
+
"netuid": netuid,
|
|
217
|
+
},
|
|
218
|
+
)
|
|
219
|
+
(
|
|
220
|
+
success,
|
|
221
|
+
error_message,
|
|
222
|
+
ext_receipt,
|
|
223
|
+
) = await meshtensor.sign_and_send_extrinsic(
|
|
224
|
+
call, wallet, wait_for_inclusion, wait_for_finalization, proxy=proxy
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
if not wait_for_finalization and not wait_for_inclusion:
|
|
228
|
+
return (
|
|
229
|
+
True,
|
|
230
|
+
"Not waiting for finalization or inclusion. Set childkey take initiated.",
|
|
231
|
+
None,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
if success:
|
|
235
|
+
ext_id = await ext_receipt.get_extrinsic_identifier()
|
|
236
|
+
await print_extrinsic_id(ext_receipt)
|
|
237
|
+
modifier = "included"
|
|
238
|
+
if wait_for_finalization:
|
|
239
|
+
modifier = "finalized"
|
|
240
|
+
print_success("Finalized")
|
|
241
|
+
return True, f"Successfully {modifier} childkey take", ext_id
|
|
242
|
+
else:
|
|
243
|
+
print_error(f"Failed: {error_message}")
|
|
244
|
+
return False, error_message, None
|
|
245
|
+
|
|
246
|
+
except SubstrateRequestException as e:
|
|
247
|
+
return (
|
|
248
|
+
False,
|
|
249
|
+
f"Exception occurred while setting childkey take: {format_error_message(e)}",
|
|
250
|
+
None,
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
async def get_childkey_take(meshtensor, hotkey: str, netuid: int) -> Optional[int]:
|
|
255
|
+
"""
|
|
256
|
+
Get the childkey take of a hotkey on a specific network.
|
|
257
|
+
Args:
|
|
258
|
+
- hotkey (str): The hotkey to search for.
|
|
259
|
+
- netuid (int): The netuid to search for.
|
|
260
|
+
|
|
261
|
+
Returns:
|
|
262
|
+
- Optional[float]: The value of the "ChildkeyTake" if found, or None if any error occurs.
|
|
263
|
+
"""
|
|
264
|
+
try:
|
|
265
|
+
childkey_take_ = await meshtensor.query(
|
|
266
|
+
module="MeshtensorModule",
|
|
267
|
+
storage_function="ChildkeyTake",
|
|
268
|
+
params=[hotkey, netuid],
|
|
269
|
+
)
|
|
270
|
+
if childkey_take_:
|
|
271
|
+
return int(childkey_take_)
|
|
272
|
+
|
|
273
|
+
except SubstrateRequestException as e:
|
|
274
|
+
print_error(f"Error querying ChildKeys: {format_error_message(e)}")
|
|
275
|
+
return None
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def prepare_child_proportions(children_with_proportions):
|
|
279
|
+
"""
|
|
280
|
+
Convert proportions to u64 and normalize, ensuring total does not exceed u64 max.
|
|
281
|
+
"""
|
|
282
|
+
children_u64 = [
|
|
283
|
+
(float_to_u64(proportion), child)
|
|
284
|
+
for proportion, child in children_with_proportions
|
|
285
|
+
]
|
|
286
|
+
total = sum(proportion for proportion, _ in children_u64)
|
|
287
|
+
|
|
288
|
+
if total > (2**64 - 1):
|
|
289
|
+
excess = total - (2**64 - 1)
|
|
290
|
+
if excess > (2**64 * 0.01): # Example threshold of 1% of u64 max
|
|
291
|
+
raise ValueError("Excess is too great to normalize proportions")
|
|
292
|
+
largest_child_index = max(
|
|
293
|
+
range(len(children_u64)), key=lambda i: children_u64[i][0]
|
|
294
|
+
)
|
|
295
|
+
children_u64[largest_child_index] = (
|
|
296
|
+
children_u64[largest_child_index][0] - excess,
|
|
297
|
+
children_u64[largest_child_index][1],
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
return children_u64
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
async def get_children(
|
|
304
|
+
wallet: Wallet, meshtensor: "MeshtensorInterface", netuid: Optional[int] = None
|
|
305
|
+
):
|
|
306
|
+
# TODO meshlet asks separately for the hotkey from the user, should we do this, or the way we do it now?
|
|
307
|
+
"""
|
|
308
|
+
Retrieves the child hotkeys for the specified wallet.
|
|
309
|
+
|
|
310
|
+
Args:
|
|
311
|
+
- wallet: The wallet object containing the hotkey information.
|
|
312
|
+
Type: Wallet
|
|
313
|
+
- meshtensor: Interface to interact with the meshtensor network.
|
|
314
|
+
Type: MeshtensorInterface
|
|
315
|
+
- netuid: Optional subnet identifier. If not provided, retrieves data for all subnets.
|
|
316
|
+
Type: Optional[int]
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
- If netuid is specified, returns the list of child hotkeys for the given netuid.
|
|
320
|
+
Type: List[tuple[int, str]]
|
|
321
|
+
- If netuid is not specified, generates and prints a summary table of all child hotkeys across all subnets.
|
|
322
|
+
"""
|
|
323
|
+
|
|
324
|
+
async def get_take(child: tuple, netuid__: int) -> float:
|
|
325
|
+
"""
|
|
326
|
+
Get the take value for a given meshtensor, hotkey, and netuid.
|
|
327
|
+
|
|
328
|
+
Arguments:
|
|
329
|
+
child: The hotkey to retrieve the take value for.
|
|
330
|
+
netuid__: the netuid to retrieve the take value for.
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
The take value as a float. If the take value is not available, it returns 0.
|
|
334
|
+
|
|
335
|
+
"""
|
|
336
|
+
child_hotkey = child[1]
|
|
337
|
+
take_u16 = await get_childkey_take(
|
|
338
|
+
meshtensor=meshtensor, hotkey=child_hotkey, netuid=netuid__
|
|
339
|
+
)
|
|
340
|
+
if take_u16:
|
|
341
|
+
return u16_to_float(take_u16)
|
|
342
|
+
else:
|
|
343
|
+
return 0
|
|
344
|
+
|
|
345
|
+
async def _render_table(
|
|
346
|
+
parent_hotkey: str,
|
|
347
|
+
netuid_children_: list[tuple[int, list[tuple[int, str]]]],
|
|
348
|
+
):
|
|
349
|
+
"""
|
|
350
|
+
Retrieves and renders children hotkeys and their details for a given parent hotkey.
|
|
351
|
+
"""
|
|
352
|
+
# Initialize Rich table for pretty printing
|
|
353
|
+
table = Table(
|
|
354
|
+
header_style="bold white",
|
|
355
|
+
border_style="bright_black",
|
|
356
|
+
style="dim",
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
# Add columns to the table with specific styles
|
|
360
|
+
table.add_column("Netuid", style="dark_orange", no_wrap=True, justify="center")
|
|
361
|
+
table.add_column("Child Hotkey", style="bold bright_magenta")
|
|
362
|
+
table.add_column("Proportion", style="bold cyan", no_wrap=True, justify="right")
|
|
363
|
+
table.add_column(
|
|
364
|
+
"Childkey Take", style="light_goldenrod2", no_wrap=True, justify="right"
|
|
365
|
+
)
|
|
366
|
+
table.add_column(
|
|
367
|
+
"Current Stake Weight", style="bold red", no_wrap=True, justify="right"
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
if not netuid_children_:
|
|
371
|
+
console.print(table)
|
|
372
|
+
console.print(
|
|
373
|
+
f"[bold red]There are currently no child hotkeys with parent hotkey: "
|
|
374
|
+
f"{wallet.name} | {wallet.hotkey_str} ({parent_hotkey}).[/bold red]"
|
|
375
|
+
)
|
|
376
|
+
return
|
|
377
|
+
|
|
378
|
+
# calculate totals per subnet
|
|
379
|
+
total_proportion = 0
|
|
380
|
+
total_stake_weight = 0
|
|
381
|
+
|
|
382
|
+
netuid_children_.sort(key=lambda x: x[0]) # Sort by netuid in ascending order
|
|
383
|
+
unique_keys = set(
|
|
384
|
+
[parent_hotkey]
|
|
385
|
+
+ [s for _, child_list in netuid_children_ for _, s in child_list]
|
|
386
|
+
)
|
|
387
|
+
hotkey_stake_dict = await meshtensor.get_total_stake_for_hotkey(
|
|
388
|
+
*unique_keys,
|
|
389
|
+
netuids=[n[0] for n in netuid_children_],
|
|
390
|
+
)
|
|
391
|
+
parent_total = sum(hotkey_stake_dict[parent_hotkey].values())
|
|
392
|
+
insert_text = (
|
|
393
|
+
" "
|
|
394
|
+
if netuid is None
|
|
395
|
+
else f" on netuids: {', '.join(str(n[0]) for n in netuid_children_)} "
|
|
396
|
+
)
|
|
397
|
+
console.print(
|
|
398
|
+
f"The total stake of parent hotkey '{parent_hotkey}'{insert_text}is {parent_total}."
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
for index, (child_netuid, children_) in enumerate(netuid_children_):
|
|
402
|
+
# calculate totals
|
|
403
|
+
total_proportion_per_netuid = 0
|
|
404
|
+
total_stake_weight_per_netuid = 0
|
|
405
|
+
avg_take_per_netuid = 0.0
|
|
406
|
+
|
|
407
|
+
hotkey_stake: dict[int, Balance] = hotkey_stake_dict[parent_hotkey]
|
|
408
|
+
|
|
409
|
+
children_info = []
|
|
410
|
+
child_takes = await asyncio.gather(
|
|
411
|
+
*[get_take(c, child_netuid) for c in children_]
|
|
412
|
+
)
|
|
413
|
+
for child, child_take in zip(children_, child_takes):
|
|
414
|
+
proportion = child[0]
|
|
415
|
+
child_hotkey = child[1]
|
|
416
|
+
|
|
417
|
+
# add to totals
|
|
418
|
+
avg_take_per_netuid += child_take
|
|
419
|
+
|
|
420
|
+
converted_proportion = u64_to_float(proportion)
|
|
421
|
+
|
|
422
|
+
children_info.append(
|
|
423
|
+
(
|
|
424
|
+
converted_proportion,
|
|
425
|
+
child_hotkey,
|
|
426
|
+
hotkey_stake_dict[child_hotkey][child_netuid],
|
|
427
|
+
child_take,
|
|
428
|
+
)
|
|
429
|
+
)
|
|
430
|
+
|
|
431
|
+
children_info.sort(
|
|
432
|
+
key=lambda x: x[0], reverse=True
|
|
433
|
+
) # sorting by proportion (highest first)
|
|
434
|
+
|
|
435
|
+
for proportion_, hotkey, stake, child_take in children_info:
|
|
436
|
+
proportion_percent = proportion_ * 100 # Proportion in percent
|
|
437
|
+
proportion_tao = (
|
|
438
|
+
hotkey_stake[child_netuid].tao * proportion_
|
|
439
|
+
) # Proportion in MESH
|
|
440
|
+
|
|
441
|
+
total_proportion_per_netuid += proportion_percent
|
|
442
|
+
|
|
443
|
+
# Conditionally format text
|
|
444
|
+
proportion_str = f"{proportion_percent:.3f}% ({proportion_tao:.3f}τ)"
|
|
445
|
+
stake_weight = stake.tao + proportion_tao
|
|
446
|
+
total_stake_weight_per_netuid += stake_weight
|
|
447
|
+
take_str = f"{child_take * 100:.3f}%"
|
|
448
|
+
|
|
449
|
+
hotkey = Text(hotkey, style="italic red" if proportion_ == 0 else "")
|
|
450
|
+
table.add_row(
|
|
451
|
+
str(child_netuid),
|
|
452
|
+
hotkey,
|
|
453
|
+
proportion_str,
|
|
454
|
+
take_str,
|
|
455
|
+
str(f"{stake_weight:.3f}"),
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
avg_take_per_netuid = avg_take_per_netuid / len(children_info)
|
|
459
|
+
|
|
460
|
+
# add totals row for this netuid
|
|
461
|
+
table.add_row(
|
|
462
|
+
"",
|
|
463
|
+
"[dim]Total[/dim]",
|
|
464
|
+
f"[dim]{total_proportion_per_netuid:.3f}%[/dim]",
|
|
465
|
+
f"[dim](avg) {avg_take_per_netuid * 100:.3f}%[/dim]",
|
|
466
|
+
f"[dim]{total_stake_weight_per_netuid:.3f}τ[/dim]",
|
|
467
|
+
style="dim",
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
# add to grand totals
|
|
471
|
+
total_proportion += total_proportion_per_netuid
|
|
472
|
+
total_stake_weight += total_stake_weight_per_netuid
|
|
473
|
+
|
|
474
|
+
# Add a dividing line if there are more than one netuid
|
|
475
|
+
if len(netuid_children_) > 1:
|
|
476
|
+
table.add_section()
|
|
477
|
+
|
|
478
|
+
console.print(table)
|
|
479
|
+
|
|
480
|
+
# Core logic for get_children
|
|
481
|
+
if netuid is None:
|
|
482
|
+
# get all netuids
|
|
483
|
+
netuids = await meshtensor.get_all_subnet_netuids()
|
|
484
|
+
netuid_children_tuples = []
|
|
485
|
+
for netuid_ in netuids:
|
|
486
|
+
success, children, err_mg = await meshtensor.get_children(
|
|
487
|
+
get_hotkey_pub_ss58(wallet), netuid_
|
|
488
|
+
)
|
|
489
|
+
if children:
|
|
490
|
+
netuid_children_tuples.append((netuid_, children))
|
|
491
|
+
if not success:
|
|
492
|
+
print_error(
|
|
493
|
+
f"Failed to get children from meshtensor {netuid_}: {err_mg}"
|
|
494
|
+
)
|
|
495
|
+
await _render_table(get_hotkey_pub_ss58(wallet), netuid_children_tuples)
|
|
496
|
+
else:
|
|
497
|
+
success, children, err_mg = await meshtensor.get_children(
|
|
498
|
+
get_hotkey_pub_ss58(wallet), netuid
|
|
499
|
+
)
|
|
500
|
+
if not success:
|
|
501
|
+
print_error(f"Failed to get children from meshtensor: {err_mg}")
|
|
502
|
+
if children:
|
|
503
|
+
netuid_children_tuples = [(netuid, children)]
|
|
504
|
+
await _render_table(get_hotkey_pub_ss58(wallet), netuid_children_tuples)
|
|
505
|
+
|
|
506
|
+
return children
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
async def set_children(
|
|
510
|
+
wallet: Wallet,
|
|
511
|
+
meshtensor: "MeshtensorInterface",
|
|
512
|
+
children: list[str],
|
|
513
|
+
proportions: list[float],
|
|
514
|
+
netuid: Optional[int] = None,
|
|
515
|
+
wait_for_inclusion: bool = True,
|
|
516
|
+
wait_for_finalization: bool = True,
|
|
517
|
+
prompt: bool = True,
|
|
518
|
+
json_output: bool = False,
|
|
519
|
+
proxy: Optional[str] = None,
|
|
520
|
+
):
|
|
521
|
+
"""Set children hotkeys."""
|
|
522
|
+
# TODO holy shit I hate this. It needs to be rewritten.
|
|
523
|
+
# Validate children SS58 addresses
|
|
524
|
+
# TODO check to see if this should be allowed to be specified by user instead of pulling from wallet
|
|
525
|
+
hotkey = get_hotkey_pub_ss58(wallet)
|
|
526
|
+
for child in children:
|
|
527
|
+
if not is_valid_ss58_address(child):
|
|
528
|
+
print_error(f"Invalid SS58 address: {child}")
|
|
529
|
+
return
|
|
530
|
+
if child == hotkey:
|
|
531
|
+
print_error("Cannot set yourself as a child.")
|
|
532
|
+
return
|
|
533
|
+
|
|
534
|
+
total_proposed = sum(proportions)
|
|
535
|
+
if total_proposed > 1:
|
|
536
|
+
raise ValueError(
|
|
537
|
+
f"Invalid proportion: The sum of all proportions cannot be greater than 1. "
|
|
538
|
+
f"Proposed sum of proportions is {total_proposed}."
|
|
539
|
+
)
|
|
540
|
+
children_with_proportions = list(zip(proportions, children))
|
|
541
|
+
successes = {}
|
|
542
|
+
if netuid is not None:
|
|
543
|
+
success, message, ext_id = await set_children_extrinsic(
|
|
544
|
+
meshtensor=meshtensor,
|
|
545
|
+
wallet=wallet,
|
|
546
|
+
netuid=netuid,
|
|
547
|
+
hotkey=hotkey,
|
|
548
|
+
proxy=proxy,
|
|
549
|
+
children_with_proportions=children_with_proportions,
|
|
550
|
+
prompt=prompt,
|
|
551
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
552
|
+
wait_for_finalization=wait_for_finalization,
|
|
553
|
+
)
|
|
554
|
+
successes[netuid] = {
|
|
555
|
+
"success": success,
|
|
556
|
+
"error": message,
|
|
557
|
+
"completion_block": None,
|
|
558
|
+
"set_block": None,
|
|
559
|
+
"extrinsic_identifier": ext_id,
|
|
560
|
+
}
|
|
561
|
+
# Result
|
|
562
|
+
if success:
|
|
563
|
+
if wait_for_inclusion and wait_for_finalization:
|
|
564
|
+
current_block, completion_block = await get_childkey_completion_block(
|
|
565
|
+
meshtensor, netuid
|
|
566
|
+
)
|
|
567
|
+
successes[netuid]["completion_block"] = completion_block
|
|
568
|
+
successes[netuid]["set_block"] = current_block
|
|
569
|
+
console.print(
|
|
570
|
+
f"Your childkey request has been submitted. It will be completed around block {completion_block}. "
|
|
571
|
+
f"The current block is {current_block}"
|
|
572
|
+
)
|
|
573
|
+
print_success("Set children hotkeys.")
|
|
574
|
+
else:
|
|
575
|
+
print_error(f"Unable to set children hotkeys. {message}")
|
|
576
|
+
else:
|
|
577
|
+
# set children on all subnets that parent is registered on
|
|
578
|
+
netuids = await meshtensor.get_all_subnet_netuids()
|
|
579
|
+
for netuid_ in netuids:
|
|
580
|
+
if netuid_ == 0: # dont include root network
|
|
581
|
+
continue
|
|
582
|
+
console.print(f"Setting children on netuid {netuid_}.")
|
|
583
|
+
success, message, ext_id = await set_children_extrinsic(
|
|
584
|
+
meshtensor=meshtensor,
|
|
585
|
+
wallet=wallet,
|
|
586
|
+
netuid=netuid_,
|
|
587
|
+
hotkey=hotkey,
|
|
588
|
+
proxy=proxy,
|
|
589
|
+
children_with_proportions=children_with_proportions,
|
|
590
|
+
prompt=prompt,
|
|
591
|
+
wait_for_inclusion=True,
|
|
592
|
+
wait_for_finalization=False,
|
|
593
|
+
)
|
|
594
|
+
current_block, completion_block = await get_childkey_completion_block(
|
|
595
|
+
meshtensor, netuid_
|
|
596
|
+
)
|
|
597
|
+
successes[netuid_] = {
|
|
598
|
+
"success": success,
|
|
599
|
+
"error": message,
|
|
600
|
+
"completion_block": completion_block,
|
|
601
|
+
"set_block": current_block,
|
|
602
|
+
"extrinsic_identifier": ext_id,
|
|
603
|
+
}
|
|
604
|
+
console.print(
|
|
605
|
+
f"Your childkey request for netuid {netuid_} has been submitted. It will be completed around "
|
|
606
|
+
f"block {completion_block}. The current block is {current_block}."
|
|
607
|
+
)
|
|
608
|
+
print_success("Sent set children request for all subnets.")
|
|
609
|
+
if json_output:
|
|
610
|
+
json_console.print(json.dumps(successes))
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
async def revoke_children(
|
|
614
|
+
wallet: Wallet,
|
|
615
|
+
meshtensor: "MeshtensorInterface",
|
|
616
|
+
netuid: Optional[int] = None,
|
|
617
|
+
proxy: Optional[str] = None,
|
|
618
|
+
wait_for_inclusion: bool = True,
|
|
619
|
+
wait_for_finalization: bool = True,
|
|
620
|
+
prompt: bool = True,
|
|
621
|
+
json_output: bool = False,
|
|
622
|
+
):
|
|
623
|
+
"""
|
|
624
|
+
Revokes the children hotkeys associated with a given network identifier (netuid).
|
|
625
|
+
"""
|
|
626
|
+
dict_output = {}
|
|
627
|
+
if netuid is not None:
|
|
628
|
+
success, message, ext_id = await set_children_extrinsic(
|
|
629
|
+
meshtensor=meshtensor,
|
|
630
|
+
wallet=wallet,
|
|
631
|
+
netuid=netuid,
|
|
632
|
+
hotkey=get_hotkey_pub_ss58(wallet),
|
|
633
|
+
children_with_proportions=[],
|
|
634
|
+
proxy=proxy,
|
|
635
|
+
prompt=prompt,
|
|
636
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
637
|
+
wait_for_finalization=wait_for_finalization,
|
|
638
|
+
)
|
|
639
|
+
dict_output[netuid] = {
|
|
640
|
+
"success": success,
|
|
641
|
+
"error": message,
|
|
642
|
+
"set_block": None,
|
|
643
|
+
"completion_block": None,
|
|
644
|
+
"extrinsic_identifier": ext_id,
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
# Result
|
|
648
|
+
if success:
|
|
649
|
+
current_block, completion_block = await get_childkey_completion_block(
|
|
650
|
+
meshtensor, netuid
|
|
651
|
+
)
|
|
652
|
+
dict_output[netuid]["completion_block"] = completion_block
|
|
653
|
+
dict_output[netuid]["set_block"] = current_block
|
|
654
|
+
console.print(
|
|
655
|
+
f":white_heavy_check_mark: Your childkey revocation request for netuid {netuid} has been submitted. "
|
|
656
|
+
f"It will be completed around block {completion_block}. The current block is {current_block}"
|
|
657
|
+
)
|
|
658
|
+
else:
|
|
659
|
+
console.print(f"Unable to revoke children hotkeys. {message}")
|
|
660
|
+
else:
|
|
661
|
+
# revoke children from ALL netuids
|
|
662
|
+
netuids = await meshtensor.get_all_subnet_netuids()
|
|
663
|
+
for netuid_ in netuids:
|
|
664
|
+
if netuid_ == 0: # dont include root network
|
|
665
|
+
continue
|
|
666
|
+
console.print(f"Revoking children from netuid {netuid_}.")
|
|
667
|
+
success, message, ext_id = await set_children_extrinsic(
|
|
668
|
+
meshtensor=meshtensor,
|
|
669
|
+
wallet=wallet,
|
|
670
|
+
netuid=netuid, # TODO should this be able to allow netuid = None ?
|
|
671
|
+
hotkey=get_hotkey_pub_ss58(wallet),
|
|
672
|
+
children_with_proportions=[],
|
|
673
|
+
proxy=proxy,
|
|
674
|
+
prompt=prompt,
|
|
675
|
+
wait_for_inclusion=True,
|
|
676
|
+
wait_for_finalization=False,
|
|
677
|
+
)
|
|
678
|
+
dict_output[netuid_] = {
|
|
679
|
+
"success": success,
|
|
680
|
+
"error": message,
|
|
681
|
+
"set_block": None,
|
|
682
|
+
"completion_block": None,
|
|
683
|
+
"extrinsic_identifier": ext_id,
|
|
684
|
+
}
|
|
685
|
+
if success:
|
|
686
|
+
current_block, completion_block = await get_childkey_completion_block(
|
|
687
|
+
meshtensor, netuid_
|
|
688
|
+
)
|
|
689
|
+
dict_output[netuid_]["completion_block"] = completion_block
|
|
690
|
+
dict_output[netuid_]["set_block"] = current_block
|
|
691
|
+
console.print(
|
|
692
|
+
f":white_heavy_check_mark: Your childkey revocation request for netuid {netuid_} has been "
|
|
693
|
+
f"submitted. It will be completed around block {completion_block}. The current block "
|
|
694
|
+
f"is {current_block}"
|
|
695
|
+
)
|
|
696
|
+
else:
|
|
697
|
+
print_error(
|
|
698
|
+
f"Childkey revocation failed for netuid {netuid_}: {message}."
|
|
699
|
+
)
|
|
700
|
+
if json_output:
|
|
701
|
+
json_console.print(json.dumps(dict_output))
|
|
702
|
+
|
|
703
|
+
|
|
704
|
+
async def childkey_take(
|
|
705
|
+
wallet: Wallet,
|
|
706
|
+
meshtensor: "MeshtensorInterface",
|
|
707
|
+
take: Optional[float],
|
|
708
|
+
hotkey: Optional[str] = None,
|
|
709
|
+
netuid: Optional[int] = None,
|
|
710
|
+
proxy: Optional[str] = None,
|
|
711
|
+
wait_for_inclusion: bool = True,
|
|
712
|
+
wait_for_finalization: bool = True,
|
|
713
|
+
prompt: bool = True,
|
|
714
|
+
decline: bool = False,
|
|
715
|
+
quiet: bool = False,
|
|
716
|
+
) -> list[tuple[Optional[int], bool, Optional[str]]]:
|
|
717
|
+
"""
|
|
718
|
+
Get or Set childkey take.
|
|
719
|
+
|
|
720
|
+
Returns:
|
|
721
|
+
List of (netuid, success, extrinsic identifier) for specified netuid (or all) and their success in setting take
|
|
722
|
+
"""
|
|
723
|
+
|
|
724
|
+
def validate_take_value(take_value: float) -> bool:
|
|
725
|
+
if not (0 <= take_value <= 0.18):
|
|
726
|
+
print_error(f"Invalid take value: {take_value}")
|
|
727
|
+
return False
|
|
728
|
+
return True
|
|
729
|
+
|
|
730
|
+
async def display_chk_take(ss58, take_netuid) -> float:
|
|
731
|
+
"""Print single key take for hotkey and netuid"""
|
|
732
|
+
chk_take = await get_childkey_take(
|
|
733
|
+
meshtensor=meshtensor, netuid=take_netuid, hotkey=ss58
|
|
734
|
+
)
|
|
735
|
+
if chk_take is None:
|
|
736
|
+
chk_take = 0
|
|
737
|
+
chk_take = u16_to_float(chk_take)
|
|
738
|
+
console.print(
|
|
739
|
+
f"Child take for {ss58} is: {chk_take * 100:.2f}% on netuid {take_netuid}."
|
|
740
|
+
)
|
|
741
|
+
return chk_take
|
|
742
|
+
|
|
743
|
+
async def chk_all_subnets(ss58):
|
|
744
|
+
"""Aggregate data for childkey take from all subnets"""
|
|
745
|
+
all_netuids = await meshtensor.get_all_subnet_netuids()
|
|
746
|
+
takes = []
|
|
747
|
+
for subnet in all_netuids:
|
|
748
|
+
if subnet == 0:
|
|
749
|
+
continue
|
|
750
|
+
curr_take = await get_childkey_take(
|
|
751
|
+
meshtensor=meshtensor, netuid=subnet, hotkey=ss58
|
|
752
|
+
)
|
|
753
|
+
if curr_take is not None:
|
|
754
|
+
take_value = u16_to_float(curr_take)
|
|
755
|
+
takes.append((subnet, take_value * 100))
|
|
756
|
+
table = Table(
|
|
757
|
+
title=f"Current Child Takes for [bright_magenta]{ss58}[/bright_magenta]"
|
|
758
|
+
)
|
|
759
|
+
table.add_column("Netuid", justify="center", style="cyan")
|
|
760
|
+
table.add_column("Take (%)", justify="right", style="magenta")
|
|
761
|
+
|
|
762
|
+
for take_netuid, take_value in takes:
|
|
763
|
+
table.add_row(str(take_netuid), f"{take_value:.2f}%")
|
|
764
|
+
|
|
765
|
+
console.print(table)
|
|
766
|
+
|
|
767
|
+
async def set_chk_take_subnet(
|
|
768
|
+
subnet: int, chk_take: float
|
|
769
|
+
) -> tuple[bool, Optional[str]]:
|
|
770
|
+
"""Set the childkey take for a single subnet"""
|
|
771
|
+
success_, message, ext_id_ = await set_childkey_take_extrinsic(
|
|
772
|
+
meshtensor=meshtensor,
|
|
773
|
+
wallet=wallet,
|
|
774
|
+
netuid=subnet,
|
|
775
|
+
hotkey=get_hotkey_pub_ss58(wallet),
|
|
776
|
+
take=chk_take,
|
|
777
|
+
proxy=proxy,
|
|
778
|
+
prompt=prompt,
|
|
779
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
780
|
+
wait_for_finalization=wait_for_finalization,
|
|
781
|
+
)
|
|
782
|
+
# Result
|
|
783
|
+
if success_:
|
|
784
|
+
print_success("Set childkey take.")
|
|
785
|
+
console.print(
|
|
786
|
+
f"The childkey take for {get_hotkey_pub_ss58(wallet)} is now set to {take * 100:.2f}%."
|
|
787
|
+
)
|
|
788
|
+
return True, ext_id_
|
|
789
|
+
else:
|
|
790
|
+
print_error(f"Unable to set childkey take. {message}")
|
|
791
|
+
return False, ext_id_
|
|
792
|
+
|
|
793
|
+
# Print childkey take for other user and return (dont offer to change take rate)
|
|
794
|
+
wallet_hk = get_hotkey_pub_ss58(wallet)
|
|
795
|
+
if not hotkey or hotkey == wallet_hk:
|
|
796
|
+
hotkey = wallet_hk
|
|
797
|
+
if hotkey != wallet_hk or not take:
|
|
798
|
+
# display childkey take for other users
|
|
799
|
+
if netuid:
|
|
800
|
+
await display_chk_take(hotkey, netuid)
|
|
801
|
+
if take:
|
|
802
|
+
console.print(
|
|
803
|
+
f"Hotkey {hotkey} not associated with wallet {wallet.name}."
|
|
804
|
+
)
|
|
805
|
+
return [(netuid, False, None)]
|
|
806
|
+
else:
|
|
807
|
+
# show child hotkey take on all subnets
|
|
808
|
+
await chk_all_subnets(hotkey)
|
|
809
|
+
if take:
|
|
810
|
+
console.print(
|
|
811
|
+
f"Hotkey {hotkey} not associated with wallet {wallet.name}."
|
|
812
|
+
)
|
|
813
|
+
return [(netuid, False, None)]
|
|
814
|
+
|
|
815
|
+
# Validate child SS58 addresses
|
|
816
|
+
if not take:
|
|
817
|
+
if not confirm_action(
|
|
818
|
+
"Would you like to change the child take?", decline=decline, quiet=quiet
|
|
819
|
+
):
|
|
820
|
+
return [(netuid, False, None)]
|
|
821
|
+
new_take_value = -1.0
|
|
822
|
+
while not validate_take_value(new_take_value):
|
|
823
|
+
new_take_value = FloatPrompt.ask(
|
|
824
|
+
"Enter the new take value (between 0 and 0.18)"
|
|
825
|
+
)
|
|
826
|
+
take = new_take_value
|
|
827
|
+
else:
|
|
828
|
+
if not validate_take_value(take):
|
|
829
|
+
return [(netuid, False, None)]
|
|
830
|
+
|
|
831
|
+
if netuid:
|
|
832
|
+
success, ext_id = await set_chk_take_subnet(subnet=netuid, chk_take=take)
|
|
833
|
+
return [(netuid, success, ext_id)]
|
|
834
|
+
else:
|
|
835
|
+
new_take_netuids = IntPrompt.ask(
|
|
836
|
+
"Enter netuid (leave blank for all)", default=None, show_default=True
|
|
837
|
+
)
|
|
838
|
+
|
|
839
|
+
if new_take_netuids:
|
|
840
|
+
success, ext_id = await set_chk_take_subnet(
|
|
841
|
+
subnet=new_take_netuids, chk_take=take
|
|
842
|
+
)
|
|
843
|
+
return [(new_take_netuids, success, ext_id)]
|
|
844
|
+
|
|
845
|
+
else:
|
|
846
|
+
netuids = await meshtensor.get_all_subnet_netuids()
|
|
847
|
+
output_list = []
|
|
848
|
+
for netuid_ in netuids:
|
|
849
|
+
if netuid_ == 0:
|
|
850
|
+
continue
|
|
851
|
+
console.print(f"Setting take of {take * 100:.2f}% on netuid {netuid_}.")
|
|
852
|
+
result, _, ext_id = await set_childkey_take_extrinsic(
|
|
853
|
+
meshtensor=meshtensor,
|
|
854
|
+
wallet=wallet,
|
|
855
|
+
netuid=netuid_,
|
|
856
|
+
hotkey=wallet_hk,
|
|
857
|
+
take=take,
|
|
858
|
+
proxy=proxy,
|
|
859
|
+
prompt=prompt,
|
|
860
|
+
wait_for_inclusion=True,
|
|
861
|
+
wait_for_finalization=False,
|
|
862
|
+
)
|
|
863
|
+
output_list.append((netuid_, result, ext_id))
|
|
864
|
+
print_success(f"Sent childkey take of {take * 100:.2f}% to all subnets.")
|
|
865
|
+
return output_list
|