# Create a redelegation

> Learn how to create a redelegation.

# Create a redelegation

Redelegation is a core feature that sets delegations apart from other permission sharing frameworks.
It allows a <GlossaryTerm term="Delegate account">delegate</GlossaryTerm> to create a delegation chain, passing on the same or reduced level of authority
from the root <GlossaryTerm term="Delegator account">delegator</GlossaryTerm>.

For example, if Alice grants Bob permission to spend 10 USDC on her behalf, Bob can further grant Carol
permission to spend up to 5 USDC on Alice's behalf-that is, Bob can redelegate. This creates a delegation
chain where the root permissions are re-shared with additional parties.

## Prerequisites

- [Install and set up the Smart Accounts Kit.](../../get-started/install.md)
- [Learn how to create a delegation.](execute-on-smart-accounts-behalf.md)

## Create a delegation

Create a [root delegation](../../concepts/delegation/overview.md#root-delegation) from Alice to Bob.

This example uses the [`erc20TransferAmount`](use-delegation-scopes/spending-limit.md#erc-20-transfer-scope) <GlossaryTerm term="Delegation scope">scope</GlossaryTerm>, allowing
Alice to delegate to Bob the ability to spend 10 USDC on her behalf.

<Tabs>
<TabItem value="delegation.ts">

```typescript

const delegation = createDelegation({
  scope: {
    type: ScopeType.Erc20TransferAmount,
    tokenAddress: '0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92',
    // USDC has 6 decimal places.
    maxAmount: parseUnits('10', 6),
  },
  to: bobSmartAccount.address,
  from: aliceSmartAccount.address,
  environment: aliceSmartAccount.environment,
})

const signedDelegation = aliceSmartAccount.signDelegation({ delegation })
```

</TabItem>
<TabItem value="config.ts">

```typescript

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

const aliceAccount = privateKeyToAccount('0x...')
const bobAccount = privateKeyToAccount('0x...')

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

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

</TabItem>
</Tabs>

## Create a redelegation

Create a [redelegation](../../concepts/delegation/overview.md#redelegation) from Bob to Carol. When creating a redelegation, you can only narrow the scope of the original authority, not expand it.

To create a redelegation, provide the signed delegation as the `parentDelegation` argument when calling [`createDelegation`](../../reference/delegation/index.md#createdelegation).
This example uses the [`erc20TransferAmount`](use-delegation-scopes/spending-limit.md#erc-20-transfer-scope) <GlossaryTerm term="Delegation scope">scope</GlossaryTerm>, allowing
Bob to delegate to Carol the ability to spend 5 USDC on Alice's behalf.

<Tabs>
<TabItem value="redelegation.ts">

```typescript

const redelegation = createDelegation({
  scope: {
    type: ScopeType.Erc20TransferAmount,
    tokenAddress: '0xc11F3a8E5C7D16b75c9E2F60d26f5321C6Af5E92',
    // USDC has 6 decimal places.
    maxAmount: parseUnits('5', 6),
  },
  to: carolSmartAccount.address,
  from: bobSmartAccount.address,
  // Signed root delegation from previous step.
  parentDelegation: signedDelegation,
  environment: bobSmartAccount.environment,
})

const signedRedelegation = bobSmartAccount.signDelegation({ delegation: redelegation })
```

</TabItem>
<TabItem value="config.ts">

```typescript
// Update the existing config to create a smart account for Carol.

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

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

</TabItem>
</Tabs>

### Limit redelegation using caveats

When you create a redelegation, apply the toolkit's [caveats](../../reference/delegation/caveats.md) to narrow the Carol's authority. For example, you can limit the authority so Carol can use the delegation only once.

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

This example uses the [`limitedCalls`](../../reference/delegation/caveats.md#limitedcalls) caveat with a limit of `1`.

```ts
// Use the config from previous step.

const caveatBuilder = createCaveatBuilder(bobSmartAccount.environment)

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

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

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

## Next steps

See [how to disable a delegation](disable-delegation.md) to revoke permissions.
