-
@ hzrd149
2025-02-21 17:54:15I'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 theapplesauce-signers
package and provides classes for building a multi-account system for clientsIts 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 theapplesauce-signers
package is now in a stable state and has a few new features - Ability to createnostrconnect://
URIs and waiting for the remote signer to connect - SDK agnostic way of subscribing and publishing to relaysFor a simple example, here is how to create a signer from a
bunker://
URIjs 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 useFor example: ```js 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 javascriptIt also can be used to modify existing replaceable events
js 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 identitiesThey 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 userssee 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
- noStrudel The main app everything is being built for and tested in
- nsite-manager Still a work-in-progress but supports multiple accounts thanks to the
applesauce-accounts
package - blossomservers.com A simple (and incomplete) nostr client for listing and reviewing public blossom servers
- libretranslate-dvm A libretranslate DVM for nostr:npub1mkvkflncllnvp3adq57klw3wge6k9llqa4r60g42ysp4yyultx6sykjgnu
- cherry-tree A chunked blob uploader / downloader. only uses applesauce for boilerplate
- nsite-homepage A simple landing page for nsite.lol
Thanks to nostr:npub1cesrkrcuelkxyhvupzm48e8hwn4005w0ya5jyvf9kh75mfegqx0q4kt37c for teaching me more about rxjs and consequentially making me re-write a lot of the core observables to be faster