@totemsdk/wots-lease 0.1.3 → 0.1.5

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,18 +85,22 @@ 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
+ // Validate device range BEFORE marking unavailable — prevents permanent index loss
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)) {
69
94
  throw new errors_js_1.DeviceRangeViolationError(indices.addressIndex, range.start, range.end);
70
95
  }
71
96
  }
97
+ await this.watermark.markUnavailable(treeId, indices, 'reserved');
72
98
  const reservationId = randomId();
73
99
  const expiresAt = Date.now() + ttlMs;
74
100
  const lease = {
75
101
  leaseId: reservationId,
76
102
  leaseToken: reservationId,
103
+ treeId,
77
104
  indices,
78
105
  expiresAt,
79
106
  status: 'active',
@@ -81,14 +108,13 @@ class LocalLeaseProvider {
81
108
  leaseTTL: ttlMs,
82
109
  };
83
110
  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
111
  await this.journal.append({
87
112
  treeId,
88
113
  branchId: params.branchId ?? 'default',
89
114
  wotsIndex: (0, watermark_js_1.flatIndex)(indices),
90
115
  indices,
91
116
  status: 'reserved',
117
+ reservationId,
92
118
  payloadHash: params.payloadHash,
93
119
  timestamp: Date.now(),
94
120
  deviceId: params.deviceId ?? this.deviceId,
@@ -101,17 +127,19 @@ class LocalLeaseProvider {
101
127
  const lease = this.leaseStore.get(reservationId);
102
128
  if (!lease)
103
129
  throw new errors_js_1.LeaseNotFoundError(reservationId);
104
- const treeId = this._treeIdByReservation.get(reservationId) ?? 'default';
130
+ if (lease.status === 'finalized')
131
+ return;
132
+ const treeId = lease.treeId ?? 'default';
105
133
  const indices = lease.indices;
106
134
  await this.watermark.markUnavailable(treeId, indices, 'committed');
107
135
  await this.leaseStore.updateStatus(reservationId, 'finalized');
108
- this._treeIdByReservation.delete(reservationId);
109
136
  await this.journal.append({
110
137
  treeId,
111
138
  branchId: 'default',
112
139
  wotsIndex: (0, watermark_js_1.flatIndex)(indices),
113
140
  indices,
114
141
  status: 'committed',
142
+ reservationId,
115
143
  txId,
116
144
  timestamp: Date.now(),
117
145
  deviceId: this.deviceId,
@@ -123,11 +151,10 @@ class LocalLeaseProvider {
123
151
  const lease = this.leaseStore.get(reservationId);
124
152
  if (!lease)
125
153
  throw new errors_js_1.LeaseNotFoundError(reservationId);
126
- const treeId = this._treeIdByReservation.get(reservationId) ?? 'default';
154
+ const treeId = lease.treeId ?? 'default';
127
155
  const indices = lease.indices;
128
156
  await this.watermark.markUnavailable(treeId, indices, 'burned');
129
157
  await this.leaseStore.updateStatus(reservationId, 'cancelled');
130
- this._treeIdByReservation.delete(reservationId);
131
158
  this.logger.warn(`[LocalLeaseProvider] Burning reservation ${reservationId}: ${reason}`);
132
159
  await this.journal.append({
133
160
  treeId,
@@ -135,6 +162,7 @@ class LocalLeaseProvider {
135
162
  wotsIndex: (0, watermark_js_1.flatIndex)(indices),
136
163
  indices,
137
164
  status: 'burned',
165
+ reservationId,
138
166
  timestamp: Date.now(),
139
167
  deviceId: this.deviceId,
140
168
  });
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.5",
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
+ }