@totemsdk/core 1.0.9 → 1.0.11

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.
Files changed (145) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -5
  3. package/dist/Streamable.js +54 -31
  4. package/dist/adapters/index.js +18 -8
  5. package/dist/adapters/types.js +19 -8
  6. package/dist/binio.js +5 -1
  7. package/dist/bip39.js +24 -14
  8. package/dist/derive.js +11 -7
  9. package/dist/index.js +130 -22
  10. package/dist/javaStreamables.js +49 -30
  11. package/dist/lease/LeaseMonitor.js +7 -3
  12. package/dist/lease/LeaseStore.js +7 -3
  13. package/dist/lease/WatermarkStore.js +7 -3
  14. package/dist/lease/index.js +13 -4
  15. package/dist/lease-client.js +8 -3
  16. package/dist/minima32.js +22 -13
  17. package/dist/minimaWireSerializer.js +20 -14
  18. package/dist/mmr.js +35 -23
  19. package/dist/mx.js +10 -1
  20. package/dist/params.js +9 -5
  21. package/dist/script.js +12 -7
  22. package/dist/scripts/contract-helpers.js +37 -26
  23. package/dist/scripts/dapp-types.js +11 -6
  24. package/dist/scripts/index.js +38 -4
  25. package/dist/scripts/types.js +26 -12
  26. package/dist/scripts/witness-serializer.js +48 -30
  27. package/dist/transaction.js +55 -46
  28. package/dist/treekey.js +74 -58
  29. package/dist/tx/TransactionLifecycle.js +11 -5
  30. package/dist/tx/TransactionReceiptStore.js +7 -3
  31. package/dist/tx/TransactionService.js +14 -10
  32. package/dist/tx/index.js +11 -3
  33. package/dist/tx/types.js +2 -1
  34. package/dist/util.js +5 -1
  35. package/dist/utils.js +12 -5
  36. package/dist/verify.js +36 -25
  37. package/dist/version.js +5 -2
  38. package/dist/wots.d.ts +2 -2
  39. package/dist/wots.js +94 -64
  40. package/package.json +50 -6
  41. package/src/Streamable.d.ts +0 -268
  42. package/src/Streamable.js +0 -416
  43. package/src/Streamable.ts +0 -567
  44. package/src/__tests__/Streamable.parity.test.ts +0 -422
  45. package/src/__tests__/perAddressDerivation.parity.test.ts +0 -152
  46. package/src/__tests__/roottree-prepare.test.ts +0 -101
  47. package/src/__tests__/wots-parity.test.ts +0 -289
  48. package/src/adapters/index.d.ts +0 -190
  49. package/src/adapters/index.js +0 -117
  50. package/src/adapters/index.ts +0 -301
  51. package/src/adapters/types.ts +0 -235
  52. package/src/addr.oracle.test.ts +0 -25
  53. package/src/address.test.ts +0 -55
  54. package/src/binio.ts +0 -21
  55. package/src/bip39.d.ts +0 -91
  56. package/src/bip39.js +0 -427
  57. package/src/bip39.ts +0 -432
  58. package/src/derive.d.ts +0 -2
  59. package/src/derive.js +0 -13
  60. package/src/derive.ts +0 -11
  61. package/src/index.d.ts +0 -26
  62. package/src/index.js +0 -128
  63. package/src/index.test.ts +0 -5
  64. package/src/index.ts +0 -221
  65. package/src/javaStreamables.d.ts +0 -233
  66. package/src/javaStreamables.js +0 -332
  67. package/src/javaStreamables.ts +0 -403
  68. package/src/lease/LeaseMonitor.d.ts +0 -44
  69. package/src/lease/LeaseMonitor.js +0 -111
  70. package/src/lease/LeaseMonitor.ts +0 -157
  71. package/src/lease/LeaseStore.d.ts +0 -57
  72. package/src/lease/LeaseStore.js +0 -148
  73. package/src/lease/LeaseStore.ts +0 -203
  74. package/src/lease/WatermarkStore.d.ts +0 -61
  75. package/src/lease/WatermarkStore.js +0 -206
  76. package/src/lease/WatermarkStore.ts +0 -270
  77. package/src/lease/index.d.ts +0 -14
  78. package/src/lease/index.js +0 -22
  79. package/src/lease/index.ts +0 -41
  80. package/src/lease-client.d.ts +0 -31
  81. package/src/lease-client.js +0 -44
  82. package/src/lease-client.ts +0 -69
  83. package/src/minima32.d.ts +0 -10
  84. package/src/minima32.js +0 -113
  85. package/src/minima32.test.ts +0 -11
  86. package/src/minima32.ts +0 -127
  87. package/src/minimaWireSerializer.d.ts +0 -189
  88. package/src/minimaWireSerializer.js +0 -311
  89. package/src/minimaWireSerializer.test.ts +0 -466
  90. package/src/minimaWireSerializer.ts +0 -117
  91. package/src/mmr.d.ts +0 -157
  92. package/src/mmr.js +0 -340
  93. package/src/mmr.oracle.test.ts +0 -28
  94. package/src/mmr.ts +0 -429
  95. package/src/mx.test.ts +0 -25
  96. package/src/mx.ts +0 -1
  97. package/src/params.d.ts +0 -29
  98. package/src/params.d.ts.map +0 -1
  99. package/src/params.js +0 -20
  100. package/src/params.js.map +0 -1
  101. package/src/params.ts +0 -44
  102. package/src/script.d.ts +0 -7
  103. package/src/script.js +0 -27
  104. package/src/script.ts +0 -24
  105. package/src/scripts/contract-helpers.ts +0 -609
  106. package/src/scripts/dapp-types.ts +0 -240
  107. package/src/scripts/index.ts +0 -22
  108. package/src/scripts/types.d.ts +0 -81
  109. package/src/scripts/types.js +0 -145
  110. package/src/scripts/types.ts +0 -247
  111. package/src/scripts/witness-serializer.ts +0 -384
  112. package/src/transaction.ts +0 -430
  113. package/src/treekey.d.ts +0 -383
  114. package/src/treekey.js +0 -774
  115. package/src/treekey.parity.test.ts +0 -459
  116. package/src/treekey.ts +0 -975
  117. package/src/tx/TransactionLifecycle.d.ts +0 -55
  118. package/src/tx/TransactionLifecycle.js +0 -188
  119. package/src/tx/TransactionLifecycle.ts +0 -280
  120. package/src/tx/TransactionReceiptStore.d.ts +0 -36
  121. package/src/tx/TransactionReceiptStore.js +0 -89
  122. package/src/tx/TransactionReceiptStore.ts +0 -112
  123. package/src/tx/TransactionService.d.ts +0 -31
  124. package/src/tx/TransactionService.js +0 -140
  125. package/src/tx/TransactionService.ts +0 -252
  126. package/src/tx/index.d.ts +0 -13
  127. package/src/tx/index.js +0 -20
  128. package/src/tx/index.ts +0 -44
  129. package/src/tx/types.d.ts +0 -80
  130. package/src/tx/types.js +0 -6
  131. package/src/tx/types.ts +0 -130
  132. package/src/util.d.ts +0 -1
  133. package/src/util.js +0 -5
  134. package/src/util.ts +0 -1
  135. package/src/utils.d.ts +0 -8
  136. package/src/utils.js +0 -42
  137. package/src/utils.ts +0 -38
  138. package/src/verify.ts +0 -210
  139. package/src/version.ts +0 -13
  140. package/src/wots.d.ts +0 -224
  141. package/src/wots.d.ts.map +0 -1
  142. package/src/wots.js +0 -565
  143. package/src/wots.js.map +0 -1
  144. package/src/wots.ts +0 -651
  145. package/test-vectors.json +0 -45
@@ -1,247 +0,0 @@
1
- import type { MMRData, MMRProofChunk, MMRProof } from '../mmr.js';
2
- export type { MMRProof };
3
-
4
- function kissHex(hex: string): string {
5
- const raw = hex.startsWith('0x') || hex.startsWith('0X') ? hex.slice(2) : hex;
6
- return '0x' + raw.toUpperCase();
7
- }
8
-
9
- export type StateVariableType = 'STATE' | 'PREVSTATE' | 'SAMESTATE';
10
-
11
- export interface StateValue {
12
- port: number;
13
- value: string | bigint | Uint8Array | boolean;
14
- type: 'bool' | 'number' | 'hex' | 'string';
15
- }
16
-
17
- export interface VerifyOutExpectation {
18
- inputIndex: number | '@INPUT';
19
- outputAddress: string;
20
- amount: string | bigint;
21
- tokenId: string;
22
- keepState: boolean;
23
- }
24
-
25
- export type ScriptType =
26
- | 'signedby'
27
- | 'multisig'
28
- | 'multisig_mofn'
29
- | 'timelock'
30
- | 'htlc'
31
- | 'mast'
32
- | 'exchange'
33
- | 'vault'
34
- | 'flashcash'
35
- | 'slowcash'
36
- | 'stateful'
37
- | 'custom';
38
-
39
- export interface ScriptDescriptor {
40
- address: string;
41
- scriptType: ScriptType;
42
- script: string;
43
- wotsRootPublicKey?: string;
44
- mastProof?: MMRProof;
45
- extraScripts?: Map<string, string>;
46
- stateVariables?: StateValue[];
47
- storeState?: boolean;
48
- verifyOutExpectations?: VerifyOutExpectation[];
49
- timelockBlock?: bigint;
50
- htlcHash?: string;
51
- htlcPreimage?: string;
52
- multisigKeys?: string[];
53
- multisigThreshold?: number;
54
- externalSignatures?: ExternalSignature[];
55
- }
56
-
57
- export interface ExternalSignature {
58
- publicKey: string;
59
- signature: string;
60
- proof?: MMRProof;
61
- signatureType: 'wots' | 'standard';
62
- validated?: boolean;
63
- }
64
-
65
- export interface ScriptCatalogEntry {
66
- address: string;
67
- script: string;
68
- scriptType: ScriptType;
69
- createdAt: number;
70
- lastUsed: number;
71
- }
72
-
73
- export interface ScriptProofResult {
74
- script: string;
75
- proof: MMRProof;
76
- serialized: Uint8Array;
77
- }
78
-
79
- export interface TransactionRoundState {
80
- round: number;
81
- previousRound: number;
82
- preservedPorts: number[];
83
- newStates: StateValue[];
84
- }
85
-
86
- export interface FlatMMRProofChunk {
87
- isLeft: boolean;
88
- data: Uint8Array;
89
- }
90
-
91
- export interface LegacyMMRProof {
92
- blockTime: bigint;
93
- proofChain: FlatMMRProofChunk[];
94
- }
95
-
96
- export function convertFlatChunkToSDK(chunk: FlatMMRProofChunk): MMRProofChunk {
97
- return {
98
- isLeft: chunk.isLeft,
99
- mmrData: { data: chunk.data, value: 0n }
100
- };
101
- }
102
-
103
- export function convertLegacyProofToSDK(legacy: LegacyMMRProof): { proof: MMRProof; blockTime: bigint } {
104
- return {
105
- proof: {
106
- chunks: legacy.proofChain.map(convertFlatChunkToSDK)
107
- },
108
- blockTime: legacy.blockTime
109
- };
110
- }
111
-
112
- export function createEmptyMMRProof(): MMRProof {
113
- return { chunks: [] };
114
- }
115
-
116
- export function createSignedByDescriptor(address: string, wotsRootPublicKey: string): ScriptDescriptor {
117
- return {
118
- address,
119
- scriptType: 'signedby',
120
- script: `RETURN SIGNEDBY(${kissHex(wotsRootPublicKey)})`,
121
- wotsRootPublicKey,
122
- mastProof: createEmptyMMRProof(),
123
- storeState: false
124
- };
125
- }
126
-
127
- export function createMultisigDescriptor(address: string, publicKey1: string, publicKey2: string, ownPublicKey: string): ScriptDescriptor {
128
- return {
129
- address,
130
- scriptType: 'multisig',
131
- script: `RETURN SIGNEDBY(${kissHex(publicKey1)}) AND SIGNEDBY(${kissHex(publicKey2)})`,
132
- wotsRootPublicKey: ownPublicKey,
133
- multisigKeys: [publicKey1, publicKey2],
134
- multisigThreshold: 2,
135
- mastProof: createEmptyMMRProof(),
136
- storeState: false
137
- };
138
- }
139
-
140
- export function createMofNMultisigDescriptor(address: string, threshold: number, publicKeys: string[], ownPublicKey: string): ScriptDescriptor {
141
- const formattedKeys = publicKeys.map(pk => kissHex(pk)).join(' ');
142
- return {
143
- address,
144
- scriptType: 'multisig_mofn',
145
- script: `RETURN MULTISIG(${threshold} ${formattedKeys})`,
146
- wotsRootPublicKey: ownPublicKey,
147
- multisigKeys: publicKeys,
148
- multisigThreshold: threshold,
149
- mastProof: createEmptyMMRProof(),
150
- storeState: false
151
- };
152
- }
153
-
154
- export function createTimelockDescriptor(address: string, publicKey: string, unlockBlock: bigint): ScriptDescriptor {
155
- return {
156
- address,
157
- scriptType: 'timelock',
158
- script: `RETURN SIGNEDBY(${kissHex(publicKey)}) AND @BLOCK GT ${unlockBlock}`,
159
- wotsRootPublicKey: publicKey,
160
- timelockBlock: unlockBlock,
161
- mastProof: createEmptyMMRProof(),
162
- storeState: false
163
- };
164
- }
165
-
166
- export function createHTLCDescriptor(address: string, ownerPublicKey: string, recipientPublicKey: string, hashLock: string, timeoutBlock: bigint, isOwner: boolean, preimage?: string): ScriptDescriptor {
167
- const script = `IF @BLOCK GT ${timeoutBlock} AND SIGNEDBY(${kissHex(ownerPublicKey)}) THEN RETURN TRUE ENDIF RETURN (SIGNEDBY(${kissHex(recipientPublicKey)}) AND SHA3(STATE(1)) EQ ${kissHex(hashLock)})`;
168
- const descriptor: ScriptDescriptor = {
169
- address,
170
- scriptType: 'htlc',
171
- script,
172
- wotsRootPublicKey: isOwner ? ownerPublicKey : recipientPublicKey,
173
- htlcHash: hashLock,
174
- timelockBlock: timeoutBlock,
175
- mastProof: createEmptyMMRProof(),
176
- storeState: false
177
- };
178
- if (preimage) {
179
- descriptor.htlcPreimage = preimage;
180
- descriptor.stateVariables = [{ port: 1, value: preimage, type: 'string' }];
181
- }
182
- return descriptor;
183
- }
184
-
185
- export function createMASTDescriptor(address: string, rootHash: string, branchScript: string, branchProof: string, wotsPublicKey?: string): ScriptDescriptor {
186
- return {
187
- address,
188
- scriptType: 'mast',
189
- script: `MAST ${kissHex(rootHash)}`,
190
- wotsRootPublicKey: wotsPublicKey,
191
- extraScripts: new Map([[branchScript, branchProof]]),
192
- mastProof: createEmptyMMRProof(),
193
- storeState: false
194
- };
195
- }
196
-
197
- export function createExchangeDescriptor(address: string, ownerPublicKey: string, desiredAddress: string, desiredAmount: string, desiredTokenId: string): ScriptDescriptor {
198
- const ownerPk = kissHex(ownerPublicKey);
199
- const script = `IF SIGNEDBY(PREVSTATE(0)) THEN RETURN TRUE ENDIF ASSERT VERIFYOUT(@INPUT PREVSTATE(1) PREVSTATE(2) PREVSTATE(3) TRUE) RETURN TRUE`;
200
- return {
201
- address,
202
- scriptType: 'exchange',
203
- script,
204
- wotsRootPublicKey: ownerPublicKey,
205
- stateVariables: [
206
- { port: 0, value: ownerPk, type: 'hex' },
207
- { port: 1, value: desiredAddress, type: 'hex' },
208
- { port: 2, value: desiredAmount, type: 'number' },
209
- { port: 3, value: desiredTokenId, type: 'hex' }
210
- ],
211
- verifyOutExpectations: [{
212
- inputIndex: '@INPUT',
213
- outputAddress: desiredAddress,
214
- amount: desiredAmount,
215
- tokenId: desiredTokenId,
216
- keepState: true
217
- }],
218
- mastProof: createEmptyMMRProof(),
219
- storeState: true
220
- };
221
- }
222
-
223
- export function createFlashCashDescriptor(address: string, ownerPublicKey: string, interestMultiplier: string = '1.01'): ScriptDescriptor {
224
- const script = `IF SIGNEDBY(PREVSTATE(1)) THEN RETURN TRUE ENDIF ASSERT SAMESTATE(1 1) RETURN VERIFYOUT(@INPUT @ADDRESS @AMOUNT*${interestMultiplier} @TOKENID TRUE)`;
225
- return {
226
- address,
227
- scriptType: 'flashcash',
228
- script,
229
- wotsRootPublicKey: ownerPublicKey,
230
- stateVariables: [{ port: 1, value: ownerPublicKey, type: 'hex' }],
231
- mastProof: createEmptyMMRProof(),
232
- storeState: true
233
- };
234
- }
235
-
236
- export function createSlowCashDescriptor(address: string, ownerPublicKey: string, withdrawalPercent: string = '0.9', cooldownBlocks: bigint = 10000n): ScriptDescriptor {
237
- const script = `IF @COINAGE LT ${cooldownBlocks} THEN RETURN FALSE ENDIF ASSERT SIGNEDBY(${kissHex(ownerPublicKey)}) AND VERIFYOUT(@INPUT @ADDRESS @AMOUNT*${withdrawalPercent} @TOKENID TRUE)`;
238
- return {
239
- address,
240
- scriptType: 'slowcash',
241
- script,
242
- wotsRootPublicKey: ownerPublicKey,
243
- timelockBlock: cooldownBlocks,
244
- mastProof: createEmptyMMRProof(),
245
- storeState: false
246
- };
247
- }
@@ -1,384 +0,0 @@
1
- import { sha3_256 } from '@noble/hashes/sha3.js';
2
- import type { MMRProof, MMRProofChunk } from '../mmr.js';
3
- import { serializeMMRProof } from '../mmr.js';
4
- import type { ScriptDescriptor, StateValue, ExternalSignature, ScriptProofResult, FlatMMRProofChunk, LegacyMMRProof } from './types.js';
5
- import { convertFlatChunkToSDK } from './types.js';
6
- import { mxToHex } from '../minima32.js';
7
-
8
- function hexToBytes(hex: string): Uint8Array {
9
- const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex;
10
- if (cleanHex.length % 2 !== 0) {
11
- throw new Error('Invalid hex string');
12
- }
13
- const bytes = new Uint8Array(cleanHex.length / 2);
14
- for (let i = 0; i < cleanHex.length; i += 2) {
15
- bytes[i / 2] = parseInt(cleanHex.slice(i, i + 2), 16);
16
- }
17
- return bytes;
18
- }
19
-
20
- function normalizeHexValue(value: string): string {
21
- if (!value) return '0x00';
22
- const trimmed = value.trim();
23
- if (trimmed.toLowerCase().startsWith('mx')) {
24
- return mxToHex(trimmed);
25
- }
26
- return trimmed.startsWith('0x') ? trimmed : '0x' + trimmed;
27
- }
28
-
29
- function bytesToHex(bytes: Uint8Array): string {
30
- return '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
31
- }
32
-
33
- function concat(...arrays: Uint8Array[]): Uint8Array {
34
- const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
35
- const result = new Uint8Array(totalLength);
36
- let offset = 0;
37
- for (const arr of arrays) {
38
- result.set(arr, offset);
39
- offset += arr.length;
40
- }
41
- return result;
42
- }
43
-
44
- export function encodeMiniNumber(value: bigint, scale: number = 0): Uint8Array {
45
- if (typeof value !== 'bigint') {
46
- throw new Error(`encodeMiniNumber requires bigint, got ${typeof value}`);
47
- }
48
-
49
- if (value === 0n) {
50
- return new Uint8Array([scale & 0xff, 1, 0]);
51
- }
52
-
53
- if (value < 0n) {
54
- throw new Error(`encodeMiniNumber does not support negative values: ${value}`);
55
- }
56
-
57
- let hex = value.toString(16);
58
- if (hex.length % 2 !== 0) {
59
- hex = '0' + hex;
60
- }
61
-
62
- let unscaledBytes = hexToBytes(hex);
63
-
64
- if (unscaledBytes.length > 0 && (unscaledBytes[0] & 0x80) !== 0) {
65
- const withLeadingZero = new Uint8Array(unscaledBytes.length + 1);
66
- withLeadingZero[0] = 0x00;
67
- withLeadingZero.set(unscaledBytes, 1);
68
- unscaledBytes = withLeadingZero;
69
- }
70
-
71
- const length = unscaledBytes.length;
72
-
73
- if (length > 32) {
74
- throw new Error(`MiniNumber data too large: ${length} bytes (max 32)`);
75
- }
76
-
77
- const result = new Uint8Array(1 + 1 + length);
78
- result[0] = scale & 0xff;
79
- result[1] = length & 0xff;
80
- result.set(unscaledBytes, 2);
81
-
82
- return result;
83
- }
84
-
85
- export function encodeMiniData(data: Uint8Array): Uint8Array {
86
- const length = data.length;
87
- const lengthBytes = new Uint8Array([
88
- (length >> 24) & 0xff,
89
- (length >> 16) & 0xff,
90
- (length >> 8) & 0xff,
91
- length & 0xff
92
- ]);
93
- return concat(lengthBytes, data);
94
- }
95
-
96
- export function encodeMiniString(str: string): Uint8Array {
97
- const utf8Bytes = new TextEncoder().encode(str);
98
- return encodeMiniData(utf8Bytes);
99
- }
100
-
101
- function encodeMiniByte(value: boolean): Uint8Array {
102
- return new Uint8Array([value ? 1 : 0]);
103
- }
104
-
105
- export function serializeMMRProofChunk(chunk: MMRProofChunk): Uint8Array {
106
- const parts: Uint8Array[] = [];
107
-
108
- parts.push(encodeMiniByte(chunk.isLeft));
109
-
110
- parts.push(encodeMiniData(chunk.mmrData.data));
111
-
112
- parts.push(encodeMiniNumber(chunk.mmrData.value));
113
-
114
- return concat(...parts);
115
- }
116
-
117
- export function serializeRealMMRProof(proof: MMRProof, blockTime: bigint = 0n): Uint8Array {
118
- return serializeMMRProof(proof, blockTime);
119
- }
120
-
121
- export function parseMMRProofFromHex(proofHex: string): { proof: MMRProof; blockTime: bigint } {
122
- const bytes = hexToBytes(proofHex);
123
- let offset = 0;
124
-
125
- const { value: blockTime, bytesRead: btRead } = readMiniNumber(bytes, offset);
126
- offset += btRead;
127
-
128
- const { value: chainLength, bytesRead: clRead } = readMiniNumber(bytes, offset);
129
- offset += clRead;
130
-
131
- const chunks: MMRProofChunk[] = [];
132
- for (let i = 0; i < Number(chainLength); i++) {
133
- const { chunk, bytesRead } = readMMRProofChunk(bytes, offset);
134
- chunks.push(chunk);
135
- offset += bytesRead;
136
- }
137
-
138
- return { proof: { chunks }, blockTime };
139
- }
140
-
141
- function readMiniNumber(bytes: Uint8Array, offset: number): { value: bigint; bytesRead: number } {
142
- const scale = bytes[offset];
143
- const length = (bytes[offset + 1] << 24) | (bytes[offset + 2] << 16) |
144
- (bytes[offset + 3] << 8) | bytes[offset + 4];
145
-
146
- if (length === 0) {
147
- return { value: 0n, bytesRead: 5 };
148
- }
149
-
150
- const dataBytes = bytes.slice(offset + 5, offset + 5 + length);
151
- let value = 0n;
152
- for (const b of dataBytes) {
153
- value = (value << 8n) | BigInt(b);
154
- }
155
-
156
- return { value, bytesRead: 5 + length };
157
- }
158
-
159
- function readMMRProofChunk(bytes: Uint8Array, offset: number): { chunk: MMRProofChunk; bytesRead: number } {
160
- let pos = offset;
161
-
162
- const isLeft = bytes[pos] === 1;
163
- pos += 1;
164
-
165
- const dataLength = (bytes[pos] << 24) | (bytes[pos + 1] << 16) |
166
- (bytes[pos + 2] << 8) | bytes[pos + 3];
167
- pos += 4;
168
-
169
- const data = bytes.slice(pos, pos + dataLength);
170
- pos += dataLength;
171
-
172
- const { value, bytesRead: valueRead } = readMiniNumber(bytes, pos);
173
- pos += valueRead;
174
-
175
- return {
176
- chunk: { isLeft, mmrData: { data, value } },
177
- bytesRead: pos - offset
178
- };
179
- }
180
-
181
- export function serializeScriptProofWithProof(script: string, proof: MMRProof, blockTime: bigint = 0n): Uint8Array {
182
- const scriptBytes = encodeMiniString(script);
183
- const proofBytes = serializeRealMMRProof(proof, blockTime);
184
- return concat(scriptBytes, proofBytes);
185
- }
186
-
187
- export const STATETYPE_HEX = 1;
188
- export const STATETYPE_NUMBER = 2;
189
- export const STATETYPE_STRING = 4;
190
- export const STATETYPE_BOOL = 8;
191
-
192
- export function encodeStateValue(stateValue: StateValue): Uint8Array {
193
- if (stateValue.port < 0 || stateValue.port > 255) {
194
- throw new Error(`StateVariable port must be 0-255, got ${stateValue.port}`);
195
- }
196
-
197
- const portByte = new Uint8Array([stateValue.port]);
198
-
199
- let typeByte: Uint8Array;
200
- let dataBytes: Uint8Array;
201
-
202
- switch (stateValue.type) {
203
- case 'bool':
204
- typeByte = new Uint8Array([STATETYPE_BOOL]);
205
- if (typeof stateValue.value === 'boolean') {
206
- dataBytes = new Uint8Array([stateValue.value ? 1 : 0]);
207
- } else if (typeof stateValue.value === 'string') {
208
- const boolValue = stateValue.value.toUpperCase() === 'TRUE';
209
- dataBytes = new Uint8Array([boolValue ? 1 : 0]);
210
- } else {
211
- throw new Error(`Invalid bool state value: ${stateValue.value}`);
212
- }
213
- break;
214
-
215
- case 'number':
216
- typeByte = new Uint8Array([STATETYPE_NUMBER]);
217
- if (typeof stateValue.value === 'bigint') {
218
- dataBytes = encodeMiniNumber(stateValue.value);
219
- } else if (typeof stateValue.value === 'string') {
220
- const numValue = BigInt(stateValue.value);
221
- dataBytes = encodeMiniNumber(numValue);
222
- } else {
223
- throw new Error(`Invalid number state value: ${stateValue.value}`);
224
- }
225
- break;
226
-
227
- case 'hex':
228
- typeByte = new Uint8Array([STATETYPE_HEX]);
229
- if (typeof stateValue.value === 'string') {
230
- const normalizedHex = normalizeHexValue(stateValue.value);
231
- dataBytes = encodeMiniData(hexToBytes(normalizedHex));
232
- } else if (stateValue.value instanceof Uint8Array) {
233
- dataBytes = encodeMiniData(stateValue.value);
234
- } else {
235
- throw new Error(`Invalid hex state value: ${stateValue.value}`);
236
- }
237
- break;
238
-
239
- case 'string':
240
- typeByte = new Uint8Array([STATETYPE_STRING]);
241
- if (typeof stateValue.value === 'string') {
242
- let bracketedValue = stateValue.value;
243
- if (!stateValue.value.startsWith('[') || !stateValue.value.endsWith(']')) {
244
- bracketedValue = `[${stateValue.value}]`;
245
- }
246
- dataBytes = encodeMiniString(bracketedValue);
247
- } else {
248
- throw new Error(`Invalid string state value: ${stateValue.value}`);
249
- }
250
- break;
251
-
252
- default:
253
- throw new Error(`Unknown state value type: ${(stateValue as any).type}`);
254
- }
255
-
256
- return concat(portByte, typeByte, dataBytes);
257
- }
258
-
259
- export function serializeStateVariables(stateValues: StateValue[]): Uint8Array {
260
- const parts: Uint8Array[] = [];
261
-
262
- const countBytes = encodeMiniNumber(BigInt(stateValues.length));
263
- parts.push(countBytes);
264
-
265
- const sorted = [...stateValues].sort((a, b) => a.port - b.port);
266
-
267
- for (const sv of sorted) {
268
- parts.push(encodeStateValue(sv));
269
- }
270
-
271
- return concat(...parts);
272
- }
273
-
274
- export function buildScriptProofFromDescriptor(descriptor: ScriptDescriptor): ScriptProofResult {
275
- const proof = descriptor.mastProof || { chunks: [] };
276
- const serialized = serializeScriptProofWithProof(descriptor.script, proof);
277
-
278
- return {
279
- script: descriptor.script,
280
- proof,
281
- serialized
282
- };
283
- }
284
-
285
- export function deduplicateScriptDescriptors(
286
- descriptors: ScriptDescriptor[]
287
- ): Map<string, ScriptDescriptor> {
288
- const unique = new Map<string, ScriptDescriptor>();
289
-
290
- for (const desc of descriptors) {
291
- const normalizedAddr = desc.address.toLowerCase();
292
- if (!unique.has(normalizedAddr)) {
293
- unique.set(normalizedAddr, desc);
294
- }
295
- }
296
-
297
- return unique;
298
- }
299
-
300
- export function serializeExtraScripts(
301
- extraScripts: Map<string, string>
302
- ): Uint8Array {
303
- const parts: Uint8Array[] = [];
304
-
305
- const countBytes = encodeMiniNumber(BigInt(extraScripts.size));
306
- parts.push(countBytes);
307
-
308
- for (const [script, proofHex] of extraScripts) {
309
- const { proof, blockTime } = proofHex
310
- ? parseMMRProofFromHex(proofHex)
311
- : { proof: { chunks: [] }, blockTime: 0n };
312
- parts.push(serializeScriptProofWithProof(script, proof, blockTime));
313
- }
314
-
315
- return concat(...parts);
316
- }
317
-
318
- export function aggregateSignatures(
319
- totemSignature: {
320
- publicKey: Uint8Array;
321
- signature: Uint8Array;
322
- },
323
- externalSignatures: ExternalSignature[]
324
- ): Uint8Array[] {
325
- const allSigProofs: Uint8Array[] = [];
326
-
327
- allSigProofs.push(serializeSignatureProof(
328
- totemSignature.publicKey,
329
- totemSignature.signature,
330
- { chunks: [] }
331
- ));
332
-
333
- for (const extSig of externalSignatures) {
334
- if (!extSig.validated) {
335
- console.warn(`[AggregateSignatures] Skipping unvalidated signature from ${extSig.publicKey}`);
336
- continue;
337
- }
338
-
339
- const proof = extSig.proof || { chunks: [] };
340
- allSigProofs.push(serializeSignatureProof(
341
- hexToBytes(extSig.publicKey),
342
- hexToBytes(extSig.signature),
343
- proof
344
- ));
345
- }
346
-
347
- return allSigProofs;
348
- }
349
-
350
- function serializeSignatureProof(
351
- publicKey: Uint8Array,
352
- signature: Uint8Array,
353
- proof: MMRProof
354
- ): Uint8Array {
355
- const parts: Uint8Array[] = [];
356
-
357
- parts.push(encodeMiniData(publicKey));
358
- parts.push(encodeMiniData(signature));
359
- parts.push(serializeRealMMRProof(proof));
360
-
361
- return concat(...parts);
362
- }
363
-
364
- export function validateExternalSignature(
365
- signature: ExternalSignature,
366
- transactionDigest: Uint8Array
367
- ): boolean {
368
- if (!signature.publicKey || !signature.signature) {
369
- return false;
370
- }
371
-
372
- console.log(`[ValidateSignature] Validating signature from ${signature.publicKey.substring(0, 16)}...`);
373
-
374
- return true;
375
- }
376
-
377
- export function computeScriptAddress(script: string): string {
378
- const cleanScript = script.trim().toUpperCase();
379
- const scriptBytes = new TextEncoder().encode(cleanScript);
380
- const hashBytes = sha3_256(scriptBytes);
381
- return bytesToHex(hashBytes);
382
- }
383
-
384
- export { concat };