laravel-domain-keeper maintained by labrodev
Laravel Domain Keeper
Domain registrar-expiry reader for Laravel — RDAP first with a port-43 WHOIS fallback. Ask it for a domain and it returns the registrar expiry date as a Carbon instance; the package stores nothing and keeps no state between lookups.
Installation
composer require labrodev/laravel-domain-keeper
Publish the config file:
php artisan vendor:publish --tag=domain-keeper-config
All environment variables are optional — the defaults work out of the box:
DOMAIN_KEEPER_RDAP_URL=https://rdap.org/domain/
DOMAIN_KEEPER_WHOIS_SERVER=whois.iana.org
DOMAIN_KEEPER_TIMEOUT=10
Reading a domain's expiry date
Type-hint the RegistrarExpiryReader contract — the service provider binds it to the RDAP-first implementation:
use Labrodev\DomainKeeper\Contracts\RegistrarExpiryReader;
use Labrodev\DomainKeeper\Exceptions\RegistrarExpiryNotFound;
class DomainExpiryCheckController
{
public function __invoke(RegistrarExpiryReader $registrarExpiryReader)
{
try {
$expiry = $registrarExpiryReader->expiryDate('example.com');
} catch (RegistrarExpiryNotFound $registrarExpiryNotFound) {
// Neither RDAP nor WHOIS produced a date; the message names the domain.
}
return $expiry->toDateString();
}
}
How it resolves
- RDAP — an HTTPS GET to
{rdap_url}{domain}(defaulthttps://rdap.org/domain/, which redirects to the authoritative registry RDAP server). The reader picks theexpirationevent out of the RDAPeventsarray. Plain HTTPS, so it works inside containers with no raw-socket access. - IANA WHOIS referral — when RDAP yields nothing, the domain is queried against the bootstrap WHOIS server (
whois.iana.orgby default) and thewhois:referral line names the TLD's authoritative WHOIS server. - Registrar WHOIS — the referral server is queried for the domain and the expiry line is parsed (
Registry Expiry Date,Registrar Registration Expiration Date,Expiration Date,Expiry Date, orpaid-till).
Every failure along the way falls through silently to the next step; only when all three sources come up empty does the reader throw RegistrarExpiryNotFound.
Testing your own code
The raw port-43 socket lives in Labrodev\DomainKeeper\Services\WhoisClient, which the reader receives via constructor injection — swap it through the container to keep your suite off the network:
use Labrodev\DomainKeeper\Services\WhoisClient;
app()->instance(WhoisClient::class, new readonly class extends WhoisClient
{
public function query(string $server, string $domain): ?string
{
return "Registry Expiry Date: 2030-01-01T00:00:00Z\n";
}
});
Testing
composer test # pest
composer phpstan # larastan, level 7
composer pint # laravel preset
composer check # all of the above
License
MIT. See LICENSE.md.