# associate-hotkey (/docs/tx/associate-hotkey)

Records on chain that the signing coldkey owns the hotkey, without
registering it on any subnet or staking anything. Useful when the pairing
should be visible before the hotkey's first registration (registration and
staking establish it as a side effect). The chain only associates hotkeys
that are not already owned: if the hotkey already belongs to a coldkey the
call succeeds but is silently a no-op — it does not error, and it does not
take over the hotkey.

| Signer    | Origin                                 | Pallet          | Wraps                                                                                                  |
| --------- | -------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------ |
| `coldkey` | signed account (pallet role may apply) | SubtensorModule | [`SubtensorModule.try_associate_hotkey`](/code/pallets/subtensor/src/macros/dispatches.rs#L1519-L1527) |

## Parameters [#parameters]

| Parameter     | Type   | Required | Description                                       |
| ------------- | ------ | -------- | ------------------------------------------------- |
| `hotkey_ss58` | string | no       | Hotkey to record as owned by the signing coldkey. |

Address parameters (`--hotkey`, `--coldkey`, `--dest`, ...) accept a raw ss58
address, an address-book or proxy-book name, or a local wallet/hotkey name.

## CLI [#cli]

Preview with `--dry-run` (shows fee, effects, and policy result without
submitting), then submit:

```bash
btcli tx associate-hotkey --dry-run
btcli tx associate-hotkey -w my_coldkey
```

## Python [#python]

```python
import bittensor as bt
from bittensor.wallet import Wallet

wallet = Wallet(name="my_coldkey", hotkey="my_hotkey")
intent = bt.AssociateHotkey()

sub = bt.Subtensor()
plan = sub.plan(intent, wallet)   # fee, effects, policy — no submission
result = sub.execute(intent, wallet)
if not result.success:
    print(result.error.code, result.error.remediation)
```

(`bt.Subtensor` is also the async client — `async with bt.Subtensor() as client:`
— see [The client](/docs/concepts/client).) Or build the intent by op name, as
an agent would:

```python
result = sub.execute_tool("associate_hotkey", {...}, wallet)
```

## On-chain implementation [#on-chain-implementation]

`SubtensorModule.try_associate_hotkey` — [`pallets/subtensor/src/macros/dispatches.rs#L1521`](/code/pallets/subtensor/src/macros/dispatches.rs#L1519-L1527):

```rust
#[pallet::call_index(91)]
#[pallet::weight(<T as crate::pallet::Config>::WeightInfo::try_associate_hotkey())]
pub fn try_associate_hotkey(origin: OriginFor<T>, hotkey: T::AccountId) -> DispatchResult {
    let coldkey = ensure_signed(origin)?;

    Self::do_try_associate_hotkey(&coldkey, &hotkey)?;

    Ok(())
}
```

Delegates to [`do_try_associate_hotkey`](/code/pallets/subtensor/src/staking/account.rs#L4).

Every file is browsable under [/code](/code) exactly as built into the runtime, or as plain text under `/code/raw/<path>` (index: [`/code/index.json`](/code/index.json)).
