@totemsdk/root-identity 1.0.8 → 1.0.9

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.
@@ -282,8 +282,13 @@ class UnifiedIdentityWallet {
282
282
  getRootUses() { return this.rootUses; }
283
283
  /** Restore root watermark from a previously persisted value. */
284
284
  setRootUses(uses) {
285
- if (uses < 0)
286
- throw new Error('uses must be non-negative');
285
+ if (!Number.isSafeInteger(uses) || uses < 0)
286
+ throw new Error('uses must be a non-negative safe integer');
287
+ // RFC-020 C1: the cursor may only advance — lowering it would re-expose
288
+ // already-spent WOTS leaves.
289
+ if (uses < this.rootUses) {
290
+ throw new Error(`Refusing to lower root uses from ${this.rootUses} to ${uses} (would reuse a WOTS leaf)`);
291
+ }
287
292
  this.rootUses = uses;
288
293
  }
289
294
  /** Number of times child `index` has signed (for persistence). */
@@ -294,8 +299,12 @@ class UnifiedIdentityWallet {
294
299
  /** Restore child watermark from a previously persisted value. */
295
300
  setChildUses(index, uses) {
296
301
  this.assertChildIndex(index);
297
- if (uses < 0)
298
- throw new Error('uses must be non-negative');
302
+ if (!Number.isSafeInteger(uses) || uses < 0)
303
+ throw new Error('uses must be a non-negative safe integer');
304
+ const current = this.childUsesMap.get(index) ?? 0;
305
+ if (uses < current) {
306
+ throw new Error(`Refusing to lower child ${index} uses from ${current} to ${uses} (would reuse a WOTS leaf)`);
307
+ }
299
308
  this.childUsesMap.set(index, uses);
300
309
  }
301
310
  /** Number of child addresses configured for this wallet. */
@@ -323,17 +332,34 @@ class UnifiedIdentityWallet {
323
332
  * across sessions. Out-of-range or invalid entries are silently skipped.
324
333
  */
325
334
  restoreWatermarkState(state) {
326
- if (typeof state?.rootUses === 'number' && state.rootUses >= 0) {
327
- this.rootUses = Math.floor(state.rootUses);
335
+ // RFC-020 C1: restore is forward-only. A stale or tampered snapshot that
336
+ // moves a cursor backwards would re-expose spent leaves, so it throws.
337
+ const nextRoot = typeof state?.rootUses === 'number'
338
+ && Number.isSafeInteger(state.rootUses)
339
+ && state.rootUses >= 0
340
+ ? state.rootUses
341
+ : undefined;
342
+ if (nextRoot !== undefined && nextRoot < this.rootUses) {
343
+ throw new Error(`Refusing to restore root uses below the current cursor (${nextRoot} < ${this.rootUses})`);
328
344
  }
345
+ const childNext = [];
329
346
  if (state?.childUses && typeof state.childUses === 'object') {
330
347
  for (const [key, uses] of Object.entries(state.childUses)) {
331
348
  const index = Number(key);
332
- if (Number.isInteger(index) && index >= 0 && index < this.childCount && typeof uses === 'number' && uses >= 0) {
333
- this.childUsesMap.set(index, Math.floor(uses));
349
+ if (Number.isInteger(index) && index >= 0 && index < this.childCount
350
+ && typeof uses === 'number' && Number.isSafeInteger(uses) && uses >= 0) {
351
+ const current = this.childUsesMap.get(index) ?? 0;
352
+ if (uses < current) {
353
+ throw new Error(`Refusing to restore child ${index} uses below the current cursor (${uses} < ${current})`);
354
+ }
355
+ childNext.push([index, uses]);
334
356
  }
335
357
  }
336
358
  }
359
+ if (nextRoot !== undefined)
360
+ this.rootUses = nextRoot;
361
+ for (const [index, uses] of childNext)
362
+ this.childUsesMap.set(index, uses);
337
363
  }
338
364
  // ── Private helpers ──────────────────────────────────────────────────────────
339
365
  assertChildIndex(index) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@totemsdk/root-identity",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Single root identity controlling up to 64 on-chain addresses — all cryptographically linked via full independent 3-level TreeKeys",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -21,7 +21,7 @@
21
21
  "LICENSE"
22
22
  ],
23
23
  "peerDependencies": {
24
- "@totemsdk/core": "^1.2.8"
24
+ "@totemsdk/core": "^1.2.11"
25
25
  },
26
26
  "peerDependenciesMeta": {
27
27
  "@totemsdk/core": {
@@ -41,7 +41,7 @@
41
41
  "jest": "^30.4.2",
42
42
  "ts-jest": "^29.0.0",
43
43
  "typescript": "^7.0.2",
44
- "@totemsdk/core": "^1.2.8"
44
+ "@totemsdk/core": "^1.2.11"
45
45
  },
46
46
  "keywords": [
47
47
  "totem",
@@ -59,13 +59,13 @@
59
59
  ],
60
60
  "author": "Totem SDK",
61
61
  "license": "MIT",
62
- "homepage": "https://totem.ing",
62
+ "homepage": "https://docs.totem.ing",
63
63
  "bugs": {
64
- "url": "https://github.com/totem-sdk/totem-sdk/issues"
64
+ "url": "https://github.com/Totem-Edge/totem-sdk/issues"
65
65
  },
66
66
  "repository": {
67
67
  "type": "git",
68
- "url": "git+https://github.com/totem-sdk/totem-sdk.git",
68
+ "url": "git+https://github.com/Totem-Edge/totem-sdk.git",
69
69
  "directory": "packages/root-identity"
70
70
  },
71
71
  "scripts": {
@@ -9,7 +9,7 @@
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/totem-sdk/totem-sdk"
12
+ "url": "https://github.com/Totem-Edge/totem-sdk"
13
13
  },
14
14
  "files": [
15
15
  "root_identity_wasm_bg.wasm",
Binary file
@@ -8,7 +8,7 @@
8
8
  "license": "MIT",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "https://github.com/totem-sdk/totem-sdk"
11
+ "url": "https://github.com/Totem-Edge/totem-sdk"
12
12
  },
13
13
  "files": [
14
14
  "root_identity_wasm_bg.wasm",