@bsv/sdk 1.10.1 → 1.10.3
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/cjs/package.json +1 -1
- package/dist/cjs/src/identity/IdentityClient.js +124 -20
- package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
- package/dist/cjs/src/primitives/ReaderUint8Array.js +180 -0
- package/dist/cjs/src/primitives/ReaderUint8Array.js.map +1 -0
- package/dist/cjs/src/primitives/WriterUint8Array.js +173 -0
- package/dist/cjs/src/primitives/WriterUint8Array.js.map +1 -0
- package/dist/cjs/src/primitives/utils.js +20 -2
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +85 -27
- package/dist/cjs/src/transaction/Beef.js.map +1 -1
- package/dist/cjs/src/transaction/BeefTx.js +32 -14
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js +25 -6
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +77 -26
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/identity/IdentityClient.js +124 -20
- package/dist/esm/src/identity/IdentityClient.js.map +1 -1
- package/dist/esm/src/primitives/ReaderUint8Array.js +176 -0
- package/dist/esm/src/primitives/ReaderUint8Array.js.map +1 -0
- package/dist/esm/src/primitives/WriterUint8Array.js +169 -0
- package/dist/esm/src/primitives/WriterUint8Array.js.map +1 -0
- package/dist/esm/src/primitives/utils.js +18 -1
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +86 -28
- package/dist/esm/src/transaction/Beef.js.map +1 -1
- package/dist/esm/src/transaction/BeefTx.js +33 -15
- package/dist/esm/src/transaction/BeefTx.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js +26 -7
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +78 -27
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/identity/IdentityClient.d.ts +8 -0
- package/dist/types/src/identity/IdentityClient.d.ts.map +1 -1
- package/dist/types/src/primitives/ReaderUint8Array.d.ts +32 -0
- package/dist/types/src/primitives/ReaderUint8Array.d.ts.map +1 -0
- package/dist/types/src/primitives/WriterUint8Array.d.ts +54 -0
- package/dist/types/src/primitives/WriterUint8Array.d.ts.map +1 -0
- package/dist/types/src/primitives/utils.d.ts +15 -3
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +24 -7
- package/dist/types/src/transaction/Beef.d.ts.map +1 -1
- package/dist/types/src/transaction/BeefTx.d.ts +13 -6
- package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
- package/dist/types/src/transaction/MerklePath.d.ts +16 -3
- package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts +44 -7
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/primitives.md +167 -29
- package/docs/reference/script.md +1 -1
- package/docs/reference/transaction.md +177 -34
- package/package.json +1 -1
- package/src/identity/IdentityClient.ts +153 -29
- package/src/identity/__tests/IdentityClient.test.ts +289 -1
- package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +9 -0
- package/src/primitives/ReaderUint8Array.ts +196 -0
- package/src/primitives/WriterUint8Array.ts +195 -0
- package/src/primitives/__tests/ReaderUint8Array.test.ts +317 -0
- package/src/primitives/__tests/WriterUint8Array.test.ts +208 -0
- package/src/primitives/utils.ts +20 -2
- package/src/transaction/Beef.ts +103 -40
- package/src/transaction/BeefTx.ts +38 -19
- package/src/transaction/MerklePath.ts +30 -9
- package/src/transaction/Transaction.ts +91 -38
- package/src/transaction/__tests/Beef.test.ts +75 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import BigNumber from './BigNumber.js'
|
|
2
|
+
import { Reader } from './utils.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Reader for serialized Uint8Array binary data.
|
|
6
|
+
*/
|
|
7
|
+
export class ReaderUint8Array {
|
|
8
|
+
public bin: Uint8Array
|
|
9
|
+
public pos: number
|
|
10
|
+
private readonly length: number
|
|
11
|
+
|
|
12
|
+
static makeReader (bin: Uint8Array | number[], pos: number = 0): Reader | ReaderUint8Array {
|
|
13
|
+
if (bin instanceof Uint8Array) {
|
|
14
|
+
return new ReaderUint8Array(bin, pos)
|
|
15
|
+
}
|
|
16
|
+
if (Array.isArray(bin)) {
|
|
17
|
+
return new Reader(bin, pos)
|
|
18
|
+
}
|
|
19
|
+
throw new Error('ReaderUint8Array.makeReader: bin must be Uint8Array or number[]')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
constructor (bin: Uint8Array | number[] = new Uint8Array(0), pos: number = 0) {
|
|
23
|
+
if (bin instanceof Uint8Array) {
|
|
24
|
+
this.bin = bin
|
|
25
|
+
} else if (Array.isArray(bin)) {
|
|
26
|
+
this.bin = new Uint8Array(bin)
|
|
27
|
+
} else {
|
|
28
|
+
throw new Error('ReaderUint8Array constructor: bin must be Uint8Array or number[]')
|
|
29
|
+
}
|
|
30
|
+
this.pos = pos
|
|
31
|
+
this.length = this.bin.length
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
public eof (): boolean {
|
|
35
|
+
return this.pos >= this.length
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
public read (len = this.length): Uint8Array {
|
|
39
|
+
const start = this.pos
|
|
40
|
+
const end = this.pos + len
|
|
41
|
+
this.pos = end
|
|
42
|
+
return this.bin.slice(start, end)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public readReverse (len = this.length): Uint8Array {
|
|
46
|
+
const buf2 = new Uint8Array(len)
|
|
47
|
+
for (let i = 0; i < len; i++) {
|
|
48
|
+
buf2[i] = this.bin[this.pos + len - 1 - i]
|
|
49
|
+
}
|
|
50
|
+
this.pos += len
|
|
51
|
+
return buf2
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public readUInt8 (): number {
|
|
55
|
+
const val = this.bin[this.pos]
|
|
56
|
+
this.pos += 1
|
|
57
|
+
return val
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public readInt8 (): number {
|
|
61
|
+
const val = this.bin[this.pos]
|
|
62
|
+
this.pos += 1
|
|
63
|
+
// If the sign bit is set, convert to negative value
|
|
64
|
+
return (val & 0x80) !== 0 ? val - 0x100 : val
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public readUInt16BE (): number {
|
|
68
|
+
const val = (this.bin[this.pos] << 8) | this.bin[this.pos + 1]
|
|
69
|
+
this.pos += 2
|
|
70
|
+
return val
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public readInt16BE (): number {
|
|
74
|
+
const val = this.readUInt16BE()
|
|
75
|
+
// If the sign bit is set, convert to negative value
|
|
76
|
+
return (val & 0x8000) !== 0 ? val - 0x10000 : val
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public readUInt16LE (): number {
|
|
80
|
+
const val = this.bin[this.pos] | (this.bin[this.pos + 1] << 8)
|
|
81
|
+
this.pos += 2
|
|
82
|
+
return val
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public readInt16LE (): number {
|
|
86
|
+
const val = this.readUInt16LE()
|
|
87
|
+
// If the sign bit is set, convert to negative value
|
|
88
|
+
const x = (val & 0x8000) !== 0 ? val - 0x10000 : val
|
|
89
|
+
return x
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public readUInt32BE (): number {
|
|
93
|
+
const val =
|
|
94
|
+
this.bin[this.pos] * 0x1000000 + // Shift the first byte by 24 bits
|
|
95
|
+
((this.bin[this.pos + 1] << 16) | // Shift the second byte by 16 bits
|
|
96
|
+
(this.bin[this.pos + 2] << 8) | // Shift the third byte by 8 bits
|
|
97
|
+
this.bin[this.pos + 3]) // The fourth byte
|
|
98
|
+
this.pos += 4
|
|
99
|
+
return val
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public readInt32BE (): number {
|
|
103
|
+
const val = this.readUInt32BE()
|
|
104
|
+
// If the sign bit is set, convert to negative value
|
|
105
|
+
return (val & 0x80000000) !== 0 ? val - 0x100000000 : val
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public readUInt32LE (): number {
|
|
109
|
+
const val =
|
|
110
|
+
(this.bin[this.pos] |
|
|
111
|
+
(this.bin[this.pos + 1] << 8) |
|
|
112
|
+
(this.bin[this.pos + 2] << 16) |
|
|
113
|
+
(this.bin[this.pos + 3] << 24)) >>>
|
|
114
|
+
0
|
|
115
|
+
this.pos += 4
|
|
116
|
+
return val
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public readInt32LE (): number {
|
|
120
|
+
const val = this.readUInt32LE()
|
|
121
|
+
// Explicitly check if the sign bit is set and then convert to a negative value
|
|
122
|
+
return (val & 0x80000000) !== 0 ? val - 0x100000000 : val
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
public readUInt64BEBn (): BigNumber {
|
|
126
|
+
const bin = Array.from(this.bin.slice(this.pos, this.pos + 8))
|
|
127
|
+
const bn = new BigNumber(bin)
|
|
128
|
+
this.pos = this.pos + 8
|
|
129
|
+
return bn
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
public readUInt64LEBn (): BigNumber {
|
|
133
|
+
const bin = Array.from(this.readReverse(8))
|
|
134
|
+
const bn = new BigNumber(bin)
|
|
135
|
+
return bn
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public readInt64LEBn (): BigNumber {
|
|
139
|
+
const OverflowInt64 = new BigNumber(2).pow(new BigNumber(63))
|
|
140
|
+
const OverflowUint64 = new BigNumber(2).pow(new BigNumber(64))
|
|
141
|
+
const bin = Array.from(this.readReverse(8))
|
|
142
|
+
let bn = new BigNumber(bin)
|
|
143
|
+
if (bn.gte(OverflowInt64)) {
|
|
144
|
+
bn = bn.sub(OverflowUint64) // Adjust for negative numbers
|
|
145
|
+
}
|
|
146
|
+
return bn
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public readVarIntNum (signed: boolean = true): number {
|
|
150
|
+
const first = this.readUInt8()
|
|
151
|
+
let bn: BigNumber
|
|
152
|
+
switch (first) {
|
|
153
|
+
case 0xfd:
|
|
154
|
+
return this.readUInt16LE()
|
|
155
|
+
case 0xfe:
|
|
156
|
+
return this.readUInt32LE()
|
|
157
|
+
case 0xff:
|
|
158
|
+
bn = signed ? this.readInt64LEBn() : this.readUInt64LEBn()
|
|
159
|
+
if (bn.lte(new BigNumber(2).pow(new BigNumber(53)))) {
|
|
160
|
+
return bn.toNumber()
|
|
161
|
+
} else {
|
|
162
|
+
throw new Error('number too large to retain precision - use readVarIntBn')
|
|
163
|
+
}
|
|
164
|
+
default:
|
|
165
|
+
return first
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public readVarInt (): Uint8Array {
|
|
170
|
+
const first = this.bin[this.pos]
|
|
171
|
+
switch (first) {
|
|
172
|
+
case 0xfd:
|
|
173
|
+
return this.read(1 + 2)
|
|
174
|
+
case 0xfe:
|
|
175
|
+
return this.read(1 + 4)
|
|
176
|
+
case 0xff:
|
|
177
|
+
return this.read(1 + 8)
|
|
178
|
+
default:
|
|
179
|
+
return this.read(1)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public readVarIntBn (): BigNumber {
|
|
184
|
+
const first = this.readUInt8()
|
|
185
|
+
switch (first) {
|
|
186
|
+
case 0xfd:
|
|
187
|
+
return new BigNumber(this.readUInt16LE())
|
|
188
|
+
case 0xfe:
|
|
189
|
+
return new BigNumber(this.readUInt32LE())
|
|
190
|
+
case 0xff:
|
|
191
|
+
return this.readUInt64LEBn()
|
|
192
|
+
default:
|
|
193
|
+
return new BigNumber(first)
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import BigNumber from './BigNumber.js'
|
|
2
|
+
import { Writer } from './utils.js'
|
|
3
|
+
|
|
4
|
+
type WriterChunk = readonly number[] | Uint8Array
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* WriterUint8Array is a utility class for writing binary data into a dynamically
|
|
8
|
+
* growing Uint8Array buffer. It provides methods to write various integer types
|
|
9
|
+
* and variable-length integers, similar to the Writer class but optimized for
|
|
10
|
+
* Uint8Array usage.
|
|
11
|
+
*/
|
|
12
|
+
export class WriterUint8Array {
|
|
13
|
+
private buffer: Uint8Array
|
|
14
|
+
private pos: number
|
|
15
|
+
private capacity: number
|
|
16
|
+
|
|
17
|
+
constructor (bufs?: WriterChunk[], initialCapacity: number = 256) {
|
|
18
|
+
if ((bufs != null) && bufs.length > 0) {
|
|
19
|
+
const totalLength = bufs.reduce((sum, buf) => sum + buf.length, 0)
|
|
20
|
+
initialCapacity = Math.max(initialCapacity, totalLength)
|
|
21
|
+
}
|
|
22
|
+
this.buffer = new Uint8Array(initialCapacity)
|
|
23
|
+
this.pos = 0
|
|
24
|
+
this.capacity = initialCapacity
|
|
25
|
+
if (bufs != null) {
|
|
26
|
+
for (const buf of bufs) {
|
|
27
|
+
this.write(buf)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns the current length of written data
|
|
34
|
+
*/
|
|
35
|
+
getLength (): number {
|
|
36
|
+
return this.pos
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @return the written data as Uint8Array copy of the internal buffer
|
|
41
|
+
*/
|
|
42
|
+
toUint8Array (): Uint8Array {
|
|
43
|
+
return this.buffer.slice(0, this.pos)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Legacy compatibility method – returns number[] (Byte[])
|
|
48
|
+
*/
|
|
49
|
+
toArray (): number[] {
|
|
50
|
+
return Array.from(this.toUint8Array())
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @return the written data as Uint8Array. CAUTION: This is zero-copy subarray of the internal buffer).
|
|
55
|
+
*/
|
|
56
|
+
toUint8ArrayZeroCopy (): Uint8Array {
|
|
57
|
+
return this.buffer.subarray(0, this.pos)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private ensureCapacity (needed: number): void {
|
|
61
|
+
if (this.pos + needed > this.capacity) {
|
|
62
|
+
let newCapacity = this.capacity * 2
|
|
63
|
+
while (this.pos + needed > newCapacity) {
|
|
64
|
+
newCapacity *= 2
|
|
65
|
+
}
|
|
66
|
+
const newBuffer = new Uint8Array(newCapacity)
|
|
67
|
+
newBuffer.set(this.buffer)
|
|
68
|
+
this.buffer = newBuffer
|
|
69
|
+
this.capacity = newCapacity
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
write (bytes: WriterChunk): this {
|
|
74
|
+
const data = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)
|
|
75
|
+
this.ensureCapacity(data.length)
|
|
76
|
+
this.buffer.set(data, this.pos)
|
|
77
|
+
this.pos += data.length
|
|
78
|
+
return this
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
writeReverse (buf: WriterChunk): this {
|
|
82
|
+
const data = buf instanceof Uint8Array ? buf : new Uint8Array(buf)
|
|
83
|
+
this.ensureCapacity(data.length)
|
|
84
|
+
for (let i = data.length - 1; i >= 0; i--) {
|
|
85
|
+
this.buffer[this.pos] = data[i]
|
|
86
|
+
this.pos += 1
|
|
87
|
+
}
|
|
88
|
+
return this
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
writeUInt8 (value: number): this {
|
|
92
|
+
this.ensureCapacity(1)
|
|
93
|
+
this.buffer[this.pos] = value & 0xff
|
|
94
|
+
this.pos += 1
|
|
95
|
+
return this
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
writeInt8 (value: number): this {
|
|
99
|
+
this.writeUInt8(value)
|
|
100
|
+
return this
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
writeUInt16LE (value: number): this {
|
|
104
|
+
this.ensureCapacity(2)
|
|
105
|
+
this.buffer[this.pos] = value & 0xff
|
|
106
|
+
this.buffer[this.pos + 1] = (value >> 8) & 0xff
|
|
107
|
+
this.pos += 2
|
|
108
|
+
return this
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
writeUInt16BE (value: number): this {
|
|
112
|
+
this.ensureCapacity(2)
|
|
113
|
+
this.buffer[this.pos] = (value >> 8) & 0xff
|
|
114
|
+
this.buffer[this.pos + 1] = value & 0xff
|
|
115
|
+
this.pos += 2
|
|
116
|
+
return this
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
writeInt16LE (value: number): this {
|
|
120
|
+
this.writeUInt16LE(value & 0xffff)
|
|
121
|
+
return this
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
writeInt16BE (value: number): this {
|
|
125
|
+
this.writeUInt16BE(value & 0xffff)
|
|
126
|
+
return this
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
writeUInt32LE (value: number): this {
|
|
130
|
+
this.ensureCapacity(4)
|
|
131
|
+
this.buffer[this.pos] = value & 0xff
|
|
132
|
+
this.buffer[this.pos + 1] = (value >> 8) & 0xff
|
|
133
|
+
this.buffer[this.pos + 2] = (value >> 16) & 0xff
|
|
134
|
+
this.buffer[this.pos + 3] = (value >> 24) & 0xff
|
|
135
|
+
this.pos += 4
|
|
136
|
+
return this
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
writeUInt32BE (value: number): this {
|
|
140
|
+
this.ensureCapacity(4)
|
|
141
|
+
this.buffer[this.pos] = (value >> 24) & 0xff
|
|
142
|
+
this.buffer[this.pos + 1] = (value >> 16) & 0xff
|
|
143
|
+
this.buffer[this.pos + 2] = (value >> 8) & 0xff
|
|
144
|
+
this.buffer[this.pos + 3] = value & 0xff
|
|
145
|
+
this.pos += 4
|
|
146
|
+
return this
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
writeInt32LE (value: number): this {
|
|
150
|
+
this.writeUInt32LE(value >>> 0)
|
|
151
|
+
return this
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
writeInt32BE (value: number): this {
|
|
155
|
+
this.writeUInt32BE(value >>> 0)
|
|
156
|
+
return this
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
writeUInt64BEBn (bn: BigNumber): this {
|
|
160
|
+
const buf = bn.toArray('be', 8)
|
|
161
|
+
this.write(buf)
|
|
162
|
+
return this
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
writeUInt64LEBn (bn: BigNumber): this {
|
|
166
|
+
const buf = bn.toArray('be', 8)
|
|
167
|
+
this.writeReverse(buf)
|
|
168
|
+
return this
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
writeUInt64LE (n: number): this {
|
|
172
|
+
const buf = new BigNumber(n).toArray('be', 8)
|
|
173
|
+
this.writeReverse(buf)
|
|
174
|
+
return this
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
writeVarIntNum (n: number): this {
|
|
178
|
+
const buf = Writer.varIntNum(n)
|
|
179
|
+
this.write(buf)
|
|
180
|
+
return this
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
writeVarIntBn (bn: BigNumber): this {
|
|
184
|
+
const buf = Writer.varIntBn(bn)
|
|
185
|
+
this.write(buf)
|
|
186
|
+
return this
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Resets the writer to empty state (reuses the buffer)
|
|
191
|
+
*/
|
|
192
|
+
reset (): void {
|
|
193
|
+
this.pos = 0
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import BigNumber from '../BigNumber'
|
|
2
|
+
import { ReaderUint8Array, Writer, toHex } from '../utils'
|
|
3
|
+
|
|
4
|
+
describe('ReaderUint8Array', () => {
|
|
5
|
+
it('should make a new Br', () => {
|
|
6
|
+
let br = new ReaderUint8Array()
|
|
7
|
+
expect(br).toBeDefined()
|
|
8
|
+
br = new ReaderUint8Array()
|
|
9
|
+
expect(br).toBeDefined()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
it('should create a new ReaderUint8Array with an Array', () => {
|
|
13
|
+
const arr: number[] = []
|
|
14
|
+
const br = new ReaderUint8Array(arr)
|
|
15
|
+
expect(br).toBeDefined()
|
|
16
|
+
expect(br.bin instanceof Uint8Array).toBeTruthy()
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
describe('#eof', () => {
|
|
20
|
+
it('should return true for a blank br', () => {
|
|
21
|
+
const br = new ReaderUint8Array([...Buffer.from([])])
|
|
22
|
+
expect(br.eof()).toBeTruthy()
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
describe('#read', () => {
|
|
27
|
+
it('should return the same buffer', () => {
|
|
28
|
+
const buf = Buffer.from([0])
|
|
29
|
+
const br = new ReaderUint8Array([...buf])
|
|
30
|
+
expect(Buffer.from(br.read()).toString('hex')).toEqual(
|
|
31
|
+
buf.toString('hex')
|
|
32
|
+
)
|
|
33
|
+
})
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('should return a buffer of this length', () => {
|
|
37
|
+
const buf = Buffer.alloc(10)
|
|
38
|
+
buf.fill(0)
|
|
39
|
+
const br = new ReaderUint8Array([...buf])
|
|
40
|
+
const buf2 = br.read(2)
|
|
41
|
+
expect(buf2.length).toEqual(2)
|
|
42
|
+
expect(br.eof()).toBeFalsy()
|
|
43
|
+
expect(br.pos).toEqual(2)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('should be able to read 0 bytes', () => {
|
|
47
|
+
const buf = Buffer.from('0101', 'hex')
|
|
48
|
+
expect(new ReaderUint8Array([...buf]).read(0).length).toEqual(0)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
describe('#readReverse', () => {
|
|
53
|
+
it('should reverse this [0, 1]', () => {
|
|
54
|
+
const buf = Buffer.from([0, 1])
|
|
55
|
+
const br = new ReaderUint8Array([...buf])
|
|
56
|
+
expect(toHex(br.readReverse())).toEqual('0100')
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should be able to read 0 bytes', () => {
|
|
60
|
+
const buf = Buffer.from('0101', 'hex')
|
|
61
|
+
expect(new ReaderUint8Array([...buf]).readReverse(0).length).toEqual(0)
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
describe('#readUInt8', () => {
|
|
66
|
+
it('should return 1', () => {
|
|
67
|
+
const buf = Buffer.alloc(1)
|
|
68
|
+
buf.writeUInt8(1, 0)
|
|
69
|
+
const br = new ReaderUint8Array([...buf])
|
|
70
|
+
expect(br.readUInt8()).toEqual(1)
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
describe('#readInt8', () => {
|
|
75
|
+
it('should return 1', () => {
|
|
76
|
+
const buf = Buffer.alloc(1)
|
|
77
|
+
buf.writeInt8(1, 0)
|
|
78
|
+
const br = new ReaderUint8Array([...buf])
|
|
79
|
+
expect(br.readInt8()).toEqual(1)
|
|
80
|
+
const bufNegative = Buffer.from('ff', 'hex')
|
|
81
|
+
const brNegative = new ReaderUint8Array([...bufNegative])
|
|
82
|
+
expect(brNegative.readInt8()).toEqual(-1)
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
describe('#readUInt16BE', () => {
|
|
87
|
+
it('should return 1', () => {
|
|
88
|
+
const buf = Buffer.alloc(2)
|
|
89
|
+
buf.writeUInt16BE(1, 0)
|
|
90
|
+
const br = new ReaderUint8Array([...buf])
|
|
91
|
+
expect(br.readUInt16BE()).toEqual(1)
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
describe('#readInt16BE', () => {
|
|
96
|
+
it('should return 1', () => {
|
|
97
|
+
const buf = Buffer.alloc(2)
|
|
98
|
+
buf.writeInt16BE(1, 0)
|
|
99
|
+
const br = new ReaderUint8Array([...buf])
|
|
100
|
+
expect(br.readInt16BE()).toEqual(1)
|
|
101
|
+
const bufNegative = Buffer.from('ffff', 'hex')
|
|
102
|
+
const brNegative = new ReaderUint8Array([...bufNegative])
|
|
103
|
+
expect(brNegative.readInt8()).toEqual(-1)
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
describe('#readUInt16LE', () => {
|
|
108
|
+
it('should return 1', () => {
|
|
109
|
+
const buf = Buffer.alloc(2)
|
|
110
|
+
buf.writeUInt16LE(1, 0)
|
|
111
|
+
const br = new ReaderUint8Array([...buf])
|
|
112
|
+
expect(br.readUInt16LE()).toEqual(1)
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
describe('#readInt16LE', () => {
|
|
117
|
+
it('should return 1', () => {
|
|
118
|
+
const buf = Buffer.alloc(2)
|
|
119
|
+
buf.writeInt16LE(1, 0)
|
|
120
|
+
const br = new ReaderUint8Array([...buf])
|
|
121
|
+
expect(br.readInt16LE()).toEqual(1)
|
|
122
|
+
const bufNegative = Buffer.from('ffff', 'hex')
|
|
123
|
+
const brNegative = new ReaderUint8Array([...bufNegative])
|
|
124
|
+
expect(brNegative.readInt8()).toEqual(-1)
|
|
125
|
+
})
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
describe('#readUInt32BE', () => {
|
|
129
|
+
it('should return 1', () => {
|
|
130
|
+
const buf = Buffer.alloc(4)
|
|
131
|
+
buf.writeUInt32BE(1, 0)
|
|
132
|
+
const br = new ReaderUint8Array([...buf])
|
|
133
|
+
expect(br.readUInt32BE()).toEqual(1)
|
|
134
|
+
})
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
describe('#readInt32BE', () => {
|
|
138
|
+
it('should return 1', () => {
|
|
139
|
+
const buf = Buffer.alloc(4)
|
|
140
|
+
buf.writeInt32BE(1, 0)
|
|
141
|
+
const br = new ReaderUint8Array([...buf])
|
|
142
|
+
expect(br.readInt32BE()).toEqual(1)
|
|
143
|
+
const bufNegative = Buffer.from('ffffffff', 'hex')
|
|
144
|
+
const brNegative = new ReaderUint8Array([...bufNegative])
|
|
145
|
+
expect(brNegative.readInt8()).toEqual(-1)
|
|
146
|
+
})
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
describe('#readUInt32LE', () => {
|
|
150
|
+
it('should return 1', () => {
|
|
151
|
+
const buf = Buffer.alloc(4)
|
|
152
|
+
buf.writeUInt32LE(1, 0)
|
|
153
|
+
const br = new ReaderUint8Array([...buf])
|
|
154
|
+
expect(br.readUInt32LE()).toEqual(1)
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
describe('#readInt32LE', () => {
|
|
159
|
+
it('should return 1', () => {
|
|
160
|
+
const buf = Buffer.alloc(4)
|
|
161
|
+
buf.writeInt32LE(1, 0)
|
|
162
|
+
const br = new ReaderUint8Array([...buf])
|
|
163
|
+
expect(br.readInt32LE()).toEqual(1)
|
|
164
|
+
expect(
|
|
165
|
+
new ReaderUint8Array([...Buffer.from('ffffffff', 'hex')]).readInt32LE()
|
|
166
|
+
).toEqual(-1)
|
|
167
|
+
})
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
describe('#readUInt64BEBn', () => {
|
|
171
|
+
it('should return 1', () => {
|
|
172
|
+
const buf = Buffer.alloc(8)
|
|
173
|
+
buf.fill(0)
|
|
174
|
+
buf.writeUInt32BE(1, 4)
|
|
175
|
+
const br = new ReaderUint8Array([...buf])
|
|
176
|
+
expect(br.readUInt64BEBn().toNumber()).toEqual(1)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it('should return 2^64', () => {
|
|
180
|
+
const buf = Buffer.alloc(8)
|
|
181
|
+
buf.fill(0xff)
|
|
182
|
+
const br = new ReaderUint8Array([...buf])
|
|
183
|
+
expect(br.readUInt64BEBn().toHex()).toEqual('ffffffffffffffff')
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
describe('#readUInt64LEBn', () => {
|
|
188
|
+
it('should return 1', () => {
|
|
189
|
+
const buf = Buffer.alloc(8)
|
|
190
|
+
buf.fill(0)
|
|
191
|
+
buf.writeUInt32LE(1, 0)
|
|
192
|
+
const br = new ReaderUint8Array([...buf])
|
|
193
|
+
expect(br.readUInt64LEBn().toNumber()).toEqual(1)
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
it('should return 2^30', () => {
|
|
197
|
+
const buf = Buffer.alloc(8)
|
|
198
|
+
buf.fill(0)
|
|
199
|
+
buf.writeUInt32LE(Math.pow(2, 30), 0)
|
|
200
|
+
const br = new ReaderUint8Array([...buf])
|
|
201
|
+
expect(br.readUInt64LEBn().toNumber()).toEqual(Math.pow(2, 30))
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
it('should return 0', () => {
|
|
205
|
+
const buf = Buffer.alloc(8)
|
|
206
|
+
buf.fill(0)
|
|
207
|
+
const br = new ReaderUint8Array([...buf])
|
|
208
|
+
expect(br.readUInt64LEBn().toNumber()).toEqual(0)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('should return 2^64', () => {
|
|
212
|
+
const buf = Buffer.alloc(8)
|
|
213
|
+
buf.fill(0xff)
|
|
214
|
+
const br = new ReaderUint8Array([...buf])
|
|
215
|
+
expect(br.readUInt64LEBn().toHex()).toEqual('ffffffffffffffff')
|
|
216
|
+
})
|
|
217
|
+
})
|
|
218
|
+
|
|
219
|
+
describe('#readVarInt', () => {
|
|
220
|
+
it('should read a 1 byte varInt', () => {
|
|
221
|
+
const buf = Buffer.from([50])
|
|
222
|
+
const br = new ReaderUint8Array([...buf])
|
|
223
|
+
expect(br.readVarInt().length).toEqual(1)
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
it('should read a 3 byte varInt', () => {
|
|
227
|
+
const buf = Buffer.from([253, 253, 0])
|
|
228
|
+
const br = new ReaderUint8Array([...buf])
|
|
229
|
+
expect(br.readVarInt().length).toEqual(3)
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
it('should read a 5 byte varInt', () => {
|
|
233
|
+
const buf = Buffer.from([254, 0, 0, 0, 0])
|
|
234
|
+
buf.writeUInt32LE(50000, 1)
|
|
235
|
+
const br = new ReaderUint8Array([...buf])
|
|
236
|
+
expect(br.readVarInt().length).toEqual(5)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it('should read a 9 byte varInt', () => {
|
|
240
|
+
const buf = new Writer()
|
|
241
|
+
.writeVarIntBn(new BigNumber(Math.pow(2, 54).toString()))
|
|
242
|
+
.toArray()
|
|
243
|
+
const br = new ReaderUint8Array([...buf])
|
|
244
|
+
expect(br.readVarInt().length).toEqual(9)
|
|
245
|
+
})
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
describe('#readVarIntNum', () => {
|
|
249
|
+
it('should read a 1 byte varInt', () => {
|
|
250
|
+
const buf = Buffer.from([50])
|
|
251
|
+
const br = new ReaderUint8Array([...buf])
|
|
252
|
+
expect(br.readVarIntNum()).toEqual(50)
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
it('should read a 3 byte varInt', () => {
|
|
256
|
+
const buf = Buffer.from([253, 253, 0])
|
|
257
|
+
const br = new ReaderUint8Array([...buf])
|
|
258
|
+
expect(br.readVarIntNum()).toEqual(253)
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
it('should read a 5 byte varInt', () => {
|
|
262
|
+
const buf = Buffer.from([254, 0, 0, 0, 0])
|
|
263
|
+
buf.writeUInt32LE(50000, 1)
|
|
264
|
+
const br = new ReaderUint8Array([...buf])
|
|
265
|
+
expect(br.readVarIntNum()).toEqual(50000)
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
it('should throw an error on a 9 byte varInt over the javascript uint precision limit', () => {
|
|
269
|
+
const buf = new Writer()
|
|
270
|
+
.writeVarIntBn(new BigNumber(Math.pow(2, 54).toString()))
|
|
271
|
+
.toArray()
|
|
272
|
+
const br = new ReaderUint8Array([...buf])
|
|
273
|
+
expect(() => {
|
|
274
|
+
br.readVarIntNum()
|
|
275
|
+
}).toThrow('number too large to retain precision - use readVarIntBn')
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
it('should not throw an error on a 9 byte varInt not over the javascript uint precision limit', () => {
|
|
279
|
+
const buf = new Writer()
|
|
280
|
+
.writeVarIntBn(new BigNumber(Math.pow(2, 53).toString()))
|
|
281
|
+
.toArray()
|
|
282
|
+
const br = new ReaderUint8Array([...buf])
|
|
283
|
+
expect(() => {
|
|
284
|
+
br.readVarIntNum()
|
|
285
|
+
}).not.toThrow('number too large to retain precision - use readVarIntBn')
|
|
286
|
+
})
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
describe('#readVarIntBn', () => {
|
|
290
|
+
it('should read a 1 byte varInt', () => {
|
|
291
|
+
const buf = Buffer.from([50])
|
|
292
|
+
const br = new ReaderUint8Array([...buf])
|
|
293
|
+
expect(br.readVarIntBn().toNumber()).toEqual(50)
|
|
294
|
+
})
|
|
295
|
+
|
|
296
|
+
it('should read a 3 byte varInt', () => {
|
|
297
|
+
const buf = Buffer.from([253, 253, 0])
|
|
298
|
+
const br = new ReaderUint8Array([...buf])
|
|
299
|
+
expect(br.readVarIntBn().toNumber()).toEqual(253)
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
it('should read a 5 byte varInt', () => {
|
|
303
|
+
const buf = Buffer.from([254, 0, 0, 0, 0])
|
|
304
|
+
buf.writeUInt32LE(50000, 1)
|
|
305
|
+
const br = new ReaderUint8Array([...buf])
|
|
306
|
+
expect(br.readVarIntBn().toNumber()).toEqual(50000)
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
it('should read a 9 byte varInt', () => {
|
|
310
|
+
const buf = Buffer.concat([
|
|
311
|
+
Buffer.from([255]),
|
|
312
|
+
Buffer.from('ffffffffffffffff', 'hex')
|
|
313
|
+
])
|
|
314
|
+
const br = new ReaderUint8Array([...buf])
|
|
315
|
+
expect(br.readVarIntBn().toHex()).toEqual('ffffffffffffffff')
|
|
316
|
+
})
|
|
317
|
+
})
|