@btc-vision/transaction 1.7.31 → 1.8.0-alpha.2
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/AUDIT/README.md +9 -0
- package/CHANGELOG.md +5 -0
- package/README.md +62 -18
- package/SECURITY.md +71 -0
- package/browser/_version.d.ts +1 -1
- package/browser/abi/ABICoder.d.ts +8 -0
- package/browser/buffer/BinaryReader.d.ts +16 -1
- package/browser/buffer/BinaryWriter.d.ts +11 -1
- package/browser/deterministic/ExtendedAddressMap.d.ts +19 -0
- package/browser/index.js +1201 -874
- package/browser/keypair/Address.d.ts +4 -1
- package/browser/mnemonic/Mnemonic.d.ts +1 -1
- package/browser/noble-curves.js +1087 -1116
- package/browser/noble-hashes.js +25 -25
- package/browser/opnet.d.ts +1 -0
- package/browser/transaction/browser/WalletNetworks.d.ts +3 -3
- package/browser/transaction/browser/types/Unisat.d.ts +2 -2
- package/browser/utils/lengths.d.ts +3 -1
- package/browser/utils/types.d.ts +3 -0
- package/browser/vendors.js +950 -911
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/abi/ABICoder.d.ts +8 -0
- package/build/abi/ABICoder.js +32 -0
- package/build/buffer/BinaryReader.d.ts +16 -1
- package/build/buffer/BinaryReader.js +66 -1
- package/build/buffer/BinaryWriter.d.ts +11 -1
- package/build/buffer/BinaryWriter.js +66 -1
- package/build/deterministic/ExtendedAddressMap.d.ts +19 -0
- package/build/deterministic/ExtendedAddressMap.js +87 -0
- package/build/keypair/Address.d.ts +4 -1
- package/build/keypair/Address.js +48 -13
- package/build/mnemonic/Mnemonic.d.ts +1 -1
- package/build/mnemonic/Mnemonic.js +2 -2
- package/build/opnet.d.ts +1 -0
- package/build/opnet.js +1 -0
- package/build/transaction/browser/WalletNetworks.d.ts +3 -3
- package/build/transaction/browser/WalletNetworks.js +3 -3
- package/build/transaction/browser/extensions/UnisatSigner.js +3 -3
- package/build/transaction/browser/types/Unisat.d.ts +2 -2
- package/build/transaction/builders/MultiSignTransaction.js +2 -2
- package/build/transaction/shared/TweakedTransaction.js +3 -3
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/build/utils/lengths.d.ts +3 -1
- package/build/utils/lengths.js +3 -1
- package/build/utils/types.d.ts +3 -0
- package/package.json +13 -13
- package/src/_version.ts +1 -1
- package/src/abi/ABICoder.ts +43 -0
- package/src/buffer/BinaryReader.ts +158 -2
- package/src/buffer/BinaryWriter.ts +143 -1
- package/src/deterministic/ExtendedAddressMap.ts +122 -0
- package/src/keypair/Address.ts +79 -14
- package/src/mnemonic/Mnemonic.ts +2 -2
- package/src/opnet.ts +1 -0
- package/src/transaction/browser/WalletNetworks.ts +3 -3
- package/src/transaction/browser/extensions/UnisatSigner.ts +3 -3
- package/src/transaction/browser/types/Unisat.ts +2 -2
- package/src/transaction/builders/MultiSignTransaction.ts +2 -2
- package/src/transaction/shared/TweakedTransaction.ts +3 -3
- package/src/utils/lengths.ts +3 -1
- package/src/utils/types.ts +4 -1
- package/test/binary-reader-writer.test.ts +457 -0
- package/test/derivePath.test.ts +26 -25
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { Address, BinaryReader, BinaryWriter, ExtendedAddressMap } from '../src/opnet.js';
|
|
3
|
+
|
|
4
|
+
describe('BinaryReader/BinaryWriter', () => {
|
|
5
|
+
// Helper to create an Address with both MLDSA and tweaked keys
|
|
6
|
+
const createFullAddress = (mldsaValue: bigint, tweakedValue: bigint): Address => {
|
|
7
|
+
return Address.fromBigInt(mldsaValue, tweakedValue);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
describe('Signed Integer Methods', () => {
|
|
11
|
+
describe('i8', () => {
|
|
12
|
+
it('should write and read positive i8', () => {
|
|
13
|
+
const writer = new BinaryWriter();
|
|
14
|
+
writer.writeI8(127);
|
|
15
|
+
writer.writeI8(0);
|
|
16
|
+
writer.writeI8(1);
|
|
17
|
+
|
|
18
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
19
|
+
expect(reader.readI8()).toBe(127);
|
|
20
|
+
expect(reader.readI8()).toBe(0);
|
|
21
|
+
expect(reader.readI8()).toBe(1);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should write and read negative i8', () => {
|
|
25
|
+
const writer = new BinaryWriter();
|
|
26
|
+
writer.writeI8(-128);
|
|
27
|
+
writer.writeI8(-1);
|
|
28
|
+
writer.writeI8(-50);
|
|
29
|
+
|
|
30
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
31
|
+
expect(reader.readI8()).toBe(-128);
|
|
32
|
+
expect(reader.readI8()).toBe(-1);
|
|
33
|
+
expect(reader.readI8()).toBe(-50);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should throw on out of range i8', () => {
|
|
37
|
+
const writer = new BinaryWriter();
|
|
38
|
+
expect(() => writer.writeI8(128)).toThrow();
|
|
39
|
+
expect(() => writer.writeI8(-129)).toThrow();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('i16', () => {
|
|
44
|
+
it('should write and read positive i16 big-endian', () => {
|
|
45
|
+
const writer = new BinaryWriter();
|
|
46
|
+
writer.writeI16(32767);
|
|
47
|
+
writer.writeI16(256);
|
|
48
|
+
writer.writeI16(0);
|
|
49
|
+
|
|
50
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
51
|
+
expect(reader.readI16()).toBe(32767);
|
|
52
|
+
expect(reader.readI16()).toBe(256);
|
|
53
|
+
expect(reader.readI16()).toBe(0);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should write and read negative i16 big-endian', () => {
|
|
57
|
+
const writer = new BinaryWriter();
|
|
58
|
+
writer.writeI16(-32768);
|
|
59
|
+
writer.writeI16(-1);
|
|
60
|
+
writer.writeI16(-256);
|
|
61
|
+
|
|
62
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
63
|
+
expect(reader.readI16()).toBe(-32768);
|
|
64
|
+
expect(reader.readI16()).toBe(-1);
|
|
65
|
+
expect(reader.readI16()).toBe(-256);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should write and read i16 little-endian', () => {
|
|
69
|
+
const writer = new BinaryWriter();
|
|
70
|
+
writer.writeI16(12345, false);
|
|
71
|
+
writer.writeI16(-12345, false);
|
|
72
|
+
|
|
73
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
74
|
+
expect(reader.readI16(false)).toBe(12345);
|
|
75
|
+
expect(reader.readI16(false)).toBe(-12345);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should throw on out of range i16', () => {
|
|
79
|
+
const writer = new BinaryWriter();
|
|
80
|
+
expect(() => writer.writeI16(32768)).toThrow();
|
|
81
|
+
expect(() => writer.writeI16(-32769)).toThrow();
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('i32', () => {
|
|
86
|
+
it('should write and read positive i32 big-endian', () => {
|
|
87
|
+
const writer = new BinaryWriter();
|
|
88
|
+
writer.writeI32(2147483647);
|
|
89
|
+
writer.writeI32(65536);
|
|
90
|
+
writer.writeI32(0);
|
|
91
|
+
|
|
92
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
93
|
+
expect(reader.readI32()).toBe(2147483647);
|
|
94
|
+
expect(reader.readI32()).toBe(65536);
|
|
95
|
+
expect(reader.readI32()).toBe(0);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should write and read negative i32 big-endian', () => {
|
|
99
|
+
const writer = new BinaryWriter();
|
|
100
|
+
writer.writeI32(-2147483648);
|
|
101
|
+
writer.writeI32(-1);
|
|
102
|
+
writer.writeI32(-65536);
|
|
103
|
+
|
|
104
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
105
|
+
expect(reader.readI32()).toBe(-2147483648);
|
|
106
|
+
expect(reader.readI32()).toBe(-1);
|
|
107
|
+
expect(reader.readI32()).toBe(-65536);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should write and read i32 little-endian', () => {
|
|
111
|
+
const writer = new BinaryWriter();
|
|
112
|
+
writer.writeI32(123456789, false);
|
|
113
|
+
writer.writeI32(-123456789, false);
|
|
114
|
+
|
|
115
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
116
|
+
expect(reader.readI32(false)).toBe(123456789);
|
|
117
|
+
expect(reader.readI32(false)).toBe(-123456789);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should throw on out of range i32', () => {
|
|
121
|
+
const writer = new BinaryWriter();
|
|
122
|
+
expect(() => writer.writeI32(2147483648)).toThrow();
|
|
123
|
+
expect(() => writer.writeI32(-2147483649)).toThrow();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('i64', () => {
|
|
128
|
+
it('should write and read positive i64 big-endian', () => {
|
|
129
|
+
const writer = new BinaryWriter();
|
|
130
|
+
writer.writeI64(9223372036854775807n);
|
|
131
|
+
writer.writeI64(4294967296n);
|
|
132
|
+
writer.writeI64(0n);
|
|
133
|
+
|
|
134
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
135
|
+
expect(reader.readI64()).toBe(9223372036854775807n);
|
|
136
|
+
expect(reader.readI64()).toBe(4294967296n);
|
|
137
|
+
expect(reader.readI64()).toBe(0n);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should write and read negative i64 big-endian', () => {
|
|
141
|
+
const writer = new BinaryWriter();
|
|
142
|
+
writer.writeI64(-9223372036854775808n);
|
|
143
|
+
writer.writeI64(-1n);
|
|
144
|
+
writer.writeI64(-4294967296n);
|
|
145
|
+
|
|
146
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
147
|
+
expect(reader.readI64()).toBe(-9223372036854775808n);
|
|
148
|
+
expect(reader.readI64()).toBe(-1n);
|
|
149
|
+
expect(reader.readI64()).toBe(-4294967296n);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should write and read i64 little-endian', () => {
|
|
153
|
+
const writer = new BinaryWriter();
|
|
154
|
+
writer.writeI64(1234567890123456789n, false);
|
|
155
|
+
writer.writeI64(-1234567890123456789n, false);
|
|
156
|
+
|
|
157
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
158
|
+
expect(reader.readI64(false)).toBe(1234567890123456789n);
|
|
159
|
+
expect(reader.readI64(false)).toBe(-1234567890123456789n);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should throw on out of range i64', () => {
|
|
163
|
+
const writer = new BinaryWriter();
|
|
164
|
+
expect(() => writer.writeI64(9223372036854775808n)).toThrow();
|
|
165
|
+
expect(() => writer.writeI64(-9223372036854775809n)).toThrow();
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
describe('Extended Address Methods', () => {
|
|
171
|
+
describe('readExtendedAddress / writeExtendedAddress', () => {
|
|
172
|
+
it('should write and read extended address', () => {
|
|
173
|
+
const writer = new BinaryWriter();
|
|
174
|
+
const address = createFullAddress(123n, 456n);
|
|
175
|
+
|
|
176
|
+
writer.writeExtendedAddress(address);
|
|
177
|
+
|
|
178
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
179
|
+
const result = reader.readExtendedAddress();
|
|
180
|
+
|
|
181
|
+
expect(result.toBigInt()).toBe(123n);
|
|
182
|
+
expect(result.tweakedToBigInt()).toBe(456n);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it('should write and read multiple extended addresses', () => {
|
|
186
|
+
const writer = new BinaryWriter();
|
|
187
|
+
const addr1 = createFullAddress(100n, 200n);
|
|
188
|
+
const addr2 = createFullAddress(300n, 400n);
|
|
189
|
+
const addr3 = createFullAddress(500n, 600n);
|
|
190
|
+
|
|
191
|
+
writer.writeExtendedAddress(addr1);
|
|
192
|
+
writer.writeExtendedAddress(addr2);
|
|
193
|
+
writer.writeExtendedAddress(addr3);
|
|
194
|
+
|
|
195
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
196
|
+
|
|
197
|
+
const result1 = reader.readExtendedAddress();
|
|
198
|
+
expect(result1.toBigInt()).toBe(100n);
|
|
199
|
+
expect(result1.tweakedToBigInt()).toBe(200n);
|
|
200
|
+
|
|
201
|
+
const result2 = reader.readExtendedAddress();
|
|
202
|
+
expect(result2.toBigInt()).toBe(300n);
|
|
203
|
+
expect(result2.tweakedToBigInt()).toBe(400n);
|
|
204
|
+
|
|
205
|
+
const result3 = reader.readExtendedAddress();
|
|
206
|
+
expect(result3.toBigInt()).toBe(500n);
|
|
207
|
+
expect(result3.tweakedToBigInt()).toBe(600n);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('should handle zero addresses', () => {
|
|
211
|
+
const writer = new BinaryWriter();
|
|
212
|
+
const address = createFullAddress(0n, 0n);
|
|
213
|
+
|
|
214
|
+
writer.writeExtendedAddress(address);
|
|
215
|
+
|
|
216
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
217
|
+
const result = reader.readExtendedAddress();
|
|
218
|
+
|
|
219
|
+
expect(result.toBigInt()).toBe(0n);
|
|
220
|
+
expect(result.tweakedToBigInt()).toBe(0n);
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('should handle max value addresses', () => {
|
|
224
|
+
const writer = new BinaryWriter();
|
|
225
|
+
const maxValue = 2n ** 256n - 1n;
|
|
226
|
+
const address = createFullAddress(maxValue, maxValue);
|
|
227
|
+
|
|
228
|
+
writer.writeExtendedAddress(address);
|
|
229
|
+
|
|
230
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
231
|
+
const result = reader.readExtendedAddress();
|
|
232
|
+
|
|
233
|
+
expect(result.toBigInt()).toBe(maxValue);
|
|
234
|
+
expect(result.tweakedToBigInt()).toBe(maxValue);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
describe('readExtendedAddressArray / writeExtendedAddressArray', () => {
|
|
239
|
+
it('should write and read empty array', () => {
|
|
240
|
+
const writer = new BinaryWriter();
|
|
241
|
+
writer.writeExtendedAddressArray([]);
|
|
242
|
+
|
|
243
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
244
|
+
const result = reader.readExtendedAddressArray();
|
|
245
|
+
|
|
246
|
+
expect(result).toEqual([]);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('should write and read array of extended addresses', () => {
|
|
250
|
+
const writer = new BinaryWriter();
|
|
251
|
+
const addresses = [
|
|
252
|
+
createFullAddress(1n, 2n),
|
|
253
|
+
createFullAddress(3n, 4n),
|
|
254
|
+
createFullAddress(5n, 6n),
|
|
255
|
+
];
|
|
256
|
+
|
|
257
|
+
writer.writeExtendedAddressArray(addresses);
|
|
258
|
+
|
|
259
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
260
|
+
const result = reader.readExtendedAddressArray();
|
|
261
|
+
|
|
262
|
+
expect(result.length).toBe(3);
|
|
263
|
+
expect(result[0].toBigInt()).toBe(1n);
|
|
264
|
+
expect(result[0].tweakedToBigInt()).toBe(2n);
|
|
265
|
+
expect(result[1].toBigInt()).toBe(3n);
|
|
266
|
+
expect(result[1].tweakedToBigInt()).toBe(4n);
|
|
267
|
+
expect(result[2].toBigInt()).toBe(5n);
|
|
268
|
+
expect(result[2].tweakedToBigInt()).toBe(6n);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('should handle large arrays', () => {
|
|
272
|
+
const writer = new BinaryWriter();
|
|
273
|
+
const addresses: Address[] = [];
|
|
274
|
+
for (let i = 0; i < 100; i++) {
|
|
275
|
+
addresses.push(createFullAddress(BigInt(i), BigInt(i * 2)));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
writer.writeExtendedAddressArray(addresses);
|
|
279
|
+
|
|
280
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
281
|
+
const result = reader.readExtendedAddressArray();
|
|
282
|
+
|
|
283
|
+
expect(result.length).toBe(100);
|
|
284
|
+
for (let i = 0; i < 100; i++) {
|
|
285
|
+
expect(result[i].toBigInt()).toBe(BigInt(i));
|
|
286
|
+
expect(result[i].tweakedToBigInt()).toBe(BigInt(i * 2));
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
describe('ExtendedAddressMapU256 Methods', () => {
|
|
293
|
+
describe('readExtendedAddressMapU256 / writeExtendedAddressMapU256', () => {
|
|
294
|
+
it('should write and read empty map', () => {
|
|
295
|
+
const writer = new BinaryWriter();
|
|
296
|
+
const map = new ExtendedAddressMap<bigint>();
|
|
297
|
+
|
|
298
|
+
writer.writeExtendedAddressMapU256(map);
|
|
299
|
+
|
|
300
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
301
|
+
const result = reader.readExtendedAddressMapU256();
|
|
302
|
+
|
|
303
|
+
expect(result.size).toBe(0);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('should write and read map with entries', () => {
|
|
307
|
+
const writer = new BinaryWriter();
|
|
308
|
+
const map = new ExtendedAddressMap<bigint>();
|
|
309
|
+
|
|
310
|
+
const addr1 = createFullAddress(100n, 200n);
|
|
311
|
+
const addr2 = createFullAddress(300n, 400n);
|
|
312
|
+
|
|
313
|
+
map.set(addr1, 1000n);
|
|
314
|
+
map.set(addr2, 2000n);
|
|
315
|
+
|
|
316
|
+
writer.writeExtendedAddressMapU256(map);
|
|
317
|
+
|
|
318
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
319
|
+
const result = reader.readExtendedAddressMapU256();
|
|
320
|
+
|
|
321
|
+
expect(result.size).toBe(2);
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
it('should handle large u256 values', () => {
|
|
325
|
+
const writer = new BinaryWriter();
|
|
326
|
+
const map = new ExtendedAddressMap<bigint>();
|
|
327
|
+
|
|
328
|
+
const addr = createFullAddress(1n, 2n);
|
|
329
|
+
const largeValue = 2n ** 256n - 1n;
|
|
330
|
+
|
|
331
|
+
map.set(addr, largeValue);
|
|
332
|
+
|
|
333
|
+
writer.writeExtendedAddressMapU256(map);
|
|
334
|
+
|
|
335
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
336
|
+
const result = reader.readExtendedAddressMapU256();
|
|
337
|
+
|
|
338
|
+
expect(result.size).toBe(1);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
describe('Schnorr Signature Methods', () => {
|
|
344
|
+
describe('readSchnorrSignature / writeSchnorrSignature', () => {
|
|
345
|
+
it('should write and read Schnorr signature', () => {
|
|
346
|
+
const writer = new BinaryWriter();
|
|
347
|
+
const address = createFullAddress(12345n, 67890n);
|
|
348
|
+
const signature = new Uint8Array(64);
|
|
349
|
+
for (let i = 0; i < 64; i++) {
|
|
350
|
+
signature[i] = i;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
writer.writeSchnorrSignature(address, signature);
|
|
354
|
+
|
|
355
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
356
|
+
const result = reader.readSchnorrSignature();
|
|
357
|
+
|
|
358
|
+
expect(result.address.toBigInt()).toBe(12345n);
|
|
359
|
+
expect(result.address.tweakedToBigInt()).toBe(67890n);
|
|
360
|
+
expect(result.signature.length).toBe(64);
|
|
361
|
+
for (let i = 0; i < 64; i++) {
|
|
362
|
+
expect(result.signature[i]).toBe(i);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
it('should throw on invalid signature length', () => {
|
|
367
|
+
const writer = new BinaryWriter();
|
|
368
|
+
const address = createFullAddress(1n, 2n);
|
|
369
|
+
const invalidSignature = new Uint8Array(32); // Should be 64
|
|
370
|
+
|
|
371
|
+
expect(() => writer.writeSchnorrSignature(address, invalidSignature)).toThrow();
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it('should handle multiple signatures', () => {
|
|
375
|
+
const writer = new BinaryWriter();
|
|
376
|
+
|
|
377
|
+
const sig1 = new Uint8Array(64).fill(1);
|
|
378
|
+
const sig2 = new Uint8Array(64).fill(2);
|
|
379
|
+
|
|
380
|
+
writer.writeSchnorrSignature(createFullAddress(1n, 2n), sig1);
|
|
381
|
+
writer.writeSchnorrSignature(createFullAddress(3n, 4n), sig2);
|
|
382
|
+
|
|
383
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
384
|
+
|
|
385
|
+
const result1 = reader.readSchnorrSignature();
|
|
386
|
+
expect(result1.address.toBigInt()).toBe(1n);
|
|
387
|
+
expect(result1.signature[0]).toBe(1);
|
|
388
|
+
|
|
389
|
+
const result2 = reader.readSchnorrSignature();
|
|
390
|
+
expect(result2.address.toBigInt()).toBe(3n);
|
|
391
|
+
expect(result2.signature[0]).toBe(2);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
describe('Mixed Operations', () => {
|
|
397
|
+
it('should handle mixed data types in sequence', () => {
|
|
398
|
+
const writer = new BinaryWriter();
|
|
399
|
+
|
|
400
|
+
// Write various types
|
|
401
|
+
writer.writeI8(-50);
|
|
402
|
+
writer.writeI16(-1000);
|
|
403
|
+
writer.writeI32(-100000);
|
|
404
|
+
writer.writeI64(-10000000000n);
|
|
405
|
+
writer.writeExtendedAddress(createFullAddress(111n, 222n));
|
|
406
|
+
writer.writeU256(999n);
|
|
407
|
+
|
|
408
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
409
|
+
|
|
410
|
+
expect(reader.readI8()).toBe(-50);
|
|
411
|
+
expect(reader.readI16()).toBe(-1000);
|
|
412
|
+
expect(reader.readI32()).toBe(-100000);
|
|
413
|
+
expect(reader.readI64()).toBe(-10000000000n);
|
|
414
|
+
|
|
415
|
+
const addr = reader.readExtendedAddress();
|
|
416
|
+
expect(addr.toBigInt()).toBe(111n);
|
|
417
|
+
expect(addr.tweakedToBigInt()).toBe(222n);
|
|
418
|
+
|
|
419
|
+
expect(reader.readU256()).toBe(999n);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('should correctly track buffer position', () => {
|
|
423
|
+
const writer = new BinaryWriter();
|
|
424
|
+
|
|
425
|
+
writer.writeI8(1);
|
|
426
|
+
writer.writeI16(2);
|
|
427
|
+
writer.writeI32(3);
|
|
428
|
+
writer.writeI64(4n);
|
|
429
|
+
writer.writeExtendedAddress(createFullAddress(5n, 6n));
|
|
430
|
+
|
|
431
|
+
const buffer = writer.getBuffer();
|
|
432
|
+
// i8: 1 byte, i16: 2 bytes, i32: 4 bytes, i64: 8 bytes, extended address: 64 bytes
|
|
433
|
+
expect(buffer.length).toBe(1 + 2 + 4 + 8 + 64);
|
|
434
|
+
});
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
describe('Error Handling', () => {
|
|
438
|
+
it('should throw when reading beyond buffer', () => {
|
|
439
|
+
const writer = new BinaryWriter();
|
|
440
|
+
writer.writeI8(1);
|
|
441
|
+
|
|
442
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
443
|
+
reader.readI8();
|
|
444
|
+
|
|
445
|
+
expect(() => reader.readI8()).toThrow();
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
it('should throw when reading extended address from insufficient buffer', () => {
|
|
449
|
+
const writer = new BinaryWriter();
|
|
450
|
+
writer.writeU256(1n); // Only 32 bytes
|
|
451
|
+
|
|
452
|
+
const reader = new BinaryReader(writer.getBuffer());
|
|
453
|
+
|
|
454
|
+
expect(() => reader.readExtendedAddress()).toThrow();
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
});
|
package/test/derivePath.test.ts
CHANGED
|
@@ -233,10 +233,11 @@ describe('Wallet.derivePath', () => {
|
|
|
233
233
|
});
|
|
234
234
|
});
|
|
235
235
|
|
|
236
|
-
describe('Mnemonic.
|
|
236
|
+
describe('Mnemonic.deriveOPWallet', () => {
|
|
237
237
|
const testMnemonic =
|
|
238
238
|
'episode frost someone page color giraffe match vanish sheriff veteran hub year pull save dizzy limb already turn reopen truth cradle rural wisdom change';
|
|
239
|
-
const unisatExpectedAddress =
|
|
239
|
+
const unisatExpectedAddress =
|
|
240
|
+
'bcrt1phn6ej9ct038j722wdzkvsk7c6pmugtd5d3qnpwxc8g40zerf2ujs55tkz3';
|
|
240
241
|
|
|
241
242
|
describe('P2TR (Taproot) derivation', () => {
|
|
242
243
|
it('should match Unisat P2TR address for regtest', () => {
|
|
@@ -247,7 +248,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
247
248
|
MLDSASecurityLevel.LEVEL2,
|
|
248
249
|
);
|
|
249
250
|
|
|
250
|
-
const wallet = mnemonic.
|
|
251
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0, 0, false);
|
|
251
252
|
|
|
252
253
|
expect(wallet.p2tr).toBe(unisatExpectedAddress);
|
|
253
254
|
});
|
|
@@ -260,7 +261,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
260
261
|
MLDSASecurityLevel.LEVEL2,
|
|
261
262
|
);
|
|
262
263
|
|
|
263
|
-
const wallet = mnemonic.
|
|
264
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0);
|
|
264
265
|
|
|
265
266
|
expect(wallet.p2tr).toMatch(/^bc1p/);
|
|
266
267
|
});
|
|
@@ -273,7 +274,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
273
274
|
MLDSASecurityLevel.LEVEL2,
|
|
274
275
|
);
|
|
275
276
|
|
|
276
|
-
const wallet = mnemonic.
|
|
277
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0);
|
|
277
278
|
|
|
278
279
|
expect(wallet.p2tr).toMatch(/^tb1p/);
|
|
279
280
|
});
|
|
@@ -288,13 +289,13 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
288
289
|
MLDSASecurityLevel.LEVEL2,
|
|
289
290
|
);
|
|
290
291
|
|
|
291
|
-
const wallet = mnemonic.
|
|
292
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2WPKH, 0);
|
|
292
293
|
|
|
293
294
|
expect(wallet.p2wpkh).toBeDefined();
|
|
294
295
|
expect(wallet.p2wpkh).toMatch(/^bc1q/);
|
|
295
296
|
});
|
|
296
297
|
|
|
297
|
-
it(
|
|
298
|
+
it("should use BIP84 path (m/84'/0'/0'/0/0)", () => {
|
|
298
299
|
const mnemonic = new Mnemonic(
|
|
299
300
|
testMnemonic,
|
|
300
301
|
'',
|
|
@@ -302,7 +303,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
302
303
|
MLDSASecurityLevel.LEVEL2,
|
|
303
304
|
);
|
|
304
305
|
|
|
305
|
-
const wallet = mnemonic.
|
|
306
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2WPKH, 0);
|
|
306
307
|
expect(wallet.p2wpkh).toBeDefined();
|
|
307
308
|
});
|
|
308
309
|
});
|
|
@@ -316,7 +317,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
316
317
|
MLDSASecurityLevel.LEVEL2,
|
|
317
318
|
);
|
|
318
319
|
|
|
319
|
-
const wallet = mnemonic.
|
|
320
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2PKH, 0);
|
|
320
321
|
|
|
321
322
|
expect(wallet.legacy).toBeDefined();
|
|
322
323
|
expect(wallet.legacy).toMatch(/^1/);
|
|
@@ -332,9 +333,9 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
332
333
|
MLDSASecurityLevel.LEVEL2,
|
|
333
334
|
);
|
|
334
335
|
|
|
335
|
-
const wallet0 = mnemonic.
|
|
336
|
-
const wallet1 = mnemonic.
|
|
337
|
-
const wallet2 = mnemonic.
|
|
336
|
+
const wallet0 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0);
|
|
337
|
+
const wallet1 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 1);
|
|
338
|
+
const wallet2 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 2);
|
|
338
339
|
|
|
339
340
|
expect(wallet0.p2tr).not.toBe(wallet1.p2tr);
|
|
340
341
|
expect(wallet1.p2tr).not.toBe(wallet2.p2tr);
|
|
@@ -349,8 +350,8 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
349
350
|
MLDSASecurityLevel.LEVEL2,
|
|
350
351
|
);
|
|
351
352
|
|
|
352
|
-
const wallet1 = mnemonic.
|
|
353
|
-
const wallet2 = mnemonic.
|
|
353
|
+
const wallet1 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 5);
|
|
354
|
+
const wallet2 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 5);
|
|
354
355
|
|
|
355
356
|
expect(wallet1.p2tr).toBe(wallet2.p2tr);
|
|
356
357
|
expect(wallet1.toPublicKeyHex()).toBe(wallet2.toPublicKeyHex());
|
|
@@ -366,8 +367,8 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
366
367
|
MLDSASecurityLevel.LEVEL2,
|
|
367
368
|
);
|
|
368
369
|
|
|
369
|
-
const account0 = mnemonic.
|
|
370
|
-
const account1 = mnemonic.
|
|
370
|
+
const account0 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0, 0);
|
|
371
|
+
const account1 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0, 1);
|
|
371
372
|
|
|
372
373
|
expect(account0.p2tr).not.toBe(account1.p2tr);
|
|
373
374
|
});
|
|
@@ -380,8 +381,8 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
380
381
|
MLDSASecurityLevel.LEVEL2,
|
|
381
382
|
);
|
|
382
383
|
|
|
383
|
-
const receiving = mnemonic.
|
|
384
|
-
const change = mnemonic.
|
|
384
|
+
const receiving = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0, 0, false);
|
|
385
|
+
const change = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0, 0, true);
|
|
385
386
|
|
|
386
387
|
expect(receiving.p2tr).not.toBe(change.p2tr);
|
|
387
388
|
});
|
|
@@ -396,7 +397,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
396
397
|
MLDSASecurityLevel.LEVEL2,
|
|
397
398
|
);
|
|
398
399
|
|
|
399
|
-
const wallet = mnemonic.
|
|
400
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0);
|
|
400
401
|
|
|
401
402
|
expect(wallet.quantumPublicKey).toBeDefined();
|
|
402
403
|
expect(wallet.quantumPublicKey.length).toBe(1312); // LEVEL2 size
|
|
@@ -411,8 +412,8 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
411
412
|
MLDSASecurityLevel.LEVEL2,
|
|
412
413
|
);
|
|
413
414
|
|
|
414
|
-
const wallet0 = mnemonic.
|
|
415
|
-
const wallet1 = mnemonic.
|
|
415
|
+
const wallet0 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0);
|
|
416
|
+
const wallet1 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 1);
|
|
416
417
|
|
|
417
418
|
expect(wallet0.address.toHex()).not.toBe(wallet1.address.toHex());
|
|
418
419
|
});
|
|
@@ -459,7 +460,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
459
460
|
);
|
|
460
461
|
|
|
461
462
|
const wallets = mnemonic.deriveMultipleUnisat(AddressTypes.P2TR, 2, 5);
|
|
462
|
-
const wallet5 = mnemonic.
|
|
463
|
+
const wallet5 = mnemonic.deriveOPWallet(AddressTypes.P2TR, 5);
|
|
463
464
|
|
|
464
465
|
expect(wallets[0].p2tr).toBe(wallet5.p2tr);
|
|
465
466
|
});
|
|
@@ -475,7 +476,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
475
476
|
);
|
|
476
477
|
|
|
477
478
|
expect(() => {
|
|
478
|
-
mnemonic.
|
|
479
|
+
mnemonic.deriveOPWallet('INVALID_TYPE' as AddressTypes, 0);
|
|
479
480
|
}).toThrow('Unsupported address type');
|
|
480
481
|
});
|
|
481
482
|
});
|
|
@@ -489,7 +490,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
489
490
|
MLDSASecurityLevel.LEVEL2,
|
|
490
491
|
);
|
|
491
492
|
|
|
492
|
-
const wallet = mnemonic.
|
|
493
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0);
|
|
493
494
|
|
|
494
495
|
expect(wallet.network.bech32).toBe('tb');
|
|
495
496
|
});
|
|
@@ -504,7 +505,7 @@ describe('Mnemonic.deriveUnisat', () => {
|
|
|
504
505
|
MLDSASecurityLevel.LEVEL3,
|
|
505
506
|
);
|
|
506
507
|
|
|
507
|
-
const wallet = mnemonic.
|
|
508
|
+
const wallet = mnemonic.deriveOPWallet(AddressTypes.P2TR, 0);
|
|
508
509
|
|
|
509
510
|
expect(wallet.securityLevel).toBe(MLDSASecurityLevel.LEVEL3);
|
|
510
511
|
expect(wallet.quantumPublicKey.length).toBe(1952); // LEVEL3 size
|