@totemsdk/wots-lease 0.1.3 → 0.1.4

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/dist/axia.js CHANGED
@@ -47,6 +47,7 @@ class AxiaLeaseProvider {
47
47
  const lease = {
48
48
  leaseId: reservationId,
49
49
  leaseToken: resp.leaseToken,
50
+ treeId: params.treeId,
50
51
  indices,
51
52
  expiresAt,
52
53
  status: 'active',
package/dist/journal.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare class LeaseJournal {
12
12
  constructor(storage: StorageAdapter, logger?: LoggerAdapter);
13
13
  initialize(): Promise<void>;
14
14
  append(entry: JournalEntry): Promise<void>;
15
+ private _verifyChain;
15
16
  getAll(): JournalEntry[];
16
17
  getByTree(treeId: string): JournalEntry[];
17
18
  getByReservation(reservationId: string): JournalEntry | undefined;
package/dist/journal.js CHANGED
@@ -5,8 +5,24 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.LeaseJournal = void 0;
8
+ const crypto_1 = require("crypto");
8
9
  const core_1 = require("@totemsdk/core");
9
10
  const STORAGE_KEY = 'totem_wots_journal';
11
+ function hashEntry(entry) {
12
+ const encoder = new TextEncoder();
13
+ const data = {
14
+ t: entry.treeId,
15
+ b: entry.branchId,
16
+ i: entry.wotsIndex,
17
+ s: entry.status,
18
+ r: entry.reservationId,
19
+ p: entry.previousHash,
20
+ ts: entry.timestamp,
21
+ d: entry.deviceId,
22
+ };
23
+ const bytes = encoder.encode(JSON.stringify(data));
24
+ return (0, crypto_1.createHash)('sha256').update(bytes).digest('hex');
25
+ }
10
26
  class LeaseJournal {
11
27
  constructor(storage, logger = new core_1.NoopLogger()) {
12
28
  this.storage = storage;
@@ -19,12 +35,40 @@ class LeaseJournal {
19
35
  return;
20
36
  const stored = await this.storage.get(STORAGE_KEY);
21
37
  this.entries = stored ?? [];
38
+ if (this.entries.length > 0) {
39
+ const ok = this._verifyChain();
40
+ if (!ok) {
41
+ this.logger.error('[LeaseJournal] hash chain integrity check FAILED — journal may be tampered');
42
+ throw new Error('Journal hash chain integrity check failed');
43
+ }
44
+ }
22
45
  this._initialized = true;
23
46
  }
24
47
  async append(entry) {
48
+ const prev = this.entries[this.entries.length - 1];
49
+ entry.previousHash = prev?.hash;
50
+ entry.hash = hashEntry(entry);
25
51
  this.entries.push(entry);
26
52
  await this.storage.set(STORAGE_KEY, this.entries);
27
- this.logger.debug(`[LeaseJournal] ${entry.status} treeId=${entry.treeId} idx=${entry.wotsIndex} txId=${entry.txId ?? '-'}`);
53
+ this.logger.debug(`[LeaseJournal] ${entry.status} treeId=${entry.treeId} idx=${entry.wotsIndex} txId=${entry.txId ?? '-'} hash=${entry.hash.slice(0, 8)}`);
54
+ }
55
+ _verifyChain() {
56
+ for (let i = 0; i < this.entries.length; i++) {
57
+ const e = this.entries[i];
58
+ const expectedHash = hashEntry(e);
59
+ if (e.hash !== expectedHash) {
60
+ this.logger.error(`[LeaseJournal] hash mismatch at entry ${i}: expected ${expectedHash}, stored ${e.hash}`);
61
+ return false;
62
+ }
63
+ if (i > 0) {
64
+ const prevHash = this.entries[i - 1].hash;
65
+ if (e.previousHash !== prevHash) {
66
+ this.logger.error(`[LeaseJournal] previousHash mismatch at entry ${i}: expected ${prevHash}, stored ${e.previousHash}`);
67
+ return false;
68
+ }
69
+ }
70
+ }
71
+ return true;
28
72
  }
29
73
  getAll() {
30
74
  return [...this.entries];
package/dist/local.d.ts CHANGED
@@ -13,10 +13,12 @@ export declare class LocalLeaseProvider implements WotsLeaseProvider {
13
13
  private readonly journal;
14
14
  private _initialized;
15
15
  private readonly deviceId;
16
- /** In-memory map: reservationId → treeId (lost on restart; watermark survives). */
17
- private readonly _treeIdByReservation;
18
16
  constructor(storage: StorageAdapter, logger?: LoggerAdapter, deviceId?: string);
19
17
  initialize(): Promise<void>;
18
+ /** Burn all active (non-expired) leases that have no matching treeId.
19
+ * On restart, leases with missing treeId (from before the treeId field was added)
20
+ * must be burned to prevent index reuse. */
21
+ private burnUnresolvedReservations;
20
22
  private recoverExpiredReservations;
21
23
  reserveKeyUse(params: ReserveParams): Promise<LeaseReservation>;
22
24
  commitKeyUse(reservationId: string, txId: string): Promise<void>;
package/dist/local.js CHANGED
@@ -22,8 +22,6 @@ class LocalLeaseProvider {
22
22
  constructor(storage, logger = new core_1.NoopLogger(), deviceId = 'local') {
23
23
  this.logger = logger;
24
24
  this._initialized = false;
25
- /** In-memory map: reservationId → treeId (lost on restart; watermark survives). */
26
- this._treeIdByReservation = new Map();
27
25
  this.watermark = new watermark_js_1.WotsWatermarkStore(storage, logger);
28
26
  this.leaseStore = new core_2.LeaseStore(storage, logger);
29
27
  this.journal = new journal_js_1.LeaseJournal(storage, logger);
@@ -36,13 +34,37 @@ class LocalLeaseProvider {
36
34
  await this.leaseStore.initialize();
37
35
  await this.journal.initialize();
38
36
  await this.recoverExpiredReservations();
37
+ await this.burnUnresolvedReservations();
39
38
  this._initialized = true;
40
39
  }
40
+ /** Burn all active (non-expired) leases that have no matching treeId.
41
+ * On restart, leases with missing treeId (from before the treeId field was added)
42
+ * must be burned to prevent index reuse. */
43
+ async burnUnresolvedReservations() {
44
+ const now = Date.now();
45
+ for (const lease of this.leaseStore.getAll()) {
46
+ if (lease.status === 'active' && lease.expiresAt >= now && !lease.treeId) {
47
+ this.logger.warn(`[LocalLeaseProvider] Burning unresolved lease ${lease.leaseId} (no treeId)`);
48
+ await this.watermark.markUnavailable('default', lease.indices, 'burned');
49
+ await this.leaseStore.updateStatus(lease.leaseId, 'cancelled');
50
+ await this.journal.append({
51
+ treeId: 'default',
52
+ branchId: 'default',
53
+ wotsIndex: (0, watermark_js_1.flatIndex)(lease.indices),
54
+ indices: lease.indices,
55
+ status: 'burned',
56
+ reservationId: lease.leaseId,
57
+ timestamp: now,
58
+ deviceId: this.deviceId,
59
+ });
60
+ }
61
+ }
62
+ }
41
63
  async recoverExpiredReservations() {
42
64
  const now = Date.now();
43
65
  for (const lease of this.leaseStore.getAll()) {
44
66
  if (lease.status === 'active' && lease.expiresAt < now) {
45
- const treeId = this._treeIdByReservation.get(lease.leaseId) ?? 'default';
67
+ const treeId = lease.treeId ?? 'default';
46
68
  await this.watermark.markUnavailable(treeId, lease.indices, 'reserved-expired');
47
69
  await this.leaseStore.updateStatus(lease.leaseId, 'expired');
48
70
  await this.journal.append({
@@ -51,6 +73,7 @@ class LocalLeaseProvider {
51
73
  wotsIndex: (0, watermark_js_1.flatIndex)(lease.indices),
52
74
  indices: lease.indices,
53
75
  status: 'reserved-expired',
76
+ reservationId: lease.leaseId,
54
77
  timestamp: now,
55
78
  deviceId: this.deviceId,
56
79
  });
@@ -62,7 +85,9 @@ class LocalLeaseProvider {
62
85
  await this.initialize();
63
86
  const treeId = params.treeId;
64
87
  const ttlMs = params.ttlMs ?? 120000;
88
+ // Atomically get the next available index AND mark it reserved in the watermark
65
89
  const indices = this.watermark.getNextIndices(treeId);
90
+ await this.watermark.markUnavailable(treeId, indices, 'reserved');
66
91
  if (params.deviceId) {
67
92
  const range = this.getDeviceRange(params.deviceId);
68
93
  if (range && (indices.addressIndex < range.start || indices.addressIndex > range.end)) {
@@ -74,6 +99,7 @@ class LocalLeaseProvider {
74
99
  const lease = {
75
100
  leaseId: reservationId,
76
101
  leaseToken: reservationId,
102
+ treeId,
77
103
  indices,
78
104
  expiresAt,
79
105
  status: 'active',
@@ -81,14 +107,13 @@ class LocalLeaseProvider {
81
107
  leaseTTL: ttlMs,
82
108
  };
83
109
  await this.leaseStore.save(lease);
84
- // Track treeId in memory so commit/burn can reference the right watermark tree
85
- this._treeIdByReservation.set(reservationId, treeId);
86
110
  await this.journal.append({
87
111
  treeId,
88
112
  branchId: params.branchId ?? 'default',
89
113
  wotsIndex: (0, watermark_js_1.flatIndex)(indices),
90
114
  indices,
91
115
  status: 'reserved',
116
+ reservationId,
92
117
  payloadHash: params.payloadHash,
93
118
  timestamp: Date.now(),
94
119
  deviceId: params.deviceId ?? this.deviceId,
@@ -101,17 +126,19 @@ class LocalLeaseProvider {
101
126
  const lease = this.leaseStore.get(reservationId);
102
127
  if (!lease)
103
128
  throw new errors_js_1.LeaseNotFoundError(reservationId);
104
- const treeId = this._treeIdByReservation.get(reservationId) ?? 'default';
129
+ if (lease.status === 'finalized')
130
+ return;
131
+ const treeId = lease.treeId ?? 'default';
105
132
  const indices = lease.indices;
106
133
  await this.watermark.markUnavailable(treeId, indices, 'committed');
107
134
  await this.leaseStore.updateStatus(reservationId, 'finalized');
108
- this._treeIdByReservation.delete(reservationId);
109
135
  await this.journal.append({
110
136
  treeId,
111
137
  branchId: 'default',
112
138
  wotsIndex: (0, watermark_js_1.flatIndex)(indices),
113
139
  indices,
114
140
  status: 'committed',
141
+ reservationId,
115
142
  txId,
116
143
  timestamp: Date.now(),
117
144
  deviceId: this.deviceId,
@@ -123,11 +150,10 @@ class LocalLeaseProvider {
123
150
  const lease = this.leaseStore.get(reservationId);
124
151
  if (!lease)
125
152
  throw new errors_js_1.LeaseNotFoundError(reservationId);
126
- const treeId = this._treeIdByReservation.get(reservationId) ?? 'default';
153
+ const treeId = lease.treeId ?? 'default';
127
154
  const indices = lease.indices;
128
155
  await this.watermark.markUnavailable(treeId, indices, 'burned');
129
156
  await this.leaseStore.updateStatus(reservationId, 'cancelled');
130
- this._treeIdByReservation.delete(reservationId);
131
157
  this.logger.warn(`[LocalLeaseProvider] Burning reservation ${reservationId}: ${reason}`);
132
158
  await this.journal.append({
133
159
  treeId,
@@ -135,6 +161,7 @@ class LocalLeaseProvider {
135
161
  wotsIndex: (0, watermark_js_1.flatIndex)(indices),
136
162
  indices,
137
163
  status: 'burned',
164
+ reservationId,
138
165
  timestamp: Date.now(),
139
166
  deviceId: this.deviceId,
140
167
  });
package/dist/stubs.d.ts CHANGED
@@ -1,23 +1,46 @@
1
1
  /**
2
- * Stub implementations for Layers 3–5.
3
- * These throw descriptive errors until the full implementations land.
2
+ * Implementations for Layers 3–5 of the WotsLeaseProvider hierarchy.
3
+ *
4
+ * Layer 3 (PersonalLeaseNodeProvider) — HTTP client for a personal @totemsdk/lookup-node
5
+ * that has lease coordination enabled ({ lease: { enabled: true } }).
6
+ * The node exposes REST endpoints under /v1/lease/*.
7
+ *
8
+ * Layers 4–5 (P2PQuorumLeaseProvider, OnchainWatermarkProvider) — require
9
+ * distributed infrastructure not yet available; they throw descriptive errors.
4
10
  */
5
11
  import type { WotsLeaseProvider, ReserveParams, LeaseReservation, LeaseCertificate, LocalWatermark, SyncResult, PersonalLeaseNodeConfig } from './types.js';
6
12
  /**
7
- * Layer 3 — personal p2p lease node.
13
+ * Layer 3 — personal lookup-node lease coordinator.
14
+ *
15
+ * Calls the HTTP REST API exposed by a running @totemsdk/lookup-node that has
16
+ * lease coordination enabled. All write operations are forwarded to the node's
17
+ * LeaseCoordinator so the node acts as the source-of-truth watermark journal
18
+ * for high-value transactions.
8
19
  *
9
- * Verifies ed25519 certs issued by a configured node public key.
10
- * Reserve/commit throws until the node is reachable — callers should
11
- * wrap with HybridLeaseProvider using a LocalLeaseProvider as the local layer.
20
+ * Wrap with HybridLeaseProvider so local reservations always succeed even when
21
+ * the personal node is temporarily unreachable:
22
+ *
23
+ * ```ts
24
+ * const provider = new HybridLeaseProvider({
25
+ * local: new LocalLeaseProvider(storage),
26
+ * node: new PersonalLeaseNodeProvider({ nodeUrl, nodePubkey }),
27
+ * threshold: 10, // escalate to node for txns >= 10 MIN
28
+ * });
29
+ * ```
12
30
  */
13
31
  export declare class PersonalLeaseNodeProvider implements WotsLeaseProvider {
14
- private readonly config;
32
+ private readonly baseUrl;
33
+ private readonly nodePubkey;
34
+ private readonly authToken?;
15
35
  constructor(config: PersonalLeaseNodeConfig);
16
- reserveKeyUse(_params: ReserveParams): Promise<LeaseReservation>;
17
- commitKeyUse(_reservationId: string, _txId: string): Promise<void>;
18
- burnReservation(_reservationId: string, _reason: string): Promise<void>;
19
- getLocalWatermark(_treeId: string): Promise<LocalWatermark>;
20
- publishWatermark(_treeId: string): Promise<void>;
36
+ private headers;
37
+ private post;
38
+ private get;
39
+ reserveKeyUse(params: ReserveParams): Promise<LeaseReservation>;
40
+ commitKeyUse(reservationId: string, txId: string): Promise<void>;
41
+ burnReservation(reservationId: string, reason: string): Promise<void>;
42
+ getLocalWatermark(treeId: string): Promise<LocalWatermark>;
43
+ publishWatermark(treeId: string): Promise<void>;
21
44
  syncLeaseJournal(): Promise<SyncResult>;
22
45
  verifyLeaseCertificate(cert?: LeaseCertificate): Promise<boolean>;
23
46
  }
package/dist/stubs.js CHANGED
@@ -1,44 +1,102 @@
1
1
  "use strict";
2
2
  /**
3
- * Stub implementations for Layers 3–5.
4
- * These throw descriptive errors until the full implementations land.
3
+ * Implementations for Layers 3–5 of the WotsLeaseProvider hierarchy.
4
+ *
5
+ * Layer 3 (PersonalLeaseNodeProvider) — HTTP client for a personal @totemsdk/lookup-node
6
+ * that has lease coordination enabled ({ lease: { enabled: true } }).
7
+ * The node exposes REST endpoints under /v1/lease/*.
8
+ *
9
+ * Layers 4–5 (P2PQuorumLeaseProvider, OnchainWatermarkProvider) — require
10
+ * distributed infrastructure not yet available; they throw descriptive errors.
5
11
  */
6
12
  Object.defineProperty(exports, "__esModule", { value: true });
7
13
  exports.OnchainWatermarkProvider = exports.P2PQuorumLeaseProvider = exports.PersonalLeaseNodeProvider = void 0;
8
14
  const errors_js_1 = require("./errors.js");
9
15
  /**
10
- * Layer 3 — personal p2p lease node.
16
+ * Layer 3 — personal lookup-node lease coordinator.
17
+ *
18
+ * Calls the HTTP REST API exposed by a running @totemsdk/lookup-node that has
19
+ * lease coordination enabled. All write operations are forwarded to the node's
20
+ * LeaseCoordinator so the node acts as the source-of-truth watermark journal
21
+ * for high-value transactions.
22
+ *
23
+ * Wrap with HybridLeaseProvider so local reservations always succeed even when
24
+ * the personal node is temporarily unreachable:
11
25
  *
12
- * Verifies ed25519 certs issued by a configured node public key.
13
- * Reserve/commit throws until the node is reachable — callers should
14
- * wrap with HybridLeaseProvider using a LocalLeaseProvider as the local layer.
26
+ * ```ts
27
+ * const provider = new HybridLeaseProvider({
28
+ * local: new LocalLeaseProvider(storage),
29
+ * node: new PersonalLeaseNodeProvider({ nodeUrl, nodePubkey }),
30
+ * threshold: 10, // escalate to node for txns >= 10 MIN
31
+ * });
32
+ * ```
15
33
  */
16
34
  class PersonalLeaseNodeProvider {
17
35
  constructor(config) {
18
- this.config = config;
19
- }
20
- reserveKeyUse(_params) {
21
- throw new errors_js_1.PersonalLeaseNodeNotConfiguredError();
22
- }
23
- commitKeyUse(_reservationId, _txId) {
24
- throw new errors_js_1.PersonalLeaseNodeNotConfiguredError();
25
- }
26
- burnReservation(_reservationId, _reason) {
27
- throw new errors_js_1.PersonalLeaseNodeNotConfiguredError();
28
- }
29
- getLocalWatermark(_treeId) {
30
- throw new errors_js_1.PersonalLeaseNodeNotConfiguredError();
31
- }
32
- publishWatermark(_treeId) {
33
- throw new errors_js_1.PersonalLeaseNodeNotConfiguredError();
34
- }
35
- syncLeaseJournal() {
36
- throw new errors_js_1.PersonalLeaseNodeNotConfiguredError();
36
+ this.baseUrl = config.nodeUrl.replace(/\/$/, '');
37
+ this.nodePubkey = config.nodePubkey;
38
+ this.authToken = config.authToken;
39
+ }
40
+ headers() {
41
+ const h = { 'Content-Type': 'application/json' };
42
+ if (this.authToken)
43
+ h['Authorization'] = `Bearer ${this.authToken}`;
44
+ return h;
45
+ }
46
+ async post(path, body) {
47
+ const res = await fetch(`${this.baseUrl}${path}`, {
48
+ method: 'POST',
49
+ headers: this.headers(),
50
+ body: JSON.stringify(body),
51
+ });
52
+ if (!res.ok) {
53
+ const text = await res.text().catch(() => '');
54
+ throw new Error(`PersonalLeaseNodeProvider: ${path} HTTP ${res.status} — ${text.slice(0, 200)}`);
55
+ }
56
+ return res.json();
57
+ }
58
+ async get(path) {
59
+ const res = await fetch(`${this.baseUrl}${path}`, { headers: this.headers() });
60
+ if (!res.ok) {
61
+ const text = await res.text().catch(() => '');
62
+ throw new Error(`PersonalLeaseNodeProvider: GET ${path} HTTP ${res.status} — ${text.slice(0, 200)}`);
63
+ }
64
+ return res.json();
65
+ }
66
+ async reserveKeyUse(params) {
67
+ const data = await this.post('/v1/lease/reserve', {
68
+ treeId: params.treeId,
69
+ branchId: params.branchId,
70
+ deviceId: params.deviceId,
71
+ ttlMs: params.ttlMs,
72
+ payloadHash: params.payloadHash,
73
+ purpose: params.purpose,
74
+ });
75
+ return { ...data.reservation, certificate: data.certificate };
76
+ }
77
+ async commitKeyUse(reservationId, txId) {
78
+ const data = await this.post('/v1/lease/commit', { reservationId, txId });
79
+ if (!data.ok)
80
+ throw new Error(`PersonalLeaseNodeProvider: commit failed — ${data.error ?? 'unknown'}`);
81
+ }
82
+ async burnReservation(reservationId, reason) {
83
+ const data = await this.post('/v1/lease/burn', { reservationId, reason });
84
+ if (!data.ok)
85
+ throw new Error(`PersonalLeaseNodeProvider: burn failed — ${data.error ?? 'unknown'}`);
86
+ }
87
+ async getLocalWatermark(treeId) {
88
+ return this.get(`/v1/lease/watermark/${encodeURIComponent(treeId)}`);
89
+ }
90
+ async publishWatermark(treeId) {
91
+ await this.post(`/v1/lease/watermark/${encodeURIComponent(treeId)}/publish`, {});
92
+ }
93
+ async syncLeaseJournal() {
94
+ return this.get('/v1/lease/journal/sync');
37
95
  }
38
96
  async verifyLeaseCertificate(cert) {
39
97
  if (!cert)
40
98
  return false;
41
- if (cert.issuedBy !== this.config.nodePubkey)
99
+ if (cert.issuedBy !== this.nodePubkey)
42
100
  return false;
43
101
  if (cert.expiresAt <= Date.now())
44
102
  return false;
package/dist/types.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @totemsdk/wots-lease — canonical v3 watermark types and WotsLeaseProvider interface
3
3
  */
4
- export type UnavailableReason = 'committed' | 'burned' | 'reserved-expired';
4
+ export type UnavailableReason = 'reserved' | 'committed' | 'burned' | 'reserved-expired';
5
5
  export interface SigningIndices {
6
6
  addressIndex: number;
7
7
  l1: number;
@@ -86,10 +86,13 @@ export interface JournalEntry {
86
86
  wotsIndex: number;
87
87
  indices: SigningIndices;
88
88
  status: 'reserved' | 'committed' | 'burned' | 'reserved-expired';
89
+ reservationId?: string;
89
90
  payloadHash?: string;
90
91
  txId?: string;
91
92
  timestamp: number;
92
93
  deviceId: string;
94
+ previousHash?: string;
95
+ hash?: string;
93
96
  }
94
97
  export interface DeviceKeyRange {
95
98
  deviceId: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@totemsdk/wots-lease",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "WOTS key-use coordination — canonical v3 watermark, provider-based lease safety layers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,22 +11,27 @@
11
11
  "import": "./dist/index.js"
12
12
  }
13
13
  },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "prepare": "tsc",
17
+ "clean": "rm -rf dist",
18
+ "test": "jest --passWithNoTests"
19
+ },
14
20
  "files": [
15
21
  "dist",
16
22
  "README.md",
17
23
  "LICENSE"
18
24
  ],
19
25
  "dependencies": {
20
- "@totemsdk/lookup-protocol": "0.1.3",
21
- "@totemsdk/core": "1.0.10"
26
+ "@totemsdk/core": "^1.1.0",
27
+ "@totemsdk/lookup-protocol": "^0.1.3"
22
28
  },
23
29
  "devDependencies": {
24
- "@noble/hashes": "^2.2.0",
25
- "@types/jest": "^29.0.0",
30
+ "@types/jest": "^30.0.0",
26
31
  "@types/node": "^20.0.0",
27
- "jest": "^29.0.0",
32
+ "jest": "^30.4.2",
28
33
  "ts-jest": "^29.0.0",
29
- "typescript": "^5.0.0"
34
+ "typescript": "^7.0.2"
30
35
  },
31
36
  "engines": {
32
37
  "node": ">=18.0.0"
@@ -36,13 +41,13 @@
36
41
  },
37
42
  "license": "MIT",
38
43
  "author": "Totem SDK",
39
- "homepage": "https://totemsdk.com",
44
+ "homepage": "https://totem.ing",
40
45
  "bugs": {
41
- "url": "https://github.com/MrGheek/axia-totem/issues"
46
+ "url": "https://github.com/totem-sdk/totem-sdk/issues"
42
47
  },
43
48
  "repository": {
44
49
  "type": "git",
45
- "url": "git+https://github.com/MrGheek/axia-totem.git",
50
+ "url": "git+https://github.com/totem-sdk/totem-sdk.git",
46
51
  "directory": "packages/totem-sdk/packages/wots-lease"
47
52
  },
48
53
  "keywords": [
@@ -54,10 +59,5 @@
54
59
  "wots",
55
60
  "kissvm",
56
61
  "utxo"
57
- ],
58
- "scripts": {
59
- "build": "tsc",
60
- "clean": "rm -rf dist",
61
- "test": "jest --passWithNoTests"
62
- }
63
- }
62
+ ]
63
+ }