@dominusnode/mastra-tools 1.3.1 → 1.5.2

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/CHANGELOG.md CHANGED
@@ -3,12 +3,14 @@
3
3
  ## 1.1.0
4
4
 
5
5
  ### Added
6
+
6
7
  - Stripe checkout top-up tool (`dominusnode_topup_stripe`) — create Stripe Checkout sessions ($5–$1,000)
7
8
  - Crypto top-up tool (`dominusnode_topup_crypto`) — NOWPayments invoices for BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK ($5–$1,000)
8
9
  - `dominusnode_update_wallet_policy` tool — update daily limits and domain allowlists for agentic wallets
9
10
  - Comprehensive test suite: 167 tests covering SSRF protection (incl. DNS rebinding), input validation, credential scrubbing, payment response fields, and all 26 tools
10
11
 
11
12
  ### Fixed
13
+
12
14
  - `topupCrypto`: use `Number.isFinite()` instead of `isNaN()` to correctly reject `NaN` and `Infinity` inputs
13
15
 
14
16
  ## 1.0.1
package/README.md CHANGED
@@ -28,16 +28,17 @@ const balance = await toolkit.checkBalance();
28
28
 
29
29
  ## Configuration
30
30
 
31
- | Environment Variable | Description | Default |
32
- |---|---|---|
33
- | `DOMINUSNODE_API_KEY` | API key (required) | -- |
34
- | `DOMINUSNODE_BASE_URL` | REST API base URL | `https://api.dominusnode.com` |
35
- | `DOMINUSNODE_PROXY_HOST` | Proxy gateway host | `proxy.dominusnode.com` |
36
- | `DOMINUSNODE_PROXY_PORT` | Proxy gateway port | `8080` |
31
+ | Environment Variable | Description | Default |
32
+ | ------------------------ | ------------------ | ----------------------------- |
33
+ | `DOMINUSNODE_API_KEY` | API key (required) | -- |
34
+ | `DOMINUSNODE_BASE_URL` | REST API base URL | `https://api.dominusnode.com` |
35
+ | `DOMINUSNODE_PROXY_HOST` | Proxy gateway host | `proxy.dominusnode.com` |
36
+ | `DOMINUSNODE_PROXY_PORT` | Proxy gateway port | `8080` |
37
37
 
38
38
  ## Available Tools (26)
39
39
 
40
40
  ### Proxy Operations
41
+
41
42
  - `dominusnode_proxied_fetch` - Fetch a URL through the rotating proxy with geo-targeting
42
43
  - `dominusnode_check_balance` - Check wallet balance and remaining bandwidth
43
44
  - `dominusnode_check_usage` - View bandwidth usage statistics
@@ -45,6 +46,7 @@ const balance = await toolkit.checkBalance();
45
46
  - `dominusnode_list_sessions` - List active proxy sessions
46
47
 
47
48
  ### Agentic Wallet Management
49
+
48
50
  - `dominusnode_create_agentic_wallet` - Create a custodial sub-wallet
49
51
  - `dominusnode_fund_agentic_wallet` - Transfer funds to an agentic wallet
50
52
  - `dominusnode_agentic_wallet_balance` - Check agentic wallet balance
@@ -56,6 +58,7 @@ const balance = await toolkit.checkBalance();
56
58
  - `dominusnode_update_wallet_policy` - Update daily limits and domain restrictions
57
59
 
58
60
  ### Team Management
61
+
59
62
  - `dominusnode_create_team` - Create a team with shared wallet
60
63
  - `dominusnode_list_teams` - List all teams
61
64
  - `dominusnode_team_details` - Get team details
@@ -66,6 +69,7 @@ const balance = await toolkit.checkBalance();
66
69
  - `dominusnode_update_team_member_role` - Change a member's role
67
70
 
68
71
  ### Payments
72
+
69
73
  - `dominusnode_topup_paypal` - Top up wallet via PayPal ($5–$1,000)
70
74
  - `dominusnode_topup_stripe` - Top up wallet via Stripe ($5–$1,000)
71
75
  - `dominusnode_topup_crypto` - Top up wallet via crypto (BTC/ETH/LTC/XMR/ZEC/USDC/SOL/USDT/DAI/BNB/LINK)
package/dist/toolkit.d.ts CHANGED
@@ -69,6 +69,8 @@ export declare class DominusNodeToolkit {
69
69
  private cachedJwt;
70
70
  private jwtExpiresAt;
71
71
  constructor(config?: DominusNodeToolkitConfig);
72
+ private static countLeadingZeroBits;
73
+ private solvePoW;
72
74
  private getApiKey;
73
75
  private ensureAuth;
74
76
  private apiRequest;
@@ -157,6 +159,10 @@ export declare class DominusNodeToolkit {
157
159
  teamInviteMember(teamId: string, email: string, role?: string): Promise<Record<string, unknown>>;
158
160
  teamListInvites(teamId: string): Promise<Record<string, unknown>>;
159
161
  teamCancelInvite(teamId: string, inviteId: string): Promise<Record<string, unknown>>;
162
+ mppInfo(): Promise<Record<string, unknown>>;
163
+ payMpp(amountCents: number, method: string): Promise<Record<string, unknown>>;
164
+ mppSessionOpen(maxDepositCents: number, method: string, poolType?: string): Promise<Record<string, unknown>>;
165
+ mppSessionClose(channelId: string): Promise<Record<string, unknown>>;
160
166
  getTools(): (import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).Tool<{
161
167
  context: any;
162
168
  }, {
@@ -417,5 +423,23 @@ export declare class DominusNodeToolkit {
417
423
  }, {
418
424
  error?: string | undefined;
419
425
  data?: unknown;
420
- }, unknown, unknown, import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).ToolExecutionContext<unknown, unknown, unknown>, "dominusnode_team_cancel_invite", unknown>)[];
426
+ }, unknown, unknown, import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).ToolExecutionContext<unknown, unknown, unknown>, "dominusnode_team_cancel_invite", unknown> | import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).Tool<unknown, {
427
+ error?: string | undefined;
428
+ data?: unknown;
429
+ }, unknown, unknown, import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).ToolExecutionContext<unknown, unknown, unknown>, "dominusnode_mpp_info", unknown> | import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).Tool<{
430
+ context: any;
431
+ }, {
432
+ error?: string | undefined;
433
+ data?: unknown;
434
+ }, unknown, unknown, import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).ToolExecutionContext<unknown, unknown, unknown>, "dominusnode_pay_mpp", unknown> | import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).Tool<{
435
+ context: any;
436
+ }, {
437
+ error?: string | undefined;
438
+ data?: unknown;
439
+ }, unknown, unknown, import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).ToolExecutionContext<unknown, unknown, unknown>, "dominusnode_mpp_session_open", unknown> | import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).Tool<{
440
+ context: any;
441
+ }, {
442
+ error?: string | undefined;
443
+ data?: unknown;
444
+ }, unknown, unknown, import("@mastra/core/tools", { with: { "resolution-mode": "import" } }).ToolExecutionContext<unknown, unknown, unknown>, "dominusnode_mpp_session_close", unknown>)[];
421
445
  }
package/dist/toolkit.js CHANGED
@@ -66,6 +66,7 @@ exports.formatCents = formatCents;
66
66
  // @ts-ignore -- available when installed in Mastra project
67
67
  const tools_1 = require("@mastra/core/tools");
68
68
  const zod_1 = require("zod");
69
+ const crypto = __importStar(require("node:crypto"));
69
70
  const http = __importStar(require("node:http"));
70
71
  const tls = __importStar(require("node:tls"));
71
72
  const dns = __importStar(require("dns/promises"));
@@ -86,7 +87,7 @@ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/
86
87
  // ---------------------------------------------------------------------------
87
88
  /** Remove any dn_live_* or dn_test_* tokens from error messages. */
88
89
  function scrubCredentials(msg) {
89
- return msg.replace(/dn_(live|test)_[A-Za-z0-9_-]+/g, "dn_$1_***REDACTED***");
90
+ return msg.replace(/dn_(live|test|proxy)_[A-Za-z0-9_-]+/g, "dn_$1_***REDACTED***");
90
91
  }
91
92
  function safeError(err) {
92
93
  const raw = err instanceof Error ? err.message : String(err);
@@ -98,7 +99,8 @@ function safeError(err) {
98
99
  function truncate(text, max = MAX_RESPONSE_CHARS) {
99
100
  if (text.length <= max)
100
101
  return text;
101
- return text.slice(0, max) + `\n\n... [truncated, ${text.length - max} chars omitted]`;
102
+ return (text.slice(0, max) +
103
+ `\n\n... [truncated, ${text.length - max} chars omitted]`);
102
104
  }
103
105
  // ---------------------------------------------------------------------------
104
106
  // SSRF Protection
@@ -389,18 +391,80 @@ class DominusNodeToolkit {
389
391
  jwtExpiresAt = 0;
390
392
  constructor(config = {}) {
391
393
  this.apiKey = config.apiKey || process.env.DOMINUSNODE_API_KEY || "";
392
- this.baseUrl = (config.baseUrl || process.env.DOMINUSNODE_BASE_URL || "https://api.dominusnode.com").replace(/\/+$/, "");
393
- this.proxyHost = config.proxyHost || process.env.DOMINUSNODE_PROXY_HOST || "proxy.dominusnode.com";
394
- const portStr = config.proxyPort?.toString() || process.env.DOMINUSNODE_PROXY_PORT || "8080";
394
+ this.baseUrl = (config.baseUrl ||
395
+ process.env.DOMINUSNODE_BASE_URL ||
396
+ "https://api.dominusnode.com").replace(/\/+$/, "");
397
+ this.proxyHost =
398
+ config.proxyHost ||
399
+ process.env.DOMINUSNODE_PROXY_HOST ||
400
+ "proxy.dominusnode.com";
401
+ const portStr = config.proxyPort?.toString() ||
402
+ process.env.DOMINUSNODE_PROXY_PORT ||
403
+ "8080";
395
404
  const port = parseInt(portStr, 10);
396
405
  this.proxyPort = isNaN(port) || port < 1 || port > 65535 ? 8080 : port;
397
- this.agentSecret = config.agentSecret || process.env.DOMINUSNODE_AGENT_SECRET;
406
+ this.agentSecret =
407
+ config.agentSecret || process.env.DOMINUSNODE_AGENT_SECRET;
408
+ }
409
+ // -----------------------------------------------------------------------
410
+ // SHA-256 Proof-of-Work solver
411
+ // -----------------------------------------------------------------------
412
+ static countLeadingZeroBits(buf) {
413
+ let count = 0;
414
+ for (const byte of buf) {
415
+ if (byte === 0) {
416
+ count += 8;
417
+ continue;
418
+ }
419
+ let mask = 0x80;
420
+ while (mask && !(byte & mask)) {
421
+ count++;
422
+ mask >>= 1;
423
+ }
424
+ break;
425
+ }
426
+ return count;
427
+ }
428
+ async solvePoW() {
429
+ try {
430
+ const resp = await fetch(`${this.baseUrl}/api/auth/pow/challenge`, {
431
+ method: "POST",
432
+ headers: { "Content-Type": "application/json" },
433
+ redirect: "error",
434
+ });
435
+ if (!resp.ok)
436
+ return null;
437
+ const text = await resp.text();
438
+ if (text.length > 10_485_760)
439
+ return null;
440
+ const challenge = JSON.parse(text);
441
+ const prefix = challenge.prefix ?? "";
442
+ const difficulty = challenge.difficulty ?? 20;
443
+ const challengeId = challenge.challengeId ?? "";
444
+ if (!prefix || !challengeId)
445
+ return null;
446
+ for (let nonce = 0; nonce < 100_000_000; nonce++) {
447
+ const hash = crypto
448
+ .createHash("sha256")
449
+ .update(prefix + nonce.toString())
450
+ .digest();
451
+ if (DominusNodeToolkit.countLeadingZeroBits(hash) >= difficulty) {
452
+ return { challengeId, nonce: nonce.toString() };
453
+ }
454
+ }
455
+ return null;
456
+ }
457
+ catch {
458
+ return null;
459
+ }
398
460
  }
399
461
  // -----------------------------------------------------------------------
400
462
  // Authentication
401
463
  // -----------------------------------------------------------------------
402
464
  getApiKey() {
403
- if (!this.apiKey || typeof this.apiKey !== "string" || this.apiKey.trim().length === 0) {
465
+ if (!this.apiKey ||
466
+ typeof this.apiKey !== "string" ||
467
+ this.apiKey.trim().length === 0) {
404
468
  throw new Error("DOMINUSNODE_API_KEY is required. " +
405
469
  'Set it to your Dominus Node API key (starts with "dn_live_" or "dn_test_").');
406
470
  }
@@ -609,7 +673,15 @@ class DominusNodeToolkit {
609
673
  const ALLOWED_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
610
674
  const methodUpper = method.toUpperCase();
611
675
  if (!ALLOWED_METHODS.has(methodUpper)) {
612
- return { status: 0, headers: {}, body: "", bytes: 0, pool: proxyType, country: country ?? "auto", error: `HTTP method "${methodUpper}" is not allowed. Only GET, HEAD, and OPTIONS are permitted.` };
676
+ return {
677
+ status: 0,
678
+ headers: {},
679
+ body: "",
680
+ bytes: 0,
681
+ pool: proxyType,
682
+ country: country ?? "auto",
683
+ error: `HTTP method "${methodUpper}" is not allowed. Only GET, HEAD, and OPTIONS are permitted.`,
684
+ };
613
685
  }
614
686
  const apiKey = this.getApiKey();
615
687
  const parts = [];
@@ -624,13 +696,18 @@ class DominusNodeToolkit {
624
696
  const result = await new Promise((resolve, reject) => {
625
697
  const timer = setTimeout(() => reject(new Error("Proxy request timed out")), REQUEST_TIMEOUT_MS);
626
698
  if (parsed.protocol === "https:") {
627
- const connectHost = parsed.hostname.includes(":") ? `[${parsed.hostname}]` : parsed.hostname;
699
+ const connectHost = parsed.hostname.includes(":")
700
+ ? `[${parsed.hostname}]`
701
+ : parsed.hostname;
628
702
  const connectReq = http.request({
629
703
  hostname: this.proxyHost,
630
704
  port: this.proxyPort,
631
705
  method: "CONNECT",
632
706
  path: `${connectHost}:${parsed.port || 443}`,
633
- headers: { "Proxy-Authorization": proxyAuth, Host: `${connectHost}:${parsed.port || 443}` },
707
+ headers: {
708
+ "Proxy-Authorization": proxyAuth,
709
+ Host: `${connectHost}:${parsed.port || 443}`,
710
+ },
634
711
  });
635
712
  connectReq.on("connect", (_res, sock) => {
636
713
  if (_res.statusCode !== 200) {
@@ -639,7 +716,12 @@ class DominusNodeToolkit {
639
716
  reject(new Error(`CONNECT failed: ${_res.statusCode}`));
640
717
  return;
641
718
  }
642
- const tlsSock = tls.connect({ host: parsed.hostname, socket: sock, servername: parsed.hostname, minVersion: "TLSv1.2" }, () => {
719
+ const tlsSock = tls.connect({
720
+ host: parsed.hostname,
721
+ socket: sock,
722
+ servername: parsed.hostname,
723
+ minVersion: "TLSv1.2",
724
+ }, () => {
643
725
  const reqLine = `${methodUpper} ${parsed.pathname + parsed.search} HTTP/1.1\r\nHost: ${parsed.host}\r\nUser-Agent: dominusnode-mastra/1.0.0\r\nConnection: close\r\n\r\n`;
644
726
  tlsSock.write(reqLine);
645
727
  const chunks = [];
@@ -664,22 +746,40 @@ class DominusNodeToolkit {
664
746
  const hdr = raw.substring(0, hEnd);
665
747
  const body = raw.substring(hEnd + 4).substring(0, MAX_RESP);
666
748
  const bodyBytes = new TextEncoder().encode(body).length;
667
- const sm = hdr.split("\r\n")[0].match(/^HTTP\/\d\.\d\s+(\d+)/);
749
+ const sm = hdr
750
+ .split("\r\n")[0]
751
+ .match(/^HTTP\/\d\.\d\s+(\d+)/);
668
752
  const hdrs = {};
669
753
  for (const l of hdr.split("\r\n").slice(1)) {
670
754
  const ci = l.indexOf(":");
671
755
  if (ci > 0)
672
- hdrs[l.substring(0, ci).trim().toLowerCase()] = l.substring(ci + 1).trim();
756
+ hdrs[l.substring(0, ci).trim().toLowerCase()] = l
757
+ .substring(ci + 1)
758
+ .trim();
673
759
  }
674
- resolve({ status: sm ? parseInt(sm[1], 10) : 0, headers: hdrs, body, bytes: bodyBytes });
760
+ resolve({
761
+ status: sm ? parseInt(sm[1], 10) : 0,
762
+ headers: hdrs,
763
+ body,
764
+ bytes: bodyBytes,
765
+ });
675
766
  };
676
767
  tlsSock.on("end", fin);
677
768
  tlsSock.on("close", fin);
678
- tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
769
+ tlsSock.on("error", (e) => {
770
+ clearTimeout(timer);
771
+ reject(e);
772
+ });
773
+ });
774
+ tlsSock.on("error", (e) => {
775
+ clearTimeout(timer);
776
+ reject(e);
679
777
  });
680
- tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
681
778
  });
682
- connectReq.on("error", (e) => { clearTimeout(timer); reject(e); });
779
+ connectReq.on("error", (e) => {
780
+ clearTimeout(timer);
781
+ reject(e);
782
+ });
683
783
  connectReq.end();
684
784
  }
685
785
  else {
@@ -688,7 +788,10 @@ class DominusNodeToolkit {
688
788
  port: this.proxyPort,
689
789
  method: methodUpper,
690
790
  path: url,
691
- headers: { "Proxy-Authorization": proxyAuth, Host: parsed.host ?? "" },
791
+ headers: {
792
+ "Proxy-Authorization": proxyAuth,
793
+ Host: parsed.host ?? "",
794
+ },
692
795
  }, (res) => {
693
796
  const chunks = [];
694
797
  let bytes = 0;
@@ -703,20 +806,33 @@ class DominusNodeToolkit {
703
806
  return;
704
807
  done = true;
705
808
  clearTimeout(timer);
706
- const body = Buffer.concat(chunks).toString("utf-8").substring(0, MAX_RESP);
809
+ const body = Buffer.concat(chunks)
810
+ .toString("utf-8")
811
+ .substring(0, MAX_RESP);
707
812
  const bodyBytes = new TextEncoder().encode(body).length;
708
813
  const hdrs = {};
709
814
  for (const [k, v] of Object.entries(res.headers)) {
710
815
  if (v)
711
816
  hdrs[k] = Array.isArray(v) ? v.join(", ") : v;
712
817
  }
713
- resolve({ status: res.statusCode ?? 0, headers: hdrs, body, bytes: bodyBytes });
818
+ resolve({
819
+ status: res.statusCode ?? 0,
820
+ headers: hdrs,
821
+ body,
822
+ bytes: bodyBytes,
823
+ });
714
824
  };
715
825
  res.on("end", fin);
716
826
  res.on("close", fin);
717
- res.on("error", (e) => { clearTimeout(timer); reject(e); });
827
+ res.on("error", (e) => {
828
+ clearTimeout(timer);
829
+ reject(e);
830
+ });
831
+ });
832
+ req.on("error", (e) => {
833
+ clearTimeout(timer);
834
+ reject(e);
718
835
  });
719
- req.on("error", (e) => { clearTimeout(timer); reject(e); });
720
836
  req.end();
721
837
  }
722
838
  });
@@ -773,9 +889,14 @@ class DominusNodeToolkit {
773
889
  throw new Error("label contains invalid control characters.");
774
890
  }
775
891
  const safeLimitCents = Math.min(Math.max(spendingLimitCents, 0), 1000000);
776
- const body = { label, spendingLimitCents: safeLimitCents };
892
+ const body = {
893
+ label,
894
+ spendingLimitCents: safeLimitCents,
895
+ };
777
896
  if (dailyLimitCents !== undefined && dailyLimitCents !== null) {
778
- if (!Number.isInteger(dailyLimitCents) || dailyLimitCents < 1 || dailyLimitCents > 1000000) {
897
+ if (!Number.isInteger(dailyLimitCents) ||
898
+ dailyLimitCents < 1 ||
899
+ dailyLimitCents > 1000000) {
779
900
  throw new Error("daily_limit_cents must be an integer between 1 and 1,000,000.");
780
901
  }
781
902
  body.dailyLimitCents = dailyLimitCents;
@@ -801,7 +922,9 @@ class DominusNodeToolkit {
801
922
  body.dailyLimitCents = null;
802
923
  }
803
924
  else {
804
- if (!Number.isInteger(dailyLimitCents) || dailyLimitCents < 1 || dailyLimitCents > 1000000) {
925
+ if (!Number.isInteger(dailyLimitCents) ||
926
+ dailyLimitCents < 1 ||
927
+ dailyLimitCents > 1000000) {
805
928
  throw new Error("daily_limit_cents must be an integer between 1 and 1,000,000, or null to remove.");
806
929
  }
807
930
  body.dailyLimitCents = dailyLimitCents;
@@ -830,7 +953,9 @@ class DominusNodeToolkit {
830
953
  }
831
954
  async fundAgenticWallet(walletId, amountCents) {
832
955
  validateUuid(walletId, "wallet_id");
833
- if (!Number.isInteger(amountCents) || amountCents < 100 || amountCents > 1000000) {
956
+ if (!Number.isInteger(amountCents) ||
957
+ amountCents < 100 ||
958
+ amountCents > 1000000) {
834
959
  throw new Error("amount_cents must be an integer between 100 ($1) and 1000000 ($10,000).");
835
960
  }
836
961
  return this.apiPost(`/api/agent-wallet/${encodeURIComponent(walletId)}/fund`, { amountCents });
@@ -884,7 +1009,9 @@ class DominusNodeToolkit {
884
1009
  }
885
1010
  async teamFund(teamId, amountCents) {
886
1011
  validateUuid(teamId, "team_id");
887
- if (!Number.isInteger(amountCents) || amountCents < 100 || amountCents > 1000000) {
1012
+ if (!Number.isInteger(amountCents) ||
1013
+ amountCents < 100 ||
1014
+ amountCents > 1000000) {
888
1015
  throw new Error("amount_cents must be an integer between 100 ($1) and 1000000 ($10,000).");
889
1016
  }
890
1017
  return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/wallet/fund`, { amountCents });
@@ -897,7 +1024,9 @@ class DominusNodeToolkit {
897
1024
  if (/[\x00-\x1f\x7f]/.test(label)) {
898
1025
  throw new Error("label contains invalid control characters.");
899
1026
  }
900
- return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/keys`, { label });
1027
+ return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/keys`, {
1028
+ label,
1029
+ });
901
1030
  }
902
1031
  async teamUsage(teamId, limit = 20) {
903
1032
  validateUuid(teamId, "team_id");
@@ -937,29 +1066,49 @@ class DominusNodeToolkit {
937
1066
  return this.apiPatch(`/api/teams/${encodeURIComponent(teamId)}/members/${encodeURIComponent(userId)}`, { role });
938
1067
  }
939
1068
  async topupPaypal(amountCents) {
940
- if (!Number.isInteger(amountCents) || amountCents < 500 || amountCents > 100000) {
1069
+ if (!Number.isInteger(amountCents) ||
1070
+ amountCents < 500 ||
1071
+ amountCents > 100000) {
941
1072
  throw new Error("amount_cents must be an integer between 500 ($5) and 100000 ($1,000).");
942
1073
  }
943
1074
  return this.apiPost("/api/wallet/topup/paypal", { amountCents });
944
1075
  }
945
1076
  async topupStripe(amountCents) {
946
- if (!Number.isInteger(amountCents) || amountCents < 500 || amountCents > 100000) {
1077
+ if (!Number.isInteger(amountCents) ||
1078
+ amountCents < 500 ||
1079
+ amountCents > 100000) {
947
1080
  throw new Error("amount_cents must be an integer between 500 ($5) and 100000 ($1,000).");
948
1081
  }
949
1082
  return this.apiPost("/api/wallet/topup/stripe", { amountCents });
950
1083
  }
951
1084
  static VALID_CRYPTO_CURRENCIES = new Set([
952
- "btc", "eth", "ltc", "xmr", "zec", "usdc", "sol", "usdt", "dai", "bnb", "link",
1085
+ "btc",
1086
+ "eth",
1087
+ "ltc",
1088
+ "xmr",
1089
+ "zec",
1090
+ "usdc",
1091
+ "sol",
1092
+ "usdt",
1093
+ "dai",
1094
+ "bnb",
1095
+ "link",
953
1096
  ]);
954
1097
  async topupCrypto(amountUsd, currency) {
955
- if (typeof amountUsd !== "number" || !Number.isFinite(amountUsd) || amountUsd < 5 || amountUsd > 1000) {
1098
+ if (typeof amountUsd !== "number" ||
1099
+ !Number.isFinite(amountUsd) ||
1100
+ amountUsd < 5 ||
1101
+ amountUsd > 1000) {
956
1102
  throw new Error("amount_usd must be a number between 5 and 1,000.");
957
1103
  }
958
1104
  const cur = String(currency ?? "").toLowerCase();
959
1105
  if (!DominusNodeToolkit.VALID_CRYPTO_CURRENCIES.has(cur)) {
960
1106
  throw new Error(`currency must be one of: ${[...DominusNodeToolkit.VALID_CRYPTO_CURRENCIES].join(", ")}.`);
961
1107
  }
962
- return this.apiPost("/api/wallet/topup/crypto", { amountUsd, currency: cur });
1108
+ return this.apiPost("/api/wallet/topup/crypto", {
1109
+ amountUsd,
1110
+ currency: cur,
1111
+ });
963
1112
  }
964
1113
  async x402Info() {
965
1114
  return this.apiGet("/api/x402/info");
@@ -1013,12 +1162,23 @@ class DominusNodeToolkit {
1013
1162
  async register(email, password) {
1014
1163
  const safeEmail = DominusNodeToolkit.validateEmail(email);
1015
1164
  const safePassword = DominusNodeToolkit.validatePassword(password);
1016
- return this.rawRequest("POST", "/api/auth/register", { email: safeEmail, password: safePassword });
1165
+ // Solve PoW for CAPTCHA-free registration
1166
+ const pow = await this.solvePoW();
1167
+ const body = {
1168
+ email: safeEmail,
1169
+ password: safePassword,
1170
+ };
1171
+ if (pow)
1172
+ body.pow = pow;
1173
+ return this.rawRequest("POST", "/api/auth/register", body);
1017
1174
  }
1018
1175
  async login(email, password) {
1019
1176
  const safeEmail = DominusNodeToolkit.validateEmail(email);
1020
1177
  const safePassword = DominusNodeToolkit.validatePassword(password);
1021
- return this.rawRequest("POST", "/api/auth/login", { email: safeEmail, password: safePassword });
1178
+ return this.rawRequest("POST", "/api/auth/login", {
1179
+ email: safeEmail,
1180
+ password: safePassword,
1181
+ });
1022
1182
  }
1023
1183
  async getAccountInfo() {
1024
1184
  return this.apiGet("/api/auth/me");
@@ -1030,7 +1190,9 @@ class DominusNodeToolkit {
1030
1190
  if (/[\x00-\x1f\x7f]/.test(token)) {
1031
1191
  throw new Error("Token contains invalid control characters.");
1032
1192
  }
1033
- return this.rawRequest("POST", "/api/auth/verify-email", { token: token.trim() });
1193
+ return this.rawRequest("POST", "/api/auth/verify-email", {
1194
+ token: token.trim(),
1195
+ });
1034
1196
  }
1035
1197
  async resendVerification() {
1036
1198
  return this.apiPost("/api/auth/resend-verification");
@@ -1095,7 +1257,10 @@ class DominusNodeToolkit {
1095
1257
  if (role !== "member" && role !== "admin") {
1096
1258
  throw new Error("role must be 'member' or 'admin'.");
1097
1259
  }
1098
- return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/members`, { userId, role });
1260
+ return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/members`, {
1261
+ userId,
1262
+ role,
1263
+ });
1099
1264
  }
1100
1265
  async teamRemoveMember(teamId, userId) {
1101
1266
  validateUuid(teamId, "team_id");
@@ -1108,7 +1273,10 @@ class DominusNodeToolkit {
1108
1273
  if (role !== "member" && role !== "admin") {
1109
1274
  throw new Error("role must be 'member' or 'admin'.");
1110
1275
  }
1111
- return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/invites`, { email: safeEmail, role });
1276
+ return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/invites`, {
1277
+ email: safeEmail,
1278
+ role,
1279
+ });
1112
1280
  }
1113
1281
  async teamListInvites(teamId) {
1114
1282
  validateUuid(teamId, "team_id");
@@ -1120,7 +1288,47 @@ class DominusNodeToolkit {
1120
1288
  return this.apiDelete(`/api/teams/${encodeURIComponent(teamId)}/invites/${encodeURIComponent(inviteId)}`);
1121
1289
  }
1122
1290
  // -----------------------------------------------------------------------
1123
- // getTools() -- returns Mastra createTool() instances for all 53 tools
1291
+ // MPP (Machine Payment Protocol) methods
1292
+ // -----------------------------------------------------------------------
1293
+ async mppInfo() {
1294
+ return this.apiGet("/api/mpp/info");
1295
+ }
1296
+ async payMpp(amountCents, method) {
1297
+ if (!Number.isInteger(amountCents) ||
1298
+ amountCents < 500 ||
1299
+ amountCents > 100_000) {
1300
+ throw new Error("amount_cents must be an integer between 500 and 100,000");
1301
+ }
1302
+ if (!["tempo", "stripe_spt", "lightning"].includes(method)) {
1303
+ throw new Error("method must be one of: tempo, stripe_spt, lightning");
1304
+ }
1305
+ return this.apiPost("/api/mpp/topup", { amountCents, method });
1306
+ }
1307
+ async mppSessionOpen(maxDepositCents, method, poolType = "dc") {
1308
+ if (!Number.isInteger(maxDepositCents) ||
1309
+ maxDepositCents < 500 ||
1310
+ maxDepositCents > 100_000) {
1311
+ throw new Error("max_deposit_cents must be an integer between 500 and 100,000");
1312
+ }
1313
+ if (!["tempo", "stripe_spt", "lightning"].includes(method)) {
1314
+ throw new Error("method must be one of: tempo, stripe_spt, lightning");
1315
+ }
1316
+ if (!["dc", "residential"].includes(poolType)) {
1317
+ throw new Error("pool_type must be dc or residential");
1318
+ }
1319
+ return this.apiPost("/api/mpp/session/open", {
1320
+ maxDepositCents,
1321
+ method,
1322
+ poolType,
1323
+ });
1324
+ }
1325
+ async mppSessionClose(channelId) {
1326
+ if (!channelId)
1327
+ throw new Error("channel_id is required");
1328
+ return this.apiPost("/api/mpp/session/close", { channelId });
1329
+ }
1330
+ // -----------------------------------------------------------------------
1331
+ // getTools() -- returns Mastra createTool() instances for all 57 tools
1124
1332
  // -----------------------------------------------------------------------
1125
1333
  getTools() {
1126
1334
  return [
@@ -1132,9 +1340,18 @@ class DominusNodeToolkit {
1132
1340
  "Only GET, HEAD, and OPTIONS methods are allowed.",
1133
1341
  inputSchema: zod_1.z.object({
1134
1342
  url: zod_1.z.string().describe("Target URL to fetch (http or https)"),
1135
- method: zod_1.z.enum(["GET", "HEAD", "OPTIONS"]).default("GET").describe("HTTP method"),
1136
- country: zod_1.z.string().optional().describe("ISO 3166-1 alpha-2 country code for geo-targeting (e.g., US, GB, DE)"),
1137
- proxyType: zod_1.z.enum(["dc", "residential"]).default("dc").describe("Proxy pool type: dc (datacenter, $3/GB) or residential ($5/GB)"),
1343
+ method: zod_1.z
1344
+ .enum(["GET", "HEAD", "OPTIONS"])
1345
+ .default("GET")
1346
+ .describe("HTTP method"),
1347
+ country: zod_1.z
1348
+ .string()
1349
+ .optional()
1350
+ .describe("ISO 3166-1 alpha-2 country code for geo-targeting (e.g., US, GB, DE)"),
1351
+ proxyType: zod_1.z
1352
+ .enum(["dc", "residential"])
1353
+ .default("dc")
1354
+ .describe("Proxy pool type: dc (datacenter, $3/GB) or residential ($5/GB)"),
1138
1355
  }),
1139
1356
  outputSchema: zod_1.z.object({
1140
1357
  status: zod_1.z.number(),
@@ -1167,7 +1384,13 @@ class DominusNodeToolkit {
1167
1384
  return await this.checkBalance();
1168
1385
  }
1169
1386
  catch (err) {
1170
- return { balanceCents: 0, balanceUsd: 0, dcGbRemaining: "0", resGbRemaining: "0", error: safeError(err) };
1387
+ return {
1388
+ balanceCents: 0,
1389
+ balanceUsd: 0,
1390
+ dcGbRemaining: "0",
1391
+ resGbRemaining: "0",
1392
+ error: safeError(err),
1393
+ };
1171
1394
  }
1172
1395
  },
1173
1396
  }),
@@ -1177,7 +1400,12 @@ class DominusNodeToolkit {
1177
1400
  description: "View bandwidth usage statistics for a specified time period. " +
1178
1401
  "Shows total bytes transferred, total cost, and request count.",
1179
1402
  inputSchema: zod_1.z.object({
1180
- days: zod_1.z.number().min(1).max(365).default(30).describe("Number of days to look back (1-365)"),
1403
+ days: zod_1.z
1404
+ .number()
1405
+ .min(1)
1406
+ .max(365)
1407
+ .default(30)
1408
+ .describe("Number of days to look back (1-365)"),
1181
1409
  }),
1182
1410
  outputSchema: zod_1.z.object({
1183
1411
  totalBytes: zod_1.z.number(),
@@ -1191,7 +1419,13 @@ class DominusNodeToolkit {
1191
1419
  return await this.checkUsage(context.days);
1192
1420
  }
1193
1421
  catch (err) {
1194
- return { totalBytes: 0, totalCostUsd: 0, requestCount: 0, period: `${context.days} days`, error: safeError(err) };
1422
+ return {
1423
+ totalBytes: 0,
1424
+ totalCostUsd: 0,
1425
+ requestCount: 0,
1426
+ period: `${context.days} days`,
1427
+ error: safeError(err),
1428
+ };
1195
1429
  }
1196
1430
  },
1197
1431
  }),
@@ -1238,12 +1472,29 @@ class DominusNodeToolkit {
1238
1472
  description: "Create a server-side custodial agentic wallet for autonomous proxy billing. " +
1239
1473
  "Set a spending limit per transaction for safety. Optionally set a daily budget cap and domain allowlist.",
1240
1474
  inputSchema: zod_1.z.object({
1241
- label: zod_1.z.string().min(1).max(100).describe('Label for this wallet (e.g., "scraper-bot", "research-agent")'),
1242
- spendingLimitCents: zod_1.z.number().int().min(0).max(1000000).default(10000)
1475
+ label: zod_1.z
1476
+ .string()
1477
+ .min(1)
1478
+ .max(100)
1479
+ .describe('Label for this wallet (e.g., "scraper-bot", "research-agent")'),
1480
+ spendingLimitCents: zod_1.z
1481
+ .number()
1482
+ .int()
1483
+ .min(0)
1484
+ .max(1000000)
1485
+ .default(10000)
1243
1486
  .describe("Max spend per transaction in cents (0 = no limit, default $100 = 10000 cents)"),
1244
- dailyLimitCents: zod_1.z.number().int().positive().max(1000000).optional()
1487
+ dailyLimitCents: zod_1.z
1488
+ .number()
1489
+ .int()
1490
+ .positive()
1491
+ .max(1000000)
1492
+ .optional()
1245
1493
  .describe("Optional daily budget cap in cents (max 1,000,000 = $10,000)"),
1246
- allowedDomains: zod_1.z.array(zod_1.z.string().max(253)).max(100).optional()
1494
+ allowedDomains: zod_1.z
1495
+ .array(zod_1.z.string().max(253))
1496
+ .max(100)
1497
+ .optional()
1247
1498
  .describe("Optional list of allowed domains for proxy access (max 100 entries)"),
1248
1499
  }),
1249
1500
  outputSchema: zod_1.z.object({
@@ -1252,7 +1503,9 @@ class DominusNodeToolkit {
1252
1503
  }),
1253
1504
  execute: async ({ context }) => {
1254
1505
  try {
1255
- return { data: await this.createAgenticWallet(context.label, context.spendingLimitCents, context.dailyLimitCents, context.allowedDomains) };
1506
+ return {
1507
+ data: await this.createAgenticWallet(context.label, context.spendingLimitCents, context.dailyLimitCents, context.allowedDomains),
1508
+ };
1256
1509
  }
1257
1510
  catch (err) {
1258
1511
  return { data: null, error: safeError(err) };
@@ -1266,7 +1519,12 @@ class DominusNodeToolkit {
1266
1519
  "Minimum $1 (100 cents), maximum $10,000 (1000000 cents).",
1267
1520
  inputSchema: zod_1.z.object({
1268
1521
  walletId: zod_1.z.string().describe("Agentic wallet ID (UUID)"),
1269
- amountCents: zod_1.z.number().int().min(100).max(1000000).describe("Amount in cents to transfer (min 100, max 1000000)"),
1522
+ amountCents: zod_1.z
1523
+ .number()
1524
+ .int()
1525
+ .min(100)
1526
+ .max(1000000)
1527
+ .describe("Amount in cents to transfer (min 100, max 1000000)"),
1270
1528
  }),
1271
1529
  outputSchema: zod_1.z.object({
1272
1530
  data: zod_1.z.unknown(),
@@ -1274,7 +1532,9 @@ class DominusNodeToolkit {
1274
1532
  }),
1275
1533
  execute: async ({ context }) => {
1276
1534
  try {
1277
- return { data: await this.fundAgenticWallet(context.walletId, context.amountCents) };
1535
+ return {
1536
+ data: await this.fundAgenticWallet(context.walletId, context.amountCents),
1537
+ };
1278
1538
  }
1279
1539
  catch (err) {
1280
1540
  return { data: null, error: safeError(err) };
@@ -1325,7 +1585,13 @@ class DominusNodeToolkit {
1325
1585
  description: "Get transaction history for an agentic wallet.",
1326
1586
  inputSchema: zod_1.z.object({
1327
1587
  walletId: zod_1.z.string().describe("Agentic wallet ID (UUID)"),
1328
- limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return (1-100, default 20)"),
1588
+ limit: zod_1.z
1589
+ .number()
1590
+ .int()
1591
+ .min(1)
1592
+ .max(100)
1593
+ .default(20)
1594
+ .describe("Number of transactions to return (1-100, default 20)"),
1329
1595
  }),
1330
1596
  outputSchema: zod_1.z.object({
1331
1597
  data: zod_1.z.unknown(),
@@ -1333,7 +1599,9 @@ class DominusNodeToolkit {
1333
1599
  }),
1334
1600
  execute: async ({ context }) => {
1335
1601
  try {
1336
- return { data: await this.agenticTransactions(context.walletId, context.limit) };
1602
+ return {
1603
+ data: await this.agenticTransactions(context.walletId, context.limit),
1604
+ };
1337
1605
  }
1338
1606
  catch (err) {
1339
1607
  return { data: null, error: safeError(err) };
@@ -1409,9 +1677,19 @@ class DominusNodeToolkit {
1409
1677
  "Set or remove daily budget caps and domain restrictions.",
1410
1678
  inputSchema: zod_1.z.object({
1411
1679
  walletId: zod_1.z.string().describe("Agentic wallet ID (UUID)"),
1412
- dailyLimitCents: zod_1.z.number().int().positive().max(1000000).nullable().optional()
1680
+ dailyLimitCents: zod_1.z
1681
+ .number()
1682
+ .int()
1683
+ .positive()
1684
+ .max(1000000)
1685
+ .nullable()
1686
+ .optional()
1413
1687
  .describe("Daily budget cap in cents (max 1,000,000). Set null to remove."),
1414
- allowedDomains: zod_1.z.array(zod_1.z.string().max(253)).max(100).nullable().optional()
1688
+ allowedDomains: zod_1.z
1689
+ .array(zod_1.z.string().max(253))
1690
+ .max(100)
1691
+ .nullable()
1692
+ .optional()
1415
1693
  .describe("List of allowed domains (max 100). Set null to remove restriction."),
1416
1694
  }),
1417
1695
  outputSchema: zod_1.z.object({
@@ -1420,7 +1698,9 @@ class DominusNodeToolkit {
1420
1698
  }),
1421
1699
  execute: async ({ context }) => {
1422
1700
  try {
1423
- return { data: await this.updateWalletPolicy(context.walletId, context.dailyLimitCents, context.allowedDomains) };
1701
+ return {
1702
+ data: await this.updateWalletPolicy(context.walletId, context.dailyLimitCents, context.allowedDomains),
1703
+ };
1424
1704
  }
1425
1705
  catch (err) {
1426
1706
  return { data: null, error: safeError(err) };
@@ -1433,8 +1713,18 @@ class DominusNodeToolkit {
1433
1713
  description: "Create a new team with shared wallet billing. " +
1434
1714
  "Teams allow multiple users to share proxy access and costs.",
1435
1715
  inputSchema: zod_1.z.object({
1436
- name: zod_1.z.string().min(1).max(100).describe("Team name (1-100 characters)"),
1437
- maxMembers: zod_1.z.number().int().min(1).max(100).optional().describe("Maximum number of team members (1-100, optional)"),
1716
+ name: zod_1.z
1717
+ .string()
1718
+ .min(1)
1719
+ .max(100)
1720
+ .describe("Team name (1-100 characters)"),
1721
+ maxMembers: zod_1.z
1722
+ .number()
1723
+ .int()
1724
+ .min(1)
1725
+ .max(100)
1726
+ .optional()
1727
+ .describe("Maximum number of team members (1-100, optional)"),
1438
1728
  }),
1439
1729
  outputSchema: zod_1.z.object({
1440
1730
  data: zod_1.z.unknown(),
@@ -1442,7 +1732,9 @@ class DominusNodeToolkit {
1442
1732
  }),
1443
1733
  execute: async ({ context }) => {
1444
1734
  try {
1445
- return { data: await this.createTeam(context.name, context.maxMembers) };
1735
+ return {
1736
+ data: await this.createTeam(context.name, context.maxMembers),
1737
+ };
1446
1738
  }
1447
1739
  catch (err) {
1448
1740
  return { data: null, error: safeError(err) };
@@ -1494,7 +1786,12 @@ class DominusNodeToolkit {
1494
1786
  "Minimum $1 (100 cents), maximum $10,000 (1000000 cents).",
1495
1787
  inputSchema: zod_1.z.object({
1496
1788
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1497
- amountCents: zod_1.z.number().int().min(100).max(1000000).describe("Amount in cents to transfer (min 100, max 1000000)"),
1789
+ amountCents: zod_1.z
1790
+ .number()
1791
+ .int()
1792
+ .min(100)
1793
+ .max(1000000)
1794
+ .describe("Amount in cents to transfer (min 100, max 1000000)"),
1498
1795
  }),
1499
1796
  outputSchema: zod_1.z.object({
1500
1797
  data: zod_1.z.unknown(),
@@ -1502,7 +1799,9 @@ class DominusNodeToolkit {
1502
1799
  }),
1503
1800
  execute: async ({ context }) => {
1504
1801
  try {
1505
- return { data: await this.teamFund(context.teamId, context.amountCents) };
1802
+ return {
1803
+ data: await this.teamFund(context.teamId, context.amountCents),
1804
+ };
1506
1805
  }
1507
1806
  catch (err) {
1508
1807
  return { data: null, error: safeError(err) };
@@ -1516,7 +1815,11 @@ class DominusNodeToolkit {
1516
1815
  "The key is shown only once -- save it immediately.",
1517
1816
  inputSchema: zod_1.z.object({
1518
1817
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1519
- label: zod_1.z.string().min(1).max(100).describe('Label for the API key (e.g., "production", "staging")'),
1818
+ label: zod_1.z
1819
+ .string()
1820
+ .min(1)
1821
+ .max(100)
1822
+ .describe('Label for the API key (e.g., "production", "staging")'),
1520
1823
  }),
1521
1824
  outputSchema: zod_1.z.object({
1522
1825
  data: zod_1.z.unknown(),
@@ -1524,7 +1827,9 @@ class DominusNodeToolkit {
1524
1827
  }),
1525
1828
  execute: async ({ context }) => {
1526
1829
  try {
1527
- return { data: await this.teamCreateKey(context.teamId, context.label) };
1830
+ return {
1831
+ data: await this.teamCreateKey(context.teamId, context.label),
1832
+ };
1528
1833
  }
1529
1834
  catch (err) {
1530
1835
  return { data: null, error: safeError(err) };
@@ -1537,7 +1842,13 @@ class DominusNodeToolkit {
1537
1842
  description: "Get the team wallet transaction history (funding, usage charges, refunds).",
1538
1843
  inputSchema: zod_1.z.object({
1539
1844
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1540
- limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return (1-100, default 20)"),
1845
+ limit: zod_1.z
1846
+ .number()
1847
+ .int()
1848
+ .min(1)
1849
+ .max(100)
1850
+ .default(20)
1851
+ .describe("Number of transactions to return (1-100, default 20)"),
1541
1852
  }),
1542
1853
  outputSchema: zod_1.z.object({
1543
1854
  data: zod_1.z.unknown(),
@@ -1545,7 +1856,9 @@ class DominusNodeToolkit {
1545
1856
  }),
1546
1857
  execute: async ({ context }) => {
1547
1858
  try {
1548
- return { data: await this.teamUsage(context.teamId, context.limit) };
1859
+ return {
1860
+ data: await this.teamUsage(context.teamId, context.limit),
1861
+ };
1549
1862
  }
1550
1863
  catch (err) {
1551
1864
  return { data: null, error: safeError(err) };
@@ -1558,8 +1871,19 @@ class DominusNodeToolkit {
1558
1871
  description: "Update a team's settings (name and/or max member count). Only owners and admins can update.",
1559
1872
  inputSchema: zod_1.z.object({
1560
1873
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1561
- name: zod_1.z.string().min(1).max(100).optional().describe("New team name (1-100 characters)"),
1562
- maxMembers: zod_1.z.number().int().min(1).max(100).optional().describe("New max member count (1-100)"),
1874
+ name: zod_1.z
1875
+ .string()
1876
+ .min(1)
1877
+ .max(100)
1878
+ .optional()
1879
+ .describe("New team name (1-100 characters)"),
1880
+ maxMembers: zod_1.z
1881
+ .number()
1882
+ .int()
1883
+ .min(1)
1884
+ .max(100)
1885
+ .optional()
1886
+ .describe("New max member count (1-100)"),
1563
1887
  }),
1564
1888
  outputSchema: zod_1.z.object({
1565
1889
  data: zod_1.z.unknown(),
@@ -1567,7 +1891,9 @@ class DominusNodeToolkit {
1567
1891
  }),
1568
1892
  execute: async ({ context }) => {
1569
1893
  try {
1570
- return { data: await this.updateTeam(context.teamId, context.name, context.maxMembers) };
1894
+ return {
1895
+ data: await this.updateTeam(context.teamId, context.name, context.maxMembers),
1896
+ };
1571
1897
  }
1572
1898
  catch (err) {
1573
1899
  return { data: null, error: safeError(err) };
@@ -1580,7 +1906,9 @@ class DominusNodeToolkit {
1580
1906
  description: "Update a team member's role (member or admin). Only owners and admins can change roles.",
1581
1907
  inputSchema: zod_1.z.object({
1582
1908
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1583
- userId: zod_1.z.string().describe("User ID (UUID) of the member whose role to change"),
1909
+ userId: zod_1.z
1910
+ .string()
1911
+ .describe("User ID (UUID) of the member whose role to change"),
1584
1912
  role: zod_1.z.enum(["member", "admin"]).describe("New role for the member"),
1585
1913
  }),
1586
1914
  outputSchema: zod_1.z.object({
@@ -1589,7 +1917,9 @@ class DominusNodeToolkit {
1589
1917
  }),
1590
1918
  execute: async ({ context }) => {
1591
1919
  try {
1592
- return { data: await this.updateTeamMemberRole(context.teamId, context.userId, context.role) };
1920
+ return {
1921
+ data: await this.updateTeamMemberRole(context.teamId, context.userId, context.role),
1922
+ };
1593
1923
  }
1594
1924
  catch (err) {
1595
1925
  return { data: null, error: safeError(err) };
@@ -1602,7 +1932,11 @@ class DominusNodeToolkit {
1602
1932
  description: "Top up your Dominus Node wallet balance via PayPal. Creates a PayPal order and returns " +
1603
1933
  "an approval URL to complete payment. Minimum $5 (500 cents), maximum $1,000 (100000 cents).",
1604
1934
  inputSchema: zod_1.z.object({
1605
- amountCents: zod_1.z.number().int().min(500).max(100000)
1935
+ amountCents: zod_1.z
1936
+ .number()
1937
+ .int()
1938
+ .min(500)
1939
+ .max(100000)
1606
1940
  .describe("Amount in cents to top up (min 500 = $5, max 100000 = $1,000)"),
1607
1941
  }),
1608
1942
  outputSchema: zod_1.z.object({
@@ -1624,7 +1958,11 @@ class DominusNodeToolkit {
1624
1958
  description: "Top up your Dominus Node wallet balance via Stripe. Creates a Stripe checkout session and returns " +
1625
1959
  "a checkout URL to complete payment. Minimum $5 (500 cents), maximum $1,000 (100000 cents).",
1626
1960
  inputSchema: zod_1.z.object({
1627
- amountCents: zod_1.z.number().int().min(500).max(100000)
1961
+ amountCents: zod_1.z
1962
+ .number()
1963
+ .int()
1964
+ .min(500)
1965
+ .max(100000)
1628
1966
  .describe("Amount in cents to top up (min 500 = $5, max 100000 = $1,000)"),
1629
1967
  }),
1630
1968
  outputSchema: zod_1.z.object({
@@ -1647,9 +1985,25 @@ class DominusNodeToolkit {
1647
1985
  "Supports BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK. " +
1648
1986
  "Minimum $5, maximum $1,000.",
1649
1987
  inputSchema: zod_1.z.object({
1650
- amountUsd: zod_1.z.number().min(5).max(1000)
1988
+ amountUsd: zod_1.z
1989
+ .number()
1990
+ .min(5)
1991
+ .max(1000)
1651
1992
  .describe("Amount in USD to top up (5-1000)"),
1652
- currency: zod_1.z.enum(["btc", "eth", "ltc", "xmr", "zec", "usdc", "sol", "usdt", "dai", "bnb", "link"])
1993
+ currency: zod_1.z
1994
+ .enum([
1995
+ "btc",
1996
+ "eth",
1997
+ "ltc",
1998
+ "xmr",
1999
+ "zec",
2000
+ "usdc",
2001
+ "sol",
2002
+ "usdt",
2003
+ "dai",
2004
+ "bnb",
2005
+ "link",
2006
+ ])
1653
2007
  .describe("Cryptocurrency to pay with"),
1654
2008
  }),
1655
2009
  outputSchema: zod_1.z.object({
@@ -1658,7 +2012,9 @@ class DominusNodeToolkit {
1658
2012
  }),
1659
2013
  execute: async ({ context }) => {
1660
2014
  try {
1661
- return { data: await this.topupCrypto(context.amountUsd, context.currency) };
2015
+ return {
2016
+ data: await this.topupCrypto(context.amountUsd, context.currency),
2017
+ };
1662
2018
  }
1663
2019
  catch (err) {
1664
2020
  return { data: null, error: safeError(err) };
@@ -1708,7 +2064,13 @@ class DominusNodeToolkit {
1708
2064
  id: "dominusnode_get_transactions",
1709
2065
  description: "Get wallet transaction history showing top-ups, charges, and refunds.",
1710
2066
  inputSchema: zod_1.z.object({
1711
- limit: zod_1.z.number().int().min(1).max(100).default(20).describe("Number of transactions to return (1-100, default 20)"),
2067
+ limit: zod_1.z
2068
+ .number()
2069
+ .int()
2070
+ .min(1)
2071
+ .max(100)
2072
+ .default(20)
2073
+ .describe("Number of transactions to return (1-100, default 20)"),
1712
2074
  }),
1713
2075
  outputSchema: zod_1.z.object({
1714
2076
  data: zod_1.z.unknown(),
@@ -1748,7 +2110,9 @@ class DominusNodeToolkit {
1748
2110
  description: "Check the status of a crypto top-up payment by invoice ID. " +
1749
2111
  "Returns payment status (pending, confirming, completed, expired).",
1750
2112
  inputSchema: zod_1.z.object({
1751
- invoiceId: zod_1.z.string().describe("Crypto invoice ID (UUID) returned from topup_crypto"),
2113
+ invoiceId: zod_1.z
2114
+ .string()
2115
+ .describe("Crypto invoice ID (UUID) returned from topup_crypto"),
1752
2116
  }),
1753
2117
  outputSchema: zod_1.z.object({
1754
2118
  data: zod_1.z.unknown(),
@@ -1769,7 +2133,13 @@ class DominusNodeToolkit {
1769
2133
  description: "Get daily bandwidth usage breakdown for the specified number of days. " +
1770
2134
  "Returns per-day bytes transferred and cost.",
1771
2135
  inputSchema: zod_1.z.object({
1772
- days: zod_1.z.number().int().min(1).max(365).default(7).describe("Number of days to look back (1-365, default 7)"),
2136
+ days: zod_1.z
2137
+ .number()
2138
+ .int()
2139
+ .min(1)
2140
+ .max(365)
2141
+ .default(7)
2142
+ .describe("Number of days to look back (1-365, default 7)"),
1773
2143
  }),
1774
2144
  outputSchema: zod_1.z.object({
1775
2145
  data: zod_1.z.unknown(),
@@ -1789,7 +2159,13 @@ class DominusNodeToolkit {
1789
2159
  id: "dominusnode_get_top_hosts",
1790
2160
  description: "Get the top hosts by bandwidth usage. Shows which domains consume the most proxy traffic.",
1791
2161
  inputSchema: zod_1.z.object({
1792
- limit: zod_1.z.number().int().min(1).max(100).default(10).describe("Number of top hosts to return (1-100, default 10)"),
2162
+ limit: zod_1.z
2163
+ .number()
2164
+ .int()
2165
+ .min(1)
2166
+ .max(100)
2167
+ .default(10)
2168
+ .describe("Number of top hosts to return (1-100, default 10)"),
1793
2169
  }),
1794
2170
  outputSchema: zod_1.z.object({
1795
2171
  data: zod_1.z.unknown(),
@@ -1811,7 +2187,11 @@ class DominusNodeToolkit {
1811
2187
  "Returns user info and initial API key.",
1812
2188
  inputSchema: zod_1.z.object({
1813
2189
  email: zod_1.z.string().describe("Email address for the new account"),
1814
- password: zod_1.z.string().min(8).max(128).describe("Password (8-128 characters)"),
2190
+ password: zod_1.z
2191
+ .string()
2192
+ .min(8)
2193
+ .max(128)
2194
+ .describe("Password (8-128 characters)"),
1815
2195
  }),
1816
2196
  outputSchema: zod_1.z.object({
1817
2197
  data: zod_1.z.unknown(),
@@ -1819,7 +2199,9 @@ class DominusNodeToolkit {
1819
2199
  }),
1820
2200
  execute: async ({ context }) => {
1821
2201
  try {
1822
- return { data: await this.register(context.email, context.password) };
2202
+ return {
2203
+ data: await this.register(context.email, context.password),
2204
+ };
1823
2205
  }
1824
2206
  catch (err) {
1825
2207
  return { data: null, error: safeError(err) };
@@ -1872,7 +2254,9 @@ class DominusNodeToolkit {
1872
2254
  description: "Verify an email address using the verification token sent to the user's email. " +
1873
2255
  "Does not require authentication.",
1874
2256
  inputSchema: zod_1.z.object({
1875
- token: zod_1.z.string().describe("Email verification token from the verification email"),
2257
+ token: zod_1.z
2258
+ .string()
2259
+ .describe("Email verification token from the verification email"),
1876
2260
  }),
1877
2261
  outputSchema: zod_1.z.object({
1878
2262
  data: zod_1.z.unknown(),
@@ -1910,8 +2294,16 @@ class DominusNodeToolkit {
1910
2294
  id: "dominusnode_update_password",
1911
2295
  description: "Change your account password. Requires current password for verification.",
1912
2296
  inputSchema: zod_1.z.object({
1913
- currentPassword: zod_1.z.string().min(8).max(128).describe("Current account password"),
1914
- newPassword: zod_1.z.string().min(8).max(128).describe("New password (8-128 characters)"),
2297
+ currentPassword: zod_1.z
2298
+ .string()
2299
+ .min(8)
2300
+ .max(128)
2301
+ .describe("Current account password"),
2302
+ newPassword: zod_1.z
2303
+ .string()
2304
+ .min(8)
2305
+ .max(128)
2306
+ .describe("New password (8-128 characters)"),
1915
2307
  }),
1916
2308
  outputSchema: zod_1.z.object({
1917
2309
  data: zod_1.z.unknown(),
@@ -1919,7 +2311,9 @@ class DominusNodeToolkit {
1919
2311
  }),
1920
2312
  execute: async ({ context }) => {
1921
2313
  try {
1922
- return { data: await this.updatePassword(context.currentPassword, context.newPassword) };
2314
+ return {
2315
+ data: await this.updatePassword(context.currentPassword, context.newPassword),
2316
+ };
1923
2317
  }
1924
2318
  catch (err) {
1925
2319
  return { data: null, error: safeError(err) };
@@ -1950,7 +2344,11 @@ class DominusNodeToolkit {
1950
2344
  description: "Create a new personal API key. The key is shown only once -- save it immediately. " +
1951
2345
  "Usage is billed against your personal wallet.",
1952
2346
  inputSchema: zod_1.z.object({
1953
- label: zod_1.z.string().min(1).max(100).describe('Label for the API key (e.g., "production", "dev-testing")'),
2347
+ label: zod_1.z
2348
+ .string()
2349
+ .min(1)
2350
+ .max(100)
2351
+ .describe('Label for the API key (e.g., "production", "dev-testing")'),
1954
2352
  }),
1955
2353
  outputSchema: zod_1.z.object({
1956
2354
  data: zod_1.z.unknown(),
@@ -2079,7 +2477,9 @@ class DominusNodeToolkit {
2079
2477
  }),
2080
2478
  execute: async ({ context }) => {
2081
2479
  try {
2082
- return { data: await this.teamRevokeKey(context.teamId, context.keyId) };
2480
+ return {
2481
+ data: await this.teamRevokeKey(context.teamId, context.keyId),
2482
+ };
2083
2483
  }
2084
2484
  catch (err) {
2085
2485
  return { data: null, error: safeError(err) };
@@ -2134,7 +2534,10 @@ class DominusNodeToolkit {
2134
2534
  inputSchema: zod_1.z.object({
2135
2535
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
2136
2536
  userId: zod_1.z.string().describe("User ID (UUID) of the user to add"),
2137
- role: zod_1.z.enum(["member", "admin"]).default("member").describe("Role for the new member"),
2537
+ role: zod_1.z
2538
+ .enum(["member", "admin"])
2539
+ .default("member")
2540
+ .describe("Role for the new member"),
2138
2541
  }),
2139
2542
  outputSchema: zod_1.z.object({
2140
2543
  data: zod_1.z.unknown(),
@@ -2142,7 +2545,9 @@ class DominusNodeToolkit {
2142
2545
  }),
2143
2546
  execute: async ({ context }) => {
2144
2547
  try {
2145
- return { data: await this.teamAddMember(context.teamId, context.userId, context.role) };
2548
+ return {
2549
+ data: await this.teamAddMember(context.teamId, context.userId, context.role),
2550
+ };
2146
2551
  }
2147
2552
  catch (err) {
2148
2553
  return { data: null, error: safeError(err) };
@@ -2163,7 +2568,9 @@ class DominusNodeToolkit {
2163
2568
  }),
2164
2569
  execute: async ({ context }) => {
2165
2570
  try {
2166
- return { data: await this.teamRemoveMember(context.teamId, context.userId) };
2571
+ return {
2572
+ data: await this.teamRemoveMember(context.teamId, context.userId),
2573
+ };
2167
2574
  }
2168
2575
  catch (err) {
2169
2576
  return { data: null, error: safeError(err) };
@@ -2178,7 +2585,10 @@ class DominusNodeToolkit {
2178
2585
  inputSchema: zod_1.z.object({
2179
2586
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
2180
2587
  email: zod_1.z.string().describe("Email address of the user to invite"),
2181
- role: zod_1.z.enum(["member", "admin"]).default("member").describe("Role for the invited member"),
2588
+ role: zod_1.z
2589
+ .enum(["member", "admin"])
2590
+ .default("member")
2591
+ .describe("Role for the invited member"),
2182
2592
  }),
2183
2593
  outputSchema: zod_1.z.object({
2184
2594
  data: zod_1.z.unknown(),
@@ -2186,7 +2596,9 @@ class DominusNodeToolkit {
2186
2596
  }),
2187
2597
  execute: async ({ context }) => {
2188
2598
  try {
2189
- return { data: await this.teamInviteMember(context.teamId, context.email, context.role) };
2599
+ return {
2600
+ data: await this.teamInviteMember(context.teamId, context.email, context.role),
2601
+ };
2190
2602
  }
2191
2603
  catch (err) {
2192
2604
  return { data: null, error: safeError(err) };
@@ -2227,7 +2639,116 @@ class DominusNodeToolkit {
2227
2639
  }),
2228
2640
  execute: async ({ context }) => {
2229
2641
  try {
2230
- return { data: await this.teamCancelInvite(context.teamId, context.inviteId) };
2642
+ return {
2643
+ data: await this.teamCancelInvite(context.teamId, context.inviteId),
2644
+ };
2645
+ }
2646
+ catch (err) {
2647
+ return { data: null, error: safeError(err) };
2648
+ }
2649
+ },
2650
+ }),
2651
+ // 54 (MPP). mpp_info
2652
+ (0, tools_1.createTool)({
2653
+ id: "dominusnode_mpp_info",
2654
+ description: "Get Machine Payment Protocol (MPP) information including enabled status, " +
2655
+ "supported payment methods, pricing, and session limits.",
2656
+ inputSchema: zod_1.z.object({}),
2657
+ outputSchema: zod_1.z.object({
2658
+ data: zod_1.z.unknown(),
2659
+ error: zod_1.z.string().optional(),
2660
+ }),
2661
+ execute: async () => {
2662
+ try {
2663
+ return { data: await this.mppInfo() };
2664
+ }
2665
+ catch (err) {
2666
+ return { data: null, error: safeError(err) };
2667
+ }
2668
+ },
2669
+ }),
2670
+ // 55 (MPP). pay_mpp
2671
+ (0, tools_1.createTool)({
2672
+ id: "dominusnode_pay_mpp",
2673
+ description: "Top up wallet via Machine Payment Protocol (MPP). " +
2674
+ "Supports tempo, stripe_spt, and lightning payment methods.",
2675
+ inputSchema: zod_1.z.object({
2676
+ amountCents: zod_1.z
2677
+ .number()
2678
+ .int()
2679
+ .min(500)
2680
+ .max(100000)
2681
+ .describe("Amount in cents to top up"),
2682
+ method: zod_1.z
2683
+ .enum(["tempo", "stripe_spt", "lightning"])
2684
+ .describe("MPP payment method"),
2685
+ }),
2686
+ outputSchema: zod_1.z.object({
2687
+ data: zod_1.z.unknown(),
2688
+ error: zod_1.z.string().optional(),
2689
+ }),
2690
+ execute: async ({ context }) => {
2691
+ try {
2692
+ return {
2693
+ data: await this.payMpp(context.amountCents, context.method),
2694
+ };
2695
+ }
2696
+ catch (err) {
2697
+ return { data: null, error: safeError(err) };
2698
+ }
2699
+ },
2700
+ }),
2701
+ // 56 (MPP). mpp_session_open
2702
+ (0, tools_1.createTool)({
2703
+ id: "dominusnode_mpp_session_open",
2704
+ description: "Open a pay-as-you-go MPP session. Returns a channelId for metered proxy usage.",
2705
+ inputSchema: zod_1.z.object({
2706
+ maxDepositCents: zod_1.z
2707
+ .number()
2708
+ .int()
2709
+ .min(500)
2710
+ .max(100000)
2711
+ .describe("Maximum deposit in cents"),
2712
+ method: zod_1.z
2713
+ .enum(["tempo", "stripe_spt", "lightning"])
2714
+ .describe("MPP payment method"),
2715
+ poolType: zod_1.z
2716
+ .enum(["dc", "residential"])
2717
+ .default("dc")
2718
+ .describe("Proxy pool type"),
2719
+ }),
2720
+ outputSchema: zod_1.z.object({
2721
+ data: zod_1.z.unknown(),
2722
+ error: zod_1.z.string().optional(),
2723
+ }),
2724
+ execute: async ({ context }) => {
2725
+ try {
2726
+ return {
2727
+ data: await this.mppSessionOpen(context.maxDepositCents, context.method, context.poolType),
2728
+ };
2729
+ }
2730
+ catch (err) {
2731
+ return { data: null, error: safeError(err) };
2732
+ }
2733
+ },
2734
+ }),
2735
+ // 57 (MPP). mpp_session_close
2736
+ (0, tools_1.createTool)({
2737
+ id: "dominusnode_mpp_session_close",
2738
+ description: "Close an MPP pay-as-you-go session. Returns the amount spent and refunded.",
2739
+ inputSchema: zod_1.z.object({
2740
+ channelId: zod_1.z
2741
+ .string()
2742
+ .min(1)
2743
+ .describe("The channelId returned from mpp_session_open"),
2744
+ }),
2745
+ outputSchema: zod_1.z.object({
2746
+ data: zod_1.z.unknown(),
2747
+ error: zod_1.z.string().optional(),
2748
+ }),
2749
+ execute: async ({ context }) => {
2750
+ try {
2751
+ return { data: await this.mppSessionClose(context.channelId) };
2231
2752
  }
2232
2753
  catch (err) {
2233
2754
  return { data: null, error: safeError(err) };
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@dominusnode/mastra-tools",
3
- "version": "1.3.1",
3
+ "version": "1.5.2",
4
4
  "description": "Dominus Node rotating proxy tools for Mastra AI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
8
  "build": "tsc",
9
+ "prepare": "npm run build",
9
10
  "test": "vitest run"
10
11
  },
11
12
  "dependencies": {