Skip to main content

Installation

npm install oathnet

# Or with yarn
yarn add oathnet

# Or with pnpm
pnpm add oathnet
Requirements: Node.js 16+ or modern browser

Quick Start

import { OathNetClient } from 'oathnet';

// Initialize client with API key (required)
const client = new OathNetClient('your-api-key');

// Search breaches
const result = await client.search.breach("[email protected]");
console.log(`Found ${result.data?.results_found} results`);

for (const record of result.data?.results || []) {
  console.log(`${record.email}: ${record.password}`);
}

TypeScript Support

Full TypeScript support with comprehensive type definitions:
import { OathNetClient } from 'oathnet';
import type { BreachRecord, StealerItem, VictimProfile } from 'oathnet';

const client = new OathNetClient('your-api-key');

// Fully typed responses
const result = await client.search.breach("[email protected]");
result.data?.results.forEach((record: BreachRecord) => {
  console.log(record.email);
  console.log(record.password);
  console.log(record.dbname);
});

Authentication

import { OathNetClient } from 'oathnet';

// Explicit API key (required)
const client = new OathNetClient('your-api-key');

// With options
const client = new OathNetClient('your-api-key', {
  baseUrl: 'https://oathnet.org/api',
  timeout: 30000
});

Search Service

// Basic search
const result = await client.search.breach("[email protected]");

// With filters
const result = await client.search.breach("[email protected]", {
  dbnames: "linkedin_2012,adobe_2013"
});

// Access results
console.log(`Total: ${result.data?.results_found}`);
console.log(`Shown: ${result.data?.results_shown}`);

for (const record of result.data?.results || []) {
  console.log(`Email: ${record.email}`);
  console.log(`Password: ${record.password}`);
  console.log(`Database: ${record.dbname}`);
}

// Pagination
if (result.data?.cursor) {
  const nextPage = await client.search.breach("[email protected]", {
    cursor: result.data.cursor
  });
}

Initialize Session

// Create a search session for quota optimization
const result = await client.search.initSession("[email protected]");

const sessionId = result.data?.session.id;
console.log(`Session ID: ${sessionId}`);
console.log(`Search Type: ${result.data?.session.search_type}`);
console.log(`Expires: ${result.data?.session.expires_at}`);
// Basic search
const result = await client.stealer.search("[email protected]");

// Advanced filtering
const result = await client.stealer.search("[email protected]", {
  domains: ["google.com", "facebook.com"],
  hasLogId: true,
  pageSize: 50
});

// Access items
for (const item of result.data?.items || []) {
  console.log(`URL: ${item.url}`);
  console.log(`Username: ${item.username}`);
  console.log(`Password: ${item.password}`);
  console.log(`Log ID: ${item.log_id}`);
}

// Pagination
if (result.data?.next_cursor) {
  const nextPage = await client.stealer.search("[email protected]", {
    cursor: result.data.next_cursor
  });
}

// Subdomain extraction
const subdomains = await client.stealer.subdomain("example.com");
console.log(`Found ${subdomains.data?.count} subdomains`);
for (const sub of subdomains.data?.subdomains || []) {
  console.log(`  ${sub}`);
}

Victims

// Search victims
const result = await client.victims.search("[email protected]");

for (const victim of result.data?.items || []) {
  console.log(`Log ID: ${victim.log_id}`);
  console.log(`Users: ${victim.device_users?.join(", ")}`);
  console.log(`Documents: ${victim.total_docs}`);
}

// Get manifest
const manifest = await client.victims.getManifest("log_id_here");
console.log(`Total Files: ${manifest.data?.total_files}`);
console.log(`Total Size: ${manifest.data?.total_size} bytes`);

for (const file of manifest.data?.files?.slice(0, 10) || []) {
  console.log(`  ${file.relative_path} (${file.size} bytes)`);
}

// Get file content
const file = await client.victims.getFile("log_id", "file_id");
console.log(file.data?.content);

// Download archive (returns path or ArrayBuffer in browser)
const archivePath = await client.victims.downloadArchive("log_id", "./archive.zip");
Search within stealer log files using regex or wildcard patterns.
// Create a file search job
const result = await client.fileSearch.create("password", {
  logIds: ["log_id_1", "log_id_2"],
  searchMode: "literal"  // literal, regex, or wildcard
});
const jobId = result.data?.job_id;
console.log(`Job ID: ${jobId}`);

// Check job status
const status = await client.fileSearch.getStatus(jobId);
console.log(`Status: ${status.data?.status}`);
if (status.data?.summary) {
  console.log(`Files scanned: ${status.data.summary.files_scanned}`);
  console.log(`Matches: ${status.data.summary.matches}`);
}

// Wait for completion and get results
const searchResult = await client.fileSearch.search("password", {
  logIds: ["log_id_1", "log_id_2"],
  searchMode: "literal"
}, 300000);  // timeout in ms

for (const match of searchResult.data?.matches || []) {
  console.log(`File: ${match.file_name}`);
  console.log(`Log ID: ${match.log_id}`);
  console.log(`Match: ${match.match_text}`);
}

Exports

Export large datasets asynchronously.
// Create an export job
const result = await client.exports.create("stealer", {
  limit: 100,         // minimum 100
  format: "jsonl"     // jsonl or csv
});
const jobId = result.data?.job_id;
console.log(`Export Job ID: ${jobId}`);

// Check export status
const status = await client.exports.getStatus(jobId);
console.log(`Status: ${status.data?.status}`);
if (status.data?.progress) {
  console.log(`Progress: ${status.data.progress.percent}%`);
}

// Wait for completion
const completed = await client.exports.waitForCompletion(jobId, 600000);
if (completed.data?.status === "completed") {
  // Download the export file
  await client.exports.download(jobId, "./export.jsonl");
}

OSINT Lookups

// IP Info
const ipInfo = await client.osint.ipInfo("8.8.8.8");
console.log(`Location: ${ipInfo.data?.city}, ${ipInfo.data?.country}`);
console.log(`ISP: ${ipInfo.data?.isp}`);
console.log(`Proxy: ${ipInfo.data?.proxy}`);

// Steam
const steam = await client.osint.steam("76561198012345678");
console.log(`Username: ${steam.data?.username}`);
console.log(`Avatar: ${steam.data?.avatar}`);

// Xbox
const xbox = await client.osint.xbox("GamerTag123");
console.log(`Username: ${xbox.data?.username}`);
console.log(`Avatar: ${xbox.data?.avatar}`);

// Discord User Info
const discord = await client.osint.discordUserinfo("123456789012345678");
console.log(`Username: ${discord.data?.username}`);
console.log(`Global Name: ${discord.data?.global_name}`);
console.log(`Created: ${discord.data?.creation_date}`);

// Discord Username History
const history = await client.osint.discordUsernameHistory("123456789012345678");
for (const entry of history.data?.history || []) {
  if (entry.name?.[0] && entry.time?.[0]) {
    console.log(`${entry.name[0]} at ${entry.time[0]}`);
  }
}

// Discord to Roblox
const robloxLink = await client.osint.discordToRoblox("123456789012345678");
if (robloxLink.data?.roblox_id) {
  console.log(`Linked Roblox: ${robloxLink.data.roblox_id}`);
}

// Roblox User Info
const roblox = await client.osint.robloxUserinfo({ userId: "123456789" });
// Or by username:
const roblox2 = await client.osint.robloxUserinfo({ username: "PlayerName" });
console.log(`Username: ${roblox.data?.username}`);
console.log(`Display Name: ${roblox.data?.['Display Name']}`);

// Holehe - Email account detection
const holehe = await client.osint.holehe("[email protected]");
console.log(`Found on ${holehe.data?.domains?.length || 0} services:`);
for (const domain of holehe.data?.domains || []) {
  console.log(`  ${domain}`);
}

// GHunt - Google account lookup
const ghunt = await client.osint.ghunt("[email protected]");
if (ghunt.data?.found) {
  console.log(`Name: ${ghunt.data.profile?.name}`);
}

// Subdomain extraction
const subdomains = await client.osint.extractSubdomain("example.com", true);
for (const sub of subdomains.data?.subdomains || []) {
  console.log(sub);
}

// Minecraft username history
const mc = await client.osint.minecraftHistory("PlayerName");
for (const entry of mc.data?.history || []) {
  console.log(`${entry.username} - ${entry.changed_at}`);
}

Utility Service

// Database name autocomplete
const result = await client.utility.dbnameAutocomplete("link");
for (const name of result || []) {
  console.log(name);  // linkedin_2012, linkedin_2021, etc.
}

Error Handling

import {
  OathNetClient,
  OathNetError,
  AuthenticationError,
  ValidationError,
  NotFoundError,
  RateLimitError,
  QuotaExceededError,
} from 'oathnet';

try {
  const result = await client.search.breach("[email protected]");
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.log("Invalid API key");
  } else if (error instanceof QuotaExceededError) {
    console.log("Daily quota exceeded");
  } else if (error instanceof RateLimitError) {
    console.log(`Rate limited. Retry after ${error.retryAfter}s`);
  } else if (error instanceof NotFoundError) {
    console.log("Resource not found");
  } else if (error instanceof ValidationError) {
    console.log(`Invalid input: ${error.message}`);
  } else if (error instanceof OathNetError) {
    console.log(`API error: ${error.message}`);
  } else {
    throw error;
  }
}

Configuration

import { OathNetClient } from 'oathnet';

const client = new OathNetClient('your-api-key', {
  baseUrl: 'https://oathnet.org/api',
  timeout: 30000       // Request timeout in ms
});