# Set up Polkadot staking with the API

You can only participate in staking on Polkadot ledgers as a validator from Ripple Custody (Vault).

You can perform the following staking tasks:

- Bond tokens: Designate tokens for staking, a prerequisite before nomination of validators.
- Unbond tokens: Remove bonded tokens from staking. After you unbond tokens, you can withdraw the unbonded tokens, or rebond the tokens.
- Rebond: Rebond and stake unbonded tokens before the unbonding period finishes.
- Bond extra: Add additional tokens to the already bonded amount.
- Withdraw unbonded: Add unbonded tokens back to the account balance.
- Chill: Clear the list of nominated validators without unbonding the tokens. To restart staking after this operation, you need to nominate new validators.
- Nominate: Nominate up to sixteen validators to which to delegate your bonded tokens.
- Set payee account: Set or change the account to receive the rewards from staking.
- Set controller: Set the account to act as controller, as described in [Account types](#account-types).


## Account types

Polkadot ledgers require the following two account types for staking:

- A stash account: Holds the funds to use for staking.
- A controller account: Controls the staking operations, such as nomination of validators.


If you want to maximize security, you can store the stash account in a separate, cold vault.

Ripple Custody (Vault) doesn't impose the two account requirement: you can also choose to configure staking with a single account type if preferred.

The following table summarizes which account has the role to submit each of the staking operations listed below:

| Operation | Controller | Stash |
|  --- | --- | --- |
| Bond |  | X |
| BondExtra |  | X |
| Unbond | X |  |
| WithdrawUnbonded | X |  |
| Rebond | X |  |
| Chill | X |  |
| Nominate | X |  |
| SetController |  | X |
| SetPayee | X |  |


## Prerequisites

To perform staking tasks on Polkadot, you need the following:

| Prerequisite | Additional information |
|  --- | --- |
| Accounts on a Polkadot ledger from which to initiate the transactions (two accounts are recommended, as described in [Account types](#account-types)) | [View account details](/pt-br/products/custody/accounts-and-assets/accounts/manage-accounts-api#view-account-details) |
| Enough funds in the account to cover the transaction fees and the amount | [Check account balances](/pt-br/products/custody/accounts-and-assets/accounts/manage-accounts-api#check-account-balances) |
| The following new IDs, in a standard UUID format:A transaction order IDAn intent ID |  |


## Perform staking tasks

System change process
All new requests to change the system state follow the same process. To familiarize yourself with this process first, see [Manage intents and approvals](/pt-br/products/custody/governance/intents/manage-intents-and-approvals).

To perform Polkadot staking tasks, follow the steps in [Manage intents and approvals](/pt-br/products/custody/governance/intents/manage-intents-and-approvals), with a payload similar to one of the following examples.

The SDK examples assume a configured client. See [Integrate via SDK](/pt-br/products/custody/get-started/integrate-via-sdk). Each SDK method builds the operation, submits the intent, and returns a pending intent. To track the intent, call `waitAccepted` and `waitExecuted` (`wait_accepted` and `wait_executed` in Python). The Java examples pass `null` for `ledgerId` and `customProperties`, and reuse the `feeStrategy` from the first example. The examples use `stashAccountId` and `controllerAccountId` for the accounts described in [Account types](#account-types).

### Payload examples

#### Bond tokens

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "a4a87f1c-7577-4115-9b54-cc445ec08fb5",
        "parameters": {
            "pallet": {
                "method": {
                    "controller": {
                        "address": "5CwKL1nknaXcVfjJaXZ7rFtCJg8sc5tk4ppCzTbAURtBXwMQ",
                        "type": "Address"
                    },
                    "value": "500000000000",
                    "payee": {
                        "destination": {
                            "accountId": "f943d65c-58e3-4ba3-83eb-d66fdce0f32a",
                            "type": "Account"
                        },
                        "type": "Account"
                    },
                    "type": "Bond"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingBond(stashAccountId, {
  value: '500000000000',
  controllerAddress: '5CwKL1nknaXcVfjJaXZ7rFtCJg8sc5tk4ppCzTbAURtBXwMQ',
  payeeAccountId: rewardAccountId,
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
import com.ripple.custody.PendingIntent;
import com.ripple.custody.models.CoreFeePriority;
import com.ripple.custody.models.CoreSubstrateFeeStrategyPriority;
import com.ripple.custody.models.CoreSubstrateStakingPayee;
import com.ripple.custody.models.CoreSubstrateStakingPayeeAccount;
import com.ripple.custody.models.CoreTransactionDestination;
import com.ripple.custody.models.CoreTransactionDestinationAccount;
import com.ripple.custody.models.CoreTransactionDestinationAddress;

CoreSubstrateFeeStrategyPriority feeStrategy =
    new CoreSubstrateFeeStrategyPriority().priority(CoreFeePriority.LOW);

CoreTransactionDestination controller = new CoreTransactionDestination(
    new CoreTransactionDestinationAddress()
        .address("5CwKL1nknaXcVfjJaXZ7rFtCJg8sc5tk4ppCzTbAURtBXwMQ")
        .type(CoreTransactionDestinationAddress.TypeEnum.ADDRESS));

CoreSubstrateStakingPayee payee = new CoreSubstrateStakingPayee(
    new CoreSubstrateStakingPayeeAccount()
        .destination(new CoreTransactionDestination(
            new CoreTransactionDestinationAccount()
                .accountId(rewardAccountId)
                .type(CoreTransactionDestinationAccount.TypeEnum.ACCOUNT)))
        .type(CoreSubstrateStakingPayeeAccount.TypeEnum.ACCOUNT));

PendingIntent pending = client.transactions().substrateStakingBond(
    domainId, stashAccountId, null, "500000000000", payee, controller,
    feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_bond(
    stash_account_id,
    value="500000000000",
    controller_address="5CwKL1nknaXcVfjJaXZ7rFtCJg8sc5tk4ppCzTbAURtBXwMQ",
    payee_account_id=reward_account_id,
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

To pay rewards to the controller, the stash, or back into the bond instead of an account, use `payeeType: 'Controller' | 'Stash' | 'Staked'` in TypeScript, `payee="Controller"`, `"Stash"`, or `"Staked"` in Python, or the `CoreSubstrateStakingPayeeController`, `CoreSubstrateStakingPayeeStash`, or `CoreSubstrateStakingPayeeStaked` model in Java.

For a program that builds and submits these operations, see example `53` (advanced chain operations) in TypeScript or Python. To get the examples, see [Examples](/pt-br/products/custody/developer-experience/sdks#examples).

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The stash account. For more information, see [Account types](#account-types). |
| `pallet.method.controller` | The controller account of the stash account. This account can be the either the stash account or another account. You can set this to an `Account`, `Endpoint` or `Address`. |
| `pallet.method.type` | `Bond` |
| `pallet.method.value` | The amount to bond, in Plancks. |
| `pallet.method.payee` | Destination of the staking rewards. The `type` can be `Controller`, `Stash`, `Staked`  or `Account`. If you specify `Account`, then you can set the `destination.type` of `Account`, `Endpoint` or `Address`. You can change this later, with the [Set payee account](#set-payee-account) operation. |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


#### Unbond tokens

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "4a15c769-fadb-40c2-adce-4c7733015bea",
        "parameters": {
            "pallet": {
                "method": {
                    "value": "1000000000000",
                    "type": "Unbond"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingUnbond(controllerAccountId, {
  value: '1000000000000',
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
PendingIntent pending = client.transactions().substrateStakingUnbond(
    domainId, controllerAccountId, null, "1000000000000", feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_unbond(
    controller_account_id,
    value="1000000000000",
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The controller account. For more information, see [Account types](#account-types). |
| `pallet.method.type` | `Unbond` |
| `pallet.method.value` | The amount to unbond from the bonded amount, in Plancks. |


#### Withdraw unbonded tokens

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "4a15c769-fadb-40c2-adce-4c7733015bea",
        "parameters": {
            "pallet": {
                "method": {
                    "numSlashingSpans": 0,
                    "type": "WithdrawUnbonded"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingWithdrawUnbonded(controllerAccountId, {
  numSlashingSpans: 0,
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
PendingIntent pending = client.transactions().substrateStakingWithdrawUnbonded(
    domainId, controllerAccountId, null, 0, feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_withdraw_unbonded(
    controller_account_id,
    num_slashing_spans=0,
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The controller account. For more information, see [Account types](#account-types). |
| `pallet.method.type` | `WithdrawUnbonded` |
| `pallet.method.numSlashingSpans` | The slashing mechanism of Polkadot splits the eras of each nominator into slashing spans to detect the events on which a nominator gets slashed. If acting as nominator, no slashing occurred during the era, the value of `method.numSlashingSpans` should be 0. |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


#### Rebond tokens

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "4a15c769-fadb-40c2-adce-4c7733015bea",
        "parameters": {
            "pallet": {
                "method": {
                    "value": "1000000000000",
                    "type": "Rebond"
                },
                "type": "Staking"
            },
            "feeStrategy": {
               "priority": "Low",
               "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingRebond(controllerAccountId, {
  value: '1000000000000',
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
PendingIntent pending = client.transactions().substrateStakingRebond(
    domainId, controllerAccountId, null, "1000000000000", feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_rebond(
    controller_account_id,
    value="1000000000000",
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The controller account. For more information, see [Account types](#account-types). |
| `pallet.method.type` | `Rebond` |
| `pallet.method.value` | The amount to rebond, in Plancks. |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


#### Bond extra

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "a4a87f1c-7577-4115-9b54-cc445ec08fb5",
        "parameters": {
            "pallet": {
                "method": {
                    "maxAdditional": "1000000000000",
                    "type": "BondExtra"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingBondExtra(stashAccountId, {
  maxAdditional: '1000000000000',
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
PendingIntent pending = client.transactions().substrateStakingBondExtra(
    domainId, stashAccountId, null, "1000000000000", feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_bond_extra(
    stash_account_id,
    max_additional="1000000000000",
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The stash account. For more information, see [Account types](#account-types). |
| `pallet.method.type` | `BondExtra` |
| `pallet.method.maxAdditional` | The funds to add to the already bonded amount, in Plancks. |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


#### Nominate staking validators

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "4a15c769-fadb-40c2-adce-4c7733015bea",
        "parameters": {
            "pallet": {
                "method": {
                    "targets": [
                        {
                           "accountId": "f943d65c-58e3-4ba3-83eb-d66fdce0f32a",
                           "type": "Account"
                        },
                        {
                           "accountId": "953d75b2-e384-46e9-8a72-a1ce753a50e2",
                           "type": "Account"
                        }
                    ],
                    "type": "Nominate"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingNominate(controllerAccountId, {
  targets: [{ toAccountId: validatorAccountId1 }, { toAccountId: validatorAccountId2 }],
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
import java.util.List;

List<CoreTransactionDestination> targets = List.of(validatorAccountId1, validatorAccountId2)
    .stream()
    .map(id -> new CoreTransactionDestination(
        new CoreTransactionDestinationAccount()
            .accountId(id)
            .type(CoreTransactionDestinationAccount.TypeEnum.ACCOUNT)))
    .toList();

PendingIntent pending = client.transactions().substrateStakingNominate(
    domainId, controllerAccountId, null, targets, feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_nominate(
    controller_account_id,
    targets=[
        {"account_id": validator_account_id_1},
        {"account_id": validator_account_id_2},
    ],
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The controller account. For more information, see [Account types](#account-types). |
| `pallet.method.targets` | Account addresses to nominate as validators. |
| `pallet.method.type` | `Nominate` |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


#### Set payee account

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "4a15c769-fadb-40c2-adce-4c7733015bea",
        "parameters": {
            "pallet": {
                "method": {
                    "payee": {
                        "destination": {
                            "accountId": "f943d65c-58e3-4ba3-83eb-d66fdce0f32a",
                            "type": "Account"
                        },
                        "type": "Account"
                    },
                    "type": "SetPayee"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingSetPayee(controllerAccountId, {
  payeeAccountId: rewardAccountId,
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
CoreSubstrateStakingPayee payee = new CoreSubstrateStakingPayee(
    new CoreSubstrateStakingPayeeAccount()
        .destination(new CoreTransactionDestination(
            new CoreTransactionDestinationAccount()
                .accountId(rewardAccountId)
                .type(CoreTransactionDestinationAccount.TypeEnum.ACCOUNT)))
        .type(CoreSubstrateStakingPayeeAccount.TypeEnum.ACCOUNT));

PendingIntent pending = client.transactions().substrateStakingSetPayee(
    domainId, controllerAccountId, null, payee, feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_set_payee(
    controller_account_id,
    to_account_id=reward_account_id,
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The controller account. For more information, see [Account types](#account-types). |
| `pallet.method.type` | `SetPayee` |
| `pallet.method.payee` | Destination of the staking rewards. The `type` can be `Controller`, `Stash`, `Staked`  or `Account`. If you specify `Account`, then you can set the `destination.type` of `Account`, `Endpoint` or `Address`. This overrides the payee set with the [Bond](#bond-tokens) operation. |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


#### Chill

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "4a15c769-fadb-40c2-adce-4c7733015bea",
        "parameters": {
            "pallet": {
                "method": {
                    "type": "Chill"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingChill(controllerAccountId, {
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
PendingIntent pending = client.transactions().substrateStakingChill(
    domainId, controllerAccountId, null, feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_chill(
    controller_account_id, fee_priority="Low", maximum_fee="20460002010"
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The controller account. For more information, see [Account types](#account-types). |
| `pallet.method.type` | `Chill` |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


#### Update controller account

API
```json
{
    "payload": {
        "id": "251c48e9-8a7d-4e1a-9c1e-224de1b55c0d",
        "accountId": "a4a87f1c-7577-4115-9b54-cc445ec08fb5",
        "parameters": {
            "pallet": {
                "method": {
                    "controller": {
                        "accountId": "f943d65c-58e3-4ba3-83eb-d66fdce0f32a",
                        "type": "Account"
                    },
                    "type": "SetController"
                },
                "type": "Staking"
            },
            "feeStrategy": {
                "priority": "Low",
                "type": "Priority"
            },
            "maximumFee": "20460002010",
            "type": "Substrate"
        },
        "customProperties": {},
        "type": "v0_CreateTransactionOrder"
    }
}
```

TypeScript
```typescript
const pending = await client.transactions.substrate.stakingSetController(stashAccountId, {
  controllerAccountId,
  feePriority: 'Low',
  maximumFee: '20460002010',
});
```

Java
```java
CoreTransactionDestination controller = new CoreTransactionDestination(
    new CoreTransactionDestinationAccount()
        .accountId(controllerAccountId)
        .type(CoreTransactionDestinationAccount.TypeEnum.ACCOUNT));

PendingIntent pending = client.transactions().substrateStakingSetController(
    domainId, stashAccountId, null, controller, feeStrategy, "20460002010", null);
```

Python
```python
pending = client.transactions.substrate.staking_set_controller(
    stash_account_id,
    to_account_id=controller_account_id,
    fee_priority="Low",
    maximum_fee="20460002010",
)
```

Fields of the `payload` block to note are as follows:

| Field | Description |
|  --- | --- |
| `accountId` | The stash account. For more information, see [Account types](#account-types). |
| `pallet.method.type` | `SetController` |
| `pallet.method.controller` | The controller wallet, either an internal `Account`, an `Endpoint`, or an external `Address`. |
| `pallet.type` | `Staking` |
| `parameters.feeStrategy` | The fee strategy to use for the transaction. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.maximumFee` | The maximum fee, in Plancks. For more information, see [Fee strategy and maximum fee](/pt-br/products/custody/transactions/reference#fee-strategy-and-maximum-fee). |
| `parameters.type` | Ledger type, in this case `Substrate`. |
| `type` | `v0_CreateTransactionOrder` |


When the transaction order is successfully approved, Ripple Custody (Vault) does the following:

- Creates a transaction, to broadcast the details on the blockchain.
- Creates one or more transfers, to represent the separate amounts associated with the transaction, such as the cryptocurrency amount and the fees.