pragma solidity ^0.8.13; contract TimelockedHashEscrow { address public immutable owner; address payable public payee; bytes32 public conditionHash; uint256 public amount; uint256 public deadline; bool public claimed; constructor() { owner = msg.sender; } function offer(bytes32 _conditionHash, address payable _payee, uint256 _deadline) external payable { require(msg.sender == owner, "!owner"); require(payee == address(0), "active"); require(_payee != address(0), "payee=0"); require(_deadline > block.timestamp, "deadline"); require(msg.value > 0, "zero value"); conditionHash = _conditionHash; payee = _payee; amount = msg.value; deadline = _deadline; claimed = false; } function claim(bytes32 preimage) external { require(msg.sender == payee, "!payee"); require(!claimed, "claimed"); require(block.timestamp <= deadline, "late"); require(keccak256(abi.encodePacked(preimage)) == conditionHash, "!secret"); claimed = true; payee = payable(address(0)); payable(msg.sender).transfer(amount); } function refund() external { require(msg.sender == owner, "!owner"); require(payee != address(0), "no escrow"); require(!claimed, "claimed"); require(block.timestamp > deadline, "early"); payee = payable(address(0)); payable(owner).transfer(amount); } }