@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
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Agent Naming Migration Notes
|
|
2
|
+
|
|
3
|
+
## Current Status
|
|
4
|
+
|
|
5
|
+
`@agenticprimitives/agent-naming` is experimental. Public helpers, record
|
|
6
|
+
schemas, ABIs, and call builders are present, but contract deployments and demo
|
|
7
|
+
wiring may still change before a stable release.
|
|
8
|
+
|
|
9
|
+
## Versioning Policy
|
|
10
|
+
|
|
11
|
+
Before `1.0`, breaking changes may happen when:
|
|
12
|
+
|
|
13
|
+
- the contract ABI changes
|
|
14
|
+
- record predicates change
|
|
15
|
+
- normalization rules change
|
|
16
|
+
- the client write path changes
|
|
17
|
+
- package-boundary rules move logic to another package
|
|
18
|
+
|
|
19
|
+
Every breaking change should update:
|
|
20
|
+
|
|
21
|
+
1. `README.md`
|
|
22
|
+
2. `docs/api.md`
|
|
23
|
+
3. `docs/security.md` when invariants change
|
|
24
|
+
4. `capability.manifest.json`
|
|
25
|
+
5. tests or examples that show the changed path
|
|
26
|
+
|
|
27
|
+
## Canonical-Identifier-First Wiring
|
|
28
|
+
|
|
29
|
+
New integrations should follow [spec 220](../../../specs/220-agent-identity-bootstrap.md):
|
|
30
|
+
|
|
31
|
+
1. Deploy or resolve the Smart Agent (`agent-account`) — canonical `Address`.
|
|
32
|
+
2. Register a forced-unique `.agent` name pointing at that address (this package).
|
|
33
|
+
3. Enroll custodians (`custody` + `identity-auth` ceremonies).
|
|
34
|
+
4. Optionally publish a profile (`agent-identity`).
|
|
35
|
+
|
|
36
|
+
Display both in UI:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
Canonical Agent ID: eip155:84532:0x…
|
|
40
|
+
Name: alice.agent (facet — may be alice2.agent if taken)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## From Ad Hoc Address Config To Names
|
|
44
|
+
|
|
45
|
+
Old app wiring often carries raw addresses and endpoint URLs in local config:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const treasury = '0x...';
|
|
49
|
+
const mcpEndpoint = 'https://...';
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
New wiring should resolve through names and records:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
const treasury = await naming.resolveName('treasury.acme.agent');
|
|
56
|
+
const records = await naming.getRecords('treasury.acme.agent');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Keep raw addresses as fallback diagnostics, not primary UI.
|
|
60
|
+
|
|
61
|
+
## From Metadata-Only Profiles To Typed Records
|
|
62
|
+
|
|
63
|
+
Use resolver records for small, frequently-read discovery fields:
|
|
64
|
+
|
|
65
|
+
- `addr`
|
|
66
|
+
- `displayName`
|
|
67
|
+
- `agentKind`
|
|
68
|
+
- `a2aEndpoint`
|
|
69
|
+
- `mcpEndpoint`
|
|
70
|
+
- `nativeId`
|
|
71
|
+
|
|
72
|
+
Use `metadataUri` plus `metadataHash` for larger profile documents.
|
|
73
|
+
|
|
74
|
+
## From Direct Writes To Encoded Calls
|
|
75
|
+
|
|
76
|
+
When writes need custom submission, prefer call builders:
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const call = buildRotateNameResolverCall({ registry, node, newResolver });
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Then submit the call through the appropriate Smart Agent, relayer, or account
|
|
83
|
+
policy path.
|
|
84
|
+
|
|
85
|
+
## Future Migration Hooks
|
|
86
|
+
|
|
87
|
+
Expected future migration areas:
|
|
88
|
+
|
|
89
|
+
- IDN/punycode support beyond ASCII labels.
|
|
90
|
+
- Generated API docs or manifest-doc synchronization.
|
|
91
|
+
- Example typecheck enforcement.
|
|
92
|
+
- Stable deployment address package.
|
|
93
|
+
- Optional compatibility layer for external ENS resolvers.
|
package/docs/security.md
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Agent Naming Security
|
|
2
|
+
|
|
3
|
+
This package is a **facet registry**, not the identity anchor. Treat names as
|
|
4
|
+
user-facing labels; bind authority to Smart Agent addresses and contract checks
|
|
5
|
+
([ADR-0010](../../../docs/architecture/decisions/0010-smart-agent-canonical-identifier.md)).
|
|
6
|
+
|
|
7
|
+
## Read-Path Discipline (No Log Scans)
|
|
8
|
+
|
|
9
|
+
Binding: [ADR-0012](../../../docs/architecture/decisions/0012-no-eth-getlogs-in-product-read-paths.md).
|
|
10
|
+
|
|
11
|
+
Product reads must use `readContract` only:
|
|
12
|
+
|
|
13
|
+
- `resolveName` and `getRecords` — compliant.
|
|
14
|
+
- `reverseResolve` — on-chain round-trip uses `readContract`; returning the
|
|
15
|
+
dotted string currently uses **chunked `eth_getLogs`** in `_reconstructName`
|
|
16
|
+
(**transitional debt** — do not add more log walkers).
|
|
17
|
+
|
|
18
|
+
Approved exits: store plaintext `label` on chain, or a naming indexer, or app
|
|
19
|
+
cache after registration. Chunking log ranges does not make log scans an
|
|
20
|
+
acceptable long-term pattern.
|
|
21
|
+
|
|
22
|
+
## Deterministic Normalization
|
|
23
|
+
|
|
24
|
+
Every name must normalize the same way on every runtime:
|
|
25
|
+
|
|
26
|
+
1. NFC normalize.
|
|
27
|
+
2. Trim whitespace.
|
|
28
|
+
3. Lowercase.
|
|
29
|
+
4. Validate labels.
|
|
30
|
+
|
|
31
|
+
Two strings that normalize identically must produce the same `namehash`.
|
|
32
|
+
|
|
33
|
+
Phase 1 uses ASCII-only labels to avoid Unicode spoofing and homoglyph attacks.
|
|
34
|
+
Do not loosen this until the package has a full IDN/punycode policy and golden
|
|
35
|
+
vectors.
|
|
36
|
+
|
|
37
|
+
## Forward And Reverse Resolution
|
|
38
|
+
|
|
39
|
+
Forward resolution answers:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
name -> address
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Reverse resolution answers:
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
address -> primary name
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Reverse resolution is only trustworthy when it round-trips:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
reverseResolve(address) -> name
|
|
55
|
+
resolveName(name) -> same address
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This prevents a malicious account from claiming someone else's name as its
|
|
59
|
+
primary name.
|
|
60
|
+
|
|
61
|
+
## Unknown Predicates
|
|
62
|
+
|
|
63
|
+
The record layer has asymmetric behavior:
|
|
64
|
+
|
|
65
|
+
- Encode side is strict. Unknown fields are not representable through
|
|
66
|
+
`AgentNameRecords` and known fields are validated before encoding.
|
|
67
|
+
- Decode side is forward-compatible. Unknown predicate ids are ignored.
|
|
68
|
+
|
|
69
|
+
This prevents clients from accidentally writing unsupported records while still
|
|
70
|
+
allowing older readers to survive newer resolver schemas.
|
|
71
|
+
|
|
72
|
+
## Passkey Material
|
|
73
|
+
|
|
74
|
+
Never store raw passkey credential IDs in naming records.
|
|
75
|
+
|
|
76
|
+
The only passkey-related record is `passkeyCredentialDigest`, a `bytes32` hash
|
|
77
|
+
of the credential ID. Use it for UI correlation only, not as an auth secret.
|
|
78
|
+
|
|
79
|
+
## CAIP-10 Native ID
|
|
80
|
+
|
|
81
|
+
`nativeId` must match CAIP-10 grammar on encode:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
namespace:reference:account
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Phase 1 encode-side namespaces are allowlisted:
|
|
88
|
+
|
|
89
|
+
- `eip155`
|
|
90
|
+
- `hedera`
|
|
91
|
+
- `solana`
|
|
92
|
+
|
|
93
|
+
`eip155` account addresses are lowercased during encode. Decode remains more
|
|
94
|
+
permissive so clients do not fail on future namespaces.
|
|
95
|
+
|
|
96
|
+
## Endpoint Records
|
|
97
|
+
|
|
98
|
+
`a2aEndpoint` and `mcpEndpoint` are discovery records. They tell clients where
|
|
99
|
+
an agent service claims to be reachable.
|
|
100
|
+
|
|
101
|
+
They do not prove endpoint control. If a product needs endpoint-control proof,
|
|
102
|
+
compose with `@agenticprimitives/agent-profile` verification methods.
|
|
103
|
+
|
|
104
|
+
## Naming Is Not Account Safety Policy
|
|
105
|
+
|
|
106
|
+
This package can build calls that rotate name owners, resolvers, records, and
|
|
107
|
+
subregistries. It does not decide who is allowed to submit those calls.
|
|
108
|
+
|
|
109
|
+
Authorization lives in the owner Smart Agent and its account safety policy. The
|
|
110
|
+
call builders return encoded calldata only; transaction submission and approval
|
|
111
|
+
flows happen outside this package.
|
|
112
|
+
|
|
113
|
+
## Subregistries
|
|
114
|
+
|
|
115
|
+
Subregistries can make child-name issuance easier, but they change the authority
|
|
116
|
+
model for a whole subtree.
|
|
117
|
+
|
|
118
|
+
Before setting a subregistry, decide:
|
|
119
|
+
|
|
120
|
+
- who can register children
|
|
121
|
+
- whether registration requires a credential, invite, fee, or stake
|
|
122
|
+
- whether names expire
|
|
123
|
+
- how disputes and reserved names are handled
|
|
124
|
+
- whether the subtree should ever become permissionless
|
|
125
|
+
|
|
126
|
+
For organization/service namespaces, prefer permissioned or credential-gated
|
|
127
|
+
subregistries unless anti-spam rules are already deployed.
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Agent Naming Troubleshooting
|
|
2
|
+
|
|
3
|
+
## `InvalidNameError`
|
|
4
|
+
|
|
5
|
+
The name failed normalization.
|
|
6
|
+
|
|
7
|
+
Common causes:
|
|
8
|
+
|
|
9
|
+
- empty string
|
|
10
|
+
- leading or trailing dot
|
|
11
|
+
- consecutive dots
|
|
12
|
+
- label starts or ends with `-`
|
|
13
|
+
- non-ASCII character
|
|
14
|
+
- label longer than 63 characters
|
|
15
|
+
|
|
16
|
+
Use `isValidAgentName(name)` for UI validation and `normalizeAgentName(name)`
|
|
17
|
+
when you want the canonical value or a detailed thrown error.
|
|
18
|
+
|
|
19
|
+
## `resolveName(name)` Returns `null`
|
|
20
|
+
|
|
21
|
+
Possible causes:
|
|
22
|
+
|
|
23
|
+
- the name is not registered
|
|
24
|
+
- the name has no resolver
|
|
25
|
+
- the resolver has no `addr` record
|
|
26
|
+
- the configured registry/universal resolver addresses point to the wrong chain
|
|
27
|
+
|
|
28
|
+
Check `chainId`, `registry`, `universalResolver`, and the normalized name.
|
|
29
|
+
|
|
30
|
+
## `reverseResolve(address)` Returns `null`
|
|
31
|
+
|
|
32
|
+
Possible causes:
|
|
33
|
+
|
|
34
|
+
- the address has no primary name
|
|
35
|
+
- the primary name node cannot be reconstructed from registry events
|
|
36
|
+
- round-trip verification failed
|
|
37
|
+
|
|
38
|
+
Round-trip failure means the primary name points somewhere else or no longer
|
|
39
|
+
resolves to the given address.
|
|
40
|
+
|
|
41
|
+
## Empty Records From `getRecords(name)`
|
|
42
|
+
|
|
43
|
+
An empty object means no known records were read. Common causes:
|
|
44
|
+
|
|
45
|
+
- no resolver is set
|
|
46
|
+
- records have not been written
|
|
47
|
+
- the resolver is on a different chain
|
|
48
|
+
- records exist only under newer predicates this SDK does not know yet
|
|
49
|
+
|
|
50
|
+
Unknown predicates are ignored on decode by design.
|
|
51
|
+
|
|
52
|
+
## Unknown Predicate Dropped On Decode
|
|
53
|
+
|
|
54
|
+
This is expected. Decode is forward-compatible and silently ignores unknown
|
|
55
|
+
predicate ids.
|
|
56
|
+
|
|
57
|
+
If the record should be first-class, add it to:
|
|
58
|
+
|
|
59
|
+
1. `src/types.ts`
|
|
60
|
+
2. `src/records.ts`
|
|
61
|
+
3. `test/records.test.ts`
|
|
62
|
+
4. `docs/api.md`
|
|
63
|
+
5. `capability.manifest.json`
|
|
64
|
+
|
|
65
|
+
## Unknown Or Invalid Record Rejected On Encode
|
|
66
|
+
|
|
67
|
+
Encode is strict. Known fields validate their expected shape:
|
|
68
|
+
|
|
69
|
+
- addresses must be 20-byte hex strings
|
|
70
|
+
- `bytes32` values must be 32-byte hex strings
|
|
71
|
+
- `agentKind` must be `person`, `org`, or `service` (a treasury is a `service`
|
|
72
|
+
agent; the `treasury` distinction lives on the profile, not the agent kind)
|
|
73
|
+
- `nativeId` must match CAIP-10 grammar and use an allowed namespace
|
|
74
|
+
|
|
75
|
+
## Native ID Validation Failed
|
|
76
|
+
|
|
77
|
+
Expected shape:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
eip155:84532:0x0000000000000000000000000000000000000003
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`nativeId` must match the `addr` record for the same Smart Agent on EVM chains.
|
|
84
|
+
If you need a new CAIP-10 namespace, add it deliberately to
|
|
85
|
+
`CAIP10_NAMESPACE_ALLOWLIST` and include a test vector.
|
|
86
|
+
|
|
87
|
+
## Resolver Unset
|
|
88
|
+
|
|
89
|
+
`setAgentRecords` requires the name to have a resolver. Install a resolver
|
|
90
|
+
through registry owner flow before writing records.
|
|
91
|
+
|
|
92
|
+
## Subregistry Unset
|
|
93
|
+
|
|
94
|
+
If a parent has no subregistry, child registration falls back to parent-owner
|
|
95
|
+
authorization. If a product expects permissionless or credential-gated child
|
|
96
|
+
registration, confirm `setSubregistry` has been applied to the parent node.
|
|
97
|
+
|
|
98
|
+
## Transaction Write Fails
|
|
99
|
+
|
|
100
|
+
The client write methods submit raw encoded calls through the supplied
|
|
101
|
+
`walletClient`. The caller must be authorized by the contracts.
|
|
102
|
+
|
|
103
|
+
If writes need to pass through a Smart Agent, relayer, or scheduled approval
|
|
104
|
+
flow, use the pure call builders in `@agenticprimitives/agent-naming/custody`
|
|
105
|
+
and submit them through that external flow.
|
|
106
|
+
|
|
107
|
+
## Confused Name With Identity
|
|
108
|
+
|
|
109
|
+
Symptom: CREATE2 address changes when the user picks a different `.agent` label,
|
|
110
|
+
or APIs accept only a name string with no `Address`.
|
|
111
|
+
|
|
112
|
+
Fix:
|
|
113
|
+
|
|
114
|
+
- Deploy / resolve the Smart Agent first (`agent-account`).
|
|
115
|
+
- Register the name as a facet pointing at that address.
|
|
116
|
+
- Never derive CREATE2 salt from the chosen `.agent` name ([spec 220](../../../specs/220-agent-identity-bootstrap.md)).
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentNamingClient,
|
|
3
|
+
labelhash,
|
|
4
|
+
namehash,
|
|
5
|
+
normalizeAgentName,
|
|
6
|
+
} from '@agenticprimitives/agent-naming';
|
|
7
|
+
|
|
8
|
+
const normalized = normalizeAgentName(' Treasury.Acme.Agent ');
|
|
9
|
+
const labelNode = labelhash('treasury');
|
|
10
|
+
const nameNode = namehash(normalized);
|
|
11
|
+
|
|
12
|
+
console.log({ normalized, labelNode, nameNode });
|
|
13
|
+
|
|
14
|
+
const naming = new AgentNamingClient({
|
|
15
|
+
rpcUrl: 'https://base-sepolia.example/rpc',
|
|
16
|
+
chainId: 84532,
|
|
17
|
+
registry: '0x0000000000000000000000000000000000000001',
|
|
18
|
+
universalResolver: '0x0000000000000000000000000000000000000002',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
async function main() {
|
|
22
|
+
const address = await naming.resolveName('treasury.acme.agent');
|
|
23
|
+
const records = await naming.getRecords('treasury.acme.agent');
|
|
24
|
+
|
|
25
|
+
if (address) {
|
|
26
|
+
const primaryName = await naming.reverseResolve(address);
|
|
27
|
+
console.log({ address, primaryName, records });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
void main();
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { namehash } from '@agenticprimitives/agent-naming';
|
|
2
|
+
import {
|
|
3
|
+
buildRecordCalls,
|
|
4
|
+
buildRotateNameOwnerCall,
|
|
5
|
+
buildRotateNameResolverCall,
|
|
6
|
+
buildSetPrimaryNameCall,
|
|
7
|
+
} from '@agenticprimitives/agent-naming/custody';
|
|
8
|
+
|
|
9
|
+
const registry = '0x0000000000000000000000000000000000000001';
|
|
10
|
+
const resolver = '0x0000000000000000000000000000000000000002';
|
|
11
|
+
const newOwner = '0x0000000000000000000000000000000000000003';
|
|
12
|
+
const node = namehash('treasury.acme.agent');
|
|
13
|
+
|
|
14
|
+
// These are pure encoded calls. Submit them through your own transaction path:
|
|
15
|
+
// a Smart Agent execute call, a relayer, or an account-safety approval flow.
|
|
16
|
+
const rotateOwner = buildRotateNameOwnerCall({
|
|
17
|
+
registry,
|
|
18
|
+
node,
|
|
19
|
+
newOwner,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const rotateResolver = buildRotateNameResolverCall({
|
|
23
|
+
registry,
|
|
24
|
+
node,
|
|
25
|
+
newResolver: resolver,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const setPrimaryName = buildSetPrimaryNameCall({
|
|
29
|
+
registry,
|
|
30
|
+
node,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const recordCalls = buildRecordCalls({
|
|
34
|
+
resolver,
|
|
35
|
+
node,
|
|
36
|
+
records: {
|
|
37
|
+
addr: newOwner,
|
|
38
|
+
agentKind: 'service', // treasury is a service subtype (profile), not an agent kind
|
|
39
|
+
displayName: 'Acme Treasury',
|
|
40
|
+
nativeId: `eip155:84532:${newOwner}`,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
console.log([rotateOwner, rotateResolver, setPrimaryName, ...recordCalls]);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGENT_KIND_ID,
|
|
3
|
+
PREDICATE_ID,
|
|
4
|
+
decodeRecords,
|
|
5
|
+
encodeRecords,
|
|
6
|
+
} from '@agenticprimitives/agent-naming/records';
|
|
7
|
+
|
|
8
|
+
const agentAddress = '0x0000000000000000000000000000000000000003';
|
|
9
|
+
|
|
10
|
+
const encoded = encodeRecords({
|
|
11
|
+
addr: agentAddress,
|
|
12
|
+
// A treasury is a SERVICE agent (agentKind='service'); 'treasury' is a profile
|
|
13
|
+
// subtype (ProfileType/serviceType), not an agent kind (specs 210/217/225 §6).
|
|
14
|
+
agentKind: 'service',
|
|
15
|
+
displayName: 'Acme Treasury',
|
|
16
|
+
a2aEndpoint: 'https://a2a.acme.example',
|
|
17
|
+
mcpEndpoint: 'https://mcp.acme.example',
|
|
18
|
+
metadataUri: 'https://metadata.acme.example/treasury.json',
|
|
19
|
+
metadataHash: '0x1111111111111111111111111111111111111111111111111111111111111111',
|
|
20
|
+
passkeyCredentialDigest: '0x2222222222222222222222222222222222222222222222222222222222222222',
|
|
21
|
+
custodyPolicy: '0x0000000000000000000000000000000000000004',
|
|
22
|
+
nativeId: `eip155:84532:${agentAddress}`,
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log(encoded);
|
|
26
|
+
|
|
27
|
+
const decoded = decodeRecords({
|
|
28
|
+
strings: {
|
|
29
|
+
[PREDICATE_ID.displayName]: 'Acme Treasury',
|
|
30
|
+
[PREDICATE_ID.a2aEndpoint]: 'https://a2a.acme.example',
|
|
31
|
+
[PREDICATE_ID.nativeId]: `eip155:84532:${agentAddress}`,
|
|
32
|
+
},
|
|
33
|
+
addresses: {
|
|
34
|
+
[PREDICATE_ID.addr]: agentAddress,
|
|
35
|
+
},
|
|
36
|
+
bytes32s: {
|
|
37
|
+
[PREDICATE_ID.agentKind]: AGENT_KIND_ID.service,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
console.log(decoded);
|
package/package.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agenticprimitives/agent-naming",
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
|
+
"description": "Agent Naming Service SDK: ENS-v2-style hierarchical naming for Smart Agents (.agent TLD). Owns name normalization, namehash/labelhash, records schemas, and the AgentNamingClient (resolve / reverse / registry). Speaks naming-domain vocabulary only \u2014 no delegation / caveat / custody concepts.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
|
|
9
|
+
"directory": "packages/agent-naming"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/agentictrustlabs/agenticprimitives/tree/master/packages/agent-naming",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/agentictrustlabs/agenticprimitives/issues"
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./records": {
|
|
24
|
+
"types": "./dist/records.d.ts",
|
|
25
|
+
"import": "./dist/records.js"
|
|
26
|
+
},
|
|
27
|
+
"./custody": {
|
|
28
|
+
"types": "./dist/custody.d.ts",
|
|
29
|
+
"import": "./dist/custody.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"LICENSE",
|
|
34
|
+
"dist",
|
|
35
|
+
"docs",
|
|
36
|
+
"examples",
|
|
37
|
+
"spec.md",
|
|
38
|
+
"README.md",
|
|
39
|
+
"AUDIT.md",
|
|
40
|
+
"CLAUDE.md"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"build": "tsc -p tsconfig.build.json",
|
|
44
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:unit": "vitest run test/normalize.test.ts test/namehash.test.ts test/records.test.ts",
|
|
47
|
+
"test:integration": "vitest run test/integration.test.ts",
|
|
48
|
+
"test:watch": "vitest",
|
|
49
|
+
"clean": "rm -rf dist"
|
|
50
|
+
},
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"@agenticprimitives/agent-account": "workspace:*",
|
|
56
|
+
"@agenticprimitives/connect-auth": "workspace:*",
|
|
57
|
+
"@agenticprimitives/types": "workspace:*",
|
|
58
|
+
"viem": "^2.50.0"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.7.0",
|
|
62
|
+
"vitest": "^2.1.0"
|
|
63
|
+
},
|
|
64
|
+
"keywords": [
|
|
65
|
+
"agent",
|
|
66
|
+
"naming",
|
|
67
|
+
"ens",
|
|
68
|
+
"smart-agent",
|
|
69
|
+
"agentic"
|
|
70
|
+
]
|
|
71
|
+
}
|
package/spec.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# @agenticprimitives/agent-naming — spec
|
|
2
|
+
|
|
3
|
+
The full design lives in [`../../specs/215-agent-naming.md`](../../specs/215-agent-naming.md).
|
|
4
|
+
|
|
5
|
+
Architecture decisions:
|
|
6
|
+
|
|
7
|
+
- [ADR-0006](../../docs/architecture/decisions/0006-agent-naming-as-resolution-layer.md)
|
|
8
|
+
— naming as resolution layer via NameContext injection (no
|
|
9
|
+
back-edges from downstream packages).
|
|
10
|
+
- [ADR-0008](../../docs/architecture/decisions/0008-caip10-nativeid-record-predicate.md)
|
|
11
|
+
— `native-id` predicate carries CAIP-10 (HCS-14 interop) without
|
|
12
|
+
UAID derivation.
|
|
13
|
+
|
|
14
|
+
Do not edit a divergent copy here — edit the canonical spec.
|