Verifying Account Abstracted Instant Actions (ERC-4337)
When using Account Abstraction with ERC-4337, you may need to verify a user’s signature on-chain (EIP-1271). This process allows smart contract wallets to sign off-chain data (via the user’s wallet logic) and then be validated on-chain by calling a contract’s isValidSignature() function.
The example below uses:
SIWE (Sign-In with Ethereum) to structure the message (nonce, domain, expiration, etc.).
ERC-4337 style message hashing to produce the correct pre-hashed data.
EIP-1271 on-chain validation via a contract call to isValidSignature()
.
Example Code Snippet
Below is a breakdown of how this code example verifies Instant Trades in an AA context.
Constructing the SIWE Message
SIWE (Sign-In with Ethereum) is used to define an off-chain message containing:
domain
: The site or application domain.address
: The user’s (or smart wallets) address—this is an EIP-1271 contract in this example.nonce
&issued_at
: Used to prevent replay attacks.expiration_time
: Defines how long this signed authorization is valid.statement
: hereaccount_address
is the ERC-4337 compliant walletchain_id
: The chain on which the address is deployed.
Encoding the Message for EIP-1271 Verification
message.prepare_message()
gives you the SIWE message as a string.The code applies EIP-191 style prefix:
\x19Ethereum Signed Message:\n<length>
. This is the same prefix typically used in MetaMask or other wallets for “personal_sign.”The prefixed message is then hashed with
keccak-256
.
The resulting hash_message
becomes the “message hash” that the smart contract will verify.
On-Chain Signature Verification
owner
is not an EOA– it’s an EIP-1271-compatible contract (smart wallet).isValidSignature(bytes32 _hash, bytes _signature)
is part of EIP-1271. The contract checks internally if the provided signature is valid for _hash.A valid signature must return
0x1626ba7e
(the EIP-1271 magic value).If the returned value is not
0x1626ba7e
, the signature is invalid.
Account Abstracted Flow– Verifying Instant Actions:
The frontend generates a SIWE message for "instant actions"
E.g., “I authorize solver XYZ to execute opens/closes until expiration_time.”
The user (or user’s wallet) signs it off-chain, producing a signature.
The solver/backend calls
_encode_erc4337(siwe_message)
to construct the same SIWE string and get thehash_message
.The solver then invokes
isValidSignature(hash_message, signature)
on the user’s smart wallet contract:
Success (
0x1626ba7e
) means the user’s contract acknowledges the signature, so the solver can proceed with “instant actions.”Failure (any other value or revert) means the signature is invalid or expired.
This ensures no new signature is required for every single open/close, provided the user already authorized a “session.”
Last updated