dominusnode-haystack 1.0.0__tar.gz → 1.1.0__tar.gz

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.

Potentially problematic release.


This version of dominusnode-haystack might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 DomiNode
3
+ Copyright (c) 2026 Dominus Node
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,8 +1,8 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: dominusnode-haystack
3
- Version: 1.0.0
4
- Summary: DomiNode rotating proxy tools for Haystack AI pipelines
5
- Author-email: DomiNode <dev@dominusnode.com>
3
+ Version: 1.1.0
4
+ Summary: Dominus Node rotating proxy tools for Haystack AI pipelines
5
+ Author-email: Dominus Node <dev@dominusnode.com>
6
6
  License: MIT
7
7
  Keywords: haystack,proxy,dominusnode,ai,tools
8
8
  Classifier: Development Status :: 4 - Beta
@@ -22,3 +22,4 @@ Requires-Dist: haystack-ai>=2.0.0
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: pytest>=7.0; extra == "dev"
24
24
  Requires-Dist: pytest-mock; extra == "dev"
25
+ Dynamic: license-file
@@ -1,6 +1,6 @@
1
1
  # dominusnode-haystack
2
2
 
3
- DomiNode rotating proxy tools for [Haystack](https://haystack.deepset.ai/) AI pipelines.
3
+ Dominus Node rotating proxy tools for [Haystack](https://haystack.deepset.ai/) AI pipelines.
4
4
 
5
5
  ## Installation
6
6
 
@@ -1,4 +1,4 @@
1
- """DomiNode tools for Haystack pipelines."""
1
+ """Dominus Node tools for Haystack pipelines."""
2
2
  from dominusnode_haystack.tools import DominusNodeToolkit
3
3
 
4
4
  __version__ = "1.0.0"
@@ -1,7 +1,7 @@
1
- """DomiNode Haystack toolkit -- 22 proxy, wallet, team, and PayPal tools.
1
+ """Dominus Node Haystack toolkit -- 26 proxy, wallet, team, and payment tools.
2
2
 
3
- Provides a Haystack-compatible toolkit class that exposes 22 Tool objects for
4
- interacting with the DomiNode rotating proxy-as-a-service platform.
3
+ Provides a Haystack-compatible toolkit class that exposes 26 Tool objects for
4
+ interacting with the Dominus Node rotating proxy-as-a-service platform.
5
5
 
6
6
  Tools cover:
7
7
  - Proxied HTTP fetching through rotating proxies
@@ -9,7 +9,7 @@ Tools cover:
9
9
  - Proxy configuration and session listing
10
10
  - Agentic wallet management (create, fund, freeze, unfreeze, delete)
11
11
  - Team management (create, list, fund, keys, usage, update, role changes)
12
- - PayPal top-up
12
+ - PayPal, Stripe, and crypto top-up
13
13
 
14
14
  Security:
15
15
  - Full SSRF prevention (private IP blocking, DNS rebinding, Teredo/6to4,
@@ -40,6 +40,7 @@ from __future__ import annotations
40
40
 
41
41
  import ipaddress
42
42
  import json
43
+ import math
43
44
  import os
44
45
  import re
45
46
  import socket
@@ -372,7 +373,7 @@ _CREDENTIAL_RE = re.compile(r"dn_(live|test)_[a-zA-Z0-9]+")
372
373
 
373
374
 
374
375
  def _sanitize_error(message: str) -> str:
375
- """Remove DomiNode API key patterns from error messages."""
376
+ """Remove Dominus Node API key patterns from error messages."""
376
377
  return _CREDENTIAL_RE.sub("***", message)
377
378
 
378
379
 
@@ -501,18 +502,18 @@ def _validate_domains(domains: Any) -> Optional[str]:
501
502
 
502
503
 
503
504
  class DominusNodeToolkit:
504
- """Haystack toolkit providing DomiNode rotating proxy tools.
505
+ """Haystack toolkit providing Dominus Node rotating proxy tools.
505
506
 
506
- Authenticates using a DomiNode API key and exposes 22 tools for proxy,
507
+ Authenticates using a Dominus Node API key and exposes 26 tools for proxy,
507
508
  wallet, team, and payment management. All tool methods return dicts
508
509
  suitable for Haystack pipeline consumption.
509
510
 
510
511
  Args:
511
- api_key: DomiNode API key (``dn_live_...`` or ``dn_test_...``).
512
+ api_key: Dominus Node API key (``dn_live_...`` or ``dn_test_...``).
512
513
  Falls back to ``DOMINUSNODE_API_KEY`` environment variable.
513
- base_url: Base URL of the DomiNode REST API.
514
- proxy_host: Hostname of the DomiNode proxy gateway.
515
- proxy_port: Port of the DomiNode proxy gateway.
514
+ base_url: Base URL of the Dominus Node REST API.
515
+ proxy_host: Hostname of the Dominus Node proxy gateway.
516
+ proxy_port: Port of the Dominus Node proxy gateway.
516
517
  timeout: HTTP request timeout in seconds.
517
518
 
518
519
  Example::
@@ -531,12 +532,14 @@ class DominusNodeToolkit:
531
532
  proxy_host: str = "proxy.dominusnode.com",
532
533
  proxy_port: int = 8080,
533
534
  timeout: float = 30.0,
535
+ agent_secret: str | None = None,
534
536
  ):
535
537
  self.api_key = api_key or os.environ.get("DOMINUSNODE_API_KEY", "")
536
538
  self.base_url = base_url.rstrip("/")
537
539
  self.proxy_host = os.environ.get("DOMINUSNODE_PROXY_HOST", proxy_host)
538
540
  self.proxy_port = int(os.environ.get("DOMINUSNODE_PROXY_PORT", str(proxy_port)))
539
541
  self.timeout = timeout
542
+ self.agent_secret: str | None = agent_secret or os.environ.get("DOMINUSNODE_AGENT_SECRET")
540
543
  self._token: str | None = None
541
544
 
542
545
  # ------------------------------------------------------------------
@@ -544,7 +547,7 @@ class DominusNodeToolkit:
544
547
  # ------------------------------------------------------------------
545
548
 
546
549
  def _authenticate(self) -> str:
547
- """Authenticate with the DomiNode API using the API key.
550
+ """Authenticate with the Dominus Node API using the API key.
548
551
 
549
552
  Returns:
550
553
  The JWT bearer token.
@@ -554,7 +557,7 @@ class DominusNodeToolkit:
554
557
  """
555
558
  if not self.api_key:
556
559
  raise RuntimeError(
557
- "DomiNode API key is required. Pass api_key or set "
560
+ "Dominus Node API key is required. Pass api_key or set "
558
561
  "DOMINUSNODE_API_KEY environment variable."
559
562
  )
560
563
 
@@ -562,13 +565,17 @@ class DominusNodeToolkit:
562
565
  timeout=self.timeout,
563
566
  follow_redirects=False,
564
567
  ) as client:
568
+ auth_headers = {
569
+ "User-Agent": "dominusnode-haystack/1.0.0",
570
+ "Content-Type": "application/json",
571
+ }
572
+ if self.agent_secret:
573
+ auth_headers["X-DominusNode-Agent"] = "mcp"
574
+ auth_headers["X-DominusNode-Agent-Secret"] = self.agent_secret
565
575
  resp = client.post(
566
576
  f"{self.base_url}/api/auth/verify-key",
567
577
  json={"apiKey": self.api_key},
568
- headers={
569
- "User-Agent": "dominusnode-haystack/1.0.0",
570
- "Content-Type": "application/json",
571
- },
578
+ headers=auth_headers,
572
579
  )
573
580
 
574
581
  if resp.status_code != 200:
@@ -599,7 +606,7 @@ class DominusNodeToolkit:
599
606
  path: str,
600
607
  body: Optional[Dict[str, Any]] = None,
601
608
  ) -> Any:
602
- """Make an authenticated API request to the DomiNode REST API.
609
+ """Make an authenticated API request to the Dominus Node REST API.
603
610
 
604
611
  Args:
605
612
  method: HTTP method (GET, POST, PATCH, DELETE).
@@ -626,6 +633,9 @@ class DominusNodeToolkit:
626
633
  "Authorization": f"Bearer {self._token}",
627
634
  },
628
635
  }
636
+ if self.agent_secret:
637
+ kwargs["headers"]["X-DominusNode-Agent"] = "mcp"
638
+ kwargs["headers"]["X-DominusNode-Agent-Secret"] = self.agent_secret
629
639
 
630
640
  if body is not None and method.upper() not in ("GET", "HEAD", "OPTIONS"):
631
641
  kwargs["json"] = body
@@ -681,7 +691,7 @@ class DominusNodeToolkit:
681
691
  proxy_type: str = "dc",
682
692
  headers: Dict[str, str] | None = None,
683
693
  ) -> Dict[str, Any]:
684
- """Fetch a URL through the DomiNode rotating proxy network.
694
+ """Fetch a URL through the Dominus Node rotating proxy network.
685
695
 
686
696
  Args:
687
697
  url: Target URL to fetch.
@@ -779,7 +789,7 @@ class DominusNodeToolkit:
779
789
  except Exception as e:
780
790
  return {
781
791
  "error": f"Proxy fetch failed: {_sanitize_error(str(e))}",
782
- "hint": "Ensure the DomiNode proxy gateway is running and accessible.",
792
+ "hint": "Ensure the Dominus Node proxy gateway is running and accessible.",
783
793
  }
784
794
 
785
795
  # ==================================================================
@@ -1404,7 +1414,84 @@ class DominusNodeToolkit:
1404
1414
  return {"error": _sanitize_error(str(e))}
1405
1415
 
1406
1416
  # ==================================================================
1407
- # Tool 24: update_wallet_policy
1417
+ # Tool 24: topup_stripe
1418
+ # ==================================================================
1419
+
1420
+ def topup_stripe(self, amount_cents: int) -> Dict[str, Any]:
1421
+ """Create a Stripe checkout session for wallet top-up.
1422
+
1423
+ Args:
1424
+ amount_cents: Amount to top up in cents (500 to 100,000).
1425
+ Minimum $5.00 (500 cents), maximum $1,000.00 (100,000 cents).
1426
+
1427
+ Returns:
1428
+ Dict with checkout session details for completing
1429
+ the Stripe payment flow.
1430
+ """
1431
+ err = _validate_positive_int(
1432
+ amount_cents, "amount_cents", min_value=500, max_value=100_000
1433
+ )
1434
+ if err:
1435
+ return {"error": err}
1436
+
1437
+ try:
1438
+ result = self._request_with_retry(
1439
+ "POST",
1440
+ "/api/wallet/topup/stripe",
1441
+ {"amountCents": amount_cents},
1442
+ )
1443
+ return result
1444
+ except Exception as e:
1445
+ return {"error": _sanitize_error(str(e))}
1446
+
1447
+ # ==================================================================
1448
+ # Tool 25: topup_crypto
1449
+ # ==================================================================
1450
+
1451
+ _VALID_CRYPTO_CURRENCIES = {
1452
+ "BTC", "ETH", "LTC", "XMR", "ZEC",
1453
+ "USDC", "SOL", "USDT", "DAI", "BNB", "LINK",
1454
+ }
1455
+
1456
+ def topup_crypto(self, amount_usd: float, currency: str) -> Dict[str, Any]:
1457
+ """Create a crypto payment invoice for wallet top-up.
1458
+
1459
+ Args:
1460
+ amount_usd: Amount in USD (5 to 1,000).
1461
+ currency: Cryptocurrency code (BTC/ETH/LTC/XMR/ZEC/USDC/SOL/
1462
+ USDT/DAI/BNB/LINK).
1463
+
1464
+ Returns:
1465
+ Dict with invoice details for completing the crypto payment.
1466
+ """
1467
+ if not isinstance(amount_usd, (int, float)) or isinstance(amount_usd, bool):
1468
+ return {"error": "amount_usd must be a number between 5 and 1,000"}
1469
+ if not math.isfinite(amount_usd):
1470
+ return {"error": "amount_usd must be a number between 5 and 1,000"}
1471
+ if amount_usd < 5 or amount_usd > 1000:
1472
+ return {"error": "amount_usd must be a number between 5 and 1,000"}
1473
+
1474
+ if not currency or not isinstance(currency, str):
1475
+ return {
1476
+ "error": "currency must be one of: BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK",
1477
+ }
1478
+ if currency.upper() not in self._VALID_CRYPTO_CURRENCIES:
1479
+ return {
1480
+ "error": "currency must be one of: BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK",
1481
+ }
1482
+
1483
+ try:
1484
+ result = self._request_with_retry(
1485
+ "POST",
1486
+ "/api/wallet/topup/crypto",
1487
+ {"amountUsd": amount_usd, "currency": currency.lower()},
1488
+ )
1489
+ return result
1490
+ except Exception as e:
1491
+ return {"error": _sanitize_error(str(e))}
1492
+
1493
+ # ==================================================================
1494
+ # Tool 26: update_wallet_policy
1408
1495
  # ==================================================================
1409
1496
 
1410
1497
  def update_wallet_policy(
@@ -1461,7 +1548,7 @@ class DominusNodeToolkit:
1461
1548
  # ==================================================================
1462
1549
 
1463
1550
  def get_tools(self) -> List[Any]:
1464
- """Return list of Haystack Tool objects for all 22 DomiNode functions.
1551
+ """Return list of Haystack Tool objects for all 26 Dominus Node functions.
1465
1552
 
1466
1553
  Each Tool wraps one of the toolkit methods with a name, description,
1467
1554
  and JSON Schema parameter definition compatible with Haystack's
@@ -1476,7 +1563,7 @@ class DominusNodeToolkit:
1476
1563
  Tool(
1477
1564
  name="dominusnode_proxied_fetch",
1478
1565
  description=(
1479
- "Fetch a URL through DomiNode's rotating proxy network. "
1566
+ "Fetch a URL through Dominus Node's rotating proxy network. "
1480
1567
  "Supports geo-targeting and datacenter/residential pool selection. "
1481
1568
  "Only GET, HEAD, OPTIONS methods are allowed."
1482
1569
  ),
@@ -1505,7 +1592,7 @@ class DominusNodeToolkit:
1505
1592
  ),
1506
1593
  Tool(
1507
1594
  name="dominusnode_check_balance",
1508
- description="Check the current DomiNode wallet balance in cents.",
1595
+ description="Check the current Dominus Node wallet balance in cents.",
1509
1596
  function=self.check_balance,
1510
1597
  parameters={
1511
1598
  "type": "object",
@@ -1514,7 +1601,7 @@ class DominusNodeToolkit:
1514
1601
  ),
1515
1602
  Tool(
1516
1603
  name="dominusnode_check_usage",
1517
- description="Check DomiNode proxy usage statistics for a given time period.",
1604
+ description="Check Dominus Node proxy usage statistics for a given time period.",
1518
1605
  function=self.check_usage,
1519
1606
  parameters={
1520
1607
  "type": "object",
@@ -1529,7 +1616,7 @@ class DominusNodeToolkit:
1529
1616
  ),
1530
1617
  Tool(
1531
1618
  name="dominusnode_get_proxy_config",
1532
- description="Get DomiNode proxy configuration including endpoints and geo-targeting options.",
1619
+ description="Get Dominus Node proxy configuration including endpoints and geo-targeting options.",
1533
1620
  function=self.get_proxy_config,
1534
1621
  parameters={
1535
1622
  "type": "object",
@@ -1538,7 +1625,7 @@ class DominusNodeToolkit:
1538
1625
  ),
1539
1626
  Tool(
1540
1627
  name="dominusnode_list_sessions",
1541
- description="List active DomiNode proxy sessions.",
1628
+ description="List active Dominus Node proxy sessions.",
1542
1629
  function=self.list_sessions,
1543
1630
  parameters={
1544
1631
  "type": "object",
@@ -1846,6 +1933,40 @@ class DominusNodeToolkit:
1846
1933
  "required": ["amount_cents"],
1847
1934
  },
1848
1935
  ),
1936
+ Tool(
1937
+ name="dominusnode_topup_stripe",
1938
+ description="Create a Stripe checkout session for wallet top-up. Minimum $5.00 (500 cents).",
1939
+ function=self.topup_stripe,
1940
+ parameters={
1941
+ "type": "object",
1942
+ "properties": {
1943
+ "amount_cents": {
1944
+ "type": "integer",
1945
+ "description": "Amount to top up in cents (500-100,000)",
1946
+ },
1947
+ },
1948
+ "required": ["amount_cents"],
1949
+ },
1950
+ ),
1951
+ Tool(
1952
+ name="dominusnode_topup_crypto",
1953
+ description="Create a crypto payment invoice for wallet top-up. Supports BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK.",
1954
+ function=self.topup_crypto,
1955
+ parameters={
1956
+ "type": "object",
1957
+ "properties": {
1958
+ "amount_usd": {
1959
+ "type": "number",
1960
+ "description": "Amount in USD (5-1,000)",
1961
+ },
1962
+ "currency": {
1963
+ "type": "string",
1964
+ "description": "Crypto currency (BTC/ETH/LTC/XMR/ZEC/USDC/SOL/USDT/DAI/BNB/LINK)",
1965
+ },
1966
+ },
1967
+ "required": ["amount_usd", "currency"],
1968
+ },
1969
+ ),
1849
1970
  Tool(
1850
1971
  name="dominusnode_update_wallet_policy",
1851
1972
  description="Update an agentic wallet's policy (daily limit and/or allowed domains).",
@@ -1,8 +1,8 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: dominusnode-haystack
3
- Version: 1.0.0
4
- Summary: DomiNode rotating proxy tools for Haystack AI pipelines
5
- Author-email: DomiNode <dev@dominusnode.com>
3
+ Version: 1.1.0
4
+ Summary: Dominus Node rotating proxy tools for Haystack AI pipelines
5
+ Author-email: Dominus Node <dev@dominusnode.com>
6
6
  License: MIT
7
7
  Keywords: haystack,proxy,dominusnode,ai,tools
8
8
  Classifier: Development Status :: 4 - Beta
@@ -22,3 +22,4 @@ Requires-Dist: haystack-ai>=2.0.0
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: pytest>=7.0; extra == "dev"
24
24
  Requires-Dist: pytest-mock; extra == "dev"
25
+ Dynamic: license-file
@@ -4,12 +4,12 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dominusnode-haystack"
7
- version = "1.0.0"
8
- description = "DomiNode rotating proxy tools for Haystack AI pipelines"
7
+ version = "1.1.0"
8
+ description = "Dominus Node rotating proxy tools for Haystack AI pipelines"
9
9
  requires-python = ">=3.9"
10
10
  license = {text = "MIT"}
11
11
  authors = [
12
- {name = "DomiNode", email = "dev@dominusnode.com"},
12
+ {name = "Dominus Node", email = "dev@dominusnode.com"},
13
13
  ]
14
14
  keywords = ["haystack", "proxy", "dominusnode", "ai", "tools"]
15
15
  classifiers = [
@@ -1197,7 +1197,7 @@ class TestGetTools:
1197
1197
  try:
1198
1198
  from haystack.tools import Tool
1199
1199
  tools = toolkit.get_tools()
1200
- assert len(tools) == 24
1200
+ assert len(tools) == 26
1201
1201
  names = [t.name for t in tools]
1202
1202
  assert "dominusnode_proxied_fetch" in names
1203
1203
  assert "dominusnode_check_balance" in names