@totemsdk/core 1.2.10 → 1.3.0

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 (56) hide show
  1. package/README.md +58 -0
  2. package/dist/address-derivation.d.ts +36 -0
  3. package/dist/address-derivation.js +54 -0
  4. package/dist/bip39.js +1 -1
  5. package/dist/bytes.d.ts +11 -0
  6. package/dist/bytes.js +39 -0
  7. package/dist/canonical-hash.d.ts +1 -0
  8. package/dist/canonical-hash.js +12 -0
  9. package/dist/canonical.d.ts +6 -1
  10. package/dist/canonical.js +6 -5
  11. package/dist/cjs/address-derivation.d.ts +36 -0
  12. package/dist/cjs/address-derivation.js +60 -0
  13. package/dist/cjs/bytes.d.ts +11 -0
  14. package/dist/cjs/bytes.js +44 -0
  15. package/dist/cjs/canonical-hash.d.ts +1 -0
  16. package/dist/cjs/canonical-hash.js +15 -0
  17. package/dist/cjs/canonical.d.ts +6 -1
  18. package/dist/cjs/canonical.js +6 -6
  19. package/dist/cjs/index.d.ts +9 -6
  20. package/dist/cjs/index.js +73 -53
  21. package/dist/cjs/lease/LeaseStore.d.ts +8 -1
  22. package/dist/cjs/lease/LeaseStore.js +92 -22
  23. package/dist/cjs/lease/WatermarkStore.js +6 -12
  24. package/dist/cjs/legacy.d.ts +15 -6
  25. package/dist/cjs/legacy.js +15 -6
  26. package/dist/cjs/scripts/contract-helpers.js +3 -3
  27. package/dist/cjs/scripts/witness-serializer.d.ts +1 -1
  28. package/dist/cjs/scripts/witness-serializer.js +28 -5
  29. package/dist/cjs/transaction.d.ts +22 -0
  30. package/dist/cjs/transaction.js +157 -6
  31. package/dist/cjs/tx/TransactionReceiptStore.js +30 -21
  32. package/dist/cjs/wasm-sync.d.ts +3 -3
  33. package/dist/cjs/wasm-sync.js +10 -3
  34. package/dist/index.d.ts +9 -6
  35. package/dist/index.js +21 -15
  36. package/dist/javaStreamables.js +1 -1
  37. package/dist/lease/LeaseStore.d.ts +8 -1
  38. package/dist/lease/LeaseStore.js +92 -22
  39. package/dist/lease/WatermarkStore.js +6 -12
  40. package/dist/legacy.d.ts +15 -6
  41. package/dist/legacy.js +15 -6
  42. package/dist/minima32.js +1 -1
  43. package/dist/mmr.js +1 -1
  44. package/dist/scripts/contract-helpers.js +4 -4
  45. package/dist/scripts/witness-serializer.d.ts +1 -1
  46. package/dist/scripts/witness-serializer.js +29 -6
  47. package/dist/transaction.d.ts +22 -0
  48. package/dist/transaction.js +155 -7
  49. package/dist/tx/TransactionReceiptStore.js +30 -21
  50. package/dist/verify.js +1 -1
  51. package/dist/wasm-async.d.ts +81 -0
  52. package/dist/wasm-async.js +91 -0
  53. package/dist/wasm-sync.d.ts +3 -3
  54. package/dist/wasm-sync.js +7 -2
  55. package/dist/wots.js +1 -1
  56. package/package.json +47 -3
@@ -43,6 +43,12 @@ export interface MinimaToken {
43
43
  name: Uint8Array;
44
44
  script: Uint8Array;
45
45
  created?: bigint;
46
+ /**
47
+ * MiniNumber scale of `totalAmount` in the serialized Token. Minima's
48
+ * `tokencreate` builds the minima amount from `MINI_UNIT` (1E-44) times
49
+ * integers, so its scale is always 44; default accordingly.
50
+ */
51
+ totalAmountScale?: number;
46
52
  }
47
53
  export interface StateVariable {
48
54
  port: number;
@@ -82,11 +88,27 @@ export interface TransactionBuildResult {
82
88
  digestTxHex: string;
83
89
  serialized: Uint8Array;
84
90
  serializedHex: string;
91
+ /** Set when the transaction creates a token (RFC-005 #2/#11). */
92
+ tokenId?: string;
85
93
  }
86
94
  export declare function parseDecimalToMiniNumber(decimal: string): ParsedMiniNumber;
87
95
  export declare function serializeCoin(coin: MinimaCoin): Uint8Array;
88
96
  export declare function serializeTransaction(tx: MinimaTransaction): Uint8Array;
89
97
  export declare function computeTransactionDigest(tx: MinimaTransaction): Uint8Array;
98
+ /**
99
+ * Compute a Minima **token id** — SHA3-256 of the MiniData-wrapped serialized
100
+ * Token, matching Java `Token.calculateTokenID()`. A newly created token's coins
101
+ * carry this value as their `tokenId`; token creation returns it.
102
+ */
103
+ export declare function computeTokenId(token: MinimaToken): Uint8Array;
104
+ /** Serialize a token descriptor (Java `Token.writeDataStream()` order). */
105
+ export declare function serializeTokenDescriptor(token: MinimaToken): Uint8Array;
106
+ /**
107
+ * Deserialize a transaction produced by {@link serializeTransaction}. The
108
+ * inverse is byte-exact for canonically-encoded transactions (outputs/inputs
109
+ * written from decimal amounts, MMR entry numbers and tokens).
110
+ */
111
+ export declare function deserializeTransaction(bytes: Uint8Array): MinimaTransaction;
90
112
  export declare function precomputeTransactionCoinID(tx: MinimaTransaction): void;
91
113
  export declare function createDefaultTransaction(): MinimaTransaction;
92
114
  export declare function buildMinimaCoin(opts: {
@@ -16,6 +16,9 @@ exports.parseDecimalToMiniNumber = parseDecimalToMiniNumber;
16
16
  exports.serializeCoin = serializeCoin;
17
17
  exports.serializeTransaction = serializeTransaction;
18
18
  exports.computeTransactionDigest = computeTransactionDigest;
19
+ exports.computeTokenId = computeTokenId;
20
+ exports.serializeTokenDescriptor = serializeTokenDescriptor;
21
+ exports.deserializeTransaction = deserializeTransaction;
19
22
  exports.precomputeTransactionCoinID = precomputeTransactionCoinID;
20
23
  exports.createDefaultTransaction = createDefaultTransaction;
21
24
  exports.buildMinimaCoin = buildMinimaCoin;
@@ -125,11 +128,11 @@ function serializeStateVariable(sv) {
125
128
  case 'string':
126
129
  typeByte = new Uint8Array([STATETYPE_STRING]);
127
130
  if (typeof sv.value === 'string') {
128
- let bracketedValue = sv.value;
129
- if (!sv.value.startsWith('[') || !sv.value.endsWith(']')) {
130
- bracketedValue = `[${sv.value}]`;
131
- }
132
- const utf8Bytes = new TextEncoder().encode(bracketedValue);
131
+ // Minima stores a string state variable as MiniString: MiniData of the
132
+ // raw UTF-8 bytes. The `[ … ]` form is KISSVM literal syntax, NOT part
133
+ // of the stored value (the C++ StateVariable::writeDataStream writes
134
+ // mData directly; the deserializer likewise strips no brackets).
135
+ const utf8Bytes = new TextEncoder().encode(sv.value);
133
136
  dataBytes = (0, Streamable_js_1.writeMiniData)(utf8Bytes);
134
137
  }
135
138
  else {
@@ -147,7 +150,10 @@ function serializeToken(token) {
147
150
  parts.push((0, Streamable_js_1.writeHashToStream)(token.coinId));
148
151
  parts.push((0, Streamable_js_1.writeMiniData)(token.script));
149
152
  parts.push((0, Streamable_js_1.writeMiniNumber)(BigInt(token.scale), 0));
150
- parts.push((0, Streamable_js_1.writeMiniNumber)(token.totalAmount, 0));
153
+ // The minima amount is a MiniNumber carrying its own scale (Java
154
+ // Token.writeDataStream → mTokenMinimaAmount.writeDataStream). Minima's
155
+ // tokencreate always builds it from MINI_UNIT (scale 44).
156
+ parts.push((0, Streamable_js_1.writeMiniNumber)(token.totalAmount, token.totalAmountScale ?? 44));
151
157
  parts.push((0, Streamable_js_1.writeMiniData)(token.name));
152
158
  parts.push((0, Streamable_js_1.writeMiniNumber)(token.created ?? 0n, 0));
153
159
  return (0, Streamable_js_1.concat)(...parts);
@@ -233,6 +239,151 @@ function computeTransactionDigest(tx) {
233
239
  const serialized = serializeTransaction(tx);
234
240
  return (0, wasm_sync_js_1.sha3_256)(serialized);
235
241
  }
242
+ /**
243
+ * Compute a Minima **token id** — SHA3-256 of the MiniData-wrapped serialized
244
+ * Token, matching Java `Token.calculateTokenID()`. A newly created token's coins
245
+ * carry this value as their `tokenId`; token creation returns it.
246
+ */
247
+ function computeTokenId(token) {
248
+ return (0, wasm_sync_js_1.sha3_256)((0, Streamable_js_1.writeMiniData)(serializeToken(token)));
249
+ }
250
+ /** Serialize a token descriptor (Java `Token.writeDataStream()` order). */
251
+ function serializeTokenDescriptor(token) {
252
+ return serializeToken(token);
253
+ }
254
+ function txReadBytes(data, c, n) {
255
+ if (n < 0 || c.offset + n > data.length) {
256
+ throw new Error(`deserializeTransaction: unexpected end of input at offset ${c.offset} (need ${n})`);
257
+ }
258
+ const out = data.slice(c.offset, c.offset + n);
259
+ c.offset += n;
260
+ return out;
261
+ }
262
+ function txReadMiniByte(data, c) {
263
+ return txReadBytes(data, c, 1)[0];
264
+ }
265
+ /** MiniData / hash: 4-byte big-endian length + bytes. */
266
+ function txReadMiniData(data, c) {
267
+ const lenBytes = txReadBytes(data, c, 4);
268
+ const len = ((lenBytes[0] << 24) | (lenBytes[1] << 16) | (lenBytes[2] << 8) | lenBytes[3]) >>> 0;
269
+ return txReadBytes(data, c, len);
270
+ }
271
+ /** MiniNumber: 1-byte scale + 1-byte length + two's-complement unscaled bytes. */
272
+ function txReadMiniNumber(data, c) {
273
+ const scale = txReadBytes(data, c, 1)[0];
274
+ const len = txReadBytes(data, c, 1)[0];
275
+ const bytes = txReadBytes(data, c, len);
276
+ let value = 0n;
277
+ for (const b of bytes)
278
+ value = (value << 8n) | BigInt(b);
279
+ // RFC-020 P2-10 (TXB-SERIAL-003): Java's BigInteger.toByteArray() (and the
280
+ // canonical writers here) use two's-complement big-endian; a set high bit
281
+ // means the value is negative. Previously this was read as unsigned.
282
+ if (bytes.length > 0 && (bytes[0] & 0x80) !== 0) {
283
+ value -= 1n << BigInt(8 * bytes.length);
284
+ }
285
+ return { value, scale };
286
+ }
287
+ function txBytesToBigInt(bytes) {
288
+ let value = 0n;
289
+ for (const b of bytes)
290
+ value = (value << 8n) | BigInt(b);
291
+ return value;
292
+ }
293
+ /** MMREntryNumber: MiniNumber(scale) followed by MiniData(unscaled). */
294
+ function txReadMMREntryNumber(data, c) {
295
+ txReadMiniNumber(data, c); // scale (always 0 for integer entry numbers)
296
+ return txBytesToBigInt(txReadMiniData(data, c));
297
+ }
298
+ function miniNumberToDecimal(value, scale) {
299
+ if (scale === 0)
300
+ return value.toString();
301
+ const digits = value.toString().padStart(scale + 1, '0');
302
+ const whole = digits.slice(0, digits.length - scale);
303
+ const frac = digits.slice(digits.length - scale);
304
+ return `${whole}.${frac}`;
305
+ }
306
+ function txReadStateVariable(data, c) {
307
+ const port = txReadBytes(data, c, 1)[0];
308
+ const type = txReadBytes(data, c, 1)[0];
309
+ switch (type) {
310
+ case STATETYPE_HEX:
311
+ return { port, type: 'hex', value: txReadMiniData(data, c) };
312
+ case STATETYPE_NUMBER:
313
+ return { port, type: 'number', value: txReadMiniNumber(data, c).value };
314
+ case STATETYPE_STRING:
315
+ return { port, type: 'string', value: new TextDecoder().decode(txReadMiniData(data, c)) };
316
+ case STATETYPE_BOOL:
317
+ return { port, type: 'bool', value: txReadMiniByte(data, c) === 1 };
318
+ default:
319
+ throw new Error(`deserializeTransaction: unknown StateVariable type ${type}`);
320
+ }
321
+ }
322
+ function txReadToken(data, c) {
323
+ const coinId = txReadMiniData(data, c);
324
+ const script = txReadMiniData(data, c);
325
+ const { value: scale } = txReadMiniNumber(data, c);
326
+ // RFC-020 P2-10 (TXB-SERIAL-002): carry the totalAmount's own scale so a
327
+ // serialize→deserialize→serialize round-trip is byte-exact (previously the
328
+ // scale was dropped and re-defaulted to 44).
329
+ const { value: totalAmount, scale: totalAmountScale } = txReadMiniNumber(data, c);
330
+ const name = txReadMiniData(data, c);
331
+ const { value: created } = txReadMiniNumber(data, c);
332
+ return { coinId, script, scale: Number(scale), totalAmount, totalAmountScale, name, created };
333
+ }
334
+ function txReadCoin(data, c) {
335
+ const coinId = txReadMiniData(data, c);
336
+ const address = txReadMiniData(data, c);
337
+ const { value: amountUnscaled, scale } = txReadMiniNumber(data, c);
338
+ const tokenId = txReadMiniData(data, c);
339
+ const storeState = txReadMiniByte(data, c) === 1;
340
+ const mmrEntryNumber = txReadMMREntryNumber(data, c);
341
+ const spent = txReadMiniByte(data, c) === 1;
342
+ const { value: created } = txReadMiniNumber(data, c);
343
+ const stateCount = Number(txReadMiniNumber(data, c).value);
344
+ const state = [];
345
+ for (let i = 0; i < stateCount; i++)
346
+ state.push(txReadStateVariable(data, c));
347
+ const hasToken = txReadMiniByte(data, c) === 1;
348
+ const token = hasToken ? txReadToken(data, c) : null;
349
+ return {
350
+ coinId,
351
+ address,
352
+ amount: miniNumberToDecimal(amountUnscaled, scale),
353
+ tokenId,
354
+ token,
355
+ storeState,
356
+ state,
357
+ mmrEntryNumber,
358
+ spent,
359
+ created,
360
+ };
361
+ }
362
+ /**
363
+ * Deserialize a transaction produced by {@link serializeTransaction}. The
364
+ * inverse is byte-exact for canonically-encoded transactions (outputs/inputs
365
+ * written from decimal amounts, MMR entry numbers and tokens).
366
+ */
367
+ function deserializeTransaction(bytes) {
368
+ const c = { offset: 0 };
369
+ const inputCount = Number(txReadMiniNumber(bytes, c).value);
370
+ const inputs = [];
371
+ for (let i = 0; i < inputCount; i++)
372
+ inputs.push(txReadCoin(bytes, c));
373
+ const outputCount = Number(txReadMiniNumber(bytes, c).value);
374
+ const outputs = [];
375
+ for (let i = 0; i < outputCount; i++)
376
+ outputs.push(txReadCoin(bytes, c));
377
+ const stateCount = Number(txReadMiniNumber(bytes, c).value);
378
+ const state = [];
379
+ for (let i = 0; i < stateCount; i++)
380
+ state.push(txReadStateVariable(bytes, c));
381
+ const linkHash = txReadMiniData(bytes, c);
382
+ if (c.offset !== bytes.length) {
383
+ throw new Error(`deserializeTransaction: ${bytes.length - c.offset} trailing byte(s) after transaction`);
384
+ }
385
+ return { linkHash, inputs, outputs, state };
386
+ }
236
387
  function precomputeTransactionCoinID(tx) {
237
388
  if (tx.inputs.length === 0)
238
389
  return;
@@ -37,33 +37,28 @@ class TransactionReceiptStore {
37
37
  return this._initialized;
38
38
  }
39
39
  async load() {
40
- try {
41
- const receipts = await this.storage.get(this.storageKey);
42
- if (receipts) {
43
- this.receipts = receipts;
44
- this.logger.debug(`Loaded ${this.receipts.length} transaction receipts`);
45
- }
46
- }
47
- catch (error) {
48
- this.logger.error('Failed to load receipts:', error);
40
+ const receipts = await this.storage.get(this.storageKey);
41
+ if (receipts) {
42
+ this.receipts = receipts;
43
+ this.logger.debug(`Loaded ${this.receipts.length} transaction receipts`);
49
44
  }
50
45
  }
51
46
  async persist() {
47
+ const trimmedReceipts = this.receipts.slice(-this.maxReceipts);
48
+ await this.storage.set(this.storageKey, trimmedReceipts);
49
+ this.receipts = trimmedReceipts;
50
+ }
51
+ async add(receipt) {
52
+ this.receipts.push(receipt);
53
+ this.logger.debug(`Added receipt: ${receipt.txpowid}`);
52
54
  try {
53
- const trimmedReceipts = this.receipts.slice(-this.maxReceipts);
54
- await this.storage.set(this.storageKey, trimmedReceipts);
55
- this.receipts = trimmedReceipts;
55
+ await this.persist();
56
56
  }
57
57
  catch (error) {
58
- this.logger.error('Failed to persist receipts:', error);
58
+ this.receipts.pop();
59
59
  throw error;
60
60
  }
61
61
  }
62
- async add(receipt) {
63
- this.receipts.push(receipt);
64
- this.logger.debug(`Added receipt: ${receipt.txpowid}`);
65
- await this.persist();
66
- }
67
62
  getAll() {
68
63
  return [...this.receipts].reverse();
69
64
  }
@@ -76,15 +71,29 @@ class TransactionReceiptStore {
76
71
  async updateStatus(txpowid, status) {
77
72
  const receipt = this.receipts.find(r => r.txpowid === txpowid);
78
73
  if (receipt) {
74
+ const previousStatus = receipt.status;
79
75
  receipt.status = status;
80
76
  this.logger.debug(`Updated receipt status: ${txpowid} → ${status}`);
81
- await this.persist();
77
+ try {
78
+ await this.persist();
79
+ }
80
+ catch (error) {
81
+ receipt.status = previousStatus;
82
+ throw error;
83
+ }
82
84
  }
83
85
  }
84
86
  async clear() {
87
+ const previous = this.receipts;
85
88
  this.receipts = [];
86
- await this.storage.remove(this.storageKey);
87
- this.logger.debug('Cleared all receipts');
89
+ try {
90
+ await this.storage.remove(this.storageKey);
91
+ this.logger.debug('Cleared all receipts');
92
+ }
93
+ catch (error) {
94
+ this.receipts = previous;
95
+ throw error;
96
+ }
88
97
  }
89
98
  count() {
90
99
  return this.receipts.length;
@@ -8,7 +8,7 @@
8
8
  * import { wotsSign, sha3_256 } from '@totemsdk/core/wasm';
9
9
  * const sig = wotsSign(seed, 0, message); // synchronous!
10
10
  */
11
- import { bytes_to_hex_wasm, clean_seed_phrase_wasm, compute_transaction_digest_wasm, concat_bytes_wasm, create_challenge_wasm, create_unified_child_tree_key_wasm, create_unified_root_tree_key_wasm, derive_chain_seed_wasm, derive_full_public_key_batch_wasm, derive_full_public_key_wasm, derive_per_address_seed_wasm, derive_pk_digest_batch_wasm, derive_pk_digest_wasm, derive_root_priv_seed_wasm, derive_unified_address_public_key_wasm, expand_private_key_wasm, generate_mnemonic_wasm, get_params, hash_chain_wasm, hex_to_bytes_wasm, make_mx_address_wasm, mine_txpow_chunk_wasm, mine_txpow_wasm, mmr_root_from_public_keys_wasm, parse_mx_address_wasm, phrase_to_seed_wasm, precompute_transaction_coin_id_wasm, serialize_transaction_wasm, sha3_256_wasm, timing_safe_equal_wasm, validate_challenge_wasm, validate_phrase_wasm, verify_mmr_proof_wasm, verify_tree_signature_wasm, wasm_tree_key_free, wasm_tree_key_get_max_uses, wasm_tree_key_get_public_key, wasm_tree_key_get_uses, wasm_tree_key_new, wasm_tree_key_set_uses, wasm_tree_key_sign, wots_pk_from_sig_wasm, wots_sign_batch_wasm, wots_sign_wasm, wots_verify_digest_wasm, wots_verify_wasm, write_mini_data_wasm, write_mini_string_wasm } from '@totemsdk/core-wasm';
11
+ import { bytes_to_hex_wasm, clean_seed_phrase_wasm, compute_transaction_digest_wasm, concat_bytes_wasm, create_unified_child_tree_key_wasm, create_unified_root_tree_key_wasm, derive_chain_seed_wasm, derive_full_public_key_batch_wasm, derive_full_public_key_wasm, derive_per_address_seed_wasm, derive_pk_digest_batch_wasm, derive_pk_digest_wasm, derive_root_priv_seed_wasm, derive_unified_address_public_key_wasm, expand_private_key_wasm, generate_mnemonic_wasm, get_params, hash_chain_wasm, hex_to_bytes_wasm, make_mx_address_wasm, mine_txpow_chunk_wasm, mine_txpow_wasm, mmr_root_from_public_keys_wasm, parse_mx_address_wasm, phrase_to_seed_wasm, precompute_transaction_coin_id_wasm, serialize_transaction_wasm, sha3_256_wasm, timing_safe_equal_wasm, validate_phrase_wasm, verify_mmr_proof_wasm, verify_tree_signature_wasm, wasm_tree_key_free, wasm_tree_key_get_max_uses, wasm_tree_key_get_public_key, wasm_tree_key_get_uses, wasm_tree_key_new, wasm_tree_key_set_uses, wasm_tree_key_sign, wots_pk_from_sig_wasm, wots_sign_batch_wasm, wots_sign_wasm, wots_verify_digest_wasm, wots_verify_wasm, write_mini_data_wasm, write_mini_string_wasm } from '@totemsdk/core-wasm';
12
12
  export declare const bytesToHex: typeof bytes_to_hex_wasm;
13
13
  export declare const hexToBytes: typeof hex_to_bytes_wasm;
14
14
  export declare const concatBytes: typeof concat_bytes_wasm;
@@ -41,8 +41,8 @@ export declare const computeTransactionDigest: typeof compute_transaction_digest
41
41
  export declare const precomputeTransactionCoinID: typeof precompute_transaction_coin_id_wasm;
42
42
  export declare const verifyTreeSignature: typeof verify_tree_signature_wasm;
43
43
  export declare const timingSafeEqual: typeof timing_safe_equal_wasm;
44
- export declare const createChallenge: typeof create_challenge_wasm;
45
- export declare const validateChallenge: typeof validate_challenge_wasm;
44
+ export declare function createChallenge(domain: string, statement: string): string;
45
+ export declare function validateChallenge(challengeJson: string, domain: string): boolean;
46
46
  export declare function writeMiniNumber(value: bigint, scale?: number): Uint8Array;
47
47
  export declare const writeMiniData: typeof write_mini_data_wasm;
48
48
  export declare const writeMiniString: typeof write_mini_string_wasm;
@@ -10,8 +10,10 @@
10
10
  * const sig = wotsSign(seed, 0, message); // synchronous!
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.wasmTreeKeyFree = exports.wasmTreeKeyGetMaxUses = exports.wasmTreeKeySetUses = exports.wasmTreeKeyGetUses = exports.wasmTreeKeyGetPublicKey = exports.wasmTreeKeySign = exports.wasmTreeKeyNew = exports.mineTxPoWChunk = exports.mineTxPoW = exports.deriveFullPublicKeyBatch = exports.derivePKdigestBatch = exports.wotsSignBatch = exports.getParams = exports.verifyMMRProof = exports.mmrRootFromPublicKeys = exports.deriveUnifiedAddressPublicKey = exports.createUnifiedRootTreeKey = exports.createUnifiedChildTreeKey = exports.writeMiniString = exports.writeMiniData = exports.validateChallenge = exports.createChallenge = exports.timingSafeEqual = exports.verifyTreeSignature = exports.precomputeTransactionCoinID = exports.computeTransactionDigest = exports.serializeTransaction = exports.parseMxAddress = exports.makeMxAddress = exports.cleanSeedPhrase = exports.validatePhrase = exports.generateWordList = exports.phraseToSeed = exports.deriveRootPrivSeed = exports.derivePerAddressSeed = exports.deriveChainSeedJava = exports.wotsPublicKeyFromSeed = exports.wotsPkFromSig = exports.wotsVerifyDigest = exports.wotsVerify = exports.wotsSign = exports.deriveFullPublicKey = exports.derivePKdigest = exports.hashChain = exports.expandPrivateKey = exports.sha3_256 = exports.concatBytes = exports.hexToBytes = exports.bytesToHex = void 0;
13
+ exports.wasmTreeKeyFree = exports.wasmTreeKeyGetMaxUses = exports.wasmTreeKeySetUses = exports.wasmTreeKeyGetUses = exports.wasmTreeKeyGetPublicKey = exports.wasmTreeKeySign = exports.wasmTreeKeyNew = exports.mineTxPoWChunk = exports.mineTxPoW = exports.deriveFullPublicKeyBatch = exports.derivePKdigestBatch = exports.wotsSignBatch = exports.getParams = exports.verifyMMRProof = exports.mmrRootFromPublicKeys = exports.deriveUnifiedAddressPublicKey = exports.createUnifiedRootTreeKey = exports.createUnifiedChildTreeKey = exports.writeMiniString = exports.writeMiniData = exports.timingSafeEqual = exports.verifyTreeSignature = exports.precomputeTransactionCoinID = exports.computeTransactionDigest = exports.serializeTransaction = exports.parseMxAddress = exports.makeMxAddress = exports.cleanSeedPhrase = exports.validatePhrase = exports.generateWordList = exports.phraseToSeed = exports.deriveRootPrivSeed = exports.derivePerAddressSeed = exports.deriveChainSeedJava = exports.wotsPublicKeyFromSeed = exports.wotsPkFromSig = exports.wotsVerifyDigest = exports.wotsVerify = exports.wotsSign = exports.deriveFullPublicKey = exports.derivePKdigest = exports.hashChain = exports.expandPrivateKey = exports.sha3_256 = exports.concatBytes = exports.hexToBytes = exports.bytesToHex = void 0;
14
14
  exports.wotsAddressFromKeypair = wotsAddressFromKeypair;
15
+ exports.createChallenge = createChallenge;
16
+ exports.validateChallenge = validateChallenge;
15
17
  exports.writeMiniNumber = writeMiniNumber;
16
18
  exports.wotsKeypairFromSeed = wotsKeypairFromSeed;
17
19
  // The bundler target initializes WASM synchronously at import time.
@@ -55,8 +57,13 @@ exports.computeTransactionDigest = core_wasm_1.compute_transaction_digest_wasm;
55
57
  exports.precomputeTransactionCoinID = core_wasm_1.precompute_transaction_coin_id_wasm;
56
58
  exports.verifyTreeSignature = core_wasm_1.verify_tree_signature_wasm;
57
59
  exports.timingSafeEqual = core_wasm_1.timing_safe_equal_wasm;
58
- exports.createChallenge = core_wasm_1.create_challenge_wasm;
59
- exports.validateChallenge = core_wasm_1.validate_challenge_wasm;
60
+ // SystemTime panics on wasm32-unknown-unknown; supply the clock from JS.
61
+ function createChallenge(domain, statement) {
62
+ return (0, core_wasm_1.create_challenge_wasm)(domain, statement, Math.floor(Date.now() / 1000));
63
+ }
64
+ function validateChallenge(challengeJson, domain) {
65
+ return (0, core_wasm_1.validate_challenge_wasm)(challengeJson, domain, Math.floor(Date.now() / 1000));
66
+ }
60
67
  function writeMiniNumber(value, scale = 0) {
61
68
  return (0, core_wasm_1.write_mini_number_wasm)(value.toString(), scale);
62
69
  }
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ export * from './adapters/index.js';
10
10
  export { LeaseStore, WatermarkStore, LeaseMonitor, prepareLease, finalizeLease, flatIndexFromLanes, type StoredLease, type LeaseStatus, type LeaseStoreConfig, type LeaseWotsIndices, type WatermarkState, type SyncResult, type WatermarkStoreConfig, type LeaseExpiryEvent, type LeaseExpiryCallback, type LeaseMonitorConfig, type PrepareArgs, type PrepareResp, } from './lease/index.js';
11
11
  export { TransactionService, TransactionLifecycle, TransactionLifecycleError, WatermarkExhaustedError, TransactionReceiptStore, type TransactionServiceConfig, type WotsSigningDependencies, type TransactionLifecycleConfig, type WatermarkSyncFunction, type PrepareResult, type TransactionReceiptStoreConfig, type PrepareRequest, type PrepareResponse, type SignRequest, type SignResult, type HierarchicalWitnessBundle, type WitnessBundle, type FinalizeRequest, type FinalizeResponse, type TransactionMetadata, type TransactionReceipt, type TransactionError, } from './tx/index.js';
12
12
  export type { WotsIndices } from './tx/index.js';
13
- export { bytesToHex, hexToBytes, concatBytes } from './wasm-sync.js';
13
+ export { bytesToHex, hexToBytes, concatBytes } from './bytes.js';
14
14
  export { sha3_256 } from './wasm-sync.js';
15
15
  export { expandPrivateKey, hashChain, derivePKdigest, deriveFullPublicKey, wotsSign, wotsVerify, wotsVerifyDigest, wotsPkFromSig, wotsPublicKeyFromSeed, wotsKeypairFromSeed, } from './wasm-sync.js';
16
16
  export * from './params.js';
@@ -20,6 +20,7 @@ export { mmrRootFromPublicKeys, verifyMMRProof, } from './wasm-sync.js';
20
20
  export { phraseToSeed, generateWordList, validatePhrase, cleanSeedPhrase, } from './bip39.js';
21
21
  export { makeMxAddress, parseMxAddress, wotsAddressFromKeypair, } from './wasm-sync.js';
22
22
  export { serializeTransaction, computeTransactionDigest, } from './wasm-sync.js';
23
+ export { deserializeTransaction } from './transaction.js';
23
24
  export { timingSafeEqual, createChallenge, validateChallenge, } from './wasm-sync.js';
24
25
  export { scriptFromWotsPk } from './script.js';
25
26
  export { makeMxAddress as encodeMx, parseMxAddress as decodeMx } from './wasm-sync.js';
@@ -30,14 +31,16 @@ export * from './scripts/index.js';
30
31
  export { scriptToAddress, addressToRoot } from './derive.js';
31
32
  export { WORD_LIST, convertStringToSeed, convertWordListToSeed, generateSeedPhrase, } from './bip39.js';
32
33
  export { MiniNumber } from './MiniNumber.js';
33
- export { type MinimaTransaction, type MinimaCoin, type ParsedMiniNumber, type MinimaToken, type StateVariable, type RawStateVariable, type CoinProofData, type SpendableCoinInput, type TransactionBuildResult, parseDecimalToMiniNumber, serializeCoin, createDefaultTransaction, buildMinimaCoin, } from './transaction.js';
34
+ export { type MinimaTransaction, type MinimaCoin, type ParsedMiniNumber, type MinimaToken, type StateVariable, type RawStateVariable, type CoinProofData, type SpendableCoinInput, type TransactionBuildResult, parseDecimalToMiniNumber, serializeCoin, serializeTransaction as serializeTransactionObject, computeTokenId, serializeTokenDescriptor, createDefaultTransaction, buildMinimaCoin, } from './transaction.js';
34
35
  export { verifySignature, verifySignatureDetailed, verifyTreeSignatureDetailed, deriveAddressFromPublicKey, normalizeHex, type VerificationResult, } from './verify.js';
35
- export { writeMiniByte, writeMMREntryNumber, concat, bigIntToByteArray, type Bytes, } from './Streamable.js';
36
+ export { deriveDeterministicAddress, deriveUnifiedAddress, deriveAddress, verifyDeterministicAddress, type AddressScheme, type DerivedAddress, } from './address-derivation.js';
37
+ export { writeMiniByte, writeMMREntryNumber, writeSignature, writeSignatureProof, concat, bigIntToByteArray, type Bytes, } from './Streamable.js';
36
38
  export { serializeMiniNumber, serializeMiniData, hashAllObjects, deriveChildTreeSeedJava, hashObject, serializeMiniNumberZERO, serializeMiniNumberONE, writeHashToStream, javaHashAllObjects, indexToMiniDataBytes, deriveUnifiedChildSeed, createMMREntryNumber, serializeMMREntryNumber, serializeMMRData, serializeMMREntry, type MMREntryNumber as JavaMMREntryNumber, type MMRData as JavaMMRData, type MMREntry as JavaMMREntry, } from './javaStreamables.js';
37
- export { TreeKey, TreeKeyNode, serializeTreeSignature, deserializeTreeSignature, getRootPublicKey, DEFAULT_KEYS_PER_LEVEL, DEFAULT_LEVELS, createUnifiedChildTreeKeyAsync, createPerAddressTreeKey, createPerAddressTreeKeyAsync, type KeyGenProgress, type ProgressCallback, type SignatureProof, type TreeSignature, } from './treekey.js';
39
+ export { TreeKey, TreeKeyNode, serializeTreeSignature, deserializeTreeSignature, getRootPublicKey, DEFAULT_KEYS_PER_LEVEL, DEFAULT_LEVELS, createUnifiedChildTreeKeyAsync, createPerAddressTreeKey, createPerAddressTreeKeyAsync, setTreeKeyLogger, disableTreeKeyLogger, type KeyGenProgress, type ProgressCallback, type SignatureProof, type TreeSignature, } from './treekey.js';
38
40
  export type { WotsKeypair, WotsSignature } from './wots.js';
39
- export { F, hex, fromHex, u16be, u32be, assert32, h, prfChainSeed, toWinternitzDigits, baseWWithChecksum, wotsSignLegacy, } from './wots.js';
40
- export { toHex, canonicalJson, hashCanonical } from './canonical.js';
41
+ export { F, hex, fromHex, setWotsLogger, disableWotsLogger, u16be, u32be, assert32, h, prfChainSeed, toWinternitzDigits, baseWWithChecksum, wotsSignLegacy, } from './wots.js';
42
+ export { toHex, canonicalJson } from './canonical.js';
43
+ export { hashCanonical } from './canonical-hash.js';
41
44
  export { utf8ToBytes, bytesToUtf8 } from './utils.js';
42
45
  export declare const MINIMA_CONSTANTS: {
43
46
  readonly WOTS_W: 8;
package/dist/index.js CHANGED
@@ -17,23 +17,24 @@ export { TransactionService, TransactionLifecycle, TransactionLifecycleError, Wa
17
17
  // Cryptographic primitives — backed by Rust/WASM (@totemsdk/core-wasm)
18
18
  // ---------------------------------------------------------------------------
19
19
  // Utilities
20
- export { bytesToHex, hexToBytes, concatBytes } from './wasm-sync.js';
21
- import { bytesToHex, parseMxAddress } from './wasm-sync.js';
20
+ export { bytesToHex, hexToBytes, concatBytes } from './bytes.js';
21
+ import { bytesToHex } from './bytes.js';
22
+ import { parseMxAddress } from './wasm-async.js';
22
23
  // SHA3-256
23
- export { sha3_256 } from './wasm-sync.js';
24
+ export { sha3_256 } from './wasm-async.js';
24
25
  // WOTS Signatures
25
- export { expandPrivateKey, hashChain, derivePKdigest, deriveFullPublicKey, wotsSign, wotsVerify, wotsVerifyDigest, wotsPkFromSig, wotsPublicKeyFromSeed, wotsKeypairFromSeed, } from './wasm-sync.js';
26
+ export { expandPrivateKey, hashChain, derivePKdigest, deriveFullPublicKey, wotsSign, wotsVerify, wotsVerifyDigest, wotsPkFromSig, wotsPublicKeyFromSeed, wotsKeypairFromSeed, } from './wasm-async.js';
26
27
  // WOTS Params (from params.ts — constants, no crypto)
27
28
  export * from './params.js';
28
29
  // Java-Compatible Serialization
29
- export { deriveChainSeedJava, derivePerAddressSeed, deriveRootPrivSeed, writeMiniNumber, writeMiniData, writeMiniString, precomputeTransactionCoinID, } from './wasm-sync.js';
30
+ export { deriveChainSeedJava, derivePerAddressSeed, deriveRootPrivSeed, writeMiniNumber, writeMiniData, writeMiniString, precomputeTransactionCoinID, } from './wasm-async.js';
30
31
  // TreeKey/TreeKeyNode — WASM-backed
31
32
  // createUnifiedChildTreeKey / createUnifiedRootTreeKey come from the TS
32
33
  // implementation (returning a full TreeKey object with setUses/sign/getPublicKey)
33
34
  // to match the object API that downstream consumers (server, root-identity)
34
35
  // rely on. The WASM binding only returns the root public key bytes.
35
36
  export { createUnifiedChildTreeKey, createUnifiedRootTreeKey, deriveUnifiedAddressPublicKey, verifyTreeSignature, } from './treekey.js';
36
- export { mmrRootFromPublicKeys, verifyMMRProof, } from './wasm-sync.js';
37
+ export { mmrRootFromPublicKeys, verifyMMRProof, } from './wasm-async.js';
37
38
  // BIP39 Seed Phrase Handling
38
39
  // The WASM binding (wasm-sync.ts) shares the canonical 2048-word BIP39 list
39
40
  // and Minima-compatible uppercase canonicalization with the TS implementation
@@ -42,18 +43,20 @@ export { mmrRootFromPublicKeys, verifyMMRProof, } from './wasm-sync.js';
42
43
  // canonical source of truth and avoids double-entering the list.
43
44
  export { phraseToSeed, generateWordList, validatePhrase, cleanSeedPhrase, } from './bip39.js';
44
45
  // Address Derivation
45
- export { makeMxAddress, parseMxAddress, wotsAddressFromKeypair, } from './wasm-sync.js';
46
+ export { makeMxAddress, parseMxAddress, wotsAddressFromKeypair, } from './wasm-async.js';
46
47
  // Transaction Serialization & Digest
47
- export { serializeTransaction, computeTransactionDigest, } from './wasm-sync.js';
48
+ export { serializeTransaction, computeTransactionDigest, } from './wasm-async.js';
49
+ // Transaction deserialization (byte-exact inverse of the TS serializer)
50
+ export { deserializeTransaction } from './transaction.js';
48
51
  // Verification
49
- export { timingSafeEqual, createChallenge, validateChallenge, } from './wasm-sync.js';
52
+ export { timingSafeEqual, createChallenge, validateChallenge, } from './wasm-async.js';
50
53
  // ---------------------------------------------------------------------------
51
54
  // TypeScript-only modules (no crypto — keep as-is)
52
55
  // ---------------------------------------------------------------------------
53
56
  // Script helpers (for address derivation)
54
57
  export { scriptFromWotsPk } from './script.js';
55
58
  // Base32 Encoding (Minima-compatible) — re-export from WASM
56
- export { makeMxAddress as encodeMx, parseMxAddress as decodeMx } from './wasm-sync.js';
59
+ export { makeMxAddress as encodeMx, parseMxAddress as decodeMx } from './wasm-async.js';
57
60
  /** Convert an Mx (radix-32) or hex Minima address to lowercase hex. */
58
61
  export function mxToHex(address) {
59
62
  const upper = address.startsWith('0x') || address.startsWith('0X') ? address.slice(2) : address;
@@ -72,18 +75,21 @@ export { WORD_LIST, convertStringToSeed, convertWordListToSeed, generateSeedPhra
72
75
  // MiniNumber class (matches Java MiniNumber/BigDecimal semantics)
73
76
  export { MiniNumber } from './MiniNumber.js';
74
77
  // Transaction types (from JS)
75
- export { parseDecimalToMiniNumber, serializeCoin, createDefaultTransaction, buildMinimaCoin, } from './transaction.js';
78
+ export { parseDecimalToMiniNumber, serializeCoin, serializeTransaction as serializeTransactionObject, computeTokenId, serializeTokenDescriptor, createDefaultTransaction, buildMinimaCoin, } from './transaction.js';
76
79
  // High-level Verification API (convenience functions for integrators)
77
80
  export { verifySignature, verifySignatureDetailed, verifyTreeSignatureDetailed, deriveAddressFromPublicKey, normalizeHex, } from './verify.js';
81
+ // Deterministic address derivation (CAN-005)
82
+ export { deriveDeterministicAddress, deriveUnifiedAddress, deriveAddress, verifyDeterministicAddress, } from './address-derivation.js';
78
83
  // Streamable primitives (low-level serialization building blocks)
79
- export { writeMiniByte, writeMMREntryNumber, concat, bigIntToByteArray, } from './Streamable.js';
84
+ export { writeMiniByte, writeMMREntryNumber, writeSignature, writeSignatureProof, concat, bigIntToByteArray, } from './Streamable.js';
80
85
  // Java-Compatible Serialization Helpers (non-crypto)
81
86
  export { serializeMiniNumber, serializeMiniData, hashAllObjects, deriveChildTreeSeedJava, hashObject, serializeMiniNumberZERO, serializeMiniNumberONE, writeHashToStream, javaHashAllObjects, indexToMiniDataBytes, deriveUnifiedChildSeed, createMMREntryNumber, serializeMMREntryNumber, serializeMMRData, serializeMMREntry, } from './javaStreamables.js';
82
87
  // TreeKey/TreeKeyNode — JS types and helpers
83
- export { TreeKey, TreeKeyNode, serializeTreeSignature, deserializeTreeSignature, getRootPublicKey, DEFAULT_KEYS_PER_LEVEL, DEFAULT_LEVELS, createUnifiedChildTreeKeyAsync, createPerAddressTreeKey, createPerAddressTreeKeyAsync, } from './treekey.js';
84
- export { F, hex, fromHex, u16be, u32be, assert32, h, prfChainSeed, toWinternitzDigits, baseWWithChecksum, wotsSignLegacy, } from './wots.js';
88
+ export { TreeKey, TreeKeyNode, serializeTreeSignature, deserializeTreeSignature, getRootPublicKey, DEFAULT_KEYS_PER_LEVEL, DEFAULT_LEVELS, createUnifiedChildTreeKeyAsync, createPerAddressTreeKey, createPerAddressTreeKeyAsync, setTreeKeyLogger, disableTreeKeyLogger, } from './treekey.js';
89
+ export { F, hex, fromHex, setWotsLogger, disableWotsLogger, u16be, u32be, assert32, h, prfChainSeed, toWinternitzDigits, baseWWithChecksum, wotsSignLegacy, } from './wots.js';
85
90
  // Canonical helpers (deterministic JSON + hashing)
86
- export { toHex, canonicalJson, hashCanonical } from './canonical.js';
91
+ export { toHex, canonicalJson } from './canonical.js';
92
+ export { hashCanonical } from './canonical-hash.js';
87
93
  // Byte/string utilities
88
94
  export { utf8ToBytes, bytesToUtf8 } from './utils.js';
89
95
  // Constants
@@ -12,7 +12,7 @@
12
12
  * NOTE: This module provides number-based wrappers for backward compatibility.
13
13
  * The canonical implementations are in Streamable.ts which uses bigint for precision.
14
14
  */
15
- import { sha3_256 } from './wasm-sync.js';
15
+ import { sha3_256 } from './wasm-async.js';
16
16
  import { writeMiniNumber as streamableWriteMiniNumber, writeMiniData as streamableWriteMiniData, writeHashToStream as streamableWriteHashToStream, bigIntToByteArray } from './Streamable.js';
17
17
  /**
18
18
  * Serialize a number in MiniNumber format (Java compatible)
@@ -33,6 +33,7 @@ export interface LeaseStoreConfig {
33
33
  export declare class LeaseStore {
34
34
  private leases;
35
35
  private _initialized;
36
+ private mutationTail;
36
37
  private readonly storageKey;
37
38
  private readonly storage;
38
39
  private readonly logger;
@@ -42,16 +43,22 @@ export declare class LeaseStore {
42
43
  private load;
43
44
  private persist;
44
45
  save(lease: StoredLease): Promise<void>;
46
+ private saveUnlocked;
47
+ delete(leaseId: string): Promise<boolean>;
48
+ private deleteUnlocked;
45
49
  get(leaseId: string): StoredLease | undefined;
46
50
  getByToken(leaseToken: string): StoredLease | undefined;
47
51
  getAll(): StoredLease[];
48
52
  getActive(): StoredLease[];
49
53
  getExpiringSoon(thresholdMs?: number): StoredLease[];
50
- delete(leaseId: string): Promise<boolean>;
51
54
  deleteByToken(leaseToken: string): Promise<boolean>;
52
55
  updateStatus(leaseId: string, status: LeaseStatus): Promise<void>;
56
+ private updateStatusUnlocked;
53
57
  cleanupExpired(): Promise<number>;
58
+ private cleanupExpiredUnlocked;
54
59
  clear(): Promise<void>;
60
+ private clearUnlocked;
61
+ private mutate;
55
62
  getMinimumTTL(): number | null;
56
63
  calculateMonitoringInterval(): number;
57
64
  private flattenIndex;