|
| 1 | +--- |
| 2 | +toc_max_heading_level: 2 |
| 3 | +--- |
| 4 | + |
| 5 | +# Create a Proxy Account |
| 6 | + |
| 7 | +This tutorial walks you through creating a standard proxy and executing a call from the proxy account using the Polkadot.js web app. You will set up a delegate account, add it as a proxy to your real account with a chosen `ProxyType`, and optionally use announcements for delayed execution. |
| 8 | + |
| 9 | +--- |
| 10 | + |
| 11 | +A standard proxy links a _delegator_ to a known account. The delegator specifies: |
| 12 | + |
| 13 | +- The _delegate_ account. |
| 14 | +- The allowed `ProxyType` (scope of permissions). |
| 15 | +- An optional delay. |
| 16 | + |
| 17 | +The delegate has access to funds in the real account and can then execute calls on behalf of the real account within the constraints of the specified `ProxyType`. |
| 18 | + |
| 19 | +:::info When to use standard proxies |
| 20 | +Delegating through a standard proxy is a good option when you want to entrust control to trusted individuals or organizations who can act on your behalf. In this setup, the delegate maintains their own independent signing capability, which allows them to initiate and authorize actions without relying on your key. This approach provides maximum operational flexibility while also making the delegate responsible for managing the security of their own keys. |
| 21 | +::: |
| 22 | + |
| 23 | +## Prerequisites |
| 24 | + |
| 25 | +- A locally running subtensor development chain. For more information, see [run a local Bittensor blockchain instance](../../local-build/deploy.md). |
| 26 | +- [Polkadot‑JS browser app](https://polkadot.js.org/apps/?#/explorer) and [Polkadot‑JS browser extension](https://chrome.google.com/webstore/detail/polkadot%7Bjs%7D-extension/mopnmbcafieddcagagdcbnhejhlodfdd) installed. |
| 27 | +- An accessible 'Alice' wallet. For more information, see [Provision Wallets for Local Deploy](../../local-build/provision-wallets). |
| 28 | +- At least 3 different accounts in your Polkadot-JS app: |
| 29 | + - Real (delegator) account that controls funds and adds the proxy. |
| 30 | + - Delegate account to perform allowed actions. |
| 31 | + - A recipient account to receive transferred funds. |
| 32 | + |
| 33 | +To import accounts into the Polkadot-JS web app, see [create and import accounts to the Polkadot-JS extension](../../keys/multisig.md#create-and-import-3-coldkey-pairs-accounts-in-the-polkadot-js-browser-extension). |
| 34 | + |
| 35 | +## Step 1: Connect Polkadot‑JS to your local chain |
| 36 | + |
| 37 | +1. Open the Polkadot‑JS app. |
| 38 | +2. In the network selector, choose Development → custom endpoint `ws://127.0.0.1:9944`. |
| 39 | +3. Confirm your local chain metadata loads and your test accounts appear in the **Accounts** tab. |
| 40 | + |
| 41 | +:::tip |
| 42 | +If the web app does not connect to your local chain, your browser’s privacy or security settings may be blocking it. Try adjusting those settings and reconnecting. |
| 43 | +::: |
| 44 | + |
| 45 | +## Step 2: Add a Proxy |
| 46 | + |
| 47 | +1. In the navbar menu, navigate to **Developers** → **Extrinsics**. |
| 48 | +2. Under “using the selected account”, pick the funded delegator account. |
| 49 | +3. Under “submit the following extrinsic”, choose the `proxy` pallet and call `addProxy(delegate, proxyType, delay)`. |
| 50 | +4. Fill the parameters: |
| 51 | + |
| 52 | + - `delegate`: select the imported delegate account from the _Accounts_ dropdown. |
| 53 | + - `proxyType`: select `SmallTransfer`; this should allow us to transfer amounts that do not exceed 0.5τ. |
| 54 | + - `delay`: optionally, include a delay in blocks. |
| 55 | + |
| 56 | +5. Click **Submit Transaction** and sign with the _delegator_ account. |
| 57 | + |
| 58 | +Your delegate is now authorized to execute small transfers on behalf of the real account. |
| 59 | + |
| 60 | +:::info |
| 61 | +A delegator can assign multiple proxies to the same delegate account. However, each proxy entry must use a unique `ProxyType`. Attempting to register a duplicate entry with the same delegate and `ProxyType` will result in a `proxy.Duplicate` error. |
| 62 | +::: |
| 63 | + |
| 64 | +### Checking an Account’s Proxies |
| 65 | + |
| 66 | +You can check which proxies are associated with an account to see their delegate addresses, proxy types, and any configured delays. To do this: |
| 67 | + |
| 68 | +1. From the **Developer** dropdown, navigate to **Chain state** → **Storage**. |
| 69 | +2. Click the **selected state query** menu and select `proxy.proxies`. |
| 70 | +3. Select the account used to create the proxy. |
| 71 | +4. Click the **+** icon to run the query. |
| 72 | + |
| 73 | +This returns the set of proxies related to the account and their information—`delegate`, `proxyType`, and `delay`. |
| 74 | + |
| 75 | +## Step 3: Execute a Proxy Call |
| 76 | + |
| 77 | +1. Go to **Developer** → **Extrinsics**. |
| 78 | +2. Under “using the selected account”, choose the delegate account. |
| 79 | +3. Select the `proxy` pallet and choose `proxy(real, forceProxyType, call)`. |
| 80 | +4. Fill the parameters: |
| 81 | + - `real`: select the real account used to create the proxy. |
| 82 | + - `forceProxyType`: leave option unchecked. |
| 83 | + - `call`: the call to be made by the delegate account. Fill the following parameters: |
| 84 | + - Select the `balances` pallet and choose the `transferKeepAlive(dest, value)` extrinsic. |
| 85 | + - `dest`: select the recipient account. |
| 86 | + - `value`: input the amount to be transferred in RAO—1 TAO = 1<sup>9</sup>RAO. |
| 87 | +5. Click **Submit Transaction** and sign the transaction from the delegate account. |
| 88 | + |
| 89 | +The runtime verifies that the call is permitted by the proxy filter and that any delay requirements have been met, then dispatches the call as if signed by the Real account. |
| 90 | + |
| 91 | +:::info |
| 92 | +After submitting the transaction, check the Polkadot.JS web app's **Explorer** page for a `balances.Transfer` event. Notice the sender is the delegator account. |
| 93 | +::: |
| 94 | + |
| 95 | +:::warning |
| 96 | + |
| 97 | +- With the SmallTransfer proxy type, transfers are limited to less than 0.5 TAO (500,000,000 RAO). Use the Transfer proxy type for amounts above this limit. See [source code: SmallTransfer limit definition](https://github.com/opentensor/subtensor/blob/main/common/src/lib.rs#L43). |
| 98 | +- The delegate account must hold enough funds to cover transaction fees, which are approximately 25 µTAO (0.000025 TAO). |
| 99 | + ::: |
| 100 | + |
| 101 | +If you configured a non-zero delay when creating the proxy, you must first make an announcement before executing the proxy call. Attempting to execute a proxy call before announcing returns a `proxy.Unannounced` error. |
| 102 | + |
| 103 | +<details> |
| 104 | +<summary><strong>Announce and execute a delayed proxy</strong></summary> |
| 105 | + |
| 106 | +Announcing a delayed proxy call requires the hash of the call that you intend to execute. Therefore, you must first generate the call hash of the transaction you want to carry out. To generate the call hash: |
| 107 | + |
| 108 | +1. Go to **Developer** → **Extrinsics**. |
| 109 | +2. Under “**using the selected account**”, pick the delegate account. |
| 110 | +3. Under “**submit the following extrinsic**”, choose the `balances` pallet and call the `transferKeepAlive(dest, value)` extrinsic. |
| 111 | +4. Fill the parameters: |
| 112 | + - `dest`: select the recipient account. |
| 113 | + - `value`: input the amount to be transferred in RAO—1 TAO = 1<sup>9</sup>RAO. |
| 114 | +5. Copy the hex code shown in the **encoded call data** field. You will use this to announce the call in the next step. |
| 115 | + |
| 116 | +--- |
| 117 | + |
| 118 | +:::info |
| 119 | +Do not submit the transaction after entering the parameters. Only copy the encoded call data once all parameters are provided. |
| 120 | +::: |
| 121 | + |
| 122 | +--- |
| 123 | + |
| 124 | +### Announce a call |
| 125 | + |
| 126 | +To announce a delayed call: |
| 127 | + |
| 128 | +1. Go to **Developer** → **Extrinsics** tab. |
| 129 | +2. Choose the `proxy` pallet and select the `announce(real, call_hash)` extrinsic. |
| 130 | +3. Fill the parameters: |
| 131 | + - `real`: select the real account used to create the proxy. |
| 132 | + - `callHash`: paste the call hash of the transaction to be executed. |
| 133 | +4. Click **Submit Transaction** and sign the transaction from the delegate account. |
| 134 | + |
| 135 | +Next, wait for the duration of the configured delay—in blocks—before executing the call. During the waiting period, the delegate can cancel the announcement—`removeAnnouncement(real, callHash)`, while the real account retains final authority to reject it—`rejectAnnouncement(delegate, callHash)`. |
| 136 | + |
| 137 | +### Execute a delayed proxy call |
| 138 | + |
| 139 | +After the announcement waiting period has passed, the delegate account can now execute the proxy if the real account did not reject it. Attempting to execute the proxy before the waiting period passes returns a `proxy.Unannounced` error. To execute a delayed proxy call: |
| 140 | + |
| 141 | +1. Go to **Developer** → **Extrinsics**. |
| 142 | +2. Under “using the selected account”, choose the delegate account. |
| 143 | +3. Select the `proxy` pallet and choose `proxyAnnounced(delegate, real, forceProxyType, call)`. |
| 144 | +4. Fill the parameters: |
| 145 | + - `delegate`: select the delegate account. |
| 146 | + - `real`: select the real account used to create the proxy. |
| 147 | + - `forceProxyType`: leave option unchecked. |
| 148 | + - `call`: the call to be made by the delegate account. Fill the following parameters: |
| 149 | + - Select the `balances` pallet and choose the `transferKeepAlive(dest, value)` extrinsic. |
| 150 | + - `dest`: select the recipient account. |
| 151 | + - `value`: input the amount to be transferred in RAO—1 TAO = 1<sup>9</sup>RAO. |
| 152 | +5. Click **Submit Transaction** and sign the transaction from the delegate account. |
| 153 | + |
| 154 | +--- |
| 155 | + |
| 156 | +:::info |
| 157 | + |
| 158 | +- The call details must exactly match the original announcement. Any change—such as modifying the recipient or amount—will result in a `proxy.Unannounced` error. |
| 159 | +- Once a delayed proxy call is executed, its announcement is cleared. To execute another proxy with the same details, you must create a new announcement and wait for the waiting period to pass. |
| 160 | + ::: |
| 161 | + |
| 162 | +--- |
| 163 | + |
| 164 | +</details> |
| 165 | + |
| 166 | +## Step 4: Remove a Proxy |
| 167 | + |
| 168 | +1. In the navbar menu, navigate to **Developers** → **Extrinsics**. |
| 169 | +2. Under “using the selected account”, pick the delegator account. |
| 170 | +3. Under "submit the following extrinsic", choose the `proxy` pallet and call `removeProxy(delegate, proxyType, delay)`. |
| 171 | +4. Fill the parameters: |
| 172 | + |
| 173 | + - `delegate`: select the imported delegate account from the _Accounts_ dropdown. |
| 174 | + - `proxyType`: select `SmallTransfer`; this should allow us to transfer amounts that do not exceed 0.5τ. |
| 175 | + - `delay`: Optionally, include a delay in blocks. |
| 176 | + |
| 177 | +5. Click **Submit Transaction** and sign with the _delegator_ account. |
| 178 | + |
| 179 | +## Troubleshooting |
| 180 | + |
| 181 | +- `proxy.Duplicate`: A proxy with the same configuration already exists on the real account. See [source code: `Duplicate` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L739). |
| 182 | +- `proxy.Unannounced`: A non-zero delay proxy requires an announcement; announce and wait the delay. See [source code: `Unannounced` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L743). |
| 183 | +- `proxy.Unproxyable`/`system.CallFiltered`: The call is not permitted under the current `ProxyType`. See [source code: `Unproxyable` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L737). |
| 184 | +- `proxy.TooMany`: You exceeded `MaxProxies` or `MaxPending`. Remove unused proxies/announcements. See [source code: `TooMany` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L731). |
| 185 | +- `proxy.NotProxy`: Ensure you're submitting from the delegate account and referencing the correct real account. See [source code: `NotProxy` error](https://github.com/opentensor/subtensor/blob/main/pallets/proxy/src/lib.rs#L735). |
| 186 | +- `Token.FundsUnavailable`: Ensure that your real account has enough available funds to cover the transaction. |
0 commit comments