@totemsdk/core 1.0.8 → 1.0.10
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/LICENSE +21 -0
- package/README.md +5 -5
- package/dist/Streamable.js +54 -31
- package/dist/adapters/index.js +18 -8
- package/dist/adapters/types.js +19 -8
- package/dist/binio.js +5 -1
- package/dist/bip39.js +24 -14
- package/dist/derive.js +11 -7
- package/dist/index.js +130 -22
- package/dist/javaStreamables.js +49 -30
- package/dist/lease/LeaseMonitor.js +7 -3
- package/dist/lease/LeaseStore.js +7 -3
- package/dist/lease/WatermarkStore.js +7 -3
- package/dist/lease/index.js +13 -4
- package/dist/lease-client.js +8 -3
- package/dist/minima32.js +22 -13
- package/dist/minimaWireSerializer.js +20 -14
- package/dist/mmr.js +35 -23
- package/dist/mx.js +10 -1
- package/dist/params.js +9 -5
- package/dist/script.js +12 -7
- package/dist/scripts/contract-helpers.js +37 -26
- package/dist/scripts/dapp-types.js +11 -6
- package/dist/scripts/index.js +38 -4
- package/dist/scripts/types.js +26 -12
- package/dist/scripts/witness-serializer.js +48 -30
- package/dist/transaction.js +55 -46
- package/dist/treekey.js +74 -58
- package/dist/tx/TransactionLifecycle.js +11 -5
- package/dist/tx/TransactionReceiptStore.js +7 -3
- package/dist/tx/TransactionService.js +14 -10
- package/dist/tx/index.js +11 -3
- package/dist/tx/types.js +2 -1
- package/dist/util.js +5 -1
- package/dist/utils.js +12 -5
- package/dist/verify.js +36 -25
- package/dist/version.js +5 -2
- package/dist/wots.js +94 -64
- package/package.json +35 -6
- package/src/Streamable.d.ts +0 -265
- package/src/Streamable.js +0 -431
- package/src/Streamable.ts +0 -567
- package/src/__tests__/Streamable.parity.test.ts +0 -422
- package/src/__tests__/perAddressDerivation.parity.test.ts +0 -152
- package/src/__tests__/roottree-prepare.test.ts +0 -101
- package/src/__tests__/wots-parity.test.ts +0 -289
- package/src/adapters/index.d.ts +0 -190
- package/src/adapters/index.js +0 -117
- package/src/adapters/index.ts +0 -301
- package/src/adapters/types.ts +0 -235
- package/src/addr.oracle.test.ts +0 -25
- package/src/address.test.ts +0 -55
- package/src/binio.ts +0 -21
- package/src/bip39.d.ts +0 -91
- package/src/bip39.js +0 -427
- package/src/bip39.ts +0 -432
- package/src/derive.d.ts +0 -2
- package/src/derive.js +0 -13
- package/src/derive.ts +0 -11
- package/src/index.d.ts +0 -26
- package/src/index.js +0 -128
- package/src/index.test.ts +0 -5
- package/src/index.ts +0 -221
- package/src/javaStreamables.d.ts +0 -233
- package/src/javaStreamables.js +0 -328
- package/src/javaStreamables.ts +0 -403
- package/src/lease/LeaseMonitor.d.ts +0 -44
- package/src/lease/LeaseMonitor.js +0 -111
- package/src/lease/LeaseMonitor.ts +0 -157
- package/src/lease/LeaseStore.d.ts +0 -57
- package/src/lease/LeaseStore.js +0 -148
- package/src/lease/LeaseStore.ts +0 -203
- package/src/lease/WatermarkStore.d.ts +0 -61
- package/src/lease/WatermarkStore.js +0 -206
- package/src/lease/WatermarkStore.ts +0 -270
- package/src/lease/index.d.ts +0 -14
- package/src/lease/index.js +0 -22
- package/src/lease/index.ts +0 -41
- package/src/lease-client.d.ts +0 -31
- package/src/lease-client.js +0 -44
- package/src/lease-client.ts +0 -69
- package/src/minima32.d.ts +0 -10
- package/src/minima32.js +0 -113
- package/src/minima32.test.ts +0 -11
- package/src/minima32.ts +0 -127
- package/src/minimaWireSerializer.d.ts +0 -189
- package/src/minimaWireSerializer.js +0 -311
- package/src/minimaWireSerializer.test.ts +0 -466
- package/src/minimaWireSerializer.ts +0 -117
- package/src/mmr.d.ts +0 -159
- package/src/mmr.js +0 -352
- package/src/mmr.oracle.test.ts +0 -28
- package/src/mmr.ts +0 -429
- package/src/mx.test.ts +0 -25
- package/src/mx.ts +0 -1
- package/src/params.d.ts +0 -29
- package/src/params.d.ts.map +0 -1
- package/src/params.js +0 -20
- package/src/params.js.map +0 -1
- package/src/params.ts +0 -44
- package/src/script.d.ts +0 -7
- package/src/script.js +0 -27
- package/src/script.ts +0 -24
- package/src/scripts/contract-helpers.ts +0 -609
- package/src/scripts/dapp-types.ts +0 -240
- package/src/scripts/index.ts +0 -22
- package/src/scripts/types.ts +0 -247
- package/src/scripts/witness-serializer.ts +0 -384
- package/src/transaction.ts +0 -430
- package/src/treekey.d.ts +0 -383
- package/src/treekey.js +0 -774
- package/src/treekey.parity.test.ts +0 -459
- package/src/treekey.ts +0 -975
- package/src/tx/TransactionLifecycle.d.ts +0 -55
- package/src/tx/TransactionLifecycle.js +0 -188
- package/src/tx/TransactionLifecycle.ts +0 -280
- package/src/tx/TransactionReceiptStore.d.ts +0 -36
- package/src/tx/TransactionReceiptStore.js +0 -89
- package/src/tx/TransactionReceiptStore.ts +0 -112
- package/src/tx/TransactionService.d.ts +0 -31
- package/src/tx/TransactionService.js +0 -140
- package/src/tx/TransactionService.ts +0 -252
- package/src/tx/index.d.ts +0 -13
- package/src/tx/index.js +0 -20
- package/src/tx/index.ts +0 -44
- package/src/tx/types.d.ts +0 -80
- package/src/tx/types.js +0 -6
- package/src/tx/types.ts +0 -130
- package/src/util.d.ts +0 -1
- package/src/util.js +0 -5
- package/src/util.ts +0 -1
- package/src/utils.d.ts +0 -8
- package/src/utils.js +0 -42
- package/src/utils.ts +0 -38
- package/src/verify.ts +0 -210
- package/src/version.ts +0 -13
- package/src/wots.d.ts +0 -224
- package/src/wots.d.ts.map +0 -1
- package/src/wots.js +0 -565
- package/src/wots.js.map +0 -1
- package/src/wots.ts +0 -651
- package/test-vectors.json +0 -45
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Streamable.parity.test.ts - Byte-for-Byte Java Parity Tests
|
|
3
|
-
*
|
|
4
|
-
* These tests validate that our TypeScript serialization produces
|
|
5
|
-
* byte-exact output matching Minima's Java implementation.
|
|
6
|
-
*
|
|
7
|
-
* JAVA REFERENCE FILES (from attached_assets):
|
|
8
|
-
* - MiniNumber_1767465037473.java: MiniNumber.writeDataStream()
|
|
9
|
-
* - MiniData_1767465051037.java: MiniData.writeDataStream(), writeHashToStream()
|
|
10
|
-
* - MMRData_1768742834148.java: MMRData.writeDataStream()
|
|
11
|
-
* - MMRProof_1768740810861.java: MMRProof.writeDataStream(), MMRProofChunk.writeDataStream()
|
|
12
|
-
* - SignatureProof_1768848582024.java: SignatureProof.writeDataStream()
|
|
13
|
-
* - Signature_1767887681489.java: Signature.writeDataStream()
|
|
14
|
-
* - Witness_1766887812428.java: Witness.writeDataStream()
|
|
15
|
-
*
|
|
16
|
-
* Created: 2026-01-26
|
|
17
|
-
* Purpose: Gate all serialization changes with Java parity validation
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
// Jest test suite (SDK uses Jest, not Vitest)
|
|
21
|
-
import {
|
|
22
|
-
hexToBytes,
|
|
23
|
-
bytesToHex,
|
|
24
|
-
concat,
|
|
25
|
-
writeMiniByte,
|
|
26
|
-
writeMiniData,
|
|
27
|
-
writeMiniNumber,
|
|
28
|
-
writeHashToStream,
|
|
29
|
-
writeMMREntryNumber,
|
|
30
|
-
bigIntToByteArray,
|
|
31
|
-
writeMMRData,
|
|
32
|
-
writeMMRProofChunk,
|
|
33
|
-
writeMMRProof,
|
|
34
|
-
writeSignatureProof,
|
|
35
|
-
writeSignature,
|
|
36
|
-
writeWitness,
|
|
37
|
-
writeHierarchicalWitness,
|
|
38
|
-
type MMRData,
|
|
39
|
-
type MMRProofChunk,
|
|
40
|
-
type MMRProof,
|
|
41
|
-
type SignatureProof,
|
|
42
|
-
type Signature,
|
|
43
|
-
} from '../Streamable';
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Helper to compare bytes and show diff on failure
|
|
47
|
-
*/
|
|
48
|
-
function expectBytesEqual(actual: Uint8Array, expected: Uint8Array, context: string = '') {
|
|
49
|
-
const actualHex = bytesToHex(actual);
|
|
50
|
-
const expectedHex = bytesToHex(expected);
|
|
51
|
-
if (actualHex !== expectedHex) {
|
|
52
|
-
console.error(`${context} Mismatch:`);
|
|
53
|
-
console.error(` Expected: ${expectedHex} (${expected.length} bytes)`);
|
|
54
|
-
console.error(` Actual: ${actualHex} (${actual.length} bytes)`);
|
|
55
|
-
}
|
|
56
|
-
expect(actualHex).toBe(expectedHex);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
describe('MiniNumber Serialization (Java Parity)', () => {
|
|
60
|
-
/**
|
|
61
|
-
* Java MiniNumber.writeDataStream():
|
|
62
|
-
* 1 byte: scale (signed)
|
|
63
|
-
* 1 byte: length of unscaled BigInteger data
|
|
64
|
-
* N bytes: unscaled BigInteger in two's complement
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
it('MiniNumber(0) → [0x00, 0x01, 0x00]', () => {
|
|
68
|
-
const result = writeMiniNumber(0n, 0);
|
|
69
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x01, 0x00]), 'MiniNumber(0)');
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('MiniNumber(1) → [0x00, 0x01, 0x01]', () => {
|
|
73
|
-
const result = writeMiniNumber(1n, 0);
|
|
74
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x01, 0x01]), 'MiniNumber(1)');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('MiniNumber(127) → [0x00, 0x01, 0x7F]', () => {
|
|
78
|
-
const result = writeMiniNumber(127n, 0);
|
|
79
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x01, 0x7F]), 'MiniNumber(127)');
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('MiniNumber(128) → [0x00, 0x02, 0x00, 0x80] (needs leading zero)', () => {
|
|
83
|
-
const result = writeMiniNumber(128n, 0);
|
|
84
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x02, 0x00, 0x80]), 'MiniNumber(128)');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('MiniNumber(255) → [0x00, 0x02, 0x00, 0xFF]', () => {
|
|
88
|
-
const result = writeMiniNumber(255n, 0);
|
|
89
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x02, 0x00, 0xFF]), 'MiniNumber(255)');
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('MiniNumber(256) → [0x00, 0x02, 0x01, 0x00]', () => {
|
|
93
|
-
const result = writeMiniNumber(256n, 0);
|
|
94
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x02, 0x01, 0x00]), 'MiniNumber(256)');
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('MiniNumber(65535) → [0x00, 0x03, 0x00, 0xFF, 0xFF]', () => {
|
|
98
|
-
const result = writeMiniNumber(65535n, 0);
|
|
99
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x03, 0x00, 0xFF, 0xFF]), 'MiniNumber(65535)');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('MiniNumber with scale=2 (e.g., 123 with 2 decimal places)', () => {
|
|
103
|
-
const result = writeMiniNumber(123n, 2);
|
|
104
|
-
expectBytesEqual(result, new Uint8Array([0x02, 0x01, 0x7B]), 'MiniNumber(123, scale=2)');
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
describe('MiniData Serialization (Java Parity)', () => {
|
|
109
|
-
/**
|
|
110
|
-
* Java MiniData.writeDataStream():
|
|
111
|
-
* 4 bytes: big-endian int length
|
|
112
|
-
* N bytes: raw data
|
|
113
|
-
*/
|
|
114
|
-
|
|
115
|
-
it('Empty MiniData → [0x00, 0x00, 0x00, 0x00]', () => {
|
|
116
|
-
const result = writeMiniData(new Uint8Array(0));
|
|
117
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x00, 0x00, 0x00]), 'Empty MiniData');
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('MiniData([0xAB]) → [0x00, 0x00, 0x00, 0x01, 0xAB]', () => {
|
|
121
|
-
const result = writeMiniData(new Uint8Array([0xAB]));
|
|
122
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x00, 0x00, 0x01, 0xAB]), 'MiniData(1 byte)');
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('MiniData(32-byte hash) → 4-byte len + 32 bytes', () => {
|
|
126
|
-
const hash = new Uint8Array(32).fill(0xAA);
|
|
127
|
-
const result = writeMiniData(hash);
|
|
128
|
-
expect(result.length).toBe(36);
|
|
129
|
-
expect(result[0]).toBe(0x00);
|
|
130
|
-
expect(result[1]).toBe(0x00);
|
|
131
|
-
expect(result[2]).toBe(0x00);
|
|
132
|
-
expect(result[3]).toBe(0x20); // 32 in hex
|
|
133
|
-
expect(result[4]).toBe(0xAA);
|
|
134
|
-
expect(result[35]).toBe(0xAA);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('writeHashToStream (Java Crypto.writeHashToStream Parity)', () => {
|
|
139
|
-
/**
|
|
140
|
-
* Java Crypto.writeHashToStream() is same as MiniData.writeDataStream()
|
|
141
|
-
*/
|
|
142
|
-
|
|
143
|
-
it('32-byte hash → 4-byte len + 32 bytes', () => {
|
|
144
|
-
const hash = hexToBytes('0x' + 'AB'.repeat(32));
|
|
145
|
-
const result = writeHashToStream(hash);
|
|
146
|
-
expect(result.length).toBe(36);
|
|
147
|
-
expect(result[3]).toBe(0x20); // length = 32
|
|
148
|
-
});
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
describe('MiniByte Serialization (Java Parity)', () => {
|
|
152
|
-
/**
|
|
153
|
-
* Java MiniByte.writeDataStream(): single byte
|
|
154
|
-
*/
|
|
155
|
-
|
|
156
|
-
it('MiniByte(false) → [0x00]', () => {
|
|
157
|
-
const result = writeMiniByte(false);
|
|
158
|
-
expectBytesEqual(result, new Uint8Array([0x00]), 'MiniByte(false)');
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it('MiniByte(true) → [0x01]', () => {
|
|
162
|
-
const result = writeMiniByte(true);
|
|
163
|
-
expectBytesEqual(result, new Uint8Array([0x01]), 'MiniByte(true)');
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('MiniByte(0) → [0x00]', () => {
|
|
167
|
-
const result = writeMiniByte(0);
|
|
168
|
-
expectBytesEqual(result, new Uint8Array([0x00]), 'MiniByte(0)');
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('MiniByte(255) → [0xFF]', () => {
|
|
172
|
-
const result = writeMiniByte(255);
|
|
173
|
-
expectBytesEqual(result, new Uint8Array([0xFF]), 'MiniByte(255)');
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
describe('BigInt to ByteArray (Java BigInteger.toByteArray Parity)', () => {
|
|
178
|
-
/**
|
|
179
|
-
* Java BigInteger.toByteArray() uses two's complement:
|
|
180
|
-
* - Zero → [0x00]
|
|
181
|
-
* - Positive with high bit set → leading 0x00 byte
|
|
182
|
-
*/
|
|
183
|
-
|
|
184
|
-
it('0n → [0x00]', () => {
|
|
185
|
-
const result = bigIntToByteArray(0n);
|
|
186
|
-
expectBytesEqual(result, new Uint8Array([0x00]), 'BigInt(0)');
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
it('1n → [0x01]', () => {
|
|
190
|
-
const result = bigIntToByteArray(1n);
|
|
191
|
-
expectBytesEqual(result, new Uint8Array([0x01]), 'BigInt(1)');
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('127n → [0x7F]', () => {
|
|
195
|
-
const result = bigIntToByteArray(127n);
|
|
196
|
-
expectBytesEqual(result, new Uint8Array([0x7F]), 'BigInt(127)');
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('128n → [0x00, 0x80] (two\'s complement needs leading zero)', () => {
|
|
200
|
-
const result = bigIntToByteArray(128n);
|
|
201
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x80]), 'BigInt(128)');
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it('255n → [0x00, 0xFF]', () => {
|
|
205
|
-
const result = bigIntToByteArray(255n);
|
|
206
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0xFF]), 'BigInt(255)');
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
it('256n → [0x01, 0x00]', () => {
|
|
210
|
-
const result = bigIntToByteArray(256n);
|
|
211
|
-
expectBytesEqual(result, new Uint8Array([0x01, 0x00]), 'BigInt(256)');
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
it('32767n → [0x7F, 0xFF]', () => {
|
|
215
|
-
const result = bigIntToByteArray(32767n);
|
|
216
|
-
expectBytesEqual(result, new Uint8Array([0x7F, 0xFF]), 'BigInt(32767)');
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it('32768n → [0x00, 0x80, 0x00] (needs leading zero)', () => {
|
|
220
|
-
const result = bigIntToByteArray(32768n);
|
|
221
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x80, 0x00]), 'BigInt(32768)');
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
describe('MMREntryNumber Serialization (Java Parity)', () => {
|
|
226
|
-
/**
|
|
227
|
-
* Java MMREntryNumber.writeDataStream():
|
|
228
|
-
* MiniNumber for scale (always 0 for integers)
|
|
229
|
-
* MiniData for unscaled BigInteger value
|
|
230
|
-
*
|
|
231
|
-
* For value=0, scale=0:
|
|
232
|
-
* [00 01 00] - MiniNumber: scale=0, len=1, data=0x00
|
|
233
|
-
* [00 00 00 01 00] - MiniData: len=1, data=0x00
|
|
234
|
-
*/
|
|
235
|
-
|
|
236
|
-
it('MMREntryNumber(0) → MiniNumber(0) + MiniData([0x00])', () => {
|
|
237
|
-
const result = writeMMREntryNumber(0n, 0);
|
|
238
|
-
const expected = concat(
|
|
239
|
-
new Uint8Array([0x00, 0x01, 0x00]), // MiniNumber for scale=0
|
|
240
|
-
new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x00]) // MiniData for value=0
|
|
241
|
-
);
|
|
242
|
-
expectBytesEqual(result, expected, 'MMREntryNumber(0)');
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it('MMREntryNumber(1) → MiniNumber(0) + MiniData([0x01])', () => {
|
|
246
|
-
const result = writeMMREntryNumber(1n, 0);
|
|
247
|
-
const expected = concat(
|
|
248
|
-
new Uint8Array([0x00, 0x01, 0x00]), // MiniNumber for scale=0
|
|
249
|
-
new Uint8Array([0x00, 0x00, 0x00, 0x01, 0x01]) // MiniData for value=1
|
|
250
|
-
);
|
|
251
|
-
expectBytesEqual(result, expected, 'MMREntryNumber(1)');
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
// ============================================================
|
|
256
|
-
// MMR STRUCTURE SERIALIZATION TESTS
|
|
257
|
-
// ============================================================
|
|
258
|
-
|
|
259
|
-
describe('MMRData Serialization (Java Parity)', () => {
|
|
260
|
-
it('MMRData with 32-byte hash and value=0', () => {
|
|
261
|
-
const hash = new Uint8Array(32).fill(0xAA);
|
|
262
|
-
const mmrData: MMRData = { data: hash, value: 0n };
|
|
263
|
-
const result = writeMMRData(mmrData);
|
|
264
|
-
|
|
265
|
-
// Expected: writeHashToStream(32 bytes) + MiniNumber(0)
|
|
266
|
-
// = [00 00 00 20] + <32 bytes> + [00 01 00]
|
|
267
|
-
expect(result.length).toBe(4 + 32 + 3); // 39 bytes
|
|
268
|
-
expect(result[0]).toBe(0x00); // length high byte
|
|
269
|
-
expect(result[3]).toBe(0x20); // length = 32
|
|
270
|
-
expect(result[4]).toBe(0xAA); // first hash byte
|
|
271
|
-
expect(result[35]).toBe(0xAA); // last hash byte
|
|
272
|
-
expect(result[36]).toBe(0x00); // MiniNumber scale
|
|
273
|
-
expect(result[37]).toBe(0x01); // MiniNumber length
|
|
274
|
-
expect(result[38]).toBe(0x00); // MiniNumber value = 0
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
it('MMRData with value=1', () => {
|
|
278
|
-
const hash = new Uint8Array(32).fill(0x00);
|
|
279
|
-
const mmrData: MMRData = { data: hash, value: 1n };
|
|
280
|
-
const result = writeMMRData(mmrData);
|
|
281
|
-
|
|
282
|
-
expect(result.length).toBe(39);
|
|
283
|
-
expect(result[38]).toBe(0x01); // MiniNumber value = 1
|
|
284
|
-
});
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
describe('MMRProofChunk Serialization (Java Parity)', () => {
|
|
288
|
-
it('MMRProofChunk(isLeft=true)', () => {
|
|
289
|
-
const hash = new Uint8Array(32).fill(0xBB);
|
|
290
|
-
const chunk: MMRProofChunk = {
|
|
291
|
-
isLeft: true,
|
|
292
|
-
mmrData: { data: hash, value: 0n }
|
|
293
|
-
};
|
|
294
|
-
const result = writeMMRProofChunk(chunk);
|
|
295
|
-
|
|
296
|
-
// Expected: MiniByte(1) + MMRData
|
|
297
|
-
// = [01] + 39 bytes = 40 bytes
|
|
298
|
-
expect(result.length).toBe(40);
|
|
299
|
-
expect(result[0]).toBe(0x01); // isLeft = true
|
|
300
|
-
expect(result[1]).toBe(0x00); // MMRData hash length high byte
|
|
301
|
-
});
|
|
302
|
-
|
|
303
|
-
it('MMRProofChunk(isLeft=false)', () => {
|
|
304
|
-
const hash = new Uint8Array(32).fill(0xCC);
|
|
305
|
-
const chunk: MMRProofChunk = {
|
|
306
|
-
isLeft: false,
|
|
307
|
-
mmrData: { data: hash, value: 0n }
|
|
308
|
-
};
|
|
309
|
-
const result = writeMMRProofChunk(chunk);
|
|
310
|
-
|
|
311
|
-
expect(result[0]).toBe(0x00); // isLeft = false
|
|
312
|
-
});
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
describe('MMRProof Serialization (Java Parity)', () => {
|
|
316
|
-
it('Empty MMRProof with blockTime=0', () => {
|
|
317
|
-
const proof: MMRProof = { blockTime: 0n, chunks: [] };
|
|
318
|
-
const result = writeMMRProof(proof);
|
|
319
|
-
|
|
320
|
-
// Expected: MiniNumber(0) + MiniNumber(0)
|
|
321
|
-
// = [00 01 00] + [00 01 00] = 6 bytes
|
|
322
|
-
expectBytesEqual(result, concat(
|
|
323
|
-
new Uint8Array([0x00, 0x01, 0x00]), // blockTime = 0
|
|
324
|
-
new Uint8Array([0x00, 0x01, 0x00]) // length = 0
|
|
325
|
-
), 'Empty MMRProof');
|
|
326
|
-
});
|
|
327
|
-
|
|
328
|
-
it('MMRProof with 1 chunk', () => {
|
|
329
|
-
const hash = new Uint8Array(32).fill(0xDD);
|
|
330
|
-
const proof: MMRProof = {
|
|
331
|
-
blockTime: 0n,
|
|
332
|
-
chunks: [{
|
|
333
|
-
isLeft: true,
|
|
334
|
-
mmrData: { data: hash, value: 0n }
|
|
335
|
-
}]
|
|
336
|
-
};
|
|
337
|
-
const result = writeMMRProof(proof);
|
|
338
|
-
|
|
339
|
-
// Expected: MiniNumber(0) + MiniNumber(1) + chunk(40 bytes)
|
|
340
|
-
// = 3 + 3 + 40 = 46 bytes
|
|
341
|
-
expect(result.length).toBe(46);
|
|
342
|
-
expect(result[5]).toBe(0x01); // length = 1
|
|
343
|
-
});
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
describe('SignatureProof Serialization (Java Parity)', () => {
|
|
347
|
-
it('SignatureProof with 32-byte pubkey, empty proof', () => {
|
|
348
|
-
const pubKey = new Uint8Array(32).fill(0x11);
|
|
349
|
-
const signature = new Uint8Array(1088).fill(0x22);
|
|
350
|
-
const sigProof: SignatureProof = {
|
|
351
|
-
leafPubkey: pubKey,
|
|
352
|
-
signature: signature,
|
|
353
|
-
mmrProof: { blockTime: 0n, chunks: [] }
|
|
354
|
-
};
|
|
355
|
-
const result = writeSignatureProof(sigProof);
|
|
356
|
-
|
|
357
|
-
// Expected: MiniData(32) + MiniData(1088) + MMRProof(6)
|
|
358
|
-
// = (4+32) + (4+1088) + 6 = 36 + 1092 + 6 = 1134 bytes
|
|
359
|
-
expect(result.length).toBe(1134);
|
|
360
|
-
expect(result[3]).toBe(0x20); // pubkey length = 32
|
|
361
|
-
// Signature length starts at byte 36 (after 4+32 pubkey bytes)
|
|
362
|
-
// 1088 = 0x00000440 in big-endian
|
|
363
|
-
expect(result[36]).toBe(0x00); // signature length byte 0
|
|
364
|
-
expect(result[37]).toBe(0x00); // signature length byte 1
|
|
365
|
-
expect(result[38]).toBe(0x04); // signature length byte 2 (1088 = 0x0440)
|
|
366
|
-
expect(result[39]).toBe(0x40); // signature length byte 3
|
|
367
|
-
});
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
describe('Signature Serialization (Java Parity)', () => {
|
|
371
|
-
it('Empty Signature (no proofs)', () => {
|
|
372
|
-
const sig: Signature = { proofs: [] };
|
|
373
|
-
const result = writeSignature(sig);
|
|
374
|
-
|
|
375
|
-
// Expected: MiniNumber(0) = [00 01 00]
|
|
376
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x01, 0x00]), 'Empty Signature');
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
it('Signature with 1 proof', () => {
|
|
380
|
-
const pubKey = new Uint8Array(32).fill(0x33);
|
|
381
|
-
const signature = new Uint8Array(1088).fill(0x44);
|
|
382
|
-
const sig: Signature = {
|
|
383
|
-
proofs: [{
|
|
384
|
-
leafPubkey: pubKey,
|
|
385
|
-
signature: signature,
|
|
386
|
-
mmrProof: { blockTime: 0n, chunks: [] }
|
|
387
|
-
}]
|
|
388
|
-
};
|
|
389
|
-
const result = writeSignature(sig);
|
|
390
|
-
|
|
391
|
-
// Expected: MiniNumber(1) + SignatureProof(1134)
|
|
392
|
-
// = 3 + 1134 = 1137 bytes
|
|
393
|
-
expect(result.length).toBe(1137);
|
|
394
|
-
expect(result[2]).toBe(0x01); // length = 1
|
|
395
|
-
});
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
describe('Witness/HierarchicalWitness Serialization (Java Parity)', () => {
|
|
399
|
-
it('Empty Witness (no proofs)', () => {
|
|
400
|
-
const witness = {
|
|
401
|
-
signatures: [],
|
|
402
|
-
coinProofs: [],
|
|
403
|
-
scriptProofs: []
|
|
404
|
-
};
|
|
405
|
-
const result = writeWitness(witness);
|
|
406
|
-
|
|
407
|
-
// Expected: 3x MiniNumber(0) = [00 01 00] [00 01 00] [00 01 00]
|
|
408
|
-
expectBytesEqual(result, concat(
|
|
409
|
-
new Uint8Array([0x00, 0x01, 0x00]),
|
|
410
|
-
new Uint8Array([0x00, 0x01, 0x00]),
|
|
411
|
-
new Uint8Array([0x00, 0x01, 0x00])
|
|
412
|
-
), 'Empty Witness');
|
|
413
|
-
});
|
|
414
|
-
|
|
415
|
-
it('Empty HierarchicalWitness', () => {
|
|
416
|
-
const bundle = { signatures: [] };
|
|
417
|
-
const result = writeHierarchicalWitness(bundle);
|
|
418
|
-
|
|
419
|
-
// Expected: MiniNumber(0) = [00 01 00]
|
|
420
|
-
expectBytesEqual(result, new Uint8Array([0x00, 0x01, 0x00]), 'Empty HierarchicalWitness');
|
|
421
|
-
});
|
|
422
|
-
});
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Parity test: Per-address key derivation matching Minima Wallet.java
|
|
3
|
-
*
|
|
4
|
-
* Verifies that derivePerAddressSeed() matches Minima Wallet.createNewKey():
|
|
5
|
-
* MiniData modifier = new MiniData(new BigInteger(Integer.toString(numkeys)));
|
|
6
|
-
* MiniData privseed = Crypto.getInstance().hashObjects(baseSeed, modifier);
|
|
7
|
-
* TreeKey treekey = TreeKey.createDefault(privseed);
|
|
8
|
-
*
|
|
9
|
-
* Created: 2026-02-05
|
|
10
|
-
* Purpose: Validate per-address key derivation matches Minima Wallet.java
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { derivePerAddressSeed, indexToMiniDataBytes } from '../javaStreamables';
|
|
14
|
-
import { TreeKey, createPerAddressTreeKey, deriveAddressPublicKey, getRootPublicKey, verifyTreeSignature } from '../treekey';
|
|
15
|
-
|
|
16
|
-
// Test seed (same as Java test)
|
|
17
|
-
const TEST_SEED = new Uint8Array([
|
|
18
|
-
0x51, 0xD9, 0xF4, 0x03, 0x27, 0x1E, 0x26, 0x72,
|
|
19
|
-
0x29, 0xB6, 0xC2, 0xA9, 0x5C, 0x5E, 0xAE, 0xD5,
|
|
20
|
-
0x27, 0x84, 0x6A, 0x1A, 0xF8, 0x9F, 0x8B, 0x1C,
|
|
21
|
-
0xF5, 0x57, 0x4B, 0x0E, 0x79, 0xA4, 0x9C, 0xF1
|
|
22
|
-
]);
|
|
23
|
-
|
|
24
|
-
function toHex(bytes: Uint8Array): string {
|
|
25
|
-
return '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('').toUpperCase();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
describe('Per-Address Key Derivation (Minima Wallet Parity)', () => {
|
|
29
|
-
// Expected values from Java TestPerAddressKeyDerivation.java
|
|
30
|
-
const javaExpected = [
|
|
31
|
-
{ index: 0, modifier: '0x00', privSeed: '0x6DD2281FD93037819358EA2DCC27C8DE4F358EB2DC17D9C5907B500184DAA172', pubKey: '0x75C8EE428AC72E1D7A4A7A7E02A6E7B8BEE4F7281B73C0199BBC0CDD59B05C88' },
|
|
32
|
-
{ index: 1, modifier: '0x01', privSeed: '0x3BAC5E60BA11049C1BAA2F065F9C21F736F3E30F37F7213EE9A37BF755AE83E5', pubKey: '0xD008FC735BC7A8FB4912584F61F7F8D9469E4146128985209B0EF5048BBEA215' },
|
|
33
|
-
{ index: 2, modifier: '0x02', privSeed: '0xF63171651D6110F9DD086EB3AC3D35CFE41DA8B504DD81C9575781C02F8EC6B0', pubKey: '0xBBC3D6F727CFD1D413CE152830F626EC89AC3435144A86BF932E6D5C0DB67BDF' },
|
|
34
|
-
{ index: 3, modifier: '0x03', privSeed: '0x65EFC1CC40BF30127B55F716860EDCB32A2C47F8434A44479A85CE0D2D2A07BA', pubKey: '0x75166F510C0457E3D1C94EA17A89D47EE4A90DBC71D94B06111C34E2AAC91D8C' },
|
|
35
|
-
{ index: 4, modifier: '0x04', privSeed: '0xF9A21A47941E47C4F98D212D98E8D8CC2A5D3AD03D473379F037CF5914433DB7', pubKey: '0xBFB7AD971C3A665F96E2A8BADDF14301DC8EBA2E45AEEA34AF85EC428F39F835' },
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
describe('indexToMiniDataBytes', () => {
|
|
39
|
-
it('converts index 0 to 0x00', () => {
|
|
40
|
-
expect(toHex(indexToMiniDataBytes(0))).toBe('0x00');
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('converts index 1 to 0x01', () => {
|
|
44
|
-
expect(toHex(indexToMiniDataBytes(1))).toBe('0x01');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
it('converts index 63 to 0x3F', () => {
|
|
48
|
-
expect(toHex(indexToMiniDataBytes(63))).toBe('0x3F');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it('converts index 64 to 0x40', () => {
|
|
52
|
-
expect(toHex(indexToMiniDataBytes(64))).toBe('0x40');
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('converts index 255 to 0xFF', () => {
|
|
56
|
-
expect(toHex(indexToMiniDataBytes(255))).toBe('0xFF');
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('converts index 256 to 0x0100 (2 bytes)', () => {
|
|
60
|
-
expect(toHex(indexToMiniDataBytes(256))).toBe('0x0100');
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe('derivePerAddressSeed', () => {
|
|
65
|
-
javaExpected.forEach(({ index, modifier, privSeed }) => {
|
|
66
|
-
it(`derives correct private seed for address ${index}`, () => {
|
|
67
|
-
const modifierBytes = indexToMiniDataBytes(index);
|
|
68
|
-
expect(toHex(modifierBytes)).toBe(modifier);
|
|
69
|
-
|
|
70
|
-
const derivedSeed = derivePerAddressSeed(TEST_SEED, index);
|
|
71
|
-
expect(toHex(derivedSeed)).toBe(privSeed);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe('Full address public key derivation', () => {
|
|
77
|
-
javaExpected.forEach(({ index, pubKey }) => {
|
|
78
|
-
it(`derives correct public key for address ${index}`, () => {
|
|
79
|
-
// Step 1: Derive private seed for this address
|
|
80
|
-
const privSeed = derivePerAddressSeed(TEST_SEED, index);
|
|
81
|
-
|
|
82
|
-
// Step 2: Create TreeKey from private seed (size=64, depth=3 matches TreeKey.createDefault)
|
|
83
|
-
const treeKey = new TreeKey(privSeed, 64, 3);
|
|
84
|
-
|
|
85
|
-
// Step 3: Get public key (MMR root)
|
|
86
|
-
const derivedPubKey = treeKey.getPublicKey();
|
|
87
|
-
|
|
88
|
-
expect(toHex(derivedPubKey)).toBe(pubKey);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
describe('createPerAddressTreeKey factory', () => {
|
|
94
|
-
javaExpected.forEach(({ index, pubKey }) => {
|
|
95
|
-
test(`factory creates correct TreeKey for address ${index}`, () => {
|
|
96
|
-
const treeKey = createPerAddressTreeKey(TEST_SEED, index);
|
|
97
|
-
|
|
98
|
-
expect(toHex(treeKey.getPublicKey())).toBe(pubKey);
|
|
99
|
-
expect(treeKey.getMaxUses()).toBe(64 * 64 * 64);
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
describe('deriveAddressPublicKey helper', () => {
|
|
105
|
-
javaExpected.forEach(({ index, pubKey }) => {
|
|
106
|
-
test(`derives correct address pubkey for index ${index}`, () => {
|
|
107
|
-
const addressPubkey = deriveAddressPublicKey(TEST_SEED, index);
|
|
108
|
-
expect(toHex(addressPubkey)).toBe(pubKey);
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
describe('setUses + sign signing flow', () => {
|
|
114
|
-
test('setUses + sign produces 3 proofs with correct structure', () => {
|
|
115
|
-
const treeKey = createPerAddressTreeKey(TEST_SEED, 0);
|
|
116
|
-
const testData = new Uint8Array(32).fill(0xAB);
|
|
117
|
-
|
|
118
|
-
treeKey.setUses(0 * 64 + 0);
|
|
119
|
-
const signature = treeKey.sign(testData);
|
|
120
|
-
|
|
121
|
-
expect(signature.proofs).toHaveLength(3);
|
|
122
|
-
expect(signature.proofs[0].leafPubkey).toHaveLength(32);
|
|
123
|
-
expect(signature.proofs[0].signature).toHaveLength(1088);
|
|
124
|
-
expect(signature.proofs[1].leafPubkey).toHaveLength(32);
|
|
125
|
-
expect(signature.proofs[1].signature).toHaveLength(1088);
|
|
126
|
-
expect(signature.proofs[2].leafPubkey).toHaveLength(32);
|
|
127
|
-
expect(signature.proofs[2].signature).toHaveLength(1088);
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
test('sign first proof root matches TreeKey root public key', () => {
|
|
131
|
-
const treeKey = createPerAddressTreeKey(TEST_SEED, 0);
|
|
132
|
-
const testData = new Uint8Array(32).fill(0xCD);
|
|
133
|
-
|
|
134
|
-
treeKey.setUses(0 * 64 + 0);
|
|
135
|
-
const signature = treeKey.sign(testData);
|
|
136
|
-
const proof0Root = getRootPublicKey(signature.proofs[0]);
|
|
137
|
-
|
|
138
|
-
expect(toHex(proof0Root)).toBe(toHex(treeKey.getPublicKey()));
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
test('sign signature verifies correctly', () => {
|
|
142
|
-
const treeKey = createPerAddressTreeKey(TEST_SEED, 1);
|
|
143
|
-
const testData = new Uint8Array(32).fill(0xEF);
|
|
144
|
-
|
|
145
|
-
treeKey.setUses(1 * 64 + 1);
|
|
146
|
-
const signature = treeKey.sign(testData);
|
|
147
|
-
const isValid = verifyTreeSignature(treeKey.getPublicKey(), testData, signature);
|
|
148
|
-
|
|
149
|
-
expect(isValid).toBe(true);
|
|
150
|
-
});
|
|
151
|
-
});
|
|
152
|
-
});
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RootTree prepare() propagation tests
|
|
3
|
-
*
|
|
4
|
-
* Verifies that TransactionService.prepare() correctly forwards walletMode
|
|
5
|
-
* and perAddressPublicKey in the POST body so the /prepare endpoint can
|
|
6
|
-
* apply RootTree-specific validation and return perAddressScript.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { TransactionService } from '../tx/TransactionService.js';
|
|
10
|
-
import type { TransactionServiceConfig } from '../tx/TransactionService.js';
|
|
11
|
-
import type { HttpClient } from '../adapters/index.js';
|
|
12
|
-
|
|
13
|
-
function makeMockHttp(capturedBodies: any[]): HttpClient {
|
|
14
|
-
return {
|
|
15
|
-
post: async <T>(_url: string, body: any): Promise<{ ok: boolean; status: number; data: T }> => {
|
|
16
|
-
capturedBodies.push({ body });
|
|
17
|
-
return {
|
|
18
|
-
ok: true,
|
|
19
|
-
status: 200,
|
|
20
|
-
data: {
|
|
21
|
-
addressIndex: 0,
|
|
22
|
-
l1: 0,
|
|
23
|
-
l2: 0,
|
|
24
|
-
leaseToken: 'mock-lease-token',
|
|
25
|
-
digestTx: '0x' + 'ab'.repeat(32),
|
|
26
|
-
digestL2: null,
|
|
27
|
-
digestL3: null,
|
|
28
|
-
txId: 'tx-mock',
|
|
29
|
-
rootPublicKey: '0x' + 'ff'.repeat(32),
|
|
30
|
-
paramSet: 'v2-spec',
|
|
31
|
-
leaseId: 'lease-mock',
|
|
32
|
-
leaseTTL: 120000,
|
|
33
|
-
perAddressScript: 'RETURN SIGNEDBY(0x' + 'ff'.repeat(32) + ')',
|
|
34
|
-
} as T,
|
|
35
|
-
};
|
|
36
|
-
},
|
|
37
|
-
get: async <T>(): Promise<{ ok: boolean; status: number; data: T }> => ({
|
|
38
|
-
ok: true, status: 200, data: {} as T,
|
|
39
|
-
}),
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const config: TransactionServiceConfig = {
|
|
44
|
-
baseUrl: 'https://api.example.com',
|
|
45
|
-
apiKey: 'test-api-key',
|
|
46
|
-
paramSet: 'v2-spec',
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const MOCK_ROOT_PK = '0x' + 'aa'.repeat(32);
|
|
50
|
-
const MOCK_PER_ADDR_PK = '0x' + 'bb'.repeat(32);
|
|
51
|
-
|
|
52
|
-
describe('TransactionService.prepare() — RootTree propagation', () => {
|
|
53
|
-
it('sends walletMode=AnonTree by default', async () => {
|
|
54
|
-
const bodies: any[] = [];
|
|
55
|
-
const svc = new TransactionService(makeMockHttp(bodies), config);
|
|
56
|
-
|
|
57
|
-
await svc.prepare(
|
|
58
|
-
{ to: 'MxABC', amount: '1', addressIndex: 0 },
|
|
59
|
-
MOCK_ROOT_PK
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
expect(bodies).toHaveLength(1);
|
|
63
|
-
expect(bodies[0].body.walletMode).toBe('AnonTree');
|
|
64
|
-
expect(bodies[0].body.perAddressPublicKey).toBeNull();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('forwards walletMode=RootTree and perAddressPublicKey in POST body', async () => {
|
|
68
|
-
const bodies: any[] = [];
|
|
69
|
-
const svc = new TransactionService(makeMockHttp(bodies), config);
|
|
70
|
-
|
|
71
|
-
await svc.prepare(
|
|
72
|
-
{
|
|
73
|
-
to: 'MxABC',
|
|
74
|
-
amount: '1',
|
|
75
|
-
addressIndex: 0,
|
|
76
|
-
walletMode: 'RootTree',
|
|
77
|
-
perAddressPublicKey: MOCK_PER_ADDR_PK,
|
|
78
|
-
},
|
|
79
|
-
MOCK_ROOT_PK
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
expect(bodies).toHaveLength(1);
|
|
83
|
-
const sent = bodies[0].body;
|
|
84
|
-
expect(sent.walletMode).toBe('RootTree');
|
|
85
|
-
expect(sent.perAddressPublicKey).toBe(MOCK_PER_ADDR_PK);
|
|
86
|
-
expect(sent.rootPublicKey).toBe(MOCK_ROOT_PK);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('PrepareResponse includes perAddressScript field from server', async () => {
|
|
90
|
-
const bodies: any[] = [];
|
|
91
|
-
const svc = new TransactionService(makeMockHttp(bodies), config);
|
|
92
|
-
|
|
93
|
-
const result = await svc.prepare(
|
|
94
|
-
{ to: 'MxABC', amount: '1', addressIndex: 0, walletMode: 'RootTree', perAddressPublicKey: MOCK_PER_ADDR_PK },
|
|
95
|
-
MOCK_ROOT_PK
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
expect(result.perAddressScript).toBeDefined();
|
|
99
|
-
expect(typeof result.perAddressScript).toBe('string');
|
|
100
|
-
});
|
|
101
|
-
});
|