Motivation
ERC7739._buildDomainBytes (introduced in #6618) reads the account's EIP-712
domain via IERC5267.eip712Domain() and abi-encodes the five domain fields
into the bytes payload that ERC7739Utils.typedDataSignStructHash consumes:
return abi.encode(
keccak256(bytes(name)),
keccak256(bytes(version)),
chainId,
verifyingContract,
salt
);
Consider whether this small primitive would be useful as a shared helper in
MessageHashUtils, next to toDomainSeparator — same inputs, different
output (raw bytes instead of the wrapped domain separator hash). Because the
operation is generic (any consumer that needs the pre-hash domain bytes could
use it), MessageHashUtils is the natural home if it lands.
Sketch
The helper should mirror toDomainSeparator and accept the ERC-5267 fields
byte, so callers get pre-hash domain bytes for any subset of fields:
function domainBytes(
bytes1 fields,
bytes32 nameHash,
bytes32 versionHash,
uint256 chainId,
address verifyingContract,
bytes32 salt
) internal pure returns (bytes memory);
function domainBytes(
bytes1 fields,
string memory name,
string memory version,
uint256 chainId,
address verifyingContract,
bytes32 salt
) internal pure returns (bytes memory);
Arguments corresponding to fields not set in fields are omitted from the
returned bytes, matching the existing toDomainSeparator(bytes1 fields, ...)
semantics.
ERC-7739 usage
ERC7739._buildDomainBytes would collapse to eip712Domain() +
MessageHashUtils.domainBytes(...). The TypedDataSign typehash is normative
and hardcodes all five domain fields, so the ERC-7739 call site always passes
the full-fields byte — but the helper itself stays fields-aware so other
consumers (with a different ERC-5267 subset) can reuse it.
Gating on a second consumer
A single call-site in ERC7739 is not enough on its own — the helper would
just move code without shared reuse. Landing this should wait until a second
consumer emerges that needs the pre-hash domain bytes (a follow-up
ERC7739-adjacent utility, a new signer flavor, etc.), at which point the
factoring pays for itself.
References
Motivation
ERC7739._buildDomainBytes(introduced in #6618) reads the account's EIP-712domain via
IERC5267.eip712Domain()and abi-encodes the five domain fieldsinto the
bytespayload thatERC7739Utils.typedDataSignStructHashconsumes:Consider whether this small primitive would be useful as a shared helper in
MessageHashUtils, next totoDomainSeparator— same inputs, differentoutput (raw bytes instead of the wrapped domain separator hash). Because the
operation is generic (any consumer that needs the pre-hash domain bytes could
use it),
MessageHashUtilsis the natural home if it lands.Sketch
The helper should mirror
toDomainSeparatorand accept the ERC-5267fieldsbyte, so callers get pre-hash domain bytes for any subset of fields:
Arguments corresponding to fields not set in
fieldsare omitted from thereturned bytes, matching the existing
toDomainSeparator(bytes1 fields, ...)semantics.
ERC-7739 usage
ERC7739._buildDomainByteswould collapse toeip712Domain()+MessageHashUtils.domainBytes(...). TheTypedDataSigntypehash is normativeand hardcodes all five domain fields, so the ERC-7739 call site always passes
the full-fields byte — but the helper itself stays fields-aware so other
consumers (with a different ERC-5267 subset) can reuse it.
Gating on a second consumer
A single call-site in
ERC7739is not enough on its own — the helper wouldjust move code without shared reuse. Landing this should wait until a second
consumer emerges that needs the pre-hash domain bytes (a follow-up
ERC7739-adjacent utility, a new signer flavor, etc.), at which point thefactoring pays for itself.
References
_buildDomainBytesinline inERC7739