Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 30 additions & 30 deletions docs/keys/proxies/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,29 +12,26 @@ See [Working with Proxies](./proxies/working-with-proxies)

Proxies allow one wallet to perform Bittensor operations on behalf of another. Used correctly, this allows you to add a strong layer of additional protection for your most important wallets and the valuable assets they control, such as large TAO or alpha holdings, or subnet ownership. Proxy relationships are useful both for one person managing their own coldkey security, and also for allowing one person to on behalf of another person or an organization.

The private key and seed phrase for a highly valuable wallet's coldkey should be kept offline as much as possible, and only used via a dedicated, highly secure [coldkey workstation](../coldkey-hotkey-security.md). By allowing one coldkey to serve as a *proxy* or stand-in for another, the "real account" or "safe wallet", we add an additional layer of security for the safe wallet by leaving it in cold storage and using the proxy instead.
The private key and seed phrase for a highly valuable wallet's coldkey should be kept offline as much as possible, and only used via a dedicated, highly secure [coldkey workstation](../coldkey-hotkey-security.md). By allowing one coldkey to serve as a _proxy_ or stand-in for another, the "real account" or "safe wallet", we add an additional layer of security for the safe wallet by leaving it in cold storage and using the proxy instead.

### Common use cases

Proxies are useful in many situations where the permissions of one coldkey should be gated behind another level of security:

- **Staking operations**: Keep your coldkey secure in cold storage while using a proxy to manage staking operations.

See [Staking with a Proxy](../../keys/proxies/staking-with-proxy.md).
- **Staking operations**: Keep your coldkey secure in cold storage while using a proxy to manage staking operations.

See [Staking with a Proxy](../../keys/proxies/staking-with-proxy.md).

- **Operational delegation**: run subnet operations tasks like setting hyperparameters from a designated operations wallet, allowing the owner wallet to remain in maximum-security deep storage.
- **Least-privilege permissions**: allow an employee or other designated operoator to perform a constrained set of calls on a project-owned wallet.
- **Least-privilege permissions**: allow an employee or other designated operator to perform a constrained set of calls on a project-owned wallet.

### Scope and Delays

The power of proxies as a security tool comes from the two ways proxies can be limited: in the scope of their permissions, and by requiring a delay with announcement before they can perform operations. It's critical to note that without using these constraints properly, proxies don't necessarily give any security benefit.

- The proxy can be constrained to specific operations. The permission scope is determined by the `ProxyType` call filter.
- The proxy can be constrained to specific operations. The permission scope is determined by the `ProxyType` call filter.
- The proxy can be constrained by a **delay** with a public **announcement**, giving the safe wallet holder time to reject a call made by they proxy (for example, if a key has been compromised).





### Terminology and parameters

- Safe wallet/real account: The wallet/account being protected by the proxy relationship.
Expand All @@ -49,41 +46,44 @@ If the proxy entry includes a non-zero delay, the delegate cannot execute the ca

The real account always retains full control over the relationship. It can revoke a proxy’s access to their proxy operations at any time by removing the proxy entry, immediately disabling the delegate’s ability to act on its behalf.

:::note proxies vs pure proxies
*Proxies*, which 'stand in' for a real account by initiating transactions on its behalf, must not be confused with *pure proxies*, which 'stand-in' for the real account in a reverse relationship, where the real account can initiate transactions on behalf of the pure proxy. Pure proxies are primarily designed to be used with multi-sig wallets.
:::info proxies vs pure proxies
_Proxies_ allow a delegate account to initiate transactions on behalf of a real account. _Pure proxies_, however, work differently: they are accounts controlled by the real account, which can initiate transactions on the pure proxy’s behalf. Pure proxies are mainly used with multisig wallets.

See also:

- [Pure proxies](../keys/proxies/pure-proxies)
- [Multi-sig wallets](../keys/multisig)
- [Polkadot.js Substrate Proxy Docs](https://wiki.polkadot.com/learn/learn-proxies/)
:::
:::

### Transaction fee payment

By default, the delegate pays the transaction fees for proxy calls in a proxy relationship. The real account can optionally be configured to pay these fees instead.

To enable this, the real account must call the [`setRealPaysFee`](https://github.com/opentensor/subtensor/blob/devnet-ready/pallets/proxy/src/lib.rs#:~:text=pub%20fn%20set_real_pays_fee) extrinsic in the `Proxy` pallet and provide the delegate account along with a boolean value indicating whether the real account should pay the transaction fee. When enabled, both the transaction value and the transaction fee are deducted from the real account rather than the delegate account.

## `ProxyType`

This defines what the proxy is allowed to do on behalf of the real account. It describes the capabilities of that proxy (e.g., staking-only, transfer-only, registration-only, etc.).

The following table shows the available `ProxyType` options and their descriptions:

| `ProxyType` | Description |
| ------------------------ | ----------------------------------------------------------------------------------- |
| `Any` | Grants full permissions to execute any call on behalf of the real account. This is the most permissive `ProxyType`; use with caution. |
| `Owner` | Allows subnet identity and settings management. Permitted operations: AdminUtils calls (except `sudo_set_sn_owner_hotkey`), `set_subnet_identity`, `update_symbol`. |
| `NonCritical` | Allows all operations except critical ones that could harm the account. Prohibited operations: `dissolve_network`, `root_register`, `burned_register`, Sudo calls. |
| `NonTransfer` | Allows all operations except token transfers. Prohibited operations: all Balances module calls, `transfer_stake`, `schedule_swap_coldkey`, `swap_coldkey`. |
| `ProxyType` | Description |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Any` | Grants full permissions to execute any call on behalf of the real account. This is the most permissive `ProxyType`; use with caution. |
| `Owner` | Allows subnet identity and settings management. Permitted operations: AdminUtils calls (except `sudo_set_sn_owner_hotkey`), `set_subnet_identity`, `update_symbol`. |
| `NonCritical` | Allows all operations except critical ones that could harm the account. Prohibited operations: `dissolve_network`, `root_register`, `burned_register`, Sudo calls. |
| `NonTransfer` | Allows all operations except token transfers. Prohibited operations: all Balances module calls, `transfer_stake`, `schedule_swap_coldkey`, `swap_coldkey`. |
| `NonFungible` | Allows all operations except token-related operations and registrations. Prohibited operations: all Balances module calls, all staking operations (`add_stake`, `remove_stake`, `unstake_all`, `swap_stake`, `move_stake`, `transfer_stake`), registration operations (`burned_register`, `root_register`), key swap operations (`schedule_swap_coldkey`, `swap_coldkey`, `swap_hotkey`). |
| `Staking` | Allows only staking-related operations: `add_stake`, `add_stake_limit`, `remove_stake`, `remove_stake_limit`, `remove_stake_full_limit`, `unstake_all`, `unstake_all_alpha`, `swap_stake`, `swap_stake_limit`, `move_stake`. |
| `Registration` | Allows only neuron registration operations: `burned_register`, `register`. |
| `Transfer` | Allows only token transfer operations: `transfer_keep_alive`, `transfer_allow_death`, `transfer_all`, `transfer_stake`. |
| `SmallTransfer` | Allows only small token transfers below 0.5 TAO. Permitted operations: `transfer_keep_alive`, `transfer_allow_death` (if value < 0.5 TAO), `transfer_stake` (if alpha_amount < 0.5 TAO). |
| `ChildKeys` | Allows only child key management operations: `set_children`, `set_childkey_take`. |
| `SudoUncheckedSetCode` | Allows only runtime code updates: `sudo_unchecked_weight` with inner call `System::set_code`. |
| `SwapHotkey` | Allows only hotkey swap operations: `swap_hotkey`. |
| `SubnetLeaseBeneficiary` | Allows subnet management and configuration operations: `start_call`, multiple `AdminUtils.sudo_set_*` calls for subnet parameters, network settings, weights, alpha values, etc. |
| `RootClaim` | Allows only root claim operations: `claim_root`. |


| `Staking` | Allows only staking-related operations: `add_stake`, `add_stake_limit`, `remove_stake`, `remove_stake_limit`, `remove_stake_full_limit`, `unstake_all`, `unstake_all_alpha`, `swap_stake`, `swap_stake_limit`, `move_stake`. |
| `Registration` | Allows only neuron registration operations: `burned_register`, `register`. |
| `Transfer` | Allows only token transfer operations: `transfer_keep_alive`, `transfer_allow_death`, `transfer_all`, `transfer_stake`. |
| `SmallTransfer` | Allows only small token transfers below 0.5 TAO. Permitted operations: `transfer_keep_alive`, `transfer_allow_death` (if value < 0.5 TAO), `transfer_stake` (if alpha_amount < 0.5 TAO). |
| `ChildKeys` | Allows only child key management operations: `set_children`, `set_childkey_take`. |
| `SudoUncheckedSetCode` | Allows only runtime code updates: `sudo_unchecked_weight` with inner call `System::set_code`. |
| `SwapHotkey` | Allows only hotkey swap operations: `swap_hotkey`. |
| `SubnetLeaseBeneficiary` | Allows subnet management and configuration operations: `start_call`, multiple `AdminUtils.sudo_set_*` calls for subnet parameters, network settings, weights, alpha values, etc. |
| `RootClaim` | Allows only root claim operations: `claim_root`. |

## Best practices for using proxies

Expand Down
23 changes: 17 additions & 6 deletions docs/keys/proxies/pure-proxies.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ It is critical to understand that pure proxies do not offer the security advanta

### Transaction flow in pure proxies

All transactions involving a pure proxy must be signed by the spawner account. Once signed, the transaction is executed on-chain as if it originated directly from the pure proxy. Unlike standard proxies, a pure proxy must hold its own funds to cover fees or transfers. The spawner then acts as an _Any proxy_, handling the signing and authorization of calls, but the balance used comes from the pure proxy's account.
All transactions involving a pure proxy must be signed by the spawner account. Once signed, the transaction is executed on-chain as if it originated directly from the pure proxy. Unlike standard proxies, a pure proxy must hold its own funds to cover the transaction value. The spawner then acts as an _Any proxy_, signing and authorizing calls and paying transaction fees, while the balance used for the call comes from the pure proxy’s account.

:::info Transaction fees
By default, the spawner account covers the transaction fee when a proxy is executed. However, if the value of the proxy relationship's `realPaysFee` parameter has been set to `True`, the transaction fees will be covered by the pure proxy account when a proxy is executed.

For more information, see [Transaction fee payment](./index.md#transaction-fee-payment)
:::

### Multisigs and Pure Proxies

Expand Down Expand Up @@ -244,8 +250,11 @@ btcli wallet transfer \
--amount 1.0
```

:::warning Pure proxy must be funded
Ensure the pure proxy account has enough funds to cover both the transfer amount and transaction fees. Transfer funds to the pure proxy first using a regular transfer.
:::warning Pure proxy account must be funded
Ensure the pure proxy account holds enough funds to cover the transaction value. Attempting to perform a proxy operation without funding the pure proxy account with return a `FundsUnavailable` error.

You can transfer funds to the pure proxy account using the `btcli wallet transfer` command in your terminal.

:::

**Other operations through pure proxies:**
Expand Down Expand Up @@ -322,8 +331,10 @@ Balances(subtensor).transfer_keep_alive(...)

:::

:::warning
Ensure the pure proxy account holds enough funds to cover both the transfer and transaction fees.
:::warning Pure proxy account must be funded
Ensure the pure proxy account holds enough funds to cover the transaction value. Attempting to perform a proxy operation without funding the pure proxy account with return a `FundsUnavailable` error.

You can transfer funds to the pure proxy account using the `btcli wallet transfer` command in your terminal.

:::

Expand All @@ -345,7 +356,7 @@ Ensure the pure proxy account holds enough funds to cover both the transfer and
:::info

- After submitting the transaction, check the Polkadot.JS web app's **Explorer** page for a `balances.Transfer` event. Notice the sender is the pure proxy account.
- Ensure the pure proxy account holds enough funds to cover both the transfer and transaction fees.
- Ensure the pure proxy account holds enough funds to cover the transaction value.
:::

</TabItem>
Expand Down