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,700 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING, Optional
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from async_substrate_interface.errors import StateDiscardedError
|
|
5
|
+
from rich.prompt import Prompt, FloatPrompt, IntPrompt
|
|
6
|
+
from scalecodec import GenericCall, ScaleBytes
|
|
7
|
+
|
|
8
|
+
from meshtensor_cli.src import COLORS
|
|
9
|
+
from meshtensor_cli.src.meshtensor.balances import Balance
|
|
10
|
+
from meshtensor_cli.src.meshtensor.utils import (
|
|
11
|
+
confirm_action,
|
|
12
|
+
print_extrinsic_id,
|
|
13
|
+
json_console,
|
|
14
|
+
console,
|
|
15
|
+
print_error,
|
|
16
|
+
print_success,
|
|
17
|
+
unlock_key,
|
|
18
|
+
ProxyAddressBook,
|
|
19
|
+
is_valid_ss58_address_prompt,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from meshtensor_cli.src.meshtensor.meshtensor_interface import MeshtensorInterface
|
|
24
|
+
from meshtensor_wallet.meshtensor_wallet import Wallet
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# TODO when 3.10 support is dropped in Oct 2026, remove this
|
|
28
|
+
if sys.version_info >= (3, 11):
|
|
29
|
+
from enum import StrEnum
|
|
30
|
+
else:
|
|
31
|
+
from enum import Enum
|
|
32
|
+
|
|
33
|
+
class StrEnum(str, Enum):
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ProxyType(StrEnum):
|
|
38
|
+
Any = "Any"
|
|
39
|
+
Owner = "Owner"
|
|
40
|
+
NonCritical = "NonCritical"
|
|
41
|
+
NonTransfer = "NonTransfer"
|
|
42
|
+
Senate = "Senate"
|
|
43
|
+
NonFungible = "NonFungible"
|
|
44
|
+
Triumvirate = "Triumvirate"
|
|
45
|
+
Governance = "Governance"
|
|
46
|
+
Staking = "Staking"
|
|
47
|
+
Registration = "Registration"
|
|
48
|
+
Transfer = "Transfer"
|
|
49
|
+
SmallTransfer = "SmallTransfer"
|
|
50
|
+
RootWeights = "RootWeights"
|
|
51
|
+
ChildKeys = "ChildKeys"
|
|
52
|
+
SudoUncheckedSetCode = "SudoUncheckedSetCode"
|
|
53
|
+
SwapHotkey = "SwapHotkey"
|
|
54
|
+
SubnetLeaseBeneficiary = "SubnetLeaseBeneficiary"
|
|
55
|
+
RootClaim = "RootClaim"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# TODO add announce with also --reject and --remove
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
async def submit_proxy(
|
|
62
|
+
meshtensor: "MeshtensorInterface",
|
|
63
|
+
wallet: "Wallet",
|
|
64
|
+
call: GenericCall,
|
|
65
|
+
wait_for_inclusion: bool,
|
|
66
|
+
wait_for_finalization: bool,
|
|
67
|
+
period: int,
|
|
68
|
+
json_output: bool,
|
|
69
|
+
proxy: Optional[str] = None,
|
|
70
|
+
announce_only: bool = False,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""
|
|
73
|
+
Submits the prepared call to the chain
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
None, prints out the result according to `json_output` flag.
|
|
77
|
+
|
|
78
|
+
"""
|
|
79
|
+
success, msg, receipt = await meshtensor.sign_and_send_extrinsic(
|
|
80
|
+
call=call,
|
|
81
|
+
wallet=wallet,
|
|
82
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
83
|
+
wait_for_finalization=wait_for_finalization,
|
|
84
|
+
era={"period": period},
|
|
85
|
+
proxy=proxy,
|
|
86
|
+
announce_only=announce_only,
|
|
87
|
+
)
|
|
88
|
+
if success:
|
|
89
|
+
if json_output:
|
|
90
|
+
json_console.print_json(
|
|
91
|
+
data={
|
|
92
|
+
"success": success,
|
|
93
|
+
"message": msg,
|
|
94
|
+
"extrinsic_identifier": await receipt.get_extrinsic_identifier(),
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
else:
|
|
98
|
+
await print_extrinsic_id(receipt)
|
|
99
|
+
print_success("Success!")
|
|
100
|
+
else:
|
|
101
|
+
if json_output:
|
|
102
|
+
json_console.print_json(
|
|
103
|
+
data={
|
|
104
|
+
"success": success,
|
|
105
|
+
"message": msg,
|
|
106
|
+
"extrinsic_identifier": None,
|
|
107
|
+
}
|
|
108
|
+
)
|
|
109
|
+
else:
|
|
110
|
+
print_error(f"Failed: {msg}")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
async def create_proxy(
|
|
114
|
+
meshtensor: "MeshtensorInterface",
|
|
115
|
+
wallet: "Wallet",
|
|
116
|
+
proxy_type: ProxyType,
|
|
117
|
+
delay: int,
|
|
118
|
+
idx: int,
|
|
119
|
+
prompt: bool,
|
|
120
|
+
decline: bool,
|
|
121
|
+
quiet: bool,
|
|
122
|
+
wait_for_inclusion: bool,
|
|
123
|
+
wait_for_finalization: bool,
|
|
124
|
+
period: int,
|
|
125
|
+
json_output: bool,
|
|
126
|
+
) -> None:
|
|
127
|
+
"""
|
|
128
|
+
Executes the create pure proxy call on the chain
|
|
129
|
+
"""
|
|
130
|
+
if prompt:
|
|
131
|
+
if not confirm_action(
|
|
132
|
+
f"This will create a Pure Proxy of type {proxy_type.value}. Do you want to proceed?",
|
|
133
|
+
decline=decline,
|
|
134
|
+
quiet=quiet,
|
|
135
|
+
):
|
|
136
|
+
return None
|
|
137
|
+
if delay > 0:
|
|
138
|
+
if not confirm_action(
|
|
139
|
+
f"By adding a non-zero delay ({delay}), all proxy calls must be announced "
|
|
140
|
+
f"{delay} blocks before they will be able to be made. Continue?",
|
|
141
|
+
decline=decline,
|
|
142
|
+
quiet=quiet,
|
|
143
|
+
):
|
|
144
|
+
return None
|
|
145
|
+
if not (ulw := unlock_key(wallet, print_out=not json_output)).success:
|
|
146
|
+
if not json_output:
|
|
147
|
+
print_error(ulw.message)
|
|
148
|
+
else:
|
|
149
|
+
json_console.print_json(
|
|
150
|
+
data={
|
|
151
|
+
"success": ulw.success,
|
|
152
|
+
"message": ulw.message,
|
|
153
|
+
"extrinsic_identifier": None,
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
return None
|
|
157
|
+
call = await meshtensor.substrate.compose_call(
|
|
158
|
+
call_module="Proxy",
|
|
159
|
+
call_function="create_pure",
|
|
160
|
+
call_params={"proxy_type": proxy_type.value, "delay": delay, "index": idx},
|
|
161
|
+
)
|
|
162
|
+
success, msg, receipt = await meshtensor.sign_and_send_extrinsic(
|
|
163
|
+
call=call,
|
|
164
|
+
wallet=wallet,
|
|
165
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
166
|
+
wait_for_finalization=wait_for_finalization,
|
|
167
|
+
era={"period": period},
|
|
168
|
+
nonce=await meshtensor.substrate.get_account_next_index(
|
|
169
|
+
wallet.coldkeypub.ss58_address
|
|
170
|
+
),
|
|
171
|
+
)
|
|
172
|
+
if success:
|
|
173
|
+
created_pure = None
|
|
174
|
+
created_spawner = None
|
|
175
|
+
created_proxy_type = None
|
|
176
|
+
for event in await receipt.triggered_events:
|
|
177
|
+
if event["event_id"] == "PureCreated":
|
|
178
|
+
attrs = event["attributes"]
|
|
179
|
+
created_pure = attrs["pure"]
|
|
180
|
+
created_spawner = attrs["who"]
|
|
181
|
+
created_proxy_type = getattr(ProxyType, attrs["proxy_type"])
|
|
182
|
+
msg = (
|
|
183
|
+
f"Created pure '{created_pure}' "
|
|
184
|
+
f"from spawner '{created_spawner}' "
|
|
185
|
+
f"with proxy type '{created_proxy_type.value}' "
|
|
186
|
+
f"with delay {delay}."
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
if json_output:
|
|
190
|
+
json_console.print_json(
|
|
191
|
+
data={
|
|
192
|
+
"success": success,
|
|
193
|
+
"message": msg,
|
|
194
|
+
"data": {
|
|
195
|
+
"pure": created_pure,
|
|
196
|
+
"spawner": created_spawner,
|
|
197
|
+
"proxy_type": created_proxy_type.value,
|
|
198
|
+
"delay": delay,
|
|
199
|
+
},
|
|
200
|
+
"extrinsic_identifier": await receipt.get_extrinsic_identifier(),
|
|
201
|
+
}
|
|
202
|
+
)
|
|
203
|
+
else:
|
|
204
|
+
await print_extrinsic_id(receipt)
|
|
205
|
+
console.print(msg)
|
|
206
|
+
if not prompt:
|
|
207
|
+
console.print(
|
|
208
|
+
f" You can add this to your config with [blue]"
|
|
209
|
+
f"meshcli config add-proxy "
|
|
210
|
+
f"--name <PROXY_NAME> --address {created_pure} --proxy-type {created_proxy_type.value} "
|
|
211
|
+
f"--delay {delay} --spawner {created_spawner}"
|
|
212
|
+
f"[/blue]"
|
|
213
|
+
)
|
|
214
|
+
else:
|
|
215
|
+
if confirm_action(
|
|
216
|
+
"Would you like to add this to your address book?",
|
|
217
|
+
decline=decline,
|
|
218
|
+
quiet=quiet,
|
|
219
|
+
):
|
|
220
|
+
proxy_name = Prompt.ask("Name this proxy")
|
|
221
|
+
note = Prompt.ask(
|
|
222
|
+
"[Optional] Add a note for this proxy", default=""
|
|
223
|
+
)
|
|
224
|
+
with ProxyAddressBook.get_db() as (conn, cursor):
|
|
225
|
+
ProxyAddressBook.add_entry(
|
|
226
|
+
conn,
|
|
227
|
+
cursor,
|
|
228
|
+
name=proxy_name,
|
|
229
|
+
ss58_address=created_pure,
|
|
230
|
+
delay=delay,
|
|
231
|
+
proxy_type=created_proxy_type.value,
|
|
232
|
+
note=note,
|
|
233
|
+
spawner=created_spawner,
|
|
234
|
+
)
|
|
235
|
+
console.print(
|
|
236
|
+
f"Added to Proxy Address Book.\n"
|
|
237
|
+
f"Show this information with [{COLORS.G.ARG}]meshcli config proxies[/{COLORS.G.ARG}]"
|
|
238
|
+
)
|
|
239
|
+
return None
|
|
240
|
+
else:
|
|
241
|
+
if json_output:
|
|
242
|
+
json_console.print_json(
|
|
243
|
+
data={
|
|
244
|
+
"success": success,
|
|
245
|
+
"message": msg,
|
|
246
|
+
"data": None,
|
|
247
|
+
"extrinsic_identifier": None,
|
|
248
|
+
}
|
|
249
|
+
)
|
|
250
|
+
else:
|
|
251
|
+
print_error(f"Failed to create pure proxy: {msg}")
|
|
252
|
+
return None
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
async def remove_proxy(
|
|
256
|
+
meshtensor: "MeshtensorInterface",
|
|
257
|
+
wallet: "Wallet",
|
|
258
|
+
proxy_type: ProxyType,
|
|
259
|
+
delegate: str,
|
|
260
|
+
delay: int,
|
|
261
|
+
prompt: bool,
|
|
262
|
+
decline: bool,
|
|
263
|
+
quiet: bool,
|
|
264
|
+
wait_for_inclusion: bool,
|
|
265
|
+
wait_for_finalization: bool,
|
|
266
|
+
period: int,
|
|
267
|
+
json_output: bool,
|
|
268
|
+
) -> None:
|
|
269
|
+
"""
|
|
270
|
+
Executes the remove proxy call on the chain
|
|
271
|
+
"""
|
|
272
|
+
if prompt:
|
|
273
|
+
if not confirm_action(
|
|
274
|
+
f"This will remove a proxy of type {proxy_type.value} for delegate {delegate}."
|
|
275
|
+
f"Do you want to proceed?",
|
|
276
|
+
decline=decline,
|
|
277
|
+
quiet=quiet,
|
|
278
|
+
):
|
|
279
|
+
return None
|
|
280
|
+
if not (ulw := unlock_key(wallet, print_out=not json_output)).success:
|
|
281
|
+
if not json_output:
|
|
282
|
+
print_error(ulw.message)
|
|
283
|
+
else:
|
|
284
|
+
json_console.print_json(
|
|
285
|
+
data={
|
|
286
|
+
"success": ulw.success,
|
|
287
|
+
"message": ulw.message,
|
|
288
|
+
"extrinsic_identifier": None,
|
|
289
|
+
}
|
|
290
|
+
)
|
|
291
|
+
return None
|
|
292
|
+
call = await meshtensor.substrate.compose_call(
|
|
293
|
+
call_module="Proxy",
|
|
294
|
+
call_function="remove_proxy",
|
|
295
|
+
call_params={
|
|
296
|
+
"proxy_type": proxy_type.value,
|
|
297
|
+
"delay": delay,
|
|
298
|
+
"delegate": delegate,
|
|
299
|
+
},
|
|
300
|
+
)
|
|
301
|
+
return await submit_proxy(
|
|
302
|
+
meshtensor=meshtensor,
|
|
303
|
+
wallet=wallet,
|
|
304
|
+
call=call,
|
|
305
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
306
|
+
wait_for_finalization=wait_for_finalization,
|
|
307
|
+
period=period,
|
|
308
|
+
json_output=json_output,
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
async def add_proxy(
|
|
313
|
+
meshtensor: "MeshtensorInterface",
|
|
314
|
+
wallet: "Wallet",
|
|
315
|
+
proxy_type: ProxyType,
|
|
316
|
+
delegate: str,
|
|
317
|
+
delay: int,
|
|
318
|
+
prompt: bool,
|
|
319
|
+
decline: bool,
|
|
320
|
+
quiet: bool,
|
|
321
|
+
wait_for_inclusion: bool,
|
|
322
|
+
wait_for_finalization: bool,
|
|
323
|
+
period: int,
|
|
324
|
+
json_output: bool,
|
|
325
|
+
):
|
|
326
|
+
"""
|
|
327
|
+
Executes the add proxy call on the chain
|
|
328
|
+
"""
|
|
329
|
+
if prompt:
|
|
330
|
+
if not confirm_action(
|
|
331
|
+
f"This will add a proxy of type {proxy_type.value} for delegate {delegate}."
|
|
332
|
+
f"Do you want to proceed?",
|
|
333
|
+
decline=decline,
|
|
334
|
+
quiet=quiet,
|
|
335
|
+
):
|
|
336
|
+
return None
|
|
337
|
+
if delay > 0:
|
|
338
|
+
if not confirm_action(
|
|
339
|
+
f"By adding a non-zero delay ({delay}), all proxy calls must be announced "
|
|
340
|
+
f"{delay} blocks before they will be able to be made. Continue?",
|
|
341
|
+
decline=decline,
|
|
342
|
+
quiet=quiet,
|
|
343
|
+
):
|
|
344
|
+
return None
|
|
345
|
+
if not (ulw := unlock_key(wallet, print_out=not json_output)).success:
|
|
346
|
+
if not json_output:
|
|
347
|
+
print_error(ulw.message)
|
|
348
|
+
else:
|
|
349
|
+
json_console.print_json(
|
|
350
|
+
data={
|
|
351
|
+
"success": ulw.success,
|
|
352
|
+
"message": ulw.message,
|
|
353
|
+
"extrinsic_identifier": None,
|
|
354
|
+
}
|
|
355
|
+
)
|
|
356
|
+
return None
|
|
357
|
+
call = await meshtensor.substrate.compose_call(
|
|
358
|
+
call_module="Proxy",
|
|
359
|
+
call_function="add_proxy",
|
|
360
|
+
call_params={
|
|
361
|
+
"proxy_type": proxy_type.value,
|
|
362
|
+
"delay": delay,
|
|
363
|
+
"delegate": delegate,
|
|
364
|
+
},
|
|
365
|
+
)
|
|
366
|
+
success, msg, receipt = await meshtensor.sign_and_send_extrinsic(
|
|
367
|
+
call=call,
|
|
368
|
+
wallet=wallet,
|
|
369
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
370
|
+
wait_for_finalization=wait_for_finalization,
|
|
371
|
+
era={"period": period},
|
|
372
|
+
)
|
|
373
|
+
if success:
|
|
374
|
+
delegatee = None
|
|
375
|
+
delegator = None
|
|
376
|
+
created_proxy_type = None
|
|
377
|
+
for event in await receipt.triggered_events:
|
|
378
|
+
if event["event_id"] == "ProxyAdded":
|
|
379
|
+
attrs = event["attributes"]
|
|
380
|
+
delegatee = attrs["delegatee"]
|
|
381
|
+
delegator = attrs["delegator"]
|
|
382
|
+
created_proxy_type = getattr(ProxyType, attrs["proxy_type"])
|
|
383
|
+
break
|
|
384
|
+
msg = (
|
|
385
|
+
f"Added proxy delegatee '{delegatee}' "
|
|
386
|
+
f"from delegator '{delegator}' "
|
|
387
|
+
f"with proxy type '{created_proxy_type.value}' "
|
|
388
|
+
f"with delay {delay}."
|
|
389
|
+
)
|
|
390
|
+
|
|
391
|
+
if json_output:
|
|
392
|
+
json_console.print_json(
|
|
393
|
+
data={
|
|
394
|
+
"success": success,
|
|
395
|
+
"message": msg,
|
|
396
|
+
"data": {
|
|
397
|
+
"delegatee": delegatee,
|
|
398
|
+
"delegator": delegator,
|
|
399
|
+
"proxy_type": created_proxy_type.value,
|
|
400
|
+
"delay": delay,
|
|
401
|
+
},
|
|
402
|
+
"extrinsic_identifier": await receipt.get_extrinsic_identifier(),
|
|
403
|
+
}
|
|
404
|
+
)
|
|
405
|
+
else:
|
|
406
|
+
await print_extrinsic_id(receipt)
|
|
407
|
+
console.print(msg)
|
|
408
|
+
if not prompt:
|
|
409
|
+
console.print(
|
|
410
|
+
f" You can add this to your config with [blue]"
|
|
411
|
+
f"meshcli config add-proxy "
|
|
412
|
+
f"--name <PROXY_NAME> --address {delegatee} --proxy-type {created_proxy_type.value} --delegator "
|
|
413
|
+
f"{delegator} --delay {delay}"
|
|
414
|
+
f"[/blue]"
|
|
415
|
+
)
|
|
416
|
+
else:
|
|
417
|
+
if confirm_action(
|
|
418
|
+
"Would you like to add this to your address book?",
|
|
419
|
+
decline=decline,
|
|
420
|
+
quiet=quiet,
|
|
421
|
+
):
|
|
422
|
+
proxy_name = Prompt.ask("Name this proxy")
|
|
423
|
+
note = Prompt.ask(
|
|
424
|
+
"[Optional] Add a note for this proxy", default=""
|
|
425
|
+
)
|
|
426
|
+
with ProxyAddressBook.get_db() as (conn, cursor):
|
|
427
|
+
ProxyAddressBook.add_entry(
|
|
428
|
+
conn,
|
|
429
|
+
cursor,
|
|
430
|
+
name=proxy_name,
|
|
431
|
+
ss58_address=delegator,
|
|
432
|
+
delay=delay,
|
|
433
|
+
proxy_type=created_proxy_type.value,
|
|
434
|
+
note=note,
|
|
435
|
+
spawner=delegatee,
|
|
436
|
+
)
|
|
437
|
+
console.print(
|
|
438
|
+
f"Added to Proxy Address Book.\n"
|
|
439
|
+
f"Show this information with [{COLORS.G.ARG}]meshcli config proxies[/{COLORS.G.ARG}]"
|
|
440
|
+
)
|
|
441
|
+
else:
|
|
442
|
+
if json_output:
|
|
443
|
+
json_console.print_json(
|
|
444
|
+
data={
|
|
445
|
+
"success": success,
|
|
446
|
+
"message": msg,
|
|
447
|
+
"data": None,
|
|
448
|
+
"extrinsic_identifier": None,
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
else:
|
|
452
|
+
print_error(f"Failed to add proxy: {msg}")
|
|
453
|
+
return None
|
|
454
|
+
|
|
455
|
+
|
|
456
|
+
async def kill_proxy(
|
|
457
|
+
meshtensor: "MeshtensorInterface",
|
|
458
|
+
wallet: "Wallet",
|
|
459
|
+
proxy_type: ProxyType,
|
|
460
|
+
height: int,
|
|
461
|
+
ext_index: int,
|
|
462
|
+
spawner: Optional[str],
|
|
463
|
+
idx: int,
|
|
464
|
+
proxy: Optional[str],
|
|
465
|
+
announce_only: bool,
|
|
466
|
+
prompt: bool,
|
|
467
|
+
wait_for_inclusion: bool,
|
|
468
|
+
wait_for_finalization: bool,
|
|
469
|
+
period: int,
|
|
470
|
+
json_output: bool,
|
|
471
|
+
) -> None:
|
|
472
|
+
"""
|
|
473
|
+
Executes the pure proxy kill call on the chain
|
|
474
|
+
"""
|
|
475
|
+
if prompt:
|
|
476
|
+
confirmation = Prompt.ask(
|
|
477
|
+
f"This will kill a Pure Proxy account of type {proxy_type.value}.\n"
|
|
478
|
+
f"[red]All access to this account will be lost. Any funds held in it will be inaccessible.[/red]"
|
|
479
|
+
f"To proceed, enter [red]KILL[/red]"
|
|
480
|
+
)
|
|
481
|
+
if confirmation != "KILL":
|
|
482
|
+
print_error("Invalid input. Exiting.")
|
|
483
|
+
return None
|
|
484
|
+
if not (ulw := unlock_key(wallet, print_out=not json_output)).success:
|
|
485
|
+
if not json_output:
|
|
486
|
+
print_error(ulw.message)
|
|
487
|
+
else:
|
|
488
|
+
json_console.print_json(
|
|
489
|
+
data={
|
|
490
|
+
"success": ulw.success,
|
|
491
|
+
"message": ulw.message,
|
|
492
|
+
"extrinsic_identifier": None,
|
|
493
|
+
}
|
|
494
|
+
)
|
|
495
|
+
return None
|
|
496
|
+
spawner = spawner or wallet.coldkeypub.ss58_address
|
|
497
|
+
call = await meshtensor.substrate.compose_call(
|
|
498
|
+
call_module="Proxy",
|
|
499
|
+
call_function="kill_pure",
|
|
500
|
+
call_params={
|
|
501
|
+
"proxy_type": proxy_type.value,
|
|
502
|
+
"index": idx,
|
|
503
|
+
"height": height,
|
|
504
|
+
"ext_index": ext_index,
|
|
505
|
+
"spawner": spawner,
|
|
506
|
+
},
|
|
507
|
+
)
|
|
508
|
+
return await submit_proxy(
|
|
509
|
+
meshtensor=meshtensor,
|
|
510
|
+
wallet=wallet,
|
|
511
|
+
call=call,
|
|
512
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
513
|
+
wait_for_finalization=wait_for_finalization,
|
|
514
|
+
period=period,
|
|
515
|
+
json_output=json_output,
|
|
516
|
+
proxy=proxy,
|
|
517
|
+
announce_only=announce_only,
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
async def execute_announced(
|
|
522
|
+
meshtensor: "MeshtensorInterface",
|
|
523
|
+
wallet: "Wallet",
|
|
524
|
+
delegate: str,
|
|
525
|
+
real: str,
|
|
526
|
+
period: int,
|
|
527
|
+
call_hex: Optional[str],
|
|
528
|
+
delay: int = 0,
|
|
529
|
+
created_block: Optional[int] = None,
|
|
530
|
+
prompt: bool = True,
|
|
531
|
+
decline: bool = False,
|
|
532
|
+
quiet: bool = False,
|
|
533
|
+
wait_for_inclusion: bool = False,
|
|
534
|
+
wait_for_finalization: bool = False,
|
|
535
|
+
json_output: bool = False,
|
|
536
|
+
) -> bool:
|
|
537
|
+
"""
|
|
538
|
+
Executes the previously-announced call on the chain.
|
|
539
|
+
|
|
540
|
+
Returns:
|
|
541
|
+
True if the submission was successful, False otherwise.
|
|
542
|
+
|
|
543
|
+
"""
|
|
544
|
+
if prompt and created_block is not None:
|
|
545
|
+
current_block = await meshtensor.substrate.get_block_number()
|
|
546
|
+
if current_block - delay < created_block:
|
|
547
|
+
if not confirm_action(
|
|
548
|
+
f"The delay for this account is set to {delay} blocks, but the call was created"
|
|
549
|
+
f" at block {created_block}. It is currently only {current_block}. The call will likely fail."
|
|
550
|
+
f" Do you want to proceed?",
|
|
551
|
+
decline=decline,
|
|
552
|
+
quiet=quiet,
|
|
553
|
+
):
|
|
554
|
+
return False
|
|
555
|
+
|
|
556
|
+
if call_hex is None:
|
|
557
|
+
if not prompt:
|
|
558
|
+
print_error(
|
|
559
|
+
f"You have not provided a call, and are using"
|
|
560
|
+
f" [{COLORS.G.ARG}]--no-prompt[/{COLORS.G.ARG}], so we are unable to request"
|
|
561
|
+
f"the information to craft this call."
|
|
562
|
+
)
|
|
563
|
+
return False
|
|
564
|
+
else:
|
|
565
|
+
call_args = {}
|
|
566
|
+
failure_ = f"Instead create the call using meshcli commands with [{COLORS.G.ARG}]--announce-only[/{COLORS.G.ARG}]"
|
|
567
|
+
block_hash = await meshtensor.substrate.get_chain_head()
|
|
568
|
+
fns = await meshtensor.substrate.get_metadata_call_functions(
|
|
569
|
+
block_hash=block_hash
|
|
570
|
+
)
|
|
571
|
+
module = Prompt.ask(
|
|
572
|
+
"Enter the module name for the call",
|
|
573
|
+
choices=list(fns.keys()),
|
|
574
|
+
show_choices=True,
|
|
575
|
+
)
|
|
576
|
+
call_fn = Prompt.ask(
|
|
577
|
+
"Enter the call function for the call",
|
|
578
|
+
choices=list(fns[module].keys()),
|
|
579
|
+
show_choices=True,
|
|
580
|
+
)
|
|
581
|
+
for arg in fns[module][call_fn].keys():
|
|
582
|
+
if not isinstance(fns[module][call_fn][arg], dict):
|
|
583
|
+
# _docs usually
|
|
584
|
+
continue
|
|
585
|
+
type_name = fns[module][call_fn][arg]["typeName"]
|
|
586
|
+
if type_name == "AccountIdLookupOf<T>":
|
|
587
|
+
value = is_valid_ss58_address_prompt(
|
|
588
|
+
f"Enter the SS58 Address for {arg}"
|
|
589
|
+
)
|
|
590
|
+
elif type_name == "T::Balance":
|
|
591
|
+
value = FloatPrompt.ask(f"Enter the amount of Tao for {arg}")
|
|
592
|
+
value = Balance.from_tao(value)
|
|
593
|
+
elif "RuntimeCall" in type_name:
|
|
594
|
+
print_error(
|
|
595
|
+
f"Unable to craft a Call Type for arg {arg}. {failure_}"
|
|
596
|
+
)
|
|
597
|
+
return False
|
|
598
|
+
elif type_name == "NetUid":
|
|
599
|
+
value = IntPrompt.ask(f"Enter the netuid for {arg}")
|
|
600
|
+
elif type_name in ("u16", "u64"):
|
|
601
|
+
value = IntPrompt.ask(f"Enter the int value for {arg}")
|
|
602
|
+
elif type_name == "bool":
|
|
603
|
+
value = Prompt.ask(
|
|
604
|
+
f"Enter the bool value for {arg}",
|
|
605
|
+
choices=["True", "False"],
|
|
606
|
+
show_choices=True,
|
|
607
|
+
)
|
|
608
|
+
if value == "True":
|
|
609
|
+
value = True
|
|
610
|
+
else:
|
|
611
|
+
value = False
|
|
612
|
+
else:
|
|
613
|
+
print_error(f"Unrecognized type name {type_name}. {failure_}")
|
|
614
|
+
return False
|
|
615
|
+
call_args[arg] = value
|
|
616
|
+
inner_call = await meshtensor.substrate.compose_call(
|
|
617
|
+
module,
|
|
618
|
+
call_fn,
|
|
619
|
+
call_params=call_args,
|
|
620
|
+
block_hash=block_hash,
|
|
621
|
+
)
|
|
622
|
+
else:
|
|
623
|
+
try:
|
|
624
|
+
runtime = await meshtensor.substrate.init_runtime(block_id=created_block)
|
|
625
|
+
inner_call = GenericCall(
|
|
626
|
+
data=ScaleBytes(data=bytearray.fromhex(call_hex)),
|
|
627
|
+
metadata=runtime.metadata,
|
|
628
|
+
)
|
|
629
|
+
inner_call.process()
|
|
630
|
+
except StateDiscardedError:
|
|
631
|
+
print_error(
|
|
632
|
+
"The state has already been discarded for this block "
|
|
633
|
+
"(you are likely not using an archive node endpoint)"
|
|
634
|
+
)
|
|
635
|
+
if prompt:
|
|
636
|
+
if not confirm_action(
|
|
637
|
+
"Would you like to try using the latest runtime? This may fail, and if so, "
|
|
638
|
+
"this command will need to be re-run on an archive node endpoint."
|
|
639
|
+
):
|
|
640
|
+
return False
|
|
641
|
+
try:
|
|
642
|
+
runtime = await meshtensor.substrate.init_runtime(block_hash=None)
|
|
643
|
+
inner_call = GenericCall(
|
|
644
|
+
data=ScaleBytes(data=bytearray.fromhex(call_hex)),
|
|
645
|
+
metadata=runtime.metadata,
|
|
646
|
+
)
|
|
647
|
+
inner_call.process()
|
|
648
|
+
except Exception as e:
|
|
649
|
+
print_error(
|
|
650
|
+
f"Failure: Unable to regenerate the call data using the latest runtime: {e}\n"
|
|
651
|
+
"You should rerun this command on an archive node endpoint."
|
|
652
|
+
)
|
|
653
|
+
if json_output:
|
|
654
|
+
json_console.print_json(
|
|
655
|
+
data={
|
|
656
|
+
"success": False,
|
|
657
|
+
"message": f"Unable to regenerate the call data using the latest runtime: {e}. "
|
|
658
|
+
"You should rerun this command on an archive node endpoint.",
|
|
659
|
+
"extrinsic_identifier": None,
|
|
660
|
+
}
|
|
661
|
+
)
|
|
662
|
+
return False
|
|
663
|
+
|
|
664
|
+
announced_call = await meshtensor.substrate.compose_call(
|
|
665
|
+
"Proxy",
|
|
666
|
+
"proxy_announced",
|
|
667
|
+
{
|
|
668
|
+
"delegate": delegate,
|
|
669
|
+
"real": real,
|
|
670
|
+
"call": inner_call,
|
|
671
|
+
"force_proxy_type": None,
|
|
672
|
+
},
|
|
673
|
+
)
|
|
674
|
+
success, msg, receipt = await meshtensor.sign_and_send_extrinsic(
|
|
675
|
+
call=announced_call,
|
|
676
|
+
wallet=wallet,
|
|
677
|
+
wait_for_inclusion=wait_for_inclusion,
|
|
678
|
+
wait_for_finalization=wait_for_finalization,
|
|
679
|
+
era={"period": period},
|
|
680
|
+
)
|
|
681
|
+
if success is True:
|
|
682
|
+
if json_output:
|
|
683
|
+
json_console.print_json(
|
|
684
|
+
data={
|
|
685
|
+
"success": True,
|
|
686
|
+
"message": msg,
|
|
687
|
+
"extrinsic_identifier": await receipt.get_extrinsic_identifier(),
|
|
688
|
+
}
|
|
689
|
+
)
|
|
690
|
+
else:
|
|
691
|
+
print_success("Success!")
|
|
692
|
+
await print_extrinsic_id(receipt)
|
|
693
|
+
else:
|
|
694
|
+
if json_output:
|
|
695
|
+
json_console.print_json(
|
|
696
|
+
data={"success": False, "message": msg, "extrinsic_identifier": None}
|
|
697
|
+
)
|
|
698
|
+
else:
|
|
699
|
+
print_error(f"Failed. {msg} ")
|
|
700
|
+
return success
|
|
File without changes
|