@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.
- package/LICENSE +201 -0
- package/README.md +172 -0
- package/dist/ceremony/cartMandate.d.ts +61 -0
- package/dist/ceremony/cartMandate.js +76 -0
- package/dist/ceremony/challengeToken.d.ts +5 -0
- package/dist/ceremony/challengeToken.js +43 -0
- package/dist/ceremony/checkout-page.d.ts +85 -0
- package/dist/ceremony/checkout-page.js +269 -0
- package/dist/ceremony/completion.d.ts +41 -0
- package/dist/ceremony/completion.js +90 -0
- package/dist/ceremony/credential-gate/dcql.d.ts +10 -0
- package/dist/ceremony/credential-gate/dcql.js +12 -0
- package/dist/ceremony/credential-gate/doc-spec.d.ts +3 -0
- package/dist/ceremony/credential-gate/doc-spec.js +16 -0
- package/dist/ceremony/credential-gate/mdoc-verify.d.ts +15 -0
- package/dist/ceremony/credential-gate/mdoc-verify.js +29 -0
- package/dist/ceremony/credential-gate/page.d.ts +20 -0
- package/dist/ceremony/credential-gate/page.js +136 -0
- package/dist/ceremony/credential-gate/request.d.ts +15 -0
- package/dist/ceremony/credential-gate/request.js +43 -0
- package/dist/ceremony/credential-gate/routes.d.ts +2 -0
- package/dist/ceremony/credential-gate/routes.js +200 -0
- package/dist/ceremony/credential-gate/verify.d.ts +51 -0
- package/dist/ceremony/credential-gate/verify.js +146 -0
- package/dist/ceremony/dc-payment/dcql.d.ts +5 -0
- package/dist/ceremony/dc-payment/dcql.js +23 -0
- package/dist/ceremony/dc-payment/page.d.ts +18 -0
- package/dist/ceremony/dc-payment/page.js +195 -0
- package/dist/ceremony/dc-payment/request.d.ts +17 -0
- package/dist/ceremony/dc-payment/request.js +50 -0
- package/dist/ceremony/dc-payment/routes.d.ts +2 -0
- package/dist/ceremony/dc-payment/routes.js +147 -0
- package/dist/ceremony/dc-payment/txData.d.ts +19 -0
- package/dist/ceremony/dc-payment/txData.js +34 -0
- package/dist/ceremony/dc-payment/verify.d.ts +108 -0
- package/dist/ceremony/dc-payment/verify.js +208 -0
- package/dist/ceremony/mandate.d.ts +71 -0
- package/dist/ceremony/mandate.js +116 -0
- package/dist/ceremony/mdoc/mdoc-iso.d.ts +44 -0
- package/dist/ceremony/mdoc/mdoc-iso.js +260 -0
- package/dist/ceremony/mdoc/mdoc.d.ts +17 -0
- package/dist/ceremony/mdoc/mdoc.js +94 -0
- package/dist/ceremony/mdoc/reader.d.ts +10 -0
- package/dist/ceremony/mdoc/reader.js +43 -0
- package/dist/ceremony/mdoc/readerContext.d.ts +8 -0
- package/dist/ceremony/mdoc/readerContext.js +29 -0
- package/dist/ceremony/mount.d.ts +57 -0
- package/dist/ceremony/mount.js +96 -0
- package/dist/ceremony/origin.d.ts +10 -0
- package/dist/ceremony/origin.js +9 -0
- package/dist/ceremony/passkey/page.d.ts +6 -0
- package/dist/ceremony/passkey/page.js +136 -0
- package/dist/ceremony/passkey/routes.d.ts +2 -0
- package/dist/ceremony/passkey/routes.js +170 -0
- package/dist/ceremony/passkey/verify.d.ts +15 -0
- package/dist/ceremony/passkey/verify.js +56 -0
- package/dist/ceremony/reconciliation.d.ts +34 -0
- package/dist/ceremony/reconciliation.js +21 -0
- package/dist/ceremony/theme.d.ts +63 -0
- package/dist/ceremony/theme.js +285 -0
- package/dist/ceremony/types.d.ts +95 -0
- package/dist/ceremony/types.js +1 -0
- package/dist/client.d.ts +39 -0
- package/dist/client.js +84 -0
- package/dist/credentials.d.ts +48 -0
- package/dist/credentials.js +127 -0
- package/dist/envelope.d.ts +62 -0
- package/dist/envelope.js +72 -0
- package/dist/gated.d.ts +39 -0
- package/dist/gated.js +41 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +49 -0
- package/dist/manifest.d.ts +28 -0
- package/dist/manifest.js +76 -0
- package/dist/store.d.ts +7 -0
- package/dist/store.js +16 -0
- package/dist/types.d.ts +146 -0
- package/dist/types.js +7 -0
- package/package.json +62 -0
package/dist/types.d.ts
ADDED
|
@@ -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
|
+
}
|