@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.
@@ -163,61 +163,141 @@ interface RangeSource {
163
163
  readAt: (offset: number, length: number) => Uint8Array;
164
164
  }
165
165
  /**
166
- * A `soft-binding-block-map`. No scope is the whole content.
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 Block {
169
- value: Uint8Array;
170
- scope?: Scope;
171
- }
172
- /**
173
- * A `soft-binding-scope-map`.
174
- */
175
- interface Scope {
176
- timespan?: Timespan;
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 `soft-binding-timespan-map`: where the range starts in the media and how long it lasts, in
180
- * milliseconds.
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
- interface Timespan {
183
- start: number;
184
- duration: number;
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 SessionKey {
197
+ interface SessionKeySummary {
190
198
  /**
191
199
  * Identifier of the session signing key.
192
200
  */
193
- kid: Uint8Array;
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
- * An asset a repository downloads, as the `byReference` request body names it.
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 Reference {
219
+ interface AssetVerifierOptions {
203
220
  /**
204
- * A short-lived https URL without credentials.
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
- url: string;
226
+ repositories: Repository[];
207
227
  /**
208
- * The asset\'s size in bytes.
228
+ * PEM trust anchors for the manifest signers the caller trusts.
209
229
  */
210
- length: number;
230
+ trustAnchors: string[];
231
+ /**
232
+ * PEM trust anchors for the time-stamping authorities the caller trusts.
233
+ */
234
+ tsaTrustAnchors: string[];
211
235
  /**
212
- * The asset\'s media type.
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
- format?: string;
215
- ranges?: import('@contentauth/c2pa-types').Range[];
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
- * C2PA validation state of a manifest (spec §14.3).
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
- type ValidationState = "Invalid" | "Valid" | "Trusted";
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: "registered";
230
- alg: string;
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
- * Where this credential came from.
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
- kid: Uint8Array;
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: SessionKey[];
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
- * The C2PA 2.4 golden-flow comparison of the embedded manifest against what the repository holds.
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
- * The segment\'s `sequenceNumber` (exact below 2^53).
387
+ * Media segment sequence number (exact below 2^53).
390
388
  */
391
- sequence: number;
389
+ sequenceNumber: number;
392
390
  /**
393
- * The span its C2PA `emsg` covers, in milliseconds.
391
+ * MP4 timescale (ticks per second) for this segment\'s timing, if present.
394
392
  */
395
- duration?: number;
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
- * How far a segment\'s presentation time may sit outside its session key\'s validity period,
404
- * in milliseconds. Absent, 5 minutes.
395
+ * Segment duration in seconds, if the container reports it.
405
396
  */
406
- skewTolerance?: number;
397
+ eventDurationSecs?: number;
407
398
  }
408
399
  /**
409
- * What a verifier trusts. An omitted list trusts nothing.
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 Trust {
412
- /**
413
- * PEM anchors for the manifest signers the caller trusts.
414
- */
415
- anchors?: string[];
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
- * What an asset verifier trusts and which repositories it may ask. An omitted list trusts or
434
- * asks nothing.
411
+ * When [`AssetVerifier::verify_asset`] queries the repository.
435
412
  */
436
- interface AssetVerifierOptions {
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
- * What one verify may do to recover a manifest, as data: the soft bindings this client looks up
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
- interface Recovery {
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
- * What this verify concludes about the asset, from signed evidence alone.
419
+ * Whether a content form runs on this verify. Judged against the byBinding results alone.
463
420
  */
464
- type Verdict = {
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
- * When a verify asks the repositories.
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
- type RecoveryTrigger = "manifestMissing" | "always";
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
- * Where a credential came from: embedded in the asset, or recovered from a repository.
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: Discovery[];
442
+ discoveries: RecoveryDiscovery[];
494
443
  fingerprintCheck: FingerprintCheck;
495
444
  };
496
445
  /**
497
- * Where one byBinding query\'s value comes from. A browser has no host engine: a vendor\'s
498
- * detector runs repository-side, through `byContent`.
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: "missing";
453
+ kind: "nothingToCompare";
523
454
  } | {
524
455
  kind: "unsupported";
525
- alg: string;
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
- * Whether the manifest\'s hard binding holds over the bytes this verify read.
464
+ * [`crate::asset::HardBinding`] as JS sees it.
534
465
  */
535
466
  type HardBinding = "match" | "mismatch";
536
467
  /**
537
- * Why repository recovery did not complete cleanly, or why one candidate was omitted.
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: "computeFailed";
541
- alg: string;
478
+ kind: "binderFailed";
479
+ binderIndex: number;
542
480
  message: string;
543
481
  } | {
544
- kind: "bindingFailed";
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
- alg: string;
491
+ binderIndex: number;
492
+ algorithm: string;
547
493
  message: string;
548
494
  } | {
549
495
  kind: "queryRefused";
550
496
  repository: string;
551
- alg: string;
497
+ algorithm: string;
552
498
  message: string;
553
499
  } | {
554
- kind: "contentFailed";
500
+ kind: "contentFormUnsupported";
555
501
  repository: string;
556
- alg: string;
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: "tooLarge";
564
- maxUploadBytes: number;
513
+ kind: "contentTooLarge";
514
+ capBytes: number;
565
515
  } | {
566
- kind: "fetchFailed";
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: "limitReached";
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 `source`, a repository (or engine) failure, or a validation
641
+ * Throws on a malformed `input`, a repository (or binder) failure, or a validation
616
642
  * failure.
617
643
  */
618
- verify(source: RangeSource, recovery?: Recovery | null): Promise<Verification>;
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
- * This stream's id and everything its init segments have registered, as CBOR for another
630
- * node to `StreamVerifier.resume` from.
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(source: RangeSource): Promise<SegmentValidation>;
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 the stream `id` for validation, handing back a `StreamSession` to feed segments to.
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(id: string): StreamSession;
702
+ open(stream_id: string): StreamSession;
674
703
  /**
675
- * Open the stream another node exported, its state merged into whatever this one holds
676
- * for that stream already.
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` with a field violation at `state` when it is not a value
681
- * `StreamSession.export` produced (`state.malformed`), or one of another export version
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<VerificationHandle & ProxyMarked>;
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(id: string): StreamSessionHandle & ProxyMarked;
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
- * The values this SDK computes for `alg` over the asset, `[]` when it finds none. `format` is the
780
- * asset's media type; omitted, the bytes name it.
781
- */
782
- computeSoftBinding(alg: string, asset: Asset, format?: string): Promise<Block[]>;
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
- devCa: typeof devCa;
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. */