@helios-lang/effect 0.1.0

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.
Files changed (64) hide show
  1. package/LICENSE +28 -0
  2. package/README.md +3 -0
  3. package/dist/Address.js +13 -0
  4. package/dist/Address.js.map +1 -0
  5. package/dist/Bech32.js +153 -0
  6. package/dist/Bech32.js.map +1 -0
  7. package/dist/Cbor.js +1171 -0
  8. package/dist/Cbor.js.map +1 -0
  9. package/dist/Uplc/Cek.js +3 -0
  10. package/dist/Uplc/Cek.js.map +1 -0
  11. package/dist/Uplc/Data.js +171 -0
  12. package/dist/Uplc/Data.js.map +1 -0
  13. package/dist/Uplc/DataSchema.js +118 -0
  14. package/dist/Uplc/DataSchema.js.map +1 -0
  15. package/dist/Uplc/Primitive.js +23 -0
  16. package/dist/Uplc/Primitive.js.map +1 -0
  17. package/dist/Uplc/index.js +4 -0
  18. package/dist/Uplc/index.js.map +1 -0
  19. package/dist/index.js +5 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/internal/Base32.js +201 -0
  22. package/dist/internal/Base32.js.map +1 -0
  23. package/dist/internal/BigEndian.js +56 -0
  24. package/dist/internal/BigEndian.js.map +1 -0
  25. package/dist/internal/Bits.js +300 -0
  26. package/dist/internal/Bits.js.map +1 -0
  27. package/dist/internal/Bytes.js +293 -0
  28. package/dist/internal/Bytes.js.map +1 -0
  29. package/dist/internal/Flat.js +298 -0
  30. package/dist/internal/Flat.js.map +1 -0
  31. package/dist/internal/Float.js +154 -0
  32. package/dist/internal/Float.js.map +1 -0
  33. package/dist/internal/Utf8.js +44 -0
  34. package/dist/internal/Utf8.js.map +1 -0
  35. package/eslint.config.mjs +30 -0
  36. package/package.json +36 -0
  37. package/src/Address.ts +20 -0
  38. package/src/Bech32.test.ts +117 -0
  39. package/src/Bech32.ts +198 -0
  40. package/src/Cbor.test.ts +1610 -0
  41. package/src/Cbor.ts +1704 -0
  42. package/src/Uplc/Cek.ts +92 -0
  43. package/src/Uplc/Data.ts +259 -0
  44. package/src/Uplc/DataSchema.test.ts +207 -0
  45. package/src/Uplc/DataSchema.ts +181 -0
  46. package/src/Uplc/Primitive.ts +56 -0
  47. package/src/Uplc/index.ts +3 -0
  48. package/src/index.ts +4 -0
  49. package/src/internal/Base32.test.ts +219 -0
  50. package/src/internal/Base32.ts +341 -0
  51. package/src/internal/BigEndian.test.ts +79 -0
  52. package/src/internal/BigEndian.ts +67 -0
  53. package/src/internal/Bits.test.ts +300 -0
  54. package/src/internal/Bits.ts +398 -0
  55. package/src/internal/Bytes.test.ts +369 -0
  56. package/src/internal/Bytes.ts +343 -0
  57. package/src/internal/Flat.test.ts +29 -0
  58. package/src/internal/Flat.ts +387 -0
  59. package/src/internal/Float.test.ts +51 -0
  60. package/src/internal/Float.ts +190 -0
  61. package/src/internal/Utf8.test.ts +69 -0
  62. package/src/internal/Utf8.ts +58 -0
  63. package/tsconfig.build.json +14 -0
  64. package/tsconfig.json +38 -0
package/dist/Cbor.js ADDED
@@ -0,0 +1,1171 @@
1
+ import { Data, Effect, Either } from "effect";
2
+ import * as BigEndian from "./internal/BigEndian.js";
3
+ import * as Bytes from "./internal/Bytes.js";
4
+ import * as Float from "./internal/Float.js";
5
+ import * as Utf8 from "./internal/Utf8.js";
6
+ const FALSE_BYTE = 244; // m = 7, n = 20
7
+ const TRUE_BYTE = 245; // m = 7, n = 21
8
+ export class DecodeError extends Data.TaggedError("Cbor.DecodeError") {
9
+ constructor(_stream, message) {
10
+ super({ message: message });
11
+ }
12
+ }
13
+ /**
14
+ * Decodes a CBOR encoded `boolean`.
15
+ * Throws an error if the next element in bytes isn't a `boolean`.
16
+ * @param bytes
17
+ * @returns
18
+ */
19
+ export const decodeBool = (bytes) => Effect.gen(function* () {
20
+ const stream = Bytes.makeStream(bytes);
21
+ const b = yield* stream.shiftOne();
22
+ if (b == TRUE_BYTE) {
23
+ return true;
24
+ }
25
+ else if (b == FALSE_BYTE) {
26
+ return false;
27
+ }
28
+ else {
29
+ return yield* new DecodeError(stream, "unexpected non-boolean cbor object");
30
+ }
31
+ });
32
+ /**
33
+ * Encodes a `boolean` into its CBOR representation.
34
+ * @param b
35
+ * @returns
36
+ */
37
+ export function encodeBool(b) {
38
+ if (b) {
39
+ return [TRUE_BYTE];
40
+ }
41
+ else {
42
+ return [FALSE_BYTE];
43
+ }
44
+ }
45
+ /**
46
+ * @param bytes
47
+ * @returns
48
+ */
49
+ export const isBool = (bytes) => Bytes.makeStream(bytes)
50
+ .peekOne()
51
+ .pipe(Effect.map((head) => head == FALSE_BYTE || head == TRUE_BYTE));
52
+ /**
53
+ * Unwraps a CBOR encoded list of bytes
54
+ * @param bytes
55
+ * cborbytes, mutated to form remaining
56
+ * @returns byteArray
57
+ */
58
+ export const decodeBytes = (bytes) => Effect.gen(function* () {
59
+ const stream = Bytes.makeStream(bytes);
60
+ if (yield* isIndefBytes(bytes)) {
61
+ yield* stream.shiftOne();
62
+ // multiple chunks
63
+ let res = [];
64
+ while ((yield* stream.peekOne()) != 255) {
65
+ const [, n] = yield* decodeDefHead(stream);
66
+ if (n > 64n) {
67
+ return yield* new DecodeError(stream, "Bytearray chunk too large");
68
+ }
69
+ res = res.concat(yield* stream.shiftMany(Number(n)));
70
+ }
71
+ if ((yield* stream.shiftOne()) != 255) {
72
+ throw new Error("invalid indef bytes termination byte");
73
+ }
74
+ return res;
75
+ }
76
+ else {
77
+ const [m, n] = yield* decodeDefHead(stream);
78
+ if (m != 2) {
79
+ return yield* new DecodeError(stream, "Invalid def bytes");
80
+ }
81
+ return yield* stream.shiftMany(Number(n));
82
+ }
83
+ });
84
+ /**
85
+ * Wraps a list of bytes using CBOR. Optionally splits the bytes into chunks.
86
+ * @example
87
+ * bytesToHex(Cbor.encodeBytes("4d01000033222220051200120011")) == "4e4d01000033222220051200120011"
88
+ * @param bytes
89
+ * @param splitIntoChunks
90
+ * @returns
91
+ * cbor bytes
92
+ */
93
+ export function encodeBytes(bytes, splitIntoChunks = false) {
94
+ bytes = Bytes.toArray(bytes).slice();
95
+ if (bytes.length <= 64 || !splitIntoChunks) {
96
+ const head = encodeDefHead(2, BigInt(bytes.length));
97
+ return head.concat(bytes);
98
+ }
99
+ else {
100
+ let res = encodeIndefHead(2);
101
+ while (bytes.length > 0) {
102
+ const chunk = bytes.splice(0, 64);
103
+ res = res.concat(encodeDefHead(2, BigInt(chunk.length))).concat(chunk);
104
+ }
105
+ res.push(255);
106
+ return res;
107
+ }
108
+ }
109
+ /**
110
+ * @param bytes
111
+ * @returns
112
+ */
113
+ export const isBytes = (bytes) => peekMajorType(bytes).pipe(Effect.map((m) => m == 2));
114
+ /**
115
+ * @param bytes
116
+ * @returns
117
+ */
118
+ export const isDefBytes = (bytes) => Effect.gen(function* () {
119
+ const stream = Bytes.makeStream(bytes);
120
+ const m = yield* peekMajorType(stream);
121
+ return m == 2 && (yield* stream.peekOne()) != 2 * 32 + 31;
122
+ });
123
+ /**
124
+ * @param bytes
125
+ * @returns
126
+ */
127
+ export const isIndefBytes = (bytes) => Bytes.makeStream(bytes)
128
+ .peekOne()
129
+ .pipe(Effect.map((head) => head == 2 * 32 + 31));
130
+ /**
131
+ * The homogenous field type case is used by the uplc ConstrData (undetermined number of UplcData items)
132
+ * @template Decoders
133
+ * Note: the conditional tuple check loses the tupleness if we just check against array, hence first we check against a tuple, and then an array (needed for the empty case)
134
+ * @param fieldDecoder
135
+ * Array for heterogenous item types, single function for homogenous item types
136
+ * @returns
137
+ */
138
+ export const decodeConstr = (fieldDecoder) => (bytes) => Effect.gen(function* () {
139
+ const stream = Bytes.makeStream(bytes);
140
+ const tag = yield* decodeConstrTag(stream);
141
+ const res = yield* decodeList((itemStream, i) => Effect.gen(function* () {
142
+ if (Array.isArray(fieldDecoder)) {
143
+ const decoder = fieldDecoder[i];
144
+ if (decoder === undefined) {
145
+ return yield* new DecodeError(stream, `expected ${fieldDecoder.length} fields, got more than ${i}`);
146
+ }
147
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
148
+ return yield* decoder(itemStream);
149
+ }
150
+ else {
151
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
152
+ return yield* fieldDecoder(itemStream);
153
+ }
154
+ }))(stream);
155
+ if (Array.isArray(fieldDecoder)) {
156
+ if (res.length < fieldDecoder.length) {
157
+ return yield* new DecodeError(stream, `expected ${fieldDecoder.length} fields, only got ${res.length}`);
158
+ }
159
+ }
160
+ return [tag, res];
161
+ });
162
+ /**
163
+ * @param bytes
164
+ * @returns
165
+ */
166
+ export const decodeConstrLazy = (bytes) => Effect.gen(function* () {
167
+ const stream = Bytes.makeStream(bytes);
168
+ const tag = yield* decodeConstrTag(stream);
169
+ const decodeField = yield* decodeListLazy(bytes);
170
+ return [tag, decodeField];
171
+ });
172
+ /**
173
+ * @param bytes
174
+ * @returns
175
+ */
176
+ const decodeConstrTag = (bytes) => Effect.gen(function* () {
177
+ const stream = Bytes.makeStream(bytes);
178
+ // constr
179
+ const [m, n] = yield* decodeDefHead(stream);
180
+ if (m != 6) {
181
+ return yield* new DecodeError(stream, "Unexpected constr tag head");
182
+ }
183
+ if (n < 102n) {
184
+ return yield* new DecodeError(stream, `unexpected encoded constr tag ${n}`);
185
+ }
186
+ else if (n == 102n) {
187
+ const [mCheck, nCheck] = yield* decodeDefHead(stream);
188
+ if (mCheck != 4 || nCheck != 2n) {
189
+ return yield* new DecodeError(stream, "Unexpected constr tag nested head");
190
+ }
191
+ return Number(yield* decodeInt(stream));
192
+ }
193
+ else if (n < 121n) {
194
+ return yield* new DecodeError(stream, `unexpected encoded constr tag ${n}`);
195
+ }
196
+ else if (n <= 127n) {
197
+ return Number(n - 121n);
198
+ }
199
+ else if (n < 1280n) {
200
+ return yield* new DecodeError(stream, `unexpected encoded constr tag ${n}`);
201
+ }
202
+ else if (n <= 1400n) {
203
+ return Number(n - 1280n + 7n);
204
+ }
205
+ else {
206
+ return yield* new DecodeError(stream, `unexpected encoded constr tag ${n}`);
207
+ }
208
+ });
209
+ /**
210
+ * Note: internally the indef list format is used if the number of fields is > 0, if the number of fields is 0 the def list format is used
211
+ * see [well-typed/cborg/serialise/src/Codec/Serialise/Class.hs](https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181).
212
+ * @param tag
213
+ * @param fields
214
+ * @returns
215
+ */
216
+ export function encodeConstr(tag, fields) {
217
+ return encodeConstrTag(tag).concat(encodeList(fields));
218
+ }
219
+ /**
220
+ * Encode a constructor tag of a ConstrData type
221
+ * @param tag
222
+ * @returns
223
+ * @throws
224
+ * If the tag is negative or not a whole number
225
+ */
226
+ function encodeConstrTag(tag) {
227
+ if (tag < 0 || tag % 1.0 != 0.0) {
228
+ throw new Error("invalid tag");
229
+ }
230
+ else if (tag >= 0 && tag <= 6) {
231
+ return encodeDefHead(6, 121n + BigInt(tag));
232
+ }
233
+ else if (tag >= 7 && tag <= 127) {
234
+ return encodeDefHead(6, 1280n + BigInt(tag - 7));
235
+ }
236
+ else {
237
+ return encodeDefHead(6, 102n)
238
+ .concat(encodeDefHead(4, 2n))
239
+ .concat(encodeInt(BigInt(tag)));
240
+ }
241
+ }
242
+ /**
243
+ * @param bytes
244
+ * @returns
245
+ */
246
+ export const isConstr = (bytes) => decodeDefHead(Bytes.makeStream(bytes).copy()).pipe(Effect.map(([m, n]) => {
247
+ if (m == 6) {
248
+ return (n == 102n || (n >= 121n && n <= 127n) || (n >= 1280n && n <= 1400n));
249
+ }
250
+ else {
251
+ return false;
252
+ }
253
+ }), Effect.catchTag("Cbor.DecodeError", () => {
254
+ return Effect.succeed(false);
255
+ }));
256
+ const FLOAT16_HEAD = 249;
257
+ const FLOAT32_HEAD = 250;
258
+ const FLOAT64_HEAD = 251;
259
+ /**
260
+ * @param bytes
261
+ * @returns
262
+ */
263
+ export const decodeFloat = (bytes) => Effect.gen(function* () {
264
+ const stream = Bytes.makeStream(bytes);
265
+ const head = yield* stream.shiftOne();
266
+ switch (head) {
267
+ case FLOAT16_HEAD:
268
+ return yield* Either.mapLeft(Float.decodeFloat16(yield* stream.shiftMany(2)), (e) => new DecodeError(stream, `failed to decode float16 (${e.message})`));
269
+ case FLOAT32_HEAD:
270
+ return yield* Either.mapLeft(Float.decodeFloat32(yield* stream.shiftMany(4)), (e) => new DecodeError(stream, `failed to decode float32 (${e.message})`));
271
+ case FLOAT64_HEAD:
272
+ return yield* Either.mapLeft(Float.decodeFloat64(yield* stream.shiftMany(8)), (e) => new DecodeError(stream, `faild to decode float64 (${e.message})`));
273
+ default:
274
+ return yield* new DecodeError(stream, "invalid float header");
275
+ }
276
+ });
277
+ /**
278
+ * @param bytes
279
+ * @returns
280
+ */
281
+ export const decodeFloat16 = (bytes) => Effect.gen(function* () {
282
+ const stream = Bytes.makeStream(bytes);
283
+ const head = yield* stream.shiftOne();
284
+ if (head != FLOAT16_HEAD) {
285
+ return yield* new DecodeError(stream, "invalid Float16 header");
286
+ }
287
+ return yield* Either.mapLeft(Float.decodeFloat16(yield* stream.shiftMany(2)), (e) => new DecodeError(stream, `failed to decode float16 (${e.message})`));
288
+ });
289
+ /**
290
+ * @param bytes
291
+ * @returns
292
+ */
293
+ export const decodeFloat32 = (bytes) => Effect.gen(function* () {
294
+ const stream = Bytes.makeStream(bytes);
295
+ const head = yield* stream.shiftOne();
296
+ if (head != FLOAT32_HEAD) {
297
+ return yield* new DecodeError(stream, "invalid Float32 header");
298
+ }
299
+ return yield* Either.mapLeft(Float.decodeFloat32(yield* stream.shiftMany(4)), (e) => new DecodeError(stream, `failed to decode float32 (${e.message})`));
300
+ });
301
+ /**
302
+ * @param bytes
303
+ * @returns
304
+ */
305
+ export const decodeFloat64 = (bytes) => Effect.gen(function* () {
306
+ const stream = Bytes.makeStream(bytes);
307
+ const head = yield* stream.shiftOne();
308
+ if (head != FLOAT64_HEAD) {
309
+ return yield* new DecodeError(stream, "invalid Float64 header");
310
+ }
311
+ return yield* Either.mapLeft(Float.decodeFloat64(yield* stream.shiftMany(8)), (e) => new DecodeError(stream, `failed to decode float32 (${e.message})`));
312
+ });
313
+ /**
314
+ * @param f
315
+ * @returns
316
+ */
317
+ export function encodeFloat16(f) {
318
+ return [FLOAT16_HEAD].concat(Float.encodeFloat16(f));
319
+ }
320
+ /**
321
+ * @param f
322
+ * @returns
323
+ */
324
+ export function encodeFloat32(f) {
325
+ return [FLOAT32_HEAD].concat(Float.encodeFloat32(f));
326
+ }
327
+ /**
328
+ * @param f
329
+ * @returns
330
+ */
331
+ export function encodeFloat64(f) {
332
+ return [FLOAT64_HEAD].concat(Float.encodeFloat64(f));
333
+ }
334
+ /**
335
+ * @param bytes
336
+ * @returns
337
+ */
338
+ export const isFloat = (bytes) => Bytes.makeStream(bytes)
339
+ .peekOne()
340
+ .pipe(Effect.map((head) => head == FLOAT16_HEAD || head == FLOAT32_HEAD || head == FLOAT64_HEAD));
341
+ /**
342
+ * @param bytes
343
+ * @returns
344
+ */
345
+ export const isFloat16 = (bytes) => Bytes.makeStream(bytes)
346
+ .peekOne()
347
+ .pipe(Effect.map((head) => head == FLOAT16_HEAD));
348
+ /**
349
+ * @param bytes
350
+ * @returns
351
+ */
352
+ export const isFloat32 = (bytes) => Bytes.makeStream(bytes)
353
+ .peekOne()
354
+ .pipe(Effect.map((head) => head == FLOAT32_HEAD));
355
+ /**
356
+ * @param bytes
357
+ * @returns
358
+ */
359
+ export const isFloat64 = (bytes) => Bytes.makeStream(bytes)
360
+ .peekOne()
361
+ .pipe(Effect.map((head) => head == FLOAT64_HEAD));
362
+ /**
363
+ * @param b0
364
+ * @returns
365
+ */
366
+ function decodeFirstHeadByte(b0) {
367
+ const m = Math.trunc(b0 / 32);
368
+ const n0 = b0 % 32;
369
+ return [m, n0];
370
+ }
371
+ /**
372
+ * @param bytes
373
+ * @returns
374
+ * [majorType, n]
375
+ */
376
+ export const decodeDefHead = (bytes) => Effect.gen(function* () {
377
+ const stream = Bytes.makeStream(bytes);
378
+ if (stream.isAtEnd()) {
379
+ return yield* new DecodeError(stream, "Empty CBOR head");
380
+ }
381
+ const first = yield* stream.shiftOne();
382
+ const [m, n0] = decodeFirstHeadByte(first);
383
+ if (n0 <= 23) {
384
+ return [m, BigInt(n0)];
385
+ }
386
+ else if (n0 == 24) {
387
+ const l = yield* decodeIntInternal(stream, 1);
388
+ return [m, l];
389
+ }
390
+ else if (n0 == 25) {
391
+ if (m == 7) {
392
+ return yield* new DecodeError(stream, "Unexpected float16 (hint: decode float16 by calling decodeFloat16 directly)");
393
+ }
394
+ const n = yield* decodeIntInternal(stream, 2);
395
+ return [m, n];
396
+ }
397
+ else if (n0 == 26) {
398
+ if (m == 7) {
399
+ return yield* new DecodeError(stream, "Unexpected float32 (hint: decode float32 by calling decodeFloat32 directly)");
400
+ }
401
+ return [m, yield* decodeIntInternal(stream, 4)];
402
+ }
403
+ else if (n0 == 27) {
404
+ if (m == 7) {
405
+ return yield* new DecodeError(stream, "Unexpected float64 (hint: decode float64 by calling decodeFloat64 directly)");
406
+ }
407
+ return [m, yield* decodeIntInternal(stream, 8)];
408
+ }
409
+ else if ((m == 2 || m == 3 || m == 4 || m == 5 || m == 7) && n0 == 31) {
410
+ // head value 31 is used an indefinite length marker for 2,3,4,5,7 (never for 0,1,6)
411
+ return yield* new DecodeError(stream, `Unexpected header m=${m} n0=${n0} (expected def instead of indef)`);
412
+ }
413
+ else {
414
+ return yield* new DecodeError(stream, "Bad CBOR header");
415
+ }
416
+ });
417
+ /**
418
+ * @param m major type
419
+ * @param n size parameter
420
+ * @returns uint8 bytes
421
+ * @throws
422
+ * If n is out of range (i.e. very very large)
423
+ */
424
+ export function encodeDefHead(m, n) {
425
+ if (n <= 23n) {
426
+ return [32 * m + Number(n)];
427
+ }
428
+ else if (n >= 24n && n <= 255n) {
429
+ return [32 * m + 24, Number(n)];
430
+ }
431
+ else if (n >= 256n && n <= 256n * 256n - 1n) {
432
+ return [
433
+ 32 * m + 25,
434
+ Number((BigInt(n) / 256n) % 256n),
435
+ Number(BigInt(n) % 256n)
436
+ ];
437
+ }
438
+ else if (n >= 256n * 256n && n <= 256n * 256n * 256n * 256n - 1n) {
439
+ const e4 = BigEndian.encode(n);
440
+ while (e4.length < 4) {
441
+ e4.unshift(0);
442
+ }
443
+ return [32 * m + 26].concat(e4);
444
+ }
445
+ else if (n >= 256n * 256n * 256n * 256n &&
446
+ n <= 256n * 256n * 256n * 256n * 256n * 256n * 256n * 256n - 1n) {
447
+ const e8 = BigEndian.encode(n);
448
+ while (e8.length < 8) {
449
+ e8.unshift(0);
450
+ }
451
+ return [32 * m + 27].concat(e8);
452
+ }
453
+ else {
454
+ throw new Error("n out of range");
455
+ }
456
+ }
457
+ /**
458
+ * @param m
459
+ * @returns
460
+ */
461
+ export function encodeIndefHead(m) {
462
+ return [32 * m + 31];
463
+ }
464
+ /**
465
+ * @param bytes
466
+ * @returns
467
+ */
468
+ export const peekMajorType = (bytes) => Bytes.makeStream(bytes)
469
+ .peekOne()
470
+ .pipe(Effect.map((head) => Math.trunc(head / 32)));
471
+ /**
472
+ * @param bytes
473
+ * @returns
474
+ */
475
+ export const peekMajorAndSimpleMinorType = (bytes) => Bytes.makeStream(bytes).peekOne().pipe(Effect.map(decodeFirstHeadByte));
476
+ /**
477
+ * Decodes a CBOR encoded bigint integer.
478
+ * @param bytes
479
+ * @returns
480
+ */
481
+ export const decodeInt = (bytes) => Effect.gen(function* () {
482
+ const stream = Bytes.makeStream(bytes);
483
+ const [m, n] = yield* decodeDefHead(stream);
484
+ if (m == 0) {
485
+ return n;
486
+ }
487
+ else if (m == 1) {
488
+ return -n - 1n;
489
+ }
490
+ else if (m == 6) {
491
+ if (n == 2n) {
492
+ return yield* decodeIntInternal(stream);
493
+ }
494
+ else if (n == 3n) {
495
+ return -(yield* decodeIntInternal(stream)) - 1n;
496
+ }
497
+ else {
498
+ return yield* new DecodeError(stream, `Unexpected tag m:${m}`);
499
+ }
500
+ }
501
+ else {
502
+ return yield* new DecodeError(stream, `Unexpected tag m:${m}`);
503
+ }
504
+ });
505
+ const decodeIntInternal = (stream, nBytes = undefined) => {
506
+ return (nBytes === undefined ? decodeBytes(stream) : stream.shiftMany(nBytes)).pipe(Effect.map(BigEndian.decode), Effect.flatMap((result) => {
507
+ if (result._tag == "Left") {
508
+ return Effect.fail(new DecodeError(stream, `failed to decode BigEndian int (${result.left.message})`));
509
+ }
510
+ else {
511
+ return Effect.succeed(result.right);
512
+ }
513
+ }));
514
+ };
515
+ /**
516
+ * Encodes a bigint integer using CBOR.
517
+ * @param n
518
+ * @returns
519
+ */
520
+ export function encodeInt(n) {
521
+ if (typeof n == "number") {
522
+ return encodeInt(BigInt(n));
523
+ }
524
+ else if (n >= 0n && n <= (2n << 63n) - 1n) {
525
+ return encodeDefHead(0, n);
526
+ }
527
+ else if (n >= 2n << 63n) {
528
+ return encodeDefHead(6, 2).concat(encodeBytes(BigEndian.encode(n)));
529
+ }
530
+ else if (n <= -1n && n >= -(2n << 63n)) {
531
+ return encodeDefHead(1, -n - 1n);
532
+ }
533
+ else {
534
+ return encodeDefHead(6, 3).concat(encodeBytes(BigEndian.encode(-n - 1n)));
535
+ }
536
+ }
537
+ /**
538
+ * @param bytes
539
+ * @returns
540
+ */
541
+ export const isInt = (bytes) => peekMajorAndSimpleMinorType(bytes).pipe(Effect.map(([m, n0]) => {
542
+ if (m == 0 || m == 1) {
543
+ return true;
544
+ }
545
+ else if (m == 6) {
546
+ return n0 == 2 || n0 == 3;
547
+ }
548
+ else {
549
+ return false;
550
+ }
551
+ }));
552
+ /**
553
+ * Decodes a CBOR encoded list.
554
+ * A decoder function is called with the bytes of every contained item (nothing is returning directly).
555
+ * @template T
556
+ * @param itemDecoder
557
+ * @returns
558
+ */
559
+ export const decodeList = (itemDecoder) => (bytes) => Effect.gen(function* () {
560
+ const stream = Bytes.makeStream(bytes);
561
+ const res = [];
562
+ if (yield* isIndefList(stream)) {
563
+ yield* stream.shiftOne();
564
+ let i = 0;
565
+ while ((yield* stream.peekOne()) != 255) {
566
+ res.push(yield* itemDecoder(stream, i));
567
+ i++;
568
+ }
569
+ const last = yield* stream.shiftOne();
570
+ if (last != 255) {
571
+ return yield* new DecodeError(stream, "Invalid def list head byte");
572
+ }
573
+ }
574
+ else {
575
+ const [m, n] = yield* decodeDefHead(stream);
576
+ if (m != 4) {
577
+ return yield* new DecodeError(stream, "invalid def list head byte");
578
+ }
579
+ for (let i = 0; i < Number(n); i++) {
580
+ res.push(yield* itemDecoder(stream, i));
581
+ }
582
+ }
583
+ return res;
584
+ });
585
+ /**
586
+ * @param bytes
587
+ * @returns
588
+ *
589
+ *
590
+ */
591
+ export const decodeListLazy = (bytes) => Effect.gen(function* () {
592
+ const stream = Bytes.makeStream(bytes);
593
+ let i = 0;
594
+ let done = false;
595
+ let checkDone;
596
+ if (yield* isIndefList(stream)) {
597
+ yield* stream.shiftOne();
598
+ checkDone = () => Effect.gen(function* () {
599
+ if ((yield* stream.peekOne()) == 255) {
600
+ yield* stream.shiftOne();
601
+ done = true;
602
+ }
603
+ });
604
+ }
605
+ else {
606
+ const [m, n] = yield* decodeDefHead(stream);
607
+ if (m != 4) {
608
+ return yield* new DecodeError(stream, "Unexpected header major type");
609
+ }
610
+ checkDone = () => {
611
+ if (i >= n) {
612
+ done = true;
613
+ }
614
+ return Effect.void;
615
+ };
616
+ }
617
+ yield* checkDone();
618
+ const decodeItem = (itemDecoder) => Effect.gen(function* () {
619
+ if (done) {
620
+ return yield* new DecodeError(stream, "end-of-list");
621
+ }
622
+ const res = yield* itemDecoder(stream, i);
623
+ i++;
624
+ yield* checkDone();
625
+ return res;
626
+ });
627
+ return decodeItem;
628
+ });
629
+ /**
630
+ * @param bytes
631
+ * @returns
632
+ */
633
+ export const decodeListLazyOption = (bytes) => Effect.gen(function* () {
634
+ const stream = Bytes.makeStream(bytes);
635
+ let i = 0;
636
+ let done = false;
637
+ let checkDone;
638
+ if (yield* isIndefList(stream)) {
639
+ yield* stream.shiftOne();
640
+ checkDone = () => Effect.gen(function* () {
641
+ if ((yield* stream.peekOne()) == 255) {
642
+ yield* stream.shiftOne();
643
+ done = true;
644
+ }
645
+ });
646
+ }
647
+ else {
648
+ const [m, n] = yield* decodeDefHead(stream);
649
+ if (m != 4) {
650
+ return yield* new DecodeError(stream, "Unexpected major type for list");
651
+ }
652
+ checkDone = () => {
653
+ if (i >= n) {
654
+ done = true;
655
+ }
656
+ return Effect.void;
657
+ };
658
+ }
659
+ yield* checkDone();
660
+ const decodeItem = (itemDecoder) => Effect.gen(function* () {
661
+ if (done) {
662
+ return undefined;
663
+ }
664
+ const res = yield* itemDecoder(stream, i);
665
+ i++;
666
+ yield* checkDone();
667
+ return res;
668
+ });
669
+ return decodeItem;
670
+ });
671
+ /**
672
+ * This follows the serialization format that the Haskell input-output-hk/plutus UPLC evaluator (i.e. empty lists use `encodeDefList`, non-empty lists use `encodeIndefList`).
673
+ * See [well-typed/cborg/serialise/src/Codec/Serialise/Class.hs](https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181).
674
+ * @param items already encoded
675
+ * @returns
676
+ */
677
+ export function encodeList(items) {
678
+ return items.length > 0 ? encodeIndefList(items) : encodeDefList(items);
679
+ }
680
+ /**
681
+ * @returns
682
+ */
683
+ function encodeIndefListStart() {
684
+ return encodeIndefHead(4);
685
+ }
686
+ /**
687
+ * @param list
688
+ * @returns
689
+ */
690
+ function encodeListInternal(list) {
691
+ /**
692
+ * @type {number[]}
693
+ */
694
+ let res = [];
695
+ for (const item of list) {
696
+ res = res.concat(item);
697
+ }
698
+ return res;
699
+ }
700
+ const INDEF_LIST_END = [255];
701
+ /**
702
+ * Encodes a list of CBOR encodeable items using CBOR indefinite length encoding.
703
+ * @param list Each item is either already serialized.
704
+ * @returns
705
+ */
706
+ export function encodeIndefList(list) {
707
+ return encodeIndefListStart()
708
+ .concat(encodeListInternal(list))
709
+ .concat(INDEF_LIST_END);
710
+ }
711
+ /**
712
+ * @param n
713
+ * @returns
714
+ */
715
+ function encodeDefListStart(n) {
716
+ return encodeDefHead(4, n);
717
+ }
718
+ /**
719
+ * Encodes a list of CBOR encodeable items using CBOR definite length encoding
720
+ * (i.e. header bytes of the element represent the length of the list).
721
+ * @param items Each item is already serialized
722
+ * @returns
723
+ */
724
+ export function encodeDefList(items) {
725
+ return encodeDefListStart(BigInt(items.length)).concat(encodeListInternal(items));
726
+ }
727
+ /**
728
+ * @param bytes
729
+ * @returns
730
+ */
731
+ export const isList = (bytes) => peekMajorType(bytes).pipe(Effect.map((m) => m == 4));
732
+ /**
733
+ * @param bytes
734
+ * @returns
735
+ */
736
+ export const isDefList = (bytes) => Effect.gen(function* () {
737
+ const stream = Bytes.makeStream(bytes);
738
+ return ((yield* peekMajorType(stream)) == 4 &&
739
+ (yield* stream.peekOne()) != 4 * 32 + 31);
740
+ });
741
+ /**
742
+ * @param bytes
743
+ * @returns
744
+ */
745
+ export const isIndefList = (bytes) => Bytes.makeStream(bytes)
746
+ .peekOne()
747
+ .pipe(Effect.map((head) => head == 4 * 32 + 31));
748
+ /**
749
+ * Decodes a CBOR encoded map.
750
+ * Calls a decoder function for each key-value pair (nothing is returned directly).
751
+ *
752
+ * The decoder function is responsible for separating the key from the value,
753
+ * which are simply stored as consecutive CBOR elements.
754
+ * @param keyDecoder
755
+ * @param valueDecoder
756
+ * @returns
757
+ */
758
+ export const decodeMap = (keyDecoder, valueDecoder) => (bytes) => Effect.gen(function* () {
759
+ const stream = Bytes.makeStream(bytes);
760
+ if (yield* isIndefMap(stream)) {
761
+ yield* stream.shiftOne();
762
+ return yield* decodeIndefMap(stream, keyDecoder, valueDecoder);
763
+ }
764
+ else {
765
+ const [m, n] = yield* decodeDefHead(stream);
766
+ if (m != 5) {
767
+ return yield* new DecodeError(stream, "invalid def map");
768
+ }
769
+ return yield* decodeDefMap(stream, Number(n), keyDecoder, valueDecoder);
770
+ }
771
+ });
772
+ /**
773
+ * Internal use only, header already decoded
774
+ * @param stream
775
+ * @param n
776
+ * @param keyDecoder
777
+ * @param valueDecoder
778
+ * @returns
779
+ */
780
+ const decodeDefMap = (stream, n, keyDecoder, valueDecoder) => Effect.gen(function* () {
781
+ const res = [];
782
+ for (let i = 0; i < n; i++) {
783
+ res.push([yield* keyDecoder(stream), yield* valueDecoder(stream)]);
784
+ }
785
+ return res;
786
+ });
787
+ /**
788
+ * Used internally, head already decoded
789
+ * @template TKey
790
+ * @template TValue
791
+ * @param stream
792
+ * @param keyDecoder
793
+ * @param valueDecoder
794
+ * @returns
795
+ */
796
+ const decodeIndefMap = (stream, keyDecoder, valueDecoder) => Effect.gen(function* () {
797
+ const res = [];
798
+ while ((yield* stream.peekOne()) != 255) {
799
+ res.push([yield* keyDecoder(stream), yield* valueDecoder(stream)]);
800
+ }
801
+ yield* stream.shiftOne();
802
+ return res;
803
+ });
804
+ /**
805
+ * Unlike lists, the default serialization format for maps seems to always be the defined format
806
+ * @param pairs already encoded
807
+ * @returns
808
+ */
809
+ export function encodeMap(pairs) {
810
+ return encodeDefMap(pairs);
811
+ }
812
+ /**
813
+ * Encodes a list of key-value pairs.
814
+ * @param pairs
815
+ * Each key and each value is an already encoded list of CBOR bytes.
816
+ * @returns
817
+ */
818
+ export function encodeDefMap(pairs) {
819
+ return encodeDefHead(5, BigInt(pairs.length)).concat(encodeMapInternal(pairs));
820
+ }
821
+ /**
822
+ * Encodes a list of key-value pairs using the length undefined format.
823
+ * @param pairs
824
+ * Each key and each value is an already encoded list of CBOR bytes.
825
+ * @returns
826
+ */
827
+ export function encodeIndefMap(pairs) {
828
+ return encodeIndefHead(5).concat(encodeMapInternal(pairs)).concat([255]);
829
+ }
830
+ /**
831
+ * @param pairs already encoded
832
+ * @returns
833
+ */
834
+ function encodeMapInternal(pairs) {
835
+ let res = [];
836
+ for (const pair of pairs) {
837
+ const key = pair[0];
838
+ const value = pair[1];
839
+ res = res.concat(key);
840
+ res = res.concat(value);
841
+ }
842
+ return res;
843
+ }
844
+ /**
845
+ * @param bytes
846
+ * @returns
847
+ */
848
+ export const isMap = (bytes) => peekMajorType(bytes).pipe(Effect.map((m) => m == 5));
849
+ /**
850
+ * @param bytes
851
+ * @returns
852
+ */
853
+ const isIndefMap = (bytes) => Bytes.makeStream(bytes)
854
+ .peekOne()
855
+ .pipe(Effect.map((head) => head == 5 * 32 + 31));
856
+ const NULL_BYTE = 246; // m = 7, n = 22
857
+ /**
858
+ * Checks if next element in `bytes` is a `null`.
859
+ * Throws an error if it isn't.
860
+ * @param bytes
861
+ * @returns
862
+ */
863
+ export const decodeNull = (bytes) => Effect.gen(function* () {
864
+ const stream = Bytes.makeStream(bytes);
865
+ const b = yield* stream.shiftOne();
866
+ if (b != NULL_BYTE) {
867
+ return yield* new DecodeError(stream, "not null");
868
+ }
869
+ return null;
870
+ });
871
+ /**
872
+ * Encode `null` into its CBOR representation.
873
+ * @param _null ignored
874
+ * @returns
875
+ */
876
+ export function encodeNull(_null = null) {
877
+ return [NULL_BYTE];
878
+ }
879
+ /**
880
+ * @param bytes
881
+ * @returns
882
+ */
883
+ export const isNull = (bytes) => Bytes.makeStream(bytes)
884
+ .peekOne()
885
+ .pipe(Effect.map((head) => head == NULL_BYTE));
886
+ /**
887
+ * Decodes a CBOR encoded object with integer keys.
888
+ * For each field a decoder is called which takes the field index and the field bytes as arguments.
889
+ * @template Decoders
890
+ * @param fieldDecoders
891
+ * @returns
892
+ */
893
+ export const decodeObjectIKey = (fieldDecoders) => (bytes) => {
894
+ const stream = Bytes.makeStream(bytes);
895
+ const res = {};
896
+ return decodeMap(() => Effect.succeed(null), (pairStream) => Effect.gen(function* () {
897
+ const key = Number(yield* decodeInt(pairStream));
898
+ const decoder = fieldDecoders[key];
899
+ if (decoder === undefined) {
900
+ return yield* new DecodeError(pairStream, `unhandled object field ${key}`);
901
+ }
902
+ /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */
903
+ res[key] = yield* decoder(pairStream);
904
+ return Effect.void;
905
+ }))(stream).pipe(Effect.map(() => {
906
+ return res;
907
+ }));
908
+ };
909
+ /**
910
+ * Decodes a CBOR encoded object with string keys.
911
+ * For each field a decoder is called which takes the field index and the field bytes as arguments.
912
+ * @template Decoders
913
+ * @param fieldDecoders
914
+ * @returns
915
+ */
916
+ export const decodeObjectSKey = (fieldDecoders) => (bytes) => {
917
+ const stream = Bytes.makeStream(bytes);
918
+ const res = {};
919
+ return decodeMap(() => Effect.succeed(null), (pairStream) => Effect.gen(function* () {
920
+ const key = yield* decodeString(pairStream);
921
+ const decoder = fieldDecoders[key];
922
+ if (decoder === undefined) {
923
+ return yield* new DecodeError(pairStream, `unhandled object field ${key}`);
924
+ }
925
+ /* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment */
926
+ res[key] = yield* decoder(pairStream);
927
+ return Effect.void;
928
+ }))(stream).pipe(Effect.map(() => {
929
+ return res;
930
+ }));
931
+ };
932
+ /**
933
+ * Encodes an object with optional fields using integer keys.
934
+ * @param object
935
+ * A `Map` with integer keys representing the field indices.
936
+ * @returns
937
+ */
938
+ export function encodeObjectIKey(object) {
939
+ const entries = object instanceof Map
940
+ ? Array.from(object.entries()).map((pair) => [
941
+ encodeInt(pair[0]),
942
+ pair[1]
943
+ ])
944
+ : Object.entries(object).map((pair) => [
945
+ encodeInt(parseInt(pair[0])),
946
+ pair[1]
947
+ ]);
948
+ return encodeDefMap(entries);
949
+ }
950
+ /**
951
+ * Encodes an object with optional fields using string keys.
952
+ * @param object
953
+ * A `Map` with string keys representing the field indices.
954
+ * @returns
955
+ */
956
+ export function encodeObjectSKey(object) {
957
+ const entries = object instanceof Map
958
+ ? Array.from(object.entries()).map((pair) => [
959
+ encodeString(pair[0]),
960
+ pair[1]
961
+ ])
962
+ : Object.entries(object).map((pair) => [encodeString(pair[0]), pair[1]]);
963
+ return encodeDefMap(entries);
964
+ }
965
+ /**
966
+ * @param bytes
967
+ * @returns
968
+ */
969
+ export const isObject = (bytes) => isMap(bytes);
970
+ const SET_TAG = 258n;
971
+ /**
972
+ * Like a list, but with an optional 258 tag
973
+ * See: https://github.com/Emurgo/cardano-serialization-lib/releases/tag/13.0.0
974
+ * @template T
975
+ * @param itemDecoder
976
+ * @returns
977
+ */
978
+ export const decodeSet = (itemDecoder) => (bytes) => Effect.gen(function* () {
979
+ const stream = Bytes.makeStream(bytes);
980
+ if (yield* isTag(stream)) {
981
+ const tag = yield* decodeTag(stream);
982
+ if (tag != SET_TAG) {
983
+ return yield* new DecodeError(stream, `expected tag ${SET_TAG} for set, got tag ${tag}`);
984
+ }
985
+ }
986
+ return yield* decodeList(itemDecoder)(stream);
987
+ });
988
+ /**
989
+ * A tagged def list (tag 258n)
990
+ * @param items
991
+ * @returns
992
+ */
993
+ export function encodeSet(items) {
994
+ return encodeTag(SET_TAG).concat(encodeDefList(items));
995
+ }
996
+ /**
997
+ * @param bytes
998
+ * @returns
999
+ */
1000
+ export const isSet = (bytes) => peekTag(bytes).pipe(Effect.map((t) => t == SET_TAG));
1001
+ /**
1002
+ * @param bytes
1003
+ * @returns
1004
+ */
1005
+ export const decodeString = (bytes) => Effect.gen(function* () {
1006
+ const stream = Bytes.makeStream(bytes);
1007
+ if (yield* isDefList(stream)) {
1008
+ let result = "";
1009
+ yield* decodeList((itemBytes) => decodeStringInternal(itemBytes).pipe(Effect.tap((s) => {
1010
+ result += s;
1011
+ })))(stream);
1012
+ return result;
1013
+ }
1014
+ else {
1015
+ return yield* decodeStringInternal(stream);
1016
+ }
1017
+ });
1018
+ /**
1019
+ * @param bytes
1020
+ * @returns
1021
+ */
1022
+ const decodeStringInternal = (bytes) => Effect.gen(function* () {
1023
+ const stream = Bytes.makeStream(bytes);
1024
+ const [m, n] = yield* decodeDefHead(stream);
1025
+ if (m !== 3) {
1026
+ return yield* new DecodeError(stream, "unexpected");
1027
+ }
1028
+ return yield* Utf8.decode(yield* stream.shiftMany(Number(n))).pipe(Effect.mapError((e) => new DecodeError(stream, `invalid utf8 (${e.message})`)));
1029
+ });
1030
+ /**
1031
+ * Encodes a Utf8 string into Cbor bytes.
1032
+ * Strings can be split into lists with chunks of up to 64 bytes
1033
+ * to play nice with Cardano tx metadata constraints.
1034
+ * @param str
1035
+ * @param split
1036
+ * @returns
1037
+ */
1038
+ export function encodeString(str, split = false) {
1039
+ const bytes = Bytes.toArray(Utf8.encode(str));
1040
+ if (split && bytes.length > 64) {
1041
+ const chunks = [];
1042
+ let i = 0;
1043
+ while (i < bytes.length) {
1044
+ // We encode the largest chunk up to 64 bytes
1045
+ // that is valid UTF-8
1046
+ let maxChunkLength = 64;
1047
+ let chunk;
1048
+ while (true) {
1049
+ chunk = bytes.slice(i, i + maxChunkLength);
1050
+ if (Utf8.isValid(chunk)) {
1051
+ break;
1052
+ }
1053
+ maxChunkLength--;
1054
+ }
1055
+ chunks.push(encodeDefHead(3, BigInt(chunk.length)).concat(chunk));
1056
+ i += chunk.length;
1057
+ }
1058
+ return encodeDefList(chunks);
1059
+ }
1060
+ else {
1061
+ return encodeDefHead(3, BigInt(bytes.length)).concat(bytes);
1062
+ }
1063
+ }
1064
+ /**
1065
+ * @param bytes
1066
+ * @returns
1067
+ */
1068
+ export const isString = (bytes) => peekMajorType(bytes).pipe(Effect.map((m) => m == 3));
1069
+ /**
1070
+ * @param bytes
1071
+ * @returns
1072
+ */
1073
+ export const decodeTag = (bytes) => Effect.gen(function* () {
1074
+ const stream = Bytes.makeStream(bytes);
1075
+ const [m, n] = yield* decodeDefHead(stream);
1076
+ if (m != 6) {
1077
+ return yield* new DecodeError(stream, "unexpected major type for tag");
1078
+ }
1079
+ return n;
1080
+ });
1081
+ /**
1082
+ * Unrelated to constructor
1083
+ * @param tag
1084
+ * @returns
1085
+ */
1086
+ export function encodeTag(tag) {
1087
+ if (typeof tag == "number") {
1088
+ return encodeTag(BigInt(tag));
1089
+ }
1090
+ else if (tag < 0) {
1091
+ throw new Error("can't encode negative tag");
1092
+ }
1093
+ return encodeDefHead(6, tag);
1094
+ }
1095
+ /**
1096
+ * @param bytes
1097
+ * @returns
1098
+ */
1099
+ export const isTag = (bytes) => peekMajorType(bytes).pipe(Effect.map((m) => m == 6));
1100
+ /**
1101
+ * @param bytes
1102
+ * @returns
1103
+ */
1104
+ export const peekTag = (bytes) => decodeTag(Bytes.makeStream(bytes).copy()).pipe(Effect.catchTag("Cbor.DecodeError", () => Effect.succeed(undefined)));
1105
+ /**
1106
+ * @param bytes
1107
+ * @returns
1108
+ */
1109
+ export const decodeTagged = (bytes) => Effect.gen(function* () {
1110
+ const stream = Bytes.makeStream(bytes);
1111
+ if (yield* isList(stream)) {
1112
+ const decodeItem = yield* decodeListLazy(stream);
1113
+ const tag = Number(yield* decodeItem(decodeInt));
1114
+ return [tag, decodeItem];
1115
+ }
1116
+ else {
1117
+ return yield* decodeConstrLazy(stream);
1118
+ }
1119
+ });
1120
+ /**
1121
+ * @template Decoders
1122
+ * @template OptionalDecoders
1123
+ * @param itemDecoders
1124
+ * @param optionalDecoders
1125
+ * Defaults to empty tuple
1126
+ * @returns
1127
+ */
1128
+ export const decodeTuple = (itemDecoders, optionalDecoders = []) => (bytes) => Effect.gen(function* () {
1129
+ const stream = Bytes.makeStream(bytes);
1130
+ /**
1131
+ * decodeList is the right decoder, but has the wrong type interface
1132
+ * Cast the result to `any` to avoid type errors
1133
+ */
1134
+ const res = yield* decodeList((itemStream, i) => Effect.gen(function* () {
1135
+ let decoder = itemDecoders[i];
1136
+ if (decoder === undefined) {
1137
+ decoder = optionalDecoders[i - itemDecoders.length];
1138
+ if (decoder === undefined) {
1139
+ return yield* new DecodeError(itemStream, `expected at most ${itemDecoders.length + optionalDecoders.length} items, got more than ${i}`);
1140
+ }
1141
+ }
1142
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
1143
+ return yield* decoder(itemStream);
1144
+ }))(stream);
1145
+ if (res.length < itemDecoders.length) {
1146
+ return yield* new DecodeError(stream, `expected at least ${itemDecoders.length} items, only got ${res.length}`);
1147
+ }
1148
+ return res;
1149
+ });
1150
+ /**
1151
+ * @param bytes
1152
+ * @returns
1153
+ */
1154
+ export function decodeTupleLazy(bytes) {
1155
+ return decodeListLazy(bytes);
1156
+ }
1157
+ /**
1158
+ * @param tuple
1159
+ * @returns
1160
+ */
1161
+ export function encodeTuple(tuple) {
1162
+ return encodeDefList(tuple);
1163
+ }
1164
+ /**
1165
+ * @param bytes
1166
+ * @returns
1167
+ */
1168
+ export function isTuple(bytes) {
1169
+ return isList(bytes);
1170
+ }
1171
+ //# sourceMappingURL=Cbor.js.map