@badgerclaw/connect 1.1.0 → 1.1.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@badgerclaw/connect",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "BadgerClaw channel plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "dependencies": {
@@ -0,0 +1,82 @@
1
+ import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
2
+ import { appendFileSync, mkdirSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { getMatrixLogService } from "../sdk-runtime.js";
6
+
7
+ export type KeyBackupStatus = {
8
+ enabled: boolean;
9
+ version: string | null;
10
+ deviceId: string | null;
11
+ };
12
+
13
+ export async function getEncryptionKeyBackupStatus(
14
+ client: MatrixClient,
15
+ ): Promise<KeyBackupStatus> {
16
+ const LogService = getMatrixLogService();
17
+ try {
18
+ const backupInfo = await client.getKeyBackupVersion();
19
+ const whoami = await client.getWhoAmI();
20
+ const deviceId = whoami.device_id ?? null;
21
+ return {
22
+ enabled: backupInfo !== null,
23
+ version: backupInfo?.version ?? null,
24
+ deviceId,
25
+ };
26
+ } catch (err) {
27
+ LogService.warn("MatrixKeyBackup", "Failed to check key backup status:", err);
28
+ return { enabled: false, version: null, deviceId: null };
29
+ }
30
+ }
31
+
32
+ export async function setupKeyBackup(client: MatrixClient): Promise<void> {
33
+ const LogService = getMatrixLogService();
34
+
35
+ let deviceId = "(unknown)";
36
+ try {
37
+ const whoami = await client.getWhoAmI();
38
+ deviceId = whoami.device_id ?? deviceId;
39
+ } catch {
40
+ // Non-fatal
41
+ }
42
+
43
+ LogService.info("MatrixKeyBackup", `Crypto ready — device ID: ${deviceId}`);
44
+
45
+ if (!client.crypto) {
46
+ LogService.info("MatrixKeyBackup", "Crypto client not available, skipping key backup setup");
47
+ return;
48
+ }
49
+
50
+ try {
51
+ const backupInfo = await client.getKeyBackupVersion();
52
+ if (!backupInfo) {
53
+ LogService.info(
54
+ "MatrixKeyBackup",
55
+ "No key backup version found on server — skipping backup setup",
56
+ );
57
+ return;
58
+ }
59
+
60
+ await client.crypto.enableKeyBackup(backupInfo);
61
+ LogService.info(
62
+ "MatrixKeyBackup",
63
+ `Key backup enabled (version ${backupInfo.version}) on device ${deviceId}`,
64
+ );
65
+ _persistBackupRecord(backupInfo.version, deviceId);
66
+ } catch (err) {
67
+ LogService.warn("MatrixKeyBackup", "Key backup setup failed:", err);
68
+ }
69
+ }
70
+
71
+ function _persistBackupRecord(version: string, deviceId: string): void {
72
+ try {
73
+ const dir = join(homedir(), ".openclaw", "backup");
74
+ mkdirSync(dir, { recursive: true });
75
+ const path = join(dir, "key-backup-record.log");
76
+ const entry =
77
+ JSON.stringify({ version, deviceId, timestamp: new Date().toISOString() }) + "\n";
78
+ appendFileSync(path, entry, "utf8");
79
+ } catch {
80
+ // Non-fatal — backup is enabled, record persistence is best-effort
81
+ }
82
+ }
@@ -2,6 +2,7 @@ import type { MatrixClient } from "@vector-im/matrix-bot-sdk";
2
2
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
3
3
  import type { CoreConfig } from "../../types.js";
4
4
  import { getMatrixLogService } from "../sdk-runtime.js";
5
+ import { setupKeyBackup } from "./backup.js";
5
6
  import { resolveMatrixAuth } from "./config.js";
6
7
  import { createMatrixClient } from "./create-client.js";
7
8
  import { startMatrixClientWithGrace } from "./startup.js";
@@ -79,6 +80,7 @@ async function ensureSharedClientStarted(params: {
79
80
  joinedRooms,
80
81
  );
81
82
  params.state.cryptoReady = true;
83
+ await setupKeyBackup(client);
82
84
  }
83
85
  } catch (err) {
84
86
  const LogService = getMatrixLogService();