@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/AUDIT.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @agenticprimitives/agent-naming — package audit
|
|
2
|
+
|
|
3
|
+
**Status:** Phase 1 (SDK skeleton + spec + pure helpers).
|
|
4
|
+
**Last refreshed:** 2026-05-23.
|
|
5
|
+
**Owner:** [security-auditor](../../docs/agents/security-auditor.md) +
|
|
6
|
+
[technical-architect-auditor](../../docs/agents/technical-architect-auditor.md).
|
|
7
|
+
**System audit cross-ref:** see
|
|
8
|
+
[`docs/architecture/product-readiness-audit.md`](../../docs/architecture/product-readiness-audit.md)
|
|
9
|
+
and the [evidence checklist](../../docs/audits/evidence-checklist.md).
|
|
10
|
+
|
|
11
|
+
This audit is Phase-1 scope only. Findings against contract behavior,
|
|
12
|
+
on-chain authority paths, and demo integration land in Phase 3+.
|
|
13
|
+
|
|
14
|
+
## Charter (what's audit-relevant in this package)
|
|
15
|
+
|
|
16
|
+
- Pure helpers (`normalizeAgentName`, `labelhash`, `namehash`): MUST
|
|
17
|
+
be deterministic + match the reference ENS algorithm + reject
|
|
18
|
+
malformed input.
|
|
19
|
+
- Record schema (`AgentNameRecords` + `records` subpath): MUST
|
|
20
|
+
refuse unknown keys on encode (fail-loud write) AND drop unknown
|
|
21
|
+
keys on decode (fail-closed read).
|
|
22
|
+
- `AgentNamingClient` (Phase 1 skeleton): MUST throw clearly when
|
|
23
|
+
invoked before contract wiring, so a Phase-1 consumer can't
|
|
24
|
+
silently get a no-op call.
|
|
25
|
+
- Vocabulary firewall against `delegation`, `account-custody`, `mcp-runtime`,
|
|
26
|
+
`tool-policy`, `key-custody`, `audit`, and MCP transport.
|
|
27
|
+
|
|
28
|
+
## Findings (Phase 1)
|
|
29
|
+
|
|
30
|
+
| ID | Severity | Finding | Evidence | Status |
|
|
31
|
+
| --- | --- | --- | --- | --- |
|
|
32
|
+
| **AN-1** | P2 | Lowercase normalization uses `String.prototype.toLowerCase`, which has Turkish-locale-specific edge cases for `İ → i` mapping. Phase 1 labels are ASCII-only so the practical risk is zero, but the locale-sensitivity is worth either documenting OR replacing with a locale-explicit map. | `src/normalize.ts:21` | open — Phase 1 acceptable (ASCII-only labels in `LABEL_RE`). Revisit when Phase 2 expands to Punycode/IDN. |
|
|
33
|
+
| **AN-2** | P2 | The package depends on `@agenticprimitives/agent-account` for ERC-1271 verification, but the Phase 1 client doesn't yet exercise it (writes throw). The dependency is declared early to lock the boundary; verify in Phase 2 that the import remains narrow (`AgentAccountClient` only, no transitive widening). | `package.json` peerDependencies; `capability.manifest.json:imports` | open — track in Phase 2 review. |
|
|
34
|
+
| **AN-3** | P3 | Multi-root TLD support exists in the contract design (per smart-agent port) but the package surface restricts to `.agent`. A future TLD addition (e.g. `.org-agent`) requires both the contract `initializeRoot` AND a surface change here. Make sure the surface change is intentional + spec'd, not snuck in. | `src/constants.ts:8` | open — design-time control; no current risk. |
|
|
35
|
+
|
|
36
|
+
## Phase-1 security invariants (verified by tests)
|
|
37
|
+
|
|
38
|
+
- ✅ `normalize` rejects empty / leading-hyphen / trailing-hyphen /
|
|
39
|
+
non-ASCII / oversize labels. Throws `InvalidNameError`. Covered in
|
|
40
|
+
`test/normalize.test.ts`.
|
|
41
|
+
- ✅ `normalize` is idempotent: `normalize(normalize(x)) === normalize(x)`.
|
|
42
|
+
- ✅ `namehash('')` = `ZERO_NODE` (`0x00…00`) per the ENS sentinel
|
|
43
|
+
convention.
|
|
44
|
+
- ✅ `namehash` matches the ENS reference algorithm under an
|
|
45
|
+
in-band independent reimplementation (`test/namehash.test.ts`
|
|
46
|
+
golden-vector table).
|
|
47
|
+
- ✅ `namehash` rejects malformed input by delegating to `normalize`.
|
|
48
|
+
- ✅ `decodeRecords` silently drops unknown predicate keys
|
|
49
|
+
(fail-closed read).
|
|
50
|
+
- ✅ `encodeRecordValue` rejects unknown predicate keys (fail-loud
|
|
51
|
+
write).
|
|
52
|
+
- ✅ `decodeRecords` drops invalid `agent-kind` values that don't
|
|
53
|
+
match the closed enum.
|
|
54
|
+
- ✅ `AgentNamingClient` throws `NS Phase 2 — wire to …` from every
|
|
55
|
+
read method (so silent no-op calls are impossible in Phase 1).
|
|
56
|
+
- ✅ `AgentNamingClient` throws `NS Phase 4 — wire to …` from every
|
|
57
|
+
write method.
|
|
58
|
+
|
|
59
|
+
## Audit events this package emits (Phase 2+)
|
|
60
|
+
|
|
61
|
+
| Action | When | Severity in audit context |
|
|
62
|
+
| --- | --- | --- |
|
|
63
|
+
| `agent-naming.resolve.{accept,reject}` | demo-mcp uses name in audit context | telemetry |
|
|
64
|
+
| `agent-naming.register` | on subname registration | forensic-critical |
|
|
65
|
+
| `agent-naming.records.update` | on resolver-record writes | forensic-critical |
|
|
66
|
+
| `agent-naming.primary-name.update` | on reverse-record writes | forensic-critical |
|
|
67
|
+
| `agent-naming.subregistry.update` | on subregistry-delegation changes | forensic-critical |
|
|
68
|
+
|
|
69
|
+
These are spec-declared in `specs/215-agent-naming.md` § 9. The
|
|
70
|
+
client doesn't yet take an `auditSink`; Phase 2 will add the optional
|
|
71
|
+
`opts.auditSink` and emit through it.
|
|
72
|
+
|
|
73
|
+
## Out-of-scope (won't audit here)
|
|
74
|
+
|
|
75
|
+
- Contract source — lives in `packages/contracts/src/naming/` (Phase 3).
|
|
76
|
+
- On-chain authority paths (subregistry delegation, owner rotation
|
|
77
|
+
via custody) — Phase 3 contract Forge tests + Phase 4 client
|
|
78
|
+
integration tests.
|
|
79
|
+
- Demo wiring — Phase 5; per-demo audit lives in the demo's
|
|
80
|
+
integration evidence rows, not in this package.
|
|
81
|
+
|
|
82
|
+
## Change log
|
|
83
|
+
|
|
84
|
+
| Date | Wave | What changed |
|
|
85
|
+
| --- | --- | --- |
|
|
86
|
+
| 2026-05-23 | NS Phase 1 | Initial audit. AN-1/2/3 open; security invariants verified by unit tests. |
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# @agenticprimitives/agent-naming — Claude guide
|
|
2
|
+
|
|
3
|
+
## Naming facet, not identity
|
|
4
|
+
Names are a **facet registration** pointing AT the canonical Smart Agent ([ADR-0010](../../docs/architecture/decisions/0010-smart-agent-canonical-identifier.md)). Forced-unique labels: [spec 220 § 5](../../specs/220-agent-identity-bootstrap.md). `addr` + `nativeId` MUST reference the same SA.
|
|
5
|
+
|
|
6
|
+
## What this package owns
|
|
7
|
+
|
|
8
|
+
- The `.agent` TLD constant (`AGENT_TLD`).
|
|
9
|
+
- Name normalization (`normalizeAgentName`) — NFC + lowercase + label
|
|
10
|
+
validation. Rejects empty / hyphen-prefixed / non-ASCII labels in v0.
|
|
11
|
+
- `labelhash` + `namehash` — ENS-compatible keccak256 hashes for
|
|
12
|
+
identifier nodes.
|
|
13
|
+
- Record schemas (`AgentNameRecords`) and predicate constants
|
|
14
|
+
(subpath `/records`).
|
|
15
|
+
- `AgentNamingClient` — read API (resolve / reverse-resolve / get
|
|
16
|
+
records) + write API skeleton (Phase 1 writes throw `NS Phase 2`).
|
|
17
|
+
- Pure encoded call builders for name-owner rotation that compose
|
|
18
|
+
into custody-policy ceremonies (subpath `/custody`).
|
|
19
|
+
|
|
20
|
+
## What this package does NOT own
|
|
21
|
+
|
|
22
|
+
- Smart-account internals → [`agent-account`](../agent-account)
|
|
23
|
+
(we consume `AgentAccountClient` for ERC-1271 verification +
|
|
24
|
+
counterfactual address derivation).
|
|
25
|
+
- Custody policy, scheduling, quorum → [`custody`](../account-custody).
|
|
26
|
+
We expose call builders only — never import.
|
|
27
|
+
- Delegation / caveat / mint → [`delegation`](../delegation).
|
|
28
|
+
- Passkey ceremonies → [`connect-auth`](../connect-auth).
|
|
29
|
+
- MCP / A2A transport → demo apps + future `a2a-runtime`.
|
|
30
|
+
- Contract source — that lives in `packages/contracts/src/naming/`
|
|
31
|
+
(Phase 3+); this package ships ABIs + client only.
|
|
32
|
+
|
|
33
|
+
## Vocabulary
|
|
34
|
+
|
|
35
|
+
**Owns:** `AgentName`, `Label`, `Node` (namehash), `NameRecord`,
|
|
36
|
+
`AgentNamingClient`, `Subregistry`, `Resolver`, `PrimaryName`,
|
|
37
|
+
`AGENT_TLD`.
|
|
38
|
+
**Disambiguation:**
|
|
39
|
+
|
|
40
|
+
- **"resolver"** here = on-chain ENS-v2 resolver. Distinct from
|
|
41
|
+
any other package.
|
|
42
|
+
- **"registry"** here = `AgentNameRegistry` contract. Distinct from
|
|
43
|
+
the factory deploy-registry in `agent-account`.
|
|
44
|
+
- **"primary name"** = reverse-record on a Smart Agent address.
|
|
45
|
+
Distinct from `connect-auth.sessionId` and `delegation.SessionRow`.
|
|
46
|
+
**Does not use:** `Delegation`, `Caveat`, `Steward`, `Custodian`,
|
|
47
|
+
`Trustee`, `KMS`, `RiskTier`, `JtiStore`, MCP / A2A transport.
|
|
48
|
+
See `capability.manifest.json:forbiddenTerms`.
|
|
49
|
+
|
|
50
|
+
## Read these first (in order)
|
|
51
|
+
|
|
52
|
+
1. `capability.manifest.json` — boundary.
|
|
53
|
+
2. `src/index.ts` — public API.
|
|
54
|
+
3. `../../specs/215-agent-naming.md` — the spec.
|
|
55
|
+
4. `src/namehash.ts` + `src/normalize.ts` — the pure substrate.
|
|
56
|
+
5. `src/client.ts` — the client skeleton.
|
|
57
|
+
|
|
58
|
+
## Stable public exports
|
|
59
|
+
|
|
60
|
+
**Constants + helpers:** `AGENT_TLD`, `normalizeAgentName`,
|
|
61
|
+
`labelhash`, `namehash`.
|
|
62
|
+
**Types:** `AgentNameRecords`, `RegisterSubnameInput`,
|
|
63
|
+
`SetPrimaryNameInput`, `SetAgentRecordsInput`,
|
|
64
|
+
`SetSubregistryInput`.
|
|
65
|
+
**Client:** `AgentNamingClient`.
|
|
66
|
+
**Errors:** `InvalidNameError`, `NameNotFoundError`,
|
|
67
|
+
`UnauthorizedNameOwnerError`.
|
|
68
|
+
**Subpaths:**
|
|
69
|
+
|
|
70
|
+
- `/records` — predicate constants + encoders/decoders.
|
|
71
|
+
- `/custody` — pure encoded call builders for custody-gated name
|
|
72
|
+
rotation (no `@agenticprimitives/account-custody` import).
|
|
73
|
+
|
|
74
|
+
## Allowed imports
|
|
75
|
+
|
|
76
|
+
`@agenticprimitives/types`, `@agenticprimitives/connect-auth`
|
|
77
|
+
(`Signer` type only), `@agenticprimitives/agent-account`
|
|
78
|
+
(`AgentAccountClient`), `viem`, `@noble/hashes` (transitive via viem).
|
|
79
|
+
|
|
80
|
+
## Forbidden imports
|
|
81
|
+
|
|
82
|
+
- `apps/*`
|
|
83
|
+
- `@agenticprimitives/delegation`, `mcp-runtime`, `tool-policy`,
|
|
84
|
+
`key-custody`, `audit`, `account-custody`
|
|
85
|
+
- `@modelcontextprotocol/sdk`
|
|
86
|
+
|
|
87
|
+
## Drift triggers — STOP and route
|
|
88
|
+
|
|
89
|
+
- "Add `getLogs` / `queryFilter` / `watchContractEvent` for a product read" —
|
|
90
|
+
**STOP.** [ADR-0012](../../docs/architecture/decisions/0012-no-eth-getlogs-in-product-read-paths.md):
|
|
91
|
+
use `readContract`, on-chain stored fields, or an indexer. There is NO log
|
|
92
|
+
walker left here — `reverseResolve` is a single `reverseResolveString` call.
|
|
93
|
+
- "Add a `try fast path / catch → slower different path` fallback" — **STOP.**
|
|
94
|
+
[ADR-0013](../../docs/architecture/decisions/0013-no-silent-fallbacks.md): one
|
|
95
|
+
mechanism per read. Empty/null is the answer; don't escalate to a log walk or
|
|
96
|
+
second contract.
|
|
97
|
+
- "Add a delegation-token mint or verify path" — **STOP.** Belongs
|
|
98
|
+
in [`delegation`](../delegation).
|
|
99
|
+
- "Add a CustodyAction to gate name rotation" — **STOP.** Belongs
|
|
100
|
+
in [`custody`](../account-custody). Compose via `agent-naming/custody`
|
|
101
|
+
call builders here without importing.
|
|
102
|
+
- "Add a passkey ceremony" — **STOP.** Belongs in [`connect-auth`](../connect-auth).
|
|
103
|
+
- "Reach for an MCP transport" — **STOP.** Out of scope.
|
|
104
|
+
- "Auto-resolve name via a system-wide hook in the worker" — **STOP.**
|
|
105
|
+
Demo-app integration only; the package itself is transport-agnostic.
|
|
106
|
+
|
|
107
|
+
## Decision Tree
|
|
108
|
+
|
|
109
|
+
- Adding a new record field? Start in `src/types.ts` and
|
|
110
|
+
`src/records.ts`; update tests and `docs/api.md`.
|
|
111
|
+
- Adding resolver reads? Start in `src/client.ts`.
|
|
112
|
+
- Adding name rotation calls? Start in `src/custody.ts`; do not import
|
|
113
|
+
`@agenticprimitives/account-custody`.
|
|
114
|
+
- Adding passkey behavior? Stop. Route to `connect-auth`.
|
|
115
|
+
- Adding delegation or caveat behavior? Stop. Route to `delegation`.
|
|
116
|
+
- Adding MCP/A2A transport? Stop. Route to app/runtime packages.
|
|
117
|
+
|
|
118
|
+
## Before you write code
|
|
119
|
+
|
|
120
|
+
- [ ] Is the change in the resolver-records / namehash / normalize /
|
|
121
|
+
client surface?
|
|
122
|
+
- [ ] Did I avoid importing from `delegation`, `account-custody`,
|
|
123
|
+
`mcp-runtime`, `tool-policy`, `key-custody`, `audit`?
|
|
124
|
+
- [ ] Did I keep `normalize` deterministic (NFC + lowercase + label
|
|
125
|
+
validation)?
|
|
126
|
+
- [ ] Did I write golden-vector tests for any namehash / labelhash
|
|
127
|
+
change?
|
|
128
|
+
- [ ] Did I update `specs/215-agent-naming.md` if the public API or
|
|
129
|
+
records schema changed?
|
|
130
|
+
|
|
131
|
+
## Security invariants (DO NOT BREAK)
|
|
132
|
+
|
|
133
|
+
- **Name normalization is deterministic.** Two strings that normalize
|
|
134
|
+
identically MUST produce identical namehashes.
|
|
135
|
+
- **No raw passkey material in records.** Only `credentialIdDigest`
|
|
136
|
+
(a hash) is ever stored in `passkey-credential-digest`.
|
|
137
|
+
- **Reverse resolution requires round-trip.** `reverseResolve(agent)`
|
|
138
|
+
returns a name only when `resolveName(name) === agent`.
|
|
139
|
+
- **Fail-closed on unknown predicates.** Unknown record keys decode
|
|
140
|
+
to `undefined`; encoders refuse unknown keys.
|
|
141
|
+
- **Write methods require the name owner.** Verified via the owner
|
|
142
|
+
Smart Agent's ERC-1271 `isValidSignature` (Phase 2+).
|
|
143
|
+
|
|
144
|
+
## Validate the package
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
pnpm --filter @agenticprimitives/agent-naming typecheck
|
|
148
|
+
pnpm --filter @agenticprimitives/agent-naming test
|
|
149
|
+
pnpm check:forbidden-terms
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Common task routing
|
|
153
|
+
|
|
154
|
+
- New record predicate → `src/records.ts` (encoder/decoder + constant)
|
|
155
|
+
- update `AgentNameRecords` type in `src/types.ts` + add a test.
|
|
156
|
+
- New client method → `src/client.ts` (Phase 1 stub with
|
|
157
|
+
`throw new Error('NS Phase 2')`; wire in Phase 2).
|
|
158
|
+
- New custody-rotation call builder → `src/custody.ts` (subpath
|
|
159
|
+
`/custody`; pure encoded call — no `@agenticprimitives/account-custody`
|
|
160
|
+
import).
|
|
161
|
+
|
|
162
|
+
## Capabilities this package participates in
|
|
163
|
+
|
|
164
|
+
- **Agent identity + service discovery** — the naming graph IS the
|
|
165
|
+
on-chain authority for "which Smart Agent answers to which
|
|
166
|
+
human-readable name." Demos use it to resolve service endpoints
|
|
167
|
+
(`a2a-endpoint`, `mcp-endpoint`) without hardcoded URLs.
|
|
168
|
+
- **Audit / forensics trail** — emits (via consumer-supplied
|
|
169
|
+
`AuditSink`): `agent-naming.{resolve,register,records.update,
|
|
170
|
+
primary-name.update,subregistry.update}`.
|
|
171
|
+
- Index of cross-cutting capabilities:
|
|
172
|
+
[`docs/architecture/cross-cutting-capabilities.md`](../../docs/architecture/cross-cutting-capabilities.md).
|
|
173
|
+
|
|
174
|
+
## Documentation map
|
|
175
|
+
|
|
176
|
+
[`README.md`](README.md) · [`docs/concepts.md`](docs/concepts.md) · [`docs/api.md`](docs/api.md) · [`docs/security.md`](docs/security.md) · [`docs/troubleshooting.md`](docs/troubleshooting.md) · [`docs/migration.md`](docs/migration.md)
|
|
177
|
+
|
|
178
|
+
## Generated files (ignore)
|
|
179
|
+
|
|
180
|
+
`dist/`, `node_modules/`, `coverage/`, `*.tsbuildinfo`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Agentic Trust Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# @agenticprimitives/agent-naming
|
|
2
|
+
|
|
3
|
+
Human-readable `.agent` **naming facets** for Smart Agents.
|
|
4
|
+
|
|
5
|
+
The canonical identifier is the Smart Agent address
|
|
6
|
+
(`@agenticprimitives/agent-account`). This package registers names and records
|
|
7
|
+
that point **at** that address — it does not create or own identity.
|
|
8
|
+
|
|
9
|
+
> **Layer:** Discover — a naming **facet** (not canonical identity — that is `agent-account`).
|
|
10
|
+
> **Canonical key:** the Smart Agent address the name resolves to.
|
|
11
|
+
|
|
12
|
+
Use this package to resolve names like `alice.agent`, `acme.agent`, and
|
|
13
|
+
`treasury.acme.agent` to Smart Agent addresses, read typed service-discovery
|
|
14
|
+
records, and build encoded calls for name-management transactions.
|
|
15
|
+
|
|
16
|
+
## Use This When
|
|
17
|
+
|
|
18
|
+
- You need forward resolution: `alice.agent -> 0x...`.
|
|
19
|
+
- You need reverse resolution from a Smart Agent address to its primary name.
|
|
20
|
+
- You need typed records such as `displayName`, `a2aEndpoint`, `mcpEndpoint`,
|
|
21
|
+
`nativeId`, or `metadataUri`.
|
|
22
|
+
- You need pure call builders for name registration, resolver updates, primary
|
|
23
|
+
name updates, or owner rotation.
|
|
24
|
+
|
|
25
|
+
## Do Not Use This For
|
|
26
|
+
|
|
27
|
+
- Passkey ceremonies or auth flows. Use `@agenticprimitives/connect-auth`.
|
|
28
|
+
- Smart-account deployment or UserOps. Use `@agenticprimitives/agent-account`.
|
|
29
|
+
- Account safety policy and approval scheduling. Use `@agenticprimitives/account-custody`.
|
|
30
|
+
- Permission-token minting or attenuation. Use `@agenticprimitives/delegation`.
|
|
31
|
+
- MCP/A2A transport wiring. Use demo apps or runtime packages.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
This package is workspace-internal and not yet published.
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm add @agenticprimitives/agent-naming
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 60-Second Quickstart
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import {
|
|
45
|
+
AgentNamingClient,
|
|
46
|
+
labelhash,
|
|
47
|
+
namehash,
|
|
48
|
+
normalizeAgentName,
|
|
49
|
+
} from '@agenticprimitives/agent-naming';
|
|
50
|
+
|
|
51
|
+
normalizeAgentName(' ALICE.AGENT '); // "alice.agent"
|
|
52
|
+
labelhash('alice'); // 0x...
|
|
53
|
+
namehash('treasury.acme.agent'); // 0x...
|
|
54
|
+
|
|
55
|
+
const naming = new AgentNamingClient({
|
|
56
|
+
rpcUrl: 'https://base-sepolia.example/rpc',
|
|
57
|
+
chainId: 84532,
|
|
58
|
+
registry: '0x0000000000000000000000000000000000000001',
|
|
59
|
+
universalResolver: '0x0000000000000000000000000000000000000002',
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const address = await naming.resolveName('alice.agent');
|
|
63
|
+
const primaryName = await naming.reverseResolve('0x0000000000000000000000000000000000000003');
|
|
64
|
+
const records = await naming.getRecords('treasury.acme.agent');
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Main Concepts
|
|
68
|
+
|
|
69
|
+
- **Canonical SA**: the ERC-4337 address every name must reference (`addr`,
|
|
70
|
+
`nativeId`). Owned by `agent-account`, not this package.
|
|
71
|
+
- **AgentName**: a normalized dotted name under `.agent` (a facet label).
|
|
72
|
+
- **Label**: one segment of a name, such as `treasury`.
|
|
73
|
+
- **Node**: ENS-compatible `namehash(name)`.
|
|
74
|
+
- **Registry**: owns name records: owner, resolver, parent, subregistry.
|
|
75
|
+
- **Resolver**: stores typed records for a node.
|
|
76
|
+
- **Primary name**: reverse record for a Smart Agent address.
|
|
77
|
+
- **Records**: typed data such as endpoints, display name, CAIP-10 `nativeId`,
|
|
78
|
+
and public-safe passkey credential digest.
|
|
79
|
+
|
|
80
|
+
See [`docs/concepts.md`](docs/concepts.md).
|
|
81
|
+
|
|
82
|
+
## Common Recipes
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
import {
|
|
86
|
+
decodeRecords,
|
|
87
|
+
encodeRecords,
|
|
88
|
+
PREDICATE_ID,
|
|
89
|
+
} from '@agenticprimitives/agent-naming/records';
|
|
90
|
+
|
|
91
|
+
const encoded = encodeRecords({
|
|
92
|
+
addr: '0x0000000000000000000000000000000000000003',
|
|
93
|
+
agentKind: 'service', // a treasury is a service agent; 'treasury' is a profile subtype
|
|
94
|
+
displayName: 'Acme Treasury',
|
|
95
|
+
nativeId: 'eip155:84532:0x0000000000000000000000000000000000000003',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const decoded = decodeRecords({
|
|
99
|
+
strings: { [PREDICATE_ID.displayName]: 'Acme Treasury' },
|
|
100
|
+
addresses: { [PREDICATE_ID.addr]: '0x0000000000000000000000000000000000000003' },
|
|
101
|
+
bytes32s: {},
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
More examples:
|
|
106
|
+
|
|
107
|
+
- [`examples/basic.ts`](examples/basic.ts)
|
|
108
|
+
- [`examples/records.ts`](examples/records.ts)
|
|
109
|
+
- [`examples/custody-rotation.ts`](examples/custody-rotation.ts)
|
|
110
|
+
|
|
111
|
+
## Runtime Support
|
|
112
|
+
|
|
113
|
+
Pure helpers and record encoders work in browser, Node, and Workers. The client
|
|
114
|
+
uses `viem` public and wallet clients and requires an RPC URL for chain reads or
|
|
115
|
+
transaction submission.
|
|
116
|
+
|
|
117
|
+
## Subpath Exports
|
|
118
|
+
|
|
119
|
+
- `@agenticprimitives/agent-naming` — public helpers, client, ABIs, and types.
|
|
120
|
+
- `@agenticprimitives/agent-naming/records` — predicate ids and typed
|
|
121
|
+
record encode/decode helpers.
|
|
122
|
+
- `@agenticprimitives/agent-naming/custody` — pure encoded call builders for
|
|
123
|
+
name-management transactions.
|
|
124
|
+
|
|
125
|
+
## Security Invariants
|
|
126
|
+
|
|
127
|
+
- Product reads use `readContract`; no `eth_getLogs` in hot paths
|
|
128
|
+
([ADR-0012](../../docs/architecture/decisions/0012-no-eth-getlogs-in-product-read-paths.md)).
|
|
129
|
+
`reverseResolve` string reconstruction is transitional log debt — do not copy.
|
|
130
|
+
- Name normalization is deterministic.
|
|
131
|
+
- Reverse resolution must round-trip before it is trusted.
|
|
132
|
+
- Unknown predicates are ignored on decode and rejected by typed encoders.
|
|
133
|
+
- Raw passkey credential IDs are never stored.
|
|
134
|
+
- Endpoint records are discovery hints, not proof of endpoint control.
|
|
135
|
+
|
|
136
|
+
See [`docs/security.md`](docs/security.md) and [`AUDIT.md`](AUDIT.md).
|
|
137
|
+
|
|
138
|
+
## Documentation Map
|
|
139
|
+
|
|
140
|
+
- [`docs/concepts.md`](docs/concepts.md) — naming model and vocabulary.
|
|
141
|
+
- [`docs/api.md`](docs/api.md) — human-readable public API guide.
|
|
142
|
+
- [`docs/security.md`](docs/security.md) — security posture and invariants.
|
|
143
|
+
- [`docs/troubleshooting.md`](docs/troubleshooting.md) — common errors.
|
|
144
|
+
- [`docs/migration.md`](docs/migration.md) — version and migration notes.
|
|
145
|
+
- [`CLAUDE.md`](CLAUDE.md) — agent routing and drift prevention.
|
|
146
|
+
- [`spec.md`](spec.md) — canonical spec pointer.
|
|
147
|
+
|
|
148
|
+
## Validation
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
pnpm check:agent-naming
|
|
152
|
+
pnpm check:public-exports
|
|
153
|
+
pnpm check:forbidden-terms
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## License
|
|
157
|
+
|
|
158
|
+
UNLICENSED.
|