@trylimbo/sdk-verifier-wasm 0.2.23 → 0.2.25-canary.37

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,141 +163,61 @@ interface RangeSource {
163
163
  readAt: (offset: number, length: number) => Uint8Array;
164
164
  }
165
165
  /**
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.
166
+ * A `soft-binding-block-map`. No scope is the whole content.
171
167
  */
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;
168
+ interface Block {
169
+ value: Uint8Array;
170
+ scope?: Scope;
183
171
  }
184
172
  /**
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.
173
+ * A `soft-binding-scope-map`.
187
174
  */
188
- type BinderSpec = {
189
- kind: "iscc";
190
- } | {
191
- kind: "held";
192
- binding: SoftBinding;
193
- };
175
+ interface Scope {
176
+ timespan?: Timespan;
177
+ }
178
+ /**
179
+ * A `soft-binding-timespan-map`: where the range starts in the media and how long it lasts, in
180
+ * milliseconds.
181
+ */
182
+ interface Timespan {
183
+ start: number;
184
+ duration: number;
185
+ }
194
186
  /**
195
187
  * A session signing key from the init manifest\'s roster (spec §19.4.4).
196
188
  */
197
- interface SessionKeySummary {
189
+ interface SessionKey {
198
190
  /**
199
191
  * Identifier of the session signing key.
200
192
  */
201
- keyId: Uint8Array;
193
+ kid: Uint8Array;
202
194
  /**
203
195
  * The session key\'s public half (SEC1-encoded bytes).
204
196
  */
205
197
  publicKey: Uint8Array;
206
198
  }
207
199
  /**
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.
200
+ * An asset a repository downloads, as the `byReference` request body names it.
218
201
  */
219
- interface AssetVerifierOptions {
220
- /**
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.
225
- */
226
- repositories: Repository[];
227
- /**
228
- * PEM trust anchors for the manifest signers the caller trusts.
229
- */
230
- trustAnchors: string[];
202
+ interface Reference {
231
203
  /**
232
- * PEM trust anchors for the time-stamping authorities the caller trusts.
204
+ * A short-lived https URL without credentials.
233
205
  */
234
- tsaTrustAnchors: string[];
235
- /**
236
- * Also trust the bundled official C2PA anchors, manifest and TSA lists, beside the
237
- * caller\'s. `false` trusts the caller\'s lists alone.
238
- */
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[];
247
- }
248
- /**
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.
255
- */
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;
206
+ url: string;
270
207
  /**
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`.
208
+ * The asset\'s size in bytes.
275
209
  */
276
- trustedIcaIssuers: string[];
210
+ length: number;
277
211
  /**
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.
212
+ * The asset\'s media type.
281
213
  */
282
- segmentSkewToleranceSecs: number;
214
+ format?: string;
215
+ ranges?: import('@contentauth/c2pa-types').Range[];
283
216
  }
284
217
  /**
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.
218
+ * C2PA validation state of a manifest (spec §14.3).
294
219
  */
295
- type AssetFormat = {
296
- kind: "sniff";
297
- } | {
298
- kind: "declared";
299
- mediaType: string;
300
- };
220
+ type ValidationState = "Invalid" | "Valid" | "Trusted";
301
221
  /**
302
222
  * One C2PA manifest repository, as the Soft Binding Resolution API spec lets a client find it.
303
223
  */
@@ -306,8 +226,8 @@ type Repository = {
306
226
  url: string;
307
227
  algorithms: string[];
308
228
  } | {
309
- kind: "listed";
310
- algorithm: string;
229
+ kind: "registered";
230
+ alg: string;
311
231
  };
312
232
  /**
313
233
  * One C2PA validation status entry (spec §15.3): the registered code, its kind, and the
@@ -331,13 +251,7 @@ interface ValidationCode {
331
251
  */
332
252
  interface Credential {
333
253
  /**
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`].
254
+ * Where this credential came from.
341
255
  */
342
256
  origin: CredentialOrigin;
343
257
  manifest: import('@contentauth/c2pa-types').ManifestStore;
@@ -346,17 +260,38 @@ interface Credential {
346
260
  */
347
261
  hardBinding: HardBinding;
348
262
  /**
349
- * Where this credential sits among the others returned. See [`crate::asset::Lineage`].
263
+ * Where this credential sits among the others returned.
350
264
  */
351
265
  lineage: Lineage;
352
266
  }
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
+ }
353
285
  /**
354
286
  * Outcome of validating a media segment against its stream\'s init.
355
287
  */
356
288
  interface MediaValidation {
357
- valid: boolean;
289
+ /**
290
+ * `invalid` on any failure, else the state of the init manifest the segment\'s key came from.
291
+ */
292
+ state: ValidationState;
358
293
  codes: ValidationCode[];
359
- keyId: Uint8Array;
294
+ kid: Uint8Array;
360
295
  timing: SegmentTiming;
361
296
  manifestId: string;
362
297
  }
@@ -367,7 +302,7 @@ interface InitValidation {
367
302
  state: ValidationState;
368
303
  codes: ValidationCode[];
369
304
  manifest: import('@contentauth/c2pa-types').ManifestStore;
370
- sessionKeys: SessionKeySummary[];
305
+ sessionKeys: SessionKey[];
371
306
  }
372
307
  /**
373
308
  * Result of `StreamSession.validate`, discriminated by `kind`.
@@ -380,80 +315,214 @@ type SegmentValidation = ({
380
315
  kind: "unknown";
381
316
  };
382
317
  /**
383
- * Timing facts carried by a media segment\'s container.
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.
384
386
  */
385
387
  interface SegmentTiming {
386
388
  /**
387
- * Media segment sequence number (exact below 2^53).
389
+ * The segment\'s `sequenceNumber` (exact below 2^53).
388
390
  */
389
- sequenceNumber: number;
391
+ sequence: number;
390
392
  /**
391
- * MP4 timescale (ticks per second) for this segment\'s timing, if present.
393
+ * The span its C2PA `emsg` covers, in milliseconds.
392
394
  */
393
- timescale?: number;
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;
394
402
  /**
395
- * Segment duration in seconds, if the container reports it.
403
+ * How far a segment\'s presentation time may sit outside its session key\'s validity period,
404
+ * in milliseconds. Absent, 5 minutes.
396
405
  */
397
- eventDurationSecs?: number;
406
+ skewTolerance?: number;
398
407
  }
399
408
  /**
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.
409
+ * What a verifier trusts. An omitted list trusts nothing.
403
410
  */
404
- interface Recovery {
405
- when: RecoveryTrigger;
406
- binders: BinderSpec[];
407
- byContent?: ByContent;
408
- byReference?: ByReference;
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[];
409
431
  }
410
432
  /**
411
- * When [`AssetVerifier::verify_asset`] queries the repository.
433
+ * What an asset verifier trusts and which repositories it may ask. An omitted list trusts or
434
+ * asks nothing.
412
435
  */
413
- type RecoveryTrigger = "manifestMissing" | "always";
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
+ }
414
446
  /**
415
- * Whether a code is a success, an informational note, or a failure.
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.
416
450
  */
417
- type ValidationCodeKind = "success" | "informational" | "failure";
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
+ }
418
461
  /**
419
- * Whether a content form runs on this verify. Judged against the byBinding results alone.
462
+ * What this verify concludes about the asset, from signed evidence alone.
420
463
  */
421
- type ContentTrigger = "byBindingMisses" | "always";
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
+ };
422
482
  /**
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.
483
+ * When a verify asks the repositories.
425
484
  */
426
- interface ByReference {
427
- after: ContentTrigger;
428
- url: string;
429
- length: number;
430
- mediaType?: string;
431
- region: import('@contentauth/c2pa-types').Range[];
432
- }
485
+ type RecoveryTrigger = "manifestMissing" | "always";
433
486
  /**
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.
487
+ * Where a credential came from: embedded in the asset, or recovered from a repository.
437
488
  */
438
489
  type CredentialOrigin = {
439
490
  kind: "embedded";
440
491
  } | {
441
492
  kind: "recovered";
442
- discoveries: RecoveryDiscovery[];
493
+ discoveries: Discovery[];
443
494
  fingerprintCheck: FingerprintCheck;
444
495
  };
445
496
  /**
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.
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.
449
518
  */
450
519
  type FingerprintCheck = {
451
520
  kind: "notNeeded";
452
521
  } | {
453
- kind: "nothingToCompare";
522
+ kind: "missing";
454
523
  } | {
455
524
  kind: "unsupported";
456
- algorithm: string;
525
+ alg: string;
457
526
  } | {
458
527
  kind: "indeterminate";
459
528
  } | {
@@ -461,59 +530,40 @@ type FingerprintCheck = {
461
530
  score: number;
462
531
  };
463
532
  /**
464
- * [`crate::asset::HardBinding`] as JS sees it.
533
+ * Whether the manifest\'s hard binding holds over the bytes this verify read.
465
534
  */
466
535
  type HardBinding = "match" | "mismatch";
467
536
  /**
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.
537
+ * Why repository recovery did not complete cleanly, or why one candidate was omitted.
476
538
  */
477
539
  type RecoveryIssue = {
478
- kind: "binderFailed";
479
- binderIndex: number;
540
+ kind: "computeFailed";
541
+ alg: string;
480
542
  message: string;
481
543
  } | {
482
- kind: "algorithmDeprecated";
483
- algorithm: string;
484
- } | {
485
- kind: "bindingUndeclared";
486
- binderIndex: number;
487
- algorithm: string;
488
- } | {
489
- kind: "bindingQueryFailed";
544
+ kind: "bindingFailed";
490
545
  repository: string;
491
- binderIndex: number;
492
- algorithm: string;
546
+ alg: string;
493
547
  message: string;
494
548
  } | {
495
549
  kind: "queryRefused";
496
550
  repository: string;
497
- algorithm: string;
498
- message: string;
499
- } | {
500
- kind: "contentFormUnsupported";
501
- repository: string;
551
+ alg: string;
502
552
  message: string;
503
553
  } | {
504
- kind: "contentQueryFailed";
554
+ kind: "contentFailed";
505
555
  repository: string;
506
- algorithm: string;
556
+ alg: string;
507
557
  message: string;
508
558
  } | {
509
559
  kind: "capabilitiesUnavailable";
510
560
  repository: string;
511
561
  message: string;
512
562
  } | {
513
- kind: "contentTooLarge";
514
- capBytes: number;
563
+ kind: "tooLarge";
564
+ maxUploadBytes: number;
515
565
  } | {
516
- kind: "candidateFetchFailed";
566
+ kind: "fetchFailed";
517
567
  repository: string;
518
568
  manifestId: string;
519
569
  message: string;
@@ -527,98 +577,22 @@ type RecoveryIssue = {
527
577
  manifestId: string;
528
578
  endpoint: string;
529
579
  } | {
530
- kind: "resourceLimitReached";
580
+ kind: "limitReached";
531
581
  message: string;
532
582
  };
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
- }
565
583
  interface AssetVerification {
566
584
  credentials: Credential[];
567
585
  recovery: RecoverySummary;
568
- goldenComparison: GoldenComparison;
586
+ /**
587
+ * Absent when there was nothing to compare.
588
+ */
589
+ golden?: Golden;
569
590
  verdict: Verdict;
570
591
  }
571
592
  interface RecoverySummary {
572
593
  status: RecoveryStatus;
573
594
  issues: RecoveryIssue[];
574
595
  }
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
- };
622
596
  type RecoveryStatus = "notRequested" | "notFound" | "recovered" | "incomplete";
623
597
  declare class AssetVerifier {
624
598
  private constructor();
@@ -638,14 +612,11 @@ declare class AssetVerifier {
638
612
  *
639
613
  * # Errors
640
614
  *
641
- * Throws on a malformed `input`, a repository (or binder) failure, or a validation
615
+ * Throws on a malformed `source`, a repository (or engine) failure, or a validation
642
616
  * failure.
643
617
  */
644
- verify(input: RangeSource, recovery?: Recovery | null): Promise<AssetVerification>;
618
+ verify(source: RangeSource, recovery?: Recovery | null): Promise<Verification>;
645
619
  }
646
- declare function C2PA_TRUST_LIST(): string;
647
- declare function C2PA_TSA_TRUST_LIST(): string;
648
- declare function DEV_CA(): string;
649
620
  /**
650
621
  * One stream being validated. It owns the session keys and manifest ids its init segments
651
622
  * advertised, so releasing the stream is dropping this object.
@@ -655,8 +626,8 @@ declare class StreamSession {
655
626
  free(): void;
656
627
  [Symbol.dispose](): void;
657
628
  /**
658
- * Everything this stream's init segments have registered, as CBOR for another node to
659
- * `StreamVerifier.resume` from.
629
+ * This stream's id and everything its init segments have registered, as CBOR for another
630
+ * node to `StreamVerifier.resume` from.
660
631
  *
661
632
  * The one piece of stream state that leaves the SDK, and only because a clustered
662
633
  * verifier needs it: the init URL is overwritten on rotation, so a node joining during
@@ -677,7 +648,7 @@ declare class StreamSession {
677
648
  * Throws an `SdkError` on parse or signature failure, or when a media segment arrives
678
649
  * before any init was processed for the stream.
679
650
  */
680
- validate(data: RangeSource): Promise<SegmentValidation>;
651
+ validate(source: RangeSource): Promise<SegmentValidation>;
681
652
  }
682
653
  declare class StreamVerifier {
683
654
  private constructor();
@@ -692,25 +663,57 @@ declare class StreamVerifier {
692
663
  */
693
664
  static create(options: StreamVerifierOptions): StreamVerifier;
694
665
  /**
695
- * Open `stream_id` for validation, handing back a `StreamSession` to feed segments to.
666
+ * Open the stream `id` for validation, handing back a `StreamSession` to feed segments to.
696
667
  *
697
668
  * No I/O: the handle carries the id so it cannot be mistyped or confused with another
698
669
  * stream's, and classification still happens per segment. Opening one id twice hands
699
670
  * back the same live session, so a component that remounts keeps the state its earlier
700
671
  * handle accumulated.
701
672
  */
702
- open(stream_id: string): StreamSession;
673
+ open(id: string): StreamSession;
703
674
  /**
704
- * Open `stream_id` on the state another node exported, merged into whatever this one
705
- * holds for that id already.
675
+ * Open the stream another node exported, its state merged into whatever this one holds
676
+ * for that stream already.
706
677
  *
707
678
  * # Errors
708
679
  *
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.
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`).
711
683
  */
712
- resume(stream_id: string, state: Uint8Array): StreamSession;
684
+ resume(state: Uint8Array): StreamSession;
713
685
  }
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;
714
717
  //#endregion
715
718
  //#region src/worker-thread.d.ts
716
719
  /**
@@ -737,9 +740,18 @@ declare abstract class Handle<T extends {
737
740
  constructor(inner: T);
738
741
  [finalizer](): void;
739
742
  }
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
+ }
740
752
  declare class AssetVerifierHandle extends Handle<AssetVerifier> {
741
753
  /** `recovery` is what this verify may do to recover a manifest, as the direct import takes it. */
742
- verify(asset: Asset, recovery: Recovery | undefined): Promise<AssetVerification>;
754
+ verify(asset: Asset, recovery: Recovery | undefined): Promise<VerificationHandle & ProxyMarked>;
743
755
  }
744
756
  /** One stream being validated. Dropping the handle releases the session it accumulated. */
745
757
  declare class StreamSessionHandle extends Handle<StreamSession> {
@@ -747,8 +759,8 @@ declare class StreamSessionHandle extends Handle<StreamSession> {
747
759
  export(): Uint8Array;
748
760
  }
749
761
  declare class StreamVerifierHandle extends Handle<StreamVerifier> {
750
- open(streamId: string): StreamSessionHandle & ProxyMarked;
751
- resume(streamId: string, state: Uint8Array): StreamSessionHandle & ProxyMarked;
762
+ open(id: string): StreamSessionHandle & ProxyMarked;
763
+ resume(state: Uint8Array): StreamSessionHandle & ProxyMarked;
752
764
  }
753
765
  /** The module's own surface, name for name with the direct import. */
754
766
  declare const sdk: {
@@ -763,13 +775,11 @@ declare const sdk: {
763
775
  StreamVerifier: {
764
776
  create: (options: StreamVerifierOptions) => StreamVerifierHandle & ProxyMarked;
765
777
  } & ProxyMarked;
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;
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[]>;
773
783
  /**
774
784
  * Read a detached manifest store. Contents, not a verdict: with no asset there is no hard binding
775
785
  * to check, so the store's validation fields state nothing this established.
@@ -780,14 +790,7 @@ declare const sdk: {
780
790
  * manifest's claim thumbnail, and any ingredient's.
781
791
  */
782
792
  resource(manifest: Asset, uri: string): Promise<Uint8Array<ArrayBufferLike> | undefined>;
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;
793
+ devCa: typeof devCa;
791
794
  close(): void;
792
795
  };
793
796
  /** What the caller's thread holds a `Comlink.Remote` of. */