@openclaw/nostr 2026.5.2 → 2026.5.3-beta.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 (59) hide show
  1. package/dist/api.js +532 -0
  2. package/dist/channel-DfEqBtUh.js +1466 -0
  3. package/dist/channel-plugin-api.js +2 -0
  4. package/dist/config-schema-DIk4jlBg.js +64 -0
  5. package/dist/default-relays-DLwdWOTu.js +4 -0
  6. package/dist/inbound-direct-dm-runtime-22bZWcIW.js +2 -0
  7. package/dist/index.js +84 -0
  8. package/dist/runtime-api.js +2 -0
  9. package/dist/setup-api.js +2 -0
  10. package/dist/setup-entry.js +11 -0
  11. package/dist/setup-plugin-api.js +165 -0
  12. package/dist/setup-surface-DxAaUTyC.js +336 -0
  13. package/dist/test-api.js +2 -0
  14. package/package.json +15 -6
  15. package/api.ts +0 -10
  16. package/channel-plugin-api.ts +0 -1
  17. package/index.ts +0 -97
  18. package/runtime-api.ts +0 -6
  19. package/setup-api.ts +0 -1
  20. package/setup-entry.ts +0 -9
  21. package/setup-plugin-api.ts +0 -3
  22. package/src/channel-api.ts +0 -15
  23. package/src/channel.inbound.test.ts +0 -176
  24. package/src/channel.outbound.test.ts +0 -128
  25. package/src/channel.setup.ts +0 -231
  26. package/src/channel.test.ts +0 -519
  27. package/src/channel.ts +0 -207
  28. package/src/config-schema.ts +0 -98
  29. package/src/default-relays.ts +0 -1
  30. package/src/gateway.ts +0 -302
  31. package/src/inbound-direct-dm-runtime.ts +0 -1
  32. package/src/metrics.ts +0 -458
  33. package/src/nostr-bus.fuzz.test.ts +0 -360
  34. package/src/nostr-bus.inbound.test.ts +0 -526
  35. package/src/nostr-bus.integration.test.ts +0 -472
  36. package/src/nostr-bus.test.ts +0 -190
  37. package/src/nostr-bus.ts +0 -789
  38. package/src/nostr-key-utils.ts +0 -94
  39. package/src/nostr-profile-core.ts +0 -134
  40. package/src/nostr-profile-http-runtime.ts +0 -6
  41. package/src/nostr-profile-http.test.ts +0 -632
  42. package/src/nostr-profile-http.ts +0 -594
  43. package/src/nostr-profile-import.test.ts +0 -119
  44. package/src/nostr-profile-import.ts +0 -262
  45. package/src/nostr-profile-url-safety.ts +0 -21
  46. package/src/nostr-profile.fuzz.test.ts +0 -430
  47. package/src/nostr-profile.test.ts +0 -412
  48. package/src/nostr-profile.ts +0 -144
  49. package/src/nostr-state-store.test.ts +0 -237
  50. package/src/nostr-state-store.ts +0 -223
  51. package/src/runtime.ts +0 -9
  52. package/src/seen-tracker.ts +0 -289
  53. package/src/session-route.ts +0 -25
  54. package/src/setup-surface.ts +0 -265
  55. package/src/test-fixtures.ts +0 -45
  56. package/src/types.ts +0 -117
  57. package/test/setup.ts +0 -5
  58. package/test-api.ts +0 -1
  59. package/tsconfig.json +0 -16
@@ -1,231 +0,0 @@
1
- import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
2
- import type { OpenClawConfig } from "openclaw/plugin-sdk/config-types";
3
- import { patchTopLevelChannelConfigSection } from "openclaw/plugin-sdk/setup";
4
- import {
5
- createDelegatedSetupWizardProxy,
6
- createStandardChannelSetupStatus,
7
- DEFAULT_ACCOUNT_ID,
8
- type ChannelSetupAdapter,
9
- } from "openclaw/plugin-sdk/setup-runtime";
10
- import { buildChannelConfigSchema, type ChannelPlugin } from "./channel-api.js";
11
- import { NostrConfigSchema } from "./config-schema.js";
12
- import { DEFAULT_RELAYS } from "./default-relays.js";
13
-
14
- const channel = "nostr" as const;
15
-
16
- type NostrAccountConfig = {
17
- enabled?: boolean;
18
- name?: string;
19
- defaultAccount?: string;
20
- privateKey?: unknown;
21
- relays?: string[];
22
- dmPolicy?: "pairing" | "allowlist" | "open" | "disabled";
23
- allowFrom?: Array<string | number>;
24
- profile?: unknown;
25
- };
26
-
27
- type ResolvedNostrSetupAccount = {
28
- accountId: string;
29
- name?: string;
30
- enabled: boolean;
31
- configured: boolean;
32
- privateKey: string;
33
- publicKey: string;
34
- relays: string[];
35
- profile?: unknown;
36
- config: NostrAccountConfig;
37
- };
38
-
39
- function getNostrConfig(cfg: OpenClawConfig): NostrAccountConfig | undefined {
40
- return (cfg.channels as Record<string, unknown> | undefined)?.nostr as
41
- | NostrAccountConfig
42
- | undefined;
43
- }
44
-
45
- function listSetupNostrAccountIds(cfg: OpenClawConfig): string[] {
46
- const nostrCfg = getNostrConfig(cfg);
47
- const privateKey = typeof nostrCfg?.privateKey === "string" ? nostrCfg.privateKey.trim() : "";
48
- if (!privateKey) {
49
- return [];
50
- }
51
- return [resolveDefaultSetupNostrAccountId(cfg)];
52
- }
53
-
54
- function resolveDefaultSetupNostrAccountId(cfg: OpenClawConfig): string {
55
- const configured = getNostrConfig(cfg)?.defaultAccount;
56
- return typeof configured === "string" && configured.trim()
57
- ? configured.trim()
58
- : DEFAULT_ACCOUNT_ID;
59
- }
60
-
61
- function resolveSetupNostrAccount(params: {
62
- cfg: OpenClawConfig;
63
- accountId?: string | null;
64
- }): ResolvedNostrSetupAccount {
65
- const nostrCfg = getNostrConfig(params.cfg);
66
- const accountId = params.accountId?.trim() || resolveDefaultSetupNostrAccountId(params.cfg);
67
- const privateKey = typeof nostrCfg?.privateKey === "string" ? nostrCfg.privateKey.trim() : "";
68
- const configured = Boolean(privateKey);
69
- return {
70
- accountId,
71
- name: typeof nostrCfg?.name === "string" ? nostrCfg.name : undefined,
72
- enabled: nostrCfg?.enabled !== false,
73
- configured,
74
- privateKey,
75
- publicKey: "",
76
- relays: nostrCfg?.relays ?? DEFAULT_RELAYS,
77
- profile: nostrCfg?.profile,
78
- config: {
79
- enabled: nostrCfg?.enabled,
80
- name: nostrCfg?.name,
81
- privateKey: nostrCfg?.privateKey,
82
- relays: nostrCfg?.relays,
83
- dmPolicy: nostrCfg?.dmPolicy,
84
- allowFrom: nostrCfg?.allowFrom,
85
- profile: nostrCfg?.profile,
86
- },
87
- };
88
- }
89
-
90
- function buildNostrSetupPatch(accountId: string, patch: Record<string, unknown>) {
91
- return {
92
- ...(accountId !== DEFAULT_ACCOUNT_ID ? { defaultAccount: accountId } : {}),
93
- ...patch,
94
- };
95
- }
96
-
97
- function parseRelayUrls(raw: string): { relays: string[]; error?: string } {
98
- const entries = raw
99
- .split(/[,\n]/)
100
- .map((entry) => entry.trim())
101
- .filter(Boolean);
102
- const relays: string[] = [];
103
- for (const entry of entries) {
104
- try {
105
- const parsed = new URL(entry);
106
- if (parsed.protocol !== "ws:" && parsed.protocol !== "wss:") {
107
- return { relays: [], error: `Relay must use ws:// or wss:// (${entry})` };
108
- }
109
- } catch {
110
- return { relays: [], error: `Invalid relay URL: ${entry}` };
111
- }
112
- relays.push(entry);
113
- }
114
- return { relays: [...new Set(relays)] };
115
- }
116
-
117
- function looksLikeNostrPrivateKey(privateKey: string): boolean {
118
- return privateKey.startsWith("nsec1") || /^[0-9a-fA-F]{64}$/.test(privateKey);
119
- }
120
-
121
- const nostrSetupAdapter: ChannelSetupAdapter = {
122
- resolveAccountId: ({ cfg, accountId }) =>
123
- accountId?.trim() || resolveDefaultSetupNostrAccountId(cfg),
124
- applyAccountName: ({ cfg, accountId, name }) =>
125
- patchTopLevelChannelConfigSection({
126
- cfg,
127
- channel,
128
- patch: buildNostrSetupPatch(accountId, name?.trim() ? { name: name.trim() } : {}),
129
- }),
130
- validateInput: ({ input }) => {
131
- const typedInput = input as {
132
- useEnv?: boolean;
133
- privateKey?: string;
134
- relayUrls?: string;
135
- };
136
- if (!typedInput.useEnv) {
137
- const privateKey = typedInput.privateKey?.trim();
138
- if (!privateKey) {
139
- return "Nostr requires --private-key or --use-env.";
140
- }
141
- if (!looksLikeNostrPrivateKey(privateKey)) {
142
- return "Nostr private key must be valid nsec or 64-character hex.";
143
- }
144
- }
145
- if (typedInput.relayUrls?.trim()) {
146
- return parseRelayUrls(typedInput.relayUrls).error ?? null;
147
- }
148
- return null;
149
- },
150
- applyAccountConfig: ({ cfg, accountId, input }) => {
151
- const typedInput = input as {
152
- useEnv?: boolean;
153
- privateKey?: string;
154
- relayUrls?: string;
155
- };
156
- const relayResult = typedInput.relayUrls?.trim()
157
- ? parseRelayUrls(typedInput.relayUrls)
158
- : { relays: [] };
159
- return patchTopLevelChannelConfigSection({
160
- cfg,
161
- channel,
162
- enabled: true,
163
- clearFields: typedInput.useEnv ? ["privateKey"] : undefined,
164
- patch: buildNostrSetupPatch(accountId, {
165
- ...(typedInput.useEnv ? {} : { privateKey: typedInput.privateKey?.trim() }),
166
- ...(relayResult.relays.length > 0 ? { relays: relayResult.relays } : {}),
167
- }),
168
- });
169
- },
170
- };
171
-
172
- const nostrSetupWizard = createDelegatedSetupWizardProxy({
173
- channel,
174
- loadWizard: async () => (await import("./setup-surface.js")).nostrSetupWizard,
175
- status: {
176
- ...createStandardChannelSetupStatus({
177
- channelLabel: "Nostr",
178
- configuredLabel: "configured",
179
- unconfiguredLabel: "needs private key",
180
- configuredHint: "configured",
181
- unconfiguredHint: "needs private key",
182
- configuredScore: 1,
183
- unconfiguredScore: 0,
184
- includeStatusLine: true,
185
- resolveConfigured: ({ cfg, accountId }) =>
186
- resolveSetupNostrAccount({ cfg, accountId }).configured,
187
- resolveExtraStatusLines: ({ cfg }) => {
188
- const account = resolveSetupNostrAccount({ cfg });
189
- return [`Relays: ${account.relays.length || DEFAULT_RELAYS.length}`];
190
- },
191
- }),
192
- },
193
- resolveShouldPromptAccountIds: () => false,
194
- delegatePrepare: true,
195
- delegateFinalize: true,
196
- });
197
-
198
- export const nostrSetupPlugin: ChannelPlugin<ResolvedNostrSetupAccount> = {
199
- id: channel,
200
- meta: {
201
- id: channel,
202
- label: "Nostr",
203
- selectionLabel: "Nostr",
204
- docsPath: "/channels/nostr",
205
- docsLabel: "nostr",
206
- blurb: "Decentralized DMs via Nostr relays (NIP-04)",
207
- order: 100,
208
- },
209
- capabilities: {
210
- chatTypes: ["direct"],
211
- media: false,
212
- },
213
- reload: { configPrefixes: ["channels.nostr"] },
214
- configSchema: buildChannelConfigSchema(NostrConfigSchema),
215
- setup: nostrSetupAdapter,
216
- setupWizard: nostrSetupWizard,
217
- config: {
218
- listAccountIds: listSetupNostrAccountIds,
219
- resolveAccount: (cfg, accountId) => resolveSetupNostrAccount({ cfg, accountId }),
220
- defaultAccountId: resolveDefaultSetupNostrAccountId,
221
- isConfigured: (account) => account.configured,
222
- describeAccount: (account) =>
223
- describeAccountSnapshot({
224
- account,
225
- configured: account.configured,
226
- extra: {
227
- publicKey: account.publicKey,
228
- },
229
- }),
230
- },
231
- };