// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {CheckpointStorage} from "../storage/CheckpointStorage.sol"; /// @title CheckpointEIP712 — typed data for relayer + validator attestations library CheckpointEIP712 { bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); bytes32 public constant BATCH_ATTESTATION_TYPEHASH = keccak256( "BatchAttestation(uint64 chainId,uint64 batchId,uint256 checkpointBlock,bytes32 blockHash,bytes32 stateRoot,bytes32 paymentsRoot,uint64 previousBatchId)" ); function domainSeparator(address verifyingContract, uint256 chainId) internal pure returns (bytes32) { return keccak256( abi.encode( DOMAIN_TYPEHASH, keccak256("Chain138MainnetCheckpoint"), keccak256("2"), chainId, verifyingContract ) ); } function hashBatchAttestation(CheckpointStorage.CheckpointHeader memory header) internal pure returns (bytes32) { return keccak256( abi.encode( BATCH_ATTESTATION_TYPEHASH, header.chainId, header.batchId, header.checkpointBlock, header.blockHash, header.stateRoot, header.paymentsRoot, header.previousBatchId ) ); } function digest( address verifyingContract, uint256 chainId, CheckpointStorage.CheckpointHeader memory header ) internal pure returns (bytes32) { bytes32 structHash = hashBatchAttestation(header); bytes32 domain = domainSeparator(verifyingContract, chainId); return keccak256(abi.encodePacked("\x19\x01", domain, structHash)); } }