SingleSignerValidation
Inherits: IERC6900ValidationModule
Title: SingleSignerValidation
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from ERC-6900 reference implementation (https://github.com/erc6900/reference-implementation)
A reference ERC-6900 validation module: one signer per (account, entityId). Validates user
operations (ECDSA over the EIP-191 user-op-hash), runtime calls (the caller must be the signer), and
ERC-1271 signatures (against the digest the account hands it).
A standalone module — invoked by the account via CALL, so it runs in its OWN storage (msg.sender is the
account; signerOf[account][entityId] is per-account). For ERC-1271, the Lattice account has ALREADY
bound the digest to its domain via ERC-7739 before calling validateSignature, so this module does a
plain signer check (no extra rehashing). Reference quality: minimal, no upgradeability, no enumeration.
Constants
_1271_MAGIC
ERC-1271 return values.
bytes4 internal constant _1271_MAGIC = 0x1626ba7e;_1271_INVALID
bytes4 internal constant _1271_INVALID = 0xffffffff;_SIG_OK
ERC-4337 authorizer field: success = 0, signature failure = 1.
uint256 internal constant _SIG_OK = 0;_SIG_FAIL
uint256 internal constant _SIG_FAIL = 1;State Variables
signerOf
The signer authorized for (account, entityId).
mapping(address account => mapping(uint32 entityId => address signer)) public signerOf;Functions
onInstall
data = abi.encode(uint32 entityId, address signer).
function onInstall(bytes calldata data) external;Parameters
| Name | Type | Description |
|---|---|---|
| data | bytes |
onUninstall
data = abi.encode(uint32 entityId).
function onUninstall(bytes calldata data) external;Parameters
| Name | Type | Description |
|---|---|---|
| data | bytes |
validateUserOp
function validateUserOp(uint32 entityId, PackedUserOperation calldata userOp, bytes32 userOpHash)
external
view
returns (uint256);Parameters
| Name | Type | Description |
|---|---|---|
| entityId | uint32 | |
| userOp | PackedUserOperation | |
| userOpHash | bytes32 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | uint256 | Packed validation data: validAfter (6 bytes) ‖ validUntil (6 bytes) ‖ authorizer (20 bytes). |
validateRuntime
MUST revert to reject the call.
function validateRuntime(address account, uint32 entityId, address sender, uint256, bytes calldata, bytes calldata)
external
view;Parameters
| Name | Type | Description |
|---|---|---|
| account | address | |
| entityId | uint32 | |
| sender | address | |
| _ | uint256 | |
| _ | bytes | |
| _ | bytes |
validateSignature
function validateSignature(address account, uint32 entityId, address, bytes32 hash, bytes calldata signature)
external
view
returns (bytes4);Parameters
| Name | Type | Description |
|---|---|---|
| account | address | |
| entityId | uint32 | |
| _ | address | |
| hash | bytes32 | |
| signature | bytes |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bytes4 | ERC-1271 magic value 0x1626ba7e if valid, or 0xffffffff if invalid. |
moduleId
Unique id in the format "vendor.module.semver"; vendor/module names MUST NOT contain a period.
function moduleId() external pure returns (string memory);Returns
| Name | Type | Description |
|---|---|---|
| <none> | string |
supportsInterface
function supportsInterface(bytes4 interfaceId) external pure returns (bool);Parameters
| Name | Type | Description |
|---|---|---|
| interfaceId | bytes4 |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bool |
Events
SignerSet
event SignerSet(address indexed account, uint32 indexed entityId, address signer);Parameters
| Name | Type | Description |
|---|---|---|
| account | address | |
| entityId | uint32 | |
| signer | address |
Errors
NotAuthorized
The runtime caller is not the configured signer.
error NotAuthorized(address account, uint32 entityId, address sender);Parameters
| Name | Type | Description |
|---|---|---|
| account | address | |
| entityId | uint32 | |
| sender | address |