> For the complete documentation index, see [llms.txt](/llms.txt).

# Create a redelegation

Redelegation is a core feature that sets [Advanced Permissions](/smart-accounts-kit/development/reference/glossary#advanced-permissions)**Advanced Permissions** Fine-grained, wallet execution permissions that dapps can request from MetaMask extension users. Based on ERC-7715. apart from other permission sharing frameworks. It allows a session account ([delegate](/smart-accounts-kit/development/reference/glossary#delegate-account)**Delegate account** The account that receives delegated authority and can redeem a delegation under its constraints.) to create a delegation chain, passing on the same or reduced level of authority from the MetaMask account ([delegator](/smart-accounts-kit/development/reference/glossary#delegator-account)**Delegator account** The account that creates and signs a delegation to grant limited authority to another account.).

For example, if a dapp is granted permission to spend 10 USDC on a user's behalf, it can further delegate that permission to specific agents, such as allowing a Swap agent to spend up to 5 USDC. This creates a permission sharing chain in which the root permissions are shared with additional parties.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

- [Install and set up the Smart Accounts Kit.](/smart-accounts-kit/1.2.0/get-started/install/)
- [Learn about Advanced Permissions.](/smart-accounts-kit/1.2.0/concepts/advanced-permissions/)
- [Learn how to request Advanced Permissions.](/smart-accounts-kit/1.2.0/guides/advanced-permissions/execute-on-metamask-users-behalf/)

## Request Advanced Permissions[​](#request-advanced-permissions "Direct link to Request Advanced Permissions")

Request Advanced Permissions from the user with the Wallet Client's [requestExecutionPermissions](/smart-accounts-kit/1.2.0/reference/advanced-permissions/wallet-client/#requestexecutionpermissions) action.

This example uses the [ERC-20 periodic permission](/smart-accounts-kit/1.2.0/guides/advanced-permissions/use-permissions/erc20-token/#erc-20-periodic-permission), allowing the user to grant dapp the ability to spend 10 USDC on their behalf.

- example.ts
- config.ts

```
import { sepolia as chain } from 'viem/chains'
import { sessionAccount, walletClient, tokenAddress } from './config.ts'
import { parseUnits } from 'viem'

// Since current time is in seconds, we need to convert milliseconds to seconds.
const currentTime = Math.floor(Date.now() / 1000)
// 1 week from now.
const expiry = currentTime + 604800

const grantedPermissions = await walletClient.requestExecutionPermissions([
  {
    chainId: chain.id,
    expiry,
    // The requested permissions will granted to the
    // session account.
    to: sessionAccount.address,
    permission: {
      type: 'erc20-token-periodic',
      data: {
        tokenAddress,
        // 10 USDC in wei format. Since USDC has 6 decimals, 10 * 10^6
        periodAmount: parseUnits('10', 6),
        // 1 day in seconds
        periodDuration: 86400,
        justification: 'Permission to transfer 10 USDC every day',
      },
      isAdjustmentAllowed: true,
    },
  },
])

```

```
import { createWalletClient, custom, createPublicClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { toMetaMaskSmartAccount, Implementation } from '@metamask/smart-accounts-kit'
import { erc7715ProviderActions } from '@metamask/smart-accounts-kit/actions'
import { sepolia as chain } from 'viem/chains'

// USDC address on Ethereum Sepolia.
export const tokenAddress = '0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238'

const publicClient = createPublicClient({
  chain,
  transport: http(),
})

const privateKey = '0x...'
const account = privateKeyToAccount(privateKey)

export const sessionAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Hybrid,
  deployParams: [account.address, [], [], []],
  deploySalt: '0x',
  signer: { account },
})

export const walletClient = createWalletClient({
  transport: custom(window.ethereum),
}).extend(erc7715ProviderActions())

```

## Decode delegations[​](#decode-delegations "Direct link to Decode delegations")

The granted permissions object includes a `context` property that represents the encoded delegations.

To create a redelegation, you must first decode these delegations to access the underlying delegations. To decode the delegations, use the [decodeDelegations](/smart-accounts-kit/1.2.0/reference/delegation/#decodedelegations) utility function.

```
import { decodeDelegations } from '@metamask/smart-accounts-kit/utils'

const permissionContext = grantedPermissions[0].context

const delegations = decodeDelegations(permissionContext)
const rootDelegation = delegations[0]

```

## Create a redelegation[​](#create-a-redelegation-1 "Direct link to Create a redelegation")

Create a [redelegation](/smart-accounts-kit/1.2.0/concepts/delegation/overview/#redelegation) from dapp to a Swap agent.

To create a redelegation, provide the signed delegation as the `parentDelegation` argument when calling [createDelegation](/smart-accounts-kit/1.2.0/reference/delegation/#createdelegation).

This example uses the [erc20TransferAmount](/smart-accounts-kit/1.2.0/guides/delegation/use-delegation-scopes/spending-limit/#erc-20-transfer-scope) [scope](/smart-accounts-kit/development/reference/glossary#delegation-scope)**Delegation scope** A predefined authority pattern representing a caveat or group of caveats, which sets the initial actions a delegate is allowed to perform. You can combine scopes with additional caveats., allowing dapp to delegate to a Swap agent the ability to spend 5 USDC on user's behalf.

note

When creating a redelegation, you can only narrow the scope of the original authority, not expand it.

- redelegation.ts
- config.ts

```
import { sessionAccount, agentSmartAccount, tokenAddress } from './config.ts'
import { createDelegation, ScopeType } from '@metamask/smart-accounts-kit'
import { parseUnits } from 'viem'

const redelegation = createDelegation({
  scope: {
    type: ScopeType.Erc20TransferAmount,
    tokenAddress,
    // USDC has 6 decimal places.
    maxAmount: parseUnits('5', 6),
  },
  to: agentSmartAccount.address,
  from: sessionAccount.address,
  // Signed root delegation extracted from Advanced Permissions.
  parentDelegation: rootDelegation,
  environment: sessionAccount.environment,
})

const signedRedelegation = await sessionAccount.signDelegation({ delegation: redelegation })

```

```
// Update the existing config to create a smart account for a Swap agent.

const agentAccount = privateKeyToAccount('0x...')

export const agentSmartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Hybrid,
  deployParams: [agentAccount.address, [], [], []],
  deploySalt: '0x',
  signer: { account: agentAccount },
})

```

### Limit redelegation using caveats[​](#limit-redelegation-using-caveats "Direct link to Limit redelegation using caveats")

When you create a redelegation, apply the toolkit's [caveats](/smart-accounts-kit/1.2.0/reference/delegation/caveats/) to narrow the Swap agent's authority. For example, you can limit the authority so Swap agent can use the delegation only once.

To apply caveats, create the `Delegation` object and use [createCaveatBuilder](/smart-accounts-kit/1.2.0/reference/delegation/#createcaveatbuilder). Use [hashDelegation](/smart-accounts-kit/1.2.0/reference/delegation/#hashdelegation) to get the delegation hash, then provide it as the `authority` field.

This example uses the [limitedCalls](/smart-accounts-kit/1.2.0/reference/delegation/caveats/#limitedcalls) caveat with a limit of `1`.

```
// Use the config from previous step.
import { sessionAccount, agentSmartAccount, tokenAddress } from './config.ts'
import { CaveatType } from '@metamask/smart-accounts-kit'
import { createCaveatBuilder, hashDelegation } from '@metamask/smart-accounts-kit/utils'

const caveatBuilder = createCaveatBuilder(sessionAccount.environment)

const caveats = caveatBuilder.addCaveat(CaveatType.LimitedCalls, { limit: 1 })

const redelegation: Delegation = {
  delegate: sessionAccount.address,
  delegator: agentSmartAccount.address,
  authority: hashDelegation(rootDelegation),
  caveats: caveats.build(),
  salt: '0x',
}

const signedRedelegation = await sessionAccount.signDelegation({ delegation: redelegation })

```
