Files
clawdbot/extensions/nostr/src/config-schema.ts
2026-01-20 20:15:56 +00:00

88 lines
2.3 KiB
TypeScript

import { z } from "zod";
import { buildChannelConfigSchema } from "clawdbot/plugin-sdk";
const allowFromEntry = z.union([z.string(), z.number()]);
/**
* Validates https:// URLs only (no javascript:, data:, file:, etc.)
*/
const safeUrlSchema = z
.string()
.url()
.refine(
(url) => {
try {
const parsed = new URL(url);
return parsed.protocol === "https:";
} catch {
return false;
}
},
{ message: "URL must use https:// protocol" }
);
/**
* NIP-01 profile metadata schema
* https://github.com/nostr-protocol/nips/blob/master/01.md
*/
export const NostrProfileSchema = z.object({
/** Username (NIP-01: name) - max 256 chars */
name: z.string().max(256).optional(),
/** Display name (NIP-01: display_name) - max 256 chars */
displayName: z.string().max(256).optional(),
/** Bio/description (NIP-01: about) - max 2000 chars */
about: z.string().max(2000).optional(),
/** Profile picture URL (must be https) */
picture: safeUrlSchema.optional(),
/** Banner image URL (must be https) */
banner: safeUrlSchema.optional(),
/** Website URL (must be https) */
website: safeUrlSchema.optional(),
/** NIP-05 identifier (e.g., "user@example.com") */
nip05: z.string().optional(),
/** Lightning address (LUD-16) */
lud16: z.string().optional(),
});
export type NostrProfile = z.infer<typeof NostrProfileSchema>;
/**
* Zod schema for channels.nostr.* configuration
*/
export const NostrConfigSchema = z.object({
/** Account name (optional display name) */
name: z.string().optional(),
/** Whether this channel is enabled */
enabled: z.boolean().optional(),
/** Private key in hex or nsec bech32 format */
privateKey: z.string().optional(),
/** WebSocket relay URLs to connect to */
relays: z.array(z.string()).optional(),
/** DM access policy: pairing, allowlist, open, or disabled */
dmPolicy: z.enum(["pairing", "allowlist", "open", "disabled"]).optional(),
/** Allowed sender pubkeys (npub or hex format) */
allowFrom: z.array(allowFromEntry).optional(),
/** Profile metadata (NIP-01 kind:0 content) */
profile: NostrProfileSchema.optional(),
});
export type NostrConfig = z.infer<typeof NostrConfigSchema>;
/**
* JSON Schema for Control UI (converted from Zod)
*/
export const nostrChannelConfigSchema = buildChannelConfigSchema(NostrConfigSchema);