@bcts/uniform-resources 1.0.0-alpha.8 → 1.0.0-beta.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.
package/dist/index.d.cts CHANGED
@@ -1,7 +1,13 @@
1
- import { Cbor } from "@bcts/dcbor";
1
+ import { Cbor, CborTaggedDecodable, CborTaggedEncodable } from "@bcts/dcbor";
2
2
 
3
+ //#region \0rolldown/runtime.js
4
+ //#endregion
3
5
  //#region src/error.d.ts
4
6
  /**
7
+ * Copyright © 2023-2026 Blockchain Commons, LLC
8
+ * Copyright © 2025-2026 Parity Technologies
9
+ *
10
+ *
5
11
  * Error type for UR encoding/decoding operations.
6
12
  */
7
13
  declare class URError extends Error {
@@ -9,18 +15,24 @@ declare class URError extends Error {
9
15
  }
10
16
  /**
11
17
  * Error type for invalid UR schemes.
18
+ *
19
+ * Message matches Rust bc-ur-rust/src/error.rs: `invalid UR scheme`.
12
20
  */
13
21
  declare class InvalidSchemeError extends URError {
14
22
  constructor();
15
23
  }
16
24
  /**
17
25
  * Error type for unspecified UR types.
26
+ *
27
+ * Message matches Rust bc-ur-rust/src/error.rs: `no UR type specified`.
18
28
  */
19
29
  declare class TypeUnspecifiedError extends URError {
20
30
  constructor();
21
31
  }
22
32
  /**
23
33
  * Error type for invalid UR types.
34
+ *
35
+ * Message matches Rust bc-ur-rust/src/error.rs: `invalid UR type`.
24
36
  */
25
37
  declare class InvalidTypeError extends URError {
26
38
  constructor();
@@ -33,22 +45,36 @@ declare class NotSinglePartError extends URError {
33
45
  }
34
46
  /**
35
47
  * Error type for unexpected UR types.
48
+ *
49
+ * Message matches Rust bc-ur-rust/src/error.rs:
50
+ * `expected UR type {expected}, but found {found}`.
36
51
  */
37
52
  declare class UnexpectedTypeError extends URError {
38
53
  constructor(expected: string, found: string);
39
54
  }
40
55
  /**
41
56
  * Error type for Bytewords encoding/decoding errors.
57
+ *
58
+ * Message matches Rust bc-ur-rust/src/error.rs: `Bytewords error ({0})`.
42
59
  */
43
60
  declare class BytewordsError extends URError {
44
61
  constructor(message: string);
45
62
  }
46
63
  /**
47
64
  * Error type for CBOR encoding/decoding errors.
65
+ *
66
+ * Message matches Rust bc-ur-rust/src/error.rs: `CBOR error ({0})`.
48
67
  */
49
68
  declare class CBORError extends URError {
50
69
  constructor(message: string);
51
70
  }
71
+ /**
72
+ * Error type for UR decoder errors.
73
+ * Matches Rust's Error::UR(String) variant.
74
+ */
75
+ declare class URDecodeError extends URError {
76
+ constructor(message: string);
77
+ }
52
78
  type Result<T> = T | Error;
53
79
  /**
54
80
  * Helper function to check if a result is an error.
@@ -108,12 +134,36 @@ declare class URType {
108
134
  */
109
135
  static from(value: string): URType;
110
136
  /**
111
- * Safely creates a URType, returning an error if invalid.
137
+ * Safely creates a URType, returning a typed `Result`-shaped
138
+ * discriminated union instead of throwing.
139
+ *
140
+ * Mirrors Rust `impl TryFrom<&str> for URType` /
141
+ * `impl TryFrom<String> for URType` (`bc-ur-rust/src/ur_type.rs`),
142
+ * which return `Result<URType, Error>`. The TS shape is the
143
+ * idiomatic discriminated form so callers can branch on `ok`
144
+ * without `instanceof`:
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const r = URType.tryFrom("test");
149
+ * if (r.ok) {
150
+ * console.log(r.value.string()); // "test"
151
+ * } else {
152
+ * console.error(r.error.message);
153
+ * }
154
+ * ```
112
155
  *
113
156
  * @param value - The UR type string
114
- * @returns Either a URType or an error
115
- */
116
- static tryFrom(value: string): URType | InvalidTypeError;
157
+ * @returns A typed Result: `{ ok: true; value: URType }` on success,
158
+ * `{ ok: false; error: InvalidTypeError }` on failure.
159
+ */
160
+ static tryFrom(value: string): {
161
+ ok: true;
162
+ value: URType;
163
+ } | {
164
+ ok: false;
165
+ error: InvalidTypeError;
166
+ };
117
167
  }
118
168
  //#endregion
119
169
  //#region src/ur.d.ts
@@ -159,11 +209,26 @@ declare class UR {
159
209
  /**
160
210
  * Creates a new UR from a UR string.
161
211
  *
212
+ * Mirrors Rust's `UR::from_ur_string` (`bc-ur-rust/src/ur.rs:25-38`):
213
+ * 1. lowercase the entire string.
214
+ * 2. strip the `"ur:"` prefix → {@link InvalidSchemeError} if absent.
215
+ * 3. split on the first `/` → {@link TypeUnspecifiedError} if absent.
216
+ * 4. validate the type via {@link URType} → {@link InvalidTypeError}.
217
+ * 5. delegate the data section to the upstream-style decoder, which
218
+ * classifies the UR as single- or multi-part. Multi-part input is
219
+ * rejected with {@link NotSinglePartError}.
220
+ * 6. decode the bytewords payload (CRC32 + minimal mapping) →
221
+ * {@link BytewordsError} on failure.
222
+ * 7. parse the resulting bytes as CBOR → {@link CBORError} on failure.
223
+ *
162
224
  * @param urString - A UR string like "ur:test/..."
163
225
  * @throws {InvalidSchemeError} If the string doesn't start with "ur:"
164
- * @throws {TypeUnspecifiedError} If no type is specified
226
+ * @throws {TypeUnspecifiedError} If no `/` separator is present
227
+ * @throws {InvalidTypeError} If the type contains invalid characters
165
228
  * @throws {NotSinglePartError} If the UR is multi-part
166
- * @throws {URError} If decoding fails
229
+ * @throws {URDecodeError} For upstream-decoder errors (invalid indices, etc.)
230
+ * @throws {BytewordsError} If bytewords decoding fails
231
+ * @throws {CBORError} If CBOR parsing fails
167
232
  *
168
233
  * @example
169
234
  * ```typescript
@@ -200,6 +265,12 @@ declare class UR {
200
265
  qrString(): string;
201
266
  /**
202
267
  * Returns the QR data as bytes (uppercase UR string as UTF-8).
268
+ *
269
+ * Mirrors Rust's `UR::qr_data` (`ur.rs:52`) which does
270
+ * `self.qr_string().as_bytes().to_vec()` — the string's UTF-8 byte
271
+ * representation. We use `TextEncoder` rather than per-codepoint
272
+ * truncation so the behaviour stays correct if the QR string ever
273
+ * contains non-ASCII characters.
203
274
  */
204
275
  qrData(): Uint8Array;
205
276
  /**
@@ -215,6 +286,12 @@ declare class UR {
215
286
  toString(): string;
216
287
  /**
217
288
  * Checks equality with another UR.
289
+ *
290
+ * Mirrors Rust's derived `PartialEq for UR` which compares the inner
291
+ * `ur_type` and the inner `cbor` field directly. We compare CBOR
292
+ * bytewise — `Uint8Array` equality, not `Array#toString` (which would
293
+ * coerce to a comma-joined string and could collide on pathological
294
+ * inputs).
218
295
  */
219
296
  equals(other: UR): boolean;
220
297
  }
@@ -226,17 +303,27 @@ declare class UR {
226
303
  * Types implementing this interface should be able to convert themselves
227
304
  * to CBOR data and associate that with a UR type identifier.
228
305
  *
306
+ * Mirrors Rust's `UREncodable` trait (`bc-ur-rust/src/ur_encodable.rs`),
307
+ * which has a blanket impl `impl<T> UREncodable for T where T:
308
+ * CBORTaggedEncodable`. TypeScript has no equivalent of blanket impls, so
309
+ * implementers either write `ur()` / `urString()` directly *or* — for a
310
+ * type that already implements `CborTaggedEncodable` — call the helper
311
+ * functions {@link urFromEncodable} / {@link urStringFromEncodable} below
312
+ * to get the same auto-derivation that Rust provides for free.
313
+ *
229
314
  * @example
230
315
  * ```typescript
231
- * class MyType implements UREncodable {
232
- * toCBOR(): CBOR {
233
- * // Convert to CBOR
316
+ * class MyType implements UREncodable, CborTaggedEncodable {
317
+ * cborTags(): Tag[] {
318
+ * return [createTag(40000, "mytype")];
234
319
  * }
235
320
  *
236
- * ur(): UR {
237
- * const cbor = this.toCBOR();
238
- * return UR.new('mytype', cbor);
239
- * }
321
+ * untaggedCbor(): Cbor { ... }
322
+ * taggedCbor(): Cbor { return createTaggedCbor(this); }
323
+ *
324
+ * // Auto-derived from the first cbor tag's name, just like Rust.
325
+ * ur(): UR { return urFromEncodable(this); }
326
+ * urString(): string { return urStringFromEncodable(this); }
240
327
  * }
241
328
  * ```
242
329
  */
@@ -250,6 +337,26 @@ interface UREncodable {
250
337
  */
251
338
  urString(): string;
252
339
  }
340
+ /**
341
+ * Concrete equivalent of Rust's default `UREncodable::ur` impl
342
+ * (`bc-ur-rust/src/ur_encodable.rs:8-18`):
343
+ *
344
+ * - Reads the first tag returned by `encodable.cborTags()`.
345
+ * - Uses that tag's `name` as the UR type, throwing if no name is set —
346
+ * matching Rust's `panic!("CBOR tag {} must have a name. Did you call
347
+ * `register_tags()`?", tag.value())`.
348
+ * - Wraps the encodable's `untaggedCbor()` in a fresh {@link UR} bound to
349
+ * that type.
350
+ *
351
+ * Use from a class implementing both `UREncodable` and
352
+ * `CborTaggedEncodable` to skip writing the boilerplate yourself.
353
+ */
354
+ declare function urFromEncodable(encodable: CborTaggedEncodable): UR;
355
+ /**
356
+ * Concrete equivalent of Rust's default `UREncodable::ur_string` impl
357
+ * (`bc-ur-rust/src/ur_encodable.rs:21`): `self.ur().string()`.
358
+ */
359
+ declare function urStringFromEncodable(encodable: CborTaggedEncodable): string;
253
360
  /**
254
361
  * Helper function to check if an object implements UREncodable.
255
362
  */
@@ -262,17 +369,26 @@ declare function isUREncodable(obj: unknown): obj is UREncodable;
262
369
  * Types implementing this interface should be able to create themselves
263
370
  * from a UR containing their data.
264
371
  *
372
+ * Mirrors Rust's `URDecodable` trait (`bc-ur-rust/src/ur_decodable.rs`),
373
+ * which has a blanket impl `impl<T> URDecodable for T where T:
374
+ * CBORTaggedDecodable`. TypeScript has no equivalent of blanket impls, so
375
+ * implementers either write `fromUR()` directly *or* — for a type that
376
+ * already implements `CborTaggedDecodable` — call the helper functions
377
+ * {@link decodableFromUR} / {@link decodableFromURString} below to get the
378
+ * same auto-derivation that Rust provides for free.
379
+ *
265
380
  * @example
266
381
  * ```typescript
267
- * class MyType implements URDecodable {
268
- * fromUR(ur: UR): MyType {
269
- * const cbor = ur.cbor();
270
- * // Decode from CBOR and return MyType instance
382
+ * class MyType implements URDecodable, CborTaggedDecodable<MyType> {
383
+ * cborTags(): Tag[] {
384
+ * return [createTag(40000, "mytype")];
271
385
  * }
386
+ * fromUntaggedCbor(cbor: Cbor): MyType { ... }
387
+ * fromTaggedCbor(cbor: Cbor): MyType { ... }
272
388
  *
273
- * fromURString(urString: string): MyType {
274
- * return this.fromUR(UR.fromURString(urString));
275
- * }
389
+ * // Auto-derived from the first cbor tag's name, matching Rust.
390
+ * fromUR(ur: UR): MyType { return decodableFromUR(this, ur); }
391
+ * fromURString(s: string): MyType { return decodableFromURString(this, s); }
276
392
  * }
277
393
  * ```
278
394
  */
@@ -297,6 +413,26 @@ interface URDecodable {
297
413
  */
298
414
  fromURString?(urString: string): unknown;
299
415
  }
416
+ /**
417
+ * Concrete equivalent of Rust's default `URDecodable::from_ur` impl
418
+ * (`bc-ur-rust/src/ur_decodable.rs:7-15`):
419
+ *
420
+ * 1. Read the first tag returned by `decodable.cborTags()`.
421
+ * 2. Verify the UR's type matches that tag's name via `UR#checkType`
422
+ * (this is what Rust's `ur.check_type(...)` does — surface
423
+ * `UnexpectedTypeError` on mismatch).
424
+ * 3. Delegate to `decodable.fromUntaggedCbor(ur.cbor())`.
425
+ *
426
+ * Use from a class implementing both `URDecodable` and
427
+ * `CborTaggedDecodable<T>` to skip the type-check / delegate boilerplate.
428
+ */
429
+ declare function decodableFromUR<T>(decodable: CborTaggedDecodable<T>, ur: UR): T;
430
+ /**
431
+ * Concrete equivalent of Rust's default `URDecodable::from_ur_string` impl
432
+ * (`bc-ur-rust/src/ur_decodable.rs:17-22`):
433
+ * `Self::from_ur(UR::from_ur_string(s)?)`.
434
+ */
435
+ declare function decodableFromURString<T>(decodable: CborTaggedDecodable<T>, urString: string): T;
300
436
  /**
301
437
  * Helper function to check if an object implements URDecodable.
302
438
  */
@@ -382,12 +518,6 @@ declare class MultipartEncoder {
382
518
  * ```
383
519
  */
384
520
  constructor(ur: UR, maxFragmentLen: number);
385
- /**
386
- * Returns whether the message fits in a single part.
387
- *
388
- * For single-part messages, consider using UR.string() directly.
389
- */
390
- isSinglePart(): boolean;
391
521
  /**
392
522
  * Gets the next part of the encoding.
393
523
  *
@@ -405,10 +535,17 @@ declare class MultipartEncoder {
405
535
  nextPart(): string;
406
536
  /**
407
537
  * Encodes a fountain part as a UR string.
538
+ *
539
+ * Always emits the multipart `ur:<type>/<seqNum>-<seqLen>/<bytewords>`
540
+ * format — including for single-part messages (`1-1/...`). This mirrors
541
+ * Rust's `bc_ur::MultipartEncoder::next_part`, which never short-circuits
542
+ * to plain UR. Callers that want plain UR for tiny payloads should use
543
+ * `UR.string()` directly instead of constructing a `MultipartEncoder`.
408
544
  */
409
545
  private _encodePart;
410
546
  /**
411
- * Encodes part metadata and data into bytes for bytewords encoding.
547
+ * Encodes part metadata and data as CBOR for bytewords encoding.
548
+ * Format: CBOR array [seqNum, seqLen, messageLen, checksum, data]
412
549
  */
413
550
  private _encodePartData;
414
551
  /**
@@ -422,17 +559,6 @@ declare class MultipartEncoder {
422
559
  * for additional redundancy.
423
560
  */
424
561
  partsCount(): number;
425
- /**
426
- * Checks if all pure parts have been emitted.
427
- *
428
- * Even after this returns true, you can continue calling nextPart()
429
- * to generate additional rateless parts for redundancy.
430
- */
431
- isComplete(): boolean;
432
- /**
433
- * Resets the encoder to start from the beginning.
434
- */
435
- reset(): void;
436
562
  }
437
563
  //#endregion
438
564
  //#region src/multipart-decoder.d.ts
@@ -473,6 +599,8 @@ declare class MultipartDecoder {
473
599
  private _parsePart;
474
600
  /**
475
601
  * Decodes a multipart UR's fountain part data.
602
+ *
603
+ * The multipart body is a CBOR array: [seqNum, seqLen, messageLen, checksum, data]
476
604
  */
477
605
  private _decodeFountainPart;
478
606
  /**
@@ -485,226 +613,29 @@ declare class MultipartDecoder {
485
613
  * @returns The decoded UR, or null if not yet complete
486
614
  */
487
615
  message(): UR | null;
488
- /**
489
- * Returns the decoding progress as a fraction (0 to 1).
490
- */
491
- progress(): number;
492
- /**
493
- * Resets the decoder to receive a new message.
494
- */
495
- reset(): void;
496
616
  }
497
617
  //#endregion
498
- //#region src/fountain.d.ts
499
- /**
500
- * Fountain code implementation for multipart URs.
501
- *
502
- * This implements a hybrid fixed-rate and rateless fountain code system
503
- * as specified in BCR-2020-005 and BCR-2024-001.
504
- *
505
- * Key concepts:
506
- * - Parts 1-seqLen are "pure" fragments (fixed-rate)
507
- * - Parts > seqLen are "mixed" fragments using XOR (rateless)
508
- * - Xoshiro256** PRNG ensures encoder/decoder agree on mixing
509
- */
510
- /**
511
- * Represents a fountain code part with metadata.
512
- */
513
- interface FountainPart {
514
- /** Sequence number (1-based) */
515
- seqNum: number;
516
- /** Total number of pure fragments */
517
- seqLen: number;
518
- /** Length of original message */
519
- messageLen: number;
520
- /** CRC32 checksum of original message */
521
- checksum: number;
522
- /** Fragment data */
523
- data: Uint8Array;
524
- }
525
- /**
526
- * Splits data into fragments of the specified size.
527
- */
528
- declare function splitMessage(message: Uint8Array, fragmentLen: number): Uint8Array[];
529
- /**
530
- * XOR two Uint8Arrays together.
531
- */
532
- declare function xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array;
533
- /**
534
- * Chooses which fragments to mix for a given sequence number.
535
- *
536
- * This uses a seeded Xoshiro256** PRNG to deterministically select fragments,
537
- * ensuring encoder and decoder agree without explicit coordination.
538
- *
539
- * @param seqNum - The sequence number (1-based)
540
- * @param seqLen - Total number of pure fragments
541
- * @param checksum - CRC32 checksum of the message
542
- * @returns Array of fragment indices (0-based)
543
- */
544
- declare function chooseFragments(seqNum: number, seqLen: number, checksum: number): number[];
545
- /**
546
- * Mixes the selected fragments using XOR.
547
- */
548
- declare function mixFragments(fragments: Uint8Array[], indices: number[]): Uint8Array;
549
- /**
550
- * Fountain encoder for creating multipart URs.
551
- */
552
- declare class FountainEncoder {
553
- private readonly fragments;
554
- private readonly messageLen;
555
- private readonly checksum;
556
- private seqNum;
557
- /**
558
- * Creates a fountain encoder for the given message.
559
- *
560
- * @param message - The message to encode
561
- * @param maxFragmentLen - Maximum length of each fragment
562
- */
563
- constructor(message: Uint8Array, maxFragmentLen: number);
564
- /**
565
- * Returns the number of pure fragments.
566
- */
567
- get seqLen(): number;
568
- /**
569
- * Returns whether the message fits in a single part.
570
- */
571
- isSinglePart(): boolean;
572
- /**
573
- * Returns whether all pure parts have been emitted.
574
- */
575
- isComplete(): boolean;
576
- /**
577
- * Generates the next fountain part.
578
- */
579
- nextPart(): FountainPart;
580
- /**
581
- * Returns the current sequence number.
582
- */
583
- currentSeqNum(): number;
584
- /**
585
- * Resets the encoder to start from the beginning.
586
- */
587
- reset(): void;
588
- }
589
- /**
590
- * Fountain decoder for reassembling multipart URs.
591
- */
592
- declare class FountainDecoder {
593
- private seqLen;
594
- private messageLen;
595
- private checksum;
596
- private readonly pureFragments;
597
- private readonly mixedParts;
598
- /**
599
- * Receives a fountain part and attempts to decode.
600
- *
601
- * @param part - The fountain part to receive
602
- * @returns true if the message is now complete
603
- */
604
- receive(part: FountainPart): boolean;
605
- /**
606
- * Attempts to extract pure fragments from mixed parts.
607
- */
608
- private reduceMixedParts;
609
- /**
610
- * Returns whether all fragments have been received.
611
- */
612
- isComplete(): boolean;
613
- /**
614
- * Reconstructs the original message.
615
- *
616
- * @returns The original message, or null if not yet complete
617
- */
618
- message(): Uint8Array | null;
619
- /**
620
- * Returns the progress as a fraction (0 to 1).
621
- */
622
- progress(): number;
623
- /**
624
- * Resets the decoder.
625
- */
626
- reset(): void;
627
- }
628
- //#endregion
629
- //#region src/xoshiro.d.ts
630
- /**
631
- * Xoshiro256** PRNG implementation.
632
- *
633
- * This is a high-quality, fast pseudo-random number generator used
634
- * for deterministic fragment selection in fountain codes.
635
- *
636
- * Reference: https://prng.di.unimi.it/
637
- */
638
- /**
639
- * Xoshiro256** pseudo-random number generator.
640
- *
641
- * This PRNG is used for deterministic mixing in fountain codes,
642
- * allowing both encoder and decoder to agree on which fragments
643
- * are combined without transmitting that information.
644
- */
645
- declare class Xoshiro256 {
646
- private s;
647
- /**
648
- * Creates a new Xoshiro256** instance from a seed.
649
- *
650
- * The seed is hashed using SHA-256 to initialize the state.
651
- * For consistent results across encoder/decoder, use the same seed.
652
- *
653
- * @param seed - The seed bytes (any length)
654
- */
655
- constructor(seed: Uint8Array);
656
- /**
657
- * Creates a Xoshiro256** instance from raw state values.
658
- * Useful for seeding with specific values.
659
- */
660
- static fromState(s0: bigint, s1: bigint, s2: bigint, s3: bigint): Xoshiro256;
661
- /**
662
- * Simple hash function for seeding.
663
- * This is a basic implementation - in production use SHA-256.
664
- */
665
- private hashSeed;
666
- /**
667
- * Converts 8 bytes to a 64-bit BigInt (little-endian).
668
- */
669
- private bytesToBigInt;
670
- /**
671
- * Generates the next 64-bit random value.
672
- */
673
- next(): bigint;
674
- /**
675
- * Generates a random double in [0, 1).
676
- */
677
- nextDouble(): number;
678
- /**
679
- * Generates a random integer in [low, high).
680
- */
681
- nextInt(low: number, high: number): number;
682
- /**
683
- * Generates a random byte [0, 255].
684
- */
685
- nextByte(): number;
686
- /**
687
- * Generates an array of random bytes.
688
- */
689
- nextData(count: number): Uint8Array;
690
- }
618
+ //#region src/utils.d.ts
691
619
  /**
692
- * Creates a seed for the Xoshiro PRNG from message checksum and sequence number.
620
+ * Copyright © 2023-2026 Blockchain Commons, LLC
621
+ * Copyright © 2025-2026 Parity Technologies
693
622
  *
694
- * This ensures that both encoder and decoder produce the same random sequence
695
- * for a given message and part number.
696
623
  */
697
- declare function createSeed(checksum: number, seqNum: number): Uint8Array;
698
- //#endregion
699
- //#region src/utils.d.ts
700
624
  /**
701
625
  * Checks if a character is a valid UR type character.
702
- * Valid characters are lowercase letters, digits, and hyphens.
626
+ *
627
+ * Mirrors Rust's `URTypeChar::is_ur_type` (`bc-ur-rust/src/utils.rs:6-19`):
628
+ * lowercase a-z, digits 0-9, and the hyphen `-`.
703
629
  */
704
630
  declare function isURTypeChar(char: string): boolean;
705
631
  /**
706
632
  * Checks if a string is a valid UR type.
707
- * Valid UR types contain only lowercase letters, digits, and hyphens.
633
+ *
634
+ * Mirrors Rust's `URTypeString::is_ur_type` (`bc-ur-rust/src/utils.rs:26-32`)
635
+ * which is `self.chars().all(...)` — meaning **the empty string is accepted**
636
+ * (a vacuously-true `all` over no chars). We mirror that here so that
637
+ * `URType::new("")` succeeds in both ports; the round-trip then fails at
638
+ * decode-time with `TypeUnspecified`.
708
639
  */
709
640
  declare function isValidURType(urType: string): boolean;
710
641
  /**
@@ -716,36 +647,78 @@ declare function validateURType(urType: string): string;
716
647
  * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2020-004-bytewords.md
717
648
  */
718
649
  declare const BYTEWORDS: string[];
719
- declare const BYTEWORDS_MAP: Map<string, number>;
720
650
  /**
721
651
  * Bytemojis for encoding/decoding bytes as emojis.
722
652
  * See: https://github.com/BlockchainCommons/Research/blob/master/papers/bcr-2024-008-bytemoji.md
723
653
  */
724
654
  declare const BYTEMOJIS: string[];
655
+ /**
656
+ * Encodes an arbitrary byte slice as a string of space-separated bytewords.
657
+ *
658
+ * Mirrors `bytewords::encode_to_words` in `bc-ur-rust` (≥ v0.19.1). Does not
659
+ * add a CRC32 checksum — use {@link encodeBytewords} for UR-style encoding.
660
+ */
661
+ declare function encodeToWords(data: Uint8Array): string;
662
+ /**
663
+ * Encodes an arbitrary byte slice as a string of space-separated bytemojis.
664
+ *
665
+ * Mirrors `bytewords::encode_to_bytemojis` in `bc-ur-rust` (≥ v0.19.1).
666
+ */
667
+ declare function encodeToBytemojis(data: Uint8Array): string;
668
+ /**
669
+ * Encodes an arbitrary byte slice as minimal bytewords (first + last letter of
670
+ * each word, concatenated with no separator).
671
+ *
672
+ * Mirrors `bytewords::encode_to_minimal_bytewords` in `bc-ur-rust`
673
+ * (≥ v0.19.1). Does not add a CRC32 checksum.
674
+ */
675
+ declare function encodeToMinimalBytewords(data: Uint8Array): string;
725
676
  /**
726
677
  * Encodes a 4-byte slice as a string of bytewords for identification.
678
+ *
679
+ * Thin wrapper over {@link encodeToWords} that enforces the 4-byte length
680
+ * contract historically used by `bc-ur-rust`'s `bytewords::identifier`.
727
681
  */
728
682
  declare function encodeBytewordsIdentifier(data: Uint8Array): string;
729
683
  /**
730
684
  * Encodes a 4-byte slice as a string of bytemojis for identification.
685
+ *
686
+ * Thin wrapper over {@link encodeToBytemojis} that enforces the 4-byte length
687
+ * contract historically used by `bc-ur-rust`'s `bytewords::bytemoji_identifier`.
731
688
  */
732
689
  declare function encodeBytemojisIdentifier(data: Uint8Array): string;
690
+ /**
691
+ * Returns `true` if `emoji` is one of the 256 bytemojis.
692
+ *
693
+ * Mirrors `bytewords::is_valid_bytemoji` in `bc-ur-rust` (≥ v0.19.1).
694
+ */
695
+ declare function isValidBytemoji(emoji: string): boolean;
696
+ /**
697
+ * Canonicalises a byteword token (2–4 ASCII letters, case-insensitive) to its
698
+ * full 4-letter lowercase form. Returns `undefined` if the token is not a
699
+ * valid byteword or any of its short forms.
700
+ *
701
+ * Mirrors `bytewords::canonicalize_byteword` in `bc-ur-rust` (≥ v0.19.1).
702
+ *
703
+ * - 2-letter tokens are matched against the first + last letter of each
704
+ * byteword (identical to the minimal bytewords encoding).
705
+ * - 3-letter tokens are matched against the first 3 and the last 3 letters of
706
+ * each byteword; if both match different entries, the first-3 match wins
707
+ * (matching rust's `or_else` priority).
708
+ * - 4-letter tokens must exactly match a full byteword (after lower-casing).
709
+ */
710
+ declare function canonicalizeByteword(token: string): string | undefined;
733
711
  /**
734
712
  * Bytewords encoding style.
735
713
  */
736
714
  declare enum BytewordsStyle {
737
715
  /** Full 4-letter words separated by spaces */
738
716
  Standard = "standard",
739
- /** Full 4-letter words without separators */
717
+ /** Full 4-letter words separated by hyphens (URI-safe) */
740
718
  Uri = "uri",
741
719
  /** First and last character only (minimal) - used by UR encoding */
742
- Minimal = "minimal",
720
+ Minimal = "minimal"
743
721
  }
744
- declare const MINIMAL_BYTEWORDS_MAP: Map<string, number>;
745
- /**
746
- * Calculate CRC32 checksum of data.
747
- */
748
- declare function crc32(data: Uint8Array): number;
749
722
  /**
750
723
  * Encode data as bytewords with the specified style.
751
724
  * Includes CRC32 checksum.
@@ -754,8 +727,23 @@ declare function encodeBytewords(data: Uint8Array, style?: BytewordsStyle): stri
754
727
  /**
755
728
  * Decode bytewords string back to data.
756
729
  * Validates and removes CRC32 checksum.
730
+ *
731
+ * Errors mirror the upstream Rust `ur::bytewords::Error` enum
732
+ * (`ur-0.4.1/src/bytewords.rs`):
733
+ * - `NonAscii` — input contains non-ASCII characters (checked first).
734
+ * - `InvalidLength` — minimal-style input has odd length.
735
+ * - `InvalidWord` — a token does not map to a byteword index.
736
+ * - `InvalidChecksum` — the trailing 4-byte CRC32 does not match.
737
+ *
738
+ * All variants are surfaced as {@link BytewordsError} with the same default
739
+ * `Display` strings as Rust (e.g. "invalid checksum", "non-ASCII"), so
740
+ * callers can branch on the error class rather than the bare `Error`
741
+ * thrown by earlier revisions of this port.
757
742
  */
758
743
  declare function decodeBytewords(encoded: string, style?: BytewordsStyle): Uint8Array;
744
+ declare namespace bytewords_namespace_d_exports {
745
+ export { BYTEMOJIS, BYTEWORDS, BytewordsStyle as Style, encodeBytemojisIdentifier as bytemojiIdentifier, canonicalizeByteword, decodeBytewords as decode, encodeBytewords as encode, encodeToBytemojis, encodeToMinimalBytewords, encodeToWords, encodeBytewordsIdentifier as identifier, isValidBytemoji };
746
+ }
759
747
  //#endregion
760
- export { BYTEMOJIS, BYTEWORDS, BYTEWORDS_MAP, BytewordsError, BytewordsStyle, CBORError, FountainDecoder, FountainEncoder, type FountainPart, InvalidSchemeError, InvalidTypeError, MINIMAL_BYTEWORDS_MAP, MultipartDecoder, MultipartEncoder, NotSinglePartError, type Result, TypeUnspecifiedError, UR, type URCodable, type URDecodable, type UREncodable, URError, URType, UnexpectedTypeError, Xoshiro256, chooseFragments, crc32, createSeed, decodeBytewords, encodeBytemojisIdentifier, encodeBytewords, encodeBytewordsIdentifier, isError, isURCodable, isURDecodable, isUREncodable, isURTypeChar, isValidURType, mixFragments, splitMessage, validateURType, xorBytes };
748
+ export { BYTEMOJIS, BYTEWORDS, BytewordsError, BytewordsStyle, CBORError, InvalidSchemeError, InvalidTypeError, MultipartDecoder, MultipartEncoder, NotSinglePartError, type Result, TypeUnspecifiedError, UR, type URCodable, type URDecodable, URDecodeError, type UREncodable, URError, URType, UnexpectedTypeError, bytewords_namespace_d_exports as bytewords, canonicalizeByteword, decodableFromUR, decodableFromURString, decodeBytewords, encodeBytemojisIdentifier, encodeBytewords, encodeBytewordsIdentifier, encodeToBytemojis, encodeToMinimalBytewords, encodeToWords, isError, isURCodable, isURDecodable, isUREncodable, isURTypeChar, isValidBytemoji, isValidURType, urFromEncodable, urStringFromEncodable, validateURType };
761
749
  //# sourceMappingURL=index.d.cts.map