@trylimbo/sdk-verifier-wasm 0.2.25-canary.37 → 0.2.25
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/gen/wasm/trylimbo_sdk_verifier.d.ts +317 -284
- package/gen/wasm/trylimbo_sdk_verifier.js +288 -223
- package/gen/wasm/trylimbo_sdk_verifier_bg.wasm +0 -0
- package/gen/wasm/trylimbo_sdk_verifier_bg.wasm.d.ts +19 -13
- package/gen/wasm/worker-thread.js +301 -194
- package/gen/wasm/worker.d.ts +306 -309
- package/package.json +1 -1
package/gen/wasm/worker.d.ts
CHANGED
|
@@ -163,61 +163,141 @@ interface RangeSource {
|
|
|
163
163
|
readAt: (offset: number, length: number) => Uint8Array;
|
|
164
164
|
}
|
|
165
165
|
/**
|
|
166
|
-
* A
|
|
166
|
+
* A C2PA soft binding: an algorithm id (from the C2PA soft-binding algorithm
|
|
167
|
+
* list, e.g. `io.iscc.v0`) plus its algorithm-specific value (the `ISCC:…` code,
|
|
168
|
+
* a watermark token, …). The signer embeds it as a `c2pa.soft-binding` assertion
|
|
169
|
+
* and indexes it, so a transcoded copy whose exact content hash no longer
|
|
170
|
+
* matches still recovers the manifest from the repository.
|
|
167
171
|
*/
|
|
168
|
-
interface
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
interface SoftBinding {
|
|
173
|
+
/**
|
|
174
|
+
* C2PA soft-binding algorithm id, e.g. `io.iscc.v0`.
|
|
175
|
+
*/
|
|
176
|
+
alg: string;
|
|
177
|
+
/**
|
|
178
|
+
* Algorithm-specific binding value: the canonical string the algorithm
|
|
179
|
+
* produces (an `ISCC:…` code, a watermark token). Its UTF-8 bytes are what
|
|
180
|
+
* the repository lookup base64-encodes.
|
|
181
|
+
*/
|
|
182
|
+
value: string;
|
|
177
183
|
}
|
|
178
184
|
/**
|
|
179
|
-
* A
|
|
180
|
-
*
|
|
185
|
+
* A binder spelled as data, so it crosses into a worker as well as the direct import: the
|
|
186
|
+
* SDK\'s own two. A browser has no host binder: a detector runs repository-side.
|
|
181
187
|
*/
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
188
|
+
type BinderSpec = {
|
|
189
|
+
kind: "iscc";
|
|
190
|
+
} | {
|
|
191
|
+
kind: "held";
|
|
192
|
+
binding: SoftBinding;
|
|
193
|
+
};
|
|
186
194
|
/**
|
|
187
195
|
* A session signing key from the init manifest\'s roster (spec §19.4.4).
|
|
188
196
|
*/
|
|
189
|
-
interface
|
|
197
|
+
interface SessionKeySummary {
|
|
190
198
|
/**
|
|
191
199
|
* Identifier of the session signing key.
|
|
192
200
|
*/
|
|
193
|
-
|
|
201
|
+
keyId: Uint8Array;
|
|
194
202
|
/**
|
|
195
203
|
* The session key\'s public half (SEC1-encoded bytes).
|
|
196
204
|
*/
|
|
197
205
|
publicKey: Uint8Array;
|
|
198
206
|
}
|
|
199
207
|
/**
|
|
200
|
-
*
|
|
208
|
+
* C2PA validation state of a manifest (spec §14.3).
|
|
209
|
+
*/
|
|
210
|
+
type ValidationState = "Invalid" | "Valid" | "Trusted";
|
|
211
|
+
/**
|
|
212
|
+
* Construction options for [`AssetVerifier::new`] (and the `AssetVerifier.create` JS
|
|
213
|
+
* binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
|
|
214
|
+
*
|
|
215
|
+
* One definition, all lanes: `#[binding]` derives the shapes directly here:
|
|
216
|
+
* tsify (camelCase) on wasm, a `uniffi::Record` on the native `ffi` build, so there is no
|
|
217
|
+
* per-lane DTO copy. Off both lanes it is a plain struct.
|
|
201
218
|
*/
|
|
202
|
-
interface
|
|
219
|
+
interface AssetVerifierOptions {
|
|
203
220
|
/**
|
|
204
|
-
*
|
|
221
|
+
* The C2PA manifest repositories recovery asks, each a Soft Binding Resolution API declared
|
|
222
|
+
* for exactly the algorithms it may be asked for. Results merge by manifest, and a match\'s
|
|
223
|
+
* `endpoint` is fetched from only when it names one of these. Empty: no recovery can be
|
|
224
|
+
* asked of this verifier.
|
|
205
225
|
*/
|
|
206
|
-
|
|
226
|
+
repositories: Repository[];
|
|
207
227
|
/**
|
|
208
|
-
*
|
|
228
|
+
* PEM trust anchors for the manifest signers the caller trusts.
|
|
209
229
|
*/
|
|
210
|
-
|
|
230
|
+
trustAnchors: string[];
|
|
231
|
+
/**
|
|
232
|
+
* PEM trust anchors for the time-stamping authorities the caller trusts.
|
|
233
|
+
*/
|
|
234
|
+
tsaTrustAnchors: string[];
|
|
211
235
|
/**
|
|
212
|
-
*
|
|
236
|
+
* Also trust the bundled official C2PA anchors, manifest and TSA lists, beside the
|
|
237
|
+
* caller\'s. `false` trusts the caller\'s lists alone.
|
|
213
238
|
*/
|
|
214
|
-
|
|
215
|
-
|
|
239
|
+
trustC2paAnchors: boolean;
|
|
240
|
+
/**
|
|
241
|
+
* Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched
|
|
242
|
+
* exactly against the credential issuer. Empty trusts no issuer: every identity assertion
|
|
243
|
+
* then reports `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`,
|
|
244
|
+
* which leaves the manifest\'s own validity untouched.
|
|
245
|
+
*/
|
|
246
|
+
trustedIcaIssuers: string[];
|
|
216
247
|
}
|
|
217
248
|
/**
|
|
218
|
-
*
|
|
249
|
+
* Construction options for [`StreamVerifier::new`] (and the `StreamVerifier.create`
|
|
250
|
+
* JS binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
|
|
251
|
+
*
|
|
252
|
+
* `#[binding]` derives the wasm shape (`trustC2paAnchors` camelCase) and,
|
|
253
|
+
* with `ffi`, a `uniffi::Record` for the native `StreamVerifier.create` binding, so there
|
|
254
|
+
* is no per-lane DTO copy. Off both lanes it is a plain struct.
|
|
219
255
|
*/
|
|
220
|
-
|
|
256
|
+
interface StreamVerifierOptions {
|
|
257
|
+
/**
|
|
258
|
+
* PEM trust anchors for the manifest signers the caller trusts.
|
|
259
|
+
*/
|
|
260
|
+
trustAnchors: string[];
|
|
261
|
+
/**
|
|
262
|
+
* PEM trust anchors for the time-stamping authorities the caller trusts.
|
|
263
|
+
*/
|
|
264
|
+
tsaTrustAnchors: string[];
|
|
265
|
+
/**
|
|
266
|
+
* Also trust the bundled official C2PA anchors, manifest and TSA lists, beside the
|
|
267
|
+
* caller\'s. `false` trusts the caller\'s lists alone.
|
|
268
|
+
*/
|
|
269
|
+
trustC2paAnchors: boolean;
|
|
270
|
+
/**
|
|
271
|
+
* Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched
|
|
272
|
+
* exactly against the credential issuer. Empty trusts no issuer: an identity assertion
|
|
273
|
+
* on the init segment\'s manifest then reports `cawg.ica.untrusted_issuer` and withholds
|
|
274
|
+
* `cawg.ica.credential_valid`.
|
|
275
|
+
*/
|
|
276
|
+
trustedIcaIssuers: string[];
|
|
277
|
+
/**
|
|
278
|
+
* How far a segment\'s timestamp may sit from wall-clock before it is rejected as
|
|
279
|
+
* skewed, in seconds: the deployment\'s own encoder-clock allowance, stated rather than
|
|
280
|
+
* assumed.
|
|
281
|
+
*/
|
|
282
|
+
segmentSkewToleranceSecs: number;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Everything one `derive` needs beyond the asset: how its format is known. The same record
|
|
286
|
+
* the native lane\'s `DeriveOptions` is, spelled as data.
|
|
287
|
+
*/
|
|
288
|
+
interface DeriveOptions {
|
|
289
|
+
format: AssetFormat;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* How a call knows the asset\'s format: stated by the caller, or read from the leading bytes.
|
|
293
|
+
* Stated, never defaulted: sniffing is a choice made by name.
|
|
294
|
+
*/
|
|
295
|
+
type AssetFormat = {
|
|
296
|
+
kind: "sniff";
|
|
297
|
+
} | {
|
|
298
|
+
kind: "declared";
|
|
299
|
+
mediaType: string;
|
|
300
|
+
};
|
|
221
301
|
/**
|
|
222
302
|
* One C2PA manifest repository, as the Soft Binding Resolution API spec lets a client find it.
|
|
223
303
|
*/
|
|
@@ -226,8 +306,8 @@ type Repository = {
|
|
|
226
306
|
url: string;
|
|
227
307
|
algorithms: string[];
|
|
228
308
|
} | {
|
|
229
|
-
kind: "
|
|
230
|
-
|
|
309
|
+
kind: "listed";
|
|
310
|
+
algorithm: string;
|
|
231
311
|
};
|
|
232
312
|
/**
|
|
233
313
|
* One C2PA validation status entry (spec §15.3): the registered code, its kind, and the
|
|
@@ -251,7 +331,13 @@ interface ValidationCode {
|
|
|
251
331
|
*/
|
|
252
332
|
interface Credential {
|
|
253
333
|
/**
|
|
254
|
-
*
|
|
334
|
+
* The bytes behind every thumbnail the manifests reference, by that reference\'s
|
|
335
|
+
* `identifier`: each manifest\'s claim thumbnail and each ingredient\'s. The manifests state
|
|
336
|
+
* identifiers and no images, so this is what a chain draws from.
|
|
337
|
+
*/
|
|
338
|
+
thumbnails: Record<string, Uint8Array>;
|
|
339
|
+
/**
|
|
340
|
+
* Where this credential came from. See [`CredentialOrigin`].
|
|
255
341
|
*/
|
|
256
342
|
origin: CredentialOrigin;
|
|
257
343
|
manifest: import('@contentauth/c2pa-types').ManifestStore;
|
|
@@ -260,38 +346,17 @@ interface Credential {
|
|
|
260
346
|
*/
|
|
261
347
|
hardBinding: HardBinding;
|
|
262
348
|
/**
|
|
263
|
-
* Where this credential sits among the others returned.
|
|
349
|
+
* Where this credential sits among the others returned. See [`crate::asset::Lineage`].
|
|
264
350
|
*/
|
|
265
351
|
lineage: Lineage;
|
|
266
352
|
}
|
|
267
|
-
/**
|
|
268
|
-
* One query that located a recovered credential: how it was asked, under which algorithm, and
|
|
269
|
-
* where the manifest came from.
|
|
270
|
-
*/
|
|
271
|
-
interface Discovery {
|
|
272
|
-
via: DiscoveryVia;
|
|
273
|
-
alg: string;
|
|
274
|
-
type: SoftBindingType;
|
|
275
|
-
/**
|
|
276
|
-
* 0-100, the repository\'s `similarityScore`.
|
|
277
|
-
*/
|
|
278
|
-
score?: number;
|
|
279
|
-
repository: string;
|
|
280
|
-
/**
|
|
281
|
-
* The resolution API the manifest was fetched from, when not `repository`.
|
|
282
|
-
*/
|
|
283
|
-
endpoint?: string;
|
|
284
|
-
}
|
|
285
353
|
/**
|
|
286
354
|
* Outcome of validating a media segment against its stream\'s init.
|
|
287
355
|
*/
|
|
288
356
|
interface MediaValidation {
|
|
289
|
-
|
|
290
|
-
* `invalid` on any failure, else the state of the init manifest the segment\'s key came from.
|
|
291
|
-
*/
|
|
292
|
-
state: ValidationState;
|
|
357
|
+
valid: boolean;
|
|
293
358
|
codes: ValidationCode[];
|
|
294
|
-
|
|
359
|
+
keyId: Uint8Array;
|
|
295
360
|
timing: SegmentTiming;
|
|
296
361
|
manifestId: string;
|
|
297
362
|
}
|
|
@@ -302,7 +367,7 @@ interface InitValidation {
|
|
|
302
367
|
state: ValidationState;
|
|
303
368
|
codes: ValidationCode[];
|
|
304
369
|
manifest: import('@contentauth/c2pa-types').ManifestStore;
|
|
305
|
-
sessionKeys:
|
|
370
|
+
sessionKeys: SessionKeySummary[];
|
|
306
371
|
}
|
|
307
372
|
/**
|
|
308
373
|
* Result of `StreamSession.validate`, discriminated by `kind`.
|
|
@@ -315,214 +380,80 @@ type SegmentValidation = ({
|
|
|
315
380
|
kind: "unknown";
|
|
316
381
|
};
|
|
317
382
|
/**
|
|
318
|
-
*
|
|
319
|
-
*/
|
|
320
|
-
type Golden = {
|
|
321
|
-
kind: "matches";
|
|
322
|
-
index: number;
|
|
323
|
-
} | {
|
|
324
|
-
kind: "differs";
|
|
325
|
-
index: number;
|
|
326
|
-
} | {
|
|
327
|
-
kind: "noneMatches";
|
|
328
|
-
candidates: number[];
|
|
329
|
-
} | {
|
|
330
|
-
kind: "unreadable";
|
|
331
|
-
index: number;
|
|
332
|
-
};
|
|
333
|
-
/**
|
|
334
|
-
* The C2PA list\'s `type` of a soft binding algorithm.
|
|
335
|
-
*/
|
|
336
|
-
type SoftBindingType = "fingerprint" | "watermark";
|
|
337
|
-
/**
|
|
338
|
-
* The Soft Binding Resolution API route a discovery came through.
|
|
339
|
-
*/
|
|
340
|
-
type DiscoveryVia = {
|
|
341
|
-
kind: "byBinding";
|
|
342
|
-
value: Uint8Array;
|
|
343
|
-
} | {
|
|
344
|
-
kind: "byContent";
|
|
345
|
-
hint?: Hint;
|
|
346
|
-
} | {
|
|
347
|
-
kind: "byReference";
|
|
348
|
-
hint?: Hint;
|
|
349
|
-
};
|
|
350
|
-
/**
|
|
351
|
-
* The evidence that singled a recovered verdict out.
|
|
352
|
-
*/
|
|
353
|
-
type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
|
|
354
|
-
/**
|
|
355
|
-
* The query a repository answers from the content: `matches/byReference` when `reference` is
|
|
356
|
-
* stated, so nothing is uploaded, else `matches/byContent` with the asset in the request.
|
|
357
|
-
*/
|
|
358
|
-
interface Content {
|
|
359
|
-
when: ContentWhen;
|
|
360
|
-
/**
|
|
361
|
-
* Where each repository downloads the asset from.
|
|
362
|
-
*/
|
|
363
|
-
reference?: Reference;
|
|
364
|
-
/**
|
|
365
|
-
* The largest asset an upload sends, in bytes; a larger one is reported `tooLarge`. Absent,
|
|
366
|
-
* 64 MiB.
|
|
367
|
-
*/
|
|
368
|
-
maxUploadBytes?: number;
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* The re-sign chain between the returned credentials, by manifest label.
|
|
372
|
-
*/
|
|
373
|
-
interface Lineage {
|
|
374
|
-
supersedes: string[];
|
|
375
|
-
supersededBy: string[];
|
|
376
|
-
}
|
|
377
|
-
/**
|
|
378
|
-
* The value a content query was hinted with, under its own algorithm.
|
|
379
|
-
*/
|
|
380
|
-
interface Hint {
|
|
381
|
-
alg: string;
|
|
382
|
-
value: Uint8Array;
|
|
383
|
-
}
|
|
384
|
-
/**
|
|
385
|
-
* Timing a media segment\'s container carries.
|
|
383
|
+
* Timing facts carried by a media segment\'s container.
|
|
386
384
|
*/
|
|
387
385
|
interface SegmentTiming {
|
|
388
386
|
/**
|
|
389
|
-
*
|
|
387
|
+
* Media segment sequence number (exact below 2^53).
|
|
390
388
|
*/
|
|
391
|
-
|
|
389
|
+
sequenceNumber: number;
|
|
392
390
|
/**
|
|
393
|
-
*
|
|
391
|
+
* MP4 timescale (ticks per second) for this segment\'s timing, if present.
|
|
394
392
|
*/
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* What a stream verifier trusts, and how far a segment\'s clock may drift.
|
|
399
|
-
*/
|
|
400
|
-
interface StreamVerifierOptions {
|
|
401
|
-
trust: Trust;
|
|
393
|
+
timescale?: number;
|
|
402
394
|
/**
|
|
403
|
-
*
|
|
404
|
-
* in milliseconds. Absent, 5 minutes.
|
|
395
|
+
* Segment duration in seconds, if the container reports it.
|
|
405
396
|
*/
|
|
406
|
-
|
|
397
|
+
eventDurationSecs?: number;
|
|
407
398
|
}
|
|
408
399
|
/**
|
|
409
|
-
* What a
|
|
400
|
+
* What one verify may do to recover a manifest, as data: the binders this client derives for
|
|
401
|
+
* itself, decided into `matches/byBinding`, and one field per content operation, absent when
|
|
402
|
+
* not to be called. It needs a configured repository and at least one query.
|
|
410
403
|
*/
|
|
411
|
-
interface
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
/**
|
|
417
|
-
* PEM anchors for the time-stamping authorities the caller trusts.
|
|
418
|
-
*/
|
|
419
|
-
tsaAnchors?: string[];
|
|
420
|
-
/**
|
|
421
|
-
* Also trust the bundled official C2PA manifest and TSA lists, beside the caller\'s.
|
|
422
|
-
*/
|
|
423
|
-
c2pa: boolean;
|
|
424
|
-
/**
|
|
425
|
-
* Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched exactly
|
|
426
|
-
* against the credential issuer. Empty trusts no issuer: every identity assertion then
|
|
427
|
-
* reports `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`, which leaves
|
|
428
|
-
* the manifest\'s own validity untouched.
|
|
429
|
-
*/
|
|
430
|
-
icaIssuers?: string[];
|
|
404
|
+
interface Recovery {
|
|
405
|
+
when: RecoveryTrigger;
|
|
406
|
+
binders: BinderSpec[];
|
|
407
|
+
byContent?: ByContent;
|
|
408
|
+
byReference?: ByReference;
|
|
431
409
|
}
|
|
432
410
|
/**
|
|
433
|
-
*
|
|
434
|
-
* asks nothing.
|
|
411
|
+
* When [`AssetVerifier::verify_asset`] queries the repository.
|
|
435
412
|
*/
|
|
436
|
-
|
|
437
|
-
/**
|
|
438
|
-
* The C2PA manifest repositories recovery asks, each a Soft Binding Resolution API declared
|
|
439
|
-
* for exactly the algorithms it may be asked for. Results merge by manifest, and a match\'s
|
|
440
|
-
* `endpoint` is fetched from only when it names one of these. Empty: no recovery can be
|
|
441
|
-
* asked of this verifier.
|
|
442
|
-
*/
|
|
443
|
-
repositories?: Repository[];
|
|
444
|
-
trust: Trust;
|
|
445
|
-
}
|
|
413
|
+
type RecoveryTrigger = "manifestMissing" | "always";
|
|
446
414
|
/**
|
|
447
|
-
*
|
|
448
|
-
* itself through `matches/byBinding`, and the content query, absent when not to be asked. It
|
|
449
|
-
* needs a configured repository and at least one query.
|
|
415
|
+
* Whether a code is a success, an informational note, or a failure.
|
|
450
416
|
*/
|
|
451
|
-
|
|
452
|
-
when: RecoveryTrigger;
|
|
453
|
-
softBindings?: SoftBindingSource[];
|
|
454
|
-
content?: Content;
|
|
455
|
-
/**
|
|
456
|
-
* The whole recovery\'s budget in milliseconds, every repository together, each request
|
|
457
|
-
* bounded by what remains. Absent, 10 minutes; at most 2147483647.
|
|
458
|
-
*/
|
|
459
|
-
timeout?: number;
|
|
460
|
-
}
|
|
417
|
+
type ValidationCodeKind = "success" | "informational" | "failure";
|
|
461
418
|
/**
|
|
462
|
-
*
|
|
419
|
+
* Whether a content form runs on this verify. Judged against the byBinding results alone.
|
|
463
420
|
*/
|
|
464
|
-
type
|
|
465
|
-
kind: "unsigned";
|
|
466
|
-
} | {
|
|
467
|
-
kind: "inconclusive";
|
|
468
|
-
} | {
|
|
469
|
-
kind: "embedded";
|
|
470
|
-
} | {
|
|
471
|
-
kind: "recovered";
|
|
472
|
-
index: number;
|
|
473
|
-
decidedBy: VerdictRule;
|
|
474
|
-
} | {
|
|
475
|
-
kind: "recoveredDerivative";
|
|
476
|
-
index: number;
|
|
477
|
-
decidedBy: VerdictRule;
|
|
478
|
-
} | {
|
|
479
|
-
kind: "ambiguous";
|
|
480
|
-
candidates: number[];
|
|
481
|
-
};
|
|
421
|
+
type ContentTrigger = "byBindingMisses" | "always";
|
|
482
422
|
/**
|
|
483
|
-
*
|
|
423
|
+
* [`crate::asset::ByReference`] as JS states it: the region is the `Range` of
|
|
424
|
+
* `@contentauth/c2pa-types`, the shape a credential\'s actions carry.
|
|
484
425
|
*/
|
|
485
|
-
|
|
426
|
+
interface ByReference {
|
|
427
|
+
after: ContentTrigger;
|
|
428
|
+
url: string;
|
|
429
|
+
length: number;
|
|
430
|
+
mediaType?: string;
|
|
431
|
+
region: import('@contentauth/c2pa-types').Range[];
|
|
432
|
+
}
|
|
486
433
|
/**
|
|
487
|
-
*
|
|
434
|
+
* [`crate::asset::CredentialOrigin`] as JS sees it: a tagged union, since each way of finding a
|
|
435
|
+
* credential carries different evidence. Lane-local for the same reason [`FingerprintCheck`] is: a
|
|
436
|
+
* tag layout is what `#[binding(wasm)]` declines to express.
|
|
488
437
|
*/
|
|
489
438
|
type CredentialOrigin = {
|
|
490
439
|
kind: "embedded";
|
|
491
440
|
} | {
|
|
492
441
|
kind: "recovered";
|
|
493
|
-
discoveries:
|
|
442
|
+
discoveries: RecoveryDiscovery[];
|
|
494
443
|
fingerprintCheck: FingerprintCheck;
|
|
495
444
|
};
|
|
496
445
|
/**
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
|
|
500
|
-
type SoftBindingSource = {
|
|
501
|
-
kind: "builtin";
|
|
502
|
-
alg: string;
|
|
503
|
-
} | {
|
|
504
|
-
kind: "held";
|
|
505
|
-
alg: string;
|
|
506
|
-
value: Uint8Array;
|
|
507
|
-
};
|
|
508
|
-
/**
|
|
509
|
-
* Whether a code is a success, an informational note, or a failure.
|
|
510
|
-
*/
|
|
511
|
-
type ValidationCodeKind = "success" | "informational" | "failure";
|
|
512
|
-
/**
|
|
513
|
-
* Whether a content form runs on this verify. Judged against the byBinding results alone.
|
|
514
|
-
*/
|
|
515
|
-
type ContentWhen = "bindingMisses" | "always";
|
|
516
|
-
/**
|
|
517
|
-
* Whether the asset\'s own fingerprint backs up a manifest that a watermark led to.
|
|
446
|
+
* [`crate::asset::FingerprintCheck`] as JS sees it: a tagged union, since `compared` carries a
|
|
447
|
+
* measurement the other two do not. Lane-local rather than `#[binding(wasm)]` on the core,
|
|
448
|
+
* because a tag layout is exactly what that macro declines to express.
|
|
518
449
|
*/
|
|
519
450
|
type FingerprintCheck = {
|
|
520
451
|
kind: "notNeeded";
|
|
521
452
|
} | {
|
|
522
|
-
kind: "
|
|
453
|
+
kind: "nothingToCompare";
|
|
523
454
|
} | {
|
|
524
455
|
kind: "unsupported";
|
|
525
|
-
|
|
456
|
+
algorithm: string;
|
|
526
457
|
} | {
|
|
527
458
|
kind: "indeterminate";
|
|
528
459
|
} | {
|
|
@@ -530,40 +461,59 @@ type FingerprintCheck = {
|
|
|
530
461
|
score: number;
|
|
531
462
|
};
|
|
532
463
|
/**
|
|
533
|
-
*
|
|
464
|
+
* [`crate::asset::HardBinding`] as JS sees it.
|
|
534
465
|
*/
|
|
535
466
|
type HardBinding = "match" | "mismatch";
|
|
536
467
|
/**
|
|
537
|
-
*
|
|
468
|
+
* [`crate::asset::Lineage`] as JS sees it.
|
|
469
|
+
*/
|
|
470
|
+
interface Lineage {
|
|
471
|
+
supersedes: string[];
|
|
472
|
+
supersededBy: string[];
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* [`crate::asset::RecoveryIssue`] as JS sees it: a tagged union, each kind with its own data.
|
|
538
476
|
*/
|
|
539
477
|
type RecoveryIssue = {
|
|
540
|
-
kind: "
|
|
541
|
-
|
|
478
|
+
kind: "binderFailed";
|
|
479
|
+
binderIndex: number;
|
|
542
480
|
message: string;
|
|
543
481
|
} | {
|
|
544
|
-
kind: "
|
|
482
|
+
kind: "algorithmDeprecated";
|
|
483
|
+
algorithm: string;
|
|
484
|
+
} | {
|
|
485
|
+
kind: "bindingUndeclared";
|
|
486
|
+
binderIndex: number;
|
|
487
|
+
algorithm: string;
|
|
488
|
+
} | {
|
|
489
|
+
kind: "bindingQueryFailed";
|
|
545
490
|
repository: string;
|
|
546
|
-
|
|
491
|
+
binderIndex: number;
|
|
492
|
+
algorithm: string;
|
|
547
493
|
message: string;
|
|
548
494
|
} | {
|
|
549
495
|
kind: "queryRefused";
|
|
550
496
|
repository: string;
|
|
551
|
-
|
|
497
|
+
algorithm: string;
|
|
552
498
|
message: string;
|
|
553
499
|
} | {
|
|
554
|
-
kind: "
|
|
500
|
+
kind: "contentFormUnsupported";
|
|
555
501
|
repository: string;
|
|
556
|
-
|
|
502
|
+
message: string;
|
|
503
|
+
} | {
|
|
504
|
+
kind: "contentQueryFailed";
|
|
505
|
+
repository: string;
|
|
506
|
+
algorithm: string;
|
|
557
507
|
message: string;
|
|
558
508
|
} | {
|
|
559
509
|
kind: "capabilitiesUnavailable";
|
|
560
510
|
repository: string;
|
|
561
511
|
message: string;
|
|
562
512
|
} | {
|
|
563
|
-
kind: "
|
|
564
|
-
|
|
513
|
+
kind: "contentTooLarge";
|
|
514
|
+
capBytes: number;
|
|
565
515
|
} | {
|
|
566
|
-
kind: "
|
|
516
|
+
kind: "candidateFetchFailed";
|
|
567
517
|
repository: string;
|
|
568
518
|
manifestId: string;
|
|
569
519
|
message: string;
|
|
@@ -577,22 +527,98 @@ type RecoveryIssue = {
|
|
|
577
527
|
manifestId: string;
|
|
578
528
|
endpoint: string;
|
|
579
529
|
} | {
|
|
580
|
-
kind: "
|
|
530
|
+
kind: "resourceLimitReached";
|
|
581
531
|
message: string;
|
|
582
532
|
};
|
|
533
|
+
/**
|
|
534
|
+
* [`crate::asset::VerdictRule`] as JS sees it.
|
|
535
|
+
*/
|
|
536
|
+
type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
|
|
537
|
+
/**
|
|
538
|
+
* [`crate::asset::Verdict`] as JS sees it.
|
|
539
|
+
*/
|
|
540
|
+
type Verdict = {
|
|
541
|
+
kind: "unsigned";
|
|
542
|
+
} | {
|
|
543
|
+
kind: "inconclusive";
|
|
544
|
+
} | {
|
|
545
|
+
kind: "embedded";
|
|
546
|
+
} | {
|
|
547
|
+
kind: "recovered";
|
|
548
|
+
index: number;
|
|
549
|
+
decidedBy: VerdictRule;
|
|
550
|
+
} | {
|
|
551
|
+
kind: "recoveredDerivative";
|
|
552
|
+
index: number;
|
|
553
|
+
decidedBy: VerdictRule;
|
|
554
|
+
} | {
|
|
555
|
+
kind: "ambiguous";
|
|
556
|
+
candidates: number[];
|
|
557
|
+
};
|
|
558
|
+
/**
|
|
559
|
+
* `matches/byContent`: the asset is uploaded to each repository, one request per algorithm that
|
|
560
|
+
* repository is declared for.
|
|
561
|
+
*/
|
|
562
|
+
interface ByContent {
|
|
563
|
+
after: ContentTrigger;
|
|
564
|
+
}
|
|
583
565
|
interface AssetVerification {
|
|
584
566
|
credentials: Credential[];
|
|
585
567
|
recovery: RecoverySummary;
|
|
586
|
-
|
|
587
|
-
* Absent when there was nothing to compare.
|
|
588
|
-
*/
|
|
589
|
-
golden?: Golden;
|
|
568
|
+
goldenComparison: GoldenComparison;
|
|
590
569
|
verdict: Verdict;
|
|
591
570
|
}
|
|
592
571
|
interface RecoverySummary {
|
|
593
572
|
status: RecoveryStatus;
|
|
594
573
|
issues: RecoveryIssue[];
|
|
595
574
|
}
|
|
575
|
+
type ContentBindingClass = "fingerprint" | "watermark";
|
|
576
|
+
type GoldenComparison = {
|
|
577
|
+
kind: "notRequested";
|
|
578
|
+
} | {
|
|
579
|
+
kind: "noEmbeddedManifest";
|
|
580
|
+
} | {
|
|
581
|
+
kind: "noRecoveredManifest";
|
|
582
|
+
} | {
|
|
583
|
+
kind: "recoveryIncomplete";
|
|
584
|
+
} | {
|
|
585
|
+
kind: "matches";
|
|
586
|
+
recoveredIndex: number;
|
|
587
|
+
} | {
|
|
588
|
+
kind: "differs";
|
|
589
|
+
recoveredIndex: number;
|
|
590
|
+
} | {
|
|
591
|
+
kind: "noneMatches";
|
|
592
|
+
candidates: number[];
|
|
593
|
+
} | {
|
|
594
|
+
kind: "unreadable";
|
|
595
|
+
recoveredIndex: number;
|
|
596
|
+
};
|
|
597
|
+
type RecoveryDiscovery = {
|
|
598
|
+
kind: "byBinding";
|
|
599
|
+
class: ContentBindingClass;
|
|
600
|
+
binding: SoftBinding;
|
|
601
|
+
binderIndex: number;
|
|
602
|
+
repositoryScore: number | undefined;
|
|
603
|
+
repository: string;
|
|
604
|
+
fetchedFrom: string;
|
|
605
|
+
} | {
|
|
606
|
+
kind: "byContent";
|
|
607
|
+
hint: SoftBinding | undefined;
|
|
608
|
+
class: ContentBindingClass;
|
|
609
|
+
algorithm: string;
|
|
610
|
+
repositoryScore: number | undefined;
|
|
611
|
+
repository: string;
|
|
612
|
+
fetchedFrom: string;
|
|
613
|
+
} | {
|
|
614
|
+
kind: "byReference";
|
|
615
|
+
hint: SoftBinding | undefined;
|
|
616
|
+
class: ContentBindingClass;
|
|
617
|
+
algorithm: string;
|
|
618
|
+
repositoryScore: number | undefined;
|
|
619
|
+
repository: string;
|
|
620
|
+
fetchedFrom: string;
|
|
621
|
+
};
|
|
596
622
|
type RecoveryStatus = "notRequested" | "notFound" | "recovered" | "incomplete";
|
|
597
623
|
declare class AssetVerifier {
|
|
598
624
|
private constructor();
|
|
@@ -612,11 +638,14 @@ declare class AssetVerifier {
|
|
|
612
638
|
*
|
|
613
639
|
* # Errors
|
|
614
640
|
*
|
|
615
|
-
* Throws on a malformed `
|
|
641
|
+
* Throws on a malformed `input`, a repository (or binder) failure, or a validation
|
|
616
642
|
* failure.
|
|
617
643
|
*/
|
|
618
|
-
verify(
|
|
644
|
+
verify(input: RangeSource, recovery?: Recovery | null): Promise<AssetVerification>;
|
|
619
645
|
}
|
|
646
|
+
declare function C2PA_TRUST_LIST(): string;
|
|
647
|
+
declare function C2PA_TSA_TRUST_LIST(): string;
|
|
648
|
+
declare function DEV_CA(): string;
|
|
620
649
|
/**
|
|
621
650
|
* One stream being validated. It owns the session keys and manifest ids its init segments
|
|
622
651
|
* advertised, so releasing the stream is dropping this object.
|
|
@@ -626,8 +655,8 @@ declare class StreamSession {
|
|
|
626
655
|
free(): void;
|
|
627
656
|
[Symbol.dispose](): void;
|
|
628
657
|
/**
|
|
629
|
-
*
|
|
630
|
-
*
|
|
658
|
+
* Everything this stream's init segments have registered, as CBOR for another node to
|
|
659
|
+
* `StreamVerifier.resume` from.
|
|
631
660
|
*
|
|
632
661
|
* The one piece of stream state that leaves the SDK, and only because a clustered
|
|
633
662
|
* verifier needs it: the init URL is overwritten on rotation, so a node joining during
|
|
@@ -648,7 +677,7 @@ declare class StreamSession {
|
|
|
648
677
|
* Throws an `SdkError` on parse or signature failure, or when a media segment arrives
|
|
649
678
|
* before any init was processed for the stream.
|
|
650
679
|
*/
|
|
651
|
-
validate(
|
|
680
|
+
validate(data: RangeSource): Promise<SegmentValidation>;
|
|
652
681
|
}
|
|
653
682
|
declare class StreamVerifier {
|
|
654
683
|
private constructor();
|
|
@@ -663,57 +692,25 @@ declare class StreamVerifier {
|
|
|
663
692
|
*/
|
|
664
693
|
static create(options: StreamVerifierOptions): StreamVerifier;
|
|
665
694
|
/**
|
|
666
|
-
* Open
|
|
695
|
+
* Open `stream_id` for validation, handing back a `StreamSession` to feed segments to.
|
|
667
696
|
*
|
|
668
697
|
* No I/O: the handle carries the id so it cannot be mistyped or confused with another
|
|
669
698
|
* stream's, and classification still happens per segment. Opening one id twice hands
|
|
670
699
|
* back the same live session, so a component that remounts keeps the state its earlier
|
|
671
700
|
* handle accumulated.
|
|
672
701
|
*/
|
|
673
|
-
open(
|
|
702
|
+
open(stream_id: string): StreamSession;
|
|
674
703
|
/**
|
|
675
|
-
* Open the
|
|
676
|
-
* for that
|
|
704
|
+
* Open `stream_id` on the state another node exported, merged into whatever this one
|
|
705
|
+
* holds for that id already.
|
|
677
706
|
*
|
|
678
707
|
* # Errors
|
|
679
708
|
*
|
|
680
|
-
* Throws an `SdkError`
|
|
681
|
-
* `StreamSession.export` produced
|
|
682
|
-
* (`state.version`).
|
|
709
|
+
* Throws an `SdkError` (`STREAM_INVALID`) when `state` is not a value
|
|
710
|
+
* `StreamSession.export` produced, or carries a version this SDK no longer reads.
|
|
683
711
|
*/
|
|
684
|
-
resume(state: Uint8Array): StreamSession;
|
|
712
|
+
resume(stream_id: string, state: Uint8Array): StreamSession;
|
|
685
713
|
}
|
|
686
|
-
/**
|
|
687
|
-
* One `verify` result held with the stores it read: `report` is the data, and `resource` reads a
|
|
688
|
-
* thumbnail from credential `credential` (its position in `report.credentials`) by the
|
|
689
|
-
* `identifier` of a resource reference in its manifest. A class rather than a field of the
|
|
690
|
-
* report because a store cannot be serialized, and one handle per verify is what a worker can
|
|
691
|
-
* proxy (a class nested in the report cannot cross a thread).
|
|
692
|
-
*/
|
|
693
|
-
declare class Verification {
|
|
694
|
-
private constructor();
|
|
695
|
-
free(): void;
|
|
696
|
-
[Symbol.dispose](): void;
|
|
697
|
-
/**
|
|
698
|
-
* The bytes of one resource credential `credential` holds, or `undefined`.
|
|
699
|
-
*
|
|
700
|
-
* # Errors
|
|
701
|
-
*
|
|
702
|
-
* Throws `READER_INVALID` when the store holds the resource but cannot produce it, and
|
|
703
|
-
* `undefined` for a `credential` out of range.
|
|
704
|
-
*/
|
|
705
|
-
resource(credential: number, uri: string): Uint8Array | undefined;
|
|
706
|
-
/**
|
|
707
|
-
* The report: credentials, recovery, golden flow and verdict.
|
|
708
|
-
*/
|
|
709
|
-
readonly report: AssetVerification;
|
|
710
|
-
}
|
|
711
|
-
/**
|
|
712
|
-
* PEM trust anchor for the Limbo Integrity development signing environment, **development
|
|
713
|
-
* only**, no security guarantees: put it in `trust.anchors` for a development build, never in a
|
|
714
|
-
* release.
|
|
715
|
-
*/
|
|
716
|
-
declare function devCa(): string;
|
|
717
714
|
//#endregion
|
|
718
715
|
//#region src/worker-thread.d.ts
|
|
719
716
|
/**
|
|
@@ -740,18 +737,9 @@ declare abstract class Handle<T extends {
|
|
|
740
737
|
constructor(inner: T);
|
|
741
738
|
[finalizer](): void;
|
|
742
739
|
}
|
|
743
|
-
/**
|
|
744
|
-
* One verify result. A wasm class cannot cross the thread, so the report and the stores behind it
|
|
745
|
-
* stay here and the caller holds this: `report()` is the data, `resource()` reads a thumbnail from
|
|
746
|
-
* a credential by its position in `report().credentials`.
|
|
747
|
-
*/
|
|
748
|
-
declare class VerificationHandle extends Handle<Verification> {
|
|
749
|
-
report(): AssetVerification;
|
|
750
|
-
resource(credential: number, uri: string): Uint8Array | undefined;
|
|
751
|
-
}
|
|
752
740
|
declare class AssetVerifierHandle extends Handle<AssetVerifier> {
|
|
753
741
|
/** `recovery` is what this verify may do to recover a manifest, as the direct import takes it. */
|
|
754
|
-
verify(asset: Asset, recovery: Recovery | undefined): Promise<
|
|
742
|
+
verify(asset: Asset, recovery: Recovery | undefined): Promise<AssetVerification>;
|
|
755
743
|
}
|
|
756
744
|
/** One stream being validated. Dropping the handle releases the session it accumulated. */
|
|
757
745
|
declare class StreamSessionHandle extends Handle<StreamSession> {
|
|
@@ -759,8 +747,8 @@ declare class StreamSessionHandle extends Handle<StreamSession> {
|
|
|
759
747
|
export(): Uint8Array;
|
|
760
748
|
}
|
|
761
749
|
declare class StreamVerifierHandle extends Handle<StreamVerifier> {
|
|
762
|
-
open(
|
|
763
|
-
resume(state: Uint8Array): StreamSessionHandle & ProxyMarked;
|
|
750
|
+
open(streamId: string): StreamSessionHandle & ProxyMarked;
|
|
751
|
+
resume(streamId: string, state: Uint8Array): StreamSessionHandle & ProxyMarked;
|
|
764
752
|
}
|
|
765
753
|
/** The module's own surface, name for name with the direct import. */
|
|
766
754
|
declare const sdk: {
|
|
@@ -775,11 +763,13 @@ declare const sdk: {
|
|
|
775
763
|
StreamVerifier: {
|
|
776
764
|
create: (options: StreamVerifierOptions) => StreamVerifierHandle & ProxyMarked;
|
|
777
765
|
} & ProxyMarked;
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
766
|
+
Binder: {
|
|
767
|
+
/**
|
|
768
|
+
* Derive one binder's binding standalone. The binder is built, used and dropped here, so there
|
|
769
|
+
* is no handle to keep: what the caller wants back is the binding.
|
|
770
|
+
*/
|
|
771
|
+
derive: (spec: BinderSpec, content: Asset, options: DeriveOptions) => Promise<SoftBinding | undefined>;
|
|
772
|
+
} & ProxyMarked;
|
|
783
773
|
/**
|
|
784
774
|
* Read a detached manifest store. Contents, not a verdict: with no asset there is no hard binding
|
|
785
775
|
* to check, so the store's validation fields state nothing this established.
|
|
@@ -790,7 +780,14 @@ declare const sdk: {
|
|
|
790
780
|
* manifest's claim thumbnail, and any ingredient's.
|
|
791
781
|
*/
|
|
792
782
|
resource(manifest: Asset, uri: string): Promise<Uint8Array<ArrayBufferLike> | undefined>;
|
|
793
|
-
|
|
783
|
+
/**
|
|
784
|
+
* Every thumbnail the store references, by the identifier it references them under. One parse
|
|
785
|
+
* and one thread hop for the whole set, where `resource` pays both per call.
|
|
786
|
+
*/
|
|
787
|
+
thumbnails(manifest: Asset): Promise<Record<string, Uint8Array<ArrayBufferLike>>>;
|
|
788
|
+
C2PA_TRUST_LIST: typeof C2PA_TRUST_LIST;
|
|
789
|
+
C2PA_TSA_TRUST_LIST: typeof C2PA_TSA_TRUST_LIST;
|
|
790
|
+
DEV_CA: typeof DEV_CA;
|
|
794
791
|
close(): void;
|
|
795
792
|
};
|
|
796
793
|
/** What the caller's thread holds a `Comlink.Remote` of. */
|