@agenticprimitives/agent-naming 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AUDIT.md +86 -0
- package/CLAUDE.md +180 -0
- package/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/abis.d.ts +1532 -0
- package/dist/abis.d.ts.map +1 -0
- package/dist/abis.js +417 -0
- package/dist/abis.js.map +1 -0
- package/dist/client.d.ts +102 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +299 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -0
- package/dist/custody.d.ts +133 -0
- package/dist/custody.d.ts.map +1 -0
- package/dist/custody.js +214 -0
- package/dist/custody.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +30 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/namehash.d.ts +31 -0
- package/dist/namehash.d.ts.map +1 -0
- package/dist/namehash.js +46 -0
- package/dist/namehash.js.map +1 -0
- package/dist/normalize.d.ts +28 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +68 -0
- package/dist/normalize.js.map +1 -0
- package/dist/records.d.ts +88 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +193 -0
- package/dist/records.js.map +1 -0
- package/dist/types.d.ts +117 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/api.md +110 -0
- package/docs/concepts.md +159 -0
- package/docs/migration.md +93 -0
- package/docs/security.md +127 -0
- package/docs/troubleshooting.md +116 -0
- package/examples/basic.ts +31 -0
- package/examples/custody-rotation.ts +44 -0
- package/examples/records.ts +41 -0
- package/package.json +71 -0
- package/spec.md +14 -0
package/dist/records.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Predicate ids + typed record encoders/decoders for the on-chain
|
|
3
|
+
* ontology-backed resolver (ADR-0009 / NS Phase 3 pivot).
|
|
4
|
+
*
|
|
5
|
+
* Subpath: `@agenticprimitives/agent-naming/records`.
|
|
6
|
+
*
|
|
7
|
+
* The `AgentNameAttributeResolver` (packages/contracts/src/naming/) inherits
|
|
8
|
+
* `AttributeStorage` and validates every write against the
|
|
9
|
+
* `OntologyTermRegistry`. Predicate keys are `bytes32` ids
|
|
10
|
+
* (`keccak256("atl:displayName")` etc.), not strings; this module is
|
|
11
|
+
* the canonical TS mirror of those ids — kept in lockstep with
|
|
12
|
+
* `packages/contracts/src/naming/AgentNamePredicates.sol`.
|
|
13
|
+
*
|
|
14
|
+
* Datatype binding:
|
|
15
|
+
* - `addr`, `custodyPolicy` → on-chain `address`
|
|
16
|
+
* - `agentKind`, `metadataHash`,
|
|
17
|
+
* `passkeyCredentialDigest` → on-chain `bytes32`
|
|
18
|
+
* - `displayName`, `a2aEndpoint`,
|
|
19
|
+
* `mcpEndpoint`, `metadataUri`,
|
|
20
|
+
* `nativeId` → on-chain `string`
|
|
21
|
+
*
|
|
22
|
+
* The encoder routes each predicate to its typed setter; the decoder
|
|
23
|
+
* routes each predicate to its typed getter. Unknown predicates are
|
|
24
|
+
* dropped on decode (fail-closed on read); encoders refuse unknown
|
|
25
|
+
* predicates (fail-loud on write).
|
|
26
|
+
*/
|
|
27
|
+
import { keccak256, toHex } from 'viem';
|
|
28
|
+
// ─── Predicate ids (mirror AgentNamePredicates.sol) ─────────────────
|
|
29
|
+
/**
|
|
30
|
+
* keccak256 of the `atl:*` CURIE. Computed at module load. These
|
|
31
|
+
* MUST equal the `AgentNamePredicates.ATL_*` constants in the
|
|
32
|
+
* Solidity library — verified by `predicates.test.ts` golden vectors.
|
|
33
|
+
*/
|
|
34
|
+
function _predId(curie) {
|
|
35
|
+
return keccak256(toHex(curie));
|
|
36
|
+
}
|
|
37
|
+
export const PREDICATE_ID = {
|
|
38
|
+
addr: _predId('atl:addr'),
|
|
39
|
+
agentKind: _predId('atl:agentKind'),
|
|
40
|
+
displayName: _predId('atl:displayName'),
|
|
41
|
+
a2aEndpoint: _predId('atl:a2aEndpoint'),
|
|
42
|
+
mcpEndpoint: _predId('atl:mcpEndpoint'),
|
|
43
|
+
metadataUri: _predId('atl:metadataURI'),
|
|
44
|
+
metadataHash: _predId('atl:metadataHash'),
|
|
45
|
+
passkeyCredentialDigest: _predId('atl:passkeyCredentialDigest'),
|
|
46
|
+
custodyPolicy: _predId('atl:custodyPolicy'),
|
|
47
|
+
nativeId: _predId('atl:nativeId'),
|
|
48
|
+
};
|
|
49
|
+
// ─── Enum value ids (mirror AgentNamePredicates.sol AGENT_KIND_*) ──
|
|
50
|
+
export const AGENT_KIND_ID = {
|
|
51
|
+
person: _predId('person'),
|
|
52
|
+
org: _predId('org'),
|
|
53
|
+
service: _predId('service'),
|
|
54
|
+
};
|
|
55
|
+
const KNOWN_AGENT_KINDS = new Set([
|
|
56
|
+
'person',
|
|
57
|
+
'org',
|
|
58
|
+
'service',
|
|
59
|
+
]);
|
|
60
|
+
// ─── Class + enum-set ids ──────────────────────────────────────────
|
|
61
|
+
/** `keccak256("atl:AgentName")` — the ShapeRegistry class id. */
|
|
62
|
+
export const CLASS_AGENT_NAME = _predId('atl:AgentName');
|
|
63
|
+
/** `keccak256("atl:AgentKindEnum")` — the enum-set id bound to `atl:agentKind`. */
|
|
64
|
+
export const AGENT_KIND_ENUM = _predId('atl:AgentKindEnum');
|
|
65
|
+
// ─── CAIP-10 namespace allowlist (ADR-0008) ────────────────────────
|
|
66
|
+
/**
|
|
67
|
+
* Phase 1 CAIP-10 namespace allowlist for `nativeId`. Strict on
|
|
68
|
+
* encode (validate-at-write), permissive on decode (forward-compat).
|
|
69
|
+
*/
|
|
70
|
+
export const CAIP10_NAMESPACE_ALLOWLIST = new Set([
|
|
71
|
+
'eip155',
|
|
72
|
+
'hedera',
|
|
73
|
+
'solana',
|
|
74
|
+
]);
|
|
75
|
+
const CAIP10_GRAMMAR = /^([-a-z0-9]{3,8}):([-_a-zA-Z0-9]{1,32}):([-.%a-zA-Z0-9]{1,128})$/;
|
|
76
|
+
/**
|
|
77
|
+
* Encode the typed `AgentNameRecords` bundle into per-predicate
|
|
78
|
+
* encoded-call args. Caller dispatches each to the resolver's typed
|
|
79
|
+
* `setXxxAttribute(node, predicate, value)` setter.
|
|
80
|
+
*/
|
|
81
|
+
export function encodeRecords(records) {
|
|
82
|
+
const out = [];
|
|
83
|
+
if (records.addr !== undefined) {
|
|
84
|
+
out.push({ predicate: PREDICATE_ID.addr, datatype: 'address', value: _validateAddress(records.addr) });
|
|
85
|
+
}
|
|
86
|
+
if (records.agentKind !== undefined) {
|
|
87
|
+
out.push({ predicate: PREDICATE_ID.agentKind, datatype: 'bytes32', value: _encodeAgentKind(records.agentKind) });
|
|
88
|
+
}
|
|
89
|
+
if (records.displayName !== undefined) {
|
|
90
|
+
out.push({ predicate: PREDICATE_ID.displayName, datatype: 'string', value: records.displayName });
|
|
91
|
+
}
|
|
92
|
+
if (records.a2aEndpoint !== undefined) {
|
|
93
|
+
out.push({ predicate: PREDICATE_ID.a2aEndpoint, datatype: 'string', value: records.a2aEndpoint });
|
|
94
|
+
}
|
|
95
|
+
if (records.mcpEndpoint !== undefined) {
|
|
96
|
+
out.push({ predicate: PREDICATE_ID.mcpEndpoint, datatype: 'string', value: records.mcpEndpoint });
|
|
97
|
+
}
|
|
98
|
+
if (records.metadataUri !== undefined) {
|
|
99
|
+
out.push({ predicate: PREDICATE_ID.metadataUri, datatype: 'string', value: records.metadataUri });
|
|
100
|
+
}
|
|
101
|
+
if (records.metadataHash !== undefined) {
|
|
102
|
+
out.push({ predicate: PREDICATE_ID.metadataHash, datatype: 'bytes32', value: _validateBytes32(records.metadataHash) });
|
|
103
|
+
}
|
|
104
|
+
if (records.passkeyCredentialDigest !== undefined) {
|
|
105
|
+
out.push({ predicate: PREDICATE_ID.passkeyCredentialDigest, datatype: 'bytes32', value: _validateBytes32(records.passkeyCredentialDigest) });
|
|
106
|
+
}
|
|
107
|
+
if (records.custodyPolicy !== undefined) {
|
|
108
|
+
out.push({ predicate: PREDICATE_ID.custodyPolicy, datatype: 'address', value: _validateAddress(records.custodyPolicy) });
|
|
109
|
+
}
|
|
110
|
+
if (records.nativeId !== undefined) {
|
|
111
|
+
out.push({ predicate: PREDICATE_ID.nativeId, datatype: 'string', value: _encodeNativeId(records.nativeId) });
|
|
112
|
+
}
|
|
113
|
+
return out;
|
|
114
|
+
}
|
|
115
|
+
export function decodeRecords(input) {
|
|
116
|
+
const out = {};
|
|
117
|
+
const addr = input.addresses[PREDICATE_ID.addr];
|
|
118
|
+
if (addr)
|
|
119
|
+
out.addr = addr;
|
|
120
|
+
const kind = input.bytes32s[PREDICATE_ID.agentKind];
|
|
121
|
+
if (kind) {
|
|
122
|
+
const k = _decodeAgentKind(kind);
|
|
123
|
+
if (k)
|
|
124
|
+
out.agentKind = k;
|
|
125
|
+
}
|
|
126
|
+
const displayName = input.strings[PREDICATE_ID.displayName];
|
|
127
|
+
if (displayName)
|
|
128
|
+
out.displayName = displayName;
|
|
129
|
+
const a2aEndpoint = input.strings[PREDICATE_ID.a2aEndpoint];
|
|
130
|
+
if (a2aEndpoint)
|
|
131
|
+
out.a2aEndpoint = a2aEndpoint;
|
|
132
|
+
const mcpEndpoint = input.strings[PREDICATE_ID.mcpEndpoint];
|
|
133
|
+
if (mcpEndpoint)
|
|
134
|
+
out.mcpEndpoint = mcpEndpoint;
|
|
135
|
+
const metadataUri = input.strings[PREDICATE_ID.metadataUri];
|
|
136
|
+
if (metadataUri)
|
|
137
|
+
out.metadataUri = metadataUri;
|
|
138
|
+
const metadataHash = input.bytes32s[PREDICATE_ID.metadataHash];
|
|
139
|
+
if (metadataHash)
|
|
140
|
+
out.metadataHash = metadataHash;
|
|
141
|
+
const digest = input.bytes32s[PREDICATE_ID.passkeyCredentialDigest];
|
|
142
|
+
if (digest)
|
|
143
|
+
out.passkeyCredentialDigest = digest;
|
|
144
|
+
const custodyPolicy = input.addresses[PREDICATE_ID.custodyPolicy];
|
|
145
|
+
if (custodyPolicy)
|
|
146
|
+
out.custodyPolicy = custodyPolicy;
|
|
147
|
+
const nativeId = input.strings[PREDICATE_ID.nativeId];
|
|
148
|
+
if (nativeId)
|
|
149
|
+
out.nativeId = nativeId;
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
// ─── Internal validators ───────────────────────────────────────────
|
|
153
|
+
function _validateAddress(value) {
|
|
154
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(value)) {
|
|
155
|
+
throw new Error(`[agent-naming/records] expected a 20-byte hex address (got "${value}")`);
|
|
156
|
+
}
|
|
157
|
+
return value.toLowerCase();
|
|
158
|
+
}
|
|
159
|
+
function _validateBytes32(value) {
|
|
160
|
+
if (!/^0x[0-9a-fA-F]{64}$/.test(value)) {
|
|
161
|
+
throw new Error(`[agent-naming/records] expected a 32-byte hex value (got "${value}")`);
|
|
162
|
+
}
|
|
163
|
+
return value.toLowerCase();
|
|
164
|
+
}
|
|
165
|
+
function _encodeAgentKind(value) {
|
|
166
|
+
if (!KNOWN_AGENT_KINDS.has(value)) {
|
|
167
|
+
throw new Error(`[agent-naming/records] agent-kind must be one of person|org|service (treasury is a service subtype, set via the profile, not the agent kind) (got "${value}")`);
|
|
168
|
+
}
|
|
169
|
+
return AGENT_KIND_ID[value];
|
|
170
|
+
}
|
|
171
|
+
function _decodeAgentKind(id) {
|
|
172
|
+
for (const [name, value] of Object.entries(AGENT_KIND_ID)) {
|
|
173
|
+
if (value.toLowerCase() === id.toLowerCase())
|
|
174
|
+
return name;
|
|
175
|
+
}
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
function _encodeNativeId(value) {
|
|
179
|
+
const m = CAIP10_GRAMMAR.exec(value);
|
|
180
|
+
if (!m) {
|
|
181
|
+
throw new Error(`[agent-naming/records] native-id must match CAIP-10 grammar (got "${value}")`);
|
|
182
|
+
}
|
|
183
|
+
const namespace = m[1];
|
|
184
|
+
if (!CAIP10_NAMESPACE_ALLOWLIST.has(namespace)) {
|
|
185
|
+
throw new Error(`[agent-naming/records] native-id namespace "${namespace}" not in allowlist ` +
|
|
186
|
+
`(${[...CAIP10_NAMESPACE_ALLOWLIST].join('|')}). PR to expand if needed.`);
|
|
187
|
+
}
|
|
188
|
+
if (namespace === 'eip155') {
|
|
189
|
+
return `${namespace}:${m[2]}:${m[3].toLowerCase()}`;
|
|
190
|
+
}
|
|
191
|
+
return value;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=records.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.js","sourceRoot":"","sources":["../src/records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAY,MAAM,MAAM,CAAC;AAGlD,uEAAuE;AAEvE;;;;GAIG;AACH,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC,eAAe,CAAC;IACnC,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC;IACvC,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC;IACvC,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC;IACvC,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC,kBAAkB,CAAC;IACzC,uBAAuB,EAAE,OAAO,CAAC,6BAA6B,CAAC;IAC/D,aAAa,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAC3C,QAAQ,EAAE,OAAO,CAAC,cAAc,CAAC;CACzB,CAAC;AAIX,sEAAsE;AAEtE,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,MAAM,EAAI,OAAO,CAAC,QAAQ,CAAC;IAC3B,GAAG,EAAO,OAAO,CAAC,KAAK,CAAC;IACxB,OAAO,EAAG,OAAO,CAAC,SAAS,CAAC;CAC7B,CAAC;AAEF,MAAM,iBAAiB,GAA2B,IAAI,GAAG,CAAC;IACxD,QAAQ;IACR,KAAK;IACL,SAAS;CACV,CAAC,CAAC;AAEH,sEAAsE;AAEtE,iEAAiE;AACjE,MAAM,CAAC,MAAM,gBAAgB,GAAQ,OAAO,CAAC,eAAe,CAAC,CAAC;AAC9D,mFAAmF;AACnF,MAAM,CAAC,MAAM,eAAe,GAAQ,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEjE,sEAAsE;AAEtE;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAwB,IAAI,GAAG,CAAC;IACrE,QAAQ;IACR,QAAQ;IACR,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,cAAc,GAAG,kEAAkE,CAAC;AAc1F;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAyB;IACrD,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACzG,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;QACpC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACnH,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACtC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACpG,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACzH,CAAC;IACD,IAAI,OAAO,CAAC,uBAAuB,KAAK,SAAS,EAAE,CAAC;QAClD,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,uBAAuB,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC/I,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACxC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,aAAa,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IAC3H,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC/G,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAgBD,MAAM,UAAU,aAAa,CAAC,KAAkB;IAC9C,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,IAAI;QAAE,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;IAC1B,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACpD,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,CAAC;YAAE,GAAG,CAAC,SAAS,GAAG,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IAC5D,IAAI,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;IAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IAC5D,IAAI,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;IAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IAC5D,IAAI,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;IAC/C,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;IAC5D,IAAI,WAAW;QAAE,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;IAC/C,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAC/D,IAAI,YAAY;QAAE,GAAG,CAAC,YAAY,GAAG,YAAY,CAAC;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAC;IACpE,IAAI,MAAM;QAAE,GAAG,CAAC,uBAAuB,GAAG,MAAM,CAAC;IACjD,MAAM,aAAa,GAAG,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;IAClE,IAAI,aAAa;QAAE,GAAG,CAAC,aAAa,GAAG,aAAa,CAAC;IACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtD,IAAI,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACtC,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sEAAsE;AAEtE,SAAS,gBAAgB,CAAC,KAAa;IACrC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,+DAA+D,KAAK,IAAI,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,KAAK,CAAC,WAAW,EAAmB,CAAC;AAC9C,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa;IACrC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CAAC,6DAA6D,KAAK,IAAI,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,KAAK,CAAC,WAAW,EAAS,CAAC;AACpC,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAgB;IACxC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,sJAAsJ,KAAK,IAAI,CAChK,CAAC;IACJ,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,gBAAgB,CAAC,EAAO;IAC/B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAuB,EAAE,CAAC;QAChF,IAAI,KAAK,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE;YAAE,OAAO,IAAI,CAAC;IAC5D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,CAAC,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,qEAAqE,KAAK,IAAI,CAAC,CAAC;IAClG,CAAC;IACD,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,CAAE,CAAC;IACxB,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CACb,+CAA+C,SAAS,qBAAqB;YAC3E,IAAI,CAAC,GAAG,0BAA0B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,4BAA4B,CAC5E,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACvD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import type { Address, Hex } from '@agenticprimitives/types';
|
|
2
|
+
/**
|
|
3
|
+
* Discriminator for the KIND of Smart Agent a name points to. Three kinds only
|
|
4
|
+
* — mirrors `@agenticprimitives/types` `AgentType` and the on-chain
|
|
5
|
+
* `AGENT_KIND_ENUM` (must stay in lockstep). `treasury` is NOT an agent kind: a
|
|
6
|
+
* treasury is a SERVICE agent (`'service'`) distinguished at the profile layer
|
|
7
|
+
* (`ProfileType: 'treasury'` / `serviceType`; specs 217/225 §6).
|
|
8
|
+
* Demo UIs use this to render different cards; audit context attaches it so
|
|
9
|
+
* forensics can filter "all events involving a service agent."
|
|
10
|
+
*/
|
|
11
|
+
export type AgentKind = 'person' | 'org' | 'service';
|
|
12
|
+
/**
|
|
13
|
+
* The typed bag of records a resolver may hold for a name. Every
|
|
14
|
+
* field is optional; an unresolved record is `undefined`. Encoders
|
|
15
|
+
* (`agent-naming/records`) refuse unknown keys; decoders quietly
|
|
16
|
+
* drop unknown predicates (fail-closed on read, fail-loud on write).
|
|
17
|
+
*
|
|
18
|
+
* Spec § 5 — record schema. New predicates must update both the
|
|
19
|
+
* type and the encoder/decoder pair AND a golden-vector test.
|
|
20
|
+
*/
|
|
21
|
+
export interface AgentNameRecords {
|
|
22
|
+
/** Forward resolution target — the Smart Agent address this name points to. */
|
|
23
|
+
addr?: Address;
|
|
24
|
+
/** Discriminator for UI + audit context. */
|
|
25
|
+
agentKind?: AgentKind;
|
|
26
|
+
/** Human-friendly label (may differ from the normalized name). */
|
|
27
|
+
displayName?: string;
|
|
28
|
+
/** A2A service endpoint URL. */
|
|
29
|
+
a2aEndpoint?: string;
|
|
30
|
+
/** MCP service endpoint URL. */
|
|
31
|
+
mcpEndpoint?: string;
|
|
32
|
+
/** Off-chain JSON manifest URL. */
|
|
33
|
+
metadataUri?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Public-safe identifier for the controlling passkey
|
|
36
|
+
* (`keccak256(credentialId)` — NEVER raw credentialId).
|
|
37
|
+
* Useful for UI affordances like "this name is controlled by
|
|
38
|
+
* the same passkey as <other-name>".
|
|
39
|
+
*/
|
|
40
|
+
passkeyCredentialDigest?: Hex;
|
|
41
|
+
/** Address of the CustodyPolicy governing the owner Smart Agent. */
|
|
42
|
+
custodyPolicy?: Address;
|
|
43
|
+
/**
|
|
44
|
+
* Off-chain JSON profile content-hash
|
|
45
|
+
* (matches `agent-profile.profileContentHash(profile)`). Stored
|
|
46
|
+
* as `bytes32` via the `atl:metadataHash` predicate. Pairs with
|
|
47
|
+
* `metadataUri` for the standard URI + content-hash anchoring
|
|
48
|
+
* pattern (ADR-0009 / NS Phase 3 pivot).
|
|
49
|
+
*/
|
|
50
|
+
metadataHash?: Hex;
|
|
51
|
+
/**
|
|
52
|
+
* CAIP-10 chain-agnostic account identifier (e.g.
|
|
53
|
+
* `eip155:84532:0xabc...`). Per ADR-0008, this enables low-cost
|
|
54
|
+
* cross-resolver interop with HCS-14 / ERC-8004 indexers without
|
|
55
|
+
* us generating UAID strings. Consumers MAY derive a UAID locally
|
|
56
|
+
* by canonical-JSON-hashing this with their own context.
|
|
57
|
+
*/
|
|
58
|
+
nativeId?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Input to `AgentNamingClient.registerSubname` — request to register
|
|
62
|
+
* `<label>.<parent>` under the `parent` namespace.
|
|
63
|
+
*
|
|
64
|
+
* The CALLER must own `parent` (verified on-chain by the registry).
|
|
65
|
+
* Phase 2+ will accept a custody-gated `Signer`; Phase 1 throws
|
|
66
|
+
* `NS Phase 2` from the client write methods.
|
|
67
|
+
*/
|
|
68
|
+
export interface RegisterSubnameInput {
|
|
69
|
+
/** Parent name (e.g. `'acme.agent'`). */
|
|
70
|
+
parent: string;
|
|
71
|
+
/** Child label (single label, no dots; e.g. `'treasury'`). */
|
|
72
|
+
label: string;
|
|
73
|
+
/** Smart Agent address that will own the new subname. */
|
|
74
|
+
owner: Address;
|
|
75
|
+
/** Resolver contract address to install for the new name. */
|
|
76
|
+
resolver?: Address;
|
|
77
|
+
/** Optional subregistry contract to grant further-down issuance. */
|
|
78
|
+
subregistry?: Address;
|
|
79
|
+
/** Optional initial record bundle. */
|
|
80
|
+
initialRecords?: AgentNameRecords;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Input to `AgentNamingClient.setPrimaryName` — set the reverse-record
|
|
84
|
+
* on a Smart Agent address so `reverseResolve(agent)` returns `name`.
|
|
85
|
+
*
|
|
86
|
+
* Round-trip verification: the resolver must also have `addr(name) ==
|
|
87
|
+
* agent`. If forward resolution disagrees, `reverseResolve` returns
|
|
88
|
+
* null. This prevents primary-name squatting.
|
|
89
|
+
*/
|
|
90
|
+
export interface SetPrimaryNameInput {
|
|
91
|
+
agent: Address;
|
|
92
|
+
name: string;
|
|
93
|
+
}
|
|
94
|
+
/** Input to `AgentNamingClient.setAgentRecords`. */
|
|
95
|
+
export interface SetAgentRecordsInput {
|
|
96
|
+
name: string;
|
|
97
|
+
records: AgentNameRecords;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Input to `AgentNamingClient.setSubregistry` — delegate child-name
|
|
101
|
+
* issuance authority for a subtree to a subregistry contract.
|
|
102
|
+
* Setting `subregistry = address(0)` reverts to the default registry.
|
|
103
|
+
*/
|
|
104
|
+
export interface SetSubregistryInput {
|
|
105
|
+
name: string;
|
|
106
|
+
subregistry: Address;
|
|
107
|
+
}
|
|
108
|
+
/** Read-only client constructor options. */
|
|
109
|
+
export interface AgentNamingClientOpts {
|
|
110
|
+
rpcUrl: string;
|
|
111
|
+
chainId: number;
|
|
112
|
+
/** AgentNameRegistry contract address for this chain. */
|
|
113
|
+
registry: Address;
|
|
114
|
+
/** AgentNameUniversalResolver contract address for this chain. */
|
|
115
|
+
universalResolver: Address;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAErD;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+EAA+E;IAC/E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,4CAA4C;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,GAAG,CAAC;IAC9B,oEAAoE;IACpE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAC;IACf,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oEAAoE;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,sCAAsC;IACtC,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oDAAoD;AACpD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,iBAAiB,EAAE,OAAO,CAAC;CAK5B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/docs/api.md
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Agent Naming API
|
|
2
|
+
|
|
3
|
+
This is the human-readable guide to the public exports in
|
|
4
|
+
`capability.manifest.json`. Keep it in sync with `src/index.ts`.
|
|
5
|
+
|
|
6
|
+
## Constants
|
|
7
|
+
|
|
8
|
+
- `AGENT_TLD`: the canonical top-level label, currently `"agent"`.
|
|
9
|
+
- `AgentTld`: type of the canonical top-level label.
|
|
10
|
+
- `ZERO_NODE`: the all-zero ENS root node.
|
|
11
|
+
|
|
12
|
+
## Name Helpers
|
|
13
|
+
|
|
14
|
+
- `normalizeAgentName(name)`: returns the canonical lowercase ASCII name or
|
|
15
|
+
throws `InvalidNameError`.
|
|
16
|
+
- `isValidAgentName(name)`: boolean wrapper around `normalizeAgentName`.
|
|
17
|
+
- `labelhash(label)`: keccak256 hash of a single label.
|
|
18
|
+
- `namehash(name)`: ENS-compatible recursive namehash of a normalized name.
|
|
19
|
+
|
|
20
|
+
## Client
|
|
21
|
+
|
|
22
|
+
- `AgentNamingClient`: viem-backed read/write client for registry and resolver
|
|
23
|
+
contracts.
|
|
24
|
+
- `AgentNamingClientOpts`: constructor options: `rpcUrl`, `chainId`,
|
|
25
|
+
`registry`, and `universalResolver`.
|
|
26
|
+
- `WriteContext`: per-call wallet context used by write methods.
|
|
27
|
+
|
|
28
|
+
Read methods:
|
|
29
|
+
|
|
30
|
+
- `resolveName(name)`: returns the resolved Smart Agent address or `null`.
|
|
31
|
+
- `reverseResolve(agent)`: returns the primary name only when the round-trip
|
|
32
|
+
check passes.
|
|
33
|
+
- `getRecords(name)`: returns a typed `AgentNameRecords` bundle.
|
|
34
|
+
|
|
35
|
+
Write methods:
|
|
36
|
+
|
|
37
|
+
- `registerSubname(input, ctx)`: registers `<label>.<parent>`.
|
|
38
|
+
- `setPrimaryName(input, ctx)`: updates a Smart Agent's primary name.
|
|
39
|
+
- `setAgentRecords(input, ctx)`: writes typed resolver records.
|
|
40
|
+
- `setSubregistry(input, ctx)`: changes child-name issuance authority.
|
|
41
|
+
|
|
42
|
+
## Core Types
|
|
43
|
+
|
|
44
|
+
- `AgentKind`: `'person' | 'org' | 'service'` (treasury is a service subtype at the profile layer, not an agent kind — specs 217/225 §6).
|
|
45
|
+
- `AgentNameRecords`: typed resolver record bundle.
|
|
46
|
+
- `RegisterSubnameInput`: registration input for child names.
|
|
47
|
+
- `SetPrimaryNameInput`: reverse-record update input.
|
|
48
|
+
- `SetAgentRecordsInput`: typed resolver-record update input.
|
|
49
|
+
- `SetSubregistryInput`: subregistry update input.
|
|
50
|
+
|
|
51
|
+
## Errors
|
|
52
|
+
|
|
53
|
+
- `InvalidNameError`: thrown when normalization rejects a name.
|
|
54
|
+
- `NameNotFoundError`: reserved for callers that need a hard failure instead
|
|
55
|
+
of `null` on missing names.
|
|
56
|
+
- `UnauthorizedNameOwnerError`: reserved for name-owner auth failures.
|
|
57
|
+
|
|
58
|
+
## Records Subpath
|
|
59
|
+
|
|
60
|
+
Import from `@agenticprimitives/agent-naming/records`.
|
|
61
|
+
|
|
62
|
+
- `PREDICATE_ID`: bytes32 ids for resolver predicates.
|
|
63
|
+
- `AGENT_KIND_ID`: bytes32 ids for `AgentKind` values.
|
|
64
|
+
- `CLASS_AGENT_NAME`: ShapeRegistry class id for an agent name.
|
|
65
|
+
- `AGENT_KIND_ENUM`: enum-set id for `agentKind`.
|
|
66
|
+
- `CAIP10_NAMESPACE_ALLOWLIST`: allowed namespaces for encode-side
|
|
67
|
+
`nativeId` validation.
|
|
68
|
+
- `encodeRecords(records)`: converts an `AgentNameRecords` bundle to typed
|
|
69
|
+
predicate writes.
|
|
70
|
+
- `decodeRecords(input)`: converts typed getter output into `AgentNameRecords`.
|
|
71
|
+
- `PredicateName`: union of known record names.
|
|
72
|
+
- `EncodedRecord`: typed encoded record shape.
|
|
73
|
+
- `DecodeInput`: grouped decode input shape.
|
|
74
|
+
|
|
75
|
+
## Call Builder Subpath
|
|
76
|
+
|
|
77
|
+
Import from `@agenticprimitives/agent-naming/custody`.
|
|
78
|
+
|
|
79
|
+
These helpers return `{ to, value, data }` and do not submit transactions.
|
|
80
|
+
|
|
81
|
+
- `buildRegisterSubnameCall`: encodes registry `register`.
|
|
82
|
+
- `buildRotateNameOwnerCall`: encodes registry `setOwner`.
|
|
83
|
+
- `buildRotateNameResolverCall`: encodes registry `setResolver`.
|
|
84
|
+
- `buildSetSubregistryCall`: encodes registry `setSubregistry`.
|
|
85
|
+
- `buildSetPrimaryNameCall`: encodes registry `setPrimaryName`.
|
|
86
|
+
- `buildSetStringAttributeCall`: encodes resolver `setStringAttribute`.
|
|
87
|
+
- `buildSetAddressAttributeCall`: encodes resolver `setAddressAttribute`.
|
|
88
|
+
- `buildSetBytes32AttributeCall`: encodes resolver `setBytes32Attribute`.
|
|
89
|
+
- `buildRecordCalls`: converts `AgentNameRecords` into resolver call array.
|
|
90
|
+
- `buildSubregistryRegisterCall`: encodes permissionless subregistry
|
|
91
|
+
registration.
|
|
92
|
+
- `ContractCall`: standard encoded call shape.
|
|
93
|
+
|
|
94
|
+
## ABIs
|
|
95
|
+
|
|
96
|
+
- `agentNameRegistryAbi`
|
|
97
|
+
- `agentNameAttributeResolverAbi`
|
|
98
|
+
- `agentNameUniversalResolverAbi`
|
|
99
|
+
- `ontologyTermRegistryAbi`
|
|
100
|
+
- `shapeRegistryAbi`
|
|
101
|
+
- `permissionlessSubregistryAbi`
|
|
102
|
+
|
|
103
|
+
ABIs are exported for consumers that need direct viem reads or custom
|
|
104
|
+
transaction flows.
|
|
105
|
+
|
|
106
|
+
## Examples
|
|
107
|
+
|
|
108
|
+
- [`../examples/basic.ts`](../examples/basic.ts)
|
|
109
|
+
- [`../examples/records.ts`](../examples/records.ts)
|
|
110
|
+
- [`../examples/custody-rotation.ts`](../examples/custody-rotation.ts)
|
package/docs/concepts.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Agent Naming Concepts
|
|
2
|
+
|
|
3
|
+
`@agenticprimitives/agent-naming` registers a **naming facet** for Smart
|
|
4
|
+
Agents: human-readable `.agent` labels and typed discovery records that **point
|
|
5
|
+
at** the canonical Smart Agent address ([ADR-0010](../../../docs/architecture/decisions/0010-smart-agent-canonical-identifier.md)).
|
|
6
|
+
|
|
7
|
+
This package does **not** own identity. The ERC-4337 Smart Agent address
|
|
8
|
+
(from `@agenticprimitives/agent-account`) is the canonical identifier. Names are
|
|
9
|
+
facet registrations — useful for UX and discovery, never the root authority.
|
|
10
|
+
|
|
11
|
+
## Canonical Identifier Vs Naming Facet
|
|
12
|
+
|
|
13
|
+
| Concept | Owner | Example |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| Canonical identity | `agent-account` | `0xabc…` / `eip155:84532:0xabc…` |
|
|
16
|
+
| Naming facet | `agent-naming` | `alice.agent` → `addr` + `nativeId` records |
|
|
17
|
+
| Profile facet | `agent-profile` | AgentCard at `metadata-uri` |
|
|
18
|
+
| Control credentials | `connect-auth` + `custody` | Passkey / SIWE → custodian on the SA |
|
|
19
|
+
|
|
20
|
+
Cross-package APIs use `Address` or CAIP-10 `nativeId`, not bare names.
|
|
21
|
+
|
|
22
|
+
## AgentName
|
|
23
|
+
|
|
24
|
+
An `AgentName` is a normalized dotted name under `.agent`, such as
|
|
25
|
+
`alice.agent`, `acme.agent`, or `treasury.acme.agent`.
|
|
26
|
+
|
|
27
|
+
Names are **not** login credentials and **not** CREATE2 salt inputs. A name
|
|
28
|
+
resolves to a Smart Agent address via resolver records. The Smart Agent and its
|
|
29
|
+
custody policy decide who can change that name or its records.
|
|
30
|
+
|
|
31
|
+
## Label
|
|
32
|
+
|
|
33
|
+
A label is one segment of a name: `alice`, `acme`, or `treasury`.
|
|
34
|
+
|
|
35
|
+
Phase 1 labels are intentionally conservative:
|
|
36
|
+
|
|
37
|
+
- ASCII lowercase letters, numbers, and hyphens only.
|
|
38
|
+
- No empty labels.
|
|
39
|
+
- No leading or trailing hyphens.
|
|
40
|
+
- Maximum 63 characters per label.
|
|
41
|
+
|
|
42
|
+
This avoids Unicode spoofing until a full IDN/punycode policy exists.
|
|
43
|
+
|
|
44
|
+
## Node And Namehash
|
|
45
|
+
|
|
46
|
+
A node is the ENS-compatible `bytes32` namehash of a normalized name.
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
namehash('agent');
|
|
50
|
+
namehash('acme.agent');
|
|
51
|
+
namehash('treasury.acme.agent');
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`ZERO_NODE` is the all-zero root sentinel. `labelhash(label)` hashes one label;
|
|
55
|
+
`namehash(name)` recursively hashes the full path from root to leaf.
|
|
56
|
+
|
|
57
|
+
## Registry
|
|
58
|
+
|
|
59
|
+
The registry owns the namespace tree. For each node, it records:
|
|
60
|
+
|
|
61
|
+
- owner Smart Agent
|
|
62
|
+
- resolver contract
|
|
63
|
+
- parent node
|
|
64
|
+
- optional subregistry
|
|
65
|
+
- optional expiry
|
|
66
|
+
|
|
67
|
+
The registry answers "who controls this name?" and "where are this name's
|
|
68
|
+
records stored?"
|
|
69
|
+
|
|
70
|
+
## Resolver
|
|
71
|
+
|
|
72
|
+
The resolver stores typed records for a node. The current record bundle is
|
|
73
|
+
`AgentNameRecords`:
|
|
74
|
+
|
|
75
|
+
- `addr`
|
|
76
|
+
- `agentKind`
|
|
77
|
+
- `displayName`
|
|
78
|
+
- `a2aEndpoint`
|
|
79
|
+
- `mcpEndpoint`
|
|
80
|
+
- `metadataUri`
|
|
81
|
+
- `metadataHash`
|
|
82
|
+
- `passkeyCredentialDigest`
|
|
83
|
+
- `custodyPolicy`
|
|
84
|
+
- `nativeId`
|
|
85
|
+
|
|
86
|
+
The resolver is for discovery and metadata. It is not an authorization system.
|
|
87
|
+
|
|
88
|
+
## Subregistry
|
|
89
|
+
|
|
90
|
+
A subregistry manages child-name issuance for a subtree.
|
|
91
|
+
|
|
92
|
+
For example, `acme.agent` can set a subregistry that manages
|
|
93
|
+
`*.acme.agent`. That subregistry may be permissioned, invite-gated,
|
|
94
|
+
credential-gated, or permissionless with anti-spam rules.
|
|
95
|
+
|
|
96
|
+
The package exposes call builders for setting a subregistry and for claiming
|
|
97
|
+
names through a permissionless subregistry. The package does not decide which
|
|
98
|
+
policy is appropriate for a product.
|
|
99
|
+
|
|
100
|
+
## Primary Name
|
|
101
|
+
|
|
102
|
+
A primary name is the reverse record for a Smart Agent address.
|
|
103
|
+
|
|
104
|
+
Forward resolution:
|
|
105
|
+
|
|
106
|
+
```text
|
|
107
|
+
alice.agent -> 0xAliceSmartAgent
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Reverse resolution:
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
0xAliceSmartAgent -> alice.agent
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Reverse resolution is trusted only when it round-trips: resolving the returned
|
|
117
|
+
name must return the same address.
|
|
118
|
+
|
|
119
|
+
## CAIP-10 Native ID
|
|
120
|
+
|
|
121
|
+
`nativeId` is the canonical Smart Agent identifier in CAIP-10 form:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
eip155:84532:0x0000000000000000000000000000000000000003
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
It MUST equal the `addr` record for EVM chains. It back-links external registries
|
|
128
|
+
(ERC-8004, HCS, ANS) to the same canonical SA. This package does not generate
|
|
129
|
+
UAID strings ([ADR-0008](../../../docs/architecture/decisions/0008-caip10-nativeid-record-predicate.md)).
|
|
130
|
+
|
|
131
|
+
Encode-side validation is strict. Decode-side behavior is more permissive for
|
|
132
|
+
forward compatibility.
|
|
133
|
+
|
|
134
|
+
## Forced-Unique Labels
|
|
135
|
+
|
|
136
|
+
When `alice.agent` is taken, bootstrap uses a sequential suffix:
|
|
137
|
+
`alice2.agent`, `alice3.agent`, … ([spec 220 § 5](../../../specs/220-agent-identity-bootstrap.md)).
|
|
138
|
+
The canonical SA address does not change when the suffix increments — only the
|
|
139
|
+
naming facet label does.
|
|
140
|
+
|
|
141
|
+
## Records And Service Discovery
|
|
142
|
+
|
|
143
|
+
Records make names useful to agents and tools:
|
|
144
|
+
|
|
145
|
+
- `a2aEndpoint` tells clients where a service agent's A2A endpoint lives.
|
|
146
|
+
- `mcpEndpoint` tells clients where its MCP endpoint lives.
|
|
147
|
+
- `metadataUri` and `metadataHash` anchor an off-chain profile.
|
|
148
|
+
- `displayName` gives UI a stable label.
|
|
149
|
+
|
|
150
|
+
Endpoint records are discovery hints. A consumer that needs endpoint-control
|
|
151
|
+
proof should compose with `@agenticprimitives/agent-profile`.
|
|
152
|
+
|
|
153
|
+
## Read Paths (No `eth_getLogs`)
|
|
154
|
+
|
|
155
|
+
Forward resolve and record reads use `readContract` only
|
|
156
|
+
([ADR-0012](../../../docs/architecture/decisions/0012-no-eth-getlogs-in-product-read-paths.md)).
|
|
157
|
+
`reverseResolve` still reconstructs the dotted string from registration **events**
|
|
158
|
+
via chunked `getLogs` — transitional until labels are stored on chain or served
|
|
159
|
+
by an indexer. Prefer caching `address → name` in apps after `setPrimaryName`.
|