@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.
- 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.d.ts +2 -2
- package/dist/wots.js +94 -64
- package/package.json +50 -6
- package/src/Streamable.d.ts +0 -268
- package/src/Streamable.js +0 -416
- 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 -332
- 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 -157
- package/src/mmr.js +0 -340
- 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.d.ts +0 -81
- package/src/scripts/types.js +0 -145
- 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/transaction.ts
DELETED
|
@@ -1,430 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transaction Serialization & Digest Computation
|
|
3
|
-
*
|
|
4
|
-
* Port of the extension's MinimaTransactionBuilder serialization logic
|
|
5
|
-
* to the SDK core for full parity with the Totem wallet extension.
|
|
6
|
-
*
|
|
7
|
-
* Matches Minima Java's Transaction.writeDataStream() and Coin.writeDataStream() exactly.
|
|
8
|
-
*
|
|
9
|
-
* CRITICAL: Before computing the transaction digest for signing, you MUST call
|
|
10
|
-
* precomputeTransactionCoinID() to set output coin IDs. Without this, the signed
|
|
11
|
-
* digest won't match what the Minima node verifies, causing allsignaturesvalid=false.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import { sha3_256 } from '@noble/hashes/sha3.js';
|
|
15
|
-
import {
|
|
16
|
-
writeMiniNumber,
|
|
17
|
-
writeMiniData,
|
|
18
|
-
writeHashToStream,
|
|
19
|
-
writeMiniByte,
|
|
20
|
-
writeMMREntryNumber,
|
|
21
|
-
concat,
|
|
22
|
-
hexToBytes,
|
|
23
|
-
bytesToHex,
|
|
24
|
-
} from './Streamable.js';
|
|
25
|
-
|
|
26
|
-
const ZERO_TXPOWID = new Uint8Array([0x00]);
|
|
27
|
-
|
|
28
|
-
const STATETYPE_HEX = 1;
|
|
29
|
-
const STATETYPE_NUMBER = 2;
|
|
30
|
-
const STATETYPE_STRING = 4;
|
|
31
|
-
const STATETYPE_BOOL = 8;
|
|
32
|
-
|
|
33
|
-
export interface MinimaTransaction {
|
|
34
|
-
linkHash: Uint8Array;
|
|
35
|
-
inputs: MinimaCoin[];
|
|
36
|
-
outputs: MinimaCoin[];
|
|
37
|
-
state: StateVariable[];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface MinimaCoin {
|
|
41
|
-
coinId: Uint8Array;
|
|
42
|
-
address: Uint8Array;
|
|
43
|
-
amount: string;
|
|
44
|
-
tokenId: Uint8Array;
|
|
45
|
-
token: MinimaToken | null;
|
|
46
|
-
storeState: boolean;
|
|
47
|
-
state: StateVariable[] | RawStateVariable[];
|
|
48
|
-
mmrEntryNumber: bigint;
|
|
49
|
-
spent: boolean;
|
|
50
|
-
created: bigint;
|
|
51
|
-
rawAmountBytes?: Uint8Array;
|
|
52
|
-
rawMmrEntryBytes?: Uint8Array;
|
|
53
|
-
rawBlockCreatedBytes?: Uint8Array;
|
|
54
|
-
rawTokenData?: Uint8Array;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface ParsedMiniNumber {
|
|
58
|
-
scale: number;
|
|
59
|
-
unscaledValue: bigint;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export interface MinimaToken {
|
|
63
|
-
coinId: Uint8Array;
|
|
64
|
-
scale: number;
|
|
65
|
-
totalAmount: bigint;
|
|
66
|
-
name: Uint8Array;
|
|
67
|
-
script: Uint8Array;
|
|
68
|
-
created?: bigint;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export interface StateVariable {
|
|
72
|
-
port: number;
|
|
73
|
-
value: string | bigint | boolean | Uint8Array;
|
|
74
|
-
type: 'bool' | 'number' | 'hex' | 'string';
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export interface RawStateVariable {
|
|
78
|
-
port: number;
|
|
79
|
-
type: number;
|
|
80
|
-
rawData: Uint8Array;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export interface CoinProofData {
|
|
84
|
-
coinId: Uint8Array;
|
|
85
|
-
address: Uint8Array;
|
|
86
|
-
rawAmountBytes: Uint8Array;
|
|
87
|
-
tokenId: Uint8Array;
|
|
88
|
-
storeState: boolean;
|
|
89
|
-
mmrEntryNumber: bigint;
|
|
90
|
-
rawMmrEntryBytes: Uint8Array;
|
|
91
|
-
spent: boolean;
|
|
92
|
-
blockCreated: bigint;
|
|
93
|
-
rawBlockCreatedBytes: Uint8Array;
|
|
94
|
-
state: RawStateVariable[];
|
|
95
|
-
rawTokenData?: Uint8Array;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface SpendableCoinInput {
|
|
99
|
-
coinId: string;
|
|
100
|
-
address: string;
|
|
101
|
-
amount: string;
|
|
102
|
-
tokenId: string;
|
|
103
|
-
rawAmountBytes?: Uint8Array;
|
|
104
|
-
coinProofData?: CoinProofData;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export interface TransactionBuildResult {
|
|
108
|
-
transaction: MinimaTransaction;
|
|
109
|
-
digestTx: Uint8Array;
|
|
110
|
-
digestTxHex: string;
|
|
111
|
-
serialized: Uint8Array;
|
|
112
|
-
serializedHex: string;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function parseDecimalToMiniNumber(decimal: string): ParsedMiniNumber {
|
|
116
|
-
if (!decimal || decimal === '') {
|
|
117
|
-
return { scale: 0, unscaledValue: 0n };
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (decimal.includes('e') || decimal.includes('E')) {
|
|
121
|
-
throw new Error(`Scientific notation not supported: "${decimal}". Convert to plain decimal first.`);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
let isNegative = false;
|
|
125
|
-
let cleaned = decimal.trim();
|
|
126
|
-
if (cleaned.startsWith('-')) {
|
|
127
|
-
isNegative = true;
|
|
128
|
-
cleaned = cleaned.slice(1);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const dotIndex = cleaned.indexOf('.');
|
|
132
|
-
|
|
133
|
-
let scale: number;
|
|
134
|
-
let unscaledStr: string;
|
|
135
|
-
|
|
136
|
-
if (dotIndex === -1) {
|
|
137
|
-
scale = 0;
|
|
138
|
-
unscaledStr = cleaned;
|
|
139
|
-
} else {
|
|
140
|
-
const wholePart = cleaned.slice(0, dotIndex);
|
|
141
|
-
const fracPart = cleaned.slice(dotIndex + 1);
|
|
142
|
-
scale = fracPart.length;
|
|
143
|
-
unscaledStr = wholePart + fracPart;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
unscaledStr = unscaledStr.replace(/^0+/, '') || '0';
|
|
147
|
-
|
|
148
|
-
let unscaledValue = BigInt(unscaledStr);
|
|
149
|
-
if (isNegative && unscaledValue !== 0n) {
|
|
150
|
-
unscaledValue = -unscaledValue;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return { scale, unscaledValue };
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function encodeParsedMiniNumber(parsed: ParsedMiniNumber): Uint8Array {
|
|
157
|
-
return writeMiniNumber(parsed.unscaledValue, parsed.scale);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
function normalizeAddressToHex(addr: string): string {
|
|
161
|
-
if (!addr) {
|
|
162
|
-
return '0x00';
|
|
163
|
-
}
|
|
164
|
-
const trimmed = addr.trim();
|
|
165
|
-
|
|
166
|
-
const hexAddr = trimmed.startsWith('0x') ? trimmed : '0x' + trimmed;
|
|
167
|
-
const cleanHex = hexAddr.slice(2);
|
|
168
|
-
if (!/^[0-9a-fA-F]*$/.test(cleanHex)) {
|
|
169
|
-
throw new Error(`Invalid hex address: contains non-hex characters`);
|
|
170
|
-
}
|
|
171
|
-
if (cleanHex.length % 2 !== 0) {
|
|
172
|
-
throw new Error(`Invalid hex address: odd length (${cleanHex.length} chars)`);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return hexAddr;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
function serializeStateVariable(sv: StateVariable): Uint8Array {
|
|
179
|
-
if (sv.port < 0 || sv.port > 255) {
|
|
180
|
-
throw new Error(`StateVariable port must be 0-255, got ${sv.port}`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const portByte = new Uint8Array([sv.port]);
|
|
184
|
-
|
|
185
|
-
let typeByte: Uint8Array;
|
|
186
|
-
let dataBytes: Uint8Array;
|
|
187
|
-
|
|
188
|
-
switch (sv.type) {
|
|
189
|
-
case 'bool':
|
|
190
|
-
typeByte = new Uint8Array([STATETYPE_BOOL]);
|
|
191
|
-
if (typeof sv.value === 'boolean') {
|
|
192
|
-
dataBytes = new Uint8Array([sv.value ? 1 : 0]);
|
|
193
|
-
} else if (typeof sv.value === 'string') {
|
|
194
|
-
dataBytes = new Uint8Array([sv.value.toUpperCase() === 'TRUE' ? 1 : 0]);
|
|
195
|
-
} else {
|
|
196
|
-
throw new Error(`Invalid bool StateVariable value: ${sv.value}`);
|
|
197
|
-
}
|
|
198
|
-
break;
|
|
199
|
-
|
|
200
|
-
case 'number':
|
|
201
|
-
typeByte = new Uint8Array([STATETYPE_NUMBER]);
|
|
202
|
-
if (typeof sv.value === 'bigint') {
|
|
203
|
-
dataBytes = writeMiniNumber(sv.value);
|
|
204
|
-
} else if (typeof sv.value === 'string') {
|
|
205
|
-
dataBytes = writeMiniNumber(BigInt(sv.value));
|
|
206
|
-
} else {
|
|
207
|
-
throw new Error(`Invalid number StateVariable value: ${sv.value}`);
|
|
208
|
-
}
|
|
209
|
-
break;
|
|
210
|
-
|
|
211
|
-
case 'hex':
|
|
212
|
-
typeByte = new Uint8Array([STATETYPE_HEX]);
|
|
213
|
-
if (typeof sv.value === 'string') {
|
|
214
|
-
const normalizedHex = normalizeAddressToHex(sv.value);
|
|
215
|
-
dataBytes = writeMiniData(hexToBytes(normalizedHex));
|
|
216
|
-
} else if (sv.value instanceof Uint8Array) {
|
|
217
|
-
dataBytes = writeMiniData(sv.value);
|
|
218
|
-
} else {
|
|
219
|
-
throw new Error(`Invalid hex StateVariable value: ${sv.value}`);
|
|
220
|
-
}
|
|
221
|
-
break;
|
|
222
|
-
|
|
223
|
-
case 'string':
|
|
224
|
-
typeByte = new Uint8Array([STATETYPE_STRING]);
|
|
225
|
-
if (typeof sv.value === 'string') {
|
|
226
|
-
let bracketedValue = sv.value;
|
|
227
|
-
if (!sv.value.startsWith('[') || !sv.value.endsWith(']')) {
|
|
228
|
-
bracketedValue = `[${sv.value}]`;
|
|
229
|
-
}
|
|
230
|
-
const utf8Bytes = new TextEncoder().encode(bracketedValue);
|
|
231
|
-
dataBytes = writeMiniData(utf8Bytes);
|
|
232
|
-
} else {
|
|
233
|
-
throw new Error(`Invalid string StateVariable value: ${sv.value}`);
|
|
234
|
-
}
|
|
235
|
-
break;
|
|
236
|
-
|
|
237
|
-
default:
|
|
238
|
-
throw new Error(`Unknown StateVariable type: ${(sv as any).type}`);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return concat(portByte, typeByte, dataBytes);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
function serializeToken(token: MinimaToken): Uint8Array {
|
|
245
|
-
// Java Token.writeDataStream() order: coinId, script, scale, totalAmount, name, created
|
|
246
|
-
const parts: Uint8Array[] = [];
|
|
247
|
-
parts.push(writeHashToStream(token.coinId));
|
|
248
|
-
parts.push(writeMiniData(token.script));
|
|
249
|
-
parts.push(writeMiniNumber(BigInt(token.scale)));
|
|
250
|
-
parts.push(writeMiniNumber(token.totalAmount, 0));
|
|
251
|
-
parts.push(writeMiniData(token.name));
|
|
252
|
-
parts.push(writeMiniNumber(token.created ?? 0n));
|
|
253
|
-
return concat(...parts);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export function serializeCoin(coin: MinimaCoin): Uint8Array {
|
|
257
|
-
const parts: Uint8Array[] = [];
|
|
258
|
-
|
|
259
|
-
parts.push(writeHashToStream(coin.coinId));
|
|
260
|
-
parts.push(writeHashToStream(coin.address));
|
|
261
|
-
|
|
262
|
-
let amountBytes: Uint8Array;
|
|
263
|
-
if (coin.rawAmountBytes && coin.rawAmountBytes.length > 0) {
|
|
264
|
-
amountBytes = coin.rawAmountBytes;
|
|
265
|
-
} else {
|
|
266
|
-
const parsedAmount = parseDecimalToMiniNumber(coin.amount);
|
|
267
|
-
amountBytes = encodeParsedMiniNumber(parsedAmount);
|
|
268
|
-
}
|
|
269
|
-
parts.push(amountBytes);
|
|
270
|
-
|
|
271
|
-
parts.push(writeMiniData(coin.tokenId));
|
|
272
|
-
parts.push(writeMiniByte(coin.storeState));
|
|
273
|
-
|
|
274
|
-
let mmrBytes: Uint8Array;
|
|
275
|
-
if (coin.rawMmrEntryBytes && coin.rawMmrEntryBytes.length > 0) {
|
|
276
|
-
mmrBytes = coin.rawMmrEntryBytes;
|
|
277
|
-
} else {
|
|
278
|
-
mmrBytes = writeMMREntryNumber(coin.mmrEntryNumber);
|
|
279
|
-
}
|
|
280
|
-
parts.push(mmrBytes);
|
|
281
|
-
|
|
282
|
-
parts.push(writeMiniByte(coin.spent));
|
|
283
|
-
|
|
284
|
-
let createdBytes: Uint8Array;
|
|
285
|
-
if (coin.rawBlockCreatedBytes && coin.rawBlockCreatedBytes.length > 0) {
|
|
286
|
-
createdBytes = coin.rawBlockCreatedBytes;
|
|
287
|
-
} else {
|
|
288
|
-
createdBytes = writeMiniNumber(coin.created);
|
|
289
|
-
}
|
|
290
|
-
parts.push(createdBytes);
|
|
291
|
-
|
|
292
|
-
const stateCountBytes = writeMiniNumber(BigInt(coin.state.length));
|
|
293
|
-
parts.push(stateCountBytes);
|
|
294
|
-
|
|
295
|
-
for (const sv of coin.state) {
|
|
296
|
-
let svBytes: Uint8Array;
|
|
297
|
-
if ('rawData' in sv) {
|
|
298
|
-
const raw = sv as RawStateVariable;
|
|
299
|
-
const portByte = new Uint8Array([raw.port]);
|
|
300
|
-
const typeByte = new Uint8Array([raw.type]);
|
|
301
|
-
svBytes = concat(portByte, typeByte, raw.rawData);
|
|
302
|
-
} else {
|
|
303
|
-
svBytes = serializeStateVariable(sv as StateVariable);
|
|
304
|
-
}
|
|
305
|
-
parts.push(svBytes);
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (coin.rawTokenData && coin.rawTokenData.length > 0) {
|
|
309
|
-
parts.push(writeMiniByte(true));
|
|
310
|
-
parts.push(coin.rawTokenData);
|
|
311
|
-
} else if (coin.token) {
|
|
312
|
-
parts.push(writeMiniByte(true));
|
|
313
|
-
parts.push(serializeToken(coin.token));
|
|
314
|
-
} else {
|
|
315
|
-
parts.push(writeMiniByte(false));
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
return concat(...parts);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
export function serializeTransaction(tx: MinimaTransaction): Uint8Array {
|
|
322
|
-
const parts: Uint8Array[] = [];
|
|
323
|
-
|
|
324
|
-
parts.push(writeMiniNumber(BigInt(tx.inputs.length)));
|
|
325
|
-
|
|
326
|
-
for (const input of tx.inputs) {
|
|
327
|
-
parts.push(serializeCoin(input));
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
parts.push(writeMiniNumber(BigInt(tx.outputs.length)));
|
|
331
|
-
|
|
332
|
-
for (const output of tx.outputs) {
|
|
333
|
-
parts.push(serializeCoin(output));
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
parts.push(writeMiniNumber(BigInt(tx.state.length)));
|
|
337
|
-
|
|
338
|
-
for (const sv of tx.state) {
|
|
339
|
-
parts.push(serializeStateVariable(sv));
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
parts.push(writeHashToStream(tx.linkHash));
|
|
343
|
-
|
|
344
|
-
return concat(...parts);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
export function computeTransactionDigest(tx: MinimaTransaction): Uint8Array {
|
|
348
|
-
const serialized = serializeTransaction(tx);
|
|
349
|
-
return sha3_256(serialized);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
export function precomputeTransactionCoinID(tx: MinimaTransaction): void {
|
|
353
|
-
if (tx.inputs.length === 0) return;
|
|
354
|
-
|
|
355
|
-
const baseCoinId = tx.inputs[0].coinId;
|
|
356
|
-
|
|
357
|
-
if (baseCoinId.length < 2) {
|
|
358
|
-
throw new Error(
|
|
359
|
-
`Cannot precompute output coinIDs: input[0].coinId is ${baseCoinId.length} byte(s) ` +
|
|
360
|
-
`(placeholder?). Real coinId from CoinProof required for signing.`
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
for (let i = 0; i < tx.outputs.length; i++) {
|
|
365
|
-
const baseCoinIdStream = writeMiniData(baseCoinId);
|
|
366
|
-
const outputIndexStream = writeMiniNumber(BigInt(i));
|
|
367
|
-
const combined = concat(baseCoinIdStream, outputIndexStream);
|
|
368
|
-
tx.outputs[i].coinId = sha3_256(combined);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
export function createDefaultTransaction(): MinimaTransaction {
|
|
373
|
-
return {
|
|
374
|
-
linkHash: ZERO_TXPOWID,
|
|
375
|
-
inputs: [],
|
|
376
|
-
outputs: [],
|
|
377
|
-
state: [],
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
export function buildMinimaCoin(opts: {
|
|
382
|
-
coinId?: Uint8Array;
|
|
383
|
-
address: Uint8Array;
|
|
384
|
-
amount: string;
|
|
385
|
-
tokenId?: Uint8Array;
|
|
386
|
-
storeState?: boolean;
|
|
387
|
-
state?: StateVariable[];
|
|
388
|
-
mmrEntryNumber?: bigint;
|
|
389
|
-
spent?: boolean;
|
|
390
|
-
created?: bigint;
|
|
391
|
-
rawAmountBytes?: Uint8Array;
|
|
392
|
-
rawMmrEntryBytes?: Uint8Array;
|
|
393
|
-
rawBlockCreatedBytes?: Uint8Array;
|
|
394
|
-
coinProofData?: CoinProofData;
|
|
395
|
-
}): MinimaCoin {
|
|
396
|
-
if (opts.coinProofData) {
|
|
397
|
-
const cpd = opts.coinProofData;
|
|
398
|
-
return {
|
|
399
|
-
coinId: cpd.coinId,
|
|
400
|
-
address: cpd.address,
|
|
401
|
-
amount: opts.amount,
|
|
402
|
-
tokenId: cpd.tokenId,
|
|
403
|
-
token: null,
|
|
404
|
-
storeState: cpd.storeState,
|
|
405
|
-
state: cpd.state,
|
|
406
|
-
mmrEntryNumber: cpd.mmrEntryNumber,
|
|
407
|
-
spent: cpd.spent,
|
|
408
|
-
created: cpd.blockCreated,
|
|
409
|
-
rawAmountBytes: cpd.rawAmountBytes,
|
|
410
|
-
rawMmrEntryBytes: cpd.rawMmrEntryBytes,
|
|
411
|
-
rawBlockCreatedBytes: cpd.rawBlockCreatedBytes,
|
|
412
|
-
};
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return {
|
|
416
|
-
coinId: opts.coinId || new Uint8Array([0x00]),
|
|
417
|
-
address: opts.address,
|
|
418
|
-
amount: opts.amount,
|
|
419
|
-
tokenId: opts.tokenId || new Uint8Array([0x00]),
|
|
420
|
-
token: null,
|
|
421
|
-
storeState: opts.storeState ?? false,
|
|
422
|
-
state: opts.state || [],
|
|
423
|
-
mmrEntryNumber: opts.mmrEntryNumber ?? 0n,
|
|
424
|
-
spent: opts.spent ?? false,
|
|
425
|
-
created: opts.created ?? 0n,
|
|
426
|
-
rawAmountBytes: opts.rawAmountBytes,
|
|
427
|
-
rawMmrEntryBytes: opts.rawMmrEntryBytes,
|
|
428
|
-
rawBlockCreatedBytes: opts.rawBlockCreatedBytes,
|
|
429
|
-
};
|
|
430
|
-
}
|