Skip to content

Commit b8993fd

Browse files
committed
Progress
1 parent ff98f15 commit b8993fd

File tree

3 files changed

+140
-14
lines changed

3 files changed

+140
-14
lines changed

bittensor_cli/src/bittensor/subtensor_interface.py

+24
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
SubnetHyperparameters,
2626
decode_account_id,
2727
DelegateInfoLite,
28+
DynamicInfo,
2829
)
2930
from bittensor_cli.src import DelegatesDetails
3031
from bittensor_cli.src.bittensor.balances import Balance
@@ -1116,3 +1117,26 @@ async def get_delegates_by_netuid_light(
11161117
return []
11171118

11181119
return DelegateInfoLite.list_from_vec_u8(result) # TODO this won't work yet
1120+
1121+
async def get_subnet_dynamic_info(self, netuid: int) -> Optional["DynamicInfo"]:
1122+
json = await self.substrate.rpc_request(
1123+
method="subnetInfo_getDynamicInfo", params=[netuid, None]
1124+
)
1125+
subnets = DynamicInfo.from_vec_u8(json["result"])
1126+
return subnets
1127+
1128+
async def get_stake_for_coldkey_and_hotkey_on_netuid(
1129+
self,
1130+
hotkey_ss58: str,
1131+
coldkey_ss58: str,
1132+
netuid: int,
1133+
block_hash: Optional[str] = None,
1134+
) -> Optional["Balance"]:
1135+
"""Returns the stake under a coldkey - hotkey - netuid pairing"""
1136+
_result = await self.substrate.query(
1137+
"SubtensorModule", "Alpha", [hotkey_ss58, coldkey_ss58, netuid], block_hash
1138+
)
1139+
if _result is None:
1140+
return None
1141+
else:
1142+
return Balance.from_rao(_result).set_unit(int(netuid))

bittensor_cli/src/commands/stake/children_hotkeys.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ async def set_children_new(
490490
netuid: int,
491491
wait_for_inclusion: bool = True,
492492
wait_for_finalization: bool = True,
493-
prompt: bool = True
493+
prompt: bool = True,
494494
):
495495
"""Set children hotkeys."""
496496
# Validate children SS58 addresses

bittensor_cli/src/commands/stake/stake.py

+115-13
Original file line numberDiff line numberDiff line change
@@ -1154,6 +1154,10 @@ async def stake_add_new(
11541154
staking_address_ss58: str,
11551155
delegate: bool,
11561156
prompt: bool,
1157+
max_stake: float,
1158+
include_hotkeys: list[str],
1159+
exclude_hotkeys: list[str],
1160+
hotkey_ss58: Optional[str] = None,
11571161
):
11581162
"""
11591163
@@ -1176,7 +1180,7 @@ async def stake_add_new(
11761180
# Init the table.
11771181
table = Table(
11781182
title="[white]Staking operation from Coldkey SS58[/white]: "
1179-
f"[bold dark_green]{wallet.coldkeypub.ss58_address}[/bold dark_green]\n",
1183+
f"[bold dark_green]{wallet.coldkeypub.ss58_address}[/bold dark_green]\n",
11801184
width=console.width - 5,
11811185
safe_box=True,
11821186
padding=(0, 1),
@@ -1211,10 +1215,12 @@ async def stake_add_new(
12111215
remaining_wallet_balance = current_wallet_balance
12121216
max_slippage = 0
12131217

1214-
for netuid in netuids:
1218+
all_dynamic_info = await asyncio.gather(
1219+
*[subtensor.get_subnet_dynamic_info(x) for x in netuids]
1220+
)
1221+
1222+
for netuid, dynamic_info in zip(netuids, all_dynamic_info):
12151223
# Check that the subnet exists.
1216-
# TODO gather this
1217-
dynamic_info = subtensor.get_subnet_dynamic_info(netuid) # TODO add
12181224
if not dynamic_info:
12191225
err_console.print(f"Subnet with netuid: {netuid} does not exist.")
12201226
continue
@@ -1236,9 +1242,7 @@ async def stake_add_new(
12361242
amount_to_stake_as_balance = Balance.from_tao(amount)
12371243
elif stake_all:
12381244
amount_to_stake_as_balance = current_wallet_balance / len(netuids)
1239-
elif (
1240-
not amount and not max_stake
1241-
): # TODO should this be an Option? Asked in Cortex channel https://discord.com/channels/799672011265015819/1176889593136693339/1291756735316365456
1245+
elif not amount and not max_stake:
12421246
if Confirm.ask(f"Stake all: [bold]{remaining_wallet_balance}[/bold]?"):
12431247
amount_to_stake_as_balance = remaining_wallet_balance
12441248
else:
@@ -1291,6 +1295,103 @@ async def stake_add_new(
12911295
str(slippage_pct),
12921296
)
12931297
)
1298+
table.add_column("Netuid", justify="center", style="grey89")
1299+
table.add_column("Hotkey", justify="center", style="light_salmon3")
1300+
table.add_column(
1301+
f"Amount ({Balance.get_unit(0)})", justify="center", style="dark_sea_green"
1302+
)
1303+
table.add_column(
1304+
f"Rate ({Balance.get_unit(netuid)}/{Balance.get_unit(0)})",
1305+
justify="center",
1306+
style="light_goldenrod2",
1307+
)
1308+
table.add_column(
1309+
f"Recieved ({Balance.get_unit(netuid)})",
1310+
justify="center",
1311+
style="light_slate_blue",
1312+
)
1313+
table.add_column("Slippage", justify="center", style="rgb(220,50,47)")
1314+
for row in rows:
1315+
table.add_row(*row)
1316+
console.print(table)
1317+
message = ""
1318+
if max_slippage > 5:
1319+
message += "-------------------------------------------------------------------------------------------------------------------\n"
1320+
message += f"[bold][yellow]WARNING:[/yellow]\tThe slippage on one of your operations is high: [bold red]{max_slippage} %[/bold red], this may result in a loss of funds.[/bold] \n"
1321+
message += "-------------------------------------------------------------------------------------------------------------------\n"
1322+
console.print(message)
1323+
console.print(
1324+
"""
1325+
[bold white]Description[/bold white]:
1326+
The table displays information about the stake operation you are about to perform.
1327+
The columns are as follows:
1328+
- [bold white]Netuid[/bold white]: The netuid of the subnet you are staking to.
1329+
- [bold white]Hotkey[/bold white]: The ss58 address of the hotkey you are staking to.
1330+
- [bold white]Amount[/bold white]: The TAO you are staking into this subnet onto this hotkey.
1331+
- [bold white]Rate[/bold white]: The rate of exchange between your TAO and the subnet's stake.
1332+
- [bold white]Received[/bold white]: The amount of stake you will receive on this subnet after slippage.
1333+
- [bold white]Slippage[/bold white]: The slippage percentage of the stake operation. (0% if the subnet is not dynamic i.e. root).
1334+
"""
1335+
)
1336+
if prompt:
1337+
if not Confirm.ask("Would you like to continue?"):
1338+
return False
1339+
1340+
async def send_extrinsic(netuid_i, amount, current):
1341+
call = await subtensor.substrate.compose_call(
1342+
call_module="SubtensorModule",
1343+
call_function="add_stake",
1344+
call_params={
1345+
"hotkey": staking_address_ss58,
1346+
"netuid": netuid_i,
1347+
"amount_staked": amount.rao,
1348+
},
1349+
)
1350+
extrinsic = await subtensor.substrate.create_signed_extrinsic(
1351+
call=call, keypair=wallet.coldkey
1352+
)
1353+
response = await subtensor.substrate.submit_extrinsic(
1354+
extrinsic, wait_for_inclusion=True, wait_for_finalization=False
1355+
)
1356+
if not prompt: # TODO verbose?
1357+
console.print(
1358+
f":white_heavy_check_mark: [green]Submitted {amount} to {netuid_i}[/green]"
1359+
)
1360+
else:
1361+
await response.process_events()
1362+
if not await response.is_success:
1363+
err_console.print(
1364+
f":cross_mark: [red]Failed[/red] with error: {response.error_message}"
1365+
)
1366+
else:
1367+
new_balance_, new_stake_ = await asyncio.gather(
1368+
subtensor.get_balance(wallet.coldkeypub.ss58_address),
1369+
subtensor.get_stake_for_coldkey_and_hotkey_on_netuid(
1370+
coldkey_ss58=wallet.coldkeypub.ss58_address,
1371+
hotkey_ss58=staking_address_ss58,
1372+
netuid=netuid_i,
1373+
),
1374+
)
1375+
new_balance = new_balance_[wallet.coldkeypub.ss58_address]
1376+
new_stake = new_stake_.set_unit(netuid_i)
1377+
console.print(
1378+
f"Balance:\n [blue]{current_wallet_balance}[/blue] :arrow_right: [green]{new_balance}[/green]"
1379+
)
1380+
console.print(
1381+
f"Subnet: {netuid_i} Stake:\n [blue]{current}[/blue] :arrow_right: [green]{new_stake}[/green]"
1382+
)
1383+
1384+
# Perform staking operation.
1385+
wallet.unlock_coldkey()
1386+
with console.status(f"\n:satellite: Staking on netuid: {netuids} ..."):
1387+
await asyncio.gather(
1388+
*[
1389+
send_extrinsic(ni, am, curr)
1390+
for (ni, am, curr) in zip(
1391+
netuids, stake_amount_balance, current_stake_balances
1392+
)
1393+
]
1394+
)
12941395

12951396

12961397
async def stake_add(
@@ -1604,10 +1705,7 @@ async def unstake(
16041705
)
16051706

16061707

1607-
async def stake_list(
1608-
wallet: Wallet,
1609-
subtensor: "SubtensorInterface"
1610-
):
1708+
async def stake_list(wallet: Wallet, subtensor: "SubtensorInterface"):
16111709
substakes = subtensor.get_stake_info_for_coldkeys(
16121710
coldkey_ss58_list=[wallet.coldkeypub.ss58_address]
16131711
)[wallet.coldkeypub.ss58_address]
@@ -1617,8 +1715,12 @@ async def stake_list(
16171715

16181716
# Token pricing info.
16191717
dynamic_info = await subtensor.get_all_subnet_dynamic_info()
1620-
emission_drain_tempo = int(await subtensor.substrate.query("SubtensorModule", "HotkeyEmissionTempo"))
1621-
balance = (await subtensor.get_balance(wallet.coldkeypub.ss58_address))[wallet.coldkeypub.ss58_address]
1718+
emission_drain_tempo = int(
1719+
await subtensor.substrate.query("SubtensorModule", "HotkeyEmissionTempo")
1720+
)
1721+
balance = (await subtensor.get_balance(wallet.coldkeypub.ss58_address))[
1722+
wallet.coldkeypub.ss58_address
1723+
]
16221724

16231725
# Iterate over substakes and aggregate them by hotkey.
16241726
hotkeys_to_substakes: dict[str, list[StakeInfo]] = {}

0 commit comments

Comments
 (0)