-
Notifications
You must be signed in to change notification settings - Fork 35
/
csuint.ts
52 lines (48 loc) · 1.6 KB
/
csuint.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import { Hex } from "../utils"
/**
* Reads the leading compact size uint from the provided variable length data.
*
* WARNING: CURRENTLY, THIS FUNCTION SUPPORTS ONLY 1-BYTE COMPACT SIZE UINTS
* AND WILL THROW ON COMPACT SIZE UINTS OF DIFFERENT BYTE LENGTH.
*
* @param varLenData Variable length data preceded by a compact size uint.
* @returns An object holding the value of the compact size uint along with the
* compact size uint byte length.
*/
function read(varLenData: Hex): {
value: number
byteLength: number
} {
if (varLenData.toString().length == 0) {
throw new Error("Empty variable length data argument")
}
// The varLenData is prefixed with the compact size uint. According to the docs
// (https://developer.bitcoin.org/reference/transactions.html#compactsize-unsigned-integers)
// a compact size uint can be 1, 3, 5 or 9 bytes. To determine the exact length,
// we need to look at the discriminant byte which is always the first byte of
// the compact size uint.
const discriminant = varLenData.toString().slice(0, 2)
switch (discriminant) {
case "ff":
case "fe":
case "fd": {
throw new Error(
"Support for 3, 5 and 9 bytes compact size uints is not implemented yet"
)
}
default: {
// The discriminant tells the compact size uint is 1 byte. That means
// the discriminant represents the value itself.
return {
value: parseInt(discriminant, 16),
byteLength: 1,
}
}
}
}
/**
* Utility functions allowing to deal with Bitcoin compact size uints.
*/
export const BitcoinCompactSizeUint = {
read,
}