Function construct_eip712_message_hash

Source
pub fn construct_eip712_message_hash(
    request: &SignTypedDataRequest,
) -> Result<[u8; 32], SignerError>
Expand description

Constructs an EIP-712 message hash from domain separator and struct hash

This function implements the EIP-712 typed data signing specification: https://eips.ethereum.org/EIPS/eip-712

§EIP-712 Format

The message hash is constructed as:

keccak256("\x19\x01" ‖ domainSeparator ‖ hashStruct(message))

§Security Considerations

CRITICAL SECURITY REQUIREMENTS:

  • Domain Separator Uniqueness: The domain separator MUST be unique to your dapp to prevent cross-contract replay attacks. Include at minimum:

    • Contract name
    • Contract version
    • Chain ID (prevents cross-chain replays)
    • Verifying contract address
  • Hash Struct Integrity: The hashStruct MUST uniquely identify your message type and data. Collisions allow signature reuse across different messages.

  • Replay Protection: Always include nonces or timestamps in your message struct to prevent replay attacks within the same contract.

  • Chain ID: MUST be included in domain separator to prevent signatures from being valid on multiple chains (mainnet, testnet, etc.)

§Arguments

  • request - The typed data signing request containing:
    • domain_separator: 32-byte hash uniquely identifying the signing domain
    • hash_struct_message: 32-byte hash of the structured message data

§Returns

  • Ok([u8; 32]) - The 32-byte message hash ready for signing
  • Err(SignerError) - If validation fails or hex decoding fails

§Errors

Returns SignerError::SigningError if:

  • Domain separator is not exactly 32 bytes
  • Hash struct is not exactly 32 bytes
  • Input contains invalid hexadecimal characters

§Examples

use crate::domain::SignTypedDataRequest;
use crate::services::signer::evm::construct_eip712_message_hash;

let request = SignTypedDataRequest {
    // 32 bytes as hex (with or without 0x prefix)
    domain_separator: "a".repeat(64),
    hash_struct_message: "b".repeat(64),
};

let hash = construct_eip712_message_hash(&request)?;
// hash is now ready for signing