Account
This directory includes contracts to build accounts for ERC-4337. These include:
-
Account
: An ERC-4337 smart account implementation that includes the core logic to process user operations. -
AccountERC7579
: An extension ofAccount
that implements support for ERC-7579 modules. -
AccountERC7579Hooked
: An extension ofAccountERC7579
with support for a single hook module (type 4). -
ERC7821
: Minimal batch executor implementation contracts. Useful to enable easy batch execution for smart contracts. -
PaymasterCore
: An ERC-4337 paymaster implementation that includes the core logic to validate and pay for user operations. -
PaymasterERC20
: A paymaster that allows users to pay for user operations using ERC-20 tokens. -
PaymasterERC721Owner
: A paymaster that allows users to pay for user operations based on ERC-721 ownership. -
PaymasterSigner
: A paymaster that allows users to pay for user operations using an authorized signature.
Core
Account
import "@openzeppelin/community-contracts/account/Account.sol";
A simple ERC4337 account implementation. This base implementation only includes the minimal logic to process user operations.
Developers must implement the AbstractSigner._rawSignatureValidation
function to define the account’s validation logic.
This core account doesn’t include any mechanism for performing arbitrary external calls. This is an essential feature that all Account should have. We leave it up to the developers to implement the mechanism of their choice. Common choices include ERC-6900, ERC-7579 and ERC-7821 (among others). |
Implementing a mechanism to validate signatures is a security-sensitive operation as it may allow an
attacker to bypass the account’s security measures. Check out SignerECDSA , SignerP256 , or SignerRSA for
digital signature validation implementations.
|
-
onlyEntryPointOrSelf()
-
onlyEntryPoint()
-
entryPoint()
-
getNonce()
-
getNonce(key)
-
validateUserOp(userOp, userOpHash, missingAccountFunds)
-
_validateUserOp(userOp, userOpHash)
-
_signableUserOpHash(, userOpHash)
-
_payPrefund(missingAccountFunds)
-
_checkEntryPoint()
-
_checkEntryPointOrSelf()
-
receive()
-
_rawSignatureValidation(hash, signature)
-
AccountUnauthorized(sender)
entryPoint() → contract IEntryPoint
public
Canonical entry point for the account that forwards and validates user operations.
validateUserOp(struct PackedUserOperation userOp, bytes32 userOpHash, uint256 missingAccountFunds) → uint256
public
Validates a user operation.
-
MUST validate the caller is a trusted EntryPoint
-
MUST validate that the signature is a valid signature of the userOpHash, and SHOULD return SIG_VALIDATION_FAILED (and not revert) on signature mismatch. Any other error MUST revert.
-
MUST pay the entryPoint (caller) at least the “missingAccountFunds” (which might be zero, in case the current account’s deposit is high enough)
Returns an encoded packed validation data that is composed of the following elements:
-
authorizer
(address
): 0 for success, 1 for failure, otherwise the address of an authorizer contract -
validUntil
(uint48
): The UserOp is valid only up to this time. Zero for “infinite”. -
validAfter
(uint48
): The UserOp is valid only after this time.
_validateUserOp(struct PackedUserOperation userOp, bytes32 userOpHash) → uint256
internal
Returns the validationData for a given user operation. By default, this checks the signature of the
signable hash (produced by _signableUserOpHash
) using the abstract signer (AbstractSigner._rawSignatureValidation
).
The userOpHash is assumed to be correct. Calling this function with a userOpHash that does not match the userOp will result in undefined behavior. |
_signableUserOpHash(struct PackedUserOperation, bytes32 userOpHash) → bytes32
internal
Virtual function that returns the signable hash for a user operations. Since v0.8.0 of the entrypoint,
userOpHash
is an EIP-712 hash that can be signed directly.
_payPrefund(uint256 missingAccountFunds)
internal
Sends the missing funds for executing the user operation to the entryPoint
.
The missingAccountFunds
must be defined by the entrypoint when calling validateUserOp
.
_checkEntryPoint()
internal
Ensures the caller is the entryPoint
.
_checkEntryPointOrSelf()
internal
Ensures the caller is the entryPoint
or the account itself.
Extensions
AccountERC7579
import "@openzeppelin/community-contracts/account/extensions/AccountERC7579.sol";
Extension of Account
that implements support for ERC-7579 modules.
To comply with the ERC-1271 support requirement, this contract defers signature validation to installed validator modules by calling {IERC7579Validator-isValidSignatureWithSender}.
This contract does not implement validation logic for user operations since this functionality is often delegated to self-contained validation modules. Developers must install a validator module upon initialization (or any other mechanism to enable execution from the account):
contract MyAccountERC7579 is AccountERC7579, Initializable {
function initializeAccount(address validator, bytes calldata validatorData) public initializer {
_installModule(MODULE_TYPE_VALIDATOR, validator, validatorData);
}
}
|
Removing all validator modules will render the account inoperable, as no user operations can be validated thereafter. |
-
onlyModule(moduleTypeId, additionalContext)
-
fallback()
-
accountId()
-
supportsExecutionMode(encodedMode)
-
supportsModule(moduleTypeId)
-
installModule(moduleTypeId, module, initData)
-
uninstallModule(moduleTypeId, module, deInitData)
-
isModuleInstalled(moduleTypeId, module, additionalContext)
-
execute(mode, executionCalldata)
-
executeFromExecutor(mode, executionCalldata)
-
isValidSignature(hash, signature)
-
_validateUserOp(userOp, userOpHash)
-
_execute(mode, executionCalldata)
-
_installModule(moduleTypeId, module, initData)
-
_uninstallModule(moduleTypeId, module, deInitData)
-
_fallback()
-
_fallbackHandler(selector)
-
_checkModule(moduleTypeId, module, additionalContext)
-
_extractUserOpValidator(userOp)
-
_extractSignatureValidator(signature)
-
_decodeFallbackData(data)
-
_rawSignatureValidation(, )
-
entryPoint()
-
getNonce()
-
getNonce(key)
-
validateUserOp(userOp, userOpHash, missingAccountFunds)
-
_signableUserOpHash(, userOpHash)
-
_payPrefund(missingAccountFunds)
-
_checkEntryPoint()
-
_checkEntryPointOrSelf()
-
receive()
-
ModuleInstalled(moduleTypeId, module)
-
ModuleUninstalled(moduleTypeId, module)
-
ERC7579MissingFallbackHandler(selector)
-
AccountUnauthorized(sender)
onlyModule(uint256 moduleTypeId, bytes additionalContext)
modifier
Modifier that checks if the caller is an installed module of the given type.
fallback(bytes) → bytes
external
See _fallback
.
supportsExecutionMode(bytes32 encodedMode) → bool
public
Supported call types:
* Single (0x00
): A single transaction execution.
* Batch (0x01
): A batch of transactions execution.
* Delegate (0xff
): A delegate call execution.
Supported exec types:
* Default (0x00
): Default execution type (revert on failure).
* Try (0x01
): Try execution type (emits ERC7579TryExecuteFail on failure).
supportsModule(uint256 moduleTypeId) → bool
public
Supported module types:
-
Validator: A module used during the validation phase to determine if a transaction is valid and should be executed on the account.
-
Executor: A module that can execute transactions on behalf of the smart account via a callback.
-
Fallback Handler: A module that can extend the fallback functionality of a smart account.
installModule(uint256 moduleTypeId, address module, bytes initData)
public
Installs a Module of a certain type on the smart account
uninstallModule(uint256 moduleTypeId, address module, bytes deInitData)
public
Uninstalls a Module of a certain type on the smart account
isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) → bool
public
Returns whether a module is installed on the smart account
execute(bytes32 mode, bytes executionCalldata)
public
Executes a transaction on behalf of the account.
executeFromExecutor(bytes32 mode, bytes executionCalldata) → bytes[] returnData
public
Executes a transaction on behalf of the account. This function is intended to be called by Executor Modules
isValidSignature(bytes32 hash, bytes signature) → bytes4
public
Implement ERC-1271 through IERC7579Validator modules. If module based validation fails, fallback to "native" validation by the abstract signer.
_validateUserOp(struct PackedUserOperation userOp, bytes32 userOpHash) → uint256
internal
Validates a user operation with _signableUserOpHash
and returns the validation data
if the module specified by the first 20 bytes of the nonce key is installed. Falls back to
Account._validateUserOp
otherwise.
See _extractUserOpValidator
for the module extraction logic.
_execute(Mode mode, bytes executionCalldata) → bytes[] returnData
internal
ERC-7579 execution logic. See supportsExecutionMode
for supported modes.
Reverts if the call type is not supported.
_installModule(uint256 moduleTypeId, address module, bytes initData)
internal
Installs a module of the given type with the given initialization data.
For the fallback module type, the initData
is expected to be the (packed) concatenation of a 4-byte
selector and the rest of the data to be sent to the handler when calling {IERC7579Module-onInstall}.
Requirements:
-
Module type must be supported. See
supportsModule
. Reverts with {ERC7579UnsupportedModuleType}. -
Module must be of the given type. Reverts with {ERC7579MismatchedModuleTypeId}.
-
Module must not be already installed. Reverts with {ERC7579AlreadyInstalledModule}.
Emits a {ModuleInstalled} event.
_uninstallModule(uint256 moduleTypeId, address module, bytes deInitData)
internal
Uninstalls a module of the given type with the given de-initialization data.
For the fallback module type, the deInitData
is expected to be the (packed) concatenation of a 4-byte
selector and the rest of the data to be sent to the handler when calling {IERC7579Module-onUninstall}.
Requirements:
-
Module must be already installed. Reverts with {ERC7579UninstalledModule} otherwise.
_fallback() → bytes
internal
Fallback function that delegates the call to the installed handler for the given selector.
Reverts with ERC7579MissingFallbackHandler
if the handler is not installed.
Calls the handler with the original msg.sender
appended at the end of the calldata following
the ERC-2771 format.
_fallbackHandler(bytes4 selector) → address
internal
Returns the fallback handler for the given selector. Returns address(0)
if not installed.
_checkModule(uint256 moduleTypeId, address module, bytes additionalContext)
internal
Checks if the module is installed. Reverts if the module is not installed.
_extractUserOpValidator(struct PackedUserOperation userOp) → address
internal
Extracts the nonce validator from the user operation.
To construct a nonce key, set nonce as follows:
<module address (20 bytes)> | <key (4 bytes)> | <nonce (8 bytes)>
The default behavior of this function replicates the behavior of Safe adapter, Etherspot’s Prime Account, and ERC7579 reference implementation. |
This is not standardized in ERC-7579 (or in any follow-up ERC). Some accounts may want to override these internal functions.
For example, Biconomy’s Nexus uses a similar yet incompatible approach (the validator address is also part of the nonce, but not at the same location)
_extractSignatureValidator(bytes signature) → address module, bytes innerSignature
internal
Extracts the signature validator from the signature.
To construct a signature, set the first 20 bytes as the module address and the remaining bytes as the signature data:
<module address (20 bytes)> | <signature data>
The default behavior of this function replicates the behavior of Safe adapter, Biconomy’s Nexus, Etherspot’s Prime Account, and ERC7579 reference implementation. |
This is not standardized in ERC-7579 (or in any follow-up ERC). Some accounts may want to override these internal functions.
_decodeFallbackData(bytes data) → bytes4 selector, bytes remaining
internal
Extract the function selector from initData/deInitData for MODULE_TYPE_FALLBACK
If we had calldata here, we could use calldata slice which are cheaper to manipulate and don’t require
actual copy. However, this would require _installModule to get a calldata bytes object instead of a memory
bytes object. This would prevent calling _installModule from a contract constructor and would force the use
of external initializers. That may change in the future, as most accounts will probably be deployed as
clones/proxy/ERC-7702 delegates and therefore rely on initializers anyway.
|
_rawSignatureValidation(bytes32, bytes) → bool
internal
By default, only use the modules for validation of userOp and signature. Disable raw signatures.
ERC7579MissingFallbackHandler(bytes4 selector)
error
The account’s fallback
was called with a selector that doesn’t have an installed handler.
AccountERC7579Hooked
import "@openzeppelin/community-contracts/account/extensions/AccountERC7579Hooked.sol";
Extension of AccountERC7579
with support for a single hook module (type 4).
If installed, this extension will call the hook module’s {IERC7579Hook-preCheck} before executing any operation
with _execute
(including execute
and executeFromExecutor
by default) and {IERC7579Hook-postCheck} thereafter.
Hook modules break the check-effect-interaction pattern. In particular, the {IERC7579Hook-preCheck} hook can
lead to potentially dangerous reentrancy. Using the withHook() modifier is safe if no effect is performed
before the preHook or after the postHook. That is the case on all functions here, but it may not be the case if
functions that have this modifier are overridden. Developers should be extremely careful when implementing hook
modules or further overriding functions that involve hooks.
|
-
withHook()
-
accountId()
-
hook()
-
supportsModule(moduleTypeId)
-
isModuleInstalled(moduleTypeId, module, data)
-
_installModule(moduleTypeId, module, initData)
-
_uninstallModule(moduleTypeId, module, deInitData)
-
_execute(mode, executionCalldata)
-
_fallback()
-
fallback()
-
supportsExecutionMode(encodedMode)
-
installModule(moduleTypeId, module, initData)
-
uninstallModule(moduleTypeId, module, deInitData)
-
execute(mode, executionCalldata)
-
executeFromExecutor(mode, executionCalldata)
-
isValidSignature(hash, signature)
-
_validateUserOp(userOp, userOpHash)
-
_fallbackHandler(selector)
-
_checkModule(moduleTypeId, module, additionalContext)
-
_extractUserOpValidator(userOp)
-
_extractSignatureValidator(signature)
-
_decodeFallbackData(data)
-
_rawSignatureValidation(, )
-
entryPoint()
-
getNonce()
-
getNonce(key)
-
validateUserOp(userOp, userOpHash, missingAccountFunds)
-
_signableUserOpHash(, userOpHash)
-
_payPrefund(missingAccountFunds)
-
_checkEntryPoint()
-
_checkEntryPointOrSelf()
-
receive()
-
ModuleInstalled(moduleTypeId, module)
-
ModuleUninstalled(moduleTypeId, module)
-
ERC7579HookModuleAlreadyPresent(hook)
-
ERC7579MissingFallbackHandler(selector)
-
AccountUnauthorized(sender)
withHook()
modifier
Calls {IERC7579Hook-preCheck} before executing the modified function and {IERC7579Hook-postCheck} thereafter.
supportsModule(uint256 moduleTypeId) → bool
public
Supports hook modules. See AccountERC7579.supportsModule
isModuleInstalled(uint256 moduleTypeId, address module, bytes data) → bool
public
Returns whether a module is installed on the smart account
_installModule(uint256 moduleTypeId, address module, bytes initData)
internal
Installs a module with support for hook modules. See AccountERC7579._installModule
_uninstallModule(uint256 moduleTypeId, address module, bytes deInitData)
internal
Uninstalls a module with support for hook modules. See AccountERC7579._uninstallModule
_execute(Mode mode, bytes executionCalldata) → bytes[]
internal
Hooked version of AccountERC7579._execute
.
_fallback() → bytes
internal
Hooked version of AccountERC7579._fallback
.
ERC7821
import "@openzeppelin/community-contracts/account/extensions/ERC7821.sol";
Minimal batch executor following ERC-7821.
Only supports supports single batch mode (0x01000000000000000000
). Does not support optional "opData".
-
execute(mode, executionData)
-
supportsExecutionMode(mode)
-
_erc7821AuthorizedExecutor(caller, , )
-
UnsupportedExecutionMode()
execute(bytes32 mode, bytes executionData)
public
Executes the calls in executionData
with no optional opData
support.
Access to this function is controlled by _erc7821AuthorizedExecutor . Changing access permissions, for
example to approve calls by the ERC-4337 entrypoint, should be implemented by overriding it.
|
Reverts and bubbles up error if any call fails.
supportsExecutionMode(bytes32 mode) → bool result
public
This function is provided for frontends to detect support.
Only returns true for:
- bytes32(0x01000000000000000000…)
: does not support optional opData
.
- bytes32(0x01000000000078210001…)
: supports optional opData
.
_erc7821AuthorizedExecutor(address caller, bytes32, bytes) → bool
internal
Access control mechanism for the execute
function.
By default, only the contract itself is allowed to execute.
Override this function to implement custom access control, for example to allow the ERC-4337 entrypoint to execute.
function _erc7821AuthorizedExecutor(
address caller,
bytes32 mode,
bytes calldata executionData
) internal view virtual override returns (bool) {
return caller == address(entryPoint()) || super._erc7821AuthorizedExecutor(caller, mode, executionData);
}
Paymaster
PaymasterCore
import "@openzeppelin/community-contracts/account/paymaster/PaymasterCore.sol";
A simple ERC4337 paymaster implementation. This base implementation only includes the minimal logic to validate and pay for user operations.
Developers must implement the PaymasterCore._validatePaymasterUserOp
function to define the paymaster’s validation
and payment logic. The context
parameter is used to pass data between the validation and execution phases.
The paymaster includes support to call the {IEntryPointStake} interface to manage the paymaster’s deposits and stakes through the internal functions {_deposit}, {_withdraw}, {_addStake}, {_unlockStake} and {_withdrawStake}.
-
Deposits are used to pay for user operations.
-
Stakes are used to guarantee the paymaster’s reputation and obtain more flexibility in accessing storage.
See [Paymaster’s unstaked reputation rules](https://eips.ethereum.org/EIPS/eip-7562#unstaked-paymasters-reputation-rules) for more details on the paymaster’s storage access limitations. |
-
onlyEntryPoint()
-
onlyWithdrawer()
-
entryPoint()
-
validatePaymasterUserOp(userOp, userOpHash, maxCost)
-
postOp(mode, context, actualGasCost, actualUserOpFeePerGas)
-
_validatePaymasterUserOp(userOp, userOpHash, requiredPreFund)
-
_postOp(, , , )
-
deposit()
-
withdraw(to, value)
-
addStake(unstakeDelaySec)
-
unlockStake()
-
withdrawStake(to)
-
_checkEntryPoint()
-
_authorizeWithdraw()
-
PaymasterUnauthorized(sender)
entryPoint() → contract IEntryPoint
public
Canonical entry point for the account that forwards and validates user operations.
validatePaymasterUserOp(struct PackedUserOperation userOp, bytes32 userOpHash, uint256 maxCost) → bytes context, uint256 validationData
public
Validates whether the paymaster is willing to pay for the user operation. See {IAccount-validateUserOp} for additional information on the return value.
Bundlers will reject this method if it modifies the state, unless it’s whitelisted. |
postOp(enum IPaymaster.PostOpMode mode, bytes context, uint256 actualGasCost, uint256 actualUserOpFeePerGas)
public
Verifies the sender is the entrypoint.
_validatePaymasterUserOp(struct PackedUserOperation userOp, bytes32 userOpHash, uint256 requiredPreFund) → bytes context, uint256 validationData
internal
Internal validation of whether the paymaster is willing to pay for the user operation. Returns the context to be passed to postOp and the validation data.
The requiredPreFund
is the amount the paymaster has to pay (in native tokens). It’s calculated
as requiredGas * userOp.maxFeePerGas
, where required
gas can be calculated from the user operation
as verificationGasLimit + callGasLimit + paymasterVerificationGasLimit + paymasterPostOpGasLimit + preVerificationGas
_postOp(enum IPaymaster.PostOpMode, bytes, uint256, uint256)
internal
Handles post user operation execution logic. The caller must be the entry point.
It receives the context
returned by _validatePaymasterUserOp
. Function is not called if no context
is returned by validatePaymasterUserOp
.
The actualUserOpFeePerGas is not tx.gasprice . A user operation can be bundled with other transactions
making the gas price of the user operation to differ.
|
_checkEntryPoint()
internal
Ensures the caller is the entryPoint
.
_authorizeWithdraw()
internal
Checks whether msg.sender
withdraw funds stake or deposit from the entrypoint on paymaster’s behalf.
Use of an access control modifier such as {Ownable-onlyOwner} is recommended.
function _authorizeUpgrade() internal onlyOwner {}
PaymasterERC20
import "@openzeppelin/community-contracts/account/paymaster/PaymasterERC20.sol";
Extension of PaymasterCore
that enables users to pay gas with ERC-20 tokens.
To enable this feature, developers must implement the {fetchDetails} function:
function _fetchDetails(
PackedUserOperation calldata userOp,
bytes32 userOpHash
) internal view override returns (uint256 validationData, IERC20 token, uint256 tokenPrice, address guarantor) {
// Implement logic to fetch the token, token price, and guarantor address from the userOp
}
-
_validatePaymasterUserOp(userOp, userOpHash, maxCost)
-
_postOp(, context, actualGasCost, actualUserOpFeePerGas)
-
_fetchDetails(userOp, userOpHash)
-
_tokenPriceDenominator()
-
withdrawTokens(token, recipient, amount)
-
entryPoint()
-
validatePaymasterUserOp(userOp, userOpHash, maxCost)
-
postOp(mode, context, actualGasCost, actualUserOpFeePerGas)
-
deposit()
-
withdraw(to, value)
-
addStake(unstakeDelaySec)
-
unlockStake()
-
withdrawStake(to)
-
_checkEntryPoint()
-
_authorizeWithdraw()
-
UserOperationSponsored(userOpHash, user, guarantor, tokenAmount, tokenPrice, paidByGuarantor)
-
PaymasterUnauthorized(sender)
_validatePaymasterUserOp(struct PackedUserOperation userOp, bytes32 userOpHash, uint256 maxCost) → bytes context, uint256 validationData
internal
Internal validation of whether the paymaster is willing to pay for the user operation. Returns the context to be passed to postOp and the validation data.
The requiredPreFund
is the amount the paymaster has to pay (in native tokens). It’s calculated
as requiredGas * userOp.maxFeePerGas
, where required
gas can be calculated from the user operation
as verificationGasLimit + callGasLimit + paymasterVerificationGasLimit + paymasterPostOpGasLimit + preVerificationGas
_postOp(enum IPaymaster.PostOpMode, bytes context, uint256 actualGasCost, uint256 actualUserOpFeePerGas)
internal
Handles post user operation execution logic. The caller must be the entry point.
It receives the context
returned by _validatePaymasterUserOp
. Function is not called if no context
is returned by validatePaymasterUserOp
.
The actualUserOpFeePerGas is not tx.gasprice . A user operation can be bundled with other transactions
making the gas price of the user operation to differ.
|
_fetchDetails(struct PackedUserOperation userOp, bytes32 userOpHash) → uint256 validationData, contract IERC20 token, uint256 tokenPrice, address guarantor
internal
Retrieves payment details for a user operation
The values returned by this internal function are:
* validationData
: ERC-4337 validation data, indicating success/failure and optional time validity (validAfter
, validUntil
).
* token
: Address of the ERC-20 token used for payment to the paymaster.
* tokenPrice
: Price of the token in native currency, scaled by _tokenPriceDenominator()
.
* guarantor
: Address of an entity advancing funds if the user lacks them; receives tokens during execution or pays if the user can’t.
Calculating the token price
Given gas fees are paid in native currency, developers can use the ERC20 price unit / native price unit
ratio to
calculate the price of an ERC20 token price in native currency. However, the token may have a different number of decimals
than the native currency. For a a generalized formula considering prices in USD and decimals, consider using:
(<ERC-20 token price in $> / 10**<ERC-20 decimals>) / (<Native token price in $> / 1e18) * _tokenPriceDenominator()
For example, suppose token is USDC ($1 with 6 decimals) and native currency is ETH (assuming $2524.86 with 18 decimals),
then each unit (1e-6) of USDC is worth (1 / 1e6) / ((252486 / 1e2) / 1e18) = 396061563.8094785
wei. The _tokenPriceDenominator()
ensures precision by avoiding fractional value loss. (i.e. the 0.8094785 part).
Guarantor
To support a guarantor, developers can use the paymasterData
field to store the guarantor’s address. Developers can disable
support for a guarantor by returning address(0)
. If supported, ensure explicit consent (e.g., signature verification) to prevent
unauthorized use.
_tokenPriceDenominator() → uint256
internal
Denominator used for interpreting the tokenPrice
returned by _fetchDetails
as "fixed point".
PaymasterERC721Owner
import "@openzeppelin/community-contracts/account/paymaster/PaymasterERC721Owner.sol";
Extension of PaymasterCore
that supports account based on ownership of an ERC-721 token.
This paymaster will sponsor user operations if the user has at least 1 token of the token specified
during construction (or via _setToken
).
-
constructor(token_)
-
token()
-
_setToken(token_)
-
_validatePaymasterUserOp(userOp, , )
-
entryPoint()
-
validatePaymasterUserOp(userOp, userOpHash, maxCost)
-
postOp(mode, context, actualGasCost, actualUserOpFeePerGas)
-
_postOp(, , , )
-
deposit()
-
withdraw(to, value)
-
addStake(unstakeDelaySec)
-
unlockStake()
-
withdrawStake(to)
-
_checkEntryPoint()
-
_authorizeWithdraw()
-
PaymasterERC721OwnerTokenSet(token)
-
PaymasterUnauthorized(sender)
_setToken(contract IERC721 token_)
internal
Sets the ERC-721 token used to validate the user operation.
_validatePaymasterUserOp(struct PackedUserOperation userOp, bytes32, uint256) → bytes context, uint256 validationData
internal
Internal validation of whether the paymaster is willing to pay for the user operation. Returns the context to be passed to postOp and the validation data.
The default context is bytes(0) . Developers that add a context when overriding this function MUST
also override _postOp to process the context passed along.
|
PaymasterSigner
import "@openzeppelin/community-contracts/account/paymaster/PaymasterSigner.sol";
Extension of PaymasterCore
that adds signature validation. See SignerECDSA
, SignerP256
or SignerRSA
.
Example of usage:
contract MyPaymasterECDSASigner is PaymasterSigner, SignerECDSA {
constructor() EIP712("MyPaymasterECDSASigner", "1") {
// Will revert if the signer is already initialized
_setSigner(signerAddr);
}
}
-
_signableUserOpHash(userOp, validAfter, validUntil)
-
_validatePaymasterUserOp(userOp, , )
-
_decodePaymasterUserOp(userOp)
-
entryPoint()
-
validatePaymasterUserOp(userOp, userOpHash, maxCost)
-
postOp(mode, context, actualGasCost, actualUserOpFeePerGas)
-
_postOp(, , , )
-
deposit()
-
withdraw(to, value)
-
addStake(unstakeDelaySec)
-
unlockStake()
-
withdrawStake(to)
-
_checkEntryPoint()
-
_authorizeWithdraw()
-
_domainSeparatorV4()
-
_hashTypedDataV4(structHash)
-
eip712Domain()
-
_EIP712Name()
-
_EIP712Version()
-
_rawSignatureValidation(hash, signature)
-
EIP712DomainChanged()
-
PaymasterUnauthorized(sender)
_signableUserOpHash(struct PackedUserOperation userOp, uint48 validAfter, uint48 validUntil) → bytes32
internal
Virtual function that returns the signable hash for a user operations. Given the userOpHash
contains the paymasterAndData
itself, it’s not possible to sign that value directly. Instead,
this function must be used to provide a custom mechanism to authorize an user operation.
_validatePaymasterUserOp(struct PackedUserOperation userOp, bytes32, uint256) → bytes context, uint256 validationData
internal
Internal validation of whether the paymaster is willing to pay for the user operation. Returns the context to be passed to postOp and the validation data.
The context returned is bytes(0) . Developers overriding this function MUST
override _postOp to process the context passed along.
|