@openclaw/nostr 2026.8.1-beta.3 → 2026.8.2

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.
Files changed (140) hide show
  1. package/dist/api.js +7 -5
  2. package/dist/{channel-ity6au4a.js → channel-CLybVB2-.js} +11 -12
  3. package/dist/channel-plugin-api.js +1 -1
  4. package/dist/doctor-contract-api.js +2 -1
  5. package/dist/{setup-adapter-ClKW2fkz.js → setup-adapter-KJ_iGKiG.js} +30 -2
  6. package/dist/setup-api.js +1 -1
  7. package/dist/setup-plugin-api.js +3 -6
  8. package/dist/{setup-surface-uA4hN27A.js → setup-surface-mA5PMspO.js} +17 -46
  9. package/node_modules/nostr-tools/lib/cjs/abstract-pool.js +7 -5
  10. package/node_modules/nostr-tools/lib/cjs/abstract-pool.js.map +2 -2
  11. package/node_modules/nostr-tools/lib/cjs/abstract-relay.js +6 -4
  12. package/node_modules/nostr-tools/lib/cjs/abstract-relay.js.map +2 -2
  13. package/node_modules/nostr-tools/lib/cjs/core.js +10 -6
  14. package/node_modules/nostr-tools/lib/cjs/core.js.map +2 -2
  15. package/node_modules/nostr-tools/lib/cjs/index.js +37 -15
  16. package/node_modules/nostr-tools/lib/cjs/index.js.map +2 -2
  17. package/node_modules/nostr-tools/lib/cjs/kinds.js +2 -0
  18. package/node_modules/nostr-tools/lib/cjs/kinds.js.map +2 -2
  19. package/node_modules/nostr-tools/lib/cjs/nip04.js.map +1 -1
  20. package/node_modules/nostr-tools/lib/cjs/nip10.js +2 -0
  21. package/node_modules/nostr-tools/lib/cjs/nip10.js.map +2 -2
  22. package/node_modules/nostr-tools/lib/cjs/nip13.js.map +1 -1
  23. package/node_modules/nostr-tools/lib/cjs/nip17.js +21 -3
  24. package/node_modules/nostr-tools/lib/cjs/nip17.js.map +2 -2
  25. package/node_modules/nostr-tools/lib/cjs/nip18.js +2 -0
  26. package/node_modules/nostr-tools/lib/cjs/nip18.js.map +2 -2
  27. package/node_modules/nostr-tools/lib/cjs/nip19.js.map +1 -1
  28. package/node_modules/nostr-tools/lib/cjs/nip21.js.map +1 -1
  29. package/node_modules/nostr-tools/lib/cjs/nip22.js +2 -0
  30. package/node_modules/nostr-tools/lib/cjs/nip22.js.map +2 -2
  31. package/node_modules/nostr-tools/lib/cjs/nip25.js +2 -0
  32. package/node_modules/nostr-tools/lib/cjs/nip25.js.map +2 -2
  33. package/node_modules/nostr-tools/lib/cjs/nip27.js.map +1 -1
  34. package/node_modules/nostr-tools/lib/cjs/nip28.js +2 -0
  35. package/node_modules/nostr-tools/lib/cjs/nip28.js.map +2 -2
  36. package/node_modules/nostr-tools/lib/cjs/nip29.js +288 -12
  37. package/node_modules/nostr-tools/lib/cjs/nip29.js.map +2 -2
  38. package/node_modules/nostr-tools/lib/cjs/nip44.js.map +1 -1
  39. package/node_modules/nostr-tools/lib/cjs/nip45.js +2 -0
  40. package/node_modules/nostr-tools/lib/cjs/nip45.js.map +2 -2
  41. package/node_modules/nostr-tools/lib/cjs/nip46.js +16 -8
  42. package/node_modules/nostr-tools/lib/cjs/nip46.js.map +2 -2
  43. package/node_modules/nostr-tools/lib/cjs/nip47.js +2 -0
  44. package/node_modules/nostr-tools/lib/cjs/nip47.js.map +2 -2
  45. package/node_modules/nostr-tools/lib/cjs/nip57.js +2 -0
  46. package/node_modules/nostr-tools/lib/cjs/nip57.js.map +2 -2
  47. package/node_modules/nostr-tools/lib/cjs/nip59.js +21 -3
  48. package/node_modules/nostr-tools/lib/cjs/nip59.js.map +2 -2
  49. package/node_modules/nostr-tools/lib/cjs/nip98.js +3 -1
  50. package/node_modules/nostr-tools/lib/cjs/nip98.js.map +2 -2
  51. package/node_modules/nostr-tools/lib/cjs/nipad.js +55 -0
  52. package/node_modules/nostr-tools/lib/cjs/nipad.js.map +7 -0
  53. package/node_modules/nostr-tools/lib/cjs/nipb0.js +2 -0
  54. package/node_modules/nostr-tools/lib/cjs/nipb0.js.map +2 -2
  55. package/node_modules/nostr-tools/lib/cjs/nipb7.js +2 -0
  56. package/node_modules/nostr-tools/lib/cjs/nipb7.js.map +2 -2
  57. package/node_modules/nostr-tools/lib/cjs/pool.js +9 -5
  58. package/node_modules/nostr-tools/lib/cjs/pool.js.map +2 -2
  59. package/node_modules/nostr-tools/lib/cjs/pure.js +10 -6
  60. package/node_modules/nostr-tools/lib/cjs/pure.js.map +2 -2
  61. package/node_modules/nostr-tools/lib/cjs/references.js.map +1 -1
  62. package/node_modules/nostr-tools/lib/cjs/relay.js +8 -4
  63. package/node_modules/nostr-tools/lib/cjs/relay.js.map +2 -2
  64. package/node_modules/nostr-tools/lib/cjs/signer.js +2 -0
  65. package/node_modules/nostr-tools/lib/cjs/signer.js.map +2 -2
  66. package/node_modules/nostr-tools/lib/cjs/utils.js +2 -0
  67. package/node_modules/nostr-tools/lib/cjs/utils.js.map +2 -2
  68. package/node_modules/nostr-tools/lib/cjs/wasm.js +10 -6
  69. package/node_modules/nostr-tools/lib/cjs/wasm.js.map +2 -2
  70. package/node_modules/nostr-tools/lib/esm/abstract-pool.js +7 -5
  71. package/node_modules/nostr-tools/lib/esm/abstract-pool.js.map +2 -2
  72. package/node_modules/nostr-tools/lib/esm/abstract-relay.js +6 -4
  73. package/node_modules/nostr-tools/lib/esm/abstract-relay.js.map +2 -2
  74. package/node_modules/nostr-tools/lib/esm/core.js +10 -6
  75. package/node_modules/nostr-tools/lib/esm/core.js.map +2 -2
  76. package/node_modules/nostr-tools/lib/esm/index.js +37 -15
  77. package/node_modules/nostr-tools/lib/esm/index.js.map +2 -2
  78. package/node_modules/nostr-tools/lib/esm/kinds.js +2 -0
  79. package/node_modules/nostr-tools/lib/esm/kinds.js.map +2 -2
  80. package/node_modules/nostr-tools/lib/esm/nip04.js.map +1 -1
  81. package/node_modules/nostr-tools/lib/esm/nip10.js +2 -0
  82. package/node_modules/nostr-tools/lib/esm/nip10.js.map +2 -2
  83. package/node_modules/nostr-tools/lib/esm/nip13.js.map +1 -1
  84. package/node_modules/nostr-tools/lib/esm/nip17.js +21 -3
  85. package/node_modules/nostr-tools/lib/esm/nip17.js.map +2 -2
  86. package/node_modules/nostr-tools/lib/esm/nip18.js +2 -0
  87. package/node_modules/nostr-tools/lib/esm/nip18.js.map +2 -2
  88. package/node_modules/nostr-tools/lib/esm/nip19.js.map +1 -1
  89. package/node_modules/nostr-tools/lib/esm/nip21.js.map +1 -1
  90. package/node_modules/nostr-tools/lib/esm/nip22.js +2 -0
  91. package/node_modules/nostr-tools/lib/esm/nip22.js.map +2 -2
  92. package/node_modules/nostr-tools/lib/esm/nip25.js +2 -0
  93. package/node_modules/nostr-tools/lib/esm/nip25.js.map +2 -2
  94. package/node_modules/nostr-tools/lib/esm/nip27.js.map +1 -1
  95. package/node_modules/nostr-tools/lib/esm/nip28.js +2 -0
  96. package/node_modules/nostr-tools/lib/esm/nip28.js.map +2 -2
  97. package/node_modules/nostr-tools/lib/esm/nip29.js +288 -12
  98. package/node_modules/nostr-tools/lib/esm/nip29.js.map +2 -2
  99. package/node_modules/nostr-tools/lib/esm/nip44.js.map +1 -1
  100. package/node_modules/nostr-tools/lib/esm/nip45.js +2 -0
  101. package/node_modules/nostr-tools/lib/esm/nip45.js.map +2 -2
  102. package/node_modules/nostr-tools/lib/esm/nip46.js +16 -8
  103. package/node_modules/nostr-tools/lib/esm/nip46.js.map +2 -2
  104. package/node_modules/nostr-tools/lib/esm/nip47.js +2 -0
  105. package/node_modules/nostr-tools/lib/esm/nip47.js.map +2 -2
  106. package/node_modules/nostr-tools/lib/esm/nip57.js +2 -0
  107. package/node_modules/nostr-tools/lib/esm/nip57.js.map +2 -2
  108. package/node_modules/nostr-tools/lib/esm/nip59.js +21 -3
  109. package/node_modules/nostr-tools/lib/esm/nip59.js.map +2 -2
  110. package/node_modules/nostr-tools/lib/esm/nip98.js +3 -1
  111. package/node_modules/nostr-tools/lib/esm/nip98.js.map +2 -2
  112. package/node_modules/nostr-tools/lib/esm/nipad.js +34 -0
  113. package/node_modules/nostr-tools/lib/esm/nipad.js.map +7 -0
  114. package/node_modules/nostr-tools/lib/esm/nipb0.js +2 -0
  115. package/node_modules/nostr-tools/lib/esm/nipb0.js.map +2 -2
  116. package/node_modules/nostr-tools/lib/esm/nipb7.js +2 -0
  117. package/node_modules/nostr-tools/lib/esm/nipb7.js.map +2 -2
  118. package/node_modules/nostr-tools/lib/esm/pool.js +9 -5
  119. package/node_modules/nostr-tools/lib/esm/pool.js.map +2 -2
  120. package/node_modules/nostr-tools/lib/esm/pure.js +10 -6
  121. package/node_modules/nostr-tools/lib/esm/pure.js.map +2 -2
  122. package/node_modules/nostr-tools/lib/esm/references.js.map +1 -1
  123. package/node_modules/nostr-tools/lib/esm/relay.js +8 -4
  124. package/node_modules/nostr-tools/lib/esm/relay.js.map +2 -2
  125. package/node_modules/nostr-tools/lib/esm/signer.js +2 -0
  126. package/node_modules/nostr-tools/lib/esm/signer.js.map +2 -2
  127. package/node_modules/nostr-tools/lib/esm/utils.js +2 -0
  128. package/node_modules/nostr-tools/lib/esm/utils.js.map +2 -2
  129. package/node_modules/nostr-tools/lib/esm/wasm.js +10 -6
  130. package/node_modules/nostr-tools/lib/esm/wasm.js.map +2 -2
  131. package/node_modules/nostr-tools/lib/nostr.bundle.js +37 -15
  132. package/node_modules/nostr-tools/lib/nostr.bundle.js.map +2 -2
  133. package/node_modules/nostr-tools/lib/types/core.d.ts +5 -0
  134. package/node_modules/nostr-tools/lib/types/nip29.d.ts +243 -3
  135. package/node_modules/nostr-tools/lib/types/nip29.test.d.ts +1 -0
  136. package/node_modules/nostr-tools/lib/types/nip46.test.d.ts +1 -0
  137. package/node_modules/nostr-tools/lib/types/nip98.d.ts +1 -1
  138. package/node_modules/nostr-tools/lib/types/nipad.d.ts +16 -0
  139. package/node_modules/nostr-tools/package.json +7 -1
  140. package/package.json +5 -5
package/dist/api.js CHANGED
@@ -1,7 +1,7 @@
1
- import { s as resolveNostrAccount } from "./setup-surface-uA4hN27A.js";
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-ity6au4a.js";
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
- if (isBlockedHostnameOrIp(url.hostname.trim().toLowerCase())) return {
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 = 64 * 1024, timeoutMs = 3e4) {
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
- return isLoopbackHost(new URL(value).hostname);
238
+ const url = new URL(value);
239
+ return isLoopbackHost(url.hostname);
238
240
  } catch {
239
241
  return false;
240
242
  }
@@ -1,6 +1,6 @@
1
- import { a as listNostrAccountIds, c as normalizePubkey, l as validatePrivateKey, n as nostrSetupContract, o as resolveDefaultNostrAccountId, r as nostrSetupWizard, s as resolveNostrAccount } from "./setup-surface-uA4hN27A.js";
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
- import { c as DEFAULT_RELAYS } from "./setup-adapter-ClKW2fkz.js";
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";
5
5
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
6
6
  import { createScopedDmSecurityResolver, createTopLevelChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
@@ -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 new Promise((resolve) => {
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: lastPublishedAt !== void 0 ? Math.max(now, lastPublishedAt + 1) : now
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 = 16 * 1024;
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 sanitizedText = sanitizeAssistantVisibleText(payload && typeof payload === "object" && "text" in payload ? payload.text ?? "" : "");
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: await bus.sendDm(normalizedTo, message)
1546
+ messageId: eventId
1548
1547
  });
1549
1548
  }
1550
1549
  };
@@ -1,2 +1,2 @@
1
- import { n as nostrPlugin } from "./channel-ity6au4a.js";
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 accountId = normalizeNostrStateAccountId(entry.name.slice(params.prefix.length, -5));
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));
@@ -1,5 +1,6 @@
1
1
  import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
3
+ import { decode } from "nostr-tools/nip19";
3
4
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/routing";
4
5
  import { createSetupTranslator, createStandardChannelSetupStatus, patchTopLevelChannelConfigSection, splitSetupEntries } from "openclaw/plugin-sdk/setup";
5
6
  import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
@@ -8,6 +9,29 @@ const DEFAULT_RELAYS = ["wss://relay.damus.io", "wss://nos.lol"];
8
9
  //#endregion
9
10
  //#region extensions/nostr/src/private-key.ts
10
11
  const NOSTR_PRIVATE_KEY_ENV_VAR = "NOSTR_PRIVATE_KEY";
12
+ const SECP256K1_ORDER = BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
13
+ /** Validate and normalize a private key (hex or NIP-19 nsec). */
14
+ function validatePrivateKey(key) {
15
+ const trimmed = key.trim();
16
+ let bytes;
17
+ if (trimmed.startsWith("nsec1") || trimmed.startsWith("NSEC1")) {
18
+ let decoded;
19
+ try {
20
+ decoded = decode(trimmed);
21
+ } catch {
22
+ throw new Error("Invalid nsec private key");
23
+ }
24
+ if (decoded.type !== "nsec") throw new Error("Invalid nsec key type");
25
+ bytes = decoded.data;
26
+ } else {
27
+ if (!/^[0-9a-fA-F]{64}$/.test(trimmed)) throw new Error("Private key must be 64 hex characters or nsec bech32 format");
28
+ bytes = Uint8Array.from({ length: 32 }, (_, index) => Number.parseInt(trimmed.slice(index * 2, index * 2 + 2), 16));
29
+ }
30
+ if (bytes.length !== 32) throw new Error("Private key must decode to 32 bytes");
31
+ const scalar = Array.from(bytes).reduce((value, byte) => value << 8n | BigInt(byte), 0n);
32
+ if (scalar === 0n || scalar >= SECP256K1_ORDER) throw new Error("Private key scalar is out of range");
33
+ return bytes;
34
+ }
11
35
  function hasConfiguredNostrPrivateKey(value) {
12
36
  return hasConfiguredSecretInput(value) || Boolean(process.env["NOSTR_PRIVATE_KEY"]?.trim());
13
37
  }
@@ -56,7 +80,11 @@ function createNostrSetupAdapter(params) {
56
80
  if (!input.useEnv) {
57
81
  const privateKey = input.privateKey?.trim();
58
82
  if (!privateKey) return "Nostr requires --private-key or --use-env.";
59
- if (!params.validatePrivateKey(privateKey)) return "Nostr private key must be valid nsec or 64-character hex.";
83
+ try {
84
+ validatePrivateKey(privateKey);
85
+ } catch {
86
+ return "Nostr private key must be valid nsec or 64-character hex.";
87
+ }
60
88
  }
61
89
  if (input.relayUrls?.trim()) return parseRelayUrls(input.relayUrls).error ?? null;
62
90
  return null;
@@ -127,4 +155,4 @@ function createNostrSetupStatus(resolveAccount) {
127
155
  });
128
156
  }
129
157
  //#endregion
130
- export { parseRelayUrls as a, DEFAULT_RELAYS as c, createNostrSetupStatus as i, createNostrSetupAdapter as n, hasConfiguredNostrPrivateKey as o, createNostrSetupContract as r, resolveNostrPrivateKey as s, buildNostrSetupPatch as t };
158
+ export { parseRelayUrls as a, validatePrivateKey as c, createNostrSetupStatus as i, DEFAULT_RELAYS as l, createNostrSetupAdapter as n, hasConfiguredNostrPrivateKey as o, createNostrSetupContract as r, resolveNostrPrivateKey as s, buildNostrSetupPatch as t };
package/dist/setup-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { r as nostrSetupWizard, t as nostrSetupAdapter } from "./setup-surface-uA4hN27A.js";
1
+ import { r as nostrSetupWizard, t as nostrSetupAdapter } from "./setup-surface-mA5PMspO.js";
2
2
  export { nostrSetupAdapter, nostrSetupWizard };
@@ -1,5 +1,5 @@
1
1
  import { i as buildChannelConfigSchema, t as NostrConfigSchema } from "./config-schema-CkYd8ACn.js";
2
- import { c as DEFAULT_RELAYS, i as createNostrSetupStatus, n as createNostrSetupAdapter, o as hasConfiguredNostrPrivateKey, r as createNostrSetupContract, s as resolveNostrPrivateKey } from "./setup-adapter-ClKW2fkz.js";
2
+ import { i as createNostrSetupStatus, l as DEFAULT_RELAYS, n as createNostrSetupAdapter, o as hasConfiguredNostrPrivateKey, r as createNostrSetupContract, s as resolveNostrPrivateKey } from "./setup-adapter-KJ_iGKiG.js";
3
3
  import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
4
4
  import { normalizeAccountId } from "openclaw/plugin-sdk/account-id";
5
5
  import { createDelegatedSetupWizardProxy } from "openclaw/plugin-sdk/setup-runtime";
@@ -38,7 +38,7 @@ function resolveSetupNostrAccount(params) {
38
38
  }
39
39
  const nostrSetupWizard = createDelegatedSetupWizardProxy({
40
40
  channel,
41
- loadWizard: async () => (await import("./setup-surface-uA4hN27A.js").then((n) => n.i)).nostrSetupWizard,
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,
@@ -61,10 +61,7 @@ const nostrSetupPlugin = {
61
61
  },
62
62
  reload: { configPrefixes: ["channels.nostr"] },
63
63
  configSchema: buildChannelConfigSchema(NostrConfigSchema),
64
- setupContract: createNostrSetupContract(createNostrSetupAdapter({
65
- resolveAccountId: (cfg, accountId) => accountId?.trim() || resolveDefaultSetupNostrAccountId(cfg),
66
- validatePrivateKey: (privateKey) => /^(?:nsec1|NSEC1)|^[0-9a-fA-F]{64}$/u.test(privateKey)
67
- })),
64
+ setupContract: createNostrSetupContract(createNostrSetupAdapter({ resolveAccountId: (cfg, accountId) => accountId?.trim() || resolveDefaultSetupNostrAccountId(cfg) })),
68
65
  setupWizard: nostrSetupWizard,
69
66
  config: {
70
67
  listAccountIds: (cfg) => resolveSetupNostrAccount({ cfg }).configured ? [resolveDefaultSetupNostrAccountId(cfg)] : [],
@@ -1,8 +1,9 @@
1
- import { a as parseRelayUrls, c as DEFAULT_RELAYS, i as createNostrSetupStatus, n as createNostrSetupAdapter, o as hasConfiguredNostrPrivateKey, r as createNostrSetupContract, s as resolveNostrPrivateKey, t as buildNostrSetupPatch } from "./setup-adapter-ClKW2fkz.js";
1
+ import { a as parseRelayUrls, c as validatePrivateKey, i as createNostrSetupStatus, l as DEFAULT_RELAYS, n as createNostrSetupAdapter, o as hasConfiguredNostrPrivateKey, r as createNostrSetupContract, s as resolveNostrPrivateKey, t as buildNostrSetupPatch } from "./setup-adapter-KJ_iGKiG.js";
2
2
  import { createAccountListHelpers } from "openclaw/plugin-sdk/account-helpers";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
5
- import { getPublicKey, nip19 } from "nostr-tools";
5
+ import { decode } from "nostr-tools/nip19";
6
+ import { getPublicKey } from "nostr-tools/pure";
6
7
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId, normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-id";
7
8
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/routing";
8
9
  import { createSetupTranslator, createTopLevelChannelDmPolicy, createTopLevelChannelParsedAllowFromPrompt, defineTokenCredential, formatDocsLink, mergeAllowFromEntries, parseSetupEntriesWithParser, patchTopLevelChannelConfigSection, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
@@ -19,34 +20,13 @@ var __exportAll = (all, no_symbols) => {
19
20
  };
20
21
  //#endregion
21
22
  //#region extensions/nostr/src/nostr-key-utils.ts
22
- /**
23
- * Validate and normalize a private key (accepts hex or nsec format)
24
- */
25
- function validatePrivateKey(key) {
26
- const trimmed = key.trim();
27
- if (trimmed.startsWith("nsec1") || trimmed.startsWith("NSEC1")) {
28
- const decoded = nip19.decode(trimmed);
29
- if (decoded.type !== "nsec") throw new Error("Invalid nsec key: wrong type");
30
- return decoded.data;
31
- }
32
- if (!/^[0-9a-fA-F]{64}$/.test(trimmed)) throw new Error("Private key must be 64 hex characters or nsec bech32 format");
33
- const bytes = /* @__PURE__ */ new Uint8Array(32);
34
- for (let i = 0; i < 32; i++) bytes[i] = Number.parseInt(trimmed.slice(i * 2, i * 2 + 2), 16);
35
- return bytes;
36
- }
37
- /**
38
- * Get public key from private key (hex or nsec format)
39
- */
40
23
  function getPublicKeyFromPrivate(privateKey) {
41
24
  return getPublicKey(validatePrivateKey(privateKey));
42
25
  }
43
- /**
44
- * Normalize a pubkey to hex format (accepts npub or hex)
45
- */
46
26
  function normalizePubkey(input) {
47
27
  const trimmed = input.trim();
48
28
  if (trimmed.startsWith("npub1") || trimmed.startsWith("NPUB1")) {
49
- const decoded = nip19.decode(trimmed);
29
+ const decoded = decode(trimmed);
50
30
  if (decoded.type !== "npub" || typeof decoded.data !== "string") throw new Error("Invalid npub key");
51
31
  return decoded.data.toLowerCase();
52
32
  }
@@ -129,34 +109,25 @@ function parseNostrAllowFrom(raw) {
129
109
  }
130
110
  });
131
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
+ });
132
122
  const nostrDmPolicy = createTopLevelChannelDmPolicy({
133
123
  label: "Nostr",
134
124
  channel,
135
125
  policyKey: "channels.nostr.dmPolicy",
136
126
  allowFromKey: "channels.nostr.allowFrom",
137
127
  getCurrent: (cfg) => cfg.channels?.nostr?.dmPolicy ?? "pairing",
138
- promptAllowFrom: createTopLevelChannelParsedAllowFromPrompt({
139
- channel,
140
- defaultAccountId: resolveDefaultNostrAccountId,
141
- noteTitle: t("wizard.nostr.allowlistTitle"),
142
- noteLines: NOSTR_ALLOW_FROM_HELP_LINES,
143
- message: t("wizard.nostr.allowFromPrompt"),
144
- placeholder: "npub1..., 0123abcd...",
145
- parseEntries: parseNostrAllowFrom,
146
- mergeEntries: ({ existing, parsed }) => mergeAllowFromEntries(existing, parsed)
147
- })
148
- });
149
- const nostrSetupAdapter = createNostrSetupAdapter({
150
- resolveAccountId: (cfg, accountId) => accountId?.trim() || resolveDefaultNostrAccountId(cfg),
151
- validatePrivateKey: (privateKey) => {
152
- try {
153
- getPublicKeyFromPrivate(privateKey);
154
- return true;
155
- } catch {
156
- return false;
157
- }
158
- }
128
+ promptAllowFrom: promptNostrAllowFrom
159
129
  });
130
+ const nostrSetupAdapter = createNostrSetupAdapter({ resolveAccountId: (cfg, accountId) => accountId?.trim() || resolveDefaultNostrAccountId(cfg) });
160
131
  const nostrSetupContract = createNostrSetupContract(nostrSetupAdapter);
161
132
  const nostrSetupWizard = {
162
133
  channel,
@@ -244,4 +215,4 @@ const nostrSetupWizard = {
244
215
  disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
245
216
  };
246
217
  //#endregion
247
- export { listNostrAccountIds as a, normalizePubkey as c, setup_surface_exports as i, validatePrivateKey as l, nostrSetupContract as n, resolveDefaultNostrAccountId as o, nostrSetupWizard as r, resolveNostrAccount as s, nostrSetupAdapter as t };
218
+ export { listNostrAccountIds as a, normalizePubkey as c, setup_surface_exports as i, nostrSetupContract as n, resolveDefaultNostrAccountId as o, nostrSetupWizard as r, resolveNostrAccount as s, nostrSetupAdapter as t };
@@ -650,10 +650,12 @@ var Subscription = class {
650
650
  this.closed = true;
651
651
  }
652
652
  this.relay.openSubs.delete(this.id);
653
- this.relay.ongoingOperations--;
654
- if (this.relay.ongoingOperations === 0) {
655
- this.relay.idleSince = Date.now();
656
- this.relay.scheduleIdleClose();
653
+ if (!this.id.startsWith("<forced-ping>")) {
654
+ this.relay.ongoingOperations--;
655
+ if (this.relay.ongoingOperations === 0) {
656
+ this.relay.idleSince = Date.now();
657
+ this.relay.scheduleIdleClose();
658
+ }
657
659
  }
658
660
  this.onclose?.(reason);
659
661
  }
@@ -1004,7 +1006,7 @@ var AbstractSimplePool = class {
1004
1006
  });
1005
1007
  } catch (err) {
1006
1008
  this.onRelayConnectionFailure?.(url);
1007
- return String("connection failure: " + String(err));
1009
+ return Promise.reject("connection failure: " + String(err));
1008
1010
  }
1009
1011
  return r.publish(event).catch(async (err) => {
1010
1012
  if (err instanceof Error && err.message.startsWith("auth-required: ") && params?.onauth) {