Installation
Copy
npm install oathnet
# Or with yarn
yarn add oathnet
# Or with pnpm
pnpm add oathnet
Quick Start
Copy
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:Copy
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
Copy
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
Breach Search
Copy
// 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
Copy
// 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}`);
V2 Stealer Search
Copy
// 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
Copy
// 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");
File Search
Search within stealer log files using regex or wildcard patterns.Copy
// 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.Copy
// 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
Copy
// 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
Copy
// 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
Copy
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
Copy
import { OathNetClient } from 'oathnet';
const client = new OathNetClient('your-api-key', {
baseUrl: 'https://oathnet.org/api',
timeout: 30000 // Request timeout in ms
});