@trylimbo/sdk-verifier-wasm 0.2.25 → 0.3.0-canary.41

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,13 +71,13 @@ 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
- * The session key\'s public half (SEC1-encoded bytes).
80
+ * SEC1 EC, raw Ed25519 or PKCS#1 DER RSA public-key bytes.
87
81
  */
88
82
  publicKey: Uint8Array;
89
83
  }
@@ -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 {
96
+ export interface Reference {
151
97
  /**
152
- * PEM trust anchors for the manifest signers the caller trusts.
98
+ * A short-lived https URL without credentials.
153
99
  */
154
- trustAnchors: string[];
155
- /**
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.
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;
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;
108
+ format?: string;
109
+ ranges?: import('@contentauth/c2pa-types').Range[];
185
110
  }
186
111
 
187
112
  /**
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,133 +205,217 @@ 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
  /**
272
212
  * Result of `StreamSession.validate`, discriminated by `kind`.
273
213
  */
274
- export type SegmentValidation = ({ kind: "init" } & InitValidation) | ({ kind: "media" } & MediaValidation) | { kind: "unknown" };
214
+ export type SegmentValidation = ({ kind: "init" } & InitValidation) | ({ kind: "media" } & MediaValidation);
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 };
275
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.
236
+ *
237
+ * What is thrown is an `Error` named `SdkError` (a stack, `instanceof Error`) that carries
238
+ * these fields; this type is the shape of its properties.
281
239
  */
282
240
  export type SdkError = ({ kind: "status" } & StatusError) | ({ kind: "reason" } & ReasonError) | ({ kind: "invalid" } & InvalidError);
283
241
 
284
242
  /**
285
- * Timing facts carried by a media segment\'s container.
243
+ * The evidence that singled a recovered verdict out.
286
244
  */
287
- export interface SegmentTiming {
245
+ export type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
246
+
247
+ /**
248
+ * The query a repository answers from the content: `matches/byReference` when `reference` is
249
+ * stated, so nothing is uploaded, else `matches/byContent` with the asset in the request.
250
+ */
251
+ export interface Content {
252
+ when: ContentWhen;
288
253
  /**
289
- * Media segment sequence number (exact below 2^53).
254
+ * Where each repository downloads the asset from.
290
255
  */
291
- sequenceNumber: number;
256
+ reference?: Reference;
257
+ /**
258
+ * The largest asset an upload sends, in bytes; a larger one is reported `tooLarge`. Absent,
259
+ * 64 MiB.
260
+ */
261
+ maxUploadBytes?: number;
262
+ }
263
+
264
+ /**
265
+ * The re-sign chain between the returned credentials, by manifest label.
266
+ */
267
+ export interface Lineage {
268
+ supersedes: string[];
269
+ supersededBy: string[];
270
+ }
271
+
272
+ /**
273
+ * The value a content query was hinted with, under its own algorithm.
274
+ */
275
+ export interface Hint {
276
+ alg: string;
277
+ value: Uint8Array;
278
+ }
279
+
280
+ /**
281
+ * Timing a media segment\'s container carries.
282
+ */
283
+ export interface SegmentTiming {
292
284
  /**
293
- * MP4 timescale (ticks per second) for this segment\'s timing, if present.
285
+ * The segment\'s `sequenceNumber`, a `bigint` as in the Node FFI lane.
294
286
  */
295
- timescale?: number;
287
+ sequence: bigint;
296
288
  /**
297
- * Segment duration in seconds, if the container reports it.
289
+ * The span its C2PA `emsg` covers, in milliseconds.
298
290
  */
299
- eventDurationSecs?: number;
291
+ duration?: number;
300
292
  }
301
293
 
302
294
  /**
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.
295
+ * What a stream verifier trusts, and how far a segment\'s clock may drift.
306
296
  */
307
- export interface Recovery {
308
- when: RecoveryTrigger;
309
- binders: BinderSpec[];
310
- byContent?: ByContent;
311
- byReference?: ByReference;
297
+ export interface StreamVerifierOptions {
298
+ trust: Trust;
299
+ /**
300
+ * How far a segment\'s presentation time may sit outside its session key\'s validity period,
301
+ * in milliseconds. Absent, 5 minutes.
302
+ */
303
+ skewTolerance?: number;
304
+ /**
305
+ * Exact HTTPS origins approved for external live-video manifest recovery.
306
+ */
307
+ manifestOrigins?: string[];
312
308
  }
313
309
 
314
310
  /**
315
- * When [`AssetVerifier::verify_asset`] queries the repository.
311
+ * What a verifier trusts. An omitted list trusts nothing.
316
312
  */
317
- export type RecoveryTrigger = "manifestMissing" | "always";
313
+ export interface Trust {
314
+ /**
315
+ * PEM anchors for the manifest signers the caller trusts.
316
+ */
317
+ anchors?: string[];
318
+ /**
319
+ * PEM anchors for the time-stamping authorities the caller trusts.
320
+ */
321
+ tsaAnchors?: string[];
322
+ /**
323
+ * Also trust the bundled official C2PA manifest and TSA lists, beside the caller\'s.
324
+ */
325
+ c2pa: boolean;
326
+ /**
327
+ * Issuer DIDs whose CAWG identity (ICA) credentials count as validated, matched exactly
328
+ * against the credential issuer. Empty trusts no issuer: every identity assertion then
329
+ * reports `cawg.ica.untrusted_issuer` and withholds `cawg.ica.credential_valid`, which leaves
330
+ * the manifest\'s own validity untouched.
331
+ */
332
+ icaIssuers?: string[];
333
+ }
318
334
 
319
335
  /**
320
- * Whether a code is a success, an informational note, or a failure.
336
+ * What an asset verifier trusts and which repositories it may ask. An omitted list trusts or
337
+ * asks nothing.
321
338
  */
322
- export type ValidationCodeKind = "success" | "informational" | "failure";
339
+ export interface AssetVerifierOptions {
340
+ /**
341
+ * The C2PA manifest repositories recovery asks, each a Soft Binding Resolution API declared
342
+ * for exactly the algorithms it may be asked for. Results merge by manifest, and a match\'s
343
+ * `endpoint` is fetched from only when it names one of these. Empty: no recovery can be
344
+ * asked of this verifier.
345
+ */
346
+ repositories?: Repository[];
347
+ trust: Trust;
348
+ }
323
349
 
324
350
  /**
325
- * Whether a content form runs on this verify. Judged against the byBinding results alone.
351
+ * What one verify may do to recover a manifest, as data: the soft bindings this client looks up
352
+ * itself through `matches/byBinding`, and the content query, absent when not to be asked. It
353
+ * needs a configured repository and at least one query.
326
354
  */
327
- export type ContentTrigger = "byBindingMisses" | "always";
355
+ export interface Recovery {
356
+ when: RecoveryTrigger;
357
+ softBindings?: SoftBindingSource[];
358
+ content?: Content;
359
+ /**
360
+ * The whole recovery\'s budget in milliseconds, every repository together, each request
361
+ * bounded by what remains. Absent, 10 minutes; at most 2147483647.
362
+ */
363
+ timeout?: number;
364
+ }
328
365
 
329
366
  /**
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.
367
+ * What this verify concludes about the asset, from signed evidence alone.
332
368
  */
333
- export interface ByReference {
334
- after: ContentTrigger;
335
- url: string;
336
- length: number;
337
- mediaType?: string;
338
- region: import('@contentauth/c2pa-types').Range[];
339
- }
369
+ export type Verdict = { kind: "unsigned" } | { kind: "inconclusive" } | { kind: "embedded" } | { kind: "invalid"; index: number } | { kind: "recovered"; index: number; decidedBy: VerdictRule } | { kind: "recoveredDerivative"; index: number; decidedBy: VerdictRule } | { kind: "ambiguous"; candidates: number[] };
340
370
 
341
371
  /**
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.
372
+ * When a verify asks the repositories.
345
373
  */
346
- export type CredentialOrigin = { kind: "embedded" } | { kind: "recovered"; discoveries: RecoveryDiscovery[]; fingerprintCheck: FingerprintCheck };
374
+ export type RecoveryTrigger = "manifestMissing" | "always";
347
375
 
348
376
  /**
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.
377
+ * Where a credential came from: embedded in the asset, or recovered from a repository.
352
378
  */
353
- export type FingerprintCheck = { kind: "notNeeded" } | { kind: "nothingToCompare" } | { kind: "unsupported"; algorithm: string } | { kind: "indeterminate" } | { kind: "compared"; score: number };
379
+ export type CredentialOrigin = { kind: "embedded" } | { kind: "recovered"; discoveries: Discovery[]; fingerprintCheck: FingerprintCheck };
354
380
 
355
381
  /**
356
- * [`crate::asset::HardBinding`] as JS sees it.
382
+ * Where one byBinding query\'s value comes from. A browser has no host engine: a vendor\'s
383
+ * detector runs repository-side, through `byContent`.
357
384
  */
358
- export type HardBinding = "match" | "mismatch";
385
+ export type SoftBindingSource = { kind: "builtin"; alg: string } | { kind: "held"; alg: string; value: Uint8Array };
359
386
 
360
387
  /**
361
- * [`crate::asset::Lineage`] as JS sees it.
388
+ * Whether a code is a success, an informational note, or a failure.
362
389
  */
363
- export interface Lineage {
364
- supersedes: string[];
365
- supersededBy: string[];
366
- }
390
+ export type ValidationCodeKind = "success" | "informational" | "failure";
367
391
 
368
392
  /**
369
- * [`crate::asset::RecoveryIssue`] as JS sees it: a tagged union, each kind with its own data.
393
+ * Whether a content form runs on this verify. Judged against the byBinding results alone.
370
394
  */
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 };
395
+ export type ContentWhen = "bindingMisses" | "always";
372
396
 
373
397
  /**
374
- * [`crate::asset::VerdictRule`] as JS sees it.
398
+ * Whether the asset\'s own fingerprint backs up a manifest that a watermark led to.
375
399
  */
376
- export type VerdictRule = "onlyCandidate" | "notSuperseded" | "hardBinding";
400
+ export type FingerprintCheck = { kind: "notNeeded" } | { kind: "missing" } | { kind: "unsupported"; alg: string } | { kind: "indeterminate" } | { kind: "compared"; score: number };
377
401
 
378
402
  /**
379
- * [`crate::asset::Verdict`] as JS sees it.
403
+ * Whether the manifest\'s hard binding holds over the bytes this verify read.
380
404
  */
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[] };
405
+ export type HardBinding = "match" | "mismatch" | "unverified";
382
406
 
383
407
  /**
384
- * `matches/byContent`: the asset is uploaded to each repository, one request per algorithm that
385
- * repository is declared for.
408
+ * Why repository recovery did not complete cleanly, or why one candidate was omitted.
386
409
  */
387
- export interface ByContent {
388
- after: ContentTrigger;
389
- }
410
+ 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
411
 
391
412
  export interface AssetVerification {
392
413
  credentials: Credential[];
393
414
  recovery: RecoverySummary;
394
- goldenComparison: GoldenComparison;
415
+ /**
416
+ * Absent when there was nothing to compare.
417
+ */
418
+ golden?: Golden;
395
419
  verdict: Verdict;
396
420
  }
397
421
 
@@ -400,12 +424,6 @@ export interface RecoverySummary {
400
424
  issues: RecoveryIssue[];
401
425
  }
402
426
 
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
427
  export type RecoveryStatus = "notRequested" | "notFound" | "recovered" | "incomplete";
410
428
 
411
429
 
@@ -422,24 +440,24 @@ export class AssetVerifier {
422
440
  /**
423
441
  * Verify an asset against the configured trust anchors and per-call recovery options.
424
442
  *
425
- * Reads the C2PA-native formats. A container format (MXF) is plugin-backed, and plugins
426
- * are native, so a master is verified through the native SDK.
443
+ * Reads the C2PA handlers included in the browser build. Additional native modules require
444
+ * the Node or Python SDK.
445
+ * `format` optionally declares the media type for inputs such as SVG and plain text.
427
446
  *
428
447
  * # Errors
429
448
  *
430
- * Throws on a malformed `input`, a repository (or binder) failure, or a validation
449
+ * Throws on a malformed `source`, a repository (or engine) failure, or a validation
431
450
  * failure.
432
451
  */
433
- verify(input: RangeSource, recovery?: Recovery | null): Promise<AssetVerification>;
452
+ verify(source: RangeSource, recovery?: Recovery | null, format?: string | null): Promise<Verification>;
434
453
  }
435
454
 
436
455
  /**
437
- * A [`RangeSource`](crate::wasm::RangeInput) over a `Blob`: a `File` off an `<input>`, a
456
+ * A `RangeSource` over a `Blob`: a `File` off an `<input>`, a
438
457
  * `Response.blob()`, a handle from the file system access API.
439
458
  *
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.
459
+ * It holds no bytes at all. The SDK reads one slice at a time, so an asset larger than the tab's
460
+ * memory verifies at the disk's speed rather than the heap's.
443
461
  *
444
462
  * # Worker only
445
463
  *
@@ -473,51 +491,6 @@ export class BlobSource {
473
491
  readonly length: number;
474
492
  }
475
493
 
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
494
  export class IntoUnderlyingByteSource {
522
495
  private constructor();
523
496
  free(): void;
@@ -547,37 +520,9 @@ export class IntoUnderlyingSource {
547
520
  }
548
521
 
549
522
  /**
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.
523
+ * A `RangeSource` over bytes the caller already holds, read in place: the array stays on the JS
524
+ * side and only the window the SDK asks for crosses, so nothing is resident here and linear
525
+ * memory's 4 GiB ceiling never applies to the asset.
581
526
  */
582
527
  export class MemorySource {
583
528
  free(): void;
@@ -596,8 +541,8 @@ export class StreamSession {
596
541
  free(): void;
597
542
  [Symbol.dispose](): void;
598
543
  /**
599
- * Everything this stream's init segments have registered, as CBOR for another node to
600
- * `StreamVerifier.resume` from.
544
+ * This stream's id and everything its init segments have registered, as CBOR for another
545
+ * node to `StreamVerifier.resume` from.
601
546
  *
602
547
  * The one piece of stream state that leaves the SDK, and only because a clustered
603
548
  * verifier needs it: the init URL is overwritten on rotation, so a node joining during
@@ -618,7 +563,7 @@ export class StreamSession {
618
563
  * Throws an `SdkError` on parse or signature failure, or when a media segment arrives
619
564
  * before any init was processed for the stream.
620
565
  */
621
- validate(data: RangeSource): Promise<SegmentValidation>;
566
+ validate(source: RangeSource): Promise<SegmentValidation>;
622
567
  }
623
568
 
624
569
  export class StreamVerifier {
@@ -634,26 +579,82 @@ export class StreamVerifier {
634
579
  */
635
580
  static create(options: StreamVerifierOptions): StreamVerifier;
636
581
  /**
637
- * Open `stream_id` for validation, handing back a `StreamSession` to feed segments to.
582
+ * Open the stream `id` for validation, handing back a `StreamSession` to feed segments to.
638
583
  *
639
584
  * No I/O: the handle carries the id so it cannot be mistyped or confused with another
640
585
  * stream's, and classification still happens per segment. Opening one id twice hands
641
586
  * back the same live session, so a component that remounts keeps the state its earlier
642
587
  * handle accumulated.
643
588
  */
644
- open(stream_id: string): StreamSession;
589
+ open(id: string): StreamSession;
590
+ /**
591
+ * Open the stream another node exported, its state merged into whatever this one holds
592
+ * for that stream already.
593
+ *
594
+ * # Errors
595
+ *
596
+ * Throws an `SdkError` with a field violation at `state` when it is not a value
597
+ * `StreamSession.export` produced (`state.malformed`), or one of another export version
598
+ * (`state.version`).
599
+ */
600
+ resume(state: Uint8Array): Promise<StreamSession>;
601
+ }
602
+
603
+ /**
604
+ * One `verify` result held with the stores it read: `report` is the data, and `resource` reads a
605
+ * thumbnail from credential `credential` (its position in `report.credentials`) by the
606
+ * `identifier` of a resource reference in its manifest. A class rather than a field of the
607
+ * report because a store cannot be serialized, and one handle per verify is what a worker can
608
+ * proxy (a class nested in the report cannot cross a thread).
609
+ */
610
+ export class Verification {
611
+ private constructor();
612
+ free(): void;
613
+ [Symbol.dispose](): void;
645
614
  /**
646
- * Open `stream_id` on the state another node exported, merged into whatever this one
647
- * holds for that id already.
615
+ * The bytes of one resource credential `credential` holds, or `undefined`.
648
616
  *
649
617
  * # Errors
650
618
  *
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.
619
+ * Throws `READER_INVALID` when the store holds the resource but cannot produce it, and
620
+ * `undefined` for a `credential` out of range.
653
621
  */
654
- resume(stream_id: string, state: Uint8Array): StreamSession;
622
+ resource(credential: number, uri: string): Uint8Array | undefined;
623
+ /**
624
+ * The report: credentials, recovery, golden flow and verdict.
625
+ */
626
+ readonly report: AssetVerification;
655
627
  }
656
628
 
629
+ /**
630
+ * The bundled C2PA Conformance Program signing-CA trust list (a release snapshot). Trusted by
631
+ * default with `trust.c2pa`; read it to pin or extend your own list.
632
+ */
633
+ export function c2paTrustList(): string;
634
+
635
+ /**
636
+ * The bundled C2PA time-stamping-authority trust list (a release snapshot).
637
+ */
638
+ export function c2paTsaTrustList(): string;
639
+
640
+ /**
641
+ * The values this SDK computes for `alg` over `source`, `[]` when it finds none. `format` is
642
+ * the asset's media type; omitted, the bytes name it.
643
+ *
644
+ * # Errors
645
+ *
646
+ * Throws on an algorithm this SDK computes no value of, a `format` that is no media type or that
647
+ * the bytes contradict, an unreadable source, or no trustworthy answer.
648
+ */
649
+ export function computeSoftBinding(alg: string, source: RangeSource, format?: string | null): Promise<Block[]>;
650
+
651
+ /**
652
+ * PEM trust anchor for the Limbo Integrity development signing environment, **development
653
+ * only**, no security guarantees: put it in `trust.anchors` for a development build, never in a
654
+ * release.
655
+ */
656
+ export function devCa(): string;
657
+
657
658
  export function init_panic_hook(): void;
658
659
 
659
660
  /**
@@ -667,80 +668,53 @@ export function init_panic_hook(): void;
667
668
  *
668
669
  * # Errors
669
670
  *
670
- * Throws `READER_INVALID` when the bytes are not a manifest store c2pa can parse.
671
+ * Rejects with `READER_INVALID` when the bytes are not a manifest store c2pa can parse.
671
672
  */
672
- export function parse(manifest: Uint8Array): import('@contentauth/c2pa-types').ManifestStore;
673
+ export function parse(manifest: Uint8Array): Promise<import('@contentauth/c2pa-types').ManifestStore>;
673
674
 
674
675
  /**
675
676
  * 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.
677
+ * under `uri`: the `identifier` on a resource reference the parsed store carries.
683
678
  *
684
679
  * # Errors
685
680
  *
686
- * Throws `READER_INVALID` when the bytes are not a manifest store c2pa can parse, or the store
681
+ * Rejects with `READER_INVALID` when the bytes are not a manifest store c2pa can parse, or the store
687
682
  * holds the resource but cannot produce it.
688
683
  */
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>;
684
+ export function resource(manifest: Uint8Array, uri: string): Promise<Uint8Array | undefined>;
704
685
 
705
686
  export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
706
687
 
707
688
  export interface InitOutput {
708
689
  readonly memory: WebAssembly.Memory;
690
+ readonly parse: (a: number, b: number) => any;
691
+ readonly resource: (a: number, b: number, c: number, d: number) => any;
709
692
  readonly __wbg_assetverifier_free: (a: number, b: number) => void;
710
- readonly __wbg_blobsource_free: (a: number, b: number) => void;
711
- readonly __wbg_bytessource_free: (a: number, b: number) => void;
712
- readonly __wbg_memorysource_free: (a: number, b: number) => void;
713
693
  readonly __wbg_streamsession_free: (a: number, b: number) => void;
714
694
  readonly __wbg_streamverifier_free: (a: number, b: number) => void;
695
+ readonly __wbg_verification_free: (a: number, b: number) => void;
715
696
  readonly assetverifier_create: (a: any) => [number, number, number];
716
- readonly assetverifier_verify: (a: number, b: any, c: number) => any;
697
+ readonly assetverifier_verify: (a: number, b: any, c: number, d: number, e: number) => any;
698
+ readonly streamsession_export: (a: number) => [number, number, number, number];
699
+ readonly streamsession_validate: (a: number, b: any) => any;
700
+ readonly streamverifier_create: (a: any) => [number, number, number];
701
+ readonly streamverifier_open: (a: number, b: number, c: number) => number;
702
+ readonly streamverifier_resume: (a: number, b: number, c: number) => any;
703
+ readonly verification_report: (a: number) => any;
704
+ readonly verification_resource: (a: number, b: number, c: number, d: number) => [number, number, number, number];
705
+ readonly computeSoftBinding: (a: number, b: number, c: any, d: number, e: number) => any;
706
+ readonly __wbg_blobsource_free: (a: number, b: number) => void;
707
+ readonly __wbg_memorysource_free: (a: number, b: number) => void;
717
708
  readonly blobsource_length: (a: number) => number;
718
709
  readonly blobsource_new: (a: any) => [number, number, number];
719
710
  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
711
  readonly memorysource_length: (a: number) => number;
724
- readonly memorysource_new: (a: number, b: number) => number;
712
+ readonly memorysource_new: (a: any) => number;
725
713
  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];
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];
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];
714
+ readonly c2paTrustList: () => [number, number];
715
+ readonly c2paTsaTrustList: () => [number, number];
716
+ readonly devCa: () => [number, number];
737
717
  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
718
  readonly __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
745
719
  readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
746
720
  readonly intounderlyingbytesource_cancel: (a: number) => void;
@@ -756,8 +730,8 @@ export interface InitOutput {
756
730
  readonly intounderlyingsink_write: (a: number, b: any) => any;
757
731
  readonly wasm_bindgen__convert__closures_____invoke__hfa954cb356c7e7e1: (a: number, b: number, c: any) => [number, number];
758
732
  readonly wasm_bindgen__convert__closures_____invoke__h32a4f2e7671466cf: (a: number, b: number, c: any, d: any) => void;
759
- 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;
733
+ readonly wasm_bindgen__convert__closures_____invoke__hbfbf6526ca40dbc0: (a: number, b: number, c: any) => void;
734
+ readonly wasm_bindgen__convert__closures_____invoke__h66de60f9da4a5479: (a: number, b: number) => void;
761
735
  readonly __wbindgen_malloc: (a: number, b: number) => number;
762
736
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
763
737
  readonly __wbindgen_exn_store: (a: number) => void;
@@ -765,6 +739,7 @@ export interface InitOutput {
765
739
  readonly __wbindgen_externrefs: WebAssembly.Table;
766
740
  readonly __wbindgen_free: (a: number, b: number, c: number) => void;
767
741
  readonly __wbindgen_destroy_closure: (a: number, b: number) => void;
742
+ readonly __externref_drop_slice: (a: number, b: number) => void;
768
743
  readonly __externref_table_dealloc: (a: number) => void;
769
744
  readonly __wbindgen_start: () => void;
770
745
  }