/** * @fileoverview CREATE2 and vanity address utilities for EscapeHub SDK. * * This module provides framework-agnostic utilities for: * - Computing CREATE2 addresses * - Building minimal proxy (clone) bytecode * - Mining vanity addresses with customizable patterns * * @module @escapehub/token-creator/create2 */ /** * CREATE2 prefix byte (0xff) as defined in EIP-1014. * Used in CREATE2 address computation: keccak256(0xff ++ deployer ++ salt ++ keccak256(initCode)) * * @example * ```typescript * import { CREATE2_PREFIX } from '@escapehub/token-creator'; * * console.log(CREATE2_PREFIX); // '0xff' * ``` */ export declare const CREATE2_PREFIX = "0xff"; /** * OpenZeppelin Clones minimal proxy bytecode prefix. * This is the first part of the EIP-1167 minimal proxy pattern. * * The full bytecode is: MINIMAL_PROXY_PREFIX + implementation address (20 bytes) + MINIMAL_PROXY_SUFFIX * * @see https://eips.ethereum.org/EIPS/eip-1167 */ export declare const MINIMAL_PROXY_PREFIX = "0x3d602d80600a3d3981f3363d3d373d3d3d363d73"; /** * OpenZeppelin Clones minimal proxy bytecode suffix. * This is the second part of the EIP-1167 minimal proxy pattern. * * The full bytecode is: MINIMAL_PROXY_PREFIX + implementation address (20 bytes) + MINIMAL_PROXY_SUFFIX * * @see https://eips.ethereum.org/EIPS/eip-1167 */ export declare const MINIMAL_PROXY_SUFFIX = "0x5af43d82803e903d91602b57fd5bf3"; /** * Zero salt (32 bytes of zeros). * Commonly used as a default salt when no vanity pattern is required. * * @example * ```typescript * import { ZERO_SALT, isZeroSalt } from '@escapehub/token-creator'; * * console.log(ZERO_SALT); * // '0x0000000000000000000000000000000000000000000000000000000000000000' * * console.log(isZeroSalt(ZERO_SALT)); // true * ``` */ export declare const ZERO_SALT = "0x0000000000000000000000000000000000000000000000000000000000000000"; /** * Vanity pattern matching mode. * * - `'prefix'`: Pattern must match the beginning of the address (after 0x) * - `'suffix'`: Pattern must match the end of the address * * @example * ```typescript * import { VanityPatternMode } from '@escapehub/token-creator'; * * const mode: VanityPatternMode = 'prefix'; * // Matches addresses like 0xDEAD... * * const suffixMode: VanityPatternMode = 'suffix'; * // Matches addresses like 0x...BEEF * ``` */ export type VanityPatternMode = 'prefix' | 'suffix'; /** * Result of vanity address mining. */ export interface VanityResult { /** * The salt that produces the vanity address (32 bytes hex string). */ salt: string; /** * The computed CREATE2 address matching the vanity pattern. * Checksummed (EIP-55) format. */ address: string; /** * Number of attempts taken to find the matching address. */ attempts: number; } /** * Options for vanity address mining. */ export interface VanityMiningOptions { /** * Hex pattern to match (without 0x prefix). * Only hex characters (0-9, a-f, A-F) are allowed. * * @example 'DEAD', 'cafe', '1234' */ pattern: string; /** * Where to match the pattern in the address. * * - `'prefix'`: Match at the start (e.g., 0xDEAD...) * - `'suffix'`: Match at the end (e.g., ...BEEF) * * @default 'prefix' */ mode?: VanityPatternMode; /** * Whether pattern matching is case-sensitive. * * When false, 'dead' matches 'DEAD', 'Dead', 'deAD', etc. * When true, pattern must match exactly (considering EIP-55 checksum). * * @default false */ caseSensitive?: boolean; /** * Maximum number of attempts before giving up. * Set to 0 or Infinity for unlimited attempts. * * @default 1_000_000 */ maxAttempts?: number; /** * Callback invoked periodically during mining to report progress. * Useful for updating UI or logging progress. * * @param attempts - Current number of attempts * @param hashRate - Current hashes per second (approximate) */ onProgress?: (attempts: number, hashRate: number) => void; /** * Starting nonce for salt generation. * Allows resuming mining from a previous point. * * @default 0 */ startNonce?: number; } /** * Computes a CREATE2 address from factory, salt, and init code hash. * * The CREATE2 address is computed as: * `keccak256(0xff ++ factoryAddress ++ salt ++ initCodeHash)[12:]` * * @param factoryAddress - Address of the factory contract deploying via CREATE2 * @param salt - 32-byte salt value (hex string with 0x prefix) * @param initCodeHash - keccak256 hash of the contract init code * @returns Checksummed CREATE2 address * * @example * ```typescript * import { computeCreate2Address, getMinimalProxyInitCodeHash } from '@escapehub/token-creator'; * * const factory = '0x1234567890123456789012345678901234567890'; * const implementation = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd'; * const salt = '0x0000000000000000000000000000000000000000000000000000000000000001'; * * const initCodeHash = getMinimalProxyInitCodeHash(implementation); * const predictedAddress = computeCreate2Address(factory, salt, initCodeHash); * * console.log(predictedAddress); // '0x...' * ``` */ export declare function computeCreate2Address(factoryAddress: string, salt: string, initCodeHash: string): string; /** * Builds the minimal proxy (EIP-1167 clone) bytecode for an implementation address. * * The bytecode follows the OpenZeppelin Clones pattern: * `MINIMAL_PROXY_PREFIX + implementation (20 bytes) + MINIMAL_PROXY_SUFFIX` * * @param implementationAddress - Address of the implementation contract * @returns The complete minimal proxy bytecode * * @example * ```typescript * import { buildMinimalProxyBytecode } from '@escapehub/token-creator'; * * const implementation = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd'; * const bytecode = buildMinimalProxyBytecode(implementation); * * console.log(bytecode); * // '0x3d602d80600a3d3981f3363d3d373d3d3d363d73abcdefabcdefabcdefabcdefabcdefabcdefabcd5af43d82803e903d91602b57fd5bf3' * ``` */ export declare function buildMinimalProxyBytecode(implementationAddress: string): string; /** * Computes the keccak256 hash of the minimal proxy bytecode for an implementation. * * This is the init code hash needed for CREATE2 address computation when * deploying clones via OpenZeppelin's Clones library. * * @param implementationAddress - Address of the implementation contract * @returns keccak256 hash of the minimal proxy bytecode * * @example * ```typescript * import { getMinimalProxyInitCodeHash, computeCreate2Address } from '@escapehub/token-creator'; * * const implementation = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd'; * const initCodeHash = getMinimalProxyInitCodeHash(implementation); * * // Use with computeCreate2Address to predict clone addresses * const factory = '0x1234567890123456789012345678901234567890'; * const salt = '0x0000000000000000000000000000000000000000000000000000000000000001'; * const cloneAddress = computeCreate2Address(factory, salt, initCodeHash); * ``` */ export declare function getMinimalProxyInitCodeHash(implementationAddress: string): string; /** * Checks if an address matches a vanity pattern. * * @param address - The address to check (with or without 0x prefix) * @param pattern - The hex pattern to match (without 0x prefix) * @param mode - Whether to match at 'prefix' or 'suffix' of address * @param caseSensitive - Whether matching is case-sensitive * @returns True if the address matches the pattern * * @example * ```typescript * import { matchesVanityPattern } from '@escapehub/token-creator'; * * // Prefix matching (case-insensitive) * matchesVanityPattern('0xDEAD1234...', 'dead', 'prefix', false); // true * matchesVanityPattern('0xDEAD1234...', 'dead', 'prefix', true); // false (case mismatch) * * // Suffix matching * matchesVanityPattern('0x...BEEF', 'beef', 'suffix', false); // true * ``` */ export declare function matchesVanityPattern(address: string, pattern: string, mode?: VanityPatternMode, caseSensitive?: boolean): boolean; /** * Validates that a pattern contains only valid hex characters. * * @param pattern - The pattern to validate (without 0x prefix) * @returns True if pattern contains only hex characters (0-9, a-f, A-F) * * @example * ```typescript * import { isValidHexPattern } from '@escapehub/token-creator'; * * isValidHexPattern('DEAD'); // true * isValidHexPattern('cafe'); // true * isValidHexPattern('1234'); // true * isValidHexPattern('GHIJ'); // false (G, H, I, J are not hex) * isValidHexPattern('0xDEAD'); // false (0x prefix not allowed) * ``` */ export declare function isValidHexPattern(pattern: string): boolean; /** * Generates a random salt, optionally incorporating a nonce. * * When a nonce is provided, the salt is derived from random bytes XORed * with the nonce to ensure uniqueness while maintaining randomness. * * @param nonce - Optional nonce to incorporate into the salt * @returns 32-byte hex string salt * * @example * ```typescript * import { generateRandomSalt } from '@escapehub/token-creator'; * * // Fully random salt * const salt1 = generateRandomSalt(); * * // Salt with nonce (for sequential mining) * const salt2 = generateRandomSalt(12345); * ``` */ export declare function generateRandomSalt(nonce?: number): string; /** * Mines a vanity address by trying different salts until a match is found. * * This is a synchronous operation that will block the event loop. * For non-blocking mining, use {@link generateSaltAsync}. * * @param factoryAddress - Address of the CREATE2 factory contract * @param initCodeHash - keccak256 hash of the contract init code * @param options - Vanity mining options * @returns The salt and address that match the pattern, or null if max attempts reached * * @throws Error if pattern is invalid * * @example * ```typescript * import { generateSalt, getMinimalProxyInitCodeHash } from '@escapehub/token-creator'; * * const factory = '0x1234567890123456789012345678901234567890'; * const implementation = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd'; * const initCodeHash = getMinimalProxyInitCodeHash(implementation); * * const result = generateSalt(factory, initCodeHash, { * pattern: 'DEAD', * mode: 'prefix', * maxAttempts: 100_000, * onProgress: (attempts, hashRate) => { * console.log(`Attempts: ${attempts}, Rate: ${hashRate} H/s`); * } * }); * * if (result) { * console.log(`Found! Address: ${result.address}, Salt: ${result.salt}`); * console.log(`Took ${result.attempts} attempts`); * } else { * console.log('No match found within max attempts'); * } * ``` */ export declare function generateSalt(factoryAddress: string, initCodeHash: string, options: VanityMiningOptions): VanityResult | null; /** * Mines a vanity address asynchronously, yielding to the event loop periodically. * * This allows other operations to proceed during mining, making it suitable * for use in web applications or Node.js servers. * * @param factoryAddress - Address of the CREATE2 factory contract * @param initCodeHash - keccak256 hash of the contract init code * @param options - Vanity mining options * @param yieldInterval - Number of attempts between event loop yields * @returns Promise resolving to the salt and address, or null if max attempts reached * * @example * ```typescript * import { generateSaltAsync, getMinimalProxyInitCodeHash } from '@escapehub/token-creator'; * * const factory = '0x1234567890123456789012345678901234567890'; * const implementation = '0xabcdefabcdefabcdefabcdefabcdefabcdefabcd'; * const initCodeHash = getMinimalProxyInitCodeHash(implementation); * * const result = await generateSaltAsync(factory, initCodeHash, { * pattern: 'CAFE', * mode: 'prefix', * maxAttempts: 500_000, * onProgress: (attempts, hashRate) => { * console.log(`Progress: ${attempts} attempts, ${hashRate} H/s`); * } * }, 1000); // Yield every 1000 attempts * * if (result) { * console.log(`Found vanity address: ${result.address}`); * } * ``` */ export declare function generateSaltAsync(factoryAddress: string, initCodeHash: string, options: VanityMiningOptions, yieldInterval?: number): Promise; /** * Normalizes an Ethereum address to checksummed format. * * @param address - The address to normalize * @returns Checksummed address (EIP-55) * @throws Error if address is invalid * * @example * ```typescript * import { normalizeAddress } from '@escapehub/token-creator'; * * normalizeAddress('0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef'); * // '0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF' (checksummed) * ``` */ export declare function normalizeAddress(address: string): string; /** * Checks if a salt is the zero salt (all zeros). * * @param salt - The salt to check * @returns True if salt is all zeros * * @example * ```typescript * import { isZeroSalt, ZERO_SALT, generateRandomSalt } from '@escapehub/token-creator'; * * isZeroSalt(ZERO_SALT); // true * isZeroSalt(generateRandomSalt()); // false (almost certainly) * ``` */ export declare function isZeroSalt(salt: string): boolean; /** * Estimates the expected number of attempts to find a vanity address. * * For prefix matching: 16^patternLength attempts on average * For case-sensitive matching with checksummed addresses, the calculation * is more complex due to EIP-55 checksum rules. * * @param patternLength - Length of the vanity pattern * @param caseSensitive - Whether matching is case-sensitive * @returns Estimated number of attempts * * @example * ```typescript * import { estimateVanityAttempts, formatAttempts } from '@escapehub/token-creator'; * * // 4-character prefix * const attempts = estimateVanityAttempts(4, false); * console.log(formatAttempts(attempts)); // '65,536' * * // 6-character prefix (harder) * const harder = estimateVanityAttempts(6, false); * console.log(formatAttempts(harder)); // '16,777,216' * ``` */ export declare function estimateVanityAttempts(patternLength: number, caseSensitive?: boolean): number; /** * Formats a large number with thousand separators. * * @param attempts - The number to format * @returns Formatted string with commas * * @example * ```typescript * import { formatAttempts } from '@escapehub/token-creator'; * * formatAttempts(1000); // '1,000' * formatAttempts(1000000); // '1,000,000' * formatAttempts(16777216); // '16,777,216' * ``` */ export declare function formatAttempts(attempts: number): string; /** * Estimates the time to find a vanity address given a hash rate. * * @param patternLength - Length of the vanity pattern * @param hashRate - Hashes per second (attempts per second) * @param caseSensitive - Whether matching is case-sensitive * @returns Estimated time in seconds * * @example * ```typescript * import { estimateVanityTime, formatDuration } from '@escapehub/token-creator'; * * // 4-character pattern at 10,000 H/s * const seconds = estimateVanityTime(4, 10_000, false); * console.log(formatDuration(seconds)); // '~7 seconds' * * // 6-character pattern at 10,000 H/s * const harder = estimateVanityTime(6, 10_000, false); * console.log(formatDuration(harder)); // '~28 minutes' * ``` */ export declare function estimateVanityTime(patternLength: number, hashRate: number, caseSensitive?: boolean): number; /** * Formats a duration in seconds to a human-readable string. * * @param seconds - Duration in seconds * @returns Human-readable duration string * * @example * ```typescript * import { formatDuration } from '@escapehub/token-creator'; * * formatDuration(5); // '~5 seconds' * formatDuration(90); // '~2 minutes' * formatDuration(3700); // '~1 hour' * formatDuration(90000); // '~1 day' * formatDuration(1000000); // '~12 days' * formatDuration(Infinity); // '∞' * ``` */ export declare function formatDuration(seconds: number): string; //# sourceMappingURL=create2.d.ts.map