@btc-vision/transaction 1.2.14 → 1.3.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/browser/_version.d.ts +1 -1
- package/browser/abi/ABICoder.d.ts +0 -1
- package/browser/buffer/BinaryReader.d.ts +22 -21
- package/browser/buffer/BinaryWriter.d.ts +12 -18
- package/browser/index.js +1 -1
- package/browser/keypair/Address.d.ts +1 -0
- package/browser/transaction/browser/BrowserSignerBase.d.ts +1 -1
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/abi/ABICoder.d.ts +0 -1
- package/build/abi/ABICoder.js +0 -4
- package/build/buffer/BinaryReader.d.ts +22 -21
- package/build/buffer/BinaryReader.js +134 -121
- package/build/buffer/BinaryWriter.d.ts +12 -18
- package/build/buffer/BinaryWriter.js +60 -89
- package/build/keypair/Address.d.ts +1 -0
- package/build/keypair/Address.js +3 -0
- package/build/transaction/browser/BrowserSignerBase.d.ts +1 -1
- package/build/transaction/browser/extensions/UnisatSigner.js +1 -1
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/abi/ABICoder.ts +0 -4
- package/src/buffer/BinaryReader.ts +230 -184
- package/src/buffer/BinaryWriter.ts +57 -102
- package/src/keypair/Address.ts +4 -0
- package/src/transaction/browser/BrowserSignerBase.ts +1 -1
- package/src/transaction/browser/extensions/UnisatSigner.ts +1 -1
|
@@ -14,13 +14,13 @@ import { BufferLike, i32, Selector, u16, u32, u8 } from '../utils/types.js';
|
|
|
14
14
|
|
|
15
15
|
export class BinaryReader {
|
|
16
16
|
private buffer: DataView;
|
|
17
|
-
|
|
18
17
|
private currentOffset: i32 = 0;
|
|
19
18
|
|
|
20
19
|
constructor(bytes: BufferLike) {
|
|
21
20
|
this.buffer = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
22
21
|
}
|
|
23
22
|
|
|
23
|
+
// Helpers for comparisons; unchanged
|
|
24
24
|
public static stringCompare(a: string, b: string): number {
|
|
25
25
|
return a.localeCompare(b);
|
|
26
26
|
}
|
|
@@ -39,257 +39,280 @@ export class BinaryReader {
|
|
|
39
39
|
|
|
40
40
|
public setBuffer(bytes: BufferLike): void {
|
|
41
41
|
this.buffer = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
42
|
-
|
|
43
42
|
this.currentOffset = 0;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Reads a single unsigned byte (u8).
|
|
47
|
+
*/
|
|
48
|
+
public readU8(): u8 {
|
|
49
|
+
this.verifyEnd(this.currentOffset + U8_BYTE_LENGTH);
|
|
50
|
+
const value = this.buffer.getUint8(this.currentOffset);
|
|
51
|
+
this.currentOffset += U8_BYTE_LENGTH;
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
49
54
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Reads an unsigned 16-bit integer. By default, big-endian.
|
|
57
|
+
* @param be - Endianness; true means big-endian (the default).
|
|
58
|
+
*/
|
|
59
|
+
public readU16(be: boolean = true): u16 {
|
|
60
|
+
this.verifyEnd(this.currentOffset + U16_BYTE_LENGTH);
|
|
61
|
+
const value = this.buffer.getUint16(this.currentOffset, !be);
|
|
62
|
+
this.currentOffset += U16_BYTE_LENGTH;
|
|
63
|
+
return value;
|
|
64
|
+
}
|
|
53
65
|
|
|
54
|
-
|
|
66
|
+
/**
|
|
67
|
+
* Reads an unsigned 32-bit integer. By default, big-endian.
|
|
68
|
+
* @param be - Endianness; true means big-endian (the default).
|
|
69
|
+
*/
|
|
70
|
+
public readU32(be: boolean = true): u32 {
|
|
71
|
+
this.verifyEnd(this.currentOffset + U32_BYTE_LENGTH);
|
|
72
|
+
const value = this.buffer.getUint32(this.currentOffset, !be);
|
|
73
|
+
this.currentOffset += U32_BYTE_LENGTH;
|
|
74
|
+
return value;
|
|
55
75
|
}
|
|
56
76
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Reads an unsigned 64-bit integer. By default, big-endian.
|
|
79
|
+
* @param be - Endianness; true means big-endian (the default).
|
|
80
|
+
*/
|
|
81
|
+
public readU64(be: boolean = true): bigint {
|
|
82
|
+
this.verifyEnd(this.currentOffset + U64_BYTE_LENGTH);
|
|
83
|
+
const value = this.buffer.getBigUint64(this.currentOffset, !be);
|
|
84
|
+
this.currentOffset += U64_BYTE_LENGTH;
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
60
87
|
|
|
61
|
-
|
|
62
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Reads a 128-bit unsigned integer. By default, read big-endian.
|
|
90
|
+
* @param be - Endianness; true => big-endian (default).
|
|
91
|
+
*/
|
|
92
|
+
public readU128(be: boolean = true): bigint {
|
|
93
|
+
const raw = this.readBytes(U128_BYTE_LENGTH);
|
|
94
|
+
let bytes = raw;
|
|
95
|
+
// If data was written in little-endian, we reverse before interpreting
|
|
96
|
+
if (!be) {
|
|
97
|
+
bytes = this.reverseBytes(raw);
|
|
98
|
+
}
|
|
99
|
+
return BigInt('0x' + this.toHexString(bytes));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Reads a 256-bit unsigned integer. Same approach as readU128.
|
|
104
|
+
* @param be - Endianness; true => big-endian (default).
|
|
105
|
+
*/
|
|
106
|
+
public readU256(be: boolean = true): bigint {
|
|
107
|
+
const raw = this.readBytes(U256_BYTE_LENGTH);
|
|
108
|
+
let bytes = raw;
|
|
109
|
+
if (!be) {
|
|
110
|
+
bytes = this.reverseBytes(raw);
|
|
111
|
+
}
|
|
112
|
+
return BigInt('0x' + this.toHexString(bytes));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Reads a 128-bit signed integer. Interpret the sign bit if big-endian.
|
|
117
|
+
* @param be - Endianness; true => big-endian (default).
|
|
118
|
+
*/
|
|
119
|
+
public readI128(be: boolean = true): bigint {
|
|
120
|
+
const raw = this.readBytes(I128_BYTE_LENGTH);
|
|
121
|
+
let bytes = raw;
|
|
122
|
+
if (!be) {
|
|
123
|
+
bytes = this.reverseBytes(raw);
|
|
63
124
|
}
|
|
64
125
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
public readU128Array(): bigint[] {
|
|
69
|
-
const length = this.readU16();
|
|
70
|
-
const result: bigint[] = new Array<bigint>(length);
|
|
126
|
+
// Construct as a 128-bit two's complement
|
|
127
|
+
let value = BigInt('0x' + this.toHexString(bytes));
|
|
71
128
|
|
|
72
|
-
|
|
73
|
-
|
|
129
|
+
// If the top bit is set (sign bit in big-endian), interpret negative
|
|
130
|
+
const signBitMask = 0x80;
|
|
131
|
+
if (bytes[0] & signBitMask) {
|
|
132
|
+
// (1 << 128)
|
|
133
|
+
const twoTo128 = BigInt(1) << BigInt(128);
|
|
134
|
+
// 2's complement
|
|
135
|
+
value = value - twoTo128;
|
|
74
136
|
}
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
75
139
|
|
|
76
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Read a boolean (u8 != 0).
|
|
142
|
+
*/
|
|
143
|
+
public readBoolean(): boolean {
|
|
144
|
+
return this.readU8() !== 0;
|
|
77
145
|
}
|
|
78
146
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Reads 32 bits
|
|
149
|
+
*/
|
|
150
|
+
public readSelector(): Selector {
|
|
151
|
+
return this.readU32(true);
|
|
152
|
+
}
|
|
82
153
|
|
|
83
|
-
|
|
84
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Reads a raw sequence of bytes (length must be known).
|
|
156
|
+
* If zeroStop = true, stops if we encounter 0x00 early.
|
|
157
|
+
*/
|
|
158
|
+
public readBytes(length: u32, zeroStop: boolean = false): Uint8Array {
|
|
159
|
+
this.verifyEnd(this.currentOffset + length);
|
|
160
|
+
let bytes = new Uint8Array(length);
|
|
161
|
+
|
|
162
|
+
for (let i: u32 = 0; i < length; i++) {
|
|
163
|
+
const b = this.buffer.getUint8(this.currentOffset++);
|
|
164
|
+
if (zeroStop && b === 0) {
|
|
165
|
+
bytes = bytes.subarray(0, i);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
bytes[i] = b;
|
|
85
169
|
}
|
|
170
|
+
return bytes;
|
|
171
|
+
}
|
|
86
172
|
|
|
87
|
-
|
|
173
|
+
/**
|
|
174
|
+
* Reads a string of the given length in raw bytes. By default, do NOT zero-stop
|
|
175
|
+
* (matching how we wrote the raw bytes).
|
|
176
|
+
*/
|
|
177
|
+
public readString(length: u16): string {
|
|
178
|
+
const textDecoder = new TextDecoder();
|
|
179
|
+
const bytes = this.readBytes(length, false);
|
|
180
|
+
return textDecoder.decode(bytes);
|
|
88
181
|
}
|
|
89
182
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Reads a string that was written as [u16 length][raw bytes].
|
|
185
|
+
*/
|
|
186
|
+
public readStringWithLength(be: boolean = true): string {
|
|
187
|
+
const length = this.readU16(be);
|
|
188
|
+
return this.readString(length);
|
|
189
|
+
}
|
|
93
190
|
|
|
94
|
-
|
|
95
|
-
|
|
191
|
+
/**
|
|
192
|
+
* Reads an address.
|
|
193
|
+
*/
|
|
194
|
+
public readAddress(): Address {
|
|
195
|
+
const bytes: u8[] = Array.from(this.readBytes(ADDRESS_BYTE_LENGTH));
|
|
196
|
+
return new Address(bytes);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Reads bytes written as [u32 length][bytes].
|
|
201
|
+
* @param maxLength if > 0, enforces an upper bound
|
|
202
|
+
* @param be
|
|
203
|
+
*/
|
|
204
|
+
public readBytesWithLength(maxLength: number = 0, be: boolean = true): Uint8Array {
|
|
205
|
+
const length = this.readU32(be);
|
|
206
|
+
if (maxLength > 0 && length > maxLength) {
|
|
207
|
+
throw new Error('Data length exceeds maximum length.');
|
|
96
208
|
}
|
|
97
209
|
|
|
98
|
-
return
|
|
210
|
+
return this.readBytes(length);
|
|
99
211
|
}
|
|
100
212
|
|
|
101
|
-
|
|
102
|
-
const length = this.readU16();
|
|
103
|
-
const result: u16[] = new Array<u16>(length);
|
|
213
|
+
// ------------------ Array readers ------------------ //
|
|
104
214
|
|
|
215
|
+
public readAddressArray(be: boolean = true): Address[] {
|
|
216
|
+
const length = this.readU16(be);
|
|
217
|
+
const result: Address[] = new Array<Address>(length);
|
|
105
218
|
for (let i = 0; i < length; i++) {
|
|
106
|
-
result[i] = this.
|
|
219
|
+
result[i] = this.readAddress();
|
|
107
220
|
}
|
|
108
|
-
|
|
109
221
|
return result;
|
|
110
222
|
}
|
|
111
223
|
|
|
112
|
-
public
|
|
113
|
-
const length = this.readU16();
|
|
114
|
-
const result:
|
|
115
|
-
|
|
224
|
+
public readU256Array(be: boolean = true): bigint[] {
|
|
225
|
+
const length = this.readU16(be);
|
|
226
|
+
const result: bigint[] = new Array<bigint>(length);
|
|
116
227
|
for (let i = 0; i < length; i++) {
|
|
117
|
-
result[i] = this.
|
|
228
|
+
result[i] = this.readU256(be);
|
|
118
229
|
}
|
|
119
|
-
|
|
120
230
|
return result;
|
|
121
231
|
}
|
|
122
232
|
|
|
123
|
-
public
|
|
124
|
-
const length = this.readU16();
|
|
125
|
-
const result:
|
|
126
|
-
|
|
233
|
+
public readU128Array(be: boolean = true): bigint[] {
|
|
234
|
+
const length = this.readU16(be);
|
|
235
|
+
const result: bigint[] = new Array<bigint>(length);
|
|
127
236
|
for (let i = 0; i < length; i++) {
|
|
128
|
-
result[i] = this.
|
|
237
|
+
result[i] = this.readU128(be);
|
|
129
238
|
}
|
|
130
|
-
|
|
131
239
|
return result;
|
|
132
240
|
}
|
|
133
241
|
|
|
134
|
-
public
|
|
135
|
-
const length = this.readU16();
|
|
136
|
-
const result:
|
|
137
|
-
|
|
242
|
+
public readU64Array(be: boolean = true): bigint[] {
|
|
243
|
+
const length = this.readU16(be);
|
|
244
|
+
const result: bigint[] = new Array<bigint>(length);
|
|
138
245
|
for (let i = 0; i < length; i++) {
|
|
139
|
-
result[i] = this.
|
|
246
|
+
result[i] = this.readU64(be);
|
|
140
247
|
}
|
|
141
|
-
|
|
142
248
|
return result;
|
|
143
249
|
}
|
|
144
250
|
|
|
145
|
-
public
|
|
146
|
-
const length = this.
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
251
|
+
public readU32Array(be: boolean = true): u32[] {
|
|
252
|
+
const length = this.readU16(be);
|
|
253
|
+
const result: u32[] = new Array<u32>(length);
|
|
254
|
+
for (let i = 0; i < length; i++) {
|
|
255
|
+
result[i] = this.readU32(be);
|
|
150
256
|
}
|
|
151
|
-
|
|
152
|
-
return this.readBytes(length);
|
|
257
|
+
return result;
|
|
153
258
|
}
|
|
154
259
|
|
|
155
|
-
public
|
|
156
|
-
const length = this.
|
|
157
|
-
const result:
|
|
158
|
-
|
|
260
|
+
public readU16Array(be: boolean = true): u16[] {
|
|
261
|
+
const length = this.readU16(be);
|
|
262
|
+
const result: u16[] = new Array<u16>(length);
|
|
159
263
|
for (let i = 0; i < length; i++) {
|
|
160
|
-
result[i] = this.
|
|
264
|
+
result[i] = this.readU16(be);
|
|
161
265
|
}
|
|
162
|
-
|
|
163
266
|
return result;
|
|
164
267
|
}
|
|
165
268
|
|
|
166
|
-
public
|
|
167
|
-
this.
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
public readU16(): u16 {
|
|
176
|
-
this.verifyEnd(this.currentOffset + U16_BYTE_LENGTH);
|
|
177
|
-
|
|
178
|
-
const value = this.buffer.getUint16(this.currentOffset, true);
|
|
179
|
-
this.currentOffset += U16_BYTE_LENGTH;
|
|
180
|
-
|
|
181
|
-
return value;
|
|
269
|
+
public readU8Array(): u8[] {
|
|
270
|
+
const length = this.readU16(true); // by default big-endian
|
|
271
|
+
const result: u8[] = new Array<u8>(length);
|
|
272
|
+
for (let i = 0; i < length; i++) {
|
|
273
|
+
result[i] = this.readU8();
|
|
274
|
+
}
|
|
275
|
+
return result;
|
|
182
276
|
}
|
|
183
277
|
|
|
184
|
-
public
|
|
185
|
-
this.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
return
|
|
278
|
+
public readStringArray(be: boolean = true): string[] {
|
|
279
|
+
const length = this.readU16(be);
|
|
280
|
+
const result: string[] = new Array<string>(length);
|
|
281
|
+
for (let i = 0; i < length; i++) {
|
|
282
|
+
result[i] = this.readStringWithLength(be);
|
|
283
|
+
}
|
|
284
|
+
return result;
|
|
191
285
|
}
|
|
192
286
|
|
|
193
|
-
public
|
|
194
|
-
this.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return
|
|
287
|
+
public readBytesArray(be: boolean = true): Uint8Array[] {
|
|
288
|
+
const length = this.readU16(be);
|
|
289
|
+
const result: Uint8Array[] = new Array<Uint8Array>(length);
|
|
290
|
+
for (let i = 0; i < length; i++) {
|
|
291
|
+
result[i] = this.readBytesWithLength(0, be);
|
|
292
|
+
}
|
|
293
|
+
return result;
|
|
200
294
|
}
|
|
201
295
|
|
|
202
|
-
|
|
203
|
-
|
|
296
|
+
/**
|
|
297
|
+
* Reads [u16 length][ (address, u256) pairs ].
|
|
298
|
+
*/
|
|
299
|
+
public readAddressValueTuple(be: boolean = true): AddressMap<bigint> {
|
|
300
|
+
const length = this.readU16(be);
|
|
204
301
|
const result = new AddressMap<bigint>();
|
|
205
302
|
|
|
206
303
|
for (let i = 0; i < length; i++) {
|
|
207
304
|
const address = this.readAddress();
|
|
208
|
-
const value = this.readU256();
|
|
209
|
-
|
|
210
|
-
if (result.has(address)) throw new Error('Duplicate address found in map');
|
|
305
|
+
const value = this.readU256(be);
|
|
211
306
|
|
|
307
|
+
if (result.has(address)) {
|
|
308
|
+
throw new Error('Duplicate address found in map');
|
|
309
|
+
}
|
|
212
310
|
result.set(address, value);
|
|
213
311
|
}
|
|
214
|
-
|
|
215
312
|
return result;
|
|
216
313
|
}
|
|
217
314
|
|
|
218
|
-
|
|
219
|
-
const next16Bytes = this.readBytes(U128_BYTE_LENGTH);
|
|
220
|
-
|
|
221
|
-
return BigInt(
|
|
222
|
-
'0x' + next16Bytes.reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), ''),
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
public readU256(): bigint {
|
|
227
|
-
const next32Bytes = this.readBytes(U256_BYTE_LENGTH);
|
|
228
|
-
|
|
229
|
-
return BigInt(
|
|
230
|
-
'0x' + next32Bytes.reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), ''),
|
|
231
|
-
);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
readI128() {
|
|
235
|
-
const next16Bytes = this.readBytes(I128_BYTE_LENGTH);
|
|
236
|
-
let value = BigInt(
|
|
237
|
-
'0x' + next16Bytes.reduce((acc, byte) => acc + byte.toString(16).padStart(2, '0'), ''),
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
if (next16Bytes[0] & 0x80) {
|
|
241
|
-
const mask = (BigInt(1) << BigInt(128)) - BigInt(1);
|
|
242
|
-
value = (value ^ mask) + BigInt(1);
|
|
243
|
-
value = -value;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
return value;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
public readBytes(length: u32, zeroStop: boolean = false): Uint8Array {
|
|
250
|
-
let bytes: Uint8Array = new Uint8Array(length);
|
|
251
|
-
for (let i: u32 = 0; i < length; i++) {
|
|
252
|
-
const byte: u8 = this.readU8();
|
|
253
|
-
if (zeroStop && byte === 0) {
|
|
254
|
-
bytes = bytes.slice(0, i);
|
|
255
|
-
break;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
bytes[i] = byte;
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
return bytes;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
public readString(length: u16): string {
|
|
265
|
-
const textDecoder = new TextDecoder();
|
|
266
|
-
const bytes = this.readBytes(length, true);
|
|
267
|
-
|
|
268
|
-
return textDecoder.decode(bytes);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
public readSelector(): Selector {
|
|
272
|
-
return this.readU32(false);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
public readStringWithLength(): string {
|
|
276
|
-
const length = this.readU16();
|
|
277
|
-
|
|
278
|
-
return this.readString(length);
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
public readBoolean(): boolean {
|
|
282
|
-
return this.readU8() !== 0;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
public readAddress(): Address {
|
|
286
|
-
const bytes: u8[] = new Array<u8>(ADDRESS_BYTE_LENGTH);
|
|
287
|
-
for (let i: u32 = 0; i < ADDRESS_BYTE_LENGTH; i++) {
|
|
288
|
-
bytes[i] = this.readU8();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
return new Address(bytes);
|
|
292
|
-
}
|
|
315
|
+
// --------------------------------------------------- //
|
|
293
316
|
|
|
294
317
|
public getOffset(): u16 {
|
|
295
318
|
return this.currentOffset;
|
|
@@ -299,9 +322,32 @@ export class BinaryReader {
|
|
|
299
322
|
this.currentOffset = offset;
|
|
300
323
|
}
|
|
301
324
|
|
|
325
|
+
/**
|
|
326
|
+
* Verifies we have enough bytes in the buffer to read up to `size`.
|
|
327
|
+
*/
|
|
302
328
|
public verifyEnd(size: i32): void {
|
|
303
|
-
if (
|
|
304
|
-
throw new Error(
|
|
329
|
+
if (size > this.buffer.byteLength) {
|
|
330
|
+
throw new Error(
|
|
331
|
+
`Attempt to read beyond buffer length: requested up to byte offset ${size}, but buffer is only ${this.buffer.byteLength} bytes.`,
|
|
332
|
+
);
|
|
305
333
|
}
|
|
306
334
|
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Utility: reverses a byte array in-place or returns a reversed copy.
|
|
338
|
+
*/
|
|
339
|
+
private reverseBytes(bytes: Uint8Array): Uint8Array {
|
|
340
|
+
const out = new Uint8Array(bytes.length);
|
|
341
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
342
|
+
out[i] = bytes[bytes.length - 1 - i];
|
|
343
|
+
}
|
|
344
|
+
return out;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Utility: turn bytes into a hex string without `0x` prefix.
|
|
349
|
+
*/
|
|
350
|
+
private toHexString(bytes: Uint8Array): string {
|
|
351
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
352
|
+
}
|
|
307
353
|
}
|