Policy List ​
Below are the policies shipped with Nostrify.
AntiDuplicationPolicy ​
Prevent messages with the exact same content from being submitted repeatedly.
It uses Deno KV to track repeated messages.
import { AntiDuplicationPolicy } from '@nostrify/policies';
const kv = await Deno.openKv();
// Reject messages with the same content within 60 seconds.
const policy = new AntiDuplicationPolicy({ kv, expireIn: 60000, minLength: 50 });
Options ​
kv
: A Deno KV instance.expireIn
: The time in milliseconds before a message with this content can be submitted again (since the last time it was posted).minLength
: The minimum length of a message to be considered for deduplication.
AnyPolicy ​
A type of pipeline policy that passes an event if any of its sub-policies pass.
import { AnyPolicy } from '@nostrify/policies';
// Block Telegram links unless there is sufficient proof-of-work.
const policy = new AnyPolicy([
new KeywordPolicy(['https://t.me/']),
new PowPolicy({ difficulty: 5 }),
]);
DomainPolicy ​
Filters events by the author's NIP-05 domain.
The policy requires event authors to have a kind 0 event with a valid nip05
property. The first argument is an NStore
instance used to retrieve the kind 0.
import { DomainPolicy } from '@nostrify/policies';
const policy = new DomainPolicy(store, {
blacklist: ['replyguy.dev', 'ethereum.xyz'],
});
Options ​
blacklist
: An array of domains to reject.whitelist
: If provided, only events from these domains are accepted.lookup
: Custom NIP-05 lookup function.
FiltersPolicy ​
Reject events that don't match the filters.
import { FiltersPolicy } from '@nostrify/policies';
// Only accept events with kinds 0, 1, 3, 5, 6, or 7.
const policy = new FiltersPolicy([{ kinds: [0, 1, 3, 5, 6, 7] }]);
HashtagPolicy ​
Reject events containing any of the banned hashtags.
import { HashtagPolicy } from '@nostrify/policies';
// Reject events containing 'nsfw'.
const policy = new HashtagPolicy(['nsfw']);
HellthreadPolicy ​
Reject messages that tag too many participants.
This rule only affects kind 1 text notes, and it counts the number of "p" tags.
import { HellthreadPolicy } from '@nostrify/policies';
// Reject kind 1 events with more than 15 "p" tags.
const policy = new HellthreadPolicy({ limit: 15 });
Options ​
limit
: The maximum number of "p" tags that can be on kind 1 events.
InvertPolicy ​
Inverts the result of another policy.
The second parameter is the message to return if the policy rejects the event.
import { InvertPolicy } from '@nostrify/policies';
// Reject events unless they contain 'moo'.
const policy = new InvertPolicy(
new KeywordPolicy(['moo']),
'blocked: event did not contain "moo"'
);
KeywordPolicy ​
Reject events containing any of the strings in its content.
import { KeywordPolicy } from '@nostrify/policies';
// Reject events containing 'moo', 'oink', or 'honk'.
const policy = new KeywordPolicy(['moo', 'oink', 'honk']);
NoOpPolicy ​
Minimal sample policy for demonstration purposes. Allows all events through.
import { NoOpPolicy } from '@nostrify/policies';
const policy = new NoOpPolicy();
OpenAIPolicy ​
Sends event content to OpenAI's Moderations API and then rejects flagged events.
import { OpenAIPolicy } from '@nostrify/policies';
// Reject events with a high toxicity score.
const policy = new OpenAIPolicy({ apiKey: Deno.env.get('OPENAI_API_KEY') });
You can also provide a custom handler for more fine-grained control.
new OpenAIPolicy({
apiKey: Deno.env.get('OPENAI_API_KEY'),
handler(event, data) {
// Loop each result.
return data.results.some((result) => {
if (result.flagged) {
const { sexual, violence } = result.categories;
// Reject only events flagged as sexual and violent.
return sexual && violence;
}
});
},
});
Options ​
apiKey
: Your OpenAI API key.handler
: Custom handler to process the OpenAI response. Rejects the event if the handler returnstrue
.endpoint
: Custom endpoint to use instead ofhttps://api.openai.com/v1/moderations
.fetch
: Custom fetch implementation.timeout
: Timeout in milliseconds for each fetch request.kinds
: Array of kinds to apply the policy to.
PipePolicy ​
Compose multiple policies into a single policy.
It is a type of pipeline policy.
import {
AntiDuplicationPolicy,
FiltersPolicy,
HellthreadPolicy,
PipePolicy,
PubkeyBanPolicy,
} from '@nostrify/policies';
// Reject messages unless they pass all policies.
const policy = new PipePolicy([
new FiltersPolicy([{ kinds: [0, 1, 3, 5, 7, 1984, 9734, 9735, 10002] }]),
new PubkeyBanPolicy(['e810fafa1e89cdf80cced8e013938e87e21b699b24c8570537be92aec4b12c18']),
new HellthreadPolicy({ limit: 100 }),
new AntiDuplicationPolicy({ kv: await Deno.openKv(), expireIn: 60000, minLength: 50 }),
]);
PowPolicy ​
Reject events which don't meet Proof-of-Work (NIP-13) criteria.
import { PowPolicy } from '@nostrify/policies';
// Require events to have proof-of-work of at least 10.
const policy = new PowPolicy({ difficulty: 10 });
Options ​
difficulty
: The minimum difficulty required for the event to pass.
PubkeyBanPolicy ​
Ban events from specific pubkeys.
import { PubkeyBanPolicy } from '@nostrify/policies';
// Reject events from these pubkeys.
const policy = new PubkeyBanPolicy(['e810...', 'fafa...', '1e89...']);
ReadOnlyPolicy ​
This policy rejects all messages.
import { ReadOnlyPolicy } from '@nostrify/policies';
const policy = new ReadOnlyPolicy();
RegexPolicy ​
Reject events whose content matches the regex.
import { RegexPolicy } from '@nostrify/policies';
// Reject events containing '🟠', '🔥', or '😳' followed by 'ChtaGPT'.
const policy = new RegexPolicy(/(🟠|🔥|😳)ChtaGPT/i);
SizePolicy ​
Reject events that are too large.
import { SizePolicy } from '@nostrify/policies';
// Reject events larger than 8 Kb.
const policy = new SizePolicy({ maxBytes: 8 * 1024 });
WhitelistPolicy ​
Allows only the listed pubkeys to post to the relay. All other events are rejected.
import { WhitelistPolicy } from '@nostrify/policies';
// Only allow events from these pubkeys.
const policy = new WhitelistPolicy(['e810...', 'fafa...', '1e89...']);