Skip to content

Commit

Permalink
feat: add beforeHandleEvent hook
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyTseng committed Sep 9, 2024
1 parent 29bc2c4 commit 69063b6
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 194 deletions.
36 changes: 26 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ Example:
```typescript
import { HandleMessagePlugin } from '@nostr-relay/common';

// message logger plugin
class MessageLoggerPlugin implements HandleMessagePlugin {
async handleMessage(ctx, message, next) {
const startTime = Date.now();
Expand All @@ -89,21 +88,38 @@ class MessageLoggerPlugin implements HandleMessagePlugin {
}
}

// blacklist plugin
class BlacklistPlugin implements HandleMessagePlugin {
blacklist = [
relay.register(new MessageLoggerPlugin());
```

### beforeHandleEvent

This method will be called before handling an event. If the method returns false, the event will be ignored.

params:

- `ctx`: The context object of the client.
- `event`: The incoming event.

Example:

```typescript
import { HandleMessagePlugin } from '@nostr-relay/common';

class BlacklistGuardPlugin implements BeforeHandleEventPlugin {
private blacklist = [
// ...
];

async handleMessage(ctx, message, next) {
if (message[0] === 'EVENT' && blacklist.includes(message[1].pubkey)) {
return;
}
return next();
beforeHandleEvent(_, event) {
const canHandle = !this.blacklist.includes(event.pubkey);
return {
canHandle,
message: canHandle ? undefined : 'block: you are blacklisted',
};
}
}

relay.register(new MessageLoggerPlugin(), new BlacklistPlugin());
relay.register(new BlacklistGuardPlugin());
```

### broadcast
Expand Down
73 changes: 55 additions & 18 deletions packages/common/src/interfaces/plugin.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,31 @@ import { Event } from './event.interface';
import { HandleMessageResult } from './handle-result.interface';
import { IncomingMessage } from './message.interface';

export type NostrRelayPlugin = HandleMessagePlugin | BroadcastPlugin;
/**
* The result of the `beforeHandleEvent` method.
*/
export type BeforeHandleEventResult = {
/**
* If the event should be handled. If the value is false, the event will be ignored.
*/
canHandle: boolean;

/**
* The message to send to the client if the event is ignored.
*/
message?: string;
};

export type NostrRelayPlugin =
| HandleMessagePlugin
| BeforeHandleEventPlugin
| BroadcastPlugin;

/**
* A plugin that will be called when a new message is received from a client.
* The plugin implement this interface will be called when a new message is received from a client.
*
* @example
* ```ts
* // message logger plugin
* class MessageLoggerPlugin implements HandleMessagePlugin {
* async handleMessage(ctx, message, next) {
* const startTime = Date.now();
Expand All @@ -20,20 +37,6 @@ export type NostrRelayPlugin = HandleMessagePlugin | BroadcastPlugin;
* return result;
* }
* }
*
* // blacklist plugin
* class BlacklistPlugin implements HandleMessagePlugin {
* blacklist = [
* // ...
* ];
*
* async handleMessage(ctx, message, next) {
* if (message[0] === 'EVENT' && blacklist.includes(message[1].pubkey)) {
* return;
* }
* return next();
* }
* }
* ```
*/
export interface HandleMessagePlugin {
Expand All @@ -52,7 +55,41 @@ export interface HandleMessagePlugin {
}

/**
* A plugin that will be called when an event is broadcasted.
* The plugin implement this interface will be called before handling an event.
* You can use this interface to implement a guard for events.
*
* @example
* ```ts
* class BlacklistGuardPlugin implements BeforeHandleEventPlugin {
* private blacklist = [
* // ...
* ];
*
* beforeHandleEvent(_, event) {
* const canHandle = !this.blacklist.includes(event.pubkey);
* return {
* canHandle,
* message: canHandle ? undefined : 'block: you are blacklisted',
* };
* }
* }
* ```
*/
export interface BeforeHandleEventPlugin {
/**
* This method will be called before handling an event.
*
* @param ctx The client context
* @param event The event will be handled
*/
beforeHandleEvent(
ctx: ClientContext,
event: Event,
): Promise<BeforeHandleEventResult> | BeforeHandleEventResult;
}

/**
* The plugin implement this interface will be called when an event is broadcasted.
*
* @example
* ```ts
Expand Down
Loading

0 comments on commit 69063b6

Please sign in to comment.