@kya-os/mcp-i 1.10.0 → 1.11.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/dist/317.js +1 -0
- package/dist/342.js +1 -0
- package/dist/354.js +1 -1
- package/dist/95.js +1 -1
- package/dist/auth/oauth/router.js +2 -2
- package/dist/cli-adapter/index.js +1 -1
- package/dist/providers/node-providers.d.ts +1 -1
- package/dist/providers/node-providers.js +9 -9
- package/dist/runtime/337.js +1 -0
- package/dist/runtime/adapter-express.js +3 -3
- package/dist/runtime/adapter-nextjs.js +5 -5
- package/dist/runtime/audit.d.ts +1 -1
- package/dist/runtime/auth-handshake.d.ts +1 -1
- package/dist/runtime/auth-handshake.js +4 -4
- package/dist/runtime/debug.d.ts +1 -1
- package/dist/runtime/debug.js +3 -2
- package/dist/runtime/delegation-hooks.d.ts +1 -1
- package/dist/runtime/delegation-verifier-agentshield.js +1 -0
- package/dist/runtime/http.js +3 -3
- package/dist/runtime/identity.d.ts +4 -4
- package/dist/runtime/identity.js +4 -4
- package/dist/runtime/index.d.ts +6 -2
- package/dist/runtime/index.js +10 -2
- package/dist/runtime/mcpi-runtime-wrapper.d.ts +1 -1
- package/dist/runtime/mcpi-runtime-wrapper.js +4 -4
- package/dist/runtime/mcpi-runtime.d.ts +9 -1
- package/dist/runtime/mcpi-runtime.js +21 -3
- package/dist/runtime/outbound-delegation.d.ts +5 -3
- package/dist/runtime/outbound-delegation.js +15 -8
- package/dist/runtime/outbound-identity-bridge.d.ts +40 -0
- package/dist/runtime/outbound-identity-bridge.js +119 -0
- package/dist/runtime/proof-batch-queue.d.ts +1 -1
- package/dist/runtime/proof.d.ts +2 -2
- package/dist/runtime/proof.js +3 -3
- package/dist/runtime/request-context.d.ts +10 -0
- package/dist/runtime/request-context.js +4 -0
- package/dist/runtime/resume-token-store-kv.d.ts +44 -0
- package/dist/runtime/resume-token-store-kv.js +93 -0
- package/dist/runtime/resume-token-store.d.ts +30 -0
- package/dist/runtime/resume-token-store.js +46 -0
- package/dist/runtime/session.d.ts +2 -2
- package/dist/runtime/session.js +12 -6
- package/dist/runtime/stdio.js +3 -3
- package/dist/runtime/utils/tools.d.ts +2 -2
- package/dist/runtime/utils/tools.js +33 -10
- package/dist/runtime/well-known.d.ts +12 -1
- package/dist/runtime/well-known.js +13 -2
- package/package.json +6 -4
- package/dist/225.js +0 -1
- package/dist/runtime/verifier-middleware.d.ts +0 -99
- package/dist/runtime/verifier-middleware.js +0 -416
|
@@ -1,416 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CoreVerifier = void 0;
|
|
4
|
-
exports.verifyWorker = verifyWorker;
|
|
5
|
-
exports.verifyExpress = verifyExpress;
|
|
6
|
-
const verifier_1 = require("@kya-os/contracts/verifier");
|
|
7
|
-
const merkle_verifier_1 = require("../storage/merkle-verifier");
|
|
8
|
-
const delegation_1 = require("../storage/delegation");
|
|
9
|
-
const mcp_i_core_1 = require("@kya-os/mcp-i-core");
|
|
10
|
-
/**
|
|
11
|
-
* Core verifier implementation
|
|
12
|
-
*/
|
|
13
|
-
class CoreVerifier {
|
|
14
|
-
config;
|
|
15
|
-
receiptVerifier;
|
|
16
|
-
delegationManager;
|
|
17
|
-
cryptoService;
|
|
18
|
-
constructor(config = {}) {
|
|
19
|
-
this.config = config;
|
|
20
|
-
this.receiptVerifier = (0, merkle_verifier_1.createReceiptVerifier)({
|
|
21
|
-
enabled: config.receiptVerification !== false,
|
|
22
|
-
ktaBaseUrl: config.ktaBaseUrl,
|
|
23
|
-
allowMockData: config.allowMockData,
|
|
24
|
-
});
|
|
25
|
-
this.delegationManager = (0, delegation_1.createDelegationManager)({
|
|
26
|
-
ktaBaseURL: config.ktaBaseUrl || "https://knowthat.ai",
|
|
27
|
-
});
|
|
28
|
-
// Initialize CryptoService if cryptoProvider is provided
|
|
29
|
-
if (config.cryptoProvider) {
|
|
30
|
-
this.cryptoService = new mcp_i_core_1.CryptoService(config.cryptoProvider);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Verify proof with optional receipt checking
|
|
35
|
-
*/
|
|
36
|
-
async verify(context) {
|
|
37
|
-
try {
|
|
38
|
-
// 1. Verify proof signature (placeholder - would use actual crypto verification)
|
|
39
|
-
const signatureValid = await this.verifySignature(context.proof, context.detachedProof);
|
|
40
|
-
if (!signatureValid) {
|
|
41
|
-
return {
|
|
42
|
-
success: false,
|
|
43
|
-
error: {
|
|
44
|
-
code: "XMCP_I_EBADPROOF",
|
|
45
|
-
message: "Invalid proof signature",
|
|
46
|
-
httpStatus: 403,
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
// 2. Check delegation if present
|
|
51
|
-
if (context.proof.delegationRef &&
|
|
52
|
-
this.config.delegationChecking !== false) {
|
|
53
|
-
const delegationValid = await this.verifyDelegation(context.proof.delegationRef);
|
|
54
|
-
if (!delegationValid) {
|
|
55
|
-
return {
|
|
56
|
-
success: false,
|
|
57
|
-
error: {
|
|
58
|
-
code: "XMCP_I_EBADPROOF",
|
|
59
|
-
message: "Delegation revoked or invalid",
|
|
60
|
-
httpStatus: 403,
|
|
61
|
-
},
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
// 3. Verify receipt if present and policy requires it
|
|
66
|
-
if (context.receipt && this.shouldVerifyReceipt()) {
|
|
67
|
-
const receiptResult = await this.receiptVerifier.verify(context.receipt);
|
|
68
|
-
if (!receiptResult.valid) {
|
|
69
|
-
return {
|
|
70
|
-
success: false,
|
|
71
|
-
error: {
|
|
72
|
-
code: "XMCP_I_ERECEIPT",
|
|
73
|
-
message: `Receipt verification failed: ${receiptResult.error}`,
|
|
74
|
-
httpStatus: 403,
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
// 4. Generate trusted headers
|
|
80
|
-
const headers = this.generateHeaders(context.proof);
|
|
81
|
-
return {
|
|
82
|
-
success: true,
|
|
83
|
-
headers,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
return {
|
|
88
|
-
success: false,
|
|
89
|
-
error: {
|
|
90
|
-
code: "XMCP_I_EVERIFY",
|
|
91
|
-
message: error instanceof Error ? error.message : "Verification failed",
|
|
92
|
-
httpStatus: 500,
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Verify proof signature
|
|
99
|
-
*
|
|
100
|
-
* Note: Full signature verification requires DetachedProof with JWS.
|
|
101
|
-
* If only ProofMeta is available, performs structure validation only.
|
|
102
|
-
* To enable full verification, provide detachedProof in VerifierContext.
|
|
103
|
-
*/
|
|
104
|
-
async verifySignature(proof, detachedProof) {
|
|
105
|
-
// Basic structure validation
|
|
106
|
-
const hasRequiredFields = !!(proof.did &&
|
|
107
|
-
proof.kid &&
|
|
108
|
-
proof.ts &&
|
|
109
|
-
proof.nonce &&
|
|
110
|
-
proof.audience &&
|
|
111
|
-
proof.sessionId &&
|
|
112
|
-
proof.requestHash &&
|
|
113
|
-
proof.responseHash);
|
|
114
|
-
if (!hasRequiredFields) {
|
|
115
|
-
return false;
|
|
116
|
-
}
|
|
117
|
-
// If we have full DetachedProof with JWS and CryptoService, verify signature
|
|
118
|
-
if (detachedProof?.jws && this.cryptoService) {
|
|
119
|
-
try {
|
|
120
|
-
// Fetch public key from DID document
|
|
121
|
-
// Note: This is a simplified implementation - production should use proper DID resolver
|
|
122
|
-
const publicKeyJwk = await this.fetchPublicKeyFromDID(proof.did, proof.kid);
|
|
123
|
-
if (!publicKeyJwk) {
|
|
124
|
-
console.warn("[CoreVerifier] Could not resolve public key from DID, skipping signature verification");
|
|
125
|
-
return true; // Fall back to structure validation only
|
|
126
|
-
}
|
|
127
|
-
// Verify JWS signature
|
|
128
|
-
return await this.cryptoService.verifyJWS(detachedProof.jws, publicKeyJwk, {
|
|
129
|
-
expectedKid: proof.kid,
|
|
130
|
-
alg: "EdDSA",
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
console.error("[CoreVerifier] Signature verification error:", error);
|
|
135
|
-
return false;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
// Fallback: structure validation only (when JWS not available)
|
|
139
|
-
return true;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Fetch public key from DID document
|
|
143
|
-
*
|
|
144
|
-
* Note: This is a simplified implementation. Production code should use
|
|
145
|
-
* a proper DID resolver that supports multiple DID methods (did:key, did:web, etc.)
|
|
146
|
-
*/
|
|
147
|
-
async fetchPublicKeyFromDID(did, kid) {
|
|
148
|
-
// For now, only support did:web resolution
|
|
149
|
-
// TODO: Add support for did:key and other DID methods
|
|
150
|
-
if (!did.startsWith("did:web:")) {
|
|
151
|
-
console.warn(`[CoreVerifier] Unsupported DID method: ${did}`);
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
try {
|
|
155
|
-
const domain = did.replace("did:web:", "").replace(/:/g, "/");
|
|
156
|
-
const didDocUrl = `https://${domain}/.well-known/did.json`;
|
|
157
|
-
const response = await fetch(didDocUrl);
|
|
158
|
-
if (!response.ok) {
|
|
159
|
-
console.warn(`[CoreVerifier] Failed to fetch DID document: ${response.status}`);
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
const didDoc = await response.json();
|
|
163
|
-
// Find verification method
|
|
164
|
-
const verificationMethod = didDoc.verificationMethod?.find((vm) => vm.id === `#${kid}` || vm.id === `${did}#${kid}` || vm.id === kid);
|
|
165
|
-
if (!verificationMethod?.publicKeyJwk) {
|
|
166
|
-
console.warn(`[CoreVerifier] Verification method ${kid} not found in DID document`);
|
|
167
|
-
return null;
|
|
168
|
-
}
|
|
169
|
-
// Validate JWK format
|
|
170
|
-
const jwk = verificationMethod.publicKeyJwk;
|
|
171
|
-
if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519") {
|
|
172
|
-
console.warn(`[CoreVerifier] Invalid JWK format: expected Ed25519, got ${jwk.kty}/${jwk.crv}`);
|
|
173
|
-
return null;
|
|
174
|
-
}
|
|
175
|
-
return jwk;
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
console.error("[CoreVerifier] DID resolution error:", error);
|
|
179
|
-
return null;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Verify delegation status
|
|
184
|
-
*/
|
|
185
|
-
async verifyDelegation(delegationRef) {
|
|
186
|
-
try {
|
|
187
|
-
return await this.delegationManager.isActive(delegationRef);
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
console.warn("Delegation verification failed:", error);
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Check if receipt verification should be performed
|
|
196
|
-
*/
|
|
197
|
-
shouldVerifyReceipt() {
|
|
198
|
-
const policy = this.config.receiptPolicy || "optional";
|
|
199
|
-
return (policy === "required" ||
|
|
200
|
-
(policy === "optional" && this.config.receiptVerification !== false));
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Generate trusted headers for successful verification
|
|
204
|
-
*/
|
|
205
|
-
generateHeaders(proof) {
|
|
206
|
-
const headers = {
|
|
207
|
-
[verifier_1.AGENT_HEADERS.DID]: proof.did,
|
|
208
|
-
[verifier_1.AGENT_HEADERS.KEY_ID]: proof.kid,
|
|
209
|
-
[verifier_1.AGENT_HEADERS.SESSION]: proof.sessionId,
|
|
210
|
-
[verifier_1.AGENT_HEADERS.CONFIDENCE]: "verified",
|
|
211
|
-
[verifier_1.AGENT_HEADERS.VERIFIED_AT]: Math.floor(Date.now() / 1000).toString(),
|
|
212
|
-
};
|
|
213
|
-
if (proof.scopeId) {
|
|
214
|
-
headers[verifier_1.AGENT_HEADERS.SCOPES] = proof.scopeId;
|
|
215
|
-
}
|
|
216
|
-
if (proof.delegationRef) {
|
|
217
|
-
headers[verifier_1.AGENT_HEADERS.DELEGATION_REF] = proof.delegationRef;
|
|
218
|
-
}
|
|
219
|
-
// Add registry URL for traceability
|
|
220
|
-
const ktaUrl = this.config.ktaBaseUrl || "https://knowthat.ai";
|
|
221
|
-
headers[verifier_1.AGENT_HEADERS.REGISTRY] =
|
|
222
|
-
`${ktaUrl}/agents/${encodeURIComponent(proof.did)}`;
|
|
223
|
-
return headers;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
exports.CoreVerifier = CoreVerifier;
|
|
227
|
-
/**
|
|
228
|
-
* Cloudflare Worker verifier
|
|
229
|
-
*/
|
|
230
|
-
async function verifyWorker(request, config) {
|
|
231
|
-
try {
|
|
232
|
-
// Extract proof from request headers or body
|
|
233
|
-
const proof = await parseProofFromHeaders(request);
|
|
234
|
-
if (!proof) {
|
|
235
|
-
return {
|
|
236
|
-
success: false,
|
|
237
|
-
error: {
|
|
238
|
-
code: "XMCP_I_ENOIDENTITY",
|
|
239
|
-
message: "No proof found in request",
|
|
240
|
-
httpStatus: 401,
|
|
241
|
-
},
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
// Extract receipt if present
|
|
245
|
-
const receipt = await parseReceiptFromHeaders(request);
|
|
246
|
-
const verifier = new CoreVerifier(config);
|
|
247
|
-
return await verifier.verify({ proof, receipt: receipt || undefined });
|
|
248
|
-
}
|
|
249
|
-
catch (error) {
|
|
250
|
-
return {
|
|
251
|
-
success: false,
|
|
252
|
-
error: {
|
|
253
|
-
code: "XMCP_I_EVERIFY",
|
|
254
|
-
message: error instanceof Error ? error.message : "Verification failed",
|
|
255
|
-
httpStatus: 500,
|
|
256
|
-
},
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Express verifier middleware
|
|
262
|
-
*/
|
|
263
|
-
function verifyExpress(config) {
|
|
264
|
-
return async (req, res, next) => {
|
|
265
|
-
try {
|
|
266
|
-
// Extract proof from request
|
|
267
|
-
const proof = await parseProofFromExpressHeaders(req);
|
|
268
|
-
if (!proof) {
|
|
269
|
-
return res.status(401).json({
|
|
270
|
-
code: "XMCP_I_ENOIDENTITY",
|
|
271
|
-
message: "No proof found in request",
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
// Extract receipt if present
|
|
275
|
-
const receipt = await parseReceiptFromExpressHeaders(req);
|
|
276
|
-
const verifier = new CoreVerifier(config);
|
|
277
|
-
const result = await verifier.verify({
|
|
278
|
-
proof,
|
|
279
|
-
receipt: receipt || undefined,
|
|
280
|
-
});
|
|
281
|
-
if (!result.success) {
|
|
282
|
-
return res.status(result.error.httpStatus).json({
|
|
283
|
-
code: result.error.code,
|
|
284
|
-
message: result.error.message,
|
|
285
|
-
details: result.error.details,
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
// Set headers and context
|
|
289
|
-
if (result.headers) {
|
|
290
|
-
Object.entries(result.headers).forEach(([key, value]) => {
|
|
291
|
-
res.setHeader(key, value);
|
|
292
|
-
});
|
|
293
|
-
// Set ctx.agent for MCP recipients
|
|
294
|
-
req.ctx = req.ctx || {};
|
|
295
|
-
req.ctx.agent = {
|
|
296
|
-
did: result.headers[verifier_1.AGENT_HEADERS.DID],
|
|
297
|
-
kid: result.headers[verifier_1.AGENT_HEADERS.KEY_ID],
|
|
298
|
-
session: result.headers[verifier_1.AGENT_HEADERS.SESSION],
|
|
299
|
-
scopes: result.headers[verifier_1.AGENT_HEADERS.SCOPES]?.split(",") || [],
|
|
300
|
-
delegationRef: result.headers[verifier_1.AGENT_HEADERS.DELEGATION_REF],
|
|
301
|
-
confidence: result.headers[verifier_1.AGENT_HEADERS.CONFIDENCE],
|
|
302
|
-
verifiedAt: parseInt(result.headers[verifier_1.AGENT_HEADERS.VERIFIED_AT]),
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
next();
|
|
306
|
-
}
|
|
307
|
-
catch (error) {
|
|
308
|
-
res.status(500).json({
|
|
309
|
-
code: "XMCP_I_EVERIFY",
|
|
310
|
-
message: error instanceof Error ? error.message : "Verification failed",
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Helper: Extract header value from different header types
|
|
317
|
-
*/
|
|
318
|
-
function getHeaderValue(headers, name) {
|
|
319
|
-
if (headers instanceof Headers) {
|
|
320
|
-
return headers.get(name);
|
|
321
|
-
}
|
|
322
|
-
const header = headers[name.toLowerCase()];
|
|
323
|
-
if (!header)
|
|
324
|
-
return null;
|
|
325
|
-
return Array.isArray(header) ? header[0] : header;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* Parse proof from request headers
|
|
329
|
-
*
|
|
330
|
-
* This function extracts ProofMeta from request headers.
|
|
331
|
-
* ProofMeta type is defined in @kya-os/contracts/proof.
|
|
332
|
-
*
|
|
333
|
-
* @param request - Fetch API Request or Express Request
|
|
334
|
-
* @returns ProofMeta (from @kya-os/contracts/proof) if found, null otherwise
|
|
335
|
-
*/
|
|
336
|
-
async function parseProofFromHeaders(request) {
|
|
337
|
-
// TODO: Implement actual proof extraction from request
|
|
338
|
-
// This would typically look for proof in headers or request body
|
|
339
|
-
// Placeholder implementation
|
|
340
|
-
// Handle both Fetch API Request and Node.js IncomingMessage
|
|
341
|
-
const proofHeader = getHeaderValue(request.headers, "KYA-Proof");
|
|
342
|
-
if (!proofHeader) {
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
try {
|
|
346
|
-
return JSON.parse(proofHeader);
|
|
347
|
-
}
|
|
348
|
-
catch {
|
|
349
|
-
return null;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* Parse receipt from request headers
|
|
354
|
-
*
|
|
355
|
-
* This function extracts Receipt from request headers.
|
|
356
|
-
* Receipt type is defined in @kya-os/contracts/registry.
|
|
357
|
-
*
|
|
358
|
-
* @param request - Fetch API Request or Express Request
|
|
359
|
-
* @returns Receipt (from @kya-os/contracts/registry) if found, null otherwise
|
|
360
|
-
*/
|
|
361
|
-
async function parseReceiptFromHeaders(request) {
|
|
362
|
-
// TODO: Implement actual receipt extraction from request
|
|
363
|
-
// This would typically look for receipt reference in headers
|
|
364
|
-
// Handle both Fetch API Request and Node.js IncomingMessage
|
|
365
|
-
const receiptRef = getHeaderValue(request.headers, "KYA-Receipt-Ref");
|
|
366
|
-
if (!receiptRef) {
|
|
367
|
-
return null;
|
|
368
|
-
}
|
|
369
|
-
// TODO: Fetch receipt by reference from storage
|
|
370
|
-
return null;
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Parse proof from Express request headers
|
|
374
|
-
*
|
|
375
|
-
* This function extracts ProofMeta from Express request headers.
|
|
376
|
-
* ProofMeta type is defined in @kya-os/contracts/proof.
|
|
377
|
-
*
|
|
378
|
-
* @param req - Express Request
|
|
379
|
-
* @returns ProofMeta (from @kya-os/contracts/proof) if found, null otherwise
|
|
380
|
-
*/
|
|
381
|
-
async function parseProofFromExpressHeaders(req) {
|
|
382
|
-
// TODO: Implement actual proof extraction from Express request
|
|
383
|
-
// This would typically look for proof in headers or request body
|
|
384
|
-
const proofHeader = req.headers["kya-proof"];
|
|
385
|
-
if (!proofHeader) {
|
|
386
|
-
return null;
|
|
387
|
-
}
|
|
388
|
-
try {
|
|
389
|
-
const headerValue = Array.isArray(proofHeader)
|
|
390
|
-
? proofHeader[0]
|
|
391
|
-
: proofHeader;
|
|
392
|
-
return JSON.parse(headerValue);
|
|
393
|
-
}
|
|
394
|
-
catch {
|
|
395
|
-
return null;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Parse receipt from Express request headers
|
|
400
|
-
*
|
|
401
|
-
* This function extracts Receipt from Express request headers.
|
|
402
|
-
* Receipt type is defined in @kya-os/contracts/registry.
|
|
403
|
-
*
|
|
404
|
-
* @param req - Express Request
|
|
405
|
-
* @returns Receipt (from @kya-os/contracts/registry) if found, null otherwise
|
|
406
|
-
*/
|
|
407
|
-
async function parseReceiptFromExpressHeaders(req) {
|
|
408
|
-
// TODO: Implement actual receipt extraction from Express request
|
|
409
|
-
// This would typically look for receipt reference in headers
|
|
410
|
-
const receiptRef = req.headers["kya-receipt-ref"];
|
|
411
|
-
if (!receiptRef) {
|
|
412
|
-
return null;
|
|
413
|
-
}
|
|
414
|
-
// TODO: Fetch receipt by reference from storage
|
|
415
|
-
return null;
|
|
416
|
-
}
|