@agentdomain/eliza-plugin 0.5.0 → 0.6.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/README.md CHANGED
@@ -10,10 +10,12 @@ The plugin gives Eliza agents a complete AgentDomain lifecycle surface:
10
10
 
11
11
  - Registration quote and x402 registration
12
12
  - Registry discovery
13
- - Agent email send/list/delete/batch, monthly usage, signed inbound webhooks, primary address updates, and Starter/Pro/Enterprise aliases
14
- - DNS management
13
+ - Agent email send/list/batch, monthly usage, signed inbound webhooks, primary address updates, and Starter/Pro/Enterprise aliases
14
+ - Typed DNS management for all 13 Spaceship-supported types, including capabilities, revision-safe batches, and BIND import/export
15
15
  - SSL repair/reconfiguration
16
16
  - RenewalVault status, funding, and auto-renew
17
- - Per-agent Premium Plan status, upgrades, and exact next-renewal tier selection
17
+ - Per-agent Premium Plan status and upgrades
18
18
 
19
19
  Configure `AGENTDOMAIN_API_URL` only if you need a custom endpoint. The default is `https://agentdomain.app/api/v1`.
20
+
21
+ Request the default base URL directly to retrieve AgentDomain's machine-readable API discovery metadata.
package/dist/index.d.ts CHANGED
@@ -234,6 +234,17 @@ export declare const listDnsAction: {
234
234
  data: import("@agentdomain/shared").DnsRecord[];
235
235
  }>;
236
236
  };
237
+ export declare const dnsCapabilitiesAction: {
238
+ name: string;
239
+ description: string;
240
+ similes: string[];
241
+ examples: never[];
242
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
243
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
244
+ text: string;
245
+ data: import("@agentdomain/shared").DnsCapabilities;
246
+ }>;
247
+ };
237
248
  export declare const createDnsAction: {
238
249
  name: string;
239
250
  description: string;
@@ -269,6 +280,42 @@ export declare const deleteDnsAction: {
269
280
  };
270
281
  }>;
271
282
  };
283
+ export declare const changeDnsRecordsAction: {
284
+ name: string;
285
+ description: string;
286
+ similes: string[];
287
+ examples: never[];
288
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
289
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
290
+ text: string;
291
+ data: import("@agentdomain/shared").DnsChangePreview;
292
+ }>;
293
+ };
294
+ export declare const importDnsZoneAction: {
295
+ name: string;
296
+ description: string;
297
+ similes: string[];
298
+ examples: never[];
299
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
300
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
301
+ text: string;
302
+ data: import("@agentdomain/shared").DnsChangePreview;
303
+ }>;
304
+ };
305
+ export declare const exportDnsZoneAction: {
306
+ name: string;
307
+ description: string;
308
+ similes: string[];
309
+ examples: never[];
310
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
311
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
312
+ text: string;
313
+ data: {
314
+ format: string;
315
+ zone: string;
316
+ };
317
+ }>;
318
+ };
272
319
  export declare const servicePlanStatusAction: {
273
320
  name: string;
274
321
  description: string;
@@ -512,6 +559,16 @@ export declare const agentDomainPlugin: {
512
559
  text: string;
513
560
  data: import("@agentdomain/shared").DnsRecord[];
514
561
  }>;
562
+ } | {
563
+ name: string;
564
+ description: string;
565
+ similes: string[];
566
+ examples: never[];
567
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
568
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
569
+ text: string;
570
+ data: import("@agentdomain/shared").DnsCapabilities;
571
+ }>;
515
572
  } | {
516
573
  name: string;
517
574
  description: string;
@@ -534,6 +591,29 @@ export declare const agentDomainPlugin: {
534
591
  success: boolean;
535
592
  };
536
593
  }>;
594
+ } | {
595
+ name: string;
596
+ description: string;
597
+ similes: string[];
598
+ examples: never[];
599
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
600
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
601
+ text: string;
602
+ data: import("@agentdomain/shared").DnsChangePreview;
603
+ }>;
604
+ } | {
605
+ name: string;
606
+ description: string;
607
+ similes: string[];
608
+ examples: never[];
609
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
610
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
611
+ text: string;
612
+ data: {
613
+ format: string;
614
+ zone: string;
615
+ };
616
+ }>;
537
617
  } | {
538
618
  name: string;
539
619
  description: string;
package/dist/index.js CHANGED
@@ -1,24 +1,38 @@
1
- import { AgentDomain } from '@agentdomain/sdk';
2
- import { AGENTDOMAIN_API_BASE_URL, SERVICE_PLAN_KEYS, SUPPORTED_TLDS, } from '@agentdomain/shared/constants';
3
- import { createPublicClient, createWalletClient, http, } from 'viem';
4
- import { privateKeyToAccount } from 'viem/accounts';
5
- import { base, baseSepolia } from 'viem/chains';
6
- import { z } from 'zod';
1
+ import { AgentDomain } from "@agentdomain/sdk";
2
+ import { AGENTDOMAIN_API_BASE_URL, SERVICE_PLAN_KEYS, SUPPORTED_TLDS, } from "@agentdomain/shared/constants";
3
+ import { DNS_RECORD_TYPES, dnsRecordSchema as sharedDnsRecordSchema, } from "@agentdomain/shared";
4
+ import { createPublicClient, createWalletClient, http, } from "viem";
5
+ import { privateKeyToAccount } from "viem/accounts";
6
+ import { base, baseSepolia } from "viem/chains";
7
+ import { z } from "zod";
7
8
  function getClients(runtime, opts = {}) {
8
- const apiUrl = runtime.getSetting('AGENTDOMAIN_API_URL') ?? AGENTDOMAIN_API_BASE_URL;
9
- const apiKey = runtime.getSetting('AGENTDOMAIN_API_KEY');
10
- const pk = runtime.getSetting('AGENT_PRIVATE_KEY');
11
- const rpc = runtime.getSetting('BASE_RPC_URL') ?? 'https://mainnet.base.org';
12
- const network = runtime.getSetting('AGENTDOMAIN_NETWORK') ?? 'base';
13
- const chain = network === 'base-sepolia' ? baseSepolia : base;
9
+ const apiUrl = runtime.getSetting("AGENTDOMAIN_API_URL") ?? AGENTDOMAIN_API_BASE_URL;
10
+ const apiKey = runtime.getSetting("AGENTDOMAIN_API_KEY");
11
+ const pk = runtime.getSetting("AGENT_PRIVATE_KEY");
12
+ const rpc = runtime.getSetting("BASE_RPC_URL") ?? "https://mainnet.base.org";
13
+ const network = runtime.getSetting("AGENTDOMAIN_NETWORK") ??
14
+ "base";
15
+ const chain = network === "base-sepolia" ? baseSepolia : base;
14
16
  if (!pk) {
15
17
  if (opts.requireWallet)
16
- throw new Error('AGENT_PRIVATE_KEY not set');
18
+ throw new Error("AGENT_PRIVATE_KEY not set");
17
19
  const ad = new AgentDomain({ apiUrl, apiKey, network });
18
- return { ad, account: null, walletClient: null, publicClient: null, network, chain, rpc };
20
+ return {
21
+ ad,
22
+ account: null,
23
+ walletClient: null,
24
+ publicClient: null,
25
+ network,
26
+ chain,
27
+ rpc,
28
+ };
19
29
  }
20
30
  const account = privateKeyToAccount(pk);
21
- const walletClient = createWalletClient({ account, chain, transport: http(rpc) });
31
+ const walletClient = createWalletClient({
32
+ account,
33
+ chain,
34
+ transport: http(rpc),
35
+ });
22
36
  const publicClient = createPublicClient({ chain, transport: http(rpc) });
23
37
  const ad = new AgentDomain({
24
38
  apiUrl,
@@ -29,7 +43,7 @@ function getClients(runtime, opts = {}) {
29
43
  });
30
44
  return { ad, account, walletClient, publicClient, network, chain, rpc };
31
45
  }
32
- const TLD_PATTERN = new RegExp(String.raw `([a-z0-9-]{3,63})\.([a-z]{2,20})\b`, 'i');
46
+ const TLD_PATTERN = new RegExp(String.raw `([a-z0-9-]{3,63})\.([a-z]{2,20})\b`, "i");
33
47
  const UUID_PATTERN = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i;
34
48
  const AMOUNT_PATTERN = /\$?\s*(\d+(?:\.\d{1,6})?)\s*(?:usdc)?/i;
35
49
  const EMAIL_PATTERN = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i;
@@ -37,19 +51,24 @@ const EMAIL_GLOBAL_PATTERN = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi;
37
51
  const EMAIL_USERNAME_PATTERN = /^[a-z0-9](?:[a-z0-9._+-]{0,62}[a-z0-9])?$/;
38
52
  const registerSchema = z.object({
39
53
  preferredName: z.string(),
40
- tld: z.enum(SUPPORTED_TLDS).default('xyz'),
54
+ tld: z.enum(SUPPORTED_TLDS).default("xyz"),
41
55
  registerBasename: z.boolean().default(true),
42
56
  registerEns: z.boolean().default(false),
43
57
  emailEnabled: z.boolean().default(true),
44
- emailUsername: z.string().trim().toLowerCase().regex(EMAIL_USERNAME_PATTERN).default('agent'),
58
+ emailUsername: z
59
+ .string()
60
+ .trim()
61
+ .toLowerCase()
62
+ .regex(EMAIL_USERNAME_PATTERN)
63
+ .default("agent"),
45
64
  years: z.number().int().min(1).max(10).default(1),
46
65
  autoRenew: z.boolean().default(false),
47
- premiumPlan: z.enum(SERVICE_PLAN_KEYS).default('included'),
66
+ premiumPlan: z.enum(SERVICE_PLAN_KEYS).default("included"),
48
67
  });
49
68
  const dnsRecordSchema = z.object({
50
- type: z.enum(['A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'TXT', 'NS', 'SRV']),
69
+ type: z.enum(DNS_RECORD_TYPES),
51
70
  name: z.string(),
52
- value: z.string(),
71
+ value: z.string().min(1).max(65_535),
53
72
  ttl: z.number().int().min(60).max(3600).default(3600),
54
73
  priority: z.number().int().min(0).optional(),
55
74
  });
@@ -57,76 +76,112 @@ function parseParamsFromText(text) {
57
76
  const m = text.match(TLD_PATTERN);
58
77
  const lower = text.toLowerCase();
59
78
  const yearsMatch = lower.match(/([1-9]|10)\s*years?/);
60
- const noBasename = lower.includes('no basename') ||
61
- lower.includes('without basename') ||
62
- lower.includes('skip basename');
63
- const noEns = lower.includes('no ens') || lower.includes('without ens') || lower.includes('skip ens');
79
+ const noBasename = lower.includes("no basename") ||
80
+ lower.includes("without basename") ||
81
+ lower.includes("skip basename");
82
+ const noEns = lower.includes("no ens") ||
83
+ lower.includes("without ens") ||
84
+ lower.includes("skip ens");
64
85
  const wantsEns = /\bens\b/.test(lower);
65
86
  return {
66
- preferredName: m?.[1]?.toLowerCase() ?? 'agent',
67
- tld: m?.[2]?.toLowerCase() ?? 'xyz',
87
+ preferredName: m?.[1]?.toLowerCase() ?? "agent",
88
+ tld: m?.[2]?.toLowerCase() ?? "xyz",
68
89
  registerBasename: !noBasename,
69
90
  registerEns: wantsEns && !noEns,
70
91
  emailEnabled: true,
71
- emailUsername: parseEmailUsername(text) ?? 'agent',
92
+ emailUsername: parseEmailUsername(text) ?? "agent",
72
93
  years: yearsMatch ? parseInt(yearsMatch[1], 10) : 1,
73
- autoRenew: lower.includes('auto renew') || lower.includes('auto-renew') || lower.includes('autorenew'),
94
+ autoRenew: lower.includes("auto renew") ||
95
+ lower.includes("auto-renew") ||
96
+ lower.includes("autorenew"),
74
97
  premiumPlan: parseRegistrationPlan(lower),
75
98
  };
76
99
  }
77
100
  function requireAgentId(text) {
78
101
  const agentId = text.match(UUID_PATTERN)?.[0];
79
102
  if (!agentId)
80
- throw new Error('Agent ID UUID is required');
103
+ throw new Error("Agent ID UUID is required");
81
104
  return agentId;
82
105
  }
83
106
  function parseAmountUsdc(text) {
84
107
  const amount = text.match(AMOUNT_PATTERN)?.[1];
85
108
  if (!amount)
86
- throw new Error('USDC amount is required');
109
+ throw new Error("USDC amount is required");
87
110
  return amount;
88
111
  }
89
112
  function parseRegistrationPlan(lower) {
90
- if (lower.includes('enterprise'))
91
- return 'enterprise';
92
- if (lower.includes('pro'))
93
- return 'pro';
94
- if (lower.includes('starter'))
95
- return 'starter';
96
- return 'included';
113
+ if (lower.includes("enterprise"))
114
+ return "enterprise";
115
+ if (lower.includes("pro"))
116
+ return "pro";
117
+ if (lower.includes("starter"))
118
+ return "starter";
119
+ return "included";
97
120
  }
98
121
  function parsePlan(text) {
99
122
  const lower = text.toLowerCase();
100
- if (lower.includes('enterprise')) {
123
+ if (lower.includes("enterprise")) {
101
124
  const match = lower.match(/(\d+(?:\.\d+)?)\s*(k|m)/);
102
125
  const monthly = match
103
- ? Math.round(Number(match[1]) * (match[2] === 'm' ? 1_000_000 : 1_000))
126
+ ? Math.round(Number(match[1]) * (match[2] === "m" ? 1_000_000 : 1_000))
104
127
  : 100_000;
105
128
  return {
106
- plan: 'enterprise',
129
+ plan: "enterprise",
107
130
  planSku: `enterprise-${monthly}`,
108
131
  };
109
132
  }
110
- return { plan: lower.includes('starter') ? 'starter' : 'pro' };
133
+ return { plan: lower.includes("starter") ? "starter" : "pro" };
111
134
  }
112
135
  function parseDnsRecord(text) {
113
136
  const lower = text.toLowerCase();
114
- const typeMatch = text.match(/\b(A|AAAA|ALIAS|CNAME|MX|TXT|NS|SRV)\b/i);
137
+ const typeMatch = text.match(/\b(A|AAAA|ALIAS|CAA|CNAME|HTTPS|MX|NS|PTR|SRV|SVCB|TLSA|TXT)\b/i);
115
138
  const nameMatch = text.match(/\bname[:=]\s*([^\s]+)/i);
116
- const valueMatch = text.match(/\bvalue[:=]\s*([^\s]+)/i);
139
+ const valueMatch = text.match(/\bvalue[:=]\s*(.+?)(?=\s+\b(?:ttl|priority)[:=]|$)/i);
117
140
  const ttlMatch = text.match(/\bttl[:=]\s*(\d+)/i);
118
141
  const priorityMatch = text.match(/\bpriority[:=]\s*(\d+)/i);
119
142
  const parsed = dnsRecordSchema.parse({
120
- type: typeMatch?.[1]?.toUpperCase() ?? (lower.includes('txt') ? 'TXT' : 'A'),
121
- name: nameMatch?.[1] ?? '@',
122
- value: valueMatch?.[1] ?? text.match(/\b(?:\d{1,3}\.){3}\d{1,3}\b/)?.[0] ?? '',
143
+ type: typeMatch?.[1]?.toUpperCase() ?? (lower.includes("txt") ? "TXT" : "A"),
144
+ name: nameMatch?.[1] ?? "@",
145
+ value: valueMatch?.[1]?.trim() ??
146
+ text.match(/\b(?:\d{1,3}\.){3}\d{1,3}\b/)?.[0] ??
147
+ "",
123
148
  ttl: ttlMatch ? Number(ttlMatch[1]) : 3600,
124
149
  priority: priorityMatch ? Number(priorityMatch[1]) : undefined,
125
150
  });
126
151
  return parsed;
127
152
  }
153
+ function parseDnsRecordsJson(text) {
154
+ const fenced = text.match(/```(?:json)?\s*([\s\S]*?)```/i)?.[1];
155
+ const json = fenced ?? text.slice(text.indexOf("["), text.lastIndexOf("]") + 1);
156
+ if (!json)
157
+ throw new Error("A JSON array of DNS records is required");
158
+ return z
159
+ .array(sharedDnsRecordSchema)
160
+ .min(1)
161
+ .max(200)
162
+ .parse(JSON.parse(json));
163
+ }
164
+ function parseZoneFile(text) {
165
+ const fenced = text.match(/```(?:bind|zone|dns)?\s*([\s\S]*?)```/i)?.[1];
166
+ if (!fenced?.trim())
167
+ throw new Error("Put the BIND zone records inside a fenced code block");
168
+ return fenced.trim();
169
+ }
170
+ function parseDnsApplyOptions(text) {
171
+ const lower = text.toLowerCase();
172
+ return {
173
+ mode: lower.includes("replace") ? "replace" : "merge",
174
+ dryRun: !/\bapply\b/i.test(text),
175
+ baseRevision: text.match(/\bbaseRevision[:=]\s*([a-f0-9]{64})/i)?.[1],
176
+ };
177
+ }
178
+ function requireDnsRevision(value) {
179
+ if (!value)
180
+ throw new Error("Apply requires baseRevision from a fresh DNS preview");
181
+ return value;
182
+ }
128
183
  function parseEmailUsername(text) {
129
- const explicit = text.match(/\b(?:email\s+username|primary\s+email|username|alias)[:=]?\s*([a-z0-9._+-]{1,64})/i)?.[1] ?? text.match(EMAIL_PATTERN)?.[0]?.split('@')[0];
184
+ const explicit = text.match(/\b(?:email\s+username|primary\s+email|username|alias)[:=]?\s*([a-z0-9._+-]{1,64})/i)?.[1] ?? text.match(EMAIL_PATTERN)?.[0]?.split("@")[0];
130
185
  const username = explicit?.trim().toLowerCase();
131
186
  return username && EMAIL_USERNAME_PATTERN.test(username) ? username : null;
132
187
  }
@@ -134,18 +189,20 @@ function parseEmailRequest(text) {
134
189
  const fromAddress = text.match(/\bfrom[:=]\s*([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})/i)?.[1];
135
190
  const explicitTo = text.match(/\bto[:=]\s*([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})/i)?.[1];
136
191
  const emails = text.match(EMAIL_GLOBAL_PATTERN) ?? [];
137
- const to = explicitTo ?? emails.find((email) => email.toLowerCase() !== fromAddress?.toLowerCase());
192
+ const to = explicitTo ??
193
+ emails.find((email) => email.toLowerCase() !== fromAddress?.toLowerCase());
138
194
  if (!to)
139
- throw new Error('Recipient email address is required');
140
- const subject = text.match(/\bsubject[:=]\s*([^|]+)/i)?.[1]?.trim() ?? 'AgentDomain message';
195
+ throw new Error("Recipient email address is required");
196
+ const subject = text.match(/\bsubject[:=]\s*([^|]+)/i)?.[1]?.trim() ??
197
+ "AgentDomain message";
141
198
  const body = text.match(/\b(?:text|body|message)[:=]\s*([\s\S]+)/i)?.[1]?.trim() ??
142
- text.replace(to, '').trim();
143
- return { to, fromAddress, subject, text: body || 'Hello from AgentDomain.' };
199
+ text.replace(to, "").trim();
200
+ return { to, fromAddress, subject, text: body || "Hello from AgentDomain." };
144
201
  }
145
202
  export const quoteRegistrationAction = {
146
- name: 'QUOTE_AGENT_REGISTRATION',
147
- description: 'Quote an AgentDomain registration before paying.',
148
- similes: ['PRICE_DOMAIN', 'REGISTRATION_QUOTE', 'QUOTE_IDENTITY'],
203
+ name: "QUOTE_AGENT_REGISTRATION",
204
+ description: "Quote an AgentDomain registration before paying.",
205
+ similes: ["PRICE_DOMAIN", "REGISTRATION_QUOTE", "QUOTE_IDENTITY"],
149
206
  examples: [],
150
207
  validate: async () => true,
151
208
  handler: async (runtime, message) => {
@@ -159,51 +216,58 @@ export const quoteRegistrationAction = {
159
216
  },
160
217
  };
161
218
  export const registerIdentityAction = {
162
- name: 'REGISTER_IDENTITY',
219
+ name: "REGISTER_IDENTITY",
163
220
  description: 'Register a complete agent identity bundle on AgentDomain. Domain, DNS, email setup, SSL certification, AgentID NFT orchestration, and platform fee are included by default. Users can say "no basename" to skip Basename, "with ENS" to add ENS, and "email username support" to customize the primary inbox.',
164
- similes: ['CLAIM_DOMAIN', 'CREATE_IDENTITY', 'GET_DOMAIN'],
221
+ similes: ["CLAIM_DOMAIN", "CREATE_IDENTITY", "GET_DOMAIN"],
165
222
  examples: [
166
223
  [
167
- { user: 'user1', content: { text: 'Register me as helpful-bot.ai email username support' } },
168
224
  {
169
- user: 'agent',
225
+ user: "user1",
226
+ content: {
227
+ text: "Register me as helpful-bot.ai email username support",
228
+ },
229
+ },
230
+ {
231
+ user: "agent",
170
232
  content: {
171
233
  text: "I'll register helpful-bot.ai with included email and SSL infrastructure now.",
172
- action: 'REGISTER_IDENTITY',
234
+ action: "REGISTER_IDENTITY",
173
235
  },
174
236
  },
175
237
  ],
176
238
  ],
177
- validate: async (runtime, _message) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY')),
239
+ validate: async (runtime, _message) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY")),
178
240
  handler: async (runtime, message) => {
179
241
  const params = parseParamsFromText(message.content.text);
180
242
  const validated = registerSchema.parse(params);
181
- const { ad, account, walletClient, chain } = getClients(runtime, { requireWallet: true });
243
+ const { ad, account, walletClient, chain } = getClients(runtime, {
244
+ requireWallet: true,
245
+ });
182
246
  if (!account || !walletClient)
183
- throw new Error('AGENT_PRIVATE_KEY not set');
247
+ throw new Error("AGENT_PRIVATE_KEY not set");
184
248
  const result = await ad.register({
185
249
  ...validated,
186
250
  emailEnabled: true,
187
251
  wallet: account.address,
188
252
  });
189
- let autoRenewMsg = '';
253
+ let autoRenewMsg = "";
190
254
  if (validated.autoRenew) {
191
- const vaultAddress = runtime.getSetting('RENEWAL_VAULT_ADDRESS');
255
+ const vaultAddress = runtime.getSetting("RENEWAL_VAULT_ADDRESS");
192
256
  if (vaultAddress) {
193
257
  try {
194
258
  const txHash = await walletClient.writeContract({
195
259
  address: vaultAddress,
196
260
  abi: [
197
261
  {
198
- type: 'function',
199
- name: 'setAutoRenew',
262
+ type: "function",
263
+ name: "setAutoRenew",
200
264
  inputs: [
201
- { name: 'tokenId', type: 'uint256' },
202
- { name: 'enabled', type: 'bool' },
265
+ { name: "tokenId", type: "uint256" },
266
+ { name: "enabled", type: "bool" },
203
267
  ],
204
268
  },
205
269
  ],
206
- functionName: 'setAutoRenew',
270
+ functionName: "setAutoRenew",
207
271
  args: [BigInt(result.nftTokenId), true],
208
272
  chain,
209
273
  account,
@@ -215,19 +279,20 @@ export const registerIdentityAction = {
215
279
  }
216
280
  }
217
281
  else {
218
- autoRenewMsg = ' (Requires RENEWAL_VAULT_ADDRESS env var to enable auto-renew on-chain).';
282
+ autoRenewMsg =
283
+ " (Requires RENEWAL_VAULT_ADDRESS env var to enable auto-renew on-chain).";
219
284
  }
220
285
  }
221
286
  return {
222
- text: `Registered ${result.domain}${result.basename ? ` and ${result.basename}` : ''}. Token #${result.nftTokenId}.${autoRenewMsg}`,
287
+ text: `Registered ${result.domain}${result.basename ? ` and ${result.basename}` : ""}. Token #${result.nftTokenId}.${autoRenewMsg}`,
223
288
  data: result,
224
289
  };
225
290
  },
226
291
  };
227
292
  export const searchAgentsAction = {
228
- name: 'SEARCH_AGENTS',
229
- description: 'Search the public AgentDomain registry by name, capability, or framework.',
230
- similes: ['FIND_AGENT', 'DISCOVER_AGENT'],
293
+ name: "SEARCH_AGENTS",
294
+ description: "Search the public AgentDomain registry by name, capability, or framework.",
295
+ similes: ["FIND_AGENT", "DISCOVER_AGENT"],
231
296
  examples: [],
232
297
  validate: async () => true,
233
298
  handler: async (runtime, message) => {
@@ -241,41 +306,43 @@ export const searchAgentsAction = {
241
306
  },
242
307
  };
243
308
  export const listEmailAction = {
244
- name: 'LIST_AGENT_EMAIL',
245
- description: 'List text-only email messages and extracted verification codes for an AgentDomain identity.',
246
- similes: ['CHECK_EMAIL', 'READ_INBOX'],
309
+ name: "LIST_AGENT_EMAIL",
310
+ description: "List text-only email messages and extracted verification codes for an AgentDomain identity.",
311
+ similes: ["CHECK_EMAIL", "READ_INBOX"],
247
312
  examples: [],
248
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY')),
313
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY")),
249
314
  handler: async (runtime, message) => {
250
315
  const { ad } = getClients(runtime);
251
316
  const agentId = message.content.text.match(/[0-9a-f-]{36}/i)?.[0];
252
317
  if (!agentId)
253
- throw new Error('Agent ID UUID is required to list email');
318
+ throw new Error("Agent ID UUID is required to list email");
254
319
  const result = await ad.listEmail(agentId, { limit: 20 });
255
320
  return { text: `Found ${result.messages.length} messages.`, data: result };
256
321
  },
257
322
  };
258
323
  export const deleteEmailMessageAction = {
259
- name: 'DELETE_AGENT_EMAIL',
260
- description: 'Permanently delete one AgentDomain email message.',
261
- similes: ['DELETE_EMAIL_MESSAGE', 'REMOVE_EMAIL_MESSAGE'],
324
+ name: "DELETE_AGENT_EMAIL",
325
+ description: "Permanently delete one AgentDomain email message.",
326
+ similes: ["DELETE_EMAIL_MESSAGE", "REMOVE_EMAIL_MESSAGE"],
262
327
  examples: [],
263
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
328
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
329
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
264
330
  handler: async (runtime, message) => {
265
331
  const { ad } = getClients(runtime);
266
- const ids = message.content.text.match(new RegExp(UUID_PATTERN.source, 'gi')) ?? [];
332
+ const ids = message.content.text.match(new RegExp(UUID_PATTERN.source, "gi")) ?? [];
267
333
  if (!ids[0] || !ids[1])
268
- throw new Error('Agent ID and message ID UUIDs are required');
334
+ throw new Error("Agent ID and message ID UUIDs are required");
269
335
  const result = await ad.deleteEmailMessage(ids[0], ids[1]);
270
336
  return { text: `Deleted email message ${ids[1]}.`, data: result };
271
337
  },
272
338
  };
273
339
  export const sendEmailAction = {
274
- name: 'SEND_AGENT_EMAIL',
275
- description: 'Send text-only email from an AgentDomain primary address or active alias.',
276
- similes: ['SEND_EMAIL', 'EMAIL_FROM_AGENT'],
340
+ name: "SEND_AGENT_EMAIL",
341
+ description: "Send text-only email from an AgentDomain primary address or active alias.",
342
+ similes: ["SEND_EMAIL", "EMAIL_FROM_AGENT"],
277
343
  examples: [],
278
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
344
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
345
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
279
346
  handler: async (runtime, message) => {
280
347
  const { ad } = getClients(runtime);
281
348
  const agentId = requireAgentId(message.content.text);
@@ -285,11 +352,12 @@ export const sendEmailAction = {
285
352
  },
286
353
  };
287
354
  export const emailUsageAction = {
288
- name: 'GET_AGENT_EMAIL_USAGE',
289
- description: 'Get combined monthly sent and received email usage.',
290
- similes: ['EMAIL_USAGE', 'EMAIL_QUOTA'],
355
+ name: "GET_AGENT_EMAIL_USAGE",
356
+ description: "Get combined monthly sent and received email usage.",
357
+ similes: ["EMAIL_USAGE", "EMAIL_QUOTA"],
291
358
  examples: [],
292
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
359
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
360
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
293
361
  handler: async (runtime, message) => {
294
362
  const { ad } = getClients(runtime);
295
363
  const result = await ad.getEmailUsage(requireAgentId(message.content.text));
@@ -300,110 +368,123 @@ export const emailUsageAction = {
300
368
  },
301
369
  };
302
370
  export const configureEmailWebhookAction = {
303
- name: 'CONFIGURE_EMAIL_WEBHOOK',
304
- description: 'Configure a signed inbound email webhook. Include an HTTPS URL in the request.',
305
- similes: ['SET_EMAIL_WEBHOOK'],
371
+ name: "CONFIGURE_EMAIL_WEBHOOK",
372
+ description: "Configure a signed inbound email webhook. Include an HTTPS URL in the request.",
373
+ similes: ["SET_EMAIL_WEBHOOK"],
306
374
  examples: [],
307
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
375
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
376
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
308
377
  handler: async (runtime, message) => {
309
378
  const { ad } = getClients(runtime);
310
379
  const agentId = requireAgentId(message.content.text);
311
380
  const url = message.content.text.match(/https:\/\/[^\s]+/)?.[0];
312
381
  if (!url)
313
- throw new Error('HTTPS webhook URL is required');
382
+ throw new Error("HTTPS webhook URL is required");
314
383
  const result = await ad.setEmailWebhook(agentId, {
315
384
  url,
316
- payloadMode: /inline/i.test(message.content.text) ? 'inline_text' : 'metadata',
385
+ payloadMode: /inline/i.test(message.content.text)
386
+ ? "inline_text"
387
+ : "metadata",
317
388
  enabled: true,
318
389
  });
319
- return { text: 'Inbound email webhook configured.', data: result };
390
+ return { text: "Inbound email webhook configured.", data: result };
320
391
  },
321
392
  };
322
393
  export const sendEmailBatchAction = {
323
- name: 'SEND_AGENT_EMAIL_BATCH',
324
- description: 'Queue up to 100 emails supplied as a JSON messages array.',
325
- similes: ['BATCH_EMAIL'],
394
+ name: "SEND_AGENT_EMAIL_BATCH",
395
+ description: "Queue up to 100 emails supplied as a JSON messages array.",
396
+ similes: ["BATCH_EMAIL"],
326
397
  examples: [],
327
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
398
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
399
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
328
400
  handler: async (runtime, message) => {
329
401
  const { ad } = getClients(runtime);
330
402
  const agentId = requireAgentId(message.content.text);
331
- const json = message.content.text.slice(message.content.text.indexOf('{'));
403
+ const json = message.content.text.slice(message.content.text.indexOf("{"));
332
404
  const parsed = JSON.parse(json);
333
- const result = await ad.sendEmailBatch(agentId, { messages: parsed.messages });
405
+ const result = await ad.sendEmailBatch(agentId, {
406
+ messages: parsed.messages,
407
+ });
334
408
  return { text: `Queued ${result.jobs.length} email jobs.`, data: result };
335
409
  },
336
410
  };
337
411
  export const updatePrimaryEmailAction = {
338
- name: 'UPDATE_PRIMARY_EMAIL',
339
- description: 'Change an AgentDomain primary email username. The old primary address stops receiving new mail.',
340
- similes: ['CHANGE_PRIMARY_EMAIL', 'RENAME_EMAIL'],
412
+ name: "UPDATE_PRIMARY_EMAIL",
413
+ description: "Change an AgentDomain primary email username. The old primary address stops receiving new mail.",
414
+ similes: ["CHANGE_PRIMARY_EMAIL", "RENAME_EMAIL"],
341
415
  examples: [],
342
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
416
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
417
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
343
418
  handler: async (runtime, message) => {
344
419
  const { ad } = getClients(runtime);
345
420
  const agentId = requireAgentId(message.content.text);
346
421
  const username = parseEmailUsername(message.content.text);
347
422
  if (!username)
348
- throw new Error('New email username is required');
423
+ throw new Error("New email username is required");
349
424
  const result = await ad.updatePrimaryEmail(agentId, username);
350
425
  return { text: result.message, data: result };
351
426
  },
352
427
  };
353
428
  export const createEmailAliasAction = {
354
- name: 'CREATE_EMAIL_ALIAS',
355
- description: 'Create a receive-and-send email alias for an AgentDomain identity. Requires available paid-plan alias capacity.',
356
- similes: ['ADD_EMAIL_ALIAS', 'CREATE_ALIAS'],
429
+ name: "CREATE_EMAIL_ALIAS",
430
+ description: "Create a receive-and-send email alias for an AgentDomain identity. Requires available paid-plan alias capacity.",
431
+ similes: ["ADD_EMAIL_ALIAS", "CREATE_ALIAS"],
357
432
  examples: [],
358
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
433
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
434
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
359
435
  handler: async (runtime, message) => {
360
436
  const { ad } = getClients(runtime);
361
437
  const agentId = requireAgentId(message.content.text);
362
438
  const username = parseEmailUsername(message.content.text);
363
439
  if (!username)
364
- throw new Error('Alias username is required');
440
+ throw new Error("Alias username is required");
365
441
  const result = await ad.createEmailAlias(agentId, username);
366
- return { text: `Created email alias ${result.address.emailAddress}.`, data: result };
442
+ return {
443
+ text: `Created email alias ${result.address.emailAddress}.`,
444
+ data: result,
445
+ };
367
446
  },
368
447
  };
369
448
  export const deleteEmailAliasAction = {
370
- name: 'DELETE_EMAIL_ALIAS',
371
- description: 'Delete an active AgentDomain email alias.',
372
- similes: ['REMOVE_EMAIL_ALIAS', 'DELETE_ALIAS'],
449
+ name: "DELETE_EMAIL_ALIAS",
450
+ description: "Delete an active AgentDomain email alias.",
451
+ similes: ["REMOVE_EMAIL_ALIAS", "DELETE_ALIAS"],
373
452
  examples: [],
374
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
453
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
454
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
375
455
  handler: async (runtime, message) => {
376
456
  const { ad } = getClients(runtime);
377
457
  const agentId = requireAgentId(message.content.text);
378
458
  const emailAddress = message.content.text.match(EMAIL_PATTERN)?.[0];
379
459
  if (!emailAddress)
380
- throw new Error('Full alias email address is required');
460
+ throw new Error("Full alias email address is required");
381
461
  const result = await ad.deleteEmailAlias(agentId, emailAddress);
382
462
  return { text: `Deleted email alias ${emailAddress}.`, data: result };
383
463
  },
384
464
  };
385
465
  export const renewalStatusAction = {
386
- name: 'GET_RENEWAL_STATUS',
387
- description: 'Get RenewalVault balance, shortfall, renewal amount, and auto-renew state.',
388
- similes: ['RENEWAL_STATUS', 'CHECK_RENEWAL', 'VAULT_STATUS'],
466
+ name: "GET_RENEWAL_STATUS",
467
+ description: "Get RenewalVault balance, shortfall, renewal amount, and auto-renew state.",
468
+ similes: ["RENEWAL_STATUS", "CHECK_RENEWAL", "VAULT_STATUS"],
389
469
  examples: [],
390
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
470
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
471
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
391
472
  handler: async (runtime, message) => {
392
473
  const { ad } = getClients(runtime);
393
474
  const agentId = requireAgentId(message.content.text);
394
475
  const status = await ad.getRenewalStatus(agentId);
395
476
  return {
396
- text: `Renewal for ${status.domain}: next $${status.nextRenewalAmountUsdc}, balance $${status.vaultBalanceUsdc}, shortfall $${status.shortfallUsdc}, auto-renew ${status.autoRenewEnabled ? 'enabled' : 'off'}.`,
477
+ text: `Renewal for ${status.domain}: next $${status.nextRenewalAmountUsdc}, balance $${status.vaultBalanceUsdc}, shortfall $${status.shortfallUsdc}, auto-renew ${status.autoRenewEnabled ? "enabled" : "off"}.`,
397
478
  data: status,
398
479
  };
399
480
  },
400
481
  };
401
482
  export const fundRenewalAction = {
402
- name: 'FUND_RENEWAL_VAULT',
403
- description: 'Deposit USDC into an AgentID renewal vault.',
404
- similes: ['DEPOSIT_RENEWAL', 'FUND_VAULT'],
483
+ name: "FUND_RENEWAL_VAULT",
484
+ description: "Deposit USDC into an AgentID renewal vault.",
485
+ similes: ["DEPOSIT_RENEWAL", "FUND_VAULT"],
405
486
  examples: [],
406
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY')),
487
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY")),
407
488
  handler: async (runtime, message) => {
408
489
  const { ad } = getClients(runtime, { requireWallet: true });
409
490
  const agentId = requireAgentId(message.content.text);
@@ -416,31 +497,35 @@ export const fundRenewalAction = {
416
497
  },
417
498
  };
418
499
  export const enableAutoRenewAction = {
419
- name: 'ENABLE_AUTO_RENEW',
420
- description: 'Enable on-chain RenewalVault auto-renew for an AgentDomain identity.',
421
- similes: ['AUTO_RENEW', 'ENABLE_RENEWAL'],
500
+ name: "ENABLE_AUTO_RENEW",
501
+ description: "Enable on-chain RenewalVault auto-renew for an AgentDomain identity.",
502
+ similes: ["AUTO_RENEW", "ENABLE_RENEWAL"],
422
503
  examples: [],
423
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') && runtime.getSetting('RENEWAL_VAULT_ADDRESS')),
504
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") &&
505
+ runtime.getSetting("RENEWAL_VAULT_ADDRESS")),
424
506
  handler: async (runtime, message) => {
425
507
  const { ad } = getClients(runtime, { requireWallet: true });
426
508
  const agentId = requireAgentId(message.content.text);
427
509
  const result = await ad.setAutoRenew(agentId, true, {
428
- renewalVaultAddress: runtime.getSetting('RENEWAL_VAULT_ADDRESS'),
510
+ renewalVaultAddress: runtime.getSetting("RENEWAL_VAULT_ADDRESS"),
429
511
  });
430
- return { text: `Auto-renew enabled for token #${result.tokenId}.`, data: result };
512
+ return {
513
+ text: `Auto-renew enabled for token #${result.tokenId}.`,
514
+ data: result,
515
+ };
431
516
  },
432
517
  };
433
518
  export const reconfigureSslAction = {
434
- name: 'RECONFIGURE_SSL',
435
- description: 'Rebuild the Cloudflare SaaS SSL hostname and sync Spaceship DNS validation records for an AgentDomain identity.',
436
- similes: ['FIX_SSL', 'REPAIR_SSL', 'SYNC_SSL'],
519
+ name: "RECONFIGURE_SSL",
520
+ description: "Rebuild the Cloudflare SaaS SSL hostname and sync Spaceship DNS validation records for an AgentDomain identity.",
521
+ similes: ["FIX_SSL", "REPAIR_SSL", "SYNC_SSL"],
437
522
  examples: [],
438
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY')),
523
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY")),
439
524
  handler: async (runtime, message) => {
440
525
  const { ad } = getClients(runtime);
441
526
  const agentId = message.content.text.match(/[0-9a-f-]{36}/i)?.[0];
442
527
  if (!agentId)
443
- throw new Error('Agent ID UUID is required to reconfigure SSL');
528
+ throw new Error("Agent ID UUID is required to reconfigure SSL");
444
529
  const result = await ad.reconfigureSsl(agentId);
445
530
  return {
446
531
  text: `SSL reconfigured for ${result.domain}. Status: ${result.sslStatus}.`,
@@ -449,11 +534,12 @@ export const reconfigureSslAction = {
449
534
  },
450
535
  };
451
536
  export const listDnsAction = {
452
- name: 'LIST_DNS_RECORDS',
453
- description: 'List DNS records for an AgentDomain identity.',
454
- similes: ['DNS_RECORDS', 'LIST_DNS'],
537
+ name: "LIST_DNS_RECORDS",
538
+ description: "List DNS records for an AgentDomain identity.",
539
+ similes: ["DNS_RECORDS", "LIST_DNS"],
455
540
  examples: [],
456
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
541
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
542
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
457
543
  handler: async (runtime, message) => {
458
544
  const { ad } = getClients(runtime);
459
545
  const agentId = requireAgentId(message.content.text);
@@ -461,61 +547,146 @@ export const listDnsAction = {
461
547
  return { text: `Found ${records.length} DNS records.`, data: records };
462
548
  },
463
549
  };
550
+ export const dnsCapabilitiesAction = {
551
+ name: "GET_DNS_CAPABILITIES",
552
+ description: "Get AgentDomain DNS record types, validation fields, limits, and provider warnings.",
553
+ similes: ["DNS_CAPABILITIES", "DNS_TYPES", "DNS_LIMITS"],
554
+ examples: [],
555
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
556
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
557
+ handler: async (runtime, message) => {
558
+ const { ad } = getClients(runtime);
559
+ const result = await ad.getDnsCapabilities(requireAgentId(message.content.text));
560
+ return {
561
+ text: `AgentDomain supports ${result.supportedTypes.length} Spaceship DNS record types.`,
562
+ data: result,
563
+ };
564
+ },
565
+ };
464
566
  export const createDnsAction = {
465
- name: 'CREATE_DNS_RECORD',
466
- description: 'Create a user-managed DNS record. Use text like: agentId type A name @ value 1.2.3.4.',
467
- similes: ['ADD_DNS', 'CREATE_DNS'],
567
+ name: "CREATE_DNS_RECORD",
568
+ description: "Create a user-managed DNS record. Use text like: agentId type A name @ value 1.2.3.4.",
569
+ similes: ["ADD_DNS", "CREATE_DNS"],
468
570
  examples: [],
469
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
571
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
572
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
470
573
  handler: async (runtime, message) => {
471
574
  const { ad } = getClients(runtime);
472
575
  const agentId = requireAgentId(message.content.text);
473
576
  const record = parseDnsRecord(message.content.text);
474
577
  const result = await ad.createDnsRecord(agentId, record);
475
- return { text: `Created ${result.type} DNS record ${result.name}.`, data: result };
578
+ return {
579
+ text: `Created ${result.type} DNS record ${result.name}.`,
580
+ data: result,
581
+ };
476
582
  },
477
583
  };
478
584
  export const updateDnsAction = {
479
- name: 'UPDATE_DNS_RECORD',
480
- description: 'Update a user-managed DNS record. Include agent UUID and record UUID.',
481
- similes: ['EDIT_DNS', 'UPDATE_DNS'],
585
+ name: "UPDATE_DNS_RECORD",
586
+ description: "Update a user-managed DNS record. Include agent UUID and record UUID.",
587
+ similes: ["EDIT_DNS", "UPDATE_DNS"],
482
588
  examples: [],
483
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
589
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
590
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
484
591
  handler: async (runtime, message) => {
485
592
  const { ad } = getClients(runtime);
486
- const ids = message.content.text.match(new RegExp(UUID_PATTERN.source, 'gi')) ?? [];
593
+ const ids = message.content.text.match(new RegExp(UUID_PATTERN.source, "gi")) ?? [];
487
594
  const agentId = ids[0];
488
595
  const recordId = ids[1];
489
596
  if (!agentId || !recordId)
490
- throw new Error('Agent ID and record ID UUIDs are required');
597
+ throw new Error("Agent ID and record ID UUIDs are required");
491
598
  const record = parseDnsRecord(message.content.text);
492
599
  const result = await ad.updateDnsRecord(agentId, recordId, record);
493
- return { text: `Updated ${result.type} DNS record ${result.name}.`, data: result };
600
+ return {
601
+ text: `Updated ${result.type} DNS record ${result.name}.`,
602
+ data: result,
603
+ };
494
604
  },
495
605
  };
496
606
  export const deleteDnsAction = {
497
- name: 'DELETE_DNS_RECORD',
498
- description: 'Delete a user-managed DNS record. Include agent UUID and record UUID.',
499
- similes: ['REMOVE_DNS', 'DELETE_DNS'],
607
+ name: "DELETE_DNS_RECORD",
608
+ description: "Delete a user-managed DNS record. Include agent UUID and record UUID.",
609
+ similes: ["REMOVE_DNS", "DELETE_DNS"],
500
610
  examples: [],
501
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
611
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
612
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
502
613
  handler: async (runtime, message) => {
503
614
  const { ad } = getClients(runtime);
504
- const ids = message.content.text.match(new RegExp(UUID_PATTERN.source, 'gi')) ?? [];
615
+ const ids = message.content.text.match(new RegExp(UUID_PATTERN.source, "gi")) ?? [];
505
616
  const agentId = ids[0];
506
617
  const recordId = ids[1];
507
618
  if (!agentId || !recordId)
508
- throw new Error('Agent ID and record ID UUIDs are required');
619
+ throw new Error("Agent ID and record ID UUIDs are required");
509
620
  const result = await ad.deleteDnsRecord(agentId, recordId);
510
621
  return { text: `Deleted DNS record ${recordId}.`, data: result };
511
622
  },
512
623
  };
624
+ export const changeDnsRecordsAction = {
625
+ name: "CHANGE_DNS_RECORDS",
626
+ description: "Preview or apply a revision-protected DNS batch from a JSON array of structured records.",
627
+ similes: ["BATCH_DNS", "PREVIEW_DNS_CHANGES", "APPLY_DNS_CHANGES"],
628
+ examples: [],
629
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
630
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
631
+ handler: async (runtime, message) => {
632
+ const { ad } = getClients(runtime);
633
+ const agentId = requireAgentId(message.content.text);
634
+ const records = parseDnsRecordsJson(message.content.text);
635
+ const options = parseDnsApplyOptions(message.content.text);
636
+ const result = options.dryRun
637
+ ? await ad.previewDnsBatch(agentId, records, options.mode)
638
+ : await ad.applyDnsBatch(agentId, records, requireDnsRevision(options.baseRevision), options.mode);
639
+ return {
640
+ text: options.dryRun
641
+ ? "DNS preview generated."
642
+ : "DNS change set applied.",
643
+ data: result,
644
+ };
645
+ },
646
+ };
647
+ export const importDnsZoneAction = {
648
+ name: "IMPORT_DNS_ZONE",
649
+ description: "Preview or apply a validated BIND DNS zone import.",
650
+ similes: ["DNS_ZONE_IMPORT", "IMPORT_BIND_ZONE"],
651
+ examples: [],
652
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
653
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
654
+ handler: async (runtime, message) => {
655
+ const { ad } = getClients(runtime);
656
+ const agentId = requireAgentId(message.content.text);
657
+ const zoneFile = parseZoneFile(message.content.text);
658
+ const options = parseDnsApplyOptions(message.content.text);
659
+ const result = options.dryRun
660
+ ? await ad.previewDnsImport(agentId, zoneFile, options.mode)
661
+ : await ad.applyDnsImport(agentId, zoneFile, requireDnsRevision(options.baseRevision), options.mode);
662
+ return {
663
+ text: options.dryRun
664
+ ? "DNS import preview generated."
665
+ : "DNS zone import applied.",
666
+ data: result,
667
+ };
668
+ },
669
+ };
670
+ export const exportDnsZoneAction = {
671
+ name: "EXPORT_DNS_ZONE",
672
+ description: "Export AgentDomain DNS records as a standard BIND zone file.",
673
+ similes: ["DNS_ZONE_EXPORT", "EXPORT_BIND_ZONE"],
674
+ examples: [],
675
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
676
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
677
+ handler: async (runtime, message) => {
678
+ const { ad } = getClients(runtime);
679
+ const zone = await ad.exportDnsZone(requireAgentId(message.content.text), /\b(?:all|complete)\b/i.test(message.content.text) ? "all" : "user");
680
+ return { text: zone, data: { format: "bind", zone } };
681
+ },
682
+ };
513
683
  export const servicePlanStatusAction = {
514
- name: 'GET_SERVICE_PLAN',
515
- description: 'Get an agent Premium Plan, limits, current period, and billing state.',
516
- similes: ['PLAN_STATUS', 'CHECK_PLAN'],
684
+ name: "GET_SERVICE_PLAN",
685
+ description: "Get an agent Premium Plan, limits, current period, and billing state.",
686
+ similes: ["PLAN_STATUS", "CHECK_PLAN"],
517
687
  examples: [],
518
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
688
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
689
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
519
690
  handler: async (runtime, message) => {
520
691
  const { ad } = getClients(runtime);
521
692
  const agentId = requireAgentId(message.content.text);
@@ -527,39 +698,45 @@ export const servicePlanStatusAction = {
527
698
  },
528
699
  };
529
700
  export const setRegistryVisibilityAction = {
530
- name: 'SET_REGISTRY_VISIBILITY',
531
- description: 'Hide or show an agent in the public AgentDomain registry. Hiding requires an active paid Premium Plan.',
532
- similes: ['HIDE_AGENT_REGISTRY', 'SHOW_AGENT_REGISTRY', 'REGISTRY_VISIBILITY'],
701
+ name: "SET_REGISTRY_VISIBILITY",
702
+ description: "Hide or show an agent in the public AgentDomain registry. Hiding requires an active paid Premium Plan.",
703
+ similes: [
704
+ "HIDE_AGENT_REGISTRY",
705
+ "SHOW_AGENT_REGISTRY",
706
+ "REGISTRY_VISIBILITY",
707
+ ],
533
708
  examples: [],
534
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
709
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
710
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
535
711
  handler: async (runtime, message) => {
536
712
  const { ad } = getClients(runtime);
537
713
  const agentId = requireAgentId(message.content.text);
538
714
  const text = message.content.text.toLowerCase();
539
- const wantsPublic = text.includes('unhide') ||
540
- text.includes('show') ||
541
- text.includes('visible') ||
542
- text.includes('public');
543
- const registryHidden = !wantsPublic && (text.includes('hide') || text.includes('private'));
715
+ const wantsPublic = text.includes("unhide") ||
716
+ text.includes("show") ||
717
+ text.includes("visible") ||
718
+ text.includes("public");
719
+ const registryHidden = !wantsPublic && (text.includes("hide") || text.includes("private"));
544
720
  const result = await ad.setRegistryVisibility(agentId, registryHidden);
545
721
  return {
546
- text: `${result.domain} is now ${result.registryVisibility.hidden ? 'hidden from' : 'visible in'} the public registry.`,
722
+ text: `${result.domain} is now ${result.registryVisibility.hidden ? "hidden from" : "visible in"} the public registry.`,
547
723
  data: result,
548
724
  };
549
725
  },
550
726
  };
551
727
  export const scheduleServicePlanRenewalAction = {
552
- name: 'SCHEDULE_SERVICE_PLAN_RENEWAL',
553
- description: 'Choose the exact AgentDomain Premium Plan SKU for the next identity renewal.',
554
- similes: ['CHANGE_RENEWAL_PLAN', 'SET_NEXT_RENEWAL_PLAN'],
728
+ name: "SCHEDULE_SERVICE_PLAN_RENEWAL",
729
+ description: "Choose the exact AgentDomain Premium Plan SKU for the next identity renewal.",
730
+ similes: ["CHANGE_RENEWAL_PLAN", "SET_NEXT_RENEWAL_PLAN"],
555
731
  examples: [],
556
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
732
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY") ||
733
+ runtime.getSetting("AGENTDOMAIN_API_KEY")),
557
734
  handler: async (runtime, message) => {
558
735
  const { ad } = getClients(runtime);
559
736
  const agentId = requireAgentId(message.content.text);
560
737
  const lower = message.content.text.toLowerCase();
561
738
  const plan = parseRegistrationPlan(lower);
562
- const parsed = plan === 'enterprise' ? parsePlan(lower) : { plan, planSku: plan };
739
+ const parsed = plan === "enterprise" ? parsePlan(lower) : { plan, planSku: plan };
563
740
  const result = await ad.scheduleServicePlanRenewal(agentId, parsed);
564
741
  return {
565
742
  text: `Scheduled ${result.renewalPlanSku} for the next identity renewal.`,
@@ -568,11 +745,11 @@ export const scheduleServicePlanRenewalAction = {
568
745
  },
569
746
  };
570
747
  export const purchaseServicePlanAction = {
571
- name: 'PURCHASE_SERVICE_PLAN',
572
- description: 'Upgrade an agent to AgentDomain Starter, Pro, or Enterprise using x402 USDC.',
573
- similes: ['BUY_PLAN', 'UPGRADE_PLAN'],
748
+ name: "PURCHASE_SERVICE_PLAN",
749
+ description: "Upgrade an agent to AgentDomain Starter, Pro, or Enterprise using x402 USDC.",
750
+ similes: ["BUY_PLAN", "UPGRADE_PLAN"],
574
751
  examples: [],
575
- validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY')),
752
+ validate: async (runtime) => Boolean(runtime.getSetting("AGENT_PRIVATE_KEY")),
576
753
  handler: async (runtime, message) => {
577
754
  const { ad } = getClients(runtime, { requireWallet: true });
578
755
  const agentId = requireAgentId(message.content.text);
@@ -588,8 +765,8 @@ export const purchaseServicePlanAction = {
588
765
  },
589
766
  };
590
767
  export const agentDomainPlugin = {
591
- name: 'agentdomain',
592
- description: 'Identity infrastructure for AI agents on Base (domain + Basename + DNS + email + SSL).',
768
+ name: "agentdomain",
769
+ description: "Identity infrastructure for AI agents on Base (domain + Basename + DNS + email + SSL).",
593
770
  actions: [
594
771
  quoteRegistrationAction,
595
772
  registerIdentityAction,
@@ -607,10 +784,14 @@ export const agentDomainPlugin = {
607
784
  fundRenewalAction,
608
785
  enableAutoRenewAction,
609
786
  reconfigureSslAction,
787
+ dnsCapabilitiesAction,
610
788
  listDnsAction,
611
789
  createDnsAction,
612
790
  updateDnsAction,
613
791
  deleteDnsAction,
792
+ changeDnsRecordsAction,
793
+ importDnsZoneAction,
794
+ exportDnsZoneAction,
614
795
  servicePlanStatusAction,
615
796
  setRegistryVisibilityAction,
616
797
  scheduleServicePlanRenewalAction,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentdomain/eliza-plugin",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "ElizaOS plugin for AgentDomain - give your Eliza agent a complete identity stack",
5
5
  "license": "Apache-2.0",
6
6
  "repository": "https://github.com/0xmdrakib/AgentDomain.git",
@@ -26,8 +26,8 @@
26
26
  "dependencies": {
27
27
  "viem": "^2.55.2",
28
28
  "zod": "^3.24.1",
29
- "@agentdomain/sdk": "^0.5.0",
30
- "@agentdomain/shared": "^0.5.0"
29
+ "@agentdomain/sdk": "^0.6.0",
30
+ "@agentdomain/shared": "^0.6.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "@elizaos/core": "^1.0.0"