Why Nostr? What is Njump?
2025-02-21 17:56:42

hzrd149 on Nostr: The next version of applesauce packages are released Look over the documentation if ...

The next version of applesauce packages are released
Look over the documentation https://hzrd149.github.io/applesauce/ if your curious. and please don't hesitate to provide feedback or ask dumb questions

I’ve been working on the applesauce libraries for a while now but I think this release is the first one I would consider to be stable enough to use

A lot of the core concepts and classes are in place and stable enough where they wont change too much next release

If you want to skip straight to the documentation you can find at hzrd149.github.io/applesauce or the typescript docs at hzrd149.github.io/applesauce/typedoc

Whats new

Accounts

The applesauce-accounts package is an extension of the applesauce-signers package and provides classes for building a multi-account system for clients

Its primary features are

  • Serialize and deserialize accounts so they can be saved in local storage or IndexededDB
  • Account manager for multiple accounts and switching between them
  • Account metadata for things like labels, app settings, etc
  • Support for NIP-46 Nostr connect accounts

see documentation for more examples

Nostr connect signer

The NostrConnectSigner class from the applesauce-signers package is now in a stable state and has a few new features

  • Ability to create nostrconnect:// URIs and waiting for the remote signer to connect
  • SDK agnostic way of subscribing and publishing to relays

For a simple example, here is how to create a signer from a bunker:// URI

const signer = await NostrConnectSigner.fromBunkerURI(
  "bunker://266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5?relay=wss://relay.nsec.app&secret=d9aa70",
  {
    permissions: NostrConnectSigner.buildSigningPermissions([0, 1, 3, 10002]),
    async onSubOpen(filters, relays, onEvent) {
      // manually open REQ
    },
    async onSubClose() {
      // close previouse REQ
    },
    async onPublishEvent(event, relays) {
      // Pubilsh an event to relays
    },
  },
);

see documentation for more examples and other signers

Event Factory

The EventFactory class is probably what I’m most proud of. its a standalone class that can be used to create various types of events from templates (blueprints) and is really simple to use

For example:

import { EventFactory } from "applesauce-factory";
import { NoteBlueprint } from "applesauce-factory/blueprints";

const factory = new EventFactory({
  // optionally pass a NIP-07 signer in to use for encryption / decryption
  signer: window.nostr
});

// Create a kind 1 note with a hashtag
let draft = await factory.create(NoteBlueprint, "hello world #grownostr");
// Sign the note so it can be published
let signed = await window.nostr.signEvent(draft);

Its included in the applesauce-factory package and can be used with any other nostr SDKs or vanilla javascript

It also can be used to modify existing replaceable events

let draft = await factory.modifyTags(
  // kind 10002 event
  mailboxes,
  // add outbox relays
  addOutboxRelay("wss://relay.io/"),
  addOutboxRelay("wss://nostr.wine/"),
  // remove inbox relay
  removeInboxRelay("wss://personal.old-relay.com/")
);

see documentation for more examples

Loaders

The applesauce-loaders package exports a bunch of loader classes that can be used to load everything from replaceable events (profiles) to timelines and NIP-05 identities

They use rx-nostr under the hood to subscribe to relays, so for the time being they will not work with other nostr SDKs

I don’t expect many other developers or apps to use them since in my experience every nostr client requires a slightly different way or loading events

They are stable enough to start using but they are not fully tested and they might change slightly in the future

The following is a short list of the loaders and what they can be used for

  • ReplaceableLoader loads any replaceable events (0, 3, 1xxxx, 3xxxx)
  • SingleEventLoader loads single events based on ids
  • TimelineLoader loads a timeline of events from multiple relays based on filters
  • TagValueLoader loads events based on a tag name (like “e”) and a value, can be used to load replies, zaps, reactions, etc
  • DnsIdentityLoader loads NIP-05 identities and supports caching
  • UserSetsLoader loads all lists events for users

see documentation for more examples

Real tests

For all new features and a lot of existing ones I’m trying to write tests to ensure I don’t leave unexpected bugs for later

I’m not going to pretend its 100% tests coverage or that it will ever get close to that point, but these tests cover some of the core classes and help me prove that my code is doing what it says its supposed to do

At the moment there are about 230 tests covering 45 files. not much but its a start

Apps built using applesauce

If you want to see some examples of applesauce being used in a nostr client I’ve been testing a lot of this code in production on the apps I’ve built in the last few months

Thanks to Cesar Dias (npub1ces…t37c) for teaching me more about rxjs and consequentially making me re-write a lot of the core observables to be faster

Author Public Key
npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr