Here is a basic example, where I'm calling a method on myContract and using a Paymaster:
await myContract.myMethod(
myArgs,
{
customData: {
paymasterParams: paymasterParams,
gasPerPubdata: utils.DEFAULT_GAS_PER_PUBDATA_LIMIT,
}
}
);
To ensure that the Paymaster can only be used for myContract and only to call myMethod I need get the calling contract and method from within the paymaster smart contract code. Getting the contract is straight forward it is available from the transaction.to
object.
It appears that the transaction.data
holds the encoded method call. So in order to access the data I have tried:
if (paymasterInputSelector == IPaymasterFlow.general.selector) {
address userAddress = address(uint160(_transaction.from));
address callerAddress = address(uint160(_transaction.to));
require(userAddress == allowedUser, "Must be an Approved User");
require(callerAddress == tokenAddr, "Invalid token address");
bytes4 funcSlct = bytes4(keccak256(bytes(_transaction.data))); //Trying to extract function selector from data
if (funcSlct == bytes4(keccak256(bytes("0x1234abcd")))) {
// compare function selector from data to the expected value.
// do something
// But this always fails!
} else {
//don't do anything, revert!
// it always reverts here.
}
// rest of the paymaster code
}
The problem is that the condition is never met and it always reverts.
I'm not sure if this an issue with the transaction object in the paymaster, or whether there is a problem with how I'm decoding and comparing the function signature/selector. Note that when it reverts it prints the transaction object to screen and data
appears with the matching function selector.