@agentdomain/eliza-plugin 0.1.1 → 0.2.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,10 @@ 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
13
+ - Agent email send/list, primary address update, and Pro/Enterprise aliases
14
14
  - DNS management
15
15
  - SSL repair/reconfiguration
16
16
  - RenewalVault status, funding, and auto-renew
17
- - Per-agent service-plan status and upgrades
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`.
package/dist/index.d.ts CHANGED
@@ -81,6 +81,49 @@ export declare const sendEmailAction: {
81
81
  data: import("@agentdomain/sdk").EmailResult;
82
82
  }>;
83
83
  };
84
+ export declare const updatePrimaryEmailAction: {
85
+ name: string;
86
+ description: string;
87
+ similes: string[];
88
+ examples: never[];
89
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
90
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
91
+ text: string;
92
+ data: {
93
+ inbox: unknown;
94
+ addresses: import("@agentdomain/sdk").EmailAddressSummary[];
95
+ message: string;
96
+ };
97
+ }>;
98
+ };
99
+ export declare const createEmailAliasAction: {
100
+ name: string;
101
+ description: string;
102
+ similes: string[];
103
+ examples: never[];
104
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
105
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
106
+ text: string;
107
+ data: {
108
+ address: import("@agentdomain/sdk").EmailAddressSummary;
109
+ addresses: import("@agentdomain/sdk").EmailAddressSummary[];
110
+ };
111
+ }>;
112
+ };
113
+ export declare const deleteEmailAliasAction: {
114
+ name: string;
115
+ description: string;
116
+ similes: string[];
117
+ examples: never[];
118
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
119
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
120
+ text: string;
121
+ data: {
122
+ deleted: true;
123
+ addresses: import("@agentdomain/sdk").EmailAddressSummary[];
124
+ };
125
+ }>;
126
+ };
84
127
  export declare const renewalStatusAction: {
85
128
  name: string;
86
129
  description: string;
@@ -182,6 +225,17 @@ export declare const servicePlanStatusAction: {
182
225
  data: import("@agentdomain/sdk").ServicePlanStatusResult;
183
226
  }>;
184
227
  };
228
+ export declare const setRegistryVisibilityAction: {
229
+ name: string;
230
+ description: string;
231
+ similes: string[];
232
+ examples: never[];
233
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
234
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
235
+ text: string;
236
+ data: import("@agentdomain/sdk").RegistryVisibilityResult;
237
+ }>;
238
+ };
185
239
  export declare const purchaseServicePlanAction: {
186
240
  name: string;
187
241
  description: string;
@@ -261,6 +315,46 @@ export declare const agentDomainPlugin: {
261
315
  text: string;
262
316
  data: import("@agentdomain/sdk").EmailResult;
263
317
  }>;
318
+ } | {
319
+ name: string;
320
+ description: string;
321
+ similes: string[];
322
+ examples: never[];
323
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
324
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
325
+ text: string;
326
+ data: {
327
+ inbox: unknown;
328
+ addresses: import("@agentdomain/sdk").EmailAddressSummary[];
329
+ message: string;
330
+ };
331
+ }>;
332
+ } | {
333
+ name: string;
334
+ description: string;
335
+ similes: string[];
336
+ examples: never[];
337
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
338
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
339
+ text: string;
340
+ data: {
341
+ address: import("@agentdomain/sdk").EmailAddressSummary;
342
+ addresses: import("@agentdomain/sdk").EmailAddressSummary[];
343
+ };
344
+ }>;
345
+ } | {
346
+ name: string;
347
+ description: string;
348
+ similes: string[];
349
+ examples: never[];
350
+ validate: (runtime: IAgentRuntime) => Promise<boolean>;
351
+ handler: (runtime: IAgentRuntime, message: Memory) => Promise<{
352
+ text: string;
353
+ data: {
354
+ deleted: true;
355
+ addresses: import("@agentdomain/sdk").EmailAddressSummary[];
356
+ };
357
+ }>;
264
358
  } | {
265
359
  name: string;
266
360
  description: string;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AgentDomain } from '@agentdomain/sdk';
2
- import { AGENTDOMAIN_API_BASE_URL, SUPPORTED_TLDS } from '@agentdomain/shared/constants';
2
+ import { AGENTDOMAIN_API_BASE_URL, SERVICE_PLAN_KEYS, SUPPORTED_TLDS, } from '@agentdomain/shared/constants';
3
3
  import { createPublicClient, createWalletClient, http, } from 'viem';
4
4
  import { privateKeyToAccount } from 'viem/accounts';
5
5
  import { base, baseSepolia } from 'viem/chains';
@@ -33,14 +33,23 @@ const TLD_PATTERN = new RegExp(String.raw `([a-z0-9-]{3,63})\.([a-z]{2,20})\b`,
33
33
  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
34
  const AMOUNT_PATTERN = /\$?\s*(\d+(?:\.\d{1,6})?)\s*(?:usdc)?/i;
35
35
  const EMAIL_PATTERN = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i;
36
+ const EMAIL_GLOBAL_PATTERN = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi;
37
+ const EMAIL_USERNAME_PATTERN = /^[a-z0-9](?:[a-z0-9._+-]{0,62}[a-z0-9])?$/;
36
38
  const registerSchema = z.object({
37
39
  preferredName: z.string(),
38
40
  tld: z.enum(SUPPORTED_TLDS).default('xyz'),
39
41
  registerBasename: z.boolean().default(true),
40
42
  registerEns: z.boolean().default(false),
41
- emailEnabled: z.boolean().default(false),
43
+ emailEnabled: z.boolean().default(true),
44
+ emailUsername: z
45
+ .string()
46
+ .trim()
47
+ .toLowerCase()
48
+ .regex(EMAIL_USERNAME_PATTERN)
49
+ .default('agent'),
42
50
  years: z.number().int().min(1).max(10).default(1),
43
51
  autoRenew: z.boolean().default(false),
52
+ premiumPlan: z.enum(SERVICE_PLAN_KEYS).default('included'),
44
53
  });
45
54
  const dnsRecordSchema = z.object({
46
55
  type: z.enum(['A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'TXT', 'NS', 'SRV']),
@@ -57,19 +66,17 @@ function parseParamsFromText(text) {
57
66
  lower.includes('without basename') ||
58
67
  lower.includes('skip basename');
59
68
  const noEns = lower.includes('no ens') || lower.includes('without ens') || lower.includes('skip ens');
60
- const noEmail = lower.includes('no email') ||
61
- lower.includes('without email') ||
62
- lower.includes('skip email') ||
63
- lower.includes('no inbox');
64
69
  const wantsEns = /\bens\b/.test(lower);
65
70
  return {
66
71
  preferredName: m?.[1]?.toLowerCase() ?? 'agent',
67
72
  tld: m?.[2]?.toLowerCase() ?? 'xyz',
68
73
  registerBasename: !noBasename,
69
74
  registerEns: wantsEns && !noEns,
70
- emailEnabled: (lower.includes('email') || lower.includes('inbox')) && !noEmail,
75
+ emailEnabled: true,
76
+ emailUsername: parseEmailUsername(text) ?? 'agent',
71
77
  years: yearsMatch ? parseInt(yearsMatch[1], 10) : 1,
72
78
  autoRenew: lower.includes('auto renew') || lower.includes('auto-renew') || lower.includes('autorenew'),
79
+ premiumPlan: parseRegistrationPlan(lower),
73
80
  };
74
81
  }
75
82
  function requireAgentId(text) {
@@ -84,15 +91,17 @@ function parseAmountUsdc(text) {
84
91
  throw new Error('USDC amount is required');
85
92
  return amount;
86
93
  }
94
+ function parseRegistrationPlan(lower) {
95
+ if (lower.includes('enterprise'))
96
+ return 'enterprise';
97
+ if (lower.includes('pro'))
98
+ return 'pro';
99
+ return 'included';
100
+ }
87
101
  function parsePlan(text) {
88
102
  const lower = text.toLowerCase();
89
103
  const plan = lower.includes('enterprise') ? 'enterprise' : 'pro';
90
- const interval = lower.includes('year') || lower.includes('annual') ? 'yearly' : 'monthly';
91
- return { plan, interval };
92
- }
93
- function parsePrepayPeriods(text) {
94
- const match = text.match(/\bprepay\s+([1-9]|1[0-2])\s*(?:periods?|months?|years?)?/i);
95
- return match ? Number(match[1]) : 1;
104
+ return { plan };
96
105
  }
97
106
  function parseDnsRecord(text) {
98
107
  const lower = text.toLowerCase();
@@ -110,14 +119,23 @@ function parseDnsRecord(text) {
110
119
  });
111
120
  return parsed;
112
121
  }
122
+ function parseEmailUsername(text) {
123
+ const explicit = text.match(/\b(?:email\s+username|primary\s+email|username|alias)[:=]?\s*([a-z0-9._+-]{1,64})/i)?.[1] ??
124
+ text.match(EMAIL_PATTERN)?.[0]?.split('@')[0];
125
+ const username = explicit?.trim().toLowerCase();
126
+ return username && EMAIL_USERNAME_PATTERN.test(username) ? username : null;
127
+ }
113
128
  function parseEmailRequest(text) {
114
- const to = text.match(EMAIL_PATTERN)?.[0];
129
+ const fromAddress = text.match(/\bfrom[:=]\s*([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})/i)?.[1];
130
+ const explicitTo = text.match(/\bto[:=]\s*([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})/i)?.[1];
131
+ const emails = text.match(EMAIL_GLOBAL_PATTERN) ?? [];
132
+ const to = explicitTo ?? emails.find((email) => email.toLowerCase() !== fromAddress?.toLowerCase());
115
133
  if (!to)
116
134
  throw new Error('Recipient email address is required');
117
135
  const subject = text.match(/\bsubject[:=]\s*([^|]+)/i)?.[1]?.trim() ?? 'AgentDomain message';
118
136
  const body = text.match(/\b(?:text|body|message)[:=]\s*([\s\S]+)/i)?.[1]?.trim() ??
119
137
  text.replace(to, '').trim();
120
- return { to, subject, text: body || 'Hello from AgentDomain.' };
138
+ return { to, fromAddress, subject, text: body || 'Hello from AgentDomain.' };
121
139
  }
122
140
  export const quoteRegistrationAction = {
123
141
  name: 'QUOTE_AGENT_REGISTRATION',
@@ -130,22 +148,22 @@ export const quoteRegistrationAction = {
130
148
  const { ad } = getClients(runtime);
131
149
  const quote = await ad.quote(params);
132
150
  return {
133
- text: `Total: $${quote.totalUsdc} USDC for ${quote.domain}. Domain $${quote.domainCostUsdc}, SSL $${quote.sslCertificationFeeUsdc}, service $${quote.serviceFeeUsdc}.`,
151
+ text: `Total: $${quote.totalUsdc} USDC for ${quote.domain}. Domain $${quote.domainCostUsdc}, platform $${quote.platformFeeUsdc ?? quote.serviceFeeUsdc}; email and SSL are included.`,
134
152
  data: quote,
135
153
  };
136
154
  },
137
155
  };
138
156
  export const registerIdentityAction = {
139
157
  name: 'REGISTER_IDENTITY',
140
- description: 'Register a complete agent identity bundle on AgentDomain. Domain, DNS, SSL certification, and service fee are mandatory. Users can say "no basename" to skip Basename, "with ENS" to add ENS, and "with email" to add email.',
158
+ 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.',
141
159
  similes: ['CLAIM_DOMAIN', 'CREATE_IDENTITY', 'GET_DOMAIN'],
142
160
  examples: [
143
161
  [
144
- { user: 'user1', content: { text: 'Register me as helpful-bot.ai with email' } },
162
+ { user: 'user1', content: { text: 'Register me as helpful-bot.ai email username support' } },
145
163
  {
146
164
  user: 'agent',
147
165
  content: {
148
- text: "I'll register helpful-bot.ai with email infrastructure now.",
166
+ text: "I'll register helpful-bot.ai with included email and SSL infrastructure now.",
149
167
  action: 'REGISTER_IDENTITY',
150
168
  },
151
169
  },
@@ -160,6 +178,7 @@ export const registerIdentityAction = {
160
178
  throw new Error('AGENT_PRIVATE_KEY not set');
161
179
  const result = await ad.register({
162
180
  ...validated,
181
+ emailEnabled: true,
163
182
  wallet: account.address,
164
183
  });
165
184
  let autoRenewMsg = '';
@@ -233,7 +252,7 @@ export const listEmailAction = {
233
252
  };
234
253
  export const sendEmailAction = {
235
254
  name: 'SEND_AGENT_EMAIL',
236
- description: 'Send text-only email from an AgentDomain identity.',
255
+ description: 'Send text-only email from an AgentDomain primary address or active alias.',
237
256
  similes: ['SEND_EMAIL', 'EMAIL_FROM_AGENT'],
238
257
  examples: [],
239
258
  validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
@@ -245,6 +264,54 @@ export const sendEmailAction = {
245
264
  return { text: `Email sent: ${result.id}.`, data: result };
246
265
  },
247
266
  };
267
+ export const updatePrimaryEmailAction = {
268
+ name: 'UPDATE_PRIMARY_EMAIL',
269
+ description: 'Change an AgentDomain primary email username. The old primary address stops receiving new mail.',
270
+ similes: ['CHANGE_PRIMARY_EMAIL', 'RENAME_EMAIL'],
271
+ examples: [],
272
+ validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
273
+ handler: async (runtime, message) => {
274
+ const { ad } = getClients(runtime);
275
+ const agentId = requireAgentId(message.content.text);
276
+ const username = parseEmailUsername(message.content.text);
277
+ if (!username)
278
+ throw new Error('New email username is required');
279
+ const result = await ad.updatePrimaryEmail(agentId, username);
280
+ return { text: result.message, data: result };
281
+ },
282
+ };
283
+ export const createEmailAliasAction = {
284
+ name: 'CREATE_EMAIL_ALIAS',
285
+ description: 'Create a receive-and-send email alias for an AgentDomain identity. Requires available Pro or Enterprise alias capacity.',
286
+ similes: ['ADD_EMAIL_ALIAS', 'CREATE_ALIAS'],
287
+ examples: [],
288
+ validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
289
+ handler: async (runtime, message) => {
290
+ const { ad } = getClients(runtime);
291
+ const agentId = requireAgentId(message.content.text);
292
+ const username = parseEmailUsername(message.content.text);
293
+ if (!username)
294
+ throw new Error('Alias username is required');
295
+ const result = await ad.createEmailAlias(agentId, username);
296
+ return { text: `Created email alias ${result.address.emailAddress}.`, data: result };
297
+ },
298
+ };
299
+ export const deleteEmailAliasAction = {
300
+ name: 'DELETE_EMAIL_ALIAS',
301
+ description: 'Delete an active AgentDomain email alias.',
302
+ similes: ['REMOVE_EMAIL_ALIAS', 'DELETE_ALIAS'],
303
+ examples: [],
304
+ validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
305
+ handler: async (runtime, message) => {
306
+ const { ad } = getClients(runtime);
307
+ const agentId = requireAgentId(message.content.text);
308
+ const emailAddress = message.content.text.match(EMAIL_PATTERN)?.[0];
309
+ if (!emailAddress)
310
+ throw new Error('Full alias email address is required');
311
+ const result = await ad.deleteEmailAlias(agentId, emailAddress);
312
+ return { text: `Deleted email alias ${emailAddress}.`, data: result };
313
+ },
314
+ };
248
315
  export const renewalStatusAction = {
249
316
  name: 'GET_RENEWAL_STATUS',
250
317
  description: 'Get RenewalVault balance, shortfall, renewal amount, and auto-renew state.',
@@ -375,7 +442,7 @@ export const deleteDnsAction = {
375
442
  };
376
443
  export const servicePlanStatusAction = {
377
444
  name: 'GET_SERVICE_PLAN',
378
- description: 'Get an agent service plan, limits, current period, and billing state.',
445
+ description: 'Get an agent Premium Plan, limits, current period, and billing state.',
379
446
  similes: ['PLAN_STATUS', 'CHECK_PLAN'],
380
447
  examples: [],
381
448
  validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
@@ -384,14 +451,36 @@ export const servicePlanStatusAction = {
384
451
  const agentId = requireAgentId(message.content.text);
385
452
  const result = await ad.getServicePlan(agentId);
386
453
  return {
387
- text: `${result.domain} is on ${result.entitlement.plan}. Email limit ${result.entitlement.limits.emailPerHour}/hour, DNS limit ${result.entitlement.limits.dnsRecords}.`,
454
+ text: `${result.domain} is on ${result.entitlement.plan}. Email limit ${result.entitlement.limits.emailPerHour}/hour, DNS limit ${result.entitlement.limits.dnsRecords}, registry hidden ${result.registryVisibility.hidden}.`,
455
+ data: result,
456
+ };
457
+ },
458
+ };
459
+ export const setRegistryVisibilityAction = {
460
+ name: 'SET_REGISTRY_VISIBILITY',
461
+ description: 'Hide or show an agent in the public AgentDomain registry. Hiding requires an active Pro or Enterprise Premium Plan.',
462
+ similes: ['HIDE_AGENT_REGISTRY', 'SHOW_AGENT_REGISTRY', 'REGISTRY_VISIBILITY'],
463
+ examples: [],
464
+ validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY') || runtime.getSetting('AGENTDOMAIN_API_KEY')),
465
+ handler: async (runtime, message) => {
466
+ const { ad } = getClients(runtime);
467
+ const agentId = requireAgentId(message.content.text);
468
+ const text = message.content.text.toLowerCase();
469
+ const wantsPublic = text.includes('unhide') ||
470
+ text.includes('show') ||
471
+ text.includes('visible') ||
472
+ text.includes('public');
473
+ const registryHidden = !wantsPublic && (text.includes('hide') || text.includes('private'));
474
+ const result = await ad.setRegistryVisibility(agentId, registryHidden);
475
+ return {
476
+ text: `${result.domain} is now ${result.registryVisibility.hidden ? 'hidden from' : 'visible in'} the public registry.`,
388
477
  data: result,
389
478
  };
390
479
  },
391
480
  };
392
481
  export const purchaseServicePlanAction = {
393
482
  name: 'PURCHASE_SERVICE_PLAN',
394
- description: 'Upgrade an agent to AgentDomain Pro or Enterprise using x402 USDC.',
483
+ description: 'Upgrade an agent to AgentDomain Pro or Enterprise Premium Plan using x402 USDC.',
395
484
  similes: ['BUY_PLAN', 'UPGRADE_PLAN'],
396
485
  examples: [],
397
486
  validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY')),
@@ -402,11 +491,9 @@ export const purchaseServicePlanAction = {
402
491
  const result = await ad.purchaseServicePlan({
403
492
  agentId,
404
493
  ...plan,
405
- autoRenew: message.content.text.toLowerCase().includes('auto'),
406
- prepayPeriods: parsePrepayPeriods(message.content.text),
407
494
  });
408
495
  return {
409
- text: `Purchased ${result.entitlement.plan} ${plan.interval} for ${result.domain}.`,
496
+ text: `Purchased ${result.entitlement.plan} Premium Plan for ${result.domain}.`,
410
497
  data: result,
411
498
  };
412
499
  },
@@ -420,6 +507,9 @@ export const agentDomainPlugin = {
420
507
  searchAgentsAction,
421
508
  sendEmailAction,
422
509
  listEmailAction,
510
+ updatePrimaryEmailAction,
511
+ createEmailAliasAction,
512
+ deleteEmailAliasAction,
423
513
  renewalStatusAction,
424
514
  fundRenewalAction,
425
515
  enableAutoRenewAction,
@@ -429,6 +519,7 @@ export const agentDomainPlugin = {
429
519
  updateDnsAction,
430
520
  deleteDnsAction,
431
521
  servicePlanStatusAction,
522
+ setRegistryVisibilityAction,
432
523
  purchaseServicePlanAction,
433
524
  ],
434
525
  evaluators: [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentdomain/eliza-plugin",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "ElizaOS plugin for AgentDomain - give your Eliza agent a complete identity stack",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -21,10 +21,10 @@
21
21
  "access": "public"
22
22
  },
23
23
  "dependencies": {
24
- "viem": "^2.21.55",
24
+ "viem": "^2.55.2",
25
25
  "zod": "^3.24.1",
26
- "@agentdomain/sdk": "^0.1.1",
27
- "@agentdomain/shared": "^0.1.1"
26
+ "@agentdomain/sdk": "^0.2.0",
27
+ "@agentdomain/shared": "^0.2.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "@elizaos/core": "^1.0.0"