@bcts/envelope 1.0.0-alpha.10
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.
- package/LICENSE +48 -0
- package/README.md +23 -0
- package/dist/index.cjs +2646 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +782 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +782 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.iife.js +2644 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.mjs +2552 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +84 -0
- package/src/base/assertion.ts +179 -0
- package/src/base/assertions.ts +153 -0
- package/src/base/cbor.ts +122 -0
- package/src/base/digest.ts +204 -0
- package/src/base/elide.ts +390 -0
- package/src/base/envelope-decodable.ts +186 -0
- package/src/base/envelope-encodable.ts +71 -0
- package/src/base/envelope.ts +988 -0
- package/src/base/error.ts +421 -0
- package/src/base/index.ts +56 -0
- package/src/base/leaf.ts +147 -0
- package/src/base/queries.ts +244 -0
- package/src/base/walk.ts +215 -0
- package/src/base/wrap.ts +26 -0
- package/src/extension/attachment.ts +280 -0
- package/src/extension/compress.ts +176 -0
- package/src/extension/encrypt.ts +297 -0
- package/src/extension/expression.ts +404 -0
- package/src/extension/index.ts +72 -0
- package/src/extension/proof.ts +227 -0
- package/src/extension/recipient.ts +440 -0
- package/src/extension/salt.ts +114 -0
- package/src/extension/signature.ts +398 -0
- package/src/extension/types.ts +92 -0
- package/src/format/diagnostic.ts +116 -0
- package/src/format/hex.ts +25 -0
- package/src/format/index.ts +13 -0
- package/src/format/tree.ts +168 -0
- package/src/index.ts +32 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/string.ts +48 -0
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
import { Digest, type DigestProvider } from "./digest";
|
|
2
|
+
import { Assertion } from "./assertion";
|
|
3
|
+
import { EnvelopeError } from "./error";
|
|
4
|
+
import type { EnvelopeEncodableValue } from "./envelope-encodable";
|
|
5
|
+
import { KnownValue } from "@bcts/known-values";
|
|
6
|
+
import type { Cbor, CborMap } from "@bcts/dcbor";
|
|
7
|
+
import {
|
|
8
|
+
cbor,
|
|
9
|
+
cborData,
|
|
10
|
+
toTaggedValue,
|
|
11
|
+
TAG_ENCODED_CBOR,
|
|
12
|
+
MajorType,
|
|
13
|
+
asByteString,
|
|
14
|
+
asCborArray,
|
|
15
|
+
asCborMap,
|
|
16
|
+
asTaggedValue,
|
|
17
|
+
tryExpectedTaggedValue,
|
|
18
|
+
} from "@bcts/dcbor";
|
|
19
|
+
import { ENVELOPE, LEAF, ENCRYPTED, COMPRESSED } from "@bcts/components";
|
|
20
|
+
|
|
21
|
+
// Type imports for extension method declarations
|
|
22
|
+
// These are imported as types only to avoid circular dependencies at runtime
|
|
23
|
+
import type { ObscureAction, ObscureType } from "./elide";
|
|
24
|
+
import type { Visitor } from "./walk";
|
|
25
|
+
import type {
|
|
26
|
+
SymmetricKey,
|
|
27
|
+
SealedMessage,
|
|
28
|
+
PublicKeyBase,
|
|
29
|
+
PrivateKeyBase,
|
|
30
|
+
Signer,
|
|
31
|
+
Verifier,
|
|
32
|
+
SignatureMetadata,
|
|
33
|
+
} from "../extension";
|
|
34
|
+
|
|
35
|
+
/// Import tag values from the tags registry
|
|
36
|
+
/// These match the Rust reference implementation in bc-tags-rust
|
|
37
|
+
const TAG_ENVELOPE = ENVELOPE.value;
|
|
38
|
+
const TAG_LEAF = LEAF.value;
|
|
39
|
+
const TAG_ENCRYPTED = ENCRYPTED.value;
|
|
40
|
+
const TAG_COMPRESSED = COMPRESSED.value;
|
|
41
|
+
|
|
42
|
+
/// The core structural variants of a Gordian Envelope.
|
|
43
|
+
///
|
|
44
|
+
/// Each variant represents a different structural form that an
|
|
45
|
+
/// envelope can take, as defined in the Gordian Envelope IETF Internet Draft.
|
|
46
|
+
/// The different cases provide different capabilities and serve different
|
|
47
|
+
/// purposes in the envelope ecosystem.
|
|
48
|
+
///
|
|
49
|
+
/// The `EnvelopeCase` is the internal representation of an envelope's
|
|
50
|
+
/// structure. While each case has unique properties, they all maintain a digest
|
|
51
|
+
/// that ensures the integrity of the envelope.
|
|
52
|
+
///
|
|
53
|
+
/// It is advised to use the other Envelope APIs for most uses. Please see the
|
|
54
|
+
/// queries module for more information on how to interact with envelopes.
|
|
55
|
+
export type EnvelopeCase =
|
|
56
|
+
| {
|
|
57
|
+
type: "node";
|
|
58
|
+
/// The subject of the node
|
|
59
|
+
subject: Envelope;
|
|
60
|
+
/// The assertions attached to the subject
|
|
61
|
+
assertions: Envelope[];
|
|
62
|
+
/// The digest of the node
|
|
63
|
+
digest: Digest;
|
|
64
|
+
}
|
|
65
|
+
| {
|
|
66
|
+
type: "leaf";
|
|
67
|
+
/// The CBOR value contained in the leaf
|
|
68
|
+
cbor: Cbor;
|
|
69
|
+
/// The digest of the leaf
|
|
70
|
+
digest: Digest;
|
|
71
|
+
}
|
|
72
|
+
| {
|
|
73
|
+
type: "wrapped";
|
|
74
|
+
/// The envelope being wrapped
|
|
75
|
+
envelope: Envelope;
|
|
76
|
+
/// The digest of the wrapped envelope
|
|
77
|
+
digest: Digest;
|
|
78
|
+
}
|
|
79
|
+
| {
|
|
80
|
+
type: "assertion";
|
|
81
|
+
/// The assertion
|
|
82
|
+
assertion: Assertion;
|
|
83
|
+
}
|
|
84
|
+
| {
|
|
85
|
+
type: "elided";
|
|
86
|
+
/// The digest of the elided content
|
|
87
|
+
digest: Digest;
|
|
88
|
+
}
|
|
89
|
+
| {
|
|
90
|
+
type: "knownValue";
|
|
91
|
+
/// The known value instance
|
|
92
|
+
value: KnownValue;
|
|
93
|
+
/// The digest of the known value
|
|
94
|
+
digest: Digest;
|
|
95
|
+
}
|
|
96
|
+
| {
|
|
97
|
+
type: "encrypted";
|
|
98
|
+
/// The encrypted message
|
|
99
|
+
message: EncryptedMessage;
|
|
100
|
+
}
|
|
101
|
+
| {
|
|
102
|
+
type: "compressed";
|
|
103
|
+
/// The compressed data
|
|
104
|
+
value: Compressed;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
// Import types from extension modules (will be available at runtime)
|
|
108
|
+
import { Compressed } from "../extension/compress";
|
|
109
|
+
import { EncryptedMessage } from "../extension/encrypt";
|
|
110
|
+
|
|
111
|
+
/// A flexible container for structured data with built-in integrity
|
|
112
|
+
/// verification.
|
|
113
|
+
///
|
|
114
|
+
/// Gordian Envelope is the primary data structure of this library. It provides a
|
|
115
|
+
/// way to encapsulate and organize data with cryptographic integrity, privacy
|
|
116
|
+
/// features, and selective disclosure capabilities.
|
|
117
|
+
///
|
|
118
|
+
/// Key characteristics of envelopes:
|
|
119
|
+
///
|
|
120
|
+
/// - **Immutability**: Envelopes are immutable. Operations that appear to
|
|
121
|
+
/// "modify" an envelope actually create a new envelope. This immutability is
|
|
122
|
+
/// fundamental to maintaining the integrity of the envelope's digest tree.
|
|
123
|
+
///
|
|
124
|
+
/// - **Efficient Cloning**: Envelopes use shallow copying for efficient O(1)
|
|
125
|
+
/// cloning. Since they're immutable, clones share the same underlying data.
|
|
126
|
+
///
|
|
127
|
+
/// - **Semantic Structure**: Envelopes can represent various semantic
|
|
128
|
+
/// relationships through subjects, predicates, and objects (similar to RDF
|
|
129
|
+
/// triples).
|
|
130
|
+
///
|
|
131
|
+
/// - **Digest Tree**: Each envelope maintains a Merkle-like digest tree that
|
|
132
|
+
/// ensures the integrity of its contents and enables verification of
|
|
133
|
+
/// individual parts.
|
|
134
|
+
///
|
|
135
|
+
/// - **Privacy Features**: Envelopes support selective disclosure through
|
|
136
|
+
/// elision, encryption, and compression of specific parts, while maintaining
|
|
137
|
+
/// the overall integrity of the structure.
|
|
138
|
+
///
|
|
139
|
+
/// - **Deterministic Representation**: Envelopes use deterministic CBOR
|
|
140
|
+
/// encoding to ensure consistent serialization across platforms.
|
|
141
|
+
///
|
|
142
|
+
/// The Gordian Envelope specification is defined in an IETF Internet Draft, and
|
|
143
|
+
/// this implementation closely follows that specification.
|
|
144
|
+
///
|
|
145
|
+
/// @example
|
|
146
|
+
/// ```typescript
|
|
147
|
+
/// // Create an envelope representing a person
|
|
148
|
+
/// const person = Envelope.new("person")
|
|
149
|
+
/// .addAssertion("name", "Alice")
|
|
150
|
+
/// .addAssertion("age", 30)
|
|
151
|
+
/// .addAssertion("email", "alice@example.com");
|
|
152
|
+
///
|
|
153
|
+
/// // Create a partially redacted version by eliding the email
|
|
154
|
+
/// const redacted = person.elideRemovingTarget(
|
|
155
|
+
/// person.assertionWithPredicate("email")
|
|
156
|
+
/// );
|
|
157
|
+
///
|
|
158
|
+
/// // The digest of both envelopes remains the same
|
|
159
|
+
/// assert(person.digest().equals(redacted.digest()));
|
|
160
|
+
/// ```
|
|
161
|
+
export class Envelope implements DigestProvider {
|
|
162
|
+
readonly #case: EnvelopeCase;
|
|
163
|
+
|
|
164
|
+
/// Private constructor. Use static factory methods to create envelopes.
|
|
165
|
+
///
|
|
166
|
+
/// @param envelopeCase - The envelope case variant
|
|
167
|
+
private constructor(envelopeCase: EnvelopeCase) {
|
|
168
|
+
this.#case = envelopeCase;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/// Returns a reference to the underlying envelope case.
|
|
172
|
+
///
|
|
173
|
+
/// The `EnvelopeCase` enum represents the specific structural variant of
|
|
174
|
+
/// this envelope. This method provides access to that underlying
|
|
175
|
+
/// variant for operations that need to differentiate between the
|
|
176
|
+
/// different envelope types.
|
|
177
|
+
///
|
|
178
|
+
/// @returns The `EnvelopeCase` that defines this envelope's structure.
|
|
179
|
+
case(): EnvelopeCase {
|
|
180
|
+
return this.#case;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/// Creates an envelope with a subject, which can be any value that
|
|
184
|
+
/// can be encoded as an envelope.
|
|
185
|
+
///
|
|
186
|
+
/// @param subject - The subject value
|
|
187
|
+
/// @returns A new envelope containing the subject
|
|
188
|
+
///
|
|
189
|
+
/// @example
|
|
190
|
+
/// ```typescript
|
|
191
|
+
/// const envelope = Envelope.new("Hello, world!");
|
|
192
|
+
/// const numberEnvelope = Envelope.new(42);
|
|
193
|
+
/// const binaryEnvelope = Envelope.new(new Uint8Array([1, 2, 3]));
|
|
194
|
+
/// ```
|
|
195
|
+
static new(subject: EnvelopeEncodableValue): Envelope {
|
|
196
|
+
// Convert the subject to an envelope
|
|
197
|
+
if (subject instanceof Envelope) {
|
|
198
|
+
return subject;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Handle primitives and create leaf envelopes
|
|
202
|
+
return Envelope.newLeaf(subject);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/// Creates an envelope with a subject, or null if subject is undefined.
|
|
206
|
+
///
|
|
207
|
+
/// @param subject - The optional subject value
|
|
208
|
+
/// @returns A new envelope or null envelope
|
|
209
|
+
static newOrNull(subject: EnvelopeEncodableValue | undefined): Envelope {
|
|
210
|
+
if (subject === undefined || subject === null) {
|
|
211
|
+
return Envelope.null();
|
|
212
|
+
}
|
|
213
|
+
return Envelope.new(subject);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/// Creates an envelope with a subject, or undefined if subject is undefined.
|
|
217
|
+
///
|
|
218
|
+
/// @param subject - The optional subject value
|
|
219
|
+
/// @returns A new envelope or undefined
|
|
220
|
+
static newOrNone(subject: EnvelopeEncodableValue | undefined): Envelope | undefined {
|
|
221
|
+
if (subject === undefined || subject === null) {
|
|
222
|
+
return undefined;
|
|
223
|
+
}
|
|
224
|
+
return Envelope.new(subject);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/// Creates an envelope from an EnvelopeCase.
|
|
228
|
+
///
|
|
229
|
+
/// This is an internal method used by extensions to create envelopes
|
|
230
|
+
/// from custom case types like compressed or encrypted.
|
|
231
|
+
///
|
|
232
|
+
/// @param envelopeCase - The envelope case to wrap
|
|
233
|
+
/// @returns A new envelope with the given case
|
|
234
|
+
static fromCase(envelopeCase: EnvelopeCase): Envelope {
|
|
235
|
+
return new Envelope(envelopeCase);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/// Creates an assertion envelope with a predicate and object.
|
|
239
|
+
///
|
|
240
|
+
/// @param predicate - The predicate of the assertion
|
|
241
|
+
/// @param object - The object of the assertion
|
|
242
|
+
/// @returns A new assertion envelope
|
|
243
|
+
///
|
|
244
|
+
/// @example
|
|
245
|
+
/// ```typescript
|
|
246
|
+
/// const assertion = Envelope.newAssertion("name", "Alice");
|
|
247
|
+
/// ```
|
|
248
|
+
static newAssertion(predicate: EnvelopeEncodableValue, object: EnvelopeEncodableValue): Envelope {
|
|
249
|
+
const predicateEnv = predicate instanceof Envelope ? predicate : Envelope.new(predicate);
|
|
250
|
+
const objectEnv = object instanceof Envelope ? object : Envelope.new(object);
|
|
251
|
+
return Envelope.newWithAssertion(new Assertion(predicateEnv, objectEnv));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/// Creates a null envelope (containing CBOR null).
|
|
255
|
+
///
|
|
256
|
+
/// @returns A null envelope
|
|
257
|
+
static null(): Envelope {
|
|
258
|
+
return Envelope.newLeaf(null);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
//
|
|
262
|
+
// Internal constructors
|
|
263
|
+
//
|
|
264
|
+
|
|
265
|
+
/// Creates an envelope with a subject and unchecked assertions.
|
|
266
|
+
///
|
|
267
|
+
/// The assertions are sorted by digest and the envelope's digest is calculated.
|
|
268
|
+
///
|
|
269
|
+
/// @param subject - The subject envelope
|
|
270
|
+
/// @param uncheckedAssertions - The assertions to attach
|
|
271
|
+
/// @returns A new node envelope
|
|
272
|
+
static newWithUncheckedAssertions(subject: Envelope, uncheckedAssertions: Envelope[]): Envelope {
|
|
273
|
+
if (uncheckedAssertions.length === 0) {
|
|
274
|
+
throw new Error("Assertions array cannot be empty");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Sort assertions by digest
|
|
278
|
+
const sortedAssertions = [...uncheckedAssertions].sort((a, b) => {
|
|
279
|
+
const aHex = a.digest().hex();
|
|
280
|
+
const bHex = b.digest().hex();
|
|
281
|
+
return aHex.localeCompare(bHex);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// Calculate digest from subject and all assertions
|
|
285
|
+
const digests = [subject.digest(), ...sortedAssertions.map((a) => a.digest())];
|
|
286
|
+
const digest = Digest.fromDigests(digests);
|
|
287
|
+
|
|
288
|
+
return new Envelope({
|
|
289
|
+
type: "node",
|
|
290
|
+
subject,
|
|
291
|
+
assertions: sortedAssertions,
|
|
292
|
+
digest,
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/// Creates an envelope with a subject and validated assertions.
|
|
297
|
+
///
|
|
298
|
+
/// All assertions must be assertion or obscured envelopes.
|
|
299
|
+
///
|
|
300
|
+
/// @param subject - The subject envelope
|
|
301
|
+
/// @param assertions - The assertions to attach
|
|
302
|
+
/// @returns A new node envelope
|
|
303
|
+
/// @throws {EnvelopeError} If any assertion is not valid
|
|
304
|
+
static newWithAssertions(subject: Envelope, assertions: Envelope[]): Envelope {
|
|
305
|
+
// Validate that all assertions are assertion or obscured envelopes
|
|
306
|
+
for (const assertion of assertions) {
|
|
307
|
+
if (!assertion.isSubjectAssertion() && !assertion.isSubjectObscured()) {
|
|
308
|
+
throw EnvelopeError.invalidFormat();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return Envelope.newWithUncheckedAssertions(subject, assertions);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/// Creates an envelope with an assertion as its subject.
|
|
316
|
+
///
|
|
317
|
+
/// @param assertion - The assertion
|
|
318
|
+
/// @returns A new assertion envelope
|
|
319
|
+
static newWithAssertion(assertion: Assertion): Envelope {
|
|
320
|
+
return new Envelope({
|
|
321
|
+
type: "assertion",
|
|
322
|
+
assertion,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/// Creates an envelope with a known value.
|
|
327
|
+
///
|
|
328
|
+
/// @param value - The known value (can be a KnownValue instance or a number/bigint)
|
|
329
|
+
/// @returns A new known value envelope
|
|
330
|
+
static newWithKnownValue(value: KnownValue | number | bigint): Envelope {
|
|
331
|
+
const knownValue = value instanceof KnownValue ? value : new KnownValue(value);
|
|
332
|
+
// Calculate digest from CBOR encoding of the known value
|
|
333
|
+
const digest = Digest.fromImage(knownValue.toCborData());
|
|
334
|
+
return new Envelope({
|
|
335
|
+
type: "knownValue",
|
|
336
|
+
value: knownValue,
|
|
337
|
+
digest,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/// Creates an envelope with encrypted content.
|
|
342
|
+
///
|
|
343
|
+
/// @param encryptedMessage - The encrypted message
|
|
344
|
+
/// @returns A new encrypted envelope
|
|
345
|
+
/// @throws {EnvelopeError} If the encrypted message doesn't have a digest
|
|
346
|
+
static newWithEncrypted(encryptedMessage: EncryptedMessage): Envelope {
|
|
347
|
+
// TODO: Validate that encrypted message has digest
|
|
348
|
+
// if (!encryptedMessage.hasDigest()) {
|
|
349
|
+
// throw EnvelopeError.missingDigest();
|
|
350
|
+
// }
|
|
351
|
+
return new Envelope({
|
|
352
|
+
type: "encrypted",
|
|
353
|
+
message: encryptedMessage,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/// Creates an envelope with compressed content.
|
|
358
|
+
///
|
|
359
|
+
/// @param compressed - The compressed data
|
|
360
|
+
/// @returns A new compressed envelope
|
|
361
|
+
/// @throws {EnvelopeError} If the compressed data doesn't have a digest
|
|
362
|
+
static newWithCompressed(compressed: Compressed): Envelope {
|
|
363
|
+
// TODO: Validate that compressed has digest
|
|
364
|
+
// if (!compressed.hasDigest()) {
|
|
365
|
+
// throw EnvelopeError.missingDigest();
|
|
366
|
+
// }
|
|
367
|
+
return new Envelope({
|
|
368
|
+
type: "compressed",
|
|
369
|
+
value: compressed,
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/// Creates an elided envelope containing only a digest.
|
|
374
|
+
///
|
|
375
|
+
/// @param digest - The digest of the elided content
|
|
376
|
+
/// @returns A new elided envelope
|
|
377
|
+
static newElided(digest: Digest): Envelope {
|
|
378
|
+
return new Envelope({
|
|
379
|
+
type: "elided",
|
|
380
|
+
digest,
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/// Creates a leaf envelope containing a CBOR value.
|
|
385
|
+
///
|
|
386
|
+
/// @param value - The value to encode as CBOR
|
|
387
|
+
/// @returns A new leaf envelope
|
|
388
|
+
static newLeaf(value: unknown): Envelope {
|
|
389
|
+
// Convert value to CBOR
|
|
390
|
+
const cbor = Envelope.valueToCbor(value);
|
|
391
|
+
|
|
392
|
+
// Calculate digest from CBOR bytes
|
|
393
|
+
const cborBytes = Envelope.cborToBytes(cbor);
|
|
394
|
+
const digest = Digest.fromImage(cborBytes);
|
|
395
|
+
|
|
396
|
+
return new Envelope({
|
|
397
|
+
type: "leaf",
|
|
398
|
+
cbor,
|
|
399
|
+
digest,
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/// Creates a wrapped envelope.
|
|
404
|
+
///
|
|
405
|
+
/// @param envelope - The envelope to wrap
|
|
406
|
+
/// @returns A new wrapped envelope
|
|
407
|
+
static newWrapped(envelope: Envelope): Envelope {
|
|
408
|
+
const digest = Digest.fromDigests([envelope.digest()]);
|
|
409
|
+
return new Envelope({
|
|
410
|
+
type: "wrapped",
|
|
411
|
+
envelope,
|
|
412
|
+
digest,
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/// Returns the digest of this envelope.
|
|
417
|
+
///
|
|
418
|
+
/// Implementation of DigestProvider interface.
|
|
419
|
+
///
|
|
420
|
+
/// @returns The envelope's digest
|
|
421
|
+
digest(): Digest {
|
|
422
|
+
const c = this.#case;
|
|
423
|
+
switch (c.type) {
|
|
424
|
+
case "node":
|
|
425
|
+
case "leaf":
|
|
426
|
+
case "wrapped":
|
|
427
|
+
case "elided":
|
|
428
|
+
case "knownValue":
|
|
429
|
+
return c.digest;
|
|
430
|
+
case "assertion":
|
|
431
|
+
return c.assertion.digest();
|
|
432
|
+
case "encrypted": {
|
|
433
|
+
// Get digest from encrypted message (AAD)
|
|
434
|
+
const digest = c.message.aadDigest();
|
|
435
|
+
if (digest === undefined) {
|
|
436
|
+
throw new Error("Encrypted envelope missing digest");
|
|
437
|
+
}
|
|
438
|
+
return digest;
|
|
439
|
+
}
|
|
440
|
+
case "compressed": {
|
|
441
|
+
// Get digest from compressed value
|
|
442
|
+
const digest = c.value.digestOpt();
|
|
443
|
+
if (digest === undefined) {
|
|
444
|
+
throw new Error("Compressed envelope missing digest");
|
|
445
|
+
}
|
|
446
|
+
return digest;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/// Returns the subject of this envelope.
|
|
452
|
+
///
|
|
453
|
+
/// For different envelope cases:
|
|
454
|
+
/// - Node: Returns the subject envelope
|
|
455
|
+
/// - Other cases: Returns the envelope itself
|
|
456
|
+
///
|
|
457
|
+
/// @returns The subject envelope
|
|
458
|
+
subject(): Envelope {
|
|
459
|
+
const c = this.#case;
|
|
460
|
+
switch (c.type) {
|
|
461
|
+
case "node":
|
|
462
|
+
return c.subject;
|
|
463
|
+
case "leaf":
|
|
464
|
+
case "wrapped":
|
|
465
|
+
case "assertion":
|
|
466
|
+
case "elided":
|
|
467
|
+
case "knownValue":
|
|
468
|
+
case "encrypted":
|
|
469
|
+
case "compressed":
|
|
470
|
+
return this;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/// Checks if the envelope's subject is an assertion.
|
|
475
|
+
///
|
|
476
|
+
/// @returns `true` if the subject is an assertion, `false` otherwise
|
|
477
|
+
isSubjectAssertion(): boolean {
|
|
478
|
+
return this.#case.type === "assertion";
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/// Checks if the envelope's subject is obscured (elided, encrypted, or compressed).
|
|
482
|
+
///
|
|
483
|
+
/// @returns `true` if the subject is obscured, `false` otherwise
|
|
484
|
+
isSubjectObscured(): boolean {
|
|
485
|
+
const t = this.#case.type;
|
|
486
|
+
return t === "elided" || t === "encrypted" || t === "compressed";
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
//
|
|
490
|
+
// CBOR conversion helpers
|
|
491
|
+
//
|
|
492
|
+
|
|
493
|
+
/// Converts a value to CBOR.
|
|
494
|
+
///
|
|
495
|
+
/// @param value - The value to convert
|
|
496
|
+
/// @returns A CBOR representation
|
|
497
|
+
private static valueToCbor(value: unknown): Cbor {
|
|
498
|
+
// Import cbor function at runtime to avoid circular dependencies
|
|
499
|
+
|
|
500
|
+
return cbor(value as Parameters<typeof cbor>[0]);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/// Converts CBOR to bytes.
|
|
504
|
+
///
|
|
505
|
+
/// @param cbor - The CBOR value
|
|
506
|
+
/// @returns Byte representation
|
|
507
|
+
private static cborToBytes(cbor: Cbor): Uint8Array {
|
|
508
|
+
// Import cborData function at runtime to avoid circular dependencies
|
|
509
|
+
|
|
510
|
+
return cborData(cbor);
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/// Returns the untagged CBOR representation of this envelope.
|
|
514
|
+
///
|
|
515
|
+
/// @returns The untagged CBOR
|
|
516
|
+
untaggedCbor(): Cbor {
|
|
517
|
+
const c = this.#case;
|
|
518
|
+
switch (c.type) {
|
|
519
|
+
case "node": {
|
|
520
|
+
// Array with subject followed by assertions
|
|
521
|
+
const result = [c.subject.untaggedCbor()];
|
|
522
|
+
for (const assertion of c.assertions) {
|
|
523
|
+
result.push(assertion.untaggedCbor());
|
|
524
|
+
}
|
|
525
|
+
return Envelope.valueToCbor(result);
|
|
526
|
+
}
|
|
527
|
+
case "leaf":
|
|
528
|
+
// Tagged with TAG_LEAF (204)
|
|
529
|
+
return toTaggedValue(TAG_LEAF, c.cbor);
|
|
530
|
+
case "wrapped":
|
|
531
|
+
// Wrapped envelopes are tagged with TAG_ENVELOPE
|
|
532
|
+
return c.envelope.taggedCbor();
|
|
533
|
+
case "assertion":
|
|
534
|
+
// Assertions convert to CBOR maps
|
|
535
|
+
return c.assertion.toCbor();
|
|
536
|
+
case "elided":
|
|
537
|
+
// Elided is just the digest bytes
|
|
538
|
+
return Envelope.valueToCbor(c.digest.data());
|
|
539
|
+
case "knownValue":
|
|
540
|
+
// TODO: Implement known value encoding
|
|
541
|
+
throw new Error("Known value encoding not yet implemented");
|
|
542
|
+
case "encrypted": {
|
|
543
|
+
// Encrypted is tagged with TAG_ENCRYPTED (40002)
|
|
544
|
+
// Contains: [ciphertext, nonce, auth, optional_aad_digest]
|
|
545
|
+
// Per BCR-2023-004 and BCR-2022-001
|
|
546
|
+
const message = c.message;
|
|
547
|
+
const digest = message.aadDigest();
|
|
548
|
+
const arr =
|
|
549
|
+
digest !== undefined
|
|
550
|
+
? [message.ciphertext(), message.nonce(), message.authTag(), digest.data()]
|
|
551
|
+
: [message.ciphertext(), message.nonce(), message.authTag()];
|
|
552
|
+
return toTaggedValue(TAG_ENCRYPTED, Envelope.valueToCbor(arr));
|
|
553
|
+
}
|
|
554
|
+
case "compressed": {
|
|
555
|
+
// Compressed is tagged with TAG_COMPRESSED (40003)
|
|
556
|
+
// and contains an array: [compressed_data, optional_digest]
|
|
557
|
+
const digest = c.value.digestOpt();
|
|
558
|
+
const data = c.value.compressedData();
|
|
559
|
+
const arr = digest !== undefined ? [data, digest.data()] : [data];
|
|
560
|
+
return toTaggedValue(TAG_COMPRESSED, Envelope.valueToCbor(arr));
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/// Returns the tagged CBOR representation of this envelope.
|
|
566
|
+
///
|
|
567
|
+
/// All envelopes are tagged with TAG_ENVELOPE (200).
|
|
568
|
+
///
|
|
569
|
+
/// @returns The tagged CBOR
|
|
570
|
+
taggedCbor(): Cbor {
|
|
571
|
+
return toTaggedValue(TAG_ENVELOPE, this.untaggedCbor());
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/// Creates an envelope from untagged CBOR.
|
|
575
|
+
///
|
|
576
|
+
/// @param cbor - The untagged CBOR value
|
|
577
|
+
/// @returns A new envelope
|
|
578
|
+
static fromUntaggedCbor(cbor: Cbor): Envelope {
|
|
579
|
+
// Check if it's a tagged value
|
|
580
|
+
const tagged = asTaggedValue(cbor);
|
|
581
|
+
if (tagged !== undefined) {
|
|
582
|
+
const [tag, item] = tagged;
|
|
583
|
+
switch (tag.value) {
|
|
584
|
+
case TAG_LEAF:
|
|
585
|
+
case TAG_ENCODED_CBOR:
|
|
586
|
+
// Leaf envelope
|
|
587
|
+
return Envelope.newLeaf(item);
|
|
588
|
+
case TAG_ENVELOPE: {
|
|
589
|
+
// Wrapped envelope
|
|
590
|
+
const envelope = Envelope.fromUntaggedCbor(item);
|
|
591
|
+
return Envelope.newWrapped(envelope);
|
|
592
|
+
}
|
|
593
|
+
case TAG_COMPRESSED: {
|
|
594
|
+
// Compressed envelope: array with [compressed_data, optional_digest]
|
|
595
|
+
const arr = asCborArray(item);
|
|
596
|
+
if (arr === undefined || arr.length < 1 || arr.length > 2) {
|
|
597
|
+
throw EnvelopeError.cbor("compressed envelope must have 1 or 2 elements");
|
|
598
|
+
}
|
|
599
|
+
// We've already checked arr.length >= 1 above
|
|
600
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
601
|
+
const compressedData = asByteString(arr.get(0)!);
|
|
602
|
+
if (compressedData === undefined) {
|
|
603
|
+
throw EnvelopeError.cbor("compressed data must be byte string");
|
|
604
|
+
}
|
|
605
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
606
|
+
const digestBytes = arr.length === 2 ? asByteString(arr.get(1)!) : undefined;
|
|
607
|
+
if (arr.length === 2 && digestBytes === undefined) {
|
|
608
|
+
throw EnvelopeError.cbor("digest must be byte string");
|
|
609
|
+
}
|
|
610
|
+
const digest = digestBytes !== undefined ? new Digest(digestBytes) : undefined;
|
|
611
|
+
|
|
612
|
+
// Import Compressed class at runtime to avoid circular dependency
|
|
613
|
+
|
|
614
|
+
const compressed = new Compressed(compressedData, digest);
|
|
615
|
+
return Envelope.fromCase({ type: "compressed", value: compressed });
|
|
616
|
+
}
|
|
617
|
+
case TAG_ENCRYPTED: {
|
|
618
|
+
// Encrypted envelope: array with [ciphertext, nonce, auth, optional_aad_digest]
|
|
619
|
+
// Per BCR-2023-004 and BCR-2022-001
|
|
620
|
+
const arr = asCborArray(item);
|
|
621
|
+
if (arr === undefined || arr.length < 3 || arr.length > 4) {
|
|
622
|
+
throw EnvelopeError.cbor("encrypted envelope must have 3 or 4 elements");
|
|
623
|
+
}
|
|
624
|
+
// We've already checked arr.length >= 3 above
|
|
625
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
626
|
+
const ciphertext = asByteString(arr.get(0)!);
|
|
627
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
628
|
+
const nonce = asByteString(arr.get(1)!);
|
|
629
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
630
|
+
const authTag = asByteString(arr.get(2)!);
|
|
631
|
+
if (ciphertext === undefined || nonce === undefined || authTag === undefined) {
|
|
632
|
+
throw EnvelopeError.cbor("ciphertext, nonce, and auth must be byte strings");
|
|
633
|
+
}
|
|
634
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
635
|
+
const digestBytes = arr.length === 4 ? asByteString(arr.get(3)!) : undefined;
|
|
636
|
+
if (arr.length === 4 && digestBytes === undefined) {
|
|
637
|
+
throw EnvelopeError.cbor("aad digest must be byte string");
|
|
638
|
+
}
|
|
639
|
+
const digest = digestBytes !== undefined ? new Digest(digestBytes) : undefined;
|
|
640
|
+
|
|
641
|
+
const message = new EncryptedMessage(ciphertext, nonce, authTag, digest);
|
|
642
|
+
return Envelope.fromCase({ type: "encrypted", message });
|
|
643
|
+
}
|
|
644
|
+
default:
|
|
645
|
+
throw EnvelopeError.cbor(`unknown envelope tag: ${tag.value}`);
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Check if it's a byte string (elided)
|
|
650
|
+
const bytes = asByteString(cbor);
|
|
651
|
+
if (bytes !== undefined) {
|
|
652
|
+
if (bytes.length !== 32) {
|
|
653
|
+
throw EnvelopeError.cbor("elided digest must be 32 bytes");
|
|
654
|
+
}
|
|
655
|
+
return Envelope.newElided(new Digest(bytes));
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Check if it's an array (node)
|
|
659
|
+
const array = asCborArray(cbor);
|
|
660
|
+
if (array !== undefined) {
|
|
661
|
+
if (array.length < 2) {
|
|
662
|
+
throw EnvelopeError.cbor("node must have at least two elements");
|
|
663
|
+
}
|
|
664
|
+
const subjectCbor = array.get(0);
|
|
665
|
+
if (subjectCbor === undefined) {
|
|
666
|
+
throw EnvelopeError.cbor("node subject is missing");
|
|
667
|
+
}
|
|
668
|
+
const subject = Envelope.fromUntaggedCbor(subjectCbor);
|
|
669
|
+
const assertions: Envelope[] = [];
|
|
670
|
+
for (let i = 1; i < array.length; i++) {
|
|
671
|
+
const assertionCbor = array.get(i);
|
|
672
|
+
if (assertionCbor === undefined) {
|
|
673
|
+
throw EnvelopeError.cbor(`node assertion at index ${i} is missing`);
|
|
674
|
+
}
|
|
675
|
+
assertions.push(Envelope.fromUntaggedCbor(assertionCbor));
|
|
676
|
+
}
|
|
677
|
+
return Envelope.newWithAssertions(subject, assertions);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Check if it's a map (assertion)
|
|
681
|
+
const map = asCborMap(cbor);
|
|
682
|
+
if (map !== undefined) {
|
|
683
|
+
const assertion = Assertion.fromCborMap(map);
|
|
684
|
+
return Envelope.newWithAssertion(assertion);
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Handle known values (unsigned integers)
|
|
688
|
+
if (cbor.type === MajorType.Unsigned) {
|
|
689
|
+
const knownValue = new KnownValue(cbor.value as number | bigint);
|
|
690
|
+
return Envelope.newWithKnownValue(knownValue);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
throw EnvelopeError.cbor("invalid envelope format");
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/// Creates an envelope from tagged CBOR.
|
|
697
|
+
///
|
|
698
|
+
/// @param cbor - The tagged CBOR value (should have TAG_ENVELOPE)
|
|
699
|
+
/// @returns A new envelope
|
|
700
|
+
static fromTaggedCbor(cbor: Cbor): Envelope {
|
|
701
|
+
try {
|
|
702
|
+
const untagged = tryExpectedTaggedValue(cbor, TAG_ENVELOPE);
|
|
703
|
+
return Envelope.fromUntaggedCbor(untagged);
|
|
704
|
+
} catch (error) {
|
|
705
|
+
throw EnvelopeError.cbor(
|
|
706
|
+
`expected TAG_ENVELOPE (${TAG_ENVELOPE})`,
|
|
707
|
+
error instanceof Error ? error : undefined,
|
|
708
|
+
);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
/// Adds an assertion to this envelope.
|
|
713
|
+
///
|
|
714
|
+
/// @param predicate - The assertion predicate
|
|
715
|
+
/// @param object - The assertion object
|
|
716
|
+
/// @returns A new envelope with the assertion added
|
|
717
|
+
///
|
|
718
|
+
/// @example
|
|
719
|
+
/// ```typescript
|
|
720
|
+
/// const person = Envelope.new("Alice")
|
|
721
|
+
/// .addAssertion("age", 30)
|
|
722
|
+
/// .addAssertion("city", "Boston");
|
|
723
|
+
/// ```
|
|
724
|
+
addAssertion(predicate: EnvelopeEncodableValue, object: EnvelopeEncodableValue): Envelope {
|
|
725
|
+
const assertion = Envelope.newAssertion(predicate, object);
|
|
726
|
+
return this.addAssertionEnvelope(assertion);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/// Adds an assertion envelope to this envelope.
|
|
730
|
+
///
|
|
731
|
+
/// @param assertion - The assertion envelope
|
|
732
|
+
/// @returns A new envelope with the assertion added
|
|
733
|
+
addAssertionEnvelope(assertion: Envelope): Envelope {
|
|
734
|
+
const c = this.#case;
|
|
735
|
+
|
|
736
|
+
// If this is already a node, add to existing assertions
|
|
737
|
+
if (c.type === "node") {
|
|
738
|
+
return Envelope.newWithAssertions(c.subject, [...c.assertions, assertion]);
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
// Otherwise, create a new node with this envelope as subject
|
|
742
|
+
return Envelope.newWithAssertions(this, [assertion]);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
/// Creates a string representation of this envelope.
|
|
746
|
+
///
|
|
747
|
+
/// @returns A string representation
|
|
748
|
+
toString(): string {
|
|
749
|
+
return `Envelope(${this.#case.type})`;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/// Creates a shallow copy of this envelope.
|
|
753
|
+
///
|
|
754
|
+
/// Since envelopes are immutable, this returns the same instance.
|
|
755
|
+
///
|
|
756
|
+
/// @returns This envelope
|
|
757
|
+
clone(): Envelope {
|
|
758
|
+
return this;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
//
|
|
762
|
+
// Format methods (implemented via prototype extension in format module)
|
|
763
|
+
//
|
|
764
|
+
|
|
765
|
+
/// Returns a tree-formatted string representation of the envelope.
|
|
766
|
+
///
|
|
767
|
+
/// The tree format displays the hierarchical structure of the envelope,
|
|
768
|
+
/// showing subjects, assertions, and their relationships.
|
|
769
|
+
///
|
|
770
|
+
/// @param options - Optional formatting options
|
|
771
|
+
/// @returns A tree-formatted string
|
|
772
|
+
declare treeFormat: (options?: {
|
|
773
|
+
hideNodes?: boolean;
|
|
774
|
+
highlightDigests?: Set<string>;
|
|
775
|
+
digestDisplay?: "short" | "full";
|
|
776
|
+
}) => string;
|
|
777
|
+
|
|
778
|
+
/// Returns a short identifier for this envelope based on its digest.
|
|
779
|
+
///
|
|
780
|
+
/// @param format - Format for the digest ('short' or 'full')
|
|
781
|
+
/// @returns A digest identifier string
|
|
782
|
+
declare shortId: (format?: "short" | "full") => string;
|
|
783
|
+
|
|
784
|
+
/// Returns a summary string for this envelope.
|
|
785
|
+
///
|
|
786
|
+
/// @param maxLength - Maximum length of the summary
|
|
787
|
+
/// @returns A summary string
|
|
788
|
+
declare summary: (maxLength?: number) => string;
|
|
789
|
+
|
|
790
|
+
/// Returns a hex representation of the envelope's CBOR encoding.
|
|
791
|
+
///
|
|
792
|
+
/// @returns A hex string
|
|
793
|
+
declare hex: () => string;
|
|
794
|
+
|
|
795
|
+
/// Returns the CBOR-encoded bytes of the envelope.
|
|
796
|
+
///
|
|
797
|
+
/// @returns The CBOR bytes
|
|
798
|
+
declare cborBytes: () => Uint8Array;
|
|
799
|
+
|
|
800
|
+
/// Returns a CBOR diagnostic notation string for the envelope.
|
|
801
|
+
///
|
|
802
|
+
/// @returns A diagnostic string
|
|
803
|
+
declare diagnostic: () => string;
|
|
804
|
+
|
|
805
|
+
//
|
|
806
|
+
// Extension methods (implemented via prototype extension in extension modules)
|
|
807
|
+
// These declarations ensure TypeScript recognizes the methods when consuming the package
|
|
808
|
+
//
|
|
809
|
+
|
|
810
|
+
// From assertions.ts
|
|
811
|
+
declare addAssertionEnvelopes: (assertions: Envelope[]) => Envelope;
|
|
812
|
+
declare addOptionalAssertionEnvelope: (assertion: Envelope | undefined) => Envelope;
|
|
813
|
+
declare addOptionalAssertion: (
|
|
814
|
+
predicate: EnvelopeEncodableValue,
|
|
815
|
+
object: EnvelopeEncodableValue | undefined,
|
|
816
|
+
) => Envelope;
|
|
817
|
+
declare addNonemptyStringAssertion: (predicate: EnvelopeEncodableValue, str: string) => Envelope;
|
|
818
|
+
declare addAssertions: (envelopes: Envelope[]) => Envelope;
|
|
819
|
+
declare addAssertionIf: (
|
|
820
|
+
condition: boolean,
|
|
821
|
+
predicate: EnvelopeEncodableValue,
|
|
822
|
+
object: EnvelopeEncodableValue,
|
|
823
|
+
) => Envelope;
|
|
824
|
+
declare addAssertionEnvelopeIf: (condition: boolean, assertionEnvelope: Envelope) => Envelope;
|
|
825
|
+
declare removeAssertion: (target: Envelope) => Envelope;
|
|
826
|
+
declare replaceAssertion: (assertion: Envelope, newAssertion: Envelope) => Envelope;
|
|
827
|
+
declare replaceSubject: (subject: Envelope) => Envelope;
|
|
828
|
+
|
|
829
|
+
// From elide.ts
|
|
830
|
+
declare elide: () => Envelope;
|
|
831
|
+
declare elideRemovingSetWithAction: (target: Set<Digest>, action: ObscureAction) => Envelope;
|
|
832
|
+
declare elideRemovingSet: (target: Set<Digest>) => Envelope;
|
|
833
|
+
declare elideRemovingArrayWithAction: (
|
|
834
|
+
target: DigestProvider[],
|
|
835
|
+
action: ObscureAction,
|
|
836
|
+
) => Envelope;
|
|
837
|
+
declare elideRemovingArray: (target: DigestProvider[]) => Envelope;
|
|
838
|
+
declare elideRemovingTargetWithAction: (
|
|
839
|
+
target: DigestProvider,
|
|
840
|
+
action: ObscureAction,
|
|
841
|
+
) => Envelope;
|
|
842
|
+
declare elideRemovingTarget: (target: DigestProvider) => Envelope;
|
|
843
|
+
declare elideRevealingSetWithAction: (target: Set<Digest>, action: ObscureAction) => Envelope;
|
|
844
|
+
declare elideRevealingSet: (target: Set<Digest>) => Envelope;
|
|
845
|
+
declare elideRevealingArrayWithAction: (
|
|
846
|
+
target: DigestProvider[],
|
|
847
|
+
action: ObscureAction,
|
|
848
|
+
) => Envelope;
|
|
849
|
+
declare elideRevealingArray: (target: DigestProvider[]) => Envelope;
|
|
850
|
+
declare elideRevealingTargetWithAction: (
|
|
851
|
+
target: DigestProvider,
|
|
852
|
+
action: ObscureAction,
|
|
853
|
+
) => Envelope;
|
|
854
|
+
declare elideRevealingTarget: (target: DigestProvider) => Envelope;
|
|
855
|
+
declare unelide: (envelope: Envelope) => Envelope;
|
|
856
|
+
declare nodesMatching: (
|
|
857
|
+
targetDigests: Set<Digest> | undefined,
|
|
858
|
+
obscureTypes: ObscureType[],
|
|
859
|
+
) => Set<Digest>;
|
|
860
|
+
declare walkUnelide: (envelopes: Envelope[]) => Envelope;
|
|
861
|
+
declare walkReplace: (target: Set<Digest>, replacement: Envelope) => Envelope;
|
|
862
|
+
declare isIdenticalTo: (other: Envelope) => boolean;
|
|
863
|
+
|
|
864
|
+
// From leaf.ts
|
|
865
|
+
declare tryLeaf: () => Cbor;
|
|
866
|
+
declare extractString: () => string;
|
|
867
|
+
declare extractNumber: () => number;
|
|
868
|
+
declare extractBoolean: () => boolean;
|
|
869
|
+
declare extractBytes: () => Uint8Array;
|
|
870
|
+
declare extractNull: () => null;
|
|
871
|
+
|
|
872
|
+
// From queries.ts
|
|
873
|
+
declare isFalse: () => boolean;
|
|
874
|
+
declare isTrue: () => boolean;
|
|
875
|
+
declare isBool: () => boolean;
|
|
876
|
+
declare isNumber: () => boolean;
|
|
877
|
+
declare isSubjectNumber: () => boolean;
|
|
878
|
+
declare isNaN: () => boolean;
|
|
879
|
+
declare isSubjectNaN: () => boolean;
|
|
880
|
+
declare isNull: () => boolean;
|
|
881
|
+
declare tryByteString: () => Uint8Array;
|
|
882
|
+
declare asByteString: () => Uint8Array | undefined;
|
|
883
|
+
declare asArray: () => readonly Cbor[] | undefined;
|
|
884
|
+
declare asMap: () => CborMap | undefined;
|
|
885
|
+
declare asText: () => string | undefined;
|
|
886
|
+
declare asLeaf: () => Cbor | undefined;
|
|
887
|
+
declare hasAssertions: () => boolean;
|
|
888
|
+
declare asAssertion: () => Envelope | undefined;
|
|
889
|
+
declare tryAssertion: () => Envelope;
|
|
890
|
+
declare asPredicate: () => Envelope | undefined;
|
|
891
|
+
declare tryPredicate: () => Envelope;
|
|
892
|
+
declare asObject: () => Envelope | undefined;
|
|
893
|
+
declare tryObject: () => Envelope;
|
|
894
|
+
declare isAssertion: () => boolean;
|
|
895
|
+
declare isElided: () => boolean;
|
|
896
|
+
declare isLeaf: () => boolean;
|
|
897
|
+
declare isNode: () => boolean;
|
|
898
|
+
declare isWrapped: () => boolean;
|
|
899
|
+
declare isInternal: () => boolean;
|
|
900
|
+
declare isObscured: () => boolean;
|
|
901
|
+
declare assertions: () => Envelope[];
|
|
902
|
+
declare assertionsWithPredicate: (predicate: EnvelopeEncodableValue) => Envelope[];
|
|
903
|
+
declare assertionWithPredicate: (predicate: EnvelopeEncodableValue) => Envelope;
|
|
904
|
+
declare optionalAssertionWithPredicate: (
|
|
905
|
+
predicate: EnvelopeEncodableValue,
|
|
906
|
+
) => Envelope | undefined;
|
|
907
|
+
declare objectForPredicate: (predicate: EnvelopeEncodableValue) => Envelope;
|
|
908
|
+
declare optionalObjectForPredicate: (predicate: EnvelopeEncodableValue) => Envelope | undefined;
|
|
909
|
+
declare objectsForPredicate: (predicate: EnvelopeEncodableValue) => Envelope[];
|
|
910
|
+
declare elementsCount: () => number;
|
|
911
|
+
|
|
912
|
+
// From walk.ts
|
|
913
|
+
declare walk: <State>(hideNodes: boolean, state: State, visit: Visitor<State>) => void;
|
|
914
|
+
|
|
915
|
+
// From wrap.ts
|
|
916
|
+
declare wrap: () => Envelope;
|
|
917
|
+
declare tryUnwrap: () => Envelope;
|
|
918
|
+
declare unwrap: () => Envelope;
|
|
919
|
+
|
|
920
|
+
// From attachment.ts
|
|
921
|
+
declare addAttachment: (
|
|
922
|
+
payload: EnvelopeEncodableValue,
|
|
923
|
+
vendor: string,
|
|
924
|
+
conformsTo?: string,
|
|
925
|
+
) => Envelope;
|
|
926
|
+
declare attachmentPayload: () => Envelope;
|
|
927
|
+
declare attachmentVendor: () => string;
|
|
928
|
+
declare attachmentConformsTo: () => string | undefined;
|
|
929
|
+
declare attachments: () => Envelope[];
|
|
930
|
+
declare attachmentsWithVendorAndConformsTo: (vendor?: string, conformsTo?: string) => Envelope[];
|
|
931
|
+
|
|
932
|
+
// From compress.ts
|
|
933
|
+
declare compress: () => Envelope;
|
|
934
|
+
declare decompress: () => Envelope;
|
|
935
|
+
declare compressSubject: () => Envelope;
|
|
936
|
+
declare decompressSubject: () => Envelope;
|
|
937
|
+
declare isCompressed: () => boolean;
|
|
938
|
+
|
|
939
|
+
// From encrypt.ts
|
|
940
|
+
declare encryptSubject: (key: SymmetricKey) => Envelope;
|
|
941
|
+
declare decryptSubject: (key: SymmetricKey) => Envelope;
|
|
942
|
+
declare encrypt: (key: SymmetricKey) => Envelope;
|
|
943
|
+
declare decrypt: (key: SymmetricKey) => Envelope;
|
|
944
|
+
declare isEncrypted: () => boolean;
|
|
945
|
+
|
|
946
|
+
// From proof.ts
|
|
947
|
+
declare proofContainsSet: (target: Set<Digest>) => Envelope | undefined;
|
|
948
|
+
declare proofContainsTarget: (target: Envelope) => Envelope | undefined;
|
|
949
|
+
declare confirmContainsSet: (target: Set<Digest>, proof: Envelope) => boolean;
|
|
950
|
+
declare confirmContainsTarget: (target: Envelope, proof: Envelope) => boolean;
|
|
951
|
+
|
|
952
|
+
// From recipient.ts
|
|
953
|
+
declare encryptSubjectToRecipient: (recipientPublicKey: PublicKeyBase) => Envelope;
|
|
954
|
+
declare encryptSubjectToRecipients: (recipients: PublicKeyBase[]) => Envelope;
|
|
955
|
+
declare addRecipient: (recipientPublicKey: PublicKeyBase, contentKey: SymmetricKey) => Envelope;
|
|
956
|
+
declare decryptSubjectToRecipient: (recipientPrivateKey: PrivateKeyBase) => Envelope;
|
|
957
|
+
declare decryptToRecipient: (recipientPrivateKey: PrivateKeyBase) => Envelope;
|
|
958
|
+
declare encryptToRecipients: (recipients: PublicKeyBase[]) => Envelope;
|
|
959
|
+
declare recipients: () => SealedMessage[];
|
|
960
|
+
|
|
961
|
+
// From salt.ts
|
|
962
|
+
declare addSalt: () => Envelope;
|
|
963
|
+
declare addSaltWithLength: (count: number) => Envelope;
|
|
964
|
+
declare addSaltBytes: (saltBytes: Uint8Array) => Envelope;
|
|
965
|
+
declare addSaltInRange: (min: number, max: number) => Envelope;
|
|
966
|
+
|
|
967
|
+
// From signature.ts
|
|
968
|
+
declare addSignature: (signer: Signer) => Envelope;
|
|
969
|
+
declare addSignatureWithMetadata: (signer: Signer, metadata?: SignatureMetadata) => Envelope;
|
|
970
|
+
declare addSignatures: (signers: Signer[]) => Envelope;
|
|
971
|
+
declare hasSignatureFrom: (verifier: Verifier) => boolean;
|
|
972
|
+
declare verifySignatureFrom: (verifier: Verifier) => Envelope;
|
|
973
|
+
declare signatures: () => Envelope[];
|
|
974
|
+
|
|
975
|
+
// From types.ts
|
|
976
|
+
declare addType: (object: EnvelopeEncodableValue) => Envelope;
|
|
977
|
+
declare types: () => Envelope[];
|
|
978
|
+
declare getType: () => Envelope;
|
|
979
|
+
declare hasType: (t: EnvelopeEncodableValue) => boolean;
|
|
980
|
+
declare checkType: (t: EnvelopeEncodableValue) => void;
|
|
981
|
+
|
|
982
|
+
// Static methods from extensions
|
|
983
|
+
declare static newAttachment: (
|
|
984
|
+
payload: EnvelopeEncodableValue,
|
|
985
|
+
vendor: string,
|
|
986
|
+
conformsTo?: string,
|
|
987
|
+
) => Envelope;
|
|
988
|
+
}
|