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.
- htcli-1.1.0.dist-info/METADATA +509 -0
- htcli-1.1.0.dist-info/RECORD +140 -0
- htcli-1.1.0.dist-info/WHEEL +4 -0
- htcli-1.1.0.dist-info/entry_points.txt +2 -0
- htcli-1.1.0.dist-info/licenses/LICENSE +21 -0
- src/__init__.py +0 -0
- src/htcli/__init__.py +5 -0
- src/htcli/client/__init__.py +338 -0
- src/htcli/client/extrinsics/__init__.py +26 -0
- src/htcli/client/extrinsics/base.py +487 -0
- src/htcli/client/extrinsics/consensus.py +79 -0
- src/htcli/client/extrinsics/governance.py +714 -0
- src/htcli/client/extrinsics/identity.py +490 -0
- src/htcli/client/extrinsics/node.py +1054 -0
- src/htcli/client/extrinsics/overwatch.py +401 -0
- src/htcli/client/extrinsics/staking.py +1504 -0
- src/htcli/client/extrinsics/subnet.py +2218 -0
- src/htcli/client/extrinsics/validator.py +203 -0
- src/htcli/client/extrinsics/wallet.py +323 -0
- src/htcli/client/offchain/__init__.py +10 -0
- src/htcli/client/offchain/backup.py +385 -0
- src/htcli/client/offchain/config.py +541 -0
- src/htcli/client/offchain/wallet.py +839 -0
- src/htcli/client/rpc/__init__.py +20 -0
- src/htcli/client/rpc/chain.py +568 -0
- src/htcli/client/rpc/node.py +783 -0
- src/htcli/client/rpc/overwatch.py +680 -0
- src/htcli/client/rpc/staking.py +216 -0
- src/htcli/client/rpc/subnet.py +2104 -0
- src/htcli/client/rpc/wallet.py +912 -0
- src/htcli/commands/__init__.py +31 -0
- src/htcli/commands/chain/__init__.py +66 -0
- src/htcli/commands/chain/display.py +204 -0
- src/htcli/commands/chain/handlers.py +260 -0
- src/htcli/commands/config/__init__.py +158 -0
- src/htcli/commands/config/display.py +353 -0
- src/htcli/commands/config/handlers.py +347 -0
- src/htcli/commands/config/prompts.py +357 -0
- src/htcli/commands/consensus/__init__.py +61 -0
- src/htcli/commands/consensus/handlers.py +100 -0
- src/htcli/commands/governance/__init__.py +49 -0
- src/htcli/commands/governance/handlers.py +81 -0
- src/htcli/commands/node/__init__.py +304 -0
- src/htcli/commands/node/display.py +749 -0
- src/htcli/commands/node/error_handling.py +470 -0
- src/htcli/commands/node/handlers.py +844 -0
- src/htcli/commands/node/prompts.py +346 -0
- src/htcli/commands/overwatch/__init__.py +219 -0
- src/htcli/commands/overwatch/display.py +396 -0
- src/htcli/commands/overwatch/error_handling.py +276 -0
- src/htcli/commands/overwatch/handlers.py +443 -0
- src/htcli/commands/overwatch/prompts.py +359 -0
- src/htcli/commands/stake/__init__.py +736 -0
- src/htcli/commands/stake/display.py +1103 -0
- src/htcli/commands/stake/error_handling.py +425 -0
- src/htcli/commands/stake/handlers.py +1902 -0
- src/htcli/commands/stake/prompts.py +1080 -0
- src/htcli/commands/subnet/__init__.py +639 -0
- src/htcli/commands/subnet/display.py +801 -0
- src/htcli/commands/subnet/error_handling.py +524 -0
- src/htcli/commands/subnet/handlers.py +2855 -0
- src/htcli/commands/subnet/prompts.py +1225 -0
- src/htcli/commands/validator/__init__.py +192 -0
- src/htcli/commands/validator/display.py +54 -0
- src/htcli/commands/validator/handlers.py +340 -0
- src/htcli/commands/wallet/__init__.py +546 -0
- src/htcli/commands/wallet/display.py +806 -0
- src/htcli/commands/wallet/error_handling.py +210 -0
- src/htcli/commands/wallet/handlers.py +3040 -0
- src/htcli/commands/wallet/prompts.py +1518 -0
- src/htcli/config.py +184 -0
- src/htcli/dependencies.py +186 -0
- src/htcli/errors/__init__.py +63 -0
- src/htcli/errors/base.py +141 -0
- src/htcli/errors/display.py +20 -0
- src/htcli/errors/handlers.py +710 -0
- src/htcli/main.py +343 -0
- src/htcli/models/__init__.py +21 -0
- src/htcli/models/enums/enum_types.py +35 -0
- src/htcli/models/errors.py +103 -0
- src/htcli/models/requests/__init__.py +197 -0
- src/htcli/models/requests/config.py +70 -0
- src/htcli/models/requests/consensus.py +19 -0
- src/htcli/models/requests/governance.py +38 -0
- src/htcli/models/requests/identity.py +51 -0
- src/htcli/models/requests/key.py +22 -0
- src/htcli/models/requests/node.py +91 -0
- src/htcli/models/requests/overwatch.py +64 -0
- src/htcli/models/requests/staking.py +580 -0
- src/htcli/models/requests/subnet.py +195 -0
- src/htcli/models/requests/validator.py +139 -0
- src/htcli/models/requests/wallet.py +118 -0
- src/htcli/models/responses/__init__.py +147 -0
- src/htcli/models/responses/base.py +18 -0
- src/htcli/models/responses/chain.py +39 -0
- src/htcli/models/responses/config.py +58 -0
- src/htcli/models/responses/identity.py +102 -0
- src/htcli/models/responses/overwatch.py +51 -0
- src/htcli/models/responses/staking.py +502 -0
- src/htcli/models/responses/subnet.py +856 -0
- src/htcli/models/responses/wallet.py +185 -0
- src/htcli/ui/__init__.py +87 -0
- src/htcli/ui/colors.py +309 -0
- src/htcli/ui/components/__init__.py +60 -0
- src/htcli/ui/components/panels.py +174 -0
- src/htcli/ui/components/progress.py +166 -0
- src/htcli/ui/components/spinners.py +92 -0
- src/htcli/ui/components/tables.py +809 -0
- src/htcli/ui/components/trees.py +721 -0
- src/htcli/ui/display.py +336 -0
- src/htcli/ui/prompts.py +870 -0
- src/htcli/utils/__init__.py +76 -0
- src/htcli/utils/blockchain/__init__.py +75 -0
- src/htcli/utils/blockchain/formatting.py +368 -0
- src/htcli/utils/blockchain/patches.py +286 -0
- src/htcli/utils/blockchain/peer_id.py +186 -0
- src/htcli/utils/blockchain/staking.py +448 -0
- src/htcli/utils/blockchain/type_registry.py +1373 -0
- src/htcli/utils/blockchain/validation.py +179 -0
- src/htcli/utils/cache.py +613 -0
- src/htcli/utils/constants.py +38 -0
- src/htcli/utils/legacy/__init__.py +12 -0
- src/htcli/utils/legacy/colors.py +311 -0
- src/htcli/utils/legacy/crypto.py +1176 -0
- src/htcli/utils/legacy/formatting.py +452 -0
- src/htcli/utils/legacy/interactive.py +306 -0
- src/htcli/utils/legacy/subnet_manifest.py +265 -0
- src/htcli/utils/legacy/validation.py +488 -0
- src/htcli/utils/logging.py +183 -0
- src/htcli/utils/network/__init__.py +20 -0
- src/htcli/utils/network/subnet.py +344 -0
- src/htcli/utils/prompts.py +27 -0
- src/htcli/utils/scale_codec.py +155 -0
- src/htcli/utils/validation/__init__.py +57 -0
- src/htcli/utils/validation/prompt_validators.py +267 -0
- src/htcli/utils/wallet/__init__.py +65 -0
- src/htcli/utils/wallet/auth.py +151 -0
- src/htcli/utils/wallet/core.py +1069 -0
- src/htcli/utils/wallet/crypto.py +1615 -0
- src/htcli/utils/wallet/migration.py +159 -0
|
@@ -0,0 +1,1103 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Stake display functions for RPC-based operations and extrinsic operations.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
from ...ui.colors import amount, info
|
|
8
|
+
from ...ui.components import HTCLIPanel, HTCLITable
|
|
9
|
+
from ...ui.display import HTCLIConsole
|
|
10
|
+
|
|
11
|
+
console = HTCLIConsole()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def display_coldkey_stakes_rpc(stakes_data: list[Any], coldkey: str):
|
|
15
|
+
"""Display coldkey stakes from RPC response."""
|
|
16
|
+
if not stakes_data:
|
|
17
|
+
console.print(info(f"No stakes found for coldkey {coldkey}"))
|
|
18
|
+
return
|
|
19
|
+
|
|
20
|
+
def _format_tensor(value: Optional[int], precision: int = 4) -> str:
|
|
21
|
+
"""Format wei value to TENSOR."""
|
|
22
|
+
if value is None or value == 0:
|
|
23
|
+
return "0.0000 TENSOR"
|
|
24
|
+
try:
|
|
25
|
+
tensor_value = int(value) / 1e18
|
|
26
|
+
return f"{tensor_value:,.{precision}f} TENSOR"
|
|
27
|
+
except (TypeError, ValueError):
|
|
28
|
+
return str(value)
|
|
29
|
+
|
|
30
|
+
# Create table for coldkey stakes with footer for totals
|
|
31
|
+
table = HTCLITable(
|
|
32
|
+
title=f"Coldkey Stakes: {coldkey}",
|
|
33
|
+
show_footer=True,
|
|
34
|
+
)
|
|
35
|
+
table.add_column("Subnet ID", style="cyan", justify="center")
|
|
36
|
+
table.add_column("Node ID", style="yellow", justify="center")
|
|
37
|
+
table.add_column("Hotkey", style="green")
|
|
38
|
+
table.add_column("Balance", style="magenta", justify="right")
|
|
39
|
+
|
|
40
|
+
total_balance = 0
|
|
41
|
+
for stake in stakes_data:
|
|
42
|
+
balance = int(stake.balance) if stake.balance else 0
|
|
43
|
+
total_balance += balance
|
|
44
|
+
table.add_row(
|
|
45
|
+
str(stake.subnet_id or "N/A"),
|
|
46
|
+
str(stake.subnet_node_id or "N/A"),
|
|
47
|
+
stake.hotkey or "N/A",
|
|
48
|
+
_format_tensor(balance),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Add totals footer
|
|
52
|
+
table.set_column_footers(
|
|
53
|
+
[
|
|
54
|
+
f"[bold]Total ({len(stakes_data)} stake{'s' if len(stakes_data) != 1 else ''})[/bold]",
|
|
55
|
+
"",
|
|
56
|
+
"",
|
|
57
|
+
f"[bold]{_format_tensor(total_balance)}[/bold]",
|
|
58
|
+
]
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
table.render()
|
|
62
|
+
console.print() # Add spacing after table
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def display_delegate_stakes_rpc(stakes_data: list[Any], account: str):
|
|
66
|
+
"""Display delegate stakes from RPC response."""
|
|
67
|
+
if not stakes_data:
|
|
68
|
+
console.print(info(f"No delegate stakes found for account {account}"))
|
|
69
|
+
return
|
|
70
|
+
|
|
71
|
+
def _format_tensor(value: Optional[int], precision: int = 4) -> str:
|
|
72
|
+
"""Format wei value to TENSOR."""
|
|
73
|
+
if value is None or value == 0:
|
|
74
|
+
return "0.0000 TENSOR"
|
|
75
|
+
try:
|
|
76
|
+
tensor_value = int(value) / 1e18
|
|
77
|
+
return f"{tensor_value:,.{precision}f} TENSOR"
|
|
78
|
+
except (TypeError, ValueError):
|
|
79
|
+
return str(value)
|
|
80
|
+
|
|
81
|
+
def _format_shares(value: Optional[int]) -> str:
|
|
82
|
+
"""Format shares value."""
|
|
83
|
+
if value is None or value == 0:
|
|
84
|
+
return "0"
|
|
85
|
+
try:
|
|
86
|
+
shares_value = int(value) / 1e18
|
|
87
|
+
return f"{shares_value:,.4f}"
|
|
88
|
+
except (TypeError, ValueError):
|
|
89
|
+
return str(value)
|
|
90
|
+
|
|
91
|
+
# Create table for delegate stakes with footer for totals
|
|
92
|
+
table = HTCLITable(
|
|
93
|
+
title=f"Subnet Delegate Stakes: {account}",
|
|
94
|
+
show_footer=True,
|
|
95
|
+
)
|
|
96
|
+
table.add_column("Subnet ID", style="cyan", justify="center")
|
|
97
|
+
table.add_column("Shares", style="yellow", justify="right")
|
|
98
|
+
table.add_column("Balance", style="magenta", justify="right")
|
|
99
|
+
|
|
100
|
+
total_shares = 0
|
|
101
|
+
total_balance = 0
|
|
102
|
+
for stake in stakes_data:
|
|
103
|
+
shares = int(stake.shares) if stake.shares else 0
|
|
104
|
+
balance = int(stake.balance) if stake.balance else 0
|
|
105
|
+
total_shares += shares
|
|
106
|
+
total_balance += balance
|
|
107
|
+
table.add_row(
|
|
108
|
+
str(stake.subnet_id),
|
|
109
|
+
_format_shares(shares),
|
|
110
|
+
_format_tensor(balance),
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Add totals footer
|
|
114
|
+
table.set_column_footers(
|
|
115
|
+
[
|
|
116
|
+
f"[bold]Total ({len(stakes_data)} stake{'s' if len(stakes_data) != 1 else ''})[/bold]",
|
|
117
|
+
f"[bold]{_format_shares(total_shares)}[/bold]",
|
|
118
|
+
f"[bold]{_format_tensor(total_balance)}[/bold]",
|
|
119
|
+
]
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
table.render()
|
|
123
|
+
console.print() # Add spacing after table
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def display_node_delegate_stakes_rpc(stakes_data: list[Any], account: str):
|
|
127
|
+
"""Display node delegate stakes from RPC response."""
|
|
128
|
+
if not stakes_data:
|
|
129
|
+
console.print(info(f"No node delegate stakes found for account {account}"))
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
def _format_tensor(value: Optional[int], precision: int = 4) -> str:
|
|
133
|
+
"""Format wei value to TENSOR."""
|
|
134
|
+
if value is None or value == 0:
|
|
135
|
+
return "0.0000 TENSOR"
|
|
136
|
+
try:
|
|
137
|
+
tensor_value = int(value) / 1e18
|
|
138
|
+
return f"{tensor_value:,.{precision}f} TENSOR"
|
|
139
|
+
except (TypeError, ValueError):
|
|
140
|
+
return str(value)
|
|
141
|
+
|
|
142
|
+
def _format_shares(value: Optional[int]) -> str:
|
|
143
|
+
"""Format shares value."""
|
|
144
|
+
if value is None or value == 0:
|
|
145
|
+
return "0"
|
|
146
|
+
try:
|
|
147
|
+
shares_value = int(value) / 1e18
|
|
148
|
+
return f"{shares_value:,.4f}"
|
|
149
|
+
except (TypeError, ValueError):
|
|
150
|
+
return str(value)
|
|
151
|
+
|
|
152
|
+
# Create table for node delegate stakes with footer for totals
|
|
153
|
+
table = HTCLITable(
|
|
154
|
+
title=f"Node Delegate Stakes: {account}",
|
|
155
|
+
show_footer=True,
|
|
156
|
+
)
|
|
157
|
+
table.add_column("Subnet ID", style="cyan", justify="center")
|
|
158
|
+
table.add_column("Node ID", style="yellow", justify="center")
|
|
159
|
+
table.add_column("Shares", style="green", justify="right")
|
|
160
|
+
table.add_column("Balance", style="magenta", justify="right")
|
|
161
|
+
|
|
162
|
+
total_shares = 0
|
|
163
|
+
total_balance = 0
|
|
164
|
+
for stake in stakes_data:
|
|
165
|
+
shares = int(stake.shares) if stake.shares else 0
|
|
166
|
+
balance = int(stake.balance) if stake.balance else 0
|
|
167
|
+
total_shares += shares
|
|
168
|
+
total_balance += balance
|
|
169
|
+
table.add_row(
|
|
170
|
+
str(stake.subnet_id),
|
|
171
|
+
str(stake.subnet_node_id),
|
|
172
|
+
_format_shares(shares),
|
|
173
|
+
_format_tensor(balance),
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
# Add totals footer
|
|
177
|
+
table.set_column_footers(
|
|
178
|
+
[
|
|
179
|
+
f"[bold]Total ({len(stakes_data)} stake{'s' if len(stakes_data) != 1 else ''})[/bold]",
|
|
180
|
+
"",
|
|
181
|
+
f"[bold]{_format_shares(total_shares)}[/bold]",
|
|
182
|
+
f"[bold]{_format_tensor(total_balance)}[/bold]",
|
|
183
|
+
]
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
table.render()
|
|
187
|
+
console.print() # Add spacing after table
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def display_proof_of_stake_rpc(
|
|
191
|
+
proof_result: bool, subnet_id: int, peer_id: str, min_class: int
|
|
192
|
+
):
|
|
193
|
+
"""Display proof of stake verification result."""
|
|
194
|
+
from ...ui.components import HTCLIPanel
|
|
195
|
+
|
|
196
|
+
status = "â
PASSED" if proof_result else "â FAILED"
|
|
197
|
+
status_color = "htcli.success" if proof_result else "htcli.error"
|
|
198
|
+
|
|
199
|
+
result_info = f"""
|
|
200
|
+
[htcli.accent]Proof of Stake Verification[/htcli.accent]
|
|
201
|
+
|
|
202
|
+
[htcli.value]Subnet ID:[/htcli.value] {subnet_id}
|
|
203
|
+
[htcli.value]Peer ID:[/htcli.value] {peer_id}
|
|
204
|
+
[htcli.value]Minimum Class:[/htcli.value] {min_class}
|
|
205
|
+
[htcli.value]Result:[/htcli.value] [{status_color}]{status}[/{status_color}]
|
|
206
|
+
|
|
207
|
+
[htcli.info]This peer {"meets" if proof_result else "does not meet"} the proof of stake requirements for subnet {subnet_id}.[/htcli.info]
|
|
208
|
+
"""
|
|
209
|
+
|
|
210
|
+
panel = HTCLIPanel(
|
|
211
|
+
result_info,
|
|
212
|
+
title="đ Proof of Stake Verification",
|
|
213
|
+
border_style="htcli.info" if proof_result else "htcli.error",
|
|
214
|
+
highlight=True,
|
|
215
|
+
)
|
|
216
|
+
panel.render(console.console)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
# ============================================================================
|
|
220
|
+
# EXTRINSIC DISPLAY FUNCTIONS - Write Operations
|
|
221
|
+
# ============================================================================
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def display_stake_add_result(response):
|
|
225
|
+
"""Display stake addition result."""
|
|
226
|
+
if hasattr(response, "success") and response.success:
|
|
227
|
+
total_stake_tensor = (
|
|
228
|
+
response.total_stake / 1e18
|
|
229
|
+
if hasattr(response, "total_stake") and response.total_stake
|
|
230
|
+
else 0
|
|
231
|
+
)
|
|
232
|
+
stake_added_tensor = (
|
|
233
|
+
(response.stake_added / 1e18)
|
|
234
|
+
if hasattr(response, "stake_added") and response.stake_added
|
|
235
|
+
else 0
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
block_hash = getattr(response, "block_hash", None)
|
|
239
|
+
content = f"""[htcli.success]â
Stake Added Successfully![/htcli.success]
|
|
240
|
+
|
|
241
|
+
[htcli.value]Amount Added:[/htcli.value] {amount(f"{stake_added_tensor:,.4f} TENSOR")}
|
|
242
|
+
[htcli.value]New Total Stake:[/htcli.value] {amount(f"{total_stake_tensor:,.4f} TENSOR")}
|
|
243
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
244
|
+
[htcli.value]Block Number:[/htcli.value] {response.block_number or "N/A"}
|
|
245
|
+
"""
|
|
246
|
+
if block_hash:
|
|
247
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
248
|
+
|
|
249
|
+
panel = HTCLIPanel(
|
|
250
|
+
content,
|
|
251
|
+
title="đ° Stake Added",
|
|
252
|
+
border_style="htcli.success",
|
|
253
|
+
highlight=True,
|
|
254
|
+
)
|
|
255
|
+
panel.render(console.console)
|
|
256
|
+
else:
|
|
257
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
258
|
+
|
|
259
|
+
# Check if it's a NotKeyOwner error and provide helpful guidance
|
|
260
|
+
if "NotKeyOwner" in error_msg or "does not own the hotkey" in error_msg:
|
|
261
|
+
content = """[htcli.error]â Failed to Add Stake[/htcli.error]
|
|
262
|
+
|
|
263
|
+
[htcli.warning]Key Ownership Error[/htcli.warning]
|
|
264
|
+
|
|
265
|
+
The coldkey wallet you selected does not own the hotkey for this node.
|
|
266
|
+
|
|
267
|
+
[htcli.info]đĄ What this means:[/htcli.info]
|
|
268
|
+
You can only add stake using the coldkey that owns the hotkey associated with the node.
|
|
269
|
+
|
|
270
|
+
[htcli.info]đĄ How to fix:[/htcli.info]
|
|
271
|
+
âĸ Make sure you're using the correct coldkey wallet that owns the node's hotkey
|
|
272
|
+
âĸ Verify the node ID and subnet ID are correct
|
|
273
|
+
âĸ If you don't own this node, you cannot add direct stake to it
|
|
274
|
+
(you can delegate stake instead using [bold]htcli stake delegate-add[/bold])
|
|
275
|
+
"""
|
|
276
|
+
panel = HTCLIPanel(
|
|
277
|
+
content,
|
|
278
|
+
title="â ī¸ Stake Addition Failed",
|
|
279
|
+
border_style="htcli.error",
|
|
280
|
+
highlight=True,
|
|
281
|
+
)
|
|
282
|
+
panel.render(console.console)
|
|
283
|
+
else:
|
|
284
|
+
# For other errors, use the simple format
|
|
285
|
+
console.print(f"[htcli.error]â Failed to add stake: {error_msg}[/]")
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def display_stake_remove_result(response):
|
|
289
|
+
"""Display stake removal result with unbonding information."""
|
|
290
|
+
if hasattr(response, "success") and response.success:
|
|
291
|
+
unbonding_amount_tensor = (
|
|
292
|
+
(response.unbonding_amount / 1e18)
|
|
293
|
+
if hasattr(response, "unbonding_amount") and response.unbonding_amount
|
|
294
|
+
else 0
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
block_hash = getattr(response, "block_hash", None)
|
|
298
|
+
block_number = getattr(response, "block_number", None)
|
|
299
|
+
content = f"""[htcli.success]â
Stake Removed Successfully![/htcli.success]
|
|
300
|
+
|
|
301
|
+
[htcli.value]Amount Removed:[/htcli.value] {amount(f"{unbonding_amount_tensor:,.4f} TENSOR")}
|
|
302
|
+
[htcli.value]Status:[/htcli.value] [yellow]Unbonding (locked)[/yellow]
|
|
303
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
304
|
+
[htcli.value]Block Number:[/htcli.value] {block_number or "N/A"}
|
|
305
|
+
"""
|
|
306
|
+
if block_hash:
|
|
307
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
308
|
+
content += """
|
|
309
|
+
[htcli.warning]â° Unbonding Period:[/htcli.warning]
|
|
310
|
+
Tokens will be available to claim after the unbonding period completes.
|
|
311
|
+
Use [bold]htcli stake claim[/bold] to claim when ready.
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
panel = HTCLIPanel(
|
|
315
|
+
content,
|
|
316
|
+
title="đ¤ Stake Removed",
|
|
317
|
+
border_style="htcli.warning",
|
|
318
|
+
highlight=True,
|
|
319
|
+
)
|
|
320
|
+
panel.render(console.console)
|
|
321
|
+
else:
|
|
322
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
323
|
+
console.print(f"[htcli.error]â Failed to remove stake: {error_msg}[/]")
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
def display_claim_result(response):
|
|
327
|
+
"""Display unbonding claim result."""
|
|
328
|
+
if hasattr(response, "success") and response.success:
|
|
329
|
+
total_claimed_tensor = (
|
|
330
|
+
(response.total_claimed / 1e18)
|
|
331
|
+
if hasattr(response, "total_claimed") and response.total_claimed
|
|
332
|
+
else 0
|
|
333
|
+
)
|
|
334
|
+
entries_claimed = (
|
|
335
|
+
response.entries_claimed if hasattr(response, "entries_claimed") else 0
|
|
336
|
+
)
|
|
337
|
+
|
|
338
|
+
if total_claimed_tensor > 0:
|
|
339
|
+
content = f"""[htcli.success]â
Unbondings Claimed Successfully![/htcli.success]
|
|
340
|
+
|
|
341
|
+
[htcli.value]Total Claimed:[/htcli.value] {amount(f"{total_claimed_tensor:,.4f} TENSOR")}
|
|
342
|
+
[htcli.value]Entries Claimed:[/htcli.value] {entries_claimed}
|
|
343
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
344
|
+
[htcli.value]Block Number:[/htcli.value] {response.block_number or "N/A"}
|
|
345
|
+
"""
|
|
346
|
+
block_hash = getattr(response, "block_hash", None)
|
|
347
|
+
if block_hash:
|
|
348
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
349
|
+
content += "\n"
|
|
350
|
+
|
|
351
|
+
panel = HTCLIPanel(
|
|
352
|
+
content,
|
|
353
|
+
title="đ° Unbonding Claimed",
|
|
354
|
+
border_style="htcli.success",
|
|
355
|
+
highlight=True,
|
|
356
|
+
)
|
|
357
|
+
panel.render()
|
|
358
|
+
else:
|
|
359
|
+
content = """[htcli.info]âšī¸ No Unbondings Ready to Claim[/htcli.info]
|
|
360
|
+
|
|
361
|
+
No tokens have completed the unbonding period yet.
|
|
362
|
+
Check back later when unbonding is complete.
|
|
363
|
+
"""
|
|
364
|
+
|
|
365
|
+
panel = HTCLIPanel(
|
|
366
|
+
content,
|
|
367
|
+
title="đĩ Claim Unbondings",
|
|
368
|
+
border_style=(
|
|
369
|
+
"htcli.success" if total_claimed_tensor > 0 else "htcli.info"
|
|
370
|
+
),
|
|
371
|
+
highlight=True,
|
|
372
|
+
)
|
|
373
|
+
panel.render(console.console)
|
|
374
|
+
else:
|
|
375
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
376
|
+
console.print(f"[htcli.error]â Failed to claim unbondings: {error_msg}[/]")
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
def display_delegate_stake_result(response, operation="add"):
|
|
380
|
+
"""Display delegate stake operation result."""
|
|
381
|
+
if hasattr(response, "success") and response.success:
|
|
382
|
+
if operation == "add":
|
|
383
|
+
stake_added_tensor = (
|
|
384
|
+
(response.stake_added / 1e18)
|
|
385
|
+
if hasattr(response, "stake_added") and response.stake_added
|
|
386
|
+
else 0
|
|
387
|
+
)
|
|
388
|
+
shares_received = (
|
|
389
|
+
response.shares_received
|
|
390
|
+
if hasattr(response, "shares_received")
|
|
391
|
+
and response.shares_received is not None
|
|
392
|
+
else 0
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
block_hash = getattr(response, "block_hash", None)
|
|
396
|
+
block_number = getattr(response, "block_number", None)
|
|
397
|
+
|
|
398
|
+
content = f"""[htcli.success]â
Delegate Stake Added![/htcli.success]
|
|
399
|
+
|
|
400
|
+
[htcli.value]Amount Added:[/htcli.value] {amount(f"{stake_added_tensor:,.4f} TENSOR")}
|
|
401
|
+
[htcli.value]Shares Received:[/htcli.value] {shares_received:,}
|
|
402
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") and response.subnet_id is not None else "N/A"}
|
|
403
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash if response.transaction_hash else "N/A"}
|
|
404
|
+
[htcli.value]Block Number:[/htcli.value] {block_number or "N/A"}
|
|
405
|
+
"""
|
|
406
|
+
if block_hash:
|
|
407
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
408
|
+
title = "đ Delegate Stake Added"
|
|
409
|
+
else:
|
|
410
|
+
shares_removed = (
|
|
411
|
+
response.shares_removed
|
|
412
|
+
if hasattr(response, "shares_removed")
|
|
413
|
+
and response.shares_removed is not None
|
|
414
|
+
else 0
|
|
415
|
+
)
|
|
416
|
+
|
|
417
|
+
block_hash = getattr(response, "block_hash", None)
|
|
418
|
+
block_number = getattr(response, "block_number", None)
|
|
419
|
+
|
|
420
|
+
content = f"""[htcli.success]â
Delegate Stake Removed![/htcli.success]
|
|
421
|
+
|
|
422
|
+
[htcli.value]Shares Removed:[/htcli.value] {shares_removed:,}
|
|
423
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") and response.subnet_id is not None else "N/A"}
|
|
424
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash if response.transaction_hash else "N/A"}
|
|
425
|
+
[htcli.value]Block Number:[/htcli.value] {block_number or "N/A"}
|
|
426
|
+
"""
|
|
427
|
+
if block_hash:
|
|
428
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
429
|
+
content += "\n[htcli.info]đĄ Tokens will be available after unbonding period.[/htcli.info]\n"
|
|
430
|
+
title = "đ Delegate Stake Removed"
|
|
431
|
+
|
|
432
|
+
panel = HTCLIPanel(
|
|
433
|
+
content,
|
|
434
|
+
title=title,
|
|
435
|
+
border_style="htcli.success",
|
|
436
|
+
highlight=True,
|
|
437
|
+
)
|
|
438
|
+
panel.render(console.console)
|
|
439
|
+
else:
|
|
440
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
441
|
+
console.print(
|
|
442
|
+
f"[htcli.error]â Failed to {operation} delegate stake: {error_msg}[/]"
|
|
443
|
+
)
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def display_validator_delegate_stake_result(response, operation="add"):
|
|
447
|
+
"""Display validator delegate stake operation result."""
|
|
448
|
+
if hasattr(response, "success") and response.success:
|
|
449
|
+
validator_id = getattr(response, "validator_id", "N/A")
|
|
450
|
+
block_hash = getattr(response, "block_hash", None)
|
|
451
|
+
block_number = getattr(response, "block_number", None)
|
|
452
|
+
if operation == "add":
|
|
453
|
+
stake_tensor = (
|
|
454
|
+
response.stake_added / 1e18
|
|
455
|
+
if hasattr(response, "stake_added") and response.stake_added
|
|
456
|
+
else 0
|
|
457
|
+
)
|
|
458
|
+
content = f"""[htcli.success]â
Validator Delegate Stake Added![/htcli.success]
|
|
459
|
+
|
|
460
|
+
[htcli.value]Amount Added:[/htcli.value] {amount(f"{stake_tensor:,.4f} TENSOR")}
|
|
461
|
+
[htcli.value]Validator ID:[/htcli.value] {validator_id}
|
|
462
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash if response.transaction_hash else "N/A"}
|
|
463
|
+
"""
|
|
464
|
+
title = "đ Validator Delegate Stake Added"
|
|
465
|
+
else:
|
|
466
|
+
shares_removed = (
|
|
467
|
+
response.shares_removed
|
|
468
|
+
if hasattr(response, "shares_removed")
|
|
469
|
+
and response.shares_removed is not None
|
|
470
|
+
else 0
|
|
471
|
+
)
|
|
472
|
+
content = f"""[htcli.success]â
Validator Delegate Stake Removed![/htcli.success]
|
|
473
|
+
|
|
474
|
+
[htcli.value]Shares Removed:[/htcli.value] {shares_removed:,}
|
|
475
|
+
[htcli.value]Validator ID:[/htcli.value] {validator_id}
|
|
476
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash if response.transaction_hash else "N/A"}
|
|
477
|
+
"""
|
|
478
|
+
title = "đ Validator Delegate Stake Removed"
|
|
479
|
+
if block_number:
|
|
480
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
481
|
+
if block_hash:
|
|
482
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
483
|
+
panel = HTCLIPanel(
|
|
484
|
+
content,
|
|
485
|
+
title=title,
|
|
486
|
+
border_style="htcli.success",
|
|
487
|
+
highlight=True,
|
|
488
|
+
)
|
|
489
|
+
panel.render(console.console)
|
|
490
|
+
else:
|
|
491
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
492
|
+
console.print(
|
|
493
|
+
f"[htcli.error]â Failed to {operation} validator delegate stake: {error_msg}[/]"
|
|
494
|
+
)
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
def display_node_delegate_stake_result(response, operation="add"):
|
|
498
|
+
"""Display node delegate stake operation result."""
|
|
499
|
+
if hasattr(response, "success") and response.success:
|
|
500
|
+
if operation == "add":
|
|
501
|
+
stake_added_tensor = (
|
|
502
|
+
(response.stake_added / 1e18)
|
|
503
|
+
if hasattr(response, "stake_added") and response.stake_added
|
|
504
|
+
else 0
|
|
505
|
+
)
|
|
506
|
+
shares_received = (
|
|
507
|
+
response.shares_received
|
|
508
|
+
if hasattr(response, "shares_received")
|
|
509
|
+
and response.shares_received is not None
|
|
510
|
+
else 0
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
block_hash = getattr(response, "block_hash", None)
|
|
514
|
+
block_number = getattr(response, "block_number", None)
|
|
515
|
+
|
|
516
|
+
content = f"""[htcli.success]â
Node Delegate Stake Added![/htcli.success]
|
|
517
|
+
|
|
518
|
+
[htcli.value]Amount Added:[/htcli.value] {amount(f"{stake_added_tensor:,.4f} TENSOR")}
|
|
519
|
+
[htcli.value]Shares Received:[/htcli.value] {shares_received:,}
|
|
520
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") and response.subnet_id is not None else "N/A"}
|
|
521
|
+
[htcli.value]Node ID:[/htcli.value] {response.subnet_node_id if hasattr(response, "subnet_node_id") and response.subnet_node_id is not None else "N/A"}
|
|
522
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash if response.transaction_hash else "N/A"}
|
|
523
|
+
[htcli.value]Block Number:[/htcli.value] {block_number or "N/A"}
|
|
524
|
+
"""
|
|
525
|
+
if block_hash:
|
|
526
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
527
|
+
title = "đ¯ Node Delegate Stake Added"
|
|
528
|
+
else:
|
|
529
|
+
shares_removed = (
|
|
530
|
+
response.shares_removed
|
|
531
|
+
if hasattr(response, "shares_removed")
|
|
532
|
+
and response.shares_removed is not None
|
|
533
|
+
else 0
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
block_hash = getattr(response, "block_hash", None)
|
|
537
|
+
block_number = getattr(response, "block_number", None)
|
|
538
|
+
|
|
539
|
+
content = f"""[htcli.success]â
Node Delegate Stake Removed![/htcli.success]
|
|
540
|
+
|
|
541
|
+
[htcli.value]Shares Removed:[/htcli.value] {shares_removed:,}
|
|
542
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") and response.subnet_id is not None else "N/A"}
|
|
543
|
+
[htcli.value]Node ID:[/htcli.value] {response.subnet_node_id if hasattr(response, "subnet_node_id") and response.subnet_node_id is not None else "N/A"}
|
|
544
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash if response.transaction_hash else "N/A"}
|
|
545
|
+
[htcli.value]Block Number:[/htcli.value] {block_number or "N/A"}
|
|
546
|
+
"""
|
|
547
|
+
if block_hash:
|
|
548
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
549
|
+
content += "\n[htcli.info]đĄ Tokens will be available after unbonding period.[/htcli.info]\n"
|
|
550
|
+
title = "đ¯ Node Delegate Stake Removed"
|
|
551
|
+
|
|
552
|
+
panel = HTCLIPanel(
|
|
553
|
+
content,
|
|
554
|
+
title=title,
|
|
555
|
+
border_style="htcli.success",
|
|
556
|
+
highlight=True,
|
|
557
|
+
)
|
|
558
|
+
panel.render(console.console)
|
|
559
|
+
else:
|
|
560
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
561
|
+
console.print(
|
|
562
|
+
f"[htcli.error]â Failed to {operation} node delegate stake: {error_msg}[/]"
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
def display_node_delegate_swap_result(response):
|
|
567
|
+
"""Display node delegate swap result."""
|
|
568
|
+
if hasattr(response, "success") and response.success:
|
|
569
|
+
shares = (
|
|
570
|
+
response.shares_swapped
|
|
571
|
+
if hasattr(response, "shares_swapped") and response.shares_swapped
|
|
572
|
+
else 0
|
|
573
|
+
)
|
|
574
|
+
block_hash = getattr(response, "block_hash", None)
|
|
575
|
+
block_number = getattr(response, "block_number", None)
|
|
576
|
+
content = f"""[htcli.success]â
Node Delegate Swap Submitted![/htcli.success]
|
|
577
|
+
|
|
578
|
+
[htcli.value]From:[/htcli.value] Subnet {getattr(response, "from_subnet_id", "N/A")} / Node {getattr(response, "from_subnet_node_id", "N/A")}
|
|
579
|
+
[htcli.value]To:[/htcli.value] Subnet {getattr(response, "to_subnet_id", "N/A")} / Node {getattr(response, "to_subnet_node_id", "N/A")}
|
|
580
|
+
[htcli.value]Shares Swapped:[/htcli.value] {shares:,}
|
|
581
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
582
|
+
"""
|
|
583
|
+
if block_number:
|
|
584
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
585
|
+
if block_hash:
|
|
586
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
587
|
+
content += "[htcli.info]â ī¸ Swap operations execute from the queue when eligible.[/htcli.info]\n"
|
|
588
|
+
panel = HTCLIPanel(
|
|
589
|
+
content,
|
|
590
|
+
title="đ Node Delegate Swap",
|
|
591
|
+
border_style="htcli.success",
|
|
592
|
+
highlight=True,
|
|
593
|
+
)
|
|
594
|
+
panel.render(console.console)
|
|
595
|
+
else:
|
|
596
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
597
|
+
console.print(
|
|
598
|
+
f"[htcli.error]â Failed to swap node delegate stake: {error_msg}[/]"
|
|
599
|
+
)
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
def display_node_delegate_transfer_result(response):
|
|
603
|
+
"""Display node delegate transfer result."""
|
|
604
|
+
if hasattr(response, "success") and response.success:
|
|
605
|
+
shares = (
|
|
606
|
+
response.shares_transferred
|
|
607
|
+
if hasattr(response, "shares_transferred") and response.shares_transferred
|
|
608
|
+
else 0
|
|
609
|
+
)
|
|
610
|
+
block_hash = getattr(response, "block_hash", None)
|
|
611
|
+
block_number = getattr(response, "block_number", None)
|
|
612
|
+
from ...utils.wallet.crypto import format_address_display
|
|
613
|
+
|
|
614
|
+
recipient = (
|
|
615
|
+
format_address_display(response.to_account, truncate=False)
|
|
616
|
+
if hasattr(response, "to_account") and response.to_account
|
|
617
|
+
else "N/A"
|
|
618
|
+
)
|
|
619
|
+
content = f"""[htcli.success]â
Node Delegate Transfer Complete![/htcli.success]
|
|
620
|
+
|
|
621
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") else "N/A"}
|
|
622
|
+
[htcli.value]Node ID:[/htcli.value] {response.subnet_node_id if hasattr(response, "subnet_node_id") else "N/A"}
|
|
623
|
+
[htcli.value]Recipient:[/htcli.value] {recipient}
|
|
624
|
+
[htcli.value]Shares Transferred:[/htcli.value] {shares:,}
|
|
625
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
626
|
+
"""
|
|
627
|
+
if block_number:
|
|
628
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
629
|
+
if block_hash:
|
|
630
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
631
|
+
panel = HTCLIPanel(
|
|
632
|
+
content,
|
|
633
|
+
title="đ¤ Node Delegate Transfer",
|
|
634
|
+
border_style="htcli.success",
|
|
635
|
+
highlight=True,
|
|
636
|
+
)
|
|
637
|
+
panel.render(console.console)
|
|
638
|
+
else:
|
|
639
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
640
|
+
console.print(
|
|
641
|
+
f"[htcli.error]â Failed to transfer node delegate stake: {error_msg}[/]"
|
|
642
|
+
)
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
def display_node_delegate_donate_result(response):
|
|
646
|
+
"""Display node delegate donation result."""
|
|
647
|
+
if hasattr(response, "success") and response.success:
|
|
648
|
+
donated_tensor = (
|
|
649
|
+
response.balance_donated / 1e18
|
|
650
|
+
if hasattr(response, "balance_donated") and response.balance_donated
|
|
651
|
+
else 0
|
|
652
|
+
)
|
|
653
|
+
block_hash = getattr(response, "block_hash", None)
|
|
654
|
+
block_number = getattr(response, "block_number", None)
|
|
655
|
+
content = f"""[htcli.success]â
Donation Submitted![/htcli.success]
|
|
656
|
+
|
|
657
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") else "N/A"}
|
|
658
|
+
[htcli.value]Node ID:[/htcli.value] {response.subnet_node_id if hasattr(response, "subnet_node_id") else "N/A"}
|
|
659
|
+
[htcli.value]Amount Donated:[/htcli.value] {amount(f"{donated_tensor:,.4f} TENSOR")}
|
|
660
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
661
|
+
"""
|
|
662
|
+
if block_number:
|
|
663
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
664
|
+
if block_hash:
|
|
665
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
666
|
+
content += "[htcli.info]đ Donation increases the node's delegate pool but not your balance.[/htcli.info]\n"
|
|
667
|
+
panel = HTCLIPanel(
|
|
668
|
+
content,
|
|
669
|
+
title="đ Node Delegate Donation",
|
|
670
|
+
border_style="htcli.success",
|
|
671
|
+
highlight=True,
|
|
672
|
+
)
|
|
673
|
+
panel.render(console.console)
|
|
674
|
+
else:
|
|
675
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
676
|
+
console.print(
|
|
677
|
+
f"[htcli.error]â Failed to donate node delegate stake: {error_msg}[/]"
|
|
678
|
+
)
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
def display_validator_delegate_swap_result(response):
|
|
682
|
+
"""Display validator delegate swap result."""
|
|
683
|
+
if hasattr(response, "success") and response.success:
|
|
684
|
+
shares = (
|
|
685
|
+
response.shares_swapped
|
|
686
|
+
if hasattr(response, "shares_swapped") and response.shares_swapped
|
|
687
|
+
else 0
|
|
688
|
+
)
|
|
689
|
+
block_hash = getattr(response, "block_hash", None)
|
|
690
|
+
block_number = getattr(response, "block_number", None)
|
|
691
|
+
content = f"""[htcli.success]â
Validator Delegate Swap Submitted![/htcli.success]
|
|
692
|
+
|
|
693
|
+
[htcli.value]From Validator:[/htcli.value] {getattr(response, "from_validator_id", "N/A")}
|
|
694
|
+
[htcli.value]To Validator:[/htcli.value] {getattr(response, "to_validator_id", "N/A")}
|
|
695
|
+
[htcli.value]Shares Swapped:[/htcli.value] {shares:,}
|
|
696
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
697
|
+
"""
|
|
698
|
+
if block_number:
|
|
699
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
700
|
+
if block_hash:
|
|
701
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
702
|
+
panel = HTCLIPanel(
|
|
703
|
+
content,
|
|
704
|
+
title="đ Validator Delegate Swap",
|
|
705
|
+
border_style="htcli.success",
|
|
706
|
+
highlight=True,
|
|
707
|
+
)
|
|
708
|
+
panel.render(console.console)
|
|
709
|
+
else:
|
|
710
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
711
|
+
console.print(
|
|
712
|
+
f"[htcli.error]â Failed to swap validator delegate stake: {error_msg}[/]"
|
|
713
|
+
)
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
def display_validator_delegate_transfer_result(response):
|
|
717
|
+
"""Display validator delegate transfer result."""
|
|
718
|
+
if hasattr(response, "success") and response.success:
|
|
719
|
+
shares = (
|
|
720
|
+
response.shares_transferred
|
|
721
|
+
if hasattr(response, "shares_transferred") and response.shares_transferred
|
|
722
|
+
else 0
|
|
723
|
+
)
|
|
724
|
+
block_hash = getattr(response, "block_hash", None)
|
|
725
|
+
block_number = getattr(response, "block_number", None)
|
|
726
|
+
from ...utils.wallet.crypto import format_address_display
|
|
727
|
+
|
|
728
|
+
recipient = (
|
|
729
|
+
format_address_display(response.to_account, truncate=False)
|
|
730
|
+
if hasattr(response, "to_account") and response.to_account
|
|
731
|
+
else "N/A"
|
|
732
|
+
)
|
|
733
|
+
content = f"""[htcli.success]â
Validator Delegate Transfer Complete![/htcli.success]
|
|
734
|
+
|
|
735
|
+
[htcli.value]Validator ID:[/htcli.value] {getattr(response, "validator_id", "N/A")}
|
|
736
|
+
[htcli.value]Recipient:[/htcli.value] {recipient}
|
|
737
|
+
[htcli.value]Shares Transferred:[/htcli.value] {shares:,}
|
|
738
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
739
|
+
"""
|
|
740
|
+
if block_number:
|
|
741
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
742
|
+
if block_hash:
|
|
743
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
744
|
+
panel = HTCLIPanel(
|
|
745
|
+
content,
|
|
746
|
+
title="đ¤ Validator Delegate Transfer",
|
|
747
|
+
border_style="htcli.success",
|
|
748
|
+
highlight=True,
|
|
749
|
+
)
|
|
750
|
+
panel.render(console.console)
|
|
751
|
+
else:
|
|
752
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
753
|
+
console.print(
|
|
754
|
+
f"[htcli.error]â Failed to transfer validator delegate stake: {error_msg}[/]"
|
|
755
|
+
)
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
def display_validator_delegate_donate_result(response):
|
|
759
|
+
"""Display validator delegate donation result."""
|
|
760
|
+
if hasattr(response, "success") and response.success:
|
|
761
|
+
donated_tensor = (
|
|
762
|
+
response.balance_donated / 1e18
|
|
763
|
+
if hasattr(response, "balance_donated") and response.balance_donated
|
|
764
|
+
else 0
|
|
765
|
+
)
|
|
766
|
+
block_hash = getattr(response, "block_hash", None)
|
|
767
|
+
block_number = getattr(response, "block_number", None)
|
|
768
|
+
content = f"""[htcli.success]â
Validator Delegate Donation Submitted![/htcli.success]
|
|
769
|
+
|
|
770
|
+
[htcli.value]Validator ID:[/htcli.value] {getattr(response, "validator_id", "N/A")}
|
|
771
|
+
[htcli.value]Amount Donated:[/htcli.value] {amount(f"{donated_tensor:,.4f} TENSOR")}
|
|
772
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
773
|
+
"""
|
|
774
|
+
if block_number:
|
|
775
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
776
|
+
if block_hash:
|
|
777
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
778
|
+
panel = HTCLIPanel(
|
|
779
|
+
content,
|
|
780
|
+
title="đ Validator Delegate Donation",
|
|
781
|
+
border_style="htcli.success",
|
|
782
|
+
highlight=True,
|
|
783
|
+
)
|
|
784
|
+
panel.render(console.console)
|
|
785
|
+
else:
|
|
786
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
787
|
+
console.print(
|
|
788
|
+
f"[htcli.error]â Failed to donate validator delegate stake: {error_msg}[/]"
|
|
789
|
+
)
|
|
790
|
+
|
|
791
|
+
|
|
792
|
+
def display_swap_validator_to_subnet_result(response):
|
|
793
|
+
"""Display swap from validator delegate to subnet delegate result."""
|
|
794
|
+
if hasattr(response, "success") and response.success:
|
|
795
|
+
shares = (
|
|
796
|
+
response.stake_swapped
|
|
797
|
+
if hasattr(response, "stake_swapped") and response.stake_swapped
|
|
798
|
+
else 0
|
|
799
|
+
)
|
|
800
|
+
block_hash = getattr(response, "block_hash", None)
|
|
801
|
+
block_number = getattr(response, "block_number", None)
|
|
802
|
+
content = f"""[htcli.success]â
Validator â Subnet Swap Submitted![/htcli.success]
|
|
803
|
+
|
|
804
|
+
[htcli.value]Source Validator:[/htcli.value] {getattr(response, "validator_id", "N/A")}
|
|
805
|
+
[htcli.value]Destination Subnet:[/htcli.value] {getattr(response, "subnet_id", "N/A")}
|
|
806
|
+
[htcli.value]Shares Swapped:[/htcli.value] {shares:,}
|
|
807
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
808
|
+
"""
|
|
809
|
+
if block_number:
|
|
810
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
811
|
+
if block_hash:
|
|
812
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
813
|
+
panel = HTCLIPanel(
|
|
814
|
+
content,
|
|
815
|
+
title="đ¤ Swap Validator â Subnet",
|
|
816
|
+
border_style="htcli.success",
|
|
817
|
+
highlight=True,
|
|
818
|
+
)
|
|
819
|
+
panel.render(console.console)
|
|
820
|
+
else:
|
|
821
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
822
|
+
console.print(
|
|
823
|
+
f"[htcli.error]â Failed to swap validator delegate stake to subnet: {error_msg}[/]"
|
|
824
|
+
)
|
|
825
|
+
|
|
826
|
+
|
|
827
|
+
def display_swap_subnet_to_validator_result(response):
|
|
828
|
+
"""Display swap from subnet delegate to validator delegate result."""
|
|
829
|
+
if hasattr(response, "success") and response.success:
|
|
830
|
+
shares = (
|
|
831
|
+
response.stake_swapped
|
|
832
|
+
if hasattr(response, "stake_swapped") and response.stake_swapped
|
|
833
|
+
else 0
|
|
834
|
+
)
|
|
835
|
+
block_hash = getattr(response, "block_hash", None)
|
|
836
|
+
block_number = getattr(response, "block_number", None)
|
|
837
|
+
content = f"""[htcli.success]â
Subnet â Validator Swap Submitted![/htcli.success]
|
|
838
|
+
|
|
839
|
+
[htcli.value]Source Subnet:[/htcli.value] {getattr(response, "subnet_id", "N/A")}
|
|
840
|
+
[htcli.value]Destination Validator:[/htcli.value] {getattr(response, "validator_id", "N/A")}
|
|
841
|
+
[htcli.value]Shares Swapped:[/htcli.value] {shares:,}
|
|
842
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
843
|
+
"""
|
|
844
|
+
if block_number:
|
|
845
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
846
|
+
if block_hash:
|
|
847
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
848
|
+
panel = HTCLIPanel(
|
|
849
|
+
content,
|
|
850
|
+
title="đĨ Swap Subnet â Validator",
|
|
851
|
+
border_style="htcli.success",
|
|
852
|
+
highlight=True,
|
|
853
|
+
)
|
|
854
|
+
panel.render(console.console)
|
|
855
|
+
else:
|
|
856
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
857
|
+
console.print(
|
|
858
|
+
f"[htcli.error]â Failed to swap subnet delegate stake to validator: {error_msg}[/]"
|
|
859
|
+
)
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
def display_swap_node_to_subnet_result(response):
|
|
863
|
+
"""Display swap from node delegate to subnet delegate result."""
|
|
864
|
+
if hasattr(response, "success") and response.success:
|
|
865
|
+
shares = (
|
|
866
|
+
response.stake_swapped
|
|
867
|
+
if hasattr(response, "stake_swapped") and response.stake_swapped
|
|
868
|
+
else 0
|
|
869
|
+
)
|
|
870
|
+
block_hash = getattr(response, "block_hash", None)
|
|
871
|
+
block_number = getattr(response, "block_number", None)
|
|
872
|
+
content = f"""[htcli.success]â
Node â Subnet Swap Submitted![/htcli.success]
|
|
873
|
+
|
|
874
|
+
[htcli.value]Source Subnet:[/htcli.value] {getattr(response, "subnet_id", "N/A")}
|
|
875
|
+
[htcli.value]Source Node:[/htcli.value] {getattr(response, "subnet_node_id", "N/A")}
|
|
876
|
+
[htcli.value]Shares Swapped:[/htcli.value] {shares:,}
|
|
877
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
878
|
+
"""
|
|
879
|
+
if block_number:
|
|
880
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
881
|
+
if block_hash:
|
|
882
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
883
|
+
content += "[htcli.info]âšī¸ Swap will execute once the queue reaches your entry.[/htcli.info]\n"
|
|
884
|
+
panel = HTCLIPanel(
|
|
885
|
+
content,
|
|
886
|
+
title="đ¤ Swap Node â Subnet",
|
|
887
|
+
border_style="htcli.success",
|
|
888
|
+
highlight=True,
|
|
889
|
+
)
|
|
890
|
+
panel.render(console.console)
|
|
891
|
+
else:
|
|
892
|
+
from ...client.extrinsics.base import get_user_friendly_error
|
|
893
|
+
|
|
894
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
895
|
+
friendly_error = get_user_friendly_error(error_msg)
|
|
896
|
+
|
|
897
|
+
# Check for specific error types and provide detailed guidance
|
|
898
|
+
if (
|
|
899
|
+
"NotEnoughStakeToWithdraw" in error_msg
|
|
900
|
+
or "Insufficient stake shares" in friendly_error
|
|
901
|
+
):
|
|
902
|
+
content = """[htcli.error]â Failed to Swap Node â Subnet[/htcli.error]
|
|
903
|
+
|
|
904
|
+
[htcli.warning]Insufficient Stake Shares[/htcli.warning]
|
|
905
|
+
|
|
906
|
+
You don't have enough stake shares in the node delegate position to swap the requested amount.
|
|
907
|
+
|
|
908
|
+
[htcli.info]đĄ What this means:[/htcli.info]
|
|
909
|
+
You tried to swap more shares than you currently have staked in the node delegate position.
|
|
910
|
+
|
|
911
|
+
[htcli.info]đĄ How to fix:[/htcli.info]
|
|
912
|
+
âĸ Check your current node delegate stake balance using:
|
|
913
|
+
[bold]htcli stake list-node-delegate --subnet-id <id> --node-id <id>[/bold]
|
|
914
|
+
âĸ Reduce the number of shares you're trying to swap
|
|
915
|
+
âĸ Make sure you're swapping from the correct subnet and node ID
|
|
916
|
+
"""
|
|
917
|
+
panel = HTCLIPanel(
|
|
918
|
+
content,
|
|
919
|
+
title="â ī¸ Swap Failed",
|
|
920
|
+
border_style="htcli.error",
|
|
921
|
+
highlight=True,
|
|
922
|
+
)
|
|
923
|
+
panel.render(console.console)
|
|
924
|
+
else:
|
|
925
|
+
# Generic error display
|
|
926
|
+
content = f"""[htcli.error]â Failed to Swap Node â Subnet[/htcli.error]
|
|
927
|
+
|
|
928
|
+
[htcli.value]Error:[/htcli.value] {friendly_error}
|
|
929
|
+
|
|
930
|
+
[htcli.info]đĄ Troubleshooting:[/htcli.info]
|
|
931
|
+
âĸ Verify you have sufficient stake shares in the node delegate position
|
|
932
|
+
âĸ Check that the subnet ID and node ID are correct
|
|
933
|
+
âĸ Ensure the node is active and not paused
|
|
934
|
+
"""
|
|
935
|
+
panel = HTCLIPanel(
|
|
936
|
+
content,
|
|
937
|
+
title="â ī¸ Swap Failed",
|
|
938
|
+
border_style="htcli.error",
|
|
939
|
+
highlight=True,
|
|
940
|
+
)
|
|
941
|
+
panel.render(console.console)
|
|
942
|
+
|
|
943
|
+
|
|
944
|
+
def display_swap_subnet_to_node_result(response):
|
|
945
|
+
"""Display swap from subnet delegate to node delegate result."""
|
|
946
|
+
if hasattr(response, "success") and response.success:
|
|
947
|
+
shares = (
|
|
948
|
+
response.stake_swapped
|
|
949
|
+
if hasattr(response, "stake_swapped") and response.stake_swapped
|
|
950
|
+
else 0
|
|
951
|
+
)
|
|
952
|
+
block_hash = getattr(response, "block_hash", None)
|
|
953
|
+
block_number = getattr(response, "block_number", None)
|
|
954
|
+
content = f"""[htcli.success]â
Subnet â Node Swap Submitted![/htcli.success]
|
|
955
|
+
|
|
956
|
+
[htcli.value]Destination Subnet:[/htcli.value] {getattr(response, "subnet_id", "N/A")}
|
|
957
|
+
[htcli.value]Destination Node:[/htcli.value] {getattr(response, "subnet_node_id", "N/A")}
|
|
958
|
+
[htcli.value]Shares Swapped:[/htcli.value] {shares:,}
|
|
959
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
960
|
+
"""
|
|
961
|
+
if block_number:
|
|
962
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
963
|
+
if block_hash:
|
|
964
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
965
|
+
content += "[htcli.info]âšī¸ Swap will execute once eligible in the queue.[/htcli.info]\n"
|
|
966
|
+
panel = HTCLIPanel(
|
|
967
|
+
content,
|
|
968
|
+
title="đĨ Swap Subnet â Node",
|
|
969
|
+
border_style="htcli.success",
|
|
970
|
+
highlight=True,
|
|
971
|
+
)
|
|
972
|
+
panel.render(console.console)
|
|
973
|
+
else:
|
|
974
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
975
|
+
console.print(
|
|
976
|
+
f"[htcli.error]â Failed to swap from subnet to node: {error_msg}[/]"
|
|
977
|
+
)
|
|
978
|
+
|
|
979
|
+
|
|
980
|
+
def display_swap_queue_update_result(response):
|
|
981
|
+
"""Display swap queue update result."""
|
|
982
|
+
if hasattr(response, "success") and response.success:
|
|
983
|
+
block_hash = getattr(response, "block_hash", None)
|
|
984
|
+
block_number = getattr(response, "block_number", None)
|
|
985
|
+
content = f"""[htcli.success]â
Swap Queue Updated![/htcli.success]
|
|
986
|
+
|
|
987
|
+
[htcli.value]Queue Entry:[/htcli.value] {response.queue_position if hasattr(response, "queue_position") else "N/A"}
|
|
988
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
989
|
+
"""
|
|
990
|
+
if block_number:
|
|
991
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
992
|
+
if block_hash:
|
|
993
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
994
|
+
content += "[htcli.info]đĄ The queue entry now points to the new target.[/htcli.info]\n"
|
|
995
|
+
panel = HTCLIPanel(
|
|
996
|
+
content,
|
|
997
|
+
title="đ ī¸ Swap Queue Update",
|
|
998
|
+
border_style="htcli.success",
|
|
999
|
+
highlight=True,
|
|
1000
|
+
)
|
|
1001
|
+
panel.render(console.console)
|
|
1002
|
+
else:
|
|
1003
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
1004
|
+
console.print(f"[htcli.error]â Failed to update swap queue: {error_msg}[/]")
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
def display_delegate_swap_result(response):
|
|
1008
|
+
"""Display delegate stake swap result."""
|
|
1009
|
+
if hasattr(response, "success") and response.success:
|
|
1010
|
+
block_hash = getattr(response, "block_hash", None)
|
|
1011
|
+
block_number = getattr(response, "block_number", None)
|
|
1012
|
+
content = f"""[htcli.success]â
Delegate Stake Swapped![/htcli.success]
|
|
1013
|
+
|
|
1014
|
+
[htcli.value]From Subnet:[/htcli.value] {response.from_subnet_id if hasattr(response, "from_subnet_id") else "N/A"}
|
|
1015
|
+
[htcli.value]To Subnet:[/htcli.value] {response.to_subnet_id if hasattr(response, "to_subnet_id") else "N/A"}
|
|
1016
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
1017
|
+
"""
|
|
1018
|
+
if block_number:
|
|
1019
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
1020
|
+
if block_hash:
|
|
1021
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
1022
|
+
content += "\n[htcli.info]đĄ Your delegate stake has been moved to the new subnet.[/htcli.info]\n"
|
|
1023
|
+
panel = HTCLIPanel(
|
|
1024
|
+
content,
|
|
1025
|
+
title="đ Delegate Stake Swapped",
|
|
1026
|
+
border_style="htcli.success",
|
|
1027
|
+
highlight=True,
|
|
1028
|
+
)
|
|
1029
|
+
panel.render(console.console)
|
|
1030
|
+
else:
|
|
1031
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
1032
|
+
console.print(f"[htcli.error]â Failed to swap delegate stake: {error_msg}[/]")
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
def display_delegate_transfer_result(response):
|
|
1036
|
+
"""Display delegate stake transfer result."""
|
|
1037
|
+
if hasattr(response, "success") and response.success:
|
|
1038
|
+
block_hash = getattr(response, "block_hash", None)
|
|
1039
|
+
block_number = getattr(response, "block_number", None)
|
|
1040
|
+
from ...utils.wallet.crypto import format_address_display
|
|
1041
|
+
|
|
1042
|
+
from_acct = (
|
|
1043
|
+
format_address_display(response.from_account, truncate=False)
|
|
1044
|
+
if hasattr(response, "from_account") and response.from_account
|
|
1045
|
+
else "N/A"
|
|
1046
|
+
)
|
|
1047
|
+
to_acct = (
|
|
1048
|
+
format_address_display(response.to_account, truncate=False)
|
|
1049
|
+
if hasattr(response, "to_account") and response.to_account
|
|
1050
|
+
else "N/A"
|
|
1051
|
+
)
|
|
1052
|
+
content = f"""[htcli.success]â
Delegate Stake Transferred![/htcli.success]
|
|
1053
|
+
|
|
1054
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") else "N/A"}
|
|
1055
|
+
[htcli.value]From:[/htcli.value] {from_acct}
|
|
1056
|
+
[htcli.value]To:[/htcli.value] {to_acct}
|
|
1057
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
1058
|
+
"""
|
|
1059
|
+
if block_number:
|
|
1060
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
1061
|
+
if block_hash:
|
|
1062
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
1063
|
+
panel = HTCLIPanel(
|
|
1064
|
+
content,
|
|
1065
|
+
title="đ¤ Delegate Stake Transferred",
|
|
1066
|
+
border_style="htcli.success",
|
|
1067
|
+
highlight=True,
|
|
1068
|
+
)
|
|
1069
|
+
panel.render(console.console)
|
|
1070
|
+
else:
|
|
1071
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
1072
|
+
console.print(
|
|
1073
|
+
f"[htcli.error]â Failed to transfer delegate stake: {error_msg}[/]"
|
|
1074
|
+
)
|
|
1075
|
+
|
|
1076
|
+
|
|
1077
|
+
def display_delegate_donate_result(response):
|
|
1078
|
+
"""Display delegate stake donation result."""
|
|
1079
|
+
if hasattr(response, "success") and response.success:
|
|
1080
|
+
block_hash = getattr(response, "block_hash", None)
|
|
1081
|
+
block_number = getattr(response, "block_number", None)
|
|
1082
|
+
content = f"""[htcli.success]â
Donation Complete![/htcli.success]
|
|
1083
|
+
|
|
1084
|
+
[htcli.value]Subnet ID:[/htcli.value] {response.subnet_id if hasattr(response, "subnet_id") else "N/A"}
|
|
1085
|
+
[htcli.value]Transaction Hash:[/htcli.value] {response.transaction_hash or "N/A"}
|
|
1086
|
+
"""
|
|
1087
|
+
if block_number:
|
|
1088
|
+
content += f"[htcli.value]Block Number:[/htcli.value] {block_number}\n"
|
|
1089
|
+
if block_hash:
|
|
1090
|
+
content += f"[htcli.value]Block Hash:[/htcli.value] {block_hash}\n"
|
|
1091
|
+
content += "\n[htcli.info]đ Thank you for contributing to the subnet treasury![/htcli.info]\n"
|
|
1092
|
+
panel = HTCLIPanel(
|
|
1093
|
+
content,
|
|
1094
|
+
title="đ Delegate Donation Complete",
|
|
1095
|
+
border_style="htcli.success",
|
|
1096
|
+
highlight=True,
|
|
1097
|
+
)
|
|
1098
|
+
panel.render(console.console)
|
|
1099
|
+
else:
|
|
1100
|
+
error_msg = response.error if hasattr(response, "error") else "Unknown error"
|
|
1101
|
+
console.print(
|
|
1102
|
+
f"[htcli.error]â Failed to donate delegate stake: {error_msg}[/]"
|
|
1103
|
+
)
|