@xyo-network/event-kit-statement-graph 0.0.1

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 ADDED
@@ -0,0 +1,59 @@
1
+ # `@xyo-network/event-kit-statement-graph`
2
+
3
+ Read-model adapter between the canonical XL1 Statement Graph viewer and the
4
+ Event Kit wake-grant authorizer.
5
+
6
+ ```ts
7
+ const readModel = createStatementGraphGrantReadModel({ viewer })
8
+ const grants = createStatementGraphWakeGrantAuthorizer({ viewer: readModel })
9
+ ```
10
+
11
+ `viewer` is any `StatementGraphViewer` — a `StateStatementGraphViewer` over
12
+ engine state, a replay controller's viewer, or another backing.
13
+
14
+ ## What this package does and does not do
15
+
16
+ It is a translation seam only. It narrows the canonical branded source/hash
17
+ types, preserves every field the authorizer needs as grant evidence, and drops
18
+ nothing. It makes no authorization decision and applies no freshness policy.
19
+
20
+ Under Statement Graph v2 the protocol owns **claim only**: there is no `target`
21
+ and no revoke verb, so the grant body names its own `publisher` and negation is
22
+ an Event Kit revocation object claimed by the pinned controller. See
23
+ [D-003](../../docs/decisions/D-003-STATEMENT-GRAPH-V2-GRANTS.md).
24
+
25
+ Addresses and hashes are **parsed**, not cast. A malformed address therefore
26
+ reaches the caller as `grant-unavailable` rather than silently querying a
27
+ nonsense key and reading as "no grant".
28
+
29
+ ## Evidence
30
+
31
+ Specs fold a `FakeStatementChain` through the real engine —
32
+ `applyStatementTransaction` over decoded blocks and verified bodies — and drive
33
+ `admitAndEnqueue` against the resulting viewer. Exact-scope claims admit; a
34
+ wrong controller, a differently scoped or unscoped route, a missing `enqueue`
35
+ permission, and a revoke all reject; a lagging view rejects as stale and an
36
+ ahead-of-finality view rejects rather than being trusted.
37
+
38
+ A never-folded read model carries watermark `-1` and fails closed as
39
+ `grant-unavailable`, keeping "the view is not ready" distinguishable from "the
40
+ controller granted nothing".
41
+
42
+ Live specs under `src/spec/api-local/` run the same fold against a **real local
43
+ XL1 chain**: a Claim transaction published with the statement-graph SDK,
44
+ confirmed and finalized, then folded from real finalized blocks into an
45
+ admission decision whose evidence cites the on-chain claim at its real height.
46
+ The gateway viewer satisfies `FinalizedBlockViewer` structurally, so the fold
47
+ code is identical across both substrates. Run with
48
+ `pnpm test:api-local-statements` — publishing specs need their own chain, since
49
+ the dev chain stops producing blocks after one statement transaction.
50
+
51
+ The full lifecycle runs live: a grant admits, a negation in a **later** finalized
52
+ transaction disables, and a later redundant claim leaves the asserted height
53
+ frozen while only the liveness clock advances. Same-block negation is covered too
54
+ via v2's `hashes[]` fan-out, where a grant and the revocation naming it ride one
55
+ transaction and the publisher is born disabled.
56
+
57
+ Bodies are served from an in-process datalake; the chain carries commitments, not
58
+ bodies. Scope-mismatch and wrong-controller vectors stay on the deterministic
59
+ chain.
@@ -0,0 +1,21 @@
1
+ import type { StatementGraphGrantReadModel } from '@xyo-network/event-kit-protocol';
2
+ import type { StatementGraphViewer } from '@xyo-network/xl1-statement-graph-engine';
3
+ export interface StatementGraphGrantReadModelOptions {
4
+ /**
5
+ * Canonical Statement Graph read surface — a `StateStatementGraphViewer` over
6
+ * engine state, a replay controller's viewer, or any other backing.
7
+ */
8
+ readonly viewer: StatementGraphViewer;
9
+ }
10
+ /**
11
+ * Adapts the canonical Statement Graph v2 viewer to the unbranded read model
12
+ * the Event Kit grant authorizer consumes.
13
+ *
14
+ * This is a translation seam only. It narrows branded query and record types
15
+ * and preserves every field the authorizer needs as grant evidence; it makes no
16
+ * authorization decision, applies no freshness policy, and drops no claim.
17
+ * Statement Graph remains the sole owner of claim semantics — and under v2 that
18
+ * is the whole lifecycle, since there is no revoke verb to own.
19
+ */
20
+ export declare function createStatementGraphGrantReadModel(options: StatementGraphGrantReadModelOptions): StatementGraphGrantReadModel;
21
+ //# sourceMappingURL=grantReadModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grantReadModel.d.ts","sourceRoot":"","sources":["../../src/grantReadModel.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAIV,4BAA4B,EAC7B,MAAM,iCAAiC,CAAA;AAExC,OAAO,KAAK,EAEV,oBAAoB,EACrB,MAAM,yCAAyC,CAAA;AAGhD,MAAM,WAAW,mCAAmC;IAClD;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAA;CACtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,mCAAmC,GAC3C,4BAA4B,CAqB9B"}
@@ -0,0 +1,3 @@
1
+ export type { StatementGraphGrantReadModelOptions } from './grantReadModel.ts';
2
+ export { createStatementGraphGrantReadModel } from './grantReadModel.ts';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mCAAmC,EAAE,MAAM,qBAAqB,CAAA;AAC9E,OAAO,EAAE,kCAAkC,EAAE,MAAM,qBAAqB,CAAA"}
@@ -0,0 +1,48 @@
1
+ // src/grantReadModel.ts
2
+ import { HashZod } from "@ariestools/sdk";
3
+ import { XyoAddressZod } from "@xyo-network/sdk-protocol/address";
4
+ function createStatementGraphGrantReadModel(options) {
5
+ const { viewer } = options;
6
+ return Object.freeze({
7
+ async head() {
8
+ return await viewer.head();
9
+ },
10
+ async claims(source, query) {
11
+ const records = await viewer.claims(XyoAddressZod.parse(source), toClaimQuery(query));
12
+ return Object.freeze(records.map(toGrantClaim));
13
+ },
14
+ async object(objectHash) {
15
+ const record = await viewer.object(HashZod.parse(objectHash));
16
+ return record === void 0 ? void 0 : toGrantObject(record);
17
+ }
18
+ });
19
+ }
20
+ function toClaimQuery(query) {
21
+ if (query === void 0) return void 0;
22
+ return {
23
+ ...query.declaredObjectSchemaPrefix === void 0 ? {} : { declaredObjectSchemaPrefix: query.declaredObjectSchemaPrefix },
24
+ ...query.objectHash === void 0 ? {} : { objectHash: HashZod.parse(query.objectHash) }
25
+ };
26
+ }
27
+ function toGrantClaim(record) {
28
+ return Object.freeze({
29
+ declaredObjectSchema: record.declaredObjectSchema,
30
+ firstBlock: record.firstBlock,
31
+ firstEventHash: record.firstEventHash,
32
+ lastBlock: record.lastBlock,
33
+ objectHash: record.objectHash,
34
+ source: record.source
35
+ });
36
+ }
37
+ function toGrantObject(record) {
38
+ return Object.freeze({
39
+ assurance: record.assurance,
40
+ declaredSchema: record.declaredSchema,
41
+ objectHash: record.objectHash,
42
+ params: record.params === null ? null : Object.freeze({ ...record.params })
43
+ });
44
+ }
45
+ export {
46
+ createStatementGraphGrantReadModel
47
+ };
48
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/grantReadModel.ts"],
4
+ "sourcesContent": ["import { HashZod } from '@ariestools/sdk'\nimport type {\n StatementGrantClaim,\n StatementGrantClaimQuery,\n StatementGrantObject,\n StatementGraphGrantReadModel,\n} from '@xyo-network/event-kit-protocol'\nimport { XyoAddressZod } from '@xyo-network/sdk-protocol/address'\nimport type {\n ClaimQuery,\n StatementGraphViewer,\n} from '@xyo-network/xl1-statement-graph-engine'\nimport type { ClaimRecord, ObjectRecord } from '@xyo-network/xl1-statement-graph-schemas'\n\nexport interface StatementGraphGrantReadModelOptions {\n /**\n * Canonical Statement Graph read surface \u2014 a `StateStatementGraphViewer` over\n * engine state, a replay controller's viewer, or any other backing.\n */\n readonly viewer: StatementGraphViewer\n}\n\n/**\n * Adapts the canonical Statement Graph v2 viewer to the unbranded read model\n * the Event Kit grant authorizer consumes.\n *\n * This is a translation seam only. It narrows branded query and record types\n * and preserves every field the authorizer needs as grant evidence; it makes no\n * authorization decision, applies no freshness policy, and drops no claim.\n * Statement Graph remains the sole owner of claim semantics \u2014 and under v2 that\n * is the whole lifecycle, since there is no revoke verb to own.\n */\nexport function createStatementGraphGrantReadModel(\n options: StatementGraphGrantReadModelOptions,\n): StatementGraphGrantReadModel {\n const { viewer } = options\n\n return Object.freeze({\n async head(): Promise<number> {\n return await viewer.head()\n },\n\n async claims(\n source: string,\n query?: StatementGrantClaimQuery,\n ): Promise<readonly StatementGrantClaim[]> {\n const records = await viewer.claims(XyoAddressZod.parse(source), toClaimQuery(query))\n return Object.freeze(records.map(toGrantClaim))\n },\n\n async object(objectHash: string): Promise<StatementGrantObject | undefined> {\n const record = await viewer.object(HashZod.parse(objectHash))\n return record === undefined ? undefined : toGrantObject(record)\n },\n })\n}\n\n/**\n * Rebrands the query fields. Parsing rather than casting means a malformed hash\n * reaches the viewer as a throw \u2014 surfacing as `grant-unavailable` \u2014 instead of\n * silently querying a nonsense key and reading as \"no grant\".\n */\nfunction toClaimQuery(query?: StatementGrantClaimQuery): ClaimQuery | undefined {\n if (query === undefined) return undefined\n return {\n ...(query.declaredObjectSchemaPrefix === undefined\n ? {}\n : { declaredObjectSchemaPrefix: query.declaredObjectSchemaPrefix }),\n ...(query.objectHash === undefined ? {} : { objectHash: HashZod.parse(query.objectHash) }),\n }\n}\n\n/**\n * `firstEventHash` identifies the materializing claim, so the authorizer can\n * cite one concrete transition as evidence rather than a bare boolean. A\n * redundant claim moves only `lastBlock`, so evidence cannot be backdated or\n * refreshed by re-claiming.\n */\nfunction toGrantClaim(record: ClaimRecord): StatementGrantClaim {\n return Object.freeze({\n declaredObjectSchema: record.declaredObjectSchema,\n firstBlock: record.firstBlock,\n firstEventHash: record.firstEventHash,\n lastBlock: record.lastBlock,\n objectHash: record.objectHash,\n source: record.source,\n })\n}\n\nfunction toGrantObject(record: ObjectRecord): StatementGrantObject {\n return Object.freeze({\n assurance: record.assurance,\n declaredSchema: record.declaredSchema,\n objectHash: record.objectHash,\n params: record.params === null ? null : Object.freeze({ ...record.params }),\n })\n}\n"],
5
+ "mappings": ";AAAA,SAAS,eAAe;AAOxB,SAAS,qBAAqB;AAyBvB,SAAS,mCACd,SAC8B;AAC9B,QAAM,EAAE,OAAO,IAAI;AAEnB,SAAO,OAAO,OAAO;AAAA,IACnB,MAAM,OAAwB;AAC5B,aAAO,MAAM,OAAO,KAAK;AAAA,IAC3B;AAAA,IAEA,MAAM,OACJ,QACA,OACyC;AACzC,YAAM,UAAU,MAAM,OAAO,OAAO,cAAc,MAAM,MAAM,GAAG,aAAa,KAAK,CAAC;AACpF,aAAO,OAAO,OAAO,QAAQ,IAAI,YAAY,CAAC;AAAA,IAChD;AAAA,IAEA,MAAM,OAAO,YAA+D;AAC1E,YAAM,SAAS,MAAM,OAAO,OAAO,QAAQ,MAAM,UAAU,CAAC;AAC5D,aAAO,WAAW,SAAY,SAAY,cAAc,MAAM;AAAA,IAChE;AAAA,EACF,CAAC;AACH;AAOA,SAAS,aAAa,OAA0D;AAC9E,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO;AAAA,IACL,GAAI,MAAM,+BAA+B,SACrC,CAAC,IACD,EAAE,4BAA4B,MAAM,2BAA2B;AAAA,IACnE,GAAI,MAAM,eAAe,SAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,MAAM,MAAM,UAAU,EAAE;AAAA,EAC1F;AACF;AAQA,SAAS,aAAa,QAA0C;AAC9D,SAAO,OAAO,OAAO;AAAA,IACnB,sBAAsB,OAAO;AAAA,IAC7B,YAAY,OAAO;AAAA,IACnB,gBAAgB,OAAO;AAAA,IACvB,WAAW,OAAO;AAAA,IAClB,YAAY,OAAO;AAAA,IACnB,QAAQ,OAAO;AAAA,EACjB,CAAC;AACH;AAEA,SAAS,cAAc,QAA4C;AACjE,SAAO,OAAO,OAAO;AAAA,IACnB,WAAW,OAAO;AAAA,IAClB,gBAAgB,OAAO;AAAA,IACvB,YAAY,OAAO;AAAA,IACnB,QAAQ,OAAO,WAAW,OAAO,OAAO,OAAO,OAAO,EAAE,GAAG,OAAO,OAAO,CAAC;AAAA,EAC5E,CAAC;AACH;",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,78 @@
1
+ {
2
+ "name": "@xyo-network/event-kit-statement-graph",
3
+ "version": "0.0.1",
4
+ "description": "Statement Graph read-model adapter for Event Kit wake grants",
5
+ "keywords": [
6
+ "xyo",
7
+ "xl1",
8
+ "event-kit",
9
+ "statement-graph",
10
+ "typescript"
11
+ ],
12
+ "bugs": {
13
+ "url": "https://github.com/XYOracleNetwork/event-kit/issues"
14
+ },
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/XYOracleNetwork/event-kit.git",
18
+ "directory": "packages/statement-graph"
19
+ },
20
+ "license": "UNLICENSED",
21
+ "sideEffects": false,
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/neutral/index.d.ts",
26
+ "default": "./dist/neutral/index.mjs"
27
+ },
28
+ "./package.json": "./package.json",
29
+ "./README.md": "./README.md"
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "README.md"
34
+ ],
35
+ "dependencies": {
36
+ "@xyo-network/event-kit-protocol": "~0.0.1"
37
+ },
38
+ "devDependencies": {
39
+ "@ariestools/lib-neutral": "~9.1.0",
40
+ "@ariestools/sdk": "~8.1.9",
41
+ "@ariestools/toolchain": "~9.1.0",
42
+ "@ariestools/tsconfig": "~9.1.0",
43
+ "@opentelemetry/api": "~1.9.1",
44
+ "@xyo-network/sdk": "~7.2.3",
45
+ "@xyo-network/sdk-protocol": "~7.2.4",
46
+ "@xyo-network/xl1-sdk": "~5.3.1",
47
+ "@xyo-network/xl1-statement-graph-engine": "~0.4.0",
48
+ "@xyo-network/xl1-statement-graph-schemas": "~0.4.0",
49
+ "@xyo-network/xl1-statement-graph-sdk": "~0.4.0",
50
+ "@xyo-network/xl1-statement-graph-testing": "~0.4.0",
51
+ "async-mutex": "~0.5.0",
52
+ "eslint": "~10.8.1",
53
+ "eslint-import-resolver-typescript": "~4.4.5",
54
+ "ethers": "~6.17.0",
55
+ "typescript": "~6.0.3",
56
+ "vite": "~8.2.1",
57
+ "vitest": "~4.1.11",
58
+ "zod": "~4.4.3",
59
+ "@xyo-network/event-kit-schemas": "~0.0.1"
60
+ },
61
+ "peerDependencies": {
62
+ "@ariestools/sdk": "^8.1",
63
+ "@opentelemetry/api": "^1.9",
64
+ "@xyo-network/sdk": "^7.2",
65
+ "@xyo-network/sdk-protocol": "^7.2",
66
+ "@xyo-network/xl1-statement-graph-engine": "^0.4",
67
+ "zod": "^4.4"
68
+ },
69
+ "engines": {
70
+ "node": ">=22"
71
+ },
72
+ "publishConfig": {
73
+ "access": "restricted"
74
+ },
75
+ "scripts": {
76
+ "test": "vitest run"
77
+ }
78
+ }