feat(domain-intelligence): add domain intelligence lookups with RDAP and DNS enrichment

This commit is contained in:
2026-04-13 16:51:41 +00:00
parent 7e973b842c
commit a694b0c8ae
9 changed files with 995 additions and 22 deletions
+112 -7
View File
@@ -1,6 +1,6 @@
# @push.rocks/smartnetwork 🌐
Comprehensive network diagnostics and IP intelligence for Node.js — speed tests, port scanning, ICMP ping, traceroute, DNS, RDAP, ASN lookups, and geolocation in a single, promise-based toolkit.
Comprehensive network diagnostics and intelligence for Node.js — speed tests, port scanning, ICMP ping, traceroute, DNS, IP & domain RDAP, ASN lookups, geolocation, and DNS record enrichment in a single, promise-based toolkit.
## Issue Reporting and Security
@@ -14,9 +14,9 @@ pnpm install @push.rocks/smartnetwork --save
## 🎯 Overview
**@push.rocks/smartnetwork** is your Swiss Army knife for network diagnostics in Node.js. Whether you're building monitoring dashboards, investigating IP ownership, or debugging connectivity — this library has you covered with a clean, async API and zero-config setup.
**@push.rocks/smartnetwork** is your Swiss Army knife for network diagnostics in Node.js. Whether you're building monitoring dashboards, investigating IP/domain ownership, or debugging connectivity — this library has you covered with a clean, async API and zero-config setup.
Under the hood, system-level operations (ICMP ping, traceroute, raw-socket port checks, gateway detection) are powered by a bundled **Rust binary** for maximum performance and cross-platform reliability. Everything else — speed tests, DNS, public IP discovery, IP intelligence, HTTP health checks — runs in pure TypeScript.
Under the hood, system-level operations (ICMP ping, traceroute, raw-socket port checks, gateway detection) are powered by a bundled **Rust binary** for maximum performance and cross-platform reliability. Everything else — speed tests, DNS, public IP discovery, IP & domain intelligence, HTTP health checks — runs in pure TypeScript.
### ✨ Key Features
@@ -27,6 +27,7 @@ Under the hood, system-level operations (ICMP ping, traceroute, raw-socket port
| 📡 **Connectivity** | ICMP ping with stats, hop-by-hop traceroute, HTTP/HTTPS health checks |
| 🌍 **DNS** | A, AAAA, MX resolution with system-first + DoH fallback strategy |
| 🔍 **IP Intelligence** | ASN, organization, geolocation, RDAP registration — all from free public sources |
| 🏢 **Domain Intelligence** | RDAP registrar/registrant, nameservers, events, DNSSEC, plus DNS enrichment (A/AAAA/MX/TXT/SOA) |
| 🖥️ **Network Discovery** | Interfaces, default gateway, public IPv4/IPv6 |
| ⚡ **Caching** | Built-in TTL cache for expensive lookups |
| 🔧 **Extensible** | Plugin architecture for custom functionality |
@@ -46,7 +47,7 @@ await network.start();
// ... use the network instance ...
// Clean up when done
// Clean up when done — tears down both the Rust bridge and the smartdns backend
await network.stop();
```
@@ -126,6 +127,104 @@ interface IIpIntelligenceResult {
---
### 🏢 Domain Intelligence
Get comprehensive domain registration and DNS data. Runs an **RDAP layer** and a **DNS layer** in parallel, then merges results:
- **RDAP** — queries the correct registry RDAP server (discovered via the [IANA DNS bootstrap](https://data.iana.org/rdap/dns.json)) for registrar, registrant, events, status flags, DNSSEC, and abuse contacts
- **DNS** — queries A, AAAA, NS, MX, TXT, and SOA records via `@push.rocks/smartdns` (system resolver first, DoH fallback)
For gTLDs (`.com`, `.org`, `.net`, etc.) you get the full picture from both layers. For ccTLDs without RDAP support (`.de`, `.fr`, `.nl`, etc.), the DNS layer fills in nameservers, resolved IPs, MX, TXT, and SOA — so you still get useful intelligence even when RDAP isn't available.
```typescript
const info = await network.getDomainIntelligence('google.com');
console.log(info);
// {
// domain: 'google.com',
// handle: '2138514_DOMAIN_COM-VRSN',
// status: ['client delete prohibited', 'server transfer prohibited', ...],
// registrationDate: '1997-09-15T04:00:00Z',
// expirationDate: '2028-09-14T04:00:00Z',
// lastChangedDate: '2019-09-09T15:39:04Z',
// registrarName: 'MarkMonitor Inc.',
// registrarIanaId: 292,
// registrantOrg: null, // often redacted under GDPR
// registrantCountry: null,
// abuseEmail: 'abusecomplaints@markmonitor.com',
// abusePhone: '+1.2086851750',
// nameservers: ['ns1.google.com', 'ns2.google.com', 'ns3.google.com', 'ns4.google.com'],
// dnssec: false,
// nameserversSource: 'rdap',
// resolvedIpv4: ['142.251.20.102', '142.251.20.113', ...],
// resolvedIpv6: ['2a00:1450:4001:c15::8b', ...],
// mxRecords: [{ priority: 10, exchange: 'smtp.google.com' }],
// txtRecords: ['v=spf1 include:_spf.google.com ~all', ...],
// soaRecord: 'ns1.google.com dns-admin.google.com 895796075 900 900 1800 60'
// }
```
Works with ccTLDs that don't have RDAP (like `.de`):
```typescript
const deInfo = await network.getDomainIntelligence('bund.de');
console.log(deInfo.registrarName); // null (no .de RDAP)
console.log(deInfo.nameservers); // ['bamberg.bund.de', 'argon.bund.de', ...]
console.log(deInfo.nameserversSource); // 'dns' — nameservers came from DNS, not RDAP
console.log(deInfo.resolvedIpv4); // ['80.245.156.34']
console.log(deInfo.mxRecords); // [{priority: 10, exchange: 'mx1.bund.de'}, ...]
```
Handles IDN (internationalized domain names) automatically:
```typescript
const idn = await network.getDomainIntelligence('münchen.de');
console.log(idn.domain); // 'xn--mnchen-3ya.de' — normalized to punycode
```
The `IDomainIntelligenceResult` interface:
```typescript
interface IDomainIntelligenceResult {
domain: string | null; // normalized ASCII form
handle: string | null; // registry handle
status: string[] | null; // EPP status codes
// Registration lifecycle (ISO 8601)
registrationDate: string | null;
expirationDate: string | null;
lastChangedDate: string | null;
// Registrar
registrarName: string | null;
registrarIanaId: number | null;
// Registrant (often redacted under GDPR)
registrantOrg: string | null;
registrantCountry: string | null;
// Abuse contact
abuseEmail: string | null;
abusePhone: string | null;
// Technical
nameservers: string[] | null;
dnssec: boolean | null; // secureDNS.delegationSigned from RDAP
nameserversSource: 'rdap' | 'dns' | null;
// DNS enrichment
resolvedIpv4: string[] | null; // A records
resolvedIpv6: string[] | null; // AAAA records
mxRecords: { priority: number | null; exchange: string }[] | null;
txtRecords: string[] | null; // SPF, DKIM, site verification, etc.
soaRecord: string | null; // raw SOA value
}
```
> 💡 **RDAP vs DNS nameservers**: When RDAP is available (most gTLDs), `nameservers` comes from the registry's authoritative parent-zone delegation (`nameserversSource: 'rdap'`). When RDAP is unavailable (many ccTLDs), the DNS layer fills in nameservers via NS record resolution (`nameserversSource: 'dns'`). The `nameserversSource` field tells you which source won.
---
### 🏎️ Speed Testing
Measure network performance via Cloudflare's global infrastructure:
@@ -263,7 +362,7 @@ console.log(`🌍 IPv6: ${publicIps.v6 || 'N/A'}`);
### ⚡ Caching
Caching applies to `getGateways()`, `getPublicIps()`, and `getIpIntelligence()`:
Caching applies to `getGateways()`, `getPublicIps()`, `getIpIntelligence()`, and `getDomainIntelligence()`:
```typescript
const network = new SmartNetwork({ cacheTtl: 60000 }); // 60s
@@ -360,6 +459,11 @@ const monitor = async () => {
console.log(`AS${intel.asn} (${intel.asnOrg}) — ${intel.city || intel.countryCode}`);
}
// Domain recon
const domain = await network.getDomainIntelligence('example.com');
console.log(`Registrar: ${domain.registrarName}, expires: ${domain.expirationDate}`);
console.log(`Nameservers (${domain.nameserversSource}):`, domain.nameservers);
await network.stop();
};
```
@@ -368,7 +472,7 @@ const monitor = async () => {
| Method | Description | Requires Rust |
|--------|-------------|:---:|
| `start()` / `stop()` | Start/stop the Rust binary bridge | — |
| `start()` / `stop()` | Start/stop the Rust bridge and smartdns backend | — |
| `getSpeed(opts?)` | Cloudflare speed test (download + upload) | No |
| `ping(host, opts?)` | ICMP ping with optional multi-ping stats | Yes |
| `traceroute(host, opts?)` | Hop-by-hop network path analysis | Yes |
@@ -381,6 +485,7 @@ const monitor = async () => {
| `resolveDns(host)` | Resolve A, AAAA, MX records | No |
| `checkEndpoint(url, opts?)` | HTTP/HTTPS health check with RTT | No |
| `getIpIntelligence(ip)` | ASN + org + geo + RDAP registration | No |
| `getDomainIntelligence(domain)` | Registrar, nameservers, events, DNS records, DNSSEC | No |
## License and Legal Information
@@ -396,7 +501,7 @@ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark G
### Company Information
Task Venture Capital GmbH
Task Venture Capital GmbH
Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or further information, please contact us via email at hello@task.vc.