@openclaw/nostr 2026.9.1-beta.1 → 2026.9.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 +7 -5
- package/dist/{channel-BwnvE_wr.js → channel-CLybVB2-.js} +10 -11
- package/dist/channel-plugin-api.js +1 -1
- package/dist/doctor-contract-api.js +2 -1
- package/dist/setup-api.js +1 -1
- package/dist/setup-plugin-api.js +1 -1
- package/dist/{setup-surface-CzjfhV72.js → setup-surface-mA5PMspO.js} +11 -10
- package/node_modules/nostr-tools/lib/cjs/index.js +20 -4
- package/node_modules/nostr-tools/lib/cjs/index.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip17.js +19 -3
- package/node_modules/nostr-tools/lib/cjs/nip17.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip46.js +7 -3
- package/node_modules/nostr-tools/lib/cjs/nip46.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip59.js +19 -3
- package/node_modules/nostr-tools/lib/cjs/nip59.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nip98.js +1 -1
- package/node_modules/nostr-tools/lib/cjs/nip98.js.map +2 -2
- package/node_modules/nostr-tools/lib/cjs/nipad.js +55 -0
- package/node_modules/nostr-tools/lib/cjs/nipad.js.map +7 -0
- package/node_modules/nostr-tools/lib/esm/index.js +20 -4
- package/node_modules/nostr-tools/lib/esm/index.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip17.js +19 -3
- package/node_modules/nostr-tools/lib/esm/nip17.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip46.js +7 -3
- package/node_modules/nostr-tools/lib/esm/nip46.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip59.js +19 -3
- package/node_modules/nostr-tools/lib/esm/nip59.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nip98.js +1 -1
- package/node_modules/nostr-tools/lib/esm/nip98.js.map +2 -2
- package/node_modules/nostr-tools/lib/esm/nipad.js +34 -0
- package/node_modules/nostr-tools/lib/esm/nipad.js.map +7 -0
- package/node_modules/nostr-tools/lib/nostr.bundle.js +20 -4
- package/node_modules/nostr-tools/lib/nostr.bundle.js.map +2 -2
- package/node_modules/nostr-tools/lib/types/nip46.test.d.ts +1 -0
- package/node_modules/nostr-tools/lib/types/nip98.d.ts +1 -1
- package/node_modules/nostr-tools/lib/types/nipad.d.ts +16 -0
- package/node_modules/nostr-tools/package.json +7 -1
- package/package.json +5 -5
package/dist/api.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { s as resolveNostrAccount } from "./setup-surface-
|
|
1
|
+
import { s as resolveNostrAccount } from "./setup-surface-mA5PMspO.js";
|
|
2
2
|
import { getPluginRuntimeGatewayRequestScope } from "./runtime-api.js";
|
|
3
3
|
import { n as NostrProfileSchema } from "./config-schema-CkYd8ACn.js";
|
|
4
|
-
import { a as getNostrRuntime, i as contentToProfile, n as nostrPlugin, o as setNostrRuntime, r as publishNostrProfile, t as getNostrProfileState } from "./channel-
|
|
4
|
+
import { a as getNostrRuntime, i as contentToProfile, n as nostrPlugin, o as setNostrRuntime, r as publishNostrProfile, t as getNostrProfileState } from "./channel-CLybVB2-.js";
|
|
5
5
|
import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { SimplePool } from "nostr-tools";
|
|
@@ -18,7 +18,8 @@ function validateUrlSafety(urlStr) {
|
|
|
18
18
|
ok: false,
|
|
19
19
|
error: "URL must use https:// protocol"
|
|
20
20
|
};
|
|
21
|
-
|
|
21
|
+
const hostname = url.hostname.trim().toLowerCase();
|
|
22
|
+
if (isBlockedHostnameOrIp(hostname)) return {
|
|
22
23
|
ok: false,
|
|
23
24
|
error: "URL must not point to private/internal addresses"
|
|
24
25
|
};
|
|
@@ -208,7 +209,7 @@ function sendJson(res, status, body) {
|
|
|
208
209
|
res.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
209
210
|
res.end(JSON.stringify(body));
|
|
210
211
|
}
|
|
211
|
-
async function readJsonBody(req, maxBytes =
|
|
212
|
+
async function readJsonBody(req, maxBytes = 65536, timeoutMs = 3e4) {
|
|
212
213
|
const result = await readJsonBodyWithLimit(req, {
|
|
213
214
|
maxBytes,
|
|
214
215
|
timeoutMs,
|
|
@@ -234,7 +235,8 @@ function isLoopbackRemoteAddress(remoteAddress) {
|
|
|
234
235
|
}
|
|
235
236
|
function isLoopbackOriginLike(value) {
|
|
236
237
|
try {
|
|
237
|
-
|
|
238
|
+
const url = new URL(value);
|
|
239
|
+
return isLoopbackHost(url.hostname);
|
|
238
240
|
} catch {
|
|
239
241
|
return false;
|
|
240
242
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as listNostrAccountIds, c as normalizePubkey, n as nostrSetupContract, o as resolveDefaultNostrAccountId, r as nostrSetupWizard, s as resolveNostrAccount } from "./setup-surface-
|
|
1
|
+
import { a as listNostrAccountIds, c as normalizePubkey, n as nostrSetupContract, o as resolveDefaultNostrAccountId, r as nostrSetupWizard, s as resolveNostrAccount } from "./setup-surface-mA5PMspO.js";
|
|
2
2
|
import { a as collectStatusIssuesFromLastError, i as buildChannelConfigSchema, n as NostrProfileSchema, o as createDefaultChannelRuntimeState, r as DEFAULT_ACCOUNT_ID, s as formatPairingApproveHint, t as NostrConfigSchema } from "./config-schema-CkYd8ACn.js";
|
|
3
3
|
import { c as validatePrivateKey, l as DEFAULT_RELAYS } from "./setup-adapter-KJ_iGKiG.js";
|
|
4
4
|
import { t as normalizeNostrStateAccountId } from "./state-account-id-CvBZ9s6P.js";
|
|
@@ -213,9 +213,7 @@ function createMetrics(onMetric) {
|
|
|
213
213
|
case "memory.seen_tracker_size":
|
|
214
214
|
state.memory.seenTrackerSize = value;
|
|
215
215
|
break;
|
|
216
|
-
case "memory.rate_limiter_entries":
|
|
217
|
-
state.memory.rateLimiterEntries = value;
|
|
218
|
-
break;
|
|
216
|
+
case "memory.rate_limiter_entries": state.memory.rateLimiterEntries = value;
|
|
219
217
|
}
|
|
220
218
|
}
|
|
221
219
|
function getSnapshot() {
|
|
@@ -365,9 +363,7 @@ function createNostrCursorStateWriter(options) {
|
|
|
365
363
|
return;
|
|
366
364
|
} catch (error) {
|
|
367
365
|
options.onBackgroundError?.(error);
|
|
368
|
-
await
|
|
369
|
-
setTimeout(resolve, options.recoveryRetryMs ?? CURSOR_RECOVERY_RETRY_MS);
|
|
370
|
-
});
|
|
366
|
+
await sleepWithAbort(CURSOR_RECOVERY_RETRY_MS);
|
|
371
367
|
}
|
|
372
368
|
})().finally(() => {
|
|
373
369
|
recoveryFlush = void 0;
|
|
@@ -679,11 +675,12 @@ function createProfileEvent(sk, profile, lastPublishedAt) {
|
|
|
679
675
|
const content = profileToContent(profile);
|
|
680
676
|
const contentJson = JSON.stringify(content);
|
|
681
677
|
const now = Math.floor(Date.now() / 1e3);
|
|
678
|
+
const createdAt = lastPublishedAt !== void 0 ? Math.max(now, lastPublishedAt + 1) : now;
|
|
682
679
|
return finalizeEvent({
|
|
683
680
|
kind: 0,
|
|
684
681
|
content: contentJson,
|
|
685
682
|
tags: [],
|
|
686
|
-
created_at:
|
|
683
|
+
created_at: createdAt
|
|
687
684
|
}, sk);
|
|
688
685
|
}
|
|
689
686
|
/** Per-relay publish timeout (ms) */
|
|
@@ -862,7 +859,7 @@ async function writeNostrProfileState(params) {
|
|
|
862
859
|
//#region extensions/nostr/src/nostr-bus.ts
|
|
863
860
|
const STARTUP_LOOKBACK_SEC = 120;
|
|
864
861
|
const STATE_PERSIST_DEBOUNCE_MS = 5e3;
|
|
865
|
-
const NOSTR_INGRESS_ENVELOPE_OVERHEAD_BYTES =
|
|
862
|
+
const NOSTR_INGRESS_ENVELOPE_OVERHEAD_BYTES = 16384;
|
|
866
863
|
const NOSTR_INGRESS_MAX_PENDING_EVENTS = 1e3;
|
|
867
864
|
const DEFAULT_INBOUND_GUARD_POLICY = createDirectDmPreCryptoGuardPolicy();
|
|
868
865
|
const CIRCUIT_BREAKER_THRESHOLD = 5;
|
|
@@ -1447,7 +1444,8 @@ const startNostrGatewayAccount = async (ctx) => {
|
|
|
1447
1444
|
commandAuthorized: resolvedAccess.commandAccess.requested ? resolvedAccess.commandAccess.authorized : void 0,
|
|
1448
1445
|
turnAdoptionLifecycle: bindIngressLifecycleToReplyOptions(lifecycle).turnAdoptionLifecycle,
|
|
1449
1446
|
deliver: async (payload) => {
|
|
1450
|
-
const
|
|
1447
|
+
const outboundText = payload && typeof payload === "object" && "text" in payload ? payload.text ?? "" : "";
|
|
1448
|
+
const sanitizedText = sanitizeAssistantVisibleText(outboundText);
|
|
1451
1449
|
if (!sanitizedText) return;
|
|
1452
1450
|
const tableMode = runtime.channel.text.resolveMarkdownTableMode({
|
|
1453
1451
|
cfg: ctx.cfg,
|
|
@@ -1542,9 +1540,10 @@ const nostrOutboundAdapter = {
|
|
|
1542
1540
|
const message = stripMarkdown(core.channel.text.convertMarkdownTables(text ?? "", tableMode));
|
|
1543
1541
|
if (!message) throw new Error("Nostr send requires non-empty text after markdown stripping.");
|
|
1544
1542
|
const normalizedTo = normalizePubkey(to);
|
|
1543
|
+
const eventId = await bus.sendDm(normalizedTo, message);
|
|
1545
1544
|
return attachChannelToResult("nostr", {
|
|
1546
1545
|
to: normalizedTo,
|
|
1547
|
-
messageId:
|
|
1546
|
+
messageId: eventId
|
|
1548
1547
|
});
|
|
1549
1548
|
}
|
|
1550
1549
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as nostrPlugin } from "./channel-
|
|
1
|
+
import { n as nostrPlugin } from "./channel-CLybVB2-.js";
|
|
2
2
|
export { nostrPlugin };
|
|
@@ -49,7 +49,8 @@ async function listLegacyFiles(params) {
|
|
|
49
49
|
const files = [];
|
|
50
50
|
for (const entry of entries) {
|
|
51
51
|
if (!entry.isFile() || !entry.name.startsWith(params.prefix) || !entry.name.endsWith(suffix)) continue;
|
|
52
|
-
const
|
|
52
|
+
const rawAccountId = entry.name.slice(params.prefix.length, -5);
|
|
53
|
+
const accountId = normalizeNostrStateAccountId(rawAccountId);
|
|
53
54
|
const filePath = path.join(dir, entry.name);
|
|
54
55
|
try {
|
|
55
56
|
const value = params.parse(await readJsonFile(filePath));
|
package/dist/setup-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { r as nostrSetupWizard, t as nostrSetupAdapter } from "./setup-surface-
|
|
1
|
+
import { r as nostrSetupWizard, t as nostrSetupAdapter } from "./setup-surface-mA5PMspO.js";
|
|
2
2
|
export { nostrSetupAdapter, nostrSetupWizard };
|
package/dist/setup-plugin-api.js
CHANGED
|
@@ -38,7 +38,7 @@ function resolveSetupNostrAccount(params) {
|
|
|
38
38
|
}
|
|
39
39
|
const nostrSetupWizard = createDelegatedSetupWizardProxy({
|
|
40
40
|
channel,
|
|
41
|
-
loadWizard: async () => (await import("./setup-surface-
|
|
41
|
+
loadWizard: async () => (await import("./setup-surface-mA5PMspO.js").then((n) => n.i)).nostrSetupWizard,
|
|
42
42
|
status: createNostrSetupStatus(resolveSetupNostrAccount),
|
|
43
43
|
resolveShouldPromptAccountIds: () => false,
|
|
44
44
|
delegatePrepare: true,
|
|
@@ -109,22 +109,23 @@ function parseNostrAllowFrom(raw) {
|
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
}
|
|
112
|
+
const promptNostrAllowFrom = createTopLevelChannelParsedAllowFromPrompt({
|
|
113
|
+
channel,
|
|
114
|
+
defaultAccountId: resolveDefaultNostrAccountId,
|
|
115
|
+
noteTitle: t("wizard.nostr.allowlistTitle"),
|
|
116
|
+
noteLines: NOSTR_ALLOW_FROM_HELP_LINES,
|
|
117
|
+
message: t("wizard.nostr.allowFromPrompt"),
|
|
118
|
+
placeholder: "npub1..., 0123abcd...",
|
|
119
|
+
parseEntries: parseNostrAllowFrom,
|
|
120
|
+
mergeEntries: ({ existing, parsed }) => mergeAllowFromEntries(existing, parsed)
|
|
121
|
+
});
|
|
112
122
|
const nostrDmPolicy = createTopLevelChannelDmPolicy({
|
|
113
123
|
label: "Nostr",
|
|
114
124
|
channel,
|
|
115
125
|
policyKey: "channels.nostr.dmPolicy",
|
|
116
126
|
allowFromKey: "channels.nostr.allowFrom",
|
|
117
127
|
getCurrent: (cfg) => cfg.channels?.nostr?.dmPolicy ?? "pairing",
|
|
118
|
-
promptAllowFrom:
|
|
119
|
-
channel,
|
|
120
|
-
defaultAccountId: resolveDefaultNostrAccountId,
|
|
121
|
-
noteTitle: t("wizard.nostr.allowlistTitle"),
|
|
122
|
-
noteLines: NOSTR_ALLOW_FROM_HELP_LINES,
|
|
123
|
-
message: t("wizard.nostr.allowFromPrompt"),
|
|
124
|
-
placeholder: "npub1..., 0123abcd...",
|
|
125
|
-
parseEntries: parseNostrAllowFrom,
|
|
126
|
-
mergeEntries: ({ existing, parsed }) => mergeAllowFromEntries(existing, parsed)
|
|
127
|
-
})
|
|
128
|
+
promptAllowFrom: promptNostrAllowFrom
|
|
128
129
|
});
|
|
129
130
|
const nostrSetupAdapter = createNostrSetupAdapter({ resolveAccountId: (cfg, accountId) => accountId?.trim() || resolveDefaultNostrAccountId(cfg) });
|
|
130
131
|
const nostrSetupContract = createNostrSetupContract(nostrSetupAdapter);
|
|
@@ -2589,13 +2589,29 @@ function wrapManyEvents(event, senderPrivateKey, recipientsPublicKeys) {
|
|
|
2589
2589
|
return wrappeds;
|
|
2590
2590
|
}
|
|
2591
2591
|
function unwrapEvent(wrap, recipientPrivateKey) {
|
|
2592
|
-
|
|
2593
|
-
|
|
2592
|
+
if (wrap.kind !== GiftWrap) {
|
|
2593
|
+
throw new Error(`unexpected wrap kind ${wrap.kind}, expected ${GiftWrap}`);
|
|
2594
|
+
}
|
|
2595
|
+
const seal = nip44Decrypt(wrap, recipientPrivateKey);
|
|
2596
|
+
if (seal.kind !== Seal) {
|
|
2597
|
+
throw new Error(`unexpected seal kind ${seal.kind}, expected ${Seal}`);
|
|
2598
|
+
}
|
|
2599
|
+
if (!verifyEvent(seal)) {
|
|
2600
|
+
throw new Error("seal signature is invalid");
|
|
2601
|
+
}
|
|
2602
|
+
const rumor = nip44Decrypt(seal, recipientPrivateKey);
|
|
2603
|
+
if (rumor.pubkey !== seal.pubkey) {
|
|
2604
|
+
throw new Error(`rumor pubkey ${rumor.pubkey} does not match seal pubkey ${seal.pubkey}`);
|
|
2605
|
+
}
|
|
2606
|
+
return rumor;
|
|
2594
2607
|
}
|
|
2595
2608
|
function unwrapManyEvents(wrappedEvents, recipientPrivateKey) {
|
|
2596
2609
|
let unwrappedEvents = [];
|
|
2597
2610
|
wrappedEvents.forEach((e) => {
|
|
2598
|
-
|
|
2611
|
+
try {
|
|
2612
|
+
unwrappedEvents.push(unwrapEvent(e, recipientPrivateKey));
|
|
2613
|
+
} catch (_err) {
|
|
2614
|
+
}
|
|
2599
2615
|
});
|
|
2600
2616
|
unwrappedEvents.sort((a, b) => a.created_at - b.created_at);
|
|
2601
2617
|
return unwrappedEvents;
|
|
@@ -3987,7 +4003,7 @@ function validateEventTimestamp(event) {
|
|
|
3987
4003
|
if (!event.created_at) {
|
|
3988
4004
|
return false;
|
|
3989
4005
|
}
|
|
3990
|
-
return Math.round(new Date().getTime() / 1e3) - event.created_at < 60;
|
|
4006
|
+
return Math.abs(Math.round(new Date().getTime() / 1e3) - event.created_at) < 60;
|
|
3991
4007
|
}
|
|
3992
4008
|
function validateEventKind(event) {
|
|
3993
4009
|
return event.kind === HTTPAuth;
|