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,354 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
import webbrowser
|
|
5
|
+
import netaddr
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from meshtensor_cli.src.meshtensor.balances import Balance
|
|
9
|
+
from meshtensor_cli.src.meshtensor.meshtensor_interface import MeshtensorInterface
|
|
10
|
+
from meshtensor_cli.src.meshtensor.utils import console, WalletLike, jinja_env
|
|
11
|
+
from meshtensor_wallet import Wallet
|
|
12
|
+
from meshtensor_cli.src import defaults
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
ROOT_SYMBOL_HTML = f"&#x{ord('τ'):X};"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def display_network_dashboard(
|
|
19
|
+
wallet: Wallet,
|
|
20
|
+
meshtensor: "MeshtensorInterface",
|
|
21
|
+
use_wry: bool = False,
|
|
22
|
+
save_file: bool = False,
|
|
23
|
+
dashboard_path: str = None,
|
|
24
|
+
coldkey_ss58: str = None,
|
|
25
|
+
) -> bool:
|
|
26
|
+
"""
|
|
27
|
+
Generate and display the HTML interface.
|
|
28
|
+
"""
|
|
29
|
+
if coldkey_ss58:
|
|
30
|
+
wallet = WalletLike(coldkeypub_ss58=coldkey_ss58, name=coldkey_ss58[:7])
|
|
31
|
+
try:
|
|
32
|
+
with console.status("[dark_sea_green3]Fetching data...", spinner="earth"):
|
|
33
|
+
_subnet_data = await fetch_subnet_data(wallet, meshtensor)
|
|
34
|
+
subnet_data = process_subnet_data(_subnet_data)
|
|
35
|
+
html_content = generate_full_page(subnet_data)
|
|
36
|
+
|
|
37
|
+
if use_wry:
|
|
38
|
+
console.print(
|
|
39
|
+
"[dark_sea_green3]Opening dashboard in a window.[/dark_sea_green3]"
|
|
40
|
+
)
|
|
41
|
+
with tempfile.NamedTemporaryFile(
|
|
42
|
+
"w", delete=False, suffix=".html"
|
|
43
|
+
) as dashboard_file:
|
|
44
|
+
url = f"file://{dashboard_file.name}"
|
|
45
|
+
dashboard_file.write(html_content)
|
|
46
|
+
|
|
47
|
+
webbrowser.open(url, new=1)
|
|
48
|
+
else:
|
|
49
|
+
if save_file:
|
|
50
|
+
dir_path = os.path.expanduser(dashboard_path)
|
|
51
|
+
else:
|
|
52
|
+
dir_path = os.path.expanduser(defaults.dashboard.path)
|
|
53
|
+
if not os.path.exists(dir_path):
|
|
54
|
+
os.makedirs(dir_path)
|
|
55
|
+
|
|
56
|
+
with tempfile.NamedTemporaryFile(
|
|
57
|
+
delete=not save_file,
|
|
58
|
+
suffix=".html",
|
|
59
|
+
mode="w",
|
|
60
|
+
dir=dir_path,
|
|
61
|
+
prefix=f"{wallet.name}_{subnet_data['block_number']}_",
|
|
62
|
+
) as f:
|
|
63
|
+
f.write(html_content)
|
|
64
|
+
temp_path = f.name
|
|
65
|
+
file_url = f"file://{os.path.abspath(temp_path)}"
|
|
66
|
+
|
|
67
|
+
if not save_file:
|
|
68
|
+
with console.status(
|
|
69
|
+
"[dark_sea_green3]Loading dashboard...[/dark_sea_green3]",
|
|
70
|
+
spinner="material",
|
|
71
|
+
):
|
|
72
|
+
webbrowser.open(file_url)
|
|
73
|
+
await asyncio.sleep(10)
|
|
74
|
+
return True
|
|
75
|
+
|
|
76
|
+
console.print("[green]Dashboard View opened in your browser[/green]")
|
|
77
|
+
console.print(f"[yellow]The HTML file is saved at: {temp_path}[/yellow]")
|
|
78
|
+
webbrowser.open(file_url)
|
|
79
|
+
return True
|
|
80
|
+
|
|
81
|
+
except Exception as e:
|
|
82
|
+
print(f"Error: {e}")
|
|
83
|
+
return False
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def int_to_ip(int_val: int) -> str:
|
|
87
|
+
"""Maps to an ip string"""
|
|
88
|
+
return str(netaddr.IPAddress(int_val))
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def get_identity(
|
|
92
|
+
hotkey_ss58: str,
|
|
93
|
+
identities: dict,
|
|
94
|
+
old_identities: dict,
|
|
95
|
+
truncate_length: int = 4,
|
|
96
|
+
return_bool: bool = False,
|
|
97
|
+
lookup_hk: bool = True,
|
|
98
|
+
) -> str:
|
|
99
|
+
"""Fetch identity of hotkey from both sources"""
|
|
100
|
+
if lookup_hk:
|
|
101
|
+
if hk_identity := identities["hotkeys"].get(hotkey_ss58):
|
|
102
|
+
return hk_identity.get("identity", {}).get("name", "") or hk_identity.get(
|
|
103
|
+
"display", "~"
|
|
104
|
+
)
|
|
105
|
+
else:
|
|
106
|
+
if ck_identity := identities["coldkeys"].get(hotkey_ss58):
|
|
107
|
+
return ck_identity.get("identity", {}).get("name", "") or ck_identity.get(
|
|
108
|
+
"display", "~"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if old_identity := old_identities.get(hotkey_ss58):
|
|
112
|
+
return old_identity.display
|
|
113
|
+
else:
|
|
114
|
+
if return_bool:
|
|
115
|
+
return False
|
|
116
|
+
else:
|
|
117
|
+
return f"{hotkey_ss58[:truncate_length]}...{hotkey_ss58[-truncate_length:]}"
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
async def fetch_subnet_data(
|
|
121
|
+
wallet: Wallet, meshtensor: "MeshtensorInterface"
|
|
122
|
+
) -> dict[str, Any]:
|
|
123
|
+
"""
|
|
124
|
+
Fetch subnet data from the network.
|
|
125
|
+
"""
|
|
126
|
+
block_hash = await meshtensor.substrate.get_chain_head()
|
|
127
|
+
|
|
128
|
+
(
|
|
129
|
+
balance,
|
|
130
|
+
stake_info,
|
|
131
|
+
metagraphs_info,
|
|
132
|
+
subnets_info,
|
|
133
|
+
ck_hk_identities,
|
|
134
|
+
old_identities,
|
|
135
|
+
block_number,
|
|
136
|
+
) = await asyncio.gather(
|
|
137
|
+
meshtensor.get_balance(wallet.coldkeypub.ss58_address, block_hash=block_hash),
|
|
138
|
+
meshtensor.get_stake_for_coldkey(
|
|
139
|
+
wallet.coldkeypub.ss58_address, block_hash=block_hash
|
|
140
|
+
),
|
|
141
|
+
meshtensor.get_all_metagraphs_info(block_hash=block_hash),
|
|
142
|
+
meshtensor.all_subnets(block_hash=block_hash),
|
|
143
|
+
meshtensor.fetch_coldkey_hotkey_identities(block_hash=block_hash),
|
|
144
|
+
meshtensor.get_delegate_identities(block_hash=block_hash),
|
|
145
|
+
meshtensor.substrate.get_block_number(block_hash=block_hash),
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
"balance": balance,
|
|
150
|
+
"stake_info": stake_info,
|
|
151
|
+
"metagraphs_info": metagraphs_info,
|
|
152
|
+
"subnets_info": subnets_info,
|
|
153
|
+
"ck_hk_identities": ck_hk_identities,
|
|
154
|
+
"old_identities": old_identities,
|
|
155
|
+
"wallet": wallet,
|
|
156
|
+
"block_number": block_number,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def process_subnet_data(raw_data: dict[str, Any]) -> dict[str, Any]:
|
|
161
|
+
"""
|
|
162
|
+
Process and prepare subnet data.
|
|
163
|
+
"""
|
|
164
|
+
balance = raw_data["balance"]
|
|
165
|
+
stake_info = raw_data["stake_info"]
|
|
166
|
+
metagraphs_info = raw_data["metagraphs_info"]
|
|
167
|
+
subnets_info = raw_data["subnets_info"]
|
|
168
|
+
ck_hk_identities = raw_data["ck_hk_identities"]
|
|
169
|
+
old_identities = raw_data["old_identities"]
|
|
170
|
+
wallet = raw_data["wallet"]
|
|
171
|
+
block_number = raw_data["block_number"]
|
|
172
|
+
|
|
173
|
+
pool_info = {info.netuid: info for info in subnets_info}
|
|
174
|
+
|
|
175
|
+
total_ideal_stake_value = Balance.from_tao(0)
|
|
176
|
+
total_slippage_value = Balance.from_tao(0)
|
|
177
|
+
|
|
178
|
+
# Process stake
|
|
179
|
+
stake_dict: dict[int, list[dict[str, Any]]] = {}
|
|
180
|
+
for stake in stake_info:
|
|
181
|
+
if stake.stake.tao > 0:
|
|
182
|
+
slippage_value, _, slippage_percentage = pool_info[
|
|
183
|
+
stake.netuid
|
|
184
|
+
].alpha_to_tao_with_slippage(stake.stake)
|
|
185
|
+
ideal_value = pool_info[stake.netuid].alpha_to_tao(stake.stake)
|
|
186
|
+
total_ideal_stake_value += ideal_value
|
|
187
|
+
total_slippage_value += slippage_value
|
|
188
|
+
stake_dict.setdefault(stake.netuid, []).append(
|
|
189
|
+
{
|
|
190
|
+
"hotkey": stake.hotkey_ss58,
|
|
191
|
+
"hotkey_identity": get_identity(
|
|
192
|
+
stake.hotkey_ss58, ck_hk_identities, old_identities
|
|
193
|
+
),
|
|
194
|
+
"amount": stake.stake.tao,
|
|
195
|
+
"emission": stake.emission.tao,
|
|
196
|
+
"is_registered": stake.is_registered,
|
|
197
|
+
"tao_emission": stake.tao_emission.tao,
|
|
198
|
+
"ideal_value": ideal_value.tao,
|
|
199
|
+
"slippage_value": slippage_value.tao,
|
|
200
|
+
"slippage_percentage": slippage_percentage,
|
|
201
|
+
}
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Process metagraph
|
|
205
|
+
subnets = []
|
|
206
|
+
for meta_info in metagraphs_info:
|
|
207
|
+
subnet_stakes = stake_dict.get(meta_info.netuid, [])
|
|
208
|
+
metagraph_info = {
|
|
209
|
+
"netuid": meta_info.netuid,
|
|
210
|
+
"name": meta_info.name,
|
|
211
|
+
"symbol": meta_info.symbol,
|
|
212
|
+
"alpha_in": 0 if meta_info.netuid == 0 else meta_info.alpha_in.tao,
|
|
213
|
+
"alpha_out": meta_info.alpha_out.tao,
|
|
214
|
+
"tao_in": 0 if meta_info.netuid == 0 else meta_info.tao_in.tao,
|
|
215
|
+
"tao_in_emission": meta_info.tao_in_emission.tao,
|
|
216
|
+
"num_uids": meta_info.num_uids,
|
|
217
|
+
"max_uids": meta_info.max_uids,
|
|
218
|
+
"moving_price": meta_info.moving_price.tao,
|
|
219
|
+
"blocks_since_last_step": "~"
|
|
220
|
+
if meta_info.netuid == 0
|
|
221
|
+
else meta_info.blocks_since_last_step,
|
|
222
|
+
"tempo": "~" if meta_info.netuid == 0 else meta_info.tempo,
|
|
223
|
+
"registration_allowed": meta_info.registration_allowed,
|
|
224
|
+
"commit_reveal_weights_enabled": meta_info.commit_reveal_weights_enabled,
|
|
225
|
+
"hotkeys": meta_info.hotkeys,
|
|
226
|
+
"coldkeys": meta_info.coldkeys,
|
|
227
|
+
"updated_identities": [],
|
|
228
|
+
"processed_axons": [],
|
|
229
|
+
"rank": meta_info.rank,
|
|
230
|
+
"trust": meta_info.trust,
|
|
231
|
+
"consensus": meta_info.consensus,
|
|
232
|
+
"incentives": meta_info.incentives,
|
|
233
|
+
"dividends": meta_info.dividends,
|
|
234
|
+
"active": meta_info.active,
|
|
235
|
+
"validator_permit": meta_info.validator_permit,
|
|
236
|
+
"pruning_score": meta_info.pruning_score,
|
|
237
|
+
"last_update": meta_info.last_update,
|
|
238
|
+
"block_at_registration": meta_info.block_at_registration,
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
# Process axon data and convert IPs
|
|
242
|
+
for axon in meta_info.axons:
|
|
243
|
+
if axon:
|
|
244
|
+
processed_axon = {
|
|
245
|
+
"ip": int_to_ip(axon["ip"]) if axon["ip"] else "N/A",
|
|
246
|
+
"port": axon["port"],
|
|
247
|
+
"ip_type": axon["ip_type"],
|
|
248
|
+
}
|
|
249
|
+
metagraph_info["processed_axons"].append(processed_axon)
|
|
250
|
+
else:
|
|
251
|
+
metagraph_info["processed_axons"].append(None)
|
|
252
|
+
|
|
253
|
+
# Add identities
|
|
254
|
+
for hotkey in meta_info.hotkeys:
|
|
255
|
+
identity = get_identity(
|
|
256
|
+
hotkey, ck_hk_identities, old_identities, truncate_length=2
|
|
257
|
+
)
|
|
258
|
+
metagraph_info["updated_identities"].append(identity)
|
|
259
|
+
|
|
260
|
+
# Balance conversion
|
|
261
|
+
for field in [
|
|
262
|
+
"emission",
|
|
263
|
+
"alpha_stake",
|
|
264
|
+
"tao_stake",
|
|
265
|
+
"total_stake",
|
|
266
|
+
]:
|
|
267
|
+
if hasattr(meta_info, field):
|
|
268
|
+
raw_data = getattr(meta_info, field)
|
|
269
|
+
if isinstance(raw_data, list):
|
|
270
|
+
metagraph_info[field] = [
|
|
271
|
+
x.tao if hasattr(x, "mesh") else x for x in raw_data
|
|
272
|
+
]
|
|
273
|
+
else:
|
|
274
|
+
metagraph_info[field] = raw_data
|
|
275
|
+
|
|
276
|
+
# Calculate price
|
|
277
|
+
price = (
|
|
278
|
+
1
|
|
279
|
+
if metagraph_info["netuid"] == 0
|
|
280
|
+
else metagraph_info["tao_in"] / metagraph_info["alpha_in"]
|
|
281
|
+
if metagraph_info["alpha_in"] > 0
|
|
282
|
+
else 0
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
# Package it all up
|
|
286
|
+
symbol_html = f"&#x{ord(meta_info.symbol):X};"
|
|
287
|
+
subnets.append(
|
|
288
|
+
{
|
|
289
|
+
"netuid": meta_info.netuid,
|
|
290
|
+
"name": meta_info.name,
|
|
291
|
+
"symbol": symbol_html,
|
|
292
|
+
"price": price,
|
|
293
|
+
"market_cap": float(
|
|
294
|
+
(metagraph_info["alpha_in"] + metagraph_info["alpha_out"]) * price
|
|
295
|
+
)
|
|
296
|
+
if price
|
|
297
|
+
else 0,
|
|
298
|
+
"emission": metagraph_info["tao_in_emission"],
|
|
299
|
+
"total_stake": metagraph_info["alpha_out"],
|
|
300
|
+
"your_stakes": subnet_stakes,
|
|
301
|
+
"metagraph_info": metagraph_info,
|
|
302
|
+
}
|
|
303
|
+
)
|
|
304
|
+
subnets.sort(key=lambda x: x["market_cap"], reverse=True)
|
|
305
|
+
|
|
306
|
+
wallet_identity = get_identity(
|
|
307
|
+
wallet.coldkeypub.ss58_address,
|
|
308
|
+
ck_hk_identities,
|
|
309
|
+
old_identities,
|
|
310
|
+
return_bool=True,
|
|
311
|
+
lookup_hk=False,
|
|
312
|
+
)
|
|
313
|
+
if not wallet_identity:
|
|
314
|
+
wallet_identity = wallet.name
|
|
315
|
+
else:
|
|
316
|
+
wallet_identity = f"{wallet_identity} ({wallet.name})"
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
"wallet_info": {
|
|
320
|
+
"name": wallet_identity,
|
|
321
|
+
"balance": balance.tao,
|
|
322
|
+
"coldkey": wallet.coldkeypub.ss58_address,
|
|
323
|
+
"total_ideal_stake_value": total_ideal_stake_value.tao,
|
|
324
|
+
"total_slippage_value": total_slippage_value.tao,
|
|
325
|
+
},
|
|
326
|
+
"subnets": subnets,
|
|
327
|
+
"block_number": block_number,
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
def generate_full_page(data: dict[str, Any]) -> str:
|
|
332
|
+
"""
|
|
333
|
+
Generate full HTML content for the interface.
|
|
334
|
+
"""
|
|
335
|
+
wallet_info = data["wallet_info"]
|
|
336
|
+
truncated_coldkey = f"{wallet_info['coldkey'][:6]}...{wallet_info['coldkey'][-6:]}"
|
|
337
|
+
block_number = data["block_number"]
|
|
338
|
+
# Calculate slippage percentage
|
|
339
|
+
ideal_value = wallet_info["total_ideal_stake_value"]
|
|
340
|
+
slippage_value = wallet_info["total_slippage_value"]
|
|
341
|
+
slippage_percentage = (
|
|
342
|
+
((ideal_value - slippage_value) / ideal_value * 100) if ideal_value > 0 else 0
|
|
343
|
+
)
|
|
344
|
+
|
|
345
|
+
template = jinja_env.get_template("view.j2")
|
|
346
|
+
|
|
347
|
+
return template.render(
|
|
348
|
+
root_symbol_html=ROOT_SYMBOL_HTML,
|
|
349
|
+
block_number=block_number,
|
|
350
|
+
truncated_coldkey=truncated_coldkey,
|
|
351
|
+
slippage_percentage=slippage_percentage,
|
|
352
|
+
wallet_info=wallet_info,
|
|
353
|
+
subnets=data["subnets"],
|
|
354
|
+
)
|