@agenticprimitives/identity-directory-adapters 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/LICENSE +21 -0
- package/README.md +48 -0
- package/dist/caip10.d.ts +7 -0
- package/dist/caip10.d.ts.map +1 -0
- package/dist/caip10.js +21 -0
- package/dist/caip10.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +16 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +33 -0
- package/dist/indexer.js.map +1 -0
- package/dist/naming.d.ts +11 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +29 -0
- package/dist/naming.js.map +1 -0
- package/dist/onchain.d.ts +23 -0
- package/dist/onchain.d.ts.map +1 -0
- package/dist/onchain.js +28 -0
- package/dist/onchain.js.map +1 -0
- package/package.json +58 -0
- package/spec.md +14 -0
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,48 @@
|
|
|
1
|
+
# @agenticprimitives/identity-directory-adapters
|
|
2
|
+
|
|
3
|
+
Port implementations for [`@agenticprimitives/identity-directory`](../identity-directory)
|
|
4
|
+
(spec 223 / [ADR-0015](../../docs/architecture/decisions/0015-identity-directory-is-an-evidence-backed-read-model.md)).
|
|
5
|
+
The composition layer that binds the directory's ports to real sources — and the
|
|
6
|
+
**one package allowed to import `agent-naming`** (spec 100 §4). The directory core
|
|
7
|
+
stays source-agnostic.
|
|
8
|
+
|
|
9
|
+
## What's here
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
makeNamingPort({ client, chainId }) wrap agent-naming + eip155 Address↔CanonicalAgentId lift
|
|
13
|
+
makeOnChainReadPort(readers) assemble OnChainReadPort from { exists, confirmsCredential }
|
|
14
|
+
viemExists(client) a contract-agnostic exists (bytecode-at-address)
|
|
15
|
+
createInMemoryIndexer(entries) an in-memory IndexerPort (demo + tests)
|
|
16
|
+
toCanonicalAgentId / addressOf eip155 CAIP-10 glue
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { createDirectory } from '@agenticprimitives/identity-directory';
|
|
23
|
+
import {
|
|
24
|
+
makeNamingPort, makeOnChainReadPort, viemExists, createInMemoryIndexer,
|
|
25
|
+
} from '@agenticprimitives/identity-directory-adapters';
|
|
26
|
+
|
|
27
|
+
const dir = createDirectory({
|
|
28
|
+
naming: makeNamingPort({ client: namingClient, chainId: 8453 }),
|
|
29
|
+
onChain: makeOnChainReadPort({
|
|
30
|
+
exists: viemExists(publicClient),
|
|
31
|
+
// app-wired to the real membership getter (isCustodian/isTrustee):
|
|
32
|
+
confirmsCredential: async (id, p) => publicClient.readContract({ /* … */ }),
|
|
33
|
+
}),
|
|
34
|
+
indexer: createInMemoryIndexer(seedEntries),
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Boundaries
|
|
39
|
+
|
|
40
|
+
- `confirmsCredential` is **app-wired** — the on-chain membership getter is
|
|
41
|
+
contract- and credential-kind-specific (an EOA address vs a passkey
|
|
42
|
+
`credentialIdDigest`), so this package does not guess it. It MUST reflect the
|
|
43
|
+
*current* set so a revoked credential returns `false` (the directory drops it).
|
|
44
|
+
- The in-memory indexer is **non-authoritative** — it proposes candidates; the
|
|
45
|
+
directory confirms them on-chain. The production indexer is a SPARQL/GraphDB
|
|
46
|
+
adapter (spec 225 §7), landing later.
|
|
47
|
+
- CAIP-10 here is **eip155-only glue**; the canonical multi-namespace builder is
|
|
48
|
+
`@agenticprimitives/agent-profile` (`/caip10`), kept out of this adapter's deps.
|
package/dist/caip10.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Address, CanonicalAgentId } from '@agenticprimitives/types';
|
|
2
|
+
export declare const EIP155_NAMESPACE: "eip155";
|
|
3
|
+
/** Build an eip155 `CanonicalAgentId` from a chainId + EVM address (lowercased). */
|
|
4
|
+
export declare function toCanonicalAgentId(chainId: number, address: Address): CanonicalAgentId;
|
|
5
|
+
/** Extract the EVM address from an eip155 `CanonicalAgentId`. Throws on a non-eip155 id. */
|
|
6
|
+
export declare function addressOf(id: CanonicalAgentId): Address;
|
|
7
|
+
//# sourceMappingURL=caip10.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caip10.d.ts","sourceRoot":"","sources":["../src/caip10.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE1E,eAAO,MAAM,gBAAgB,EAAG,QAAiB,CAAC;AAElD,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,gBAAgB,CAEtF;AAED,4FAA4F;AAC5F,wBAAgB,SAAS,CAAC,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAMvD"}
|
package/dist/caip10.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// EVM-only CAIP-10 glue for the directory adapters.
|
|
2
|
+
//
|
|
3
|
+
// The canonical, multi-namespace CAIP-10 builder/parser lives in
|
|
4
|
+
// `@agenticprimitives/agent-profile` (`/caip10`, `buildCaip10Address`). These are
|
|
5
|
+
// the eip155-only helpers this EVM adapter needs — spec 100 §4 deliberately keeps
|
|
6
|
+
// agent-profile OUT of the adapter's dependency set, and this adapter only ever
|
|
7
|
+
// produces/parses `eip155:<chainId>:<address>` ids.
|
|
8
|
+
export const EIP155_NAMESPACE = 'eip155';
|
|
9
|
+
/** Build an eip155 `CanonicalAgentId` from a chainId + EVM address (lowercased). */
|
|
10
|
+
export function toCanonicalAgentId(chainId, address) {
|
|
11
|
+
return `${EIP155_NAMESPACE}:${chainId}:${address.toLowerCase()}`;
|
|
12
|
+
}
|
|
13
|
+
/** Extract the EVM address from an eip155 `CanonicalAgentId`. Throws on a non-eip155 id. */
|
|
14
|
+
export function addressOf(id) {
|
|
15
|
+
const parts = id.split(':');
|
|
16
|
+
if (parts.length !== 3 || parts[0] !== EIP155_NAMESPACE) {
|
|
17
|
+
throw new Error(`identity-directory-adapters: expected an eip155 CanonicalAgentId, got "${id}"`);
|
|
18
|
+
}
|
|
19
|
+
return parts[2];
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=caip10.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caip10.js","sourceRoot":"","sources":["../src/caip10.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,EAAE;AACF,iEAAiE;AACjE,kFAAkF;AAClF,kFAAkF;AAClF,gFAAgF;AAChF,oDAAoD;AAIpD,MAAM,CAAC,MAAM,gBAAgB,GAAG,QAAiB,CAAC;AAElD,oFAAoF;AACpF,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,OAAgB;IAClE,OAAO,GAAG,gBAAgB,IAAI,OAAO,IAAI,OAAO,CAAC,WAAW,EAAE,EAAsB,CAAC;AACvF,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,SAAS,CAAC,EAAoB;IAC5C,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,gBAAgB,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,0EAA0E,EAAE,GAAG,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAY,CAAC;AAC7B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { toCanonicalAgentId, addressOf, EIP155_NAMESPACE } from './caip10';
|
|
2
|
+
export { makeNamingPort, type NamingReads } from './naming';
|
|
3
|
+
export { makeOnChainReadPort, viemExists, type OnChainReaders } from './onchain';
|
|
4
|
+
export { createInMemoryIndexer, type IndexerEntry } from './indexer';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// @agenticprimitives/identity-directory-adapters — port implementations.
|
|
2
|
+
//
|
|
3
|
+
// The composition layer that wires identity-directory's ports to real sources.
|
|
4
|
+
// The ONE package allowed to import agent-naming (spec 100 §4 / ADR-0015); kept
|
|
5
|
+
// out of the directory core so the read model stays source-agnostic.
|
|
6
|
+
//
|
|
7
|
+
// See:
|
|
8
|
+
// - capability.manifest.json — boundary
|
|
9
|
+
// - ../../specs/223-identity-directory.md — the contract
|
|
10
|
+
// - ../identity-directory — the ports these implement
|
|
11
|
+
export { toCanonicalAgentId, addressOf, EIP155_NAMESPACE } from './caip10';
|
|
12
|
+
export { makeNamingPort } from './naming';
|
|
13
|
+
export { makeOnChainReadPort, viemExists } from './onchain';
|
|
14
|
+
export { createInMemoryIndexer } from './indexer';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,qEAAqE;AACrE,EAAE;AACF,OAAO;AACP,0CAA0C;AAC1C,2DAA2D;AAC3D,wDAAwD;AAExD,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAoB,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAuB,MAAM,WAAW,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAqB,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CanonicalAgentId, CredentialPrincipal, Assurance } from '@agenticprimitives/types';
|
|
2
|
+
import type { IndexerPort } from '@agenticprimitives/identity-directory';
|
|
3
|
+
/** A credential/oidc → agent edge with provenance. For OIDC, `principalId` is `${iss}#${sub}`. */
|
|
4
|
+
export interface IndexerEntry {
|
|
5
|
+
agent: CanonicalAgentId;
|
|
6
|
+
principalKind: CredentialPrincipal['kind'];
|
|
7
|
+
principalId: string;
|
|
8
|
+
assurance?: Assurance;
|
|
9
|
+
ref?: string;
|
|
10
|
+
blockNumber?: bigint;
|
|
11
|
+
}
|
|
12
|
+
/** An in-memory IndexerPort, seedable + appendable. */
|
|
13
|
+
export declare function createInMemoryIndexer(entries?: IndexerEntry[]): IndexerPort & {
|
|
14
|
+
add(entry: IndexerEntry): void;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=indexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACjG,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,uCAAuC,CAAC;AAEvF,kGAAkG;AAClG,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,gBAAgB,CAAC;IACxB,aAAa,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,uDAAuD;AACvD,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,YAAY,EAAO,GAC3B,WAAW,GAAG;IAAE,GAAG,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAA;CAAE,CAyBlD"}
|
package/dist/indexer.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// IndexerPort adapter — in-memory (demo + tests).
|
|
2
|
+
//
|
|
3
|
+
// The production IndexerPort is a SPARQL/GraphDB-backed adapter (spec 225 §7);
|
|
4
|
+
// this is the "indexed registry" without a backend yet. It is NON-AUTHORITATIVE:
|
|
5
|
+
// it only PROPOSES candidate agents — the directory confirms them against the
|
|
6
|
+
// authoritative on-chain read before treating them as onchain-confirmed
|
|
7
|
+
// (spec 223 §7). So a stale/poisoned entry here can never, by itself, authorize.
|
|
8
|
+
/** An in-memory IndexerPort, seedable + appendable. */
|
|
9
|
+
export function createInMemoryIndexer(entries = []) {
|
|
10
|
+
const store = [...entries];
|
|
11
|
+
function linksFor(kind, id) {
|
|
12
|
+
return store
|
|
13
|
+
.filter((e) => e.principalKind === kind && e.principalId === id)
|
|
14
|
+
.map((e) => ({
|
|
15
|
+
agent: e.agent,
|
|
16
|
+
assurance: e.assurance ?? 'asserted',
|
|
17
|
+
ref: e.ref ?? 'in-memory',
|
|
18
|
+
blockNumber: e.blockNumber,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
async agentsByCredential(principal) {
|
|
23
|
+
return linksFor(principal.kind, principal.id);
|
|
24
|
+
},
|
|
25
|
+
async agentsByOidcSubject(iss, sub) {
|
|
26
|
+
return linksFor('oidc', `${iss}#${sub}`);
|
|
27
|
+
},
|
|
28
|
+
add(entry) {
|
|
29
|
+
store.push(entry);
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=indexer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.js","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AACjF,8EAA8E;AAC9E,wEAAwE;AACxE,iFAAiF;AAejF,uDAAuD;AACvD,MAAM,UAAU,qBAAqB,CACnC,UAA0B,EAAE;IAE5B,MAAM,KAAK,GAAmB,CAAC,GAAG,OAAO,CAAC,CAAC;IAE3C,SAAS,QAAQ,CAAC,IAAiC,EAAE,EAAU;QAC7D,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,IAAI,IAAI,CAAC,CAAC,WAAW,KAAK,EAAE,CAAC;aAC/D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,UAAU;YACpC,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,WAAW;YACzB,WAAW,EAAE,CAAC,CAAC,WAAW;SAC3B,CAAC,CAAC,CAAC;IACR,CAAC;IAED,OAAO;QACL,KAAK,CAAC,kBAAkB,CAAC,SAAS;YAChC,OAAO,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,KAAK,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG;YAChC,OAAO,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;QAC3C,CAAC;QACD,GAAG,CAAC,KAAK;YACP,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/naming.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { NamingPort } from '@agenticprimitives/identity-directory';
|
|
2
|
+
import type { AgentNamingClient } from '@agenticprimitives/agent-naming';
|
|
3
|
+
/** The subset of `AgentNamingClient` the NamingPort needs (also satisfied by a test double). */
|
|
4
|
+
export type NamingReads = Pick<AgentNamingClient, 'resolveName' | 'reverseResolve'>;
|
|
5
|
+
export interface MakeNamingPortOpts {
|
|
6
|
+
client: NamingReads;
|
|
7
|
+
/** The chainId the naming registry lives on — binds `Address → CanonicalAgentId`. */
|
|
8
|
+
chainId: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function makeNamingPort(opts: MakeNamingPortOpts): NamingPort;
|
|
11
|
+
//# sourceMappingURL=naming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGzE,gGAAgG;AAChG,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,gBAAgB,CAAC,CAAC;AAEpF,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,UAAU,CAkBnE"}
|
package/dist/naming.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// NamingPort adapter — wraps agent-naming's read client.
|
|
2
|
+
//
|
|
3
|
+
// This is the eip155 Address ↔ CanonicalAgentId lift (audit P1-2): the shipped
|
|
4
|
+
// agent-naming client is chain-UNqualified (resolveName → Address), so the
|
|
5
|
+
// adapter binds a configured chainId to lift the result. A `null` from the
|
|
6
|
+
// client is a terminal "no such name" (ADR-0013) — the directory core does not
|
|
7
|
+
// escalate to another port.
|
|
8
|
+
import { toCanonicalAgentId, addressOf } from './caip10';
|
|
9
|
+
export function makeNamingPort(opts) {
|
|
10
|
+
return {
|
|
11
|
+
async forward(name) {
|
|
12
|
+
const addr = await opts.client.resolveName(name);
|
|
13
|
+
return addr ? toCanonicalAgentId(opts.chainId, addr) : null;
|
|
14
|
+
},
|
|
15
|
+
async reverse(id) {
|
|
16
|
+
// Only eip155 ids round-trip through EVM naming; a non-eip155 id has no
|
|
17
|
+
// reverse here (returns null rather than throwing into the read path).
|
|
18
|
+
let address;
|
|
19
|
+
try {
|
|
20
|
+
address = addressOf(id);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return opts.client.reverseResolve(address);
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,EAAE;AACF,+EAA+E;AAC/E,2EAA2E;AAC3E,2EAA2E;AAC3E,+EAA+E;AAC/E,4BAA4B;AAK5B,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAWzD,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,IAAI;YAChB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9D,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,EAAE;YACd,wEAAwE;YACxE,uEAAuE;YACvE,IAAI,OAAgB,CAAC;YACrB,IAAI,CAAC;gBACH,OAAO,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,IAAI,CAAC;YACd,CAAC;YACD,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CanonicalAgentId, CredentialPrincipal } from '@agenticprimitives/types';
|
|
2
|
+
import type { OnChainReadPort } from '@agenticprimitives/identity-directory';
|
|
3
|
+
import type { PublicClient } from 'viem';
|
|
4
|
+
export interface OnChainReaders {
|
|
5
|
+
/** Does the agent exist as a deployed account on this chain? */
|
|
6
|
+
exists(id: CanonicalAgentId): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Is `principal` CURRENTLY a control credential of `id`? Wire this to the
|
|
9
|
+
* appropriate on-chain membership getter (e.g. `isCustodian`/`isTrustee`).
|
|
10
|
+
* MUST reflect the current set so a revoked credential returns false
|
|
11
|
+
* (the directory drops it — audit P1-3).
|
|
12
|
+
*/
|
|
13
|
+
confirmsCredential(id: CanonicalAgentId, principal: CredentialPrincipal): Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
/** Assemble an OnChainReadPort from the two reader functions. */
|
|
16
|
+
export declare function makeOnChainReadPort(readers: OnChainReaders): OnChainReadPort;
|
|
17
|
+
/**
|
|
18
|
+
* A contract-agnostic `exists` reader: an agent "exists" when there is bytecode
|
|
19
|
+
* at its address (deployed). Counterfactual (not-yet-deployed) agents read as
|
|
20
|
+
* `false` — wire a factory/initCode check if you need to treat them as existing.
|
|
21
|
+
*/
|
|
22
|
+
export declare function viemExists(client: Pick<PublicClient, 'getCode'>): (id: CanonicalAgentId) => Promise<boolean>;
|
|
23
|
+
//# sourceMappingURL=onchain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onchain.d.ts","sourceRoot":"","sources":["../src/onchain.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACtF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAGzC,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,MAAM,CAAC,EAAE,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,EAAE,gBAAgB,EAAE,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5F;AAED,iEAAiE;AACjE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,cAAc,GAAG,eAAe,CAK5E;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,gBAAgB,KAAK,OAAO,CAAC,OAAO,CAAC,CAK5G"}
|
package/dist/onchain.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// OnChainReadPort adapter (viem).
|
|
2
|
+
//
|
|
3
|
+
// `exists` is contract-agnostic (bytecode-at-address) and provided here.
|
|
4
|
+
// `confirmsCredential` maps a CredentialPrincipal to an on-chain membership
|
|
5
|
+
// CHECK (isCustodian/isTrustee on the AgentAccount/custody contract) — that
|
|
6
|
+
// getter is contract- AND credential-kind-specific (an EOA address vs a passkey
|
|
7
|
+
// credentialIdDigest read differently), so it is WIRED BY THE APP rather than
|
|
8
|
+
// guessed here. The adapter assembles the port from the two readers.
|
|
9
|
+
import { addressOf } from './caip10';
|
|
10
|
+
/** Assemble an OnChainReadPort from the two reader functions. */
|
|
11
|
+
export function makeOnChainReadPort(readers) {
|
|
12
|
+
return {
|
|
13
|
+
exists: (id) => readers.exists(id),
|
|
14
|
+
confirmsCredential: (id, principal) => readers.confirmsCredential(id, principal),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A contract-agnostic `exists` reader: an agent "exists" when there is bytecode
|
|
19
|
+
* at its address (deployed). Counterfactual (not-yet-deployed) agents read as
|
|
20
|
+
* `false` — wire a factory/initCode check if you need to treat them as existing.
|
|
21
|
+
*/
|
|
22
|
+
export function viemExists(client) {
|
|
23
|
+
return async (id) => {
|
|
24
|
+
const code = await client.getCode({ address: addressOf(id) });
|
|
25
|
+
return !!code && code !== '0x';
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=onchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onchain.js","sourceRoot":"","sources":["../src/onchain.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,yEAAyE;AACzE,4EAA4E;AAC5E,4EAA4E;AAC5E,gFAAgF;AAChF,8EAA8E;AAC9E,qEAAqE;AAKrE,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAcrC,iEAAiE;AACjE,MAAM,UAAU,mBAAmB,CAAC,OAAuB;IACzD,OAAO;QACL,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClC,kBAAkB,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,EAAE,SAAS,CAAC;KACjF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,MAAqC;IAC9D,OAAO,KAAK,EAAE,EAAE,EAAE,EAAE;QAClB,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,IAAI,CAAC;IACjC,CAAC,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agenticprimitives/identity-directory-adapters",
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
|
+
"description": "Port implementations for @agenticprimitives/identity-directory: NamingPort (wraps agent-naming), OnChainReadPort (viem readContract), IndexerPort (in-memory; SPARQL/GraphDB later). The one composition layer allowed to import agent-naming (spec 100 \u00a74 / ADR-0015).",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/agentictrustlabs/agenticprimitives.git",
|
|
9
|
+
"directory": "packages/identity-directory-adapters"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/agentictrustlabs/agenticprimitives/tree/master/packages/identity-directory-adapters",
|
|
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
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"LICENSE",
|
|
26
|
+
"dist",
|
|
27
|
+
"spec.md",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsc -p tsconfig.build.json",
|
|
32
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:unit": "vitest run test/unit",
|
|
35
|
+
"test:integration": "vitest run test/integration --passWithNoTests",
|
|
36
|
+
"test:watch": "vitest",
|
|
37
|
+
"clean": "rm -rf dist"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"@agenticprimitives/agent-naming": "workspace:*",
|
|
44
|
+
"@agenticprimitives/identity-directory": "workspace:*",
|
|
45
|
+
"@agenticprimitives/types": "workspace:*",
|
|
46
|
+
"viem": "^2.50.0"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"vitest": "^2.1.0"
|
|
50
|
+
},
|
|
51
|
+
"keywords": [
|
|
52
|
+
"identity",
|
|
53
|
+
"directory",
|
|
54
|
+
"adapters",
|
|
55
|
+
"ports",
|
|
56
|
+
"agentic"
|
|
57
|
+
]
|
|
58
|
+
}
|
package/spec.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Spec — @agenticprimitives/identity-directory-adapters
|
|
2
|
+
|
|
3
|
+
This package implements the ports defined by
|
|
4
|
+
[`specs/223-identity-directory.md`](../../specs/223-identity-directory.md) §5
|
|
5
|
+
(NamingPort / OnChainReadPort / IndexerPort). The directory's contract — domain
|
|
6
|
+
model, convergence, doctrine — is spec 223; this package adds no new contract,
|
|
7
|
+
only source bindings.
|
|
8
|
+
|
|
9
|
+
Decision record: [ADR-0015 — identity-directory is an evidence-backed read model](../../docs/architecture/decisions/0015-identity-directory-is-an-evidence-backed-read-model.md).
|
|
10
|
+
Boundary: [spec 100 §4](../../specs/100-package-boundary-doctrine.md) — adapters is
|
|
11
|
+
the one composition layer permitted to import `agent-naming`.
|
|
12
|
+
|
|
13
|
+
This file is the per-package pointer required by `check:package-docs`; do not
|
|
14
|
+
duplicate the spec here — edit spec 223.
|