@openmobilehub/attestomcp-gate 0.1.0

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.
Files changed (79) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +172 -0
  3. package/dist/ceremony/cartMandate.d.ts +61 -0
  4. package/dist/ceremony/cartMandate.js +76 -0
  5. package/dist/ceremony/challengeToken.d.ts +5 -0
  6. package/dist/ceremony/challengeToken.js +43 -0
  7. package/dist/ceremony/checkout-page.d.ts +85 -0
  8. package/dist/ceremony/checkout-page.js +269 -0
  9. package/dist/ceremony/completion.d.ts +41 -0
  10. package/dist/ceremony/completion.js +90 -0
  11. package/dist/ceremony/credential-gate/dcql.d.ts +10 -0
  12. package/dist/ceremony/credential-gate/dcql.js +12 -0
  13. package/dist/ceremony/credential-gate/doc-spec.d.ts +3 -0
  14. package/dist/ceremony/credential-gate/doc-spec.js +16 -0
  15. package/dist/ceremony/credential-gate/mdoc-verify.d.ts +15 -0
  16. package/dist/ceremony/credential-gate/mdoc-verify.js +29 -0
  17. package/dist/ceremony/credential-gate/page.d.ts +20 -0
  18. package/dist/ceremony/credential-gate/page.js +136 -0
  19. package/dist/ceremony/credential-gate/request.d.ts +15 -0
  20. package/dist/ceremony/credential-gate/request.js +43 -0
  21. package/dist/ceremony/credential-gate/routes.d.ts +2 -0
  22. package/dist/ceremony/credential-gate/routes.js +200 -0
  23. package/dist/ceremony/credential-gate/verify.d.ts +51 -0
  24. package/dist/ceremony/credential-gate/verify.js +146 -0
  25. package/dist/ceremony/dc-payment/dcql.d.ts +5 -0
  26. package/dist/ceremony/dc-payment/dcql.js +23 -0
  27. package/dist/ceremony/dc-payment/page.d.ts +18 -0
  28. package/dist/ceremony/dc-payment/page.js +195 -0
  29. package/dist/ceremony/dc-payment/request.d.ts +17 -0
  30. package/dist/ceremony/dc-payment/request.js +50 -0
  31. package/dist/ceremony/dc-payment/routes.d.ts +2 -0
  32. package/dist/ceremony/dc-payment/routes.js +147 -0
  33. package/dist/ceremony/dc-payment/txData.d.ts +19 -0
  34. package/dist/ceremony/dc-payment/txData.js +34 -0
  35. package/dist/ceremony/dc-payment/verify.d.ts +108 -0
  36. package/dist/ceremony/dc-payment/verify.js +208 -0
  37. package/dist/ceremony/mandate.d.ts +71 -0
  38. package/dist/ceremony/mandate.js +116 -0
  39. package/dist/ceremony/mdoc/mdoc-iso.d.ts +44 -0
  40. package/dist/ceremony/mdoc/mdoc-iso.js +260 -0
  41. package/dist/ceremony/mdoc/mdoc.d.ts +17 -0
  42. package/dist/ceremony/mdoc/mdoc.js +94 -0
  43. package/dist/ceremony/mdoc/reader.d.ts +10 -0
  44. package/dist/ceremony/mdoc/reader.js +43 -0
  45. package/dist/ceremony/mdoc/readerContext.d.ts +8 -0
  46. package/dist/ceremony/mdoc/readerContext.js +29 -0
  47. package/dist/ceremony/mount.d.ts +57 -0
  48. package/dist/ceremony/mount.js +96 -0
  49. package/dist/ceremony/origin.d.ts +10 -0
  50. package/dist/ceremony/origin.js +9 -0
  51. package/dist/ceremony/passkey/page.d.ts +6 -0
  52. package/dist/ceremony/passkey/page.js +136 -0
  53. package/dist/ceremony/passkey/routes.d.ts +2 -0
  54. package/dist/ceremony/passkey/routes.js +170 -0
  55. package/dist/ceremony/passkey/verify.d.ts +15 -0
  56. package/dist/ceremony/passkey/verify.js +56 -0
  57. package/dist/ceremony/reconciliation.d.ts +34 -0
  58. package/dist/ceremony/reconciliation.js +21 -0
  59. package/dist/ceremony/theme.d.ts +63 -0
  60. package/dist/ceremony/theme.js +285 -0
  61. package/dist/ceremony/types.d.ts +95 -0
  62. package/dist/ceremony/types.js +1 -0
  63. package/dist/client.d.ts +39 -0
  64. package/dist/client.js +84 -0
  65. package/dist/credentials.d.ts +48 -0
  66. package/dist/credentials.js +127 -0
  67. package/dist/envelope.d.ts +62 -0
  68. package/dist/envelope.js +72 -0
  69. package/dist/gated.d.ts +39 -0
  70. package/dist/gated.js +41 -0
  71. package/dist/index.d.ts +18 -0
  72. package/dist/index.js +49 -0
  73. package/dist/manifest.d.ts +28 -0
  74. package/dist/manifest.js +76 -0
  75. package/dist/store.d.ts +7 -0
  76. package/dist/store.js +16 -0
  77. package/dist/types.d.ts +146 -0
  78. package/dist/types.js +7 -0
  79. package/package.json +62 -0
@@ -0,0 +1,146 @@
1
+ export interface DcqlClaim {
2
+ path: string[];
3
+ intent_to_retain?: boolean;
4
+ }
5
+ export interface DcqlCredentialOption {
6
+ id: string;
7
+ format: "mso_mdoc";
8
+ meta: Record<string, string>;
9
+ claims: DcqlClaim[];
10
+ }
11
+ export interface DcqlQuery {
12
+ credentials: DcqlCredentialOption[];
13
+ }
14
+ /**
15
+ * How honestly the presented mdoc is trusted. v0.1 enforces *disclosure*
16
+ * (explicit positive claim) and *binding* (nonce / ephemeral key), but NOT
17
+ * *trust* (issuer / device signatures) — a self-crafted mdoc would pass. The
18
+ * manifest and the envelope both carry this so the limitation is stated in the
19
+ * type, not buried in prose: it's a flow demo, not a real safety control yet.
20
+ */
21
+ export type TrustLevel = "presence-only-demo" | "issuer-verified";
22
+ export type Effect = {
23
+ kind: "gate";
24
+ } | {
25
+ kind: "discount";
26
+ percent?: number;
27
+ amount?: number;
28
+ } | {
29
+ kind: "authorize";
30
+ };
31
+ export interface OrderLine {
32
+ /** Product id. */
33
+ id: string;
34
+ /** Quantity (matches the demo's `PricedCartLine.quantity`). */
35
+ quantity: number;
36
+ /** Cents; authoritative (catalog). */
37
+ unitPrice: number;
38
+ /**
39
+ * Per-product age threshold (21 for alcohol), re-derived server-side onto the
40
+ * line from the catalog (invariant #2). `PricedCartLine` doesn't carry it
41
+ * natively — the gate enriches the order before resolving the policy.
42
+ */
43
+ minimumAge?: number;
44
+ /** Product category (e.g. "Beverages"); available to custom `.when()` predicates. */
45
+ category?: string;
46
+ /** Example custom flag a `prescription` `appliesTo` reads. */
47
+ requiresRx?: boolean;
48
+ }
49
+ export interface GateOrder {
50
+ /** Stable per checkout (created once). */
51
+ id: string;
52
+ /** Cents; re-derived server-side. */
53
+ total: number;
54
+ /** ISO 4217. */
55
+ currency: string;
56
+ /** Carries the data conditional predicates read. */
57
+ lines: OrderLine[];
58
+ }
59
+ /**
60
+ * A gate in the policy. Built-ins (`age.over(21)`, `membership.discount(10)`,
61
+ * `payment.in("usd")`) and customs (`defineCredential`) are the same shape; the
62
+ * resolver reads `effect` + `params` + `ui` and runs `when` / `appliesTo`.
63
+ */
64
+ export interface Credential {
65
+ /** `"age"` / `"membership"` / `"payment"` / custom. */
66
+ id: string;
67
+ /** What to ask the wallet. */
68
+ request: DcqlQuery;
69
+ /** Reads disclosed claims → proven? (Security: explicit positive claim.) */
70
+ verify: (claims: Record<string, unknown>) => boolean;
71
+ /** `gate()` | `discount({percent})` | `authorize()`. */
72
+ effect: Effect;
73
+ /**
74
+ * Inclusion predicate — the gate is in the manifest only when this returns
75
+ * true (absent ⇒ always applies). `defineCredential` sets the definition-time
76
+ * conditional here (e.g. prescription only for Rx); `.when()` composes a
77
+ * call-site conditional onto it (AND). One field, one check in the resolver.
78
+ */
79
+ appliesTo?: (order: GateOrder) => boolean;
80
+ /** The card shown in Context 2 (the checkout page). */
81
+ ui: {
82
+ label: string;
83
+ action: string;
84
+ };
85
+ /** Builder-derived parameters (`age.over(21)` → `{ minAge: 21 }`). */
86
+ params?: {
87
+ minAge?: number;
88
+ percent?: number;
89
+ currency?: string;
90
+ };
91
+ /**
92
+ * Attach a call-site conditional (e.g. `age.over(21).when(hasAlcohol)`).
93
+ * Returns a NEW Credential (chainable, non-mutating); the predicate is AND-ed
94
+ * onto any existing `appliesTo`.
95
+ */
96
+ when(predicate: (order: GateOrder) => boolean): Credential;
97
+ }
98
+ export interface Step {
99
+ /** The gate. */
100
+ credential: Credential;
101
+ /** `required(c)` → true; `optional(c)` → false. */
102
+ required: boolean;
103
+ }
104
+ /** The flat, JSON-safe element of `requires`. No functions. */
105
+ export interface VerificationManifestEntry {
106
+ credential: string;
107
+ required: boolean;
108
+ effect: "gate" | "discount" | "authorize";
109
+ /** Where it runs (Principle VII — honesty in the type). */
110
+ enforcedAt: "tool" | "checkout";
111
+ /** mdoc trust (Principle VII; matches the envelope's field — no regression). */
112
+ trust_level: TrustLevel;
113
+ /** From `ui.label`; human-readable for agent / widget. */
114
+ label: string;
115
+ /** age only. */
116
+ minAge?: number;
117
+ /** discount only. */
118
+ discountPct?: number;
119
+ /** Per-order link (gate / authorize effects). */
120
+ approveUrl?: string;
121
+ }
122
+ export interface VerificationRecord {
123
+ ageVerified?: boolean;
124
+ loyalty?: {
125
+ applied: boolean;
126
+ membershipNumber: string | null;
127
+ };
128
+ /** Custom credential results, keyed by credential id. */
129
+ [credentialId: string]: unknown;
130
+ }
131
+ export interface VerificationStore {
132
+ read(orderId: string): VerificationRecord | undefined | Promise<VerificationRecord | undefined>;
133
+ write(orderId: string, record: VerificationRecord): void | Promise<void>;
134
+ clear(orderId: string): void | Promise<void>;
135
+ }
136
+ export interface AttestoMcpOptions {
137
+ /**
138
+ * Absolute origin the wallet ceremony binds to (e.g. `https://shop.example`).
139
+ * Optional — defaults to `http://localhost:<PORT|3000>` so zero-config local
140
+ * dev works. Warns (never throws) if it's not absolute, or if it resolves to
141
+ * localhost in production. Set it to your public origin for any deployment.
142
+ */
143
+ walletOrigin?: string;
144
+ /** Per-order verification state; default in-memory, pluggable (Redis). */
145
+ store?: VerificationStore;
146
+ }
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ // @openmobilehub/attestomcp-gate — public types (the contract, in TypeScript).
2
+ //
3
+ // Two layers (see specs/001-attesto-sdk/data-model.md):
4
+ // • policy — code: builders carry functions (.when / verify / appliesTo) and live in your server.
5
+ // • manifest — data: `requirements()` resolves the policy server-side and emits a flat, JSON-safe
6
+ // manifest. Functions NEVER cross the wire. `requirements()` is that code→data boundary.
7
+ export {};
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@openmobilehub/attestomcp-gate",
3
+ "version": "0.1.0",
4
+ "description": "The consent layer for AI agents — require a verifiable credential from the user's wallet before a consequential MCP tool completes. Identity leads; payments is one application.",
5
+ "license": "Apache-2.0",
6
+ "author": "Open Mobile Hub (Linux Foundation)",
7
+ "homepage": "https://github.com/openmobilehub/mcp-apps-shopping-demo/tree/main/packages/attestomcp-gate#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/openmobilehub/mcp-apps-shopping-demo.git",
11
+ "directory": "packages/attestomcp-gate"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/openmobilehub/mcp-apps-shopping-demo/issues"
15
+ },
16
+ "type": "module",
17
+ "sideEffects": false,
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
22
+ }
23
+ },
24
+ "main": "./dist/index.js",
25
+ "types": "./dist/index.d.ts",
26
+ "engines": {
27
+ "node": ">=20"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc -p tsconfig.json && tsc -p tsconfig.test.json",
36
+ "test": "vitest run"
37
+ },
38
+ "keywords": [
39
+ "mcp",
40
+ "agent",
41
+ "verifiable-credentials",
42
+ "openid4vp",
43
+ "mdoc",
44
+ "consent",
45
+ "agentic-commerce"
46
+ ],
47
+ "dependencies": {
48
+ "@hpke/core": "^1.9.0",
49
+ "@peculiar/x509": "^1.14.3",
50
+ "@simplewebauthn/browser": "^13.3.0",
51
+ "@simplewebauthn/server": "^13.3.1",
52
+ "cbor-x": "^1.6.4",
53
+ "jose": "^5.10.0"
54
+ },
55
+ "devDependencies": {
56
+ "@types/supertest": "^7.2.0",
57
+ "supertest": "^7.2.2"
58
+ },
59
+ "publishConfig": {
60
+ "access": "public"
61
+ }
62
+ }