@openclaw/nostr 2026.5.30-beta.1 → 2026.5.31-beta.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/dist/api.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { o as resolveNostrAccount } from "./setup-surface-CVEYWXAG.js";
|
|
2
2
|
import { getPluginRuntimeGatewayRequestScope } from "./runtime-api.js";
|
|
3
3
|
import { n as NostrProfileSchema } from "./config-schema-DIiXiBKr.js";
|
|
4
|
-
import { a as setNostrRuntime, i as getNostrRuntime, n as nostrPlugin, o as contentToProfile, r as publishNostrProfile, t as getNostrProfileState } from "./channel-
|
|
4
|
+
import { a as setNostrRuntime, i as getNostrRuntime, n as nostrPlugin, o as contentToProfile, r as publishNostrProfile, t as getNostrProfileState } from "./channel-nsm56KpS.js";
|
|
5
5
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { SimplePool, verifyEvent } from "nostr-tools";
|
|
8
|
+
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
8
9
|
import { readJsonBodyWithLimit, requestBodyErrorToText } from "openclaw/plugin-sdk/webhook-request-guards";
|
|
9
10
|
import { createFixedWindowRateLimiter } from "openclaw/plugin-sdk/webhook-ingress";
|
|
10
|
-
import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
11
11
|
import { isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
|
|
12
12
|
//#region extensions/nostr/src/nostr-profile-url-safety.ts
|
|
13
13
|
function validateUrlSafety(urlStr) {
|
|
@@ -5,10 +5,9 @@ import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
|
5
5
|
import { createScopedDmSecurityResolver, createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
6
6
|
import { createChatChannelPlugin } from "openclaw/plugin-sdk/channel-core";
|
|
7
7
|
import { createChannelMessageAdapterFromOutbound } from "openclaw/plugin-sdk/channel-outbound";
|
|
8
|
-
import { buildPassiveChannelStatusSummary, buildTrafficStatusSummary, runStoppablePassiveMonitor
|
|
8
|
+
import { buildPassiveChannelStatusSummary, buildTrafficStatusSummary, runStoppablePassiveMonitor } from "openclaw/plugin-sdk/extension-shared";
|
|
9
9
|
import { createComputedAccountStatusAdapter } from "openclaw/plugin-sdk/status-helpers";
|
|
10
10
|
import { normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
11
|
-
import { z } from "zod";
|
|
12
11
|
import { resolveStableChannelMessageIngress } from "openclaw/plugin-sdk/channel-ingress-runtime";
|
|
13
12
|
import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
|
|
14
13
|
import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result";
|
|
@@ -16,10 +15,8 @@ import { SimplePool, finalizeEvent, getPublicKey, verifyEvent } from "nostr-tool
|
|
|
16
15
|
import { decrypt, encrypt } from "nostr-tools/nip04";
|
|
17
16
|
import { createDirectDmPreCryptoGuardPolicy } from "openclaw/plugin-sdk/direct-dm-guard-policy";
|
|
18
17
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
19
|
-
import os from "node:os";
|
|
20
|
-
import path from "node:path";
|
|
21
|
-
import { privateFileStore } from "openclaw/plugin-sdk/security-runtime";
|
|
22
18
|
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
|
19
|
+
import { resolveIntegerOption } from "openclaw/plugin-sdk/number-runtime";
|
|
23
20
|
import { buildChannelOutboundSessionRoute, stripChannelTargetPrefix } from "openclaw/plugin-sdk/core";
|
|
24
21
|
//#region extensions/nostr/src/metrics.ts
|
|
25
22
|
/**
|
|
@@ -410,78 +407,40 @@ const { setRuntime: setNostrRuntime, getRuntime: getNostrRuntime } = createPlugi
|
|
|
410
407
|
//#region extensions/nostr/src/nostr-state-store.ts
|
|
411
408
|
const STORE_VERSION = 2;
|
|
412
409
|
const PROFILE_STATE_VERSION = 1;
|
|
413
|
-
const NullableFiniteNumberSchema = z.number().finite().nullable().catch(null);
|
|
414
|
-
const NostrBusStateV1Schema = z.object({
|
|
415
|
-
version: z.literal(1),
|
|
416
|
-
lastProcessedAt: NullableFiniteNumberSchema,
|
|
417
|
-
gatewayStartedAt: NullableFiniteNumberSchema
|
|
418
|
-
});
|
|
419
|
-
const NostrBusStateSchema = z.object({
|
|
420
|
-
version: z.literal(2),
|
|
421
|
-
lastProcessedAt: NullableFiniteNumberSchema,
|
|
422
|
-
gatewayStartedAt: NullableFiniteNumberSchema,
|
|
423
|
-
recentEventIds: z.array(z.unknown()).catch([]).transform((ids) => ids.filter((id) => typeof id === "string"))
|
|
424
|
-
});
|
|
425
|
-
const NostrProfileStateSchema = z.object({
|
|
426
|
-
version: z.literal(1),
|
|
427
|
-
lastPublishedAt: NullableFiniteNumberSchema,
|
|
428
|
-
lastPublishedEventId: z.string().nullable().catch(null),
|
|
429
|
-
lastPublishResults: z.record(z.string(), z.enum([
|
|
430
|
-
"ok",
|
|
431
|
-
"failed",
|
|
432
|
-
"timeout"
|
|
433
|
-
])).nullable().catch(null)
|
|
434
|
-
});
|
|
435
410
|
function normalizeAccountId(accountId) {
|
|
436
411
|
const trimmed = accountId?.trim();
|
|
437
412
|
if (!trimmed) return "default";
|
|
438
413
|
return trimmed.replace(/[^a-z0-9._-]+/gi, "_");
|
|
439
414
|
}
|
|
440
|
-
function
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
const stateDir = getNostrRuntime().state.resolveStateDir(env, os.homedir);
|
|
447
|
-
const normalized = normalizeAccountId(accountId);
|
|
448
|
-
return path.join(stateDir, "nostr", `profile-state-${normalized}.json`);
|
|
415
|
+
function openNostrBusStateStore(env) {
|
|
416
|
+
return getNostrRuntime().state.openKeyedStore({
|
|
417
|
+
namespace: "bus-state",
|
|
418
|
+
maxEntries: 256,
|
|
419
|
+
...env ? { env } : {}
|
|
420
|
+
});
|
|
449
421
|
}
|
|
450
|
-
function
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
version: 2,
|
|
457
|
-
lastProcessedAt: parsedV1.lastProcessedAt,
|
|
458
|
-
gatewayStartedAt: parsedV1.gatewayStartedAt,
|
|
459
|
-
recentEventIds: []
|
|
460
|
-
};
|
|
422
|
+
function openNostrProfileStateStore(env) {
|
|
423
|
+
return getNostrRuntime().state.openKeyedStore({
|
|
424
|
+
namespace: "profile-state",
|
|
425
|
+
maxEntries: 256,
|
|
426
|
+
...env ? { env } : {}
|
|
427
|
+
});
|
|
461
428
|
}
|
|
462
429
|
async function readNostrBusState(params) {
|
|
463
|
-
|
|
464
|
-
try {
|
|
465
|
-
const raw = await privateFileStore(path.dirname(filePath)).readTextIfExists(path.basename(filePath));
|
|
466
|
-
if (raw === null) return null;
|
|
467
|
-
return safeParseState(raw);
|
|
468
|
-
} catch {
|
|
469
|
-
return null;
|
|
470
|
-
}
|
|
430
|
+
return await openNostrBusStateStore(params.env).lookup(normalizeAccountId(params.accountId)) ?? null;
|
|
471
431
|
}
|
|
472
432
|
async function writeNostrBusState(params) {
|
|
473
|
-
const filePath = resolveNostrStatePath(params.accountId, params.env);
|
|
474
433
|
const payload = {
|
|
475
434
|
version: STORE_VERSION,
|
|
476
435
|
lastProcessedAt: params.lastProcessedAt,
|
|
477
436
|
gatewayStartedAt: params.gatewayStartedAt,
|
|
478
437
|
recentEventIds: (params.recentEventIds ?? []).filter((x) => typeof x === "string")
|
|
479
438
|
};
|
|
480
|
-
await
|
|
439
|
+
await openNostrBusStateStore(params.env).register(normalizeAccountId(params.accountId), payload);
|
|
481
440
|
}
|
|
482
441
|
/**
|
|
483
442
|
* Determine the `since` timestamp for subscription.
|
|
484
|
-
* Returns the later of: lastProcessedAt or gatewayStartedAt (both from
|
|
443
|
+
* Returns the later of: lastProcessedAt or gatewayStartedAt (both from state),
|
|
485
444
|
* falling back to `now` for fresh starts.
|
|
486
445
|
*/
|
|
487
446
|
function computeSinceTimestamp(state, nowSec = Math.floor(Date.now() / 1e3)) {
|
|
@@ -490,36 +449,29 @@ function computeSinceTimestamp(state, nowSec = Math.floor(Date.now() / 1e3)) {
|
|
|
490
449
|
if (candidates.length === 0) return nowSec;
|
|
491
450
|
return Math.max(...candidates);
|
|
492
451
|
}
|
|
493
|
-
function safeParseProfileState(raw) {
|
|
494
|
-
return safeParseJsonWithSchema(NostrProfileStateSchema, raw);
|
|
495
|
-
}
|
|
496
452
|
async function readNostrProfileState(params) {
|
|
497
|
-
|
|
498
|
-
try {
|
|
499
|
-
const raw = await privateFileStore(path.dirname(filePath)).readTextIfExists(path.basename(filePath));
|
|
500
|
-
if (raw === null) return null;
|
|
501
|
-
return safeParseProfileState(raw);
|
|
502
|
-
} catch {
|
|
503
|
-
return null;
|
|
504
|
-
}
|
|
453
|
+
return await openNostrProfileStateStore(params.env).lookup(normalizeAccountId(params.accountId)) ?? null;
|
|
505
454
|
}
|
|
506
455
|
async function writeNostrProfileState(params) {
|
|
507
|
-
const filePath = resolveNostrProfileStatePath(params.accountId, params.env);
|
|
508
456
|
const payload = {
|
|
509
457
|
version: PROFILE_STATE_VERSION,
|
|
510
458
|
lastPublishedAt: params.lastPublishedAt,
|
|
511
459
|
lastPublishedEventId: params.lastPublishedEventId,
|
|
512
460
|
lastPublishResults: params.lastPublishResults
|
|
513
461
|
};
|
|
514
|
-
await
|
|
462
|
+
await openNostrProfileStateStore(params.env).register(normalizeAccountId(params.accountId), payload);
|
|
515
463
|
}
|
|
516
464
|
//#endregion
|
|
517
465
|
//#region extensions/nostr/src/seen-tracker.ts
|
|
518
466
|
/**
|
|
467
|
+
* LRU-based seen event tracker with TTL support.
|
|
468
|
+
* Prevents unbounded memory growth under high load or abuse.
|
|
469
|
+
*/
|
|
470
|
+
/**
|
|
519
471
|
* Create a new seen tracker with LRU eviction and TTL expiration.
|
|
520
472
|
*/
|
|
521
473
|
function createSeenTracker(options) {
|
|
522
|
-
const maxEntries = options?.maxEntries
|
|
474
|
+
const maxEntries = resolveIntegerOption(options?.maxEntries, 1e5, { min: 1 });
|
|
523
475
|
const ttlMs = options?.ttlMs ?? 3600 * 1e3;
|
|
524
476
|
const pruneIntervalMs = options?.pruneIntervalMs ?? 600 * 1e3;
|
|
525
477
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as nostrPlugin } from "./channel-
|
|
1
|
+
import { n as nostrPlugin } from "./channel-nsm56KpS.js";
|
|
2
2
|
export { nostrPlugin };
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
//#region extensions/nostr/doctor-contract-api.ts
|
|
4
|
+
const BUS_STATE_NAMESPACE = "bus-state";
|
|
5
|
+
const PROFILE_STATE_NAMESPACE = "profile-state";
|
|
6
|
+
const MAX_NOSTR_STATE_ENTRIES = 256;
|
|
7
|
+
function normalizeAccountId(accountId) {
|
|
8
|
+
const trimmed = accountId?.trim();
|
|
9
|
+
if (!trimmed) return "default";
|
|
10
|
+
return trimmed.replace(/[^a-z0-9._-]+/gi, "_");
|
|
11
|
+
}
|
|
12
|
+
function finiteNumberOrNull(value) {
|
|
13
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
14
|
+
}
|
|
15
|
+
function parseBusState(value) {
|
|
16
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
17
|
+
const parsed = value;
|
|
18
|
+
if (parsed.version !== 1 && parsed.version !== 2) return null;
|
|
19
|
+
return {
|
|
20
|
+
version: 2,
|
|
21
|
+
lastProcessedAt: finiteNumberOrNull(parsed.lastProcessedAt),
|
|
22
|
+
gatewayStartedAt: finiteNumberOrNull(parsed.gatewayStartedAt),
|
|
23
|
+
recentEventIds: parsed.version === 2 && Array.isArray(parsed.recentEventIds) ? parsed.recentEventIds.filter((entry) => typeof entry === "string") : []
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function parseProfileState(value) {
|
|
27
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
28
|
+
const parsed = value;
|
|
29
|
+
if (parsed.version !== 1) return null;
|
|
30
|
+
const rawResults = parsed.lastPublishResults;
|
|
31
|
+
const lastPublishResults = {};
|
|
32
|
+
if (rawResults && typeof rawResults === "object" && !Array.isArray(rawResults)) {
|
|
33
|
+
for (const [relay, result] of Object.entries(rawResults)) if (result === "ok" || result === "failed" || result === "timeout") lastPublishResults[relay] = result;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
version: 1,
|
|
37
|
+
lastPublishedAt: finiteNumberOrNull(parsed.lastPublishedAt),
|
|
38
|
+
lastPublishedEventId: typeof parsed.lastPublishedEventId === "string" ? parsed.lastPublishedEventId : null,
|
|
39
|
+
lastPublishResults: rawResults === null || Object.keys(lastPublishResults).length === 0 ? null : lastPublishResults
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
async function fileExists(filePath) {
|
|
43
|
+
try {
|
|
44
|
+
return (await fs.stat(filePath)).isFile();
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function readJsonFile(filePath) {
|
|
50
|
+
return JSON.parse(await fs.readFile(filePath, "utf8"));
|
|
51
|
+
}
|
|
52
|
+
async function listLegacyFiles(params) {
|
|
53
|
+
const dir = path.join(params.stateDir, "nostr");
|
|
54
|
+
let entries = [];
|
|
55
|
+
try {
|
|
56
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
57
|
+
} catch {
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
const suffix = ".json";
|
|
61
|
+
const files = [];
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
if (!entry.isFile() || !entry.name.startsWith(params.prefix) || !entry.name.endsWith(suffix)) continue;
|
|
64
|
+
const accountId = normalizeAccountId(entry.name.slice(params.prefix.length, -5));
|
|
65
|
+
const filePath = path.join(dir, entry.name);
|
|
66
|
+
try {
|
|
67
|
+
const value = params.parse(await readJsonFile(filePath));
|
|
68
|
+
if (value) files.push({
|
|
69
|
+
accountId,
|
|
70
|
+
filePath,
|
|
71
|
+
value
|
|
72
|
+
});
|
|
73
|
+
} catch {}
|
|
74
|
+
}
|
|
75
|
+
return files;
|
|
76
|
+
}
|
|
77
|
+
async function archiveLegacySource(params) {
|
|
78
|
+
const archivedPath = `${params.filePath}.migrated`;
|
|
79
|
+
if (await fileExists(archivedPath)) {
|
|
80
|
+
params.warnings.push(`Left migrated ${params.label} source in place because ${archivedPath} already exists`);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
await fs.rename(params.filePath, archivedPath);
|
|
85
|
+
params.changes.push(`Archived ${params.label} legacy source -> ${archivedPath}`);
|
|
86
|
+
} catch (err) {
|
|
87
|
+
params.warnings.push(`Failed archiving ${params.label} legacy source: ${String(err)}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function ensureStoreCapacity(params) {
|
|
91
|
+
const existingKeys = new Set((await params.store.entries()).map((entry) => entry.key));
|
|
92
|
+
const missingKeys = new Set(params.files.map((file) => file.accountId).filter((key) => !existingKeys.has(key)));
|
|
93
|
+
if (missingKeys.size > params.maxEntries - existingKeys.size) {
|
|
94
|
+
params.warnings.push(`Skipped migrating ${params.label} because plugin state has room for ${params.maxEntries - existingKeys.size} of ${missingKeys.size} missing entries; left legacy sources in place`);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
return existingKeys;
|
|
98
|
+
}
|
|
99
|
+
const stateMigrations = [{
|
|
100
|
+
id: "nostr-bus-state-json-to-plugin-state",
|
|
101
|
+
label: "Nostr bus state",
|
|
102
|
+
async detectLegacyState(params) {
|
|
103
|
+
const files = await listLegacyFiles({
|
|
104
|
+
stateDir: params.stateDir,
|
|
105
|
+
prefix: "bus-state-",
|
|
106
|
+
parse: parseBusState
|
|
107
|
+
});
|
|
108
|
+
if (files.length === 0) return null;
|
|
109
|
+
return { preview: [`- Nostr bus state: ${files.length} ${files.length === 1 ? "account" : "accounts"} -> plugin state (${BUS_STATE_NAMESPACE})`] };
|
|
110
|
+
},
|
|
111
|
+
async migrateLegacyState(params) {
|
|
112
|
+
const changes = [];
|
|
113
|
+
const warnings = [];
|
|
114
|
+
const files = await listLegacyFiles({
|
|
115
|
+
stateDir: params.stateDir,
|
|
116
|
+
prefix: "bus-state-",
|
|
117
|
+
parse: parseBusState
|
|
118
|
+
});
|
|
119
|
+
const store = params.context.openPluginStateKeyedStore({
|
|
120
|
+
namespace: BUS_STATE_NAMESPACE,
|
|
121
|
+
maxEntries: MAX_NOSTR_STATE_ENTRIES
|
|
122
|
+
});
|
|
123
|
+
const existingKeys = await ensureStoreCapacity({
|
|
124
|
+
files,
|
|
125
|
+
store,
|
|
126
|
+
maxEntries: MAX_NOSTR_STATE_ENTRIES,
|
|
127
|
+
label: "Nostr bus state",
|
|
128
|
+
warnings
|
|
129
|
+
});
|
|
130
|
+
if (!existingKeys) return {
|
|
131
|
+
changes,
|
|
132
|
+
warnings
|
|
133
|
+
};
|
|
134
|
+
let imported = 0;
|
|
135
|
+
for (const file of files) {
|
|
136
|
+
if (!existingKeys.has(file.accountId)) {
|
|
137
|
+
await store.register(file.accountId, file.value);
|
|
138
|
+
existingKeys.add(file.accountId);
|
|
139
|
+
imported++;
|
|
140
|
+
}
|
|
141
|
+
await archiveLegacySource({
|
|
142
|
+
filePath: file.filePath,
|
|
143
|
+
label: "Nostr bus state",
|
|
144
|
+
changes,
|
|
145
|
+
warnings
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
if (imported > 0) changes.unshift(`Migrated ${imported} Nostr bus-state ${imported === 1 ? "entry" : "entries"} -> plugin state`);
|
|
149
|
+
return {
|
|
150
|
+
changes,
|
|
151
|
+
warnings
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}, {
|
|
155
|
+
id: "nostr-profile-state-json-to-plugin-state",
|
|
156
|
+
label: "Nostr profile state",
|
|
157
|
+
async detectLegacyState(params) {
|
|
158
|
+
const files = await listLegacyFiles({
|
|
159
|
+
stateDir: params.stateDir,
|
|
160
|
+
prefix: "profile-state-",
|
|
161
|
+
parse: parseProfileState
|
|
162
|
+
});
|
|
163
|
+
if (files.length === 0) return null;
|
|
164
|
+
return { preview: [`- Nostr profile state: ${files.length} ${files.length === 1 ? "account" : "accounts"} -> plugin state (${PROFILE_STATE_NAMESPACE})`] };
|
|
165
|
+
},
|
|
166
|
+
async migrateLegacyState(params) {
|
|
167
|
+
const changes = [];
|
|
168
|
+
const warnings = [];
|
|
169
|
+
const files = await listLegacyFiles({
|
|
170
|
+
stateDir: params.stateDir,
|
|
171
|
+
prefix: "profile-state-",
|
|
172
|
+
parse: parseProfileState
|
|
173
|
+
});
|
|
174
|
+
const store = params.context.openPluginStateKeyedStore({
|
|
175
|
+
namespace: PROFILE_STATE_NAMESPACE,
|
|
176
|
+
maxEntries: MAX_NOSTR_STATE_ENTRIES
|
|
177
|
+
});
|
|
178
|
+
const existingKeys = await ensureStoreCapacity({
|
|
179
|
+
files,
|
|
180
|
+
store,
|
|
181
|
+
maxEntries: MAX_NOSTR_STATE_ENTRIES,
|
|
182
|
+
label: "Nostr profile state",
|
|
183
|
+
warnings
|
|
184
|
+
});
|
|
185
|
+
if (!existingKeys) return {
|
|
186
|
+
changes,
|
|
187
|
+
warnings
|
|
188
|
+
};
|
|
189
|
+
let imported = 0;
|
|
190
|
+
for (const file of files) {
|
|
191
|
+
if (!existingKeys.has(file.accountId)) {
|
|
192
|
+
await store.register(file.accountId, file.value);
|
|
193
|
+
existingKeys.add(file.accountId);
|
|
194
|
+
imported++;
|
|
195
|
+
}
|
|
196
|
+
await archiveLegacySource({
|
|
197
|
+
filePath: file.filePath,
|
|
198
|
+
label: "Nostr profile state",
|
|
199
|
+
changes,
|
|
200
|
+
warnings
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
if (imported > 0) changes.unshift(`Migrated ${imported} Nostr profile-state ${imported === 1 ? "entry" : "entries"} -> plugin state`);
|
|
204
|
+
return {
|
|
205
|
+
changes,
|
|
206
|
+
warnings
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}];
|
|
210
|
+
//#endregion
|
|
211
|
+
export { stateMigrations };
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/nostr",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.31-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/nostr",
|
|
9
|
-
"version": "2026.5.
|
|
9
|
+
"version": "2026.5.31-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"nostr-tools": "2.23.5",
|
|
12
12
|
"zod": "4.4.3"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"openclaw": ">=2026.5.
|
|
15
|
+
"openclaw": ">=2026.5.31-beta.1"
|
|
16
16
|
},
|
|
17
17
|
"peerDependenciesMeta": {
|
|
18
18
|
"openclaw": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/nostr",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.31-beta.1",
|
|
4
4
|
"description": "OpenClaw Nostr channel plugin for NIP-04 encrypted direct messages.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"zod": "4.4.3"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"openclaw": ">=2026.5.
|
|
15
|
+
"openclaw": ">=2026.5.31-beta.1"
|
|
16
16
|
},
|
|
17
17
|
"peerDependenciesMeta": {
|
|
18
18
|
"openclaw": {
|
|
@@ -50,10 +50,10 @@
|
|
|
50
50
|
"minHostVersion": ">=2026.4.10"
|
|
51
51
|
},
|
|
52
52
|
"compat": {
|
|
53
|
-
"pluginApi": ">=2026.5.
|
|
53
|
+
"pluginApi": ">=2026.5.31-beta.1"
|
|
54
54
|
},
|
|
55
55
|
"build": {
|
|
56
|
-
"openclawVersion": "2026.5.
|
|
56
|
+
"openclawVersion": "2026.5.31-beta.1"
|
|
57
57
|
},
|
|
58
58
|
"release": {
|
|
59
59
|
"publishToClawHub": true,
|