Files
openclaw/extensions/nostr/index.ts
Pavan Kumar Gondhi 6517c700de fix(nostr): require operator.admin scope for profile mutation routes [AI] (#63553)
* fix: address issue

* fix: address review feedback

* fix: address review feedback

* fix: finalize issue changes

* fix: address PR review feedback

* fix: address review-pr skill feedback

* fix: address PR review feedback

* fix: address review-pr skill feedback

* fix: address PR review feedback

* fix: address PR review feedback

* fix: address PR review feedback

* fix: address PR review feedback

* docs: add changelog entry for PR merge
2026-04-10 16:38:41 +05:30

95 lines
2.7 KiB
TypeScript

import {
defineBundledChannelEntry,
loadBundledEntryExportSync,
} from "openclaw/plugin-sdk/channel-entry-contract";
import type { PluginRuntime, ResolvedNostrAccount } from "./api.js";
function createNostrProfileHttpHandler() {
return loadBundledEntryExportSync<
(params: Record<string, unknown>) => (ctx: unknown) => Promise<void> | void
>(import.meta.url, {
specifier: "./api.js",
exportName: "createNostrProfileHttpHandler",
});
}
function getNostrRuntime() {
return loadBundledEntryExportSync<() => PluginRuntime>(import.meta.url, {
specifier: "./api.js",
exportName: "getNostrRuntime",
})();
}
function resolveNostrAccount(params: { cfg: unknown; accountId: string }) {
return loadBundledEntryExportSync<
(params: { cfg: unknown; accountId: string }) => ResolvedNostrAccount
>(import.meta.url, {
specifier: "./api.js",
exportName: "resolveNostrAccount",
})(params);
}
export default defineBundledChannelEntry({
id: "nostr",
name: "Nostr",
description: "Nostr DM channel plugin via NIP-04",
importMetaUrl: import.meta.url,
plugin: {
specifier: "./api.js",
exportName: "nostrPlugin",
},
runtime: {
specifier: "./api.js",
exportName: "setNostrRuntime",
},
registerFull(api) {
const httpHandler = createNostrProfileHttpHandler()({
getConfigProfile: (accountId: string) => {
const runtime = getNostrRuntime();
const cfg = runtime.config.loadConfig();
const account = resolveNostrAccount({ cfg, accountId });
return account.profile;
},
updateConfigProfile: async (accountId: string, profile: unknown) => {
const runtime = getNostrRuntime();
const cfg = runtime.config.loadConfig();
const channels = (cfg.channels ?? {}) as Record<string, unknown>;
const nostrConfig = (channels.nostr ?? {}) as Record<string, unknown>;
await runtime.config.writeConfigFile({
...cfg,
channels: {
...channels,
nostr: {
...nostrConfig,
profile,
},
},
});
},
getAccountInfo: (accountId: string) => {
const runtime = getNostrRuntime();
const cfg = runtime.config.loadConfig();
const account = resolveNostrAccount({ cfg, accountId });
if (!account.configured || !account.publicKey) {
return null;
}
return {
pubkey: account.publicKey,
relays: account.relays,
};
},
log: api.logger,
});
api.registerHttpRoute({
path: "/api/channels/nostr",
auth: "gateway",
match: "prefix",
gatewayRuntimeScopeSurface: "trusted-operator",
handler: httpHandler,
});
},
});