@trylimbo/sdk-verifier-wasm 0.2.12-canary.26 → 0.2.12-canary.29

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.
@@ -20,7 +20,7 @@ export interface RangeSource {
20
20
  * list, e.g. `io.iscc.v0`) plus its algorithm-specific value (the `ISCC:…` code,
21
21
  * a watermark token, …). The signer embeds it as a `c2pa.soft-binding` assertion
22
22
  * and indexes it, so a transcoded copy whose exact content hash no longer
23
- * matches still recovers the manifest from the registry.
23
+ * matches still recovers the manifest from the repository.
24
24
  */
25
25
  export interface SoftBinding {
26
26
  /**
@@ -30,18 +30,25 @@ export interface SoftBinding {
30
30
  /**
31
31
  * Algorithm-specific binding value: the canonical string the algorithm
32
32
  * produces (an `ISCC:…` code, a watermark token). Its UTF-8 bytes are what
33
- * the registry lookup base64-encodes.
33
+ * the repository lookup base64-encodes.
34
34
  */
35
35
  value: string;
36
36
  }
37
37
 
38
+ /**
39
+ * A binder spelled as data, so it crosses into a worker as well as the direct import: the
40
+ * SDK\'s own two. A browser has no host binder: a detector runs repository-side.
41
+ */
42
+ export type BinderSpec = { kind: "iscc" } | { kind: "held"; binding: SoftBinding };
43
+
38
44
  /**
39
45
  * A canonical gRPC/Connect status code: the coarse, closed failure class.
40
46
  *
41
- * The wasm lane projects this as the Connect `snake_case` string, so a consumer
42
- * narrows on `err.code === \"resource_exhausted\"`; the native lane projects an enum.
47
+ * The wasm lane projects this as a camelCase string like every other tagged value
48
+ * there, so a consumer narrows on `err.code === \"resourceExhausted\"`; the native lane
49
+ * projects an enum.
43
50
  */
44
- export type Code = "canceled" | "unknown" | "invalid_argument" | "deadline_exceeded" | "not_found" | "already_exists" | "permission_denied" | "resource_exhausted" | "failed_precondition" | "aborted" | "out_of_range" | "unimplemented" | "internal" | "unavailable" | "data_loss" | "unauthenticated";
51
+ export type Code = "canceled" | "unknown" | "invalidArgument" | "deadlineExceeded" | "notFound" | "alreadyExists" | "permissionDenied" | "resourceExhausted" | "failedPrecondition" | "aborted" | "outOfRange" | "unimplemented" | "internal" | "unavailable" | "dataLoss" | "unauthenticated";
45
52
 
46
53
  /**
47
54
  * A request-validation fault, `google.rpc.BadRequest` (`kind: \"invalid\"`).
@@ -96,70 +103,101 @@ export type ValidationState = "Invalid" | "Valid" | "Trusted";
96
103
 
97
104
  /**
98
105
  * Construction options for [`AssetVerifier::new`] (and the `AssetVerifier.create` JS
99
- * binding). `trust_c2pa_anchors` defaults to `true` when omitted.
106
+ * binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
100
107
  *
101
108
  * One definition, all lanes: `#[binding]` derives the shapes directly here:
102
- * tsify (camelCase, optional fields) on wasm, a `uniffi::Record` on the native
103
- * `ffi` build, so there is no per-lane DTO copy. Off both lanes it is a plain struct.
109
+ * tsify (camelCase) on wasm, a `uniffi::Record` on the native `ffi` build, so there is no
110
+ * per-lane DTO copy. Off both lanes it is a plain struct.
104
111
  */
105
112
  export interface AssetVerifierOptions {
106
113
  /**
107
- * The registry to recover from. Omit for a verifier that only checks embedded manifests.
114
+ * The C2PA manifest repositories recovery asks, each a Soft Binding Resolution API declared
115
+ * for exactly the algorithms it may be asked for. Results merge by manifest, and a match\'s
116
+ * `endpoint` is fetched from only when it names one of these. Empty: no recovery can be
117
+ * asked of this verifier.
108
118
  */
109
- registry?: RegistryOptions;
119
+ repositories: Repository[];
110
120
  /**
111
- * PEM trust anchors for the caller\'s own issuers.
121
+ * PEM trust anchors for the manifest signers the caller trusts.
112
122
  */
113
123
  trustAnchors: string[];
114
124
  /**
115
- * Also trust the bundled official C2PA anchors on top of `trust_anchors`.
116
- * Defaults to `true`; set `false` to trust only `trust_anchors`.
125
+ * PEM trust anchors for the time-stamping authorities the caller trusts.
126
+ */
127
+ tsaTrustAnchors: string[];
128
+ /**
129
+ * Also trust the bundled official C2PA anchors, manifest and TSA lists, beside the
130
+ * caller\'s. `false` trusts the caller\'s lists alone.
117
131
  */
118
- trustC2paAnchors?: boolean;
132
+ trustC2paAnchors: boolean;
119
133
  /**
120
134
  * Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched
121
- * exactly against the credential issuer. Omitted or empty trusts no issuer: every
122
- * identity assertion then reports `cawg.ica.untrusted_issuer` and withholds
123
- * `cawg.ica.credential_valid`, which leaves the manifest\'s own validity untouched.
135
+ * exactly against the credential issuer. Empty trusts no issuer: every identity assertion
136
+ * then reports `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`,
137
+ * which leaves the manifest\'s own validity untouched.
124
138
  */
125
- trustedIcaIssuers?: string[];
139
+ trustedIcaIssuers: string[];
126
140
  }
127
141
 
128
142
  /**
129
143
  * Construction options for [`StreamVerifier::new`] (and the `StreamVerifier.create`
130
- * JS binding). `trust_c2pa_anchors` defaults to `true` when omitted.
144
+ * JS binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
131
145
  *
132
- * `#[binding]` derives the wasm shape (`trustC2paAnchors` camelCase, optional) and,
146
+ * `#[binding]` derives the wasm shape (`trustC2paAnchors` camelCase) and,
133
147
  * with `ffi`, a `uniffi::Record` for the native `StreamVerifier.create` binding, so there
134
148
  * is no per-lane DTO copy. Off both lanes it is a plain struct.
135
149
  */
136
150
  export interface StreamVerifierOptions {
137
151
  /**
138
- * PEM trust anchors for the caller\'s own issuers.
152
+ * PEM trust anchors for the manifest signers the caller trusts.
139
153
  */
140
154
  trustAnchors: string[];
141
155
  /**
142
- * Also trust the bundled official C2PA anchors on top of `trust_anchors`.
143
- * Defaults to `true`; set `false` to trust only `trust_anchors`.
156
+ * PEM trust anchors for the time-stamping authorities the caller trusts.
157
+ */
158
+ tsaTrustAnchors: string[];
159
+ /**
160
+ * Also trust the bundled official C2PA anchors, manifest and TSA lists, beside the
161
+ * caller\'s. `false` trusts the caller\'s lists alone.
144
162
  */
145
- trustC2paAnchors?: boolean;
163
+ trustC2paAnchors: boolean;
146
164
  /**
147
165
  * Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched
148
- * exactly against the credential issuer. Omitted or empty trusts no issuer: an
149
- * identity assertion on the init segment\'s manifest then reports
150
- * `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`.
166
+ * exactly against the credential issuer. Empty trusts no issuer: an identity assertion
167
+ * on the init segment\'s manifest then reports `cawg.ica.untrusted_issuer` and withholds
168
+ * `cawg.ica.credential_valid`.
151
169
  */
152
- trustedIcaIssuers?: string[];
170
+ trustedIcaIssuers: string[];
153
171
  /**
154
172
  * How far a segment\'s timestamp may sit from wall-clock before it is rejected as
155
- * skewed. Defaults to [`DEFAULT_SEGMENT_SKEW_TOLERANCE_SECS`]. A deployment whose
156
- * encoder clock drifts further than that needs this rather than a fork.
173
+ * skewed, in seconds: the deployment\'s own encoder-clock allowance, stated rather than
174
+ * assumed.
157
175
  */
158
- segmentSkewToleranceSecs?: number;
176
+ segmentSkewToleranceSecs: number;
177
+ }
178
+
179
+ /**
180
+ * Everything one `derive` needs beyond the asset: how its format is known. The same record
181
+ * the native lane\'s `DeriveOptions` is, spelled as data.
182
+ */
183
+ export interface DeriveOptions {
184
+ format: AssetFormat;
159
185
  }
160
186
 
161
187
  /**
162
- * One C2PA validation status entry (spec §15.3).
188
+ * How a call knows the asset\'s format: stated by the caller, or read from the leading bytes.
189
+ * Stated, never defaulted: sniffing is a choice made by name.
190
+ */
191
+ export type AssetFormat = { kind: "sniff" } | { kind: "declared"; mediaType: string };
192
+
193
+ /**
194
+ * One C2PA manifest repository, as the Soft Binding Resolution API spec lets a client find it.
195
+ */
196
+ export type Repository = { kind: "named"; url: string; algorithms: string[] } | { kind: "listed"; algorithm: string };
197
+
198
+ /**
199
+ * One C2PA validation status entry (spec §15.3): the registered code, its kind, and the
200
+ * spec\'s own free-text `explanation`, which is where anything finer than the code lives.
163
201
  */
164
202
  export interface ValidationCode {
165
203
  /**
@@ -167,6 +205,11 @@ export interface ValidationCode {
167
205
  */
168
206
  code: string;
169
207
  kind: ValidationCodeKind;
208
+ /**
209
+ * Prose for a reader, never a value to branch on: a stream failure names which of the
210
+ * registered code\'s listed causes it hit here.
211
+ */
212
+ explanation?: string;
170
213
  }
171
214
 
172
215
  /**
@@ -178,37 +221,11 @@ export interface FieldViolation {
178
221
  reason: string;
179
222
  }
180
223
 
181
- /**
182
- * One `matches/byContent` upload per selected detector.
183
- */
184
- export interface ByContent {
185
- after: ContentTrigger;
186
- detectors: Detectors;
187
- }
188
-
189
- /**
190
- * One `matches/byReference` query per selected detector. The registry downloads the asset
191
- * from `url`, so the client reads no bytes for it.
192
- */
193
- export interface ByReference {
194
- after: ContentTrigger;
195
- detectors: Detectors;
196
- /**
197
- * A short-lived https URL without credentials.
198
- */
199
- url: string;
200
- /**
201
- * The asset\'s size in bytes, which caps the registry\'s download.
202
- */
203
- length: number;
204
- mediaType?: string;
205
- }
206
-
207
224
  /**
208
225
  * One `verify` credential: the c2pa `ManifestStore`, where it came from, whether the asset\'s
209
226
  * own fingerprint backs it up, and whether its hard binding holds over the bytes read.
210
227
  */
211
- export interface FoundCredential {
228
+ export interface Credential {
212
229
  /**
213
230
  * The bytes behind every thumbnail the manifests reference, by that reference\'s
214
231
  * `identifier`: each manifest\'s claim thumbnail and each ingredient\'s. The manifests state
@@ -220,10 +237,6 @@ export interface FoundCredential {
220
237
  */
221
238
  origin: CredentialOrigin;
222
239
  manifest: import('@contentauth/c2pa-types').ManifestStore;
223
- /**
224
- * Whether the asset\'s own fingerprint backs up a mark that led here (C2PA 2.4 1.2.2.3).
225
- */
226
- fingerprintCheck: FingerprintCheck;
227
240
  /**
228
241
  * Whether the manifest\'s hard binding holds over the bytes this verify read.
229
242
  */
@@ -256,7 +269,7 @@ export interface InitValidation {
256
269
  }
257
270
 
258
271
  /**
259
- * Result of `StreamValidation.validate`, discriminated by `kind`.
272
+ * Result of `StreamSession.validate`, discriminated by `kind`.
260
273
  */
261
274
  export type SegmentValidation = ({ kind: "init" } & InitValidation) | ({ kind: "media" } & MediaValidation) | { kind: "unknown" };
262
275
 
@@ -287,51 +300,21 @@ export interface SegmentTiming {
287
300
  }
288
301
 
289
302
  /**
290
- * What one verify may do with the registry. Required whenever a registry is configured.
291
- *
292
- * One field per Soft Binding Resolution API operation, and an absent one is not called.
293
- * `matches/byBinding` is decided by the binders handed to the verify: each is derived and looked
294
- * up, all together, and every result is kept. The content forms run after that, each for the
295
- * detectors it names, hinted with the first fingerprint the binders derived. Results merge by
296
- * manifest; nothing is ranked or dropped.
303
+ * What one verify may do to recover a manifest, as data: the binders this client derives for
304
+ * itself, decided into `matches/byBinding`, and one field per content operation, absent when
305
+ * not to be called. It needs a configured repository and at least one query.
297
306
  */
298
307
  export interface Recovery {
299
- /**
300
- * When the registry is consulted at all.
301
- */
302
- when: RecoveryPolicy;
303
- /**
304
- * `matches/byContent`: the bounded asset bytes travel in the request.
305
- */
308
+ when: RecoveryTrigger;
309
+ binders: BinderSpec[];
306
310
  byContent?: ByContent;
307
- /**
308
- * `matches/byReference`: the registry fetches the asset from the caller\'s URL instead, for
309
- * an asset above the upload cap.
310
- */
311
311
  byReference?: ByReference;
312
312
  }
313
313
 
314
314
  /**
315
- * When [`AssetVerifier::verify_asset`] queries the registry.
316
- */
317
- export type RecoveryPolicy = "whenMissing" | "always";
318
-
319
- /**
320
- * Where the registry is. What a verify may do with it is per call, in [`Recovery`].
315
+ * When [`AssetVerifier::verify_asset`] queries the repository.
321
316
  */
322
- export interface RegistryOptions {
323
- /**
324
- * Soft Binding Resolution API base URL (`https://registry.trylimbo.com`).
325
- */
326
- url: string;
327
- /**
328
- * Federated resolution APIs a match may name as holding its manifest, beside the ones the
329
- * C2PA algorithm list publishes, which are always allowed. C2PA 2.4 lets a match carry an
330
- * `endpoint`; one allowed is fetched from, any other is reported as refused. Checked like
331
- * `url`: https, or http on loopback only.
332
- */
333
- endpoints?: string[];
334
- }
317
+ export type RecoveryTrigger = "manifestMissing" | "always";
335
318
 
336
319
  /**
337
320
  * Whether a code is a success, an informational note, or a failure.
@@ -344,17 +327,23 @@ export type ValidationCodeKind = "success" | "informational" | "failure";
344
327
  export type ContentTrigger = "byBindingMisses" | "always";
345
328
 
346
329
  /**
347
- * Which advertised server-side detectors a content form runs. Every selected detector runs,
348
- * including one a local binder already queried by binding.
330
+ * [`crate::asset::ByReference`] as JS states it: the region is the `Range` of
331
+ * `@contentauth/c2pa-types`, the shape a credential\'s actions carry.
349
332
  */
350
- export type Detectors = { kind: "fingerprint" } | { kind: "watermark" } | { kind: "all" } | { kind: "named"; algorithms: string[] };
333
+ export interface ByReference {
334
+ after: ContentTrigger;
335
+ url: string;
336
+ length: number;
337
+ mediaType?: string;
338
+ region: import('@contentauth/c2pa-types').Range[];
339
+ }
351
340
 
352
341
  /**
353
342
  * [`crate::asset::CredentialOrigin`] as JS sees it: a tagged union, since each way of finding a
354
343
  * credential carries different evidence. Lane-local for the same reason [`FingerprintCheck`] is: a
355
344
  * tag layout is what `#[binding(wasm)]` declines to express.
356
345
  */
357
- export type CredentialOrigin = { kind: "embedded" } | { kind: "recovered"; discoveries: RecoveryDiscovery[] };
346
+ export type CredentialOrigin = { kind: "embedded" } | { kind: "recovered"; discoveries: RecoveryDiscovery[]; fingerprintCheck: FingerprintCheck };
358
347
 
359
348
  /**
360
349
  * [`crate::asset::FingerprintCheck`] as JS sees it: a tagged union, since `compared` carries a
@@ -366,7 +355,7 @@ export type FingerprintCheck = { kind: "notNeeded" } | { kind: "nothingToCompare
366
355
  /**
367
356
  * [`crate::asset::HardBinding`] as JS sees it.
368
357
  */
369
- export type HardBinding = "holds" | "mismatch";
358
+ export type HardBinding = "match" | "mismatch";
370
359
 
371
360
  /**
372
361
  * [`crate::asset::Lineage`] as JS sees it.
@@ -379,7 +368,7 @@ export interface Lineage {
379
368
  /**
380
369
  * [`crate::asset::RecoveryIssue`] as JS sees it: a tagged union, each kind with its own data.
381
370
  */
382
- export type RecoveryIssue = { kind: "binder"; binderIndex: number; message: string } | { kind: "deprecatedAlgorithm"; algorithm: string } | { kind: "bindingQuery"; binderIndex: number; algorithm: string; message: string } | { kind: "queryRefused"; algorithm: string; message: string } | { kind: "contentForm"; message: string } | { kind: "contentQuery"; algorithm: string; message: string } | { kind: "capabilities"; message: string } | { kind: "contentTooLarge"; capBytes: number } | { kind: "candidateFetch"; manifestId: string; message: string } | { kind: "candidateValidation"; manifestId: string; reason: string } | { kind: "endpointRefused"; manifestId: string; endpoint: string } | { kind: "resourceLimit"; message: string };
371
+ export type RecoveryIssue = { kind: "binderFailed"; binderIndex: number; message: string } | { kind: "algorithmDeprecated"; algorithm: string } | { kind: "bindingUndeclared"; binderIndex: number; algorithm: string } | { kind: "bindingQueryFailed"; repository: string; binderIndex: number; algorithm: string; message: string } | { kind: "queryRefused"; repository: string; algorithm: string; message: string } | { kind: "contentFormUnsupported"; repository: string; message: string } | { kind: "contentQueryFailed"; repository: string; algorithm: string; message: string } | { kind: "capabilitiesUnavailable"; repository: string; message: string } | { kind: "contentTooLarge"; capBytes: number } | { kind: "candidateFetchFailed"; repository: string; manifestId: string; message: string } | { kind: "candidateInvalid"; manifestId: string; reason: string } | { kind: "endpointRefused"; repository: string; manifestId: string; endpoint: string } | { kind: "resourceLimitReached"; message: string };
383
372
 
384
373
  /**
385
374
  * [`crate::asset::VerdictRule`] as JS sees it.
@@ -391,8 +380,16 @@ export type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
391
380
  */
392
381
  export type Verdict = { kind: "unsigned" } | { kind: "inconclusive" } | { kind: "embedded" } | { kind: "recovered"; index: number; decidedBy: VerdictRule } | { kind: "recoveredDerivative"; index: number; decidedBy: VerdictRule } | { kind: "ambiguous"; candidates: number[] };
393
382
 
383
+ /**
384
+ * `matches/byContent`: the asset is uploaded to each repository, one request per algorithm that
385
+ * repository is declared for.
386
+ */
387
+ export interface ByContent {
388
+ after: ContentTrigger;
389
+ }
390
+
394
391
  export interface AssetVerification {
395
- credentials: FoundCredential[];
392
+ credentials: Credential[];
396
393
  recovery: RecoverySummary;
397
394
  goldenComparison: GoldenComparison;
398
395
  verdict: Verdict;
@@ -407,7 +404,7 @@ export type ContentBindingClass = "fingerprint" | "watermark";
407
404
 
408
405
  export type GoldenComparison = { kind: "notRequested" } | { kind: "noEmbeddedManifest" } | { kind: "noRecoveredManifest" } | { kind: "recoveryIncomplete" } | { kind: "matches"; recoveredIndex: number } | { kind: "differs"; recoveredIndex: number } | { kind: "noneMatches"; candidates: number[] } | { kind: "unreadable"; recoveredIndex: number };
409
406
 
410
- export type RecoveryDiscovery = { method: "byBinding"; class: ContentBindingClass; binding: SoftBinding; binderIndex: number; registryScore: number | undefined; endpoint: string | undefined } | { method: "byContent"; hint: SoftBinding | undefined; class: ContentBindingClass; algorithm: string; registryScore: number | undefined; endpoint: string | undefined } | { method: "byReference"; hint: SoftBinding | undefined; class: ContentBindingClass; algorithm: string; registryScore: number | undefined; endpoint: string | undefined };
407
+ export type RecoveryDiscovery = { kind: "byBinding"; class: ContentBindingClass; binding: SoftBinding; binderIndex: number; repositoryScore: number | undefined; repository: string; fetchedFrom: string } | { kind: "byContent"; hint: SoftBinding | undefined; class: ContentBindingClass; algorithm: string; repositoryScore: number | undefined; repository: string; fetchedFrom: string } | { kind: "byReference"; hint: SoftBinding | undefined; class: ContentBindingClass; algorithm: string; repositoryScore: number | undefined; repository: string; fetchedFrom: string };
411
408
 
412
409
  export type RecoveryStatus = "notRequested" | "notFound" | "recovered" | "incomplete";
413
410
 
@@ -430,40 +427,10 @@ export class AssetVerifier {
430
427
  *
431
428
  * # Errors
432
429
  *
433
- * Throws on a malformed `input`, a registry (or binder) failure, or a validation
430
+ * Throws on a malformed `input`, a repository (or binder) failure, or a validation
434
431
  * failure.
435
432
  */
436
- verify(input: RangeSource, options: VerifyOptions): Promise<AssetVerification>;
437
- }
438
-
439
- /**
440
- * A soft-binding binder a client runs itself. Build with `Binder.iscc()` or
441
- * `Binder.held(binding)`, and pass a list to `verify`.
442
- *
443
- * Vendor watermark detection is registry-side in this SDK: configured detectors participate in
444
- * `verify` through `byContent`, while `Binder.held` covers values already available to the caller.
445
- */
446
- export class Binder {
447
- private constructor();
448
- free(): void;
449
- [Symbol.dispose](): void;
450
- /**
451
- * Derive this binder's binding standalone; `undefined` when it finds none.
452
- * Input is a `RangeSource` (format inferred from content when omitted).
453
- *
454
- * # Errors
455
- *
456
- * Throws on malformed or unreadable input.
457
- */
458
- derive(content: RangeSource, format?: string | null): Promise<SoftBinding | undefined>;
459
- /**
460
- * A binder contributing a binding you already hold (e.g. an out-of-band video ISCC).
461
- */
462
- static held(binding: SoftBinding): Binder;
463
- /**
464
- * Local ISCC Image-Code for supported image formats.
465
- */
466
- static iscc(): Binder;
433
+ verify(input: RangeSource, recovery?: Recovery | null): Promise<AssetVerification>;
467
434
  }
468
435
 
469
436
  /**
@@ -527,6 +494,30 @@ export function C2PA_TSA_TRUST_LIST(): string;
527
494
 
528
495
  export function DEV_CA(): string;
529
496
 
497
+ /**
498
+ * A binder contributing a binding you already hold (e.g. an out-of-band video ISCC):
499
+ * `new HeldBinder(binding)`, the spelling the native lane uses. A verify takes it as data,
500
+ * `{ kind: "held", binding }`, in `recovery.binders`.
501
+ */
502
+ export class HeldBinder {
503
+ free(): void;
504
+ [Symbol.dispose](): void;
505
+ /**
506
+ * Hand back the held binding; reads nothing.
507
+ *
508
+ * # Errors
509
+ *
510
+ * Throws when the source cannot be opened.
511
+ */
512
+ derive(content: RangeSource, options: DeriveOptions): Promise<SoftBinding | undefined>;
513
+ /**
514
+ * # Errors
515
+ *
516
+ * Throws `SdkError.invalid` on a binding with an empty algorithm or value.
517
+ */
518
+ constructor(binding: SoftBinding);
519
+ }
520
+
530
521
  export class IntoUnderlyingByteSource {
531
522
  private constructor();
532
523
  free(): void;
@@ -555,6 +546,28 @@ export class IntoUnderlyingSource {
555
546
  pull(controller: ReadableStreamDefaultController): Promise<any>;
556
547
  }
557
548
 
549
+ /**
550
+ * The SDK's local ISCC Image-Code binder, for a standalone `derive`: `new IsccBinder()`, the
551
+ * spelling the native lane uses. A verify takes it as data, `{ kind: "iscc" }`, in
552
+ * `recovery.binders`, because a class cannot cross into a worker.
553
+ *
554
+ * Vendor watermark detection is repository-side in this SDK: configured detectors participate in
555
+ * `verify` through `byContent`, while a held binder covers values already available to the caller.
556
+ */
557
+ export class IsccBinder {
558
+ free(): void;
559
+ [Symbol.dispose](): void;
560
+ /**
561
+ * Derive the asset's ISCC standalone; `undefined` when the format yields none.
562
+ *
563
+ * # Errors
564
+ *
565
+ * Throws on malformed or unreadable input.
566
+ */
567
+ derive(content: RangeSource, options: DeriveOptions): Promise<SoftBinding | undefined>;
568
+ constructor();
569
+ }
570
+
558
571
  /**
559
572
  * An in-memory [`RangeSource`](crate::wasm::RangeInput), for a caller that already holds the whole
560
573
  * asset as bytes.
@@ -578,7 +591,7 @@ export class MemorySource {
578
591
  * One stream being validated. It owns the session keys and manifest ids its init segments
579
592
  * advertised, so releasing the stream is dropping this object.
580
593
  */
581
- export class StreamValidation {
594
+ export class StreamSession {
582
595
  private constructor();
583
596
  free(): void;
584
597
  [Symbol.dispose](): void;
@@ -621,14 +634,14 @@ export class StreamVerifier {
621
634
  */
622
635
  static create(options: StreamVerifierOptions): StreamVerifier;
623
636
  /**
624
- * Open `stream_id` for validation, handing back a `StreamValidation` to feed segments to.
637
+ * Open `stream_id` for validation, handing back a `StreamSession` to feed segments to.
625
638
  *
626
639
  * No I/O: the handle carries the id so it cannot be mistyped or confused with another
627
640
  * stream's, and classification still happens per segment. Opening one id twice hands
628
641
  * back the same live session, so a component that remounts keeps the state its earlier
629
642
  * handle accumulated.
630
643
  */
631
- open(stream_id: string): StreamValidation;
644
+ open(stream_id: string): StreamSession;
632
645
  /**
633
646
  * Open `stream_id` on the state another node exported, merged into whatever this one
634
647
  * holds for that id already.
@@ -636,24 +649,15 @@ export class StreamVerifier {
636
649
  * # Errors
637
650
  *
638
651
  * Throws an `SdkError` (`STREAM_INVALID`) when `state` is not a value
639
- * `StreamValidation.export` produced, or carries a version this SDK no longer reads.
652
+ * `StreamSession.export` produced, or carries a version this SDK no longer reads.
640
653
  */
641
- resume(stream_id: string, state: Uint8Array): StreamValidation;
642
- }
643
-
644
- /**
645
- * Per-call soft-binding inputs. `recovery` is required when the verifier has a registry.
646
- */
647
- export class VerifyOptions {
648
- free(): void;
649
- [Symbol.dispose](): void;
650
- constructor(binders: Binder[], recovery?: Recovery | null);
654
+ resume(stream_id: string, state: Uint8Array): StreamSession;
651
655
  }
652
656
 
653
657
  export function init_panic_hook(): void;
654
658
 
655
659
  /**
656
- * Parse a detached C2PA manifest store: a `.c2pa` sidecar, or the bytes a registry serves for a
660
+ * Parse a detached C2PA manifest store: a `.c2pa` sidecar, or the bytes a repository serves for a
657
661
  * manifest id.
658
662
  *
659
663
  * Contents, not a verdict. A hard binding is a hash of the asset, so a store read without one
@@ -706,7 +710,8 @@ export interface InitOutput {
706
710
  readonly __wbg_blobsource_free: (a: number, b: number) => void;
707
711
  readonly __wbg_bytessource_free: (a: number, b: number) => void;
708
712
  readonly __wbg_memorysource_free: (a: number, b: number) => void;
709
- readonly __wbg_verifyoptions_free: (a: number, b: number) => void;
713
+ readonly __wbg_streamsession_free: (a: number, b: number) => void;
714
+ readonly __wbg_streamverifier_free: (a: number, b: number) => void;
710
715
  readonly assetverifier_create: (a: any) => [number, number, number];
711
716
  readonly assetverifier_verify: (a: number, b: any, c: number) => any;
712
717
  readonly blobsource_length: (a: number) => number;
@@ -720,23 +725,22 @@ export interface InitOutput {
720
725
  readonly memorysource_readAt: (a: number, b: number, c: number) => any;
721
726
  readonly parse: (a: number, b: number) => [number, number, number];
722
727
  readonly resource: (a: number, b: number, c: number, d: number) => [number, number, number, number];
728
+ readonly streamsession_export: (a: number) => [number, number, number, number];
729
+ readonly streamsession_validate: (a: number, b: any) => any;
730
+ readonly streamverifier_create: (a: any) => [number, number, number];
731
+ readonly streamverifier_open: (a: number, b: number, c: number) => number;
732
+ readonly streamverifier_resume: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
723
733
  readonly thumbnails: (a: number, b: number) => [number, number, number];
724
- readonly verifyoptions_new: (a: number, b: number, c: number) => number;
725
- readonly __wbg_binder_free: (a: number, b: number) => void;
726
- readonly binder_derive: (a: number, b: any, c: number, d: number) => any;
727
- readonly binder_held: (a: any) => [number, number, number];
728
- readonly binder_iscc: () => number;
729
734
  readonly C2PA_TRUST_LIST: () => [number, number];
730
735
  readonly C2PA_TSA_TRUST_LIST: () => [number, number];
731
736
  readonly DEV_CA: () => [number, number];
732
737
  readonly init_panic_hook: () => void;
733
- readonly __wbg_streamvalidation_free: (a: number, b: number) => void;
734
- readonly __wbg_streamverifier_free: (a: number, b: number) => void;
735
- readonly streamvalidation_export: (a: number) => [number, number, number, number];
736
- readonly streamvalidation_validate: (a: number, b: any) => any;
737
- readonly streamverifier_create: (a: any) => [number, number, number];
738
- readonly streamverifier_open: (a: number, b: number, c: number) => number;
739
- readonly streamverifier_resume: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
738
+ readonly __wbg_heldbinder_free: (a: number, b: number) => void;
739
+ readonly __wbg_isccbinder_free: (a: number, b: number) => void;
740
+ readonly heldbinder_derive: (a: number, b: any, c: any) => any;
741
+ readonly heldbinder_new: (a: any) => [number, number, number];
742
+ readonly isccbinder_derive: (a: number, b: any, c: any) => any;
743
+ readonly isccbinder_new: () => number;
740
744
  readonly __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
741
745
  readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
742
746
  readonly intounderlyingbytesource_cancel: (a: number) => void;