@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
package/src/Streamable.ts
DELETED
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Streamable.ts - Canonical Java-Compatible Serialization Primitives
|
|
3
|
-
*
|
|
4
|
-
* This module provides byte-exact serialization functions matching
|
|
5
|
-
* Minima's Java Streamable interface and its implementations.
|
|
6
|
-
*
|
|
7
|
-
* JAVA REFERENCE CLASSES:
|
|
8
|
-
* - MiniData.writeDataStream(): 4-byte int length + raw bytes
|
|
9
|
-
* - MiniNumber.writeDataStream(): 1-byte scale + 1-byte len + BigInteger bytes
|
|
10
|
-
* - MiniString.writeDataStream(): delegates to MiniData(UTF-8 bytes)
|
|
11
|
-
* - MiniByte.writeDataStream(): single byte
|
|
12
|
-
* - Crypto.writeHashToStream(): 4-byte int length + hash bytes
|
|
13
|
-
* - MMREntryNumber.writeDataStream(): 1-byte len + BigInteger bytes
|
|
14
|
-
*
|
|
15
|
-
* CRITICAL NOTES:
|
|
16
|
-
* - MiniNumber uses 1-byte length, NOT 4-byte like MiniData
|
|
17
|
-
* - BigInteger.toByteArray() uses two's complement (leading 0 if high bit set)
|
|
18
|
-
* - Zero encodes as length=1, value=0x00
|
|
19
|
-
*
|
|
20
|
-
* Created: 2026-01-20
|
|
21
|
-
* Purpose: Single source of truth for all Minima type serialization
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
// Common type alias for byte arrays
|
|
25
|
-
export type Bytes = Uint8Array;
|
|
26
|
-
|
|
27
|
-
export function hexToBytes(hex: string): Uint8Array {
|
|
28
|
-
const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex;
|
|
29
|
-
if (cleanHex.length === 0) {
|
|
30
|
-
return new Uint8Array(0);
|
|
31
|
-
}
|
|
32
|
-
if (cleanHex.length % 2 !== 0) {
|
|
33
|
-
throw new Error(`Invalid hex string: odd length (${cleanHex.length})`);
|
|
34
|
-
}
|
|
35
|
-
const bytes = new Uint8Array(cleanHex.length / 2);
|
|
36
|
-
for (let i = 0; i < cleanHex.length; i += 2) {
|
|
37
|
-
bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
|
|
38
|
-
}
|
|
39
|
-
return bytes;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function bytesToHex(bytes: Uint8Array): string {
|
|
43
|
-
return '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export function concat(...arrays: Uint8Array[]): Uint8Array {
|
|
47
|
-
const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
|
|
48
|
-
const result = new Uint8Array(totalLength);
|
|
49
|
-
let offset = 0;
|
|
50
|
-
for (const arr of arrays) {
|
|
51
|
-
result.set(arr, offset);
|
|
52
|
-
offset += arr.length;
|
|
53
|
-
}
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Encode a MiniByte per Java MiniByte.writeDataStream()
|
|
59
|
-
*
|
|
60
|
-
* Format: single byte (0-255)
|
|
61
|
-
*/
|
|
62
|
-
export function writeMiniByte(value: number | boolean): Uint8Array {
|
|
63
|
-
if (typeof value === 'boolean') {
|
|
64
|
-
return new Uint8Array([value ? 1 : 0]);
|
|
65
|
-
}
|
|
66
|
-
if (value < 0 || value > 255) {
|
|
67
|
-
throw new Error(`MiniByte value must be 0-255, got ${value}`);
|
|
68
|
-
}
|
|
69
|
-
return new Uint8Array([value & 0xff]);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Encode a MiniData per Java MiniData.writeDataStream()
|
|
74
|
-
*
|
|
75
|
-
* Format: 4-byte big-endian int length + raw bytes
|
|
76
|
-
*/
|
|
77
|
-
export function writeMiniData(data: Uint8Array): Uint8Array {
|
|
78
|
-
const length = data.length;
|
|
79
|
-
const lengthBytes = new Uint8Array([
|
|
80
|
-
(length >> 24) & 0xff,
|
|
81
|
-
(length >> 16) & 0xff,
|
|
82
|
-
(length >> 8) & 0xff,
|
|
83
|
-
length & 0xff
|
|
84
|
-
]);
|
|
85
|
-
return concat(lengthBytes, data);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Encode a MiniString per Java MiniString.writeDataStream()
|
|
90
|
-
*
|
|
91
|
-
* Format: MiniData encoding of UTF-8 bytes
|
|
92
|
-
* = 4-byte int length + UTF-8 bytes
|
|
93
|
-
*/
|
|
94
|
-
export function writeMiniString(str: string): Uint8Array {
|
|
95
|
-
const utf8Bytes = new TextEncoder().encode(str);
|
|
96
|
-
return writeMiniData(utf8Bytes);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Convert a BigInt to Java BigInteger.toByteArray() format.
|
|
101
|
-
*
|
|
102
|
-
* Java BigInteger uses two's complement:
|
|
103
|
-
* - Zero → [0x00]
|
|
104
|
-
* - Positive with high bit set → leading 0x00 byte
|
|
105
|
-
*
|
|
106
|
-
* @param value - The BigInt value (must be non-negative)
|
|
107
|
-
* @returns Uint8Array in two's complement format
|
|
108
|
-
*/
|
|
109
|
-
export function bigIntToByteArray(value: bigint): Uint8Array {
|
|
110
|
-
if (value < 0n) {
|
|
111
|
-
throw new Error(`bigIntToByteArray does not support negative values: ${value}`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (value === 0n) {
|
|
115
|
-
return new Uint8Array([0]);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
let hex = value.toString(16);
|
|
119
|
-
if (hex.length % 2 !== 0) {
|
|
120
|
-
hex = '0' + hex;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
let bytes = hexToBytes('0x' + hex);
|
|
124
|
-
|
|
125
|
-
if (bytes.length > 0 && (bytes[0] & 0x80) !== 0) {
|
|
126
|
-
const withLeadingZero = new Uint8Array(bytes.length + 1);
|
|
127
|
-
withLeadingZero[0] = 0x00;
|
|
128
|
-
withLeadingZero.set(bytes, 1);
|
|
129
|
-
bytes = withLeadingZero;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return bytes;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Encode a MiniNumber per Java MiniNumber.writeDataStream()
|
|
137
|
-
*
|
|
138
|
-
* Format:
|
|
139
|
-
* 1 byte: scale (number of decimal places, signed)
|
|
140
|
-
* 1 byte: length of unscaled BigInteger data
|
|
141
|
-
* N bytes: unscaled BigInteger in two's complement
|
|
142
|
-
*
|
|
143
|
-
* CRITICAL: Uses 1-byte length, NOT 4-byte like MiniData!
|
|
144
|
-
*
|
|
145
|
-
* @param value - The unscaled BigInt value
|
|
146
|
-
* @param scale - The scale (decimal places), default 0
|
|
147
|
-
*/
|
|
148
|
-
export function writeMiniNumber(value: bigint, scale: number = 0): Uint8Array {
|
|
149
|
-
if (typeof value !== 'bigint') {
|
|
150
|
-
throw new Error(`writeMiniNumber requires bigint, got ${typeof value}`);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (value < 0n) {
|
|
154
|
-
throw new Error(`writeMiniNumber does not support negative values: ${value}`);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const unscaledBytes = bigIntToByteArray(value);
|
|
158
|
-
const length = unscaledBytes.length;
|
|
159
|
-
|
|
160
|
-
if (length > 255) {
|
|
161
|
-
throw new Error(`MiniNumber data too large: ${length} bytes (max 255)`);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const result = new Uint8Array(1 + 1 + length);
|
|
165
|
-
result[0] = scale & 0xff;
|
|
166
|
-
result[1] = length & 0xff;
|
|
167
|
-
result.set(unscaledBytes, 2);
|
|
168
|
-
|
|
169
|
-
return result;
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Encode a hash per Java Crypto.writeHashToStream()
|
|
174
|
-
*
|
|
175
|
-
* Format: 4-byte big-endian int length + hash bytes
|
|
176
|
-
* (Same as MiniData)
|
|
177
|
-
*/
|
|
178
|
-
export function writeHashToStream(hash: Uint8Array): Uint8Array {
|
|
179
|
-
return writeMiniData(hash);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Encode an MMREntryNumber per Java MMREntryNumber.writeDataStream()
|
|
184
|
-
*
|
|
185
|
-
* Java source (MMREntryNumber.java):
|
|
186
|
-
* MiniNumber.WriteToStream(zOut, mNumber.scale()); // scale as MiniNumber
|
|
187
|
-
* MiniData.WriteToStream(zOut, mNumber.unscaledValue().toByteArray()); // unscaled as MiniData
|
|
188
|
-
*
|
|
189
|
-
* Format:
|
|
190
|
-
* - MiniNumber for scale (always 0 for integer values)
|
|
191
|
-
* - MiniData for unscaled BigInteger value
|
|
192
|
-
*
|
|
193
|
-
* For integer MMREntryNumber (scale=0), this encodes as:
|
|
194
|
-
* [00 01 00] - MiniNumber: scale=0, len=1, data=0x00
|
|
195
|
-
* [00 00 00 LL ...] - MiniData: 4-byte len + BigInteger bytes
|
|
196
|
-
*/
|
|
197
|
-
export function writeMMREntryNumber(value: bigint, scale: number = 0): Uint8Array {
|
|
198
|
-
if (value < 0n) {
|
|
199
|
-
throw new Error(`writeMMREntryNumber does not support negative values: ${value}`);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Write scale as MiniNumber (scale of scale is always 0)
|
|
203
|
-
const scaleBytes = writeMiniNumber(BigInt(scale), 0);
|
|
204
|
-
|
|
205
|
-
// Write unscaled value as MiniData
|
|
206
|
-
const unscaledBytes = bigIntToByteArray(value);
|
|
207
|
-
const unscaledData = writeMiniData(unscaledBytes);
|
|
208
|
-
|
|
209
|
-
return concat(scaleBytes, unscaledData);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* StateVariable type constants from Java StateVariable.java
|
|
214
|
-
*/
|
|
215
|
-
export const STATETYPE_HEX = 1;
|
|
216
|
-
export const STATETYPE_NUMBER = 2;
|
|
217
|
-
export const STATETYPE_STRING = 4;
|
|
218
|
-
export const STATETYPE_BOOL = 8;
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
* High-level StateVariable value type
|
|
222
|
-
*/
|
|
223
|
-
export interface StateVariableValue {
|
|
224
|
-
port: number;
|
|
225
|
-
value: string | bigint | boolean | Uint8Array;
|
|
226
|
-
type: 'bool' | 'number' | 'hex' | 'string';
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Normalize hex/address string to 0x format.
|
|
231
|
-
* Handles both Mx (Minima Base32) and 0x formats.
|
|
232
|
-
* Matches Java's StateVariable constructor behavior.
|
|
233
|
-
*
|
|
234
|
-
* Note: For Mx conversion, caller should use mxToHex from minima-base32
|
|
235
|
-
* This function handles 0x prefix normalization only.
|
|
236
|
-
*/
|
|
237
|
-
export function normalizeHexString(value: string): string {
|
|
238
|
-
if (!value) {
|
|
239
|
-
return '0x00';
|
|
240
|
-
}
|
|
241
|
-
const trimmed = value.trim();
|
|
242
|
-
return trimmed.startsWith('0x') ? trimmed : '0x' + trimmed;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Serialize a StateVariable per Java StateVariable.writeDataStream()
|
|
247
|
-
*
|
|
248
|
-
* Format:
|
|
249
|
-
* 1. port (MiniByte - 1 byte, 0-255)
|
|
250
|
-
* 2. type (MiniByte - 1 byte: HEX=1, NUMBER=2, STRING=4, BOOL=8)
|
|
251
|
-
* 3. data (format depends on type):
|
|
252
|
-
* - BOOL: MiniByte (1 byte: 0 or 1)
|
|
253
|
-
* - HEX: MiniData (4-byte length + hex bytes)
|
|
254
|
-
* - NUMBER: MiniNumber (1-byte scale + 1-byte len + data)
|
|
255
|
-
* - STRING: MiniString (4-byte length + UTF-8 with brackets)
|
|
256
|
-
*
|
|
257
|
-
* @param sv - StateVariable with high-level value
|
|
258
|
-
* @param mxToHex - Optional function to convert Mx addresses to 0x hex
|
|
259
|
-
*/
|
|
260
|
-
export function writeStateVariable(
|
|
261
|
-
sv: StateVariableValue,
|
|
262
|
-
mxToHex?: (addr: string) => string
|
|
263
|
-
): Uint8Array {
|
|
264
|
-
if (sv.port < 0 || sv.port > 255) {
|
|
265
|
-
throw new Error(`StateVariable port must be 0-255, got ${sv.port}`);
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
const portByte = writeMiniByte(sv.port);
|
|
269
|
-
|
|
270
|
-
let typeByte: Uint8Array;
|
|
271
|
-
let dataBytes: Uint8Array;
|
|
272
|
-
|
|
273
|
-
switch (sv.type) {
|
|
274
|
-
case 'bool':
|
|
275
|
-
typeByte = writeMiniByte(STATETYPE_BOOL);
|
|
276
|
-
if (typeof sv.value === 'boolean') {
|
|
277
|
-
dataBytes = writeMiniByte(sv.value);
|
|
278
|
-
} else if (typeof sv.value === 'string') {
|
|
279
|
-
dataBytes = writeMiniByte(sv.value.toUpperCase() === 'TRUE');
|
|
280
|
-
} else {
|
|
281
|
-
throw new Error(`Invalid bool StateVariable value: ${sv.value}`);
|
|
282
|
-
}
|
|
283
|
-
break;
|
|
284
|
-
|
|
285
|
-
case 'number':
|
|
286
|
-
typeByte = writeMiniByte(STATETYPE_NUMBER);
|
|
287
|
-
if (typeof sv.value === 'bigint') {
|
|
288
|
-
dataBytes = writeMiniNumber(sv.value);
|
|
289
|
-
} else if (typeof sv.value === 'string') {
|
|
290
|
-
dataBytes = writeMiniNumber(BigInt(sv.value));
|
|
291
|
-
} else {
|
|
292
|
-
throw new Error(`Invalid number StateVariable value: ${sv.value}`);
|
|
293
|
-
}
|
|
294
|
-
break;
|
|
295
|
-
|
|
296
|
-
case 'hex':
|
|
297
|
-
typeByte = writeMiniByte(STATETYPE_HEX);
|
|
298
|
-
if (typeof sv.value === 'string') {
|
|
299
|
-
let normalizedHex = sv.value;
|
|
300
|
-
if (sv.value.toLowerCase().startsWith('mx') && mxToHex) {
|
|
301
|
-
normalizedHex = mxToHex(sv.value);
|
|
302
|
-
} else {
|
|
303
|
-
normalizedHex = normalizeHexString(sv.value);
|
|
304
|
-
}
|
|
305
|
-
dataBytes = writeMiniData(hexToBytes(normalizedHex));
|
|
306
|
-
} else if (sv.value instanceof Uint8Array) {
|
|
307
|
-
dataBytes = writeMiniData(sv.value);
|
|
308
|
-
} else {
|
|
309
|
-
throw new Error(`Invalid hex StateVariable value: ${sv.value}`);
|
|
310
|
-
}
|
|
311
|
-
break;
|
|
312
|
-
|
|
313
|
-
case 'string':
|
|
314
|
-
typeByte = writeMiniByte(STATETYPE_STRING);
|
|
315
|
-
if (typeof sv.value === 'string') {
|
|
316
|
-
let bracketedValue = sv.value;
|
|
317
|
-
if (!sv.value.startsWith('[') || !sv.value.endsWith(']')) {
|
|
318
|
-
bracketedValue = `[${sv.value}]`;
|
|
319
|
-
}
|
|
320
|
-
dataBytes = writeMiniString(bracketedValue);
|
|
321
|
-
} else {
|
|
322
|
-
throw new Error(`Invalid string StateVariable value: ${sv.value}`);
|
|
323
|
-
}
|
|
324
|
-
break;
|
|
325
|
-
|
|
326
|
-
default:
|
|
327
|
-
throw new Error(`Unknown StateVariable type: ${(sv as any).type}`);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return concat(portByte, typeByte, dataBytes);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// ============================================================
|
|
334
|
-
// MMR DATA STRUCTURES
|
|
335
|
-
// ============================================================
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* MMRData interface matching Java MMRData structure
|
|
339
|
-
*/
|
|
340
|
-
export interface MMRData {
|
|
341
|
-
data: Uint8Array; // 32-byte hash
|
|
342
|
-
value: bigint; // Sum value (MiniNumber)
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Write MMRData per Java MMRData.writeDataStream()
|
|
347
|
-
*
|
|
348
|
-
* Java source (MMRData.java):
|
|
349
|
-
* mData.writeHashToStream(zOut); // 4-byte len + hash
|
|
350
|
-
* mValue.writeDataStream(zOut); // MiniNumber
|
|
351
|
-
*/
|
|
352
|
-
export function writeMMRData(mmrData: MMRData): Uint8Array {
|
|
353
|
-
const hashBytes = writeHashToStream(mmrData.data);
|
|
354
|
-
const valueBytes = writeMiniNumber(mmrData.value, 0);
|
|
355
|
-
return concat(hashBytes, valueBytes);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* MMRProofChunk interface matching Java MMRProofChunk structure
|
|
360
|
-
*/
|
|
361
|
-
export interface MMRProofChunk {
|
|
362
|
-
isLeft: boolean;
|
|
363
|
-
mmrData: MMRData;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Write MMRProofChunk per Java MMRProofChunk.writeDataStream()
|
|
368
|
-
*
|
|
369
|
-
* Java source (MMRProof.java inner class):
|
|
370
|
-
* mLeft.writeDataStream(zOut); // MiniByte (1 byte)
|
|
371
|
-
* mMMRData.writeDataStream(zOut); // MMRData
|
|
372
|
-
*/
|
|
373
|
-
export function writeMMRProofChunk(chunk: MMRProofChunk): Uint8Array {
|
|
374
|
-
const leftByte = writeMiniByte(chunk.isLeft);
|
|
375
|
-
const dataBytes = writeMMRData(chunk.mmrData);
|
|
376
|
-
return concat(leftByte, dataBytes);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
/**
|
|
380
|
-
* MMRProof interface matching Java MMRProof structure
|
|
381
|
-
*/
|
|
382
|
-
export interface MMRProof {
|
|
383
|
-
blockTime: bigint;
|
|
384
|
-
chunks: MMRProofChunk[];
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* Write MMRProof per Java MMRProof.writeDataStream()
|
|
389
|
-
*
|
|
390
|
-
* Java source (MMRProof.java):
|
|
391
|
-
* mBlockTime.writeDataStream(zOut); // MiniNumber
|
|
392
|
-
* MiniNumber.WriteToStream(zOut, len); // Array length as MiniNumber
|
|
393
|
-
* for each chunk: chunk.writeDataStream(zOut);
|
|
394
|
-
*/
|
|
395
|
-
export function writeMMRProof(proof: MMRProof): Uint8Array {
|
|
396
|
-
const blockTimeBytes = writeMiniNumber(proof.blockTime, 0);
|
|
397
|
-
const lengthBytes = writeMiniNumber(BigInt(proof.chunks.length), 0);
|
|
398
|
-
|
|
399
|
-
const parts: Uint8Array[] = [blockTimeBytes, lengthBytes];
|
|
400
|
-
for (const chunk of proof.chunks) {
|
|
401
|
-
parts.push(writeMMRProofChunk(chunk));
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
return concat(...parts);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
// ============================================================
|
|
408
|
-
// SIGNATURE STRUCTURES
|
|
409
|
-
// ============================================================
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* SignatureProof interface matching Java SignatureProof structure
|
|
413
|
-
*
|
|
414
|
-
* CRITICAL FIX (January 2026): Java's Winternitz.getPublicKey() returns a 32-byte DIGEST!
|
|
415
|
-
* BouncyCastle's WinternitzOTSignature.getPublicKey() hashes the full 1088-byte key
|
|
416
|
-
* and returns SHA3-256(full_key) = 32 bytes. The MMR tree and SignatureProof use this digest.
|
|
417
|
-
*/
|
|
418
|
-
export interface SignatureProof {
|
|
419
|
-
leafPubkey: Uint8Array; // 32-byte WOTS public key DIGEST (SHA3-256 of full L=34 × 32 byte key)
|
|
420
|
-
signature: Uint8Array; // 1088-byte WOTS signature
|
|
421
|
-
mmrProof: MMRProof; // MMR proof to root
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
/**
|
|
425
|
-
* Write SignatureProof per Java SignatureProof.writeDataStream()
|
|
426
|
-
*
|
|
427
|
-
* Java source (SignatureProof.java):
|
|
428
|
-
* mPublicKey.writeDataStream(zOut); // MiniData
|
|
429
|
-
* mSignature.writeDataStream(zOut); // MiniData
|
|
430
|
-
* mProof.writeDataStream(zOut); // MMRProof
|
|
431
|
-
*/
|
|
432
|
-
export function writeSignatureProof(sigProof: SignatureProof): Uint8Array {
|
|
433
|
-
const pubKeyBytes = writeMiniData(sigProof.leafPubkey);
|
|
434
|
-
const sigBytes = writeMiniData(sigProof.signature);
|
|
435
|
-
const proofBytes = writeMMRProof(sigProof.mmrProof);
|
|
436
|
-
return concat(pubKeyBytes, sigBytes, proofBytes);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Signature interface matching Java Signature structure
|
|
441
|
-
* A Signature contains an array of SignatureProofs (for hierarchical signing)
|
|
442
|
-
*/
|
|
443
|
-
export interface Signature {
|
|
444
|
-
proofs: SignatureProof[];
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Write Signature per Java Signature.writeDataStream()
|
|
449
|
-
*
|
|
450
|
-
* Java source (Signature.java):
|
|
451
|
-
* MiniNumber.WriteToStream(zOut, mSignatures.size());
|
|
452
|
-
* for each sig: sig.writeDataStream(zOut);
|
|
453
|
-
*/
|
|
454
|
-
export function writeSignature(sig: Signature): Uint8Array {
|
|
455
|
-
const lengthBytes = writeMiniNumber(BigInt(sig.proofs.length), 0);
|
|
456
|
-
|
|
457
|
-
const parts: Uint8Array[] = [lengthBytes];
|
|
458
|
-
for (const proof of sig.proofs) {
|
|
459
|
-
parts.push(writeSignatureProof(proof));
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return concat(...parts);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// ============================================================
|
|
466
|
-
// WITNESS / HIERARCHICAL WITNESS
|
|
467
|
-
// ============================================================
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* CoinProof interface (simplified - coin proofs in witness)
|
|
471
|
-
* Full implementation would include coin data + MMR proof
|
|
472
|
-
*/
|
|
473
|
-
export interface CoinProof {
|
|
474
|
-
data: Uint8Array; // Serialized coin proof data
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* ScriptProof interface (simplified - script proofs in witness)
|
|
479
|
-
*/
|
|
480
|
-
export interface ScriptProof {
|
|
481
|
-
data: Uint8Array; // Serialized script proof data
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
/**
|
|
485
|
-
* Witness interface matching Java Witness structure
|
|
486
|
-
* Used for full transaction witness serialization
|
|
487
|
-
*/
|
|
488
|
-
export interface Witness {
|
|
489
|
-
signatures: Signature[];
|
|
490
|
-
coinProofs: CoinProof[];
|
|
491
|
-
scriptProofs: ScriptProof[];
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/**
|
|
495
|
-
* Write Witness per Java Witness.writeDataStream()
|
|
496
|
-
*
|
|
497
|
-
* Java source (Witness.java):
|
|
498
|
-
* MiniNumber.WriteToStream(zOut, mSignatureProofs.size());
|
|
499
|
-
* for each sp: sp.writeDataStream(zOut);
|
|
500
|
-
* MiniNumber.WriteToStream(zOut, mCoinProofs.size());
|
|
501
|
-
* for each cp: cp.writeDataStream(zOut);
|
|
502
|
-
* MiniNumber.WriteToStream(zOut, mScriptProofs.size());
|
|
503
|
-
* for each sp: sp.writeDataStream(zOut);
|
|
504
|
-
*/
|
|
505
|
-
export function writeWitness(witness: Witness): Uint8Array {
|
|
506
|
-
const parts: Uint8Array[] = [];
|
|
507
|
-
|
|
508
|
-
// Signatures
|
|
509
|
-
parts.push(writeMiniNumber(BigInt(witness.signatures.length), 0));
|
|
510
|
-
for (const sig of witness.signatures) {
|
|
511
|
-
parts.push(writeSignature(sig));
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
// Coin proofs
|
|
515
|
-
parts.push(writeMiniNumber(BigInt(witness.coinProofs.length), 0));
|
|
516
|
-
for (const cp of witness.coinProofs) {
|
|
517
|
-
parts.push(cp.data);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
// Script proofs
|
|
521
|
-
parts.push(writeMiniNumber(BigInt(witness.scriptProofs.length), 0));
|
|
522
|
-
for (const sp of witness.scriptProofs) {
|
|
523
|
-
parts.push(sp.data);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
return concat(...parts);
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* HierarchicalWitnessBundle - Simplified witness for WOTS hierarchical signing
|
|
531
|
-
* This is the format used by Totem for transaction signing
|
|
532
|
-
*/
|
|
533
|
-
export interface HierarchicalWitnessBundle {
|
|
534
|
-
signatures: Signature[];
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
/**
|
|
538
|
-
* Write a simplified hierarchical witness (signatures only)
|
|
539
|
-
* Used for WOTS transaction signing flow
|
|
540
|
-
*/
|
|
541
|
-
export function writeHierarchicalWitness(bundle: HierarchicalWitnessBundle): Uint8Array {
|
|
542
|
-
const lengthBytes = writeMiniNumber(BigInt(bundle.signatures.length), 0);
|
|
543
|
-
|
|
544
|
-
const parts: Uint8Array[] = [lengthBytes];
|
|
545
|
-
for (const sig of bundle.signatures) {
|
|
546
|
-
parts.push(writeSignature(sig));
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
return concat(...parts);
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* Write hierarchical witness and return as hex string
|
|
554
|
-
*/
|
|
555
|
-
export function writeHierarchicalWitnessToHex(bundle: HierarchicalWitnessBundle): string {
|
|
556
|
-
return bytesToHex(writeHierarchicalWitness(bundle));
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// ============================================================
|
|
560
|
-
// EXTENSION-MATCHING ALIASES
|
|
561
|
-
// ============================================================
|
|
562
|
-
// The extension's WitnessSerializer uses encode* naming, while SDK uses write* naming.
|
|
563
|
-
// These aliases provide compatibility with extension code.
|
|
564
|
-
|
|
565
|
-
export const encodeMiniNumber = writeMiniNumber;
|
|
566
|
-
export const encodeMiniData = writeMiniData;
|
|
567
|
-
export const encodeMiniString = writeMiniString;
|