Skip to content

Event Factory

The EventFactory is a class is used to provide a Signer and relay hints to the blueprints

Creating a factory

When creating a new event factory you can pass a context object in that is used by all blueprints

ts
const signer = new SimpleSigner();

const factory = new EventFactory({
  // optionally pass a signer in (required for encryption)
  signer: signer,
  // optionally set a NIP-89 client
  client: {
    name: "My Awesome Client",
    address: {
      pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
      identifier: "awesome-client",
    },
  },
});

Relay hints

Relay hints can ge added to all event tags that support them by passing in getEventRelayHint and getPubkeyRelayHint methods into the context

ts
const factory = new EventFactory({
  getEventRelayHint: async (event) => {
    // an async process to find the best relay hint for this event
    try {
      return await calculateRelayHint(event)
    }
    catch(){
      return undefined
    }
  },
  getPubkeyRelayHint: async (pubkey) => {
    // an async process to find a relay hint for this pubkey
    return loadPubkeyMailboxes(pubkey).then((mailboxes) => getOutboxes(mailboxes)[0]);
  },
});

Using a blueprint

The factory.create method can be used to create an event from a blueprint

ts
await factory.create(NoteBlueprint, "hello world");

Modifying an event

The EventFactory.modify and EventFactory.modifyTags methods can be used to modify replaceable events

The first method modify takes a list of EventOperations and is useful for modifying common properties of a list event like name, description, or image

js
const list = {
  kind: 30003,
  content: "",
  tags: [
    ["title", "read later"],
    ["description", "notes ill read later"],
  ],
};

const modified = await factory.modify(
  list,
  setListTitle("read never"),
  setListDescription("I will never get around to reading these notes"),
);

The second method modifyTags takes of list of TagOperations and is useful for modifying the public (or hidden) tags array of a replaceable event

For example, removing an e tag from a bookmark list

js
const list = {
  kind: 30003,
  content: "",
  tags: [
    ["d", "bookmarked-events"],
    ["e", "00004df629c94f844e1986ba6cd5e04ef26acc966f3af10eeb085221a71c951b"],
  ],
};

const modified = await factory.modifyTags(
  list,
  // pass tag operations in directly to modify public tags
  removeEventTag("00004df629c94f844e1986ba6cd5e04ef26acc966f3af10eeb085221a71c951b"),
);

Or adding an inbox relay to a NIP-65 mailboxes event

js
const mailboxes = {
  kind: 10002,
  content: "",
  tags: [["r", "wss://relay.io/", "read"]],
};

const modified = await factory.modifyTags(
  mailboxes,
  // will change the existing "r" tag to ["r, "wss://relay.io/"] (both read and write)
  addOutboxRelay("wss://relay.io/"),
  // will add a new ["r", "wss://nostr.wine/", "write"] tag
  addOutboxRelay("wss://nostr.wine/"),
);

It also supports modifying the "hidden" tags (encrypted tags array) in NIP-51 list events content

js
const list = {
  kind: 30003,
  content: "KRf3JTN1KcM0YduFfeHPoIXf+2H5fpdv02sU4CZ8zR0=?iv=zNnctFWMyU92HdpUl/XTOg==",
  tags: [["d", "28bn20gh82"]],
};

// add a signer to factory so it can decrypt
factory.context.signer = window.nostr;

// will attempt to decrypt "content" before modifying hidden tags
const modified = await factory.modifyTags(list, {
  hidden: [removeEventTag("00004df629c94f844e1986ba6cd5e04ef26acc966f3af10eeb085221a71c951b")],
});

Quick helper methods

The EventFactory class has a few helper methods on it for building common event types:

Manually creating an event

The factory.process method can be used to create an event from an EventTemplate and EventOperations

ts
import { includeSingletonTag, setContent, includeAltTag } from "applesauce-factory/operations";

await factory.process(
  { kind: 1063 },
  setContent("the bitcoin whitepaper"),
  includeAltTag("File metadata"),
  includeSingletonTag(["x", "b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553"]),
  includeSingletonTag(["size", "184292"]),
  includeSingletonTag(["m", "application/pdf"]),
  includeSingletonTag([
    "url",
    "https://cdn.example.com/b1674191a88ec5cdd733e4240a81803105dc412d6c6708d53ab94fc248f4f553.pdf",
  ]),
);

Prebuilt blueprints

The applesauce-factory package comes with common event blueprints for social clients. you can find them in the typescript docs