@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.
@@ -16,37 +16,31 @@ export interface RangeSource {
16
16
 
17
17
 
18
18
  /**
19
- * A C2PA soft binding: an algorithm id (from the C2PA soft-binding algorithm
20
- * list, e.g. `io.iscc.v0`) plus its algorithm-specific value (the `ISCC:…` code,
21
- * a watermark token, …). The signer embeds it as a `c2pa.soft-binding` assertion
22
- * and indexes it, so a transcoded copy whose exact content hash no longer
23
- * matches still recovers the manifest from the repository.
19
+ * A `soft-binding-block-map`. No scope is the whole content.
24
20
  */
25
- export interface SoftBinding {
26
- /**
27
- * C2PA soft-binding algorithm id, e.g. `io.iscc.v0`.
28
- */
29
- alg: string;
30
- /**
31
- * Algorithm-specific binding value: the canonical string the algorithm
32
- * produces (an `ISCC:…` code, a watermark token). Its UTF-8 bytes are what
33
- * the repository lookup base64-encodes.
34
- */
35
- value: string;
21
+ export interface Block {
22
+ value: Uint8Array;
23
+ scope?: Scope;
36
24
  }
37
25
 
38
26
  /**
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.
27
+ * A `soft-binding-scope-map`.
41
28
  */
42
- export type BinderSpec = { kind: "iscc" } | { kind: "held"; binding: SoftBinding };
29
+ export interface Scope {
30
+ timespan?: Timespan;
31
+ }
32
+
33
+ /**
34
+ * A `soft-binding-timespan-map`: where the range starts in the media and how long it lasts, in
35
+ * milliseconds.
36
+ */
37
+ export interface Timespan {
38
+ start: number;
39
+ duration: number;
40
+ }
43
41
 
44
42
  /**
45
43
  * A canonical gRPC/Connect status code: the coarse, closed failure class.
46
- *
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.
50
44
  */
51
45
  export type Code = "canceled" | "unknown" | "invalidArgument" | "deadlineExceeded" | "notFound" | "alreadyExists" | "permissionDenied" | "resourceExhausted" | "failedPrecondition" | "aborted" | "outOfRange" | "unimplemented" | "internal" | "unavailable" | "dataLoss" | "unauthenticated";
52
46
 
@@ -77,11 +71,11 @@ export interface ReasonError {
77
71
  /**
78
72
  * A session signing key from the init manifest\'s roster (spec §19.4.4).
79
73
  */
80
- export interface SessionKeySummary {
74
+ export interface SessionKey {
81
75
  /**
82
76
  * Identifier of the session signing key.
83
77
  */
84
- keyId: Uint8Array;
78
+ kid: Uint8Array;
85
79
  /**
86
80
  * The session key\'s public half (SEC1-encoded bytes).
87
81
  */
@@ -97,103 +91,33 @@ export interface StatusError {
97
91
  }
98
92
 
99
93
  /**
100
- * C2PA validation state of a manifest (spec §14.3).
101
- */
102
- export type ValidationState = "Invalid" | "Valid" | "Trusted";
103
-
104
- /**
105
- * Construction options for [`AssetVerifier::new`] (and the `AssetVerifier.create` JS
106
- * binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
107
- *
108
- * One definition, all lanes: `#[binding]` derives the shapes directly here:
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.
111
- */
112
- export interface AssetVerifierOptions {
113
- /**
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.
118
- */
119
- repositories: Repository[];
120
- /**
121
- * PEM trust anchors for the manifest signers the caller trusts.
122
- */
123
- trustAnchors: string[];
124
- /**
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.
131
- */
132
- trustC2paAnchors: boolean;
133
- /**
134
- * Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched
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.
138
- */
139
- trustedIcaIssuers: string[];
140
- }
141
-
142
- /**
143
- * Construction options for [`StreamVerifier::new`] (and the `StreamVerifier.create`
144
- * JS binding). Every field is stated: nothing here is chosen on the caller\'s behalf.
145
- *
146
- * `#[binding]` derives the wasm shape (`trustC2paAnchors` camelCase) and,
147
- * with `ffi`, a `uniffi::Record` for the native `StreamVerifier.create` binding, so there
148
- * is no per-lane DTO copy. Off both lanes it is a plain struct.
94
+ * An asset a repository downloads, as the `byReference` request body names it.
149
95
  */
150
- export interface StreamVerifierOptions {
151
- /**
152
- * PEM trust anchors for the manifest signers the caller trusts.
153
- */
154
- trustAnchors: string[];
96
+ export interface Reference {
155
97
  /**
156
- * PEM trust anchors for the time-stamping authorities the caller trusts.
98
+ * A short-lived https URL without credentials.
157
99
  */
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.
162
- */
163
- trustC2paAnchors: boolean;
100
+ url: string;
164
101
  /**
165
- * Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched
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`.
102
+ * The asset\'s size in bytes.
169
103
  */
170
- trustedIcaIssuers: string[];
104
+ length: number;
171
105
  /**
172
- * How far a segment\'s timestamp may sit from wall-clock before it is rejected as
173
- * skewed, in seconds: the deployment\'s own encoder-clock allowance, stated rather than
174
- * assumed.
106
+ * The asset\'s media type.
175
107
  */
176
- segmentSkewToleranceSecs: number;
108
+ format?: string;
109
+ ranges?: import('@contentauth/c2pa-types').Range[];
177
110
  }
178
111
 
179
112
  /**
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;
185
- }
186
-
187
- /**
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.
113
+ * C2PA validation state of a manifest (spec §14.3).
190
114
  */
191
- export type AssetFormat = { kind: "sniff" } | { kind: "declared"; mediaType: string };
115
+ export type ValidationState = "Invalid" | "Valid" | "Trusted";
192
116
 
193
117
  /**
194
118
  * One C2PA manifest repository, as the Soft Binding Resolution API spec lets a client find it.
195
119
  */
196
- export type Repository = { kind: "named"; url: string; algorithms: string[] } | { kind: "listed"; algorithm: string };
120
+ export type Repository = { kind: "named"; url: string; algorithms: string[] } | { kind: "registered"; alg: string };
197
121
 
198
122
  /**
199
123
  * One C2PA validation status entry (spec §15.3): the registered code, its kind, and the
@@ -227,13 +151,7 @@ export interface FieldViolation {
227
151
  */
228
152
  export interface Credential {
229
153
  /**
230
- * The bytes behind every thumbnail the manifests reference, by that reference\'s
231
- * `identifier`: each manifest\'s claim thumbnail and each ingredient\'s. The manifests state
232
- * identifiers and no images, so this is what a chain draws from.
233
- */
234
- thumbnails: Record<string, Uint8Array>;
235
- /**
236
- * Where this credential came from. See [`CredentialOrigin`].
154
+ * Where this credential came from.
237
155
  */
238
156
  origin: CredentialOrigin;
239
157
  manifest: import('@contentauth/c2pa-types').ManifestStore;
@@ -242,18 +160,40 @@ export interface Credential {
242
160
  */
243
161
  hardBinding: HardBinding;
244
162
  /**
245
- * Where this credential sits among the others returned. See [`crate::asset::Lineage`].
163
+ * Where this credential sits among the others returned.
246
164
  */
247
165
  lineage: Lineage;
248
166
  }
249
167
 
168
+ /**
169
+ * One query that located a recovered credential: how it was asked, under which algorithm, and
170
+ * where the manifest came from.
171
+ */
172
+ export interface Discovery {
173
+ via: DiscoveryVia;
174
+ alg: string;
175
+ type: SoftBindingType;
176
+ /**
177
+ * 0-100, the repository\'s `similarityScore`.
178
+ */
179
+ score?: number;
180
+ repository: string;
181
+ /**
182
+ * The resolution API the manifest was fetched from, when not `repository`.
183
+ */
184
+ endpoint?: string;
185
+ }
186
+
250
187
  /**
251
188
  * Outcome of validating a media segment against its stream\'s init.
252
189
  */
253
190
  export interface MediaValidation {
254
- valid: boolean;
191
+ /**
192
+ * `invalid` on any failure, else the state of the init manifest the segment\'s key came from.
193
+ */
194
+ state: ValidationState;
255
195
  codes: ValidationCode[];
256
- keyId: Uint8Array;
196
+ kid: Uint8Array;
257
197
  timing: SegmentTiming;
258
198
  manifestId: string;
259
199
  }
@@ -265,7 +205,7 @@ export interface InitValidation {
265
205
  state: ValidationState;
266
206
  codes: ValidationCode[];
267
207
  manifest: import('@contentauth/c2pa-types').ManifestStore;
268
- sessionKeys: SessionKeySummary[];
208
+ sessionKeys: SessionKey[];
269
209
  }
270
210
 
271
211
  /**
@@ -273,125 +213,202 @@ export interface InitValidation {
273
213
  */
274
214
  export type SegmentValidation = ({ kind: "init" } & InitValidation) | ({ kind: "media" } & MediaValidation) | { kind: "unknown" };
275
215
 
216
+ /**
217
+ * The C2PA 2.4 golden-flow comparison of the embedded manifest against what the repository holds.
218
+ */
219
+ export type Golden = { kind: "matches"; index: number } | { kind: "differs"; index: number } | { kind: "noneMatches"; candidates: number[] } | { kind: "unreadable"; index: number };
220
+
221
+ /**
222
+ * The C2PA list\'s `type` of a soft binding algorithm.
223
+ */
224
+ export type SoftBindingType = "fingerprint" | "watermark";
225
+
226
+ /**
227
+ * The Soft Binding Resolution API route a discovery came through.
228
+ */
229
+ export type DiscoveryVia = { kind: "byBinding"; value: Uint8Array } | { kind: "byContent"; hint?: Hint } | { kind: "byReference"; hint?: Hint };
230
+
276
231
  /**
277
232
  * The error every SDK call throws: a decoded `google.rpc.Status`, discriminated
278
233
  * by `kind`. A consumer switches on `err.kind` (`\"reason\" | \"invalid\" | \"status\"`)
279
234
  * and reads the shape-specific fields; `code` and `message` are common to every
280
- * shape. Thrown as a plain object across the wasm boundary (tsify).
235
+ * shape.
281
236
  */
282
237
  export type SdkError = ({ kind: "status" } & StatusError) | ({ kind: "reason" } & ReasonError) | ({ kind: "invalid" } & InvalidError);
283
238
 
284
239
  /**
285
- * Timing facts carried by a media segment\'s container.
240
+ * The evidence that singled a recovered verdict out.
286
241
  */
287
- export interface SegmentTiming {
242
+ export type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
243
+
244
+ /**
245
+ * The query a repository answers from the content: `matches/byReference` when `reference` is
246
+ * stated, so nothing is uploaded, else `matches/byContent` with the asset in the request.
247
+ */
248
+ export interface Content {
249
+ when: ContentWhen;
288
250
  /**
289
- * Media segment sequence number (exact below 2^53).
251
+ * Where each repository downloads the asset from.
290
252
  */
291
- sequenceNumber: number;
253
+ reference?: Reference;
292
254
  /**
293
- * MP4 timescale (ticks per second) for this segment\'s timing, if present.
255
+ * The largest asset an upload sends, in bytes; a larger one is reported `tooLarge`. Absent,
256
+ * 64 MiB.
294
257
  */
295
- timescale?: number;
258
+ maxUploadBytes?: number;
259
+ }
260
+
261
+ /**
262
+ * The re-sign chain between the returned credentials, by manifest label.
263
+ */
264
+ export interface Lineage {
265
+ supersedes: string[];
266
+ supersededBy: string[];
267
+ }
268
+
269
+ /**
270
+ * The value a content query was hinted with, under its own algorithm.
271
+ */
272
+ export interface Hint {
273
+ alg: string;
274
+ value: Uint8Array;
275
+ }
276
+
277
+ /**
278
+ * Timing a media segment\'s container carries.
279
+ */
280
+ export interface SegmentTiming {
281
+ /**
282
+ * The segment\'s `sequenceNumber` (exact below 2^53).
283
+ */
284
+ sequence: number;
296
285
  /**
297
- * Segment duration in seconds, if the container reports it.
286
+ * The span its C2PA `emsg` covers, in milliseconds.
298
287
  */
299
- eventDurationSecs?: number;
288
+ duration?: number;
300
289
  }
301
290
 
302
291
  /**
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.
292
+ * What a stream verifier trusts, and how far a segment\'s clock may drift.
306
293
  */
307
- export interface Recovery {
308
- when: RecoveryTrigger;
309
- binders: BinderSpec[];
310
- byContent?: ByContent;
311
- byReference?: ByReference;
294
+ export interface StreamVerifierOptions {
295
+ trust: Trust;
296
+ /**
297
+ * How far a segment\'s presentation time may sit outside its session key\'s validity period,
298
+ * in milliseconds. Absent, 5 minutes.
299
+ */
300
+ skewTolerance?: number;
312
301
  }
313
302
 
314
303
  /**
315
- * When [`AssetVerifier::verify_asset`] queries the repository.
304
+ * What a verifier trusts. An omitted list trusts nothing.
316
305
  */
317
- export type RecoveryTrigger = "manifestMissing" | "always";
306
+ export interface Trust {
307
+ /**
308
+ * PEM anchors for the manifest signers the caller trusts.
309
+ */
310
+ anchors?: string[];
311
+ /**
312
+ * PEM anchors for the time-stamping authorities the caller trusts.
313
+ */
314
+ tsaAnchors?: string[];
315
+ /**
316
+ * Also trust the bundled official C2PA manifest and TSA lists, beside the caller\'s.
317
+ */
318
+ c2pa: boolean;
319
+ /**
320
+ * Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched exactly
321
+ * against the credential issuer. Empty trusts no issuer: every identity assertion then
322
+ * reports `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`, which leaves
323
+ * the manifest\'s own validity untouched.
324
+ */
325
+ icaIssuers?: string[];
326
+ }
318
327
 
319
328
  /**
320
- * Whether a code is a success, an informational note, or a failure.
329
+ * What an asset verifier trusts and which repositories it may ask. An omitted list trusts or
330
+ * asks nothing.
321
331
  */
322
- export type ValidationCodeKind = "success" | "informational" | "failure";
332
+ export interface AssetVerifierOptions {
333
+ /**
334
+ * The C2PA manifest repositories recovery asks, each a Soft Binding Resolution API declared
335
+ * for exactly the algorithms it may be asked for. Results merge by manifest, and a match\'s
336
+ * `endpoint` is fetched from only when it names one of these. Empty: no recovery can be
337
+ * asked of this verifier.
338
+ */
339
+ repositories?: Repository[];
340
+ trust: Trust;
341
+ }
323
342
 
324
343
  /**
325
- * Whether a content form runs on this verify. Judged against the byBinding results alone.
344
+ * What one verify may do to recover a manifest, as data: the soft bindings this client looks up
345
+ * itself through `matches/byBinding`, and the content query, absent when not to be asked. It
346
+ * needs a configured repository and at least one query.
326
347
  */
327
- export type ContentTrigger = "byBindingMisses" | "always";
348
+ export interface Recovery {
349
+ when: RecoveryTrigger;
350
+ softBindings?: SoftBindingSource[];
351
+ content?: Content;
352
+ /**
353
+ * The whole recovery\'s budget in milliseconds, every repository together, each request
354
+ * bounded by what remains. Absent, 10 minutes; at most 2147483647.
355
+ */
356
+ timeout?: number;
357
+ }
328
358
 
329
359
  /**
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.
360
+ * What this verify concludes about the asset, from signed evidence alone.
332
361
  */
333
- export interface ByReference {
334
- after: ContentTrigger;
335
- url: string;
336
- length: number;
337
- mediaType?: string;
338
- region: import('@contentauth/c2pa-types').Range[];
339
- }
362
+ 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[] };
340
363
 
341
364
  /**
342
- * [`crate::asset::CredentialOrigin`] as JS sees it: a tagged union, since each way of finding a
343
- * credential carries different evidence. Lane-local for the same reason [`FingerprintCheck`] is: a
344
- * tag layout is what `#[binding(wasm)]` declines to express.
365
+ * When a verify asks the repositories.
345
366
  */
346
- export type CredentialOrigin = { kind: "embedded" } | { kind: "recovered"; discoveries: RecoveryDiscovery[]; fingerprintCheck: FingerprintCheck };
367
+ export type RecoveryTrigger = "manifestMissing" | "always";
347
368
 
348
369
  /**
349
- * [`crate::asset::FingerprintCheck`] as JS sees it: a tagged union, since `compared` carries a
350
- * measurement the other two do not. Lane-local rather than `#[binding(wasm)]` on the core,
351
- * because a tag layout is exactly what that macro declines to express.
370
+ * Where a credential came from: embedded in the asset, or recovered from a repository.
352
371
  */
353
- export type FingerprintCheck = { kind: "notNeeded" } | { kind: "nothingToCompare" } | { kind: "unsupported"; algorithm: string } | { kind: "indeterminate" } | { kind: "compared"; score: number };
372
+ export type CredentialOrigin = { kind: "embedded" } | { kind: "recovered"; discoveries: Discovery[]; fingerprintCheck: FingerprintCheck };
354
373
 
355
374
  /**
356
- * [`crate::asset::HardBinding`] as JS sees it.
375
+ * Where one byBinding query\'s value comes from. A browser has no host engine: a vendor\'s
376
+ * detector runs repository-side, through `byContent`.
357
377
  */
358
- export type HardBinding = "match" | "mismatch";
378
+ export type SoftBindingSource = { kind: "builtin"; alg: string } | { kind: "held"; alg: string; value: Uint8Array };
359
379
 
360
380
  /**
361
- * [`crate::asset::Lineage`] as JS sees it.
381
+ * Whether a code is a success, an informational note, or a failure.
362
382
  */
363
- export interface Lineage {
364
- supersedes: string[];
365
- supersededBy: string[];
366
- }
383
+ export type ValidationCodeKind = "success" | "informational" | "failure";
367
384
 
368
385
  /**
369
- * [`crate::asset::RecoveryIssue`] as JS sees it: a tagged union, each kind with its own data.
386
+ * Whether a content form runs on this verify. Judged against the byBinding results alone.
370
387
  */
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 };
388
+ export type ContentWhen = "bindingMisses" | "always";
372
389
 
373
390
  /**
374
- * [`crate::asset::VerdictRule`] as JS sees it.
391
+ * Whether the asset\'s own fingerprint backs up a manifest that a watermark led to.
375
392
  */
376
- export type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
393
+ export type FingerprintCheck = { kind: "notNeeded" } | { kind: "missing" } | { kind: "unsupported"; alg: string } | { kind: "indeterminate" } | { kind: "compared"; score: number };
377
394
 
378
395
  /**
379
- * [`crate::asset::Verdict`] as JS sees it.
396
+ * Whether the manifest\'s hard binding holds over the bytes this verify read.
380
397
  */
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[] };
398
+ export type HardBinding = "match" | "mismatch";
382
399
 
383
400
  /**
384
- * `matches/byContent`: the asset is uploaded to each repository, one request per algorithm that
385
- * repository is declared for.
401
+ * Why repository recovery did not complete cleanly, or why one candidate was omitted.
386
402
  */
387
- export interface ByContent {
388
- after: ContentTrigger;
389
- }
403
+ export type RecoveryIssue = { kind: "computeFailed"; alg: string; message: string } | { kind: "bindingFailed"; repository: string; alg: string; message: string } | { kind: "queryRefused"; repository: string; alg: string; message: string } | { kind: "contentFailed"; repository: string; alg: string; message: string } | { kind: "capabilitiesUnavailable"; repository: string; message: string } | { kind: "tooLarge"; maxUploadBytes: number } | { kind: "fetchFailed"; repository: string; manifestId: string; message: string } | { kind: "candidateInvalid"; manifestId: string; reason: string } | { kind: "endpointRefused"; repository: string; manifestId: string; endpoint: string } | { kind: "limitReached"; message: string };
390
404
 
391
405
  export interface AssetVerification {
392
406
  credentials: Credential[];
393
407
  recovery: RecoverySummary;
394
- goldenComparison: GoldenComparison;
408
+ /**
409
+ * Absent when there was nothing to compare.
410
+ */
411
+ golden?: Golden;
395
412
  verdict: Verdict;
396
413
  }
397
414
 
@@ -400,12 +417,6 @@ export interface RecoverySummary {
400
417
  issues: RecoveryIssue[];
401
418
  }
402
419
 
403
- export type ContentBindingClass = "fingerprint" | "watermark";
404
-
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 };
406
-
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 };
408
-
409
420
  export type RecoveryStatus = "notRequested" | "notFound" | "recovered" | "incomplete";
410
421
 
411
422
 
@@ -427,19 +438,18 @@ export class AssetVerifier {
427
438
  *
428
439
  * # Errors
429
440
  *
430
- * Throws on a malformed `input`, a repository (or binder) failure, or a validation
441
+ * Throws on a malformed `source`, a repository (or engine) failure, or a validation
431
442
  * failure.
432
443
  */
433
- verify(input: RangeSource, recovery?: Recovery | null): Promise<AssetVerification>;
444
+ verify(source: RangeSource, recovery?: Recovery | null): Promise<Verification>;
434
445
  }
435
446
 
436
447
  /**
437
- * A [`RangeSource`](crate::wasm::RangeInput) over a `Blob`: a `File` off an `<input>`, a
448
+ * A `RangeSource` over a `Blob`: a `File` off an `<input>`, a
438
449
  * `Response.blob()`, a handle from the file system access API.
439
450
  *
440
- * The only source here that holds nothing. The SDK reads one slice at a time, so an asset larger
441
- * than the tab's memory verifies at the disk's speed rather than the heap's, and neither ceiling
442
- * the other two carry applies.
451
+ * It holds no bytes at all. The SDK reads one slice at a time, so an asset larger than the tab's
452
+ * memory verifies at the disk's speed rather than the heap's.
443
453
  *
444
454
  * # Worker only
445
455
  *
@@ -473,51 +483,6 @@ export class BlobSource {
473
483
  readonly length: number;
474
484
  }
475
485
 
476
- /**
477
- * A [`RangeSource`](crate::wasm::RangeInput) over bytes the caller already holds, read in place.
478
- *
479
- * [`MemorySource`] without the copy: the array stays on the JS side and only the window the SDK
480
- * asks for crosses, so nothing is resident here and linear memory's 4 GiB ceiling never applies to
481
- * the asset.
482
- */
483
- export class BytesSource {
484
- free(): void;
485
- [Symbol.dispose](): void;
486
- constructor(data: Uint8Array);
487
- readAt(offset: number, length: number): Uint8Array;
488
- readonly length: number;
489
- }
490
-
491
- export function C2PA_TRUST_LIST(): string;
492
-
493
- export function C2PA_TSA_TRUST_LIST(): string;
494
-
495
- export function DEV_CA(): string;
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
-
521
486
  export class IntoUnderlyingByteSource {
522
487
  private constructor();
523
488
  free(): void;
@@ -547,37 +512,9 @@ export class IntoUnderlyingSource {
547
512
  }
548
513
 
549
514
  /**
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
-
571
- /**
572
- * An in-memory [`RangeSource`](crate::wasm::RangeInput), for a caller that already holds the whole
573
- * asset as bytes.
574
- *
575
- * # Size ceiling
576
- *
577
- * The constructor copies the bytes into wasm linear memory, which is 32-bit addressed, so the
578
- * asset and everything else the module allocates share a 4 GiB ceiling (a browser tab reaches its
579
- * own memory limit well before that). [`BytesSource`] takes the same bytes without the copy, and
580
- * [`BlobSource`] holds nothing at all.
515
+ * A `RangeSource` over bytes the caller already holds, read in place: the array stays on the JS
516
+ * side and only the window the SDK asks for crosses, so nothing is resident here and linear
517
+ * memory's 4 GiB ceiling never applies to the asset.
581
518
  */
582
519
  export class MemorySource {
583
520
  free(): void;
@@ -596,8 +533,8 @@ export class StreamSession {
596
533
  free(): void;
597
534
  [Symbol.dispose](): void;
598
535
  /**
599
- * Everything this stream's init segments have registered, as CBOR for another node to
600
- * `StreamVerifier.resume` from.
536
+ * This stream's id and everything its init segments have registered, as CBOR for another
537
+ * node to `StreamVerifier.resume` from.
601
538
  *
602
539
  * The one piece of stream state that leaves the SDK, and only because a clustered
603
540
  * verifier needs it: the init URL is overwritten on rotation, so a node joining during
@@ -618,7 +555,7 @@ export class StreamSession {
618
555
  * Throws an `SdkError` on parse or signature failure, or when a media segment arrives
619
556
  * before any init was processed for the stream.
620
557
  */
621
- validate(data: RangeSource): Promise<SegmentValidation>;
558
+ validate(source: RangeSource): Promise<SegmentValidation>;
622
559
  }
623
560
 
624
561
  export class StreamVerifier {
@@ -634,26 +571,82 @@ export class StreamVerifier {
634
571
  */
635
572
  static create(options: StreamVerifierOptions): StreamVerifier;
636
573
  /**
637
- * Open `stream_id` for validation, handing back a `StreamSession` to feed segments to.
574
+ * Open the stream `id` for validation, handing back a `StreamSession` to feed segments to.
638
575
  *
639
576
  * No I/O: the handle carries the id so it cannot be mistyped or confused with another
640
577
  * stream's, and classification still happens per segment. Opening one id twice hands
641
578
  * back the same live session, so a component that remounts keeps the state its earlier
642
579
  * handle accumulated.
643
580
  */
644
- open(stream_id: string): StreamSession;
581
+ open(id: string): StreamSession;
645
582
  /**
646
- * Open `stream_id` on the state another node exported, merged into whatever this one
647
- * holds for that id already.
583
+ * Open the stream another node exported, its state merged into whatever this one holds
584
+ * for that stream already.
648
585
  *
649
586
  * # Errors
650
587
  *
651
- * Throws an `SdkError` (`STREAM_INVALID`) when `state` is not a value
652
- * `StreamSession.export` produced, or carries a version this SDK no longer reads.
588
+ * Throws an `SdkError` with a field violation at `state` when it is not a value
589
+ * `StreamSession.export` produced (`state.malformed`), or one of another export version
590
+ * (`state.version`).
653
591
  */
654
- resume(stream_id: string, state: Uint8Array): StreamSession;
592
+ resume(state: Uint8Array): StreamSession;
655
593
  }
656
594
 
595
+ /**
596
+ * One `verify` result held with the stores it read: `report` is the data, and `resource` reads a
597
+ * thumbnail from credential `credential` (its position in `report.credentials`) by the
598
+ * `identifier` of a resource reference in its manifest. A class rather than a field of the
599
+ * report because a store cannot be serialized, and one handle per verify is what a worker can
600
+ * proxy (a class nested in the report cannot cross a thread).
601
+ */
602
+ export class Verification {
603
+ private constructor();
604
+ free(): void;
605
+ [Symbol.dispose](): void;
606
+ /**
607
+ * The bytes of one resource credential `credential` holds, or `undefined`.
608
+ *
609
+ * # Errors
610
+ *
611
+ * Throws `READER_INVALID` when the store holds the resource but cannot produce it, and
612
+ * `undefined` for a `credential` out of range.
613
+ */
614
+ resource(credential: number, uri: string): Uint8Array | undefined;
615
+ /**
616
+ * The report: credentials, recovery, golden flow and verdict.
617
+ */
618
+ readonly report: AssetVerification;
619
+ }
620
+
621
+ /**
622
+ * The bundled C2PA Conformance Program signing-CA trust list (a release snapshot). Trusted by
623
+ * default with `trust.c2pa`; read it to pin or extend your own list.
624
+ */
625
+ export function c2paTrustList(): string;
626
+
627
+ /**
628
+ * The bundled C2PA time-stamping-authority trust list (a release snapshot).
629
+ */
630
+ export function c2paTsaTrustList(): string;
631
+
632
+ /**
633
+ * The values this SDK computes for `alg` over `source`, `[]` when it finds none. `format` is
634
+ * the asset's media type; omitted, the bytes name it.
635
+ *
636
+ * # Errors
637
+ *
638
+ * Throws on an algorithm this SDK computes no value of, a `format` that is no media type or that
639
+ * the bytes contradict, an unreadable source, or no trustworthy answer.
640
+ */
641
+ export function computeSoftBinding(alg: string, source: RangeSource, format?: string | null): Promise<Block[]>;
642
+
643
+ /**
644
+ * PEM trust anchor for the Limbo Integrity development signing environment, **development
645
+ * only**, no security guarantees: put it in `trust.anchors` for a development build, never in a
646
+ * release.
647
+ */
648
+ export function devCa(): string;
649
+
657
650
  export function init_panic_hook(): void;
658
651
 
659
652
  /**
@@ -669,78 +662,51 @@ export function init_panic_hook(): void;
669
662
  *
670
663
  * Throws `READER_INVALID` when the bytes are not a manifest store c2pa can parse.
671
664
  */
672
- export function parse(manifest: Uint8Array): import('@contentauth/c2pa-types').ManifestStore;
665
+ export function parse(manifest: Uint8Array): Promise<import('@contentauth/c2pa-types').ManifestStore>;
673
666
 
674
667
  /**
675
668
  * The bytes of one resource in a detached manifest store, or `undefined` when it holds none
676
- * under `uri`.
677
- *
678
- * `uri` is the `identifier` on a resource reference the store carries, so walking the chain in
679
- * the parsed store is what produces it: any manifest's claim thumbnail, including a non-active
680
- * one, and any ingredient's. Render it with the `format` beside that identifier. A `uri` naming a
681
- * manifest rather than a resource answers that manifest's own JUMBF, so pass what a reference
682
- * states, never a bare label.
669
+ * under `uri`: the `identifier` on a resource reference the parsed store carries.
683
670
  *
684
671
  * # Errors
685
672
  *
686
673
  * Throws `READER_INVALID` when the bytes are not a manifest store c2pa can parse, or the store
687
674
  * holds the resource but cannot produce it.
688
675
  */
689
- export function resource(manifest: Uint8Array, uri: string): Uint8Array | undefined;
690
-
691
- /**
692
- * Every thumbnail the store references, by the `identifier` it references them under: each
693
- * manifest's claim thumbnail and each ingredient's, whichever manifest carries them.
694
- *
695
- * One parse for the whole set, where `resource` pays one per call, so a chain view asks once
696
- * instead of once per tile. Render each one as the `format` beside its identifier. A reference
697
- * the store cannot produce is left out rather than failing the set.
698
- *
699
- * # Errors
700
- *
701
- * Throws `READER_INVALID` when the bytes are not a manifest store c2pa can parse.
702
- */
703
- export function thumbnails(manifest: Uint8Array): Record<string, Uint8Array>;
676
+ export function resource(manifest: Uint8Array, uri: string): Promise<Uint8Array | undefined>;
704
677
 
705
678
  export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
706
679
 
707
680
  export interface InitOutput {
708
681
  readonly memory: WebAssembly.Memory;
682
+ readonly computeSoftBinding: (a: number, b: number, c: any, d: number, e: number) => any;
709
683
  readonly __wbg_assetverifier_free: (a: number, b: number) => void;
710
684
  readonly __wbg_blobsource_free: (a: number, b: number) => void;
711
- readonly __wbg_bytessource_free: (a: number, b: number) => void;
712
685
  readonly __wbg_memorysource_free: (a: number, b: number) => void;
713
686
  readonly __wbg_streamsession_free: (a: number, b: number) => void;
714
687
  readonly __wbg_streamverifier_free: (a: number, b: number) => void;
688
+ readonly __wbg_verification_free: (a: number, b: number) => void;
715
689
  readonly assetverifier_create: (a: any) => [number, number, number];
716
690
  readonly assetverifier_verify: (a: number, b: any, c: number) => any;
717
691
  readonly blobsource_length: (a: number) => number;
718
692
  readonly blobsource_new: (a: any) => [number, number, number];
719
693
  readonly blobsource_readAt: (a: number, b: number, c: number) => [number, number, number];
720
- readonly bytessource_length: (a: number) => number;
721
- readonly bytessource_new: (a: any) => number;
722
- readonly bytessource_readAt: (a: number, b: number, c: number) => any;
723
694
  readonly memorysource_length: (a: number) => number;
724
- readonly memorysource_new: (a: number, b: number) => number;
695
+ readonly memorysource_new: (a: any) => number;
725
696
  readonly memorysource_readAt: (a: number, b: number, c: number) => any;
726
- readonly parse: (a: number, b: number) => [number, number, number];
727
- readonly resource: (a: number, b: number, c: number, d: number) => [number, number, number, number];
697
+ readonly parse: (a: number, b: number) => any;
698
+ readonly resource: (a: number, b: number, c: number, d: number) => any;
728
699
  readonly streamsession_export: (a: number) => [number, number, number, number];
729
700
  readonly streamsession_validate: (a: number, b: any) => any;
730
701
  readonly streamverifier_create: (a: any) => [number, number, number];
731
702
  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];
733
- readonly thumbnails: (a: number, b: number) => [number, number, number];
734
- readonly C2PA_TRUST_LIST: () => [number, number];
735
- readonly C2PA_TSA_TRUST_LIST: () => [number, number];
736
- readonly DEV_CA: () => [number, number];
703
+ readonly streamverifier_resume: (a: number, b: number, c: number) => [number, number, number];
704
+ readonly verification_report: (a: number) => any;
705
+ readonly verification_resource: (a: number, b: number, c: number, d: number) => [number, number, number, number];
706
+ readonly c2paTrustList: () => [number, number];
707
+ readonly c2paTsaTrustList: () => [number, number];
708
+ readonly devCa: () => [number, number];
737
709
  readonly init_panic_hook: () => void;
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;
744
710
  readonly __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
745
711
  readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
746
712
  readonly intounderlyingbytesource_cancel: (a: number) => void;
@@ -757,7 +723,7 @@ export interface InitOutput {
757
723
  readonly wasm_bindgen__convert__closures_____invoke__hfa954cb356c7e7e1: (a: number, b: number, c: any) => [number, number];
758
724
  readonly wasm_bindgen__convert__closures_____invoke__h32a4f2e7671466cf: (a: number, b: number, c: any, d: any) => void;
759
725
  readonly wasm_bindgen__convert__closures_____invoke__hedf60f9cb8ab20c3: (a: number, b: number, c: any) => void;
760
- readonly wasm_bindgen__convert__closures_____invoke__hcc9f2329e90526d5: (a: number, b: number) => void;
726
+ readonly wasm_bindgen__convert__closures_____invoke__hbf782ef36cea6846: (a: number, b: number) => void;
761
727
  readonly __wbindgen_malloc: (a: number, b: number) => number;
762
728
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
763
729
  readonly __wbindgen_exn_store: (a: number) => void;
@@ -765,6 +731,7 @@ export interface InitOutput {
765
731
  readonly __wbindgen_externrefs: WebAssembly.Table;
766
732
  readonly __wbindgen_free: (a: number, b: number, c: number) => void;
767
733
  readonly __wbindgen_destroy_closure: (a: number, b: number) => void;
734
+ readonly __externref_drop_slice: (a: number, b: number) => void;
768
735
  readonly __externref_table_dealloc: (a: number) => void;
769
736
  readonly __wbindgen_start: () => void;
770
737
  }