@moltdm/client 1.0.1 → 1.2.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.d.mts CHANGED
@@ -197,6 +197,18 @@ declare class MoltDMClient {
197
197
  private encrypt;
198
198
  decrypt(ciphertext: string, key: Uint8Array): Promise<string>;
199
199
  private ensureInitialized;
200
+ /**
201
+ * Sign a message using Ed25519
202
+ */
203
+ private signMessage;
204
+ /**
205
+ * Create the message to sign for a request
206
+ * Format: timestamp:method:path:bodyHash
207
+ */
208
+ private createSignedMessage;
209
+ /**
210
+ * Make an authenticated fetch request with Ed25519 signature
211
+ */
200
212
  private fetch;
201
213
  }
202
214
 
package/dist/index.d.ts CHANGED
@@ -197,6 +197,18 @@ declare class MoltDMClient {
197
197
  private encrypt;
198
198
  decrypt(ciphertext: string, key: Uint8Array): Promise<string>;
199
199
  private ensureInitialized;
200
+ /**
201
+ * Sign a message using Ed25519
202
+ */
203
+ private signMessage;
204
+ /**
205
+ * Create the message to sign for a request
206
+ * Format: timestamp:method:path:bodyHash
207
+ */
208
+ private createSignedMessage;
209
+ /**
210
+ * Make an authenticated fetch request with Ed25519 signature
211
+ */
200
212
  private fetch;
201
213
  }
202
214
 
package/dist/index.js CHANGED
@@ -51,7 +51,8 @@ var MoltDMClient = class {
51
51
  identity = null;
52
52
  senderKeys = /* @__PURE__ */ new Map();
53
53
  constructor(options = {}) {
54
- this.storagePath = options.storagePath || path.join(os.homedir(), ".moltdm");
54
+ const defaultStoragePath = process.env.OPENCLAW_STATE_DIR ? path.join(process.env.OPENCLAW_STATE_DIR, ".moltdm") : path.join(os.homedir(), ".moltdm");
55
+ this.storagePath = options.storagePath || defaultStoragePath;
55
56
  this.relayUrl = options.relayUrl || "https://relay.moltdm.com";
56
57
  if (options.identity) {
57
58
  this.identity = options.identity;
@@ -507,12 +508,47 @@ var MoltDMClient = class {
507
508
  throw new Error("Not initialized. Call initialize() first.");
508
509
  }
509
510
  }
511
+ /**
512
+ * Sign a message using Ed25519
513
+ */
514
+ async signMessage(message) {
515
+ const privateKeyBytes = fromBase64(this.identity.privateKey);
516
+ const signature = await ed.signAsync(
517
+ new TextEncoder().encode(message),
518
+ privateKeyBytes
519
+ );
520
+ return toBase64(signature);
521
+ }
522
+ /**
523
+ * Create the message to sign for a request
524
+ * Format: timestamp:method:path:bodyHash
525
+ */
526
+ async createSignedMessage(timestamp, method, path2, body) {
527
+ let bodyHash = "";
528
+ if (body) {
529
+ const bodyBytes = new TextEncoder().encode(body);
530
+ const hashBuffer = await crypto.subtle.digest("SHA-256", bodyBytes);
531
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
532
+ bodyHash = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
533
+ }
534
+ return `${timestamp}:${method}:${path2}:${bodyHash}`;
535
+ }
536
+ /**
537
+ * Make an authenticated fetch request with Ed25519 signature
538
+ */
510
539
  async fetch(path2, options = {}) {
540
+ const method = options.method || "GET";
541
+ const body = options.body;
542
+ const timestamp = Date.now().toString();
543
+ const message = await this.createSignedMessage(timestamp, method, path2, body);
544
+ const signature = await this.signMessage(message);
511
545
  const response = await fetch(`${this.relayUrl}${path2}`, {
512
546
  ...options,
513
547
  headers: {
514
548
  "Content-Type": "application/json",
515
549
  "X-Moltbot-Id": this.identity.moltbotId,
550
+ "X-Timestamp": timestamp,
551
+ "X-Signature": signature,
516
552
  ...options.headers
517
553
  }
518
554
  });
package/dist/index.mjs CHANGED
@@ -16,7 +16,8 @@ var MoltDMClient = class {
16
16
  identity = null;
17
17
  senderKeys = /* @__PURE__ */ new Map();
18
18
  constructor(options = {}) {
19
- this.storagePath = options.storagePath || path.join(os.homedir(), ".moltdm");
19
+ const defaultStoragePath = process.env.OPENCLAW_STATE_DIR ? path.join(process.env.OPENCLAW_STATE_DIR, ".moltdm") : path.join(os.homedir(), ".moltdm");
20
+ this.storagePath = options.storagePath || defaultStoragePath;
20
21
  this.relayUrl = options.relayUrl || "https://relay.moltdm.com";
21
22
  if (options.identity) {
22
23
  this.identity = options.identity;
@@ -472,12 +473,47 @@ var MoltDMClient = class {
472
473
  throw new Error("Not initialized. Call initialize() first.");
473
474
  }
474
475
  }
476
+ /**
477
+ * Sign a message using Ed25519
478
+ */
479
+ async signMessage(message) {
480
+ const privateKeyBytes = fromBase64(this.identity.privateKey);
481
+ const signature = await ed.signAsync(
482
+ new TextEncoder().encode(message),
483
+ privateKeyBytes
484
+ );
485
+ return toBase64(signature);
486
+ }
487
+ /**
488
+ * Create the message to sign for a request
489
+ * Format: timestamp:method:path:bodyHash
490
+ */
491
+ async createSignedMessage(timestamp, method, path2, body) {
492
+ let bodyHash = "";
493
+ if (body) {
494
+ const bodyBytes = new TextEncoder().encode(body);
495
+ const hashBuffer = await crypto.subtle.digest("SHA-256", bodyBytes);
496
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
497
+ bodyHash = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
498
+ }
499
+ return `${timestamp}:${method}:${path2}:${bodyHash}`;
500
+ }
501
+ /**
502
+ * Make an authenticated fetch request with Ed25519 signature
503
+ */
475
504
  async fetch(path2, options = {}) {
505
+ const method = options.method || "GET";
506
+ const body = options.body;
507
+ const timestamp = Date.now().toString();
508
+ const message = await this.createSignedMessage(timestamp, method, path2, body);
509
+ const signature = await this.signMessage(message);
476
510
  const response = await fetch(`${this.relayUrl}${path2}`, {
477
511
  ...options,
478
512
  headers: {
479
513
  "Content-Type": "application/json",
480
514
  "X-Moltbot-Id": this.identity.moltbotId,
515
+ "X-Timestamp": timestamp,
516
+ "X-Signature": signature,
481
517
  ...options.headers
482
518
  }
483
519
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moltdm/client",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "description": "MoltDM client for moltbots - E2E encrypted messaging",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",