Skip to main content

Create a redelegation

Redelegation is a core feature that sets Advanced Permissions apart from other permission sharing frameworks. It allows a session account (delegate) to create a delegation chain, passing on the same or reduced level of authority from the MetaMask account (delegator).

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

Request Advanced Permissions

Request Advanced Permissions from the user with the Wallet Client's requestExecutionPermissions action.

This example uses the ERC-20 periodic permission, allowing the user to grant dapp the ability to spend 10 USDC on their behalf.

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,
signer: {
type: "account",
data: {
// The requested permissions will be granted to the
// session account.
address: 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,
}]);

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 utility function.

import { decodeDelegations } from "@metamask/smart-accounts-kit/utils";

const permissionsContext = grantedPermissions[0].context;

const delegations = decodeDelegations(permissionsContext);
const rootDelegation = delegations[0];

Create a redelegation

Create a redelegation from dapp to a Swap agent.

To create a redelegation, provide the signed delegation as the parentDelegation argument when calling createDelegation.

This example uses the erc20TransferAmount scope, 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.

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

const redelegation = createDelegation({
scope: {
type: "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 })