EIPs
EIP-6492 — Signature validation for predeploy contracts
EIP-1271 validates a signature against a deployed contract. EIP-6492 extends that to contracts that aren’t deployed yet — the smart account address is known (via CREATE2), but the code isn’t on-chain.
The signature is wrapped: (factory, factory_calldata, inner_signature) || MAGIC_BYTES. A universal validator contract:
- Detects the wrapped form via the trailing magic bytes.
- If the address has no code, deploys it using the factory + calldata.
- Calls
isValidSignatureon the now-deployed contract.
import {
wrap_signature,
unwrap_signature,
is_wrapped_signature,
verify_hash,
} from "@ethernauta/eip/6492";
const wrapped = wrap_signature({
factory,
factory_calldata,
inner_signature,
});
const ok = await verify_hash({
address: counterfactual_account,
hash: digest,
signature: wrapped,
})(reader({ chain_id: eip155_1.chain_id })); Surface
| Export | Type | Purpose |
|---|---|---|
MAGIC_BYTES | Bytes32 | 0x6492…6492 — sentinel suffix. |
VALIDATOR_BYTECODE | Bytes | Compiled universal validator. |
wrap_signature | (args) => Bytes | Produce a wrapped signature. |
unwrap_signature | (bytes) => UnwrappedSignature | Reverse wrap_signature. |
is_wrapped_signature | (bytes) => boolean | Detect via magic bytes. |
UnwrappedSignature | type | { factory, factory_calldata, inner_signature }. |
verify_hash | Readable<boolean> | Run the universal validator. |
How the universal validator works
The trick is that verify_hash deploys an ephemeral contract (via eth_call with the validator bytecode as to: null) that handles both the deployment and the isValidSignature call in a single state-less execution. No transaction is sent; nothing is persisted. Pure read.
This is what makes counterfactual signatures verifiable from a Readable<T> — no wallet, no gas.
Cross-EIP verification
In practice you rarely call this directly. The universal verifiers in @ethernauta/crypto walk the full hierarchy:
import { verify_message_universal } from "@ethernauta/crypto";
// works for: EOA, deployed smart account, counterfactual smart account
const ok = await verify_message_universal({
address,
message,
signature,
})(reader); See also
- EIP-1014 — CREATE2 address derivation (the “counterfactual” half).
- EIP-1271 — deployed contract signatures (the inner case).
- @ethernauta/crypto — universal verifiers.