@openclaw/nostr 2026.7.2-beta.7 → 2026.7.33

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 (159) hide show
  1. package/dist/{channel-O6-jXoT5.js → .setup/channel-B4SX7Iq6.mjs} +554 -877
  2. package/dist/{config-schema-CelPzg1N.js → .setup/config-schema-DIiXiBKr.mjs} +1 -1
  3. package/dist/.setup/inbound-direct-dm-runtime-EdLLVtkh.mjs +2 -0
  4. package/dist/{setup-adapter-BjKmSwdW.js → .setup/setup-adapter-DEU3o8MF.mjs} +1 -31
  5. package/dist/.setup/setup-plugin-api-DzlCumkz.mjs +2 -0
  6. package/dist/.setup/setup-plugin-api-csfJrRxD.mjs +111 -0
  7. package/dist/{setup-surface-BJCFpe02.js → .setup/setup-surface-DWa6-9ku.mjs} +70 -41
  8. package/dist/api.js +72 -61
  9. package/dist/channel-plugin-api.js +1 -1
  10. package/dist/doctor-contract-api.js +3 -2
  11. package/dist/setup-api.js +1 -1
  12. package/dist/setup-entry.js +2 -1
  13. package/dist/setup-plugin-api.js +1 -112
  14. package/node_modules/nostr-tools/lib/cjs/abstract-pool.js +28 -59
  15. package/node_modules/nostr-tools/lib/cjs/abstract-pool.js.map +3 -3
  16. package/node_modules/nostr-tools/lib/cjs/abstract-relay.js +7 -44
  17. package/node_modules/nostr-tools/lib/cjs/abstract-relay.js.map +2 -2
  18. package/node_modules/nostr-tools/lib/cjs/core.js +1 -17
  19. package/node_modules/nostr-tools/lib/cjs/core.js.map +3 -3
  20. package/node_modules/nostr-tools/lib/cjs/filter.js.map +1 -1
  21. package/node_modules/nostr-tools/lib/cjs/index.js +130 -172
  22. package/node_modules/nostr-tools/lib/cjs/index.js.map +4 -4
  23. package/node_modules/nostr-tools/lib/cjs/kinds.js +1 -17
  24. package/node_modules/nostr-tools/lib/cjs/kinds.js.map +3 -3
  25. package/node_modules/nostr-tools/lib/cjs/nip04.js.map +1 -1
  26. package/node_modules/nostr-tools/lib/cjs/nip10.js +5 -20
  27. package/node_modules/nostr-tools/lib/cjs/nip10.js.map +3 -3
  28. package/node_modules/nostr-tools/lib/cjs/nip13.js.map +1 -1
  29. package/node_modules/nostr-tools/lib/cjs/nip17.js +23 -30
  30. package/node_modules/nostr-tools/lib/cjs/nip17.js.map +4 -4
  31. package/node_modules/nostr-tools/lib/cjs/nip18.js +14 -21
  32. package/node_modules/nostr-tools/lib/cjs/nip18.js.map +4 -4
  33. package/node_modules/nostr-tools/lib/cjs/nip19.js.map +1 -1
  34. package/node_modules/nostr-tools/lib/cjs/nip21.js.map +1 -1
  35. package/node_modules/nostr-tools/lib/cjs/nip22.js +7 -22
  36. package/node_modules/nostr-tools/lib/cjs/nip22.js.map +3 -3
  37. package/node_modules/nostr-tools/lib/cjs/nip25.js +14 -21
  38. package/node_modules/nostr-tools/lib/cjs/nip25.js.map +4 -4
  39. package/node_modules/nostr-tools/lib/cjs/nip27.js.map +1 -1
  40. package/node_modules/nostr-tools/lib/cjs/nip28.js +14 -21
  41. package/node_modules/nostr-tools/lib/cjs/nip28.js.map +4 -4
  42. package/node_modules/nostr-tools/lib/cjs/nip29.js.map +1 -1
  43. package/node_modules/nostr-tools/lib/cjs/nip30.js.map +2 -2
  44. package/node_modules/nostr-tools/lib/cjs/nip42.js.map +2 -2
  45. package/node_modules/nostr-tools/lib/cjs/nip44.js.map +1 -1
  46. package/node_modules/nostr-tools/lib/cjs/nip45.js +9 -22
  47. package/node_modules/nostr-tools/lib/cjs/nip45.js.map +4 -4
  48. package/node_modules/nostr-tools/lib/cjs/nip46.js +70 -111
  49. package/node_modules/nostr-tools/lib/cjs/nip46.js.map +4 -4
  50. package/node_modules/nostr-tools/lib/cjs/nip47.js +18 -25
  51. package/node_modules/nostr-tools/lib/cjs/nip47.js.map +4 -4
  52. package/node_modules/nostr-tools/lib/cjs/nip57.js +16 -23
  53. package/node_modules/nostr-tools/lib/cjs/nip57.js.map +4 -4
  54. package/node_modules/nostr-tools/lib/cjs/nip58.js.map +2 -2
  55. package/node_modules/nostr-tools/lib/cjs/nip59.js +7 -16
  56. package/node_modules/nostr-tools/lib/cjs/nip59.js.map +3 -3
  57. package/node_modules/nostr-tools/lib/cjs/nip75.js.map +1 -1
  58. package/node_modules/nostr-tools/lib/cjs/nip94.js.map +1 -1
  59. package/node_modules/nostr-tools/lib/cjs/nip98.js +16 -23
  60. package/node_modules/nostr-tools/lib/cjs/nip98.js.map +4 -4
  61. package/node_modules/nostr-tools/lib/cjs/nip99.js.map +2 -2
  62. package/node_modules/nostr-tools/lib/cjs/nipb0.js +17 -38
  63. package/node_modules/nostr-tools/lib/cjs/nipb0.js.map +4 -4
  64. package/node_modules/nostr-tools/lib/cjs/nipb7.js +7 -13
  65. package/node_modules/nostr-tools/lib/cjs/nipb7.js.map +2 -2
  66. package/node_modules/nostr-tools/lib/cjs/pool.js +61 -102
  67. package/node_modules/nostr-tools/lib/cjs/pool.js.map +4 -4
  68. package/node_modules/nostr-tools/lib/cjs/pure.js +14 -21
  69. package/node_modules/nostr-tools/lib/cjs/pure.js.map +4 -4
  70. package/node_modules/nostr-tools/lib/cjs/references.js.map +1 -1
  71. package/node_modules/nostr-tools/lib/cjs/relay.js +42 -86
  72. package/node_modules/nostr-tools/lib/cjs/relay.js.map +4 -4
  73. package/node_modules/nostr-tools/lib/cjs/signer.js +14 -21
  74. package/node_modules/nostr-tools/lib/cjs/signer.js.map +4 -4
  75. package/node_modules/nostr-tools/lib/cjs/utils.js +0 -10
  76. package/node_modules/nostr-tools/lib/cjs/utils.js.map +2 -2
  77. package/node_modules/nostr-tools/lib/cjs/wasm.js +2 -16
  78. package/node_modules/nostr-tools/lib/cjs/wasm.js.map +4 -4
  79. package/node_modules/nostr-tools/lib/esm/abstract-pool.js +28 -59
  80. package/node_modules/nostr-tools/lib/esm/abstract-pool.js.map +3 -3
  81. package/node_modules/nostr-tools/lib/esm/abstract-relay.js +7 -44
  82. package/node_modules/nostr-tools/lib/esm/abstract-relay.js.map +2 -2
  83. package/node_modules/nostr-tools/lib/esm/core.js +1 -15
  84. package/node_modules/nostr-tools/lib/esm/core.js.map +3 -3
  85. package/node_modules/nostr-tools/lib/esm/filter.js.map +1 -1
  86. package/node_modules/nostr-tools/lib/esm/index.js +80 -122
  87. package/node_modules/nostr-tools/lib/esm/index.js.map +4 -4
  88. package/node_modules/nostr-tools/lib/esm/kinds.js +1 -17
  89. package/node_modules/nostr-tools/lib/esm/kinds.js.map +3 -3
  90. package/node_modules/nostr-tools/lib/esm/nip04.js.map +1 -1
  91. package/node_modules/nostr-tools/lib/esm/nip10.js +5 -18
  92. package/node_modules/nostr-tools/lib/esm/nip10.js.map +3 -3
  93. package/node_modules/nostr-tools/lib/esm/nip13.js.map +1 -1
  94. package/node_modules/nostr-tools/lib/esm/nip17.js +8 -15
  95. package/node_modules/nostr-tools/lib/esm/nip17.js.map +4 -4
  96. package/node_modules/nostr-tools/lib/esm/nip18.js +8 -15
  97. package/node_modules/nostr-tools/lib/esm/nip18.js.map +4 -4
  98. package/node_modules/nostr-tools/lib/esm/nip19.js.map +1 -1
  99. package/node_modules/nostr-tools/lib/esm/nip21.js.map +1 -1
  100. package/node_modules/nostr-tools/lib/esm/nip22.js +7 -20
  101. package/node_modules/nostr-tools/lib/esm/nip22.js.map +3 -3
  102. package/node_modules/nostr-tools/lib/esm/nip25.js +8 -15
  103. package/node_modules/nostr-tools/lib/esm/nip25.js.map +4 -4
  104. package/node_modules/nostr-tools/lib/esm/nip27.js.map +1 -1
  105. package/node_modules/nostr-tools/lib/esm/nip28.js +8 -15
  106. package/node_modules/nostr-tools/lib/esm/nip28.js.map +4 -4
  107. package/node_modules/nostr-tools/lib/esm/nip29.js.map +1 -1
  108. package/node_modules/nostr-tools/lib/esm/nip30.js.map +2 -2
  109. package/node_modules/nostr-tools/lib/esm/nip42.js.map +2 -2
  110. package/node_modules/nostr-tools/lib/esm/nip44.js.map +1 -1
  111. package/node_modules/nostr-tools/lib/esm/nip45.js +10 -23
  112. package/node_modules/nostr-tools/lib/esm/nip45.js.map +4 -4
  113. package/node_modules/nostr-tools/lib/esm/nip46.js +54 -95
  114. package/node_modules/nostr-tools/lib/esm/nip46.js.map +4 -4
  115. package/node_modules/nostr-tools/lib/esm/nip47.js +8 -15
  116. package/node_modules/nostr-tools/lib/esm/nip47.js.map +4 -4
  117. package/node_modules/nostr-tools/lib/esm/nip57.js +10 -17
  118. package/node_modules/nostr-tools/lib/esm/nip57.js.map +4 -4
  119. package/node_modules/nostr-tools/lib/esm/nip58.js.map +2 -2
  120. package/node_modules/nostr-tools/lib/esm/nip59.js +1 -10
  121. package/node_modules/nostr-tools/lib/esm/nip59.js.map +3 -3
  122. package/node_modules/nostr-tools/lib/esm/nip75.js.map +1 -1
  123. package/node_modules/nostr-tools/lib/esm/nip94.js.map +1 -1
  124. package/node_modules/nostr-tools/lib/esm/nip98.js +8 -15
  125. package/node_modules/nostr-tools/lib/esm/nip98.js.map +4 -4
  126. package/node_modules/nostr-tools/lib/esm/nip99.js.map +2 -2
  127. package/node_modules/nostr-tools/lib/esm/nipb0.js +18 -39
  128. package/node_modules/nostr-tools/lib/esm/nipb0.js.map +4 -4
  129. package/node_modules/nostr-tools/lib/esm/nipb7.js +7 -13
  130. package/node_modules/nostr-tools/lib/esm/nipb7.js.map +2 -2
  131. package/node_modules/nostr-tools/lib/esm/pool.js +54 -95
  132. package/node_modules/nostr-tools/lib/esm/pool.js.map +4 -4
  133. package/node_modules/nostr-tools/lib/esm/pure.js +8 -15
  134. package/node_modules/nostr-tools/lib/esm/pure.js.map +4 -4
  135. package/node_modules/nostr-tools/lib/esm/references.js.map +1 -1
  136. package/node_modules/nostr-tools/lib/esm/relay.js +36 -80
  137. package/node_modules/nostr-tools/lib/esm/relay.js.map +4 -4
  138. package/node_modules/nostr-tools/lib/esm/signer.js +8 -15
  139. package/node_modules/nostr-tools/lib/esm/signer.js.map +4 -4
  140. package/node_modules/nostr-tools/lib/esm/utils.js +0 -10
  141. package/node_modules/nostr-tools/lib/esm/utils.js.map +2 -2
  142. package/node_modules/nostr-tools/lib/esm/wasm.js +3 -17
  143. package/node_modules/nostr-tools/lib/esm/wasm.js.map +4 -4
  144. package/node_modules/nostr-tools/lib/nostr.bundle.js +77 -121
  145. package/node_modules/nostr-tools/lib/nostr.bundle.js.map +4 -4
  146. package/node_modules/nostr-tools/lib/types/abstract-pool.d.ts +4 -7
  147. package/node_modules/nostr-tools/lib/types/abstract-relay.d.ts +2 -7
  148. package/node_modules/nostr-tools/lib/types/helpers.d.ts +2 -0
  149. package/node_modules/nostr-tools/lib/types/kinds.d.ts +0 -2
  150. package/node_modules/nostr-tools/lib/types/nipb0.d.ts +1 -0
  151. package/node_modules/nostr-tools/lib/types/nipb7.d.ts +1 -0
  152. package/node_modules/nostr-tools/lib/types/relay.d.ts +2 -2
  153. package/node_modules/nostr-tools/lib/types/utils.d.ts +0 -4
  154. package/node_modules/nostr-tools/package.json +1 -1
  155. package/openclaw.plugin.json +5 -0
  156. package/package.json +15 -41
  157. package/dist/inbound-direct-dm-runtime-DHn9NoYN.js +0 -2
  158. package/node_modules/nostr-tools/lib/types/nipb0.test.d.ts +0 -1
  159. /package/dist/{state-account-id-CvBZ9s6P.js → .setup/state-account-id-CvBZ9s6P.mjs} +0 -0
@@ -1,6 +1,6 @@
1
1
  import { collectStatusIssuesFromLastError, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
2
2
  import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, formatPairingApproveHint } from "openclaw/plugin-sdk/channel-plugin-common";
3
- import { AllowFromListSchema, DmPolicySchema, MarkdownConfigSchema } from "openclaw/plugin-sdk/channel-config-schema";
3
+ import { AllowFromListSchema, DmPolicySchema, MarkdownConfigSchema } from "openclaw/plugin-sdk/channel-config-primitives";
4
4
  import { buildSecretInputSchema } from "openclaw/plugin-sdk/secret-input";
5
5
  import { z } from "zod";
6
6
  //#region extensions/nostr/src/config-schema.ts
@@ -0,0 +1,2 @@
1
+ import { dispatchInboundDirectDmWithRuntime } from "openclaw/plugin-sdk/channel-inbound";
2
+ export { dispatchInboundDirectDmWithRuntime };
@@ -1,7 +1,6 @@
1
1
  import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
2
2
  import { DEFAULT_ACCOUNT_ID } from "openclaw/plugin-sdk/routing";
3
3
  import { patchTopLevelChannelConfigSection, splitSetupEntries } from "openclaw/plugin-sdk/setup";
4
- import { defineChannelSetupContract } from "openclaw/plugin-sdk/channel-setup";
5
4
  //#region extensions/nostr/src/default-relays.ts
6
5
  const DEFAULT_RELAYS = ["wss://relay.damus.io", "wss://nos.lol"];
7
6
  //#endregion
@@ -66,34 +65,5 @@ function createNostrSetupAdapter(params) {
66
65
  }
67
66
  };
68
67
  }
69
- function createNostrSetupContract(adapter) {
70
- return defineChannelSetupContract({
71
- fields: {
72
- privateKey: {
73
- kind: "string",
74
- sensitive: true,
75
- cli: {
76
- flags: "--private-key <key>",
77
- description: "Nostr private key"
78
- }
79
- },
80
- relayUrls: {
81
- kind: "string",
82
- cli: {
83
- flags: "--relay-urls <urls>",
84
- description: "Nostr relay URLs"
85
- }
86
- },
87
- useEnv: {
88
- kind: "boolean",
89
- cli: {
90
- flags: "--use-env",
91
- description: "Use NOSTR_PRIVATE_KEY"
92
- }
93
- }
94
- },
95
- legacyAdapter: adapter
96
- });
97
- }
98
68
  //#endregion
99
- export { DEFAULT_RELAYS as a, parseRelayUrls as i, createNostrSetupAdapter as n, createNostrSetupContract as r, buildNostrSetupPatch as t };
69
+ export { DEFAULT_RELAYS as i, createNostrSetupAdapter as n, parseRelayUrls as r, buildNostrSetupPatch as t };
@@ -0,0 +1,2 @@
1
+ import { t as nostrSetupPlugin } from "./setup-plugin-api-csfJrRxD.mjs";
2
+ export { nostrSetupPlugin };
@@ -0,0 +1,111 @@
1
+ import { i as buildChannelConfigSchema, t as NostrConfigSchema } from "./config-schema-DIiXiBKr.mjs";
2
+ import { i as DEFAULT_RELAYS, n as createNostrSetupAdapter } from "./setup-adapter-DEU3o8MF.mjs";
3
+ import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
4
+ import { DEFAULT_ACCOUNT_ID, createDelegatedSetupWizardProxy, createSetupTranslator, createStandardChannelSetupStatus } from "openclaw/plugin-sdk/setup-runtime";
5
+ //#region extensions/nostr/src/channel.setup.ts
6
+ const t = createSetupTranslator();
7
+ const channel = "nostr";
8
+ function getNostrConfig(cfg) {
9
+ return cfg.channels?.nostr;
10
+ }
11
+ function listSetupNostrAccountIds(cfg) {
12
+ const nostrCfg = getNostrConfig(cfg);
13
+ if (!(typeof nostrCfg?.privateKey === "string" ? nostrCfg.privateKey.trim() : "")) return [];
14
+ return [resolveDefaultSetupNostrAccountId(cfg)];
15
+ }
16
+ function resolveDefaultSetupNostrAccountId(cfg) {
17
+ const configured = getNostrConfig(cfg)?.defaultAccount;
18
+ return typeof configured === "string" && configured.trim() ? configured.trim() : DEFAULT_ACCOUNT_ID;
19
+ }
20
+ function resolveSetupNostrAccount(params) {
21
+ const nostrCfg = getNostrConfig(params.cfg);
22
+ const accountId = params.accountId?.trim() || resolveDefaultSetupNostrAccountId(params.cfg);
23
+ const privateKey = typeof nostrCfg?.privateKey === "string" ? nostrCfg.privateKey.trim() : "";
24
+ const configured = Boolean(privateKey);
25
+ return {
26
+ accountId,
27
+ name: typeof nostrCfg?.name === "string" ? nostrCfg.name : void 0,
28
+ enabled: nostrCfg?.enabled !== false,
29
+ configured,
30
+ privateKey,
31
+ publicKey: "",
32
+ relays: nostrCfg?.relays ?? DEFAULT_RELAYS,
33
+ profile: nostrCfg?.profile,
34
+ config: {
35
+ enabled: nostrCfg?.enabled,
36
+ name: nostrCfg?.name,
37
+ privateKey: nostrCfg?.privateKey,
38
+ relays: nostrCfg?.relays,
39
+ dmPolicy: nostrCfg?.dmPolicy,
40
+ allowFrom: nostrCfg?.allowFrom,
41
+ profile: nostrCfg?.profile
42
+ }
43
+ };
44
+ }
45
+ function looksLikeNostrPrivateKey(privateKey) {
46
+ return privateKey.startsWith("nsec1") || /^[0-9a-fA-F]{64}$/.test(privateKey);
47
+ }
48
+ const nostrSetupAdapter = createNostrSetupAdapter({
49
+ resolveAccountId: (cfg, accountId) => accountId?.trim() || resolveDefaultSetupNostrAccountId(cfg),
50
+ validatePrivateKey: looksLikeNostrPrivateKey
51
+ });
52
+ const nostrSetupWizard = createDelegatedSetupWizardProxy({
53
+ channel,
54
+ loadWizard: async () => (await import("./setup-surface-DWa6-9ku.mjs").then((n) => n.r)).nostrSetupWizard,
55
+ status: { ...createStandardChannelSetupStatus({
56
+ channelLabel: "Nostr",
57
+ configuredLabel: t("wizard.channels.statusConfigured"),
58
+ unconfiguredLabel: t("wizard.channels.statusNeedsPrivateKey"),
59
+ configuredHint: t("wizard.channels.statusConfigured"),
60
+ unconfiguredHint: t("wizard.channels.statusNeedsPrivateKey"),
61
+ configuredScore: 1,
62
+ unconfiguredScore: 0,
63
+ includeStatusLine: true,
64
+ resolveConfigured: ({ cfg, accountId }) => resolveSetupNostrAccount({
65
+ cfg,
66
+ accountId
67
+ }).configured,
68
+ resolveExtraStatusLines: ({ cfg }) => {
69
+ return [`Relays: ${resolveSetupNostrAccount({ cfg }).relays.length || DEFAULT_RELAYS.length}`];
70
+ }
71
+ }) },
72
+ resolveShouldPromptAccountIds: () => false,
73
+ delegatePrepare: true,
74
+ delegateFinalize: true
75
+ });
76
+ const nostrSetupPlugin = {
77
+ id: channel,
78
+ meta: {
79
+ id: channel,
80
+ label: "Nostr",
81
+ selectionLabel: "Nostr",
82
+ docsPath: "/channels/nostr",
83
+ docsLabel: "nostr",
84
+ blurb: "Decentralized DMs via Nostr relays (NIP-04)",
85
+ order: 100
86
+ },
87
+ capabilities: {
88
+ chatTypes: ["direct"],
89
+ media: false
90
+ },
91
+ reload: { configPrefixes: ["channels.nostr"] },
92
+ configSchema: buildChannelConfigSchema(NostrConfigSchema),
93
+ setup: nostrSetupAdapter,
94
+ setupWizard: nostrSetupWizard,
95
+ config: {
96
+ listAccountIds: listSetupNostrAccountIds,
97
+ resolveAccount: (cfg, accountId) => resolveSetupNostrAccount({
98
+ cfg,
99
+ accountId
100
+ }),
101
+ defaultAccountId: resolveDefaultSetupNostrAccountId,
102
+ isConfigured: (account) => account.configured,
103
+ describeAccount: (account) => describeAccountSnapshot({
104
+ account,
105
+ configured: account.configured,
106
+ extra: { publicKey: account.publicKey }
107
+ })
108
+ }
109
+ };
110
+ //#endregion
111
+ export { nostrSetupPlugin as t };
@@ -1,11 +1,11 @@
1
- import { a as DEFAULT_RELAYS, i as parseRelayUrls, n as createNostrSetupAdapter, r as createNostrSetupContract, t as buildNostrSetupPatch } from "./setup-adapter-BjKmSwdW.js";
2
- import { createAccountListHelpers } from "openclaw/plugin-sdk/account-helpers";
1
+ import { i as DEFAULT_RELAYS, n as createNostrSetupAdapter, r as parseRelayUrls, t as buildNostrSetupPatch } from "./setup-adapter-DEU3o8MF.mjs";
3
2
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
3
  import { hasConfiguredSecretInput, normalizeSecretInputString } from "openclaw/plugin-sdk/secret-input";
5
4
  import { getPublicKey, nip19 } from "nostr-tools";
6
5
  import { DEFAULT_ACCOUNT_ID, normalizeAccountId, normalizeOptionalAccountId } from "openclaw/plugin-sdk/account-id";
6
+ import { listCombinedAccountIds, resolveListedDefaultAccountId } from "openclaw/plugin-sdk/account-resolution";
7
7
  import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1 } from "openclaw/plugin-sdk/routing";
8
- import { createSetupTranslator, createStandardChannelSetupStatus, createTopLevelChannelDmPolicy, createTopLevelChannelParsedAllowFromPrompt, defineTokenCredential, formatDocsLink, mergeAllowFromEntries, parseSetupEntriesWithParser, patchTopLevelChannelConfigSection, setSetupChannelEnabled } from "openclaw/plugin-sdk/setup";
8
+ import { createSetupTranslator, createStandardChannelSetupStatus, createTopLevelChannelDmPolicy, createTopLevelChannelParsedAllowFromPrompt, formatDocsLink, mergeAllowFromEntries, parseSetupEntriesWithParser, patchTopLevelChannelConfigSection } from "openclaw/plugin-sdk/setup";
9
9
  //#region \0rolldown/runtime.js
10
10
  var __defProp = Object.defineProperty;
11
11
  var __exportAll = (all, no_symbols) => {
@@ -24,7 +24,7 @@ var __exportAll = (all, no_symbols) => {
24
24
  */
25
25
  function validatePrivateKey(key) {
26
26
  const trimmed = key.trim();
27
- if (trimmed.startsWith("nsec1") || trimmed.startsWith("NSEC1")) {
27
+ if (trimmed.startsWith("nsec1")) {
28
28
  const decoded = nip19.decode(trimmed);
29
29
  if (decoded.type !== "nsec") throw new Error("Invalid nsec key: wrong type");
30
30
  return decoded.data;
@@ -38,14 +38,15 @@ function validatePrivateKey(key) {
38
38
  * Get public key from private key (hex or nsec format)
39
39
  */
40
40
  function getPublicKeyFromPrivate(privateKey) {
41
- return getPublicKey(validatePrivateKey(privateKey));
41
+ const sk = validatePrivateKey(privateKey);
42
+ return getPublicKey(sk);
42
43
  }
43
44
  /**
44
45
  * Normalize a pubkey to hex format (accepts npub or hex)
45
46
  */
46
47
  function normalizePubkey(input) {
47
48
  const trimmed = input.trim();
48
- if (trimmed.startsWith("npub1") || trimmed.startsWith("NPUB1")) {
49
+ if (trimmed.startsWith("npub1")) {
49
50
  const decoded = nip19.decode(trimmed);
50
51
  if (decoded.type !== "npub" || typeof decoded.data !== "string") throw new Error("Invalid npub key");
51
52
  return decoded.data.toLowerCase();
@@ -55,13 +56,30 @@ function normalizePubkey(input) {
55
56
  }
56
57
  //#endregion
57
58
  //#region extensions/nostr/src/types.ts
58
- const { listAccountIds: listNostrAccountIds, resolveDefaultAccountId: resolveDefaultNostrAccountId } = createAccountListHelpers("nostr", {
59
- fallbackAccountIdWhenEmpty: false,
60
- resolveImplicitAccountId: (cfg) => {
61
- const account = cfg.channels?.nostr;
62
- return normalizeSecretInputString(account?.privateKey) ? normalizeOptionalAccountId(account?.defaultAccount) ?? DEFAULT_ACCOUNT_ID : void 0;
63
- }
64
- });
59
+ function resolveConfiguredDefaultNostrAccountId(cfg) {
60
+ const nostrCfg = cfg.channels?.nostr;
61
+ return normalizeOptionalAccountId(nostrCfg?.defaultAccount);
62
+ }
63
+ /**
64
+ * List all configured Nostr account IDs
65
+ */
66
+ function listNostrAccountIds(cfg) {
67
+ const nostrCfg = cfg.channels?.nostr;
68
+ const privateKey = normalizeSecretInputString(nostrCfg?.privateKey);
69
+ return listCombinedAccountIds({
70
+ configuredAccountIds: [],
71
+ implicitAccountId: privateKey ? resolveConfiguredDefaultNostrAccountId(cfg) ?? DEFAULT_ACCOUNT_ID : void 0
72
+ });
73
+ }
74
+ /**
75
+ * Get the default account ID
76
+ */
77
+ function resolveDefaultNostrAccountId(cfg) {
78
+ return resolveListedDefaultAccountId({
79
+ accountIds: listNostrAccountIds(cfg),
80
+ configuredDefaultAccountId: resolveConfiguredDefaultNostrAccountId(cfg)
81
+ });
82
+ }
65
83
  /**
66
84
  * Resolve a Nostr account from config
67
85
  */
@@ -99,7 +117,6 @@ function resolveNostrAccount(opts) {
99
117
  //#region extensions/nostr/src/setup-surface.ts
100
118
  var setup_surface_exports = /* @__PURE__ */ __exportAll({
101
119
  nostrSetupAdapter: () => nostrSetupAdapter,
102
- nostrSetupContract: () => nostrSetupContract,
103
120
  nostrSetupWizard: () => nostrSetupWizard
104
121
  });
105
122
  const t = createSetupTranslator();
@@ -129,22 +146,23 @@ function parseNostrAllowFrom(raw) {
129
146
  }
130
147
  });
131
148
  }
149
+ const promptNostrAllowFrom = createTopLevelChannelParsedAllowFromPrompt({
150
+ channel,
151
+ defaultAccountId: resolveDefaultNostrAccountId,
152
+ noteTitle: t("wizard.nostr.allowlistTitle"),
153
+ noteLines: NOSTR_ALLOW_FROM_HELP_LINES,
154
+ message: t("wizard.nostr.allowFromPrompt"),
155
+ placeholder: "npub1..., 0123abcd...",
156
+ parseEntries: parseNostrAllowFrom,
157
+ mergeEntries: ({ existing, parsed }) => mergeAllowFromEntries(existing, parsed)
158
+ });
132
159
  const nostrDmPolicy = createTopLevelChannelDmPolicy({
133
160
  label: "Nostr",
134
161
  channel,
135
162
  policyKey: "channels.nostr.dmPolicy",
136
163
  allowFromKey: "channels.nostr.allowFrom",
137
164
  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
- })
165
+ promptAllowFrom: promptNostrAllowFrom
148
166
  });
149
167
  const nostrSetupAdapter = createNostrSetupAdapter({
150
168
  resolveAccountId: (cfg, accountId) => accountId?.trim() || resolveDefaultNostrAccountId(cfg),
@@ -157,7 +175,6 @@ const nostrSetupAdapter = createNostrSetupAdapter({
157
175
  }
158
176
  }
159
177
  });
160
- const nostrSetupContract = createNostrSetupContract(nostrSetupAdapter);
161
178
  const nostrSetupWizard = {
162
179
  channel,
163
180
  resolveAccountIdForConfigure: ({ accountOverride, defaultAccountId }) => accountOverride?.trim() || defaultAccountId,
@@ -195,9 +212,8 @@ const nostrSetupWizard = {
195
212
  patch: buildNostrSetupPatch(accountId, {})
196
213
  })
197
214
  },
198
- credentials: [defineTokenCredential({
215
+ credentials: [{
199
216
  inputKey: "privateKey",
200
- configKey: "privateKey",
201
217
  providerHint: channel,
202
218
  credentialLabel: "private key",
203
219
  preferredEnvVar: "NOSTR_PRIVATE_KEY",
@@ -207,23 +223,32 @@ const nostrSetupWizard = {
207
223
  keepPrompt: t("wizard.nostr.privateKeyKeep"),
208
224
  inputPrompt: t("wizard.nostr.privateKeyInput"),
209
225
  allowEnv: ({ accountId }) => accountId === DEFAULT_ACCOUNT_ID$1,
210
- resolveAccount: ({ cfg, accountId }) => resolveNostrAccount({
226
+ inspect: ({ cfg, accountId }) => {
227
+ const account = resolveNostrAccount({
228
+ cfg,
229
+ accountId
230
+ });
231
+ return {
232
+ accountConfigured: account.configured,
233
+ hasConfiguredValue: hasConfiguredSecretInput(account.config.privateKey),
234
+ resolvedValue: normalizeSecretInputString(account.config.privateKey),
235
+ envValue: process.env.NOSTR_PRIVATE_KEY?.trim()
236
+ };
237
+ },
238
+ applyUseEnv: async ({ cfg, accountId }) => patchTopLevelChannelConfigSection({
211
239
  cfg,
212
- accountId
240
+ channel,
241
+ enabled: true,
242
+ clearFields: ["privateKey"],
243
+ patch: buildNostrSetupPatch(accountId, {})
213
244
  }),
214
- accountConfigured: (account) => account.configured,
215
- resolvedValue: (account) => normalizeSecretInputString(account.config.privateKey),
216
- envValue: () => process.env.NOSTR_PRIVATE_KEY?.trim(),
217
- patchAccount: ({ cfg, accountId, patch, clearFields }) => patchTopLevelChannelConfigSection({
245
+ applySet: async ({ cfg, accountId, resolvedValue }) => patchTopLevelChannelConfigSection({
218
246
  cfg,
219
247
  channel,
220
248
  enabled: true,
221
- clearFields,
222
- patch: buildNostrSetupPatch(accountId, patch)
223
- }),
224
- useEnv: { clearFields: ["privateKey"] },
225
- set: { value: "resolved" }
226
- })],
249
+ patch: buildNostrSetupPatch(accountId, { privateKey: resolvedValue })
250
+ })
251
+ }],
227
252
  textInputs: [{
228
253
  inputKey: "relayUrls",
229
254
  message: t("wizard.nostr.relayUrlsPrompt"),
@@ -254,7 +279,11 @@ const nostrSetupWizard = {
254
279
  }
255
280
  }],
256
281
  dmPolicy: nostrDmPolicy,
257
- disable: (cfg) => setSetupChannelEnabled(cfg, channel, false)
282
+ disable: (cfg) => patchTopLevelChannelConfigSection({
283
+ cfg,
284
+ channel,
285
+ patch: { enabled: false }
286
+ })
258
287
  };
259
288
  //#endregion
260
- 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 };
289
+ export { resolveDefaultNostrAccountId as a, validatePrivateKey as c, listNostrAccountIds as i, nostrSetupWizard as n, resolveNostrAccount as o, setup_surface_exports as r, normalizePubkey as s, nostrSetupAdapter as t };
package/dist/api.js CHANGED
@@ -1,15 +1,15 @@
1
- import { s as resolveNostrAccount } from "./setup-surface-BJCFpe02.js";
1
+ import { o as resolveNostrAccount } from "./.setup/setup-surface-DWa6-9ku.mjs";
2
2
  import { getPluginRuntimeGatewayRequestScope } from "./runtime-api.js";
3
- import { n as NostrProfileSchema } from "./config-schema-CelPzg1N.js";
4
- import { a as getNostrRuntime, i as contentToProfile, n as nostrPlugin, o as setNostrRuntime, r as publishNostrProfile, t as getNostrProfileState } from "./channel-O6-jXoT5.js";
3
+ import { n as NostrProfileSchema } from "./.setup/config-schema-DIiXiBKr.mjs";
4
+ import { a as setNostrRuntime, i as getNostrRuntime, n as nostrPlugin, o as contentToProfile, r as publishNostrProfile, t as getNostrProfileState } from "./.setup/channel-B4SX7Iq6.mjs";
5
5
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
6
6
  import { z } from "zod";
7
- import { SimplePool } from "nostr-tools";
7
+ import { SimplePool, verifyEvent } from "nostr-tools";
8
+ import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
8
9
  import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
9
- import { isBlockedHostnameOrIp, isLoopbackHost } from "openclaw/plugin-sdk/ssrf-runtime";
10
10
  import { readJsonBodyWithLimit, requestBodyErrorToText } from "openclaw/plugin-sdk/webhook-request-guards";
11
11
  import { createFixedWindowRateLimiter } from "openclaw/plugin-sdk/webhook-ingress";
12
- import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
12
+ import { isBlockedHostnameOrIp } from "openclaw/plugin-sdk/ssrf-runtime";
13
13
  //#region extensions/nostr/src/nostr-profile-url-safety.ts
14
14
  function validateUrlSafety(urlStr) {
15
15
  try {
@@ -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
  };
@@ -79,49 +80,72 @@ async function importProfileFromRelays(opts) {
79
80
  relaysQueried: []
80
81
  };
81
82
  const pool = new SimplePool();
82
- const relaysQueried = [...relays];
83
- let deadlineTimer;
84
- const deadline = new Promise((resolve) => {
85
- deadlineTimer = setTimeout(resolve, timeoutMs);
86
- deadlineTimer.unref?.();
87
- });
88
- const subscriptions = [];
83
+ const relaysQueried = [];
84
+ const timers = [];
85
+ const scheduleTimeout = (callback) => {
86
+ const timer = setTimeout(callback, timeoutMs);
87
+ timer.unref?.();
88
+ timers.push(timer);
89
+ return timer;
90
+ };
89
91
  try {
90
92
  const events = [];
91
- await Promise.race([Promise.all(relays.map((relay) => new Promise((resolve) => {
92
- const subscription = pool.subscribeMany([relay], {
93
- kinds: [0],
94
- authors: [pubkey],
95
- limit: 1
96
- }, {
97
- onevent(event) {
98
- events.push({
99
- event,
100
- relay
101
- });
102
- },
103
- oneose() {
104
- resolve();
105
- },
106
- onclose() {
107
- resolve();
108
- }
109
- });
110
- subscriptions.push(subscription);
111
- }))), deadline]);
93
+ const timeoutPromise = new Promise((resolve) => {
94
+ scheduleTimeout(resolve);
95
+ });
96
+ const subscriptionPromise = new Promise((resolve) => {
97
+ let completed = 0;
98
+ for (const relay of relays) {
99
+ relaysQueried.push(relay);
100
+ const profileFilter = {
101
+ kinds: [0],
102
+ authors: [pubkey],
103
+ limit: 1
104
+ };
105
+ const sub = pool.subscribeMany([relay], profileFilter, {
106
+ onevent(event) {
107
+ events.push({
108
+ event,
109
+ relay
110
+ });
111
+ },
112
+ oneose() {
113
+ completed++;
114
+ if (completed >= relays.length) resolve();
115
+ },
116
+ onclose() {
117
+ completed++;
118
+ if (completed >= relays.length) resolve();
119
+ }
120
+ });
121
+ scheduleTimeout(() => {
122
+ sub.close();
123
+ });
124
+ }
125
+ });
126
+ await Promise.race([subscriptionPromise, timeoutPromise]);
127
+ for (const timer of timers.splice(0)) clearTimeout(timer);
112
128
  if (events.length === 0) return {
113
129
  ok: false,
114
130
  error: "No profile found on any relay",
115
131
  relaysQueried
116
132
  };
117
- const bestEvent = events.reduce((current, candidate) => {
118
- const candidateIsNewer = candidate.event.created_at > current.event.created_at;
119
- const candidateWinsTie = candidate.event.created_at === current.event.created_at && candidate.event.id < current.event.id;
120
- return candidateIsNewer || candidateWinsTie ? candidate : current;
121
- });
122
- let parsedContent;
133
+ let bestEvent = null;
134
+ for (const item of events) if (!bestEvent || item.event.created_at > bestEvent.event.created_at) bestEvent = item;
135
+ if (!bestEvent) return {
136
+ ok: false,
137
+ error: "No valid profile event found",
138
+ relaysQueried
139
+ };
140
+ if (!verifyEvent(bestEvent.event)) return {
141
+ ok: false,
142
+ error: "Profile event has invalid signature",
143
+ relaysQueried,
144
+ sourceRelay: bestEvent.relay
145
+ };
146
+ let content;
123
147
  try {
124
- parsedContent = JSON.parse(bestEvent.event.content);
148
+ content = JSON.parse(bestEvent.event.content);
125
149
  } catch {
126
150
  return {
127
151
  ok: false,
@@ -130,23 +154,9 @@ async function importProfileFromRelays(opts) {
130
154
  sourceRelay: bestEvent.relay
131
155
  };
132
156
  }
133
- if (typeof parsedContent !== "object" || parsedContent === null || Array.isArray(parsedContent)) return {
134
- ok: false,
135
- error: "Profile event content must be a JSON object",
136
- relaysQueried,
137
- sourceRelay: bestEvent.relay
138
- };
139
- const sanitizedProfile = sanitizeProfileUrls(contentToProfile(parsedContent));
140
- const validatedProfile = NostrProfileSchema.safeParse(sanitizedProfile);
141
- if (!validatedProfile.success) return {
142
- ok: false,
143
- error: "Profile event content has invalid fields",
144
- relaysQueried,
145
- sourceRelay: bestEvent.relay
146
- };
147
157
  return {
148
158
  ok: true,
149
- profile: validatedProfile.data,
159
+ profile: sanitizeProfileUrls(contentToProfile(content)),
150
160
  event: {
151
161
  id: bestEvent.event.id,
152
162
  pubkey: bestEvent.event.pubkey,
@@ -156,8 +166,7 @@ async function importProfileFromRelays(opts) {
156
166
  sourceRelay: bestEvent.relay
157
167
  };
158
168
  } finally {
159
- if (deadlineTimer) clearTimeout(deadlineTimer);
160
- for (const subscription of subscriptions) subscription.close();
169
+ for (const timer of timers) clearTimeout(timer);
161
170
  pool.close(relays);
162
171
  }
163
172
  }
@@ -208,7 +217,7 @@ function sendJson(res, status, body) {
208
217
  res.setHeader("Content-Type", "application/json; charset=utf-8");
209
218
  res.end(JSON.stringify(body));
210
219
  }
211
- async function readJsonBody(req, maxBytes = 64 * 1024, timeoutMs = 3e4) {
220
+ async function readJsonBody(req, maxBytes = 65536, timeoutMs = 3e4) {
212
221
  const result = await readJsonBodyWithLimit(req, {
213
222
  maxBytes,
214
223
  timeoutMs,
@@ -234,7 +243,9 @@ function isLoopbackRemoteAddress(remoteAddress) {
234
243
  }
235
244
  function isLoopbackOriginLike(value) {
236
245
  try {
237
- return isLoopbackHost(new URL(value).hostname);
246
+ const url = new URL(value);
247
+ const hostname = normalizeLowercaseStringOrEmpty(url.hostname);
248
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
238
249
  } catch {
239
250
  return false;
240
251
  }
@@ -1,2 +1,2 @@
1
- import { n as nostrPlugin } from "./channel-O6-jXoT5.js";
1
+ import { n as nostrPlugin } from "./.setup/channel-B4SX7Iq6.mjs";
2
2
  export { nostrPlugin };
@@ -1,4 +1,4 @@
1
- import { t as normalizeNostrStateAccountId } from "./state-account-id-CvBZ9s6P.js";
1
+ import { t as normalizeNostrStateAccountId } from "./.setup/state-account-id-CvBZ9s6P.mjs";
2
2
  import fs from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import { archiveLegacyStateSource } from "openclaw/plugin-sdk/runtime-doctor";
@@ -51,7 +51,8 @@ async function listLegacyFiles(params) {
51
51
  const files = [];
52
52
  for (const entry of entries) {
53
53
  if (!entry.isFile() || !entry.name.startsWith(params.prefix) || !entry.name.endsWith(suffix)) continue;
54
- const accountId = normalizeNostrStateAccountId(entry.name.slice(params.prefix.length, -5));
54
+ const rawAccountId = entry.name.slice(params.prefix.length, -5);
55
+ const accountId = normalizeNostrStateAccountId(rawAccountId);
55
56
  const filePath = path.join(dir, entry.name);
56
57
  try {
57
58
  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-BJCFpe02.js";
1
+ import { n as nostrSetupWizard, t as nostrSetupAdapter } from "./.setup/setup-surface-DWa6-9ku.mjs";
2
2
  export { nostrSetupAdapter, nostrSetupWizard };
@@ -1,9 +1,10 @@
1
1
  import { defineBundledChannelSetupEntry } from "openclaw/plugin-sdk/channel-entry-contract";
2
+ import { fileURLToPath } from "node:url";
2
3
  //#region extensions/nostr/setup-entry.ts
3
4
  var setup_entry_default = defineBundledChannelSetupEntry({
4
5
  importMetaUrl: import.meta.url,
5
6
  plugin: {
6
- specifier: "./setup-plugin-api.js",
7
+ specifier: fileURLToPath(new URL(".setup/setup-plugin-api-DzlCumkz.mjs", import.meta.url).href),
7
8
  exportName: "nostrSetupPlugin"
8
9
  }
9
10
  });