Skip to content

Commit 12dd075

Browse files
Josh Earlenbaughjpe442
Josh Earlenbaugh
authored andcommitted
Added commnets throughtout unstaking script
1 parent f5810ea commit 12dd075

File tree

1 file changed

+62
-4
lines changed

1 file changed

+62
-4
lines changed

docs/staking-and-delegation/managing-stake-sdk.md

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,47 @@ import bittensor as bt
247247
import bittensor_wallet
248248
from bittensor import tao
249249

250+
<<<<<<< HEAD
251+
=======
252+
# Load environmental variables
253+
wallet_name = os.environ.get('WALLET')
254+
total_to_unstake = os.environ.get('TOTAL_TAO_TO_UNSTAKE')
255+
max_stakes_to_unstake = os.environ.get('MAX_STAKES_TO_UNSTAKE')
256+
257+
# Basic input validation for wallet and TAO amount
258+
if wallet_name is None:
259+
sys.exit("wallet name not specified. Usage: `TOTAL_TAO_TO_UNSTAKE=1 MAX_STAKES_TO_UNSTAKE=10 WALLET=my-wallet-name ./unstakerscript.py`")
260+
261+
if total_to_unstake is None:
262+
print("Unstaking total not specified, defaulting to 1 TAO.")
263+
total_to_unstake = 1
264+
else:
265+
try:
266+
total_to_unstake = float(total_to_unstake)
267+
except:
268+
sys.exit("invalid TAO amount!")
269+
270+
if max_stakes_to_unstake is None:
271+
max_stakes_to_unstake = 10
272+
else:
273+
try:
274+
max_stakes_to_unstake = int(max_stakes_to_unstake)
275+
except:
276+
sys.exit("invalid number for MAX_STAKES_TO_UNSTAKE")
277+
278+
# Print summary for configuration
279+
print(f"🔍 Using wallet: {wallet_name}")
280+
print(f"🧮 Unstaking a total of {total_to_unstake} TAO across up to {max_stakes_to_unstake} lowest-emission validators")
281+
282+
# Initialize Bittensor wallet and balamce object
283+
total_to_unstake = bt.Balance.from_tao(total_to_unstake)
284+
wallet = bt.wallet(wallet_name)
285+
wallet_ck = wallet.coldkeypub.ss58_address
286+
287+
unstake_minimum = 0.0005 # TAO
288+
289+
# Async helper to perform the actual unstake call
290+
>>>>>>> 84a50fd (Added commnets throughtout unstaking script)
250291
async def perform_unstake(subtensor, stake, amount):
251292
try:
252293
print(f"⏳ Attempting to unstake {amount} from {stake.hotkey_ss58} on subnet {stake.netuid}")
@@ -255,6 +296,8 @@ async def perform_unstake(subtensor, stake, amount):
255296
wallet, hotkey_ss58=stake.hotkey_ss58, netuid=stake.netuid, amount=amount
256297
)
257298
elapsed = time.time() - start
299+
300+
# Check result object and log outcome
258301
if result:
259302
print(f"✅ Successfully unstaked {amount} from {stake.hotkey_ss58} on subnet {stake.netuid} in {elapsed:.2f}s")
260303
return True
@@ -265,38 +308,50 @@ async def perform_unstake(subtensor, stake, amount):
265308
print(f"❌ Error during unstake from {stake.hotkey_ss58} on subnet {stake.netuid}: {e}")
266309
return False
267310

268-
311+
# Main async workflow
269312
async def main():
313+
# Use the async_subtensor context manager to interact with the chain
270314
async with bt.async_subtensor(network='test') as subtensor:
271315
try:
316+
#Retrive all active active stakes asscociated with the coldkey
272317
stakes = await subtensor.get_stake_for_coldkey(wallet_ck)
273318
except Exception as e:
274319
sys.exit(f"❌ Failed to get stake info: {e}")
275320

276-
# Filter and sort
321+
# Filter: Remove small stakes that are under the minimum threshold
277322
stakes = list(filter(lambda s: float(s.stake.tao) > unstake_minimum, stakes))
323+
324+
# Sort by emission rate (lowest emission first)
278325
stakes = sorted(stakes, key=lambda s: s.emission.tao)
326+
327+
# Limit to the N lowest emission validators
279328
stakes = stakes[:max_stakes_to_unstake]
280329

281330
if not stakes:
282331
sys.exit("❌ No eligible stakes found to unstake.")
283332

333+
# Print a summary of selected stakes before executint
284334
print(f"\n📊 Preparing to unstake from {len(stakes)} validators:\n")
285335
for s in stakes:
286336
print(f"Validator: {s.hotkey_ss58}\n NetUID: {s.netuid}\n Stake: {s.stake}\n Emission: {s.emission}\n-----------")
287337

288-
# Prepare concurrent unstake tasks
338+
# Determine how much TAO to unstake per validator
289339
amount_per_stake = total_to_unstake / len(stakes)
340+
341+
# Prepare all unstake calls to run concurrently
290342
tasks = [
291343
perform_unstake(subtensor, stake, min(amount_per_stake, stake.stake))
292344
for stake in stakes
293345
]
294346

347+
# Execute unstatke tasks concurrently using ayncio
295348
results = await asyncio.gather(*tasks)
296-
success_count = sum(results)
297349

350+
# Count successes and print final report
351+
success_count = sum(results)
298352
print(f"\n🎯 Unstake complete. Success: {success_count}/{len(stakes)}")
299353

354+
<<<<<<< HEAD
300355
wallet_name = os.environ.get('WALLET')
301356
total_to_unstake = os.environ.get('TOTAL_TAO_TO_UNSTAKE')
302357
max_stakes_to_unstake = os.environ.get('MAX_STAKES_TO_UNSTAKE')
@@ -331,6 +386,9 @@ wallet_ck = wallet.coldkeypub.ss58_address
331386
# There is a global on-chain minimum balanced allowed for unstaking operations.
332387
unstake_minimum = 0.0005
333388

389+
=======
390+
# Run the async workflow
391+
>>>>>>> 84a50fd (Added commnets throughtout unstaking script)
334392
asyncio.run(main())
335393

336394
```

0 commit comments

Comments
 (0)