@dominusnode/flowise-tools 1.0.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/toolkit.js CHANGED
@@ -2,9 +2,10 @@
2
2
  /**
3
3
  * Dominus Node Flowise Toolkit
4
4
  *
5
- * Provides 24 LangChain-compatible DynamicStructuredTool instances for use
5
+ * Provides 53 LangChain-compatible DynamicStructuredTool instances for use
6
6
  * inside Flowise AI workflows. Covers proxied fetching, wallet management,
7
- * agentic wallets, teams, PayPal top-up, and x402 micropayment info.
7
+ * agentic wallets, teams, Stripe/PayPal/crypto top-up, x402 micropayment info,
8
+ * account management, API key management, plans, sessions, and usage analytics.
8
9
  *
9
10
  * Security:
10
11
  * - Full SSRF protection (private IP blocking, DNS rebinding, Teredo/6to4,
@@ -391,6 +392,7 @@ class DominusNodeToolkit {
391
392
  const portVal = Number(options.proxyPort || process.env.DOMINUSNODE_PROXY_PORT || 8080);
392
393
  this.proxyPort = isNaN(portVal) || portVal < 1 || portVal > 65535 ? 8080 : portVal;
393
394
  this.timeout = options.timeout || 30000;
395
+ this.agentSecret = options.agentSecret || process.env.DOMINUSNODE_AGENT_SECRET;
394
396
  }
395
397
  // -----------------------------------------------------------------------
396
398
  // Authentication
@@ -402,12 +404,17 @@ class DominusNodeToolkit {
402
404
  if (!this.apiKey.startsWith("dn_live_") && !this.apiKey.startsWith("dn_test_")) {
403
405
  throw new Error('DOMINUSNODE_API_KEY must start with "dn_live_" or "dn_test_".');
404
406
  }
407
+ const authHeaders = {
408
+ "Content-Type": "application/json",
409
+ "User-Agent": "dominusnode-flowise/1.0.0",
410
+ };
411
+ if (this.agentSecret) {
412
+ authHeaders["X-DominusNode-Agent"] = "mcp";
413
+ authHeaders["X-DominusNode-Agent-Secret"] = this.agentSecret;
414
+ }
405
415
  const res = await fetch(`${this.baseUrl}/api/auth/verify-key`, {
406
416
  method: "POST",
407
- headers: {
408
- "Content-Type": "application/json",
409
- "User-Agent": "dominusnode-flowise/1.0.0",
410
- },
417
+ headers: authHeaders,
411
418
  body: JSON.stringify({ apiKey: this.apiKey }),
412
419
  redirect: "error",
413
420
  signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
@@ -439,6 +446,10 @@ class DominusNodeToolkit {
439
446
  Accept: "application/json",
440
447
  "User-Agent": "dominusnode-flowise/1.0.0",
441
448
  };
449
+ if (this.agentSecret) {
450
+ headers["X-DominusNode-Agent"] = "mcp";
451
+ headers["X-DominusNode-Agent-Secret"] = this.agentSecret;
452
+ }
442
453
  const init = {
443
454
  method,
444
455
  headers,
@@ -511,6 +522,76 @@ class DominusNodeToolkit {
511
522
  }
512
523
  }
513
524
  // -----------------------------------------------------------------------
525
+ // Unauthenticated request helper (register, login, verifyEmail)
526
+ // -----------------------------------------------------------------------
527
+ async _unauthenticatedRequest(method, path, body) {
528
+ const url = `${this.baseUrl}${path}`;
529
+ const headers = {
530
+ "Content-Type": "application/json",
531
+ "User-Agent": "dominusnode-flowise/1.0.0",
532
+ };
533
+ if (this.agentSecret) {
534
+ headers["X-DominusNode-Agent"] = "mcp";
535
+ headers["X-DominusNode-Agent-Secret"] = this.agentSecret;
536
+ }
537
+ const init = {
538
+ method,
539
+ headers,
540
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
541
+ redirect: "error",
542
+ };
543
+ if (body) {
544
+ init.body = JSON.stringify(body);
545
+ }
546
+ let res;
547
+ try {
548
+ res = await fetch(url, init);
549
+ }
550
+ catch (err) {
551
+ throw new Error(`Request failed: ${safeError(err)}`);
552
+ }
553
+ let rawText;
554
+ try {
555
+ rawText = await res.text();
556
+ }
557
+ catch {
558
+ rawText = "";
559
+ }
560
+ if (new TextEncoder().encode(rawText).length > MAX_RESPONSE_BYTES) {
561
+ throw new Error("Response too large");
562
+ }
563
+ if (!res.ok) {
564
+ let errorMsg = `Error ${res.status}`;
565
+ if (rawText) {
566
+ try {
567
+ const parsed = JSON.parse(rawText);
568
+ stripDangerousKeys(parsed);
569
+ if (parsed.error) {
570
+ errorMsg = `Error ${res.status}: ${scrubCredentials(String(parsed.error))}`;
571
+ }
572
+ else if (parsed.message) {
573
+ errorMsg = `Error ${res.status}: ${scrubCredentials(String(parsed.message))}`;
574
+ }
575
+ }
576
+ catch {
577
+ errorMsg = `Error ${res.status}: ${scrubCredentials(rawText.slice(0, 200))}`;
578
+ }
579
+ }
580
+ throw new Error(errorMsg);
581
+ }
582
+ if (!rawText || rawText.trim().length === 0) {
583
+ return {};
584
+ }
585
+ try {
586
+ const parsed = JSON.parse(rawText);
587
+ stripDangerousKeys(parsed);
588
+ return parsed;
589
+ }
590
+ catch {
591
+ throw new Error("Failed to parse response as JSON");
592
+ }
593
+ }
594
+ // -----------------------------------------------------------------------
514
595
  // Tool 1: proxiedFetch
515
596
  // -----------------------------------------------------------------------
516
597
  async proxiedFetch(url, method = "GET", country, proxyType = "dc") {
@@ -1342,7 +1423,57 @@ class DominusNodeToolkit {
1342
1423
  }
1343
1424
  }
1344
1425
  // -----------------------------------------------------------------------
1345
- // Tool 23: x402Info
1426
+ // Tool 23: topupStripe
1427
+ // -----------------------------------------------------------------------
1428
+ async topupStripe(amountCents) {
1429
+ try {
1430
+ if (!Number.isInteger(amountCents) || amountCents < 500 || amountCents > 100000) {
1431
+ return "Error: amount_cents must be an integer between 500 ($5) and 100000 ($1,000).";
1432
+ }
1433
+ const data = await this._requestWithRetry("POST", "/api/wallet/topup/stripe", { amountCents });
1434
+ return [
1435
+ "Stripe Checkout Session Created",
1436
+ "",
1437
+ `Session ID: ${data.sessionId}`,
1438
+ `Amount: ${formatCents(amountCents)}`,
1439
+ `Checkout URL: ${data.url}`,
1440
+ "",
1441
+ "Open the checkout URL in a browser to complete payment.",
1442
+ "Once paid, the funds will be credited to your wallet automatically.",
1443
+ ].join("\n");
1444
+ }
1445
+ catch (err) {
1446
+ return `Error: ${safeError(err)}`;
1447
+ }
1448
+ }
1449
+ async topupCrypto(amountUsd, currency) {
1450
+ try {
1451
+ if (typeof amountUsd !== "number" || !Number.isFinite(amountUsd) || amountUsd < 5 || amountUsd > 1000) {
1452
+ return "Error: amount_usd must be a number between 5 and 1,000.";
1453
+ }
1454
+ const cur = String(currency ?? "").toLowerCase();
1455
+ if (!DominusNodeToolkit.VALID_CRYPTO_CURRENCIES.has(cur)) {
1456
+ return `Error: currency must be one of: ${[...DominusNodeToolkit.VALID_CRYPTO_CURRENCIES].join(", ")}.`;
1457
+ }
1458
+ const data = await this._requestWithRetry("POST", "/api/wallet/topup/crypto", { amountUsd, currency: cur });
1459
+ return [
1460
+ "Crypto Payment Invoice Created",
1461
+ "",
1462
+ `Invoice ID: ${data.invoiceId}`,
1463
+ `Amount: $${amountUsd}`,
1464
+ `Pay: ${data.priceAmount} ${data.payCurrency?.toUpperCase() ?? cur.toUpperCase()}`,
1465
+ `Payment URL: ${data.invoiceUrl}`,
1466
+ "",
1467
+ "Open the payment URL to complete payment.",
1468
+ "Once confirmed on-chain, the funds will be credited to your wallet.",
1469
+ ].join("\n");
1470
+ }
1471
+ catch (err) {
1472
+ return `Error: ${safeError(err)}`;
1473
+ }
1474
+ }
1475
+ // -----------------------------------------------------------------------
1476
+ // Tool 25: x402Info
1346
1477
  // -----------------------------------------------------------------------
1347
1478
  async x402Info() {
1348
1479
  try {
@@ -1354,176 +1485,804 @@ class DominusNodeToolkit {
1354
1485
  }
1355
1486
  }
1356
1487
  // -----------------------------------------------------------------------
1357
- // getTools() -- returns LangChain DynamicStructuredTool[] for Flowise
1488
+ // Tool 26: getProxyStatus
1358
1489
  // -----------------------------------------------------------------------
1359
- getTools() {
1360
- return [
1361
- // 1. proxied_fetch
1362
- new tools_1.DynamicStructuredTool({
1363
- name: "dominusnode_proxied_fetch",
1364
- description: "Fetch a URL through Dominus Node's rotating proxy network. Supports geo-targeting " +
1365
- "by country. Returns status code, headers, and response body (truncated).",
1366
- schema: zod_1.z.object({
1367
- url: zod_1.z.string().describe("The target URL to fetch (http or https)"),
1368
- method: zod_1.z.enum(["GET", "HEAD", "OPTIONS"]).default("GET").describe("HTTP method"),
1369
- country: zod_1.z.string().optional().describe("ISO 3166-1 alpha-2 country code for geo-targeting (e.g., US, GB, DE)"),
1370
- proxyType: zod_1.z.enum(["dc", "residential"]).default("dc").describe("Proxy pool: dc ($3/GB) or residential ($5/GB)"),
1371
- }),
1372
- func: async ({ url, method, country, proxyType }) => {
1373
- return this.proxiedFetch(url, method, country, proxyType);
1374
- },
1375
- }),
1376
- // 2. check_balance
1377
- new tools_1.DynamicStructuredTool({
1378
- name: "dominusnode_check_balance",
1379
- description: "Check your Dominus Node wallet balance and estimated remaining bandwidth at current pricing.",
1380
- schema: zod_1.z.object({}),
1381
- func: async () => {
1382
- return this.checkBalance();
1383
- },
1384
- }),
1385
- // 3. check_usage
1386
- new tools_1.DynamicStructuredTool({
1387
- name: "dominusnode_check_usage",
1388
- description: "View bandwidth usage statistics for a specified time period. Shows total bytes, cost, and request count.",
1389
- schema: zod_1.z.object({
1390
- days: zod_1.z.number().min(1).max(365).default(30).describe("Number of days to look back (1-365)"),
1391
- }),
1392
- func: async ({ days }) => {
1393
- return this.checkUsage(days);
1394
- },
1395
- }),
1396
- // 4. get_proxy_config
1397
- new tools_1.DynamicStructuredTool({
1398
- name: "dominusnode_get_proxy_config",
1399
- description: "Get available proxy pools, pricing, supported countries, and endpoint configuration.",
1400
- schema: zod_1.z.object({}),
1401
- func: async () => {
1402
- return this.getProxyConfig();
1403
- },
1404
- }),
1405
- // 5. list_sessions
1406
- new tools_1.DynamicStructuredTool({
1407
- name: "dominusnode_list_sessions",
1408
- description: "List all active proxy sessions showing target hosts, bandwidth used, and status.",
1409
- schema: zod_1.z.object({}),
1410
- func: async () => {
1411
- return this.listSessions();
1412
- },
1413
- }),
1414
- // 6. create_agentic_wallet
1415
- new tools_1.DynamicStructuredTool({
1416
- name: "dominusnode_create_agentic_wallet",
1417
- description: "Create a server-side custodial agentic wallet for autonomous proxy billing. " +
1418
- "Set a spending limit per transaction for safety. Optionally set a daily budget cap and domain allowlist.",
1419
- schema: zod_1.z.object({
1420
- label: zod_1.z.string().min(1).max(100).describe('Label for this wallet (e.g., "scraper-bot")'),
1421
- spendingLimitCents: zod_1.z
1422
- .number()
1423
- .int()
1424
- .min(0)
1425
- .max(1000000)
1426
- .default(10000)
1427
- .describe("Max spend per transaction in cents (0 = no limit, default $100)"),
1428
- dailyLimitCents: zod_1.z
1429
- .number()
1430
- .int()
1431
- .positive()
1432
- .max(1000000)
1433
- .optional()
1434
- .describe("Optional daily budget cap in cents (max 1,000,000 = $10,000)"),
1435
- allowedDomains: zod_1.z
1436
- .array(zod_1.z.string().max(253))
1437
- .max(100)
1438
- .optional()
1439
- .describe("Optional list of allowed domains for proxy access (max 100 entries)"),
1440
- }),
1441
- func: async ({ label, spendingLimitCents, dailyLimitCents, allowedDomains }) => {
1442
- return this.createAgenticWallet(label, spendingLimitCents, dailyLimitCents, allowedDomains);
1443
- },
1444
- }),
1445
- // 7. fund_agentic_wallet
1446
- new tools_1.DynamicStructuredTool({
1447
- name: "dominusnode_fund_agentic_wallet",
1448
- description: "Transfer funds from your main wallet to an agentic wallet. Min $1, max $10,000.",
1449
- schema: zod_1.z.object({
1450
- walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
1451
- amountCents: zod_1.z.number().int().min(100).max(1000000).describe("Amount in cents to transfer"),
1452
- }),
1453
- func: async ({ walletId, amountCents }) => {
1454
- return this.fundAgenticWallet(walletId, amountCents);
1455
- },
1456
- }),
1457
- // 8. agentic_wallet_balance
1458
- new tools_1.DynamicStructuredTool({
1459
- name: "dominusnode_agentic_wallet_balance",
1460
- description: "Check the balance and details of an agentic wallet.",
1461
- schema: zod_1.z.object({
1462
- walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
1463
- }),
1464
- func: async ({ walletId }) => {
1465
- return this.agenticWalletBalance(walletId);
1466
- },
1467
- }),
1468
- // 9. list_agentic_wallets
1469
- new tools_1.DynamicStructuredTool({
1470
- name: "dominusnode_list_agentic_wallets",
1471
- description: "List all your agentic wallets with balances and status.",
1472
- schema: zod_1.z.object({}),
1473
- func: async () => {
1474
- return this.listAgenticWallets();
1475
- },
1476
- }),
1477
- // 10. agentic_transactions
1478
- new tools_1.DynamicStructuredTool({
1479
- name: "dominusnode_agentic_transactions",
1480
- description: "Get transaction history for an agentic wallet.",
1481
- schema: zod_1.z.object({
1482
- walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
1483
- limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return"),
1484
- }),
1485
- func: async ({ walletId, limit }) => {
1486
- return this.agenticTransactions(walletId, limit);
1487
- },
1488
- }),
1489
- // 11. freeze_agentic_wallet
1490
- new tools_1.DynamicStructuredTool({
1491
- name: "dominusnode_freeze_agentic_wallet",
1492
- description: "Freeze an agentic wallet to prevent spending. Balance is preserved until unfrozen.",
1493
- schema: zod_1.z.object({
1494
- walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
1495
- }),
1496
- func: async ({ walletId }) => {
1497
- return this.freezeAgenticWallet(walletId);
1498
- },
1499
- }),
1500
- // 12. unfreeze_agentic_wallet
1501
- new tools_1.DynamicStructuredTool({
1502
- name: "dominusnode_unfreeze_agentic_wallet",
1503
- description: "Unfreeze a previously frozen agentic wallet to re-enable spending.",
1504
- schema: zod_1.z.object({
1505
- walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
1506
- }),
1507
- func: async ({ walletId }) => {
1508
- return this.unfreezeAgenticWallet(walletId);
1509
- },
1510
- }),
1511
- // 13. delete_agentic_wallet
1512
- new tools_1.DynamicStructuredTool({
1513
- name: "dominusnode_delete_agentic_wallet",
1514
- description: "Delete an agentic wallet. Must be unfrozen first. Remaining balance refunded to main wallet.",
1515
- schema: zod_1.z.object({
1516
- walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
1517
- }),
1518
- func: async ({ walletId }) => {
1519
- return this.deleteAgenticWallet(walletId);
1520
- },
1521
- }),
1522
- // 13b. update_wallet_policy
1523
- new tools_1.DynamicStructuredTool({
1524
- name: "dominusnode_update_wallet_policy",
1525
- description: "Update spending policy for an agentic wallet. Set or remove daily budget caps and domain restrictions.",
1526
- schema: zod_1.z.object({
1490
+ async getProxyStatus() {
1491
+ try {
1492
+ const data = await this._requestWithRetry("GET", "/api/proxy/status");
1493
+ const lines = [
1494
+ "Proxy Status",
1495
+ "",
1496
+ ];
1497
+ if (data.status)
1498
+ lines.push(`Status: ${data.status}`);
1499
+ if (data.uptime !== undefined)
1500
+ lines.push(`Uptime: ${data.uptime}`);
1501
+ if (data.activeConnections !== undefined)
1502
+ lines.push(`Active Connections: ${data.activeConnections}`);
1503
+ if (data.providerStatus)
1504
+ lines.push(`Provider Status: ${JSON.stringify(data.providerStatus)}`);
1505
+ if (Object.keys(data).length === 0) {
1506
+ lines.push("No status data available.");
1507
+ }
1508
+ return truncate(lines.join("\n"));
1509
+ }
1510
+ catch (err) {
1511
+ return `Error: ${safeError(err)}`;
1512
+ }
1513
+ }
1514
+ // -----------------------------------------------------------------------
1515
+ // Tool 27: getTransactions
1516
+ // -----------------------------------------------------------------------
1517
+ async getTransactions(limit = 20) {
1518
+ try {
1519
+ const lim = Math.min(Math.max(Math.floor(limit), 1), 100);
1520
+ const data = await this._requestWithRetry("GET", `/api/wallet/transactions?limit=${lim}`);
1521
+ const txs = data.transactions ?? [];
1522
+ if (txs.length === 0) {
1523
+ return "No wallet transactions found.";
1524
+ }
1525
+ const lines = [`Wallet Transactions (${txs.length})`, ""];
1526
+ for (const tx of txs) {
1527
+ const sign = tx.type === "topup" || tx.type === "fund" || tx.type === "refund" ? "+" : "-";
1528
+ lines.push(` ${sign}${formatCents(tx.amountCents)} [${tx.type}] ${tx.description}`);
1529
+ lines.push(` ${tx.createdAt}`);
1530
+ }
1531
+ return truncate(lines.join("\n"));
1532
+ }
1533
+ catch (err) {
1534
+ return `Error: ${safeError(err)}`;
1535
+ }
1536
+ }
1537
+ // -----------------------------------------------------------------------
1538
+ // Tool 28: getForecast
1539
+ // -----------------------------------------------------------------------
1540
+ async getForecast() {
1541
+ try {
1542
+ const data = await this._requestWithRetry("GET", "/api/wallet/forecast");
1543
+ const lines = [
1544
+ "Wallet Balance Forecast",
1545
+ "",
1546
+ `Current Balance: ${formatCents(data.balanceCents ?? 0)}`,
1547
+ `Average Daily Spend: ${formatCents(data.avgDailySpendCents ?? 0)}`,
1548
+ `Estimated Days Remaining: ${data.daysRemaining ?? "N/A"}`,
1549
+ ];
1550
+ if (data.estimatedDepletionDate) {
1551
+ lines.push(`Estimated Depletion Date: ${data.estimatedDepletionDate}`);
1552
+ }
1553
+ return lines.join("\n");
1554
+ }
1555
+ catch (err) {
1556
+ return `Error: ${safeError(err)}`;
1557
+ }
1558
+ }
1559
+ // -----------------------------------------------------------------------
1560
+ // Tool 29: checkPayment
1561
+ // -----------------------------------------------------------------------
1562
+ async checkPayment(invoiceId) {
1563
+ try {
1564
+ if (!invoiceId || invoiceId.trim().length === 0) {
1565
+ return "Error: invoice_id is required.";
1566
+ }
1567
+ if (/[\x00-\x1f\x7f]/.test(invoiceId)) {
1568
+ return "Error: invoice_id contains invalid control characters.";
1569
+ }
1570
+ const data = await this._requestWithRetry("GET", `/api/wallet/topup/crypto/${encodeURIComponent(invoiceId.trim())}/status`);
1571
+ const lines = [
1572
+ "Crypto Payment Status",
1573
+ "",
1574
+ `Invoice ID: ${data.invoiceId ?? invoiceId}`,
1575
+ `Status: ${data.status ?? "unknown"}`,
1576
+ `Amount: $${data.amountUsd ?? "N/A"}`,
1577
+ `Currency: ${data.payCurrency?.toUpperCase() ?? "N/A"}`,
1578
+ ];
1579
+ if (data.paidAt) {
1580
+ lines.push(`Paid At: ${data.paidAt}`);
1581
+ }
1582
+ return lines.join("\n");
1583
+ }
1584
+ catch (err) {
1585
+ return `Error: ${safeError(err)}`;
1586
+ }
1587
+ }
1588
+ // -----------------------------------------------------------------------
1589
+ // Tool 30: getDailyUsage
1590
+ // -----------------------------------------------------------------------
1591
+ async getDailyUsage(days = 7) {
1592
+ try {
1593
+ const d = Math.min(Math.max(Math.floor(days), 1), 365);
1594
+ const data = await this._requestWithRetry("GET", `/api/usage/daily?days=${d}`);
1595
+ const dayEntries = data.days ?? [];
1596
+ if (dayEntries.length === 0) {
1597
+ return "No daily usage data available.";
1598
+ }
1599
+ const lines = [`Daily Usage (last ${d} days)`, ""];
1600
+ for (const day of dayEntries) {
1601
+ lines.push(` ${day.date}: ${formatBytes(day.bytes)} | ${formatCents(day.costCents)} | ${day.requests} reqs`);
1602
+ }
1603
+ return truncate(lines.join("\n"));
1604
+ }
1605
+ catch (err) {
1606
+ return `Error: ${safeError(err)}`;
1607
+ }
1608
+ }
1609
+ // -----------------------------------------------------------------------
1610
+ // Tool 31: getTopHosts
1611
+ // -----------------------------------------------------------------------
1612
+ async getTopHosts(limit = 10) {
1613
+ try {
1614
+ const lim = Math.min(Math.max(Math.floor(limit), 1), 100);
1615
+ const data = await this._requestWithRetry("GET", `/api/usage/top-hosts?limit=${lim}`);
1616
+ const hosts = data.hosts ?? [];
1617
+ if (hosts.length === 0) {
1618
+ return "No top hosts data available.";
1619
+ }
1620
+ const lines = [`Top Hosts by Bandwidth (${hosts.length})`, ""];
1621
+ for (const h of hosts) {
1622
+ lines.push(` ${h.host}: ${formatBytes(h.bytes)} | ${formatCents(h.costCents)} | ${h.requests} reqs`);
1623
+ }
1624
+ return truncate(lines.join("\n"));
1625
+ }
1626
+ catch (err) {
1627
+ return `Error: ${safeError(err)}`;
1628
+ }
1629
+ }
1630
+ // -----------------------------------------------------------------------
1631
+ // Tool 32: register (unauthenticated)
1632
+ // -----------------------------------------------------------------------
1633
+ async register(email, password) {
1634
+ try {
1635
+ if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
1636
+ return "Error: a valid email address is required.";
1637
+ }
1638
+ if (!password || password.length < 8 || password.length > 128) {
1639
+ return "Error: password must be between 8 and 128 characters.";
1640
+ }
1641
+ const data = await this._unauthenticatedRequest("POST", "/api/auth/register", { email, password });
1642
+ return [
1643
+ "Account Created",
1644
+ "",
1645
+ `User ID: ${data.user?.id ?? "N/A"}`,
1646
+ `Email: ${data.user?.email ?? email}`,
1647
+ "",
1648
+ "Verify your email to unlock financial features.",
1649
+ "MCP agents are auto-verified via agent headers.",
1650
+ ].join("\n");
1651
+ }
1652
+ catch (err) {
1653
+ return `Error: ${safeError(err)}`;
1654
+ }
1655
+ }
1656
+ // -----------------------------------------------------------------------
1657
+ // Tool 33: login (unauthenticated)
1658
+ // -----------------------------------------------------------------------
1659
+ async login(email, password) {
1660
+ try {
1661
+ if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
1662
+ return "Error: a valid email address is required.";
1663
+ }
1664
+ if (!password || password.length < 1) {
1665
+ return "Error: password is required.";
1666
+ }
1667
+ const data = await this._unauthenticatedRequest("POST", "/api/auth/login", { email, password });
1668
+ if (data.mfaRequired) {
1669
+ return [
1670
+ "MFA Required",
1671
+ "",
1672
+ `Challenge Token: ${data.challengeToken ?? "N/A"}`,
1673
+ "",
1674
+ "Multi-factor authentication is required. Complete the MFA challenge to proceed.",
1675
+ ].join("\n");
1676
+ }
1677
+ return [
1678
+ "Login Successful",
1679
+ "",
1680
+ "Access and refresh tokens have been issued.",
1681
+ "Use get_account_info to view your account details.",
1682
+ ].join("\n");
1683
+ }
1684
+ catch (err) {
1685
+ return `Error: ${safeError(err)}`;
1686
+ }
1687
+ }
1688
+ // -----------------------------------------------------------------------
1689
+ // Tool 34: getAccountInfo
1690
+ // -----------------------------------------------------------------------
1691
+ async getAccountInfo() {
1692
+ try {
1693
+ const data = await this._requestWithRetry("GET", "/api/auth/me");
1694
+ const user = data.user;
1695
+ return [
1696
+ "Account Information",
1697
+ "",
1698
+ `User ID: ${user?.id ?? "N/A"}`,
1699
+ `Email: ${user?.email ?? "N/A"}`,
1700
+ `Plan: ${user?.plan ?? "N/A"}`,
1701
+ `Email Verified: ${user?.emailVerified ?? false}`,
1702
+ `Status: ${user?.status ?? "N/A"}`,
1703
+ `Created: ${user?.createdAt ?? "N/A"}`,
1704
+ ].join("\n");
1705
+ }
1706
+ catch (err) {
1707
+ return `Error: ${safeError(err)}`;
1708
+ }
1709
+ }
1710
+ // -----------------------------------------------------------------------
1711
+ // Tool 35: verifyEmail (unauthenticated)
1712
+ // -----------------------------------------------------------------------
1713
+ async verifyEmail(token) {
1714
+ try {
1715
+ if (!token || token.trim().length === 0) {
1716
+ return "Error: verification token is required.";
1717
+ }
1718
+ if (/[\x00-\x1f\x7f]/.test(token)) {
1719
+ return "Error: token contains invalid control characters.";
1720
+ }
1721
+ await this._unauthenticatedRequest("POST", "/api/auth/verify-email", {
1722
+ token: token.trim(),
1723
+ });
1724
+ return "Email verified successfully. Financial features are now unlocked.";
1725
+ }
1726
+ catch (err) {
1727
+ return `Error: ${safeError(err)}`;
1728
+ }
1729
+ }
1730
+ // -----------------------------------------------------------------------
1731
+ // Tool 36: resendVerification
1732
+ // -----------------------------------------------------------------------
1733
+ async resendVerification() {
1734
+ try {
1735
+ await this._requestWithRetry("POST", "/api/auth/resend-verification");
1736
+ return "Verification email sent. Check your inbox for the verification link.";
1737
+ }
1738
+ catch (err) {
1739
+ return `Error: ${safeError(err)}`;
1740
+ }
1741
+ }
1742
+ // -----------------------------------------------------------------------
1743
+ // Tool 37: updatePassword
1744
+ // -----------------------------------------------------------------------
1745
+ async updatePassword(currentPassword, newPassword) {
1746
+ try {
1747
+ if (!currentPassword || currentPassword.length < 1) {
1748
+ return "Error: current password is required.";
1749
+ }
1750
+ if (!newPassword || newPassword.length < 8 || newPassword.length > 128) {
1751
+ return "Error: new password must be between 8 and 128 characters.";
1752
+ }
1753
+ await this._requestWithRetry("POST", "/api/auth/change-password", {
1754
+ currentPassword,
1755
+ newPassword,
1756
+ });
1757
+ return "Password updated successfully.";
1758
+ }
1759
+ catch (err) {
1760
+ return `Error: ${safeError(err)}`;
1761
+ }
1762
+ }
1763
+ // -----------------------------------------------------------------------
1764
+ // Tool 38: listKeys
1765
+ // -----------------------------------------------------------------------
1766
+ async listKeys() {
1767
+ try {
1768
+ const data = await this._requestWithRetry("GET", "/api/keys");
1769
+ const keys = data.keys ?? [];
1770
+ if (keys.length === 0) {
1771
+ return "No API keys found. Use create_key to create one.";
1772
+ }
1773
+ const lines = [`API Keys (${keys.length})`, ""];
1774
+ for (const k of keys) {
1775
+ lines.push(` ${k.label ?? "unlabeled"} (${k.id.slice(0, 8)}...)`);
1776
+ lines.push(` Prefix: ${k.prefix} | Created: ${k.createdAt}`);
1777
+ }
1778
+ return truncate(lines.join("\n"));
1779
+ }
1780
+ catch (err) {
1781
+ return `Error: ${safeError(err)}`;
1782
+ }
1783
+ }
1784
+ // -----------------------------------------------------------------------
1785
+ // Tool 39: createKey
1786
+ // -----------------------------------------------------------------------
1787
+ async createKey(label) {
1788
+ try {
1789
+ if (label !== undefined) {
1790
+ if (label.length === 0 || label.length > 100) {
1791
+ return "Error: label must be 1-100 characters.";
1792
+ }
1793
+ if (/[\x00-\x1f\x7f]/.test(label)) {
1794
+ return "Error: label contains invalid control characters.";
1795
+ }
1796
+ }
1797
+ const body = {};
1798
+ if (label)
1799
+ body.label = label.trim();
1800
+ const data = await this._requestWithRetry("POST", "/api/keys", body);
1801
+ return [
1802
+ "API Key Created",
1803
+ "",
1804
+ `Key ID: ${data.id}`,
1805
+ `API Key: ${data.key}`,
1806
+ `Prefix: ${data.prefix}`,
1807
+ `Label: ${data.label ?? ""}`,
1808
+ `Created: ${data.createdAt}`,
1809
+ "",
1810
+ "IMPORTANT: Save this API key now -- it will not be shown again.",
1811
+ ].join("\n");
1812
+ }
1813
+ catch (err) {
1814
+ return `Error: ${safeError(err)}`;
1815
+ }
1816
+ }
1817
+ // -----------------------------------------------------------------------
1818
+ // Tool 40: revokeKey
1819
+ // -----------------------------------------------------------------------
1820
+ async revokeKey(keyId) {
1821
+ try {
1822
+ const kid = validateUuid(keyId, "key_id");
1823
+ await this._requestWithRetry("DELETE", `/api/keys/${encodeURIComponent(kid)}`);
1824
+ return [
1825
+ "API Key Revoked",
1826
+ "",
1827
+ `Key ID: ${kid}`,
1828
+ "",
1829
+ "The key is now permanently deactivated and cannot be used.",
1830
+ ].join("\n");
1831
+ }
1832
+ catch (err) {
1833
+ return `Error: ${safeError(err)}`;
1834
+ }
1835
+ }
1836
+ // -----------------------------------------------------------------------
1837
+ // Tool 41: getPlan
1838
+ // -----------------------------------------------------------------------
1839
+ async getPlan() {
1840
+ try {
1841
+ const data = await this._requestWithRetry("GET", "/api/plans/user/plan");
1842
+ const lines = [
1843
+ "Current Plan",
1844
+ "",
1845
+ `Plan ID: ${data.id ?? "N/A"}`,
1846
+ `Name: ${data.name ?? "N/A"}`,
1847
+ ];
1848
+ if (data.bandwidthLimitBytes !== undefined) {
1849
+ lines.push(`Bandwidth Limit: ${formatBytes(data.bandwidthLimitBytes)}`);
1850
+ }
1851
+ if (data.pricePerGbCents !== undefined) {
1852
+ lines.push(`Price Per GB: ${formatCents(data.pricePerGbCents)}`);
1853
+ }
1854
+ if (data.features && data.features.length > 0) {
1855
+ lines.push(`Features: ${data.features.join(", ")}`);
1856
+ }
1857
+ return lines.join("\n");
1858
+ }
1859
+ catch (err) {
1860
+ return `Error: ${safeError(err)}`;
1861
+ }
1862
+ }
1863
+ // -----------------------------------------------------------------------
1864
+ // Tool 42: listPlans
1865
+ // -----------------------------------------------------------------------
1866
+ async listPlans() {
1867
+ try {
1868
+ const data = await this._requestWithRetry("GET", "/api/plans");
1869
+ const plans = data.plans ?? [];
1870
+ if (plans.length === 0) {
1871
+ return "No plans available.";
1872
+ }
1873
+ const lines = [`Available Plans (${plans.length})`, ""];
1874
+ for (const p of plans) {
1875
+ lines.push(` ${p.name} (${p.id})`);
1876
+ if (p.bandwidthLimitBytes !== undefined) {
1877
+ lines.push(` Bandwidth: ${formatBytes(p.bandwidthLimitBytes)} | Price: ${formatCents(p.pricePerGbCents)}/GB`);
1878
+ }
1879
+ if (p.features && p.features.length > 0) {
1880
+ lines.push(` Features: ${p.features.join(", ")}`);
1881
+ }
1882
+ lines.push("");
1883
+ }
1884
+ return truncate(lines.join("\n"));
1885
+ }
1886
+ catch (err) {
1887
+ return `Error: ${safeError(err)}`;
1888
+ }
1889
+ }
1890
+ // -----------------------------------------------------------------------
1891
+ // Tool 43: changePlan
1892
+ // -----------------------------------------------------------------------
1893
+ async changePlan(planId) {
1894
+ try {
1895
+ if (!planId || planId.trim().length === 0) {
1896
+ return "Error: plan_id is required.";
1897
+ }
1898
+ if (/[\x00-\x1f\x7f]/.test(planId)) {
1899
+ return "Error: plan_id contains invalid control characters.";
1900
+ }
1901
+ const data = await this._requestWithRetry("PUT", "/api/plans/user/plan", { planId: planId.trim() });
1902
+ return [
1903
+ "Plan Changed",
1904
+ "",
1905
+ `New Plan: ${data.name ?? data.id ?? planId}`,
1906
+ data.message ? `Message: ${data.message}` : "",
1907
+ ].filter(Boolean).join("\n");
1908
+ }
1909
+ catch (err) {
1910
+ return `Error: ${safeError(err)}`;
1911
+ }
1912
+ }
1913
+ // -----------------------------------------------------------------------
1914
+ // Tool 44: teamDelete
1915
+ // -----------------------------------------------------------------------
1916
+ async teamDelete(teamId) {
1917
+ try {
1918
+ const tid = validateUuid(teamId, "team_id");
1919
+ await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}`);
1920
+ return [
1921
+ "Team Deleted",
1922
+ "",
1923
+ `Team ID: ${tid}`,
1924
+ "",
1925
+ "The team has been permanently deleted.",
1926
+ ].join("\n");
1927
+ }
1928
+ catch (err) {
1929
+ return `Error: ${safeError(err)}`;
1930
+ }
1931
+ }
1932
+ // -----------------------------------------------------------------------
1933
+ // Tool 45: teamRevokeKey
1934
+ // -----------------------------------------------------------------------
1935
+ async teamRevokeKey(teamId, keyId) {
1936
+ try {
1937
+ const tid = validateUuid(teamId, "team_id");
1938
+ const kid = validateUuid(keyId, "key_id");
1939
+ await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}/keys/${encodeURIComponent(kid)}`);
1940
+ return [
1941
+ "Team API Key Revoked",
1942
+ "",
1943
+ `Team ID: ${tid}`,
1944
+ `Key ID: ${kid}`,
1945
+ "",
1946
+ "The team key is now permanently deactivated.",
1947
+ ].join("\n");
1948
+ }
1949
+ catch (err) {
1950
+ return `Error: ${safeError(err)}`;
1951
+ }
1952
+ }
1953
+ // -----------------------------------------------------------------------
1954
+ // Tool 46: teamListKeys
1955
+ // -----------------------------------------------------------------------
1956
+ async teamListKeys(teamId) {
1957
+ try {
1958
+ const tid = validateUuid(teamId, "team_id");
1959
+ const data = await this._requestWithRetry("GET", `/api/teams/${encodeURIComponent(tid)}/keys`);
1960
+ const keys = data.keys ?? [];
1961
+ if (keys.length === 0) {
1962
+ return "No API keys found for this team. Use team_create_key to create one.";
1963
+ }
1964
+ const lines = [`Team API Keys (${keys.length})`, ""];
1965
+ for (const k of keys) {
1966
+ lines.push(` ${k.label ?? "unlabeled"} (${k.id.slice(0, 8)}...)`);
1967
+ lines.push(` Prefix: ${k.prefix} | Created: ${k.createdAt}`);
1968
+ }
1969
+ return truncate(lines.join("\n"));
1970
+ }
1971
+ catch (err) {
1972
+ return `Error: ${safeError(err)}`;
1973
+ }
1974
+ }
1975
+ // -----------------------------------------------------------------------
1976
+ // Tool 47: teamListMembers
1977
+ // -----------------------------------------------------------------------
1978
+ async teamListMembers(teamId) {
1979
+ try {
1980
+ const tid = validateUuid(teamId, "team_id");
1981
+ const data = await this._requestWithRetry("GET", `/api/teams/${encodeURIComponent(tid)}/members`);
1982
+ const members = data.members ?? [];
1983
+ if (members.length === 0) {
1984
+ return "No members found for this team.";
1985
+ }
1986
+ const lines = [`Team Members (${members.length})`, ""];
1987
+ for (const m of members) {
1988
+ lines.push(` ${m.email} -- ${m.role}`);
1989
+ lines.push(` User ID: ${m.userId} | Joined: ${m.joinedAt}`);
1990
+ }
1991
+ return truncate(lines.join("\n"));
1992
+ }
1993
+ catch (err) {
1994
+ return `Error: ${safeError(err)}`;
1995
+ }
1996
+ }
1997
+ // -----------------------------------------------------------------------
1998
+ // Tool 48: teamAddMember
1999
+ // -----------------------------------------------------------------------
2000
+ async teamAddMember(teamId, email, role) {
2001
+ try {
2002
+ const tid = validateUuid(teamId, "team_id");
2003
+ if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
2004
+ return "Error: a valid email address is required.";
2005
+ }
2006
+ if (role !== undefined && role !== "member" && role !== "admin") {
2007
+ return "Error: role must be 'member' or 'admin'.";
2008
+ }
2009
+ const body = { email };
2010
+ if (role)
2011
+ body.role = role;
2012
+ const data = await this._requestWithRetry("POST", `/api/teams/${encodeURIComponent(tid)}/members`, body);
2013
+ return [
2014
+ "Team Member Added",
2015
+ "",
2016
+ `Team ID: ${tid}`,
2017
+ `Email: ${data.email ?? email}`,
2018
+ `Role: ${data.role ?? role ?? "member"}`,
2019
+ ].join("\n");
2020
+ }
2021
+ catch (err) {
2022
+ return `Error: ${safeError(err)}`;
2023
+ }
2024
+ }
2025
+ // -----------------------------------------------------------------------
2026
+ // Tool 49: teamRemoveMember
2027
+ // -----------------------------------------------------------------------
2028
+ async teamRemoveMember(teamId, userId) {
2029
+ try {
2030
+ const tid = validateUuid(teamId, "team_id");
2031
+ const uid = validateUuid(userId, "user_id");
2032
+ await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}/members/${encodeURIComponent(uid)}`);
2033
+ return [
2034
+ "Team Member Removed",
2035
+ "",
2036
+ `Team ID: ${tid}`,
2037
+ `User ID: ${uid}`,
2038
+ ].join("\n");
2039
+ }
2040
+ catch (err) {
2041
+ return `Error: ${safeError(err)}`;
2042
+ }
2043
+ }
2044
+ // -----------------------------------------------------------------------
2045
+ // Tool 50: teamInviteMember
2046
+ // -----------------------------------------------------------------------
2047
+ async teamInviteMember(teamId, email, role) {
2048
+ try {
2049
+ const tid = validateUuid(teamId, "team_id");
2050
+ if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
2051
+ return "Error: a valid email address is required.";
2052
+ }
2053
+ if (role !== undefined && role !== "member" && role !== "admin") {
2054
+ return "Error: role must be 'member' or 'admin'.";
2055
+ }
2056
+ const body = { email };
2057
+ if (role)
2058
+ body.role = role;
2059
+ const data = await this._requestWithRetry("POST", `/api/teams/${encodeURIComponent(tid)}/invites`, body);
2060
+ return [
2061
+ "Team Invitation Sent",
2062
+ "",
2063
+ `Invite ID: ${data.id ?? "N/A"}`,
2064
+ `Team ID: ${tid}`,
2065
+ `Email: ${data.email ?? email}`,
2066
+ `Role: ${data.role ?? role ?? "member"}`,
2067
+ data.expiresAt ? `Expires: ${data.expiresAt}` : "",
2068
+ ].filter(Boolean).join("\n");
2069
+ }
2070
+ catch (err) {
2071
+ return `Error: ${safeError(err)}`;
2072
+ }
2073
+ }
2074
+ // -----------------------------------------------------------------------
2075
+ // Tool 51: teamListInvites
2076
+ // -----------------------------------------------------------------------
2077
+ async teamListInvites(teamId) {
2078
+ try {
2079
+ const tid = validateUuid(teamId, "team_id");
2080
+ const data = await this._requestWithRetry("GET", `/api/teams/${encodeURIComponent(tid)}/invites`);
2081
+ const invites = data.invites ?? [];
2082
+ if (invites.length === 0) {
2083
+ return "No pending invitations for this team.";
2084
+ }
2085
+ const lines = [`Team Invitations (${invites.length})`, ""];
2086
+ for (const inv of invites) {
2087
+ lines.push(` ${inv.email} -- ${inv.role} [${inv.status}]`);
2088
+ lines.push(` Invite ID: ${inv.id.slice(0, 8)}... | Created: ${inv.createdAt}`);
2089
+ }
2090
+ return truncate(lines.join("\n"));
2091
+ }
2092
+ catch (err) {
2093
+ return `Error: ${safeError(err)}`;
2094
+ }
2095
+ }
2096
+ // -----------------------------------------------------------------------
2097
+ // Tool 52: teamCancelInvite
2098
+ // -----------------------------------------------------------------------
2099
+ async teamCancelInvite(teamId, inviteId) {
2100
+ try {
2101
+ const tid = validateUuid(teamId, "team_id");
2102
+ const iid = validateUuid(inviteId, "invite_id");
2103
+ await this._requestWithRetry("DELETE", `/api/teams/${encodeURIComponent(tid)}/invites/${encodeURIComponent(iid)}`);
2104
+ return [
2105
+ "Team Invitation Cancelled",
2106
+ "",
2107
+ `Team ID: ${tid}`,
2108
+ `Invite ID: ${iid}`,
2109
+ ].join("\n");
2110
+ }
2111
+ catch (err) {
2112
+ return `Error: ${safeError(err)}`;
2113
+ }
2114
+ }
2115
+ // -----------------------------------------------------------------------
2116
+ // getTools() -- returns LangChain DynamicStructuredTool[] for Flowise
2117
+ // -----------------------------------------------------------------------
2118
+ getTools() {
2119
+ return [
2120
+ // 1. proxied_fetch
2121
+ new tools_1.DynamicStructuredTool({
2122
+ name: "dominusnode_proxied_fetch",
2123
+ description: "Fetch a URL through Dominus Node's rotating proxy network. Supports geo-targeting " +
2124
+ "by country. Returns status code, headers, and response body (truncated).",
2125
+ schema: zod_1.z.object({
2126
+ url: zod_1.z.string().describe("The target URL to fetch (http or https)"),
2127
+ method: zod_1.z.enum(["GET", "HEAD", "OPTIONS"]).default("GET").describe("HTTP method"),
2128
+ country: zod_1.z.string().optional().describe("ISO 3166-1 alpha-2 country code for geo-targeting (e.g., US, GB, DE)"),
2129
+ proxyType: zod_1.z.enum(["dc", "residential"]).default("dc").describe("Proxy pool: dc ($3/GB) or residential ($5/GB)"),
2130
+ }),
2131
+ func: async ({ url, method, country, proxyType }) => {
2132
+ return this.proxiedFetch(url, method, country, proxyType);
2133
+ },
2134
+ }),
2135
+ // 2. check_balance
2136
+ new tools_1.DynamicStructuredTool({
2137
+ name: "dominusnode_check_balance",
2138
+ description: "Check your Dominus Node wallet balance and estimated remaining bandwidth at current pricing.",
2139
+ schema: zod_1.z.object({}),
2140
+ func: async () => {
2141
+ return this.checkBalance();
2142
+ },
2143
+ }),
2144
+ // 3. check_usage
2145
+ new tools_1.DynamicStructuredTool({
2146
+ name: "dominusnode_check_usage",
2147
+ description: "View bandwidth usage statistics for a specified time period. Shows total bytes, cost, and request count.",
2148
+ schema: zod_1.z.object({
2149
+ days: zod_1.z.number().min(1).max(365).default(30).describe("Number of days to look back (1-365)"),
2150
+ }),
2151
+ func: async ({ days }) => {
2152
+ return this.checkUsage(days);
2153
+ },
2154
+ }),
2155
+ // 4. get_proxy_config
2156
+ new tools_1.DynamicStructuredTool({
2157
+ name: "dominusnode_get_proxy_config",
2158
+ description: "Get available proxy pools, pricing, supported countries, and endpoint configuration.",
2159
+ schema: zod_1.z.object({}),
2160
+ func: async () => {
2161
+ return this.getProxyConfig();
2162
+ },
2163
+ }),
2164
+ // 5. list_sessions
2165
+ new tools_1.DynamicStructuredTool({
2166
+ name: "dominusnode_list_sessions",
2167
+ description: "List all active proxy sessions showing target hosts, bandwidth used, and status.",
2168
+ schema: zod_1.z.object({}),
2169
+ func: async () => {
2170
+ return this.listSessions();
2171
+ },
2172
+ }),
2173
+ // 6. create_agentic_wallet
2174
+ new tools_1.DynamicStructuredTool({
2175
+ name: "dominusnode_create_agentic_wallet",
2176
+ description: "Create a server-side custodial agentic wallet for autonomous proxy billing. " +
2177
+ "Set a spending limit per transaction for safety. Optionally set a daily budget cap and domain allowlist.",
2178
+ schema: zod_1.z.object({
2179
+ label: zod_1.z.string().min(1).max(100).describe('Label for this wallet (e.g., "scraper-bot")'),
2180
+ spendingLimitCents: zod_1.z
2181
+ .number()
2182
+ .int()
2183
+ .min(0)
2184
+ .max(1000000)
2185
+ .default(10000)
2186
+ .describe("Max spend per transaction in cents (0 = no limit, default $100)"),
2187
+ dailyLimitCents: zod_1.z
2188
+ .number()
2189
+ .int()
2190
+ .positive()
2191
+ .max(1000000)
2192
+ .optional()
2193
+ .describe("Optional daily budget cap in cents (max 1,000,000 = $10,000)"),
2194
+ allowedDomains: zod_1.z
2195
+ .array(zod_1.z.string().max(253))
2196
+ .max(100)
2197
+ .optional()
2198
+ .describe("Optional list of allowed domains for proxy access (max 100 entries)"),
2199
+ }),
2200
+ func: async ({ label, spendingLimitCents, dailyLimitCents, allowedDomains }) => {
2201
+ return this.createAgenticWallet(label, spendingLimitCents, dailyLimitCents, allowedDomains);
2202
+ },
2203
+ }),
2204
+ // 7. fund_agentic_wallet
2205
+ new tools_1.DynamicStructuredTool({
2206
+ name: "dominusnode_fund_agentic_wallet",
2207
+ description: "Transfer funds from your main wallet to an agentic wallet. Min $1, max $10,000.",
2208
+ schema: zod_1.z.object({
2209
+ walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
2210
+ amountCents: zod_1.z.number().int().min(100).max(1000000).describe("Amount in cents to transfer"),
2211
+ }),
2212
+ func: async ({ walletId, amountCents }) => {
2213
+ return this.fundAgenticWallet(walletId, amountCents);
2214
+ },
2215
+ }),
2216
+ // 8. agentic_wallet_balance
2217
+ new tools_1.DynamicStructuredTool({
2218
+ name: "dominusnode_agentic_wallet_balance",
2219
+ description: "Check the balance and details of an agentic wallet.",
2220
+ schema: zod_1.z.object({
2221
+ walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
2222
+ }),
2223
+ func: async ({ walletId }) => {
2224
+ return this.agenticWalletBalance(walletId);
2225
+ },
2226
+ }),
2227
+ // 9. list_agentic_wallets
2228
+ new tools_1.DynamicStructuredTool({
2229
+ name: "dominusnode_list_agentic_wallets",
2230
+ description: "List all your agentic wallets with balances and status.",
2231
+ schema: zod_1.z.object({}),
2232
+ func: async () => {
2233
+ return this.listAgenticWallets();
2234
+ },
2235
+ }),
2236
+ // 10. agentic_transactions
2237
+ new tools_1.DynamicStructuredTool({
2238
+ name: "dominusnode_agentic_transactions",
2239
+ description: "Get transaction history for an agentic wallet.",
2240
+ schema: zod_1.z.object({
2241
+ walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
2242
+ limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return"),
2243
+ }),
2244
+ func: async ({ walletId, limit }) => {
2245
+ return this.agenticTransactions(walletId, limit);
2246
+ },
2247
+ }),
2248
+ // 11. freeze_agentic_wallet
2249
+ new tools_1.DynamicStructuredTool({
2250
+ name: "dominusnode_freeze_agentic_wallet",
2251
+ description: "Freeze an agentic wallet to prevent spending. Balance is preserved until unfrozen.",
2252
+ schema: zod_1.z.object({
2253
+ walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
2254
+ }),
2255
+ func: async ({ walletId }) => {
2256
+ return this.freezeAgenticWallet(walletId);
2257
+ },
2258
+ }),
2259
+ // 12. unfreeze_agentic_wallet
2260
+ new tools_1.DynamicStructuredTool({
2261
+ name: "dominusnode_unfreeze_agentic_wallet",
2262
+ description: "Unfreeze a previously frozen agentic wallet to re-enable spending.",
2263
+ schema: zod_1.z.object({
2264
+ walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
2265
+ }),
2266
+ func: async ({ walletId }) => {
2267
+ return this.unfreezeAgenticWallet(walletId);
2268
+ },
2269
+ }),
2270
+ // 13. delete_agentic_wallet
2271
+ new tools_1.DynamicStructuredTool({
2272
+ name: "dominusnode_delete_agentic_wallet",
2273
+ description: "Delete an agentic wallet. Must be unfrozen first. Remaining balance refunded to main wallet.",
2274
+ schema: zod_1.z.object({
2275
+ walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
2276
+ }),
2277
+ func: async ({ walletId }) => {
2278
+ return this.deleteAgenticWallet(walletId);
2279
+ },
2280
+ }),
2281
+ // 13b. update_wallet_policy
2282
+ new tools_1.DynamicStructuredTool({
2283
+ name: "dominusnode_update_wallet_policy",
2284
+ description: "Update spending policy for an agentic wallet. Set or remove daily budget caps and domain restrictions.",
2285
+ schema: zod_1.z.object({
1527
2286
  walletId: zod_1.z.string().uuid().describe("Agentic wallet ID (UUID)"),
1528
2287
  dailyLimitCents: zod_1.z
1529
2288
  .number()
@@ -1651,7 +2410,34 @@ class DominusNodeToolkit {
1651
2410
  return this.topupPaypal(amountCents);
1652
2411
  },
1653
2412
  }),
1654
- // 24. x402_info
2413
+ // 23. topup_stripe
2414
+ new tools_1.DynamicStructuredTool({
2415
+ name: "dominusnode_topup_stripe",
2416
+ description: "Top up your Dominus Node wallet via Stripe. Creates a Stripe checkout session and returns " +
2417
+ "a checkout URL. Minimum $5 (500 cents), maximum $1,000 (100000 cents).",
2418
+ schema: zod_1.z.object({
2419
+ amountCents: zod_1.z.number().int().min(500).max(100000).describe("Amount in cents to top up (min 500 = $5)"),
2420
+ }),
2421
+ func: async ({ amountCents }) => {
2422
+ return this.topupStripe(amountCents);
2423
+ },
2424
+ }),
2425
+ // 24. topup_crypto
2426
+ new tools_1.DynamicStructuredTool({
2427
+ name: "dominusnode_topup_crypto",
2428
+ description: "Top up your Dominus Node wallet via cryptocurrency. Creates a crypto payment invoice. " +
2429
+ "Supports BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK. " +
2430
+ "Minimum $5, maximum $1,000.",
2431
+ schema: zod_1.z.object({
2432
+ amountUsd: zod_1.z.number().min(5).max(1000).describe("Amount in USD to top up (5-1000)"),
2433
+ currency: zod_1.z.enum(["btc", "eth", "ltc", "xmr", "zec", "usdc", "sol", "usdt", "dai", "bnb", "link"])
2434
+ .describe("Cryptocurrency to pay with"),
2435
+ }),
2436
+ func: async ({ amountUsd, currency }) => {
2437
+ return this.topupCrypto(amountUsd, currency);
2438
+ },
2439
+ }),
2440
+ // 25. x402_info
1655
2441
  new tools_1.DynamicStructuredTool({
1656
2442
  name: "dominusnode_x402_info",
1657
2443
  description: "Get x402 micropayment protocol information including supported facilitators, " +
@@ -1661,8 +2447,310 @@ class DominusNodeToolkit {
1661
2447
  return this.x402Info();
1662
2448
  },
1663
2449
  }),
2450
+ // 26. get_proxy_status
2451
+ new tools_1.DynamicStructuredTool({
2452
+ name: "dominusnode_get_proxy_status",
2453
+ description: "Get proxy health and status information including uptime, active connections, and provider status.",
2454
+ schema: zod_1.z.object({}),
2455
+ func: async () => {
2456
+ return this.getProxyStatus();
2457
+ },
2458
+ }),
2459
+ // 27. get_transactions
2460
+ new tools_1.DynamicStructuredTool({
2461
+ name: "dominusnode_get_transactions",
2462
+ description: "Get wallet transaction history including top-ups, usage charges, and refunds.",
2463
+ schema: zod_1.z.object({
2464
+ limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return (1-100)"),
2465
+ }),
2466
+ func: async ({ limit }) => {
2467
+ return this.getTransactions(limit);
2468
+ },
2469
+ }),
2470
+ // 28. get_forecast
2471
+ new tools_1.DynamicStructuredTool({
2472
+ name: "dominusnode_get_forecast",
2473
+ description: "Get a wallet balance forecast based on recent usage patterns. Shows estimated days until balance depletion.",
2474
+ schema: zod_1.z.object({}),
2475
+ func: async () => {
2476
+ return this.getForecast();
2477
+ },
2478
+ }),
2479
+ // 29. check_payment
2480
+ new tools_1.DynamicStructuredTool({
2481
+ name: "dominusnode_check_payment",
2482
+ description: "Check the status of a cryptocurrency payment invoice. Use after creating a crypto top-up.",
2483
+ schema: zod_1.z.object({
2484
+ invoiceId: zod_1.z.string().min(1).describe("The invoice ID from the crypto top-up creation"),
2485
+ }),
2486
+ func: async ({ invoiceId }) => {
2487
+ return this.checkPayment(invoiceId);
2488
+ },
2489
+ }),
2490
+ // 30. get_daily_usage
2491
+ new tools_1.DynamicStructuredTool({
2492
+ name: "dominusnode_get_daily_usage",
2493
+ description: "Get daily usage breakdown showing bandwidth, cost, and request count per day.",
2494
+ schema: zod_1.z.object({
2495
+ days: zod_1.z.number().int().min(1).max(365).default(7).describe("Number of days to look back (1-365)"),
2496
+ }),
2497
+ func: async ({ days }) => {
2498
+ return this.getDailyUsage(days);
2499
+ },
2500
+ }),
2501
+ // 31. get_top_hosts
2502
+ new tools_1.DynamicStructuredTool({
2503
+ name: "dominusnode_get_top_hosts",
2504
+ description: "Get the top accessed hosts ranked by bandwidth usage. Useful for understanding proxy usage patterns.",
2505
+ schema: zod_1.z.object({
2506
+ limit: zod_1.z.number().int().min(1).max(100).default(10).describe("Number of top hosts to return (1-100)"),
2507
+ }),
2508
+ func: async ({ limit }) => {
2509
+ return this.getTopHosts(limit);
2510
+ },
2511
+ }),
2512
+ // 32. register
2513
+ new tools_1.DynamicStructuredTool({
2514
+ name: "dominusnode_register",
2515
+ description: "Register a new Dominus Node account. Returns user info. " +
2516
+ "After registering, verify email or rely on MCP agent auto-verification.",
2517
+ schema: zod_1.z.object({
2518
+ email: zod_1.z.string().email().describe("Email address for the new account"),
2519
+ password: zod_1.z.string().min(8).max(128).describe("Password (min 8, max 128 characters)"),
2520
+ }),
2521
+ func: async ({ email, password }) => {
2522
+ return this.register(email, password);
2523
+ },
2524
+ }),
2525
+ // 33. login
2526
+ new tools_1.DynamicStructuredTool({
2527
+ name: "dominusnode_login",
2528
+ description: "Log into an existing Dominus Node account. Returns login status. " +
2529
+ "Detects MFA requirements and surfaces challenge tokens.",
2530
+ schema: zod_1.z.object({
2531
+ email: zod_1.z.string().email().describe("Account email address"),
2532
+ password: zod_1.z.string().min(1).describe("Account password"),
2533
+ }),
2534
+ func: async ({ email, password }) => {
2535
+ return this.login(email, password);
2536
+ },
2537
+ }),
2538
+ // 34. get_account_info
2539
+ new tools_1.DynamicStructuredTool({
2540
+ name: "dominusnode_get_account_info",
2541
+ description: "Get the current authenticated account information including email, plan, verification status, and creation date.",
2542
+ schema: zod_1.z.object({}),
2543
+ func: async () => {
2544
+ return this.getAccountInfo();
2545
+ },
2546
+ }),
2547
+ // 35. verify_email
2548
+ new tools_1.DynamicStructuredTool({
2549
+ name: "dominusnode_verify_email",
2550
+ description: "Verify email address using the verification token sent to email. " +
2551
+ "MCP agents are auto-verified via agent headers.",
2552
+ schema: zod_1.z.object({
2553
+ token: zod_1.z.string().min(1).describe("Email verification token from the verification email"),
2554
+ }),
2555
+ func: async ({ token }) => {
2556
+ return this.verifyEmail(token);
2557
+ },
2558
+ }),
2559
+ // 36. resend_verification
2560
+ new tools_1.DynamicStructuredTool({
2561
+ name: "dominusnode_resend_verification",
2562
+ description: "Resend the email verification token to the account's email address.",
2563
+ schema: zod_1.z.object({}),
2564
+ func: async () => {
2565
+ return this.resendVerification();
2566
+ },
2567
+ }),
2568
+ // 37. update_password
2569
+ new tools_1.DynamicStructuredTool({
2570
+ name: "dominusnode_update_password",
2571
+ description: "Change the password for the current Dominus Node account. Requires the current password.",
2572
+ schema: zod_1.z.object({
2573
+ currentPassword: zod_1.z.string().min(1).describe("Current account password"),
2574
+ newPassword: zod_1.z.string().min(8).max(128).describe("New password (min 8, max 128 characters)"),
2575
+ }),
2576
+ func: async ({ currentPassword, newPassword }) => {
2577
+ return this.updatePassword(currentPassword, newPassword);
2578
+ },
2579
+ }),
2580
+ // 38. list_keys
2581
+ new tools_1.DynamicStructuredTool({
2582
+ name: "dominusnode_list_keys",
2583
+ description: "List all API keys for the current account. Shows key ID, label, prefix, and creation date.",
2584
+ schema: zod_1.z.object({}),
2585
+ func: async () => {
2586
+ return this.listKeys();
2587
+ },
2588
+ }),
2589
+ // 39. create_key
2590
+ new tools_1.DynamicStructuredTool({
2591
+ name: "dominusnode_create_key",
2592
+ description: "Create a new API key for the current account. The key is shown only once on creation.",
2593
+ schema: zod_1.z.object({
2594
+ label: zod_1.z.string().min(1).max(100).optional().describe('Optional label for the API key (e.g., "production")'),
2595
+ }),
2596
+ func: async ({ label }) => {
2597
+ return this.createKey(label);
2598
+ },
2599
+ }),
2600
+ // 40. revoke_key
2601
+ new tools_1.DynamicStructuredTool({
2602
+ name: "dominusnode_revoke_key",
2603
+ description: "Revoke (permanently delete) an API key. The key will immediately stop working.",
2604
+ schema: zod_1.z.object({
2605
+ keyId: zod_1.z.string().uuid().describe("UUID of the API key to revoke"),
2606
+ }),
2607
+ func: async ({ keyId }) => {
2608
+ return this.revokeKey(keyId);
2609
+ },
2610
+ }),
2611
+ // 41. get_plan
2612
+ new tools_1.DynamicStructuredTool({
2613
+ name: "dominusnode_get_plan",
2614
+ description: "Get the current user's plan details including bandwidth limits, pricing tier, and features.",
2615
+ schema: zod_1.z.object({}),
2616
+ func: async () => {
2617
+ return this.getPlan();
2618
+ },
2619
+ }),
2620
+ // 42. list_plans
2621
+ new tools_1.DynamicStructuredTool({
2622
+ name: "dominusnode_list_plans",
2623
+ description: "List all available Dominus Node plans with pricing, bandwidth limits, and features.",
2624
+ schema: zod_1.z.object({}),
2625
+ func: async () => {
2626
+ return this.listPlans();
2627
+ },
2628
+ }),
2629
+ // 43. change_plan
2630
+ new tools_1.DynamicStructuredTool({
2631
+ name: "dominusnode_change_plan",
2632
+ description: "Change the current user's plan. Provide the plan ID of the desired plan from list_plans.",
2633
+ schema: zod_1.z.object({
2634
+ planId: zod_1.z.string().min(1).describe("ID of the plan to switch to"),
2635
+ }),
2636
+ func: async ({ planId }) => {
2637
+ return this.changePlan(planId);
2638
+ },
2639
+ }),
2640
+ // 44. team_delete
2641
+ new tools_1.DynamicStructuredTool({
2642
+ name: "dominusnode_team_delete",
2643
+ description: "Delete a team permanently. Requires owner role. All team keys are revoked and members removed.",
2644
+ schema: zod_1.z.object({
2645
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID) to delete"),
2646
+ }),
2647
+ func: async ({ teamId }) => {
2648
+ return this.teamDelete(teamId);
2649
+ },
2650
+ }),
2651
+ // 45. team_revoke_key
2652
+ new tools_1.DynamicStructuredTool({
2653
+ name: "dominusnode_team_revoke_key",
2654
+ description: "Revoke (delete) a team API key. Requires owner or admin role.",
2655
+ schema: zod_1.z.object({
2656
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2657
+ keyId: zod_1.z.string().uuid().describe("UUID of the team key to revoke"),
2658
+ }),
2659
+ func: async ({ teamId, keyId }) => {
2660
+ return this.teamRevokeKey(teamId, keyId);
2661
+ },
2662
+ }),
2663
+ // 46. team_list_keys
2664
+ new tools_1.DynamicStructuredTool({
2665
+ name: "dominusnode_team_list_keys",
2666
+ description: "List all API keys for a team. Shows key ID, label, prefix, and creation date.",
2667
+ schema: zod_1.z.object({
2668
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2669
+ }),
2670
+ func: async ({ teamId }) => {
2671
+ return this.teamListKeys(teamId);
2672
+ },
2673
+ }),
2674
+ // 47. team_list_members
2675
+ new tools_1.DynamicStructuredTool({
2676
+ name: "dominusnode_team_list_members",
2677
+ description: "List all members of a team with their roles and join dates.",
2678
+ schema: zod_1.z.object({
2679
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2680
+ }),
2681
+ func: async ({ teamId }) => {
2682
+ return this.teamListMembers(teamId);
2683
+ },
2684
+ }),
2685
+ // 48. team_add_member
2686
+ new tools_1.DynamicStructuredTool({
2687
+ name: "dominusnode_team_add_member",
2688
+ description: "Add a member to a team by email address. Optionally specify their role (member or admin).",
2689
+ schema: zod_1.z.object({
2690
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2691
+ email: zod_1.z.string().email().describe("Email address of the user to add"),
2692
+ role: zod_1.z.enum(["member", "admin"]).optional().describe("Role for the new member (default: member)"),
2693
+ }),
2694
+ func: async ({ teamId, email, role }) => {
2695
+ return this.teamAddMember(teamId, email, role);
2696
+ },
2697
+ }),
2698
+ // 49. team_remove_member
2699
+ new tools_1.DynamicStructuredTool({
2700
+ name: "dominusnode_team_remove_member",
2701
+ description: "Remove a member from a team. Requires owner or admin role. Cannot remove the owner.",
2702
+ schema: zod_1.z.object({
2703
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2704
+ userId: zod_1.z.string().uuid().describe("User ID (UUID) of the member to remove"),
2705
+ }),
2706
+ func: async ({ teamId, userId }) => {
2707
+ return this.teamRemoveMember(teamId, userId);
2708
+ },
2709
+ }),
2710
+ // 50. team_invite_member
2711
+ new tools_1.DynamicStructuredTool({
2712
+ name: "dominusnode_team_invite_member",
2713
+ description: "Send a team invitation to an email address. Invited users can accept to join the team.",
2714
+ schema: zod_1.z.object({
2715
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2716
+ email: zod_1.z.string().email().describe("Email address to invite"),
2717
+ role: zod_1.z.enum(["member", "admin"]).optional().describe("Role for the invited member (default: member)"),
2718
+ }),
2719
+ func: async ({ teamId, email, role }) => {
2720
+ return this.teamInviteMember(teamId, email, role);
2721
+ },
2722
+ }),
2723
+ // 51. team_list_invites
2724
+ new tools_1.DynamicStructuredTool({
2725
+ name: "dominusnode_team_list_invites",
2726
+ description: "List all pending invitations for a team. Shows invite ID, email, role, and status.",
2727
+ schema: zod_1.z.object({
2728
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2729
+ }),
2730
+ func: async ({ teamId }) => {
2731
+ return this.teamListInvites(teamId);
2732
+ },
2733
+ }),
2734
+ // 52. team_cancel_invite
2735
+ new tools_1.DynamicStructuredTool({
2736
+ name: "dominusnode_team_cancel_invite",
2737
+ description: "Cancel a pending team invitation. Requires owner or admin role.",
2738
+ schema: zod_1.z.object({
2739
+ teamId: zod_1.z.string().uuid().describe("Team ID (UUID)"),
2740
+ inviteId: zod_1.z.string().uuid().describe("UUID of the invitation to cancel"),
2741
+ }),
2742
+ func: async ({ teamId, inviteId }) => {
2743
+ return this.teamCancelInvite(teamId, inviteId);
2744
+ },
2745
+ }),
1664
2746
  ];
1665
2747
  }
1666
2748
  }
1667
2749
  exports.DominusNodeToolkit = DominusNodeToolkit;
2750
+ // -----------------------------------------------------------------------
2751
+ // Tool 24: topupCrypto
2752
+ // -----------------------------------------------------------------------
2753
+ DominusNodeToolkit.VALID_CRYPTO_CURRENCIES = new Set([
2754
+ "btc", "eth", "ltc", "xmr", "zec", "usdc", "sol", "usdt", "dai", "bnb", "link",
2755
+ ]);
1668
2756
  //# sourceMappingURL=toolkit.js.map