@dominusnode/mastra-tools 1.3.0 → 1.3.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/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
  }
@@ -602,50 +666,138 @@ class DominusNodeToolkit {
602
666
  // Tool implementations
603
667
  // -----------------------------------------------------------------------
604
668
  async proxiedFetch(url, method = "GET", country, proxyType = "dc") {
605
- const parsedUrl = validateTargetUrl(url);
606
- await checkDnsRebinding(parsedUrl.hostname);
607
- const validCountry = validateCountry(country);
608
- const ALLOWED_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
609
- const methodUpper = method.toUpperCase();
610
- if (!ALLOWED_METHODS.has(methodUpper)) {
611
- throw new Error(`HTTP method "${methodUpper}" is not allowed. Only GET, HEAD, and OPTIONS are permitted.`);
612
- }
613
- const apiKey = this.getApiKey();
614
- const parts = [];
615
- if (proxyType && proxyType !== "auto")
616
- parts.push(proxyType);
617
- if (validCountry)
618
- parts.push(`country-${validCountry.toUpperCase()}`);
619
- const username = parts.length > 0 ? parts.join("-") : "auto";
620
- const proxyAuth = "Basic " + Buffer.from(`${username}:${apiKey}`).toString("base64");
621
- const parsed = new URL(url);
622
- const MAX_RESP = 1_048_576; // 1MB
623
- const result = await new Promise((resolve, reject) => {
624
- const timer = setTimeout(() => reject(new Error("Proxy request timed out")), REQUEST_TIMEOUT_MS);
625
- if (parsed.protocol === "https:") {
626
- const connectHost = parsed.hostname.includes(":") ? `[${parsed.hostname}]` : parsed.hostname;
627
- const connectReq = http.request({
628
- hostname: this.proxyHost,
629
- port: this.proxyPort,
630
- method: "CONNECT",
631
- path: `${connectHost}:${parsed.port || 443}`,
632
- headers: { "Proxy-Authorization": proxyAuth, Host: `${connectHost}:${parsed.port || 443}` },
633
- });
634
- connectReq.on("connect", (_res, sock) => {
635
- if (_res.statusCode !== 200) {
669
+ try {
670
+ const parsedUrl = validateTargetUrl(url);
671
+ await checkDnsRebinding(parsedUrl.hostname);
672
+ const validCountry = validateCountry(country);
673
+ const ALLOWED_METHODS = new Set(["GET", "HEAD", "OPTIONS"]);
674
+ const methodUpper = method.toUpperCase();
675
+ if (!ALLOWED_METHODS.has(methodUpper)) {
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
+ };
685
+ }
686
+ const apiKey = this.getApiKey();
687
+ const parts = [];
688
+ if (proxyType && proxyType !== "auto")
689
+ parts.push(proxyType);
690
+ if (validCountry)
691
+ parts.push(`country-${validCountry.toUpperCase()}`);
692
+ const username = parts.length > 0 ? parts.join("-") : "auto";
693
+ const proxyAuth = "Basic " + Buffer.from(`${username}:${apiKey}`).toString("base64");
694
+ const parsed = new URL(url);
695
+ const MAX_RESP = 1_048_576; // 1MB
696
+ const result = await new Promise((resolve, reject) => {
697
+ const timer = setTimeout(() => reject(new Error("Proxy request timed out")), REQUEST_TIMEOUT_MS);
698
+ if (parsed.protocol === "https:") {
699
+ const connectHost = parsed.hostname.includes(":")
700
+ ? `[${parsed.hostname}]`
701
+ : parsed.hostname;
702
+ const connectReq = http.request({
703
+ hostname: this.proxyHost,
704
+ port: this.proxyPort,
705
+ method: "CONNECT",
706
+ path: `${connectHost}:${parsed.port || 443}`,
707
+ headers: {
708
+ "Proxy-Authorization": proxyAuth,
709
+ Host: `${connectHost}:${parsed.port || 443}`,
710
+ },
711
+ });
712
+ connectReq.on("connect", (_res, sock) => {
713
+ if (_res.statusCode !== 200) {
714
+ clearTimeout(timer);
715
+ sock.destroy();
716
+ reject(new Error(`CONNECT failed: ${_res.statusCode}`));
717
+ return;
718
+ }
719
+ const tlsSock = tls.connect({
720
+ host: parsed.hostname,
721
+ socket: sock,
722
+ servername: parsed.hostname,
723
+ minVersion: "TLSv1.2",
724
+ }, () => {
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`;
726
+ tlsSock.write(reqLine);
727
+ const chunks = [];
728
+ let bytes = 0;
729
+ tlsSock.on("data", (c) => {
730
+ bytes += c.length;
731
+ if (bytes <= MAX_RESP + 16384)
732
+ chunks.push(c);
733
+ });
734
+ let done = false;
735
+ const fin = () => {
736
+ if (done)
737
+ return;
738
+ done = true;
739
+ clearTimeout(timer);
740
+ const raw = Buffer.concat(chunks).toString("utf-8");
741
+ const hEnd = raw.indexOf("\r\n\r\n");
742
+ if (hEnd === -1) {
743
+ reject(new Error("Malformed response"));
744
+ return;
745
+ }
746
+ const hdr = raw.substring(0, hEnd);
747
+ const body = raw.substring(hEnd + 4).substring(0, MAX_RESP);
748
+ const bodyBytes = new TextEncoder().encode(body).length;
749
+ const sm = hdr
750
+ .split("\r\n")[0]
751
+ .match(/^HTTP\/\d\.\d\s+(\d+)/);
752
+ const hdrs = {};
753
+ for (const l of hdr.split("\r\n").slice(1)) {
754
+ const ci = l.indexOf(":");
755
+ if (ci > 0)
756
+ hdrs[l.substring(0, ci).trim().toLowerCase()] = l
757
+ .substring(ci + 1)
758
+ .trim();
759
+ }
760
+ resolve({
761
+ status: sm ? parseInt(sm[1], 10) : 0,
762
+ headers: hdrs,
763
+ body,
764
+ bytes: bodyBytes,
765
+ });
766
+ };
767
+ tlsSock.on("end", fin);
768
+ tlsSock.on("close", fin);
769
+ tlsSock.on("error", (e) => {
770
+ clearTimeout(timer);
771
+ reject(e);
772
+ });
773
+ });
774
+ tlsSock.on("error", (e) => {
775
+ clearTimeout(timer);
776
+ reject(e);
777
+ });
778
+ });
779
+ connectReq.on("error", (e) => {
636
780
  clearTimeout(timer);
637
- sock.destroy();
638
- reject(new Error(`CONNECT failed: ${_res.statusCode}`));
639
- return;
640
- }
641
- const tlsSock = tls.connect({ host: parsed.hostname, socket: sock, servername: parsed.hostname, minVersion: "TLSv1.2" }, () => {
642
- 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`;
643
- tlsSock.write(reqLine);
781
+ reject(e);
782
+ });
783
+ connectReq.end();
784
+ }
785
+ else {
786
+ const req = http.request({
787
+ hostname: this.proxyHost,
788
+ port: this.proxyPort,
789
+ method: methodUpper,
790
+ path: url,
791
+ headers: {
792
+ "Proxy-Authorization": proxyAuth,
793
+ Host: parsed.host ?? "",
794
+ },
795
+ }, (res) => {
644
796
  const chunks = [];
645
797
  let bytes = 0;
646
- tlsSock.on("data", (c) => {
798
+ res.on("data", (c) => {
647
799
  bytes += c.length;
648
- if (bytes <= MAX_RESP + 16384)
800
+ if (bytes <= MAX_RESP)
649
801
  chunks.push(c);
650
802
  });
651
803
  let done = false;
@@ -654,76 +806,56 @@ class DominusNodeToolkit {
654
806
  return;
655
807
  done = true;
656
808
  clearTimeout(timer);
657
- const raw = Buffer.concat(chunks).toString("utf-8");
658
- const hEnd = raw.indexOf("\r\n\r\n");
659
- if (hEnd === -1) {
660
- reject(new Error("Malformed response"));
661
- return;
662
- }
663
- const hdr = raw.substring(0, hEnd);
664
- const body = raw.substring(hEnd + 4).substring(0, MAX_RESP);
665
- const sm = hdr.split("\r\n")[0].match(/^HTTP\/\d\.\d\s+(\d+)/);
809
+ const body = Buffer.concat(chunks)
810
+ .toString("utf-8")
811
+ .substring(0, MAX_RESP);
812
+ const bodyBytes = new TextEncoder().encode(body).length;
666
813
  const hdrs = {};
667
- for (const l of hdr.split("\r\n").slice(1)) {
668
- const ci = l.indexOf(":");
669
- if (ci > 0)
670
- hdrs[l.substring(0, ci).trim().toLowerCase()] = l.substring(ci + 1).trim();
814
+ for (const [k, v] of Object.entries(res.headers)) {
815
+ if (v)
816
+ hdrs[k] = Array.isArray(v) ? v.join(", ") : v;
671
817
  }
672
- resolve({ status: sm ? parseInt(sm[1], 10) : 0, headers: hdrs, body });
818
+ resolve({
819
+ status: res.statusCode ?? 0,
820
+ headers: hdrs,
821
+ body,
822
+ bytes: bodyBytes,
823
+ });
673
824
  };
674
- tlsSock.on("end", fin);
675
- tlsSock.on("close", fin);
676
- tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
677
- });
678
- tlsSock.on("error", (e) => { clearTimeout(timer); reject(e); });
679
- });
680
- connectReq.on("error", (e) => { clearTimeout(timer); reject(e); });
681
- connectReq.end();
682
- }
683
- else {
684
- const req = http.request({
685
- hostname: this.proxyHost,
686
- port: this.proxyPort,
687
- method: methodUpper,
688
- path: url,
689
- headers: { "Proxy-Authorization": proxyAuth, Host: parsed.host ?? "" },
690
- }, (res) => {
691
- const chunks = [];
692
- let bytes = 0;
693
- res.on("data", (c) => {
694
- bytes += c.length;
695
- if (bytes <= MAX_RESP)
696
- chunks.push(c);
825
+ res.on("end", fin);
826
+ res.on("close", fin);
827
+ res.on("error", (e) => {
828
+ clearTimeout(timer);
829
+ reject(e);
830
+ });
697
831
  });
698
- let done = false;
699
- const fin = () => {
700
- if (done)
701
- return;
702
- done = true;
832
+ req.on("error", (e) => {
703
833
  clearTimeout(timer);
704
- const body = Buffer.concat(chunks).toString("utf-8").substring(0, MAX_RESP);
705
- const hdrs = {};
706
- for (const [k, v] of Object.entries(res.headers)) {
707
- if (v)
708
- hdrs[k] = Array.isArray(v) ? v.join(", ") : v;
709
- }
710
- resolve({ status: res.statusCode ?? 0, headers: hdrs, body });
711
- };
712
- res.on("end", fin);
713
- res.on("close", fin);
714
- res.on("error", (e) => { clearTimeout(timer); reject(e); });
715
- });
716
- req.on("error", (e) => { clearTimeout(timer); reject(e); });
717
- req.end();
718
- }
719
- });
720
- return {
721
- status: result.status,
722
- headers: result.headers,
723
- body: truncate(scrubCredentials(result.body)),
724
- pool: proxyType,
725
- country: validCountry ?? "auto",
726
- };
834
+ reject(e);
835
+ });
836
+ req.end();
837
+ }
838
+ });
839
+ return {
840
+ status: result.status,
841
+ headers: result.headers,
842
+ body: truncate(scrubCredentials(result.body)),
843
+ bytes: result.bytes,
844
+ pool: proxyType,
845
+ country: validCountry ?? "auto",
846
+ };
847
+ }
848
+ catch (err) {
849
+ return {
850
+ status: 0,
851
+ headers: {},
852
+ body: "",
853
+ bytes: 0,
854
+ pool: proxyType,
855
+ country: country ?? "auto",
856
+ error: safeError(err),
857
+ };
858
+ }
727
859
  }
728
860
  async checkBalance() {
729
861
  const data = await this.apiGet("/api/wallet");
@@ -757,9 +889,14 @@ class DominusNodeToolkit {
757
889
  throw new Error("label contains invalid control characters.");
758
890
  }
759
891
  const safeLimitCents = Math.min(Math.max(spendingLimitCents, 0), 1000000);
760
- const body = { label, spendingLimitCents: safeLimitCents };
892
+ const body = {
893
+ label,
894
+ spendingLimitCents: safeLimitCents,
895
+ };
761
896
  if (dailyLimitCents !== undefined && dailyLimitCents !== null) {
762
- if (!Number.isInteger(dailyLimitCents) || dailyLimitCents < 1 || dailyLimitCents > 1000000) {
897
+ if (!Number.isInteger(dailyLimitCents) ||
898
+ dailyLimitCents < 1 ||
899
+ dailyLimitCents > 1000000) {
763
900
  throw new Error("daily_limit_cents must be an integer between 1 and 1,000,000.");
764
901
  }
765
902
  body.dailyLimitCents = dailyLimitCents;
@@ -785,7 +922,9 @@ class DominusNodeToolkit {
785
922
  body.dailyLimitCents = null;
786
923
  }
787
924
  else {
788
- if (!Number.isInteger(dailyLimitCents) || dailyLimitCents < 1 || dailyLimitCents > 1000000) {
925
+ if (!Number.isInteger(dailyLimitCents) ||
926
+ dailyLimitCents < 1 ||
927
+ dailyLimitCents > 1000000) {
789
928
  throw new Error("daily_limit_cents must be an integer between 1 and 1,000,000, or null to remove.");
790
929
  }
791
930
  body.dailyLimitCents = dailyLimitCents;
@@ -814,7 +953,9 @@ class DominusNodeToolkit {
814
953
  }
815
954
  async fundAgenticWallet(walletId, amountCents) {
816
955
  validateUuid(walletId, "wallet_id");
817
- if (!Number.isInteger(amountCents) || amountCents < 100 || amountCents > 1000000) {
956
+ if (!Number.isInteger(amountCents) ||
957
+ amountCents < 100 ||
958
+ amountCents > 1000000) {
818
959
  throw new Error("amount_cents must be an integer between 100 ($1) and 1000000 ($10,000).");
819
960
  }
820
961
  return this.apiPost(`/api/agent-wallet/${encodeURIComponent(walletId)}/fund`, { amountCents });
@@ -868,7 +1009,9 @@ class DominusNodeToolkit {
868
1009
  }
869
1010
  async teamFund(teamId, amountCents) {
870
1011
  validateUuid(teamId, "team_id");
871
- if (!Number.isInteger(amountCents) || amountCents < 100 || amountCents > 1000000) {
1012
+ if (!Number.isInteger(amountCents) ||
1013
+ amountCents < 100 ||
1014
+ amountCents > 1000000) {
872
1015
  throw new Error("amount_cents must be an integer between 100 ($1) and 1000000 ($10,000).");
873
1016
  }
874
1017
  return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/wallet/fund`, { amountCents });
@@ -881,7 +1024,9 @@ class DominusNodeToolkit {
881
1024
  if (/[\x00-\x1f\x7f]/.test(label)) {
882
1025
  throw new Error("label contains invalid control characters.");
883
1026
  }
884
- return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/keys`, { label });
1027
+ return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/keys`, {
1028
+ label,
1029
+ });
885
1030
  }
886
1031
  async teamUsage(teamId, limit = 20) {
887
1032
  validateUuid(teamId, "team_id");
@@ -921,29 +1066,49 @@ class DominusNodeToolkit {
921
1066
  return this.apiPatch(`/api/teams/${encodeURIComponent(teamId)}/members/${encodeURIComponent(userId)}`, { role });
922
1067
  }
923
1068
  async topupPaypal(amountCents) {
924
- if (!Number.isInteger(amountCents) || amountCents < 500 || amountCents > 100000) {
1069
+ if (!Number.isInteger(amountCents) ||
1070
+ amountCents < 500 ||
1071
+ amountCents > 100000) {
925
1072
  throw new Error("amount_cents must be an integer between 500 ($5) and 100000 ($1,000).");
926
1073
  }
927
1074
  return this.apiPost("/api/wallet/topup/paypal", { amountCents });
928
1075
  }
929
1076
  async topupStripe(amountCents) {
930
- if (!Number.isInteger(amountCents) || amountCents < 500 || amountCents > 100000) {
1077
+ if (!Number.isInteger(amountCents) ||
1078
+ amountCents < 500 ||
1079
+ amountCents > 100000) {
931
1080
  throw new Error("amount_cents must be an integer between 500 ($5) and 100000 ($1,000).");
932
1081
  }
933
1082
  return this.apiPost("/api/wallet/topup/stripe", { amountCents });
934
1083
  }
935
1084
  static VALID_CRYPTO_CURRENCIES = new Set([
936
- "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",
937
1096
  ]);
938
1097
  async topupCrypto(amountUsd, currency) {
939
- 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) {
940
1102
  throw new Error("amount_usd must be a number between 5 and 1,000.");
941
1103
  }
942
1104
  const cur = String(currency ?? "").toLowerCase();
943
1105
  if (!DominusNodeToolkit.VALID_CRYPTO_CURRENCIES.has(cur)) {
944
1106
  throw new Error(`currency must be one of: ${[...DominusNodeToolkit.VALID_CRYPTO_CURRENCIES].join(", ")}.`);
945
1107
  }
946
- return this.apiPost("/api/wallet/topup/crypto", { amountUsd, currency: cur });
1108
+ return this.apiPost("/api/wallet/topup/crypto", {
1109
+ amountUsd,
1110
+ currency: cur,
1111
+ });
947
1112
  }
948
1113
  async x402Info() {
949
1114
  return this.apiGet("/api/x402/info");
@@ -997,12 +1162,23 @@ class DominusNodeToolkit {
997
1162
  async register(email, password) {
998
1163
  const safeEmail = DominusNodeToolkit.validateEmail(email);
999
1164
  const safePassword = DominusNodeToolkit.validatePassword(password);
1000
- 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);
1001
1174
  }
1002
1175
  async login(email, password) {
1003
1176
  const safeEmail = DominusNodeToolkit.validateEmail(email);
1004
1177
  const safePassword = DominusNodeToolkit.validatePassword(password);
1005
- 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
+ });
1006
1182
  }
1007
1183
  async getAccountInfo() {
1008
1184
  return this.apiGet("/api/auth/me");
@@ -1014,7 +1190,9 @@ class DominusNodeToolkit {
1014
1190
  if (/[\x00-\x1f\x7f]/.test(token)) {
1015
1191
  throw new Error("Token contains invalid control characters.");
1016
1192
  }
1017
- 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
+ });
1018
1196
  }
1019
1197
  async resendVerification() {
1020
1198
  return this.apiPost("/api/auth/resend-verification");
@@ -1079,7 +1257,10 @@ class DominusNodeToolkit {
1079
1257
  if (role !== "member" && role !== "admin") {
1080
1258
  throw new Error("role must be 'member' or 'admin'.");
1081
1259
  }
1082
- return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/members`, { userId, role });
1260
+ return this.apiPost(`/api/teams/${encodeURIComponent(teamId)}/members`, {
1261
+ userId,
1262
+ role,
1263
+ });
1083
1264
  }
1084
1265
  async teamRemoveMember(teamId, userId) {
1085
1266
  validateUuid(teamId, "team_id");
@@ -1092,7 +1273,10 @@ class DominusNodeToolkit {
1092
1273
  if (role !== "member" && role !== "admin") {
1093
1274
  throw new Error("role must be 'member' or 'admin'.");
1094
1275
  }
1095
- 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
+ });
1096
1280
  }
1097
1281
  async teamListInvites(teamId) {
1098
1282
  validateUuid(teamId, "team_id");
@@ -1104,7 +1288,47 @@ class DominusNodeToolkit {
1104
1288
  return this.apiDelete(`/api/teams/${encodeURIComponent(teamId)}/invites/${encodeURIComponent(inviteId)}`);
1105
1289
  }
1106
1290
  // -----------------------------------------------------------------------
1107
- // 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
1108
1332
  // -----------------------------------------------------------------------
1109
1333
  getTools() {
1110
1334
  return [
@@ -1116,25 +1340,30 @@ class DominusNodeToolkit {
1116
1340
  "Only GET, HEAD, and OPTIONS methods are allowed.",
1117
1341
  inputSchema: zod_1.z.object({
1118
1342
  url: zod_1.z.string().describe("Target URL to fetch (http or https)"),
1119
- method: zod_1.z.enum(["GET", "HEAD", "OPTIONS"]).default("GET").describe("HTTP method"),
1120
- country: zod_1.z.string().optional().describe("ISO 3166-1 alpha-2 country code for geo-targeting (e.g., US, GB, DE)"),
1121
- 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)"),
1122
1355
  }),
1123
1356
  outputSchema: zod_1.z.object({
1124
1357
  status: zod_1.z.number(),
1125
1358
  headers: zod_1.z.record(zod_1.z.string()),
1126
1359
  body: zod_1.z.string(),
1360
+ bytes: zod_1.z.number(),
1127
1361
  pool: zod_1.z.string(),
1128
1362
  country: zod_1.z.string(),
1129
1363
  error: zod_1.z.string().optional(),
1130
1364
  }),
1131
1365
  execute: async ({ context }) => {
1132
- try {
1133
- return await this.proxiedFetch(context.url, context.method, context.country, context.proxyType);
1134
- }
1135
- catch (err) {
1136
- return { status: 0, headers: {}, body: "", pool: context.proxyType ?? "dc", country: context.country ?? "auto", error: safeError(err) };
1137
- }
1366
+ return await this.proxiedFetch(context.url, context.method, context.country, context.proxyType);
1138
1367
  },
1139
1368
  }),
1140
1369
  // 2. check_balance
@@ -1155,7 +1384,13 @@ class DominusNodeToolkit {
1155
1384
  return await this.checkBalance();
1156
1385
  }
1157
1386
  catch (err) {
1158
- 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
+ };
1159
1394
  }
1160
1395
  },
1161
1396
  }),
@@ -1165,7 +1400,12 @@ class DominusNodeToolkit {
1165
1400
  description: "View bandwidth usage statistics for a specified time period. " +
1166
1401
  "Shows total bytes transferred, total cost, and request count.",
1167
1402
  inputSchema: zod_1.z.object({
1168
- 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)"),
1169
1409
  }),
1170
1410
  outputSchema: zod_1.z.object({
1171
1411
  totalBytes: zod_1.z.number(),
@@ -1179,7 +1419,13 @@ class DominusNodeToolkit {
1179
1419
  return await this.checkUsage(context.days);
1180
1420
  }
1181
1421
  catch (err) {
1182
- 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
+ };
1183
1429
  }
1184
1430
  },
1185
1431
  }),
@@ -1226,12 +1472,29 @@ class DominusNodeToolkit {
1226
1472
  description: "Create a server-side custodial agentic wallet for autonomous proxy billing. " +
1227
1473
  "Set a spending limit per transaction for safety. Optionally set a daily budget cap and domain allowlist.",
1228
1474
  inputSchema: zod_1.z.object({
1229
- label: zod_1.z.string().min(1).max(100).describe('Label for this wallet (e.g., "scraper-bot", "research-agent")'),
1230
- 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)
1231
1486
  .describe("Max spend per transaction in cents (0 = no limit, default $100 = 10000 cents)"),
1232
- 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()
1233
1493
  .describe("Optional daily budget cap in cents (max 1,000,000 = $10,000)"),
1234
- 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()
1235
1498
  .describe("Optional list of allowed domains for proxy access (max 100 entries)"),
1236
1499
  }),
1237
1500
  outputSchema: zod_1.z.object({
@@ -1240,7 +1503,9 @@ class DominusNodeToolkit {
1240
1503
  }),
1241
1504
  execute: async ({ context }) => {
1242
1505
  try {
1243
- 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
+ };
1244
1509
  }
1245
1510
  catch (err) {
1246
1511
  return { data: null, error: safeError(err) };
@@ -1254,7 +1519,12 @@ class DominusNodeToolkit {
1254
1519
  "Minimum $1 (100 cents), maximum $10,000 (1000000 cents).",
1255
1520
  inputSchema: zod_1.z.object({
1256
1521
  walletId: zod_1.z.string().describe("Agentic wallet ID (UUID)"),
1257
- 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)"),
1258
1528
  }),
1259
1529
  outputSchema: zod_1.z.object({
1260
1530
  data: zod_1.z.unknown(),
@@ -1262,7 +1532,9 @@ class DominusNodeToolkit {
1262
1532
  }),
1263
1533
  execute: async ({ context }) => {
1264
1534
  try {
1265
- return { data: await this.fundAgenticWallet(context.walletId, context.amountCents) };
1535
+ return {
1536
+ data: await this.fundAgenticWallet(context.walletId, context.amountCents),
1537
+ };
1266
1538
  }
1267
1539
  catch (err) {
1268
1540
  return { data: null, error: safeError(err) };
@@ -1313,7 +1585,13 @@ class DominusNodeToolkit {
1313
1585
  description: "Get transaction history for an agentic wallet.",
1314
1586
  inputSchema: zod_1.z.object({
1315
1587
  walletId: zod_1.z.string().describe("Agentic wallet ID (UUID)"),
1316
- 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)"),
1317
1595
  }),
1318
1596
  outputSchema: zod_1.z.object({
1319
1597
  data: zod_1.z.unknown(),
@@ -1321,7 +1599,9 @@ class DominusNodeToolkit {
1321
1599
  }),
1322
1600
  execute: async ({ context }) => {
1323
1601
  try {
1324
- return { data: await this.agenticTransactions(context.walletId, context.limit) };
1602
+ return {
1603
+ data: await this.agenticTransactions(context.walletId, context.limit),
1604
+ };
1325
1605
  }
1326
1606
  catch (err) {
1327
1607
  return { data: null, error: safeError(err) };
@@ -1397,9 +1677,19 @@ class DominusNodeToolkit {
1397
1677
  "Set or remove daily budget caps and domain restrictions.",
1398
1678
  inputSchema: zod_1.z.object({
1399
1679
  walletId: zod_1.z.string().describe("Agentic wallet ID (UUID)"),
1400
- 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()
1401
1687
  .describe("Daily budget cap in cents (max 1,000,000). Set null to remove."),
1402
- 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()
1403
1693
  .describe("List of allowed domains (max 100). Set null to remove restriction."),
1404
1694
  }),
1405
1695
  outputSchema: zod_1.z.object({
@@ -1408,7 +1698,9 @@ class DominusNodeToolkit {
1408
1698
  }),
1409
1699
  execute: async ({ context }) => {
1410
1700
  try {
1411
- 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
+ };
1412
1704
  }
1413
1705
  catch (err) {
1414
1706
  return { data: null, error: safeError(err) };
@@ -1421,8 +1713,18 @@ class DominusNodeToolkit {
1421
1713
  description: "Create a new team with shared wallet billing. " +
1422
1714
  "Teams allow multiple users to share proxy access and costs.",
1423
1715
  inputSchema: zod_1.z.object({
1424
- name: zod_1.z.string().min(1).max(100).describe("Team name (1-100 characters)"),
1425
- 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)"),
1426
1728
  }),
1427
1729
  outputSchema: zod_1.z.object({
1428
1730
  data: zod_1.z.unknown(),
@@ -1430,7 +1732,9 @@ class DominusNodeToolkit {
1430
1732
  }),
1431
1733
  execute: async ({ context }) => {
1432
1734
  try {
1433
- return { data: await this.createTeam(context.name, context.maxMembers) };
1735
+ return {
1736
+ data: await this.createTeam(context.name, context.maxMembers),
1737
+ };
1434
1738
  }
1435
1739
  catch (err) {
1436
1740
  return { data: null, error: safeError(err) };
@@ -1482,7 +1786,12 @@ class DominusNodeToolkit {
1482
1786
  "Minimum $1 (100 cents), maximum $10,000 (1000000 cents).",
1483
1787
  inputSchema: zod_1.z.object({
1484
1788
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1485
- 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)"),
1486
1795
  }),
1487
1796
  outputSchema: zod_1.z.object({
1488
1797
  data: zod_1.z.unknown(),
@@ -1490,7 +1799,9 @@ class DominusNodeToolkit {
1490
1799
  }),
1491
1800
  execute: async ({ context }) => {
1492
1801
  try {
1493
- return { data: await this.teamFund(context.teamId, context.amountCents) };
1802
+ return {
1803
+ data: await this.teamFund(context.teamId, context.amountCents),
1804
+ };
1494
1805
  }
1495
1806
  catch (err) {
1496
1807
  return { data: null, error: safeError(err) };
@@ -1504,7 +1815,11 @@ class DominusNodeToolkit {
1504
1815
  "The key is shown only once -- save it immediately.",
1505
1816
  inputSchema: zod_1.z.object({
1506
1817
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1507
- 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")'),
1508
1823
  }),
1509
1824
  outputSchema: zod_1.z.object({
1510
1825
  data: zod_1.z.unknown(),
@@ -1512,7 +1827,9 @@ class DominusNodeToolkit {
1512
1827
  }),
1513
1828
  execute: async ({ context }) => {
1514
1829
  try {
1515
- return { data: await this.teamCreateKey(context.teamId, context.label) };
1830
+ return {
1831
+ data: await this.teamCreateKey(context.teamId, context.label),
1832
+ };
1516
1833
  }
1517
1834
  catch (err) {
1518
1835
  return { data: null, error: safeError(err) };
@@ -1525,7 +1842,13 @@ class DominusNodeToolkit {
1525
1842
  description: "Get the team wallet transaction history (funding, usage charges, refunds).",
1526
1843
  inputSchema: zod_1.z.object({
1527
1844
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1528
- 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)"),
1529
1852
  }),
1530
1853
  outputSchema: zod_1.z.object({
1531
1854
  data: zod_1.z.unknown(),
@@ -1533,7 +1856,9 @@ class DominusNodeToolkit {
1533
1856
  }),
1534
1857
  execute: async ({ context }) => {
1535
1858
  try {
1536
- return { data: await this.teamUsage(context.teamId, context.limit) };
1859
+ return {
1860
+ data: await this.teamUsage(context.teamId, context.limit),
1861
+ };
1537
1862
  }
1538
1863
  catch (err) {
1539
1864
  return { data: null, error: safeError(err) };
@@ -1546,8 +1871,19 @@ class DominusNodeToolkit {
1546
1871
  description: "Update a team's settings (name and/or max member count). Only owners and admins can update.",
1547
1872
  inputSchema: zod_1.z.object({
1548
1873
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1549
- name: zod_1.z.string().min(1).max(100).optional().describe("New team name (1-100 characters)"),
1550
- 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)"),
1551
1887
  }),
1552
1888
  outputSchema: zod_1.z.object({
1553
1889
  data: zod_1.z.unknown(),
@@ -1555,7 +1891,9 @@ class DominusNodeToolkit {
1555
1891
  }),
1556
1892
  execute: async ({ context }) => {
1557
1893
  try {
1558
- 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
+ };
1559
1897
  }
1560
1898
  catch (err) {
1561
1899
  return { data: null, error: safeError(err) };
@@ -1568,7 +1906,9 @@ class DominusNodeToolkit {
1568
1906
  description: "Update a team member's role (member or admin). Only owners and admins can change roles.",
1569
1907
  inputSchema: zod_1.z.object({
1570
1908
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
1571
- 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"),
1572
1912
  role: zod_1.z.enum(["member", "admin"]).describe("New role for the member"),
1573
1913
  }),
1574
1914
  outputSchema: zod_1.z.object({
@@ -1577,7 +1917,9 @@ class DominusNodeToolkit {
1577
1917
  }),
1578
1918
  execute: async ({ context }) => {
1579
1919
  try {
1580
- 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
+ };
1581
1923
  }
1582
1924
  catch (err) {
1583
1925
  return { data: null, error: safeError(err) };
@@ -1590,7 +1932,11 @@ class DominusNodeToolkit {
1590
1932
  description: "Top up your Dominus Node wallet balance via PayPal. Creates a PayPal order and returns " +
1591
1933
  "an approval URL to complete payment. Minimum $5 (500 cents), maximum $1,000 (100000 cents).",
1592
1934
  inputSchema: zod_1.z.object({
1593
- 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)
1594
1940
  .describe("Amount in cents to top up (min 500 = $5, max 100000 = $1,000)"),
1595
1941
  }),
1596
1942
  outputSchema: zod_1.z.object({
@@ -1612,7 +1958,11 @@ class DominusNodeToolkit {
1612
1958
  description: "Top up your Dominus Node wallet balance via Stripe. Creates a Stripe checkout session and returns " +
1613
1959
  "a checkout URL to complete payment. Minimum $5 (500 cents), maximum $1,000 (100000 cents).",
1614
1960
  inputSchema: zod_1.z.object({
1615
- 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)
1616
1966
  .describe("Amount in cents to top up (min 500 = $5, max 100000 = $1,000)"),
1617
1967
  }),
1618
1968
  outputSchema: zod_1.z.object({
@@ -1635,9 +1985,25 @@ class DominusNodeToolkit {
1635
1985
  "Supports BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK. " +
1636
1986
  "Minimum $5, maximum $1,000.",
1637
1987
  inputSchema: zod_1.z.object({
1638
- amountUsd: zod_1.z.number().min(5).max(1000)
1988
+ amountUsd: zod_1.z
1989
+ .number()
1990
+ .min(5)
1991
+ .max(1000)
1639
1992
  .describe("Amount in USD to top up (5-1000)"),
1640
- 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
+ ])
1641
2007
  .describe("Cryptocurrency to pay with"),
1642
2008
  }),
1643
2009
  outputSchema: zod_1.z.object({
@@ -1646,7 +2012,9 @@ class DominusNodeToolkit {
1646
2012
  }),
1647
2013
  execute: async ({ context }) => {
1648
2014
  try {
1649
- return { data: await this.topupCrypto(context.amountUsd, context.currency) };
2015
+ return {
2016
+ data: await this.topupCrypto(context.amountUsd, context.currency),
2017
+ };
1650
2018
  }
1651
2019
  catch (err) {
1652
2020
  return { data: null, error: safeError(err) };
@@ -1696,7 +2064,13 @@ class DominusNodeToolkit {
1696
2064
  id: "dominusnode_get_transactions",
1697
2065
  description: "Get wallet transaction history showing top-ups, charges, and refunds.",
1698
2066
  inputSchema: zod_1.z.object({
1699
- 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)"),
1700
2074
  }),
1701
2075
  outputSchema: zod_1.z.object({
1702
2076
  data: zod_1.z.unknown(),
@@ -1736,7 +2110,9 @@ class DominusNodeToolkit {
1736
2110
  description: "Check the status of a crypto top-up payment by invoice ID. " +
1737
2111
  "Returns payment status (pending, confirming, completed, expired).",
1738
2112
  inputSchema: zod_1.z.object({
1739
- 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"),
1740
2116
  }),
1741
2117
  outputSchema: zod_1.z.object({
1742
2118
  data: zod_1.z.unknown(),
@@ -1757,7 +2133,13 @@ class DominusNodeToolkit {
1757
2133
  description: "Get daily bandwidth usage breakdown for the specified number of days. " +
1758
2134
  "Returns per-day bytes transferred and cost.",
1759
2135
  inputSchema: zod_1.z.object({
1760
- 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)"),
1761
2143
  }),
1762
2144
  outputSchema: zod_1.z.object({
1763
2145
  data: zod_1.z.unknown(),
@@ -1777,7 +2159,13 @@ class DominusNodeToolkit {
1777
2159
  id: "dominusnode_get_top_hosts",
1778
2160
  description: "Get the top hosts by bandwidth usage. Shows which domains consume the most proxy traffic.",
1779
2161
  inputSchema: zod_1.z.object({
1780
- 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)"),
1781
2169
  }),
1782
2170
  outputSchema: zod_1.z.object({
1783
2171
  data: zod_1.z.unknown(),
@@ -1799,7 +2187,11 @@ class DominusNodeToolkit {
1799
2187
  "Returns user info and initial API key.",
1800
2188
  inputSchema: zod_1.z.object({
1801
2189
  email: zod_1.z.string().describe("Email address for the new account"),
1802
- 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)"),
1803
2195
  }),
1804
2196
  outputSchema: zod_1.z.object({
1805
2197
  data: zod_1.z.unknown(),
@@ -1807,7 +2199,9 @@ class DominusNodeToolkit {
1807
2199
  }),
1808
2200
  execute: async ({ context }) => {
1809
2201
  try {
1810
- return { data: await this.register(context.email, context.password) };
2202
+ return {
2203
+ data: await this.register(context.email, context.password),
2204
+ };
1811
2205
  }
1812
2206
  catch (err) {
1813
2207
  return { data: null, error: safeError(err) };
@@ -1860,7 +2254,9 @@ class DominusNodeToolkit {
1860
2254
  description: "Verify an email address using the verification token sent to the user's email. " +
1861
2255
  "Does not require authentication.",
1862
2256
  inputSchema: zod_1.z.object({
1863
- 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"),
1864
2260
  }),
1865
2261
  outputSchema: zod_1.z.object({
1866
2262
  data: zod_1.z.unknown(),
@@ -1898,8 +2294,16 @@ class DominusNodeToolkit {
1898
2294
  id: "dominusnode_update_password",
1899
2295
  description: "Change your account password. Requires current password for verification.",
1900
2296
  inputSchema: zod_1.z.object({
1901
- currentPassword: zod_1.z.string().min(8).max(128).describe("Current account password"),
1902
- 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)"),
1903
2307
  }),
1904
2308
  outputSchema: zod_1.z.object({
1905
2309
  data: zod_1.z.unknown(),
@@ -1907,7 +2311,9 @@ class DominusNodeToolkit {
1907
2311
  }),
1908
2312
  execute: async ({ context }) => {
1909
2313
  try {
1910
- return { data: await this.updatePassword(context.currentPassword, context.newPassword) };
2314
+ return {
2315
+ data: await this.updatePassword(context.currentPassword, context.newPassword),
2316
+ };
1911
2317
  }
1912
2318
  catch (err) {
1913
2319
  return { data: null, error: safeError(err) };
@@ -1938,7 +2344,11 @@ class DominusNodeToolkit {
1938
2344
  description: "Create a new personal API key. The key is shown only once -- save it immediately. " +
1939
2345
  "Usage is billed against your personal wallet.",
1940
2346
  inputSchema: zod_1.z.object({
1941
- 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")'),
1942
2352
  }),
1943
2353
  outputSchema: zod_1.z.object({
1944
2354
  data: zod_1.z.unknown(),
@@ -2067,7 +2477,9 @@ class DominusNodeToolkit {
2067
2477
  }),
2068
2478
  execute: async ({ context }) => {
2069
2479
  try {
2070
- return { data: await this.teamRevokeKey(context.teamId, context.keyId) };
2480
+ return {
2481
+ data: await this.teamRevokeKey(context.teamId, context.keyId),
2482
+ };
2071
2483
  }
2072
2484
  catch (err) {
2073
2485
  return { data: null, error: safeError(err) };
@@ -2122,7 +2534,10 @@ class DominusNodeToolkit {
2122
2534
  inputSchema: zod_1.z.object({
2123
2535
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
2124
2536
  userId: zod_1.z.string().describe("User ID (UUID) of the user to add"),
2125
- 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"),
2126
2541
  }),
2127
2542
  outputSchema: zod_1.z.object({
2128
2543
  data: zod_1.z.unknown(),
@@ -2130,7 +2545,9 @@ class DominusNodeToolkit {
2130
2545
  }),
2131
2546
  execute: async ({ context }) => {
2132
2547
  try {
2133
- 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
+ };
2134
2551
  }
2135
2552
  catch (err) {
2136
2553
  return { data: null, error: safeError(err) };
@@ -2151,7 +2568,9 @@ class DominusNodeToolkit {
2151
2568
  }),
2152
2569
  execute: async ({ context }) => {
2153
2570
  try {
2154
- return { data: await this.teamRemoveMember(context.teamId, context.userId) };
2571
+ return {
2572
+ data: await this.teamRemoveMember(context.teamId, context.userId),
2573
+ };
2155
2574
  }
2156
2575
  catch (err) {
2157
2576
  return { data: null, error: safeError(err) };
@@ -2166,7 +2585,10 @@ class DominusNodeToolkit {
2166
2585
  inputSchema: zod_1.z.object({
2167
2586
  teamId: zod_1.z.string().describe("Team ID (UUID)"),
2168
2587
  email: zod_1.z.string().describe("Email address of the user to invite"),
2169
- 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"),
2170
2592
  }),
2171
2593
  outputSchema: zod_1.z.object({
2172
2594
  data: zod_1.z.unknown(),
@@ -2174,7 +2596,9 @@ class DominusNodeToolkit {
2174
2596
  }),
2175
2597
  execute: async ({ context }) => {
2176
2598
  try {
2177
- 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
+ };
2178
2602
  }
2179
2603
  catch (err) {
2180
2604
  return { data: null, error: safeError(err) };
@@ -2215,7 +2639,116 @@ class DominusNodeToolkit {
2215
2639
  }),
2216
2640
  execute: async ({ context }) => {
2217
2641
  try {
2218
- 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) };
2219
2752
  }
2220
2753
  catch (err) {
2221
2754
  return { data: null, error: safeError(err) };