@dominusnode/pi-extension 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Changelog
2
+
3
+ ## [1.0.0] - 2026-03-02
4
+
5
+ ### Added
6
+ - Initial release of `@dominusnode/pi-extension`
7
+ - 26 tools covering the full Dominus Node feature suite:
8
+ - Proxied fetch (HTTP/HTTPS via DC + residential pools with geo-targeting)
9
+ - Wallet management (balance, usage, proxy config, sessions)
10
+ - Agentic wallets (create, fund, balance, transactions, freeze, unfreeze, delete, policy)
11
+ - Teams (create, list, details, fund, API key management, usage, update, member roles)
12
+ - Payments (Stripe, PayPal, crypto: BTC/ETH/LTC/XMR/ZEC/USDC/SOL/USDT/DAI/BNB/LINK)
13
+ - x402 micropayment info
14
+ - Full SSRF protection (RFC1918, CGNAT, Teredo/6to4, IPv4-mapped IPv6, DNS rebinding, .localhost/.local/.internal/.arpa TLDs)
15
+ - OFAC sanctioned country validation (CU, IR, KP, RU, SY)
16
+ - Credential scrubbing in all error outputs (`dn_live_*` / `dn_test_*`)
17
+ - Prototype pollution prevention (recursive `stripDangerousKeys`)
18
+ - HTTP method restriction for proxied fetch (GET/HEAD/OPTIONS only)
19
+ - TypeBox parameter schemas for all 26 tools
20
+ - Pi Package manifest (`"pi"` key in package.json)
21
+ - Skill documentation (`skills/use-dominus-proxy.md`)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dominus Node
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # @dominusnode/pi-extension
2
+
3
+ [Pi](https://github.com/badlogic/pi-mono) extension providing **26 tools** for the [Dominus Node](https://dominusnode.com) rotating proxy and management platform.
4
+
5
+ ## What is Pi?
6
+
7
+ Pi (pi-mono) is a TypeScript/Node.js agentic coding framework by Mario Zechner. It powers OpenClaw and supports building AI agent workflows with type-safe tool definitions using `@sinclair/typebox`.
8
+
9
+ ## Installation
10
+
11
+ ### As a Pi Package (recommended)
12
+
13
+ ```bash
14
+ npm install @dominusnode/pi-extension
15
+ ```
16
+
17
+ Declare in your project's `package.json`:
18
+ ```json
19
+ {
20
+ "pi": {
21
+ "extensions": ["./node_modules/@dominusnode/pi-extension/dist"]
22
+ }
23
+ }
24
+ ```
25
+
26
+ ### Manual Extension
27
+
28
+ Copy or symlink the `dist/` folder into your Pi extensions directory:
29
+ ```bash
30
+ ~/.pi/agent/extensions/dominusnode/ # global
31
+ .pi/extensions/dominusnode/ # project-local
32
+ ```
33
+
34
+ ## Authentication
35
+
36
+ ```bash
37
+ export DOMINUSNODE_API_KEY="dn_live_your_key_here"
38
+ ```
39
+
40
+ Get your API key at [dominusnode.com](https://dominusnode.com) → Dashboard → API Keys.
41
+
42
+ ## Available Tools (26 total)
43
+
44
+ | Tool | Description |
45
+ |------|-------------|
46
+ | `dominusnode_proxied_fetch` | Fetch a URL through rotating IPs (DC or residential) |
47
+ | `dominusnode_check_balance` | Get wallet balance |
48
+ | `dominusnode_check_usage` | Bandwidth usage stats |
49
+ | `dominusnode_get_proxy_config` | Proxy endpoint details |
50
+ | `dominusnode_list_sessions` | Active proxy sessions |
51
+ | `dominusnode_create_agentic_wallet` | Create agent sub-wallet |
52
+ | `dominusnode_fund_agentic_wallet` | Fund agent sub-wallet |
53
+ | `dominusnode_check_agentic_balance` | Sub-wallet balance |
54
+ | `dominusnode_list_agentic_wallets` | All sub-wallets |
55
+ | `dominusnode_agentic_transactions` | Sub-wallet transaction history |
56
+ | `dominusnode_freeze_agentic_wallet` | Freeze sub-wallet |
57
+ | `dominusnode_unfreeze_agentic_wallet` | Unfreeze sub-wallet |
58
+ | `dominusnode_delete_agentic_wallet` | Delete sub-wallet |
59
+ | `dominusnode_create_team` | Create team with shared wallet |
60
+ | `dominusnode_list_teams` | List teams |
61
+ | `dominusnode_team_details` | Team details and balance |
62
+ | `dominusnode_team_fund` | Fund team wallet |
63
+ | `dominusnode_team_create_api_key` | Create team API key |
64
+ | `dominusnode_team_usage` | Team bandwidth stats |
65
+ | `dominusnode_update_team` | Update team settings |
66
+ | `dominusnode_update_team_member_role` | Change member role |
67
+ | `dominusnode_topup_paypal` | Top up via PayPal |
68
+ | `dominusnode_topup_stripe` | Top up via Stripe |
69
+ | `dominusnode_topup_crypto` | Top up via crypto (BTC/ETH/USDC/...) |
70
+ | `dominusnode_x402_info` | x402 micropayment config |
71
+ | `dominusnode_update_wallet_policy` | Set spending limits/domain restrictions |
72
+
73
+ ## Proxy Usage
74
+
75
+ ```bash
76
+ # Datacenter pool ($3/GB — fastest)
77
+ curl -x "http://dc-country-US:${DOMINUSNODE_API_KEY}@proxy.dominusnode.com:8080" \
78
+ "https://target-site.com/page"
79
+
80
+ # Residential pool ($5/GB — appears as regular user)
81
+ curl -x "http://residential-country-GB:${DOMINUSNODE_API_KEY}@proxy.dominusnode.com:8080" \
82
+ "https://target-site.com/page"
83
+ ```
84
+
85
+ ## Agentic Wallet Pattern (for Pi swarms)
86
+
87
+ Give each sub-agent its own wallet with a spending cap:
88
+
89
+ ```
90
+ 1. dominusnode_create_agentic_wallet(label="research-agent-1", spendingLimitCents=500)
91
+ 2. dominusnode_fund_agentic_wallet(walletId=<id>, amountCents=1000)
92
+ 3. Sub-agent uses its wallet ID for proxy authentication
93
+ 4. dominusnode_check_agentic_balance(walletId=<id>) — monitor spend
94
+ 5. dominusnode_freeze_agentic_wallet(walletId=<id>) — suspend if needed
95
+ ```
96
+
97
+ ## Security
98
+
99
+ - **SSRF protection**: Private IPs, RFC1918, CGNAT, loopback, link-local, Teredo/6to4, IPv4-mapped IPv6, hex/octal/decimal normalization, zone ID stripping
100
+ - **DNS rebinding protection**: Hostname resolved before each request; private IPs in DNS results are blocked
101
+ - **.localhost / .local / .internal / .arpa** TLDs blocked
102
+ - **OFAC compliance**: Requests to sanctioned countries (CU, IR, KP, RU, SY) are rejected
103
+ - **Credential scrubbing**: API keys redacted from all error messages
104
+ - **Prototype pollution prevention**: Recursive key stripping on all parsed JSON
105
+ - **HTTP method restriction**: Only GET, HEAD, OPTIONS permitted via `proxied_fetch`
106
+ - **10 MB response cap** + 4000 character truncation
107
+ - **Redirect following disabled** to prevent open redirect abuse
108
+
109
+ ## Pricing
110
+
111
+ | Pool | Price | Best for |
112
+ |------|-------|----------|
113
+ | Datacenter | $3.00/GB | Fast scraping, APIs, speed-sensitive tasks |
114
+ | Residential | $5.00/GB | Bypassing geo-blocks, appearing as real user |
115
+
116
+ ## License
117
+
118
+ MIT — see [LICENSE](./LICENSE)
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Dominus Node — Pi Extension
3
+ *
4
+ * Pi-mono extension providing 26 tools for the Dominus Node rotating proxy
5
+ * and management platform. Loaded by the pi coding agent from:
6
+ * ~/.pi/agent/extensions/dominusnode/ (global)
7
+ * .pi/extensions/dominusnode/ (project-local)
8
+ *
9
+ * Usage:
10
+ * export DOMINUSNODE_API_KEY="dn_live_your_key_here"
11
+ * # pi agent discovers and loads this extension automatically
12
+ *
13
+ * Or install as a Pi Package:
14
+ * npm install @dominusnode/pi-extension
15
+ * # declare in package.json "pi": { "extensions": ["./node_modules/@dominusnode/pi-extension/dist"] }
16
+ *
17
+ * @see https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/extensions.md
18
+ */
19
+ import { DominusNodeToolkit, scrubCredentials, isPrivateIp, normalizeIpv4, validateTargetUrl, validateCountry, validateUuid, stripDangerousKeys, checkDnsRebinding, truncate, formatBytes, formatCents, SANCTIONED_COUNTRIES, BLOCKED_HOSTNAMES } from "./toolkit.js";
20
+ export { DominusNodeToolkit, scrubCredentials, isPrivateIp, normalizeIpv4, validateTargetUrl, validateCountry, validateUuid, stripDangerousKeys, checkDnsRebinding, truncate, formatBytes, formatCents, SANCTIONED_COUNTRIES, BLOCKED_HOSTNAMES, };
21
+ interface PiTool {
22
+ name: string;
23
+ label: string;
24
+ description: string;
25
+ parameters: unknown;
26
+ execute: (toolCallId: string, params: Record<string, unknown>, signal: AbortSignal, onUpdate: (text: string) => void, ctx: unknown) => Promise<{
27
+ content: Array<{
28
+ type: "text";
29
+ text: string;
30
+ }>;
31
+ details: Record<string, unknown>;
32
+ }>;
33
+ }
34
+ interface ExtensionAPI {
35
+ registerTool(tool: PiTool): void;
36
+ }
37
+ export default function dominusNodeExtension(pi: ExtensionAPI): void;
package/dist/index.js ADDED
@@ -0,0 +1,373 @@
1
+ "use strict";
2
+ /**
3
+ * Dominus Node — Pi Extension
4
+ *
5
+ * Pi-mono extension providing 26 tools for the Dominus Node rotating proxy
6
+ * and management platform. Loaded by the pi coding agent from:
7
+ * ~/.pi/agent/extensions/dominusnode/ (global)
8
+ * .pi/extensions/dominusnode/ (project-local)
9
+ *
10
+ * Usage:
11
+ * export DOMINUSNODE_API_KEY="dn_live_your_key_here"
12
+ * # pi agent discovers and loads this extension automatically
13
+ *
14
+ * Or install as a Pi Package:
15
+ * npm install @dominusnode/pi-extension
16
+ * # declare in package.json "pi": { "extensions": ["./node_modules/@dominusnode/pi-extension/dist"] }
17
+ *
18
+ * @see https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/extensions.md
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.BLOCKED_HOSTNAMES = exports.SANCTIONED_COUNTRIES = exports.formatCents = exports.formatBytes = exports.truncate = exports.checkDnsRebinding = exports.stripDangerousKeys = exports.validateUuid = exports.validateCountry = exports.validateTargetUrl = exports.normalizeIpv4 = exports.isPrivateIp = exports.scrubCredentials = exports.DominusNodeToolkit = void 0;
22
+ exports.default = dominusNodeExtension;
23
+ const typebox_1 = require("@sinclair/typebox");
24
+ const toolkit_js_1 = require("./toolkit.js");
25
+ Object.defineProperty(exports, "DominusNodeToolkit", { enumerable: true, get: function () { return toolkit_js_1.DominusNodeToolkit; } });
26
+ Object.defineProperty(exports, "scrubCredentials", { enumerable: true, get: function () { return toolkit_js_1.scrubCredentials; } });
27
+ Object.defineProperty(exports, "isPrivateIp", { enumerable: true, get: function () { return toolkit_js_1.isPrivateIp; } });
28
+ Object.defineProperty(exports, "normalizeIpv4", { enumerable: true, get: function () { return toolkit_js_1.normalizeIpv4; } });
29
+ Object.defineProperty(exports, "validateTargetUrl", { enumerable: true, get: function () { return toolkit_js_1.validateTargetUrl; } });
30
+ Object.defineProperty(exports, "validateCountry", { enumerable: true, get: function () { return toolkit_js_1.validateCountry; } });
31
+ Object.defineProperty(exports, "validateUuid", { enumerable: true, get: function () { return toolkit_js_1.validateUuid; } });
32
+ Object.defineProperty(exports, "stripDangerousKeys", { enumerable: true, get: function () { return toolkit_js_1.stripDangerousKeys; } });
33
+ Object.defineProperty(exports, "checkDnsRebinding", { enumerable: true, get: function () { return toolkit_js_1.checkDnsRebinding; } });
34
+ Object.defineProperty(exports, "truncate", { enumerable: true, get: function () { return toolkit_js_1.truncate; } });
35
+ Object.defineProperty(exports, "formatBytes", { enumerable: true, get: function () { return toolkit_js_1.formatBytes; } });
36
+ Object.defineProperty(exports, "formatCents", { enumerable: true, get: function () { return toolkit_js_1.formatCents; } });
37
+ Object.defineProperty(exports, "SANCTIONED_COUNTRIES", { enumerable: true, get: function () { return toolkit_js_1.SANCTIONED_COUNTRIES; } });
38
+ Object.defineProperty(exports, "BLOCKED_HOSTNAMES", { enumerable: true, get: function () { return toolkit_js_1.BLOCKED_HOSTNAMES; } });
39
+ // ---------------------------------------------------------------------------
40
+ // Extension default export — called by Pi on load
41
+ // ---------------------------------------------------------------------------
42
+ function dominusNodeExtension(pi) {
43
+ const toolkit = new toolkit_js_1.DominusNodeToolkit();
44
+ // ── Tool 1: proxied_fetch ────────────────────────────────────────────────
45
+ pi.registerTool({
46
+ name: "dominusnode_proxied_fetch",
47
+ label: "DominusNode: Proxied Fetch",
48
+ description: "Fetch a URL through Dominus Node's rotating proxy network (datacenter or residential IPs). " +
49
+ "Use for web scraping, bypassing geo-restrictions, or rotating IPs. " +
50
+ "Only GET, HEAD, and OPTIONS are permitted. Private/internal URLs are blocked.",
51
+ parameters: typebox_1.Type.Object({
52
+ url: typebox_1.Type.String({ description: "Target URL to fetch (http or https only)" }),
53
+ method: typebox_1.Type.Optional(typebox_1.Type.Union([
54
+ typebox_1.Type.Literal("GET"), typebox_1.Type.Literal("HEAD"), typebox_1.Type.Literal("OPTIONS"),
55
+ ], { description: "HTTP method (default: GET)" })),
56
+ country: typebox_1.Type.Optional(typebox_1.Type.String({ description: "ISO 3166-1 two-letter country code for geo-targeting (e.g. US, GB, DE)" })),
57
+ proxyType: typebox_1.Type.Optional(typebox_1.Type.Union([
58
+ typebox_1.Type.Literal("dc"), typebox_1.Type.Literal("residential"), typebox_1.Type.Literal("auto"),
59
+ ], { description: "Proxy pool: 'dc' (datacenter, $3/GB), 'residential' ($5/GB), or 'auto' (default: dc)" })),
60
+ }),
61
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
62
+ return toolkit.proxiedFetch(String(params.url ?? ""), String(params.method ?? "GET"), params.country ? String(params.country) : undefined, String(params.proxyType ?? "dc"));
63
+ },
64
+ });
65
+ // ── Tool 2: check_balance ────────────────────────────────────────────────
66
+ pi.registerTool({
67
+ name: "dominusnode_check_balance",
68
+ label: "DominusNode: Check Wallet Balance",
69
+ description: "Get the current wallet balance and account details for the Dominus Node account.",
70
+ parameters: typebox_1.Type.Object({}),
71
+ async execute(_id, _params, _signal, _onUpdate, _ctx) {
72
+ return toolkit.checkBalance();
73
+ },
74
+ });
75
+ // ── Tool 3: check_usage ──────────────────────────────────────────────────
76
+ pi.registerTool({
77
+ name: "dominusnode_check_usage",
78
+ label: "DominusNode: Check Bandwidth Usage",
79
+ description: "Get bandwidth usage statistics for the past N days (1–365). Shows bytes consumed by datacenter and residential proxy pools.",
80
+ parameters: typebox_1.Type.Object({
81
+ days: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Number of days to look back (default: 30, max: 365)", minimum: 1, maximum: 365 })),
82
+ }),
83
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
84
+ return toolkit.checkUsage(params.days !== undefined ? Number(params.days) : 30);
85
+ },
86
+ });
87
+ // ── Tool 4: get_proxy_config ─────────────────────────────────────────────
88
+ pi.registerTool({
89
+ name: "dominusnode_get_proxy_config",
90
+ label: "DominusNode: Get Proxy Config",
91
+ description: "Retrieve the proxy endpoint configuration (host, port, proxy URL format) for manual proxy setup.",
92
+ parameters: typebox_1.Type.Object({}),
93
+ async execute(_id, _params, _signal, _onUpdate, _ctx) {
94
+ return toolkit.getProxyConfig();
95
+ },
96
+ });
97
+ // ── Tool 5: list_sessions ────────────────────────────────────────────────
98
+ pi.registerTool({
99
+ name: "dominusnode_list_sessions",
100
+ label: "DominusNode: List Active Sessions",
101
+ description: "List currently active proxy sessions, including their start times and bytes consumed.",
102
+ parameters: typebox_1.Type.Object({}),
103
+ async execute(_id, _params, _signal, _onUpdate, _ctx) {
104
+ return toolkit.listSessions();
105
+ },
106
+ });
107
+ // ── Tool 6: create_agentic_wallet ────────────────────────────────────────
108
+ pi.registerTool({
109
+ name: "dominusnode_create_agentic_wallet",
110
+ label: "DominusNode: Create Agentic Wallet",
111
+ description: "Create a server-side sub-wallet for an AI agent with an optional per-transaction spending limit. " +
112
+ "Useful for giving sub-agents controlled budgets. Wallets are funded from the main wallet.",
113
+ parameters: typebox_1.Type.Object({
114
+ label: typebox_1.Type.String({ description: "Human-readable name for this wallet (e.g. 'research-agent-1')" }),
115
+ spendingLimitCents: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Maximum spend per transaction in cents (e.g. 500 = $5.00)", minimum: 1, maximum: 1000000 })),
116
+ }),
117
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
118
+ return toolkit.createAgenticWallet(String(params.label ?? ""), params.spendingLimitCents !== undefined ? Number(params.spendingLimitCents) : undefined);
119
+ },
120
+ });
121
+ // ── Tool 7: fund_agentic_wallet ──────────────────────────────────────────
122
+ pi.registerTool({
123
+ name: "dominusnode_fund_agentic_wallet",
124
+ label: "DominusNode: Fund Agentic Wallet",
125
+ description: "Transfer funds from the main wallet to an agentic sub-wallet. Amount in cents (e.g. 1000 = $10.00).",
126
+ parameters: typebox_1.Type.Object({
127
+ walletId: typebox_1.Type.String({ description: "UUID of the agentic wallet to fund" }),
128
+ amountCents: typebox_1.Type.Number({ description: "Amount to transfer in cents (e.g. 1000 = $10.00)", minimum: 1 }),
129
+ }),
130
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
131
+ return toolkit.fundAgenticWallet(String(params.walletId ?? ""), Number(params.amountCents));
132
+ },
133
+ });
134
+ // ── Tool 8: check_agentic_balance ────────────────────────────────────────
135
+ pi.registerTool({
136
+ name: "dominusnode_check_agentic_balance",
137
+ label: "DominusNode: Check Agentic Wallet Balance",
138
+ description: "Get the balance and details of a specific agentic sub-wallet.",
139
+ parameters: typebox_1.Type.Object({
140
+ walletId: typebox_1.Type.String({ description: "UUID of the agentic wallet" }),
141
+ }),
142
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
143
+ return toolkit.checkAgenticBalance(String(params.walletId ?? ""));
144
+ },
145
+ });
146
+ // ── Tool 9: list_agentic_wallets ─────────────────────────────────────────
147
+ pi.registerTool({
148
+ name: "dominusnode_list_agentic_wallets",
149
+ label: "DominusNode: List Agentic Wallets",
150
+ description: "List all agentic sub-wallets associated with this account.",
151
+ parameters: typebox_1.Type.Object({}),
152
+ async execute(_id, _params, _signal, _onUpdate, _ctx) {
153
+ return toolkit.listAgenticWallets();
154
+ },
155
+ });
156
+ // ── Tool 10: agentic_transactions ───────────────────────────────────────
157
+ pi.registerTool({
158
+ name: "dominusnode_agentic_transactions",
159
+ label: "DominusNode: Agentic Wallet Transactions",
160
+ description: "List recent transactions for an agentic sub-wallet.",
161
+ parameters: typebox_1.Type.Object({
162
+ walletId: typebox_1.Type.String({ description: "UUID of the agentic wallet" }),
163
+ limit: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Number of transactions to return (default: 20, max: 100)", minimum: 1, maximum: 100 })),
164
+ }),
165
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
166
+ return toolkit.agenticTransactions(String(params.walletId ?? ""), params.limit !== undefined ? Number(params.limit) : 20);
167
+ },
168
+ });
169
+ // ── Tool 11: freeze_agentic_wallet ───────────────────────────────────────
170
+ pi.registerTool({
171
+ name: "dominusnode_freeze_agentic_wallet",
172
+ label: "DominusNode: Freeze Agentic Wallet",
173
+ description: "Freeze an agentic sub-wallet to prevent further spending. The wallet must be unfrozen before it can be deleted.",
174
+ parameters: typebox_1.Type.Object({
175
+ walletId: typebox_1.Type.String({ description: "UUID of the agentic wallet to freeze" }),
176
+ }),
177
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
178
+ return toolkit.freezeAgenticWallet(String(params.walletId ?? ""));
179
+ },
180
+ });
181
+ // ── Tool 12: unfreeze_agentic_wallet ─────────────────────────────────────
182
+ pi.registerTool({
183
+ name: "dominusnode_unfreeze_agentic_wallet",
184
+ label: "DominusNode: Unfreeze Agentic Wallet",
185
+ description: "Unfreeze a previously frozen agentic sub-wallet to resume spending.",
186
+ parameters: typebox_1.Type.Object({
187
+ walletId: typebox_1.Type.String({ description: "UUID of the agentic wallet to unfreeze" }),
188
+ }),
189
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
190
+ return toolkit.unfreezeAgenticWallet(String(params.walletId ?? ""));
191
+ },
192
+ });
193
+ // ── Tool 13: delete_agentic_wallet ───────────────────────────────────────
194
+ pi.registerTool({
195
+ name: "dominusnode_delete_agentic_wallet",
196
+ label: "DominusNode: Delete Agentic Wallet",
197
+ description: "Permanently delete an agentic sub-wallet. Any remaining balance is returned to the main wallet. The wallet must be frozen first.",
198
+ parameters: typebox_1.Type.Object({
199
+ walletId: typebox_1.Type.String({ description: "UUID of the agentic wallet to delete (must be frozen first)" }),
200
+ }),
201
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
202
+ return toolkit.deleteAgenticWallet(String(params.walletId ?? ""));
203
+ },
204
+ });
205
+ // ── Tool 14: create_team ─────────────────────────────────────────────────
206
+ pi.registerTool({
207
+ name: "dominusnode_create_team",
208
+ label: "DominusNode: Create Team",
209
+ description: "Create a new team with a shared wallet. Teams allow multiple users or agents to share bandwidth and billing.",
210
+ parameters: typebox_1.Type.Object({
211
+ name: typebox_1.Type.String({ description: "Team name" }),
212
+ maxMembers: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Maximum number of members (default: 10, max: 100)", minimum: 1, maximum: 100 })),
213
+ }),
214
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
215
+ return toolkit.createTeam(String(params.name ?? ""), params.maxMembers !== undefined ? Number(params.maxMembers) : 10);
216
+ },
217
+ });
218
+ // ── Tool 15: list_teams ──────────────────────────────────────────────────
219
+ pi.registerTool({
220
+ name: "dominusnode_list_teams",
221
+ label: "DominusNode: List Teams",
222
+ description: "List all teams the current account belongs to.",
223
+ parameters: typebox_1.Type.Object({
224
+ limit: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Number of teams to return (default: 20, max: 100)", minimum: 1, maximum: 100 })),
225
+ }),
226
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
227
+ return toolkit.listTeams(params.limit !== undefined ? Number(params.limit) : 20);
228
+ },
229
+ });
230
+ // ── Tool 16: team_details ────────────────────────────────────────────────
231
+ pi.registerTool({
232
+ name: "dominusnode_team_details",
233
+ label: "DominusNode: Team Details",
234
+ description: "Get detailed information about a team, including wallet balance, members, and settings.",
235
+ parameters: typebox_1.Type.Object({
236
+ teamId: typebox_1.Type.String({ description: "UUID of the team" }),
237
+ }),
238
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
239
+ return toolkit.teamDetails(String(params.teamId ?? ""));
240
+ },
241
+ });
242
+ // ── Tool 17: team_fund ───────────────────────────────────────────────────
243
+ pi.registerTool({
244
+ name: "dominusnode_team_fund",
245
+ label: "DominusNode: Fund Team Wallet",
246
+ description: "Transfer funds from the main wallet to a team's shared wallet. Amount in cents.",
247
+ parameters: typebox_1.Type.Object({
248
+ teamId: typebox_1.Type.String({ description: "UUID of the team" }),
249
+ amountCents: typebox_1.Type.Number({ description: "Amount to transfer in cents (e.g. 1000 = $10.00)", minimum: 1 }),
250
+ }),
251
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
252
+ return toolkit.teamFund(String(params.teamId ?? ""), Number(params.amountCents));
253
+ },
254
+ });
255
+ // ── Tool 18: team_create_api_key ─────────────────────────────────────────
256
+ pi.registerTool({
257
+ name: "dominusnode_team_create_api_key",
258
+ label: "DominusNode: Create Team API Key",
259
+ description: "Generate a new API key scoped to a team. Traffic through this key bills to the team wallet. The key is shown only once.",
260
+ parameters: typebox_1.Type.Object({
261
+ teamId: typebox_1.Type.String({ description: "UUID of the team" }),
262
+ label: typebox_1.Type.String({ description: "Label for the API key (e.g. 'research-agent')" }),
263
+ }),
264
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
265
+ return toolkit.teamCreateApiKey(String(params.teamId ?? ""), String(params.label ?? ""));
266
+ },
267
+ });
268
+ // ── Tool 19: team_usage ──────────────────────────────────────────────────
269
+ pi.registerTool({
270
+ name: "dominusnode_team_usage",
271
+ label: "DominusNode: Team Bandwidth Usage",
272
+ description: "Get bandwidth usage statistics for a team over the past N days.",
273
+ parameters: typebox_1.Type.Object({
274
+ teamId: typebox_1.Type.String({ description: "UUID of the team" }),
275
+ days: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Number of days to look back (default: 30, max: 365)", minimum: 1, maximum: 365 })),
276
+ }),
277
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
278
+ return toolkit.teamUsage(String(params.teamId ?? ""), params.days !== undefined ? Number(params.days) : 30);
279
+ },
280
+ });
281
+ // ── Tool 20: update_team ─────────────────────────────────────────────────
282
+ pi.registerTool({
283
+ name: "dominusnode_update_team",
284
+ label: "DominusNode: Update Team",
285
+ description: "Update a team's name or maximum member count.",
286
+ parameters: typebox_1.Type.Object({
287
+ teamId: typebox_1.Type.String({ description: "UUID of the team" }),
288
+ name: typebox_1.Type.Optional(typebox_1.Type.String({ description: "New team name" })),
289
+ maxMembers: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "New maximum member count (1–100)", minimum: 1, maximum: 100 })),
290
+ }),
291
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
292
+ return toolkit.updateTeam(String(params.teamId ?? ""), params.name !== undefined ? String(params.name) : undefined, params.maxMembers !== undefined ? Number(params.maxMembers) : undefined);
293
+ },
294
+ });
295
+ // ── Tool 21: update_team_member_role ─────────────────────────────────────
296
+ pi.registerTool({
297
+ name: "dominusnode_update_team_member_role",
298
+ label: "DominusNode: Update Team Member Role",
299
+ description: "Promote or demote a team member between 'admin' and 'member' roles.",
300
+ parameters: typebox_1.Type.Object({
301
+ teamId: typebox_1.Type.String({ description: "UUID of the team" }),
302
+ userId: typebox_1.Type.String({ description: "UUID of the user to update" }),
303
+ role: typebox_1.Type.Union([typebox_1.Type.Literal("admin"), typebox_1.Type.Literal("member")], { description: "New role: 'admin' or 'member'" }),
304
+ }),
305
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
306
+ return toolkit.updateTeamMemberRole(String(params.teamId ?? ""), String(params.userId ?? ""), String(params.role ?? ""));
307
+ },
308
+ });
309
+ // ── Tool 22: topup_paypal ────────────────────────────────────────────────
310
+ pi.registerTool({
311
+ name: "dominusnode_topup_paypal",
312
+ label: "DominusNode: Top Up Wallet via PayPal",
313
+ description: "Create a PayPal checkout session to add funds to the Dominus Node wallet. Returns a payment URL to redirect the user to.",
314
+ parameters: typebox_1.Type.Object({
315
+ amountCents: typebox_1.Type.Number({ description: "Amount to add in cents (min: 500 = $5.00, max: 1,000,000 = $10,000.00)", minimum: 500, maximum: 1000000 }),
316
+ }),
317
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
318
+ return toolkit.topupPaypal(Number(params.amountCents));
319
+ },
320
+ });
321
+ // ── Tool 23: topup_stripe ────────────────────────────────────────────────
322
+ pi.registerTool({
323
+ name: "dominusnode_topup_stripe",
324
+ label: "DominusNode: Top Up Wallet via Stripe",
325
+ description: "Create a Stripe checkout session to add funds to the Dominus Node wallet. Supports cards and Link. Returns a payment URL.",
326
+ parameters: typebox_1.Type.Object({
327
+ amountCents: typebox_1.Type.Number({ description: "Amount to add in cents (min: 500 = $5.00, max: 1,000,000 = $10,000.00)", minimum: 500, maximum: 1000000 }),
328
+ }),
329
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
330
+ return toolkit.topupStripe(Number(params.amountCents));
331
+ },
332
+ });
333
+ // ── Tool 24: topup_crypto ────────────────────────────────────────────────
334
+ pi.registerTool({
335
+ name: "dominusnode_topup_crypto",
336
+ label: "DominusNode: Top Up Wallet via Crypto",
337
+ description: "Create a cryptocurrency invoice to add funds to the Dominus Node wallet. " +
338
+ "Supported currencies: BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, LINK. " +
339
+ "Returns a payment address and invoice details.",
340
+ parameters: typebox_1.Type.Object({
341
+ amountUsd: typebox_1.Type.Number({ description: "Amount in USD (min: $5, max: $10,000)", minimum: 5, maximum: 10000 }),
342
+ currency: typebox_1.Type.String({ description: "Crypto currency code: BTC, ETH, LTC, XMR, ZEC, USDC, SOL, USDT, DAI, BNB, or LINK" }),
343
+ }),
344
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
345
+ return toolkit.topupCrypto(Number(params.amountUsd), String(params.currency ?? ""));
346
+ },
347
+ });
348
+ // ── Tool 25: x402_info ───────────────────────────────────────────────────
349
+ pi.registerTool({
350
+ name: "dominusnode_x402_info",
351
+ label: "DominusNode: x402 Micropayment Info",
352
+ description: "Get x402 micropayment configuration: payment facilitator addresses, supported chains (Base, Polygon, Solana, etc.), " +
353
+ "USDC contract addresses, and price-per-request details for autonomous agent payments.",
354
+ parameters: typebox_1.Type.Object({}),
355
+ async execute(_id, _params, _signal, _onUpdate, _ctx) {
356
+ return toolkit.x402Info();
357
+ },
358
+ });
359
+ // ── Tool 26: update_wallet_policy ────────────────────────────────────────
360
+ pi.registerTool({
361
+ name: "dominusnode_update_wallet_policy",
362
+ label: "DominusNode: Update Agentic Wallet Policy",
363
+ description: "Update spending policy for an agentic sub-wallet: set a daily spending limit or restrict it to allowed domains.",
364
+ parameters: typebox_1.Type.Object({
365
+ walletId: typebox_1.Type.String({ description: "UUID of the agentic wallet" }),
366
+ dailyLimitCents: typebox_1.Type.Optional(typebox_1.Type.Number({ description: "Daily spending limit in cents (0 = no limit)", minimum: 0, maximum: 1000000 })),
367
+ allowedDomains: typebox_1.Type.Optional(typebox_1.Type.Array(typebox_1.Type.String(), { description: "List of domains this wallet is permitted to make requests to (e.g. ['example.com', 'api.service.io'])" })),
368
+ }),
369
+ async execute(_id, params, _signal, _onUpdate, _ctx) {
370
+ return toolkit.updateWalletPolicy(String(params.walletId ?? ""), params.dailyLimitCents !== undefined ? Number(params.dailyLimitCents) : undefined, params.allowedDomains !== undefined ? params.allowedDomains : undefined);
371
+ },
372
+ });
373
+ }