@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.
Files changed (54) hide show
  1. package/AUDIT.md +86 -0
  2. package/CLAUDE.md +180 -0
  3. package/LICENSE +21 -0
  4. package/README.md +158 -0
  5. package/dist/abis.d.ts +1532 -0
  6. package/dist/abis.d.ts.map +1 -0
  7. package/dist/abis.js +417 -0
  8. package/dist/abis.js.map +1 -0
  9. package/dist/client.d.ts +102 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +299 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/constants.d.ts +8 -0
  14. package/dist/constants.d.ts.map +1 -0
  15. package/dist/constants.js +7 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/custody.d.ts +133 -0
  18. package/dist/custody.d.ts.map +1 -0
  19. package/dist/custody.js +214 -0
  20. package/dist/custody.js.map +1 -0
  21. package/dist/errors.d.ts +15 -0
  22. package/dist/errors.d.ts.map +1 -0
  23. package/dist/errors.js +30 -0
  24. package/dist/errors.js.map +1 -0
  25. package/dist/index.d.ts +10 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +22 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/namehash.d.ts +31 -0
  30. package/dist/namehash.d.ts.map +1 -0
  31. package/dist/namehash.js +46 -0
  32. package/dist/namehash.js.map +1 -0
  33. package/dist/normalize.d.ts +28 -0
  34. package/dist/normalize.d.ts.map +1 -0
  35. package/dist/normalize.js +68 -0
  36. package/dist/normalize.js.map +1 -0
  37. package/dist/records.d.ts +88 -0
  38. package/dist/records.d.ts.map +1 -0
  39. package/dist/records.js +193 -0
  40. package/dist/records.js.map +1 -0
  41. package/dist/types.d.ts +117 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/types.js +2 -0
  44. package/dist/types.js.map +1 -0
  45. package/docs/api.md +110 -0
  46. package/docs/concepts.md +159 -0
  47. package/docs/migration.md +93 -0
  48. package/docs/security.md +127 -0
  49. package/docs/troubleshooting.md +116 -0
  50. package/examples/basic.ts +31 -0
  51. package/examples/custody-rotation.ts +44 -0
  52. package/examples/records.ts +41 -0
  53. package/package.json +71 -0
  54. package/spec.md +14 -0
@@ -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":"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"}
@@ -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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -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)
@@ -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`.