Migration Guide: v2 to v3
This guide will help you migrate your existing applesauce v2 applications to v3. Applesauce v3 introduces several breaking changes that improve the API consistency and modernize the codebase, but require some code updates.
Overview of Major Changes
- Async APIs: All signer and account methods now return Promises (no more synchronous APIs)
- NIP-07 Updates: Removed
getRelays
method as it's no longer part of the NIP-07 specification - Relay Operations:
publish
andauthenticate
methods now return Promises instead of Observables - Factory Reorganization: Event operations have been reorganized into groups which breaks imports
1. Accounts & Signers Changes
Async API Migration
Major Change: All signer and account methods now return Promises instead of being synchronous. This is to help standardize the API and make it easier to wrap and extend the classes.
import { SimpleSigner } from "applesauce-accounts";
// v2 - Synchronous API
const account = new SimpleSigner();
const pubkey = account.getPubkey(); // Returns string directly
const event = account.signEvent(draft); // Returns NostrEvent directly
// v3 - Async API
const account = new SimpleSigner();
const pubkey = await account.getPubkey(); // Returns Promise<string>
const event = await account.signEvent(draft); // Returns Promise<NostrEvent>
Removed getRelays Method
The getRelays
method has been removed from all signers and accounts as it's no longer part of the NIP-07 specification:
// v2 - This method existed
const relays = await account.getRelays(); // ❌ Removed in v3
New ExtensionAccount.fromExtension Method
A new static method has been added for creating extension accounts:
// v3 - New static method
import { ExtensionAccount } from "applesauce-accounts";
const account = await ExtensionAccount.fromExtension(); // Creates account from window.nostr
Migration Steps
- Add await keywords to all account and signer method calls:
// v2
const pubkey = account.getPubkey();
const encrypted = account.encrypt(pubkey, message);
const decrypted = account.decrypt(pubkey, encryptedMessage);
const signed = account.signEvent(draft);
// v3
const pubkey = await account.getPubkey();
const encrypted = await account.encrypt(pubkey, message);
const decrypted = await account.decrypt(pubkey, encryptedMessage);
const signed = await account.signEvent(draft);
- Remove getRelays usage:
// v2 - Remove this
const relays = await account.getRelays();
2. Relay Changes
Promise-Based Publish Methods
Major Change: Relay publish methods now return Promises instead of Observables.
import { lastValueFrom } from "rxjs";
// v2 - Observable-based
const response = await lastValueFrom(relay.publish(event));
const responses = await lastValueFrom(pool.publish(event, relays));
// v3 - Promise-based
const response = await relay.publish(event); // Returns Promise<PublishResponse>
const responses = await pool.publish(event, relays); // Returns Promise<PublishResponse[]>
Authentication Methods
Authentication methods also now return Promises:
// v2 - Observable-based
const authResponse = await lastValueFrom(relay.authenticate(challenge));
const authResponse2 = await lastValueFrom(relay.auth(challenge));
// v3 - Promise-based
const authResponse = await relay.authenticate(challenge); // Returns Promise<PublishResponse>
const authResponse2 = await relay.auth(challenge); // Returns Promise<PublishResponse>
Removed Interfaces
The following interfaces have been removed:
IRelayState
- Use the Relay class directlyNip01Actions
- Methods are now part of the Relay class
Migration Steps
- Remove lastValueFrom usage for publish methods:
// v2
import { lastValueFrom } from "rxjs";
const response = await lastValueFrom(relay.publish(event));
// v3
const response = await relay.publish(event);
- Update authentication calls:
// v2
const authResponse = await lastValueFrom(relay.authenticate(challenge));
// v3
const authResponse = await relay.authenticate(challenge);
3. Factory & Operations Changes
Reorganized Exports
Major Change: Event operations have been reorganized and all exports have been renamed.
Import groups of operations instead of individual methods
Most of the operations have been moved into groups to make it easier to import and use them.
// v2
import { setListTitle, setListImage, setListDescription } from "applesauce-factory/operations";
await factory.build(
{ kind: 30000 },
setListTitle("new list"),
setListImage("https://example.com/image.png"),
setListDescription("This is a new list"),
);
// v3 - Use new names
import { List } from "applesauce-factory/operations";
await factory.build(
{ kind: 30000 },
List.setTitle("new list"),
List.setImage("https://example.com/image.png"),
List.setDescription("This is a new list"),
);
Summary of Required Changes
Breaking Changes (Must Update)
- Add
await
to all account/signer method calls - they now return Promises - Remove
getRelays()
usage on signers and accounts - method no longer exists - Update relay publish calls - remove
lastValueFrom()
wrapper since it returns a promise - Update relay authentication calls - remove
lastValueFrom()
wrapper since it returns a promise
Recommended Updates
- Use new
ExtensionAccount.fromExtension()
static method for creating extension accounts