labrodev/laravel-domain-keeper

Domain registrar-expiry reader for Laravel — RDAP first with a port-43 WHOIS fallback.

Maintainers

Package info

github.com/labrodev/laravel-domain-keeper

pkg:composer/labrodev/laravel-domain-keeper

Transparency log

Statistics

Installs: 8

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-07-22 10:24 UTC

This package is auto-updated.

Last update: 2026-07-22 10:25:33 UTC


README

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

  1. RDAP — an HTTPS GET to {rdap_url}{domain} (default https://rdap.org/domain/, which redirects to the authoritative registry RDAP server). The reader picks the expiration event out of the RDAP events array. Plain HTTPS, so it works inside containers with no raw-socket access.
  2. IANA WHOIS referral — when RDAP yields nothing, the domain is queried against the bootstrap WHOIS server (whois.iana.org by default) and the whois: referral line names the TLD's authoritative WHOIS server.
  3. 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, or paid-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.