Create a delegation
Delegation is the ability for a smart contract account (the delegator) to grant permission to another smart contract account, or externally owned account (the delegate) to perform specific executions on the delegator's behalf, under defined rules and conditions.
Prerequisites
- Install and set up the MetaMask Delegation Toolkit.
- Configure the toolkit.
- Create a delegator account.
The DelegationStruct
type
Delegations are created using the DelegationStruct
type, which is specified as follows:
export type DelegationStruct = {
delegate: Hex; // The address to which the delegation is being granted.
delegator: Hex; // The address that is granting the delegation.
authority: Hex; // Hash of the parent delegation, or the constant ROOT_AUTHORITY.
caveats: CaveatStruct[]; // Caveats that restrict the authority being granted.
salt: bigint; // Used to avoid hash collisions between identical delegations.
signature: Hex; // Signature from the delegator account.
};
The examples on this page demonstrate delegations without any restrictions. Unrestricted delegations grant complete control over the account to the delegate, which can pose significant security risks. It is crucial to add caveats to limit the delegated authority. Learn how to restrict a delegation using caveat enforcers.
The examples on this page assume the existence of a delegatorSmartAccount
.
Create a root delegation
A root delegation is a delegation that doesn't derive its authority from another delegation. It is when a delegator delegates its own authority away, as opposed to a redelegation. Create a root delegation as follows:
import {
createRootDelegation,
} from "@codefi/delegator-core-viem";
// ...
// The address to which the delegation is granted.
const delegate = "0x2FcB88EC2359fA635566E66415D31dD381CF5585";
const delegation = createRootDelegation(
delegate,
delegatorSmartAccount.address,
[] // Empty caveats array - we recommend adding appropriate restrictions.
);
Create an open delegation
An open delegation is a delegation that doesn't specify a delegate.
This means that any account can redeem the delegation.
You must create open delegations carefully, to ensure that they are not misused.
Create an open delegation by setting the delegate property to the special address
0x0000000000000000000000000000000000000a11
(available via the constant ANY_BENEFICIARY
).
import {
createOpenRootDelegation,
} from "@codefi/delegator-core-viem";
// ...
const openRootDelegation = createOpenRootDelegation(
delegatorSmartAccount.address,
[] // Empty caveats array - we recommend adding appropriate restrictions.
);
Create a redelegation
A recipient of a delegation (the delegate), can redelegate that authority to a third party, potentially applying additional restrictions. Create a redelegation as follows:
import {
createDelegation,
getDelegationHashOffchain
} from "@codefi/delegator-core-viem";
// ...
// A received delegation, where the delegate is equal to delegatorSmartAccount.address.
const delegation = { ... };
// The address to which the redelegation is granted.
const delegate = "0x2FcB88EC2359fA635566E66415D31dD381CF5585";
// The authority is the (typed data) hash of the delegation from which the authority is derived.
const authority = getDelegationHashOffchain(delegation);
const delegation = createDelegation(
delegate,
delegatorSmartAccount.address,
authority,
[] // Empty caveats array - we recommend adding appropriate restrictions.
);
Create an open redelegation
An open redelegation is a redelegation that doesn't specify a delegate. This means that any account can redeem the redelegation. As with open delegations, you must create open redelegations carefully, to ensure that they are not misused. Create an open redelegation as follows:
import {
createOpenDelegation,
getDelegationHashOffchain
} from "@codefi/delegator-core-viem";
// ...
// A received delegation, where the delegate is equal to delegatorSmartAccount.address
const delegation = { ... };
// The authority is the (typed data) hash of the delegation from which the authority is derived.
const authority = getDelegationHashOffchain(delegation);
const delegation = createOpenDelegation(
delegatorSmartAccount.address,
authority,
[] // Empty caveats array - we recommend adding appropriate restrictions.
);
Sign a delegation
A delegation must be signed by the delegator to be valid for redemption. The MetaMaskSmartAccount
supports signing the delegation using EIP-712 Typed Data via the signDelegation
method.
Sign a delegation as follows:
import {
createRootDelegation
} from "@codefi/delegator-core-viem";
// ...
// The address to which the redelegation is granted.
const delegate = "0x2FcB88EC2359fA635566E66415D31dD381CF5585";
// A received delegation, where the delegator is equal to delegatorSmartAccount.address
const delegation = createRootDelegation(
delegate,
delegatorSmartAccount.address,
[] // Empty caveats array - we recommend adding appropriate restrictions.
);
const signature = await delegatorSmartAccount.signDelegation({ delegation });
const signedDelegation = {
...delegation,
signature
};