@agenticprimitives/estate-projection 0.0.0-alpha.21 → 0.0.0-alpha.22

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/README.md CHANGED
@@ -7,19 +7,47 @@ another estate cannot read either. What the estate publishes is two Merkle roots
7
7
  **live-grant root** (every grant currently live) and the **membership root** (every countersigned relationship
8
8
  credential). They are anchored on public ground with a monotonic sequence, signed by the estate's governance.
9
9
 
10
- A holder presents one leaf with its opening and a proof. A verifier in another estate checks it against the roots
11
- it reads from the anchor and learns exactly one thing: this subject holds a live grant, or is a member, in that
12
- estate as of that sequence. It learns nothing else — not the terms, not the counterparty, not any other leaf.
10
+ A holder presents one leaf with its opening and a proof, and **signs the verifier's challenge**. A verifier in another
11
+ estate checks it against the roots it reads from the anchor and learns exactly one thing: this subject holds a live
12
+ grant, or is a member, in that estate as of that sequence. It learns nothing else — not the terms, not the
13
+ counterparty, not any other leaf.
13
14
 
14
15
  ```ts
15
- import { buildProjection, makeAuthorityPresentation, verifyAuthorityPresentation } from '@agenticprimitives/estate-projection';
16
+ import { buildProjection, makeAuthorityPresentation, authorityPresentationTypedData, verifyAuthorityPresentation } from '@agenticprimitives/estate-projection';
16
17
 
17
18
  const projection = buildProjection({ chainId: 34348, governance, sequence: 7, liveGrants, memberships });
18
19
  // … the estate signs projectionDigest(projection) and anchors the roots on public ground …
19
- const pres = makeAuthorityPresentation(projection, 'membership', credentialDigest, { nonce, audience });
20
- const verdict = verifyAuthorityPresentation(pres, rootsReadFromTheRegistry, { subject, nonce, audience, now, maxAgeSeconds: 3600 });
20
+ const leaf = makeAuthorityPresentation(projection, 'membership', credentialDigest, { nonce, audience });
21
+ // … the SUBJECT's runtime signs the challenge with its Smart Agent (chainId: where that account lives) …
22
+ const pres = { ...leaf, subjectSignature: await subjectAccount.signTypedData(authorityPresentationTypedData(leaf, { chainId })) };
23
+ const verdict = await verifyAuthorityPresentation(pres, rootsReadFromTheRegistry,
24
+ { subject, nonce, audience, now, maxAgeSeconds: 3600 },
25
+ { chainId, verifySubjectSignature: (subject, digest, signature) => universalValidator.isValid(subject, digest, signature) });
26
+ // → { ok: true, estateId, set: 'membership', sequence: 7, subject, grade: 'standing' }
21
27
  ```
22
28
 
29
+ ## Proof of possession, not a bearer value (spec 445 §3.8)
30
+
31
+ Suite `merkle-membership-v2`. Two things make a presentation unusable by anyone but its subject:
32
+
33
+ - **The leaf commits to its subject.** `commitmentOf(digest, blind, subject) = keccak256(digest ‖ blind ‖ subject32)`,
34
+ the address left-padded to 32 bytes — `keccak256(abi.encode(digest, blind, subject))` in Solidity.
35
+ - **The subject signs the challenge.** EIP-712, domain `{ name: 'AgenticAuthorityPresentation', version: '2', chainId }`,
36
+ struct `AuthorityPresentation(bytes32 estateId,string set,uint64 sequence,bytes32 commitment,bytes nonce,string audience)`.
37
+ The chain id is declared by signer and verifier; it is never defaulted.
38
+
39
+ The verifier's signature check is injected (`verifySubjectSignature`) — wire the `UniversalSignatureValidator` /
40
+ ERC-1271 read; this package imports no chain client. Without it, without a chain id, or without a signature, a v2
41
+ presentation is refused.
42
+
43
+ **v1 (`merkle-membership-v1`) is a bearer value**: its leaf, `commitmentOfV1(digest, blind)`, names no subject, so
44
+ anyone who has seen a presentation can present it. It is refused (`bearer_v1_refused`) unless the verifier passes
45
+ `acceptBearerV1: true`, and the verdict then says `grade: 'bearer'` — a receipt must say so too.
46
+
47
+ **Migration.** An estate re-anchors: rebuild with `buildProjection` (v2 leaves), sign `projectionDigest`, `setRoots`
48
+ at the next sequence. No contract change — the registry stores roots, not leaves. Holders' stored openings stay valid
49
+ (same digest and blind); their old presentations go stale with the sequence.
50
+
23
51
  ## The issuer row
24
52
 
25
53
  A credential issuer anchors one more root on the same registry: its **live-credential** set, the credentials it still
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export declare const PACKAGE_NAME = "@agenticprimitives/estate-projection";
2
- export declare const PACKAGE_STATUS = "w3-merkle-presentation+issuer-row";
2
+ export declare const PACKAGE_STATUS = "w3-merkle-presentation-v2+issuer-row";
3
3
  export declare const SPEC_REF = "specs/410-thesis-review-ten-additions.md";
4
- export { commitmentOf, buildProjection, projectionDigest, estateIdOf, type EstateProjectionV1, type ProjectionLeafV1, type ProjectionSet, } from './projection.js';
5
- export { makeAuthorityPresentation, verifyAuthorityPresentation, type AuthorityPresentationV1, type AnchoredRoots, type PresentationVerdict, } from './presentation.js';
4
+ export { commitmentOf, commitmentOfV1, buildProjection, projectionDigest, estateIdOf, type EstateProjectionV1, type ProjectionLeafV1, type ProjectionSet, type MerkleSuite, } from './projection.js';
5
+ export { makeAuthorityPresentation, verifyAuthorityPresentation, authorityPresentationTypedData, authorityPresentationDigest, AUTHORITY_PRESENTATION_DOMAIN_NAME, AUTHORITY_PRESENTATION_DOMAIN_VERSION, AUTHORITY_PRESENTATION_EIP712_TYPES, type AuthorityPresentationV1, type AuthorityPresentationSigned, type AnchoredRoots, type PresentationVerdict, type PresentationGrade, type VerifyAuthorityPresentationOptions, } from './presentation.js';
6
+ export { estateProjectionRegistryAbi, readAnchoredRoots, readDeclaredSigner, type EstateRegistryReader, type AnchoredRootsRead, } from './registry.js';
6
7
  export { EMPTY_ROOT, ISSUER_ROW_TAG, credentialDigestOf, buildIssuerProjection, issuerRowArgs, issuerRootsOf, makeCredentialStatusPresentation, verifyCredentialStatusPresentation, type IssuerProjectionV1, type IssuerAnchoredRoots, type CredentialStatusPresentationV1, type CredentialStatusVerdict, } from './issuer.js';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,YAAY,yCAAyC,CAAC;AACnE,eAAO,MAAM,cAAc,sCAAsC,CAAC;AAClE,eAAO,MAAM,QAAQ,6CAA6C,CAAC;AAEnE,OAAO,EACL,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,GAChI,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EAAE,2BAA2B,EAAE,KAAK,uBAAuB,EAAE,KAAK,aAAa,EAAE,KAAK,mBAAmB,GACnI,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EACnG,gCAAgC,EAAE,kCAAkC,EACpE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,KAAK,8BAA8B,EAAE,KAAK,uBAAuB,GACrH,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,YAAY,yCAAyC,CAAC;AACnE,eAAO,MAAM,cAAc,yCAAyC,CAAC;AACrE,eAAO,MAAM,QAAQ,6CAA6C,CAAC;AAEnE,OAAO,EACL,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,GAClK,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,2BAA2B,EACnH,kCAAkC,EAAE,qCAAqC,EAAE,mCAAmC,EAC9G,KAAK,uBAAuB,EAAE,KAAK,2BAA2B,EAAE,KAAK,aAAa,EAAE,KAAK,mBAAmB,EAAE,KAAK,iBAAiB,EACpI,KAAK,kCAAkC,GACxC,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,2BAA2B,EAAE,iBAAiB,EAAE,kBAAkB,EAClE,KAAK,oBAAoB,EAAE,KAAK,iBAAiB,GAClD,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EACnG,gCAAgC,EAAE,kCAAkC,EACpE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,KAAK,8BAA8B,EAAE,KAAK,uBAAuB,GACrH,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -13,10 +13,12 @@
13
13
  // needed. Resolution / evidence, NEVER authority (ADR-0056 / ADR-0057): whether the receiving estate lets the agent
14
14
  // ACT is its own mandate, verified per step.
15
15
  export const PACKAGE_NAME = '@agenticprimitives/estate-projection';
16
- export const PACKAGE_STATUS = 'w3-merkle-presentation+issuer-row';
16
+ export const PACKAGE_STATUS = 'w3-merkle-presentation-v2+issuer-row';
17
17
  export const SPEC_REF = 'specs/410-thesis-review-ten-additions.md';
18
- export { commitmentOf, buildProjection, projectionDigest, estateIdOf, } from './projection.js';
19
- export { makeAuthorityPresentation, verifyAuthorityPresentation, } from './presentation.js';
18
+ export { commitmentOf, commitmentOfV1, buildProjection, projectionDigest, estateIdOf, } from './projection.js';
19
+ export { makeAuthorityPresentation, verifyAuthorityPresentation, authorityPresentationTypedData, authorityPresentationDigest, AUTHORITY_PRESENTATION_DOMAIN_NAME, AUTHORITY_PRESENTATION_DOMAIN_VERSION, AUTHORITY_PRESENTATION_EIP712_TYPES, } from './presentation.js';
20
+ // Spec 445 / generation 4 / B2 (REG-2) — rows keyed by (estateId, signer); the signer is the estate's declaration.
21
+ export { estateProjectionRegistryAbi, readAnchoredRoots, readDeclaredSigner, } from './registry.js';
20
22
  // Spec 305 W2 / zkID alignment §4 (Z3) — THE ISSUER ROW: a credential issuer's live-credential root anchored on the
21
23
  // same registry, and the status presentation a holder brings beside a credential presentation.
22
24
  export { EMPTY_ROOT, ISSUER_ROW_TAG, credentialDigestOf, buildIssuerProjection, issuerRowArgs, issuerRootsOf, makeCredentialStatusPresentation, verifyCredentialStatusPresentation, } from './issuer.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,mHAAmH;AACnH,oHAAoH;AACpH,8GAA8G;AAC9G,kHAAkH;AAClH,iHAAiH;AACjH,EAAE;AACF,mHAAmH;AACnH,qHAAqH;AACrH,kHAAkH;AAClH,iHAAiH;AACjH,oHAAoH;AACpH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,YAAY,GAAG,sCAAsC,CAAC;AACnE,MAAM,CAAC,MAAM,cAAc,GAAG,mCAAmC,CAAC;AAClE,MAAM,CAAC,MAAM,QAAQ,GAAG,0CAA0C,CAAC;AAEnE,OAAO,EACL,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,GAC5D,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EAAE,2BAA2B,GACvD,MAAM,mBAAmB,CAAC;AAC3B,oHAAoH;AACpH,+FAA+F;AAC/F,OAAO,EACL,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EACnG,gCAAgC,EAAE,kCAAkC,GAErE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,EAAE;AACF,mHAAmH;AACnH,oHAAoH;AACpH,8GAA8G;AAC9G,kHAAkH;AAClH,iHAAiH;AACjH,EAAE;AACF,mHAAmH;AACnH,qHAAqH;AACrH,kHAAkH;AAClH,iHAAiH;AACjH,oHAAoH;AACpH,6CAA6C;AAC7C,MAAM,CAAC,MAAM,YAAY,GAAG,sCAAsC,CAAC;AACnE,MAAM,CAAC,MAAM,cAAc,GAAG,sCAAsC,CAAC;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,0CAA0C,CAAC;AAEnE,OAAO,EACL,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAAE,UAAU,GAC5E,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,yBAAyB,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,2BAA2B,EACnH,kCAAkC,EAAE,qCAAqC,EAAE,mCAAmC,GAG/G,MAAM,mBAAmB,CAAC;AAC3B,mHAAmH;AACnH,OAAO,EACL,2BAA2B,EAAE,iBAAiB,EAAE,kBAAkB,GAEnE,MAAM,eAAe,CAAC;AACvB,oHAAoH;AACpH,+FAA+F;AAC/F,OAAO,EACL,UAAU,EAAE,cAAc,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EACnG,gCAAgC,EAAE,kCAAkC,GAErE,MAAM,aAAa,CAAC"}
package/dist/issuer.d.ts CHANGED
@@ -28,7 +28,8 @@ export declare function buildIssuerProjection(input: {
28
28
  subject: `0x${string}`;
29
29
  }>;
30
30
  }): IssuerProjectionV1;
31
- /** The registry call an issuer row is anchored with — `setRoots(issuerId, liveCredentialRoot, EMPTY_ROOT, ISSUER_ROW_TAG, sequence)`
31
+ /** The registry call an issuer row is anchored with — `setRoots(issuerId, liveCredentialRoot, EMPTY_ROOT, ISSUER_ROW_TAG, sequence)`,
32
+ * sent BY the issuer's signer (generation 4: `setRoots` writes the caller's row; there is no `register`)
32
33
  * — and the digest its signer signs: the SAME preimage `projectionDigest` uses for an estate, so one registry, one
33
34
  * signature rule. */
34
35
  export declare function issuerRowArgs(p: Pick<IssuerProjectionV1, 'issuerId' | 'sequence' | 'liveCredentialRoot'>): {
@@ -38,17 +39,22 @@ export declare function issuerRowArgs(p: Pick<IssuerProjectionV1, 'issuerId' | '
38
39
  charterHash: Hex;
39
40
  sequence: number;
40
41
  };
41
- /** What the verifier READ from the registry under the issuer's row. `charterHash` must be the issuer tag. */
42
+ /** What the verifier READ from the registry under the issuer's row. `charterHash` must be the issuer tag.
43
+ * Spec 445 / generation 4 / B2 (REG-2): `signer` is the row read — the issuer's DECLARED signer. */
42
44
  export interface IssuerAnchoredRoots {
43
45
  issuerId: Hex;
46
+ signer: `0x${string}`;
44
47
  sequence: number;
45
48
  liveCredentialRoot: Hex;
46
49
  charterHash: Hex;
47
50
  anchoredAt: number;
48
51
  }
49
- /** A read of `roots(issuerId)` → the issuer's anchored root, or null when the row is not an issuer row. */
52
+ /** A read of `roots(issuerId, issuerSigner)` (generation 4: rows are keyed by signer — the issuer row is the issuer
53
+ * signer's row, read with `readAnchoredRoots`) → the issuer's anchored root, or null when the row is not an issuer
54
+ * row or names no signer. */
50
55
  export declare function issuerRootsOf(read: {
51
56
  estateId: Hex;
57
+ signer: `0x${string}`;
52
58
  liveGrantRoot: Hex;
53
59
  membershipRoot: Hex;
54
60
  charterHash: Hex;
@@ -1 +1 @@
1
- {"version":3,"file":"issuer.d.ts","sourceRoot":"","sources":["../src/issuer.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAsB,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAiD,KAAK,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACvH,OAAO,EAA4B,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAElF,eAAO,MAAM,UAAU,EAAE,GAA4B,CAAC;AACtD,4HAA4H;AAC5H,eAAO,MAAM,cAAc,EAAE,GAAmD,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,yBAAyB,CAAC;IAChC,mHAAmH;IACnH,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,GAAG,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;yHACyH;AACzH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAGzD;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3E,eAAe,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACrF,GAAG,kBAAkB,CAMrB;AAED;;sBAEsB;AACtB,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,UAAU,GAAG,oBAAoB,CAAC,GAAG;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,aAAa,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAEzM;AAED,6GAA6G;AAC7G,MAAM,WAAW,mBAAmB;IAAG,QAAQ,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAEvI,2GAA2G;AAC3G,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,aAAa,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,mBAAmB,GAAG,IAAI,CAGlL;AAED;;wBAEwB;AACxB,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,sCAAsC,CAAC;IAC7C,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CAAC;IACnD,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IACtC,UAAU,EAAE,GAAG,CAAC;IAChB,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,gCAAgC,CAAC,CAAC,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,8BAA8B,GAAG,IAAI,CAKpL;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,mBAAmB,GAAG,WAAW,GAAG,iBAAiB,GAAG,mBAAmB,GAAG,OAAO,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,UAAU,GAAG,oBAAoB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5M;wGACwG;AACxG,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,8BAA8B,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,CAYhO"}
1
+ {"version":3,"file":"issuer.d.ts","sourceRoot":"","sources":["../src/issuer.ts"],"names":[],"mappings":"AA8BA,OAAO,EAAsB,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AACpD,OAAO,EAAiD,KAAK,UAAU,EAAE,MAAM,uCAAuC,CAAC;AACvH,OAAO,EAA8B,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEpF,eAAO,MAAM,UAAU,EAAE,GAA4B,CAAC;AACtD,4HAA4H;AAC5H,eAAO,MAAM,cAAc,EAAE,GAAmD,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,yBAAyB,CAAC;IAChC,mHAAmH;IACnH,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,GAAG,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;yHACyH;AACzH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,GAAG,CAGzD;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE;IAC3C,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3E,eAAe,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACrF,GAAG,kBAAkB,CAMrB;AAED;;;sBAGsB;AACtB,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,UAAU,GAAG,oBAAoB,CAAC,GAAG;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,aAAa,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAEzM;AAED;qGACqG;AACrG,MAAM,WAAW,mBAAmB;IAAG,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,kBAAkB,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAE9J;;8BAE8B;AAC9B,wBAAgB,aAAa,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,aAAa,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,GAAG,CAAC;IAAC,WAAW,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,mBAAmB,GAAG,IAAI,CAIzM;AAED;;wBAEwB;AACxB,MAAM,WAAW,8BAA8B;IAC7C,IAAI,EAAE,sCAAsC,CAAC;IAC7C,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CAAC;IACnD,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IACtC,UAAU,EAAE,GAAG,CAAC;IAChB,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,gCAAgC,CAAC,CAAC,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,8BAA8B,GAAG,IAAI,CAKpL;AAED,MAAM,MAAM,uBAAuB,GAC/B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC7C;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,mBAAmB,GAAG,WAAW,GAAG,iBAAiB,GAAG,mBAAmB,GAAG,OAAO,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,UAAU,GAAG,oBAAoB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5M;wGACwG;AACxG,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,8BAA8B,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,CAahO"}
package/dist/issuer.js CHANGED
@@ -17,9 +17,18 @@
17
17
  // of zkID alignment §4; the zk suite (`zk-membership-v1`: the same claim inside the proof, no opening) is reserved,
18
18
  // and is what an OpenAC Show would carry once the profile admits a status input. A verifier that needs unlinkability
19
19
  // MUST NOT demand this presentation; one that would otherwise phone the issuer's status list may.
20
+ //
21
+ // WHY THIS LEAF STAYS `keccak256(digest ‖ blind)` (spec 445 §3.8 / audit H-14 — considered, deliberately not changed).
22
+ // The estate leaf was a bearer value because it CLAIMED something about a subject it did not commit to. This leaf
23
+ // claims nothing about an address: it says "the issuer still stands behind the credential with this digest". The
24
+ // verdict names no subject, so there is no subject to re-aim. Possession is proved where the credential is presented
25
+ // — its own holder binding (the key-binding / device-key signature over the verifier's challenge) — and a status
26
+ // presentation is only ever evidence BESIDE that presentation. A copied status opening gives its copier nothing
27
+ // without the credential and its holder key. The caller's duty that follows: the status it accepts must be the
28
+ // status OF the credential it was shown — compare `pres.opening.digest` with `credentialDigestOf(jwt)`.
20
29
  import { keccak256, toBytes } from 'viem';
21
30
  import { buildCorpusTree, merkleProof, verifyInclusion } from '@agenticprimitives/content-primitives';
22
- import { commitmentOf, estateIdOf } from './projection.js';
31
+ import { commitmentOfV1, estateIdOf } from './projection.js';
23
32
  export const EMPTY_ROOT = `0x${'00'.repeat(32)}`;
24
33
  /** The `charterHash` slot of an issuer row: a reader that finds this tag knows the first root is a LIVE-CREDENTIAL root. */
25
34
  export const ISSUER_ROW_TAG = keccak256(toBytes('ap.issuer-projection.v1'));
@@ -31,22 +40,27 @@ export function credentialDigestOf(issuerJwt) {
31
40
  }
32
41
  export function buildIssuerProjection(input) {
33
42
  const leaves = input.liveCredentials
34
- .map((r) => ({ set: 'live-credential', digest: r.digest, blind: r.blind, subject: r.subject, commitment: commitmentOf(r.digest, r.blind) }))
43
+ .map((r) => ({ set: 'live-credential', digest: r.digest, blind: r.blind, subject: r.subject, commitment: commitmentOfV1(r.digest, r.blind), suite: 'merkle-membership-v1' }))
35
44
  .sort((a, b) => (a.commitment < b.commitment ? -1 : a.commitment > b.commitment ? 1 : 0));
36
45
  const tree = buildCorpusTree(leaves.map((l) => l.commitment));
37
46
  return { type: 'ap.issuer-projection.v1', issuerId: estateIdOf(input.chainId, input.issuer), sequence: input.sequence, liveCredentialRoot: tree.root, builtAt: (input.now ?? (() => new Date()))().toISOString(), leaves, tree };
38
47
  }
39
- /** The registry call an issuer row is anchored with — `setRoots(issuerId, liveCredentialRoot, EMPTY_ROOT, ISSUER_ROW_TAG, sequence)`
48
+ /** The registry call an issuer row is anchored with — `setRoots(issuerId, liveCredentialRoot, EMPTY_ROOT, ISSUER_ROW_TAG, sequence)`,
49
+ * sent BY the issuer's signer (generation 4: `setRoots` writes the caller's row; there is no `register`)
40
50
  * — and the digest its signer signs: the SAME preimage `projectionDigest` uses for an estate, so one registry, one
41
51
  * signature rule. */
42
52
  export function issuerRowArgs(p) {
43
53
  return { estateId: p.issuerId, liveGrantRoot: p.liveCredentialRoot, membershipRoot: EMPTY_ROOT, charterHash: ISSUER_ROW_TAG, sequence: p.sequence };
44
54
  }
45
- /** A read of `roots(issuerId)` → the issuer's anchored root, or null when the row is not an issuer row. */
55
+ /** A read of `roots(issuerId, issuerSigner)` (generation 4: rows are keyed by signer — the issuer row is the issuer
56
+ * signer's row, read with `readAnchoredRoots`) → the issuer's anchored root, or null when the row is not an issuer
57
+ * row or names no signer. */
46
58
  export function issuerRootsOf(read) {
47
59
  if (read.charterHash.toLowerCase() !== ISSUER_ROW_TAG.toLowerCase())
48
60
  return null;
49
- return { issuerId: read.estateId, sequence: read.sequence, liveCredentialRoot: read.liveGrantRoot, charterHash: read.charterHash, anchoredAt: read.anchoredAt };
61
+ if (typeof read.signer !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(read.signer) || /^0x0{40}$/.test(read.signer))
62
+ return null;
63
+ return { issuerId: read.estateId, signer: read.signer.toLowerCase(), sequence: read.sequence, liveCredentialRoot: read.liveGrantRoot, charterHash: read.charterHash, anchoredAt: read.anchoredAt };
50
64
  }
51
65
  export function makeCredentialStatusPresentation(p, credentialDigest, challenge) {
52
66
  const i = p.leaves.findIndex((l) => l.digest.toLowerCase() === credentialDigest.toLowerCase());
@@ -66,6 +80,8 @@ export function verifyCredentialStatusPresentation(pres, anchored, expect) {
66
80
  return { ok: false, code: 'malformed', reason: 'the merkle suite needs the opening' };
67
81
  if (anchored.charterHash.toLowerCase() !== ISSUER_ROW_TAG.toLowerCase())
68
82
  return { ok: false, code: 'not_an_issuer_row', reason: 'the anchored row is not an issuer row' };
83
+ if (typeof anchored.signer !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(anchored.signer) || /^0x0{40}$/.test(anchored.signer))
84
+ return { ok: false, code: 'malformed', reason: 'the anchored issuer roots name no signer row (generation 4: roots(issuerId, issuerSigner))' };
69
85
  if (pres.issuerId.toLowerCase() !== anchored.issuerId.toLowerCase())
70
86
  return { ok: false, code: 'issuer_mismatch', reason: 'the presentation names another issuer' };
71
87
  if (pres.nonce !== expect.nonce || pres.audience !== expect.audience)
@@ -74,7 +90,7 @@ export function verifyCredentialStatusPresentation(pres, anchored, expect) {
74
90
  return { ok: false, code: pres.sequence > anchored.sequence ? 'ahead_of_anchor' : 'stale', reason: `the presentation is against sequence ${pres.sequence}; the anchor is ${anchored.sequence}` };
75
91
  if (expect.now - anchored.anchoredAt > expect.maxAgeSeconds)
76
92
  return { ok: false, code: 'stale', reason: `the anchored projection is older than ${expect.maxAgeSeconds}s` };
77
- if (commitmentOf(pres.opening.digest, pres.opening.blind).toLowerCase() !== pres.commitment.toLowerCase())
93
+ if (commitmentOfV1(pres.opening.digest, pres.opening.blind).toLowerCase() !== pres.commitment.toLowerCase())
78
94
  return { ok: false, code: 'opening_mismatch', reason: 'the opening does not commit to the leaf' };
79
95
  if (!verifyInclusion(pres.commitment, pres.proof, anchored.liveCredentialRoot))
80
96
  return { ok: false, code: 'not_live', reason: 'the credential is not in the issuer\'s live set at this sequence' };
@@ -1 +1 @@
1
- {"version":3,"file":"issuer.js","sourceRoot":"","sources":["../src/issuer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"issuer.js","sourceRoot":"","sources":["../src/issuer.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,21 @@
1
- import type { Hex } from 'viem';
1
+ import { type Hex } from 'viem';
2
2
  import { type EstateProjectionV1, type ProjectionSet } from './projection.js';
3
3
  /**
4
4
  * `authority-presentation-v1` — what a holder shows a verifier in ANOTHER estate: one leaf, its opening, a proof, the
5
5
  * root it is against and the sequence that root was anchored under. `suite` names the construction; a verifier that
6
6
  * accepts one need not accept another (`zk-membership-v1` is reserved: the same claim without the opening).
7
+ *
8
+ * Spec 445 §3.8 (audit H-14) — A PRESENTATION IS PROOF OF POSSESSION, NOT A BEARER VALUE. Under `merkle-membership-v1`
9
+ * the leaf named no subject and `subject` / `nonce` / `audience` were plain fields, so anyone who had SEEN a
10
+ * presentation could rewrite the three and present it as themselves. Under `merkle-membership-v2`:
11
+ * 1. the leaf commits to its subject (`commitmentOf(digest, blind, subject)`), so the opening opens for one party;
12
+ * 2. the subject's Smart Agent signs the verifier's challenge (`subjectSignature`, EIP-712 below), so a member
13
+ * cannot hand a usable presentation to a non-member either, and one verifier's copy is useless at the next.
14
+ * The envelope `type` is unchanged; the suite is the version.
7
15
  */
8
16
  export interface AuthorityPresentationV1 {
9
17
  type: 'ap.authority-presentation.v1';
10
- suite: 'merkle-membership-v1' | 'zk-membership-v1';
18
+ suite: 'merkle-membership-v1' | 'merkle-membership-v2' | 'zk-membership-v1';
11
19
  estateId: Hex;
12
20
  set: ProjectionSet;
13
21
  sequence: number;
@@ -18,39 +26,145 @@ export interface AuthorityPresentationV1 {
18
26
  };
19
27
  commitment: Hex;
20
28
  proof: Hex[];
21
- /** Whom this is about — the verifier binds it to the party in front of it. */
29
+ /** Whom this is about. v2: committed in the leaf AND the signer of `subjectSignature`. v1: an unsigned field. */
22
30
  subject: `0x${string}`;
23
- /** Replay bounds, set by the verifier's challenge. */
31
+ /** Replay bounds, set by the verifier's challenge. v2: inside what the subject signed. */
24
32
  nonce: Hex;
25
33
  audience: string;
34
+ /** v2, REQUIRED to verify: the subject Smart Agent's signature over `authorityPresentationDigest`. Absent on what
35
+ * `makeAuthorityPresentation` returns — the estate hands out the leaf, the SUBJECT's runtime signs the challenge. */
36
+ subjectSignature?: Hex;
26
37
  }
38
+ /** The EIP-712 domain of the subject's signature. No `verifyingContract`: the estate is in the struct (`estateId`),
39
+ * and the signature is checked by the subject's own account (ERC-1271), not by a contract of ours. */
40
+ export declare const AUTHORITY_PRESENTATION_DOMAIN_NAME = "AgenticAuthorityPresentation";
41
+ export declare const AUTHORITY_PRESENTATION_DOMAIN_VERSION = "2";
42
+ /** What the subject signs: the leaf (by commitment, in its estate, set and sequence) and THIS verifier's challenge.
43
+ * `nonce` is `bytes` (a challenge's length is the verifier's choice); `set` and `audience` are strings. */
44
+ export declare const AUTHORITY_PRESENTATION_EIP712_TYPES: {
45
+ readonly AuthorityPresentation: readonly [{
46
+ readonly name: "estateId";
47
+ readonly type: "bytes32";
48
+ }, {
49
+ readonly name: "set";
50
+ readonly type: "string";
51
+ }, {
52
+ readonly name: "sequence";
53
+ readonly type: "uint64";
54
+ }, {
55
+ readonly name: "commitment";
56
+ readonly type: "bytes32";
57
+ }, {
58
+ readonly name: "nonce";
59
+ readonly type: "bytes";
60
+ }, {
61
+ readonly name: "audience";
62
+ readonly type: "string";
63
+ }];
64
+ };
65
+ export type AuthorityPresentationSigned = Pick<AuthorityPresentationV1, 'estateId' | 'set' | 'sequence' | 'commitment' | 'nonce' | 'audience'>;
66
+ /** The typed data the subject's runtime signs (`signTypedData`) — `chainId` is the chain the SUBJECT's account lives
67
+ * on, where the verifier will ask it (ERC-1271 / ERC-6492) whether the signature is its own. Hex fields are
68
+ * lowercased so the digest is a function of the bytes, not of how a hop happened to case them. */
69
+ export declare function authorityPresentationTypedData(pres: AuthorityPresentationSigned, opts: {
70
+ chainId: number;
71
+ }): {
72
+ domain: {
73
+ name: string;
74
+ version: string;
75
+ chainId: number;
76
+ };
77
+ types: {
78
+ readonly AuthorityPresentation: readonly [{
79
+ readonly name: "estateId";
80
+ readonly type: "bytes32";
81
+ }, {
82
+ readonly name: "set";
83
+ readonly type: "string";
84
+ }, {
85
+ readonly name: "sequence";
86
+ readonly type: "uint64";
87
+ }, {
88
+ readonly name: "commitment";
89
+ readonly type: "bytes32";
90
+ }, {
91
+ readonly name: "nonce";
92
+ readonly type: "bytes";
93
+ }, {
94
+ readonly name: "audience";
95
+ readonly type: "string";
96
+ }];
97
+ };
98
+ primaryType: "AuthorityPresentation";
99
+ message: {
100
+ estateId: Hex;
101
+ set: ProjectionSet;
102
+ sequence: bigint;
103
+ commitment: Hex;
104
+ nonce: Hex;
105
+ audience: string;
106
+ };
107
+ };
108
+ /** The EIP-712 digest of the above — what an ERC-1271 `isValidSignature(digest, signature)` read is asked about. */
109
+ export declare function authorityPresentationDigest(pres: AuthorityPresentationSigned, opts: {
110
+ chainId: number;
111
+ }): Hex;
112
+ /** The estate's half: one leaf, its opening and proof, against the verifier's challenge. For a v2 projection the result
113
+ * is NOT yet presentable — the subject signs `authorityPresentationDigest(pres, { chainId })` and the signature is
114
+ * attached as `subjectSignature`. A projection stored before spec 445 §3.8 yields a v1 (bearer) presentation. */
27
115
  export declare function makeAuthorityPresentation(p: EstateProjectionV1, set: ProjectionSet, digest: Hex, challenge: {
28
116
  nonce: Hex;
29
117
  audience: string;
30
118
  }): AuthorityPresentationV1 | null;
31
- /** What the verifier READ from `EstateProjectionRegistry` on public ground — the live original, never the presentation's word. */
119
+ /** What the verifier READ from `EstateProjectionRegistry` on public ground — the live original, never the presentation's word.
120
+ * Spec 445 / generation 4 / B2 (REG-2): rows are keyed by `(estateId, signer)`; `signer` names the row that was read —
121
+ * the estate's DECLARED projection signer (`readAnchoredRoots`), never one the presentation suggests. */
32
122
  export interface AnchoredRoots {
33
123
  estateId: Hex;
124
+ signer: `0x${string}`;
34
125
  sequence: number;
35
126
  liveGrantRoot: Hex;
36
127
  membershipRoot: Hex;
37
128
  anchoredAt: number;
38
129
  }
130
+ /**
131
+ * The verifier's side of the subject signature, INJECTED: this package imports no chain client. The app wires the
132
+ * `UniversalSignatureValidator` / ERC-1271 read against `subject` on `chainId`. A throw is a refusal.
133
+ */
134
+ export interface VerifyAuthorityPresentationOptions {
135
+ /** The chain the subject's Smart Agent is asked on; it is the EIP-712 domain's chainId. Required for v2. */
136
+ chainId?: number;
137
+ /** Required for v2 — none supplied ⇒ `subject_signature_unverifiable` (fail closed; never "accepted unchecked"). */
138
+ verifySubjectSignature?: (subject: `0x${string}`, digest: Hex, signature: Hex) => Promise<boolean>;
139
+ /** Accept a `merkle-membership-v1` presentation — a BEARER value: it proves someone saw this opening, not that the
140
+ * party in front of you is its subject. Default false. The verdict then says `grade: 'bearer'`; a receipt must too. */
141
+ acceptBearerV1?: boolean;
142
+ }
143
+ /** `standing`: the committed subject signed this verifier's challenge. `bearer`: a v1 opening anyone who saw it could
144
+ * present (only under `acceptBearerV1`). */
145
+ export type PresentationGrade = 'standing' | 'bearer';
39
146
  export type PresentationVerdict = {
40
147
  ok: true;
41
148
  estateId: Hex;
42
149
  set: Exclude<ProjectionSet, 'live-credential'>;
43
150
  sequence: number;
44
151
  subject: `0x${string}`;
152
+ grade: PresentationGrade;
45
153
  } | {
46
154
  ok: false;
47
- code: 'suite_unsupported' | 'malformed' | 'estate_mismatch' | 'stale' | 'ahead_of_anchor' | 'opening_mismatch' | 'not_in_root' | 'challenge_mismatch' | 'subject_mismatch';
155
+ code: 'suite_unsupported' | 'bearer_v1_refused' | 'malformed' | 'estate_mismatch' | 'stale' | 'ahead_of_anchor' | 'opening_mismatch' | 'not_in_root' | 'challenge_mismatch' | 'subject_mismatch' | 'chain_undeclared' | 'subject_signature_missing' | 'subject_signature_unverifiable' | 'subject_signature_invalid';
48
156
  reason: string;
49
157
  };
50
158
  /**
51
159
  * Verify against the ANCHORED roots the verifier read itself. The freshness policy is the verifier's: `maxAge`
52
160
  * bounds how old the anchored sequence may be; a presentation against a sequence the registry has not anchored
53
161
  * is refused, not fetched. Learns `live` / `member`, never "how much" — no score, no ranking (ADR-0056).
162
+ *
163
+ * ASYNC since spec 445 §3.8: the subject's signature is an account read. There is deliberately no synchronous
164
+ * sibling — a second entry point would be the place the signature check is not made (445 §0).
165
+ *
166
+ * v2 order: shape → estate → challenge → subject → sequence/freshness → opening (WITH the subject) → inclusion →
167
+ * signature. The signature is last so no account read is spent on a presentation the tree already refuses.
54
168
  */
55
169
  export declare function verifyAuthorityPresentation(pres: AuthorityPresentationV1, anchored: AnchoredRoots, expect: {
56
170
  subject: `0x${string}`;
@@ -58,5 +172,5 @@ export declare function verifyAuthorityPresentation(pres: AuthorityPresentationV
58
172
  audience: string;
59
173
  now: number;
60
174
  maxAgeSeconds: number;
61
- }): PresentationVerdict;
175
+ }, opts?: VerifyAuthorityPresentationOptions): Promise<PresentationVerdict>;
62
176
  //# sourceMappingURL=presentation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../src/presentation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,EAA0B,KAAK,kBAAkB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEtG;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,8BAA8B,CAAC;IACrC,KAAK,EAAE,sBAAsB,GAAG,kBAAkB,CAAC;IACnD,QAAQ,EAAE,GAAG,CAAC;IACd,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,uGAAuG;IACvG,OAAO,CAAC,EAAE;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC;IACtC,UAAU,EAAE,GAAG,CAAC;IAChB,KAAK,EAAE,GAAG,EAAE,CAAC;IACb,8EAA8E;IAC9E,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IACvB,sDAAsD;IACtD,KAAK,EAAE,GAAG,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,kBAAkB,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE;IAAE,KAAK,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,GAAG,IAAI,CAI7K;AAED,kIAAkI;AAClI,MAAM,WAAW,aAAa;IAAG,QAAQ,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,GAAG,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AAE/H,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAA;CAAE,GACrH;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,mBAAmB,GAAG,WAAW,GAAG,iBAAiB,GAAG,OAAO,GAAG,iBAAiB,GAAG,kBAAkB,GAAG,aAAa,GAAG,oBAAoB,GAAG,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9M;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,uBAAuB,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE;IAAE,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,mBAAmB,CAc7N"}
1
+ {"version":3,"file":"presentation.d.ts","sourceRoot":"","sources":["../src/presentation.ts"],"names":[],"mappings":"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"}
@@ -1,25 +1,84 @@
1
1
  import { verifyInclusion } from '@agenticprimitives/content-primitives';
2
- import { commitmentOf, proofFor } from './projection.js';
2
+ import { hashTypedData } from 'viem';
3
+ import { commitmentOf, commitmentOfV1, proofFor } from './projection.js';
4
+ /** The EIP-712 domain of the subject's signature. No `verifyingContract`: the estate is in the struct (`estateId`),
5
+ * and the signature is checked by the subject's own account (ERC-1271), not by a contract of ours. */
6
+ export const AUTHORITY_PRESENTATION_DOMAIN_NAME = 'AgenticAuthorityPresentation';
7
+ export const AUTHORITY_PRESENTATION_DOMAIN_VERSION = '2';
8
+ /** What the subject signs: the leaf (by commitment, in its estate, set and sequence) and THIS verifier's challenge.
9
+ * `nonce` is `bytes` (a challenge's length is the verifier's choice); `set` and `audience` are strings. */
10
+ export const AUTHORITY_PRESENTATION_EIP712_TYPES = {
11
+ AuthorityPresentation: [
12
+ { name: 'estateId', type: 'bytes32' },
13
+ { name: 'set', type: 'string' },
14
+ { name: 'sequence', type: 'uint64' },
15
+ { name: 'commitment', type: 'bytes32' },
16
+ { name: 'nonce', type: 'bytes' },
17
+ { name: 'audience', type: 'string' },
18
+ ],
19
+ };
20
+ /** A chain id is declared or it is an error — never defaulted, never inferred from the estate id (which is a hash). */
21
+ function declaredChainId(chainId) {
22
+ if (typeof chainId !== 'number' || !Number.isSafeInteger(chainId) || chainId <= 0)
23
+ throw new Error('authority presentation: chainId must be declared — the chain the subject Smart Agent\'s signature is verified on');
24
+ return chainId;
25
+ }
26
+ /** The typed data the subject's runtime signs (`signTypedData`) — `chainId` is the chain the SUBJECT's account lives
27
+ * on, where the verifier will ask it (ERC-1271 / ERC-6492) whether the signature is its own. Hex fields are
28
+ * lowercased so the digest is a function of the bytes, not of how a hop happened to case them. */
29
+ export function authorityPresentationTypedData(pres, opts) {
30
+ return {
31
+ domain: { name: AUTHORITY_PRESENTATION_DOMAIN_NAME, version: AUTHORITY_PRESENTATION_DOMAIN_VERSION, chainId: declaredChainId(opts.chainId) },
32
+ types: AUTHORITY_PRESENTATION_EIP712_TYPES,
33
+ primaryType: 'AuthorityPresentation',
34
+ message: {
35
+ estateId: pres.estateId.toLowerCase(), set: pres.set, sequence: BigInt(pres.sequence),
36
+ commitment: pres.commitment.toLowerCase(), nonce: pres.nonce.toLowerCase(), audience: pres.audience,
37
+ },
38
+ };
39
+ }
40
+ /** The EIP-712 digest of the above — what an ERC-1271 `isValidSignature(digest, signature)` read is asked about. */
41
+ export function authorityPresentationDigest(pres, opts) {
42
+ return hashTypedData(authorityPresentationTypedData(pres, opts));
43
+ }
44
+ /** The estate's half: one leaf, its opening and proof, against the verifier's challenge. For a v2 projection the result
45
+ * is NOT yet presentable — the subject signs `authorityPresentationDigest(pres, { chainId })` and the signature is
46
+ * attached as `subjectSignature`. A projection stored before spec 445 §3.8 yields a v1 (bearer) presentation. */
3
47
  export function makeAuthorityPresentation(p, set, digest, challenge) {
4
48
  const hit = proofFor(p, set, digest);
5
49
  if (!hit)
6
50
  return null;
7
- return { type: 'ap.authority-presentation.v1', suite: 'merkle-membership-v1', estateId: p.estateId, set, sequence: p.sequence, opening: { digest: hit.leaf.digest, blind: hit.leaf.blind }, commitment: hit.leaf.commitment, proof: hit.proof, subject: hit.leaf.subject, nonce: challenge.nonce, audience: challenge.audience };
51
+ const suite = (hit.leaf.suite ?? p.suite) === 'merkle-membership-v2' ? 'merkle-membership-v2' : 'merkle-membership-v1';
52
+ return { type: 'ap.authority-presentation.v1', suite, estateId: p.estateId, set, sequence: p.sequence, opening: { digest: hit.leaf.digest, blind: hit.leaf.blind }, commitment: hit.leaf.commitment, proof: hit.proof, subject: hit.leaf.subject, nonce: challenge.nonce, audience: challenge.audience };
8
53
  }
9
54
  /**
10
55
  * Verify against the ANCHORED roots the verifier read itself. The freshness policy is the verifier's: `maxAge`
11
56
  * bounds how old the anchored sequence may be; a presentation against a sequence the registry has not anchored
12
57
  * is refused, not fetched. Learns `live` / `member`, never "how much" — no score, no ranking (ADR-0056).
58
+ *
59
+ * ASYNC since spec 445 §3.8: the subject's signature is an account read. There is deliberately no synchronous
60
+ * sibling — a second entry point would be the place the signature check is not made (445 §0).
61
+ *
62
+ * v2 order: shape → estate → challenge → subject → sequence/freshness → opening (WITH the subject) → inclusion →
63
+ * signature. The signature is last so no account read is spent on a presentation the tree already refuses.
13
64
  */
14
- export function verifyAuthorityPresentation(pres, anchored, expect) {
65
+ export async function verifyAuthorityPresentation(pres, anchored, expect, opts = {}) {
15
66
  if (pres.type !== 'ap.authority-presentation.v1')
16
67
  return { ok: false, code: 'malformed', reason: 'not an authority presentation' };
17
- if (pres.suite !== 'merkle-membership-v1')
68
+ if (pres.suite !== 'merkle-membership-v2' && pres.suite !== 'merkle-membership-v1')
18
69
  return { ok: false, code: 'suite_unsupported', reason: `suite ${pres.suite} is not verified here` };
70
+ const v2 = pres.suite === 'merkle-membership-v2';
71
+ if (!v2 && opts.acceptBearerV1 !== true)
72
+ return { ok: false, code: 'bearer_v1_refused', reason: 'a merkle-membership-v1 presentation is a bearer value (spec 445 §3.8); the estate re-anchors a v2 projection, or the verifier opts in with acceptBearerV1 and grades it bearer' };
19
73
  if (!pres.opening)
20
74
  return { ok: false, code: 'malformed', reason: 'the merkle suite needs the opening' };
75
+ if (typeof pres.subject !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(pres.subject))
76
+ return { ok: false, code: 'malformed', reason: 'the subject is not an address' };
21
77
  if (pres.estateId.toLowerCase() !== anchored.estateId.toLowerCase())
22
78
  return { ok: false, code: 'estate_mismatch', reason: 'the presentation names another estate' };
79
+ // REG-2 (generation 4): roots that name no signer row were not read the generation-4 way — refuse, never guess.
80
+ if (typeof anchored.signer !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(anchored.signer) || /^0x0{40}$/.test(anchored.signer))
81
+ return { ok: false, code: 'malformed', reason: 'the anchored roots name no signer row — read roots(estateId, declaredSigner) with readAnchoredRoots' };
23
82
  if (pres.nonce.toLowerCase() !== expect.nonce.toLowerCase() || pres.audience !== expect.audience)
24
83
  return { ok: false, code: 'challenge_mismatch', reason: 'the presentation does not answer this challenge' };
25
84
  if (pres.subject.toLowerCase() !== expect.subject.toLowerCase())
@@ -28,13 +87,50 @@ export function verifyAuthorityPresentation(pres, anchored, expect) {
28
87
  return { ok: false, code: pres.sequence > anchored.sequence ? 'ahead_of_anchor' : 'stale', reason: `the presentation is against sequence ${pres.sequence}; the anchor is at ${anchored.sequence}` };
29
88
  if (expect.now - anchored.anchoredAt > expect.maxAgeSeconds)
30
89
  return { ok: false, code: 'stale', reason: `the anchored projection is older than ${expect.maxAgeSeconds}s` };
31
- if (commitmentOf(pres.opening.digest, pres.opening.blind).toLowerCase() !== pres.commitment.toLowerCase())
32
- return { ok: false, code: 'opening_mismatch', reason: 'the opening does not commit to the leaf' };
90
+ let opened;
91
+ try {
92
+ opened = v2 ? commitmentOf(pres.opening.digest, pres.opening.blind, pres.subject) : commitmentOfV1(pres.opening.digest, pres.opening.blind);
93
+ }
94
+ catch {
95
+ return { ok: false, code: 'malformed', reason: 'the opening is not two bytes32' };
96
+ }
97
+ // v2: the subject is INSIDE the commitment — an opening re-aimed at another subject stops here.
98
+ if (opened.toLowerCase() !== pres.commitment.toLowerCase())
99
+ return { ok: false, code: 'opening_mismatch', reason: v2 ? 'the opening does not commit to the leaf for this subject' : 'the opening does not commit to the leaf' };
33
100
  if (pres.set === 'live-credential')
34
101
  return { ok: false, code: 'malformed', reason: 'a live-credential leaf is an ISSUER row\'s — verify it with verifyCredentialStatusPresentation against the issuer\'s anchor' };
102
+ if (pres.set !== 'live-grant' && pres.set !== 'membership')
103
+ return { ok: false, code: 'malformed', reason: 'unknown set' };
35
104
  const root = pres.set === 'live-grant' ? anchored.liveGrantRoot : anchored.membershipRoot;
36
105
  if (!verifyInclusion(pres.commitment, pres.proof, root))
37
106
  return { ok: false, code: 'not_in_root', reason: `the leaf is not in the anchored ${pres.set} root` };
38
- return { ok: true, estateId: pres.estateId, set: pres.set, sequence: pres.sequence, subject: pres.subject };
107
+ const subject = pres.subject.toLowerCase();
108
+ if (!v2)
109
+ return { ok: true, estateId: pres.estateId, set: pres.set, sequence: pres.sequence, subject, grade: 'bearer' };
110
+ // Proof of possession: the committed subject signed THIS challenge. The digest is recomputed here from the values
111
+ // just checked against the verifier's own challenge — never taken from the presentation.
112
+ if (!pres.subjectSignature || !/^0x([0-9a-fA-F]{2})+$/.test(pres.subjectSignature))
113
+ return { ok: false, code: 'subject_signature_missing', reason: 'a v2 presentation carries the subject\'s signature over the challenge' };
114
+ if (typeof opts.verifySubjectSignature !== 'function')
115
+ return { ok: false, code: 'subject_signature_unverifiable', reason: 'no subject-signature check was supplied; a v2 presentation is never accepted unchecked' };
116
+ if (typeof opts.chainId !== 'number' || !Number.isSafeInteger(opts.chainId) || opts.chainId <= 0)
117
+ return { ok: false, code: 'chain_undeclared', reason: 'the chain the subject signature is verified on must be declared; it is never defaulted' };
118
+ let digest;
119
+ try {
120
+ digest = authorityPresentationDigest(pres, { chainId: opts.chainId });
121
+ }
122
+ catch {
123
+ return { ok: false, code: 'malformed', reason: 'the signed fields cannot be encoded' };
124
+ }
125
+ let good = false;
126
+ try {
127
+ good = (await opts.verifySubjectSignature(subject, digest, pres.subjectSignature)) === true;
128
+ }
129
+ catch {
130
+ good = false;
131
+ }
132
+ if (!good)
133
+ return { ok: false, code: 'subject_signature_invalid', reason: 'the subject did not sign this presentation for this challenge' };
134
+ return { ok: true, estateId: pres.estateId, set: pres.set, sequence: pres.sequence, subject, grade: 'standing' };
39
135
  }
40
136
  //# sourceMappingURL=presentation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"presentation.js","sourceRoot":"","sources":["../src/presentation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"presentation.js","sourceRoot":"","sources":["../src/presentation.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,7 @@
1
1
  import { type Hex } from 'viem';
2
+ /** The Merkle constructions a leaf can be built under. `v1` is the pre-445 leaf, `keccak256(digest ‖ blind)`: it names
3
+ * no subject, so its presentation is a BEARER value. `v2` (spec 445 §3.8, audit H-14) commits the subject into the leaf. */
4
+ export type MerkleSuite = 'merkle-membership-v1' | 'merkle-membership-v2';
2
5
  import { type CorpusTree } from '@agenticprimitives/content-primitives';
3
6
  /** The estate's two sets, and (spec 305 W2 Z3) an ISSUER's one: `live-credential` — the credentials an issuer currently
4
7
  * vouches for (issued, unexpired, unrevoked). Inclusion proves not-revoked; a revocation is a removal and a new root —
@@ -15,13 +18,33 @@ export interface ProjectionLeafV1 {
15
18
  /** The subject this leaf is about (the delegate; the member) — kept by the estate, never in the tree. */
16
19
  subject: `0x${string}`;
17
20
  commitment: Hex;
21
+ /** The construction `commitment` was built under. Absent on a record written before spec 445 §3.8 ⇒ v1. */
22
+ suite?: MerkleSuite;
18
23
  }
19
- /** `keccak256(digest ‖ blind)` — the same construction for both sets, so a verifier's code is one function. */
20
- export declare function commitmentOf(digest: Hex, blind: Hex): Hex;
24
+ /**
25
+ * The v2 leaf (spec 445 §3.8 — a presentation is proof of possession, not a bearer value): the leaf COMMITS TO ITS
26
+ * SUBJECT, so an opening re-presented under another subject does not open the leaf.
27
+ *
28
+ * commitment = keccak256(digest ‖ blind ‖ subject32) — 96 bytes in
29
+ *
30
+ * `subject32` is the 20-byte address left-padded with 12 zero bytes to 32 (the ABI word for an `address`), lowercase
31
+ * hex — case never reaches the hash. In Solidity: `keccak256(abi.encodePacked(digest, blind, bytes32(uint256(uint160(subject)))))`,
32
+ * which is byte-identical to `keccak256(abi.encode(digest, blind, subject))`. The same construction for both sets.
33
+ */
34
+ export declare function commitmentOf(digest: Hex, blind: Hex, subject: `0x${string}`): Hex;
35
+ /**
36
+ * The v1 leaf, `keccak256(digest ‖ blind)` — NO SUBJECT. Kept under an explicit name for two readers only: a projection
37
+ * built before spec 445 §3.8 (its presentation is graded `bearer` and refused unless the verifier opts in), and the
38
+ * ISSUER row (`issuer.ts`), whose leaf is a credential and not a claim about an address. Never use it for a new
39
+ * estate leaf.
40
+ */
41
+ export declare function commitmentOfV1(digest: Hex, blind: Hex): Hex;
21
42
  export interface EstateProjectionV1 {
22
43
  type: 'ap.estate-projection.v1';
23
44
  /** The estate: keccak256 of `eip155:<chainId>:<governance address>` — the one thing public ground learns. */
24
45
  estateId: Hex;
46
+ /** The leaf construction of BOTH trees. Absent on a projection stored before spec 445 §3.8 ⇒ v1 (bearer). */
47
+ suite?: MerkleSuite;
25
48
  sequence: number;
26
49
  liveGrantRoot: Hex;
27
50
  membershipRoot: Hex;
@@ -41,7 +64,8 @@ export interface EstateProjectionV1 {
41
64
  }
42
65
  export declare function estateIdOf(chainId: number, governance: `0x${string}`): Hex;
43
66
  /** Build both trees from what the estate vouches for right now. Leaves are sorted by commitment so the root is a
44
- * function of the SET, not of the order the estate happened to list it in. */
67
+ * function of the SET, not of the order the estate happened to list it in. Leaves are v2 (subject-committing, spec
68
+ * 445 §3.8) — there is no option to build a v1 tree; an estate that anchored v1 re-anchors (a sequence bump). */
45
69
  export declare function buildProjection(input: {
46
70
  chainId: number;
47
71
  governance: `0x${string}`;
@@ -1 +1 @@
1
- {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,uCAAuC,CAAC;AAEtG;;kHAEkH;AAClH,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG,iBAAiB,CAAC;AAE5E;4GAC4G;AAC5G,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,aAAa,CAAC;IACnB,2FAA2F;IAC3F,MAAM,EAAE,GAAG,CAAC;IACZ,qGAAqG;IACrG,KAAK,EAAE,GAAG,CAAC;IACX,yGAAyG;IACzG,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IACvB,UAAU,EAAE,GAAG,CAAC;CACjB;AAED,+GAA+G;AAC/G,wBAAgB,YAAY,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG,CAGzD;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,yBAAyB,CAAC;IAChC,6GAA6G;IAC7G,QAAQ,EAAE,GAAG,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,GAAG,CAAC;IACnB,cAAc,EAAE,GAAG,CAAC;IACpB,wEAAwE;IACxE,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,iGAAiG;IACjG,MAAM,EAAE;QAAE,SAAS,EAAE,gBAAgB,EAAE,CAAC;QAAC,UAAU,EAAE,gBAAgB,EAAE,CAAA;KAAE,CAAC;IAC1E,yCAAyC;IACzC,KAAK,EAAE;QAAE,SAAS,EAAE,UAAU,CAAC;QAAC,UAAU,EAAE,UAAU,CAAA;KAAE,CAAC;CAC1D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,MAAM,EAAE,GAAG,GAAG,CAE1E;AAED;+EAC+E;AAC/E,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,GAAG,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IAClG,UAAU,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC/E,WAAW,EAAE,aAAa,CAAC;QAAE,MAAM,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACjF,GAAG,kBAAkB,CAWrB;AAED,uHAAuH;AACvH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,EAAE,UAAU,GAAG,UAAU,GAAG,eAAe,GAAG,gBAAgB,GAAG,aAAa,CAAC,GAAG,GAAG,CAG/I;AAED,iDAAiD;AACjD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,kBAAkB,EAAE,GAAG,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,GAAG,EAAE,CAAA;CAAE,GAAG,IAAI,CAMhI"}
1
+ {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,48 @@
1
1
  import { keccak256 } from 'viem';
2
2
  import { buildCorpusTree, merkleProof } from '@agenticprimitives/content-primitives';
3
- /** `keccak256(digest ‖ blind)` — the same construction for both sets, so a verifier's code is one function. */
4
- export function commitmentOf(digest, blind) {
5
- if (!/^0x[0-9a-fA-F]{64}$/.test(digest) || !/^0x[0-9a-fA-F]{64}$/.test(blind))
3
+ const BYTES32 = /^0x[0-9a-fA-F]{64}$/;
4
+ const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
5
+ /**
6
+ * The v2 leaf (spec 445 §3.8 — a presentation is proof of possession, not a bearer value): the leaf COMMITS TO ITS
7
+ * SUBJECT, so an opening re-presented under another subject does not open the leaf.
8
+ *
9
+ * commitment = keccak256(digest ‖ blind ‖ subject32) — 96 bytes in
10
+ *
11
+ * `subject32` is the 20-byte address left-padded with 12 zero bytes to 32 (the ABI word for an `address`), lowercase
12
+ * hex — case never reaches the hash. In Solidity: `keccak256(abi.encodePacked(digest, blind, bytes32(uint256(uint160(subject)))))`,
13
+ * which is byte-identical to `keccak256(abi.encode(digest, blind, subject))`. The same construction for both sets.
14
+ */
15
+ export function commitmentOf(digest, blind, subject) {
16
+ if (!BYTES32.test(digest) || !BYTES32.test(blind))
6
17
  throw new Error('commitmentOf: digest and blind are bytes32');
18
+ if (typeof subject !== 'string' || !ADDRESS.test(subject))
19
+ throw new Error('commitmentOf: subject is a 20-byte address (the v1 leaf, which names no subject, is commitmentOfV1)');
20
+ return keccak256(`0x${digest.slice(2)}${blind.slice(2)}${'00'.repeat(12)}${subject.slice(2).toLowerCase()}`);
21
+ }
22
+ /**
23
+ * The v1 leaf, `keccak256(digest ‖ blind)` — NO SUBJECT. Kept under an explicit name for two readers only: a projection
24
+ * built before spec 445 §3.8 (its presentation is graded `bearer` and refused unless the verifier opts in), and the
25
+ * ISSUER row (`issuer.ts`), whose leaf is a credential and not a claim about an address. Never use it for a new
26
+ * estate leaf.
27
+ */
28
+ export function commitmentOfV1(digest, blind) {
29
+ if (!BYTES32.test(digest) || !BYTES32.test(blind))
30
+ throw new Error('commitmentOfV1: digest and blind are bytes32');
7
31
  return keccak256(`0x${digest.slice(2)}${blind.slice(2)}`);
8
32
  }
9
33
  export function estateIdOf(chainId, governance) {
10
34
  return keccak256(new TextEncoder().encode(`eip155:${chainId}:${governance.toLowerCase()}`));
11
35
  }
12
36
  /** Build both trees from what the estate vouches for right now. Leaves are sorted by commitment so the root is a
13
- * function of the SET, not of the order the estate happened to list it in. */
37
+ * function of the SET, not of the order the estate happened to list it in. Leaves are v2 (subject-committing, spec
38
+ * 445 §3.8) — there is no option to build a v1 tree; an estate that anchored v1 re-anchors (a sequence bump). */
14
39
  export function buildProjection(input) {
15
- const toLeaves = (set, rows) => rows.map((r) => ({ set, digest: r.digest, blind: r.blind, subject: r.subject, commitment: commitmentOf(r.digest, r.blind) })).sort((a, b) => (a.commitment < b.commitment ? -1 : 1));
40
+ const toLeaves = (set, rows) => rows.map((r) => ({ set, digest: r.digest, blind: r.blind, subject: r.subject, commitment: commitmentOf(r.digest, r.blind, r.subject), suite: 'merkle-membership-v2' })).sort((a, b) => (a.commitment < b.commitment ? -1 : 1));
16
41
  const liveGrant = toLeaves('live-grant', input.liveGrants);
17
42
  const membership = toLeaves('membership', input.memberships);
18
43
  const trees = { liveGrant: buildCorpusTree(liveGrant.map((l) => l.commitment)), membership: buildCorpusTree(membership.map((l) => l.commitment)) };
19
44
  return {
20
- type: 'ap.estate-projection.v1', estateId: estateIdOf(input.chainId, input.governance), sequence: input.sequence,
45
+ type: 'ap.estate-projection.v1', estateId: estateIdOf(input.chainId, input.governance), suite: 'merkle-membership-v2', sequence: input.sequence,
21
46
  liveGrantRoot: trees.liveGrant.root, membershipRoot: trees.membership.root, ...(input.charterHash ? { charterHash: input.charterHash } : {}),
22
47
  builtAt: (input.now ?? (() => new Date()))().toISOString(), leaves: { liveGrant, membership }, trees,
23
48
  };
@@ -1 +1 @@
1
- {"version":3,"file":"projection.js","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,MAAM,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,WAAW,EAAmB,MAAM,uCAAuC,CAAC;AAoBtG,+GAA+G;AAC/G,MAAM,UAAU,YAAY,CAAC,MAAW,EAAE,KAAU;IAClD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAC7I,OAAO,SAAS,CAAC,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAS,CAAC,CAAC;AACnE,CAAC;AAkBD,MAAM,UAAU,UAAU,CAAC,OAAe,EAAE,UAAyB;IACnE,OAAO,SAAS,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,OAAO,IAAI,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;AAC9F,CAAC;AAED;+EAC+E;AAC/E,MAAM,UAAU,eAAe,CAAC,KAI/B;IACC,MAAM,QAAQ,GAAG,CAAC,GAAkB,EAAE,IAAwE,EAAsB,EAAE,CACpI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvL,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,QAAQ,CAAC,YAAY,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,EAAE,SAAS,EAAE,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,UAAU,EAAE,eAAe,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;IACnJ,OAAO;QACL,IAAI,EAAE,yBAAyB,EAAE,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ;QAChH,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5I,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,KAAK;KACrG,CAAC;AACJ,CAAC;AAED,uHAAuH;AACvH,MAAM,UAAU,gBAAgB,CAAC,CAAyG;IACxI,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,IAAK,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAU,CAAC;IACjE,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAS,CAAC,CAAC;AAC5K,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,QAAQ,CAAC,CAAqB,EAAE,GAAkB,EAAE,MAAW;IAC7E,MAAM,MAAM,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;IAC/E,MAAM,IAAI,GAAG,GAAG,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;IAC3E,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IACnF,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAE,EAAE,KAAK,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC"}
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../src/projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,287 @@
1
+ import type { Hex } from 'viem';
2
+ import type { AnchoredRoots } from './presentation.js';
3
+ /** The generation-4 `EstateProjectionRegistry` surface this package reads and its consumers write. Not in
4
+ * `check:abi-sync`; the B2 test pins it to the contract's shape. */
5
+ export declare const estateProjectionRegistryAbi: readonly [{
6
+ readonly type: "function";
7
+ readonly name: "roots";
8
+ readonly stateMutability: "view";
9
+ readonly inputs: readonly [{
10
+ readonly name: "estateId";
11
+ readonly type: "bytes32";
12
+ }, {
13
+ readonly name: "signer";
14
+ readonly type: "address";
15
+ }];
16
+ readonly outputs: readonly [{
17
+ readonly name: "liveGrantRoot";
18
+ readonly type: "bytes32";
19
+ }, {
20
+ readonly name: "membershipRoot";
21
+ readonly type: "bytes32";
22
+ }, {
23
+ readonly name: "charterHash";
24
+ readonly type: "bytes32";
25
+ }, {
26
+ readonly name: "sequence";
27
+ readonly type: "uint64";
28
+ }, {
29
+ readonly name: "anchoredAt";
30
+ readonly type: "uint64";
31
+ }];
32
+ }, {
33
+ readonly type: "function";
34
+ readonly name: "isRetired";
35
+ readonly stateMutability: "view";
36
+ readonly inputs: readonly [{
37
+ readonly name: "estateId";
38
+ readonly type: "bytes32";
39
+ }, {
40
+ readonly name: "signer";
41
+ readonly type: "address";
42
+ }];
43
+ readonly outputs: readonly [{
44
+ readonly type: "bool";
45
+ }];
46
+ }, {
47
+ readonly type: "function";
48
+ readonly name: "successorOf";
49
+ readonly stateMutability: "view";
50
+ readonly inputs: readonly [{
51
+ readonly name: "estateId";
52
+ readonly type: "bytes32";
53
+ }, {
54
+ readonly name: "signer";
55
+ readonly type: "address";
56
+ }];
57
+ readonly outputs: readonly [{
58
+ readonly type: "address";
59
+ }];
60
+ }, {
61
+ readonly type: "function";
62
+ readonly name: "declaredSignerOf";
63
+ readonly stateMutability: "view";
64
+ readonly inputs: readonly [{
65
+ readonly name: "estateId";
66
+ readonly type: "bytes32";
67
+ }];
68
+ readonly outputs: readonly [{
69
+ readonly name: "signer";
70
+ readonly type: "address";
71
+ }];
72
+ }, {
73
+ readonly type: "function";
74
+ readonly name: "estateIdOf";
75
+ readonly stateMutability: "pure";
76
+ readonly inputs: readonly [{
77
+ readonly name: "chainId";
78
+ readonly type: "uint256";
79
+ }, {
80
+ readonly name: "governance";
81
+ readonly type: "address";
82
+ }];
83
+ readonly outputs: readonly [{
84
+ readonly type: "bytes32";
85
+ }];
86
+ }, {
87
+ readonly type: "function";
88
+ readonly name: "MAX_SEQUENCE_STEP";
89
+ readonly stateMutability: "view";
90
+ readonly inputs: readonly [];
91
+ readonly outputs: readonly [{
92
+ readonly type: "uint64";
93
+ }];
94
+ }, {
95
+ readonly type: "function";
96
+ readonly name: "setRoots";
97
+ readonly stateMutability: "nonpayable";
98
+ readonly inputs: readonly [{
99
+ readonly name: "estateId";
100
+ readonly type: "bytes32";
101
+ }, {
102
+ readonly name: "liveGrantRoot";
103
+ readonly type: "bytes32";
104
+ }, {
105
+ readonly name: "membershipRoot";
106
+ readonly type: "bytes32";
107
+ }, {
108
+ readonly name: "charterHash";
109
+ readonly type: "bytes32";
110
+ }, {
111
+ readonly name: "sequence";
112
+ readonly type: "uint64";
113
+ }];
114
+ readonly outputs: readonly [];
115
+ }, {
116
+ readonly type: "function";
117
+ readonly name: "rotateSigner";
118
+ readonly stateMutability: "nonpayable";
119
+ readonly inputs: readonly [{
120
+ readonly name: "estateId";
121
+ readonly type: "bytes32";
122
+ }, {
123
+ readonly name: "to";
124
+ readonly type: "address";
125
+ }];
126
+ readonly outputs: readonly [];
127
+ }, {
128
+ readonly type: "function";
129
+ readonly name: "declareSigner";
130
+ readonly stateMutability: "nonpayable";
131
+ readonly inputs: readonly [{
132
+ readonly name: "signer";
133
+ readonly type: "address";
134
+ }];
135
+ readonly outputs: readonly [{
136
+ readonly name: "estateId";
137
+ readonly type: "bytes32";
138
+ }];
139
+ }, {
140
+ readonly type: "event";
141
+ readonly name: "RootsAnchored";
142
+ readonly inputs: readonly [{
143
+ readonly name: "estateId";
144
+ readonly type: "bytes32";
145
+ readonly indexed: true;
146
+ }, {
147
+ readonly name: "signer";
148
+ readonly type: "address";
149
+ readonly indexed: true;
150
+ }, {
151
+ readonly name: "sequence";
152
+ readonly type: "uint64";
153
+ readonly indexed: true;
154
+ }, {
155
+ readonly name: "liveGrantRoot";
156
+ readonly type: "bytes32";
157
+ readonly indexed: false;
158
+ }, {
159
+ readonly name: "membershipRoot";
160
+ readonly type: "bytes32";
161
+ readonly indexed: false;
162
+ }, {
163
+ readonly name: "charterHash";
164
+ readonly type: "bytes32";
165
+ readonly indexed: false;
166
+ }];
167
+ }, {
168
+ readonly type: "event";
169
+ readonly name: "EstateSignerDeclared";
170
+ readonly inputs: readonly [{
171
+ readonly name: "estateId";
172
+ readonly type: "bytes32";
173
+ readonly indexed: true;
174
+ }, {
175
+ readonly name: "governance";
176
+ readonly type: "address";
177
+ readonly indexed: true;
178
+ }, {
179
+ readonly name: "signer";
180
+ readonly type: "address";
181
+ readonly indexed: true;
182
+ }];
183
+ }, {
184
+ readonly type: "event";
185
+ readonly name: "EstateSignerRotated";
186
+ readonly inputs: readonly [{
187
+ readonly name: "estateId";
188
+ readonly type: "bytes32";
189
+ readonly indexed: true;
190
+ }, {
191
+ readonly name: "from";
192
+ readonly type: "address";
193
+ readonly indexed: true;
194
+ }, {
195
+ readonly name: "to";
196
+ readonly type: "address";
197
+ readonly indexed: true;
198
+ }];
199
+ }, {
200
+ readonly type: "error";
201
+ readonly name: "NotRegistered";
202
+ readonly inputs: readonly [{
203
+ readonly name: "estateId";
204
+ readonly type: "bytes32";
205
+ }, {
206
+ readonly name: "signer";
207
+ readonly type: "address";
208
+ }];
209
+ }, {
210
+ readonly type: "error";
211
+ readonly name: "SignerRetired";
212
+ readonly inputs: readonly [{
213
+ readonly name: "estateId";
214
+ readonly type: "bytes32";
215
+ }, {
216
+ readonly name: "signer";
217
+ readonly type: "address";
218
+ }, {
219
+ readonly name: "successor";
220
+ readonly type: "address";
221
+ }];
222
+ }, {
223
+ readonly type: "error";
224
+ readonly name: "SequenceNotAbove";
225
+ readonly inputs: readonly [{
226
+ readonly name: "last";
227
+ readonly type: "uint64";
228
+ }, {
229
+ readonly name: "given";
230
+ readonly type: "uint64";
231
+ }];
232
+ }, {
233
+ readonly type: "error";
234
+ readonly name: "SequenceStepTooLarge";
235
+ readonly inputs: readonly [{
236
+ readonly name: "last";
237
+ readonly type: "uint64";
238
+ }, {
239
+ readonly name: "given";
240
+ readonly type: "uint64";
241
+ }];
242
+ }, {
243
+ readonly type: "error";
244
+ readonly name: "ZeroAddress";
245
+ readonly inputs: readonly [];
246
+ }];
247
+ /** An injected contract read — `publicClient.readContract` has this shape. A throw is "the anchor could not be read". */
248
+ export type EstateRegistryReader = (call: {
249
+ address: `0x${string}`;
250
+ abi: typeof estateProjectionRegistryAbi;
251
+ functionName: 'roots' | 'isRetired' | 'successorOf' | 'declaredSignerOf';
252
+ args: readonly unknown[];
253
+ }) => Promise<unknown>;
254
+ export type AnchoredRootsRead = {
255
+ status: 'anchored';
256
+ roots: AnchoredRoots & {
257
+ charterHash: Hex;
258
+ };
259
+ } | {
260
+ status: 'unanchored';
261
+ estateId: Hex;
262
+ signer: `0x${string}`;
263
+ } | {
264
+ status: 'retired';
265
+ estateId: Hex;
266
+ signer: `0x${string}`;
267
+ successor: `0x${string}`;
268
+ };
269
+ /**
270
+ * Read the estate's row — `roots(estateId, declaredSigner)` — refusing a retired row. `declaredSigner` is the estate's
271
+ * DECLARATION (its `atl:projectionSigner` record, or `declaredSignerOf` on the registry's chain): the caller reads it
272
+ * from there, never from the presentation in hand. `unanchored` = the declared signer has anchored nothing for this
273
+ * id (an answer, not a trigger: no other row is consulted). `retired` = the signer rotated away; the estate's
274
+ * declaration is stale or the presentation is against a retired row — refuse either way.
275
+ */
276
+ export declare function readAnchoredRoots(read: EstateRegistryReader, at: {
277
+ registry: `0x${string}`;
278
+ estateId: Hex;
279
+ declaredSigner: `0x${string}`;
280
+ }): Promise<AnchoredRootsRead>;
281
+ /** `declaredSignerOf(estateId)` — the same-chain declaration (only the governance the id is derived from can make
282
+ * it). Null when none was declared there; the estate's `atl:projectionSigner` on its own chain is then the source. */
283
+ export declare function readDeclaredSigner(read: EstateRegistryReader, at: {
284
+ registry: `0x${string}`;
285
+ estateId: Hex;
286
+ }): Promise<`0x${string}` | null>;
287
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;qEACqE;AACrE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2C9B,CAAC;AAEX,yHAAyH;AACzH,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE;IACxC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IACvB,GAAG,EAAE,OAAO,2BAA2B,CAAC;IACxC,YAAY,EAAE,OAAO,GAAG,WAAW,GAAG,aAAa,GAAG,kBAAkB,CAAC;IACzE,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;CAC1B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAEvB,MAAM,MAAM,iBAAiB,GACzB;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,aAAa,GAAG;QAAE,WAAW,EAAE,GAAG,CAAA;KAAE,CAAA;CAAE,GACnE;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAA;CAAE,GAC9D;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,MAAM,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,SAAS,EAAE,KAAK,MAAM,EAAE,CAAA;CAAE,CAAC;AAM1F;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAC;IAAC,cAAc,EAAE,KAAK,MAAM,EAAE,CAAA;CAAE,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAgB7K;AAED;uHACuH;AACvH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,GAAG,CAAA;CAAE,GAAG,OAAO,CAAC,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC,CAKlJ"}
@@ -0,0 +1,89 @@
1
+ /** The generation-4 `EstateProjectionRegistry` surface this package reads and its consumers write. Not in
2
+ * `check:abi-sync`; the B2 test pins it to the contract's shape. */
3
+ export const estateProjectionRegistryAbi = [
4
+ { type: 'function', name: 'roots', stateMutability: 'view',
5
+ inputs: [{ name: 'estateId', type: 'bytes32' }, { name: 'signer', type: 'address' }],
6
+ outputs: [
7
+ { name: 'liveGrantRoot', type: 'bytes32' }, { name: 'membershipRoot', type: 'bytes32' }, { name: 'charterHash', type: 'bytes32' },
8
+ { name: 'sequence', type: 'uint64' }, { name: 'anchoredAt', type: 'uint64' },
9
+ ] },
10
+ { type: 'function', name: 'isRetired', stateMutability: 'view',
11
+ inputs: [{ name: 'estateId', type: 'bytes32' }, { name: 'signer', type: 'address' }], outputs: [{ type: 'bool' }] },
12
+ { type: 'function', name: 'successorOf', stateMutability: 'view',
13
+ inputs: [{ name: 'estateId', type: 'bytes32' }, { name: 'signer', type: 'address' }], outputs: [{ type: 'address' }] },
14
+ { type: 'function', name: 'declaredSignerOf', stateMutability: 'view',
15
+ inputs: [{ name: 'estateId', type: 'bytes32' }], outputs: [{ name: 'signer', type: 'address' }] },
16
+ { type: 'function', name: 'estateIdOf', stateMutability: 'pure',
17
+ inputs: [{ name: 'chainId', type: 'uint256' }, { name: 'governance', type: 'address' }], outputs: [{ type: 'bytes32' }] },
18
+ { type: 'function', name: 'MAX_SEQUENCE_STEP', stateMutability: 'view', inputs: [], outputs: [{ type: 'uint64' }] },
19
+ /** Writes the CALLER's row; the sequence must rise by 1 … MAX_SEQUENCE_STEP. */
20
+ { type: 'function', name: 'setRoots', stateMutability: 'nonpayable',
21
+ inputs: [
22
+ { name: 'estateId', type: 'bytes32' }, { name: 'liveGrantRoot', type: 'bytes32' }, { name: 'membershipRoot', type: 'bytes32' },
23
+ { name: 'charterHash', type: 'bytes32' }, { name: 'sequence', type: 'uint64' },
24
+ ], outputs: [] },
25
+ /** RETIRES the caller's row and records `successorOf(estateId, caller) = to`; writes nothing into `to`'s row. */
26
+ { type: 'function', name: 'rotateSigner', stateMutability: 'nonpayable',
27
+ inputs: [{ name: 'estateId', type: 'bytes32' }, { name: 'to', type: 'address' }], outputs: [] },
28
+ /** Same-chain declaration: the estate id is computed from `(block.chainid, msg.sender)`, so only that governance declares. */
29
+ { type: 'function', name: 'declareSigner', stateMutability: 'nonpayable',
30
+ inputs: [{ name: 'signer', type: 'address' }], outputs: [{ name: 'estateId', type: 'bytes32' }] },
31
+ { type: 'event', name: 'RootsAnchored', inputs: [
32
+ { name: 'estateId', type: 'bytes32', indexed: true }, { name: 'signer', type: 'address', indexed: true }, { name: 'sequence', type: 'uint64', indexed: true },
33
+ { name: 'liveGrantRoot', type: 'bytes32', indexed: false }, { name: 'membershipRoot', type: 'bytes32', indexed: false }, { name: 'charterHash', type: 'bytes32', indexed: false },
34
+ ] },
35
+ { type: 'event', name: 'EstateSignerDeclared', inputs: [
36
+ { name: 'estateId', type: 'bytes32', indexed: true }, { name: 'governance', type: 'address', indexed: true }, { name: 'signer', type: 'address', indexed: true },
37
+ ] },
38
+ { type: 'event', name: 'EstateSignerRotated', inputs: [
39
+ { name: 'estateId', type: 'bytes32', indexed: true }, { name: 'from', type: 'address', indexed: true }, { name: 'to', type: 'address', indexed: true },
40
+ ] },
41
+ { type: 'error', name: 'NotRegistered', inputs: [{ name: 'estateId', type: 'bytes32' }, { name: 'signer', type: 'address' }] },
42
+ { type: 'error', name: 'SignerRetired', inputs: [{ name: 'estateId', type: 'bytes32' }, { name: 'signer', type: 'address' }, { name: 'successor', type: 'address' }] },
43
+ { type: 'error', name: 'SequenceNotAbove', inputs: [{ name: 'last', type: 'uint64' }, { name: 'given', type: 'uint64' }] },
44
+ { type: 'error', name: 'SequenceStepTooLarge', inputs: [{ name: 'last', type: 'uint64' }, { name: 'given', type: 'uint64' }] },
45
+ { type: 'error', name: 'ZeroAddress', inputs: [] },
46
+ ];
47
+ const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
48
+ const BYTES32 = /^0x[0-9a-fA-F]{64}$/;
49
+ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000';
50
+ /**
51
+ * Read the estate's row — `roots(estateId, declaredSigner)` — refusing a retired row. `declaredSigner` is the estate's
52
+ * DECLARATION (its `atl:projectionSigner` record, or `declaredSignerOf` on the registry's chain): the caller reads it
53
+ * from there, never from the presentation in hand. `unanchored` = the declared signer has anchored nothing for this
54
+ * id (an answer, not a trigger: no other row is consulted). `retired` = the signer rotated away; the estate's
55
+ * declaration is stale or the presentation is against a retired row — refuse either way.
56
+ */
57
+ export async function readAnchoredRoots(read, at) {
58
+ if (!ADDRESS.test(at.registry))
59
+ throw new Error('estate registry: registry is not an address');
60
+ if (!BYTES32.test(at.estateId))
61
+ throw new Error('estate registry: estateId is not a bytes32');
62
+ if (!ADDRESS.test(at.declaredSigner) || at.declaredSigner.toLowerCase() === ZERO_ADDRESS)
63
+ throw new Error('estate registry: the declared signer is not a non-zero address — read it from the estate\'s atl:projectionSigner, never from a presentation');
64
+ const estateId = at.estateId.toLowerCase();
65
+ const signer = at.declaredSigner.toLowerCase();
66
+ const retired = await read({ address: at.registry, abi: estateProjectionRegistryAbi, functionName: 'isRetired', args: [estateId, signer] });
67
+ if (retired === true) {
68
+ const successor = String(await read({ address: at.registry, abi: estateProjectionRegistryAbi, functionName: 'successorOf', args: [estateId, signer] })).toLowerCase();
69
+ return { status: 'retired', estateId, signer, successor };
70
+ }
71
+ const r = await read({ address: at.registry, abi: estateProjectionRegistryAbi, functionName: 'roots', args: [estateId, signer] });
72
+ if (!Array.isArray(r) || r.length !== 5)
73
+ throw new Error('estate registry: roots() returned an unexpected shape');
74
+ const [liveGrantRoot, membershipRoot, charterHash, sequence, anchoredAt] = r;
75
+ if (Number(anchoredAt) === 0)
76
+ return { status: 'unanchored', estateId, signer };
77
+ return { status: 'anchored', roots: { estateId, signer, sequence: Number(sequence), liveGrantRoot, membershipRoot, charterHash, anchoredAt: Number(anchoredAt) } };
78
+ }
79
+ /** `declaredSignerOf(estateId)` — the same-chain declaration (only the governance the id is derived from can make
80
+ * it). Null when none was declared there; the estate's `atl:projectionSigner` on its own chain is then the source. */
81
+ export async function readDeclaredSigner(read, at) {
82
+ if (!ADDRESS.test(at.registry))
83
+ throw new Error('estate registry: registry is not an address');
84
+ if (!BYTES32.test(at.estateId))
85
+ throw new Error('estate registry: estateId is not a bytes32');
86
+ const s = String(await read({ address: at.registry, abi: estateProjectionRegistryAbi, functionName: 'declaredSignerOf', args: [at.estateId.toLowerCase()] })).toLowerCase();
87
+ return ADDRESS.test(s) && s !== ZERO_ADDRESS ? s : null;
88
+ }
89
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agenticprimitives/estate-projection",
3
- "version": "0.0.0-alpha.21",
3
+ "version": "0.0.0-alpha.22",
4
4
  "description": "An estate's public projection of its authority (spec 410 §4): the live-grant root and the membership root over blinded commitments, anchored on public ground; the authority presentation a verifier in another estate checks against them, learning that a grant is live or an agent is a member and nothing else.",
5
5
  "homepage": "https://agenticprimitives.dev",
6
6
  "bugs": {
@@ -35,8 +35,8 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "viem": "^2.52.2",
38
- "@agenticprimitives/content-primitives": "1.0.0-alpha.41",
39
- "@agenticprimitives/types": "1.0.0-alpha.46"
38
+ "@agenticprimitives/content-primitives": "1.0.0-alpha.42",
39
+ "@agenticprimitives/types": "1.0.0-alpha.47"
40
40
  },
41
41
  "devDependencies": {
42
42
  "vitest": "^4.1.11",