I’m trying to use the MetaMask Delegation Toolkit in my dApp. I need to sign a delegation so that my relayer can sponsor user transactions in the stateless7702 smart wallet. But the toolkit throws the error:
Details: External signature requests cannot sign delegations for internal accounts.
I don’t see why the toolkit should have a problem signing the delegation payload, in the MetaMask toolkit source code i can see its just a wrapper for a signed typed data rpc call.
Here is the relevant code from my dApp, the failure is when I call const signature = await delegatorSmartAccount.signDelegation({delegation});
values: IAddDelegationFormValues,
formikHelpers: FormikHelpers<IAddDelegationFormValues>,
) => {
try {
// TODO: Implement delegation creation logic
console.log("Creating delegation with values:", values);
console.log("Escrow Wallet ID:", escrowWalletId);
// Use the delegation library to create the delegation.
if (!walletClient || !walletClient.account) {
openSnackbar({
open: true,
message: "Wallet not connected",
alert: { severity: "info" },
});
handleClose();
return;
}
const delegatorSmartAccount = await toMetaMaskSmartAccount({
client: walletClient,
implementation: Implementation.Stateless7702,
address: walletClient.account.address, // "0x63c0c19a282a1B52b07dD5a65b58948A07DAE32B",
signatory: { walletClient: walletClient }
});
console.log("CHARLIE delegatorSmartAccount", delegatorSmartAccount);
const environment = delegatorSmartAccount.environment;
const caveatBuilder = createCaveatBuilder(environment, {allowEmptyCaveats: true});
if (values.contractAddresses.length > 0) {
caveatBuilder.addCaveat("allowedTargets", values.contractAddresses as `0x${string}`[]);
}
if (values.methods.length > 0) {
caveatBuilder.addCaveat("allowedMethods", values.methods);
}
if (values.startDate && values.endDate) {
caveatBuilder.addCaveat("timestamp", Number(values.startDate), Number(values.endDate));
}
const caveats = caveatBuilder.build();
console.log("CHARLIE caveats", caveats);
const delegation = createDelegation({
from: walletClient.account.address,
to: escrowWalletAddress as `0x${string}`,
caveats: caveats
});
console.log("CHARLIE delegation", delegation);
const signature = await delegatorSmartAccount.signDelegation({delegation});
console.log("CHARLIE signature", signature);
// For now, just show a success message and close the modal
openSnackbar({
open: true,
message: "Delegation creation will be implemented soon",
alert: { severity: "info" },
});
handleClose();
} catch (error) {
console.error("Delegation creation failed:", error);
openSnackbar({
open: true,
message: "Failed to create delegation",
alert: { severity: "error" },
});
} finally {
formikHelpers.setSubmitting(false);
}
``