@moltdm/client 1.3.2 → 1.4.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.
package/dist/index.js CHANGED
@@ -30,33 +30,156 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
+ BrowserStorage: () => BrowserStorage,
34
+ FileStorage: () => FileStorage,
35
+ MemoryStorage: () => MemoryStorage,
33
36
  MoltDMClient: () => MoltDMClient,
34
37
  default: () => index_default
35
38
  });
36
39
  module.exports = __toCommonJS(index_exports);
37
40
  var ed = __toESM(require("@noble/ed25519"));
38
41
  var import_ed25519 = require("@noble/curves/ed25519");
39
- var fs = __toESM(require("fs"));
40
- var path = __toESM(require("path"));
41
- var os = __toESM(require("os"));
42
- var import_crypto = require("crypto");
42
+ var MemoryStorage = class {
43
+ data = /* @__PURE__ */ new Map();
44
+ async get(key) {
45
+ return this.data.get(key) ?? null;
46
+ }
47
+ async set(key, value) {
48
+ this.data.set(key, value);
49
+ }
50
+ async delete(key) {
51
+ this.data.delete(key);
52
+ }
53
+ };
54
+ var BrowserStorage = class {
55
+ prefix;
56
+ constructor(prefix = "moltdm") {
57
+ this.prefix = prefix;
58
+ }
59
+ async get(key) {
60
+ if (typeof localStorage === "undefined") return null;
61
+ return localStorage.getItem(`${this.prefix}:${key}`);
62
+ }
63
+ async set(key, value) {
64
+ if (typeof localStorage === "undefined") return;
65
+ localStorage.setItem(`${this.prefix}:${key}`, value);
66
+ }
67
+ async delete(key) {
68
+ if (typeof localStorage === "undefined") return;
69
+ localStorage.removeItem(`${this.prefix}:${key}`);
70
+ }
71
+ };
72
+ var FileStorage = class {
73
+ basePath;
74
+ _fs = null;
75
+ _path = null;
76
+ _initialized = false;
77
+ constructor(basePath) {
78
+ this.basePath = basePath || ".moltdm";
79
+ }
80
+ async ensureModules() {
81
+ if (this._initialized) return;
82
+ if (typeof window !== "undefined") {
83
+ console.warn("FileStorage is not supported in browser. Use BrowserStorage instead.");
84
+ return;
85
+ }
86
+ try {
87
+ const fs = await import(
88
+ /* webpackIgnore: true */
89
+ "fs"
90
+ );
91
+ const path = await import(
92
+ /* webpackIgnore: true */
93
+ "path"
94
+ );
95
+ const os = await import(
96
+ /* webpackIgnore: true */
97
+ "os"
98
+ );
99
+ this._fs = fs;
100
+ this._path = path;
101
+ if (this.basePath === ".moltdm") {
102
+ const envPath = process.env.OPENCLAW_STATE_DIR;
103
+ this.basePath = envPath ? path.join(envPath, ".moltdm") : path.join(os.homedir(), ".moltdm");
104
+ }
105
+ if (!fs.existsSync(this.basePath)) {
106
+ fs.mkdirSync(this.basePath, { recursive: true });
107
+ }
108
+ this._initialized = true;
109
+ } catch (e) {
110
+ console.error("Failed to load Node.js modules for FileStorage:", e);
111
+ }
112
+ }
113
+ async get(key) {
114
+ await this.ensureModules();
115
+ if (!this._fs) return null;
116
+ const filePath = this._path.join(this.basePath, `${key}.json`);
117
+ if (!this._fs.existsSync(filePath)) return null;
118
+ return this._fs.readFileSync(filePath, "utf-8");
119
+ }
120
+ async set(key, value) {
121
+ await this.ensureModules();
122
+ if (!this._fs) return;
123
+ const filePath = this._path.join(this.basePath, `${key}.json`);
124
+ this._fs.writeFileSync(filePath, value);
125
+ }
126
+ async delete(key) {
127
+ await this.ensureModules();
128
+ if (!this._fs) return;
129
+ const filePath = this._path.join(this.basePath, `${key}.json`);
130
+ if (this._fs.existsSync(filePath)) {
131
+ this._fs.unlinkSync(filePath);
132
+ }
133
+ }
134
+ };
43
135
  function toBase64(bytes) {
44
- return Buffer.from(bytes).toString("base64");
136
+ if (typeof Buffer !== "undefined") {
137
+ return Buffer.from(bytes).toString("base64");
138
+ }
139
+ let binary = "";
140
+ for (let i = 0; i < bytes.length; i++) {
141
+ binary += String.fromCharCode(bytes[i]);
142
+ }
143
+ return btoa(binary);
45
144
  }
46
145
  function fromBase64(str) {
47
- return new Uint8Array(Buffer.from(str, "base64"));
146
+ if (typeof Buffer !== "undefined") {
147
+ return new Uint8Array(Buffer.from(str, "base64"));
148
+ }
149
+ const binary = atob(str);
150
+ const bytes = new Uint8Array(binary.length);
151
+ for (let i = 0; i < binary.length; i++) {
152
+ bytes[i] = binary.charCodeAt(i);
153
+ }
154
+ return bytes;
155
+ }
156
+ async function hmacSha256(key, data) {
157
+ const keyBuffer = new Uint8Array(key).buffer;
158
+ const dataBuffer = new Uint8Array(data).buffer;
159
+ const cryptoKey = await crypto.subtle.importKey(
160
+ "raw",
161
+ keyBuffer,
162
+ { name: "HMAC", hash: "SHA-256" },
163
+ false,
164
+ ["sign"]
165
+ );
166
+ const signature = await crypto.subtle.sign("HMAC", cryptoKey, dataBuffer);
167
+ return new Uint8Array(signature);
48
168
  }
49
169
  var MoltDMClient = class {
50
- storagePath;
170
+ storage;
51
171
  relayUrl;
52
172
  identity = null;
53
- // Our sender keys (for messages we send)
54
173
  senderKeys = /* @__PURE__ */ new Map();
55
- // Received sender keys (for messages from others) - keyed by `${convId}:${fromId}`
56
174
  receivedSenderKeys = /* @__PURE__ */ new Map();
57
175
  constructor(options = {}) {
58
- const defaultStoragePath = process.env.OPENCLAW_STATE_DIR ? path.join(process.env.OPENCLAW_STATE_DIR, ".moltdm") : path.join(os.homedir(), ".moltdm");
59
- this.storagePath = options.storagePath || defaultStoragePath;
176
+ if (options.storage) {
177
+ this.storage = options.storage;
178
+ } else if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
179
+ this.storage = new BrowserStorage();
180
+ } else {
181
+ this.storage = new FileStorage(options.storagePath);
182
+ }
60
183
  this.relayUrl = options.relayUrl || "https://relay.moltdm.com";
61
184
  if (options.identity) {
62
185
  this.identity = options.identity;
@@ -88,16 +211,12 @@ var MoltDMClient = class {
88
211
  await this.loadSenderKeys();
89
212
  return;
90
213
  }
91
- if (!fs.existsSync(this.storagePath)) {
92
- fs.mkdirSync(this.storagePath, { recursive: true });
93
- }
94
- const identityPath = path.join(this.storagePath, "identity.json");
95
- if (fs.existsSync(identityPath)) {
96
- const data = fs.readFileSync(identityPath, "utf-8");
97
- this.identity = JSON.parse(data);
214
+ const identityJson = await this.storage.get("identity");
215
+ if (identityJson) {
216
+ this.identity = JSON.parse(identityJson);
98
217
  } else {
99
218
  await this.createIdentity();
100
- fs.writeFileSync(identityPath, JSON.stringify(this.identity, null, 2));
219
+ await this.storage.set("identity", JSON.stringify(this.identity));
101
220
  }
102
221
  await this.loadSenderKeys();
103
222
  }
@@ -149,10 +268,9 @@ var MoltDMClient = class {
149
268
  };
150
269
  }
151
270
  async loadSenderKeys() {
152
- const keysPath = path.join(this.storagePath, "sender_keys.json");
153
- if (fs.existsSync(keysPath)) {
154
- const data = fs.readFileSync(keysPath, "utf-8");
155
- const keys = JSON.parse(data);
271
+ const keysJson = await this.storage.get("sender_keys");
272
+ if (keysJson) {
273
+ const keys = JSON.parse(keysJson);
156
274
  for (const [convId, keyData] of Object.entries(keys)) {
157
275
  const k = keyData;
158
276
  const chainKey = fromBase64(k.chainKey || k.key || "");
@@ -164,10 +282,9 @@ var MoltDMClient = class {
164
282
  });
165
283
  }
166
284
  }
167
- const receivedPath = path.join(this.storagePath, "received_sender_keys.json");
168
- if (fs.existsSync(receivedPath)) {
169
- const data = fs.readFileSync(receivedPath, "utf-8");
170
- const keys = JSON.parse(data);
285
+ const receivedJson = await this.storage.get("received_sender_keys");
286
+ if (receivedJson) {
287
+ const keys = JSON.parse(receivedJson);
171
288
  for (const [key, keyData] of Object.entries(keys)) {
172
289
  const k = keyData;
173
290
  this.receivedSenderKeys.set(key, {
@@ -179,7 +296,6 @@ var MoltDMClient = class {
179
296
  }
180
297
  }
181
298
  async saveSenderKeys() {
182
- const keysPath = path.join(this.storagePath, "sender_keys.json");
183
299
  const obj = {};
184
300
  for (const [convId, keyData] of this.senderKeys) {
185
301
  obj[convId] = {
@@ -189,8 +305,7 @@ var MoltDMClient = class {
189
305
  messageIndex: keyData.messageIndex
190
306
  };
191
307
  }
192
- fs.writeFileSync(keysPath, JSON.stringify(obj, null, 2));
193
- const receivedPath = path.join(this.storagePath, "received_sender_keys.json");
308
+ await this.storage.set("sender_keys", JSON.stringify(obj));
194
309
  const receivedObj = {};
195
310
  for (const [key, keyData] of this.receivedSenderKeys) {
196
311
  receivedObj[key] = {
@@ -199,7 +314,7 @@ var MoltDMClient = class {
199
314
  messageIndex: keyData.messageIndex
200
315
  };
201
316
  }
202
- fs.writeFileSync(receivedPath, JSON.stringify(receivedObj, null, 2));
317
+ await this.storage.set("received_sender_keys", JSON.stringify(receivedObj));
203
318
  }
204
319
  // ============================================
205
320
  // Sender Keys Protocol (Signal-style)
@@ -208,37 +323,25 @@ var MoltDMClient = class {
208
323
  * Derive message key from chain key using HMAC
209
324
  * message_key = HMAC-SHA256(chain_key, 0x01)
210
325
  */
211
- deriveMessageKey(chainKey) {
212
- const keyBuffer = Buffer.from(chainKey);
213
- const hmac = (0, import_crypto.createHmac)("sha256", keyBuffer);
214
- hmac.update(Buffer.from([1]));
215
- const digest = hmac.digest();
216
- const result = new Uint8Array(32);
217
- result.set(new Uint8Array(digest));
218
- return result;
326
+ async deriveMessageKey(chainKey) {
327
+ return hmacSha256(chainKey, new Uint8Array([1]));
219
328
  }
220
329
  /**
221
330
  * Ratchet chain key forward
222
331
  * new_chain_key = HMAC-SHA256(chain_key, 0x02)
223
332
  */
224
- ratchetChainKey(chainKey) {
225
- const keyBuffer = Buffer.from(chainKey);
226
- const hmac = (0, import_crypto.createHmac)("sha256", keyBuffer);
227
- hmac.update(Buffer.from([2]));
228
- const digest = hmac.digest();
229
- const result = new Uint8Array(32);
230
- result.set(new Uint8Array(digest));
231
- return result;
333
+ async ratchetChainKey(chainKey) {
334
+ return hmacSha256(chainKey, new Uint8Array([2]));
232
335
  }
233
336
  /**
234
337
  * Ratchet a chain key forward N steps (for catching up on missed messages)
235
338
  */
236
- ratchetChainKeyN(chainKey, steps) {
339
+ async ratchetChainKeyN(chainKey, steps) {
237
340
  const messageKeys = [];
238
341
  let current = chainKey;
239
342
  for (let i = 0; i < steps; i++) {
240
- messageKeys.push(this.deriveMessageKey(current));
241
- current = this.ratchetChainKey(current);
343
+ messageKeys.push(await this.deriveMessageKey(current));
344
+ current = await this.ratchetChainKey(current);
242
345
  }
243
346
  return { chainKey: current, messageKeys };
244
347
  }
@@ -332,27 +435,24 @@ var MoltDMClient = class {
332
435
  async send(conversationId, content, options) {
333
436
  this.ensureInitialized();
334
437
  let senderKeyState = this.senderKeys.get(conversationId);
335
- const isNewKey = !senderKeyState;
336
438
  if (!senderKeyState) {
337
439
  const initialKey = crypto.getRandomValues(new Uint8Array(32));
338
440
  senderKeyState = {
339
441
  chainKey: initialKey,
340
442
  initialChainKey: new Uint8Array(initialKey),
341
- // Copy for distribution
342
443
  version: 1,
343
444
  messageIndex: 0
344
445
  };
345
446
  this.senderKeys.set(conversationId, senderKeyState);
346
447
  }
347
- const messageKey = this.deriveMessageKey(senderKeyState.chainKey);
448
+ const messageKey = await this.deriveMessageKey(senderKeyState.chainKey);
348
449
  const currentIndex = senderKeyState.messageIndex;
349
- senderKeyState.chainKey = this.ratchetChainKey(senderKeyState.chainKey);
450
+ senderKeyState.chainKey = await this.ratchetChainKey(senderKeyState.chainKey);
350
451
  senderKeyState.messageIndex++;
351
452
  const ciphertext = await this.encrypt(content, messageKey);
352
453
  const encryptedSenderKeys = await this.encryptChainKeyForRecipients(
353
454
  conversationId,
354
455
  senderKeyState.initialChainKey
355
- // Send the original, unratcheted key
356
456
  );
357
457
  const response = await this.fetch(`/api/conversations/${conversationId}/messages`, {
358
458
  method: "POST",
@@ -404,26 +504,23 @@ var MoltDMClient = class {
404
504
  sharedSecretCopy.set(new Uint8Array(sharedSecret));
405
505
  const chainKeyCopy = new Uint8Array(32);
406
506
  chainKeyCopy.set(new Uint8Array(chainKey));
407
- const keyMaterial = await crypto.subtle.importKey(
408
- "raw",
409
- sharedSecretCopy.buffer,
410
- { name: "HKDF" },
411
- false,
412
- ["deriveKey"]
413
- );
507
+ const keyMaterial = await crypto.subtle.importKey("raw", sharedSecretCopy.buffer, { name: "HKDF" }, false, [
508
+ "deriveKey"
509
+ ]);
414
510
  const aesKey = await crypto.subtle.deriveKey(
415
- { name: "HKDF", hash: "SHA-256", salt: new Uint8Array(32), info: new TextEncoder().encode("moltdm-sender-key") },
511
+ {
512
+ name: "HKDF",
513
+ hash: "SHA-256",
514
+ salt: new Uint8Array(32),
515
+ info: new TextEncoder().encode("moltdm-sender-key")
516
+ },
416
517
  keyMaterial,
417
518
  { name: "AES-GCM", length: 256 },
418
519
  false,
419
520
  ["encrypt"]
420
521
  );
421
522
  const iv = crypto.getRandomValues(new Uint8Array(12));
422
- const encrypted = await crypto.subtle.encrypt(
423
- { name: "AES-GCM", iv },
424
- aesKey,
425
- chainKeyCopy.buffer
426
- );
523
+ const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, aesKey, chainKeyCopy.buffer);
427
524
  const combined = new Uint8Array(32 + 12 + encrypted.byteLength);
428
525
  combined.set(ephemeralPublic);
429
526
  combined.set(iv, 32);
@@ -457,17 +554,18 @@ var MoltDMClient = class {
457
554
  ["deriveKey"]
458
555
  );
459
556
  const aesKey = await crypto.subtle.deriveKey(
460
- { name: "HKDF", hash: "SHA-256", salt: new Uint8Array(32), info: new TextEncoder().encode("moltdm-sender-key") },
557
+ {
558
+ name: "HKDF",
559
+ hash: "SHA-256",
560
+ salt: new Uint8Array(32),
561
+ info: new TextEncoder().encode("moltdm-sender-key")
562
+ },
461
563
  keyMaterial,
462
564
  { name: "AES-GCM", length: 256 },
463
565
  false,
464
566
  ["decrypt"]
465
567
  );
466
- const decrypted = await crypto.subtle.decrypt(
467
- { name: "AES-GCM", iv },
468
- aesKey,
469
- encrypted
470
- );
568
+ const decrypted = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, aesKey, encrypted);
471
569
  return new Uint8Array(decrypted);
472
570
  } catch (e) {
473
571
  console.error("Failed to decrypt chain key:", e);
@@ -483,9 +581,11 @@ var MoltDMClient = class {
483
581
  const keyId = `${conversationId}:${fromId}`;
484
582
  let receivedKey = this.receivedSenderKeys.get(keyId);
485
583
  if (!encryptedSenderKeys) {
486
- console.error(`[decrypt] Message ${message.id} has no encryptedSenderKeys - was sent before Sender Keys implementation`);
584
+ console.error(`[decrypt] Message ${message.id} has no encryptedSenderKeys - sent before Sender Keys`);
487
585
  } else if (!encryptedSenderKeys[this.moltbotId]) {
488
- console.error(`[decrypt] Message ${message.id} has encryptedSenderKeys but not for us (${this.moltbotId}). Available: ${Object.keys(encryptedSenderKeys).join(", ")}`);
586
+ console.error(
587
+ `[decrypt] Message ${message.id} missing key for ${this.moltbotId}. Available: ${Object.keys(encryptedSenderKeys).join(", ")}`
588
+ );
489
589
  }
490
590
  if (encryptedSenderKeys && encryptedSenderKeys[this.moltbotId]) {
491
591
  if (!receivedKey || receivedKey.version !== senderKeyVersion) {
@@ -509,7 +609,7 @@ var MoltDMClient = class {
509
609
  }
510
610
  if (messageIndex > receivedKey.messageIndex) {
511
611
  const steps = messageIndex - receivedKey.messageIndex + 1;
512
- const { chainKey, messageKeys } = this.ratchetChainKeyN(receivedKey.chainKey, steps);
612
+ const { chainKey, messageKeys } = await this.ratchetChainKeyN(receivedKey.chainKey, steps);
513
613
  const messageKey = messageKeys[messageKeys.length - 1];
514
614
  receivedKey.chainKey = chainKey;
515
615
  receivedKey.messageIndex = messageIndex + 1;
@@ -517,14 +617,14 @@ var MoltDMClient = class {
517
617
  await this.saveSenderKeys();
518
618
  return this.decrypt(ciphertext, messageKey);
519
619
  } else if (messageIndex === receivedKey.messageIndex) {
520
- const messageKey = this.deriveMessageKey(receivedKey.chainKey);
521
- receivedKey.chainKey = this.ratchetChainKey(receivedKey.chainKey);
620
+ const messageKey = await this.deriveMessageKey(receivedKey.chainKey);
621
+ receivedKey.chainKey = await this.ratchetChainKey(receivedKey.chainKey);
522
622
  receivedKey.messageIndex++;
523
623
  this.receivedSenderKeys.set(keyId, receivedKey);
524
624
  await this.saveSenderKeys();
525
625
  return this.decrypt(ciphertext, messageKey);
526
626
  } else {
527
- console.error(`Message index ${messageIndex} is in the past (current: ${receivedKey.messageIndex})`);
627
+ console.error(`[decrypt] Message index ${messageIndex} is in the past (current: ${receivedKey.messageIndex})`);
528
628
  return null;
529
629
  }
530
630
  }
@@ -549,28 +649,22 @@ var MoltDMClient = class {
549
649
  // ============================================
550
650
  async react(conversationId, messageId, emoji) {
551
651
  this.ensureInitialized();
552
- const response = await this.fetch(
553
- `/api/conversations/${conversationId}/messages/${messageId}/reactions`,
554
- {
555
- method: "POST",
556
- body: JSON.stringify({ emoji })
557
- }
558
- );
652
+ const response = await this.fetch(`/api/conversations/${conversationId}/messages/${messageId}/reactions`, {
653
+ method: "POST",
654
+ body: JSON.stringify({ emoji })
655
+ });
559
656
  const data = await response.json();
560
657
  return data.reaction;
561
658
  }
562
659
  async unreact(conversationId, messageId, emoji) {
563
660
  this.ensureInitialized();
564
- await this.fetch(
565
- `/api/conversations/${conversationId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`,
566
- { method: "DELETE" }
567
- );
661
+ await this.fetch(`/api/conversations/${conversationId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}`, {
662
+ method: "DELETE"
663
+ });
568
664
  }
569
665
  async getReactions(conversationId, messageId) {
570
666
  this.ensureInitialized();
571
- const response = await this.fetch(
572
- `/api/conversations/${conversationId}/messages/${messageId}/reactions`
573
- );
667
+ const response = await this.fetch(`/api/conversations/${conversationId}/messages/${messageId}/reactions`);
574
668
  const data = await response.json();
575
669
  return data.reactions;
576
670
  }
@@ -694,9 +788,7 @@ var MoltDMClient = class {
694
788
  const encryptionKeys = {
695
789
  identityKey: this.identity.publicKey,
696
790
  privateKey: this.identity.privateKey,
697
- // Ed25519 private key for signing
698
791
  signedPreKeyPrivate: this.identity.signedPreKey.privateKey,
699
- // X25519 private key for decrypting sender keys
700
792
  senderKeys: senderKeysObj
701
793
  };
702
794
  const response = await this.fetch("/api/pair/approve", {
@@ -736,16 +828,14 @@ var MoltDMClient = class {
736
828
  return data.events;
737
829
  }
738
830
  // ============================================
739
- // Encryption (Simplified for demo)
831
+ // Encryption
740
832
  // ============================================
741
833
  async encrypt(plaintext, key) {
742
834
  const iv = crypto.getRandomValues(new Uint8Array(12));
743
835
  const encoder = new TextEncoder();
744
836
  const data = encoder.encode(plaintext);
745
837
  const keyBuffer = new Uint8Array(key).buffer;
746
- const cryptoKey = await crypto.subtle.importKey("raw", keyBuffer, { name: "AES-GCM" }, false, [
747
- "encrypt"
748
- ]);
838
+ const cryptoKey = await crypto.subtle.importKey("raw", keyBuffer, { name: "AES-GCM" }, false, ["encrypt"]);
749
839
  const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, cryptoKey, data);
750
840
  const combined = new Uint8Array(iv.length + encrypted.byteLength);
751
841
  combined.set(iv);
@@ -757,9 +847,7 @@ var MoltDMClient = class {
757
847
  const iv = combined.slice(0, 12);
758
848
  const encrypted = combined.slice(12);
759
849
  const keyBuffer = new Uint8Array(key).buffer;
760
- const cryptoKey = await crypto.subtle.importKey("raw", keyBuffer, { name: "AES-GCM" }, false, [
761
- "decrypt"
762
- ]);
850
+ const cryptoKey = await crypto.subtle.importKey("raw", keyBuffer, { name: "AES-GCM" }, false, ["decrypt"]);
763
851
  const decrypted = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, cryptoKey, encrypted);
764
852
  const decoder = new TextDecoder();
765
853
  return decoder.decode(decrypted);
@@ -772,22 +860,12 @@ var MoltDMClient = class {
772
860
  throw new Error("Not initialized. Call initialize() first.");
773
861
  }
774
862
  }
775
- /**
776
- * Sign a message using Ed25519
777
- */
778
863
  async signMessage(message) {
779
864
  const privateKeyBytes = fromBase64(this.identity.privateKey);
780
- const signature = await ed.signAsync(
781
- new TextEncoder().encode(message),
782
- privateKeyBytes
783
- );
865
+ const signature = await ed.signAsync(new TextEncoder().encode(message), privateKeyBytes);
784
866
  return toBase64(signature);
785
867
  }
786
- /**
787
- * Create the message to sign for a request
788
- * Format: timestamp:method:path:bodyHash
789
- */
790
- async createSignedMessage(timestamp, method, path2, body) {
868
+ async createSignedMessage(timestamp, method, path, body) {
791
869
  let bodyHash = "";
792
870
  if (body) {
793
871
  const bodyBytes = new TextEncoder().encode(body);
@@ -795,18 +873,15 @@ var MoltDMClient = class {
795
873
  const hashArray = Array.from(new Uint8Array(hashBuffer));
796
874
  bodyHash = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
797
875
  }
798
- return `${timestamp}:${method}:${path2}:${bodyHash}`;
876
+ return `${timestamp}:${method}:${path}:${bodyHash}`;
799
877
  }
800
- /**
801
- * Make an authenticated fetch request with Ed25519 signature
802
- */
803
- async fetch(path2, options = {}) {
878
+ async fetch(path, options = {}) {
804
879
  const method = options.method || "GET";
805
880
  const body = options.body;
806
881
  const timestamp = Date.now().toString();
807
- const message = await this.createSignedMessage(timestamp, method, path2, body);
882
+ const message = await this.createSignedMessage(timestamp, method, path, body);
808
883
  const signature = await this.signMessage(message);
809
- const response = await fetch(`${this.relayUrl}${path2}`, {
884
+ const response = await fetch(`${this.relayUrl}${path}`, {
810
885
  ...options,
811
886
  headers: {
812
887
  "Content-Type": "application/json",
@@ -826,5 +901,8 @@ var MoltDMClient = class {
826
901
  var index_default = MoltDMClient;
827
902
  // Annotate the CommonJS export names for ESM import in node:
828
903
  0 && (module.exports = {
904
+ BrowserStorage,
905
+ FileStorage,
906
+ MemoryStorage,
829
907
  MoltDMClient
830
908
  });