# IPaymaster
The Paymaster Interface
Contracts implementing this interface exist to make decision about paying the transaction fee to the relay.
There are two callbacks here that are executed by the RelayHub: preRelayedCall
and postRelayedCall
.
It is recommended that your implementation inherits from the abstract BasePaymaster contract.
# Functions
# getGasAndDataLimits()
→ struct IPaymaster.GasAndDataLimits limits
(external)
Return the Gas Limits for Paymaster's functions and maximum msg.data length values for this Paymaster. This function allows different paymasters to have different properties without changes to the RelayHub.
# Return values
An instance of the GasAndDataLimits
struct
# acceptanceBudget
If the transactions consumes more than acceptanceBudget
this Paymaster will be charged for gas no matter what.
Transaction that gets rejected after consuming more than acceptanceBudget
gas is on this Paymaster's expense.
Should be set to an amount gas this Paymaster expects to spend deciding whether to accept or reject a request.
This includes gas consumed by calculations in the preRelayedCall
, Forwarder
and the recipient contract.
⚠️ Warning ⚠️ As long this value is above preRelayedCallGasLimit
(see defaults in BasePaymaster
), the Paymaster is guaranteed it will never pay for rejected transactions.
If this value is below preRelayedCallGasLimit
, it might might make Paymaster open to a "griefing" attack.
The relayers should prefer lower acceptanceBudget
, as it improves their chances of being compensated.
From a Relay's point of view, this is the highest gas value a bad Paymaster may cost the relay,
since the paymaster will pay anything above that value regardless of whether the transaction succeeds or reverts.
Specifying value too high might make the call rejected by relayers (see maxAcceptanceBudget
in server config).
# preRelayedCallGasLimit
The max gas usage of preRelayedCall. Any revert of the preRelayedCall
is a request rejection by the paymaster.
As long as acceptanceBudget
is above preRelayedCallGasLimit
, any such revert is not payed by the paymaster.
# postRelayedCallGasLimit
The max gas usage of postRelayedCall. The Paymaster is not charged for the maximum, only for actually used gas. Note that an OOG will revert the inner transaction, but the paymaster will be charged for it anyway.
# getTrustedForwarder()
→ address trustedForwarder
(external)
⚠️ Warning ⚠️ using incorrect Forwarder may cause the Paymaster to agreeing to pay for invalid transactions.
# Return values
The address of the Forwarder
that is trusted by this Paymaster to execute the requests.
# getRelayHub()
→ address relayHub
(external)
# Return values
The address of the RelayHub
that is trusted by this Paymaster to execute the requests.
# preRelayedCall(struct GsnTypes.RelayRequest relayRequest, bytes signature, bytes approvalData, uint256 maxPossibleGas)
→ bytes context, bool rejectOnRecipientRevert
(external)
Called by the Relay in view mode and later by the RelayHub
on-chain to validate that
the Paymaster agrees to pay for this call.
The request is considered to be rejected by the Paymaster in one of the following conditions:
preRelayedCall()
method reverts- the
Forwarder
reverts because of nonce or signature error - the
Paymaster
returnedrejectOnRecipientRevert: true
and the recipient contract reverted (and all that did not consume more thanacceptanceBudget
gas).
In any of the above cases, all Paymaster calls and the recipient call are reverted.
In any other case the Paymaster will pay for the gas cost of the transaction.
Note that even if postRelayedCall
is reverted the Paymaster will be charged.
relayRequest: - the full relay request structure
signature: - user's EIP712-compatible signature of the relayRequest
.
Note that in most cases the paymaster shouldn't try use it at all. It is always checked
by the forwarder immediately after preRelayedCall returns.
approvalData: - extra dapp-specific data (e.g. signature from trusted party)
maxPossibleGas: - based on values returned from getGasAndDataLimits
the RelayHub will calculate the maximum possible amount of gas the user may be charged for.
In order to convert this value to wei, the Paymaster has to call "relayHub.calculateCharge()"
# Return values
byte array to be passed to postRelayedCall. Can contain any data needed by this Paymaster in any form or be empty if no extra data is needed.
flag that allows a Paymaster to "delegate" the rejection to the recipient code.
It also means the Paymaster trust the recipient to reject fast: both preRelayedCall,
forwarder check and recipient checks must fit into the GasLimits.acceptanceBudget,
otherwise the TX is paid by the Paymaster.
true
if the Paymaster wants to reject the TX if the recipient reverts.
false
if the Paymaster wants rejects by the recipient to be completed on chain and paid by the Paymaster.
# postRelayedCall(bytes context, bool success, uint256 gasUseWithoutPost, struct GsnTypes.RelayData relayData)
(external)
This method is called after the actual relayed function call. It may be used to record the transaction (e.g. charge the caller by some contract logic) for this call.
Revert in this functions causes a revert of the client's relayed call (and preRelayedCall(), but the Paymaster is still committed to pay the relay for the entire transaction.
context: The call context, as returned by the preRelayedCall
success: true
if the relayed call succeeded, false if it reverted
gasUseWithoutPost: The actual amount of gas used by the entire transaction, EXCEPT the gas used by the postRelayedCall itself.
relayData: The relay params of the request. can be used by relayHub.calculateCharge()
# versionPaymaster()
→ string
(external)
# Return values
The SemVer string of this Paymaster's version.
# Structs
# GasAndDataLimits
uint256 acceptanceBudget
uint256 preRelayedCallGasLimit
uint256 postRelayedCallGasLimit
uint256 calldataSizeLimit