Skip to content

Commit

Permalink
use nostrify
Browse files Browse the repository at this point in the history
  • Loading branch information
shuesken committed Aug 10, 2024
1 parent 084cd7e commit d70e2ca
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 78 deletions.
3 changes: 0 additions & 3 deletions common/constants.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import { nostrTools } from "../deps.ts";
type Kind = nostrTools.Kind;

export const PRIVATE_KEY_STORAGE_KEY = "__nostrPrivateKey" as const;
export const RELAYS_STORAGE_KEY = "__nostrRelays" as const;
export const PLUS_CODE_TAG_KEY = "l" as const;
Expand Down
3 changes: 3 additions & 0 deletions deno.jsonc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"tasks": {
"run": "deno run --allow-net --allow-env main.ts"
},
"imports": {
"@nostrify/nostrify": "jsr:@nostrify/nostrify@^0.30.0"
}
}
78 changes: 77 additions & 1 deletion deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions deps.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * as nostrToolsRelay from "npm:nostr-tools/relay";
export * as nostrTools from "npm:nostr-tools";
export * as cliffy from "https://deno.land/x/[email protected]/mod.ts";
export * as nostrify from "@nostrify/nostrify";
104 changes: 58 additions & 46 deletions validation/repost.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { nostrToolsRelay } from "../deps.ts";
const { Relay } = nostrToolsRelay;

import { nostrTools } from "../deps.ts";
const { finalizeEvent } = nostrTools;
type Event = nostrTools.Event;
type EventTemplate = nostrTools.EventTemplate;
type VerifiedEvent = nostrTools.VerifiedEvent;
import { nostrify } from "../deps.ts";
const { NPool, NRelay1, NSecSigner } = nostrify;
type Tags = string[][];

import {
Expand All @@ -16,31 +10,48 @@ import {
} from "../common/constants.ts";
import { DEV_PUBKEY } from "../common/constants.ts";
import { validateEvent } from "./validate.ts";
import { NSet } from "@nostrify/nostrify";

async function getRelay(
isDev: true | undefined
): Promise<nostrToolsRelay.Relay> {
const relayUrl = isDev ? DEV_RELAYS[0] : DEFAULT_RELAYS[0];
async function getRelayPool(isDev: true | undefined) {
const relays = isDev ? DEV_RELAYS : DEFAULT_RELAYS;

console.log(`#nadQka Connecting to ${relayUrl}`);
const relay = await Relay.connect(relayUrl);
console.log(`#CmJWu4 Connected to ${relay.url}`);
return relay;
// should be chosen according to outbox model
// https://nostrify.dev/relay/outbox
const pool = new NPool({
open(url) {
return new NRelay1(url);
},
async reqRouter(filter: nostrify.NostrFilter[]) {
const map = new Map();
relays.map((relay) => {
map.set(relay, filter);
});
return map;
},
async eventRouter(_event) {
return relays;
},
});

return pool;
}

async function publishEvent(
relay: nostrToolsRelay.Relay,
event: VerifiedEvent
relayPool: nostrify.NPool,
event: nostrify.NostrEvent
) {
console.log("Publishing event…");
await relay.publish(event);
await relayPool.event(event);
console.log("Event published.");
}

/**
* Take a nostr event that was signed by a user and generate the repost event.
*/
function generateRepostedEvent(originalEvent: Event, privateKey: Uint8Array) {
async function generateRepostedEvent(
originalEvent: nostrify.NostrEvent,
privateKey: Uint8Array
) {
const derivedTags = deriveTags(originalEvent);
const derivedContent = deriveContent(originalEvent);
const dTag = ["d", `${originalEvent.pubkey}:${originalEvent.id}`];
Expand All @@ -51,21 +62,22 @@ function generateRepostedEvent(originalEvent: Event, privateKey: Uint8Array) {
`${originalEvent.created_at}`,
];

const eventTemplate: EventTemplate = {
const signer = new NSecSigner(privateKey);
const eventTemplate = {
kind: MAP_NOTE_REPOST_KIND,
created_at: Math.floor(Date.now() / 1000),
tags: [eTag, pTag, dTag, originalCreatedAtTag, ...derivedTags],
content: derivedContent,
};
const signedEvent = finalizeEvent(eventTemplate, privateKey);
const signedEvent = await signer.signEvent(eventTemplate);
return signedEvent;
}

function deriveTags(event: Event): Tags {
function deriveTags(event: nostrify.NostrEvent): Tags {
return event.tags;
}

function deriveContent(event: Event): string {
function deriveContent(event: nostrify.NostrEvent): string {
return event.content;
}

Expand All @@ -75,51 +87,51 @@ function deriveContent(event: Event): string {
function createFilter(
isDev: true | undefined,
maxAgeMinutes: number | undefined
): nostrTools.Filter {
): nostrify.NostrFilter[] {
const maxAgeSeconds =
typeof maxAgeMinutes === "undefined" ? 60 * 60 : maxAgeMinutes * 60;

const baseFilter: nostrTools.Filter = {
const baseFilter: nostrify.NostrFilter = {
kinds: [MAP_NOTE_KIND],
since: Math.floor(Date.now() / 1e3) - maxAgeSeconds,
};

if (isDev) {
return { ...baseFilter, authors: [DEV_PUBKEY] };
return [{ ...baseFilter, authors: [DEV_PUBKEY] }];
}

return baseFilter;
return [baseFilter];
}

export async function repost(
privateKey: Uint8Array,
isDev: true | undefined,
maxAgeMinutes: number | undefined
) {
const relay = await getRelay(isDev);
const relayPool = await getRelayPool(isDev);

const filter = createFilter(isDev, maxAgeMinutes);

const oneose = isDev
? () => {
globalThis.setTimeout(() => {
relay.close();
}, 10e3);
}
: () => {};

const sub = relay.subscribe([filter], {
onevent: async (event) => {
console.log("#9wKiBL Got event", event);
const controller = new AbortController();
const signal = controller.signal;
const subscription = relayPool.req(filter, { signal });

const isEventValid = await validateEvent(relay, event);
for await (const msg of subscription) {
if (msg[0] === "EVENT") {
const event = msg[2];
const isEventValid = await validateEvent(relayPool, event);
if (!isEventValid) {
console.info(`Discarding event…`);
return;
}
const repostedEvent = generateRepostedEvent(event, privateKey);
publishEvent(relay, repostedEvent);
},
oneose,
});
const repostedEvent = await generateRepostedEvent(event, privateKey);
publishEvent(relayPool, repostedEvent);
} else if (msg[0] === "EOSE") {
if (isDev) {
globalThis.setTimeout(() => {
controller.abort();
}, 10e3);
}
}
}
}
Loading

0 comments on commit d70e2ca

Please sign in to comment.