|
50 | 50 | )
|
51 | 51 |
|
52 | 52 |
|
| 53 | +async def associate_hotkey( |
| 54 | + wallet: Wallet, |
| 55 | + subtensor: SubtensorInterface, |
| 56 | + hotkey_ss58: str, |
| 57 | +): |
| 58 | + """Associates a hotkey with a wallet""" |
| 59 | + owner_ss58 = await subtensor.get_hotkey_owner(hotkey_ss58) |
| 60 | + if owner_ss58: |
| 61 | + if owner_ss58 == wallet.coldkeypub.ss58_address: |
| 62 | + console.print( |
| 63 | + f":white_heavy_check_mark: Hotkey [{COLORS.GENERAL.HK}]{hotkey_ss58}[/{COLORS.GENERAL.HK}] is already " |
| 64 | + f"associated with \nwallet [blue]{wallet.name}[/blue], " |
| 65 | + f"SS58: [{COLORS.GENERAL.CK}]{owner_ss58}[/{COLORS.GENERAL.CK}]" |
| 66 | + ) |
| 67 | + return True |
| 68 | + else: |
| 69 | + owner_wallet = _get_wallet_by_ss58(wallet.path, owner_ss58) |
| 70 | + wallet_name = owner_wallet.name if owner_wallet else "unknown wallet" |
| 71 | + console.print( |
| 72 | + f"[yellow]Warning[/yellow]: Hotkey [{COLORS.GENERAL.HK}]{hotkey_ss58}[/{COLORS.GENERAL.HK}] is already associated with \n" |
| 73 | + f"wallet: [blue]{wallet_name}[/blue], SS58: [{COLORS.GENERAL.CK}]{owner_ss58}[/{COLORS.GENERAL.CK}]" |
| 74 | + ) |
| 75 | + return False |
| 76 | + else: |
| 77 | + console.print( |
| 78 | + f"Hotkey [{COLORS.GENERAL.HK}]{hotkey_ss58}[/{COLORS.GENERAL.HK}] is not associated with any wallet" |
| 79 | + ) |
| 80 | + |
| 81 | + if not Confirm.ask("Do you want to continue with the association?"): |
| 82 | + return False |
| 83 | + |
| 84 | + if not unlock_key(wallet).success: |
| 85 | + return False |
| 86 | + |
| 87 | + call = await subtensor.substrate.compose_call( |
| 88 | + call_module="SubtensorModule", |
| 89 | + call_function="try_associate_hotkey", |
| 90 | + call_params={ |
| 91 | + "hotkey": hotkey_ss58, |
| 92 | + }, |
| 93 | + ) |
| 94 | + |
| 95 | + with console.status(":satellite: Associating hotkey on-chain..."): |
| 96 | + success, err_msg = await subtensor.sign_and_send_extrinsic( |
| 97 | + call, |
| 98 | + wallet, |
| 99 | + wait_for_inclusion=True, |
| 100 | + wait_for_finalization=False, |
| 101 | + ) |
| 102 | + |
| 103 | + if not success: |
| 104 | + console.print( |
| 105 | + f"[red]:cross_mark: Failed to associate hotkey: {err_msg}[/red]" |
| 106 | + ) |
| 107 | + return False |
| 108 | + |
| 109 | + console.print( |
| 110 | + f"[green]:white_heavy_check_mark: Successfully associated hotkey[/green] " |
| 111 | + f"[{COLORS.GENERAL.HK}]{hotkey_ss58}[/{COLORS.GENERAL.HK}] with \nwallet [blue]{wallet.name}[/blue], " |
| 112 | + f"SS58: [{COLORS.GENERAL.CK}]{wallet.coldkeypub.ss58_address}[/{COLORS.GENERAL.CK}]" |
| 113 | + ) |
| 114 | + return True |
| 115 | + |
| 116 | + |
53 | 117 | async def regen_coldkey(
|
54 | 118 | wallet: Wallet,
|
55 | 119 | mnemonic: Optional[str],
|
@@ -257,6 +321,15 @@ def get_coldkey_wallets_for_path(path: str) -> list[Wallet]:
|
257 | 321 | return wallets
|
258 | 322 |
|
259 | 323 |
|
| 324 | +def _get_wallet_by_ss58(path: str, ss58_address: str) -> Optional[Wallet]: |
| 325 | + """Find a wallet by its SS58 address in the given path.""" |
| 326 | + ss58_addresses, wallet_names = _get_coldkey_ss58_addresses_for_path(path) |
| 327 | + for wallet_name, addr in zip(wallet_names, ss58_addresses): |
| 328 | + if addr == ss58_address: |
| 329 | + return Wallet(path=path, name=wallet_name) |
| 330 | + return None |
| 331 | + |
| 332 | + |
260 | 333 | def _get_coldkey_ss58_addresses_for_path(path: str) -> tuple[list[str], list[str]]:
|
261 | 334 | """Get all coldkey ss58 addresses from path."""
|
262 | 335 |
|
@@ -1596,8 +1669,7 @@ async def find_coldkey_swap_extrinsic(
|
1596 | 1669 | """
|
1597 | 1670 |
|
1598 | 1671 | current_block, genesis_block = await asyncio.gather(
|
1599 |
| - subtensor.substrate.get_block_number(), |
1600 |
| - subtensor.substrate.get_block_hash(0) |
| 1672 | + subtensor.substrate.get_block_number(), subtensor.substrate.get_block_hash(0) |
1601 | 1673 | )
|
1602 | 1674 | if (
|
1603 | 1675 | current_block - start_block > 300
|
|
0 commit comments