Create a redelegation
Redelegation is a core feature that sets delegations apart from other permission sharing frameworks. It allows a delegate to create a delegation chain, passing on the same or reduced level of authority from the root delegator.
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 reshared with additional parties.
Prerequisites
Create a delegation
Create a root delegation from Alice to Bob.
This example uses the erc20TransferAmount scope, allowing
Alice to delegate to Bob the ability to spend 10 USDC on her behalf.
- delegation.ts
- config.ts
import { aliceSmartAccount, bobSmartAccount } from "./config.ts";
import { createDelegation } from '@metamask/smart-accounts-kit'
import { parseUnits } from 'viem'
const delegation = createDelegation({
scope: {
type: "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 })
import { Implementation, toMetaMaskSmartAccount } from "@metamask/smart-accounts-kit"
import { privateKeyToAccount } from "viem/accounts"
import { createPublicClient, http } from "viem"
import { sepolia as chain } from "viem/chains"
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 },
})
Create a redelegation
Create a 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.
This example uses the erc20TransferAmount scope, allowing
Bob to delegate to Carol the ability to spend 5 USDC on Alice's behalf.
- redelegation.ts
- config.ts
import { bobSmartAccount, carolSmartAccount } from "./config.ts"
import { createDelegation } from '@metamask/smart-accounts-kit'
import { parseUnits } from 'viem'
const redelegation = createDelegation({
scope: {
type: "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 })
// 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 },
})
Next steps
- See how to disable a delegation to revoke permissions.