bolt12-utils 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 (51) hide show
  1. package/dist/bech32.d.ts +31 -0
  2. package/dist/bech32.d.ts.map +1 -0
  3. package/dist/bech32.js +161 -0
  4. package/dist/bech32.js.map +1 -0
  5. package/dist/bigsize.d.ts +22 -0
  6. package/dist/bigsize.d.ts.map +1 -0
  7. package/dist/bigsize.js +87 -0
  8. package/dist/bigsize.js.map +1 -0
  9. package/dist/fields.d.ts +61 -0
  10. package/dist/fields.d.ts.map +1 -0
  11. package/dist/fields.js +99 -0
  12. package/dist/fields.js.map +1 -0
  13. package/dist/generated.d.ts +179 -0
  14. package/dist/generated.d.ts.map +1 -0
  15. package/dist/generated.js +565 -0
  16. package/dist/generated.js.map +1 -0
  17. package/dist/index.d.ts +47 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +125 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/merkle.d.ts +55 -0
  22. package/dist/merkle.d.ts.map +1 -0
  23. package/dist/merkle.js +144 -0
  24. package/dist/merkle.js.map +1 -0
  25. package/dist/offer.d.ts +45 -0
  26. package/dist/offer.d.ts.map +1 -0
  27. package/dist/offer.js +288 -0
  28. package/dist/offer.js.map +1 -0
  29. package/dist/payer_proof.d.ts +89 -0
  30. package/dist/payer_proof.d.ts.map +1 -0
  31. package/dist/payer_proof.js +576 -0
  32. package/dist/payer_proof.js.map +1 -0
  33. package/dist/tlv.d.ts +26 -0
  34. package/dist/tlv.d.ts.map +1 -0
  35. package/dist/tlv.js +65 -0
  36. package/dist/tlv.js.map +1 -0
  37. package/dist/utils.d.ts +12 -0
  38. package/dist/utils.d.ts.map +1 -0
  39. package/dist/utils.js +52 -0
  40. package/dist/utils.js.map +1 -0
  41. package/package.json +47 -0
  42. package/src/bech32.ts +187 -0
  43. package/src/bigsize.ts +97 -0
  44. package/src/fields.ts +147 -0
  45. package/src/generated.ts +697 -0
  46. package/src/index.ts +132 -0
  47. package/src/merkle.ts +163 -0
  48. package/src/offer.ts +328 -0
  49. package/src/payer_proof.ts +727 -0
  50. package/src/tlv.ts +75 -0
  51. package/src/utils.ts +49 -0
package/src/tlv.ts ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * TLV (Type-Length-Value) stream parsing for BOLT12.
3
+ *
4
+ * A TLV stream is a sequence of records, each consisting of:
5
+ * - type: BigSize
6
+ * - length: BigSize
7
+ * - value: `length` bytes
8
+ *
9
+ * Records MUST appear in strictly ascending type order.
10
+ */
11
+
12
+ import { readBigSize, writeBigSize } from './bigsize.js';
13
+
14
+ export interface TlvRecord {
15
+ type: bigint;
16
+ length: bigint;
17
+ value: Uint8Array;
18
+ }
19
+
20
+ /**
21
+ * Parse a TLV stream from raw bytes.
22
+ * Returns an array of TLV records.
23
+ * Throws if types are not in ascending order.
24
+ */
25
+ export function parseTlvStream(data: Uint8Array): TlvRecord[] {
26
+ const records: TlvRecord[] = [];
27
+ let offset = 0;
28
+ let lastType = -1n;
29
+
30
+ while (offset < data.length) {
31
+ // Read type
32
+ const typeResult = readBigSize(data, offset);
33
+ offset += typeResult.bytesRead;
34
+ const tlvType = typeResult.value;
35
+
36
+ // Check ascending order
37
+ if (tlvType <= lastType) {
38
+ throw new Error('TLV fields not in ascending order');
39
+ }
40
+ lastType = tlvType;
41
+
42
+ // Read length
43
+ if (offset >= data.length) {
44
+ throw new Error('Truncated TLV: missing length');
45
+ }
46
+ const lengthResult = readBigSize(data, offset);
47
+ offset += lengthResult.bytesRead;
48
+ const tlvLength = lengthResult.value;
49
+
50
+ // Read value
51
+ const len = Number(tlvLength);
52
+ if (offset + len > data.length) {
53
+ throw new Error('Truncated TLV: value extends beyond data');
54
+ }
55
+ const value = data.slice(offset, offset + len);
56
+ offset += len;
57
+
58
+ records.push({ type: tlvType, length: tlvLength, value });
59
+ }
60
+
61
+ return records;
62
+ }
63
+
64
+ /**
65
+ * Serialize a TLV record to bytes (type + length + value).
66
+ */
67
+ export function serializeTlvRecord(record: TlvRecord): Uint8Array {
68
+ const typeBytes = writeBigSize(record.type);
69
+ const lengthBytes = writeBigSize(record.length);
70
+ const result = new Uint8Array(typeBytes.length + lengthBytes.length + record.value.length);
71
+ result.set(typeBytes, 0);
72
+ result.set(lengthBytes, typeBytes.length);
73
+ result.set(record.value, typeBytes.length + lengthBytes.length);
74
+ return result;
75
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Shared utility functions for BOLT12 modules.
3
+ */
4
+
5
+ /** Read a truncated big-endian unsigned integer from bytes. Empty = 0. */
6
+ export function readTruncatedUint(data: Uint8Array): bigint {
7
+ if (data.length === 0) {
8
+ return 0n;
9
+ }
10
+ let val = 0n;
11
+ for (let i = 0; i < data.length; i++) {
12
+ val = (val << 8n) | BigInt(data[i]);
13
+ }
14
+ return val;
15
+ }
16
+
17
+ /** Convert bytes to lowercase hex string. */
18
+ export function toHex(buf: Uint8Array): string {
19
+ let hex = '';
20
+ for (let i = 0; i < buf.length; i++) {
21
+ hex += buf[i].toString(16).padStart(2, '0');
22
+ }
23
+ return hex;
24
+ }
25
+
26
+ /** Check if a TLV type is a signature element (240-1000 inclusive). */
27
+ export function isSignatureType(type: bigint): boolean {
28
+ return type >= 240n && type <= 1000n;
29
+ }
30
+
31
+ /** Compare two byte arrays lexicographically. */
32
+ export function compareBytes(a: Uint8Array, b: Uint8Array): number {
33
+ const len = Math.min(a.length, b.length);
34
+ for (let i = 0; i < len; i++) {
35
+ if (a[i] < b[i]) {
36
+ return -1;
37
+ }
38
+ if (a[i] > b[i]) {
39
+ return 1;
40
+ }
41
+ }
42
+ if (a.length < b.length) {
43
+ return -1;
44
+ }
45
+ if (a.length > b.length) {
46
+ return 1;
47
+ }
48
+ return 0;
49
+ }