@violetclaire/popcorn-mcp 0.1.3 → 0.1.5
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 +55 -18
- package/dist/packages/mcp/src/core.d.ts +1 -1
- package/dist/packages/mcp/src/core.js +14 -2
- package/dist/packages/mcp/src/core.js.map +1 -1
- package/dist/packages/mcp/src/index.js +19 -2
- package/dist/packages/mcp/src/index.js.map +1 -1
- package/dist/packages/mcp/src/server.js +10 -2
- package/dist/packages/mcp/src/server.js.map +1 -1
- package/dist/packages/mcp/src/v2-interface.d.ts +34 -0
- package/dist/packages/mcp/src/v2-interface.js +81 -0
- package/dist/packages/mcp/src/v2-interface.js.map +1 -0
- package/dist/packages/mcp/src/v2-schema.d.ts +3 -0
- package/dist/packages/mcp/src/v2-schema.js +27 -0
- package/dist/packages/mcp/src/v2-schema.js.map +1 -0
- package/dist/verify/typescript/src/v2.d.ts +192 -0
- package/dist/verify/typescript/src/v2.js +554 -0
- package/dist/verify/typescript/src/v2.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
const encoder = new TextEncoder();
|
|
2
|
+
function decodeBase64Url(value) {
|
|
3
|
+
if (!/^[A-Za-z0-9_-]+$/.test(value)) {
|
|
4
|
+
throw new Error("compact JWS contains invalid base64url");
|
|
5
|
+
}
|
|
6
|
+
const decoded = Buffer.from(value, "base64url");
|
|
7
|
+
const copy = new Uint8Array(new ArrayBuffer(decoded.length));
|
|
8
|
+
copy.set(decoded);
|
|
9
|
+
return copy;
|
|
10
|
+
}
|
|
11
|
+
function parseJsonPart(value, label) {
|
|
12
|
+
try {
|
|
13
|
+
return JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
throw new Error(`${label} is not valid base64url JSON`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function isRecord(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21
|
+
}
|
|
22
|
+
function requireExactKeys(value, expected, label) {
|
|
23
|
+
const actualKeys = Object.keys(value).sort();
|
|
24
|
+
const expectedKeys = [...expected].sort();
|
|
25
|
+
if (actualKeys.length !== expectedKeys.length ||
|
|
26
|
+
actualKeys.some((key, index) => key !== expectedKeys[index])) {
|
|
27
|
+
throw new Error(`${label} contains missing or unsupported fields`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function canonicalJson(value) {
|
|
31
|
+
if (Array.isArray(value))
|
|
32
|
+
return `[${value.map(canonicalJson).join(",")}]`;
|
|
33
|
+
if (isRecord(value)) {
|
|
34
|
+
return `{${Object.keys(value)
|
|
35
|
+
.sort()
|
|
36
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`)
|
|
37
|
+
.join(",")}}`;
|
|
38
|
+
}
|
|
39
|
+
return JSON.stringify(value);
|
|
40
|
+
}
|
|
41
|
+
function encodeBase64Url(value) {
|
|
42
|
+
return Buffer.from(value).toString("base64url");
|
|
43
|
+
}
|
|
44
|
+
async function sha256Base64Url(value) {
|
|
45
|
+
const input = typeof value === "string" ? encoder.encode(value) : value;
|
|
46
|
+
const bytes = new Uint8Array(new ArrayBuffer(input.byteLength));
|
|
47
|
+
bytes.set(input);
|
|
48
|
+
return encodeBase64Url(await crypto.subtle.digest("SHA-256", bytes));
|
|
49
|
+
}
|
|
50
|
+
export async function digestWitnessSignedPayload(compactJws) {
|
|
51
|
+
if (typeof compactJws !== "string") {
|
|
52
|
+
throw new Error("compact_jws is missing");
|
|
53
|
+
}
|
|
54
|
+
const parts = compactJws.split(".");
|
|
55
|
+
if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
|
|
56
|
+
throw new Error("compact_jws must contain exactly three parts");
|
|
57
|
+
}
|
|
58
|
+
const payloadBytes = decodeBase64Url(parts[1]);
|
|
59
|
+
if (Buffer.from(payloadBytes).toString("base64url") !== parts[1]) {
|
|
60
|
+
throw new Error("compact JWS signed payload is not canonical base64url");
|
|
61
|
+
}
|
|
62
|
+
return sha256Base64Url(payloadBytes);
|
|
63
|
+
}
|
|
64
|
+
function requireSha256Digest(value, label) {
|
|
65
|
+
if (!isRecord(value) ||
|
|
66
|
+
value.algorithm !== "sha-256" ||
|
|
67
|
+
typeof value.value !== "string" ||
|
|
68
|
+
!/^[A-Za-z0-9_-]{43}$/.test(value.value)) {
|
|
69
|
+
throw new Error(`${label} must be an unpadded base64url SHA-256 digest`);
|
|
70
|
+
}
|
|
71
|
+
requireExactKeys(value, ["algorithm", "value"], label);
|
|
72
|
+
}
|
|
73
|
+
function requireNonce(value) {
|
|
74
|
+
if (typeof value !== "string" || !/^[A-Za-z0-9_-]{43}$/.test(value)) {
|
|
75
|
+
throw new Error("nonce must be 32 unpadded base64url bytes");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function requireFinite(value, label) {
|
|
79
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
80
|
+
throw new Error(`${label} must be a finite non-negative number`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function parseUtc(value, label) {
|
|
84
|
+
if (typeof value !== "string" || !value.endsWith("Z")) {
|
|
85
|
+
throw new Error(`${label} must be an explicit UTC timestamp`);
|
|
86
|
+
}
|
|
87
|
+
const parsed = Date.parse(value);
|
|
88
|
+
if (!Number.isFinite(parsed))
|
|
89
|
+
throw new Error(`${label} is invalid`);
|
|
90
|
+
return parsed;
|
|
91
|
+
}
|
|
92
|
+
export function evaluateWitnessAgainstSchedule(witnessWindowUtc, executionWindowUtc) {
|
|
93
|
+
const witnessEarliestMs = parseUtc(witnessWindowUtc.earliest, "witness_window_utc.earliest");
|
|
94
|
+
const witnessLatestMs = parseUtc(witnessWindowUtc.latest, "witness_window_utc.latest");
|
|
95
|
+
if (witnessEarliestMs > witnessLatestMs) {
|
|
96
|
+
throw new Error("witness_window_utc is not ordered");
|
|
97
|
+
}
|
|
98
|
+
const opensMs = parseUtc(executionWindowUtc.opens_at, "execution_window_utc.opens_at");
|
|
99
|
+
const closesMs = parseUtc(executionWindowUtc.closes_at, "execution_window_utc.closes_at");
|
|
100
|
+
if (opensMs >= closesMs) {
|
|
101
|
+
throw new Error("execution_window_utc is not ordered");
|
|
102
|
+
}
|
|
103
|
+
let decision;
|
|
104
|
+
let reason;
|
|
105
|
+
if (witnessLatestMs < opensMs) {
|
|
106
|
+
decision = "STOP";
|
|
107
|
+
reason = "witness_window_entirely_before_execution_window";
|
|
108
|
+
}
|
|
109
|
+
else if (witnessEarliestMs > closesMs) {
|
|
110
|
+
decision = "STOP";
|
|
111
|
+
reason = "witness_window_entirely_after_execution_window";
|
|
112
|
+
}
|
|
113
|
+
else if (witnessEarliestMs >= opensMs && witnessLatestMs <= closesMs) {
|
|
114
|
+
decision = "TIME_CHECK_PASSED";
|
|
115
|
+
reason = "witness_window_entirely_inside_execution_window";
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
decision = "RECHECK";
|
|
119
|
+
reason = "witness_uncertainty_crosses_execution_boundary";
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
decision,
|
|
123
|
+
authorization_granted: false,
|
|
124
|
+
reason,
|
|
125
|
+
witness_window_utc: {
|
|
126
|
+
earliest: witnessWindowUtc.earliest,
|
|
127
|
+
latest: witnessWindowUtc.latest,
|
|
128
|
+
},
|
|
129
|
+
execution_window_utc: {
|
|
130
|
+
opens_at: executionWindowUtc.opens_at,
|
|
131
|
+
closes_at: executionWindowUtc.closes_at,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
function requireIntegerRelationship(actual, expected, label) {
|
|
136
|
+
if (!Number.isSafeInteger(expected) || expected < 0 || actual !== expected) {
|
|
137
|
+
throw new Error(`${label} signed relationship is invalid`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function validateReceiptSemantics(receipt, expectedNodeId) {
|
|
141
|
+
if (receipt.node_id !== expectedNodeId)
|
|
142
|
+
throw new Error("unexpected node_id");
|
|
143
|
+
if (receipt.protocol_id !== "POPCORN/1.0")
|
|
144
|
+
throw new Error("unexpected protocol_id");
|
|
145
|
+
if (!receipt.anchor_id || !receipt.payment_identifier) {
|
|
146
|
+
throw new Error("receipt identifiers are missing");
|
|
147
|
+
}
|
|
148
|
+
const requestReceivedMs = parseUtc(receipt.request_received_at_utc, "request_received_at_utc");
|
|
149
|
+
const observedMs = parseUtc(receipt.observed_at_utc, "observed_at_utc");
|
|
150
|
+
const measurementMs = parseUtc(receipt.measurement_at_utc, "measurement_at_utc");
|
|
151
|
+
const validUntilMs = parseUtc(receipt.valid_until_utc, "valid_until_utc");
|
|
152
|
+
requireIntegerRelationship(measurementMs - requestReceivedMs, receipt.server_processing_duration_ms, "server_processing_duration_ms");
|
|
153
|
+
requireIntegerRelationship(measurementMs - observedMs, receipt.post_anchor_processing_duration_ms, "post_anchor_processing_duration_ms");
|
|
154
|
+
requireIntegerRelationship(validUntilMs - measurementMs, receipt.validity_at_measurement_ms, "validity_at_measurement_ms");
|
|
155
|
+
requireIntegerRelationship(validUntilMs - observedMs, receipt.freshness_window_ms, "freshness_window_ms");
|
|
156
|
+
if (receipt.unix_time_milliseconds !== observedMs) {
|
|
157
|
+
throw new Error("unix_time_milliseconds signed relationship is invalid");
|
|
158
|
+
}
|
|
159
|
+
if (receipt.evidence_scope?.type !== "bearer_temporal_evidence" ||
|
|
160
|
+
receipt.evidence_scope.caller_bound !== false ||
|
|
161
|
+
receipt.evidence_scope.task_bound !== false ||
|
|
162
|
+
receipt.evidence_scope.authorization_granted !== false) {
|
|
163
|
+
throw new Error("temporal evidence must be bearer, non-authorizing, and unbound");
|
|
164
|
+
}
|
|
165
|
+
return { measurementMs, validUntilMs };
|
|
166
|
+
}
|
|
167
|
+
export async function verifyPopcornTemporalEvidence(response, jwks, monotonic, options = {}) {
|
|
168
|
+
if (!isRecord(response) || !isRecord(response.temporal_receipt)) {
|
|
169
|
+
throw new Error("response is missing temporal_receipt");
|
|
170
|
+
}
|
|
171
|
+
if (!isRecord(response.temporal_attestation)) {
|
|
172
|
+
throw new Error("response is missing temporal_attestation");
|
|
173
|
+
}
|
|
174
|
+
const compact = response.temporal_attestation.compact_jws;
|
|
175
|
+
if (typeof compact !== "string")
|
|
176
|
+
throw new Error("compact_jws is missing");
|
|
177
|
+
const parts = compact.split(".");
|
|
178
|
+
if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
|
|
179
|
+
throw new Error("compact_jws must contain exactly three parts");
|
|
180
|
+
}
|
|
181
|
+
const [encodedHeader, encodedPayload, encodedSignature] = parts;
|
|
182
|
+
const header = parseJsonPart(encodedHeader, "protected header");
|
|
183
|
+
if (!isRecord(header) || header.alg !== "ES256" || typeof header.kid !== "string") {
|
|
184
|
+
throw new Error("protected header must contain alg=ES256 and kid");
|
|
185
|
+
}
|
|
186
|
+
if (response.temporal_attestation.algorithm !== undefined &&
|
|
187
|
+
response.temporal_attestation.algorithm !== "ES256") {
|
|
188
|
+
throw new Error("attestation algorithm does not match ES256");
|
|
189
|
+
}
|
|
190
|
+
if (response.temporal_attestation.key_id !== undefined &&
|
|
191
|
+
response.temporal_attestation.key_id !== header.kid) {
|
|
192
|
+
throw new Error("attestation key_id does not match protected kid");
|
|
193
|
+
}
|
|
194
|
+
const key = jwks?.keys?.find((candidate) => candidate.kid === header.kid);
|
|
195
|
+
if (!key)
|
|
196
|
+
throw new Error(`kid ${header.kid} is absent from JWKS`);
|
|
197
|
+
if (key.kty !== "EC" ||
|
|
198
|
+
key.crv !== "P-256" ||
|
|
199
|
+
(key.alg !== undefined && key.alg !== "ES256") ||
|
|
200
|
+
(key.use !== undefined && key.use !== "sig")) {
|
|
201
|
+
throw new Error("JWKS key is not an ES256 P-256 signature key");
|
|
202
|
+
}
|
|
203
|
+
const signature = decodeBase64Url(encodedSignature);
|
|
204
|
+
if (signature.byteLength !== 64)
|
|
205
|
+
throw new Error("ES256 signature must be 64 bytes");
|
|
206
|
+
const publicKey = await crypto.subtle.importKey("jwk", key, { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
|
|
207
|
+
const signatureVerified = await crypto.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, publicKey, signature, encoder.encode(`${encodedHeader}.${encodedPayload}`));
|
|
208
|
+
if (!signatureVerified)
|
|
209
|
+
throw new Error("ES256 temporal receipt signature is invalid");
|
|
210
|
+
const signedReceipt = parseJsonPart(encodedPayload, "signed payload");
|
|
211
|
+
if (canonicalJson(signedReceipt) !== canonicalJson(response.temporal_receipt)) {
|
|
212
|
+
throw new Error("response temporal_receipt does not equal the signed payload");
|
|
213
|
+
}
|
|
214
|
+
const receipt = signedReceipt;
|
|
215
|
+
const { measurementMs } = validateReceiptSemantics(receipt, options.expected_node_id ?? "767-2676.com");
|
|
216
|
+
requireFinite(monotonic.paid_request_start_monotonic_ms, "paid request start");
|
|
217
|
+
requireFinite(monotonic.paid_response_receive_monotonic_ms, "paid response receive");
|
|
218
|
+
const decisionMonotonicMs = monotonic.decision_monotonic_ms ?? monotonic.paid_response_receive_monotonic_ms;
|
|
219
|
+
requireFinite(decisionMonotonicMs, "decision time");
|
|
220
|
+
if (monotonic.paid_response_receive_monotonic_ms <
|
|
221
|
+
monotonic.paid_request_start_monotonic_ms ||
|
|
222
|
+
decisionMonotonicMs < monotonic.paid_response_receive_monotonic_ms) {
|
|
223
|
+
throw new Error("monotonic observations are out of order");
|
|
224
|
+
}
|
|
225
|
+
const rttMs = monotonic.paid_response_receive_monotonic_ms -
|
|
226
|
+
monotonic.paid_request_start_monotonic_ms;
|
|
227
|
+
const uncertaintyMs = Math.max(0, rttMs - Math.min(receipt.server_processing_duration_ms, rttMs));
|
|
228
|
+
const remainingAtReceiptMs = Math.max(0, receipt.validity_at_measurement_ms - uncertaintyMs);
|
|
229
|
+
const elapsedSinceReceiptMs = decisionMonotonicMs - monotonic.paid_response_receive_monotonic_ms;
|
|
230
|
+
const remainingNowMs = Math.max(0, remainingAtReceiptMs - elapsedSinceReceiptMs);
|
|
231
|
+
const earliestNowMs = measurementMs + elapsedSinceReceiptMs;
|
|
232
|
+
const latestNowMs = earliestNowMs + uncertaintyMs;
|
|
233
|
+
const result = {
|
|
234
|
+
signature_verified: true,
|
|
235
|
+
key_id: header.kid,
|
|
236
|
+
temporal_receipt: receipt,
|
|
237
|
+
paid_request_rtt_ms: rttMs,
|
|
238
|
+
network_uncertainty_ms: uncertaintyMs,
|
|
239
|
+
remaining_validity_at_receipt_ms: remainingAtReceiptMs,
|
|
240
|
+
remaining_validity_now_ms: remainingNowMs,
|
|
241
|
+
temporal_interval_now_utc: {
|
|
242
|
+
earliest: new Date(earliestNowMs).toISOString(),
|
|
243
|
+
latest: new Date(latestNowMs).toISOString(),
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
if (options.execution_window_utc) {
|
|
247
|
+
const opensMs = parseUtc(options.execution_window_utc.opens_at_utc, "opens_at_utc");
|
|
248
|
+
const closesMs = parseUtc(options.execution_window_utc.closes_at_utc, "closes_at_utc");
|
|
249
|
+
if (opensMs >= closesMs)
|
|
250
|
+
throw new Error("execution_window_utc is not ordered");
|
|
251
|
+
const eligible = remainingNowMs > 0 && earliestNowMs >= opensMs && latestNowMs < closesMs;
|
|
252
|
+
result.execution_window = {
|
|
253
|
+
eligible,
|
|
254
|
+
next_action: eligible ? "continue_task" : "request_new_temporal_anchor",
|
|
255
|
+
reason: eligible
|
|
256
|
+
? "verified_interval_within_execution_window"
|
|
257
|
+
: remainingNowMs === 0
|
|
258
|
+
? "temporal_evidence_expired"
|
|
259
|
+
: "verified_interval_not_within_execution_window",
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
return result;
|
|
263
|
+
}
|
|
264
|
+
export async function verifyPopcornWitnessEvidence(response, jwks, options) {
|
|
265
|
+
return verifyPopcornWitnessEvidenceInternal(response, jwks, options, new Set());
|
|
266
|
+
}
|
|
267
|
+
async function verifyPopcornWitnessEvidenceInternal(response, jwks, options, seenAttestations, verifyPredecessor = true) {
|
|
268
|
+
if (!isRecord(response) || !isRecord(response.witness_receipt)) {
|
|
269
|
+
throw new Error("response is missing witness_receipt");
|
|
270
|
+
}
|
|
271
|
+
if (!isRecord(response.witness_attestation)) {
|
|
272
|
+
throw new Error("response is missing witness_attestation");
|
|
273
|
+
}
|
|
274
|
+
// Presentation metadata is unsigned and must not prevent verification of
|
|
275
|
+
// the complete, cryptographically bound witness_receipt.
|
|
276
|
+
// Required envelope members are checked explicitly above and below.
|
|
277
|
+
requireExactKeys(response.witness_attestation, ["format", "algorithm", "key_id", "key_set", "compact_jws"], "witness_attestation");
|
|
278
|
+
const compact = response.witness_attestation.compact_jws;
|
|
279
|
+
if (typeof compact !== "string")
|
|
280
|
+
throw new Error("compact_jws is missing");
|
|
281
|
+
if (seenAttestations.has(compact)) {
|
|
282
|
+
throw new Error("witness receipt chain contains a cycle");
|
|
283
|
+
}
|
|
284
|
+
seenAttestations.add(compact);
|
|
285
|
+
const parts = compact.split(".");
|
|
286
|
+
if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
|
|
287
|
+
throw new Error("compact_jws must contain exactly three parts");
|
|
288
|
+
}
|
|
289
|
+
const [encodedHeader, encodedPayload, encodedSignature] = parts;
|
|
290
|
+
const header = parseJsonPart(encodedHeader, "protected header");
|
|
291
|
+
if (!isRecord(header) ||
|
|
292
|
+
header.alg !== "ES256" ||
|
|
293
|
+
typeof header.kid !== "string" ||
|
|
294
|
+
header.typ !== "popcorn-witness+jws") {
|
|
295
|
+
throw new Error("protected header must contain alg=ES256, kid, and typ=popcorn-witness+jws");
|
|
296
|
+
}
|
|
297
|
+
if (response.witness_attestation.format !== "JWS") {
|
|
298
|
+
throw new Error("attestation format does not match JWS");
|
|
299
|
+
}
|
|
300
|
+
if (response.witness_attestation.algorithm !== "ES256") {
|
|
301
|
+
throw new Error("attestation algorithm does not match ES256");
|
|
302
|
+
}
|
|
303
|
+
if (response.witness_attestation.key_id !== header.kid) {
|
|
304
|
+
throw new Error("attestation key_id does not match protected kid");
|
|
305
|
+
}
|
|
306
|
+
if (response.witness_attestation.key_set !== "/.well-known/popcorn-keys.json") {
|
|
307
|
+
throw new Error("attestation key_set is not canonical");
|
|
308
|
+
}
|
|
309
|
+
if (response.payment_status !== "settled") {
|
|
310
|
+
throw new Error("witness payment_status is not settled");
|
|
311
|
+
}
|
|
312
|
+
const key = jwks?.keys?.find((candidate) => candidate.kid === header.kid);
|
|
313
|
+
if (!key)
|
|
314
|
+
throw new Error(`kid ${header.kid} is absent from JWKS`);
|
|
315
|
+
if (key.kty !== "EC" ||
|
|
316
|
+
key.crv !== "P-256" ||
|
|
317
|
+
(key.alg !== undefined && key.alg !== "ES256") ||
|
|
318
|
+
(key.use !== undefined && key.use !== "sig")) {
|
|
319
|
+
throw new Error("JWKS key is not an ES256 P-256 signature key");
|
|
320
|
+
}
|
|
321
|
+
const signature = decodeBase64Url(encodedSignature);
|
|
322
|
+
if (signature.byteLength !== 64)
|
|
323
|
+
throw new Error("ES256 signature must be 64 bytes");
|
|
324
|
+
const publicKey = await crypto.subtle.importKey("jwk", key, { name: "ECDSA", namedCurve: "P-256" }, false, ["verify"]);
|
|
325
|
+
const signatureVerified = await crypto.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, publicKey, signature, encoder.encode(`${encodedHeader}.${encodedPayload}`));
|
|
326
|
+
if (!signatureVerified)
|
|
327
|
+
throw new Error("ES256 witness receipt signature is invalid");
|
|
328
|
+
const signedReceipt = parseJsonPart(encodedPayload, "signed payload");
|
|
329
|
+
if (canonicalJson(signedReceipt) !== canonicalJson(response.witness_receipt)) {
|
|
330
|
+
throw new Error("response witness_receipt does not equal the signed payload");
|
|
331
|
+
}
|
|
332
|
+
const receipt = signedReceipt;
|
|
333
|
+
requireExactKeys(receipt, [
|
|
334
|
+
"receipt_id",
|
|
335
|
+
"tain",
|
|
336
|
+
"node_id",
|
|
337
|
+
"protocol_id",
|
|
338
|
+
"request_received_at_utc",
|
|
339
|
+
"witnessed_at_utc",
|
|
340
|
+
"statement_created_at_utc",
|
|
341
|
+
"unix_time_milliseconds",
|
|
342
|
+
"clock_accuracy_radius_ms",
|
|
343
|
+
"witness_window_utc",
|
|
344
|
+
"server_processing_duration_ms",
|
|
345
|
+
"post_witness_processing_duration_ms",
|
|
346
|
+
"commitment",
|
|
347
|
+
"payment_identifier",
|
|
348
|
+
"payment_transaction",
|
|
349
|
+
"evidence_scope",
|
|
350
|
+
"issuing_origin",
|
|
351
|
+
"issuance_endpoint",
|
|
352
|
+
"tain_verification_uri",
|
|
353
|
+
"contribution_license_uri",
|
|
354
|
+
"license_terms_digest",
|
|
355
|
+
], "witness_receipt");
|
|
356
|
+
if (receipt.node_id !== (options.expected_node_id ?? "767-2676.com")) {
|
|
357
|
+
throw new Error("unexpected node_id");
|
|
358
|
+
}
|
|
359
|
+
if (receipt.protocol_id !== "POPCORN-WITNESS/2.0") {
|
|
360
|
+
throw new Error("unexpected protocol_id");
|
|
361
|
+
}
|
|
362
|
+
if (typeof receipt.receipt_id !== "string" ||
|
|
363
|
+
!/^pwr_[0-9a-f]{32}$/.test(receipt.receipt_id) ||
|
|
364
|
+
typeof receipt.payment_identifier !== "string" ||
|
|
365
|
+
receipt.payment_identifier.length === 0 ||
|
|
366
|
+
!(receipt.payment_transaction === null ||
|
|
367
|
+
typeof receipt.payment_transaction === "string")) {
|
|
368
|
+
throw new Error("receipt identifiers are missing");
|
|
369
|
+
}
|
|
370
|
+
if (typeof receipt.tain !== "string" || !/^tain_[0-9A-HJKMNP-TV-Z]{26}$/.test(receipt.tain)) {
|
|
371
|
+
throw new Error("witness receipt tain is missing or malformed");
|
|
372
|
+
}
|
|
373
|
+
if (receipt.issuing_origin !== "https://767-2676.com" ||
|
|
374
|
+
(receipt.issuance_endpoint !== "/v1/receipt" && receipt.issuance_endpoint !== "/v2/receipt") ||
|
|
375
|
+
receipt.tain_verification_uri !== `https://767-2676.com/v1/receipt/tain/${receipt.tain}` ||
|
|
376
|
+
receipt.contribution_license_uri !== "https://767-2676.com/license/contribution/1.0") {
|
|
377
|
+
throw new Error("witness receipt provenance or license URI is invalid");
|
|
378
|
+
}
|
|
379
|
+
requireSha256Digest(receipt.license_terms_digest, "license_terms_digest");
|
|
380
|
+
// Optional QR/letterhead data is presentation-only; it is not signed evidence.
|
|
381
|
+
const requestReceivedMs = parseUtc(receipt.request_received_at_utc, "request_received_at_utc");
|
|
382
|
+
const witnessedMs = parseUtc(receipt.witnessed_at_utc, "witnessed_at_utc");
|
|
383
|
+
const alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
384
|
+
let tainTimestampMs = 0n;
|
|
385
|
+
for (const character of receipt.tain.slice(5, 15)) {
|
|
386
|
+
tainTimestampMs = (tainTimestampMs << 5n) | BigInt(alphabet.indexOf(character));
|
|
387
|
+
}
|
|
388
|
+
if (tainTimestampMs !== BigInt(witnessedMs)) {
|
|
389
|
+
throw new Error("witness receipt tain does not match witnessed_at_utc");
|
|
390
|
+
}
|
|
391
|
+
const statementCreatedMs = parseUtc(receipt.statement_created_at_utc, "statement_created_at_utc");
|
|
392
|
+
if (requestReceivedMs > witnessedMs || witnessedMs > statementCreatedMs) {
|
|
393
|
+
throw new Error("witness receipt timestamps are out of order");
|
|
394
|
+
}
|
|
395
|
+
requireIntegerRelationship(statementCreatedMs - requestReceivedMs, receipt.server_processing_duration_ms, "server_processing_duration_ms");
|
|
396
|
+
requireIntegerRelationship(statementCreatedMs - witnessedMs, receipt.post_witness_processing_duration_ms, "post_witness_processing_duration_ms");
|
|
397
|
+
if (receipt.unix_time_milliseconds !== witnessedMs) {
|
|
398
|
+
throw new Error("unix_time_milliseconds signed relationship is invalid");
|
|
399
|
+
}
|
|
400
|
+
if (!Number.isSafeInteger(receipt.clock_accuracy_radius_ms) ||
|
|
401
|
+
receipt.clock_accuracy_radius_ms < 0) {
|
|
402
|
+
throw new Error("clock_accuracy_radius_ms must be a non-negative safe integer");
|
|
403
|
+
}
|
|
404
|
+
const maxRadiusMs = options.max_clock_accuracy_radius_ms ?? 60_000;
|
|
405
|
+
if (!Number.isSafeInteger(maxRadiusMs) || maxRadiusMs < 0) {
|
|
406
|
+
throw new Error("max_clock_accuracy_radius_ms must be a non-negative safe integer");
|
|
407
|
+
}
|
|
408
|
+
if (receipt.clock_accuracy_radius_ms > maxRadiusMs) {
|
|
409
|
+
throw new Error("witness clock accuracy exceeds local policy");
|
|
410
|
+
}
|
|
411
|
+
const earliest = new Date(witnessedMs - receipt.clock_accuracy_radius_ms).toISOString();
|
|
412
|
+
const latest = new Date(witnessedMs + receipt.clock_accuracy_radius_ms).toISOString();
|
|
413
|
+
if (!isRecord(receipt.witness_window_utc)) {
|
|
414
|
+
throw new Error("witness_window_utc is missing");
|
|
415
|
+
}
|
|
416
|
+
requireExactKeys(receipt.witness_window_utc, ["earliest", "latest"], "witness_window_utc");
|
|
417
|
+
if (receipt.witness_window_utc?.earliest !== earliest ||
|
|
418
|
+
receipt.witness_window_utc?.latest !== latest) {
|
|
419
|
+
throw new Error("witness_window_utc signed relationship is invalid");
|
|
420
|
+
}
|
|
421
|
+
if (!isRecord(receipt.commitment))
|
|
422
|
+
throw new Error("commitment is missing");
|
|
423
|
+
requireExactKeys(receipt.commitment, ["payload_digest", "nonce", "previous_attestation_digest"], "commitment");
|
|
424
|
+
requireSha256Digest(receipt.commitment.payload_digest, "payload_digest");
|
|
425
|
+
requireNonce(receipt.commitment.nonce);
|
|
426
|
+
if (receipt.commitment.previous_attestation_digest !== null) {
|
|
427
|
+
requireSha256Digest(receipt.commitment.previous_attestation_digest, "previous_attestation_digest");
|
|
428
|
+
}
|
|
429
|
+
const scope = receipt.evidence_scope;
|
|
430
|
+
const expectedScope = {
|
|
431
|
+
type: "payload_commitment_witness",
|
|
432
|
+
payload_disclosed: false,
|
|
433
|
+
caller_identity_proven: false,
|
|
434
|
+
recipient_delivery_proven: false,
|
|
435
|
+
action_execution_proven: false,
|
|
436
|
+
nonce_uniqueness_enforced: false,
|
|
437
|
+
replay_prevented: false,
|
|
438
|
+
authorization_granted: false,
|
|
439
|
+
external_atomic_clock_alignment_proven: false,
|
|
440
|
+
clock_accuracy_independently_verified: false,
|
|
441
|
+
payer_authorization_bound_to_commitment: false,
|
|
442
|
+
};
|
|
443
|
+
if (canonicalJson(scope) !== canonicalJson(expectedScope)) {
|
|
444
|
+
throw new Error("witness evidence scope is invalid");
|
|
445
|
+
}
|
|
446
|
+
requireNonce(options.expected_nonce);
|
|
447
|
+
if (receipt.commitment.nonce !== options.expected_nonce) {
|
|
448
|
+
throw new Error("receipt nonce does not match the expected request nonce");
|
|
449
|
+
}
|
|
450
|
+
const hasPayload = options.expected_payload !== undefined;
|
|
451
|
+
const hasDigest = options.expected_payload_digest !== undefined;
|
|
452
|
+
if (hasPayload === hasDigest) {
|
|
453
|
+
throw new Error("provide exactly one expected_payload or expected_payload_digest");
|
|
454
|
+
}
|
|
455
|
+
const expectedPayloadDigest = hasPayload
|
|
456
|
+
? await sha256Base64Url(options.expected_payload)
|
|
457
|
+
: options.expected_payload_digest;
|
|
458
|
+
if (!/^[A-Za-z0-9_-]{43}$/.test(expectedPayloadDigest)) {
|
|
459
|
+
throw new Error("expected_payload_digest must be an unpadded base64url SHA-256 digest");
|
|
460
|
+
}
|
|
461
|
+
if (receipt.commitment.payload_digest.value !== expectedPayloadDigest) {
|
|
462
|
+
throw new Error("receipt payload digest does not match the expected payload");
|
|
463
|
+
}
|
|
464
|
+
let previousAttestationDigestMatched = false;
|
|
465
|
+
if (verifyPredecessor &&
|
|
466
|
+
receipt.commitment.previous_attestation_digest !== null) {
|
|
467
|
+
if (options.previous_receipt === undefined) {
|
|
468
|
+
throw new Error("previous receipt is required to verify the claimed chain");
|
|
469
|
+
}
|
|
470
|
+
try {
|
|
471
|
+
await verifyPopcornWitnessEvidenceInternal(options.previous_receipt.response, options.previous_receipt.jwks, options.previous_receipt.verification, seenAttestations);
|
|
472
|
+
}
|
|
473
|
+
catch (error) {
|
|
474
|
+
const message = error instanceof Error ? error.message : "verification failed";
|
|
475
|
+
throw new Error(`previous receipt verification failed: ${message}`);
|
|
476
|
+
}
|
|
477
|
+
const expectedPreviousDigest = await digestWitnessSignedPayload(options.previous_receipt.response.witness_attestation.compact_jws);
|
|
478
|
+
if (receipt.commitment.previous_attestation_digest.value !== expectedPreviousDigest) {
|
|
479
|
+
throw new Error("previous signed payload digest does not match the claimed chain");
|
|
480
|
+
}
|
|
481
|
+
previousAttestationDigestMatched = true;
|
|
482
|
+
}
|
|
483
|
+
else if (verifyPredecessor &&
|
|
484
|
+
options.previous_receipt !== undefined) {
|
|
485
|
+
throw new Error("receipt does not contain a previous attestation commitment");
|
|
486
|
+
}
|
|
487
|
+
return {
|
|
488
|
+
signature_verified: true,
|
|
489
|
+
key_id: header.kid,
|
|
490
|
+
witness_receipt: receipt,
|
|
491
|
+
payload_digest_verified: true,
|
|
492
|
+
nonce_verified: true,
|
|
493
|
+
previous_attestation_digest_matched: previousAttestationDigestMatched,
|
|
494
|
+
replay_key: `${receipt.protocol_id}:${receipt.node_id}:${receipt.commitment.nonce}`,
|
|
495
|
+
payment_replay_key: `x402:${receipt.payment_identifier}`,
|
|
496
|
+
witness_window_utc: { earliest, latest },
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
export async function verifyPopcornWitnessChain(entries) {
|
|
500
|
+
if (!Array.isArray(entries) || entries.length === 0) {
|
|
501
|
+
throw new Error("witness chain must contain at least one receipt");
|
|
502
|
+
}
|
|
503
|
+
const seenAttestations = new Set();
|
|
504
|
+
const verifiedEntries = [];
|
|
505
|
+
let previousSignedPayloadDigest = null;
|
|
506
|
+
for (const [index, entry] of entries.entries()) {
|
|
507
|
+
const rawEntry = entry;
|
|
508
|
+
if (!isRecord(rawEntry) || !isRecord(rawEntry.verification)) {
|
|
509
|
+
throw new Error(`witness chain entry ${index} is invalid`);
|
|
510
|
+
}
|
|
511
|
+
if (Object.hasOwn(rawEntry.verification, "previous_receipt")) {
|
|
512
|
+
throw new Error(`witness chain entry ${index} must not contain recursive previous_receipt input`);
|
|
513
|
+
}
|
|
514
|
+
let verified;
|
|
515
|
+
try {
|
|
516
|
+
verified = await verifyPopcornWitnessEvidenceInternal(entry.response, entry.jwks, entry.verification, seenAttestations, false);
|
|
517
|
+
}
|
|
518
|
+
catch (error) {
|
|
519
|
+
const message = error instanceof Error ? error.message : "verification failed";
|
|
520
|
+
throw new Error(`witness chain entry ${index} verification failed: ${message}`);
|
|
521
|
+
}
|
|
522
|
+
const claimedPreviousDigest = verified.witness_receipt.commitment.previous_attestation_digest;
|
|
523
|
+
if (index === 0) {
|
|
524
|
+
if (claimedPreviousDigest !== null) {
|
|
525
|
+
throw new Error("witness chain entry 0 must start with previous_attestation_digest null");
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
if (claimedPreviousDigest === null) {
|
|
530
|
+
throw new Error(`witness chain entry ${index} is missing its predecessor digest`);
|
|
531
|
+
}
|
|
532
|
+
if (claimedPreviousDigest.value !== previousSignedPayloadDigest) {
|
|
533
|
+
throw new Error(`witness chain entry ${index} predecessor digest does not match entry ${index - 1}`);
|
|
534
|
+
}
|
|
535
|
+
verified = {
|
|
536
|
+
...verified,
|
|
537
|
+
previous_attestation_digest_matched: true,
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
const signedPayloadDigest = await digestWitnessSignedPayload(entry.response.witness_attestation.compact_jws);
|
|
541
|
+
verifiedEntries.push({
|
|
542
|
+
index,
|
|
543
|
+
signed_payload_digest: signedPayloadDigest,
|
|
544
|
+
verified,
|
|
545
|
+
});
|
|
546
|
+
previousSignedPayloadDigest = signedPayloadDigest;
|
|
547
|
+
}
|
|
548
|
+
return {
|
|
549
|
+
chain_length: verifiedEntries.length,
|
|
550
|
+
head_signed_payload_digest: previousSignedPayloadDigest,
|
|
551
|
+
entries: verifiedEntries,
|
|
552
|
+
};
|
|
553
|
+
}
|
|
554
|
+
//# sourceMappingURL=v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.js","sourceRoot":"","sources":["../../../../../../verify/typescript/src/v2.ts"],"names":[],"mappings":"AA6MA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,SAAS,eAAe,CAAC,KAAa;IACpC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAChD,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IACjD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,8BAA8B,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,gBAAgB,CACvB,KAA8B,EAC9B,QAAkB,EAClB,KAAa;IAEb,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7C,MAAM,YAAY,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,IACE,UAAU,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM;QACzC,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,YAAY,CAAC,KAAK,CAAC,CAAC,EAC5D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,yCAAyC,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAC3E,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;aAC1B,IAAI,EAAE;aACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;aACnE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IAClB,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,eAAe,CAAC,KAAkB;IACzC,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,KAA0B;IACvD,MAAM,KAAK,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACxE,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;IAChE,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjB,OAAO,eAAe,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,UAAkB;IAElB,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,YAAY,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,eAAe,CAAC,YAAY,CAAC,CAAC;AACvC,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAc,EAAE,KAAa;IACxD,IACE,CAAC,QAAQ,CAAC,KAAK,CAAC;QAChB,KAAK,CAAC,SAAS,KAAK,SAAS;QAC7B,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC/B,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EACxC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,+CAA+C,CAAC,CAAC;IAC3E,CAAC;IACD,gBAAgB,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;AACzD,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACpE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IACjD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,uCAAuC,CAAC,CAAC;IACnE,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,oCAAoC,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,aAAa,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,gBAAsD,EACtD,kBAAsD;IAEtD,MAAM,iBAAiB,GAAG,QAAQ,CAChC,gBAAgB,CAAC,QAAQ,EACzB,6BAA6B,CAC9B,CAAC;IACF,MAAM,eAAe,GAAG,QAAQ,CAC9B,gBAAgB,CAAC,MAAM,EACvB,2BAA2B,CAC5B,CAAC;IACF,IAAI,iBAAiB,GAAG,eAAe,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CACtB,kBAAkB,CAAC,QAAQ,EAC3B,+BAA+B,CAChC,CAAC;IACF,MAAM,QAAQ,GAAG,QAAQ,CACvB,kBAAkB,CAAC,SAAS,EAC5B,gCAAgC,CACjC,CAAC;IACF,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,IAAI,QAA6C,CAAC;IAClD,IAAI,MAAyC,CAAC;IAC9C,IAAI,eAAe,GAAG,OAAO,EAAE,CAAC;QAC9B,QAAQ,GAAG,MAAM,CAAC;QAClB,MAAM,GAAG,iDAAiD,CAAC;IAC7D,CAAC;SAAM,IAAI,iBAAiB,GAAG,QAAQ,EAAE,CAAC;QACxC,QAAQ,GAAG,MAAM,CAAC;QAClB,MAAM,GAAG,gDAAgD,CAAC;IAC5D,CAAC;SAAM,IAAI,iBAAiB,IAAI,OAAO,IAAI,eAAe,IAAI,QAAQ,EAAE,CAAC;QACvE,QAAQ,GAAG,mBAAmB,CAAC;QAC/B,MAAM,GAAG,iDAAiD,CAAC;IAC7D,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,SAAS,CAAC;QACrB,MAAM,GAAG,gDAAgD,CAAC;IAC5D,CAAC;IAED,OAAO;QACL,QAAQ;QACR,qBAAqB,EAAE,KAAK;QAC5B,MAAM;QACN,kBAAkB,EAAE;YAClB,QAAQ,EAAE,gBAAgB,CAAC,QAAQ;YACnC,MAAM,EAAE,gBAAgB,CAAC,MAAM;SAChC;QACD,oBAAoB,EAAE;YACpB,QAAQ,EAAE,kBAAkB,CAAC,QAAQ;YACrC,SAAS,EAAE,kBAAkB,CAAC,SAAS;SACxC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CACjC,MAAc,EACd,QAAgB,EAChB,KAAa;IAEb,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,QAAQ,GAAG,CAAC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC3E,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,iCAAiC,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED,SAAS,wBAAwB,CAC/B,OAAwB,EACxB,cAAsB;IAEtB,IAAI,OAAO,CAAC,OAAO,KAAK,cAAc;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,WAAW,KAAK,aAAa;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACrF,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,iBAAiB,GAAG,QAAQ,CAChC,OAAO,CAAC,uBAAuB,EAC/B,yBAAyB,CAC1B,CAAC;IACF,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,QAAQ,CAC5B,OAAO,CAAC,kBAAkB,EAC1B,oBAAoB,CACrB,CAAC;IACF,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;IAE1E,0BAA0B,CACxB,aAAa,GAAG,iBAAiB,EACjC,OAAO,CAAC,6BAA6B,EACrC,+BAA+B,CAChC,CAAC;IACF,0BAA0B,CACxB,aAAa,GAAG,UAAU,EAC1B,OAAO,CAAC,kCAAkC,EAC1C,oCAAoC,CACrC,CAAC;IACF,0BAA0B,CACxB,YAAY,GAAG,aAAa,EAC5B,OAAO,CAAC,0BAA0B,EAClC,4BAA4B,CAC7B,CAAC;IACF,0BAA0B,CACxB,YAAY,GAAG,UAAU,EACzB,OAAO,CAAC,mBAAmB,EAC3B,qBAAqB,CACtB,CAAC;IACF,IAAI,OAAO,CAAC,sBAAsB,KAAK,UAAU,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,IACE,OAAO,CAAC,cAAc,EAAE,IAAI,KAAK,0BAA0B;QAC3D,OAAO,CAAC,cAAc,CAAC,YAAY,KAAK,KAAK;QAC7C,OAAO,CAAC,cAAc,CAAC,UAAU,KAAK,KAAK;QAC3C,OAAO,CAAC,cAAc,CAAC,qBAAqB,KAAK,KAAK,EACtD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,QAAyB,EACzB,IAAmB,EACnB,SAA+B,EAC/B,OAAO,GAA6E,EAAE;IAEtF,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC;IAC1D,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC;IAChE,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAChE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,OAAO,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;QAClF,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IACE,QAAQ,CAAC,oBAAoB,CAAC,SAAS,KAAK,SAAS;QACrD,QAAQ,CAAC,oBAAoB,CAAC,SAAS,KAAK,OAAO,EACnD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,IACE,QAAQ,CAAC,oBAAoB,CAAC,MAAM,KAAK,SAAS;QAClD,QAAQ,CAAC,oBAAoB,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,EACnD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1E,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,CAAC,GAAG,sBAAsB,CAAC,CAAC;IACnE,IACE,GAAG,CAAC,GAAG,KAAK,IAAI;QAChB,GAAG,CAAC,GAAG,KAAK,OAAO;QACnB,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO,CAAC;QAC9C,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,CAAC,EAC5C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;IACpD,IAAI,SAAS,CAAC,UAAU,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACrF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAC7C,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAC;IACF,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAClD,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,SAAS,EACT,SAAS,EACT,OAAO,CAAC,MAAM,CAAC,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC,CACrD,CAAC;IACF,IAAI,CAAC,iBAAiB;QAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAEvF,MAAM,aAAa,GAAG,aAAa,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IACtE,IAAI,aAAa,CAAC,aAAa,CAAC,KAAK,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,OAAO,GAAG,aAAgC,CAAC;IACjD,MAAM,EAAE,aAAa,EAAE,GAAG,wBAAwB,CAChD,OAAO,EACP,OAAO,CAAC,gBAAgB,IAAI,cAAc,CAC3C,CAAC;IAEF,aAAa,CAAC,SAAS,CAAC,+BAA+B,EAAE,oBAAoB,CAAC,CAAC;IAC/E,aAAa,CAAC,SAAS,CAAC,kCAAkC,EAAE,uBAAuB,CAAC,CAAC;IACrF,MAAM,mBAAmB,GACvB,SAAS,CAAC,qBAAqB,IAAI,SAAS,CAAC,kCAAkC,CAAC;IAClF,aAAa,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;IACpD,IACE,SAAS,CAAC,kCAAkC;QAC1C,SAAS,CAAC,+BAA+B;QAC3C,mBAAmB,GAAG,SAAS,CAAC,kCAAkC,EAClE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,KAAK,GACT,SAAS,CAAC,kCAAkC;QAC5C,SAAS,CAAC,+BAA+B,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC5B,CAAC,EACD,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAC/D,CAAC;IACF,MAAM,oBAAoB,GAAG,IAAI,CAAC,GAAG,CACnC,CAAC,EACD,OAAO,CAAC,0BAA0B,GAAG,aAAa,CACnD,CAAC;IACF,MAAM,qBAAqB,GACzB,mBAAmB,GAAG,SAAS,CAAC,kCAAkC,CAAC;IACrE,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,GAAG,qBAAqB,CAAC,CAAC;IACjF,MAAM,aAAa,GAAG,aAAa,GAAG,qBAAqB,CAAC;IAC5D,MAAM,WAAW,GAAG,aAAa,GAAG,aAAa,CAAC;IAElD,MAAM,MAAM,GAA6B;QACvC,kBAAkB,EAAE,IAAI;QACxB,MAAM,EAAE,MAAM,CAAC,GAAG;QAClB,gBAAgB,EAAE,OAAO;QACzB,mBAAmB,EAAE,KAAK;QAC1B,sBAAsB,EAAE,aAAa;QACrC,gCAAgC,EAAE,oBAAoB;QACtD,yBAAyB,EAAE,cAAc;QACzC,yBAAyB,EAAE;YACzB,QAAQ,EAAE,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE;YAC/C,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE;SAC5C;KACF,CAAC;IAEF,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACpF,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QACvF,IAAI,OAAO,IAAI,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAChF,MAAM,QAAQ,GACZ,cAAc,GAAG,CAAC,IAAI,aAAa,IAAI,OAAO,IAAI,WAAW,GAAG,QAAQ,CAAC;QAC3E,MAAM,CAAC,gBAAgB,GAAG;YACxB,QAAQ;YACR,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,6BAA6B;YACvE,MAAM,EAAE,QAAQ;gBACd,CAAC,CAAC,2CAA2C;gBAC7C,CAAC,CAAC,cAAc,KAAK,CAAC;oBACpB,CAAC,CAAC,2BAA2B;oBAC7B,CAAC,CAAC,+CAA+C;SACtD,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,QAAgC,EAChC,IAAmB,EACnB,OAAmC;IAEnC,OAAO,oCAAoC,CACzC,QAAQ,EACR,IAAI,EACJ,OAAO,EACP,IAAI,GAAG,EAAU,CAClB,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,oCAAoC,CACjD,QAAgC,EAChC,IAAmB,EACnB,OAAmC,EACnC,gBAA6B,EAC7B,iBAAiB,GAAG,IAAI;IAExB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAC/D,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,yEAAyE;IACzE,yDAAyD;IACzD,oEAAoE;IACpE,gBAAgB,CACd,QAAQ,CAAC,mBAAmB,EAC5B,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,CAAC,EAC3D,qBAAqB,CACtB,CAAC;IAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,mBAAmB,CAAC,WAAW,CAAC;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3E,IAAI,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC;IAChE,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC;IAChE,IACE,CAAC,QAAQ,CAAC,MAAM,CAAC;QACjB,MAAM,CAAC,GAAG,KAAK,OAAO;QACtB,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ;QAC9B,MAAM,CAAC,GAAG,KAAK,qBAAqB,EACpC,CAAC;QACD,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,mBAAmB,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,QAAQ,CAAC,mBAAmB,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,QAAQ,CAAC,mBAAmB,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,QAAQ,CAAC,mBAAmB,CAAC,OAAO,KAAK,gCAAgC,EAAE,CAAC;QAC9E,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,QAAQ,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,KAAK,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1E,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,MAAM,CAAC,GAAG,sBAAsB,CAAC,CAAC;IACnE,IACE,GAAG,CAAC,GAAG,KAAK,IAAI;QAChB,GAAG,CAAC,GAAG,KAAK,OAAO;QACnB,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK,OAAO,CAAC;QAC9C,CAAC,GAAG,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,KAAK,KAAK,CAAC,EAC5C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAC;IACpD,IAAI,SAAS,CAAC,UAAU,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACrF,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAC7C,KAAK,EACL,GAAG,EACH,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,EACtC,KAAK,EACL,CAAC,QAAQ,CAAC,CACX,CAAC;IACF,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAClD,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,EAClC,SAAS,EACT,SAAS,EACT,OAAO,CAAC,MAAM,CAAC,GAAG,aAAa,IAAI,cAAc,EAAE,CAAC,CACrD,CAAC;IACF,IAAI,CAAC,iBAAiB;QAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAEtF,MAAM,aAAa,GAAG,aAAa,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IACtE,IAAI,aAAa,CAAC,aAAa,CAAC,KAAK,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,OAAO,GAAG,aAA+B,CAAC;IAChD,gBAAgB,CACd,OAA6C,EAC7C;QACE,YAAY;QACZ,MAAM;QACN,SAAS;QACT,aAAa;QACb,yBAAyB;QACzB,kBAAkB;QAClB,0BAA0B;QAC1B,wBAAwB;QACxB,0BAA0B;QAC1B,oBAAoB;QACpB,+BAA+B;QAC/B,qCAAqC;QACrC,YAAY;QACZ,oBAAoB;QACpB,qBAAqB;QACrB,gBAAgB;QAChB,gBAAgB;QAChB,mBAAmB;QACnB,uBAAuB;QACvB,0BAA0B;QAC1B,sBAAsB;KACvB,EACD,iBAAiB,CAClB,CAAC;IACF,IAAI,OAAO,CAAC,OAAO,KAAK,CAAC,OAAO,CAAC,gBAAgB,IAAI,cAAc,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,CAAC,WAAW,KAAK,qBAAqB,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC5C,CAAC;IACD,IACE,OAAO,OAAO,CAAC,UAAU,KAAK,QAAQ;QACtC,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QAC9C,OAAO,OAAO,CAAC,kBAAkB,KAAK,QAAQ;QAC9C,OAAO,CAAC,kBAAkB,CAAC,MAAM,KAAK,CAAC;QACvC,CAAC,CACC,OAAO,CAAC,mBAAmB,KAAK,IAAI;YACpC,OAAO,OAAO,CAAC,mBAAmB,KAAK,QAAQ,CAChD,EACD,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5F,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,KAAK,sBAAsB;QACjD,CAAC,OAAO,CAAC,iBAAiB,KAAK,aAAa,IAAI,OAAO,CAAC,iBAAiB,KAAK,aAAa,CAAC;QAC5F,OAAO,CAAC,qBAAqB,KAAK,wCAAwC,OAAO,CAAC,IAAI,EAAE;QACxF,OAAO,CAAC,wBAAwB,KAAK,+CAA+C,EAAE,CAAC;QACzF,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,mBAAmB,CAAC,OAAO,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,CAAC;IAC1E,+EAA+E;IAE/E,MAAM,iBAAiB,GAAG,QAAQ,CAChC,OAAO,CAAC,uBAAuB,EAC/B,yBAAyB,CAC1B,CAAC;IACF,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,kCAAkC,CAAC;IACpD,IAAI,eAAe,GAAG,EAAE,CAAC;IACzB,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;QAClD,eAAe,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAClF,CAAC;IACD,IAAI,eAAe,KAAK,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;IAC1E,CAAC;IACD,MAAM,kBAAkB,GAAG,QAAQ,CACjC,OAAO,CAAC,wBAAwB,EAChC,0BAA0B,CAC3B,CAAC;IACF,IAAI,iBAAiB,GAAG,WAAW,IAAI,WAAW,GAAG,kBAAkB,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,0BAA0B,CACxB,kBAAkB,GAAG,iBAAiB,EACtC,OAAO,CAAC,6BAA6B,EACrC,+BAA+B,CAChC,CAAC;IACF,0BAA0B,CACxB,kBAAkB,GAAG,WAAW,EAChC,OAAO,CAAC,mCAAmC,EAC3C,qCAAqC,CACtC,CAAC;IACF,IAAI,OAAO,CAAC,sBAAsB,KAAK,WAAW,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAC3E,CAAC;IACD,IACE,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,wBAAwB,CAAC;QACvD,OAAO,CAAC,wBAAwB,GAAG,CAAC,EACpC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,WAAW,GAAG,OAAO,CAAC,4BAA4B,IAAI,MAAM,CAAC;IACnE,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,OAAO,CAAC,wBAAwB,GAAG,WAAW,EAAE,CAAC;QACnD,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC,WAAW,EAAE,CAAC;IACxF,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC,WAAW,EAAE,CAAC;IACtF,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC1C,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IACD,gBAAgB,CACd,OAAO,CAAC,kBAAkB,EAC1B,CAAC,UAAU,EAAE,QAAQ,CAAC,EACtB,oBAAoB,CACrB,CAAC;IACF,IACE,OAAO,CAAC,kBAAkB,EAAE,QAAQ,KAAK,QAAQ;QACjD,OAAO,CAAC,kBAAkB,EAAE,MAAM,KAAK,MAAM,EAC7C,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC5E,gBAAgB,CACd,OAAO,CAAC,UAAU,EAClB,CAAC,gBAAgB,EAAE,OAAO,EAAE,6BAA6B,CAAC,EAC1D,YAAY,CACb,CAAC;IACF,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;IACzE,YAAY,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,UAAU,CAAC,2BAA2B,KAAK,IAAI,EAAE,CAAC;QAC5D,mBAAmB,CACjB,OAAO,CAAC,UAAU,CAAC,2BAA2B,EAC9C,6BAA6B,CAC9B,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,cAAc,CAAC;IACrC,MAAM,aAAa,GAAG;QACpB,IAAI,EAAE,4BAA4B;QAClC,iBAAiB,EAAE,KAAK;QACxB,sBAAsB,EAAE,KAAK;QAC7B,yBAAyB,EAAE,KAAK;QAChC,uBAAuB,EAAE,KAAK;QAC9B,yBAAyB,EAAE,KAAK;QAChC,gBAAgB,EAAE,KAAK;QACvB,qBAAqB,EAAE,KAAK;QAC5B,sCAAsC,EAAE,KAAK;QAC7C,qCAAqC,EAAE,KAAK;QAC5C,uCAAuC,EAAE,KAAK;KAC/C,CAAC;IACF,IAAI,aAAa,CAAC,KAAK,CAAC,KAAK,aAAa,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACvD,CAAC;IAED,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IACrC,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,KAAK,OAAO,CAAC,cAAc,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC7E,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,gBAAgB,KAAK,SAAS,CAAC;IAC1D,MAAM,SAAS,GAAG,OAAO,CAAC,uBAAuB,KAAK,SAAS,CAAC;IAChE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IACD,MAAM,qBAAqB,GAAG,UAAU;QACtC,CAAC,CAAC,MAAM,eAAe,CAAC,OAAO,CAAC,gBAAuC,CAAC;QACxE,CAAC,CAAE,OAAO,CAAC,uBAAkC,CAAC;IAChD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,KAAK,qBAAqB,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,gCAAgC,GAAG,KAAK,CAAC;IAC7C,IACE,iBAAiB;QACjB,OAAO,CAAC,UAAU,CAAC,2BAA2B,KAAK,IAAI,EACvD,CAAC;QACD,IAAI,OAAO,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;YAC3C,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,CAAC;YACH,MAAM,oCAAoC,CACxC,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EACjC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAC7B,OAAO,CAAC,gBAAgB,CAAC,YAAY,EACrC,gBAAgB,CACjB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,yCAAyC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,MAAM,sBAAsB,GAAG,MAAM,0BAA0B,CAC7D,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,mBAAmB,CAAC,WAAW,CAClE,CAAC;QACF,IACE,OAAO,CAAC,UAAU,CAAC,2BAA2B,CAAC,KAAK,KAAK,sBAAsB,EAC/E,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QACD,gCAAgC,GAAG,IAAI,CAAC;IAC1C,CAAC;SAAM,IACL,iBAAiB;QACjB,OAAO,CAAC,gBAAgB,KAAK,SAAS,EACtC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IAChF,CAAC;IAED,OAAO;QACL,kBAAkB,EAAE,IAAI;QACxB,MAAM,EAAE,MAAM,CAAC,GAAG;QAClB,eAAe,EAAE,OAAO;QACxB,uBAAuB,EAAE,IAAI;QAC7B,cAAc,EAAE,IAAI;QACpB,mCAAmC,EAAE,gCAAgC;QACrE,UAAU,EAAE,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE;QACnF,kBAAkB,EAAE,QAAQ,OAAO,CAAC,kBAAkB,EAAE;QACxD,kBAAkB,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;KACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,OAAqC;IAErC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC3C,MAAM,eAAe,GAAgC,EAAE,CAAC;IACxD,IAAI,2BAA2B,GAAkB,IAAI,CAAC;IAEtD,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAY,KAAK,CAAC;QAChC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,aAAa,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CACb,uBAAuB,KAAK,oDAAoD,CACjF,CAAC;QACJ,CAAC;QAED,IAAI,QAAiC,CAAC;QACtC,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,oCAAoC,CACnD,KAAK,CAAC,QAAQ,EACd,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,YAAY,EAClB,gBAAgB,EAChB,KAAK,CACN,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,qBAAqB,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,uBAAuB,KAAK,yBAAyB,OAAO,EAAE,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,qBAAqB,GACzB,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,2BAA2B,CAAC;QAClE,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,qBAAqB,KAAK,IAAI,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CACb,uBAAuB,KAAK,oCAAoC,CACjE,CAAC;YACJ,CAAC;YACD,IAAI,qBAAqB,CAAC,KAAK,KAAK,2BAA2B,EAAE,CAAC;gBAChE,MAAM,IAAI,KAAK,CACb,uBAAuB,KAAK,4CAA4C,KAAK,GAAG,CAAC,EAAE,CACpF,CAAC;YACJ,CAAC;YACD,QAAQ,GAAG;gBACT,GAAG,QAAQ;gBACX,mCAAmC,EAAE,IAAI;aAC1C,CAAC;QACJ,CAAC;QAED,MAAM,mBAAmB,GAAG,MAAM,0BAA0B,CAC1D,KAAK,CAAC,QAAQ,CAAC,mBAAmB,CAAC,WAAW,CAC/C,CAAC;QACF,eAAe,CAAC,IAAI,CAAC;YACnB,KAAK;YACL,qBAAqB,EAAE,mBAAmB;YAC1C,QAAQ;SACT,CAAC,CAAC;QACH,2BAA2B,GAAG,mBAAmB,CAAC;IACpD,CAAC;IAED,OAAO;QACL,YAAY,EAAE,eAAe,CAAC,MAAM;QACpC,0BAA0B,EAAE,2BAAqC;QACjE,OAAO,EAAE,eAAe;KACzB,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@violetclaire/popcorn-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"mcpName": "io.github.violetclaire/popcorn-mcp",
|
|
5
5
|
"description": "Trusted timestamp and proof-of-existence evidence for authorization expiry, with a free offline sample and an RFC 3161 / OpenTimestamps comparison.",
|
|
6
6
|
"type": "module",
|
|
@@ -64,14 +64,14 @@
|
|
|
64
64
|
"homepage": "https://767-2676.com/agents",
|
|
65
65
|
"bugs": "https://github.com/violetclaire/popcorn-temporal-anchor/issues",
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@modelcontextprotocol/server": "2.
|
|
67
|
+
"@modelcontextprotocol/server": "2.3.1",
|
|
68
68
|
"@x402/evm": "2.24.0",
|
|
69
69
|
"@x402/fetch": "2.24.0",
|
|
70
70
|
"viem": "2.56.3",
|
|
71
71
|
"zod": "4.5.4"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
|
-
"@modelcontextprotocol/client": "2.
|
|
74
|
+
"@modelcontextprotocol/client": "2.3.1",
|
|
75
75
|
"@types/node": "26.4.0",
|
|
76
76
|
"tsx": "4.23.13",
|
|
77
77
|
"typescript": "7.0.2"
|