// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; /** * @title EnvValidation * @notice Library for validating environment variables in deployment scripts * @dev Provides helper functions to validate private keys, addresses, and RPC URLs */ library EnvValidation { error InvalidPrivateKey(); error InvalidAddress(string name); error InvalidRPCURL(); error MissingEnvironmentVariable(string name); /** * @notice Validates that a private key is set and has correct format * @dev Checks that PRIVATE_KEY env var is set and is a valid hex string (64 chars without 0x) * @param key The private key string from environment */ function validatePrivateKey(string memory key) internal pure { bytes memory keyBytes = bytes(key); // Check minimum length (64 hex chars = 32 bytes) if (keyBytes.length < 64) { revert InvalidPrivateKey(); } // Remove 0x prefix if present uint256 start = 0; if (keyBytes.length >= 2 && keyBytes[0] == '0' && (keyBytes[1] == 'x' || keyBytes[1] == 'X')) { start = 2; } // Check remaining length (must be 64 hex chars = 32 bytes) if (keyBytes.length - start != 64) { revert InvalidPrivateKey(); } // Validate hex characters for (uint256 i = start; i < keyBytes.length; i++) { bytes1 char = keyBytes[i]; if (!((char >= 0x30 && char <= 0x39) || // 0-9 (char >= 0x41 && char <= 0x46) || // A-F (char >= 0x61 && char <= 0x66))) { // a-f revert InvalidPrivateKey(); } } } /** * @notice Validates that an address is not zero * @param addr The address to validate * @param name Name of the variable for error messages */ function validateAddress(address addr, string memory name) internal pure { if (addr == address(0)) { revert InvalidAddress(name); } } /** * @notice Validates that an RPC URL is set and has correct format * @param url The RPC URL string */ function validateRpcUrl(string memory url) internal pure { bytes memory urlBytes = bytes(url); if (urlBytes.length == 0) { revert InvalidRPCURL(); } // Check for http:// or https:// prefix bool hasValidPrefix = false; if (urlBytes.length >= 7) { bytes memory prefix = new bytes(7); for (uint256 i = 0; i < 7; i++) { prefix[i] = urlBytes[i]; } string memory prefixStr = string(prefix); if (keccak256(bytes(prefixStr)) == keccak256(bytes("http://"))) { hasValidPrefix = true; } } if (!hasValidPrefix && urlBytes.length >= 8) { bytes memory prefix = new bytes(8); for (uint256 i = 0; i < 8; i++) { prefix[i] = urlBytes[i]; } string memory prefixStr = string(prefix); if (keccak256(bytes(prefixStr)) == keccak256(bytes("https://"))) { hasValidPrefix = true; } } if (!hasValidPrefix) { revert InvalidRPCURL(); } } }