@agentdomain/eliza-plugin 0.7.0 → 0.8.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 +39 -5
- package/dist/index.js +20 -19
- package/dist/text-parsing.d.ts +14 -0
- package/dist/text-parsing.js +226 -0
- package/package.json +22 -7
package/README.md
CHANGED
|
@@ -1,22 +1,51 @@
|
|
|
1
1
|
# @agentdomain/eliza-plugin
|
|
2
2
|
|
|
3
|
-
ElizaOS
|
|
3
|
+
ElizaOS actions for AgentDomain identity infrastructure.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
|
-
npm install @agentdomain/eliza-plugin
|
|
8
|
+
npm install @agentdomain/eliza-plugin @elizaos/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Add the plugin
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import agentDomainPlugin from '@agentdomain/eliza-plugin';
|
|
15
|
+
|
|
16
|
+
export const character = {
|
|
17
|
+
name: 'Domain Agent',
|
|
18
|
+
plugins: [agentDomainPlugin],
|
|
19
|
+
};
|
|
7
20
|
```
|
|
8
21
|
|
|
22
|
+
## Actions
|
|
23
|
+
|
|
9
24
|
The plugin gives Eliza agents a complete AgentDomain lifecycle surface:
|
|
10
25
|
|
|
11
26
|
- Registration quote and x402 registration
|
|
12
27
|
- Registry discovery
|
|
13
28
|
- 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
|
|
29
|
+
- Typed DNS management for all 13 supported types, including capabilities, revision-safe batches, and BIND import/export
|
|
15
30
|
- SSL repair/reconfiguration
|
|
16
31
|
- RenewalVault status, funding, and auto-renew
|
|
17
32
|
- Per-agent Premium Plan status and upgrades
|
|
18
33
|
|
|
19
|
-
|
|
34
|
+
## Runtime configuration
|
|
35
|
+
|
|
36
|
+
The default API is `https://api.agentdomain.app/api/v1`. Configure
|
|
37
|
+
`AGENTDOMAIN_API_URL` only for a documented alternate environment.
|
|
38
|
+
|
|
39
|
+
- `AGENTDOMAIN_API_KEY` authorizes agent-scoped DNS, email, and management calls.
|
|
40
|
+
- `AGENT_PRIVATE_KEY` is needed only for wallet-authorized or paid operations.
|
|
41
|
+
- `AGENTDOMAIN_NETWORK` defaults to `base`.
|
|
42
|
+
- `BASE_RPC_URL` optionally selects the Base RPC used for wallet operations.
|
|
43
|
+
- `RENEWAL_VAULT_ADDRESS` is required for direct auto-renew actions.
|
|
44
|
+
- `AGENTDOMAIN_BUILDER_CODE` identifies the public application for supported
|
|
45
|
+
direct Base transactions.
|
|
46
|
+
|
|
47
|
+
Inject credentials with the runtime's secret facility. Do not place a private
|
|
48
|
+
key or API key in a character file, repository, command line, or log.
|
|
20
49
|
|
|
21
50
|
Set `AGENTDOMAIN_BUILDER_CODE` to your public ERC-8021 app identifier whenever
|
|
22
51
|
the runtime can submit direct Base writes. The value is not a private key.
|
|
@@ -25,4 +54,9 @@ or invalid attribution stops the direct transaction before submission. Reads,
|
|
|
25
54
|
offchain signatures, Ethereum L1 ENS operations, and standard x402 v2 paid
|
|
26
55
|
requests are not changed.
|
|
27
56
|
|
|
28
|
-
|
|
57
|
+
## Links
|
|
58
|
+
|
|
59
|
+
- [ElizaOS guide](https://docs.agentdomain.app/frameworks/elizaos)
|
|
60
|
+
- [API discovery](https://api.agentdomain.app/api/v1)
|
|
61
|
+
- [Source](https://github.com/0xmdrakib/AgentDomain/tree/main/packages/eliza-plugin)
|
|
62
|
+
- [Security policy](https://github.com/0xmdrakib/AgentDomain/security/policy)
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { createPublicClient, createWalletClient, http } from 'viem';
|
|
|
5
5
|
import { privateKeyToAccount } from 'viem/accounts';
|
|
6
6
|
import { base, baseSepolia } from 'viem/chains';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
+
import { extractEmailAddresses, extractFencedBlock, parseCompactQuantity, readLabeledEmail, readLabeledEmailUsername, readLabeledRemainder, } from './text-parsing.js';
|
|
8
9
|
/** Builds the attributed direct calldata used by Eliza's post-registration auto-renew step. */
|
|
9
10
|
export function encodeElizaAutoRenewCalldata(tokenId, builderCode) {
|
|
10
11
|
if (!builderCode) {
|
|
@@ -42,8 +43,6 @@ function getClients(runtime, opts = {}) {
|
|
|
42
43
|
const TLD_PATTERN = new RegExp(String.raw `([a-z0-9-]{3,63})\.([a-z]{2,20})\b`, 'i');
|
|
43
44
|
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;
|
|
44
45
|
const AMOUNT_PATTERN = /\$?\s*(\d+(?:\.\d{1,6})?)\s*(?:usdc)?/i;
|
|
45
|
-
const EMAIL_PATTERN = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i;
|
|
46
|
-
const EMAIL_GLOBAL_PATTERN = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi;
|
|
47
46
|
const EMAIL_USERNAME_PATTERN = /^[a-z0-9](?:[a-z0-9._+-]{0,62}[a-z0-9])?$/;
|
|
48
47
|
const registerSchema = z.object({
|
|
49
48
|
preferredName: z.string(),
|
|
@@ -108,9 +107,9 @@ function parseRegistrationPlan(lower) {
|
|
|
108
107
|
function parsePlan(text) {
|
|
109
108
|
const lower = text.toLowerCase();
|
|
110
109
|
if (lower.includes('enterprise')) {
|
|
111
|
-
const
|
|
112
|
-
const monthly =
|
|
113
|
-
? Math.round(
|
|
110
|
+
const quantity = parseCompactQuantity(lower);
|
|
111
|
+
const monthly = quantity
|
|
112
|
+
? Math.round(quantity.value * (quantity.suffix === 'm' ? 1_000_000 : 1_000))
|
|
114
113
|
: 100_000;
|
|
115
114
|
return {
|
|
116
115
|
plan: 'enterprise',
|
|
@@ -123,27 +122,29 @@ function parseDnsRecord(text) {
|
|
|
123
122
|
const lower = text.toLowerCase();
|
|
124
123
|
const typeMatch = text.match(/\b(A|AAAA|ALIAS|CAA|CNAME|HTTPS|MX|NS|PTR|SRV|SVCB|TLSA|TXT)\b/i);
|
|
125
124
|
const nameMatch = text.match(/\bname[:=]\s*([^\s]+)/i);
|
|
126
|
-
const
|
|
125
|
+
const value = readLabeledRemainder(text, ['value'], {
|
|
126
|
+
stopLabels: ['ttl', 'priority'],
|
|
127
|
+
});
|
|
127
128
|
const ttlMatch = text.match(/\bttl[:=]\s*(\d+)/i);
|
|
128
129
|
const priorityMatch = text.match(/\bpriority[:=]\s*(\d+)/i);
|
|
129
130
|
const parsed = dnsRecordSchema.parse({
|
|
130
131
|
type: typeMatch?.[1]?.toUpperCase() ?? (lower.includes('txt') ? 'TXT' : 'A'),
|
|
131
132
|
name: nameMatch?.[1] ?? '@',
|
|
132
|
-
value:
|
|
133
|
+
value: value ?? text.match(/\b(?:\d{1,3}\.){3}\d{1,3}\b/)?.[0] ?? '',
|
|
133
134
|
ttl: ttlMatch ? Number(ttlMatch[1]) : 3600,
|
|
134
135
|
priority: priorityMatch ? Number(priorityMatch[1]) : undefined,
|
|
135
136
|
});
|
|
136
137
|
return parsed;
|
|
137
138
|
}
|
|
138
139
|
function parseDnsRecordsJson(text) {
|
|
139
|
-
const fenced = text
|
|
140
|
+
const fenced = extractFencedBlock(text, ['json']);
|
|
140
141
|
const json = fenced ?? text.slice(text.indexOf('['), text.lastIndexOf(']') + 1);
|
|
141
142
|
if (!json)
|
|
142
143
|
throw new Error('A JSON array of DNS records is required');
|
|
143
144
|
return z.array(sharedDnsRecordSchema).min(1).max(200).parse(JSON.parse(json));
|
|
144
145
|
}
|
|
145
146
|
function parseZoneFile(text) {
|
|
146
|
-
const fenced = text
|
|
147
|
+
const fenced = extractFencedBlock(text, ['bind', 'zone', 'dns']);
|
|
147
148
|
if (!fenced?.trim())
|
|
148
149
|
throw new Error('Put the BIND zone records inside a fenced code block');
|
|
149
150
|
return fenced.trim();
|
|
@@ -162,20 +163,20 @@ function requireDnsRevision(value) {
|
|
|
162
163
|
return value;
|
|
163
164
|
}
|
|
164
165
|
function parseEmailUsername(text) {
|
|
165
|
-
const explicit = text
|
|
166
|
+
const explicit = readLabeledEmailUsername(text, ['email username', 'primary email', 'username', 'alias']) ??
|
|
167
|
+
extractEmailAddresses(text)[0]?.split('@')[0];
|
|
166
168
|
const username = explicit?.trim().toLowerCase();
|
|
167
169
|
return username && EMAIL_USERNAME_PATTERN.test(username) ? username : null;
|
|
168
170
|
}
|
|
169
171
|
function parseEmailRequest(text) {
|
|
170
|
-
const fromAddress = text
|
|
171
|
-
const explicitTo = text
|
|
172
|
-
const emails = text
|
|
172
|
+
const fromAddress = readLabeledEmail(text, ['from']);
|
|
173
|
+
const explicitTo = readLabeledEmail(text, ['to']);
|
|
174
|
+
const emails = extractEmailAddresses(text);
|
|
173
175
|
const to = explicitTo ?? emails.find((email) => email.toLowerCase() !== fromAddress?.toLowerCase());
|
|
174
176
|
if (!to)
|
|
175
177
|
throw new Error('Recipient email address is required');
|
|
176
|
-
const subject = text
|
|
177
|
-
const body =
|
|
178
|
-
text.replace(to, '').trim();
|
|
178
|
+
const subject = readLabeledRemainder(text, ['subject'], { stopCharacter: '|' }) ?? 'AgentDomain message';
|
|
179
|
+
const body = readLabeledRemainder(text, ['text', 'body', 'message']) ?? text.replace(to, '').trim();
|
|
179
180
|
return { to, fromAddress, subject, text: body || 'Hello from AgentDomain.' };
|
|
180
181
|
}
|
|
181
182
|
export const quoteRegistrationAction = {
|
|
@@ -412,7 +413,7 @@ export const deleteEmailAliasAction = {
|
|
|
412
413
|
handler: async (runtime, message) => {
|
|
413
414
|
const { ad } = getClients(runtime);
|
|
414
415
|
const agentId = requireAgentId(message.content.text);
|
|
415
|
-
const emailAddress = message.content.text
|
|
416
|
+
const emailAddress = extractEmailAddresses(message.content.text)[0];
|
|
416
417
|
if (!emailAddress)
|
|
417
418
|
throw new Error('Full alias email address is required');
|
|
418
419
|
const result = await ad.deleteEmailAlias(agentId, emailAddress);
|
|
@@ -470,7 +471,7 @@ export const enableAutoRenewAction = {
|
|
|
470
471
|
};
|
|
471
472
|
export const reconfigureSslAction = {
|
|
472
473
|
name: 'RECONFIGURE_SSL',
|
|
473
|
-
description: 'Rebuild the
|
|
474
|
+
description: 'Rebuild the managed SSL hostname and sync DNS validation records for an AgentDomain identity.',
|
|
474
475
|
similes: ['FIX_SSL', 'REPAIR_SSL', 'SYNC_SSL'],
|
|
475
476
|
examples: [],
|
|
476
477
|
validate: async (runtime) => Boolean(runtime.getSetting('AGENT_PRIVATE_KEY')),
|
|
@@ -509,7 +510,7 @@ export const dnsCapabilitiesAction = {
|
|
|
509
510
|
const { ad } = getClients(runtime);
|
|
510
511
|
const result = await ad.getDnsCapabilities(requireAgentId(message.content.text));
|
|
511
512
|
return {
|
|
512
|
-
text: `AgentDomain supports ${result.supportedTypes.length}
|
|
513
|
+
text: `AgentDomain supports ${result.supportedTypes.length} DNS record types.`,
|
|
513
514
|
data: result,
|
|
514
515
|
};
|
|
515
516
|
},
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface CompactQuantity {
|
|
2
|
+
value: number;
|
|
3
|
+
suffix: 'k' | 'm';
|
|
4
|
+
}
|
|
5
|
+
export declare function readLabeledRemainder(text: string, labels: readonly string[], options?: {
|
|
6
|
+
requireSeparator?: boolean;
|
|
7
|
+
stopCharacter?: string;
|
|
8
|
+
stopLabels?: readonly string[];
|
|
9
|
+
}): string | undefined;
|
|
10
|
+
export declare function readLabeledEmailUsername(text: string, labels: readonly string[]): string | undefined;
|
|
11
|
+
export declare function extractEmailAddresses(text: string): string[];
|
|
12
|
+
export declare function readLabeledEmail(text: string, labels: readonly string[]): string | undefined;
|
|
13
|
+
export declare function extractFencedBlock(text: string, optionalLanguages: readonly string[]): string | undefined;
|
|
14
|
+
export declare function parseCompactQuantity(text: string): CompactQuantity | undefined;
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
function isAsciiWhitespace(character) {
|
|
2
|
+
return character === ' ' || character === '\t' || character === '\r' || character === '\n';
|
|
3
|
+
}
|
|
4
|
+
function isAsciiDigit(character) {
|
|
5
|
+
return character !== undefined && character >= '0' && character <= '9';
|
|
6
|
+
}
|
|
7
|
+
function isAsciiLetter(character) {
|
|
8
|
+
return (character !== undefined &&
|
|
9
|
+
((character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z')));
|
|
10
|
+
}
|
|
11
|
+
function isAsciiAlphanumeric(character) {
|
|
12
|
+
return isAsciiDigit(character) || isAsciiLetter(character);
|
|
13
|
+
}
|
|
14
|
+
function isWordCharacter(character) {
|
|
15
|
+
return isAsciiAlphanumeric(character) || character === '_';
|
|
16
|
+
}
|
|
17
|
+
function isEmailLocalCharacter(character) {
|
|
18
|
+
return (isAsciiAlphanumeric(character) ||
|
|
19
|
+
character === '.' ||
|
|
20
|
+
character === '_' ||
|
|
21
|
+
character === '%' ||
|
|
22
|
+
character === '+' ||
|
|
23
|
+
character === '-');
|
|
24
|
+
}
|
|
25
|
+
function isEmailDomainCharacter(character) {
|
|
26
|
+
return isAsciiAlphanumeric(character) || character === '.' || character === '-';
|
|
27
|
+
}
|
|
28
|
+
function skipWhitespace(text, start) {
|
|
29
|
+
let cursor = start;
|
|
30
|
+
while (cursor < text.length && isAsciiWhitespace(text[cursor]))
|
|
31
|
+
cursor += 1;
|
|
32
|
+
return cursor;
|
|
33
|
+
}
|
|
34
|
+
function asciiCharactersEqual(left, right) {
|
|
35
|
+
if (left === right)
|
|
36
|
+
return true;
|
|
37
|
+
if (left === undefined || !isAsciiLetter(left) || !isAsciiLetter(right))
|
|
38
|
+
return false;
|
|
39
|
+
return (left.charCodeAt(0) | 32) === (right.charCodeAt(0) | 32);
|
|
40
|
+
}
|
|
41
|
+
function matchesAsciiCaseInsensitive(text, pattern, start) {
|
|
42
|
+
if (start + pattern.length > text.length)
|
|
43
|
+
return false;
|
|
44
|
+
for (let offset = 0; offset < pattern.length; offset += 1) {
|
|
45
|
+
if (!asciiCharactersEqual(text[start + offset], pattern[offset]))
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
function findLabeledValue(text, labels, requireSeparator, fromIndex = 0, requireWhitespaceBefore = false) {
|
|
51
|
+
let best = null;
|
|
52
|
+
for (const label of labels) {
|
|
53
|
+
let searchFrom = fromIndex;
|
|
54
|
+
while (searchFrom + label.length <= text.length) {
|
|
55
|
+
if (!matchesAsciiCaseInsensitive(text, label, searchFrom)) {
|
|
56
|
+
searchFrom += 1;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
const labelStart = searchFrom;
|
|
60
|
+
const labelEnd = labelStart + label.length;
|
|
61
|
+
const hasStartBoundary = labelStart === 0 || !isWordCharacter(text[labelStart - 1]);
|
|
62
|
+
const hasEndBoundary = labelEnd === text.length || !isWordCharacter(text[labelEnd]);
|
|
63
|
+
const hasRequiredWhitespace = !requireWhitespaceBefore ||
|
|
64
|
+
labelStart === fromIndex ||
|
|
65
|
+
isAsciiWhitespace(text[labelStart - 1]);
|
|
66
|
+
if (hasStartBoundary && hasEndBoundary && hasRequiredWhitespace) {
|
|
67
|
+
let valueStart = skipWhitespace(text, labelEnd);
|
|
68
|
+
const hasSeparator = text[valueStart] === ':' || text[valueStart] === '=';
|
|
69
|
+
if (hasSeparator)
|
|
70
|
+
valueStart = skipWhitespace(text, valueStart + 1);
|
|
71
|
+
if (!requireSeparator || hasSeparator) {
|
|
72
|
+
if (best === null || labelStart < best.labelStart)
|
|
73
|
+
best = { labelStart, valueStart };
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
searchFrom += 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return best;
|
|
81
|
+
}
|
|
82
|
+
export function readLabeledRemainder(text, labels, options = {}) {
|
|
83
|
+
const match = findLabeledValue(text, labels, options.requireSeparator ?? true);
|
|
84
|
+
if (match === null)
|
|
85
|
+
return undefined;
|
|
86
|
+
let valueEnd = text.length;
|
|
87
|
+
if (options.stopCharacter) {
|
|
88
|
+
const stop = text.indexOf(options.stopCharacter, match.valueStart);
|
|
89
|
+
if (stop >= 0)
|
|
90
|
+
valueEnd = stop;
|
|
91
|
+
}
|
|
92
|
+
if (options.stopLabels?.length) {
|
|
93
|
+
const stop = findLabeledValue(text, options.stopLabels, true, match.valueStart, true);
|
|
94
|
+
if (stop !== null && stop.labelStart < valueEnd)
|
|
95
|
+
valueEnd = stop.labelStart;
|
|
96
|
+
}
|
|
97
|
+
const value = text.slice(match.valueStart, valueEnd).trim();
|
|
98
|
+
return value || undefined;
|
|
99
|
+
}
|
|
100
|
+
export function readLabeledEmailUsername(text, labels) {
|
|
101
|
+
const match = findLabeledValue(text, labels, false);
|
|
102
|
+
if (match === null || !isEmailLocalCharacter(text[match.valueStart]))
|
|
103
|
+
return undefined;
|
|
104
|
+
let end = match.valueStart;
|
|
105
|
+
while (end < text.length && isEmailLocalCharacter(text[end]))
|
|
106
|
+
end += 1;
|
|
107
|
+
return text.slice(match.valueStart, end);
|
|
108
|
+
}
|
|
109
|
+
function isValidDomain(domain) {
|
|
110
|
+
let labelStart = 0;
|
|
111
|
+
let dotCount = 0;
|
|
112
|
+
for (let index = 0; index <= domain.length; index += 1) {
|
|
113
|
+
if (index < domain.length && domain[index] !== '.') {
|
|
114
|
+
if (!isAsciiAlphanumeric(domain[index]) && domain[index] !== '-')
|
|
115
|
+
return false;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (index === labelStart ||
|
|
119
|
+
!isAsciiAlphanumeric(domain[labelStart]) ||
|
|
120
|
+
!isAsciiAlphanumeric(domain[index - 1])) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
if (index < domain.length) {
|
|
124
|
+
dotCount += 1;
|
|
125
|
+
labelStart = index + 1;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (dotCount < 1 || domain.length - labelStart < 2)
|
|
129
|
+
return false;
|
|
130
|
+
for (let index = labelStart; index < domain.length; index += 1) {
|
|
131
|
+
if (!isAsciiLetter(domain[index]))
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
function isValidEmailParts(local, domain) {
|
|
137
|
+
if (!local || local.startsWith('.') || local.endsWith('.') || local.includes('..') || !domain) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return isValidDomain(domain);
|
|
141
|
+
}
|
|
142
|
+
function readEmailAt(text, start) {
|
|
143
|
+
if (!isEmailLocalCharacter(text[start]))
|
|
144
|
+
return { nextIndex: start + 1 };
|
|
145
|
+
let cursor = start;
|
|
146
|
+
while (cursor < text.length && isEmailLocalCharacter(text[cursor]))
|
|
147
|
+
cursor += 1;
|
|
148
|
+
const localEnd = cursor;
|
|
149
|
+
if (text[cursor] !== '@')
|
|
150
|
+
return { nextIndex: cursor };
|
|
151
|
+
cursor += 1;
|
|
152
|
+
const domainStart = cursor;
|
|
153
|
+
while (cursor < text.length && isEmailDomainCharacter(text[cursor]))
|
|
154
|
+
cursor += 1;
|
|
155
|
+
let addressEnd = cursor;
|
|
156
|
+
while (addressEnd > domainStart && text[addressEnd - 1] === '.')
|
|
157
|
+
addressEnd -= 1;
|
|
158
|
+
const local = text.slice(start, localEnd);
|
|
159
|
+
const domain = text.slice(domainStart, addressEnd);
|
|
160
|
+
return {
|
|
161
|
+
email: isValidEmailParts(local, domain) ? text.slice(start, addressEnd) : undefined,
|
|
162
|
+
nextIndex: Math.max(cursor, start + 1),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
export function extractEmailAddresses(text) {
|
|
166
|
+
const emails = [];
|
|
167
|
+
let cursor = 0;
|
|
168
|
+
while (cursor < text.length) {
|
|
169
|
+
if (!isEmailLocalCharacter(text[cursor])) {
|
|
170
|
+
cursor += 1;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const result = readEmailAt(text, cursor);
|
|
174
|
+
if (result.email)
|
|
175
|
+
emails.push(result.email);
|
|
176
|
+
cursor = result.nextIndex;
|
|
177
|
+
}
|
|
178
|
+
return emails;
|
|
179
|
+
}
|
|
180
|
+
export function readLabeledEmail(text, labels) {
|
|
181
|
+
const match = findLabeledValue(text, labels, true);
|
|
182
|
+
if (match === null)
|
|
183
|
+
return undefined;
|
|
184
|
+
return readEmailAt(text, match.valueStart).email;
|
|
185
|
+
}
|
|
186
|
+
export function extractFencedBlock(text, optionalLanguages) {
|
|
187
|
+
const openingFence = text.indexOf('```');
|
|
188
|
+
if (openingFence < 0)
|
|
189
|
+
return undefined;
|
|
190
|
+
let contentStart = openingFence + 3;
|
|
191
|
+
for (const language of optionalLanguages) {
|
|
192
|
+
if (matchesAsciiCaseInsensitive(text, language, contentStart)) {
|
|
193
|
+
contentStart += language.length;
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
contentStart = skipWhitespace(text, contentStart);
|
|
198
|
+
const closingFence = text.indexOf('```', contentStart);
|
|
199
|
+
return closingFence < 0 ? undefined : text.slice(contentStart, closingFence);
|
|
200
|
+
}
|
|
201
|
+
export function parseCompactQuantity(text) {
|
|
202
|
+
let cursor = 0;
|
|
203
|
+
while (cursor < text.length) {
|
|
204
|
+
if (!isAsciiDigit(text[cursor])) {
|
|
205
|
+
cursor += 1;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
const numberStart = cursor;
|
|
209
|
+
while (cursor < text.length && isAsciiDigit(text[cursor]))
|
|
210
|
+
cursor += 1;
|
|
211
|
+
if (text[cursor] === '.' && isAsciiDigit(text[cursor + 1])) {
|
|
212
|
+
cursor += 1;
|
|
213
|
+
while (cursor < text.length && isAsciiDigit(text[cursor]))
|
|
214
|
+
cursor += 1;
|
|
215
|
+
}
|
|
216
|
+
const numberEnd = cursor;
|
|
217
|
+
const suffixIndex = skipWhitespace(text, cursor);
|
|
218
|
+
const suffix = text[suffixIndex]?.toLowerCase();
|
|
219
|
+
if (suffix === 'k' || suffix === 'm') {
|
|
220
|
+
const value = Number(text.slice(numberStart, numberEnd));
|
|
221
|
+
if (Number.isFinite(value))
|
|
222
|
+
return { value, suffix };
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentdomain/eliza-plugin",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "ElizaOS plugin for AgentDomain
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "ElizaOS plugin for AgentDomain identity, DNS, email, and renewal workflows",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agentdomain",
|
|
7
|
+
"ai-agents",
|
|
8
|
+
"elizaos",
|
|
9
|
+
"identity",
|
|
10
|
+
"x402",
|
|
11
|
+
"base"
|
|
12
|
+
],
|
|
5
13
|
"license": "Apache-2.0",
|
|
6
|
-
"repository":
|
|
7
|
-
|
|
8
|
-
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/0xmdrakib/AgentDomain.git",
|
|
17
|
+
"directory": "packages/eliza-plugin"
|
|
18
|
+
},
|
|
19
|
+
"homepage": "https://docs.agentdomain.app/frameworks/elizaos",
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/0xmdrakib/AgentDomain/issues"
|
|
22
|
+
},
|
|
9
23
|
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
10
25
|
"main": "./dist/index.js",
|
|
11
26
|
"types": "./dist/index.d.ts",
|
|
12
27
|
"exports": {
|
|
@@ -28,8 +43,8 @@
|
|
|
28
43
|
"dependencies": {
|
|
29
44
|
"viem": "^2.55.2",
|
|
30
45
|
"zod": "^3.24.1",
|
|
31
|
-
"@agentdomain/sdk": "^0.
|
|
32
|
-
"@agentdomain/shared": "^0.
|
|
46
|
+
"@agentdomain/sdk": "^0.8.0",
|
|
47
|
+
"@agentdomain/shared": "^0.8.0"
|
|
33
48
|
},
|
|
34
49
|
"peerDependencies": {
|
|
35
50
|
"@elizaos/core": "^1.0.0"
|