diff --git a/README.md b/README.md index cf49eab..740235c 100644 --- a/README.md +++ b/README.md @@ -71,9 +71,10 @@ but normal installations do not need it. - An address ending in `.cltc` configures testnet and displays `CLTC`. - An address ending in `.clc` configures mainnet and displays `CLC`. -The faucet address must be the registered canonical 40-character short -address. Faucet claims also require canonical short addresses; vanity aliases -are not accepted by the claim form. +The faucet address itself must be the registered canonical 40-character short +address. Faucet recipients may enter either a canonical short address or a +registered vanity address. Vanity inputs are resolved through RPC, and the +canonical owner address is used for the transfer and 24-hour claim ledger. Point the faucet at its dedicated wallet and provide that wallet's decryption key: diff --git a/api.php b/api.php index ebda0eb..3b26845 100644 --- a/api.php +++ b/api.php @@ -51,14 +51,14 @@ try { json_response(['success' => false, 'error' => 'Request body must be JSON.'], 400); } - $requestedAddress = normalize_requested_address( + $requestedInput = normalize_requested_address( (string) ($body['address'] ?? ''), $network['suffix'] ); - if ($requestedAddress === null) { + if ($requestedInput === null) { json_response([ 'success' => false, - 'error' => "Enter a valid registered {$network['network']} wallet address.", + 'error' => "Enter a valid {$network['network']} wallet or vanity address.", ], 422); } @@ -70,19 +70,38 @@ try { $now = time(); $nowMs = (int) floor(microtime(true) * 1000); + $rateLimit = with_ledger_lock(true, function (array &$ledger) use ( + $nowMs, + $config + ): bool { + $lastRequest = (int) $ledger['last_request_timestamp_ms']; + if ($nowMs - $lastRequest < $config['minimum_request_interval_ms']) { + return false; + } + $ledger['last_request_timestamp_ms'] = $nowMs; + return true; + }); + if (!$rateLimit) { + json_response([ + 'success' => false, + 'error' => 'The faucet is busy. Try again.', + ], 429); + } + + $requestedAddress = resolve_requested_address($requestedInput, $network['suffix']); + if ($requestedAddress === null) { + json_response([ + 'success' => false, + 'error' => "The {$network['network']} wallet or vanity address is not registered.", + ], 422); + } + $precheck = with_ledger_lock(true, function (array &$ledger) use ( $requestedAddress, $clientIp, $now, - $nowMs, $config ): array { - $lastRequest = (int) $ledger['last_request_timestamp_ms']; - if ($nowMs - $lastRequest < $config['minimum_request_interval_ms']) { - return ['allowed' => false, 'status' => 429, 'error' => 'The faucet is busy. Try again.']; - } - $ledger['last_request_timestamp_ms'] = $nowMs; - $addressClaim = active_claim( $ledger['addresses'], $requestedAddress, diff --git a/index.html b/index.html index 27206f2..ccf9933 100644 --- a/index.html +++ b/index.html @@ -66,7 +66,7 @@