Redeem a delegation
To redeem a delegation, a delegate
must submit a user operation that calls the redeemDelegation
function on the MetaMaskSmartAccount
instance. Multiple delegations may be redeemed within a single user operation.
Prerequisites
- Install and set up the MetaMask Delegation Toolkit.
- Configure the toolkit.
Redeem a delegation
Assuming the existence of a bundler client, a MetaMaskSmartAccount
instance, and a signed delegation granted to this smart contract account, the following example shows how to submit a user operation redeeming the delegation.
import { DelegationFramework } from '@codefi/delegator-core-viem';
//...
// The delegations array is a chain of delegations. If the delegation is a root, then it will be only one.
// Otherwise it must be all of the delegations in the chain, in order from leaf to root. This is the order
// returned from the delegation service.
const delegations: DelegationStruct[] = [ delegation ];
// SINGLE_DEFAULT is the default execution mode. See below for an explanation of the different execution modes available.
const mode: ExecutionMode = SINGLE_DEFAULT;
// For SINGLE execution modes, the executions array must be length 1.
const executions: ExecutionStruct[] = [{
target, // the address being called as a hex string
value, // the value of the call as a bigint
callData // the calldata as a hex string
}];
const redeemDelegationCalldata = DelegationFramework.encode.redeemDelegations(
[ delegations ],
[ mode ],
[ executions ]
);
const userOperationHash = await bundler.sendUserOperation({
account: delegatorSmartAccount,
calls: [
{
to: delegatorSmartAccount.address,
data: redeemDelegationCalldata
}
],
maxFeePerGas,
maxPriortyFeePerGas
});
Redeem multiple delegations
Multiple delegations may be redeemed in a single user operation, each independent of the others.
Each element in the delegationsArray
, must have a corresponding element in the executionsArray
and modes
.
import { DelegationFramework } from '@codefi/delegator-core-viem';
//...
const delegationsArray: DelegationStruct[][] = [
[ delegation1 ]
[ delegation2 ]
[ delegation3 ]
];
const modes: ExecutionMode = [
SINGLE_DEFAULT,
SINGLE_DEFAULT,
SINGLE_DEFAULT
];
const executionsArray: ExecutionStruct = [
[ execution1 ],
[ execution2 ],
[ execution3 ]
];
const redeemDelegationsCalldata = DelegationFramework.encode.redeemDelegations(
delegationsArray,
modes,
executionsArray
);
const userOperationHash = await bundler.sendUserOperation({
account: delegatorSmartAccount,
calls: [
{
to: delegatorSmartAccount.address,
data: redeemDelegationsCalldata
}
],
maxFeePerGas,
maxPriortyFeePerGas
});
Execution modes
The Delegation Toolkit supports a number of execution modes, which are based on ERC-7579. See the ERC implementation which describes execution modes in detail
The supported execution modes are SINGLE_DEFAULT_MODE
, SINGLE_TRY_MODE
, BATCH_DEFAULT_MODE
, and BATCH_TRY_MODE
.
SINGLE
execution modes
In SINGLE
execution modes, only a single delegation chain and a single execution may be provided. This mode processes delegations sequentially:
- For each delegation in the chain, all caveats'
before
hooks are called. - The single redeemed action is executed.
- For each delegation in the chain, all caveats'
after
hooks are called.
BATCH
execution modes
In BATCH
execution modes, multiple delegation chains and multiple executions may be provided. This mode executes delegations interleaved:
- For each chain in the batch, and each delegation in the chain, all caveats'
before
hooks are called` - Each redeemed actions is executed.
- For each chain in the batch, and each delegation in the chain, all caveats'
after
hooks are called`
BATCH
mode allows for powerful use cases, but the Delegation Framework currently does not include any BATCH
compatible caveat enforcers.
DEFAULT
modes
In DEFAULT
modes, if a revert occurs during redemption, the entire user operation will revert at that point.
TRY
modes
In TRY
modes, if a revert occurs during redemption of the delegation, execution of the user operation will continue.