Promblem with the delegation with the delegation-toolkit

I’m building my dapp with scaffoldETH 2 and anvil. I want to show the features of eip-7702 and i’ve chosen to use the MetaMask delegation-toolkit. I have 3 smart account (Alice, Bob and Charles) and Alice must send ETH in batch to Bob and Charles. Alice became a smart account and has the smart contract code within that allows to send ETH in batch. So Alice signs a delegation to permit one sponsor (a normal EOA) to pay the gas on her behalf.

I think the problem is when the sponsor redeems the delegation, i get an error that says:

TransactionExecutionError: Execution reverted for an unknown reason.

  83 |   try {
> 84 |     const txHash = await sponsorWalletClient.sendTransaction({
     |                    ^
  85 |       to: getDeleGatorEnvironment(chainId).DelegationManager,
  86 |       data: redeemDelegationCalldata,
  87 |     });

here’s my code for the delegation:

export async function createDelegationForAccount(smartAccount: any,) {
  const delegatorEnvironment = smartAccount.environment;
  const caveatBuilder = createCaveatBuilder(delegatorEnvironment);

  const caveats = createCaveatBuilder(environment)
    .addCaveat("allowedMethods", ["execute((address,uint256,bytes)[])","multiSendETH(address[],uint256[])"])
    .build();

  const delegation = createDelegation({
    to: sponsorAccount.address as `0x${string}`,
    from: smartAccount.address as `0x${string}`,
    caveats
  });

  const signature = await smartAccount.signDelegation({ delegation });

  return { ...delegation, signature };
}

This is the redeem function:


export async function redeemDeleg(
  signedDelegation: Delegation,
  recipients: string[],
  amounts: string[],
  smartAccount: any,
) {


  const { delegator, delegate, signature } = signedDelegation;
  console.log("Delegator:", delegator);
  console.log("Delegate:", delegate);
  console.log("Caveats:", signedDelegation.caveats);
  console.log("Delegation:", signedDelegation);

  const mode: ExecutionMode = SINGLE_DEFAULT_MODE;
  const chainId = 31337;
  const contract = deployedContracts[chainId].MyContract;

  const parsedAmounts = amounts.map(a => BigInt(Math.floor(parseFloat(a) * 1e18)));
  const totalAmount = parsedAmounts.reduce((acc, x) => acc + x, 0n);
  console.log("total amount:", totalAmount);

  const multiSendData = encodeFunctionData({
    abi: contract.abi,
    functionName: "multiSendETH",
    args: [recipients, parsedAmounts],
  });


  const execution: ExecutionStruct = {
    target: smartAccount.address,
    value: totalAmount,
    callData: multiSendData
  };


  const delegations: Delegation[] = [signedDelegation];
  const executions: ExecutionStruct[][] = [[execution]];


  const redeemDelegationCalldata = DelegationManager.encode.redeemDelegations({
    delegations: [delegations],
    modes: [mode],
    executions,
  });

  inspectRedeemCalldata(redeemDelegationCalldata);

  try {
    const txHash = await sponsorWalletClient.sendTransaction({
      to: getDeleGatorEnvironment(chainId).DelegationManager,
      data: redeemDelegationCalldata,
    });
    console.log("Transaction hash:", txHash);
  } catch (err: any) {
    console.error("Full error:", err);
    if (err.cause?.data) {
      console.error("Revert data:", err.cause.data);
    }
  }
}

Here’s also the contract code, i tested the contract before doing the delegation and it works fine.

contract MyContract {
    struct Call {
        address to;
        uint256 value;
        bytes data;
    }

    /// @notice Executes a batch of calls on behalf of the account
    /// @dev Compatible with Delegation Toolkit caveat: allowedMethods = ["execute((address,uint256,bytes)[])"]
    function execute(Call[] calldata calls) external payable {
        for (uint256 i = 0; i < calls.length; i++) {
            (bool success, ) = calls[i].to.call{value: calls[i].value}(calls[i].data);
            require(success, "Call failed");
        }
    }

    /// @notice Sends ETH to multiple recipients
    function multiSendETH(address[] calldata recipients, uint256[] calldata amounts) external payable {
        require(recipients.length == amounts.length, "Length mismatch");

        uint256 total = 0;
        for (uint256 i = 0; i < amounts.length; i++) {
            total += amounts[i];
        }

        require(msg.value >= total, "Insufficient ETH");

        for (uint256 i = 0; i < recipients.length; i++) {
            (bool sent, ) = recipients[i].call{value: amounts[i]}("");
            require(sent, "ETH send failed");
        }
    }

    /// @notice Returns the contract address
    function getAddress() external view returns (address) {
        return address(this);
    }

    /// @notice Accepts ETH
    receive() external payable {}
}

I can’t figure out what is the problem, i tested so many solution but none resolve the error.
I need an help with the problem because it’s blocking me from go ahead for almost a week now.

Thanks to everyone.

Sounds like a tricky issue. Double-checking network settings or trying with the latest version of the toolkit might help, but it’d be great if support could clarify this further.

Let me study it please, I might missing the error output could you please reshare it @fedeb02

The only error I can see is :
TransactionExecutionError: Execution reverted for an unknown reason.

  83 |   try {
> 84 |     const txHash = await sponsorWalletClient.sendTransaction({
     |                    ^
  85 |       to: getDeleGatorEnvironment(chainId).DelegationManager,
  86 |       data: redeemDelegationCalldata,
  87 |     });

there is also the specific of the error, don’t know if it can helps

Request Arguments:
  from:  0x70997970C51812dc3A010C7d01b50e0d17dc79C8
  to:    0x2e2ed0cfd3ad2f1d34481277b3204d807ca2f8c2
  data:  0xcef6d2090000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000036000000000000000000000000000000000000000000000000000000000000003a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000070997970c51812dc3a010c7d01b50e0d17dc79c8000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000e801d84fa97b50751dbf25036d067dcf18858bf000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000083f707e6bfb48820400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000041fbdc9db727307a8aaf3c89925c28fb37f78a081250e377143a8085101b3d74560f640d340f5457666358660141801ccd202c8facc40714c0a765163f14a673df1b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Details: execution reverted
Version: viem@2.34.0

Could you please open a case: https://support.metamask.io/ start a conversation and then ask for tech support