# Table of Contents
- [applesauce](#applesauce)
- [AppleSauce](#applesauce)
- [Getting Started | applesauce](#getting-started-applesauce)
- [Migration Guide: v1 to v2 | applesauce](#migration-guide-v1-to-v2-applesauce)
- [Beginner's Tutorial | applesauce](#beginner-s-tutorial-applesauce)
- [Glossary | applesauce](#glossary-applesauce)
- [1. Introduction to EventStore | applesauce](#1-introduction-to-eventstore-applesauce)
- [2. Using Helper Methods | applesauce](#2-using-helper-methods-applesauce)
- [5. Loading Specific Events with Loaders | applesauce](#5-loading-specific-events-with-loaders-applesauce)
- [7. Publishing Events | applesauce](#7-publishing-events-applesauce)
- [4. Connecting to Relays | applesauce](#4-connecting-to-relays-applesauce)
- [3. Building Reactive UI with Models | applesauce](#3-building-reactive-ui-with-models-applesauce)
- [Relays | applesauce](#relays-applesauce)
- [Relay Pool | applesauce](#relay-pool-applesauce)
- [Loaders | applesauce](#loaders-applesauce)
- [Factory | applesauce](#factory-applesauce)
- [Accounts | applesauce](#accounts-applesauce)
- [Zaps Loader | applesauce](#zaps-loader-applesauce)
- [Event Loader | applesauce](#event-loader-applesauce)
- [Address Loader | applesauce](#address-loader-applesauce)
- [RxJS Operators | applesauce](#rxjs-operators-applesauce)
- [Signers | applesauce](#signers-applesauce)
- [Timeline Loader | applesauce](#timeline-loader-applesauce)
- [Reactions Loader | applesauce](#reactions-loader-applesauce)
- [6. Creating Events with EventFactory | applesauce](#6-creating-events-with-eventfactory-applesauce)
- [Actions | applesauce](#actions-applesauce)
- [Text content | applesauce](#text-content-applesauce)
- [Tag Value Loader | applesauce](#tag-value-loader-applesauce)
- [EventFactory | applesauce](#eventfactory-applesauce)
- [Event Blueprints | applesauce](#event-blueprints-applesauce)
- [8. Running Actions with ActionHub | applesauce](#8-running-actions-with-actionhub-applesauce)
- [Wallet | applesauce](#wallet-applesauce)
- [Models | applesauce](#models-applesauce)
- [Managing events | applesauce](#managing-events-applesauce)
- [Wallet Connect | applesauce](#wallet-connect-applesauce)
- [Migration Guide: v2 to v3 | applesauce](#migration-guide-v2-to-v3-applesauce)
- [Relay Class | applesauce](#relay-class-applesauce)
- [AppleSauce](#applesauce)
- [Markdown | applesauce](#markdown-applesauce)
- [WalletService Class | applesauce](#walletservice-class-applesauce)
- [Applesauce packages | applesauce](#applesauce-packages-applesauce)
- [Wallet Actions | applesauce](#wallet-actions-applesauce)
- [Nostr Connect | applesauce](#nostr-connect-applesauce)
- [Nostr Connect Provider | applesauce](#nostr-connect-provider-applesauce)
- [Action Hub | applesauce](#action-hub-applesauce)
- [Actions | applesauce](#actions-applesauce)
- [Event Operations | applesauce](#event-operations-applesauce)
- [WalletConnect Class | applesauce](#walletconnect-class-applesauce)
- [Account Manager | applesauce](#account-manager-applesauce)
- [Applesauce-react | applesauce](#applesauce-react-applesauce)
- [Tag Operations | applesauce](#tag-operations-applesauce)
- [applesauce](#applesauce)
- [Models | applesauce](#models-applesauce)
- [React Hooks | applesauce](#react-hooks-applesauce)
- [Accounts | applesauce](#accounts-applesauce)
- [Text Content | applesauce](#text-content-applesauce)
- [Helpers | applesauce](#helpers-applesauce)
- [applesauce-accounts | AppleSauce](#applesauce-accounts-applesauce)
- [applesauce-actions | AppleSauce](#applesauce-actions-applesauce)
- [applesauce-content | AppleSauce](#applesauce-content-applesauce)
- [applesauce-dvm | AppleSauce](#applesauce-dvm-applesauce)
- [applesauce-solidjs | AppleSauce](#applesauce-solidjs-applesauce)
- [applesauce-core | AppleSauce](#applesauce-core-applesauce)
- [applesauce-loaders | AppleSauce](#applesauce-loaders-applesauce)
- [applesauce-factory | AppleSauce](#applesauce-factory-applesauce)
- [applesauce-react | AppleSauce](#applesauce-react-applesauce)
- [SerialPortSigner | AppleSauce](#serialportsigner-applesauce)
- [isFromCache | AppleSauce](#isfromcache-applesauce)
- [AccountsProvider | AppleSauce](#accountsprovider-applesauce)
- [ExtensionSigner | AppleSauce](#extensionsigner-applesauce)
- [ensureSingletonTag | AppleSauce](#ensuresingletontag-applesauce)
- [Model | AppleSauce](#model-applesauce)
- [getTagValue | AppleSauce](#gettagvalue-applesauce)
- [getIndexableTags | AppleSauce](#getindexabletags-applesauce)
- [AmberClipboardSigner | AppleSauce](#amberclipboardsigner-applesauce)
- [links | AppleSauce](#links-applesauce)
- [nostrMentions | AppleSauce](#nostrmentions-applesauce)
- [useEventFactory | AppleSauce](#useeventfactory-applesauce)
- [useActiveAccount | AppleSauce](#useactiveaccount-applesauce)
- [useAccountManager | AppleSauce](#useaccountmanager-applesauce)
- [isValidProfile | AppleSauce](#isvalidprofile-applesauce)
- [hashtags | AppleSauce](#hashtags-applesauce)
- [emojis | AppleSauce](#emojis-applesauce)
- [addSeenRelay | AppleSauce](#addseenrelay-applesauce)
- [Link | AppleSauce](#link-applesauce)
- [Hashtag | AppleSauce](#hashtag-applesauce)
- [Nip07Interface | AppleSauce](#nip07interface-applesauce)
- [ReadonlySigner | AppleSauce](#readonlysigner-applesauce)
- [getCommentReplyPointer | AppleSauce](#getcommentreplypointer-applesauce)
- [galleries | AppleSauce](#galleries-applesauce)
- [getSeenRelays | AppleSauce](#getseenrelays-applesauce)
- [getProfileContent | AppleSauce](#getprofilecontent-applesauce)
- [lightningInvoices | AppleSauce](#lightninginvoices-applesauce)
- [getZapRecipient | AppleSauce](#getzaprecipient-applesauce)
- [isValidZap | AppleSauce](#isvalidzap-applesauce)
- [Emoji | AppleSauce](#emoji-applesauce)
- [getZapAddressPointer | AppleSauce](#getzapaddresspointer-applesauce)
- [getZapSender | AppleSauce](#getzapsender-applesauce)
- [getZapEventPointer | AppleSauce](#getzapeventpointer-applesauce)
- [getZapRequest | AppleSauce](#getzaprequest-applesauce)
- [Gallery | AppleSauce](#gallery-applesauce)
- [cashuTokens | AppleSauce](#cashutokens-applesauce)
- [getProfilePointerFromPTag | AppleSauce](#getprofilepointerfromptag-applesauce)
- [getAddressPointerFromATag | AppleSauce](#getaddresspointerfromatag-applesauce)
- [getEventPointerFromETag | AppleSauce](#geteventpointerfrometag-applesauce)
- [getEventPointerFromQTag | AppleSauce](#geteventpointerfromqtag-applesauce)
- [parseLNURLOrAddress | AppleSauce](#parselnurloraddress-applesauce)
- [getDeleteIds | AppleSauce](#getdeleteids-applesauce)
- [getAddressPointerForEvent | AppleSauce](#getaddresspointerforevent-applesauce)
- [getDeleteCoordinates | AppleSauce](#getdeletecoordinates-applesauce)
- [Mention | AppleSauce](#mention-applesauce)
- [getPackName | AppleSauce](#getpackname-applesauce)
- [parseBolt11 | AppleSauce](#parsebolt11-applesauce)
- [getEmojiTag | AppleSauce](#getemojitag-applesauce)
- [getInboxes | AppleSauce](#getinboxes-applesauce)
- [useRenderedContent | AppleSauce](#userenderedcontent-applesauce)
- [getURLFilename | AppleSauce](#geturlfilename-applesauce)
- [isAudioURL | AppleSauce](#isaudiourl-applesauce)
- [isImageURL | AppleSauce](#isimageurl-applesauce)
- [isVideoURL | AppleSauce](#isvideourl-applesauce)
- [applesauce-wallet | AppleSauce](#applesauce-wallet-applesauce)
- [applesauce-signers | AppleSauce](#applesauce-signers-applesauce)
- [getOutboxes | AppleSauce](#getoutboxes-applesauce)
- [getCommentRootPointer | AppleSauce](#getcommentrootpointer-applesauce)
- [isStreamURL | AppleSauce](#isstreamurl-applesauce)
- [isETag | AppleSauce](#isetag-applesauce)
- [canHaveHiddenTags | AppleSauce](#canhavehiddentags-applesauce)
- [isRTag | AppleSauce](#isrtag-applesauce)
- [isPTag | AppleSauce](#isptag-applesauce)
- [isTTag | AppleSauce](#isttag-applesauce)
- [isATag | AppleSauce](#isatag-applesauce)
- [isDTag | AppleSauce](#isdtag-applesauce)
- [getHiddenTags | AppleSauce](#gethiddentags-applesauce)
- [hasHiddenTags | AppleSauce](#hashiddentags-applesauce)
- [isHiddenTagsLocked | AppleSauce](#ishiddentagslocked-applesauce)
- [SerialPortAccount | AppleSauce](#serialportaccount-applesauce)
- [isFilterEqual | AppleSauce](#isfilterequal-applesauce)
- [unixNow | AppleSauce](#unixnow-applesauce)
- [createQTagFromEventPointer | AppleSauce](#createqtagfromeventpointer-applesauce)
- [fillAndTrimTag | AppleSauce](#fillandtrimtag-applesauce)
- [getZapPayment | AppleSauce](#getzappayment-applesauce)
- [ReadonlyAccount | AppleSauce](#readonlyaccount-applesauce)
- [TextNoteContentSymbol | AppleSauce](#textnotecontentsymbol-applesauce)
- [getEmojis | AppleSauce](#getemojis-applesauce)
- [AmberClipboardAccount | AppleSauce](#amberclipboardaccount-applesauce)
- [SimpleSigner | AppleSauce](#simplesigner-applesauce)
- [markFromCache | AppleSauce](#markfromcache-applesauce)
- [NostrConnectAccount | AppleSauce](#nostrconnectaccount-applesauce)
- [PasswordAccount | AppleSauce](#passwordaccount-applesauce)
- [FactoryProvider | AppleSauce](#factoryprovider-applesauce)
- [isEvent | AppleSauce](#isevent-applesauce)
- [useEventStore | AppleSauce](#useeventstore-applesauce)
- [SimpleAccount | AppleSauce](#simpleaccount-applesauce)
- [useObservableMemo | AppleSauce](#useobservablememo-applesauce)
- [Action | AppleSauce](#action-applesauce)
- [createPTagFromProfilePointer | AppleSauce](#createptagfromprofilepointer-applesauce)
- [EventStoreProvider | AppleSauce](#eventstoreprovider-applesauce)
- [remarkNostrMentions | AppleSauce](#remarknostrmentions-applesauce)
- [getParsedContent | AppleSauce](#getparsedcontent-applesauce)
- [PasswordSigner | AppleSauce](#passwordsigner-applesauce)
- [unlockHiddenTags | AppleSauce](#unlockhiddentags-applesauce)
- [ExtensionAccount | AppleSauce](#extensionaccount-applesauce)
- [AccountManager | AppleSauce](#accountmanager-applesauce)
- [ActionHub | AppleSauce](#actionhub-applesauce)
- [Accounts | AppleSauce](#accounts-applesauce)
- [NostrConnectSigner | AppleSauce](#nostrconnectsigner-applesauce)
- [Relay | AppleSauce](#relay-applesauce)
- [NostrConnectProvider | AppleSauce](#nostrconnectprovider-applesauce)
- [applesauce-relay | AppleSauce](#applesauce-relay-applesauce)
- [Actions | AppleSauce](#actions-applesauce)
- [applesauce-wallet-connect | AppleSauce](#applesauce-wallet-connect-applesauce)
- [WalletConnect | AppleSauce](#walletconnect-applesauce)
- [Helpers | AppleSauce](#helpers-applesauce)
- [TagOperations | AppleSauce](#tagoperations-applesauce)
- [Blueprints | AppleSauce](#blueprints-applesauce)
- [Models | AppleSauce](#models-applesauce)
- [Operations | AppleSauce](#operations-applesauce)
- [Actions | AppleSauce](#actions-applesauce)
- [Helpers | AppleSauce](#helpers-applesauce)
- [ProxySigner | AppleSauce](#proxysigner-applesauce)
- [SignerMismatchError | AppleSauce](#signermismatcherror-applesauce)
- [DecryptionCache | AppleSauce](#decryptioncache-applesauce)
- [SerializedAccount | AppleSauce](#serializedaccount-applesauce)
- [EventTemplate | AppleSauce](#eventtemplate-applesauce)
- [IAccountConstructor | AppleSauce](#iaccountconstructor-applesauce)
- [BaseAccount | AppleSauce](#baseaccount-applesauce)
- [IAccount | AppleSauce](#iaccount-applesauce)
- [ActionConstructor | AppleSauce](#actionconstructor-applesauce)
- [ActionContext | AppleSauce](#actioncontext-applesauce)
- [PublishMethod | AppleSauce](#publishmethod-applesauce)
- [Helpers | AppleSauce](#helpers-applesauce)
- [Markdown | AppleSauce](#markdown-applesauce)
- [Nast | AppleSauce](#nast-applesauce)
- [Text | AppleSauce](#text-applesauce)
- [TimeoutError | AppleSauce](#timeouterror-applesauce)
- [EventSet | AppleSauce](#eventset-applesauce)
- [IEventClaims | AppleSauce](#ieventclaims-applesauce)
- [IEventStoreActions | AppleSauce](#ieventstoreactions-applesauce)
- [IEventSet | AppleSauce](#ieventset-applesauce)
- [EventStore | AppleSauce](#eventstore-applesauce)
- [IEventStoreModels | AppleSauce](#ieventstoremodels-applesauce)
- [PublishMethod | AppleSauce](#publishmethod-applesauce)
- [DVMClient | AppleSauce](#dvmclient-applesauce)
- [IEventStoreRead | AppleSauce](#ieventstoreread-applesauce)
- [IEventStore | AppleSauce](#ieventstore-applesauce)
- [ClientPointerContext | AppleSauce](#clientpointercontext-applesauce)
- [EventFactory | AppleSauce](#eventfactory-applesauce)
- [Getting Started | applesauce](#getting-started-applesauce)
- [Blueprints | AppleSauce](#blueprints-applesauce)
- [Helpers | AppleSauce](#helpers-applesauce)
- [SubscriptionMethod | AppleSauce](#subscriptionmethod-applesauce)
- [IEventStoreStreams | AppleSauce](#ieventstorestreams-applesauce)
- [EmojiContext | AppleSauce](#emojicontext-applesauce)
- [IEventStoreSubscriptions | AppleSauce](#ieventstoresubscriptions-applesauce)
- [EventFactoryClient | AppleSauce](#eventfactoryclient-applesauce)
- [EventFactoryContext | AppleSauce](#eventfactorycontext-applesauce)
- [ModelConstructor | AppleSauce](#modelconstructor-applesauce)
- [EventSigner | AppleSauce](#eventsigner-applesauce)
- [Emoji | AppleSauce](#emoji-applesauce)
- [PublishOptions | AppleSauce](#publishoptions-applesauce)
- [NameValueTag | AppleSauce](#namevaluetag-applesauce)
- [PublishResponse | AppleSauce](#publishresponse-applesauce)
- [AddNutzapInfoMint | AppleSauce](#addnutzapinfomint-applesauce)
- [createATagFromAddressPointer | AppleSauce](#createatagfromaddresspointer-applesauce)
- [ChannelHiddenModel | AppleSauce](#channelhiddenmodel-applesauce)
- [createCommentTagsFromCommentPointer | AppleSauce](#createcommenttagsfromcommentpointer-applesauce)
- [WalletConnectEncryptionMethod | AppleSauce](#walletconnectencryptionmethod-applesauce)
- [SubscriptionOptions | AppleSauce](#subscriptionoptions-applesauce)
- [BunkerURI | AppleSauce](#bunkeruri-applesauce)
- [PicturePostBlueprintOptions | AppleSauce](#picturepostblueprintoptions-applesauce)
- [AddBlossomServer | AppleSauce](#addblossomserver-applesauce)
- [ConsolidateTokens | AppleSauce](#consolidatetokens-applesauce)
- [addBlossomServerTag | AppleSauce](#addblossomservertag-applesauce)
- [NostrConnectResponse | AppleSauce](#nostrconnectresponse-applesauce)
- [ChannelMessagesModel | AppleSauce](#channelmessagesmodel-applesauce)
- [createETagFromEventPointer | AppleSauce](#createetagfromeventpointer-applesauce)
- [ReportReason | AppleSauce](#reportreason-applesauce)
- [CalendarRsvp | AppleSauce](#calendarrsvp-applesauce)
- [SubscriptionResponse | AppleSauce](#subscriptionresponse-applesauce)
- [PollBlueprintOptions | AppleSauce](#pollblueprintoptions-applesauce)
- [WalletNotification | AppleSauce](#walletnotification-applesauce)
- [AddDMRelay | AppleSauce](#adddmrelay-applesauce)
- [WalletService | AppleSauce](#walletservice-applesauce)
- [CreateWallet | AppleSauce](#createwallet-applesauce)
- [Channel | AppleSauce](#channel-applesauce)
- [addEventBookmarkTag | AppleSauce](#addeventbookmarktag-applesauce)
- [NostrConnectMethod | AppleSauce](#nostrconnectmethod-applesauce)
- [ChannelMetadataModel | AppleSauce](#channelmetadatamodel-applesauce)
- [createETagWithMarkerFromEventPointer | AppleSauce](#createetagwithmarkerfromeventpointer-applesauce)
- [NostrPublishMethod | AppleSauce](#nostrpublishmethod-applesauce)
- [LRU | AppleSauce](#lru-applesauce)
- [PollResponseBlueprintOptions | AppleSauce](#pollresponseblueprintoptions-applesauce)
- [completeOnEose | AppleSauce](#completeoneose-applesauce)
- [WalletServiceHandlers | AppleSauce](#walletservicehandlers-applesauce)
- [AddEventToCalendar | AppleSauce](#addeventtocalendar-applesauce)
- [NutzapEvent | AppleSauce](#nutzapevent-applesauce)
- [Client | AppleSauce](#client-applesauce)
- [addEventTag | AppleSauce](#addeventtag-applesauce)
- [ConnectResponseResults | AppleSauce](#connectresponseresults-applesauce)
- [ChannelMutedModel | AppleSauce](#channelmutedmodel-applesauce)
- [createGroupHTagFromGroupPointer | AppleSauce](#creategrouphtagfromgrouppointer-applesauce)
- [EncryptedContentCache | AppleSauce](#encryptedcontentcache-applesauce)
- [NostrSubscriptionMethod | AppleSauce](#nostrsubscriptionmethod-applesauce)
- [markFromRelay | AppleSauce](#markfromrelay-applesauce)
- [WalletServiceOptions | AppleSauce](#walletserviceoptions-applesauce)
- [ShareBlueprintOptions | AppleSauce](#shareblueprintoptions-applesauce)
- [Helpers | AppleSauce](#helpers-applesauce)
- [AddFavoriteRelay | AppleSauce](#addfavoriterelay-applesauce)
- [NutzapProfile | AppleSauce](#nutzapprofile-applesauce)
- [Comment | AppleSauce](#comment-applesauce)
- [addGroupTag | AppleSauce](#addgrouptag-applesauce)
- [CommentsModel | AppleSauce](#commentsmodel-applesauce)
- [createGroupTagFromGroupPointer | AppleSauce](#creategrouptagfromgrouppointer-applesauce)
- [EncryptedContentSigner | AppleSauce](#encryptedcontentsigner-applesauce)
- [WalletSupport | AppleSauce](#walletsupport-applesauce)
- [GetBalanceHandler | AppleSauce](#getbalancehandler-applesauce)
- [onlyEvents | AppleSauce](#onlyevents-applesauce)
- [WrappedMessageBlueprintOptions | AppleSauce](#wrappedmessageblueprintoptions-applesauce)
- [AddFavoriteRelaySet | AppleSauce](#addfavoriterelayset-applesauce)
- [ReceiveToken | AppleSauce](#receivetoken-applesauce)
- [Content | AppleSauce](#content-applesauce)
- [addHashtag | AppleSauce](#addhashtag-applesauce)
- [ContactsModel | AppleSauce](#contactsmodel-applesauce)
- [EncryptionMethods | AppleSauce](#encryptionmethods-applesauce)
- [NostrPool | AppleSauce](#nostrpool-applesauce)
- [GetInfoHandler | AppleSauce](#getinfohandler-applesauce)
- [ensureAddressPointerTag | AppleSauce](#ensureaddresspointertag-applesauce)
- [CalendarBlueprint | AppleSauce](#calendarblueprint-applesauce)
- [storeEvents | AppleSauce](#storeevents-applesauce)
- [AddInboxRelay | AppleSauce](#addinboxrelay-applesauce)
- [Delete | AppleSauce](#delete-applesauce)
- [RemoveNutzapInfoMint | AppleSauce](#removenutzapinfomint-applesauce)
- [addInboxRelay | AppleSauce](#addinboxrelay-applesauce)
- [EncryptedContentModel | AppleSauce](#encryptedcontentmodel-applesauce)
- [PollOption | AppleSauce](#polloption-applesauce)
- [ListTransactionsHandler | AppleSauce](#listtransactionshandler-applesauce)
- [ensureEventPointerTag | AppleSauce](#ensureeventpointertag-applesauce)
- [WalletAuthURI | AppleSauce](#walletauthuri-applesauce)
- [ChannelMessageBlueprint | AppleSauce](#channelmessageblueprint-applesauce)
- [RemoveNutzapInfoRelay | AppleSauce](#removenutzapinforelay-applesauce)
- [toEventStore | AppleSauce](#toeventstore-applesauce)
- [AddOutboxRelay | AppleSauce](#addoutboxrelay-applesauce)
- [Geohash | AppleSauce](#geohash-applesauce)
- [addMailboxRelay | AppleSauce](#addmailboxrelay-applesauce)
- [EventModel | AppleSauce](#eventmodel-applesauce)
- [AddressPointerWithoutD | AppleSauce](#addresspointerwithoutd-applesauce)
- [GetBalanceResult | AppleSauce](#getbalanceresult-applesauce)
- [ensureKTag | AppleSauce](#ensurektag-applesauce)
- [ChannelMessageReplyBlueprint | AppleSauce](#channelmessagereplyblueprint-applesauce)
- [LookupInvoiceHandler | AppleSauce](#lookupinvoicehandler-applesauce)
- [AddRelayToRelaySet | AppleSauce](#addrelaytorelayset-applesauce)
- [RolloverTokens | AppleSauce](#rollovertokens-applesauce)
- [GiftWrap | AppleSauce](#giftwrap-applesauce)
- [addNameValueTag | AppleSauce](#addnamevaluetag-applesauce)
- [MakeInvoiceHandler | AppleSauce](#makeinvoicehandler-applesauce)
- [ensureMarkedAddressPointerTag | AppleSauce](#ensuremarkedaddresspointertag-applesauce)
- [CommentBlueprint | AppleSauce](#commentblueprint-applesauce)
- [AddSearchRelay | AppleSauce](#addsearchrelay-applesauce)
- [SetNutzapInfoPubkey | AppleSauce](#setnutzapinfopubkey-applesauce)
- [Groups | AppleSauce](#groups-applesauce)
- [addOutboxRelay | AppleSauce](#addoutboxrelay-applesauce)
- [EventZapsModel | AppleSauce](#eventzapsmodel-applesauce)
- [CalendarEventParticipant | AppleSauce](#calendareventparticipant-applesauce)
- [MultiPayInvoiceHandler | AppleSauce](#multipayinvoicehandler-applesauce)
- [ensureMarkedEventPointerTag | AppleSauce](#ensuremarkedeventpointertag-applesauce)
- [WalletResponse | AppleSauce](#walletresponse-applesauce)
- [DeleteBlueprint | AppleSauce](#deleteblueprint-applesauce)
- [AddUserToFollowSet | AppleSauce](#addusertofollowset-applesauce)
- [LiveChatMessageBlueprintOptions | AppleSauce](#livechatmessageblueprintoptions-applesauce)
- [RelayOptions | AppleSauce](#relayoptions-applesauce)
- [ALLOWED_PIN_KINDS | AppleSauce](#allowed-pin-kinds-applesauce)
- [AddNutzapInfoRelay | AppleSauce](#addnutzapinforelay-applesauce)
- [Calendar | AppleSauce](#calendar-applesauce)
- [removeCoordinateTag | AppleSauce](#removecoordinatetag-applesauce)
- [CalendarEventsModel | AppleSauce](#calendareventsmodel-applesauce)
- [Blueprints | AppleSauce](#blueprints-applesauce)
- [createCommentTagsForEvent | AppleSauce](#createcommenttagsforevent-applesauce)
- [WalletConnectOptions | AppleSauce](#walletconnectoptions-applesauce)
- [NoteBlueprintOptions | AppleSauce](#noteblueprintoptions-applesauce)
- [registerCommonAccountTypes | AppleSauce](#registercommonaccounttypes-applesauce)
- [RequestOptions | AppleSauce](#requestoptions-applesauce)
- [NostrConnectAppMetadata | AppleSauce](#nostrconnectappmetadata-applesauce)
- [AddBlockedRelay | AppleSauce](#addblockedrelay-applesauce)
- [CompleteSpend | AppleSauce](#completespend-applesauce)
- [addAddressTag | AppleSauce](#addaddresstag-applesauce)
- [NostrConnectURI | AppleSauce](#nostrconnecturi-applesauce)
- [CalendarEvent | AppleSauce](#calendarevent-applesauce)
- [EventsModel | AppleSauce](#eventsmodel-applesauce)
- [Bookmarks | AppleSauce](#bookmarks-applesauce)
- [GetInfoResult | AppleSauce](#getinforesult-applesauce)
- [UnlockWallet | AppleSauce](#unlockwallet-applesauce)
- [addPubkeyTag | AppleSauce](#addpubkeytag-applesauce)
- [FavoriteRelaySetsModel | AppleSauce](#favoriterelaysetsmodel-applesauce)
- [ChannelMetadataContent | AppleSauce](#channelmetadatacontent-applesauce)
- [Hashtags | AppleSauce](#hashtags-applesauce)
- [MultiPayKeysendHandler | AppleSauce](#multipaykeysendhandler-applesauce)
- [ensureMarkedProfilePointerTag | AppleSauce](#ensuremarkedprofilepointertag-applesauce)
- [ListTransactionsResult | AppleSauce](#listtransactionsresult-applesauce)
- [FileMetadataBlueprint | AppleSauce](#filemetadatablueprint-applesauce)
- [BookmarkEvent | AppleSauce](#bookmarkevent-applesauce)
- [UpdateNutzapInfo | AppleSauce](#updatenutzapinfo-applesauce)
- [Highlight | AppleSauce](#highlight-applesauce)
- [addRelayTag | AppleSauce](#addrelaytag-applesauce)
- [FavoriteRelaysModel | AppleSauce](#favoriterelaysmodel-applesauce)
- [CommentAddressPointer | AppleSauce](#commentaddresspointer-applesauce)
- [ensureNamedValueTag | AppleSauce](#ensurenamedvaluetag-applesauce)
- [Transaction | AppleSauce](#transaction-applesauce)
- [FollowSetBlueprint | AppleSauce](#followsetblueprint-applesauce)
- [PayInvoiceHandler | AppleSauce](#payinvoicehandler-applesauce)
- [CreateBookmarkList | AppleSauce](#createbookmarklist-applesauce)
- [WalletAddPrivateKey | AppleSauce](#walletaddprivatekey-applesauce)
- [LegacyMessage | AppleSauce](#legacymessage-applesauce)
- [removeAddressTag | AppleSauce](#removeaddresstag-applesauce)
- [GiftWrapRumorModel | AppleSauce](#giftwraprumormodel-applesauce)
- [CommentEventPointer | AppleSauce](#commenteventpointer-applesauce)
- [ensureProfilePointerTag | AppleSauce](#ensureprofilepointertag-applesauce)
- [MakeInvoiceParams | AppleSauce](#makeinvoiceparams-applesauce)
- [GiftWrapBlueprint | AppleSauce](#giftwrapblueprint-applesauce)
- [PayKeysendHandler | AppleSauce](#paykeysendhandler-applesauce)
- [CreateBookmarkSet | AppleSauce](#createbookmarkset-applesauce)
- [List | AppleSauce](#list-applesauce)
- [removeBlossomServerTag | AppleSauce](#removeblossomservertag-applesauce)
- [GiftWrapsModel | AppleSauce](#giftwrapsmodel-applesauce)
- [CommentExternalPointer | AppleSauce](#commentexternalpointer-applesauce)
- [ensureQuoteEventPointerTag | AppleSauce](#ensurequoteeventpointertag-applesauce)
- [PayInvoiceResult | AppleSauce](#payinvoiceresult-applesauce)
- [SerializedWalletConnect | AppleSauce](#serializedwalletconnect-applesauce)
- [GroupMessageBlueprint | AppleSauce](#groupmessageblueprint-applesauce)
- [CreateFollowSet | AppleSauce](#createfollowset-applesauce)
- [LiveStream | AppleSauce](#livestream-applesauce)
- [removeEventBookmarkTag | AppleSauce](#removeeventbookmarktag-applesauce)
- [HiddenContactsModel | AppleSauce](#hiddencontactsmodel-applesauce)
- [DecodeResult | AppleSauce](#decoderesult-applesauce)
- [PayKeysendResult | AppleSauce](#paykeysendresult-applesauce)
- [eventPipe | AppleSauce](#eventpipe-applesauce)
- [HighlightBlueprint | AppleSauce](#highlightblueprint-applesauce)
- [SerializedWalletService | AppleSauce](#serializedwalletservice-applesauce)
- [CreateMailboxes | AppleSauce](#createmailboxes-applesauce)
- [Mailboxes | AppleSauce](#mailboxes-applesauce)
- [removeEventTag | AppleSauce](#removeeventtag-applesauce)
- [HiddenMuteModel | AppleSauce](#hiddenmutemodel-applesauce)
- [WalletRequest | AppleSauce](#walletrequest-applesauce)
- [getContentPointers | AppleSauce](#getcontentpointers-applesauce)
- [ExternalIdentifiers | AppleSauce](#externalidentifiers-applesauce)
- [LegacyMessageBlueprint | AppleSauce](#legacymessageblueprint-applesauce)
- [CreatePinList | AppleSauce](#createpinlist-applesauce)
- [Note | AppleSauce](#note-applesauce)
- [removeGroupTag | AppleSauce](#removegrouptag-applesauce)
- [LegacyMessageReplies | AppleSauce](#legacymessagereplies-applesauce)
- [WalletMethod | AppleSauce](#walletmethod-applesauce)
- [identity | AppleSauce](#identity-applesauce)
- [ExternalPointer | AppleSauce](#externalpointer-applesauce)
- [LegacyMessageReplyBlueprint | AppleSauce](#legacymessagereplyblueprint-applesauce)
- [CreateProfile | AppleSauce](#createprofile-applesauce)
- [PicturePost | AppleSauce](#picturepost-applesauce)
- [removeHashtag | AppleSauce](#removehashtag-applesauce)
- [LegacyMessagesGroup | AppleSauce](#legacymessagesgroup-applesauce)
- [NotificationType | AppleSauce](#notificationtype-applesauce)
- [FileMetadata | AppleSauce](#filemetadata-applesauce)
- [pipeFromAsyncArray | AppleSauce](#pipefromasyncarray-applesauce)
- [CreateRelaySet | AppleSauce](#createrelayset-applesauce)
- [LiveChatMessageBlueprint | AppleSauce](#livechatmessageblueprint-applesauce)
- [skip | AppleSauce](#skip-applesauce)
- [removeInboxRelay | AppleSauce](#removeinboxrelay-applesauce)
- [LegacyMessagesGroups | AppleSauce](#legacymessagesgroups-applesauce)
- [WalletConnectURI | AppleSauce](#walletconnecturi-applesauce)
- [GroupPointer | AppleSauce](#grouppointer-applesauce)
- [NoteBlueprint | AppleSauce](#noteblueprint-applesauce)
- [FollowUser | AppleSauce](#followuser-applesauce)
- [Poll | AppleSauce](#poll-applesauce)
- [PollResponse | AppleSauce](#pollresponse-applesauce)
- [removeMailboxRelay | AppleSauce](#removemailboxrelay-applesauce)
- [LegacyMessageThreads | AppleSauce](#legacymessagethreads-applesauce)
- [HandlerLinkPlatform | AppleSauce](#handlerlinkplatform-applesauce)
- [tagPipe | AppleSauce](#tagpipe-applesauce)
- [NoteReplyBlueprint | AppleSauce](#notereplyblueprint-applesauce)
- [MuteHashtag | AppleSauce](#mutehashtag-applesauce)
- [Profile | AppleSauce](#profile-applesauce)
- [removeNameValueTag | AppleSauce](#removenamevaluetag-applesauce)
- [HandlerLinkType | AppleSauce](#handlerlinktype-applesauce)
- [MailboxesModel | AppleSauce](#mailboxesmodel-applesauce)
- [PicturePostBlueprint | AppleSauce](#picturepostblueprint-applesauce)
- [MuteThread | AppleSauce](#mutethread-applesauce)
- [Reaction | AppleSauce](#reaction-applesauce)
- [removeOutboxRelay | AppleSauce](#removeoutboxrelay-applesauce)
- [MuteModel | AppleSauce](#mutemodel-applesauce)
- [HighlightAttribution | AppleSauce](#highlightattribution-applesauce)
- [PollBlueprint | AppleSauce](#pollblueprint-applesauce)
- [MuteUser | AppleSauce](#muteuser-applesauce)
- [removePubkeyTag | AppleSauce](#removepubkeytag-applesauce)
- [ProfileModel | AppleSauce](#profilemodel-applesauce)
- [HighlightAttributionRole | AppleSauce](#highlightattributionrole-applesauce)
- [PollResponseBlueprint | AppleSauce](#pollresponseblueprint-applesauce)
- [Stream | AppleSauce](#stream-applesauce)
- [MuteWord | AppleSauce](#muteword-applesauce)
- [StreamChat | AppleSauce](#streamchat-applesauce)
- [removeRelayTag | AppleSauce](#removerelaytag-applesauce)
- [PublicContactsModel | AppleSauce](#publiccontactsmodel-applesauce)
- [MediaAttachment | AppleSauce](#mediaattachment-applesauce)
- [ReactionBlueprint | AppleSauce](#reactionblueprint-applesauce)
- [NewBlockedRelays | AppleSauce](#newblockedrelays-applesauce)
- [removeSingletonTag | AppleSauce](#removesingletontag-applesauce)
- [PublicMuteModel | AppleSauce](#publicmutemodel-applesauce)
- [Mutes | AppleSauce](#mutes-applesauce)
- [WrappedMessage | AppleSauce](#wrappedmessage-applesauce)
- [ShareBlueprint | AppleSauce](#shareblueprint-applesauce)
- [NewBlossomServers | AppleSauce](#newblossomservers-applesauce)
- [setSingletonTag | AppleSauce](#setsingletontag-applesauce)
- [ReactionsModel | AppleSauce](#reactionsmodel-applesauce)
- [Zap | AppleSauce](#zap-applesauce)
- [SingleChoicePollResponseBlueprint | AppleSauce](#singlechoicepollresponseblueprint-applesauce)
- [NewContacts | AppleSauce](#newcontacts-applesauce)
- [ReceivedZapsModel | AppleSauce](#receivedzapsmodel-applesauce)
- [MetaTagOptions | AppleSauce](#metatagoptions-applesauce)
- [ParseResult | AppleSauce](#parseresult-applesauce)
- [StreamChatMessage | AppleSauce](#streamchatmessage-applesauce)
- [NewDMRelays | AppleSauce](#newdmrelays-applesauce)
- [ReplaceableModel | AppleSauce](#replaceablemodel-applesauce)
- [PollType | AppleSauce](#polltype-applesauce)
- [ModifyTagsOptions | AppleSauce](#modifytagsoptions-applesauce)
- [WrappedMessageBlueprint | AppleSauce](#wrappedmessageblueprint-applesauce)
- [NewFavoriteRelays | AppleSauce](#newfavoriterelays-applesauce)
- [ReplaceableSetModel | AppleSauce](#replaceablesetmodel-applesauce)
- [includeAltTag | AppleSauce](#includealttag-applesauce)
- [ReadListTags | AppleSauce](#readlisttags-applesauce)
- [WrappedMessageReplyBlueprint | AppleSauce](#wrappedmessagereplyblueprint-applesauce)
- [NewSearchRelays | AppleSauce](#newsearchrelays-applesauce)
- [RepliesModel | AppleSauce](#repliesmodel-applesauce)
- [includeNameValueTag | AppleSauce](#includenamevaluetag-applesauce)
- [ReportedEvent | AppleSauce](#reportedevent-applesauce)
- [PinNote | AppleSauce](#pinnote-applesauce)
- [SearchRelaysModel | AppleSauce](#searchrelaysmodel-applesauce)
- [includeReplaceableIdentifier | AppleSauce](#includereplaceableidentifier-applesauce)
---
# applesauce
[Skip to content](https://hzrd149.github.io/applesauce/#VPContent)
AppleSauceModular SDK for Nostr
===============================
Build reactive nostr UI with less code
[Getting Started](https://hzrd149.github.io/applesauce/introduction/getting-started.html)
[Reference](https://hzrd149.github.io/applesauce/typedoc/index.html)
[Examples](https://hzrd149.github.io/applesauce/examples/)
[Migrations](https://hzrd149.github.io/applesauce/migration/v1-v2.html)
Utilities
---------
At its core AppleSauce is packages of helper methods to help parse and understand nostr events.
Reactive
--------
AppleSauce is built using RxJS observables, which makes subscribing to events and filters simple.
Modular
-------
Every piece of the packages can be used independently, helpers, event store, and signers.
Flexible
--------
Easily request events from relays without making connection state. or use any other nostr library to talk to relays.
---
# AppleSauce
AppleSauce
==========
AppleSauce[](https://hzrd149.github.io/applesauce/typedoc/index.html#applesauce)
=================================================================================
AppleSauce is a collection typescript libraries to make building nostr web clients easier and is used in [noStrudel](https://github.com/hzrd149/nostrudel)
The full documentation can be found on the [documentation](https://hzrd149.github.io/applesauce)
site.
Installation[](https://hzrd149.github.io/applesauce/typedoc/index.html#installation)
-------------------------------------------------------------------------------------
# using npmnpm install applesauce-core# using pnpmpnpm install applesauce-core# using yarnyarn add applesauce-core
Development Setup[](https://hzrd149.github.io/applesauce/typedoc/index.html#development-setup)
-----------------------------------------------------------------------------------------------
Clone the repository:
git clone https://github.com/hzrd149/applesauce.gitcd applesauce
Install dependencies:
pnpm install
Build the project:
pnpm build
Running tests[](https://hzrd149.github.io/applesauce/typedoc/index.html#running-tests)
---------------------------------------------------------------------------------------
This repo uses [vitest](https://vitest.dev/)
for all tests
# Run all testspnpm test# Run coverage testspnpm coverage# Run the tests in dev modepnpm vitest
Running documentation[](https://hzrd149.github.io/applesauce/typedoc/index.html#running-documentation)
-------------------------------------------------------------------------------------------------------
This repo is setup with [typedoc](https://typedoc.org/)
for the typescript documentation and [vitepress](https://vitepress.dev/)
for the documentation site
# Build the typedocspnpm typedoc
The `packages/docs` is the package for the docs site
cd packages/docs# Run vitepress devpnpm dev# Build vitepresspnpm build
React[](https://hzrd149.github.io/applesauce/typedoc/index.html#react)
-----------------------------------------------------------------------
The `applesauce-react` package contains various hooks and providers for using applesauce in react components, [Docs](https://hzrd149.github.io/applesauce/react/getting-started.html)
Contributing[](https://hzrd149.github.io/applesauce/typedoc/index.html#contributing)
-------------------------------------------------------------------------------------
1. Fork the repository
2. Create your feature branch: `git checkout -b feature/my-new-feature`
3. Install dependencies: `pnpm install`
4. Make your changes
5. Run tests: `pnpm test`
6. Build the project: `pnpm build`
7. Format code: `pnpm format`
8. Commit your changes: `git commit -am 'Add some feature'`
9. Push to the branch: `git push origin feature/my-new-feature`
10. Submit a pull request
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[AppleSauce](https://hzrd149.github.io/applesauce/typedoc/index.html#applesauce)
* [Installation](https://hzrd149.github.io/applesauce/typedoc/index.html#installation)
* [Development Setup](https://hzrd149.github.io/applesauce/typedoc/index.html#development-setup)
* [Running tests](https://hzrd149.github.io/applesauce/typedoc/index.html#running-tests)
* [Running documentation](https://hzrd149.github.io/applesauce/typedoc/index.html#running-documentation)
* [React](https://hzrd149.github.io/applesauce/typedoc/index.html#react)
* [Contributing](https://hzrd149.github.io/applesauce/typedoc/index.html#contributing)
---
# Getting Started | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/introduction/getting-started.html#VPContent)
Return to top
Getting Started [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#getting-started)
============================================================================================================
Ready to build reactive Nostr applications with applesauce? Follow our step-by-step tutorial that will teach you everything you need to know.
📚 [Complete Tutorial](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html)
[](https://hzrd149.github.io/applesauce/introduction/getting-started.html#%F0%9F%93%9A-complete-tutorial)
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Our beginner-friendly tutorial covers:
1. **[Event Store](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html)
** - The reactive database at the heart of applesauce
2. **[Helpers](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html)
** - Extract and parse data from Nostr events
3. **[Models](https://hzrd149.github.io/applesauce/tutorial/03-models.html)
** - Build reactive UI components
4. **[Relay Pool](https://hzrd149.github.io/applesauce/tutorial/04-relays.html)
** - Connect to Nostr relays and receive events
5. **[Loaders](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html)
** - Load specific events on-demand
6. **[Event Factory](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html)
** - Create and sign events
7. **[Publishing](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html)
** - Publish events to relays
8. **[Actions](https://hzrd149.github.io/applesauce/tutorial/08-actions.html)
** - Run complex actions like following users
Each section includes complete code examples and builds toward a working social media application.
Quick Overview [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#quick-overview)
----------------------------------------------------------------------------------------------------------
Applesauce consists of several key components that work together:
### EventStore [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#eventstore)
A reactive in-memory database that stores Nostr events and notifies your UI when data changes.
ts
import { EventStore } from "applesauce-core";
const eventStore = new EventStore();
// Subscribe to timeline updates
eventStore.timeline({ kinds: [1] }).subscribe((notes) => {
console.log(`Timeline updated with ${notes.length} notes`);
});
### Helpers [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#helpers)
Utility functions that extract useful data from raw Nostr events.
ts
import { getProfileContent, getDisplayName } from "applesauce-core/helpers";
const profile = getProfileContent(profileEvent);
const name = getDisplayName(profile);
### Models [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#models)
Pre-built subscriptions that combine EventStore with helpers for reactive UI components.
ts
import { ProfileModel } from "applesauce-core/models";
// Automatically parses and updates when profile changes
eventStore.model(ProfileModel, pubkey).subscribe((profile) => {
console.log("Profile updated:", profile);
});
### RelayPool [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#relaypool)
Manages connections to Nostr relays and provides reactive subscriptions.
ts
import { RelayPool, onlyEvents } from "applesauce-relay";
const pool = new RelayPool();
pool
.relay("wss://relay.damus.io")
.subscription({ kinds: [1] })
.pipe(onlyEvents())
.subscribe((event) => {
eventStore.add(event);
});
### EventFactory [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#eventfactory)
Creates and signs Nostr events using pre-built blueprints.
ts
import { EventFactory } from "applesauce-factory";
import { NoteBlueprint } from "applesauce-factory/blueprints";
const factory = new EventFactory({ signer });
const note = await factory.create(NoteBlueprint, "Hello Nostr!");
const signed = await factory.sign(note);
Next Steps [](https://hzrd149.github.io/applesauce/introduction/getting-started.html#next-steps)
--------------------------------------------------------------------------------------------------
* **Start with the [tutorial](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html)
** to learn step-by-step
* **Browse the [examples](https://hzrd149.github.io/applesauce/examples)
** to see whats possible
* **Check the [API documentation](https://hzrd149.github.io/applesauce/typedoc/)
** for detailed reference
---
# Migration Guide: v1 to v2 | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/migration/v1-v2.html#VPContent)
Return to top
Migration Guide: v1 to v2 [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#migration-guide-v1-to-v2)
==================================================================================================================
This guide will help you migrate your existing applesauce v1 applications to v2. Applesauce v2 introduces several breaking changes that improve the API consistency and performance, but require some code updates.
Overview of Major Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#overview-of-major-changes)
-------------------------------------------------------------------------------------------------------------------
* **Loaders**: All loader classes have been removed and replaced with functional loaders that return observables
* **Queries → Models**: The "Queries" namespace has been renamed to "Models" throughout the codebase
* **QueryStore Removal**: QueryStore has been merged into EventStore - use `eventStore.model()` instead
* **React Hooks**: `useStoreQuery` has been renamed to `useEventModel`
* **EventStore API**: Methods now return synchronous observables that emit `undefined` for missing events
1\. Loader Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_1-loader-changes)
----------------------------------------------------------------------------------------------------
### The Problem [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#the-problem)
In v1, loaders were classes that extended RxJS Subjects, making them stateful and harder to work with:
ts
// v1 - Class-based loaders
import { TimelineLoader, SingleEventLoader, ReplaceableLoader } from "applesauce-loaders/loaders";
const timelineLoader = new TimelineLoader(rxNostr, ...args);
const eventLoader = new SingleEventLoader(rxNostr, ...args);
const replaceableLoader = new ReplaceableLoader(rxNostr, ...args);
// The loaders had to be subscribe to globaly to work
replaceableLoader.subscribe((event) => eventStore.add(event));
// Request a profile
replaceableLoader.next({ kind: 0, pubkey });
// Then wait for the result
replaceableLoader.subscribe((event) => {
if (event.kind === 0 && event.pubkey === pubkey) console.log(event);
});
This was difficult to work with since passing the request to the loader and subscribing to the results were two separate steps.
### The Solution [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#the-solution)
In v2, loaders are functions that return observables, making them stateless and more functional:
ts
// v2 - Functional loaders
import { createTimelineLoader, createEventLoader, createAddressLoader } from "applesauce-loaders/loaders";
// Create loader functions
const timeline = createTimelineLoader(pool, { eventStore });
const eventLoader = createEventLoader(pool, { eventStore });
const addressLoader = createAddressLoader(pool, { eventStore });
// Request a single event
const event = await eventLoader({ id: "event-id" }).subscribe((evetn) => {
console.log(event);
});
// Request a profile
const profile = await addressLoader({ kind: 0, pubkey }).subscribe((events) => {
console.log(events);
});
// Load next page on a timeline
const timeline = await timeline().subscribe((events) => {
This allows the loaders to be used in a more functional way, since each request returns an observable and only returns the data for that single request.
### Migration Steps [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#migration-steps)
1. **Replace TimelineLoader**:
For code that is using the `TimelineLoader` class, you can replace it with the `createTimelineLoader` function:
ts
// v1
const loader = new TimelineLoader(rxNostr, ...opts);
// Start the loader
loader.subscribe((events) => {
// Handle events
});
// Request the next page of the timeline
loader.next();
// v2
const timelineLoader = createTimelineLoader(
// A RelayPool instance or request method
pool,
// Relays to load from
["wss://relay.example.com"],
// Filters for the timeline
[{ kinds: [1], limit: 20 }],
{
// EventStore instance for deduplication
eventStore,
// Any other options
...opts,
},
);
// Request the next page of the timeline
timelineLoader().subscribe((events) => {
// Handle events
});
2. **Replace SingleEventLoader**:
For code that is using the `SingleEventLoader` class, you can replace it with the `createEventLoader` function:
ts
// v1
const loader = new SingleEventLoader(rxNostr, ...opts);
loader.subscribe((event) => {
// Handle event
});
loader.next("event-id");
// v2
const eventLoader = createEventLoader(pool, { eventStore });
eventLoader({ id: "event-id", relays: ["wss://relay.example.com"] }).subscribe((event) => {
// Handle event
});
3. **Replace ReplaceableLoader**:
For code that is using the `ReplaceableLoader` class, you can replace it with the `createAddressLoader` function:
ts
// v1
const loader = new ReplaceableLoader(rxNostr, ...opts);
loader.subscribe((event) => {
// Handle event
});
loader.next({ kind: 0, pubkey });
// v2
const addressLoader = createAddressLoader(pool, { eventStore });
addressLoader({ kind: 0, pubkey, relays: ["wss://relay.example.com"] }).subscribe((events) => {
// Handle events
});
### New Loader Namespace [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#new-loader-namespace)
All loaders are now exported under the `Loaders` namespace:
ts
// v2 - Import from namespace
import { Loaders } from "applesauce-loaders";
const timelineLoader = Loaders.timelineLoader(pool, options);
const eventLoader = Loaders.eventPointerLoader(pool, options);
const addressLoader = Loaders.addressPointerLoader(pool, options);
2\. Queries to Models [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_2-queries-to-models)
----------------------------------------------------------------------------------------------------------
In v2, the `Queries` namespace has been renamed to `Models` throughout the codebase.
They are still functionally the same, but the names have been changed for clarity. and to allow the query store to be removed.
ts
// v1
import { Queries } from "applesauce-core";
// or import individual models
import { ProfileQuery, TimelineQuery } from "applesauce-core/queries";
const query = queryStore.createQuery(Queries.ProfileQuery, pubkey);
const timeline = queryStore.createQuery(Queries.TimelineQuery, { kinds: [1] });
// v2
import { Models } from "applesauce-core";
// or import individual models
import { ProfileModel, TimelineModel } from "applesauce-core/models";
const profile = eventStore.model(Models.ProfileModel, pubkey);
const timeline = eventStore.model(Models.TimelineModel, { kinds: [1] });
3\. QueryStore Removal [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_3-querystore-removal)
------------------------------------------------------------------------------------------------------------
### The Problem [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#the-problem-1)
In v1, the QueryStore was seperate from the EventStore. This made things difficult since apps would need to manage two separate stores.
ts
// v1
import { EventStore, QueryStore, Queries } from "applesauce-core";
const eventStore = new EventStore();
const queryStore = new QueryStore(eventStore);
const profile = queryStore.createQuery(Queries.ProfileQuery, pubkey);
### The Solution [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#the-solution-1)
In v2, QueryStore has been merged into EventStore. Use `eventStore.model()` directly:
ts
// v2
import { EventStore, Models } from "applesauce-core";
const eventStore = new EventStore();
const profile = eventStore.model(Models.ProfileModel, pubkey);
4\. React Integration Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_4-react-integration-changes)
--------------------------------------------------------------------------------------------------------------------------
### The Problem [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#the-problem-2)
In v1, React integration required QueryStore providers and specific hooks:
tsx
// v1
import { QueryStoreProvider } from "applesauce-react/providers";
import { useStoreQuery } from "applesauce-react/hooks";
import { Queries } from "applesauce-core";
function App() {
const queryStore = new QueryStore(eventStore);
return (
);
}
function Profile({ pubkey }) {
const profile = useStoreQuery(Queries.ProfileQuery, [pubkey]);
return
{profile?.name}
;
}
### The Solution [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#the-solution-2)
In v2, use EventStore directly with the renamed hook:
tsx
// v2
import { EventStoreProvider } from "applesauce-react/providers";
import { useEventModel } from "applesauce-react/hooks";
import { Models } from "applesauce-core";
function App() {
return (
);
}
function Profile({ pubkey }) {
const profile = useEventModel(Models.ProfileModel, [pubkey]);
return
{profile?.name}
;
}
### Migration Steps [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#migration-steps-1)
1. **Remove QueryStoreProvider**:
tsx
// v1 - Remove
// v2 - Use EventStoreProvider
2. **Update hook imports and usage**:
tsx
// v1
import { useStoreQuery } from "applesauce-react/hooks";
const profile = useStoreQuery(Queries.ProfileQuery, pubkey);
// v2
import { useEventModel } from "applesauce-react/hooks";
const profile = useEventModel(Models.ProfileModel, pubkey);
5\. EventStore Stream Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_5-eventstore-stream-changes)
--------------------------------------------------------------------------------------------------------------------------
### The Problem [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#the-problem-3)
In v1, EventStore streams used inconsistent naming without the RxJS convention. In v2, all EventStore streams follow RxJS naming conventions with `$` suffix:
ts
// v1 - Inconsistent stream naming
eventStore.inserts.subscribe((event) => {
console.log("New event:", event);
});
eventStore.updates.subscribe((event) => {
console.log("Updated event:", event);
});
eventStore.removes.subscribe((event) => {
console.log("Removed event:", event);
});
// v2 - Consistent stream naming with $ suffix
eventStore.insert$.subscribe((event) => {
console.log("New event:", event);
});
eventStore.update$.subscribe((event) => {
console.log("Updated event:", event);
});
eventStore.remove$.subscribe((event) => {
console.log("Removed event:", event);
});
### Migration Steps [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#migration-steps-2)
1. **Update stream subscriptions**:
ts
// v1
eventStore.inserts.subscribe(handler);
eventStore.updates.subscribe(handler);
eventStore.removes.subscribe(handler);
// v2
eventStore.insert$.subscribe(handler);
eventStore.update$.subscribe(handler);
eventStore.remove$.subscribe(handler);
6\. Removed APIs [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_6-removed-apis)
------------------------------------------------------------------------------------------------
Several APIs have been removed in v2. Here's how to handle them:
### Removed Methods [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#removed-methods)
* **`getPointerFromTag`**: This method has been removed. Use the individual pointer helper functions instead:
ts
// v1
import { getPointerFromTag } from "applesauce-core";
const pointer = getPointerFromTag(tag);
// v2 - Use specific pointer helpers
import { getEventPointerFromTag, getAddressPointerFromTag, getPubkeyPointerFromTag } from "applesauce-core/helpers";
const eventPointer = getEventPointerFromTag(tag);
const addressPointer = getAddressPointerFromTag(tag);
const pubkeyPointer = getPubkeyPointerFromTag(tag);
### Renamed Methods [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#renamed-methods)
* **`setEventContentEncryptionMethod`** → **`setEncryptedContentEncryptionMethod`**:
ts
// v1
import { setEventContentEncryptionMethod } from "applesauce-core";
setEventContentEncryptionMethod(kind, "nip04");
// v2
import { setEncryptedContentEncryptionMethod } from "applesauce-core";
setEncryptedContentEncryptionMethod(kind, "nip04");
7\. EventStore Return Value Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_7-eventstore-return-value-changes)
--------------------------------------------------------------------------------------------------------------------------------------
### EventStore.add() Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#eventstore-add-changes)
The `EventStore.add()` method now has more specific return behavior:
ts
// v2 - Updated return values
const result = eventStore.add(event);
if (result === null) {
// Event was ignored by verifyEvent function
console.log("Event was rejected");
} else if (result === event) {
// Event was successfully added as new
console.log("New event added");
} else {
// Event was a duplicate, existing event returned
console.log("Duplicate event, existing instance returned");
}
### EventStore.update() Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#eventstore-update-changes)
The `EventStore.update()` method now returns a boolean:
ts
// v2 - Returns boolean
const wasUpdated = eventStore.update(event);
if (wasUpdated) {
console.log("Event was updated successfully");
} else {
console.log("Event update failed");
}
### Migration Steps [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#migration-steps-3)
1. **Handle null returns from add()**:
ts
// v1
const addedEvent = eventStore.add(event);
// addedEvent was always the event or existing event
// v2
const result = eventStore.add(event);
if (result === null) {
// Handle rejected event
console.warn("Event was rejected by verification");
} else {
// Use the returned event (could be existing duplicate)
const addedEvent = result;
}
2. **Handle boolean returns from update()**:
ts
// v1
eventStore.update(event); // void return
// v2
const success = eventStore.update(event);
if (!success) {
console.warn("Failed to update event");
}
8\. Additional Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#_8-additional-changes)
------------------------------------------------------------------------------------------------------------
Summary of Required Changes [](https://hzrd149.github.io/applesauce/migration/v1-v2.html#summary-of-required-changes)
-----------------------------------------------------------------------------------------------------------------------
1. **Replace all loader classes** with functional loaders
2. **Rename all `Queries` to `Models`** in imports and usage
3. **Remove QueryStore** and use `eventStore.model()` directly
4. **Update React hooks** from `useStoreQuery` to `useEventModel`
5. **Replace QueryStoreProvider** with `EventStoreProvider`
6. **Update EventStore stream names** from `inserts`/`updates`/`removes` to `insert$`/`update$`/`remove$`
7. **Replace removed APIs** like `getPointerFromTag` with specific pointer helpers
8. **Rename methods** like `setEventContentEncryptionMethod` → `setEncryptedContentEncryptionMethod`
9. **Handle new return values** from `EventStore.add()` (can return `null`) and `EventStore.update()` (returns boolean)
---
# Beginner's Tutorial | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html#VPContent)
Return to top
Beginner's Tutorial [](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html#beginner-s-tutorial)
================================================================================================================
Welcome to the Applesauce tutorial! This step-by-step guide will teach you how to build reactive Nostr applications using the applesauce library ecosystem.
What You'll Learn [](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html#what-you-ll-learn)
------------------------------------------------------------------------------------------------------------
By the end of this tutorial, you'll understand how to:
* Set up an in-memory reactive database for Nostr events
* Parse and display user profiles and content
* Create reactive UI components that respond to data changes
* Connect to Nostr relays and subscribe to events
* Create and publish new Nostr events
Tutorial Structure [](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html#tutorial-structure)
--------------------------------------------------------------------------------------------------------------
This tutorial is broken down into digestible sections:
1. **[Introduction to EventStore](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html)
** - Learn about the reactive database at the heart of applesauce
2. **[Working with Helpers](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html)
** - Parse profiles and extract data from events
3. **[Building Reactive UI with Models](https://hzrd149.github.io/applesauce/tutorial/03-models.html)
** - Create React components that respond to data changes
4. **[Connecting to Relays](https://hzrd149.github.io/applesauce/tutorial/04-relays.html)
** - Subscribe to Nostr relays and receive events
5. **[Loading Specific Events with Loaders](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html)
** - Load specific events from relays
6. **[Creating Events with EventFactory](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html)
** - Set up event creation and signing
7. **[Publishing Events](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html)
** - Publish events to relays and handle responses
8. **[Using Actions](https://hzrd149.github.io/applesauce/tutorial/08-actions.html)
** - Run complex actions like following users
Prerequisites [](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html#prerequisites)
----------------------------------------------------------------------------------------------------
* Basic knowledge of JavaScript/TypeScript
* Familiarity with React hooks (`useState`, `useEffect`)
* Understanding of RxJS observables (helpful but not required)
* A Nostr extension wallet (like [Alby](https://getalby.com/)
or [nos2x](https://github.com/fiatjaf/nos2x)
)
Getting Started [](https://hzrd149.github.io/applesauce/tutorial/00-introduction.html#getting-started)
--------------------------------------------------------------------------------------------------------
Let's begin with [Introduction to EventStore](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html)
to learn about the foundation of applesauce applications.
---
# Glossary | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/introduction/glossary.html#VPContent)
Return to top
Glossary [](https://hzrd149.github.io/applesauce/introduction/glossary.html#glossary)
=======================================================================================
Event [](https://hzrd149.github.io/applesauce/introduction/glossary.html#event)
---------------------------------------------------------------------------------
A nostr event defined in [NIP-01](https://github.com/nostr-protocol/nips/blob/master/01.md)
Signer [](https://hzrd149.github.io/applesauce/introduction/glossary.html#signer)
-----------------------------------------------------------------------------------
A class that follows the [NIP-07](https://github.com/nostr-protocol/nips/blob/master/07.md)
API
Helper method [](https://hzrd149.github.io/applesauce/introduction/glossary.html#helper-method)
-------------------------------------------------------------------------------------------------
A function that takes an event and returns some computed value from it.
Event store [](https://hzrd149.github.io/applesauce/introduction/glossary.html#event-store)
---------------------------------------------------------------------------------------------
A in-memory database of events that can be subscribed to. (see [Event Store](https://hzrd149.github.io/applesauce/core/event-store.html)
)
Observable [](https://hzrd149.github.io/applesauce/introduction/glossary.html#observable)
-------------------------------------------------------------------------------------------
A lazy stream of values that is active when subscribed to. (see [Observables](https://rxjs.dev/guide/observable)
)
Model [](https://hzrd149.github.io/applesauce/introduction/glossary.html#model)
---------------------------------------------------------------------------------
Computed state from the event store that can be subscribed to. (see [Models](https://hzrd149.github.io/applesauce/core/models.html)
)
Encrypted content [](https://hzrd149.github.io/applesauce/introduction/glossary.html#encrypted-content)
---------------------------------------------------------------------------------------------------------
The `content` field of an event that is encrypted using NIP-04 or NIP-44.
Hidden content [](https://hzrd149.github.io/applesauce/introduction/glossary.html#hidden-content)
---------------------------------------------------------------------------------------------------
The `content` field that is encrypted by the signer to its own pubkey. primary used in NIP-51 lists.
Hidden tags [](https://hzrd149.github.io/applesauce/introduction/glossary.html#hidden-tags)
---------------------------------------------------------------------------------------------
An array of event tags that is in the **hidden content**
---
# 1. Introduction to EventStore | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#VPContent)
Return to top
1\. Introduction to EventStore [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#_1-introduction-to-eventstore)
====================================================================================================================================
The `EventStore` is the heart of every applesauce application. Its a reactive in-memory database specifically designed for Nostr events. Instead of constantly fetching data from relays, your UI components subscribe to the EventStore and automatically update when new events arrive.
What is the EventStore? [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#what-is-the-eventstore)
----------------------------------------------------------------------------------------------------------------------
The EventStore is a reactive database that:
* **Stores events in memory** for fast access
* **Deduplicates events** automatically
* **Handles replaceable events** (like profiles) by keeping only the latest version
* **Notifies subscribers** when relevant events are added, updated, or removed
* **Works with RxJS observables** for reactive programming
Creating an EventStore [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#creating-an-eventstore)
---------------------------------------------------------------------------------------------------------------------
Creating an EventStore is simple:
typescript
import { EventStore } from "applesauce-core";
// Create a single event store for your entire app
const eventStore = new EventStore();
> 💡 **Best Practice**: Create only one EventStore instance for your entire application and share it across components.
Adding Events [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#adding-events)
---------------------------------------------------------------------------------------------------
You can add events to the store using the `add()` method:
typescript
const event = {
content: "These numbers are so kind.",
created_at: 1745847253,
id: "621233a1ad1b91620f0b4a308c2113243a98925909cdb7b26284cbb4d835a18c",
kind: 1,
pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
sig: "eb8f30f7c44d031bfe315d476165f5cf29c21f1eaf07128f5a673cdb3b69ebf7902dacc06987f8d764b17225aefecdbc91992165e03372e40f57639a41203a1c",
tags: [],
};
// Add the event to the store
eventStore.add(event);
The EventStore automatically:
* **Deduplicates** - Won't add the same event twice
* **Replaces** - Updates replaceable events (kind 0 profiles, kind 3 contacts, etc.) with newer versions
* **Notifies** - Triggers updates for any components subscribed to this event
Checking for Events [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#checking-for-events)
---------------------------------------------------------------------------------------------------------------
You can check if events exist in the store:
typescript
// Check if a specific event exists
const hasEvent = eventStore.hasEvent("abc123...");
// Check if a user has a profile
const hasProfile = eventStore.hasReplaceable(0, "userPubkey");
// Get an event directly
const event = eventStore.getEvent("abc123...");
// Get a user's latest profile
const profile = eventStore.getReplaceable(0, "userPubkey");
Subscribing to Events [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#subscribing-to-events)
-------------------------------------------------------------------------------------------------------------------
The real power of the EventStore comes from its reactive subscriptions. Here are the main subscription types:
### Single Event Subscription [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#single-event-subscription)
typescript
// Subscribe to a specific event
eventStore.event("abc123...").subscribe((event) => {
if (event) {
console.log("Event found:", event);
} else {
console.log("Event not in store or was deleted");
}
});
### Replaceable Event Subscription [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#replaceable-event-subscription)
typescript
// Subscribe to a user's profile (kind 0)
eventStore.replaceable(0, "userPubkey").subscribe((profile) => {
if (profile) {
console.log("User profile:", profile);
}
});
### Stream Subscription [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#stream-subscription)
typescript
// Subscribe to all text notes as they're added
eventStore.stream({ kinds: [1] }).subscribe((event) => {
console.log("New text note:", event);
});
### Timeline Subscription [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#timeline-subscription)
typescript
// Subscribe to a sorted timeline of text notes
eventStore.timeline({ kinds: [1] }).subscribe((events) => {
console.log(`Timeline updated with ${events.length} notes`);
// events is a sorted array (newest first)
});
A Simple Example [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#a-simple-example)
---------------------------------------------------------------------------------------------------------
Let's see how this works in practice:
typescript
import { EventStore } from "applesauce-core";
// Create the store
const eventStore = new EventStore();
// Subscribe to all text notes
eventStore.timeline({ kinds: [1] }).subscribe((timeline) => {
console.log(`Timeline has ${timeline.length} notes`);
});
// Add some events
eventStore.add({
content: 'I just wish LLMs would stop saying their solutions are "comprehensive" or "powerful"',
created_at: 1749596768,
id: "77941979d4c04283fd9b2f0a280749248cbd41babe3a0731c1597a6d54ae7874",
kind: 1,
pubkey: "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322",
sig: "a0884549f09ef805d3ffa917c3d9e189882295f1b819c038e5d28ea1a668f4455f66ada40749dbdb6dfd48c323f507889330a2a4742b0cb66d8997afb31ff47e",
tags: [["client", "Coracle", "31990:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:1685968093690"]],
});
eventStore.add({
content: "These numbers are so kind.",
created_at: 1745847253,
id: "621233a1ad1b91620f0b4a308c2113243a98925909cdb7b26284cbb4d835a18c",
kind: 1,
pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
sig: "eb8f30f7c44d031bfe315d476165f5cf29c21f1eaf07128f5a673cdb3b69ebf7902dacc06987f8d764b17225aefecdbc91992165e03372e40f57639a41203a1c",
tags: [],
});
// The timeline subscription will fire twice:
// First: "Timeline has 1 notes"
// Then: "Timeline has 2 notes"
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#key-concepts)
-------------------------------------------------------------------------------------------------
* **Reactive**: Changes to the EventStore automatically update your UI
* **In-memory**: Events are stored in RAM for fast access (not persisted)
* **Deduplication**: The same event won't be added twice
* **Replaceable events**: Newer versions replace older ones automatically
* **Filters**: Use Nostr filters to subscribe to specific types of events
Why Use EventStore? [](https://hzrd149.github.io/applesauce/tutorial/01-event-store.html#why-use-eventstore)
--------------------------------------------------------------------------------------------------------------
Without EventStore, you'd need to:
* Manually track which events you've already received
* Handle event deduplication yourself
* Manually update UI components when new events arrive
* Deal with replaceable event logic
With EventStore, all of this is handled automatically, letting you focus on building your application logic.
---
# 2. Using Helper Methods | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#VPContent)
Return to top
2\. Using Helper Methods [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#_2-using-helper-methods)
====================================================================================================================
Helper methods are the Swiss Army knife of applesauce. They extract useful information from raw Nostr events, making it easy to display user profiles, parse content, and work with different event types.
What are Helpers? [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#what-are-helpers)
------------------------------------------------------------------------------------------------------
Helpers are utility functions that:
* **Parse event content** - Extract structured data from JSON or text
* **Handle different event types** - Kind 0 profiles, kind 1 notes, kind 3 contacts, etc.
* **Provide fallbacks** - Return sensible defaults when data is missing
* **Validate data** - Ensure the extracted data is properly formatted
Essential Profile Helpers [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#essential-profile-helpers)
-----------------------------------------------------------------------------------------------------------------------
Let's start with the most commonly used helpers for working with user profiles.
### Getting Profile Content [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#getting-profile-content)
The `getProfileContent` helper extracts and parses a user's profile from a kind 0 event:
typescript
import { getProfileContent } from "applesauce-core/helpers";
// A raw kind 0 profile event
const profileEvent = {
content:
'{"name":"fiatjaf","about":"~","picture":"https://fiatjaf.com/static/favicon.jpg","nip05":"_@fiatjaf.com","lud16":"fiatjaf@zbd.gg","website":"https://nostr.technology"}',
created_at: 1738588530,
id: "c43be8b4634298e97dde3020a5e6aeec37d7f5a4b0259705f496e81a550c8f8b",
kind: 0,
pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
relays: [""],
sig: "202a1bf6a58943d660c1891662dbdda142aa8e5bca9d4a3cb03cde816ad3bdda6f4ec3b880671506c2820285b32218a0afdec2d172de9694d83972190ab4f9da",
tags: [],
};
// Extract the profile content
const profile = getProfileContent(profileEvent);
console.log(profile);
// Output:
// {
// name: "fiatjaf",
// about: "~",
// picture: "https://fiatjaf.com/static/favicon.jpg",
// nip05: "_@fiatjaf.com",
// lud16: "fiatjaf@zbd.gg",
// website: "https://nostr.technology",
// }
If the profile content is invalid JSON or missing, `getProfileContent` returns `undefined` rather than throwing an error.
### Getting Display Names [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#getting-display-names)
The `getDisplayName` helper provides a user-friendly name with intelligent fallbacks:
typescript
import { getDisplayName } from "applesauce-core/helpers";
// Profile with a name
const profile1 = { name: "Alice", display_name: "Alice in Nostrland" };
console.log(getDisplayName(profile1)); // "Alice in Nostrland"
// Profile with only a name
const profile2 = { name: "Bob" };
console.log(getDisplayName(profile2)); // "Bob"
// Profile with no name
const profile3 = { about: "Just a user" };
console.log(getDisplayName(profile3)); // "Unknown"
// Can also pass a pubkey as fallback
console.log(getDisplayName(profile3, "npub1...")); // "npub1..."
The helper checks for names in this order:
1. `display_name` field
2. `name` field
3. Provided fallback
4. "Unknown"
### Getting Profile Pictures [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#getting-profile-pictures)
Similar to display names, `getProfilePicture` provides intelligent fallbacks for profile images:
typescript
import { getProfilePicture } from "applesauce-core/helpers";
// Profile with picture
const profile1 = { picture: "https://example.com/alice.jpg" };
console.log(getProfilePicture(profile1)); // "https://example.com/alice.jpg"
// Profile without picture - provide fallback
const profile2 = { name: "Bob" };
const fallbackUrl = "https://robohash.org/bob.png";
console.log(getProfilePicture(profile2, fallbackUrl)); // "https://robohash.org/bob.png"
Putting It Together: Profile Component [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#putting-it-together-profile-component)
------------------------------------------------------------------------------------------------------------------------------------------------
Let's create a React component that uses these helpers:
tsx
import React from "react";
import { getDisplayName, getProfilePicture } from "applesauce-core/helpers";
function ProfileCard({ profile }: { profile: NostrEvent }) {
// Get the profile content
const content = getProfileContent(profile);
// Get display name with pubkey fallback
const displayName = getDisplayName(content, profile.pubkey.slice(0, 8) + "...");
// Get profile picture with robohash fallback
const profilePicture = getProfilePicture(content, `https://robohash.org/${profile.pubkey}.png`);
return (
{displayName}
{content?.about &&
{content.about}
}
);
}
Other Useful Helpers [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#other-useful-helpers)
-------------------------------------------------------------------------------------------------------------
There are many more helpers available. Checkout the [typedocs](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html#addrelayhintstopointer)
to see all the helpers.
Here are some commonly used ones:
### Content Helpers [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#content-helpers)
typescript
import { getArticleTitle, getArticleSummary, getHashtags, getMentions } from "applesauce-core/helpers";
// Extract article title from long-form content (kind 30023)
const title = getArticleTitle(articleEvent);
// Get the users in a NIP-51 user list
const people = getEventPointersFromList(listEvent); // [{pubkey: "pubkey1"}, {pubkey: "pubkey2"}]
// Get outbox relays from a kind 10002 relay list event
const outboxes = getOutboxes(relayListEvent);
// ["wss://relay1.com", "wss://relay2.com"]
// Get inbox relays
const inboxes = getInboxes(relayListEvent);
// ["wss://inbox1.com", "wss://inbox2.com"]
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#key-concepts)
---------------------------------------------------------------------------------------------
* **Helpers parse raw events** into usable data
* **Fallbacks** prevent your UI from breaking
* **Composable** - combine helpers with EventStore subscriptions
* **Type-safe** - TypeScript definitions help catch errors
Real-World Example [](https://hzrd149.github.io/applesauce/tutorial/02-helpers.html#real-world-example)
---------------------------------------------------------------------------------------------------------
Here's a complete example showing helpers in action:
typescript
import { EventStore } from "applesauce-core";
import { getProfileContent, getDisplayName, getProfilePicture } from "applesauce-core/helpers";
const eventStore = new EventStore();
function displayUserInfo(pubkey: string) {
// Get the user's profile from the store
const profileEvent = eventStore.getReplaceable(0, pubkey);
if (profileEvent) {
const profile = getProfileContent(profileEvent);
const name = getDisplayName(profile, pubkey.slice(0, 8) + "...");
const picture = getProfilePicture(profile, `https://robohash.org/${pubkey}.png`);
console.log(`Name: ${name}`);
console.log(`Picture: ${picture}`);
console.log(`About: ${profile?.about || "No bio available"}`);
} else {
console.log("Profile not found in store");
}
}
---
# 5. Loading Specific Events with Loaders | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#VPContent)
Return to top
5\. Loading Specific Events with Loaders [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#_5-loading-specific-events-with-loaders)
====================================================================================================================================================
Loaders are specialized utilities that help you fetch specific events from relays efficiently. While RelayPool subscriptions are great for real-time feeds, loaders are perfect for loading individual events, user profiles, or addressable events on-demand.
What are Loaders? [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#what-are-loaders)
------------------------------------------------------------------------------------------------------
Loaders are functions that:
* **Use the relay pool** to fetch events from multiple relays
* **Load specific events** by ID, address, or other criteria
* **Handle multiple relays** automatically for better reliability
* **Return observables** that complete when the request is complete
* **Integrate with EventStore** to automatically store loaded events
Event Loader [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#event-loader)
---------------------------------------------------------------------------------------------
The `createEventLoader` function creates a loader for fetching events by their IDs.
### Setting up Event Loader [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#setting-up-event-loader)
typescript
import { createEventLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { EventStore } from "applesauce-core";
const pool = new RelayPool();
const eventStore = new EventStore();
// Create an event loader
const eventLoader = createEventLoader(pool, {
// Add events to the EventStore and deduplicate them
eventStore,
// Always check these relays for events
extraRelays: ["wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"],
});
### Loading Events by ID [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#loading-events-by-id)
typescript
// Make a request and subscribe to the result
eventLoader({
id: "621233a1ad1b91620f0b4a308c2113243a98925909cdb7b26284cbb4d835a18c",
relays: ["wss://relay.damus.io"],
}).subscribe((event) => {
console.log("Loaded event:", event.id);
console.log("Content:", event.content);
// Event is automatically added to EventStore
});
### Loading Multiple Events [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#loading-multiple-events)
Since the event loader returns an observable, you can use the `merge` operator from RxJS to make multiple requests at once.
typescript
// Make two requests at once and subscribe to the results
merge(
eventLoader({ id: "621233a1ad1b91620f0b4a308c2113243a98925909cdb7b26284cbb4d835a18c" }),
eventLoader({ id: "77941979d4c04283fd9b2f0a280749248cbd41babe3a0731c1597a6d54ae7874" }),
).subscribe({
next: (event) => {
console.log("Loaded event:", event.id);
},
complete: () => {
console.log("Both requested completed");
},
});
Address Loader [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#address-loader)
-------------------------------------------------------------------------------------------------
The `createAddressLoader` function creates a loader for fetching addressable events (kinds 30000-39999) by their `kind`, `pubkey` and optional `identifier`.
### Setting up Address Loader [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#setting-up-address-loader)
typescript
import { createAddressLoader } from "applesauce-loaders/loaders";
// Create an address loader
const addressLoader = createAddressLoader(pool, { eventStore });
### Loading Addressable Events [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#loading-addressable-events)
typescript
// Load a specific addressable event
const pointer = {
kind: 30023, // Long-form content
pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
identifier: "my-article",
relays: ["wss://relay.damus.io", "wss://nos.lol"],
};
// Create the request and subscribe to the result
addressLoader(pointer).subscribe((event) => {
console.log("Loaded article:", event.id);
console.log("Title:", getArticleTitle(event));
});
### Loading Multiple [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#loading-multiple)
Again, same as the event loader. the address loader returns an observable, so you can use the `merge` operator from RxJS to make multiple requests at once.
typescript
// Make two requests at once and subscribe to the results
merge(
addressLoader({ kind: 30023, pubkey: "pubkey1", identifier: "article-1" }),
addressLoader({ kind: 30023, pubkey: "pubkey2", identifier: "article-2" }),
).subscribe({
next: (event) => {
console.log("Loaded addressable event:", event.id);
},
complete: () => {
console.log("All addressable events loaded");
},
});
Practical Examples [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#practical-examples)
---------------------------------------------------------------------------------------------------------
### Loading a User's Profile [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#loading-a-user-s-profile)
typescript
const addressLoader = createAddressLoader(pool, { eventStore });
function loadUserProfile(pubkey: string, relays: string[]) {
return addressLoader({ kind: 0, pubkey, relays }).pipe(
// Take only the first (most recent) profile
take(1),
map((event) => getProfileContent(event)),
);
}
// Usage
loadUserProfile(
// Pass pubkey
"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
// And the relays to load from
["wss://relay.damus.io", "wss://nos.lol"],
).subscribe((profile) => {
if (profile) {
console.log("Profile loaded:", profile.name);
}
});
Loader Configuration [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#loader-configuration)
-------------------------------------------------------------------------------------------------------------
### Custom Relays [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#custom-relays)
The event loader and address loader both take an `extraRelays` option. This is an array of relays that will always be checked for events.
typescript
const addressLoader = createEventLoader(pool, {
eventStore,
extraRelays: ["wss://relay.damus.io", "wss://nos.lol"],
});
const articleLoader = createAddressLoader(pool, {
eventStore,
extraRelays: ["wss://relay.nostr.band", "wss://relay.damus.io"],
});
### Timeout Configuration [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#timeout-configuration)
The event loader and address loader both take a `timeout` option which can be used to configure the timeout for the requests.
typescript
// Create loader with custom timeout
const eventLoader = createEventLoader(pool, {
eventStore,
extraRelays: ["wss://relay.damus.io"],
timeout: 10000, // 10 second timeout
});
### Cache Configuration [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#cache-configuration)
The event loader and address loader both take a `cacheRequest` option which is used to load events from a local cache first.
typescript
// A method to load events from a local cache
async function cacheRequest(filters: Filter[]) {
// Make a request to your custom local cache
const events = await localCache.getEventsForFilters(filters);
// Return the events as an array of events
return events;
}
// Create the loader with the cache request option
const eventLoader = createEventLoader(pool, { eventStore, cacheRequest });
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#key-concepts)
---------------------------------------------------------------------------------------------
* **Loaders fetch specific events** on-demand, unlike subscriptions
* **Results are added to the EventStore** automatically
* **Observables complete** when the request is complete
Best Practices [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#best-practices)
-------------------------------------------------------------------------------------------------
### 1\. Check EventStore First [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#_1-check-eventstore-first)
typescript
// Always check if the event is already loaded
const existingEvent = eventStore.getEvent(eventId);
if (existingEvent) {
// Use existing event
console.log("Event already loaded:", existingEvent.content);
} else {
// Load from relays
eventLoader({ ids: [eventId] }).subscribe(/* ... */);
}
### 2\. Use Relays in requests [](https://hzrd149.github.io/applesauce/tutorial/05-loaders.html#_2-use-relays-in-requests)
Its better to pass the relays to the request than to use the `extraRelays` option.
typescript
// Use multiple relays for better reliability
const eventLoader = createEventLoader(pool, { eventStore });
eventLoader({ id: eventId, relays: ["wss://relay.damus.io", "wss://nos.lol"] }).subscribe((event) => {
console.log("Loaded event:", event.id);
});
---
# 7. Publishing Events | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#VPContent)
Return to top
7\. Publishing Events [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#_7-publishing-events)
=================================================================================================================
The final step in building a Nostr app is publishing your events to relays so other users can see them. The `RelayPool` provides methods for publishing events and handling the responses from relays.
What is Publishing? [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#what-is-publishing)
-------------------------------------------------------------------------------------------------------------
Publishing is the process of:
* **Sending signed events to relays** - Broadcasting your content to the network
* **Handling relay responses** - Success, errors, or rejection messages
* **Managing multiple relays** - Publishing to several relays for redundancy
* **Providing user feedback** - Showing publication status to users
Basic Event Publishing [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#basic-event-publishing)
--------------------------------------------------------------------------------------------------------------------
Here's how to publish a single event to a relay using the `pool.relay` method to select a single relay and the `publish` method to publish the event.
typescript
const pool = new RelayPool();
const event: NostrEvent = {
// ...signed nostr event
};
try {
const response = await pool.relay("wss://relay.damus.io").publish(event);
if (response.ok) {
console.log(`Event published successfully to ${response.from}`);
} else {
console.log(`Failed to publish event to ${response.from}: ${response.message}`);
}
} catch (error) {
console.error("Error publishing event:", error);
}
INFO
The `publish` method now returns a `Promise` directly, so you can use `await` or `.then()` instead of subscribing to an Observable.
Publishing to Multiple Relays [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#publishing-to-multiple-relays)
----------------------------------------------------------------------------------------------------------------------------------
For better reach and redundancy the `pool.publish` method can be used with multiple relays.
typescript
const relays = ["wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"];
const event: NostrEvent = {
// ...signed nostr event
};
try {
const responses = await pool.publish(relays, event);
responses.forEach((response) => {
if (response.ok) {
console.log(`Event published successfully to ${response.from}`);
} else {
console.log(`Failed to publish event to ${response.from}: ${response.message}`);
}
});
} catch (error) {
console.error("Error publishing to relays:", error);
}
Adding Events to the EventStore [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#adding-events-to-the-eventstore)
--------------------------------------------------------------------------------------------------------------------------------------
Once the event is published to relays, its good to add it to the event store so your UI can see it without needing to load it from the relay again.
typescript
try {
const response = await pool.relay("wss://relay.damus.io").publish(event);
if (response.ok) {
eventStore.add(event);
}
} catch (error) {
console.error("Error publishing event:", error);
}
Using with .then() instead of async/await [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#using-with-then-instead-of-async-await)
-------------------------------------------------------------------------------------------------------------------------------------------------------
If you prefer using `.then()` instead of async/await:
typescript
pool
.relay("wss://relay.damus.io")
.publish(event)
.then((response) => {
if (response.ok) {
console.log(`Event published successfully to ${response.from}`);
eventStore.add(event);
} else {
console.log(`Failed to publish event to ${response.from}: ${response.message}`);
}
})
.catch((error) => {
console.error("Error publishing event:", error);
});
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#key-concepts)
------------------------------------------------------------------------------------------------
* **Publishing sends events to relays** so others can see them
* **Handle relay responses** - success, errors, or rejections
* **Publish to multiple relays** for better reach and redundancy
* **Add published events to EventStore** to see them in your UI
* **Provide user feedback** about publishing status
* **Handle errors gracefully** with try/catch or .catch()
Best Practices [](https://hzrd149.github.io/applesauce/tutorial/07-publishing.html#best-practices)
----------------------------------------------------------------------------------------------------
1. **Always publish to multiple relays** for redundancy
2. **Handle rate limiting** with delays and retries
3. **Provide clear user feedback** about publishing status
4. **Add published events to EventStore** after successful publish
5. **Don't spam relays** - use reasonable delays between publishes
6. **Use try/catch blocks** to handle errors gracefully
---
# 4. Connecting to Relays | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#VPContent)
Return to top
4\. Connecting to Relays [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#_4-connecting-to-relays)
===================================================================================================================
The `RelayPool` class is your gateway to the Nostr network. It manages connections to multiple relays and provides a reactive interface for subscribing to events and publishing. Let's learn how to connect to relays and feed real events into your EventStore.
What is RelayPool? [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#what-is-relaypool)
-------------------------------------------------------------------------------------------------------
RelayPool is a connection manager that:
* **Manages WebSocket connections** to multiple Nostr relays
* **Handles reconnection** automatically when connections drop
* **Provides subscription methods** that return RxJS observables
* **Deduplicates subscriptions** across multiple relays
* **Handles relay-specific logic** like authentication and rate limiting
Creating a RelayPool [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#creating-a-relaypool)
------------------------------------------------------------------------------------------------------------
typescript
import { RelayPool } from "applesauce-relay";
// Create a relay pool
const pool = new RelayPool();
> 💡 **Best Practice**: Create one RelayPool instance for your entire application, just like EventStore.
Basic Relay Subscription [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#basic-relay-subscription)
--------------------------------------------------------------------------------------------------------------------
Here's how to subscribe to events from a single relay:
typescript
import { RelayPool, onlyEvents } from "applesauce-relay";
import { EventStore, mapEventsToStore } from "applesauce-core";
const pool = new RelayPool();
const eventStore = new EventStore();
// Subscribe to text notes from a specific relay
pool
.relay("wss://relay.damus.io")
.subscription({ kinds: [1], limit: 20 })
.pipe(
// Filter out non-event messages (EOSE, NOTICE, etc.)
onlyEvents(),
// Add events to the EventStore (deduplicates automatically)
mapEventsToStore(eventStore),
)
.subscribe((event) => {
console.log("New event added to store:", event.id);
});
Multiple Relays [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#multiple-relays)
--------------------------------------------------------------------------------------------------
The relay pool also provides a `subscription` method that can take an array of relays and opens the same subscription on all relays.
typescript
const relays = ["wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"];
// Subscribe to all relays simultaneously
pool
.subscription(relays, { kinds: [1], limit: 20 })
.pipe(onlyEvents(), mapEventsToStore(eventStore))
.subscribe((event) => {
console.log(event);
});
Duplicate Event Handling [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#duplicate-event-handling)
--------------------------------------------------------------------------------------------------------------------
The relay pool will return all events from all relays. this means that you get some duplicate events. to solve this you can use the `mapEventsToStore` operator.
typescript
const eventStore = new EventStore();
const relays = ["wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"];
pool
.subscription(relays, { kinds: [1], limit: 20 })
.pipe(onlyEvents(), mapEventsToStore(eventStore))
.subscribe((event) => {
console.log(event);
// Only logs unique events
});
Handling Relay Responses [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#handling-relay-responses)
--------------------------------------------------------------------------------------------------------------------
RelayPool subscriptions will emit events and the `"EOSE"` message when the relay has sent all events. Use the `onlyEvents()` operator to ignore the `"EOSE"` message:
typescript
pool
.relay("wss://relay.damus.io")
.subscription({ kinds: [1] })
.subscribe((message) => {
console.log(message);
// Logs: [event1, event2, event3, "EOSE"]
});
// vs with onlyEvents()
pool
.relay("wss://relay.damus.io")
.subscription({ kinds: [1] })
.pipe(onlyEvents())
.subscribe((event) => {
console.log("Event only:", event);
// Logs: [event1, event2, event3]
});
Error Handling [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#error-handling)
------------------------------------------------------------------------------------------------
The returned observable will error if the relay connection fails. make sure to handle errors gracefully.
typescript
pool
.relay("wss://relay.damus.io")
.subscription({ kinds: [1] })
.pipe(onlyEvents())
.subscribe({
next: (event) => {
// Handle successful event
eventStore.add(event);
},
error: (error) => {
console.error("Relay subscription error:", error);
// Maybe try connecting to a different relay
},
});
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#key-concepts)
--------------------------------------------------------------------------------------------
* **RelayPool manages connections** to multiple Nostr relays
* **Use onlyEvents()** to filter subscription messages
* **mapEventsToStore()** automatically adds events to EventStore
* **Subscriptions are reactive** - they automatically update your UI
* **Handle errors gracefully** - relay connections can fail
* **Deduplicate across relays** - same event from multiple relays is only added once
Common Patterns [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#common-patterns)
--------------------------------------------------------------------------------------------------
### Auto-reconnecting Timeline [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#auto-reconnecting-timeline)
typescript
function createAutoReconnectingSubscription(relayUrl: string) {
return pool
.relay(relayUrl)
.subscription({ kinds: [1], limit: 100 })
.pipe(
onlyEvents(),
mapEventsToStore(eventStore),
// Retry on error
retry({ count: 3, delay: 1000 }),
);
}
Example: React Timeline [](https://hzrd149.github.io/applesauce/tutorial/04-relays.html#example-react-timeline)
-----------------------------------------------------------------------------------------------------------------
Here's a complete react example using the RelayPool and EventStore to display a live timeline:
tsx
import React, { useEffect } from "react";
import { RelayPool, onlyEvents } from "applesauce-relay";
import { EventStore, mapEventsToStore, mapEventsToTimeline } from "applesauce-core";
import { ProfileModel, TimelineModel } from "applesauce-core/models";
import { getDisplayName, getProfilePicture } from "applesauce-core/helpers";
import { useObservableMemo } from "applesauce-react/hooks";
// Create global instances
const eventStore = new EventStore();
const pool = new RelayPool();
function NoteCard({ note }: { note: any }) {
const profile = useObservableMemo(() => eventStore.model(ProfileModel, note.pubkey), [note.pubkey]);
const name = getDisplayName(profile, note.pubkey.slice(0, 8) + "...");
const avatar = getProfilePicture(profile, `https://robohash.org/${note.pubkey}.png`);
return (
);
}
function LiveFeed() {
// This timeline will automatically update as new events arrive
const timeline = useObservableMemo(() => eventStore.model(TimelineModel, { kinds: [1] }), []);
return (
Latest Notes ({timeline?.length || 0})
{timeline?.map((note) => )}
);
}
function App() {
useEffect(() => {
// Start subscription when component mounts
const subscription = pool
.relay("wss://relay.damus.io")
.subscription({ kinds: [1], limit: 50 })
.pipe(
// Filter out non-event messages (EOSE, NOTICE, etc.)
onlyEvents(),
// Add events to the EventStore and deduplicate them
mapEventsToStore(eventStore),
)
.subscribe({
next: (event) => console.log("Added event:", event.id),
error: (err) => console.error("Relay error:", err),
complete: () => console.log("Subscription complete"),
});
// Cleanup subscription on unmount
return () => subscription.unsubscribe();
}, []);
return (
Live Nostr Feed
);
}
export default App;
---
# 3. Building Reactive UI with Models | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/03-models.html#VPContent)
Return to top
3\. Building Reactive UI with Models [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#_3-building-reactive-ui-with-models)
===========================================================================================================================================
Models are pre-built subscriptions that combine the EventStore with helpers to provide computed state. Instead of manually subscribing to events and parsing them, models give you clean, reactive data that automatically updates when relevant events change.
What are Models? [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#what-are-models)
---------------------------------------------------------------------------------------------------
Models are functions that:
* **Combine EventStore subscriptions with helpers** - No manual parsing needed
* **Provide computed state** - Transform raw events into useful data structures
* **Cache results** - Same model with same parameters reuses the same observable
* **Handle complex logic** - Like loading missing data or combining multiple event types
* **Return RxJS observables** - Can be subscribed to or used with operators
Using Models with EventStore [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#using-models-with-eventstore)
----------------------------------------------------------------------------------------------------------------------------
The `eventStore.model()` method is how you create and subscribe to models:
typescript
import { ProfileModel } from "applesauce-core/models";
// Create a model subscription
const profileSubscription = eventStore
.model(ProfileModel, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d")
.subscribe((profile) => {
if (profile) {
console.log("Profile:", profile);
// Profile is already parsed and ready to use
console.log("Name:", profile.name);
console.log("About:", profile.about);
} else {
console.log("Profile not found");
}
});
// Don't forget to unsubscribe when done
// profileSubscription.unsubscribe();
ProfileModel Example [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#profilemodel-example)
------------------------------------------------------------------------------------------------------------
The `ProfileModel` automatically handles profile events (kind 0) and parses their content:
typescript
import { EventStore } from "applesauce-core";
import { ProfileModel } from "applesauce-core/models";
const eventStore = new EventStore();
const pubkey = "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d";
// Subscribe to profile updates
eventStore.model(ProfileModel, pubkey).subscribe((profile) => {
if (profile) {
console.log("User profile updated:");
console.log("- Name:", profile.name || "No name");
console.log("- About:", profile.about || "No bio");
console.log("- Picture:", profile.picture || "No picture");
console.log("- Website:", profile.website || "No website");
}
});
// Add a profile event to see the model in action
eventStore.add({
content:
'{"name":"fiatjaf","about":"~","picture":"https://fiatjaf.com/static/favicon.jpg","nip05":"_@fiatjaf.com","lud16":"fiatjaf@zbd.gg","website":"https://nostr.technology"}',
created_at: 1738588530,
id: "c43be8b4634298e97dde3020a5e6aeec37d7f5a4b0259705f496e81a550c8f8b",
kind: 0,
pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
relays: [""],
sig: "202a1bf6a58943d660c1891662dbdda142aa8e5bca9d4a3cb03cde816ad3bdda6f4ec3b880671506c2820285b32218a0afdec2d172de9694d83972190ab4f9da",
tags: [],
});
// The subscription will fire with the parsed profile data
TimelineModel Example [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#timelinemodel-example)
--------------------------------------------------------------------------------------------------------------
The `TimelineModel` provides a sorted, reactive timeline of events:
typescript
import { TimelineModel } from "applesauce-core/models";
// Subscribe to all text notes (kind 1)
eventStore.model(TimelineModel, { kinds: [1] }).subscribe((timeline) => {
console.log(`Timeline updated: ${timeline.length} notes`);
timeline.forEach((note, index) => {
console.log(`${index + 1}. ${note.content.slice(0, 50)}...`);
console.log(` By: ${note.pubkey.slice(0, 8)}`);
console.log(` At: ${new Date(note.created_at * 1000).toLocaleString()}`);
});
});
// Add some notes to see the timeline update
eventStore.add({
content: 'I just wish LLMs would stop saying their solutions are "comprehensive" or "powerful"',
created_at: 1749596768,
id: "77941979d4c04283fd9b2f0a280749248cbd41babe3a0731c1597a6d54ae7874",
kind: 1,
pubkey: "97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322",
sig: "a0884549f09ef805d3ffa917c3d9e189882295f1b819c038e5d28ea1a668f4455f66ada40749dbdb6dfd48c323f507889330a2a4742b0cb66d8997afb31ff47e",
tags: [["client", "Coracle", "31990:97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322:1685968093690"]],
});
eventStore.add({
content: "These numbers are so kind.",
created_at: 1745847253,
id: "621233a1ad1b91620f0b4a308c2113243a98925909cdb7b26284cbb4d835a18c",
kind: 1,
pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
sig: "eb8f30f7c44d031bfe315d476165f5cf29c21f1eaf07128f5a673cdb3b69ebf7902dacc06987f8d764b17225aefecdbc91992165e03372e40f57639a41203a1c",
tags: [],
});
// Timeline will update twice, showing 1 note then 2 notes
Model Caching [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#model-caching)
----------------------------------------------------------------------------------------------
Models with the same parameters are cached and reused:
typescript
// These two subscriptions share the same underlying model
const subscription1 = eventStore
.model(ProfileModel, "621233a1ad1b91620f0b4a308c2113243a98925909cdb7b26284cbb4d835a18c")
.subscribe(console.log);
const subscription2 = eventStore
.model(ProfileModel, "621233a1ad1b91620f0b4a308c2113243a98925909cdb7b26284cbb4d835a18c")
.subscribe(console.log);
// Both subscriptions will receive the same data
// Only one actual subscription is created internally
// Always unsubscribe when done
subscription1.unsubscribe();
subscription2.unsubscribe();
Combining Models with RxJS Operators [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#combining-models-with-rxjs-operators)
--------------------------------------------------------------------------------------------------------------------------------------------
Since models return RxJS observables, you can use operators to transform the data:
typescript
import { map, filter } from "rxjs/operators";
// Only get profiles that have names
eventStore
.model(ProfileModel, pubkey)
.pipe(
filter((profile) => profile && profile.name),
map((profile) => profile.name.toUpperCase()),
)
.subscribe((name) => {
console.log("Profile name in caps:", name);
});
// Get timeline length
eventStore
.model(TimelineModel, { kinds: [1] })
.pipe(map((timeline) => timeline.length))
.subscribe((count) => {
console.log("Timeline has", count, "notes");
});
Other Useful Models [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#other-useful-models)
----------------------------------------------------------------------------------------------------------
### MailboxesModel [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#mailboxesmodel)
Gets a user's inbox and outbox relays from their relay list (kind 10002):
typescript
import { MailboxesModel } from "applesauce-core/models";
eventStore.model(MailboxesModel, pubkey).subscribe((mailboxes) => {
if (mailboxes) {
console.log("Outbox relays:", mailboxes.outboxes);
console.log("Inbox relays:", mailboxes.inboxes);
}
});
### RepliesModel [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#repliesmodel)
Gets all replies to a specific event:
typescript
import { RepliesModel } from "applesauce-core/models";
const noteId = "abc123...";
eventStore.model(RepliesModel, noteId).subscribe((replies) => {
console.log(`Found ${replies.length} replies to note ${noteId}`);
replies.forEach((reply) => {
console.log(`- ${reply.content.slice(0, 50)}...`);
});
});
### ContactsModel [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#contactsmodel)
Gets a user's contact list (kind 3):
typescript
import { ContactsModel } from "applesauce-core/models";
eventStore.model(ContactsModel, pubkey).subscribe((contacts) => {
if (contacts) {
console.log("Following", contacts.length, "people:");
contacts.forEach((contact) => {
console.log(`- ${contact.pubkey.slice(0, 8)}`);
});
}
});
Working with Multiple Models [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#working-with-multiple-models)
----------------------------------------------------------------------------------------------------------------------------
You can combine multiple models using the `combineLatest` operator from RxJS to build complex views:
typescript
import { combineLatest } from "rxjs";
const pubkey = "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d";
// Combine profile and timeline data
combineLatest([\
eventStore.model(ProfileModel, pubkey),\
eventStore.model(TimelineModel, { kinds: [1], authors: [pubkey] }),\
]).subscribe(([profile, timeline]) => {
const name = profile?.name || "Unknown";
const noteCount = timeline.length;
console.log(`${name} has posted ${noteCount} notes`);
});
Missing Event Handling [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#missing-event-handling)
----------------------------------------------------------------------------------------------------------------
Models handle missing events gracefully and typically return `undefined` when events aren't available:
typescript
eventStore.model(ProfileModel, "nonexistent-pubkey").subscribe((profile) => {
if (profile === undefined) {
console.log("Profile not found or still loading");
} else {
console.log("Profile loaded:", profile);
}
});
Model Performance [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#model-performance)
------------------------------------------------------------------------------------------------------
Models are designed for performance:
* **Cached** - Models with the same parameters are reused
* **Lazy** - Only created when subscribed to
* **Efficient** - Use internal EventStore subscriptions
* **Memory-safe** - Automatically cleaned up when no subscribers
typescript
// This is efficient - only one ProfileModel created
const model = eventStore.model(ProfileModel, pubkey);
const sub1 = model.subscribe(handleProfile1);
const sub2 = model.subscribe(handleProfile2);
const sub3 = model.subscribe(handleProfile3);
// Clean up all subscriptions
sub1.unsubscribe();
sub2.unsubscribe();
sub3.unsubscribe();
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#key-concepts)
--------------------------------------------------------------------------------------------
* **Models transform raw events** into useful data structures
* **Use `eventStore.model()`** to create model subscriptions
* **Models return observables** - can be used with RxJS operators
* **Models handle parsing** - no need to use helper methods manually
* **Models are reactive** - automatically update when events change
Example: React user profile [](https://hzrd149.github.io/applesauce/tutorial/03-models.html#example-react-user-profile)
-------------------------------------------------------------------------------------------------------------------------
For React applications, you can use the `useObservableMemo` hook from `applesauce-react` to easily integrate models:
tsx
import React from "react";
import { useObservableMemo } from "applesauce-react/hooks";
import { ProfileModel, TimelineModel } from "applesauce-core/models";
import { getDisplayName, getProfilePicture } from "applesauce-core/helpers";
function UserProfile({ pubkey }: { pubkey: string }) {
// Create a new model for the user's profile and subscribe to it
const profile = useObservableMemo(() => eventStore.model(ProfileModel, pubkey), [pubkey]);
// Create a new model for the user's notes and subscribe to it
const timeline = useObservableMemo(
() => eventStore.model(TimelineModel, { kinds: [1], authors: [pubkey] }),
[pubkey],
);
const displayName = getDisplayName(profile, pubkey.slice(0, 8) + "...");
const avatar = getProfilePicture(profile, `https://robohash.org/${pubkey}.png`);
return (
{displayName}
{profile?.about &&
{profile.about}
}
Notes ({timeline?.length || 0})
{timeline?.map((note) => (
{note.content}
))}
);
}
---
# Relays | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/relays/package.html#VPContent)
Return to top
Relays [](https://hzrd149.github.io/applesauce/relays/package.html#relays)
============================================================================
The `applesauce-relay` package contains a few classes to make connecting to relays easier.
Features [](https://hzrd149.github.io/applesauce/relays/package.html#features)
--------------------------------------------------------------------------------
* Simple to setup
* Automatic connection management
* NIP-42 auth support
* Negentrapy support
Installation [](https://hzrd149.github.io/applesauce/relays/package.html#installation)
----------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-relay
sh
yarn install applesauce-relay
sh
pnpm install applesauce-relay
---
# Relay Pool | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/relays/pool.html#VPContent)
Return to top
Relay Pool [](https://hzrd149.github.io/applesauce/relays/pool.html#relay-pool)
=================================================================================
The `RelayPool` class in `applesauce-relay` provides a powerful way to manage multiple relay connections, allowing you to interact with multiple relays as if they were a single entity.
Features [](https://hzrd149.github.io/applesauce/relays/pool.html#features)
-----------------------------------------------------------------------------
* Connect to multiple relays
* Create and manage groups of relays
* Send requests and events to multiple relays simultaneously
* Maintain a blacklist of relays to avoid
Relay Management [](https://hzrd149.github.io/applesauce/relays/pool.html#relay-management)
---------------------------------------------------------------------------------------------
The RelayPool provides methods to create and manage relay connections:
typescript
// Get or create a relay connection
const relay = pool.relay("wss://relay.example.com");
// Create a group of relays
const group = pool.group(["wss://relay1.example.com", "wss://relay2.example.com"]);
Making Requests [](https://hzrd149.github.io/applesauce/relays/pool.html#making-requests)
-------------------------------------------------------------------------------------------
The RelayPool provides several methods to interact with relays. These methods mirror those found in the `Relay` class, allowing you to use familiar patterns while working with multiple relays simultaneously.
### REQ Method [](https://hzrd149.github.io/applesauce/relays/pool.html#req-method)
The `req` method sends a subscription request to multiple relays:
typescript
// Send a REQ to multiple relays
pool
.req(relays, {
kinds: [1],
limit: 10,
})
.subscribe({
next: (response) => {
if (response === "EOSE") {
console.log("End of stored events from all relays");
} else {
console.log("Event", response);
}
},
error: (error) => {
console.error("Subscription error:", error);
},
});
### Event Method [](https://hzrd149.github.io/applesauce/relays/pool.html#event-method)
The `event` method sends an `EVENT` message to multiple relays and returns an observable of the responses from each relay.
typescript
const event = {
kind: 1,
content: "Hello from RelayPool!",
created_at: Math.floor(Date.now() / 1000),
tags: [],
// ... other required fields
};
// Subscribe to a stream of responses
pool.event(relays, event).subscribe({
next: (response) => {
console.log(`Published to ${response.from}:`, response.ok);
if (!response.ok) console.log(`Error message: ${response.message}`);
},
complete: () => {
console.log("Publishing complete");
},
});
### Publish Method [](https://hzrd149.github.io/applesauce/relays/pool.html#publish-method)
The `publish` method is a wrapper around the `event` method that returns a `Promise` and automatically handles reconnecting and retrying:
typescript
// Publish with retries (defaults to 3 retries)
const responses = await pool.publish(relays, event);
for (const response of responses) {
console.log(`Published to ${response.from}:`, response.ok, response.message);
}
### Request Method [](https://hzrd149.github.io/applesauce/relays/pool.html#request-method)
The `request` method allows you to make one-off requests with automatic retries:
typescript
// Request with automatic retries
pool
.request(
relays,
{
kinds: [1],
authors: ["pubkey1", "pubkey2"],
limit: 50,
},
{
retries: 2,
timeout: 5000, // 5 seconds
},
)
.subscribe({
next: (event) => console.log("Received event:", event.id),
complete: () => console.log("Request complete"),
});
### Subscription Method [](https://hzrd149.github.io/applesauce/relays/pool.html#subscription-method)
The `subscription` method creates persistent subscriptions that automatically reconnect:
typescript
// Create persistent subscription
const subscription = pool
.subscription(
relays,
{
kinds: [1, 7],
"#t": ["nostr"],
},
{
id: "custom-sub-id", // optional custom subscription ID
retries: Infinity, // retry forever
},
)
.subscribe({
next: (response) => {
if (response === "EOSE") {
console.log("End of stored events");
} else {
console.log("Subscription update:", response);
}
},
});
// Later, you can unsubscribe
subscription.unsubscribe();
All of these methods accept the same parameters as their counterparts in the `Relay` class, making it easy to transition between working with individual relays and relay pools.
Relay Groups [](https://hzrd149.github.io/applesauce/relays/pool.html#relay-groups)
-------------------------------------------------------------------------------------
The `RelayGroup` class is used internally by RelayPool to manage collections of relays. You can access relay groups directly through the pool:
typescript
// Create a group of relays
const group = pool.group(["wss://relay1.example.com", "wss://relay2.example.com"]);
// Make requests to the group
group.req({ kinds: [1] }).subscribe((response) => console.log(response));
// Send events to the group
group.event(event).subscribe((response) => console.log(response));
// Use other group methods
group.publish(event).subscribe((response) => console.log(response));
group.request({ kinds: [1] }).subscribe((event) => console.log(event));
group.subscription({ kinds: [1] }).subscribe((response) => console.log(response));
The RelayGroup intelligently merges responses from multiple relays, emitting EOSE only when all relays have sent their EOSE signals.
Observable Properties [](https://hzrd149.github.io/applesauce/relays/pool.html#observable-properties)
-------------------------------------------------------------------------------------------------------
The RelayPool provides observables for tracking relays and groups:
typescript
// Subscribe to changes in the relays map
pool.relays$.subscribe((relaysMap) => {
console.log("Relays updated:", Array.from(relaysMap.keys()));
});
// Subscribe to changes in the relay groups map
pool.groups$.subscribe((groupsMap) => {
console.log("Groups updated:", Array.from(groupsMap.keys()));
});
---
# Loaders | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/loaders/package.html#VPContent)
Return to top
Loaders [](https://hzrd149.github.io/applesauce/loaders/package.html#loaders)
===============================================================================
The `applesauce-loaders` package provides a set of pre-built loaders for common methods of loading events from a relay pool.
Features [](https://hzrd149.github.io/applesauce/loaders/package.html#features)
---------------------------------------------------------------------------------
* Easy to setup and use
* Built-in request batching
* Built-in event deduplication (using an event store)
* Flexible enough to work with any relay connection pool
Installation [](https://hzrd149.github.io/applesauce/loaders/package.html#installation)
-----------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-loaders
sh
yarn install applesauce-loaders
sh
pnpm install applesauce-loaders
---
# Factory | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/factory/package.html#VPContent)
Return to top
Factory [](https://hzrd149.github.io/applesauce/factory/package.html#factory)
===============================================================================
The `applesauce-factory` package provides the `EventFactory` and operations for creating and modifying Nostr events.
Features [](https://hzrd149.github.io/applesauce/factory/package.html#features)
---------------------------------------------------------------------------------
* Works with any NIP-07 signer ( `applesauce-signers` )
* Tons of pre-built operations for creating and modifying events
* Support for encrypted tags in NIP-51 events
* Pre-built operations for NIP-59 gift wrapping
* Blueprints for common event types
* Relays hints for `e` and `p` tags
Installation [](https://hzrd149.github.io/applesauce/factory/package.html#installation)
-----------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-factory
sh
yarn install applesauce-factory
sh
pnpm install applesauce-factory
---
# Accounts | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/accounts/package.html#VPContent)
Return to top
Accounts [](https://hzrd149.github.io/applesauce/accounts/package.html#accounts)
==================================================================================
The `applesauce-accounts` package provides a set of classes for managing accounts and their associated signers.
Features [](https://hzrd149.github.io/applesauce/accounts/package.html#features)
----------------------------------------------------------------------------------
* Full account manager class
* Support for saving and loading accounts from JSON
* Integrated with the `applesauce-signers` package
* Suports custom account types
* Custom account metadata (name, icon, etc)
Installation [](https://hzrd149.github.io/applesauce/accounts/package.html#installation)
------------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-accounts
sh
yarn install applesauce-accounts
sh
pnpm install applesauce-accounts
---
# Zaps Loader | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/loaders/zaps-loader.html#VPContent)
Return to top
Zaps Loader [](https://hzrd149.github.io/applesauce/loaders/zaps-loader.html#zaps-loader)
===========================================================================================
The Zaps Loader is a specialized loader for fetching [NIP-57](https://github.com/nostr-protocol/nips/blob/master/57.md)
zap events for any given Nostr event. It is built on top of the [Tag Value Loader](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html)
and automatically handles both regular events and addressable events.
WARNING
The observable returned by the Zaps Loader MUST be subscribed to in order for the request to be made. No request will be sent until you call `.subscribe()` on the returned observable.
Basic Usage [](https://hzrd149.github.io/applesauce/loaders/zaps-loader.html#basic-usage)
-------------------------------------------------------------------------------------------
ts
import { createZapsLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
// Create a relay pool
const pool = new RelayPool();
// Create a zaps loader (do this once at the app level)
const zapsLoader = createZapsLoader(pool);
// Later, use the loader to fetch zaps for any event
const someEvent = { id: "event_id", kind: 1 /* ... */ };
zapsLoader(someEvent, ["wss://relay.example.com"]).subscribe((zapEvent) => {
console.log("Received zap:", zapEvent);
});
How It Works [](https://hzrd149.github.io/applesauce/loaders/zaps-loader.html#how-it-works)
---------------------------------------------------------------------------------------------
The Zaps Loader automatically:
* Determines if the target event is addressable (replaceable) or a regular event
* Uses the appropriate tag (`a` for addressable events, `e` for regular events) to fetch zaps
* Merges relay hints from the event's seen relays (if `useSeenRelays` is enabled)
* Filters results to only return NIP-57 zap events (kind 9735)
Configuration Options [](https://hzrd149.github.io/applesauce/loaders/zaps-loader.html#configuration-options)
---------------------------------------------------------------------------------------------------------------
The `createZapsLoader` function accepts these options:
* `useSeenRelays`: Whether to include relays where the event was seen (default `true`)
* All other options from Tag Value Loader: `bufferTime`, `bufferSize`, `authors`, `since`, `cacheRequest`, `extraRelays`, `eventStore`
ts
const zapsLoader = createZapsLoader(pool, {
useSeenRelays: true,
bufferTime: 500,
eventStore,
cacheRequest,
});
Example with React [](https://hzrd149.github.io/applesauce/loaders/zaps-loader.html#example-with-react)
---------------------------------------------------------------------------------------------------------
tsx
import { createZapsLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { useEffect, useState } from "react";
// Setup at app level
const pool = new RelayPool();
const zapsLoader = createZapsLoader(pool);
function ZapsComponent({ event }) {
const [zaps, setZaps] = useState([]);
useEffect(() => {
const subscription = zapsLoader(event).subscribe((zapEvent) => {
setZaps((prev) => [...prev, zapEvent]);
});
return () => subscription.unsubscribe();
}, [event.id]);
return (
Zaps ({zaps.length})
{zaps.map((zap) => (
Zap amount: {/* parse zap amount from event */}
))}
);
}
Addressable vs Regular Events [](https://hzrd149.github.io/applesauce/loaders/zaps-loader.html#addressable-vs-regular-events)
-------------------------------------------------------------------------------------------------------------------------------
The loader automatically handles both types of events:
* **Regular events** (kind 0, 1, etc.): Uses `e` tags to find zaps
* **Addressable events** (kind 30000+): Uses `a` tags with the replaceable address
This abstraction means you don't need to worry about the event type - just pass any event to the loader.
---
# Event Loader | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/loaders/event-loader.html#VPContent)
Return to top
Event Loader [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#event-loader)
==============================================================================================
The Event Loader is a specialized loader for fetching Nostr events by their IDs. It provides an efficient way to batch and deduplicate requests, cache results, and handle relay hints.
WARNING
The observable returned by the Event Loader MUST be subscribed to in order for the request to be made. No request will be sent until you call `.subscribe()` on the returned observable.
Basic Usage [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#basic-usage)
--------------------------------------------------------------------------------------------
ts
import { createEventLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
// Create a relay pool
const pool = new RelayPool();
// Create an event loader (do this once at the app level)
const eventLoader = createEventLoader(pool);
// Later, use the loader to fetch events
eventLoader({
id: "event_id",
relays: ["wss://relay.example.com"],
}).subscribe((event) => {
console.log("Loaded event:", event);
});
Configuration Options [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#configuration-options)
----------------------------------------------------------------------------------------------------------------
The `createEventLoader` function accepts these options:
* `bufferTime`: Time interval to buffer requests in ms (default 1000)
* `bufferSize`: Max buffer size (default 200)
* `eventStore`: An event store used to deduplicate events
* `cacheRequest`: A method used to load events from a local cache
* `followRelayHints`: Whether to follow relay hints (default true)
* `extraRelays`: An array of relays to always fetch from
WARNING
If an event store is not provided, the loader will not be able to deduplicate events.
Working with Relay Pools [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#working-with-relay-pools)
----------------------------------------------------------------------------------------------------------------------
The Event Loader requires a request method for loading Nostr events from relays. You can provide this in multiple ways:
### Using a RelayPool instance [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#using-a-relaypool-instance)
The simplest approach is to pass a RelayPool instance directly:
ts
import { createEventLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
const pool = new RelayPool();
const eventLoader = createEventLoader(pool, {
eventStore,
cacheRequest,
});
### Using a custom request method [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#using-a-custom-request-method)
You can also provide a custom request method, such as one from nostr-tools:
ts
import { createEventLoader } from "applesauce-loaders/loaders";
import { SimplePool } from "nostr-tools";
const pool = SimplePool();
// Create a custom request function using nostr-tools
function customRequest(relays, filters) {
return new Observable((observer) => {
const sub = pool.subscribeMany(relays, filters, {
onevent: (event) => observer.next(event),
eose: () => observer.complete(),
});
return () => sub.close();
});
}
// Create event loader with custom request
const eventLoader = createEventLoader(customRequest, options);
Loading from cache [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#loading-from-cache)
----------------------------------------------------------------------------------------------------------
For improved performance, you can configure the loader to use a local cache:
ts
import { createEventLoader } from "applesauce-loaders/loaders";
import { openDB, getEventsForFilters } from "nostr-idb";
// Setup a local event cache
const cache = await openDB();
function cacheRequest(filters) {
return getEventsForFilters(cache, filters);
}
const eventLoader = createEventLoader(pool, {
cacheRequest,
eventStore,
});
// Events from cache are automatically marked using markFromCache
eventLoader(pointer).subscribe((event) => {
if (!isFromCache(event)) {
// This is a new event from the network
addEvents(cache, [event]);
}
});
Real-World Example [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#real-world-example)
----------------------------------------------------------------------------------------------------------
Here's how you might use the Event Loader in a React application:
tsx
import { createEventLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { EventStore } from "applesauce-core";
import { useEffect } from "react";
// Setup at app level
const eventStore = new EventStore();
const pool = new RelayPool();
const eventLoader = createEventLoader(pool, { eventStore });
function EventComponent({ eventId, relays }) {
const [event, setEvent] = useState(null);
// Load the event when component mounts
useEffect(() => {
const subscription = eventLoader({
id: eventId,
relays,
}).subscribe((event) => setEvent(event));
return () => subscription.unsubscribe();
}, [eventId]);
if (!event) return
Loading...
;
return
{event.content}
;
}
Loading Sequence [](https://hzrd149.github.io/applesauce/loaders/event-loader.html#loading-sequence)
------------------------------------------------------------------------------------------------------
The Event Loader follows this sequence when loading events:
1. Attempt to load from cache (if configured)
2. Use relay hints from event pointers (if enabled)
3. Fetch from additional relays (if configured)
This approach ensures efficient event loading with minimal network requests.
---
# Address Loader | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/loaders/address-loader.html#VPContent)
Return to top
Address Loader [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#address-loader)
====================================================================================================
The Address Loader is a specialized loader for fetching Nostr replaceable events by their address (kind, pubkey, and optional identifier). It provides an efficient way to batch and deduplicate requests, cache results, and handle relay hints.
WARNING
The observable returned by the Address Loader MUST be subscribed to in order for the request to be made. No request will be sent until you call `.subscribe()` on the returned observable.
Basic Usage [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#basic-usage)
----------------------------------------------------------------------------------------------
ts
import { createAddressLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
// Create a relay pool
const pool = new RelayPool();
// Create an address loader (do this once at the app level)
const addressLoader = createAddressLoader(pool);
// Later, use the loader to fetch events by address
addressLoader({
kind: 0,
pubkey: "user_pubkey",
relays: ["wss://relay.example.com"],
}).subscribe((event) => {
console.log("Loaded profile:", event);
});
Configuration Options [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#configuration-options)
------------------------------------------------------------------------------------------------------------------
The `createAddressLoader` function accepts these options:
* `bufferTime`: Time interval to buffer requests in ms (default 1000)
* `bufferSize`: Max buffer size (default 200)
* `eventStore`: An event store used to deduplicate events
* `cacheRequest`: A method used to load events from a local cache
* `followRelayHints`: Whether to follow relay hints (default true)
* `lookupRelays`: Fallback lookup relays to check when event can't be found
* `extraRelays`: An array of relays to always fetch from
WARNING
If an event store is not provided, the loader will not be able to deduplicate events.
Working with Relay Pools [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#working-with-relay-pools)
------------------------------------------------------------------------------------------------------------------------
The Address Loader requires a request method for loading Nostr events from relays. You can provide this in multiple ways:
### Using a RelayPool instance [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#using-a-relaypool-instance)
The simplest approach is to pass a RelayPool instance directly:
ts
import { createAddressLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
const pool = new RelayPool();
const addressLoader = createAddressLoader(pool, {
eventStore,
cacheRequest,
});
### Using a custom request method [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#using-a-custom-request-method)
You can also provide a custom request method, such as one from nostr-tools:
ts
import { createAddressLoader } from "applesauce-loaders/loaders";
import { SimplePool } from "nostr-tools";
import { Observable } from "rxjs";
const pool = SimplePool();
// Create a custom request function using nostr-tools
function customRequest(relays, filters) {
return new Observable((observer) => {
const sub = pool.subscribeMany(relays, filters, {
onevent: (event) => observer.next(event),
eose: () => observer.complete(),
});
return () => sub.close();
});
}
// Create address loader with custom request
const addressLoader = createAddressLoader(customRequest, options);
Loading from cache [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#loading-from-cache)
------------------------------------------------------------------------------------------------------------
For improved performance, you can configure the loader to use a local cache:
ts
import { createAddressLoader } from "applesauce-loaders/loaders";
import { openDB, getEventsForFilters } from "nostr-idb";
// Setup a local event cache
const cache = await openDB();
function cacheRequest(filters) {
return getEventsForFilters(cache, filters);
}
const addressLoader = createAddressLoader(pool, {
cacheRequest,
eventStore,
});
// Events from cache are automatically marked using markFromCache
addressLoader({ kind: 0, pubkey: "user_pubkey" }).subscribe((event) => {
if (!isFromCache(event)) {
// This is a new event from the network
addEvents(cache, [event]);
}
});
Real-World Example [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#real-world-example)
------------------------------------------------------------------------------------------------------------
Here's how you might use the Address Loader in a React application to load user profiles:
tsx
import { EventStore } from "applesauce-core";
import { createAddressLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { kinds } from "nostr-tools";
import { useEffect, useState } from "react";
import { EMPTY, ignoreElements, merge } from "rxjs";
// Setup at app level
const eventStore = new EventStore();
const pool = new RelayPool();
const addressLoader = createAddressLoader(pool, {
eventStore,
lookupRelays: ["wss://purplepag.es/"],
});
function ProfileComponent({ pubkey, relays }) {
const [profile, setProfile] = useState(null);
// Load the profile when component mounts
useEffect(() => {
// Check if we already have the profile
if (eventStore.hasReplaceable(kinds.Metadata, pubkey)) {
setProfile(eventStore.getLatestReplaceable(kinds.Metadata, pubkey));
return;
}
// Load profile from the network
const subscription = addressLoader({
kind: kinds.Metadata,
pubkey,
relays,
}).subscribe((event) => {
setProfile(JSON.parse(event.content));
});
return () => subscription.unsubscribe();
}, [pubkey]);
if (!profile) return
Loading profile...
;
return (
{profile.name || "Anonymous"}
{profile.picture && }
{profile.about}
);
}
Loading Sequence [](https://hzrd149.github.io/applesauce/loaders/address-loader.html#loading-sequence)
--------------------------------------------------------------------------------------------------------
The Address Loader follows this sequence when loading events:
1. Attempt to load from cache (if configured)
2. Use relay hints from address pointers (if enabled)
3. Fetch from additional relays (if configured)
4. Try fallback lookup relays (if configured)
This approach ensures efficient event loading with minimal network requests while providing good fallback options for retrieving replaceable events.
---
# RxJS Operators | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/relays/operators.html#VPContent)
Return to top
RxJS Operators [](https://hzrd149.github.io/applesauce/relays/operators.html#rxjs-operators)
==============================================================================================
The `applesauce-relay` package provides several RxJS operators to help process and transform streams of events from Nostr relays.
onlyEvents [](https://hzrd149.github.io/applesauce/relays/operators.html#onlyevents)
--------------------------------------------------------------------------------------
The `onlyEvents` operator filters the subscription response stream to only emit Nostr events, removing any "EOSE" (End Of Stored Events) messages.
typescript
import { onlyEvents } from "applesauce-relay/operators";
// Subscribe to events and only receive Nostr events (no EOSE messages)
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(onlyEvents())
.subscribe((event) => {
// This will only receive events, not "EOSE" strings
console.log(event.id);
});
markFromRelay [](https://hzrd149.github.io/applesauce/relays/operators.html#markfromrelay)
--------------------------------------------------------------------------------------------
The `markFromRelay` operator adds metadata to events indicating which relay they were received from. This is useful for tracking event propagation across the network.
typescript
import { markFromRelay } from "applesauce-relay/operators";
import { getSeenRelays } from "applesauce-core/helpers";
// Create a new relay instance
const relay = new Relay("wss://relay.example.com");
// Subscribe to events and mark them as coming from this relay
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(markFromRelay(relay.url))
.subscribe((response) => {
if (typeof response !== "string") {
// Check which relays this event has been seen on
console.log(getSeenRelays(response));
}
});
completeOnEose [](https://hzrd149.github.io/applesauce/relays/operators.html#completeoneose)
----------------------------------------------------------------------------------------------
The `completeOnEose` operator completes the subscription stream when an "EOSE" (End Of Stored Events) message is received. This is particularly useful for one-off requests where you want to collect all events and then process them together.
typescript
import { completeOnEose } from "applesauce-relay/operators";
import { lastValueFrom } from "rxjs";
import { toArray } from "rxjs/operators";
// Method 1: Complete the stream when EOSE is received
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(completeOnEose())
.subscribe({
next: (event) => console.log(event.id),
complete: () => console.log("All stored events received"),
});
// Method 2: Collect all events into an array
const events = await lastValueFrom(
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(completeOnEose(), toArray()),
);
// Method 3: Include the EOSE message in the stream
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(completeOnEose(true))
.subscribe((response) => {
if (response === "EOSE") {
console.log("End of stored events");
} else {
console.log("Event:", response.id);
}
});
storeEvents [](https://hzrd149.github.io/applesauce/relays/operators.html#storeevents)
----------------------------------------------------------------------------------------
The `storeEvents` operator adds all events from the subscription stream to an `EventStore` without filtering or removing duplicates. The stream continues to emit all original messages.
typescript
import { storeEvents } from "applesauce-relay/operators";
import { EventStore } from "applesauce-core";
// Create an event store
const eventStore = new EventStore();
// Subscribe to events and add them to the store
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(storeEvents(eventStore))
.subscribe((response) => {
if (response === "EOSE") {
// Access all events from the store
const allEvents = eventStore.getAll();
console.log(`Received ${allEvents.length} events`);
}
});
toEventStore [](https://hzrd149.github.io/applesauce/relays/operators.html#toeventstore)
------------------------------------------------------------------------------------------
The `toEventStore` operator adds all events to an `EventStore`, removes duplicates, and returns a sorted array of events when the EOSE message is received. This is perfect for fetching and processing a complete set of events.
WARNING
This operator is deprecated. It's recommended to use the `mapEventsToStore` and `mapEventsToTimeline` operators from `applesauce-core/observable` instead.
typescript
import { toEventStore } from "applesauce-relay/operators";
import { EventStore } from "applesauce-core";
import { lastValueFrom } from "rxjs";
// Create an event store
const eventStore = new EventStore();
// Fetch events, deduplicate, and sort them
const timeline = await lastValueFrom(
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(toEventStore(eventStore)),
);
console.log(`Received ${timeline.length} unique events`);
### Recommended alternative [](https://hzrd149.github.io/applesauce/relays/operators.html#recommended-alternative)
typescript
import { mapEventsToStore, mapEventsToTimeline } from "applesauce-core/observable";
import { completeOnEose } from "applesauce-relay/operators";
import { EventStore } from "applesauce-core";
import { lastValueFrom } from "rxjs";
// Create an event store
const eventStore = new EventStore();
// Fetch events, deduplicate, and sort them
const timeline = await lastValueFrom(
relay
.req({
kinds: [1],
limit: 10,
})
.pipe(completeOnEose(), mapEventsToStore(eventStore, true), mapEventsToTimeline()),
);
console.log(`Received ${timeline.length} unique events`);
Combining Operators [](https://hzrd149.github.io/applesauce/relays/operators.html#combining-operators)
--------------------------------------------------------------------------------------------------------
These operators can be combined to create powerful data processing pipelines:
typescript
import { markFromRelay, onlyEvents, completeOnEose } from "applesauce-relay/operators";
import { mapEventsToStore, mapEventsToTimeline } from "applesauce-core/observable";
import { EventStore } from "applesauce-core";
import { lastValueFrom } from "rxjs";
// Create an event store
const eventStore = new EventStore();
// Create a relay pool
const pool = new RelayPool();
// Define relay URLs
const relays = ["wss://relay1.example.com", "wss://relay2.example.com"];
// Fetch events from multiple relays, track where they came from,
// deduplicate, and sort them
const timeline = await lastValueFrom(
pool
.req(relays, {
kinds: [1],
limit: 10,
})
.pipe(
// Mark each event with its source relay
markFromRelay(relays[0]),
// Filter out EOSE messages
onlyEvents(),
// Complete when all events are received
completeOnEose(),
// Store events and remove duplicates
mapEventsToStore(eventStore, true),
// Create a sorted timeline
mapEventsToTimeline(),
),
);
console.log(`Received ${timeline.length} unique events`);
---
# Signers | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/signers/package.html#VPContent)
Return to top
Signers [](https://hzrd149.github.io/applesauce/signers/package.html#signers)
===============================================================================
All signers in the `applesauce-signers` package are compatible with the [NIP-07](https://github.com/nostr-protocol/nips/blob/master/07.md)
API
Features [](https://hzrd149.github.io/applesauce/signers/package.html#features)
---------------------------------------------------------------------------------
* All signers follow the [NIP-07](https://github.com/nostr-protocol/nips/blob/master/07.md)
API
* [NIP-46](https://github.com/nostr-protocol/nips/blob/master/46.md)
`bunker://` URI support
* Support for client initinated NIP-46 connection (`nostrconnect://` URIs)
* [NIP-49](https://github.com/nostr-protocol/nips/blob/master/49.md)
encrypted password signer
* Support for [nostr-signing-device](https://github.com/lnbits/nostr-signing-device)
on chrome based browsers
* Support for [Amber](https://github.com/greenart7c3/Amber)
clipboard signer (deprecated)
Installation [](https://hzrd149.github.io/applesauce/signers/package.html#installation)
-----------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-signers
sh
yarn install applesauce-signers
sh
pnpm install applesauce-signers
---
# Timeline Loader | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#VPContent)
Return to top
Timeline Loader [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#timeline-loader)
=======================================================================================================
The Timeline Loader is designed for fetching paginated Nostr events in chronological order. It maintains state between calls, allowing you to efficiently load timeline events in blocks until you reach a specific timestamp or exhaust available events.
WARNING
The observable returned by the Timeline Loader MUST be subscribed to in order for the request to be made. No request will be sent until you call `.subscribe()` on the returned observable.
Basic Usage [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#basic-usage)
-----------------------------------------------------------------------------------------------
ts
import { createTimelineLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
// Create a relay pool
const pool = new RelayPool();
// Create a timeline loader
const timelineLoader = createTimelineLoader(
pool,
["wss://relay.example.com"],
{ kinds: [1] }, // Load text notes
);
// Initial load - gets the most recent events
timelineLoader().subscribe((event) => {
console.log("Loaded event:", event);
});
// Later, load older events by calling the loader again
// Each call continues from where the previous one left off
timelineLoader().subscribe((event) => {
console.log("Loaded older event:", event);
});
// Load events until a specific timestamp
const oneWeekAgo = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60;
timelineLoader(oneWeekAgo).subscribe((event) => {
console.log("Event from last week:", event);
});
Configuration Options [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#configuration-options)
-------------------------------------------------------------------------------------------------------------------
The `createTimelineLoader` function accepts these options:
* `limit`: Maximum number of events to request per filter
* `cache`: A method used to load events from a local cache
* `eventStore`: An event store to pass all events to
WARNING
If an event store is not provided, the loader will not be able to deduplicate events.
Working with Relay Pools [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#working-with-relay-pools)
-------------------------------------------------------------------------------------------------------------------------
The Timeline Loader requires a request method for loading Nostr events from relays. You can provide this in multiple ways:
### Using a RelayPool instance [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#using-a-relaypool-instance)
The simplest approach is to pass a RelayPool instance directly:
ts
import { createTimelineLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { EventStore } from "applesauce-core";
const eventStore = new EventStore();
const pool = new RelayPool();
const timelineLoader = createTimelineLoader(
pool,
["wss://relay.example.com"],
{ kinds: [1], authors: ["user_pubkey"] },
{ eventStore },
);
### Using a custom request method [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#using-a-custom-request-method)
You can also provide a custom request method, such as one from nostr-tools:
ts
import { createTimelineLoader } from "applesauce-loaders/loaders";
import { SimplePool } from "nostr-tools";
import { Observable } from "rxjs";
const pool = SimplePool();
// Create a custom request function using nostr-tools
function customRequest(relays, filters) {
return new Observable((observer) => {
const sub = pool.subscribeMany(relays, filters, {
onevent: (event) => observer.next(event),
eose: () => observer.complete(),
});
return () => sub.close();
});
}
// Create a function that matches the UpstreamPool interface
const customPool = {
request: customRequest,
};
// Create timeline loader with custom pool
const timelineLoader = createTimelineLoader(customPool, ["wss://relay.example.com"], filters);
Loading from cache [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#loading-from-cache)
-------------------------------------------------------------------------------------------------------------
For improved performance, you can configure the loader to use a local cache:
ts
import { createTimelineLoader } from "applesauce-loaders/loaders";
import { openDB, getEventsForFilters } from "nostr-idb";
// Setup a local event cache
const cache = await openDB();
function cacheRequest(filters) {
return getEventsForFilters(cache, filters);
}
const timelineLoader = createTimelineLoader(
pool,
["wss://relay.example.com"],
{ kinds: [1] },
{ cache: cacheRequest, eventStore },
);
Real-World Example [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#real-world-example)
-------------------------------------------------------------------------------------------------------------
Here's how you might use the Timeline Loader in a React application for an infinite scrolling feed:
tsx
import { createTimelineLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { EventStore } from "applesauce-core";
import { useEffect, useState } from "react";
// Setup at app level
const eventStore = new EventStore();
const pool = new RelayPool();
function Feed() {
const [events, setEvents] = useState([]);
const [loading, setLoading] = useState(false);
const [timelineLoader, setTimelineLoader] = useState(null);
// Initialize the timeline loader
useEffect(() => {
const loader = createTimelineLoader(
pool,
["wss://relay.example.com"],
{ kinds: [1] }, // Load text notes
{ eventStore },
);
setTimelineLoader(() => loader);
// Load initial events
loadMoreEvents(loader);
}, []);
// Function to load more events
const loadMoreEvents = (loader) => {
if (!loader || loading) return;
setLoading(true);
const subscription = loader().subscribe({
next: (event) => {
setEvents((prev) => [...prev, event]);
},
complete: () => {
setLoading(false);
},
});
return () => subscription.unsubscribe();
};
return (
{events.map((event) => (
{event.content}
))}
);
}
Loading Sequence [](https://hzrd149.github.io/applesauce/loaders/timeline-loader.html#loading-sequence)
---------------------------------------------------------------------------------------------------------
The Timeline Loader follows this sequence when loading events:
1. Start with a cursor at Infinity (most recent events)
2. Attempt to load from cache (if configured)
3. Fetch from specified relays in parallel
4. Update the cursor to the oldest event's timestamp
5. Each subsequent call starts from the updated cursor
6. Stop when no more events are returned or the specified timestamp is reached
This stateful approach allows efficient pagination through chronological timelines with minimal code complexity.
---
# Reactions Loader | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#VPContent)
Return to top
Reactions Loader [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#reactions-loader)
==========================================================================================================
The Reactions Loader is a specialized loader for fetching [NIP-25](https://github.com/nostr-protocol/nips/blob/master/25.md)
reaction events for any given Nostr event. It is built on top of the [Tag Value Loader](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html)
and automatically handles both regular events and addressable events.
WARNING
The observable returned by the Reactions Loader MUST be subscribed to in order for the request to be made. No request will be sent until you call `.subscribe()` on the returned observable.
Basic Usage [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#basic-usage)
------------------------------------------------------------------------------------------------
ts
import { createReactionsLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
// Create a relay pool
const pool = new RelayPool();
// Create a reactions loader (do this once at the app level)
const reactionsLoader = createReactionsLoader(pool);
// Later, use the loader to fetch reactions for any event
const someEvent = { id: "event_id", kind: 1 /* ... */ };
reactionsLoader(someEvent, ["wss://relay.example.com"]).subscribe((reactionEvent) => {
console.log("Received reaction:", reactionEvent);
});
How It Works [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#how-it-works)
--------------------------------------------------------------------------------------------------
The Reactions Loader automatically:
* Determines if the target event is addressable (replaceable) or a regular event
* Uses the appropriate tag (`a` for addressable events, `e` for regular events) to fetch reactions
* Merges relay hints from the event's seen relays (if `useSeenRelays` is enabled)
* Filters results to only return NIP-25 reaction events (kind 7)
Configuration Options [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#configuration-options)
--------------------------------------------------------------------------------------------------------------------
The `createReactionsLoader` function accepts these options:
* `useSeenRelays`: Whether to include relays where the event was seen (default `true`)
* All other options from Tag Value Loader: `bufferTime`, `bufferSize`, `authors`, `since`, `cacheRequest`, `extraRelays`, `eventStore`
ts
const reactionsLoader = createReactionsLoader(pool, {
useSeenRelays: true,
bufferTime: 500,
eventStore,
cacheRequest,
});
Example with React [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#example-with-react)
--------------------------------------------------------------------------------------------------------------
tsx
import { createReactionsLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { useEffect, useState } from "react";
// Setup at app level
const pool = new RelayPool();
const reactionsLoader = createReactionsLoader(pool);
function ReactionsComponent({ event }) {
const [reactions, setReactions] = useState([]);
useEffect(() => {
const subscription = reactionsLoader(event).subscribe((reactionEvent) => {
setReactions((prev) => [...prev, reactionEvent]);
});
return () => subscription.unsubscribe();
}, [event.id]);
// Group reactions by content
const reactionCounts = reactions.reduce((acc, reaction) => {
const content = reaction.content || "+";
acc[content] = (acc[content] || 0) + 1;
return acc;
}, {});
return (
);
}
Understanding Reaction Events [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#understanding-reaction-events)
------------------------------------------------------------------------------------------------------------------------------------
NIP-25 reaction events have the following structure:
* **Kind**: 7 (reaction)
* **Content**: Usually an emoji (👍, ❤️, etc.) or "+" for likes, "-" for dislikes
* **Tags**: Include `e` or `a` tags referencing the reacted-to event
Example reaction event:
json
{
"kind": 7,
"content": "🔥",
"tags": [\
["e", "event_id_being_reacted_to"],\
["p", "pubkey_of_event_author"]\
],
"created_at": 1234567890,
"pubkey": "reactor_pubkey"
}
Addressable vs Regular Events [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#addressable-vs-regular-events)
------------------------------------------------------------------------------------------------------------------------------------
The loader automatically handles both types of events:
* **Regular events** (kind 0, 1, etc.): Uses `e` tags to find reactions
* **Addressable events** (kind 30000 to 39999): Uses `a` tags with the replaceable address
This abstraction means you don't need to worry about the event type - just pass any event to the loader.
Advanced Example: Reaction Analytics [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#advanced-example-reaction-analytics)
-------------------------------------------------------------------------------------------------------------------------------------------------
tsx
import { createReactionsLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { useEffect, useState } from "react";
const pool = new RelayPool();
const reactionsLoader = createReactionsLoader(pool);
function ReactionAnalytics({ event }) {
const [reactions, setReactions] = useState([]);
const [uniqueReactors, setUniqueReactors] = useState(new Set());
useEffect(() => {
const subscription = reactionsLoader(event).subscribe((reaction) => {
setReactions((prev) => [...prev, reaction]);
setUniqueReactors((prev) => new Set([...prev, reaction.pubkey]));
});
return () => subscription.unsubscribe();
}, [event.id]);
const positiveReactions = reactions.filter((r) => r.content === "+" || r.content === "👍" || r.content === "❤️");
const negativeReactions = reactions.filter((r) => r.content === "-" || r.content === "👎");
return (
Reaction Summary
Total reactions: {reactions.length}
Unique reactors: {uniqueReactors.size}
Positive: {positiveReactions.length}
Negative: {negativeReactions.length}
);
}
Performance Considerations [](https://hzrd149.github.io/applesauce/loaders/reactions-loader.html#performance-considerations)
------------------------------------------------------------------------------------------------------------------------------
The Reactions Loader is optimized for performance through:
* **Batching**: Multiple reaction requests are automatically batched together
* **Deduplication**: Events are deduplicated when an event store is provided
* **Caching**: Local cache integration prevents unnecessary network requests
* **Relay optimization**: Uses seen relays from the target event for better discovery
For best performance, ensure you provide an `eventStore` and `cacheRequest` when creating the loader.
---
# 6. Creating Events with EventFactory | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#VPContent)
Return to top
6\. Creating Events with EventFactory [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#_6-creating-events-with-eventfactory)
====================================================================================================================================================
The `EventFactory` class is your tool for creating, signing, and modifying Nostr events. It provides a clean API with pre-built blueprints for common event types and handles the complexities of event creation for you.
What is the EventFactory? [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#what-is-the-eventfactory)
----------------------------------------------------------------------------------------------------------------------------
The `EventFactory` is a builder that:
* **Creates events using blueprints** - Pre-built templates for common event types
* **Handles signing** - Integrates with signers to sign events
* **Manages metadata** - Automatically adds client tags, relay hints, etc.
* **Provides operations** - Composable functions to modify events
* **Ensures validity** - Creates properly formatted Nostr events
Setting up the EventFactory [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#setting-up-the-eventfactory)
---------------------------------------------------------------------------------------------------------------------------------
First, you'll need a signer. For browser apps, the `ExtensionSigner` works with Nostr browser extensions:
typescript
import { EventFactory } from "applesauce-factory";
import { ExtensionSigner } from "applesauce-signers";
// Create a signer that uses the browser extension (like Alby or nos2x)
const signer = new ExtensionSigner();
// Create the event factory with the signer
const factory = new EventFactory({
signer,
// Optional: Add client information to events
client: {
name: "My Nostr App",
address: { identifier: "my-app", pubkey: "app-pubkey" },
},
});
> 💡 **Best Practice**: Create one `EventFactory` instance at the top level of your app and pass it down or use a context.
Creating a Text Note [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#creating-a-text-note)
-------------------------------------------------------------------------------------------------------------------
Let's create a simple text note using the `NoteBlueprint`:
typescript
import { NoteBlueprint } from "applesauce-factory/blueprints";
async function createNote() {
try {
// Use the NoteBlueprint to create a draft event
const draft = await factory.create(NoteBlueprint, "Hello Nostr! This is my first note. #introductions");
// Sign the draft event with the signer
const signed = await factory.sign(draft);
console.log("Created note:", signed);
return signed;
} catch (error) {
console.error("Failed to create note:", error);
}
}
Different Event Types with Blueprints [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#different-event-types-with-blueprints)
-----------------------------------------------------------------------------------------------------------------------------------------------------
EventFactory comes with blueprints for many common event types:
### Text Note with Hashtags [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#text-note-with-hashtags)
The `NoteBlueprint` is setup to automatically handle hashtags and mentions.
typescript
import { NoteBlueprint } from "applesauce-factory/blueprints";
// Simple note
const hashtagsNote = await factory.create(NoteBlueprint, "Just posted my first note! #introductions");
console.log(hashtagsNote.tags);
// Output: [["t", "introductions"]]
// Note with hashtags (automatically parsed)
const mentionsNote = await factory.create(
NoteBlueprint,
"GM nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6",
);
console.log(mentionsNote.tags);
// Output: [["p", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"]]
### Reply to Another Note [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#reply-to-another-note)
The `NoteReplyBlueprint` can be used to create a reply event to another kind 1 note.
typescript
import { NoteReplyBlueprint } from "applesauce-factory/blueprints";
// Reply to an existing note
const originalNote = {
/* some note event */
};
const reply = await factory.create(NoteReplyBlueprint, originalNote, "Great point! I totally disagree.");
### Reaction (Like) [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#reaction-like)
The `ReactionBlueprint` can be used to create a reaction event to any nostr event.
typescript
import { ReactionBlueprint } from "applesauce-factory/blueprints";
// React to a note with a like
const reaction = await factory.create(ReactionBlueprint, originalNote, "+");
// React with a heart
const heartReaction = await factory.create(ReactionBlueprint, originalNote, "❤️");
### Repost/Share [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#repost-share)
The `ShareBlueprint` can be used to create a repost/share event of any nostr event.
typescript
import { ShareBlueprint } from "applesauce-factory/blueprints";
// Share/repost a note
const repost = await factory.create(ShareBlueprint, originalNote);
Custom Event Creation [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#custom-event-creation)
---------------------------------------------------------------------------------------------------------------------
For more complex events, you can use the `build()` method with [operations](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Operations.EventOperations.html)
:
typescript
import { setContent, includeHashtags, includeAltTag } from "applesauce-factory/operations";
// Build a custom note with specific operations
const customNote = await factory.build(
{ kind: 1 }, // Start with a kind 1 note
setContent("Check out this amazing project!"),
includeHashtags(["nostr", "project"]),
includeAltTag("A short text note"),
);
const signed = await factory.sign(customNote);
Error Handling Best Practices [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#error-handling-best-practices)
-------------------------------------------------------------------------------------------------------------------------------------
Any step in the event creation process can fail. You should handle these errors gracefully.
typescript
async function createNoteWithErrorHandling(content: string) {
try {
// Try to create the note
const draft = await factory.create(NoteBlueprint, content);
const signed = await factory.sign(draft);
return signed;
} catch (error) {
console.error("Failed to create note:", error);
return null;
}
}
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/06-event-factory.html#key-concepts)
---------------------------------------------------------------------------------------------------
* **EventFactory creates events** using blueprints and operations
* **Signers handle cryptography** - you don't need to manage keys directly
* **Blueprints are templates** for common event types
* **Always sign events** before using them or publishing them
* **Handle errors gracefully** - users might cancel signing or
* **Add events to EventStore** to see them in your UI
---
# Actions | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/actions/package.html#VPContent)
Return to top
Actions [](https://hzrd149.github.io/applesauce/actions/package.html#actions)
===============================================================================
The `applesauce-actions` package provides pre-built actions for common actions a nostr app might need.
Features [](https://hzrd149.github.io/applesauce/actions/package.html#features)
---------------------------------------------------------------------------------
* Built on `applesauce-factory` to create and modify events
* Compatible with any NIP-07 signer ( and `applesauce-signers` )
* Works with any nostr SDK for publishing events
Installation [](https://hzrd149.github.io/applesauce/actions/package.html#installation)
-----------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-actions
sh
yarn install applesauce-actions
sh
pnpm install applesauce-actions
---
# Text content | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/content/package.html#VPContent)
Return to top
Text content [](https://hzrd149.github.io/applesauce/content/package.html#text-content)
=========================================================================================
The `applesauce-content` package provides tools for parsing and rendering the text `content` of nostr events.
Installation [](https://hzrd149.github.io/applesauce/content/package.html#installation)
-----------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-content
sh
yarn install applesauce-content
sh
pnpm install applesauce-content
---
# Tag Value Loader | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#VPContent)
Return to top
Tag Value Loader [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#tag-value-loader)
==========================================================================================================
The Tag Value Loader is a specialized loader for fetching Nostr events by their tag values. It provides an efficient way to batch and deduplicate requests, cache results, and handle relay hints.
WARNING
The observable returned by the Tag Value Loader MUST be subscribed to in order for the request to be made. No request will be sent until you call `.subscribe()` on the returned observable.
Basic Usage [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#basic-usage)
------------------------------------------------------------------------------------------------
ts
import { createTagValueLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
// Create a relay pool
const pool = new RelayPool();
// Create a tag value loader for a specific tag (do this once at the app level)
const eTagLoader = createTagValueLoader(pool, "e");
// Later, use the loader to fetch events by tag value
eTagLoader({
value: "event_id",
relays: ["wss://relay.example.com"],
}).subscribe((event) => {
console.log("Loaded event:", event);
});
Configuration Options [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#configuration-options)
--------------------------------------------------------------------------------------------------------------------
The `createTagValueLoader` function accepts these options:
* `bufferTime`: Time interval to buffer requests in ms (default 1000)
* `bufferSize`: Max buffer size (default 200)
* `kinds`: Restrict queries to specific kinds
* `authors`: Restrict queries to specific authors
* `since`: Restrict queries since timestamp
* `cacheRequest`: A method used to load events from a local cache
* `extraRelays`: An array of relays to always fetch from
* `eventStore`: An event store used to deduplicate events
WARNING
If an event store is not provided, the loader will not be able to deduplicate events.
Working with Relay Pools [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#working-with-relay-pools)
--------------------------------------------------------------------------------------------------------------------------
The Tag Value Loader requires a request method for loading Nostr events from relays. You can provide this in multiple ways:
### Using a RelayPool instance [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#using-a-relaypool-instance)
The simplest approach is to pass a RelayPool instance directly:
ts
import { createTagValueLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
const pool = new RelayPool();
const eTagLoader = createTagValueLoader(pool, "e", {
eventStore,
cacheRequest,
});
### Using a custom request method [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#using-a-custom-request-method)
You can also provide a custom request method, such as one from nostr-tools:
ts
import { createTagValueLoader } from "applesauce-loaders/loaders";
import { SimplePool } from "nostr-tools";
import { Observable } from "rxjs";
const pool = SimplePool();
// Create a custom request function using nostr-tools
function customRequest(relays, filters) {
return new Observable((observer) => {
const sub = pool.subscribeMany(relays, filters, {
onevent: (event) => observer.next(event),
eose: () => observer.complete(),
});
return () => sub.close();
});
}
// Create tag value loader with custom request
const eTagLoader = createTagValueLoader(customRequest, "e", options);
Loading from cache [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#loading-from-cache)
--------------------------------------------------------------------------------------------------------------
For improved performance, you can configure the loader to use a local cache:
ts
import { createTagValueLoader } from "applesauce-loaders/loaders";
import { openDB, getEventsForFilters } from "nostr-idb";
// Setup a local event cache
const cache = await openDB();
function cacheRequest(filters) {
return getEventsForFilters(cache, filters);
}
const eTagLoader = createTagValueLoader(pool, "e", {
cacheRequest,
eventStore,
});
// Events from cache are automatically marked using markFromCache
eTagLoader({ value: "event_id" }).subscribe((event) => {
if (!isFromCache(event)) {
// This is a new event from the network
addEvents(cache, [event]);
}
});
Creating Specialized Loaders [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#creating-specialized-loaders)
----------------------------------------------------------------------------------------------------------------------------------
The Tag Value Loader can be used to create specialized loaders for specific use cases:
### Reactions Loader [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#reactions-loader)
ts
import { createTagValueLoader } from "applesauce-loaders/loaders";
import { kinds } from "nostr-tools";
import { getReplaceableAddress, isReplaceable, getSeenRelays, mergeRelaySets } from "applesauce-core/helpers";
function createReactionsLoader(pool, options) {
// Create tag value loaders for both events and addressable events
const eventLoader = createTagValueLoader(pool, "e", { ...options, kinds: [kinds.Reaction] });
const addressableLoader = createTagValueLoader(pool, "a", { ...options, kinds: [kinds.Reaction] });
// Return a function that uses the appropriate loader based on event type
return (event, relays) => {
// Use addressable loader for replaceable events, otherwise use event loader
return isReplaceable(event.kind)
? addressableLoader({ value: getReplaceableAddress(event), relays })
: eventLoader({ value: event.id, relays });
};
}
### Zaps Loader [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#zaps-loader)
ts
import { createTagValueLoader } from "applesauce-loaders/loaders";
import { kinds } from "nostr-tools";
import { getReplaceableAddress, isReplaceable, getSeenRelays, mergeRelaySets } from "applesauce-core/helpers";
function createZapsLoader(pool, options) {
// Create tag value loaders for both events and addressable events
const eventLoader = createTagValueLoader(pool, "e", { ...options, kinds: [kinds.Zap] });
const addressableLoader = createTagValueLoader(pool, "a", { ...options, kinds: [kinds.Zap] });
// Return a function that uses the appropriate loader based on event type
return (event, relays) => {
// Use addressable loader for replaceable events, otherwise use event loader
return isReplaceable(event.kind)
? addressableLoader({ value: getReplaceableAddress(event), relays })
: eventLoader({ value: event.id, relays });
};
}
Real-World Example [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#real-world-example)
--------------------------------------------------------------------------------------------------------------
Here's how you might use the Tag Value Loader in a React application to fetch replies to a note:
tsx
import { EventStore } from "applesauce-core";
import { createTagValueLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
import { useEffect, useState } from "react";
// Setup at app level
const eventStore = new EventStore();
const pool = new RelayPool();
const eTagLoader = createTagValueLoader(pool, "e", { eventStore });
function RepliesComponent({ noteId, relays }) {
const [replies, setReplies] = useState([]);
// Load replies when component mounts
useEffect(() => {
const subscription = eTagLoader({
value: noteId,
relays,
}).subscribe((event) => {
// Only add replies that reference this note in the root tag
if (event.tags.some((tag) => tag[0] === "e" && tag[1] === noteId && tag[3] === "root")) {
setReplies((prev) => [...prev, event]);
}
});
return () => subscription.unsubscribe();
}, [noteId]);
return (
Replies ({replies.length})
{replies.map((reply) => (
{reply.content}
))}
);
}
Loading Sequence [](https://hzrd149.github.io/applesauce/loaders/tag-value-loader.html#loading-sequence)
----------------------------------------------------------------------------------------------------------
The Tag Value Loader follows this sequence when loading events:
1. Attempt to load from cache (if configured)
2. Fetch from specified relays and any additional relays
3. Deduplicate events (if an event store is configured)
This approach ensures efficient event loading with minimal network requests.
---
# EventFactory | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/factory/event-factory.html#VPContent)
Return to top
EventFactory [](https://hzrd149.github.io/applesauce/factory/event-factory.html#eventfactory)
===============================================================================================
The `EventFactory` class is the main interface for creating, building, and modifying Nostr events. It provides a convenient wrapper around event operations and blueprints, making it easy to work with different types of Nostr events.
Creating an EventFactory [](https://hzrd149.github.io/applesauce/factory/event-factory.html#creating-an-eventfactory)
-----------------------------------------------------------------------------------------------------------------------
The `EventFactory` is initialized with an `EventFactoryContext` that contains configuration options including signers, relay hints, and client information.
### Basic Usage [](https://hzrd149.github.io/applesauce/factory/event-factory.html#basic-usage)
typescript
import { EventFactory } from "applesauce-factory";
// Create with empty context (minimal setup)
const factory = new EventFactory();
// Create with signer
const factory = new EventFactory({
signer: mySigner, // Any NIP-07 compatible signer
});
### With Full Context [](https://hzrd149.github.io/applesauce/factory/event-factory.html#with-full-context)
typescript
import { EventFactory } from "applesauce-factory";
const factory = new EventFactory({
// Required for signing events
signer: {
getPublicKey: () => "your-pubkey",
signEvent: (template) => signedEvent,
nip04: { encrypt, decrypt }, // Optional NIP-04 support
nip44: { encrypt, decrypt }, // Optional NIP-44 support
},
// Optional: Add client tag to events
client: {
name: "My Nostr App",
address: { identifier: "my-app", pubkey: "app-pubkey" },
},
// Optional: Provide relay hints for tags
getEventRelayHint: (eventId) => "wss://relay.example.com",
getPubkeyRelayHint: (pubkey) => "wss://relay.example.com",
// Optional: Custom emojis for text content
emojis: [{ name: "custom", url: "https://example.com/emoji.png" }],
});
Core Methods [](https://hzrd149.github.io/applesauce/factory/event-factory.html#core-methods)
-----------------------------------------------------------------------------------------------
### `create()` - Using Blueprints [](https://hzrd149.github.io/applesauce/factory/event-factory.html#create-using-blueprints)
The `create()` method uses pre-built blueprints to create common event types. Blueprints are pre-built sets of operations that can be used to create events.
typescript
// Create a short text note (kind 1)
const noteEvent = await factory.create(NoteBlueprint, "Hello Nostr!");
// Create a reaction event (kind 7)
const reactionEvent = await factory.create(ReactionBlueprint, eventToReactTo, "+");
// Create a reply to a note
const replyEvent = await factory.create(NoteReplyBlueprint, noteToReplyTo, "Hello back!");
// Create a comment (NIP-22)
const commentEvent = await factory.create(CommentBlueprint, articleToCommentOn, "Great article!");
### `build()` - Build an event using operations [](https://hzrd149.github.io/applesauce/factory/event-factory.html#build-build-an-event-using-operations)
The `build()` method takes a starting template and builds an event using operations.
typescript
const customEvent = await factory.build(
// Start with a template
{ kind: 30023 },
setContent("# My Article\n\nThis is my article content..."),
// Include the "title" and "published_at" tags
includeNameValueTag(["title", "My Article Title"]),
includeNameValueTag(["published_at", "1234567890"]),
// Include only one "d" tag
includeSingletonTag(["d", "article-id"]),
);
### `modify()` - Updating Existing Events [](https://hzrd149.github.io/applesauce/factory/event-factory.html#modify-updating-existing-events)
The `modify()` method updates an existing event with a new `created_at` timestamp and operations.
typescript
// Modify an existing event
const modifiedEvent = await factory.modify(
existingEvent,
// Replace the "title" and "published_at" tags
includeNameValueTag(["title", "My Article Title"]),
includeNameValueTag(["published_at", "1234567890"]),
);
// Modify tags specifically
const updatedEvent = await factory.modifyTags(existingEvent, addPubkeyTag("user_pubkey"));
Event Lifecycle [](https://hzrd149.github.io/applesauce/factory/event-factory.html#event-lifecycle)
-----------------------------------------------------------------------------------------------------
### 1\. Template → Signed [](https://hzrd149.github.io/applesauce/factory/event-factory.html#_1-template-%E2%86%92-signed)
typescript
// 1. Create template
const draft = await factory.build({
kind: 1,
content: "Hello Nostr!",
});
// 2. Sign the event (creates NostrEvent)
const signed = await factory.sign(draft);
### 2\. Working with Operations [](https://hzrd149.github.io/applesauce/factory/event-factory.html#_2-working-with-operations)
Operations are functions that modify events during creation or modification:
typescript
import { setContent, addHashtags, addMentions, includeClientTag } from "applesauce-factory/operations";
const event = await factory.build(
{ kind: 1 },
setContent("My post content"),
addHashtags(["nostr", "bitcoin"]),
addMentions(["npub1..."]),
includeClientTag("My App", "naddr1..."),
);
Helper Methods [](https://hzrd149.github.io/applesauce/factory/event-factory.html#helper-methods)
---------------------------------------------------------------------------------------------------
The `EventFactory` includes convenient helper methods for common event types:
typescript
// Short text note
const note = await factory.note("Hello World!", {
hashtags: ["greeting"],
});
// Reply to a note
const reply = await factory.noteReply(noteToReplyTo, "Great post!");
// Reaction
const reaction = await factory.reaction(eventToReactTo, "🔥");
// Delete event
const deleteEvent = await factory.delete([eventToDelete, ...eventsToDelete], "I didn't mean to post my nsec1...");
// Share/repost
const share = await factory.share(eventToShare);
// Comment (NIP-22)
const comment = await factory.comment(articleToCommentOn, "Interesting perspective!");
Advanced Features [](https://hzrd149.github.io/applesauce/factory/event-factory.html#advanced-features)
---------------------------------------------------------------------------------------------------------
### Encrypted Content [](https://hzrd149.github.io/applesauce/factory/event-factory.html#encrypted-content)
When working with encrypted content in events, the factory preserves plaintext content so the app wont need to decrypt it later:
typescript
// Create a draft NIP-04 message
const draft = await factory.build(
{ kind: 4 },
setEncryptedContent("other_pubkey", "Hello how have you been?"),
includeNameValueTag(["p", "other_pubkey"]),
);
// Signe the event
const signed = await factory.sign(draft);
// The plaintext content is still available for the app to use
const content = getEncryptedContent(signed);
### Replaceable Events [](https://hzrd149.github.io/applesauce/factory/event-factory.html#replaceable-events)
For replaceable events (kinds 10000-19999 and 30000-39999), the factory automatically includes required `d` tags:
typescript
// Automatically adds "d" tag for addressable events
const profileEvent = await factory.build({
kind: 30023, // Long-form content
content: "Article content...",
// "d" tag will be automatically added if missing
});
### Relay Hints [](https://hzrd149.github.io/applesauce/factory/event-factory.html#relay-hints)
When relay hint functions are provided in the context, they're automatically used for `e` and `p` tags:
typescript
const factory = new EventFactory({
signer: mySigner,
getEventRelayHint: (eventId) => "wss://relay.example.com",
getPubkeyRelayHint: (pubkey) => "wss://relay.example.com",
});
// Tags will automatically include relay hints
const reply = await factory.noteReply("Great post!", "event-id");
// Results in: ["e", "event-id", "wss://relay.example.com"]
Error Handling [](https://hzrd149.github.io/applesauce/factory/event-factory.html#error-handling)
---------------------------------------------------------------------------------------------------
typescript
try {
const event = await factory.create(NoteBlueprint, "Hello World!");
console.log("Event created:", event);
} catch (error) {
if (error.message.includes("signer")) {
console.error("Signer not available or failed");
} else {
console.error("Event creation failed:", error);
}
}
---
# Event Blueprints | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/factory/blueprints.html#VPContent)
Return to top
Event Blueprints [](https://hzrd149.github.io/applesauce/factory/blueprints.html#event-blueprints)
====================================================================================================
Blueprints are pre-configured templates for creating common Nostr events. They encapsulate the logic for setting the correct event kind, content, and tags for specific event types, making it easy to create well-formed Nostr events.
Using Blueprints [](https://hzrd149.github.io/applesauce/factory/blueprints.html#using-blueprints)
----------------------------------------------------------------------------------------------------
### With EventFactory [](https://hzrd149.github.io/applesauce/factory/blueprints.html#with-eventfactory)
The most common way to use blueprints is through an `EventFactory` instance. This allows you to reuse the same context (signer, relay hints, etc.) across multiple events.
typescript
import { EventFactory } from "applesauce-factory";
import { NoteBlueprint, ReactionBlueprint } from "applesauce-factory/blueprints";
// Create a factory with your context
const factory = new EventFactory({
signer: mySigner,
client: { name: "MyApp", address: { identifier: "myapp", pubkey: "pubkey..." } },
});
// Create events using the factory's helper methods
const note = await factory.note("Hello, Nostr!");
const reaction = await factory.reaction(someEvent, "🔥");
// Or use the generic create method with any blueprint
const customNote = await factory.create(NoteBlueprint, "Custom note content #nostr", {
zapSplit: [{ pubkey: "pubkey...", weight: 100 }],
});
### With One-off Context [](https://hzrd149.github.io/applesauce/factory/blueprints.html#with-one-off-context)
For one-time event creation, you can use the `create` function with a context and blueprint:
typescript
import { create } from "applesauce-factory";
import { NoteBlueprint, CommentBlueprint } from "applesauce-factory/blueprints";
// Create a single event with a one-off context
const note = await create(
{ signer: mySigner }, // context
NoteBlueprint, // blueprint constructor
"Hello, world!", // blueprint arguments
);
// Create a comment on an existing event
const comment = await create({ signer: mySigner }, CommentBlueprint, parentEvent, "Great post!");
Available Blueprints [](https://hzrd149.github.io/applesauce/factory/blueprints.html#available-blueprints)
------------------------------------------------------------------------------------------------------------
* `NoteBlueprint(content, options?)`
* `CommentBlueprint(parent, content, options?)`
* `NoteReplyBlueprint(parent, content, options?)`
* `ReactionBlueprint(event, emoji?)`
* `ShareBlueprint(event, options?)`
* `PicturePostBlueprint(pictures, content, options?)`
* `FileMetadataBlueprint(file, options?)`
* `DeleteBlueprint(events)`
* `LiveStreamBlueprint(title, options?)`
And a lot more in the [reference](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Blueprints.html)
.
Custom Blueprints [](https://hzrd149.github.io/applesauce/factory/blueprints.html#custom-blueprints)
------------------------------------------------------------------------------------------------------
You can create your own custom blueprints by following the same pattern used by the built-in blueprints. A blueprint is a function that returns a call to the `blueprint()` helper function.
### Basic Custom Blueprint [](https://hzrd149.github.io/applesauce/factory/blueprints.html#basic-custom-blueprint)
typescript
import { kinds } from "nostr-tools";
import { blueprint } from "applesauce-factory";
import { includeSingletonTag, MetaTagOptions } from "applesauce-factory/operations";
/** Custom event blueprint */
export function AppConfigBlueprint(config: Record) {
return blueprint(
kinds.AplicationData, // or your custom kind number
// Add your operations here
setContent(JSON.stringify(config)),
includeSingletonTag(["d", "app-config"]),
);
}
### Using Your Custom Blueprint [](https://hzrd149.github.io/applesauce/factory/blueprints.html#using-your-custom-blueprint)
Once created, use your custom blueprint just like the built-in ones:
typescript
// With EventFactory
const customEvent = await factory.create(AppConfigBlueprint, { theme: "light" });
// With one-off context
const advancedEvent = await create({ signer: mySigner }, AppConfigBlueprint, { theme: "light" });
Blueprint Patterns [](https://hzrd149.github.io/applesauce/factory/blueprints.html#blueprint-patterns)
--------------------------------------------------------------------------------------------------------
### Common Patterns [](https://hzrd149.github.io/applesauce/factory/blueprints.html#common-patterns)
1. **Type Safety**: Always define TypeScript types for your blueprint options
2. **Conditional Operations**: Use ternary operators to conditionally apply operations
3. **Reusable Operations**: Extract common logic into reusable operation functions
4. **Context Usage**: Leverage the context for relay hints, custom emojis, and other shared data
### Best Practices [](https://hzrd149.github.io/applesauce/factory/blueprints.html#best-practices)
* Keep blueprints focused on a single event type
* Use descriptive names and comprehensive JSDoc comments
* Validate inputs when necessary (like the `PicturePostBlueprint` does for image types)
* Combine multiple operations for complex event structures
* Always handle optional parameters gracefully
---
# 8. Running Actions with ActionHub | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#VPContent)
Return to top
8\. Running Actions with ActionHub [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#_8-running-actions-with-actionhub)
========================================================================================================================================
The `ActionHub` is the central orchestrator for running actions in your Nostr application. It combines your EventStore, EventFactory, and publishing logic into a unified interface, making it simple to execute complex actions that read from your local data and publish new events to the network.
What is ActionHub? [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#what-is-actionhub)
--------------------------------------------------------------------------------------------------------
ActionHub is a class that:
* **Executes pre-built actions** - Like following users, creating contact lists, etc.
* **Handles event creation and publishing** - Automatically creates, signs, and publishes events
* **Provides error handling** - Gracefully handles validation and publishing errors
* **Offers flexible execution modes** - Automatic publishing or manual control
Setting up ActionHub [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#setting-up-actionhub)
-------------------------------------------------------------------------------------------------------------
### Basic Setup [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#basic-setup)
To create an ActionHub, you need your `EventStore` and `EventFactory` instances:
typescript
import { ActionHub } from "applesauce-actions";
import { EventStore } from "applesauce-core";
import { EventFactory } from "applesauce-factory";
import { ExtensionSigner } from "applesauce-factory/signers";
// Your existing instances
const eventStore = new EventStore();
const signer = new ExtensionSigner();
const eventFactory = new EventFactory({ signer });
// Create ActionHub without automatic publishing
const actionHub = new ActionHub(eventStore, eventFactory);
### With Custom Publishing Logic [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#with-custom-publishing-logic)
For most applications, you'll want to provide a publish method that handles how events are sent to relays:
typescript
import { RelayPool } from "applesauce-relay";
import { NostrEvent } from "nostr-tools";
const pool = new RelayPool();
const defaultRelays = ["wss://relay.damus.io", "wss://nos.lol", "wss://relay.nostr.band"];
// Create a custom publish function
function publish(event: NostrEvent) {
return pool.publish(event, defaultRelays);
}
// Create ActionHub with automatic publishing
const actionHub = new ActionHub(eventStore, eventFactory, publish);
Running Actions [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#running-actions)
---------------------------------------------------------------------------------------------------
### Using `hub.run()` - Automatic Publishing [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#using-hub-run-automatic-publishing)
The `hub.run()` method executes an action and automatically publishes all generated events:
typescript
import { FollowUser, UnfollowUser, NewContacts } from "applesauce-actions/actions";
// Create a new contact list (if one doesn't exist)
try {
await actionHub.run(NewContacts);
console.log("Contact list created successfully");
} catch (error) {
if (error.message.includes("contact list already exists")) {
console.log("User already has a contact list");
} else {
console.error("Failed to create contact list:", error);
}
}
// Follow a user - events are automatically published
const userToFollow = "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d";
const relayHint = "wss://relay.damus.io";
try {
await actionHub.run(FollowUser, userToFollow, relayHint);
console.log("Successfully followed user");
} catch (error) {
console.error("Failed to follow user:", error);
}
// Unfollow a user
try {
await actionHub.run(UnfollowUser, userToFollow);
console.log("Successfully unfollowed user");
} catch (error) {
console.error("Failed to unfollow user:", error);
}
### Using `hub.exec()` for Manual Control [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#using-hub-exec-for-manual-control)
For more control over event handling, you can use `hub.exec()` which returns an observable:
typescript
import { tap, catchError } from "rxjs/operators";
import { EMPTY } from "rxjs";
// Execute action with manual event handling
actionHub.exec(FollowUser, userPubkey, relayHint).subscribe({
next: async (event) => {
try {
// Custom publishing logic for this specific action
await customPublish(event);
console.log("Event published successfully");
} catch (error) {
console.error("Failed to publish event:", error);
}
},
error: (error) => {
console.error("Action failed:", error);
},
complete: () => {
console.log("Action completed");
},
});
Available Actions [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#available-actions)
-------------------------------------------------------------------------------------------------------
There are a lot of pre-built [actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.Actions.html)
, but here are a few common ones that are worth mentioning.
### Contact List Actions [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#contact-list-actions)
typescript
import { NewContacts, FollowUser, UnfollowUser } from "applesauce-actions/actions";
// Create a new contact list
await actionHub.run(NewContacts);
// Follow a user
await actionHub.run(FollowUser, pubkey, relayHint);
// Unfollow a user
await actionHub.run(UnfollowUser, pubkey);
### Profile Actions [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#profile-actions)
typescript
import { UpdateProfile } from "applesauce-actions/actions";
// Update your profile
await actionHub.run(UpdateProfile, {
name: "Alice",
about: "Bitcoin developer",
picture: "https://example.com/alice.jpg",
website: "https://alice.dev",
});
Error Handling [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#error-handling)
-------------------------------------------------------------------------------------------------
Actions can fail for various reasons. Always handle errors appropriately:
typescript
async function safeFollowUser(pubkey, relayHint) {
try {
await actionHub.run(FollowUser, pubkey, relayHint);
return { success: true };
} catch (error) {
console.error("Follow action failed:", error);
if (error.message.includes("contact list")) {
// Try to create contact list first
try {
await actionHub.run(NewContacts);
await actionHub.run(FollowUser, pubkey, relayHint);
return { success: true };
} catch (retryError) {
return { success: false, error: "Failed to create contact list" };
}
}
if (error.message.includes("signer")) {
return { success: false, error: "Please connect your Nostr extension" };
}
return { success: false, error: error.message };
}
}
// Usage
const result = await safeFollowUser(pubkey, relayHint);
if (result.success) {
console.log("User followed successfully");
} else {
console.error("Failed to follow user:", result.error);
}
Configuration Options [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#configuration-options)
---------------------------------------------------------------------------------------------------------------
### Disable Automatic EventStore Saving [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#disable-automatic-eventstore-saving)
By default, `ActionHub` saves all generated events to your `EventStore`. You can disable this:
typescript
const actionHub = new ActionHub(eventStore, eventFactory, publish);
actionHub.saveToStore = false; // Disable automatic saving
// Now events are only published, not saved to local store
await actionHub.run(FollowUser, pubkey, relayHint);
### Conditional Saving [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#conditional-saving)
You might want to save events only after successful publishing:
typescript
const actionHub = new ActionHub(eventStore, eventFactory);
actionHub.saveToStore = false; // Disable automatic saving
// Manual event handling with conditional saving
await actionHub.exec(FollowUser, pubkey, relayHint).forEach(async (event) => {
try {
// Publish first
await publish(event);
// Save to store only after successful publish
eventStore.add(event);
console.log("Event published and saved");
} catch (error) {
console.error("Failed to publish, not saving to store:", error);
}
});
Best Practices [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#best-practices)
-------------------------------------------------------------------------------------------------
### 1\. Single ActionHub Instance [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#_1-single-actionhub-instance)
Create one ActionHub instance for your entire application:
typescript
// app.ts
export const actionHub = new ActionHub(eventStore, eventFactory, publish);
// other-file.ts
import { actionHub } from "./app";
await actionHub.run(FollowUser, pubkey);
### 2\. Error Handling [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#_2-error-handling)
Actions can throw errors so many sure to handle them gracefully.
typescript
try {
await actionHub.run(FollowUser, pubkey);
} catch (error) {
console.error("Failed to follow user:", error);
}
Key Concepts [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#key-concepts)
---------------------------------------------------------------------------------------------
* **ActionHub orchestrates** EventStore, EventFactory, and publishing
* **Actions are pre-built** functions for common Nostr operations
* **`hub.run()` provides automatic** event creation and publishing
* **`hub.exec()` gives manual control** over event handling
* **Error handling is crucial** for good user experience
* **Single instance per app** is recommended for consistency
Next Steps [](https://hzrd149.github.io/applesauce/tutorial/08-actions.html#next-steps)
-----------------------------------------------------------------------------------------
You now know enough to build a Nostr application! Checkout some some of the examples apps in the [examples](https://hzrd149.github.io/applesauce/examples)
directory to see whats possible.
---
# Wallet | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/wallet/package.html#VPContent)
Return to top
Wallet [](https://hzrd149.github.io/applesauce/wallet/package.html#wallet)
============================================================================
The `applesauce-wallet` package provides a set of actions and queries for managing [NIP-60](https://github.com/nostr-protocol/nips/blob/master/60.md)
wallets and [Cashu](https://github.com/cashubtc/cashu)
tokens.
WARNING
The `applesauce-wallet` package is still a work-in-progress and is still missing many features.
Installation [](https://hzrd149.github.io/applesauce/wallet/package.html#installation)
----------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-wallet
sh
yarn install applesauce-wallet
sh
pnpm install applesauce-wallet
---
# Models | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/wallet/models.html#VPContent)
Return to top
Models [](https://hzrd149.github.io/applesauce/wallet/models.html#models)
===========================================================================
The `applesauce-wallet` package provides a few pre-built models for subscribing to the state of the wallet.
WalletModel [](https://hzrd149.github.io/applesauce/wallet/models.html#walletmodel)
-------------------------------------------------------------------------------------
The `WalletModel` subscribes to the state of a NIP-60 wallet, providing information about whether it's locked and its associated mints.
typescript
import { WalletModel } from "applesauce-wallet/models";
const wallet = eventStore.model(WalletModel, pubkey).subscribe((info) => {
if (!info) return console.log("No wallet found");
if (info.locked) {
console.log("Wallet is locked");
} else {
console.log("Wallet mints:", info.mints);
console.log("Has private key:", !!info.privateKey);
}
});
WalletTokensQuery [](https://hzrd149.github.io/applesauce/wallet/models.html#wallettokensquery)
-------------------------------------------------------------------------------------------------
The `WalletTokensQuery` subscribes to all token events for a wallet, with optional filtering by locked status.
typescript
import { WalletTokensModel } from "applesauce-wallet/models";
// Get all tokens
const allTokens = eventStore.model(WalletTokensModel, pubkey);
// Get only unlocked tokens
const unlockedTokens = eventStore.model(WalletTokensModel, pubkey, false);
WalletBalanceQuery [](https://hzrd149.github.io/applesauce/wallet/models.html#walletbalancequery)
---------------------------------------------------------------------------------------------------
The `WalletBalanceQuery` returns the visible balance of a wallet for each mint.
typescript
import { WalletBalanceModel } from "applesauce-wallet/models";
eventStore.model(WalletBalanceModel, pubkey).subscribe((balances) => {
for (const [mint, amount] of Object.entries(balances)) {
console.log(`Balance for ${mint}: ${amount}`);
}
});
---
# Managing events | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/core/event-store.html#VPContent)
Return to top
Managing events [](https://hzrd149.github.io/applesauce/core/event-store.html#managing-events)
================================================================================================
The `EventStore` is a reactive in-memory event database
At its core the event store uses the [`Database`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.Database.html)
class to store and index events
Creating an event store [](https://hzrd149.github.io/applesauce/core/event-store.html#creating-an-event-store)
----------------------------------------------------------------------------------------------------------------
ts
import { EventStore } from "applesauce-core";
const eventStore = new EventStore();
INFO
Its recommended to only create a single event store for your app
Adding events [](https://hzrd149.github.io/applesauce/core/event-store.html#adding-events)
--------------------------------------------------------------------------------------------
To add events to the event store you can use the [`eventStore.add`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.EventStore.html#add)
method
Adding events to the event store will update any subscriptions that match that event
ts
eventStore.timeline({kinds: [1]}).subscribe(events => {
console.log(`timeline updated (${events.length})`)
})
const event = { kind: 1, ... }
eventStore.add(event)
### Duplicate an replaceable events [](https://hzrd149.github.io/applesauce/core/event-store.html#duplicate-an-replaceable-events)
The event store understands to to handle replaceable (`1xxxx`) and parameterized replaceable events (`3xxxx`)
If the event store already has the event (same `id`) or if its a replaceable event and it already has newer version of it. `eventStore.add` will returning the **existing** instance of the event
This allows you to easily deduplicate events from multiple relays
ts
const incoming = [\
{\
id: "f177c37f...",\
kind: 1,\
content: "",\
pubkey: "c3ae4ad8...",\
created_at: 1733345284,\
tags: [],\
sig: "...",\
},\
{\
id: "efd33141...",\
kind: 1,\
content: "",\
pubkey: "20d29810...",\
created_at: 1733343882,\
tags: [],\
sig: "...",\
},\
// duplicate of #1\
{\
id: "f177c37f...",\
kind: 1,\
content: "",\
pubkey: "c3ae4ad8...",\
created_at: 1733345284,\
tags: [],\
sig: "...",\
},\
];
const sub = eventStore.stream({ kinds: [1] }).subscribe((event) => {
console.log("new event", event);
});
// add first event
eventStore.add(incoming[0]);
// add second event
eventStore.add(incoming[1]);
// add duplicate event
const event = eventStore.add(incoming[2]);
// since the event f177c37f has already been added
// the subscription will not update and the returned event is the original
console.log(event !== incoming[2]);
Subscribing [](https://hzrd149.github.io/applesauce/core/event-store.html#subscribing)
----------------------------------------------------------------------------------------
Subscriptions are rxjs [observables](https://rxjs.dev/guide/observable)
that update when new events are added to the event store
### Single events [](https://hzrd149.github.io/applesauce/core/event-store.html#single-events)
Subscribing to a single event will notify you when the event has been added to the event store or when it is deleted
ts
const event = {
content: "Hashtags are useless.",
created_at: 1733153425,
id: "000021ba6f5f4da9d1f913c73dcf8fc8347052b4e74e14a2e41101c0f40792c8",
kind: 1,
pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
sig: "6f197e399d1ebae054fbc20570fc8ef113a79afaa6057125170ba81afcecea2449969c9d1dbc61ff50328cae7166e9981734ba29672d9ae45acb675ff45ebd84",
tags: [["nonce", "8002", "16"]],
};
const sub = eventStore.event("000021ba6f5f4da9d1f913c73dcf8fc8347052b4e74e14a2e41101c0f40792c8").subscribe((event) => {
// value maybe undefined when the event is not in the event store
// or if it has been deleted
if (event) {
console.log("event has been found", event);
}
});
eventStore.add(event);
### Replaceable events [](https://hzrd149.github.io/applesauce/core/event-store.html#replaceable-events)
Subscribing to a replaceable event will notify you when there is a newer version or when it is deleted
ts
const original = {
id: "7607adc3934f368bf1a00cb1023e455707a90af94a29c2acf877dffb0ec4c0cb",
pubkey: "d8dd41ef1e287dfc668d2473fbef8fa9deea5c2ef03947105ef568e68827e7e4",
created_at: 1733346633,
kind: 0,
tags: [],
content: '{ "name": "john" }',
sig: "b706636043a64c5d1a07cabf66db08b1374d6efa4558e8832f5b90becb5cba190215a2ec1303e11dac494977801600b012959daa7145fba6d96ae3fcb629759e",
};
const updated = {
id: "2f54a4491a31451cbe0d296297649af458d89df2f24d7f86d2474fd0607e29a1",
pubkey: "d8dd41ef1e287dfc668d2473fbef8fa9deea5c2ef03947105ef568e68827e7e4",
created_at: 1733346633,
kind: 0,
tags: [],
content: '{ "name": "john smith" }',
sig: "d66ecc0fb2b9170818defb593150563061716bce82d276d07b4b68be9ab542b2d14bb1335eb62971a84be5f315ecf32bdf53000e780a20330f63d7803a1fd95c",
};
eventStore.add(original);
// get the original and listen for any updates
const sub = eventStore
.replaceable(0, "d8dd41ef1e287dfc668d2473fbef8fa9deea5c2ef03947105ef568e68827e7e4")
.subscribe((event) => {
// first event will be the original
if (event) console.log("Profile Updated", event);
});
// this will trigger the subscription
eventStore.add(updated);
### Streams [](https://hzrd149.github.io/applesauce/core/event-store.html#streams)
A stream subscription takes a filter(s) and returns all events that match and notifies you when there are new events
ts
const sub = eventStore.stream({ kinds: [1] }).subscribe((event) => {
console.log("Found text note", event);
});
// or if you only want to subscribe to future events
const sub = eventStore.stream({ kinds: [1] }, true).subscribe((event) => {
console.log("Found new text note", event);
});
### Timelines [](https://hzrd149.github.io/applesauce/core/event-store.html#timelines)
A timeline subscription takes a filter(s) and returns a sorted array of events that match the filter(s)
ts
const timeline = eventStore.timeline({ kinds: [1] }).subscribe((events) => {
console.log(events);
});
// fetch some events using another library
fetchEvents({ kinds: [1, 0] }, (event) => {
// timeline will update for each new event
eventStore.add(event);
});
Fallback event loaders [](https://hzrd149.github.io/applesauce/core/event-store.html#fallback-event-loaders)
--------------------------------------------------------------------------------------------------------------
The event store has three optional loader methods that act as fallbacks when events are not found in the store. These loaders are particularly useful for loading user profiles or other single events on-demand when the UI needs them.
### Setting up custom loaders [](https://hzrd149.github.io/applesauce/core/event-store.html#setting-up-custom-loaders)
You can implement your own loader methods using any Nostr library or relay connection approach:
ts
import { EventStore } from "applesauce-core";
const eventStore = new EventStore();
// Event loader - loads events by ID
eventStore.eventLoader = async (pointer) => {
console.log("loading event", pointer);
const event = await cache.getEventById(pointer.id);
if (event) return event;
};
// Replaceable loader - loads kind 0, 3, 1xxxx events
eventStore.replaceableLoader = async (pointer) => {
console.log("loading replaceable event", pointer);
return await loadReplaceableEvent(pointer.kind, pointer.pubkey);
};
// Addressable loader - loads kind 3xxxx events
eventStore.addressableLoader = async (pointer) => {
console.log("loading addressable event", pointer);
const event = await fetchAddressableEvent(pointer.kind, pointer.pubkey, pointer.identifier);
if (event) return event;
};
Now if events are subscribed to and they don't exist in the store, the loaders will be called.
ts
const sub = eventStore
.profile("3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d")
.subscribe((profile) => {
if (profile) console.log("Profile loaded:", profile);
});
// Console:
// loading replaceable event { kind: 0, pubkey: '3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d' }
// Profile loaded: { name: 'fiatjaf', ... }
The loaders are called automatically and the loaded events are added to the store, making them available for future requests and updating any active subscriptions.
### Using with applesauce-loaders [](https://hzrd149.github.io/applesauce/core/event-store.html#using-with-applesauce-loaders)
While you can implement loaders with any Nostr library, the `applesauce-relay` and `applesauce-loaders` packages make it much simpler:
ts
import { EventStore } from "applesauce-core";
import { createAddressLoader, createEventLoader } from "applesauce-loaders/loaders";
import { RelayPool } from "applesauce-relay";
const eventStore = new EventStore();
const pool = new RelayPool();
// Create an address loader that handles all addressable and replaceable events
const addressLoader = createAddressLoader(pool, {
// Try a local relay first for caching
cacheRequest: (filters) => pool.relay("ws://localhost:4869").request(filters),
// Fallback to public relays
lookupRelays: ["wss://purplepag.es", "wss://relay.damus.io"],
});
// Set loaders on event store
eventStore.addressableLoader = addressLoader;
eventStore.replaceableLoader = addressLoader;
// Create an event loader that loads events by ID
const eventLoader = createEventLoader(pool, {
// Try a local relay first for caching
cacheRequest: (filters) => pool.relay("ws://localhost:4869").request(filters),
});
// Set loader on event store
eventStore.eventLoader = eventLoader;
Static Methods [](https://hzrd149.github.io/applesauce/core/event-store.html#static-methods)
----------------------------------------------------------------------------------------------
The event store provides several methods to directly access events without creating subscriptions. These methods are useful when you need to check for or retrieve events synchronously.
### Event Management [](https://hzrd149.github.io/applesauce/core/event-store.html#event-management)
* `add(event)`: Add a new event to the store
* `remove(event)`: Remove an event from the store
* `update(event)`: Notify the store that an event has been updated
### Checking Event Existence [](https://hzrd149.github.io/applesauce/core/event-store.html#checking-event-existence)
* `hasEvent(id)`: Check if an event with a specific ID exists in the store
* `hasReplaceable(kind, pubkey, identifier?)`: Check if a replaceable event exists for the given kind and pubkey combination
### Retrieving Events [](https://hzrd149.github.io/applesauce/core/event-store.html#retrieving-events)
* `getEvent(id)`: Get a single event by its ID
* `getReplaceable(kind, pubkey, identifier?)`: Get the latest version of a replaceable event
* `getReplaceableHistory(kind, pubkey, identifier?)`: Get the history of all versions of a replaceable event
* `getByFilters(filters)`: Get a set of all events that match the given filter(s)
* `getTimeline(filters)`: Get a sorted array of events that match the given filter(s)
Example usage:
ts
// Check if an event exists
const exists = eventStore.hasEvent("000021ba6f5f...");
// Get an event by ID
const event = eventStore.getEvent("000021ba6f5f...");
// Get events matching filters
const events = eventStore.getByFilters({ kinds: [1], authors: ["000021ba6f5f..."] });
// Get a timeline of events
const timeline = eventStore.getTimeline({ kinds: [1] });
// Check and get replaceable events
const hasProfile = eventStore.hasReplaceable(0, "000021ba6f5f...");
const profile = eventStore.getReplaceable(0, "000021ba6f5f...");
---
# Wallet Connect | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/wallet-connect/package.html#VPContent)
Return to top
Wallet Connect [](https://hzrd149.github.io/applesauce/wallet-connect/package.html#wallet-connect)
====================================================================================================
The `applesauce-wallet-connect` package provides a complete implementation of [NIP-47](https://github.com/nostr-protocol/nips/blob/master/47.md)
Nostr Wallet Connect for both clients and services.
Features [](https://hzrd149.github.io/applesauce/wallet-connect/package.html#features)
----------------------------------------------------------------------------------------
* **WalletConnect**: Client-side implementation for connecting to NIP-47 wallet services
* **WalletService**: Service-side implementation for creating NIP-47 wallet services
* Full support for all NIP-47 methods
* Support for both `nostr+walletconnect://` and `nostr+walletauth://` connection URIs
* TypeScript support with full type safety
* RxJS-based reactive architecture
* Support for both NIP-04 and NIP-44 encryption
* Comprehensive error handling with typed errors
Installation [](https://hzrd149.github.io/applesauce/wallet-connect/package.html#installation)
------------------------------------------------------------------------------------------------
npmyarnpnpm
sh
npm install applesauce-wallet-connect
sh
yarn install applesauce-wallet-connect
sh
pnpm install applesauce-wallet-connect
Quick Start [](https://hzrd149.github.io/applesauce/wallet-connect/package.html#quick-start)
----------------------------------------------------------------------------------------------
### Client (WalletConnect) [](https://hzrd149.github.io/applesauce/wallet-connect/package.html#client-walletconnect)
Connect to a wallet service using a connection string:
typescript
import { WalletConnect } from "applesauce-wallet-connect";
const wallet = WalletConnect.fromConnectionString("nostr+walletconnect://relay.example.com?secret=...&pubkey=...");
// Pay an invoice
const result = await wallet.payInvoice("lnbc1...");
console.log("Payment preimage:", result.preimage);
// Get wallet balance
const balance = await wallet.getBalance();
console.log("Balance:", balance.balance, "msats");
### Service (WalletService) [](https://hzrd149.github.io/applesauce/wallet-connect/package.html#service-walletservice)
Create a wallet service that handles NIP-47 requests:
typescript
import { WalletService } from "applesauce-wallet-connect";
import { SimpleSigner } from "applesauce-signers";
// Create a signer for the service
const signer = new SimpleSigner();
// Define method handlers
const handlers = {
get_info: async () => ({
alias: "My Wallet",
color: "#ff0000",
pubkey: await signer.getPublicKey(),
network: "mainnet" as const,
block_height: 800000,
block_hash: "0000...0000",
methods: ["get_info", "get_balance", "pay_invoice"],
}),
get_balance: async () => ({
balance: 100000, // 100 sats in msats
}),
pay_invoice: async (params) => {
// Implement your payment logic here
console.log("Paying invoice:", params.invoice);
return {
preimage: "payment_preimage_here",
fees_paid: 1000,
};
},
};
// Create the service
const service = new WalletService({
subscriptionMethod: mySubscriptionMethod,
publishMethod: myPublishMethod,
relays: ["wss://relay.example.com"],
signer,
handlers,
});
// Start the service
await service.start();
console.log("Wallet service started");
// Get the connection string for the wallet service
console.log(service.getConnectionString());
Supported Methods [](https://hzrd149.github.io/applesauce/wallet-connect/package.html#supported-methods)
----------------------------------------------------------------------------------------------------------
Both WalletConnect and WalletService support all NIP-47 methods:
* `get_info` - Get wallet information
* `get_balance` - Get wallet balance
* `pay_invoice` - Pay a Lightning invoice
* `multi_pay_invoice` - Pay multiple invoices
* `pay_keysend` - Send a keysend payment
* `multi_pay_keysend` - Send multiple keysend payments
* `make_invoice` - Create a new invoice
* `lookup_invoice` - Look up an invoice
* `list_transactions` - List transactions
---
# Migration Guide: v2 to v3 | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/migration/v2-v3.html#VPContent)
Return to top
Migration Guide: v2 to v3 [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#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 [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#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` and `authenticate` methods now return Promises instead of Observables
* **Factory Reorganization**: Event operations have been reorganized into groups which breaks imports
1\. Accounts & Signers Changes [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#_1-accounts-signers-changes)
--------------------------------------------------------------------------------------------------------------------------
### Async API Migration [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#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.
ts
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
const event = await account.signEvent(draft); // Returns Promise
### Removed getRelays Method [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#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:
ts
// v2 - This method existed
const relays = await account.getRelays(); // ❌ Removed in v3
### New ExtensionAccount.fromExtension Method [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#new-extensionaccount-fromextension-method)
A new static method has been added for creating extension accounts:
ts
// v3 - New static method
import { ExtensionAccount } from "applesauce-accounts";
const account = await ExtensionAccount.fromExtension(); // Creates account from window.nostr
### Migration Steps [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#migration-steps)
1. **Add await keywords** to all account and signer method calls:
ts
// 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);
2. **Remove getRelays usage**:
ts
// v2 - Remove this
const relays = await account.getRelays();
2\. Relay Changes [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#_2-relay-changes)
--------------------------------------------------------------------------------------------------
### Promise-Based Publish Methods [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#promise-based-publish-methods)
**Major Change**: Relay publish methods now return Promises instead of Observables.
ts
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
const responses = await pool.publish(event, relays); // Returns Promise
### Authentication Methods [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#authentication-methods)
Authentication methods also now return Promises:
ts
// 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
const authResponse2 = await relay.auth(challenge); // Returns Promise
### Removed Interfaces [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#removed-interfaces)
The following interfaces have been removed:
* `IRelayState` - Use the Relay class directly
* `Nip01Actions` - Methods are now part of the Relay class
### Migration Steps [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#migration-steps-1)
1. **Remove lastValueFrom usage** for publish methods:
ts
// v2
import { lastValueFrom } from "rxjs";
const response = await lastValueFrom(relay.publish(event));
// v3
const response = await relay.publish(event);
2. **Update authentication calls**:
ts
// v2
const authResponse = await lastValueFrom(relay.authenticate(challenge));
// v3
const authResponse = await relay.authenticate(challenge);
3\. Factory & Operations Changes [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#_3-factory-operations-changes)
------------------------------------------------------------------------------------------------------------------------------
### Reorganized Exports [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#reorganized-exports)
**Major Change**: Event operations have been reorganized and all exports have been renamed.
### Import groups of operations instead of individual methods [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#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.
ts
// 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 [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#summary-of-required-changes)
-----------------------------------------------------------------------------------------------------------------------
### Breaking Changes (Must Update) [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#breaking-changes-must-update)
1. **Add `await` to all account/signer method calls** - they now return Promises
2. **Remove `getRelays()` usage on signers and accounts** - method no longer exists
3. **Update relay publish calls** - remove `lastValueFrom()` wrapper since it returns a promise
4. **Update relay authentication calls** - remove `lastValueFrom()` wrapper since it returns a promise
### Recommended Updates [](https://hzrd149.github.io/applesauce/migration/v2-v3.html#recommended-updates)
1. **Use new `ExtensionAccount.fromExtension()` static method** for creating extension accounts
---
# Relay Class | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/relays/relays.html#VPContent)
Return to top
Relay Class [](https://hzrd149.github.io/applesauce/relays/relays.html#relay-class)
=====================================================================================
The `Relay` class provides a reactive interface for connecting to and communicating with Nostr relays using RxJS observables.
Creating a Relay Connection [](https://hzrd149.github.io/applesauce/relays/relays.html#creating-a-relay-connection)
---------------------------------------------------------------------------------------------------------------------
typescript
import { Relay } from "applesauce-relay";
// Create a new relay instance
const relay = new Relay("wss://relay.example.com");
// Access relay state observables
relay.connected$.subscribe((connected) => console.log("Connection status:", connected));
relay.notices$.subscribe((notices) => console.log("Relay notices:", notices));
Subscribing to Events [](https://hzrd149.github.io/applesauce/relays/relays.html#subscribing-to-events)
---------------------------------------------------------------------------------------------------------
The `req` or `subscription` methods returns an observable that emits events from the relay.
WARNING
The `req` method will `complete` when the connection is closed or `error` when the connection has an error. for Persistent subscriptions you should use the `subscription` method.
typescript
// Subscribe to specific kinds of events
relay
.req({
kinds: [1],
authors: ["pubkey1", "pubkey2"],
})
.subscribe({
next: (response) => {
if (response === "EOSE") {
console.log("End of stored events");
} else {
console.log("Event:", response);
}
},
error: (err) => console.error("Subscription error:", err),
});
Publishing Events [](https://hzrd149.github.io/applesauce/relays/relays.html#publishing-events)
-------------------------------------------------------------------------------------------------
Send events to the relay using the `event` or `publish` methods.
INFO
The `publish` method is a wrapper around the `event` method that returns a `Promise` and automatically handles reconnecting and retrying.
typescript
import { generatePrivateKey, getPublicKey, getEventHash, signEvent } from "nostr-tools";
const sk = generatePrivateKey();
const pk = getPublicKey(sk);
const event = {
kind: 1,
pubkey: pk,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: "Hello Nostr!",
};
event.id = getEventHash(event);
event.sig = signEvent(event, sk);
// Use the observable method
relay.event(event).subscribe((response) => {
console.log(`Published: ${response.ok}`, response.message);
});
// Or use the publish method with await
const response = await relay.publish(event);
console.log(`Published: ${response.ok}`, response.message);
Making One-time Requests [](https://hzrd149.github.io/applesauce/relays/relays.html#making-one-time-requests)
---------------------------------------------------------------------------------------------------------------
Use the `request` method for one-time queries that complete after receiving `EOSE`.
typescript
import { lastValueFrom } from "rxjs";
import { getProfileContent } from "applesauce-core/helpers";
// Get latest user profile
async function getProfile(pubkey) {
const events = await lastValueFrom(
relay.request({
kinds: [0],
authors: [pubkey],
limit: 1,
}),
);
return getProfileContent(events[0]);
}
Authentication [](https://hzrd149.github.io/applesauce/relays/relays.html#authentication)
-------------------------------------------------------------------------------------------
The `Relay` class supports [NIP-42](https://github.com/nostr-protocol/nips/blob/master/42.md)
authentication and keeps track of the authentication state and challenge.
* `challenge$` - An observable that tracks the authentication challenge from the relay.
* `authenticated$` - An observable that tracks the authentication state of the relay.
* `authenticate` - An async method that can be used to authenticate the relay.
More information about authentication can be found in the [typedocs](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-relay.Relay)
.
typescript
// Listen for authentication challenges
relay.challenge$.subscribe((challenge) => {
if (!challenge) return;
// Using browser extension as signer
relay
.authenticate(window.nostr)
.then(() => {
console.log("Authentication successful");
})
.catch((err) => {
console.error("Authentication failed:", err);
});
});
If you want to manually build the authentication event you can use the `auth` method to send the event to the relay.
typescript
import { makeAuthEvent } from "nostr-tools/nip42";
// Listen for authentication challenges
relay.challenge$.subscribe(async (challenge) => {
if (!challenge) return;
// Create a new auth event and sign it
const auth = await window.nostr.signEvent(makeAuthEvent(relay.url, challenge));
// Send it to the relay and wait for the response
relay.auth(auth).subscribe({
next: (response) => {
console.log("Authentication response:", response);
},
error: (err) => {
console.error("Authentication failed:", err);
},
});
});
Persistent Subscriptions [](https://hzrd149.github.io/applesauce/relays/relays.html#persistent-subscriptions)
---------------------------------------------------------------------------------------------------------------
The `subscription` method can be used to create persistent subscriptions that automatically reconnect after connection issues. It provides two key options for handling failures:
### Retry Options [](https://hzrd149.github.io/applesauce/relays/relays.html#retry-options)
The `retries` option controls how many times the subscription will retry when encountering errors. It accepts either a number or a full RxJS `RetryConfig` object.
typescript
// Basic retry with number of attempts
const subscription = relay
.subscription({ kinds: [1, 6], since: Math.floor(Date.now() / 1000) }, { id: "feed", retries: 3 })
.subscribe({
next: (response) => {
if (response !== "EOSE") {
console.log("New event:", response.content);
}
},
});
// Advanced retry with custom configuration
const subscription = relay
.subscription(
{ kinds: [1] },
{
id: "advanced-feed",
retries: {
count: 5,
delay: 1000,
resetOnSuccess: true,
},
},
)
.subscribe(console.log);
### Reconnection Options [](https://hzrd149.github.io/applesauce/relays/relays.html#reconnection-options)
The `reconnect` option controls whether the subscription should automatically reconnect when the WebSocket connection is closed. It accepts:
* `true` - Reconnect infinitely
* `false` (default) - Don't reconnect
* `number` - Reconnect a specific number of times
* `RepeatConfig` - Full RxJS repeat configuration
typescript
// Infinite reconnection
const subscription = relay
.subscription({ kinds: [1] }, { id: "persistent-feed", reconnect: true })
.subscribe(console.log);
// Limited reconnection attempts
const subscription = relay.subscription({ kinds: [1] }, { id: "limited-feed", reconnect: 5 }).subscribe(console.log);
// Custom reconnection with delay
const subscription = relay
.subscription(
{ kinds: [1] },
{
id: "custom-feed",
reconnect: {
count: 10,
delay: 2000,
},
},
)
.subscribe(console.log);
### How It Works [](https://hzrd149.github.io/applesauce/relays/relays.html#how-it-works)
Under the hood, the `subscription` method uses RxJS operators to implement retry and reconnection logic:
1. **Retry Logic**: Uses the [`retry()`](https://rxjs.dev/api/operators/retry)
operator to retry failed subscriptions based on the `retries` option
2. **Reconnection Logic**: Uses the [`repeat()`](https://rxjs.dev/api/operators/repeat)
operator to restart the subscription when the connection is lost based on the `reconnect` option
The default behavior provides 3 retries and no automatic reconnection, but you can customize these values based on your application's needs.
Dynamic Filters [](https://hzrd149.github.io/applesauce/relays/relays.html#dynamic-filters)
---------------------------------------------------------------------------------------------
The `req`, and `subscription` methods can accept an observable for the filters. this allows for you to set the filters later or update them dynamically.
WARNING
Make sure to use a `ReplaySubject`, `BehaviorSubject`, or the `shareReplay(1)` operator to keep the last filters in case the relay disconnects and needs to resubscribe.
typescript
import { BehaviorSubject } from "rxjs";
import { onlyEvents } from "applesauce-relay/operators";
// Create a subject with initial filters
const filters = new BehaviorSubject({
kinds: [1],
limit: 20,
});
// Subscribe using dynamic filters
relay
.req(filters)
.pipe(onlyEvents())
.subscribe((event) => console.log(event.content));
// Update filters later
setTimeout(() => {
filters.next({
kinds: [1],
"#t": ["nostr"],
limit: 20,
});
}, 5000);
Relay Information [](https://hzrd149.github.io/applesauce/relays/relays.html#relay-information)
-------------------------------------------------------------------------------------------------
The `Relay` class keeps track of the relay information and emits it as an observable from the `information$` property.
typescript
// Get relay information
relay.information$.subscribe((info) => {
if (info) {
console.log("Relay name:", info.name);
console.log("Supported NIPs:", info.supported_nips);
console.log("Software:", info.software);
if (info.limitation) {
console.log("Max message size:", info.limitation.max_message_length);
}
}
});
---
# AppleSauce
AppleSauce
==========
Modules
-------
[applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-accounts)
[applesauce-actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-actions)
[applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-content)
[applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-core)
[applesauce-dvm](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-dvm)
[applesauce-factory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-factory)
[applesauce-loaders](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-loaders)
[applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-react)
[applesauce-relay](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-relay.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-relay)
[applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-signers)
[applesauce-solidjs](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-solidjs)
[applesauce-wallet](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-wallet)
[applesauce-wallet-connect](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet-connect.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-wallet-connect)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Modules
[applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-accounts)
[applesauce-actions](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-actions)
[applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-content)
[applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-core)
[applesauce-dvm](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-dvm)
[applesauce-factory](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-factory)
[applesauce-loaders](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-loaders)
[applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-react)
[applesauce-relay](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-relay)
[applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-signers)
[applesauce-solidjs](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-solidjs)
[applesauce-wallet](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-wallet)
[applesauce-wallet-connect](https://hzrd149.github.io/applesauce/typedoc/modules.html#applesauce-wallet-connect)
---
# Markdown | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/content/markdown.html#VPContent)
Return to top
Markdown [](https://hzrd149.github.io/applesauce/content/markdown.html#markdown)
==================================================================================
The `applesauce-content` package exports some [remark](https://www.npmjs.com/package/remark)
transformers. see remark [docs](https://remark.js.org/)
to see how to add additional transformers
Nostr Mentions [](https://hzrd149.github.io/applesauce/content/markdown.html#nostr-mentions)
----------------------------------------------------------------------------------------------
The [`remarkNostrMentions`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Markdown.remarkNostrMentions.html)
transformer can be used to linkify [NIP-21](https://github.com/nostr-protocol/nips/blob/master/21.md)
`nostr:` URIs
---
# WalletService Class | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#VPContent)
Return to top
WalletService Class [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#walletservice-class)
=====================================================================================================================
The `WalletService` class provides a service-side implementation for creating NIP-47 wallet services. It handles incoming wallet requests, processes them through configured handlers, and sends responses back to clients.
Overview [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#overview)
-----------------------------------------------------------------------------------------------
`WalletService` is designed to be a complete server for Nostr Wallet Connect clients. It provides:
* **Request Handling**: Automatic processing of NIP-47 wallet requests
* **Handler System**: Pluggable method handlers for different wallet operations
* **Encryption Support**: Automatic handling of NIP-04 and NIP-44 encryption
* **Response Management**: Structured response handling with error support
* **Notification Support**: Ability to send notifications to connected clients
* **Lifecycle Management**: Start/stop functionality with proper cleanup
Creating a Service [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#creating-a-service)
-------------------------------------------------------------------------------------------------------------------
### Basic Service Setup [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#basic-service-setup)
typescript
import { WalletService, WalletServiceHandlers } from "applesauce-wallet-connect";
import { SimpleSigner } from "applesauce-signers";
// Create a signer for the service
const signer = new SimpleSigner();
// Define method handlers
const handlers: WalletServiceHandlers = {
get_info: async () => ({
alias: "My Lightning Wallet",
color: "#ff6600",
pubkey: await signer.getPublicKey(),
network: "mainnet",
block_height: 800000,
block_hash: "0000000000000000000000000000000000000000000000000000000000000000",
methods: ["get_info", "get_balance", "pay_invoice", "make_invoice"],
}),
get_balance: async () => ({
balance: 1000000, // 1000 sats
}),
pay_invoice: async (params) => {
// Implement your payment logic here
console.log(`Paying invoice: ${params.invoice} for ${params.amount} msats`);
return {
preimage: "payment_preimage_here",
fees_paid: 1000,
};
},
};
// Create the service
const service = new WalletService({
relays: ["wss://relay.example.com"],
signer,
handlers,
notifications: ["payment_received", "payment_sent"],
});
// Start the service
await service.start();
console.log("Wallet service started");
// Get the connection string for clients
const connectionString = service.getConnectionString();
console.log("Clients can connect using:", connectionString);
### Setting Up Relay Methods [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#setting-up-relay-methods)
The service needs methods for subscribing to and publishing events. You can set these globally or per instance:
typescript
import { RelayPool } from "applesauce-relay";
const pool = new RelayPool();
// Set global methods
WalletService.subscriptionMethod = pool.subscription.bind(pool);
WalletService.publishMethod = pool.publish.bind(pool);
// Now all instances will use these methods by default
const service = new WalletService(options);
For more details on setting up relay methods, see the [Nostr Connect documentation](https://hzrd149.github.io/applesauce/signers/nostr-connect.html)
.
Handling Authentication Requests [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#handling-authentication-requests)
-----------------------------------------------------------------------------------------------------------------------------------------------
### Processing Auth URIs [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#processing-auth-uris)
When a client wants to connect, they'll provide a `nostr+walletauth://` URI. You need to:
1. **Parse the URI**: Extract the client's public key and secret
2. **Create a Service**: Use the extracted information to create a service instance
3. **Start the Service**: Begin listening for requests from that client
typescript
import { parseWalletAuthURI } from "applesauce-wallet-connect/helpers";
// Parse the auth URI from the client
const { secret, service: clientPubkey, relays } = parseWalletAuthURI(authUri);
// Create a service instance for this client
const walletService = new WalletService({
relays,
signer,
handlers,
secret: hexToBytes(secret), // Convert hex secret to bytes
});
// Start the service
await walletService.start();
// The client can now connect using the connection string
const connectionString = walletService.getConnectionString();
### Using fromAuthURI [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#using-fromauthuri)
For convenience, you can use the `fromAuthURI` static method:
typescript
const walletService = await WalletService.fromAuthURI(authUri, {
signer,
handlers,
});
await walletService.start();
Method Handlers [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#method-handlers)
-------------------------------------------------------------------------------------------------------------
### Understanding Handlers [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#understanding-handlers)
Handlers are functions that implement the actual wallet functionality. Each handler corresponds to a NIP-47 command:
* `get_info`: Return wallet information
* `get_balance`: Return current balance
* `pay_invoice`: Process Lightning invoice payments
* `make_invoice`: Create new Lightning invoices
* `pay_keysend`: Send keysend payments
* And more...
For a complete list of available commands and their parameters, see the [NIP-47 specification](https://github.com/nostr-protocol/nips/blob/master/47.md#commands)
.
### Handler Implementation [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#handler-implementation)
Each handler receives the parameters from the client request and should return the appropriate result:
typescript
const handlers: WalletServiceHandlers = {
get_info: async () => {
// Return wallet information
return {
alias: "My Wallet",
color: "#ff6600",
pubkey: await signer.getPublicKey(),
network: "mainnet",
block_height: 800000,
block_hash: "0000000000000000000000000000000000000000000000000000000000000000",
methods: ["get_info", "get_balance", "pay_invoice"],
};
},
get_balance: async () => {
// Get balance from your Lightning node or database
const balance = await getLightningBalance();
return { balance };
},
pay_invoice: async (params) => {
const { invoice, amount } = params;
// Validate the invoice
if (!isValidInvoice(invoice)) {
throw new InvalidInvoiceError("Invalid Lightning invoice format");
}
// Check balance
const balance = await getLightningBalance();
if (balance < amount) {
throw new InsufficientBalanceError(`Insufficient balance: ${balance} msats, required: ${amount} msats`);
}
// Process the payment through your Lightning node
const result = await processLightningPayment(invoice, amount);
return {
preimage: result.preimage,
fees_paid: result.fees_paid,
};
},
};
Error Handling [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#error-handling)
-----------------------------------------------------------------------------------------------------------
### Throwing Typed Errors [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#throwing-typed-errors)
When implementing handlers, you should throw appropriate error types for different failure scenarios:
typescript
import {
InsufficientBalanceError,
InvalidInvoiceError,
InternalError,
WalletBaseError,
} from "applesauce-wallet-connect/helpers/error";
const payInvoiceHandler: PayInvoiceHandler = async (params) => {
try {
const { invoice, amount } = params;
// Validate invoice
if (!isValidInvoice(invoice)) {
throw new InvalidInvoiceError("Invalid Lightning invoice format");
}
// Check balance
const balance = await getLightningBalance();
if (balance < amount) {
throw new InsufficientBalanceError(`Insufficient balance: ${balance} msats, required: ${amount} msats`);
}
// Process payment
const result = await processPayment(invoice, amount);
return result;
} catch (error) {
if (error instanceof WalletBaseError) {
throw error; // Re-throw wallet errors
}
// Wrap unexpected errors
throw new InternalError(`Payment processing failed: ${error.message}`);
}
};
### Available Error Types [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#available-error-types)
* `InsufficientBalanceError`: When there's not enough balance
* `InvalidInvoiceError`: When an invoice is malformed
* `RateLimitedError`: When rate limits are exceeded
* `RestrictedError`: When an operation is not allowed
* `UserRejectedError`: When the user rejects the operation
* `NotImplementedError`: When a method is not supported
* `InternalError`: For unexpected internal errors
For a complete list of error types, see the [typedocs](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet-connect.html)
.
Sending Notifications [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#sending-notifications)
-------------------------------------------------------------------------------------------------------------------------
### Notifying Clients [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#notifying-clients)
You can send notifications to connected clients about important events:
typescript
// Send a payment received notification
await service.notify("payment_received", {
payment_hash: "abc123...",
amount: 100000,
fee: 1000,
});
// Send a payment sent notification
await service.notify("payment_sent", {
payment_hash: "def456...",
amount: 50000,
fee: 500,
});
### Supported Notification Types [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#supported-notification-types)
* `payment_received`: When a payment is received
* `payment_sent`: When a payment is sent
* `payment_failed`: When a payment fails
Service Lifecycle [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#service-lifecycle)
-----------------------------------------------------------------------------------------------------------------
### Starting and Stopping [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#starting-and-stopping)
typescript
// Start the service
await service.start();
// Check if running
if (service.isRunning()) {
console.log("Service is active");
}
// Stop the service
service.stop();
### Graceful Shutdown [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#graceful-shutdown)
typescript
// Handle shutdown signals
process.on("SIGTERM", () => {
console.log("Shutting down wallet service...");
service.stop();
process.exit(0);
});
process.on("SIGINT", () => {
console.log("Shutting down wallet service...");
service.stop();
process.exit(0);
});
Advanced Usage [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#advanced-usage)
-----------------------------------------------------------------------------------------------------------
### Dynamic Method Support [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#dynamic-method-support)
You can conditionally enable methods based on runtime conditions:
typescript
const handlers: WalletServiceHandlers = {};
// Only enable payment methods if payment processor is available
if (paymentProcessor.isAvailable()) {
handlers.pay_invoice = payInvoiceHandler;
handlers.make_invoice = makeInvoiceHandler;
}
// Always enable info methods
handlers.get_info = getInfoHandler;
handlers.get_balance = getBalanceHandler;
const service = new WalletService({
relays: ["wss://relay.example.com"],
signer,
handlers,
});
### Custom Error Types [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-service.html#custom-error-types)
You can create custom error types for your specific use cases:
typescript
import { WalletBaseError } from "applesauce-wallet-connect/helpers/error";
class PaymentProcessorError extends WalletBaseError {
constructor(
public processorCode: string,
message: string,
) {
super("INTERNAL", `Payment processor error (${processorCode}): ${message}`);
}
}
const payInvoiceHandler: PayInvoiceHandler = async (params) => {
try {
const result = await paymentProcessor.pay(params.invoice);
return result;
} catch (error) {
if (error.code === "INSUFFICIENT_FUNDS") {
throw new InsufficientBalanceError("Insufficient balance in payment processor");
}
throw new PaymentProcessorError(error.code, error.message);
}
};
---
# Applesauce packages | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/introduction/packages.html#VPContent)
Return to top
Applesauce packages [](https://hzrd149.github.io/applesauce/introduction/packages.html#applesauce-packages)
=============================================================================================================
Core [](https://hzrd149.github.io/applesauce/introduction/packages.html#core)
-------------------------------------------------------------------------------
The `applesauce-core` package contains the `EventStore` and the majority of the helpers, and models. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
npmyarnpnpm
sh
npm install applesauce-core
sh
yarn install applesauce-core
sh
pnpm install applesauce-core
Content [](https://hzrd149.github.io/applesauce/introduction/packages.html#content)
-------------------------------------------------------------------------------------
The `applesauce-content` package contains helpers for parsing text content and markdown. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
npmyarnpnpm
sh
npm install applesauce-content
sh
yarn install applesauce-content
sh
pnpm install applesauce-content
Signers [](https://hzrd149.github.io/applesauce/introduction/packages.html#signers)
-------------------------------------------------------------------------------------
The `applesauce-signers` package contains a bunch of NIP-07 compatible signer classes. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
npmyarnpnpm
sh
npm install applesauce-signers
sh
yarn install applesauce-signers
sh
pnpm install applesauce-signers
Accounts [](https://hzrd149.github.io/applesauce/introduction/packages.html#accounts)
---------------------------------------------------------------------------------------
The `applesauce-accounts` package contains the main `AccountManager` class and various types of common nostr account types. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
npmyarnpnpm
sh
npm install applesauce-accounts
sh
yarn install applesauce-accounts
sh
pnpm install applesauce-accounts
Factory [](https://hzrd149.github.io/applesauce/introduction/packages.html#factory)
-------------------------------------------------------------------------------------
The `applesauce-factory` package contains the main `EventFactory` class and a lot of [Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Blueprints.html)
and [Operations](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Operations.html)
for creating an modifying nostr events. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html)
npmyarnpnpm
sh
npm install applesauce-factory
sh
yarn install applesauce-factory
sh
pnpm install applesauce-factory
Loaders [](https://hzrd149.github.io/applesauce/introduction/packages.html#loaders)
-------------------------------------------------------------------------------------
The `applesauce-loaders` package provides loaders that simplify fetching nostr events from multiple relays. These loaders can be integrated with any nostr connection framework of your choice. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html)
npmyarnpnpm
sh
npm install applesauce-loaders
sh
yarn install applesauce-loaders
sh
pnpm install applesauce-loaders
:::
Actions [](https://hzrd149.github.io/applesauce/introduction/packages.html#actions)
-------------------------------------------------------------------------------------
The `applesauce-actions` package provides prebuilt actions that apps can use. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html)
npmyarnpnpm
sh
npm install applesauce-actions
sh
yarn install applesauce-actions
sh
pnpm install applesauce-actions
Relays [](https://hzrd149.github.io/applesauce/introduction/packages.html#relays)
-----------------------------------------------------------------------------------
The `applesauce-relay` package provides a flexible api for communicating with Nostr relays, built on top of [RxJS](https://rxjs.dev/)
.
npmyarnpnpm
sh
npm install applesauce-relay
sh
yarn install applesauce-relay
sh
pnpm install applesauce-relay
React [](https://hzrd149.github.io/applesauce/introduction/packages.html#react)
---------------------------------------------------------------------------------
The `applesauce-react` package contains a bunch of useful react hooks for working with other applesauce packages. [see more](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
npmyarnpnpm
sh
npm install applesauce-react
sh
yarn install applesauce-react
sh
pnpm install applesauce-react
Wallet [](https://hzrd149.github.io/applesauce/introduction/packages.html#wallet)
-----------------------------------------------------------------------------------
The `applesauce-wallet` package provides queries and actions for [NIP-60](https://github.com/nostr-protocol/nips/blob/master/60.md)
cashu wallets.
npmyarnpnpm
sh
npm install applesauce-wallet
sh
yarn install applesauce-wallet
sh
pnpm install applesauce-wallet
---
# Wallet Actions | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/wallet/actions.html#VPContent)
Return to top
Wallet Actions [](https://hzrd149.github.io/applesauce/wallet/actions.html#wallet-actions)
============================================================================================
The `applesauce-wallet` package provides a set of [Actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.Actions.html)
for common wallet operations.
CreateWallet [](https://hzrd149.github.io/applesauce/wallet/actions.html#createwallet)
----------------------------------------------------------------------------------------
Creates a new NIP-60 wallet event and wallet backup.
typescript
import { CreateWallet } from "applesauce-wallet/actions";
await hub.run(CreateWallet, ["wss://mint.example.com"], privateKey);
WalletAddPrivateKey [](https://hzrd149.github.io/applesauce/wallet/actions.html#walletaddprivatekey)
------------------------------------------------------------------------------------------------------
Adds a private key to an existing wallet event.
typescript
import { WalletAddPrivateKey } from "applesauce-wallet/actions";
await hub.run(WalletAddPrivateKey, privateKey);
UnlockWallet [](https://hzrd149.github.io/applesauce/wallet/actions.html#unlockwallet)
----------------------------------------------------------------------------------------
Unlocks the wallet event and optionally unlocks tokens and history events.
typescript
import { UnlockWallet } from "applesauce-wallet/actions";
// Unlock just the wallet
await hub.run(UnlockWallet);
// Unlock wallet and associated tokens/history
await hub.run(UnlockWallet, { tokens: true, history: true });
ReceiveToken [](https://hzrd149.github.io/applesauce/wallet/actions.html#receivetoken)
----------------------------------------------------------------------------------------
Adds a Cashu token to the wallet and optionally marks nutzaps as redeemed.
typescript
import { ReceiveToken } from "applesauce-wallet/actions";
await hub.run(ReceiveToken, token, redeemedEventIds);
RolloverTokens [](https://hzrd149.github.io/applesauce/wallet/actions.html#rollovertokens)
--------------------------------------------------------------------------------------------
Deletes old tokens and creates a new consolidated token.
typescript
import { RolloverTokens } from "applesauce-wallet/actions";
await hub.run(RolloverTokens, oldTokenEvents, newToken);
CompleteSpend [](https://hzrd149.github.io/applesauce/wallet/actions.html#completespend)
------------------------------------------------------------------------------------------
Finalizes a spend operation by deleting spent tokens and creating a history entry.
typescript
import { CompleteSpend } from "applesauce-wallet/actions";
await hub.run(CompleteSpend, spentTokenEvents, changeToken);
ConsolidateTokens [](https://hzrd149.github.io/applesauce/wallet/actions.html#consolidatetokens)
--------------------------------------------------------------------------------------------------
Combines all unlocked token events into a single event per mint.
typescript
import { ConsolidateTokens } from "applesauce-wallet/actions";
// Consolidate all unlocked tokens
await hub.run(ConsolidateTokens);
// Ignore locked tokens during consolidation
await hub.run(ConsolidateTokens, { ignoreLocked: true });
WARNING
Actions will throw errors if preconditions are not met (e.g., trying to add a private key to a locked wallet)
---
# Nostr Connect | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#VPContent)
Return to top
Nostr Connect [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#nostr-connect)
=================================================================================================
The [`NostrConnectSigner`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectSigner.html)
is a client side implementation of a [NIP-46](https://github.com/nostr-protocol/nips/blob/master/46.md)
remote signer.
Relay Communication [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#relay-communication)
-------------------------------------------------------------------------------------------------------------
The `NostrConnectSigner` requires two methods for communicating with relays: a subscription method for receiving events and a publish method for sending events.
These methods can be set either through the constructor or globally on the class. At least one of these approaches must be used before creating a `NostrConnectSigner` instance.
typescript
import { Observable } from "rxjs";
function subscriptionMethod(relays, filters) {
return new Observable((observer) => {
// Create subscription to relays
const cleanup = subscribeToRelays(relays, filters, (event) => {
observer.next(event);
});
return () => cleanup();
});
}
async function publishMethod(relays, event) {
for (const relay of relays) {
await publishToRelay(relay, event);
}
}
// Set methods globally once at app initialization
NostrConnectSigner.subscriptionMethod = subscriptionMethod;
NostrConnectSigner.publishMethod = publishMethod;
// Or pass them as options when creating a signer
const signer = new NostrConnectSigner({
relays: ["wss://relay.example.com"],
subscriptionMethod,
publishMethod,
// ... other options
});
### Using the relay pool [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#using-the-relay-pool)
The simplest way to set these methods is to use the `RelayPool` from the `applesauce-relay` package.
typescript
import { RelayPool } from "applesauce-relay";
const pool = new RelayPool();
// Set the pool globally
NostrConnectSigner.pool = pool;
// Or pass the pool as an option when creating a signer
const signer = new NostrConnectSigner({
relays: ["wss://relay.example.com"],
pool,
// ... other options
});
Connecting to a remote signer [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#connecting-to-a-remote-signer)
---------------------------------------------------------------------------------------------------------------------------------
The `NostrConnectSigner` can be created with a remote signer's public key, and will automatically connect to it.
js
import { NostrConnectSigner } from "applesauce-signers";
const signer = new NostrConnectSigner({
remote: "",
// Optional: Users pubkey
pubkey: "",
// Optional: Custom subscription method
subscriptionMethod: customSubMethod,
// Optional: Custom publish method
publishMethod: customPubMethod,
// Optional: Custom auth handler
onAuth: async (url) => {
// Handle auth requests
},
});
// start the connection process
await signer.connect(/* optional secret */, /* optional requested permissions */);
console.log("Connected!");
// get the users pubkey
const pubkey = await signer.getPublicKey();
console.log("Users pubkey is", pubkey);
Initiating connection from client [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#initiating-connection-from-client)
-----------------------------------------------------------------------------------------------------------------------------------------
To start a connection from the client side, you can use the `getNostrConnectURI` and `waitForSigner` methods:
js
const signer = new NostrConnectSigner({
subscriptionMethod: customSubMethod,
publishMethod: customPubMethod,
relays: ["wss://relay.example.com"],
// ... other options
});
// get the nostrconnect:// URI with optional metadata
const uri = signer.getNostrConnectURI({
name: "My App",
url: "https://example.com",
image: "https://example.com/icon.png",
permissions: NostrConnectSigner.buildSigningPermissions([0, 1, 3, 10002]),
});
console.log(uri);
// Create an optional AbortSignal to cancel the waiting process if needed
const controller = new AbortController();
const signal = controller.signal;
try {
// wait for the remote signer to connect, optionally passing an AbortSignal
await signer.waitForSigner(signal);
console.log("Connected!");
const pubkey = await signer.getPublicKey();
console.log("Users pubkey is", pubkey);
} catch (error) {
console.error("Connection was aborted:", error);
}
// Later, if you need to abort the waiting process:
setTimeout(() => {
controller.abort();
}, 10_000);
Handling bunker URIs [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#handling-bunker-uris)
---------------------------------------------------------------------------------------------------------------
The `NostrConnectSigner.fromBunkerURI` method can be used to create a new signer from a `bunker://` URI, it will return a promise that will resolve when the signer is connected.
js
const signer = await NostrConnectSigner.fromBunkerURI(
"bunker://266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5?relay=wss://relay.nsec.app&secret=d9aa70",
{
permissions: NostrConnectSigner.buildSigningPermissions([0, 1, 3, 10002]),
// ... other options
},
);
You can also parse a bunker URI manually using `NostrConnectSigner.parseBunkerURI`:
js
const { remote, relays, secret } = NostrConnectSigner.parseBunkerURI(uri);
Permissions [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#permissions)
---------------------------------------------------------------------------------------------
The `NostrConnectSigner` uses a set of predefined permissions that can be requested from the remote signer:
typescript
enum Permission {
GetPublicKey = "get_pubic_key",
SignEvent = "sign_event",
Nip04Encrypt = "nip04_encrypt",
Nip04Decrypt = "nip04_decrypt",
Nip44Encrypt = "nip44_encrypt",
Nip44Decrypt = "nip44_decrypt",
}
Use the static `NostrConnectSigner.buildSigningPermissions` method to create an array of signing permissions for specific event kinds:
js
const permissions = NostrConnectSigner.buildSigningPermissions([0, 1, 3, 10002]);
These permissions can be passed when:
* Connecting to a remote signer via `connect(secret, permissions)`
* Creating a nostr connect URI via `getNostrConnectURI({ permissions })`
* Creating a signer from a bunker URI via `fromBunkerURI(uri, { permissions })`
App Metadata [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#app-metadata)
-----------------------------------------------------------------------------------------------
When creating a nostr connect URI, you can provide metadata about your application:
typescript
type NostrConnectAppMetadata = {
name?: string;
image?: string;
url?: string | URL;
permissions?: string[];
};
This metadata is used to display information about your application to the user when they connect their signer.
Encryption Methods [](https://hzrd149.github.io/applesauce/signers/nostr-connect.html#encryption-methods)
-----------------------------------------------------------------------------------------------------------
The `NostrConnectSigner` supports both NIP-04 and NIP-44 encryption through the `nip04` and `nip44` properties:
typescript
// NIP-04 encryption
const encrypted = await signer.nip04.encrypt(pubkey, plaintext);
const decrypted = await signer.nip04.decrypt(pubkey, ciphertext);
// NIP-44 encryption
const encrypted = await signer.nip44.encrypt(pubkey, plaintext);
const decrypted = await signer.nip44.decrypt(pubkey, ciphertext);
---
# Nostr Connect Provider | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#VPContent)
Return to top
Nostr Connect Provider [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#nostr-connect-provider)
=====================================================================================================================
The [`NostrConnectProvider`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectProvider.html)
is a server-side implementation of a [NIP-46](https://github.com/nostr-protocol/nips/blob/master/46.md)
remote signer. It allows clients to connect and request signing operations through encrypted Nostr events.
Upstream signer [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#upstream-signer)
-------------------------------------------------------------------------------------------------------
The `NostrConnectProvider` requires an upstream signer that will be used for the common [NIP-07](https://github.com/nostr-protocol/nips/blob/master/07.md)
operations (`sign_event`, `nip04_encrypt`, etc.)
typescript
import { SimpleSigner } from "applesauce-signers";
// Create a new signer for the users key
const upstream = SimpleSigner.fromKey("nsec1...");
// Create a new provider that will use the upstream signer
const provider = new NostrConnectProvider({
relays: ["wss://relay.example.com"],
upstream,
});
// Or create a new provider that uses the user's key for signing and communication (legacy)
const provider = new NostrConnectProvider({
relays: ["wss://relay.example.com"],
upstream,
// Explicitly set the signer that is used for communication to the users signer
signer: upstream,
});
// Start the provider
await provider.start(/* optional nostrconnect:// URI */);
Relay Communication [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#relay-communication)
---------------------------------------------------------------------------------------------------------------
The `NostrConnectProvider` requires two methods for communicating with relays: a subscription method for receiving events and a publish method for sending events.
These methods can be set either through the constructor or globally on the class. At least one of these approaches must be used before creating a `NostrConnectProvider` instance.
typescript
import { Observable } from "rxjs";
function subscriptionMethod(relays, filters) {
return new Observable((observer) => {
// Create subscription to relays
const cleanup = subscribeToRelays(relays, filters, (event) => {
observer.next(event);
});
return () => cleanup();
});
}
async function publishMethod(relays, event) {
for (const relay of relays) {
await publishToRelay(relay, event);
}
}
// Set methods globally once at app initialization
NostrConnectProvider.subscriptionMethod = subscriptionMethod;
NostrConnectProvider.publishMethod = publishMethod;
// Or pass them as options when creating a provider
const provider = new NostrConnectProvider({
relays: ["wss://relay.example.com"],
subscriptionMethod,
publishMethod,
// ... other options
});
### Using the relay pool [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#using-the-relay-pool)
The simplest way to set these methods is to use the `RelayPool` from the `applesauce-relay` package.
typescript
import { RelayPool } from "applesauce-relay";
const pool = new RelayPool();
// Set the pool globally
NostrConnectProvider.pool = pool;
// Or pass the pool as an option when creating a provider
const provider = new NostrConnectProvider({
relays: ["wss://relay.example.com"],
pool,
// ... other options
});
Authorization Callbacks [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#authorization-callbacks)
-----------------------------------------------------------------------------------------------------------------------
The provider supports several authorization callbacks to control what operations clients can perform:
typescript
const provider = new NostrConnectProvider({
// ... other options
// Control connection requests
onConnect: (client, permissions) => {
// Return true to accept, false to reject
return permissions.includes("sign_event"); // Only allow clients that request signing
},
// Control event signing
onSignEvent: (draft, client) => {
// Check if the event kind is allowed
if (draft.kind === 1) return true; // Allow text notes
if (draft.kind === 3) return true; // Allow contact lists
throw new Error("Unsupported event kind"); // Reject other kinds with custom message
},
// Control NIP-04 encryption/decryption
onNip04Encrypt: (pubkey, plaintext, client) => true,
onNip04Decrypt: (pubkey, ciphertext, client) => true,
// Control NIP-44 encryption/decryption
onNip44Encrypt: (pubkey, plaintext, client) => true,
onNip44Decrypt: (pubkey, ciphertext, client) => true,
});
Waiting for Client (`bunker://` URI) [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#waiting-for-client-bunker-uri)
------------------------------------------------------------------------------------------------------------------------------------------
To create a provider that waits for clients to connect, you can use the `waitForClient` method:
typescript
import { NostrConnectProvider, SimpleSigner } from "applesauce-signers";
// Create a signer for the users key
const user = SimpleSigner.fromKey("nsec1...");
// Create a signer for the provider's identity (recomended to be different from the upstream signer)
const signer = new SimpleSigner();
const provider = new NostrConnectProvider({
relays: ["wss://relay.signer.com"],
upstream: user, // Signer for actual operations
signer: signer, // Provider's identity (optional, will create a new SimpleSigner if not provided)
secret: "my-secret-key", // Recommended secret for client authentication (optional)
onClientConnect: (client) => {
console.log("Client connected:", client);
},
onClientDisconnect: (client) => {
console.log("Client disconnected:", client);
},
onConnect: (client, permissions) => {
console.log("Connection request from:", client, "with permissions:", permissions);
return true; // Accept the connection
},
onSignEvent: (draft, client) => {
console.log("Sign request from:", client, "for event:", draft);
return true; // Allow signing
},
// ... other authorization callbacks
});
// Start the provider and wait for a client
try {
// Get the bunker:// URI for clients to connect
const bunkerUri = await provider.getBunkerURI();
console.log("Bunker URI:", bunkerUri);
// Open the subscription and wait for the client to connect
const clientPubkey = await provider.waitForClient();
console.log("Connected to client:", clientPubkey);
} catch (error) {
console.error("Failed to connect:", error);
}
// Stop the provider when done
await provider.stop();
### Getting the Bunker URI [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#getting-the-bunker-uri)
The `getBunkerURI()` method returns a `bunker://` URI that clients can use to connect:
typescript
const bunkerUri = await provider.getBunkerURI();
// Returns: bunker://?relay=&secret=
This URI can be displayed as a QR code or shared with clients to initiate connections.
Connect to client (`nostrconnect://` URI) [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#connect-to-client-nostrconnect-uri)
----------------------------------------------------------------------------------------------------------------------------------------------------
To create a provider that responds to a client's `nostrconnect://` URI, pass the URI to the `start` method:
typescript
import { NostrConnectProvider, SimpleSigner } from "applesauce-signers";
// Create a signer for the users key
const user = SimpleSigner.fromKey("nsec1...");
// Create a new provider with the users signer
const provider = new NostrConnectProvider({
relays: ["wss://relay.signer.com"],
upstream: user,
onClientConnect: (client) => {
console.log("Client connected:", client);
},
onConnect: (client, permissions) => {
console.log("Connection request from:", client, "with permissions:", permissions);
return true;
},
// ... other callbacks
});
// Get the nostrconnect:// URI from the client
const nostrConnectUri = "nostrconnect://client-pubkey?secret=shared-secret&relay=wss://relay.signer.com&name=MyApp";
try {
// Start the provider and respond to the client's `nostrconnect://` URI
await provider.start(nostrConnectUri);
console.log("Provider started and connected to client");
} catch (error) {
console.error("Failed to start provider:", error);
}
// Stop when done
await provider.stop();
### Handling Initial Connect Requests [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#handling-initial-connect-requests)
You can also start a provider with an initial `connect` request event:
typescript
// Start with a connect request event
await provider.start(connectRequestEvent);
// Or start and wait for the first connect request
await provider.start();
New `connect` requests [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#new-connect-requests)
-------------------------------------------------------------------------------------------------------------------
Its not recomended but it is possible to listen for `connect` requests sent to the users pubkey and create a connection.
typescript
const pool = new RelayPool();
const user = SimpleSigner.fromKey("nsec1...");
const providers: NostrConnectProvider[] = [];
// Open a new subscription that will listen for new `connect` requests
pool
.subscription(["wss://relay.signer.com"], { kinds: [kinds.NostrConnect], "#p": [await user.getPublicKey()] })
.subscribe((event) => {
// WARNING: manually validate that this is a new `connect` request, otherwise you will create infinite providers!
// Presume this is a `connect` request and ask the user if they want to connect to the random client that just asked
if ((await askUserForConnection(event.pubkey, event)) === false) return;
// Create a new provider that will respond to the connect request
const provider = new NostrConnectProvider({
relays: ["wss://relay.signer.com"],
upstream: user,
pool,
// Use the users signer, since the client is expecting to hear back from the users pubkey
signer: user,
});
// Start the provider and respond to the `connect` request
provider.start(event);
providers.push(provider);
});
// Later close all providers
function shutdown() {
for (const provider of providers) {
provider.stop();
}
}
Provider Lifecycle [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#provider-lifecycle)
-------------------------------------------------------------------------------------------------------------
### Starting the Provider [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#starting-the-provider)
typescript
// Start without waiting for a specific client
await provider.start();
// Start and respond to a specific nostrconnect:// URI
await provider.start(nostrConnectUri);
// Start and respond to a connect request event
await provider.start(connectRequestEvent);
### Stopping the Provider [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#stopping-the-provider)
typescript
await provider.stop();
This will:
* Close the relay subscription
* Clear the state
* Cancel any pending operations
### Checking Provider Status [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#checking-provider-status)
typescript
if (provider.listening) {
console.log("Provider is listening for requests");
}
if (provider.connected) {
console.log("Provider is connected to client:", provider.client);
}
Error Handling [](https://hzrd149.github.io/applesauce/signers/bunker-provider.html#error-handling)
-----------------------------------------------------------------------------------------------------
The provider automatically handles errors and sends appropriate error responses to clients:
typescript
const upstream = {
signEvent: async (draft) => {
// Errors throw in the upstream signer will be passed along to the client
throw new Error("You shall not sign!");
},
};
const provider = new NostrConnectProvider({
// ... other options
onConnect: (client, permissions) => {
// Errors throw in the callback methods will be passed along to the client
throw new Error("You shall not pass!");
},
});
---
# Action Hub | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/actions/action-hub.html#VPContent)
Return to top
Action Hub [](https://hzrd149.github.io/applesauce/actions/action-hub.html#action-hub)
========================================================================================
The [ActionHub](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-actions.ActionHub.html)
class is the central orchestrator for running actions in your Nostr application. It combines an event store, event factory, and optional publish method into a unified interface, making it simple to execute actions that read from your local event store and publish new events to the Nostr network.
Creating an Action Hub [](https://hzrd149.github.io/applesauce/actions/action-hub.html#creating-an-action-hub)
----------------------------------------------------------------------------------------------------------------
### Basic Setup [](https://hzrd149.github.io/applesauce/actions/action-hub.html#basic-setup)
To create an ActionHub, you need an event store and event factory. Optionally, you can provide a publish method to automatically handle event publishing.
ts
import { ActionHub } from "applesauce-actions";
import { NostrEvent } from "nostr-tools";
// Create a basic ActionHub without automatic publishing
const hub = new ActionHub(eventStore, eventFactory);
// Or create one with automatic publishing
const publish = async (event: NostrEvent) => {
console.log("Publishing event:", event.kind);
await relayPool.publish(event, defaultRelays);
};
const hub = new ActionHub(eventStore, eventFactory, publish);
### With Custom Publishing Logic [](https://hzrd149.github.io/applesauce/actions/action-hub.html#with-custom-publishing-logic)
You can provide sophisticated publishing logic when creating your ActionHub:
ts
const publish = async (event: NostrEvent) => {
// Log the event
console.log("Publishing", event);
// Publish to relays
await app.relayPool.publish(event, app.defaultRelays);
// Save to local backup
await localBackup.save(event);
// Notify UI of new event
eventBus.emit("eventPublished", event);
};
const hub = new ActionHub(eventStore, eventFactory, publish);
INFO
For performance reasons, it's recommended to create only one `ActionHub` instance for your entire application and reuse it across all action executions.
Configuration Options [](https://hzrd149.github.io/applesauce/actions/action-hub.html#configuration-options)
--------------------------------------------------------------------------------------------------------------
### Save to Store [](https://hzrd149.github.io/applesauce/actions/action-hub.html#save-to-store)
By default, the ActionHub will automatically save all events created by actions to your event store. You can disable this behavior:
ts
const hub = new ActionHub(eventStore, eventFactory, publish);
hub.saveToStore = false; // Disable automatic saving to event store
Running Actions [](https://hzrd149.github.io/applesauce/actions/action-hub.html#running-actions)
--------------------------------------------------------------------------------------------------
The ActionHub provides two primary methods for executing actions: `.run()` for fire-and-forget execution with automatic publishing, and `.exec()` for fine-grained control over event handling.
### Using `.run()` - Automatic Publishing [](https://hzrd149.github.io/applesauce/actions/action-hub.html#using-run-automatic-publishing)
The [ActionHub.run](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-actions.ActionHub.html#run)
method executes an action and automatically publishes all generated events using the publish method provided during ActionHub creation.
WARNING
`ActionHub.run()` will throw an error if no `publish` method was provided when creating the ActionHub.
ts
import { FollowUser, NewContacts } from "applesauce-actions/actions";
// Create a new contact list (throws if one already exists)
try {
await hub.run(NewContacts);
console.log("Contact list created successfully");
} catch (err) {
console.error("Failed to create contact list:", err.message);
}
// Follow a user - events are automatically published
await hub.run(
FollowUser,
"3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
"wss://pyramid.fiatjaf.com/",
);
// Unfollow a user
await hub.run(UnfollowUser, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d");
### Using `.exec()` - Manual Event Handling [](https://hzrd149.github.io/applesauce/actions/action-hub.html#using-exec-manual-event-handling)
The [ActionHub.exec](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-actions.ActionHub.html#exec)
method executes an action and returns an RxJS Observable of events, giving you complete control over how events are handled and published.
#### Using RxJS forEach for Simple Cases [](https://hzrd149.github.io/applesauce/actions/action-hub.html#using-rxjs-foreach-for-simple-cases)
The RxJS [Observable.forEach](https://rxjs.dev/api/index/class/Observable#foreach)
method provides a clean way to handle all events with a single function:
ts
import { FollowUser } from "applesauce-actions/actions";
// Custom publishing logic for this specific action
const customPublish = async (event: NostrEvent) => {
// Publish to specific relays
await relayPool.publish(event, ["wss://relay.damus.io", "wss://nos.lol"]);
// Save to local database with custom metadata
await localDatabase.saveContactListUpdate(event, { source: "user_action" });
};
// Execute action and handle each event
await hub.exec(NewContacts).forEach(customPublish);
// Follow user with custom handling
await hub
.exec(FollowUser, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", "wss://pyramid.fiatjaf.com/")
.forEach(customPublish);
#### Using RxJS Subscriptions for Advanced Control [](https://hzrd149.github.io/applesauce/actions/action-hub.html#using-rxjs-subscriptions-for-advanced-control)
For more complex scenarios, you can manually subscribe to the observable:
ts
import { tap, catchError, finalize } from "rxjs/operators";
import { EMPTY } from "rxjs";
const subscription = hub
.exec(FollowUser, userPubkey, relayUrl)
.pipe(
tap((event) => console.log("Generated event:", event.kind)),
catchError((err) => {
console.error("Action failed:", err);
return EMPTY; // Handle errors gracefully
}),
finalize(() => console.log("Action completed")),
)
.subscribe({
next: async (event) => {
try {
await customPublish(event);
console.log("Event published successfully");
} catch (err) {
console.error("Failed to publish event:", err);
}
},
complete: () => {
console.log("All events processed");
subscription.unsubscribe();
},
error: (err) => {
console.error("Observable error:", err);
subscription.unsubscribe();
},
});
#### Collecting Events Before Publishing [](https://hzrd149.github.io/applesauce/actions/action-hub.html#collecting-events-before-publishing)
You can collect all events from an action before publishing them:
ts
import { toArray, lastValueFrom } from "rxjs";
// Collect all events into an array
const events = await lastValueFrom(hub.exec(NewContacts).pipe(toArray()));
console.log(`Action generated ${events.length} events`);
// Publish them in a specific order or with delays
for (const event of events) {
await publish(event);
await delay(100); // Small delay between publishes
}
Error Handling [](https://hzrd149.github.io/applesauce/actions/action-hub.html#error-handling)
------------------------------------------------------------------------------------------------
### Action Validation Errors [](https://hzrd149.github.io/applesauce/actions/action-hub.html#action-validation-errors)
Actions will throw errors for various validation failures:
ts
try {
await hub.run(NewContacts);
} catch (err) {
if (err.message.includes("contact list already exists")) {
console.log("User already has a contact list");
} else {
console.error("Unexpected error:", err);
}
}
### Publishing Errors [](https://hzrd149.github.io/applesauce/actions/action-hub.html#publishing-errors)
When using `.exec()`, you can handle publishing errors independently:
ts
await hub.exec(FollowUser, userPubkey).forEach(async (event) => {
try {
await publish(event);
} catch (publishError) {
console.error("Failed to publish event:", publishError);
// Could retry, save for later, or notify user
await saveForRetry(event);
}
});
Best Practices [](https://hzrd149.github.io/applesauce/actions/action-hub.html#best-practices)
------------------------------------------------------------------------------------------------
### Single ActionHub Instance [](https://hzrd149.github.io/applesauce/actions/action-hub.html#single-actionhub-instance)
Create one ActionHub instance per application and reuse it:
ts
// app.ts
export const actionHub = new ActionHub(eventStore, eventFactory, publish);
// other-file.ts
import { actionHub } from "./app.js";
await actionHub.run(FollowUser, pubkey);
### Conditional Event Store Saving [](https://hzrd149.github.io/applesauce/actions/action-hub.html#conditional-event-store-saving)
For actions that generate many events, you might want to control when events are saved to the store:
ts
const hub = new ActionHub(eventStore, eventFactory, publish);
// Disable automatic saving for bulk operations
hub.saveToStore = false;
// Run bulk action
const events = await lastValueFrom(hub.exec(BulkFollowUsers, userList).pipe(toArray()));
// Manually save only successful events
for (const event of events) {
try {
await publish(event);
await eventStore.add(event); // Save only after successful publish
} catch (err) {
console.error("Skipping failed event:", err);
}
}
// Re-enable automatic saving
hub.saveToStore = true;
---
# Actions | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/actions/actions.html#VPContent)
Return to top
Actions [](https://hzrd149.github.io/applesauce/actions/actions.html#actions)
===============================================================================
Actions are the core building blocks for creating and modifying Nostr events in a structured way. An [Action](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-actions.Action.html)
is an [AsyncIterator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncIterator)
that reads from the `EventStore` and yields signed Nostr events ready for publishing.
What is an Action? [](https://hzrd149.github.io/applesauce/actions/actions.html#what-is-an-action)
----------------------------------------------------------------------------------------------------
An action is a function that returns an async generator. The generator has access to:
* `events` - The event store for reading existing events
* `factory` - The event factory for creating and signing new events
* `self` - The current user's public key
Actions follow this basic pattern:
ts
import { Action } from "applesauce-actions";
function MyAction(param1: string, param2?: boolean): Action {
return async function* ({ events, factory, self }) {
// Read existing events from the store
const existingEvent = events.getReplaceable(kind, self);
// Create or modify events using the factory
const draft = await factory.modify(existingEvent, ...operations);
// Sign and yield the event for publishing
yield await factory.sign(draft);
};
}
WARNING
To avoid overriding replaceable events, actions should throw if an existing replaceable event can't be found when expected.
Pre-built Actions [](https://hzrd149.github.io/applesauce/actions/actions.html#pre-built-actions)
---------------------------------------------------------------------------------------------------
The `applesauce-actions` package comes with many pre-built actions for common social client operations. You can find the complete list in the [reference](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.Actions.html)
.
Some examples include:
* `CreateProfile` / `UpdateProfile` - Managing user profiles
* `FollowUser` / `UnfollowUser` - Managing contact lists
* `BookmarkEvent` / `UnbookmarkEvent` - Managing bookmarks
* `MuteUser` / `UnmuteUser` - Managing mute lists
* `PinNote` / `UnpinNote` - Managing pinned notes
Action Patterns [](https://hzrd149.github.io/applesauce/actions/actions.html#action-patterns)
-----------------------------------------------------------------------------------------------
### Creating New Events [](https://hzrd149.github.io/applesauce/actions/actions.html#creating-new-events)
When creating a new replaceable event, actions typically check if one already exists:
ts
export function CreateProfile(content: ProfileContent): Action {
return async function* ({ events, factory, self }) {
const metadata = events.getReplaceable(kinds.Metadata, self);
if (metadata) throw new Error("Profile already exists");
const draft = await factory.build({ kind: kinds.Metadata }, setProfileContent(content));
yield await factory.sign(draft);
};
}
### Updating Existing Events [](https://hzrd149.github.io/applesauce/actions/actions.html#updating-existing-events)
When updating events, actions verify the event exists before modifying:
ts
export function UpdateProfile(content: Partial): Action {
return async function* ({ events, factory, self }) {
const metadata = events.getReplaceable(kinds.Metadata, self);
if (!metadata) throw new Error("Profile does not exist");
const draft = await factory.modify(metadata, updateProfileContent(content));
yield await factory.sign(draft);
};
}
### Modifying Tags [](https://hzrd149.github.io/applesauce/actions/actions.html#modifying-tags)
Many actions work by adding or removing tags from existing events:
ts
export function FollowUser(pubkey: string, relay?: string, hidden = false): Action {
return async function* ({ events, factory, self }) {
const contacts = events.getReplaceable(kinds.Contacts, self);
if (!contacts) throw new Error("Missing contacts event");
const pointer = { pubkey, relays: relay ? [relay] : undefined };
const operation = addPubkeyTag(pointer);
const draft = await factory.modifyTags(contacts, hidden ? { hidden: operation } : operation);
yield await factory.sign(draft);
};
}
### Complex Operations [](https://hzrd149.github.io/applesauce/actions/actions.html#complex-operations)
Some actions perform multiple operations or create multiple events:
ts
export function CreateBookmarkSet(
title: string,
description: string,
additional: { image?: string; hidden?: NostrEvent[]; public?: NostrEvent[] },
): Action {
return async function* ({ events, factory, self }) {
const existing = getBookmarkEvent(events, self);
if (existing) throw new Error("Bookmark list already exists");
const draft = await factory.build(
{ kind: kinds.BookmarkList },
setListTitle(title),
setListDescription(description),
additional.image ? setListImage(additional.image) : undefined,
additional.public ? modifyPublicTags(...additional.public.map(addEventBookmarkTag)) : undefined,
additional.hidden ? modifyHiddenTags(...additional.hidden.map(addEventBookmarkTag)) : undefined,
);
yield await factory.sign(draft);
};
}
Creating Custom Actions [](https://hzrd149.github.io/applesauce/actions/actions.html#creating-custom-actions)
---------------------------------------------------------------------------------------------------------------
To create your own action, define a function that returns an async generator that yields signed events:
ts
import { Action } from "applesauce-actions";
import { kinds } from "nostr-tools";
function SetDisplayName(displayName: string): Action {
return async function* ({ events, factory, self }) {
// Get the current profile
const profile = events.getReplaceable(kinds.Metadata, self);
if (!profile) throw new Error("Profile not found");
// Parse existing content
const content = JSON.parse(profile.content || "{}");
// Update the display name
content.display_name = displayName;
// Create a new profile event with updated content
const draft = await factory.modify(profile, (event) => {
event.content = JSON.stringify(content);
return event;
});
// Sign and yield the event
yield await factory.sign(draft);
};
}
### Multi-Event Actions [](https://hzrd149.github.io/applesauce/actions/actions.html#multi-event-actions)
Actions can yield multiple events if needed:
ts
function CreateUserSetup(profile: ProfileContent, initialFollows: string[]): Action {
return async function* ({ events, factory, self }) {
// Create profile
const profileDraft = await factory.build({ kind: kinds.Metadata }, setProfileContent(profile));
yield await factory.sign(profileDraft);
// Create contacts list
const contactsDraft = await factory.build({
kind: kinds.Contacts,
tags: initialFollows.map((pubkey) => ["p", pubkey]),
});
yield await factory.sign(contactsDraft);
};
}
Best Practices [](https://hzrd149.github.io/applesauce/actions/actions.html#best-practices)
---------------------------------------------------------------------------------------------
1. **Validate inputs** - Check that required events exist before attempting modifications
2. **Use factory operations** - Leverage the event factory's built-in operations for common tasks
3. **Handle errors gracefully** - Throw descriptive errors when preconditions aren't met
4. **Keep actions focused** - Each action should have a single, clear responsibility
5. **Document parameters** - Use JSDoc comments to describe action parameters and behavior
The async generator pattern allows actions to be composable, testable, and easy to reason about while providing a clean interface for event creation and modification.
---
# Event Operations | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/factory/event-operations.html#VPContent)
Return to top
Event Operations [](https://hzrd149.github.io/applesauce/factory/event-operations.html#event-operations)
==========================================================================================================
Event operations are the core building blocks of the event factory system. They provide a composable, functional approach to creating and modifying Nostr events by focusing on single-responsibility transformations.
Overview [](https://hzrd149.github.io/applesauce/factory/event-operations.html#overview)
------------------------------------------------------------------------------------------
An event operation is a function that takes an event template and returns a modified version of that event. Operations are designed to be:
* **Composable**: Multiple operations can be chained together using `eventPipe()`
* **Pure**: Operations don't mutate the input, they return new objects
* **Focused**: Each operation handles one specific aspect of event creation/modification
* **Async-aware**: Operations can be synchronous or asynchronous
See all avaliable event operations in the [reference](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Operations.EventOperations.html)
.
Type Definition [](https://hzrd149.github.io/applesauce/factory/event-operations.html#type-definition)
--------------------------------------------------------------------------------------------------------
typescript
type EventOperation = (draft: EventTemplate, context: EventFactoryContext) => EventTemplate | Promise;
Every event operation receives:
* **`draft`**: The current event template/draft to transform
* **`context`**: An `EventFactoryContext` containing optional signer, relay hints, emojis, and client information
Core Patterns [](https://hzrd149.github.io/applesauce/factory/event-operations.html#core-patterns)
----------------------------------------------------------------------------------------------------
### 1\. Simple Property Operations [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_1-simple-property-operations)
These operations modify basic event properties like content or timestamps:
typescript
// Set event content
export function setContent(content: string): EventOperation {
return async (draft) => {
return { ...draft, content };
};
}
// Update created_at timestamp
export function updateCreatedAt(): EventOperation {
return (draft) => ({ ...draft, created_at: unixNow() });
}
### 2\. Tag Manipulation Operations [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_2-tag-manipulation-operations)
These operations modify the event's tags array using the [`modifyPublicTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Operations.EventOperations.modifyPublicTags.html)
and [`modifyHiddenTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Operations.EventOperations.modifyHiddenTags.html)
event operations and some [tag operations](https://hzrd149.github.io/applesauce/factory/tag-operations.html)
:
typescript
// Include a singleton tag (only one instance allowed)
export function includeSingletonTag(tag: [string, ...string[]], replace = true): EventOperation {
return modifyPublicTags(setSingletonTag(tag, replace));
}
// Include NIP-31 alt tag
export function includeAltTag(description: string): EventOperation {
return modifyPublicTags(setSingletonTag(["alt", description]));
}
### 3\. Context-Aware Operations [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_3-context-aware-operations)
These operations use the context to make decisions or fetch additional data:
typescript
// Include reaction tags with relay hints
export function includeReactionTags(event: NostrEvent): EventOperation {
return async (draft, ctx) => {
let tags = Array.from(draft.tags);
const eventHint = await ctx?.getEventRelayHint?.(event.id);
const pubkeyHint = await ctx?.getPubkeyRelayHint?.(event.pubkey);
// Add tags with relay hints if available
tags = ensureEventPointerTag(tags, {
id: event.id,
relays: eventHint ? [eventHint] : undefined,
});
return { ...draft, tags };
};
}
### 4\. Composite Operations [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_4-composite-operations)
These operations can combine multiple smaller operations using `eventPipe()` for example:
typescript
// Set text content with automatic processing
export function setShortTextContent(content: string, options?: TextContentOptions): EventOperation {
return eventPipe(
setContent(content), // Set the content
repairContentNostrLinks(), // Fix @mentions
tagPubkeyMentionedInContent(), // Add "p" tags for mentions
includeQuoteTags(), // Add "q" tags for quotes
includeContentHashtags(), // Add "t" tags for hashtags
options?.emojis ? includeContentEmojiTags(options.emojis) : skip(),
options?.contentWarning !== undefined ? setContentWarning(options.contentWarning) : skip(),
);
}
Custom Operations [](https://hzrd149.github.io/applesauce/factory/event-operations.html#custom-operations)
------------------------------------------------------------------------------------------------------------
### Basic Custom Operation [](https://hzrd149.github.io/applesauce/factory/event-operations.html#basic-custom-operation)
Here's how to create a simple operation that adds a "title" tag:
typescript
export function setTitle(title: string): EventOperation {
return (draft) => {
let tags = Array.from(draft.tags);
// Remove existing title tags
tags = tags.filter((tag) => tag[0] !== "title");
// Add new title tag
tags.push(["title", title]);
return { ...draft, tags };
};
}
### JSON Content Merger Operation [](https://hzrd149.github.io/applesauce/factory/event-operations.html#json-content-merger-operation)
Here's an example of a more complex operation that merges JSON data into existing JSON content:
typescript
export function mergeJsonContent(jsonData: Record): EventOperation {
return (draft) => {
let existingContent: Record = {};
// Try to parse existing content as JSON
if (draft.content) {
try {
existingContent = JSON.parse(draft.content);
} catch (error) {
// If parsing fails, treat as empty object
existingContent = {};
}
}
// Merge the new data with existing content
const mergedContent = { ...existingContent, ...jsonData };
// Return draft with updated JSON content
return { ...draft, content: JSON.stringify(mergedContent) };
};
}
// Usage example:
const draft = await factory.modify(
existingEvent,
mergeJsonContent({
version: "1.0",
author: "Alice",
tags: ["music", "art"],
}),
);
### Context-Aware Custom Operation [](https://hzrd149.github.io/applesauce/factory/event-operations.html#context-aware-custom-operation)
Here's an operation that uses the context to conditionally add client information:
typescript
export function includeClientTag(): EventOperation {
return (draft, ctx) => {
// Only add client tag if client info is available in context
if (!ctx.client?.name) return draft;
let tags = Array.from(draft.tags);
// Remove existing client tags
tags = tags.filter((tag) => tag[0] !== "client");
// Add client tag with optional address
const clientTag = ["client", ctx.client.name];
if (ctx.client.address) {
const { kind, pubkey, identifier } = ctx.client.address;
clientTag.push(`${kind}:${pubkey}:${identifier}`);
}
tags.push(clientTag);
return { ...draft, tags };
};
}
### Async Custom Operation [](https://hzrd149.github.io/applesauce/factory/event-operations.html#async-custom-operation)
Operations can be asynchronous when they need to perform I/O or complex computations:
typescript
export function includeHashOfContent(): EventOperation {
return async (draft) => {
// Simulate async hash computation
const hash = await computeHash(draft.content);
let tags = Array.from(draft.tags);
tags = tags.filter((tag) => tag[0] !== "content-hash");
tags.push(["content-hash", hash]);
return { ...draft, tags };
};
}
async function computeHash(content: string): Promise {
// Your hash implementation here
return "sha256:" + content.length.toString(); // Simplified example
}
Best Practices [](https://hzrd149.github.io/applesauce/factory/event-operations.html#best-practices)
------------------------------------------------------------------------------------------------------
### 1\. Single Responsibility [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_1-single-responsibility)
Each operation should focus on one specific transformation:
typescript
// Good: Focused on one thing
export function setTitle(title: string): EventOperation {
/* ... */
}
// Avoid: Doing too many things
export function setTitleAndContentAndTags(/* ... */) {
/* ... */
}
### 2\. Immutability [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_2-immutability)
Always return new objects, never mutate the input:
typescript
// Good: Creates new objects
return { ...draft, content: newContent };
// Bad: Mutates input
draft.content = newContent;
return draft;
### 3\. Array Copying [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_3-array-copying)
When modifying tags, always copy the array first:
typescript
// Good: Copy first
let tags = Array.from(draft.tags);
tags.push(newTag);
// Bad: Direct mutation
draft.tags.push(newTag);
### 4\. Conditional Operations [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_4-conditional-operations)
Use `skip()` for conditional operations in pipes:
typescript
eventPipe(
setContent(content),
shouldAddTitle ? setTitle(title) : skip(),
// ... other operations
);
### 5\. Error Handling [](https://hzrd149.github.io/applesauce/factory/event-operations.html#_5-error-handling)
Handle errors gracefully if there error isn't critical, especially in async operations:
typescript
export function safeJsonOperation(data: any): EventOperation {
return (draft) => {
try {
const content = JSON.stringify(data);
return { ...draft, content };
} catch (error) {
console.warn("Failed to serialize JSON data:", error);
return draft; // Return unchanged on error
}
};
}
Composition [](https://hzrd149.github.io/applesauce/factory/event-operations.html#composition)
------------------------------------------------------------------------------------------------
The `eventPipe()` function allows you to compose multiple operations into a single operation:
typescript
function setArticleContent(content: string): EventOperation {
return eventPipe(
// Set the content
setShortTextContent(content),
// Add an alt tag for accessibility
includeAltTag("A long form article"),
// Update the created_at timestamp
updateCreatedAt(),
// Add a client tag
includeClientTag(),
);
}
// Use in event factory
const event = await factory.build({ kind: 300023 }, setArticleContent("...content"));
Operations in a pipe are executed sequentially, with each operation receiving the result of the previous operation. The `eventPipe()` function handles both synchronous and asynchronous operations seamlessly.
---
# WalletConnect Class | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#VPContent)
Return to top
WalletConnect Class [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#walletconnect-class)
=====================================================================================================================
The `WalletConnect` class provides a client-side implementation for connecting to NIP-47 wallet services. It handles all communication with wallet services, including request encryption, response decryption, and notification handling.
Overview [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#overview)
-----------------------------------------------------------------------------------------------
`WalletConnect` is designed to be a complete client for interacting with Nostr Wallet Connect services. It provides:
* **Reactive Architecture**: Built on RxJS for efficient event handling
* **Encryption Support**: Automatic handling of NIP-04 and NIP-44 encryption
* **Request Management**: Built-in timeout handling and error management
* **Notification Support**: Real-time wallet notifications
* **Type Safety**: Full TypeScript support with typed responses
Relay Connections [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#relay-connections)
-----------------------------------------------------------------------------------------------------------------
The `WalletConnect` requires two methods for communicating with relays: a subscription method for receiving events and a publish method for sending events.
These methods can be set either through the constructor or globally on the class. At least one of these approaches must be used before creating a `WalletConnect` instance.
typescript
import { Observable } from "rxjs";
function subscriptionMethod(relays, filters) {
return new Observable((observer) => {
// Create subscription to relays
const cleanup = subscribeToRelays(relays, filters, (event) => {
observer.next(event);
});
return () => cleanup();
});
}
async function publishMethod(relays, event) {
for (const relay of relays) {
await publishToRelay(relay, event);
}
}
// Set methods globally once at app initialization
WalletConnect.subscriptionMethod = subscriptionMethod;
WalletConnect.publishMethod = publishMethod;
// Or pass them as options when creating a signer
const signer = new WalletConnect({
relays: ["wss://relay.example.com"],
subscriptionMethod,
publishMethod,
// ... other options
});
### Using the relay pool [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#using-the-relay-pool)
The simplest way to set these methods is to use the `RelayPool` from the `applesauce-relay` package.
typescript
import { RelayPool } from "applesauce-relay";
const pool = new RelayPool();
// Set the pool globally
WalletConnect.pool = pool;
// Or pass the pool as an option when creating a client
const client = new WalletConnect({
relays: ["wss://relay.example.com"],
pool,
// ... other options
});
Using a `nostr+walletconnect://` URI [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#using-a-nostr-walletconnect-uri)
--------------------------------------------------------------------------------------------------------------------------------------------------
The most common way to create a client is using a connection string:
typescript
import { WalletConnect } from "applesauce-wallet-connect";
// Create a new client from a connection string
const wallet = WalletConnect.fromConnectionString(
"nostr+walletconnect://relay.example.com?secret=abc123&pubkey=def456",
);
// Start using the wallet
await wallet.getInfo();
await wallet.payInvoice("lnbc1...");
Using a `nostr+walletauth://` URI [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#using-a-nostr-walletauth-uri)
--------------------------------------------------------------------------------------------------------------------------------------------
Some wallets support a `nostr+walletauth://` URI for the client app to request a connection from the wallet service.
typescript
import { WalletConnect } from "applesauce-wallet-connect";
// Create a new client with a random secret key
const secret = generateSecretKey();
const wallet = new WalletConnect(
secret,
relays: ["wss://relay.wallet.com"],
);
// Get the auth URI and show it to the user as a QR code
const authUri = wallet.getAuthURI();
// Wait for the service to respond
await wallet.waitForService();
console.log("Connected to wallet service!");
// Start using the wallet
await wallet.getInfo();
Checking Wallet Capabilities [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#checking-wallet-capabilities)
---------------------------------------------------------------------------------------------------------------------------------------
Before using specific methods, it's good practice to check what the wallet supports:
typescript
// Get the wallet's supported methods and capabilities
const support = await wallet.getSupport();
if (support) {
console.log("Supported methods:", support.methods);
console.log("Encryption methods:", support.encryption);
console.log("Notification types:", support.notifications);
}
// Check specific method support
if (await wallet.supportsMethod("pay_invoice")) {
console.log("Wallet supports invoice payments");
}
if (await wallet.supportsNotifications()) {
console.log("Wallet supports notifications");
}
Basic Wallet Operations [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#basic-wallet-operations)
-----------------------------------------------------------------------------------------------------------------------------
### Getting Wallet Information [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#getting-wallet-information)
typescript
// Get basic wallet info
const info = await wallet.getInfo();
console.log("Wallet alias:", info.alias);
console.log("Network:", info.network);
// Get current balance
const balance = await wallet.getBalance();
console.log("Balance:", balance.balance, "msats");
### Transaction History [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#transaction-history)
typescript
// Get recent transactions
const transactions = await wallet.listTransactions({
limit: 10,
type: "incoming",
});
transactions.transactions.forEach((tx) => {
console.log(`${tx.type}: ${tx.amount} msats`);
});
Payment Operations [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#payment-operations)
-------------------------------------------------------------------------------------------------------------------
### Invoice Payments [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#invoice-payments)
typescript
// Pay a Lightning invoice
const result = await wallet.payInvoice("lnbc1...");
console.log("Payment successful:", result.preimage);
// Pay multiple invoices at once
const results = await wallet.payMultipleInvoices([{ invoice: "lnbc1..." }, { invoice: "lnbc2..." }]);
### Keysend Payments [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#keysend-payments)
typescript
// Send a keysend payment
const result = await wallet.payKeysend(
"pubkey123...",
100000, // 100 sats in msats
undefined, // preimage (optional)
[{ type: 696969, value: "Hello from Nostr!" }], // TLV records
);
### Creating Invoices [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#creating-invoices)
typescript
// Create a new invoice
const invoice = await wallet.makeInvoice(50000, {
description: "Coffee payment",
expiry: 3600, // 1 hour
});
console.log("Invoice created:", invoice.payment_request);
Notifications [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#notifications)
---------------------------------------------------------------------------------------------------------
### Using the notification Method [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#using-the-notification-method)
The `notification` method allows you to listen for specific types of notifications:
typescript
// Listen for payment received notifications
const subscription = wallet.notification("payment_received", (notification) => {
const { payment_hash, amount, fee } = notification;
console.log(`Payment received: ${amount} msats`);
});
// Listen for payment sent notifications
const sentSubscription = wallet.notification("payment_sent", (notification) => {
console.log("Payment sent successfully");
});
// Clean up when done
subscription.unsubscribe();
sentSubscription.unsubscribe();
### Using Observables [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#using-observables)
For more advanced usage, you can subscribe to the observables directly:
typescript
import { filter, map } from "rxjs";
// Subscribe to all notifications
wallet.notifications$.subscribe((notification) => {
console.log("Notification:", notification);
});
// Filter notifications by type
wallet.notifications$
.pipe(
filter((n) => n.notification_type === "payment_received"),
map((n) => n.notification),
)
.subscribe((notification) => {
console.log("Payment received:", notification);
});
Available Observables [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#available-observables)
-------------------------------------------------------------------------------------------------------------------------
### support$ [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#support)
Emits wallet support information when it changes:
typescript
wallet.support$.subscribe((support) => {
if (support) {
console.log("Wallet supports:", support.methods);
}
});
### notifications$ [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#notifications-1)
Emits all wallet notifications:
typescript
wallet.notifications$.subscribe((notification) => {
console.log("Notification:", notification);
});
### encryption$ [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#encryption)
Emits the preferred encryption method:
typescript
wallet.encryption$.subscribe((method) => {
console.log("Using encryption:", method);
});
Error Handling [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#error-handling)
-----------------------------------------------------------------------------------------------------------
WalletConnect provides comprehensive error handling with typed errors:
typescript
try {
const result = await wallet.payInvoice("lnbc1...");
console.log("Payment successful:", result.preimage);
} catch (error) {
if (error instanceof InsufficientBalanceError) {
console.log("Not enough balance:", error.message);
} else if (error instanceof InvalidInvoiceError) {
console.log("Invalid invoice:", error.message);
} else {
console.log("Unexpected error:", error.message);
}
}
### Common Error Types [](https://hzrd149.github.io/applesauce/wallet-connect/wallet-connect.html#common-error-types)
* `InsufficientBalanceError`: When the wallet doesn't have enough balance
* `InvalidInvoiceError`: When an invoice is malformed
* `RateLimitedError`: When too many requests are made
* `UserRejectedError`: When the user rejects the operation
For a complete list of error types and their meanings, see the [typedocs](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-wallet-connect.WalletConnect.html)
.
---
# Account Manager | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/accounts/manager.html#VPContent)
Return to top
Account Manager [](https://hzrd149.github.io/applesauce/accounts/manager.html#account-manager)
================================================================================================
The [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
class is the core of the library, as its name suggests its used to manage multiple accounts
Account types [](https://hzrd149.github.io/applesauce/accounts/manager.html#account-types)
--------------------------------------------------------------------------------------------
By default the account manager comes with no account types. you have to manually add them when you create the instance. luckily there is a handy method to add the most common types [registerCommonAccountTypes](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.registerCommonAccountTypes.html)
ts
import { AccountManager, registerCommonAccountTypes, AmberClipboardAccount } from "applesauce-accounts";
// create an account manager instance
const manager = new AccountManager();
// register common account types
registerCommonAccountTypes(manager);
// manually add account type
manager.registerType(AmberClipboardAccount);
Adding and removing accounts [](https://hzrd149.github.io/applesauce/accounts/manager.html#adding-and-removing-accounts)
--------------------------------------------------------------------------------------------------------------------------
ts
import { AccountManager, registerCommonAccountTypes, SimpleAccount } from "applesauce-accounts";
// create an account manager instance
const manager = new AccountManager();
// register common account types
registerCommonAccountTypes(manager);
// subscribe to the active account
manager.active$.subscribe((account) => {
if (account) console.log(`${account.id} is now active`);
else console.log("no account is active");
updateUI();
});
// create an account
const account = SimpleAccount.fromKey("788229e1801c4576391d39a03610293ea7e6645c9d39aca54c62fc6d71cbc385");
// add it to the manager
manager.addAccount(account);
// set it as active
manager.setActive(account);
// later, remove the account and the active account will also update
manager.removeAccount(account.id);
Active account [](https://hzrd149.github.io/applesauce/accounts/manager.html#active-account)
----------------------------------------------------------------------------------------------
The `AccountManager` class exposes a set of methods to track which account is active and switch the active account
* `AccountManager.active` gets the currently active account
* `AccountManager.active$` an observable of the active account, can be used to subscribe to changes
* `AccountManager.setActive(id: string | Account)` set the active account
Persisting accounts [](https://hzrd149.github.io/applesauce/accounts/manager.html#persisting-accounts)
--------------------------------------------------------------------------------------------------------
The account manager exposes two methods that can be used to persist accounts between app reloads. `toJSON` and `fromJSON`
ts
import { AccountManager, registerCommonAccountTypes, SimpleAccount } from "applesauce-accounts";
// create an account manager instance
const manager = new AccountManager();
// register common account types
registerCommonAccountTypes(manager);
// first load all accounts from localStorage
const json = JSON.parse(localStorage.getItem("accounts") || "[]");
await manager.fromJSON(json);
// next, subscribe to any accounts added or removed
manager.accounts$.subscribe((accounts) => {
// save all the accounts into the "accounts" field
localStorage.setItem("accounts", JSON.stringify(manager.toJSON()));
});
// load active account from storage
const active = localStorage.getItem("active");
if (active) manager.setActive(active);
// subscribe to active changes
manager.active$.subscribe((account) => {
if (account) localStorage.setItem("active", account.id);
else localStorage.clearItem("active");
});
---
# Applesauce-react | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/react/package.html#VPContent)
Return to top
Applesauce-react [](https://hzrd149.github.io/applesauce/react/package.html#applesauce-react)
===============================================================================================
Install [](https://hzrd149.github.io/applesauce/react/package.html#install)
-----------------------------------------------------------------------------
bash
npm install applesauce-react
Using providers [](https://hzrd149.github.io/applesauce/react/package.html#using-providers)
---------------------------------------------------------------------------------------------
To start using applesauce with react you must add some of the providers to your react root
* If you want to use the `useEventModel` hook you must add the [EventStoreProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.EventStoreProvider.html)
* If you want to use the `useEventFactory` hook you must add the [FactoryProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.FactoryProvider.html)
* If you want to use the `useAccountManager` or `useActiveAccount` hook you must add the [AccountsProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.AccountsProvider.html)
* If you want to use the `useEventStore` hook you must add the `EventStoreProvider` or [EventStoreProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.EventStoreProvider.html)
Simple setup [](https://hzrd149.github.io/applesauce/react/package.html#simple-setup)
---------------------------------------------------------------------------------------
A simple example would look like
js
import { EventStore } from "applesauce-core";
import { useEventStore } from "applesauce-react/hooks";
import { EventStoreProvider } from "applesauce-react/providers";
const eventStore = new EventStore();
function App() {
// get event store from context
const store = useEventStore();
return ;
}
const root = createRoot(document.getElementById("root"));
root.render(
// the EventStoreProvider also wraps the EventStoreProvider
,
);
Advanced setup [](https://hzrd149.github.io/applesauce/react/package.html#advanced-setup)
-------------------------------------------------------------------------------------------
A more complete example that uses all the providers would look something like
First create a new `AccountManager` that saves its state to local storage
js
// accounts.js
import { safeParse } from "applesauce-core/helpers/json";
import { AccountManager, registerCommonAccountTypes } from "applesauce-accounts";
// setup account manager
const accountManager = new AccountManager();
registerCommonAccountTypes(accountManager);
accountManager.registerType(AmberClipboardAccount);
// load all accounts
if (localStorage.getItem("accounts")) {
const json = safeParse(localStorage.getItem("accounts"));
if (json) accountManager.fromJSON(json);
}
// save accounts to localStorage when they change
accountManager.accounts$.subscribe(() => {
localStorage.setItem("accounts", JSON.stringify(accountManager.toJSON()));
});
// load active account
if (localStorage.active) accountManager.setActive(localStorage.active);
// save active to localStorage
accountManager.active$.subscribe((account) => {
if (account) localStorage.setItem("active", account.id);
else localStorage.removeItem("active");
});
export default accountManager;
Next update `app.js` to use the new hooks
js
// app.js
import { NoteBlueprint } from "applesauce-factory/blueprints";
import { useEventStore, useEventFactory, useActiveAccount } from "applesauce-react/hooks";
function App() {
// get event store from context
const account = useActiveAccount();
const store = useEventStore();
const factory = useEventFactory();
const post = async () => {
// ignore if no active account
if (!account) return;
const draft = await factory.create(NoteBlueprint, "hello world");
const signed = await account.signEvent(draft);
store.add(signed);
};
return (
);
}
export default App;
And finally update `index.js` to use the Providers
js
// index.js
import { EventStore } from "applesauce-core";
import { EventFactory } from "applesauce-factory";
import { NoteBlueprint } from "applesauce-factory/blueprints";
import { useEventStore, useEventFactory, useActiveAccount, EventStoreProvider } from "applesauce-react/hooks";
import { AccountsProvider, FactoryProvider } from "applesauce-react/providers";
import accountManager from "./accounts.js";
import App from "./app.js";
// create event store and factory
const eventStore = new EventStore();
const factory = new EventFactory({
// use the active signer from the account manager
signer: accountManager.signer,
});
const root = createRoot(document.getElementById("root"));
root.render(
// provide the stores, factory, and accounts to the react app
,
);
---
# Tag Operations | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/factory/tag-operations.html#VPContent)
Return to top
Tag Operations [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#tag-operations)
====================================================================================================
Tag operations are specialized functions designed to modify arrays of Nostr event tags. Unlike [event operations](https://hzrd149.github.io/applesauce/factory/event-operations.html)
which work on entire events, tag operations focus exclusively on transforming tag arrays. This makes them perfect for use with [`modifyPublicTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Operations.EventOperations.modifyPublicTags.html)
and [`modifyHiddenTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Operations.EventOperations.modifyHiddenTags.html)
event operations, allowing precise control over both public event tags and hidden encrypted tags on NIP-51 lists.
Overview [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#overview)
----------------------------------------------------------------------------------------
A tag operation is a function that takes an array of tags and returns a modified version of that array. Tag operations are designed to be:
* **Composable**: Multiple tag operations can be chained together using `tagPipe()`
* **Pure**: Operations don't mutate the input array, they return new arrays
* **Focused**: Each operation handles one specific type of tag transformation
* **Async-aware**: Operations can be synchronous or asynchronous
* **Context-aware**: Operations can use relay hints and other context information
See all available tag operations in the [reference](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Operations.TagOperations.html)
.
Type Definition [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#type-definition)
------------------------------------------------------------------------------------------------------
typescript
type TagOperation = (tags: string[][], context: EventFactoryContext) => string[][] | Promise;
Every tag operation receives:
* **`tags`**: The current array of tags to transform
* **`context`**: An `EventFactoryContext` containing optional signer, relay hints, emojis, and client information
Usage with Event Operations [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#usage-with-event-operations)
------------------------------------------------------------------------------------------------------------------------------
Tag operations are typically used within event operations via `modifyPublicTags` and `modifyHiddenTags`:
typescript
// Modify public tags
const eventOp = modifyPublicTags(
addPubkeyTag("npub1..."),
setSingletonTag(["title", "My List"]),
removeEventTag("event-id"),
);
// Modify hidden tags (requires signer)
const hiddenOp = modifyHiddenTags(addEventTag("secret-event-id"), addPubkeyTag("secret-pubkey"));
// Use both in event creation
const event = await factory.build(
{ kind: 30000 }, // Follow set
eventOp,
hiddenOp,
);
Core Patterns [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#core-patterns)
--------------------------------------------------------------------------------------------------
### 1\. Simple Tag Manipulation [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_1-simple-tag-manipulation)
These operations add, remove, or modify basic tags:
typescript
// Add a pubkey tag with relay hint
export function addPubkeyTag(pubkey: string | ProfilePointer, replace = true): TagOperation {
return async (tags, { getPubkeyRelayHint }) => {
const pointer = typeof pubkey === "string" ? { pubkey: pubkey } : { ...pubkey };
// Add relay hint if available
if (getPubkeyRelayHint && pointer.relays?.[0] === undefined) {
const hint = await getPubkeyRelayHint(pointer.pubkey);
if (hint) pointer.relays = [hint];
}
// Remove existing matching tags if replace is true
if (replace) tags = tags.filter((t) => !(t[0] === "p" && t[1] === pointer.pubkey));
// Add new tag
return [...tags, createPTagFromProfilePointer(pointer)];
};
}
// Remove all matching tags
export function removePubkeyTag(pubkey: string): TagOperation {
return (tags) => tags.filter((t) => !(t[0] === "p" && t[1] === pubkey));
}
### 2\. Singleton Tag Operations [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_2-singleton-tag-operations)
These operations ensure only one instance of a tag type exists using the [`ensureSingletonTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.ensureSingletonTag.html)
helper function:
typescript
// Set a singleton tag (only one allowed)
export function setSingletonTag(tag: [string, ...string[]], replace = true): TagOperation {
return (tags) => ensureSingletonTag(tags, tag, replace);
}
// Remove all instances of a singleton tag
export function removeSingletonTag(tag: string): TagOperation {
return (tags) => tags.filter((t) => !(t[0] === tag));
}
### 3\. Name/Value Tag Operations [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_3-name-value-tag-operations)
These operations handle tags with name-value pairs:
typescript
// Add a name/value tag with optional custom matcher
export function addNameValueTag(
tag: [string, string, ...string[]],
replace = true,
matcher?: (a: string, b: string) => boolean,
): TagOperation {
return (tags) => {
if (replace) return ensureNamedValueTag(tags, tag, true, matcher);
else return [...tags, tag];
};
}
// Remove matching name/value tags
export function removeNameValueTag(tag: string[]): TagOperation {
return (tags) => tags.filter((t) => !(t[0] === tag[0] && t[1] === tag[1]));
}
### 4\. Context-Aware Operations [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_4-context-aware-operations)
These operations use the context to fetch relay hints or other information:
typescript
// Add event tag with automatic relay hint
export function addEventTag(id: string | EventPointer, replace = true): TagOperation {
return async (tags, { getEventRelayHint }) => {
const pointer = typeof id === "string" ? { id } : id;
// Fetch relay hint from context if available
if (getEventRelayHint && pointer.relays?.[0] === undefined) {
const hint = await getEventRelayHint(pointer.id);
if (hint) pointer.relays = [hint];
}
// Remove existing tags if replace is true
if (replace) tags = tags.filter((t) => !(t[0] === "e" && t[1] === pointer.id));
return [...tags, createETagFromEventPointer(pointer)];
};
}
### 5\. Specialized Operations [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_5-specialized-operations)
These operations handle specific use cases like bookmarks or relays:
typescript
// Add relay tag with URL normalization
export function addRelayTag(url: string | URL, tagName = "relay", replace = true): TagOperation {
url = normalizeURL(url).toString();
return addNameValueTag([tagName, url], replace, (a, b) => isSameURL(a, b));
}
// Add bookmark tag (handles both events and articles)
export function addEventBookmarkTag(event: NostrEvent): TagOperation {
if (event.kind !== kinds.ShortTextNote && event.kind !== kinds.LongFormArticle)
throw new Error(`Event kind (${event.kind}) cannot be added to bookmarks`);
return isReplaceable(event.kind) ? addCoordinateTag(getAddressPointerForEvent(event)) : addEventTag(event.id);
}
Custom Operations [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#custom-operations)
----------------------------------------------------------------------------------------------------------
### Basic Custom Operation [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#basic-custom-operation)
Here's how to create a simple operation that adds a custom tag:
typescript
export function addCustomTag(value: string): TagOperation {
return (tags) => {
// Remove existing custom tags
const filtered = tags.filter((tag) => tag[0] !== "custom");
// Add new custom tag
return [...filtered, ["custom", value]];
};
}
### Conditional Tag Operation [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#conditional-tag-operation)
Create operations that conditionally modify tags:
typescript
export function addConditionalTag(condition: boolean, tag: [string, ...string[]]): TagOperation {
return (tags) => {
if (!condition) return tags;
// Remove existing tags of this type
const filtered = tags.filter((t) => t[0] !== tag[0]);
// Add the new tag
return [...filtered, tag];
};
}
### Async Tag Operation with Context [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#async-tag-operation-with-context)
Operations can be asynchronous and use context:
typescript
export function addTagWithRelayHint(eventId: string): TagOperation {
return async (tags, { getEventRelayHint }) => {
// Fetch relay hint asynchronously
const relayHint = await getEventRelayHint?.(eventId);
// Create tag with or without relay hint
const tag = relayHint ? ["e", eventId, relayHint] : ["e", eventId];
return [...tags, tag];
};
}
### Bulk Tag Operation [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#bulk-tag-operation)
Handle multiple items at once:
typescript
export function addMultiplePubkeyTags(pubkeys: string[]): TagOperation {
return async (tags, context) => {
let result = [...tags];
// Add each pubkey tag
for (const pubkey of pubkeys) {
result = await addPubkeyTag(pubkey)(result, context);
}
return result;
};
}
Best Practices [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#best-practices)
----------------------------------------------------------------------------------------------------
### 1\. Immutability [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_1-immutability)
Always return new arrays, never mutate the input:
typescript
// Good: Creates new array
return [...tags, newTag];
// Bad: Mutates input
tags.push(newTag);
return tags;
### 2\. Filtering Before Adding [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_2-filtering-before-adding)
When replacing tags, filter first:
typescript
// Good: Filter then add
const filtered = tags.filter((t) => t[0] !== "title");
return [...filtered, ["title", newTitle]];
// Avoid: Complex logic
return tags.map((t) => (t[0] === "title" ? ["title", newTitle] : t));
### 3\. Handle Edge Cases [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_3-handle-edge-cases)
Check for invalid inputs:
typescript
export function safeAddTag(tag: [string, ...string[]]): TagOperation {
// Validate tag format
if (!tag || tag.length < 2 || !tag[0] || !tag[1]) {
throw new Error("Invalid tag format");
}
return (tags) => {
return [...tags, tag];
};
}
### 4\. Use Helper Functions [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#_4-use-helper-functions)
Leverage existing helper functions:
typescript
import { ensureSingletonTag } from "applesauce-factory/helpers/tag";
export function addUniqueTag(tag: [string, ...string[]]): TagOperation {
// Replace any existing tags with the same name to ensure only one instance of the tag exists
return (tags) => ensureSingletonTag(tags, tag, true);
}
Composition [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#composition)
----------------------------------------------------------------------------------------------
The `tagPipe()` function allows you to compose multiple tag operations into a single operation:
typescript
function setupListTags(title: string, pubkeys: string[]): TagOperation {
return tagPipe(
// Set the title
setSingletonTag(["title", title]),
// Add all pubkeys
...pubkeys.map((pubkey) => addPubkeyTag(pubkey)),
// Remove any old description
removeSingletonTag("description"),
);
}
// Use in event operation
const eventOp = factory.build(
{ kind: 30000 },
// Use the modifyPublicTags to modify the public tags on the event
modifyPublicTags(setupListTags("My Friends", ["npub1...", "npub2..."])),
);
Integration with Hidden Tags [](https://hzrd149.github.io/applesauce/factory/tag-operations.html#integration-with-hidden-tags)
--------------------------------------------------------------------------------------------------------------------------------
Tag operations work seamlessly with both public and hidden tags using the [`modifyPublicTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Operations.EventOperations.modifyPublicTags.html)
and [`modifyHiddenTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Operations.EventOperations.modifyHiddenTags.html)
event operations:
typescript
// Create operations for both public and hidden tags
const publicTags = tagPipe(setSingletonTag(["title", "Public List"]), addPubkeyTag("public-user"));
const hiddenTags = tagPipe(addPubkeyTag("secret-user"), addPubkeyTag("other-user"));
// Apply to event
const event = await factory.build({ kind: 30000 }, modifyPublicTags(publicTags), modifyHiddenTags(hiddenTags));
This separation allows you to maintain public metadata while keeping sensitive information encrypted in hidden tags, perfect for NIP-51 lists and other privacy-focused applications.
---
# applesauce
[Skip to content](https://hzrd149.github.io/applesauce/signers/signers.html#VPContent)
Return to top
Password Signer [](https://hzrd149.github.io/applesauce/signers/signers.html#password-signer)
-----------------------------------------------------------------------------------------------
The [PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html)
is a [NIP-49](https://github.com/nostr-protocol/nips/blob/master/49.md)
(Private Key Encryption) signer
To reuse an existing `ncryptsec` you can set the `signer.ncryptsec` field
ts
// create a new password signer
const signer = new PasswordSigner();
// use a pre-existing ncryptsec
signer.ncryptsec = "ncryptsec1q...";
To create a new ncryptsec you can set the `signer.key` field on the signer
ts
// create a new password signer
const signer = new PasswordSigner();
// or create a new one using a key and password
const randomBytes = new Uint8Array(64);
window.crypto.getRandomValues(randomBytes);
signer.key = randomBytes;
signer.setPassword("changeme");
// new ncryptset
console.log(signer.ncryptsec);
### Locking and Unlocking [](https://hzrd149.github.io/applesauce/signers/signers.html#locking-and-unlocking)
To unlock the signer so it can sign events you have to call the [`unlock`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html#unlock)
method
ts
try {
const password = prompt("Enter Password");
await signer.unlock(password);
} catch (err) {
console.log("Failed to unlock signer. maybe incorrect password?");
}
### Changing the password [](https://hzrd149.github.io/applesauce/signers/signers.html#changing-the-password)
To change the password you can simply unlock the signer then call [`setPassword`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html#setPassword)
ts
try {
const unlockPassword = prompt("Enter current password");
await signer.unlock(unlockPassword);
// set new password
const unlockPassword = prompt("Enter new password");
await signer.setPassword(unlockPassword);
} catch (err) {
console.log("Failed to unlock signer. maybe incorrect password?");
}
### Additional fields and methods [](https://hzrd149.github.io/applesauce/signers/signers.html#additional-fields-and-methods)
* [`unlocked`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html#unlocked)
a boolean field whether the signer is unlocked
* [`testPassword`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html#testPassword)
will return a promise that resolves or rejects based on if can decrypt the ncryptsec
Simple Signer [](https://hzrd149.github.io/applesauce/signers/signers.html#simple-signer)
-------------------------------------------------------------------------------------------
The [`SimpleSigner`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
class is a standard signer that holds the secret key in memory and supports NIP-04 and NIP-44 encryption
You can create a new signer and secret key by not passing anything into the constructor
ts
const signer = new SimpleSigner();
Or you can import and existing secret key
ts
const key = new Uint8Array();
window.crypto.getRandomValues(key);
// pass the key into constructor
const signer = new SimpleSigner(key);
// or set it manually
signer.key = key;
Serial Port Signer [](https://hzrd149.github.io/applesauce/signers/signers.html#serial-port-signer)
-----------------------------------------------------------------------------------------------------
The [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
is a that supports the [nostr-signing-device](https://github.com/lnbits/nostr-signing-device)
WARNING
This signer only works on chrome browsers and does not support NIP-44 encryption
### Checking support [](https://hzrd149.github.io/applesauce/signers/signers.html#checking-support)
The signer exposes a static property [`SerialPortSigner.SUPPORTED`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#SUPPORTED)
that will test if `navigator.serial` is supported
Amber Clipboard Signer [](https://hzrd149.github.io/applesauce/signers/signers.html#amber-clipboard-signer)
-------------------------------------------------------------------------------------------------------------
The [`AmberClipboardSigner`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
class can be used to connect to the [Amber web api](https://github.com/greenart7c3/Amber/blob/master/docs/web-apps.md)
WARNING
This signer can NOT work in the background and always requires direct user approval
---
# Models | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/core/models.html#VPContent)
Return to top
Models [](https://hzrd149.github.io/applesauce/core/models.html#models)
=========================================================================
Models are pre-built methods for subscribing to computed state from the `EventStore`.
INFO
Models do not fetch any events from relays, they only subscribe to the events that are already in the event store.
Using models [](https://hzrd149.github.io/applesauce/core/models.html#using-models)
-------------------------------------------------------------------------------------
The [`eventStore.model`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.EventStore.html#model)
method can be used to create a model and returns a rxjs observable that can be subscribed to.
ts
import { TimelineModel } from "applesauce-core/models";
// The first argument is the model constructor and the remaining are passed to the model
const observable = eventStore.model(TimelineModel, { kinds: [1] });
// start the query by subscribing to it
observable.subscribe((events) => {
console.log(events);
});
// adding events to the event store will update the timeline query
eventStore.add({kind: 1, content: 'new note', ...})
Performance [](https://hzrd149.github.io/applesauce/core/models.html#performance)
-----------------------------------------------------------------------------------
Models with similar arguments are cached in the event store and reused for performance reasons. This can help with multiple UI components subscribing to the same model.
ts
import { ProfileModel } from "applesauce-core/models";
// Create the first model
const first = eventStore.model(ProfileModel, { pubkey: "pubkey" });
// Create the second model
const second = eventStore.model(ProfileModel, { pubkey: "pubkey" });
// Both will be the same observable
console.log(first === second); // true
Prebuilt Models [](https://hzrd149.github.io/applesauce/core/models.html#prebuilt-models)
-------------------------------------------------------------------------------------------
There are some common prebuilt models that come with `applesauce-core`
* [`ProfileModel`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.Models.ProfileModel.html)
subscribes to a single pubkey's profile (kind 0)
* [`TimelineModel`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.Models.TimelineModel.html)
subscribes to a sorted array of events that match filters
* [`RepliesQuery`](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.Models.RepliesModel.html)
subscribes to all NIP-10 and NIP-22 replies to an event
And there are a lot more in [the docs](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Models.html)
Custom Models [](https://hzrd149.github.io/applesauce/core/models.html#custom-models)
---------------------------------------------------------------------------------------
A custom model is simply a function that returns a [`Model`](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Model.html)
function.
ts
import { Model } from "applesauce-core";
function CustomModel(arg: string): Model {
return (eventStore) =>
new Observable((observer) => {
// observable code here
observer.next("testing");
});
}
As an example here is a custom model that will parse a [NIP-78](https://github.com/nostr-protocol/nips/blob/master/78.md)
app event that contains JSON
ts
import { map } from "rxjs/operators";
import { Model } from "applesauce-core";
/** A model that gets JSON from a app data event */
function AppSettingsModel(pubkey: string): Model {
return (eventStore) =>
eventStore.replaceable(30078, pubkey, "app-settings").pipe(
map((event) => {
if (!event) return undefined;
return JSON.parse(event.content) as T;
}),
);
}
// Create the model and subscribe to it
const sub = eventStore
.model(AppSettingsModel, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d")
.subscribe((json) => {
// json will either be undefined or { theme: string }
if (json) console.log("updated data", json);
});
// Add an event to the event store to trigger the model
eventStore.add({
kind: 30078,
content: '{"theme": "dark"}',
// rest of event
});
---
# React Hooks | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/react/hooks.html#VPContent)
Return to top
React Hooks [](https://hzrd149.github.io/applesauce/react/hooks.html#react-hooks)
===================================================================================
useObservableMemo [](https://hzrd149.github.io/applesauce/react/hooks.html#useobservablememo)
-----------------------------------------------------------------------------------------------
The [`useObservableMemo`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useObservableMemo.html)
hook is a thing wrapper around the `useObservableState` hook from [observable-hooks](https://observable-hooks.js.org/)
that re-creates the observable when the dependencies change and allows `undefined` to returned
This is useful for subscribing to observables that are not created yet
ts
const account = useActiveAccount(); // IAccount | null
const profile = useObservableMemo(() => {
if (account) return eventStore.profile(account.pubkey);
else return undefined;
}, [account.pubkey]);
useEventStore [](https://hzrd149.github.io/applesauce/react/hooks.html#useeventstore)
---------------------------------------------------------------------------------------
The [`useEventStore`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventStore.html)
hook can be used at access the `EventStore` from anywhere in the react tree
useModel [](https://hzrd149.github.io/applesauce/react/hooks.html#usemodel)
-----------------------------------------------------------------------------
The [`useModel`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useModel.html)
hook requires the `EventStoreProvider` and can be used to create and run a model in the `EventStore` and subscribe to the results
ts
function UserAvatar({ pubkey }: { pubkey: string }) {
const profile = useModel(ProfileQuery, [pubkey]);
// profile will be undefined until the event is loaded
return
}
useEventFactory [](https://hzrd149.github.io/applesauce/react/hooks.html#useeventfactory)
-------------------------------------------------------------------------------------------
The [`useEventFactory`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventFactory.html)
hook can be used at access the `EventFactory` from anywhere in the react tree
useActiveAccount [](https://hzrd149.github.io/applesauce/react/hooks.html#useactiveaccount)
---------------------------------------------------------------------------------------------
The [useActiveAccount](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useActiveAccount.html)
hook requires the `AccountsProvider` and returns the currently active account or `undefined`
useAccountManager [](https://hzrd149.github.io/applesauce/react/hooks.html#useaccountmanager)
-----------------------------------------------------------------------------------------------
The [useAccountManager](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useAccountManager.html)
hook requires the `AccountsProvider` and returns the `AccountManager` class
useRenderedContent [](https://hzrd149.github.io/applesauce/react/hooks.html#userenderedcontent)
-------------------------------------------------------------------------------------------------
The [useRenderedContent](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useRenderedContent.html)
hook can be used to parse and render an events `content` into a JSX tree
INFO
The components directory should be defined outside of the component itself to avoid unnecessary re-renders
js
const event = { content: "hello world #grownostr", tags: [["t", "grownostr"]] };
// a directory of optional components to use when rendering the content
const components = {
// render hashtags inline
hashtag: ({ node }) => {node.name},
// custom NIP-30 emojis
emoji: ({ node }) => ,
};
// A simple component to render an event
function SimpleNote({ event }) {
const content = useRenderedContent(event, components);
return (
{event.pubkey} {event.created_at}
{content}
);
}
// render the event
;
---
# Accounts | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/accounts/accounts.html#VPContent)
Return to top
Accounts [](https://hzrd149.github.io/applesauce/accounts/accounts.html#accounts)
===================================================================================
The [account classes](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
are simple wrappers around various [Signers](https://hzrd149.github.io/applesauce/signers/signers.html)
and expose a `toJSON` and `fromJSON` method to let you save them to localStorage or indexeddb databases
Built-in account types [](https://hzrd149.github.io/applesauce/accounts/accounts.html#built-in-account-types)
---------------------------------------------------------------------------------------------------------------
* [ExtensionAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ExtensionAccount.html)
is a wrapper around [ExtensionSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html)
* [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
is a wrapper around [PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html)
* [NostrConnectAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html)
is a wrapper around [NostrConnectSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectSigner.html)
* [SimpleAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html)
is a wrapper around [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
* [SerialPortAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html)
is a wrapper around [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
* [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
is a wrapper around [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
* [AmberClipboardAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html)
is a wrapper around [AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
Creating new accounts [](https://hzrd149.github.io/applesauce/accounts/accounts.html#creating-new-accounts)
-------------------------------------------------------------------------------------------------------------
All account classes require the signer to be created and setup first
ts
import { SimpleSigner } from "applesauce-signers/signers";
import { SimpleAccount } from "applesauce-accounts/accounts";
// create the signer first
const signer = new SimpleSigner();
// setup signer
const pubkey = await signer.getPublicKey();
// create account
const account = new SimpleAccount(pubkey, signer);
For a nostr connect signer it would look something like
ts
import { NostrConnectSigner } from "applesauce-signers/signers";
import { NostrConnectAccount } from "applesauce-accounts/accounts";
const signer = await NostrConnectSigner.fromBunkerURI("bunker://....");
const pubkey = await signer.getPublicKey();
const account = new NostrConnectAccount(pubkey, signer);
Request queue [](https://hzrd149.github.io/applesauce/accounts/accounts.html#request-queue)
---------------------------------------------------------------------------------------------
By default all accounts use a request queue, so the signer only gets on sign/encrypt/decrypt request at a time. This should make it safe to make a bunch of requests to the account without overloading the user
ts
import { ExtensionSigner } from "applesauce-signers/signers";
import { ExtensionAccount } from "applesauce-accounts/accounts";
const signer = new ExtensionSigner();
const pubkey = await signer.getPublicKey();
const account = new ExtensionAccount(pubkey, signer);
// make requests
account.signEvent({ kind: 1, content: "hello world", created_at: 0, tags: [] }).then((signed) => {
console.log(signed);
});
// make another without waiting
account.signEvent({ kind: 1, content: "creating spam", created_at: 0, tags: [] }).then((signed) => {
console.log(signed);
});
account.nip04
.decrypt("3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", "encrypted-text")
.then((plaintext) => {
console.log(plaintext);
});
All the requests will be made one at a time in order, if any request fails (user rejects, signer timeout) then the queue will continue
The `account.abortQueue(reason?: Error)` method can be used to abort all pending requests. this will cause all promises to throw with `undefined` or `reason` if it was passed to the `abortQueue` method
To disable the request queue set `account.disableQueue = false` directly after creating the account. it can also be disabled on the `AccountManager` before any accounts are added
Custom account types [](https://hzrd149.github.io/applesauce/accounts/accounts.html#custom-account-types)
-----------------------------------------------------------------------------------------------------------
To create your own account type first your going to need to create a new signer class that implements [Nip07Interface](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.Nip07Interface.html)
### Create a new signer class [](https://hzrd149.github.io/applesauce/accounts/accounts.html#create-a-new-signer-class)
ts
class ApiSigner implements Nip07Interface {
nip04: {
encrypt: (pubkey: string, plaintext: string) => Promise | string;
decrypt: (pubkey: string, ciphertext: string) => Promise | string;
};
nip44: {
encrypt: (pubkey: string, plaintext: string) => Promise | string;
decrypt: (pubkey: string, ciphertext: string) => Promise | string;
};
constructor(public api: string) {
// extra boilerplate to make sure encryption methods are nested under .nip04 and .nip44
this.nip04 = {
encrypt: this.nip04Encrypt.bind(this),
decrypt: this.nip04Decrypt.bind(this),
};
this.nip44 = {
encrypt: this.nip44Encrypt.bind(this),
decrypt: this.nip44Decrypt.bind(this),
};
}
async getPublicKey(): Promise {
const res = await fetch(this.api + "/get-public-key");
const json = await res.json();
return json.pubkey;
}
async signEvent(template: EventTemplate): Promise {
const res = await fetch(this.api + "/sign", { body: template, method: "POST" });
const json = await res.json();
return json.event;
}
nip04Encrypt(): string {
throw new Error("Not implemented yet");
}
nip04Decrypt(): string {
throw new Error("Not implemented yet");
}
nip44Encrypt(): string {
throw new Error("Not implemented yet");
}
nip44Decrypt(): string {
throw new Error("Not implemented yet");
}
}
### Create a new account class [](https://hzrd149.github.io/applesauce/accounts/accounts.html#create-a-new-account-class)
Next create a new account class that extends `BaseAccount` to wrap the signer
ts
import { SerializedAccount, BaseAccount } from "applesauce-accounts";
type ApiAccountSignerData = {
api: string;
};
// Its good practice to make the class have a generic type for metadata
export default class ApiAccount extends BaseAccount<
ApiSigner,
ApiAccountSignerData,
Metadata
> {
// NOTE: you must set the static type, otherwise it cant be used in the AccountManager
static type = "api-account";
// add a toJSON method that saves all relevant information for the account
toJSON() {
return {
// save basic account information
type: ApiAccount.type,
id: this.id,
pubkey: this.pubkey,
metadata: this.metadata,
// save important signer data
signer: {
api: this.signer.api,
},
};
}
// add a static fromJSON method so it can be re-created when the app loads again
static fromJSON(
json: SerializedAccount,
): ApiAccount {
// create signer with saved data
const signer = new ApiSigner(json.signer.api);
// create new account class
const account = new ApiAccount(json.pubkey, signer);
// don't forget to call loadCommonFields, it sets the id and metadata
return super.loadCommonFields(account);
}
}
### Add account type to account manager [](https://hzrd149.github.io/applesauce/accounts/accounts.html#add-account-type-to-account-manager)
Next you need to register the account type
Now you can create a new `ApiSigner` and add it to the account manager
ts
const signer = new ApiSigner("https://api.example.com");
const pubkey = await signer.getPublicKey();
const account = new ApiAccount(pubkey, signer);
accountManager.addAccount(account);
accountManager.setActive(account);
---
# Text Content | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/content/text.html#VPContent)
Return to top
Text Content [](https://hzrd149.github.io/applesauce/content/text.html#text-content)
======================================================================================
Parsing content [](https://hzrd149.github.io/applesauce/content/text.html#parsing-content)
--------------------------------------------------------------------------------------------
The [`getParsedContent`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.getParsedContent.html)
method can be used to parse and transform an event into the content syntax tree
Cashing [](https://hzrd149.github.io/applesauce/content/text.html#cashing)
----------------------------------------------------------------------------
Because parsing and transforming content is an expensive operation `getParsedContent` method will cache the results on the event under a [Symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol)
, by default this is the [`TextNoteContentSymbol`](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-content.Text.TextNoteContentSymbol.html)
If your parsing or transforming different event kinds than kind 1, its recommended to create a new `Symbol` to and pass to `getParsedContent` to avoid cache collisions with the default kind 1 processor
Links [](https://hzrd149.github.io/applesauce/content/text.html#links)
------------------------------------------------------------------------
The [`links`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.links.html)
transformer can be used to parse URLs and add [`Link`](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html)
nodes to the tree
Mentions [](https://hzrd149.github.io/applesauce/content/text.html#mentions)
------------------------------------------------------------------------------
The [`nostrMentions`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.nostrMentions.html)
transformer can be used to add [`Mention`](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html)
nodes to the tree
Hashtags [](https://hzrd149.github.io/applesauce/content/text.html#hashtags)
------------------------------------------------------------------------------
The [`hashtags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.hashtags.html)
transformer can be used to add [`Hashtag`](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html)
nodes to the tree
Emojis [](https://hzrd149.github.io/applesauce/content/text.html#emojis)
--------------------------------------------------------------------------
The [`emojis`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.emojis.html)
transformer will add [`Emoji`](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html)
tags for any [NIP-30](https://github.com/nostr-protocol/nips/blob/master/30.md)
emojis
Galleries [](https://hzrd149.github.io/applesauce/content/text.html#galleries)
--------------------------------------------------------------------------------
The [`galleries`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.galleries.html)
transformer will group image URLs into a [`Gallery`](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html)
node
Lightning invoices [](https://hzrd149.github.io/applesauce/content/text.html#lightning-invoices)
--------------------------------------------------------------------------------------------------
The [`lightningInvoices`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.lightningInvoices.html)
transformer can be used to parse bolt11 lightning invoices in the content
Cashu tokens and payment requests [](https://hzrd149.github.io/applesauce/content/text.html#cashu-tokens-and-payment-requests)
--------------------------------------------------------------------------------------------------------------------------------
The [`cashuTokens`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.cashuTokens.html)
transformer can be used to parse cashu tokens in the content
---
# Helpers | applesauce
[Skip to content](https://hzrd149.github.io/applesauce/core/helpers.html#VPContent)
Return to top
Helpers [](https://hzrd149.github.io/applesauce/core/helpers.html#helpers)
============================================================================
`applesauce-core` and other packages export helper methods for working with events.
WARNING
Some helper methods may throw errors. make sure your app can handle errors correctly.
Core helpers [](https://hzrd149.github.io/applesauce/core/helpers.html#core-helpers)
--------------------------------------------------------------------------------------
The [`applesauce-core`](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
package contains the majority of the helper methods
### Events [](https://hzrd149.github.io/applesauce/core/helpers.html#events)
* [`isEvent`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isEvent.html)
Checks if an object is a nostr event
* [`markFromCache`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.markFromCache.html)
Marks an event as being from the cache
* [`isFromCache`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isFromCache.html)
Checks if an event is marked from cache
* [`getTagValue`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getTagValue.html)
Gets the value of the first tag matching the name
* [`getIndexableTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getIndexableTags.html)
Get a `Set` of all indexable tags on the event
### Profiles [](https://hzrd149.github.io/applesauce/core/helpers.html#profiles)
* [`getProfileContent`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getProfileContent.html)
Returns the parsed profile content for a kind 0 event
* [`isValidProfile`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isValidProfile.html)
Checks if the content of the kind 0 event is valid JSON
### Mailboxes [](https://hzrd149.github.io/applesauce/core/helpers.html#mailboxes)
* [`getInboxes`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getInboxes.html)
Gets the inbox relays from a `10002` event
* [`getOutboxes`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getOutboxes.html)
Gets the outbox relays from a `10002` event
### Comments [](https://hzrd149.github.io/applesauce/core/helpers.html#comments)
* [`getCommentRootPointer`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentRootPointer.html)
Get the root pointer for a NIP-22 comment
* [`getCommentReplyPointer`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentReplyPointer.html)
Get the reply pointer for a NIP-22 comment
### Event relays [](https://hzrd149.github.io/applesauce/core/helpers.html#event-relays)
* [`addSeenRelay`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.addSeenRelay.html)
Adds a relay to the list of relay the event was seen on
* [`getSeenRelays`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getSeenRelays.html)
Get the list of relays this event was seen on
### Zaps [](https://hzrd149.github.io/applesauce/core/helpers.html#zaps)
* [`isValidZap`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isValidZap.html)
Checks if an event is a valid zap and can be parsed
* [`getZapSender`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapSender.html)
Gets the senders pubkey
* [`getZapRecipient`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRecipient.html)
Gets the pubkey of the user who received the zap
* [`getZapPayment`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapPayment.html)
Gets the parsed bolt11 invoice
* [`getZapAddressPointer`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapAddressPointer.html)
Gets the address pointer of the zap
* [`getZapEventPointer`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapEventPointer.html)
Gets the event pointer of the zap
* [`getZapRequest`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRequest.html)
Gets the zap request event inside the zap event
### Lightning [](https://hzrd149.github.io/applesauce/core/helpers.html#lightning)
* [`parseBolt11`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.parseBolt11.html)
Parses a bolt11 lightning invoice
* [`parseLNURLOrAddress`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.parseLNURLOrAddress.html)
Parses a LNURL or lightning address into a LNURLp
### Pointers [](https://hzrd149.github.io/applesauce/core/helpers.html#pointers)
* [`getEventPointerFromETag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromETag.html)
Creates an `EventPointer` from a standard "e" tag
* [`getEventPointerFromQTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromQTag.html)
Creates an `EventPointer` from a standard "q" tag
* [`getAddressPointerFromATag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerFromATag.html)
Creates an `AddressPointer` from a standard "a" tag
* [`getProfilePointerFromPTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getProfilePointerFromPTag.html)
Creates an `ProfilePointer` from a standard "p" tag
* [`getAddressPointerForEvent`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerForEvent.html)
Returns an `AddressPointer` for a replaceable event
### Delete events [](https://hzrd149.github.io/applesauce/core/helpers.html#delete-events)
* [`getDeleteIds`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getDeleteIds.html)
Gets a list of referenced event ids
* [`getDeleteCoordinates`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getDeleteCoordinates.html)
Get the list of replaceable event coordinates the event is referencing
### Emojis [](https://hzrd149.github.io/applesauce/core/helpers.html#emojis)
* [`getPackName`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getPackName.html)
Gets the emoji pack name
* [`getEmojis`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEmojis.html)
Get all emojis in an emoji pack
* [`getEmojiTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEmojiTag.html)
CGets an "emoji" tag that matches an emoji code
### URLs [](https://hzrd149.github.io/applesauce/core/helpers.html#urls)
* [`getURLFilename`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getURLFilename.html)
returns the filename part fo the path in a URL
* [`isAudioURL`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isAudioURL.html)
Checks if the URL ends with a audio file extension
* [`isVideoURL`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isVideoURL.html)
Checks if the URL ends with a video file extension
* [`isImageURL`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isImageURL.html)
Checks if the URL ends with a image file extension
* [`isStreamURL`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isStreamURL.html)
Checks if the URL ends with a stream file extension
### Tags [](https://hzrd149.github.io/applesauce/core/helpers.html#tags)
* [`isETag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isETag.html)
Checks if tag is an "e" tag and has at least one value
* [`isATag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isATag.html)
Checks if tag is an "a" tag and has at least one value
* [`isPTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isPTag.html)
Checks if tag is an "p" tag and has at least one value
* [`isDTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isDTag.html)
Checks if tag is an "d" tag and has at least one value
* [`isRTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isRTag.html)
Checks if tag is an "r" tag and has at least one value
* [`isTTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isTTag.html)
Checks if tag is an "t" tag and has at least one value
### Hidden Tags [](https://hzrd149.github.io/applesauce/core/helpers.html#hidden-tags)
Hidden tags are used in [NIP-51](https://github.com/nostr-protocol/nips/blob/master/51.md)
lists and [NIP-60](https://github.com/nostr-protocol/nips/blob/master/60.md)
wallets
* [`canHaveHiddenTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.canHaveHiddenTags.html)
Checks if a given event kind can have hidden tags
* [`hasHiddenTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.hasHiddenTags.html)
Checks if an event has hidden tags
* [`getHiddenTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getHiddenTags.html)
Returns the hidden tags for an event if they are unlocked
* [`isHiddenTagsLocked`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isHiddenTagsLocked.html)
Checks if the hidden tags are locked
* [`unlockHiddenTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.unlockHiddenTags.html)
Unlocks the hidden tags using a `signer`
* [`modifyEventTags`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.modifyEventTags.html)
Modifies an events public or hidden tags
### Filters [](https://hzrd149.github.io/applesauce/core/helpers.html#filters)
* [`isFilterEqual`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isFilterEqual.html)
Check if two filters are equal
### Time [](https://hzrd149.github.io/applesauce/core/helpers.html#time)
* [`unixNow`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.unixNow.html)
Returns the current unix timestamp
Factory Helpers [](https://hzrd149.github.io/applesauce/core/helpers.html#factory-helpers)
--------------------------------------------------------------------------------------------
The [`applesauce-factory`](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Helpers.html)
package exports some helpers for building events and tags
Some of the most useful ones are
* [`fillAndTrimTag`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.fillAndTrimTag.html)
Replaces `undefined` or `null` in tags with `""` and trims to tag down to a set length if it ends with `""`
* [`createQTagFromEventPointer`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.createQTagFromEventPointer.html)
Creates a `"q"` tag for from an `EventPointer` to tag quoted events
* [`createPTagFromProfilePointer`](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.createPTagFromProfilePointer.html)
Creates a `"p"` tag for from a `ProfilePointer` to tag mentioned pubkeys
---
# applesauce-accounts | AppleSauce
* [applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
Module applesauce-accounts
==========================
applesauce-accounts[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#applesauce-accounts)
=========================================================================================================================
A simple nostr account management system built on top of [applesauce-signers](https://hzrd149.github.io/applesauce/signers/installation.html)
See [documentation](https://hzrd149.github.io/applesauce/signers/signers.html)
Namespaces
----------
[Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#accounts)
Classes
-------
[AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#accountmanager)
[BaseAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#baseaccount)
[ProxySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.ProxySigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#proxysigner)
[SignerMismatchError](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.SignerMismatchError.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#signermismatcherror)
Interfaces
----------
[DecryptionCache](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.DecryptionCache.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#decryptioncache)
[IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#iaccount)
[IAccountConstructor](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccountConstructor.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#iaccountconstructor)
Type Aliases
------------
[EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#eventtemplate)
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#serializedaccount)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#applesauce-accounts)
Namespaces
[Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#accounts)
Classes
[AccountManager](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#accountmanager)
[BaseAccount](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#baseaccount)
[ProxySigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#proxysigner)
[SignerMismatchError](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#signermismatcherror)
Interfaces
[DecryptionCache](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#decryptioncache)
[IAccount](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#iaccount)
[IAccountConstructor](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#iaccountconstructor)
Type Aliases
[EventTemplate](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#eventtemplate)
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html#serializedaccount)
---
# applesauce-actions | AppleSauce
* [applesauce-actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html)
Module applesauce-actions
=========================
Applesauce Actions[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#applesauce-actions)
======================================================================================================================
A collection of pre-built actions nostr clients can use. Built on top of `applesauce-core` and `applesauce-factory`.
[Documentation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html)
Installation[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#installation)
----------------------------------------------------------------------------------------------------------
npm install applesauce-actions
Overview[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#overview)
--------------------------------------------------------------------------------------------------
Actions are common pre-built async operations that apps can perform. They use:
* `EventStore` for access to known nostr events
* `EventFactory` to build and sign new nostr events
* A `publish` method to publish or save the resulting events
The package provides an `ActionHub` class that combines these components into a single manager for easier action execution.
Basic Usage[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#basic-usage)
--------------------------------------------------------------------------------------------------------
import { ActionHub } from "applesauce-actions";import { FollowUser } from "applesauce-actions/actions";async function publishEvent(event: NostrEvent) { await relayPool.publish(event, ["wss://relay.example.com"]);}// Create an action hub with your event store, factory and publish methodconst hub = new ActionHub(eventStore, eventFactory, publishEvent);// Example: Follow a userawait hub .exec(FollowUser, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d") .forEach((event) => publishEvent(event));
For more detailed documentation and examples, visit the [full documentation](https://hzrd149.github.io/applesauce/overview/actions.html)
.
Namespaces
----------
[Actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.Actions.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actions)
Classes
-------
[ActionHub](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-actions.ActionHub.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actionhub)
Type Aliases
------------
[Action](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-actions.Action.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#action)
[ActionConstructor](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-actions.ActionConstructor.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actionconstructor)
[ActionContext](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-actions.ActionContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actioncontext)
[PublishMethod](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-actions.PublishMethod.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#publishmethod)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[Applesauce Actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#applesauce-actions)
* [Installation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#installation)
* [Overview](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#overview)
* [Basic Usage](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#basic-usage)
Namespaces
[Actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actions)
Classes
[ActionHub](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actionhub)
Type Aliases
[Action](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#action)
[ActionConstructor](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actionconstructor)
[ActionContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#actioncontext)
[PublishMethod](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-actions.html#publishmethod)
---
# applesauce-content | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
Module applesauce-content
=========================
applesauce-content[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#applesauce-content)
======================================================================================================================
applesauce package for parsing text note content
Example[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#example)
------------------------------------------------------------------------------------------------
import { getParsedContent } from "applesauce-content/text";const stringContent = `hello nostr!nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6`;const ats = getParsedContent(stringContent);console.log(ats);/*{ type: 'root', event: undefined, children: [ { type: 'text', value: 'hello nostr!' }, { type: 'text', value: '\n' }, { type: 'mention', decoded: [Object], encoded: 'npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6' } ]}*/
Namespaces
----------
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Helpers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#helpers)
[Markdown](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Markdown.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#markdown)
[Nast](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Nast.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#nast)
[Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#text)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#applesauce-content)
* [Example](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#example)
Namespaces
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#helpers)
[Markdown](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#markdown)
[Nast](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#nast)
[Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html#text)
---
# applesauce-dvm | AppleSauce
* [applesauce-dvm](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html)
Module applesauce-dvm
=====================
Applesauce DVM[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#applesauce-dvm)
==========================================================================================================
Helpers and blueprints for [NIP-90](https://github.com/nostr-protocol/nips/blob/master/90.md)
data vending machines.
Installation[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#installation)
------------------------------------------------------------------------------------------------------
npm install applesauce-dvm
Usage[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#usage)
----------------------------------------------------------------------------------------
import { DVMClient } from "applesauce-dvm";import { RelayPool, onlyEvents } from "applesauce-relay";import { EventFactory } from "applesauce-factory";import { SimpleSigner } from "applesauce-signers/signers";// Create a relay pool for connectionsconst pool = new RelayPool();// Create an event factory for signing and creating eventsconst signer = new SimpleSigner();const factory = new EventFactory({ signer });// Create a DVM clientconst client = new DVMClient( factory, ["wss://relay.example.com/"], // A publish method that publishes to the relays async (relays, event) => { await lastValueFrom(pool.event(relays, event)); }, // A subscribe method that subscribes to the relays (relays, filters) => { return pool.req(relays, filters).pipe(onlyEvents()); },);// Make a kind 5002 translation requestclient.translate("Hello, world!").subscribe((event) => { console.log(event);});
Namespaces
----------
[Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.Blueprints.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#blueprints)
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.Helpers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#helpers)
Classes
-------
[DVMClient](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-dvm.DVMClient.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#dvmclient)
Type Aliases
------------
[PublishMethod](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-dvm.PublishMethod.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#publishmethod)
[SubscriptionMethod](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-dvm.SubscriptionMethod.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#subscriptionmethod)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[Applesauce DVM](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#applesauce-dvm)
* [Installation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#installation)
* [Usage](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#usage)
Namespaces
[Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#blueprints)
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#helpers)
Classes
[DVMClient](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#dvmclient)
Type Aliases
[PublishMethod](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#publishmethod)
[SubscriptionMethod](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-dvm.html#subscriptionmethod)
---
# applesauce-solidjs | AppleSauce
* [applesauce-solidjs](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html)
Module applesauce-solidjs
=========================
applesauce-solidjs[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#applesauce-solidjs)
======================================================================================================================
[SolidJS](https://www.solidjs.com/)
hooks and providers for applesauce
Installation[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#installation)
----------------------------------------------------------------------------------------------------------
npm install applesauce-solidjs
Example[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#example)
------------------------------------------------------------------------------------------------
import { from } from "solid-js";import { EventStore, Models } from "applesauce-core";const eventStore = new EventStore();function UserName({ pubkey }: { pubkey: string }) { const profile = from(eventStore.model(Models.ProfileModel, [pubkey])); return {profile() ? profile().name : "loading..."};}function App() { return (
App
);}
Namespaces
----------
[Context](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.Context.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#context)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-solidjs](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#applesauce-solidjs)
* [Installation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#installation)
* [Example](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#example)
Namespaces
[Context](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-solidjs.html#context)
---
# applesauce-core | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
Module applesauce-core
======================
applesauce-core[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#applesauce-core)
=============================================================================================================
AppleSauce is a collection of utilities for building reactive nostr applications. The core package provides an in-memory event database and reactive models to help you build nostr UIs with less code.
Key Components[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#key-components)
-----------------------------------------------------------------------------------------------------------
* **Helpers**: Core utility methods for parsing and extracting data from nostr events
* **EventStore**: In-memory database for storing and subscribing to nostr events
* **Models**: Complex subscriptions for common nostr data patterns
Documentation[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#documentation)
---------------------------------------------------------------------------------------------------------
For detailed documentation and guides, visit:
* [Getting Started](https://hzrd149.github.io/applesauce/introduction/getting-started)
* [API Reference](https://hzrd149.github.io/applesauce/typedoc/)
Example[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#example)
---------------------------------------------------------------------------------------------
import { EventStore } from "applesauce-core";import { ProfileModel, TimelineModel } from "applesauce-core/models";import { Relay } from "nostr-tools/relay";// Create a single EventStore instance for your appconst eventStore = new EventStore();// Use any nostr library for relay connections (nostr-tools, ndk, nostrify, etc...)const relay = await Relay.connect("wss://relay.example.com");// Subscribe to events and add them to the storeconst sub = relay.subscribe([{ authors: ["3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"] }], { onevent(event) { eventStore.add(event); },});// Subscribe to profile changes using ProfileModelconst profile = eventStore.model(ProfileModel, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d");profile.subscribe((parsed) => { if (parsed) console.log(parsed);});// Subscribe to a timeline of eventsconst timeline = eventStore.model(TimelineModel, { kinds: [1] });timeline.subscribe((events) => { console.log(events);});
Namespaces
----------
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#helpers)
[Models](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Models.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#models)
Classes
-------
[EventSet](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.EventSet.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#eventset)
[EventStore](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.EventStore.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#eventstore)
[TimeoutError](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-core.TimeoutError.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#timeouterror)
Interfaces
----------
[IEventClaims](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventClaims.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventclaims)
[IEventSet](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventSet.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventset)
[IEventStore](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStore.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstore)
[IEventStoreActions](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStoreActions.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoreactions)
[IEventStoreModels](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStoreModels.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoremodels)
[IEventStoreRead](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStoreRead.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoreread)
[IEventStoreStreams](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStoreStreams.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstorestreams)
[IEventStoreSubscriptions](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStoreSubscriptions.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoresubscriptions)
Type Aliases
------------
[Model](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Model.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#model)
[ModelConstructor](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.ModelConstructor.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#modelconstructor)
Functions
---------
[defined](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.defined.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#defined)
[firstValueFrom](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.firstValueFrom.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#firstvaluefrom)
[getObservableValue](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.getObservableValue.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#getobservablevalue)
[lastValueFrom](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.lastValueFrom.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#lastvaluefrom)
[mapEventsToStore](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.mapEventsToStore.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#mapeventstostore)
[mapEventsToTimeline](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.mapEventsToTimeline.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#mapeventstotimeline)
[simpleTimeout](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.simpleTimeout.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#simpletimeout)
[watchEventsUpdates](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.watchEventsUpdates.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#watcheventsupdates)
[watchEventUpdates](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.watchEventUpdates.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#watcheventupdates)
[withImmediateValueOrDefault](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.withImmediateValueOrDefault.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#withimmediatevalueordefault)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#applesauce-core)
* [Key Components](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#key-components)
* [Documentation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#documentation)
* [Example](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#example)
Namespaces
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#helpers)
[Models](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#models)
Classes
[EventSet](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#eventset)
[EventStore](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#eventstore)
[TimeoutError](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#timeouterror)
Interfaces
[IEventClaims](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventclaims)
[IEventSet](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventset)
[IEventStore](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstore)
[IEventStoreActions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoreactions)
[IEventStoreModels](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoremodels)
[IEventStoreRead](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoreread)
[IEventStoreStreams](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstorestreams)
[IEventStoreSubscriptions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#ieventstoresubscriptions)
Type Aliases
[Model](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#model)
[ModelConstructor](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#modelconstructor)
Functions
[defined](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#defined)
[firstValueFrom](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#firstvaluefrom)
[getObservableValue](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#getobservablevalue)
[lastValueFrom](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#lastvaluefrom)
[mapEventsToStore](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#mapeventstostore)
[mapEventsToTimeline](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#mapeventstotimeline)
[simpleTimeout](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#simpletimeout)
[watchEventsUpdates](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#watcheventsupdates)
[watchEventUpdates](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#watcheventupdates)
[withImmediateValueOrDefault](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html#withimmediatevalueordefault)
---
# applesauce-loaders | AppleSauce
* [applesauce-loaders](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html)
Module applesauce-loaders
=========================
applesauce-loaders[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#applesauce-loaders)
======================================================================================================================
A collection of functional loading methods to make common event loading patterns easier.
[Documentation](https://hzrd149.github.io/applesauce/loaders/package.html)
[typedoc](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html)
Address Loader[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#address-loader)
--------------------------------------------------------------------------------------------------------------
The Address Loader is a specialized loader for fetching Nostr replaceable events by their address (kind, pubkey, and optional identifier). It provides an efficient way to batch and deduplicate requests, cache results, and handle relay hints.
import { createAddressLoader } from "applesauce-loaders/loaders";import { EventStore } from "applesauce-core";import { RelayPool } from "applesauce-relay";const eventStore = new EventStore();const pool = new RelayPool();// Create an address loader (do this once at the app level)const addressLoader = createAddressLoader(pool, { // Pass all events to the event store to deduplicate them eventStore, // Optional configuration options bufferTime: 1000, followRelayHints: true, extraRelays: ["wss://relay.example.com"],});// Load a profile (kind 0)addressLoader({ kind: 0, pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", relays: ["wss://relay.example.com"],}).subscribe((event) => { // Handle the loaded event console.log(event);});// Load a contact list (kind 3)addressLoader({ kind: 3, pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", relays: ["wss://relay.example.com"],}).subscribe((event) => { // Handle the loaded event console.log(event);});// Load a parameterized replaceable eventaddressLoader({ kind: 30000, pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", identifier: "list of bad people", relays: ["wss://relay.example.com"],}).subscribe((event) => { // Handle the loaded event console.log(event);});
Event Loader[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#event-loader)
----------------------------------------------------------------------------------------------------------
The Event Loader is a specialized loader for fetching Nostr events by their IDs. It provides an efficient way to batch and deduplicate requests, cache results, and handle relay hints.
import { createEventLoader } from "applesauce-loaders/loaders";// Create an event loader (do this once at the app level)const eventLoader = createEventLoader(pool, { // Pass all events to the event store to deduplicate them eventStore, // Optional configuration options bufferTime: 1000, followRelayHints: true, extraRelays: ["wss://relay.example.com"],});// Load an event by IDeventLoader({ id: "2650f6292166624f45795248edb9ca136c276a3d10a0d8f4efd2b8b23eb2d5fc", relays: ["wss://relay.example.com"],}).subscribe((event) => { // Handle the loaded event console.log(event);});// Load from extra relayseventLoader({ id: "2650f6292166624f45795248edb9ca136c276a3d10a0d8f4efd2b8b23eb2d5fc", relays: ["wss://relay.example.com"],}).subscribe((event) => { // Handle the loaded event console.log(event);});
Timeline Loader[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#timeline-loader)
----------------------------------------------------------------------------------------------------------------
The Timeline Loader is designed for fetching paginated Nostr events in chronological order. It maintains state between calls, allowing you to efficiently load timeline events in blocks until you reach a specific timestamp or exhaust available events.
import { createTimelineLoader } from "applesauce-loaders/loaders";// Create a timeline loaderconst timelineLoader = createTimelineLoader( pool, ["wss://relay.example.com"], { kinds: [1] }, // Load text notes { eventStore },);// Initial load - gets the most recent eventstimelineLoader().subscribe((event) => { console.log("Loaded event:", event);});// Later, load older events by calling the loader again// Each call continues from where the previous one left offtimelineLoader().subscribe((event) => { console.log("Loaded older event:", event);});// Load events until a specific timestampconst oneWeekAgo = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60;timelineLoader(oneWeekAgo).subscribe((event) => { console.log("Event from last week:", event);});
Loading from cache[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#loading-from-cache)
----------------------------------------------------------------------------------------------------------------------
All loaders support a `cacheRequest` option to load events from a local cache.
import { NostrEvent, Filter } from "nostr-tools";import { createEventLoader } from "applesauce-loaders/loaders";// Custom method for loading events from a databaseasync function cacheRequest(filters: Filter[]): Promise { return await cacheDatabase.getEvents(filters);}const eventLoader = createEventLoader(pool, { // Pass all events to the event store to deduplicate them eventStore, // Pass a custom cache method cacheRequest, // Optional configuration options bufferTime: 1000,});// Because no relays are specified, the event will be loaded from the cacheeventLoader({ id: "2650f6292166624f45795248edb9ca136c276a3d10a0d8f4efd2b8b23eb2d5fc",}).subscribe((event) => { // Handle the loaded event console.log(event);});
Configuration Options[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#configuration-options)
----------------------------------------------------------------------------------------------------------------------------
All loaders accept these common configuration options:
### Address Loader Options[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#address-loader-options)
* `bufferTime`: Time interval to buffer requests in ms (default 1000)
* `bufferSize`: Max buffer size (default 200)
* `eventStore`: An event store used to deduplicate events
* `cacheRequest`: A method used to load events from a local cache
* `followRelayHints`: Whether to follow relay hints (default true)
* `lookupRelays`: Fallback lookup relays to check when event can't be found
* `extraRelays`: An array of relays to always fetch from
### Event Loader Options[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#event-loader-options)
* `bufferTime`: Time interval to buffer requests in ms (default 1000)
* `bufferSize`: Max buffer size (default 200)
* `eventStore`: An event store used to deduplicate events
* `cacheRequest`: A method used to load events from a local cache
* `followRelayHints`: Whether to follow relay hints (default true)
* `extraRelays`: An array of relays to always fetch from
### Timeline Loader Options[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#timeline-loader-options)
* `limit`: Maximum number of events to request per filter
* `cache`: A method used to load events from a local cache
* `eventStore`: An event store to pass all events to
Working with Relay Pools[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#working-with-relay-pools)
----------------------------------------------------------------------------------------------------------------------------------
All loaders require a request method for loading Nostr events from relays. You can provide this in multiple ways:
### Using a RelayPool instance[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#using-a-relaypool-instance)
The simplest approach is to pass a RelayPool instance directly:
import { createAddressLoader, createEventLoader } from "applesauce-loaders/loaders";import { RelayPool } from "applesauce-relay";const pool = new RelayPool();const addressLoader = createAddressLoader(pool, { eventStore });const eventLoader = createEventLoader(pool, { eventStore });
### Using a custom request method[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#using-a-custom-request-method)
You can also provide a custom request method, such as one from nostr-tools:
import { createEventLoader } from "applesauce-loaders/loaders";import { SimplePool } from "nostr-tools";import { Observable } from "rxjs";const pool = SimplePool();// Create a custom request function using nostr-toolsfunction customRequest(relays, filters) { return new Observable((observer) => { const sub = pool.subscribeMany(relays, filters, { onevent: (event) => observer.next(event), eose: () => observer.complete(), }); return () => sub.close(); });}// Create event loader with custom requestconst eventLoader = createEventLoader(customRequest, options);
Namespaces
----------
[Loaders](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.Loaders.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#loaders)
[Operators](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.Operators.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#operators)
Type Aliases
------------
[CacheRequest](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-loaders.CacheRequest.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#cacherequest)
[FilterRequest](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-loaders.FilterRequest.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#filterrequest)
[NostrRequest](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-loaders.NostrRequest.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#nostrrequest)
[TimelessFilter](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-loaders.TimelessFilter.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#timelessfilter)
[UpstreamPool](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-loaders.UpstreamPool.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#upstreampool)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-loaders](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#applesauce-loaders)
* [Address Loader](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#address-loader)
* [Event Loader](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#event-loader)
* [Timeline Loader](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#timeline-loader)
* [Loading from cache](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#loading-from-cache)
* [Configuration Options](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#configuration-options)
* * [Address Loader Options](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#address-loader-options)
* [Event Loader Options](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#event-loader-options)
* [Timeline Loader Options](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#timeline-loader-options)
* [Working with Relay Pools](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#working-with-relay-pools)
* * [Using a RelayPool instance](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#using-a-relaypool-instance)
* [Using a custom request method](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#using-a-custom-request-method)
Namespaces
[Loaders](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#loaders)
[Operators](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#operators)
Type Aliases
[CacheRequest](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#cacherequest)
[FilterRequest](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#filterrequest)
[NostrRequest](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#nostrrequest)
[TimelessFilter](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#timelessfilter)
[UpstreamPool](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-loaders.html#upstreampool)
---
# applesauce-factory | AppleSauce
* [applesauce-factory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html)
Module applesauce-factory
=========================
applesauce-factory[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#applesauce-factory)
======================================================================================================================
applesauce event factory is a package for easily creating or modifying nostr events
Documentation[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#documentation)
------------------------------------------------------------------------------------------------------------
For detailed documentation and guides, visit:
* [Documentation](https://hzrd149.github.io/applesauce/overview/factory.html)
* [API Reference](https://hzrd149.github.io/applesauce/typedoc/)
Creating a Factory[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#creating-a-factory)
----------------------------------------------------------------------------------------------------------------------
When creating a new event factory you can pass a [context](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-factory.EventFactoryContext.html)
object that is used by all blueprints:
const signer = new SimpleSigner();const factory = new EventFactory({ // optionally pass a signer in (required for encryption) signer: signer, // or pass NIP-07 window.nostr if it exists // optionally set a NIP-89 client client: { name: "My Awesome Client", address: { pubkey: "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", identifier: "awesome-client", }, },});
Creating a short text note[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#creating-a-short-text-note)
--------------------------------------------------------------------------------------------------------------------------------------
import { EventFactory } from "applesauce-factory";import { NoteBlueprint } from "applesauce-factory/blueprints";const factory = new EventFactory({ // config options, // see https://hzrd149.github.io/applesauce/typedoc/types/applesauce-factory.EventFactoryContext.html});const unsignedEvent = await factory.create( NoteBlueprint, "hello nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6 #introductions",);console.log(unsignedEvent);{ kind: 1, content: "hello nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6 #introductions", created_at: 0, tags: [['p', '3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d'], ['t', 'introductions']]}
Relay Hints[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#relay-hints)
--------------------------------------------------------------------------------------------------------
Relay hints can be added to all event tags that support them by passing in `getEventRelayHint` and `getPubkeyRelayHint` methods into the context:
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]); },});
Modifying Events[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#modifying-events)
------------------------------------------------------------------------------------------------------------------
The factory provides methods to modify existing events:
* `EventFactory.modify` - Takes a list of EventOperations to modify common properties
* `EventFactory.modifyTags` - Takes a list of TagOperations to modify the tags array
Example of modifying a list:
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"),);
Prebuilt Blueprints[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#prebuilt-blueprints)
------------------------------------------------------------------------------------------------------------------------
The `applesauce-factory` package comes with common event blueprints for social clients. you can find them in the [typescript docs](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Blueprints.html)
Namespaces
----------
[Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Blueprints.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#blueprints)
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Helpers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#helpers)
[Operations](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Operations.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#operations)
Classes
-------
[EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactory)
Interfaces
----------
[ClientPointerContext](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-factory.ClientPointerContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#clientpointercontext)
[EmojiContext](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-factory.EmojiContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#emojicontext)
[EventFactoryClient](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-factory.EventFactoryClient.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactoryclient)
[EventFactoryContext](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-factory.EventFactoryContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactorycontext)
[EventSigner](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-factory.EventSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventsigner)
[EventSignerContext](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-factory.EventSignerContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventsignercontext)
[RelayHintContext](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-factory.RelayHintContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#relayhintcontext)
Type Aliases
------------
[EventBlueprint](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-factory.EventBlueprint.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventblueprint)
[EventFactoryTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-factory.EventFactoryTemplate.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactorytemplate)
[EventOperation](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-factory.EventOperation.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventoperation)
[Operation](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-factory.Operation.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#operation)
[TagOperation](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-factory.TagOperation.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#tagoperation)
Functions
---------
[blueprint](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.blueprint.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#blueprint)
[build](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.build.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#build)
[create](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.create.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#create)
[modify](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.modify.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#modify)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-factory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#applesauce-factory)
* [Documentation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#documentation)
* [Creating a Factory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#creating-a-factory)
* [Creating a short text note](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#creating-a-short-text-note)
* [Relay Hints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#relay-hints)
* [Modifying Events](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#modifying-events)
* [Prebuilt Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#prebuilt-blueprints)
Namespaces
[Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#blueprints)
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#helpers)
[Operations](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#operations)
Classes
[EventFactory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactory)
Interfaces
[ClientPointerContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#clientpointercontext)
[EmojiContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#emojicontext)
[EventFactoryClient](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactoryclient)
[EventFactoryContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactorycontext)
[EventSigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventsigner)
[EventSignerContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventsignercontext)
[RelayHintContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#relayhintcontext)
Type Aliases
[EventBlueprint](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventblueprint)
[EventFactoryTemplate](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventfactorytemplate)
[EventOperation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#eventoperation)
[Operation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#operation)
[TagOperation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#tagoperation)
Functions
[blueprint](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#blueprint)
[build](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#build)
[create](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#create)
[modify](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html#modify)
---
# applesauce-react | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
Module applesauce-react
=======================
applesauce-react[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#applesauce-react)
================================================================================================================
React hooks and providers for applesauce
Installation[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#installation)
--------------------------------------------------------------------------------------------------------
npm install applesauce-react
Example[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#example)
----------------------------------------------------------------------------------------------
import { EventStore, Models } from "applesauce-core";import { EventStoreProvider } from "applesauce-react/providers";import { useEventModel } from "applesauce-react/hooks";const eventStore = new EventStore();function UserName({ pubkey }) { const profile = useEventModel(Models.ProfileModel, [pubkey]); return {profile.name || "loading..."};}function App() { return (
App
);}
Namespaces
----------
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Helpers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#helpers)
[Hooks](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Hooks.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#hooks)
Variables
---------
[AccountsContext](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-react.AccountsContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#accountscontext)
[ActionsContext](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-react.ActionsContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#actionscontext)
[EventStoreContext](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-react.EventStoreContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#eventstorecontext)
[FactoryContext](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-react.FactoryContext.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#factorycontext)
Functions
---------
[AccountsProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.AccountsProvider.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#accountsprovider)
[ActionsProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.ActionsProvider.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#actionsprovider)
[EventStoreProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.EventStoreProvider.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#eventstoreprovider)
[FactoryProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.FactoryProvider.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#factoryprovider)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#applesauce-react)
* [Installation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#installation)
* [Example](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#example)
Namespaces
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#helpers)
[Hooks](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#hooks)
Variables
[AccountsContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#accountscontext)
[ActionsContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#actionscontext)
[EventStoreContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#eventstorecontext)
[FactoryContext](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#factorycontext)
Functions
[AccountsProvider](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#accountsprovider)
[ActionsProvider](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#actionsprovider)
[EventStoreProvider](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#eventstoreprovider)
[FactoryProvider](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html#factoryprovider)
---
# SerialPortSigner | AppleSauce
* [applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
* [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
Class SerialPortSigner
======================
A signer that works with [nostr-signing-device](https://github.com/lnbits/nostr-signing-device)
#### Implements
* [ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#constructor)
### Properties
[lastCommand](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#lastcommand)
[log](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#log)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04)
[pubkey?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#pubkey)
[verifyEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#verifyevent)
[writer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#writer)
[METHOD\_LOG](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_log)
[METHOD\_PING](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_ping)
[METHOD\_PUBLIC\_KEY](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_public_key)
[METHOD\_RESTORE](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_restore)
[METHOD\_SHARED\_SECRET](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_shared_secret)
[METHOD\_SIGN\_MESSAGE](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_sign_message)
[PUBLIC\_METHODS](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#public_methods)
[SUPPORTED](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#supported)
### Accessors
[isConnected](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#isconnected)
### Methods
[callMethodOnDevice](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#callmethodondevice)
[connectToDevice](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#connecttodevice)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#getpublickey)
[nip04Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04decrypt)
[nip04Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04encrypt)
[parseResponse](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#parseresponse)
[ping](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#ping)
[readFromSerialPort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#readfromserialport)
[restore](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#restore)
[sendCommand](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#sendcommand)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#signevent)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#constructor)
* new SerialPortSigner(): [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#constructorserialportsigner)
#### Returns [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
Properties
----------
### `Protected`lastCommand[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#lastcommand)
lastCommand: null | Deferred = null
### `Protected`log[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#log)
log: Debugger = ...
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04)
nip04: {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### `Optional`pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#pubkey)
pubkey?: string
### verifyEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#verifyevent)
verifyEvent: (event: Event) \=> event is VerifiedEvent = verifyEvent
### `Protected`writer[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#writer)
writer: null | WritableStreamDefaultWriter = null
### `Static`METHOD\_LOG[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_log)
METHOD\_LOG: string = "/log"
### `Static`METHOD\_PING[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_ping)
METHOD\_PING: string = "/ping"
### `Static`METHOD\_PUBLIC\_KEY[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_public_key)
METHOD\_PUBLIC\_KEY: string = "/public-key"
### `Static`METHOD\_RESTORE[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_restore)
METHOD\_RESTORE: string = "/restore"
### `Static`METHOD\_SHARED\_SECRET[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_shared_secret)
METHOD\_SHARED\_SECRET: string = "/shared-secret"
### `Static`METHOD\_SIGN\_MESSAGE[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_sign_message)
METHOD\_SIGN\_MESSAGE: string = "/sign-message"
### `Static`PUBLIC\_METHODS[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#public_methods)
PUBLIC\_METHODS: string\[\] = ...
### `Static`SUPPORTED[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#supported)
SUPPORTED: boolean = ...
Accessors
---------
### isConnected[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#isconnected)
* get isConnected(): boolean
#### Returns boolean
Methods
-------
### callMethodOnDevice[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#callmethodondevice)
* callMethodOnDevice(
method: string,
params: string\[\],
opts?: DeviceOpts,
): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#callmethodondevice-1)
#### Parameters
* method: string
* params: string\[\]
* opts: DeviceOpts = {}
#### Returns Promise
### connectToDevice[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#connecttodevice)
* connectToDevice(\_\_namedParameters: DeviceOpts): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#connecttodevice-1)
#### Parameters
* \_\_namedParameters: DeviceOpts
#### Returns Promise
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#getpublickey-1)
Returns the public key on the device
#### Returns Promise
### nip04Decrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04decrypt)
* nip04Decrypt(pubkey: string, data: string): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04decrypt-1)
#### Parameters
* pubkey: string
* data: string
#### Returns Promise
### nip04Encrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04encrypt)
* nip04Encrypt(pubkey: string, text: string): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04encrypt-1)
#### Parameters
* pubkey: string
* text: string
#### Returns Promise
### `Protected`parseResponse[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#parseresponse)
* parseResponse(value: string): { data: string; method: string }[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#parseresponse-1)
#### Parameters
* value: string
#### Returns { data: string; method: string }
### ping[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#ping)
* ping(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#ping-1)
Pings to device to see if the connection is open
#### Returns void
### `Protected`readFromSerialPort[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#readfromserialport)
* readFromSerialPort(
reader: ReadableStreamDefaultReader,
): (separator?: string) \=> Promise<{ done: boolean; value: string }\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#readfromserialport-1)
#### Parameters
* reader: ReadableStreamDefaultReader
#### Returns (separator?: string) \=> Promise<{ done: boolean; value: string }\>
### restore[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#restore)
* restore(secretKey: Uint8Array): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#restore-1)
Sets the secret key used on the device
#### Parameters
* secretKey: Uint8Array
#### Returns Promise
### sendCommand[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#sendcommand)
* sendCommand(method: string, params?: string\[\]): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#sendcommand-1)
#### Parameters
* method: string
* params: string\[\] = \[\]
#### Returns Promise
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#signevent)
* signEvent(draft: EventTemplate & { pubkey?: string }): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#signevent-1)
Requires the device to sign an event
#### Parameters
* draft: EventTemplate & { pubkey?: string }
#### Returns Promise
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#constructor)
Properties
[lastCommand](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#lastcommand)
[log](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#log)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#pubkey)
[verifyEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#verifyevent)
[writer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#writer)
[METHOD\_LOG](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_log)
[METHOD\_PING](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_ping)
[METHOD\_PUBLIC\_KEY](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_public_key)
[METHOD\_RESTORE](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_restore)
[METHOD\_SHARED\_SECRET](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_shared_secret)
[METHOD\_SIGN\_MESSAGE](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#method_sign_message)
[PUBLIC\_METHODS](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#public_methods)
[SUPPORTED](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#supported)
Accessors
[isConnected](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#isconnected)
Methods
[callMethodOnDevice](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#callmethodondevice)
[connectToDevice](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#connecttodevice)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#getpublickey)
[nip04Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04decrypt)
[nip04Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#nip04encrypt)
[parseResponse](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#parseresponse)
[ping](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#ping)
[readFromSerialPort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#readfromserialport)
[restore](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#restore)
[sendCommand](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#sendcommand)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html#signevent)
---
# isFromCache | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isFromCache](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isFromCache.html)
Function isFromCache
====================
* isFromCache(event: Event): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isFromCache.html#isfromcache)
Returns if an event was from a cache
#### Parameters
* event: Event
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# AccountsProvider | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
* [AccountsProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.AccountsProvider.html)
Function AccountsProvider
=========================
* AccountsProvider(
\_\_namedParameters: PropsWithChildren<{ manager?: [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
}\>,
): Element[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.AccountsProvider.html#accountsprovider)
Provides an AccountManager to the component tree
#### Parameters
* \_\_namedParameters: PropsWithChildren<{ manager?: [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
}\>
#### Returns Element
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# ExtensionSigner | AppleSauce
* [applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
* [ExtensionSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html)
Class ExtensionSigner
=====================
A signer that is a proxy for window.nostr
#### Implements
* [ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#constructor)
### Properties
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#pubkey)
### Accessors
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#nip44)
### Methods
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#getpublickey)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#signevent)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#constructor)
* new ExtensionSigner(): [ExtensionSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#constructorextensionsigner)
#### Returns [ExtensionSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html)
Properties
----------
### `Protected`pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#pubkey)
pubkey: undefined | string = undefined
Accessors
---------
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#nip04)
* get nip04(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#nip44)
* get nip44(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
Methods
-------
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#getpublickey-1)
#### Returns Promise
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#signevent)
* signEvent(template: EventTemplate): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#signevent-1)
#### Parameters
* template: EventTemplate
#### Returns Promise
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#constructor)
Properties
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#pubkey)
Accessors
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#nip44)
Methods
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#getpublickey)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html#signevent)
---
# ensureSingletonTag | AppleSauce
* [applesauce-factory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Helpers.html)
* [ensureSingletonTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.ensureSingletonTag.html)
Function ensureSingletonTag
===========================
* ensureSingletonTag(
tags: string\[\]\[\],
tag: \[string, ...string\[\]\],
replace?: boolean,
): string\[\]\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.ensureSingletonTag.html#ensuresingletontag)
Ensures a single named tag exists
#### Parameters
* tags: string\[\]\[\]
* tag: \[string, ...string\[\]\]
* replace: boolean = true
#### Returns string\[\]\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# Model | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Model](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Model.html)
Type Alias Model
===================
Model: (events: [IEventStore](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStore.html)
) \=> Observable<[T](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Model.html#t)
\>
A computed view of an event set or event store
#### Type Parameters
* T extends unknown
#### Type declaration
* * (events: [IEventStore](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStore.html)
): Observable<[T](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Model.html#t)
\>
* #### Parameters
* events: [IEventStore](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStore.html)
#### Returns Observable<[T](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Model.html#t)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getTagValue | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getTagValue](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getTagValue.html)
Function getTagValue
====================
* getTagValue<[T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getTagValue.html#gettagvaluet)
extends { content: string; kind: number; tags: string\[\]\[\] }\>(
event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getTagValue.html#gettagvaluet)
,
name: string,
): undefined | string[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getTagValue.html#gettagvalue)
Returns the second index ( tag\[1\] ) of the first tag that matches the name If the event has any hidden tags they will be searched first
#### Type Parameters
* T extends { content: string; kind: number; tags: string\[\]\[\] }
#### Parameters
* event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getTagValue.html#gettagvaluet)
* name: string
#### Returns undefined | string
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getIndexableTags | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getIndexableTags](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getIndexableTags.html)
Function getIndexableTags
=========================
* getIndexableTags(event: Event): Set[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getIndexableTags.html#getindexabletags)
Returns a Set of tag names and values that are indexable
#### Parameters
* event: Event
#### Returns Set
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# AmberClipboardSigner | AppleSauce
* [applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
* [AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
Class AmberClipboardSigner
==========================
A Signer for [amber](https://github.com/greenart7c3/Amber)
clipboard API
#### See[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#see)
[https://github.com/greenart7c3/Amber/blob/master/docs/web-apps.md](https://github.com/greenart7c3/Amber/blob/master/docs/web-apps.md)
#### Implements
* [ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#constructor)
### Properties
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44)
[pubkey?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#pubkey)
[verifyEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#verifyevent)
[SUPPORTED](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#supported)
### Methods
[destroy](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#destroy)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#getpublickey)
[nip04Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04decrypt)
[nip04Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04encrypt)
[nip44Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44decrypt)
[nip44Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44encrypt)
[rejectPending](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#rejectpending)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#signevent)
[createGetPublicKeyIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#creategetpublickeyintent)
[createNip04DecryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04decryptintent)
[createNip04EncryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04encryptintent)
[createNip44DecryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44decryptintent)
[createNip44EncryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44encryptintent)
[createSignEventIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createsigneventintent)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#constructor)
* new AmberClipboardSigner(): [AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#constructoramberclipboardsigner)
#### Returns [AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
Properties
----------
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04)
nip04: {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44)
nip44: {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### `Optional`pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#pubkey)
pubkey?: string
### verifyEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#verifyevent)
verifyEvent: (event: Event) \=> event is VerifiedEvent = verifyEvent
### `Static`SUPPORTED[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#supported)
SUPPORTED: false | (() \=> Promise) = ...
If the signer is supported on this platform
#### Type declaration
* false
* () \=> Promise
* * (): Promise
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/Clipboard/readText)
#### Returns Promise
Methods
-------
### destroy[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#destroy)
* destroy(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#destroy-1)
Removes any event listeners created
#### Returns void
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#getpublickey-1)
#### Returns Promise
### nip04Decrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04decrypt)
* nip04Decrypt(pubkey: string, data: string): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04decrypt-1)
#### Parameters
* pubkey: string
* data: string
#### Returns Promise
### nip04Encrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04encrypt)
* nip04Encrypt(pubkey: string, plaintext: string): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04encrypt-1)
#### Parameters
* pubkey: string
* plaintext: string
#### Returns Promise
### nip44Decrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44decrypt)
* nip44Decrypt(pubkey: string, data: string): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44decrypt-1)
#### Parameters
* pubkey: string
* data: string
#### Returns Promise
### nip44Encrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44encrypt)
* nip44Encrypt(pubkey: string, plaintext: string): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44encrypt-1)
#### Parameters
* pubkey: string
* plaintext: string
#### Returns Promise
### rejectPending[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#rejectpending)
* rejectPending(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#rejectpending-1)
Reject the currently pending request
#### Returns void
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#signevent)
* signEvent(draft: EventTemplate & { pubkey?: string }): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#signevent-1)
#### Parameters
* draft: EventTemplate & { pubkey?: string }
#### Returns Promise
### `Static`createGetPublicKeyIntent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#creategetpublickeyintent)
* createGetPublicKeyIntent(): string[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#creategetpublickeyintent-1)
#### Returns string
### `Static`createNip04DecryptIntent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04decryptintent)
* createNip04DecryptIntent(pubkey: string, ciphertext: string): string[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04decryptintent-1)
#### Parameters
* pubkey: string
* ciphertext: string
#### Returns string
### `Static`createNip04EncryptIntent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04encryptintent)
* createNip04EncryptIntent(pubkey: string, plainText: string): string[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04encryptintent-1)
#### Parameters
* pubkey: string
* plainText: string
#### Returns string
### `Static`createNip44DecryptIntent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44decryptintent)
* createNip44DecryptIntent(pubkey: string, ciphertext: string): string[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44decryptintent-1)
#### Parameters
* pubkey: string
* ciphertext: string
#### Returns string
### `Static`createNip44EncryptIntent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44encryptintent)
* createNip44EncryptIntent(pubkey: string, plainText: string): string[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44encryptintent-1)
#### Parameters
* pubkey: string
* plainText: string
#### Returns string
### `Static`createSignEventIntent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createsigneventintent)
* createSignEventIntent(draft: EventTemplate): string[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createsigneventintent-1)
#### Parameters
* draft: EventTemplate
#### Returns string
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#constructor)
Properties
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#pubkey)
[verifyEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#verifyevent)
[SUPPORTED](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#supported)
Methods
[destroy](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#destroy)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#getpublickey)
[nip04Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04decrypt)
[nip04Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip04encrypt)
[nip44Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44decrypt)
[nip44Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#nip44encrypt)
[rejectPending](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#rejectpending)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#signevent)
[createGetPublicKeyIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#creategetpublickeyintent)
[createNip04DecryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04decryptintent)
[createNip04EncryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip04encryptintent)
[createNip44DecryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44decryptintent)
[createNip44EncryptIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createnip44encryptintent)
[createSignEventIntent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html#createsigneventintent)
---
# links | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [links](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.links.html)
Function links
==============
* links(): Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.links.html#links)
Finds and creates web links in the tree
#### Returns Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# nostrMentions | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [nostrMentions](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.nostrMentions.html)
Function nostrMentions
======================
* nostrMentions(): Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.nostrMentions.html#nostrmentions)
Finds and creates NIP-19 nostr mentions in the tree
#### Returns Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# useEventFactory | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
* [Hooks](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Hooks.html)
* [useEventFactory](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventFactory.html)
Function useEventFactory
========================
* useEventFactory(require: false): undefined | [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventFactory.html#useeventfactory)
#### Parameters
* require: false
#### Returns undefined | [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
* useEventFactory(require: true): [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventFactory.html#useeventfactory-1)
#### Parameters
* require: true
#### Returns [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
* useEventFactory(): [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventFactory.html#useeventfactory-2)
#### Returns [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# useActiveAccount | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
* [Hooks](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Hooks.html)
* [useActiveAccount](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useActiveAccount.html)
Function useActiveAccount
=========================
* useActiveAccount(): undefined | [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useActiveAccount.html#useactiveaccount)
#### Returns undefined | [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# useAccountManager | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
* [Hooks](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Hooks.html)
* [useAccountManager](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useAccountManager.html)
Function useAccountManager
==========================
* useAccountManager(): [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useAccountManager.html#useaccountmanager)
#### Returns [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
* useAccountManager(require: false): undefined | [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useAccountManager.html#useaccountmanager-1)
#### Parameters
* require: false
#### Returns undefined | [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
* useAccountManager(require: true): [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useAccountManager.html#useaccountmanager-2)
#### Parameters
* require: true
#### Returns [AccountManager](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.AccountManager.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isValidProfile | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isValidProfile](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isValidProfile.html)
Function isValidProfile
=======================
* isValidProfile(profile?: Event): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isValidProfile.html#isvalidprofile)
Checks if the content of the kind 0 event is valid JSON
#### Parameters
* `Optional`profile: Event
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# hashtags | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [hashtags](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.hashtags.html)
Function hashtags
=================
* hashtags(): Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.hashtags.html#hashtags)
Find and create hashtag notes in provided tree
#### Returns Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# emojis | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [emojis](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.emojis.html)
Function emojis
===============
* emojis(): Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.emojis.html#emojis)
Finds and creates emoji nodes in the tree
#### Returns Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# addSeenRelay | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [addSeenRelay](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.addSeenRelay.html)
Function addSeenRelay
=====================
* addSeenRelay(event: Event, relay: string): Set[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.addSeenRelay.html#addseenrelay)
Marks an event as being seen on a relay
#### Parameters
* event: Event
* relay: string
#### Returns Set
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# Link | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Nast](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Nast.html)
* [Link](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html)
Interface Link
==============
interface Link {
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#data)
?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
;
[href](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#href)
: string;
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#position)
?: Position;
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#type)
: "link";
[value](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#value)
: string;
}
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-content.Nast.Link)
)
* [Node](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Node.html)
* Link
##### Index
### Properties
[data?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#data)
[href](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#href)
[position?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#position)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#type)
[value](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#value)
Properties
----------
### `Optional`data[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#data)
data?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
### href[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#href)
href: string
### `Optional`position[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#position)
position?: Position
Position of a node in a source document.
Nodes that are generated (not in the original source document) must not have a position.
### type[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#type)
type: "link"
Node type.
### value[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#value)
value: string
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Properties
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#data)
[href](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#href)
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#position)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#type)
[value](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Link.html#value)
---
# Hashtag | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Nast](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Nast.html)
* [Hashtag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html)
Interface Hashtag
=================
interface Hashtag {
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#data)
?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
;
[hashtag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#hashtag)
: string;
[name](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#name)
: string;
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#position)
?: Position;
[tag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#tag)
?: \["t", ...string\[\]\];
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#type)
: "hashtag";
}
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-content.Nast.Hashtag)
)
* [Node](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Node.html)
* Hashtag
##### Index
### Properties
[data?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#data)
[hashtag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#hashtag)
[name](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#name)
[position?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#position)
[tag?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#tag)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#type)
Properties
----------
### `Optional`data[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#data)
data?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
### hashtag[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#hashtag)
hashtag: string
The lowercase canonical name
### name[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#name)
name: string
The name as it was written in the event
### `Optional`position[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#position)
position?: Position
Position of a node in a source document.
Nodes that are generated (not in the original source document) must not have a position.
### `Optional`tag[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#tag)
tag?: \["t", ...string\[\]\]
The indexable tag for the hashtag. will be undefined if none was found
### type[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#type)
type: "hashtag"
Node type.
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Properties
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#data)
[hashtag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#hashtag)
[name](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#name)
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#position)
[tag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#tag)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Hashtag.html#type)
---
# Nip07Interface | AppleSauce
* [applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
* [Nip07Interface](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.Nip07Interface.html)
Type Alias Nip07Interface
=========================
Nip07Interface: [ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
#### Deprecated[](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.Nip07Interface.html#deprecated)
Use ISigner instead
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# ReadonlySigner | AppleSauce
* [applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
* [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
Class ReadonlySigner
====================
A signer that only implements getPublicKey and throws on ever other method
#### Implements
* [ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#constructor)
### Properties
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44)
### Methods
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#getpublickey)
[nip04Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04decrypt)
[nip04Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04encrypt)
[nip44Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44decrypt)
[nip44Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44encrypt)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#signevent)
[fromPubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#frompubkey)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#constructor)
* new ReadonlySigner(pubkey: string): [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#constructorreadonlysigner)
#### Parameters
* pubkey: string
#### Returns [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
Properties
----------
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04)
nip04: {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44)
nip44: {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
Methods
-------
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#getpublickey-1)
#### Returns Promise
### nip04Decrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04decrypt)
* nip04Decrypt(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04decrypt-1)
#### Returns Promise
### nip04Encrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04encrypt)
* nip04Encrypt(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04encrypt-1)
#### Returns Promise
### nip44Decrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44decrypt)
* nip44Decrypt(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44decrypt-1)
#### Returns Promise
### nip44Encrypt[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44encrypt)
* nip44Encrypt(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44encrypt-1)
#### Returns Promise
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#signevent)
* signEvent(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#signevent-1)
#### Returns Promise
### `Static`fromPubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#frompubkey)
* fromPubkey(pubkey: string): [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#frompubkey-1)
Creates a ReadonlySigner from a hex public key or NIP-19 npub
#### Parameters
* pubkey: string
#### Returns [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#constructor)
Properties
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44)
Methods
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#getpublickey)
[nip04Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04decrypt)
[nip04Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip04encrypt)
[nip44Decrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44decrypt)
[nip44Encrypt](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#nip44encrypt)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#signevent)
[fromPubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html#frompubkey)
---
# getCommentReplyPointer | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getCommentReplyPointer](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentReplyPointer.html)
Function getCommentReplyPointer
===============================
* getCommentReplyPointer(comment: Event): null | [CommentPointer](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.CommentPointer.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentReplyPointer.html#getcommentreplypointer)
Returns the reply pointer for a comment
#### Parameters
* comment: Event
#### Returns null | [CommentPointer](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.CommentPointer.html)
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentReplyPointer.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# galleries | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [galleries](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.galleries.html)
Function galleries
==================
* galleries(types?: string\[\]): Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.galleries.html#galleries)
Group images into galleries in an ATS tree
#### Parameters
* types: string\[\] = IMAGE\_EXT
#### Returns Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getSeenRelays | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getSeenRelays](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getSeenRelays.html)
Function getSeenRelays
======================
* getSeenRelays(event: Event): undefined | Set[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getSeenRelays.html#getseenrelays)
Returns the set of relays this event was seen on
#### Parameters
* event: Event
#### Returns undefined | Set
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getProfileContent | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getProfileContent](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getProfileContent.html)
Function getProfileContent
==========================
* getProfileContent(event: Event): [ProfileContent](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.ProfileContent.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getProfileContent.html#getprofilecontent)
Returns the parsed profile content for a kind 0 event
#### Parameters
* event: Event
#### Returns [ProfileContent](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.ProfileContent.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# lightningInvoices | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [lightningInvoices](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.lightningInvoices.html)
Function lightningInvoices
==========================
* lightningInvoices(): Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.lightningInvoices.html#lightninginvoices)
Finds and creates lightning invoice nodes in the tree
#### Returns Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getZapRecipient | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getZapRecipient](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRecipient.html)
Function getZapRecipient
========================
* getZapRecipient(zap: Event): string[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRecipient.html#getzaprecipient)
Gets the receivers pubkey
#### Parameters
* zap: Event
#### Returns string
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRecipient.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isValidZap | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isValidZap](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isValidZap.html)
Function isValidZap
===================
* isValidZap(zap?: Event): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isValidZap.html#isvalidzap)
Checks if the zap is valid DOES NOT validate LNURL address
#### Parameters
* `Optional`zap: Event
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# Emoji | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Nast](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Nast.html)
* [Emoji](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html)
Interface Emoji
===============
interface Emoji {
[code](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#code)
: string;
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#data)
?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
;
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#position)
?: Position;
[raw](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#raw)
: string;
[tag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#tag)
: \["emoji", ...string\[\]\];
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#type)
: "emoji";
[url](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#url)
: string;
}
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-content.Nast.Emoji)
)
* [Node](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Node.html)
* Emoji
##### Index
### Properties
[code](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#code)
[data?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#data)
[position?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#position)
[raw](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#raw)
[tag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#tag)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#type)
[url](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#url)
Properties
----------
### code[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#code)
code: string
### `Optional`data[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#data)
data?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
### `Optional`position[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#position)
position?: Position
Position of a node in a source document.
Nodes that are generated (not in the original source document) must not have a position.
### raw[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#raw)
raw: string
### tag[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#tag)
tag: \["emoji", ...string\[\]\]
### type[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#type)
type: "emoji"
Node type.
### url[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#url)
url: string
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Properties
[code](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#code)
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#data)
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#position)
[raw](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#raw)
[tag](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#tag)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#type)
[url](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Emoji.html#url)
---
# getZapAddressPointer | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getZapAddressPointer](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapAddressPointer.html)
Function getZapAddressPointer
=============================
* getZapAddressPointer(zap: Event): null | AddressPointer[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapAddressPointer.html#getzapaddresspointer)
Gets the AddressPointer that was zapped
#### Parameters
* zap: Event
#### Returns null | AddressPointer
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getZapSender | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getZapSender](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapSender.html)
Function getZapSender
=====================
* getZapSender(zap: Event): string[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapSender.html#getzapsender)
Returns the senders pubkey
#### Parameters
* zap: Event
#### Returns string
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getZapEventPointer | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getZapEventPointer](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapEventPointer.html)
Function getZapEventPointer
===========================
* getZapEventPointer(zap: Event): null | EventPointer[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapEventPointer.html#getzapeventpointer)
Gets the EventPointer that was zapped
#### Parameters
* zap: Event
#### Returns null | EventPointer
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getZapRequest | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getZapRequest](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRequest.html)
Function getZapRequest
======================
* getZapRequest(zap: Event): Event[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRequest.html#getzaprequest)
Returns the zap request event inside the zap receipt
#### Parameters
* zap: Event
#### Returns Event
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapRequest.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# Gallery | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Nast](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Nast.html)
* [Gallery](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html)
Interface Gallery
=================
interface Gallery {
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#data)
?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
;
[links](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#links)
: string\[\];
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#position)
?: Position;
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#type)
: "gallery";
}
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-content.Nast.Gallery)
)
* [Node](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Node.html)
* Gallery
##### Index
### Properties
[data?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#data)
[links](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#links)
[position?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#position)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#type)
Properties
----------
### `Optional`data[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#data)
data?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
### links[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#links)
links: string\[\]
### `Optional`position[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#position)
position?: Position
Position of a node in a source document.
Nodes that are generated (not in the original source document) must not have a position.
### type[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#type)
type: "gallery"
Node type.
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Properties
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#data)
[links](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#links)
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#position)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Gallery.html#type)
---
# cashuTokens | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [cashuTokens](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.cashuTokens.html)
Function cashuTokens
====================
* cashuTokens(): Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-content.Text.cashuTokens.html#cashutokens)
Parse cashu tokens from an ATS tree
#### Returns Transformer<[Root](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Root.html)
\>
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getProfilePointerFromPTag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getProfilePointerFromPTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getProfilePointerFromPTag.html)
Function getProfilePointerFromPTag
==================================
* getProfilePointerFromPTag(tag: string\[\]): ProfilePointer[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getProfilePointerFromPTag.html#getprofilepointerfromptag)
Gets a ProfilePointer from a common "p" tag
#### Parameters
* tag: string\[\]
#### Returns ProfilePointer
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getProfilePointerFromPTag.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getAddressPointerFromATag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getAddressPointerFromATag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerFromATag.html)
Function getAddressPointerFromATag
==================================
* getAddressPointerFromATag(tag: string\[\]): AddressPointer[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerFromATag.html#getaddresspointerfromatag)
Get an AddressPointer from a common "a" tag
#### Parameters
* tag: string\[\]
#### Returns AddressPointer
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerFromATag.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getEventPointerFromETag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getEventPointerFromETag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromETag.html)
Function getEventPointerFromETag
================================
* getEventPointerFromETag(tag: string\[\]): EventPointer[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromETag.html#geteventpointerfrometag)
Gets an EventPointer form a common "e" tag
#### Parameters
* tag: string\[\]
#### Returns EventPointer
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromETag.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getEventPointerFromQTag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getEventPointerFromQTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromQTag.html)
Function getEventPointerFromQTag
================================
* getEventPointerFromQTag(tag: string\[\]): EventPointer[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromQTag.html#geteventpointerfromqtag)
Gets an EventPointer form a common "q" tag
#### Parameters
* tag: string\[\]
#### Returns EventPointer
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEventPointerFromQTag.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# parseLNURLOrAddress | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [parseLNURLOrAddress](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.parseLNURLOrAddress.html)
Function parseLNURLOrAddress
============================
* parseLNURLOrAddress(addressOrLNURL: string): undefined | URL[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.parseLNURLOrAddress.html#parselnurloraddress)
#### Parameters
* addressOrLNURL: string
#### Returns undefined | URL
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getDeleteIds | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getDeleteIds](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getDeleteIds.html)
Function getDeleteIds
=====================
* getDeleteIds(deleteEvent: Event): string\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getDeleteIds.html#getdeleteids)
#### Parameters
* deleteEvent: Event
#### Returns string\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getAddressPointerForEvent | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getAddressPointerForEvent](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerForEvent.html)
Function getAddressPointerForEvent
==================================
* getAddressPointerForEvent(event: Event, relays?: string\[\]): AddressPointer[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerForEvent.html#getaddresspointerforevent)
Returns an AddressPointer for a replaceable event
#### Parameters
* event: Event
* `Optional`relays: string\[\]
#### Returns AddressPointer
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getAddressPointerForEvent.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getDeleteCoordinates | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getDeleteCoordinates](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getDeleteCoordinates.html)
Function getDeleteCoordinates
=============================
* getDeleteCoordinates(deleteEvent: Event): string\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getDeleteCoordinates.html#getdeletecoordinates)
#### Parameters
* deleteEvent: Event
#### Returns string\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# Mention | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Nast](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Nast.html)
* [Mention](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html)
Interface Mention
=================
interface Mention {
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#data)
?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
;
[decoded](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#decoded)
:
| { data: EventPointer; type: "nevent" }
| { data: ProfilePointer; type: "nprofile" }
| { data: AddressPointer; type: "naddr" }
| { data: string; type: "npub" }
| { data: Uint8Array; type: "nsec" }
| { data: string; type: "note" };
[encoded](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#encoded)
: string;
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#position)
?: Position;
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#type)
: "mention";
}
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-content.Nast.Mention)
)
* [Node](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Node.html)
* Mention
##### Index
### Properties
[data?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#data)
[decoded](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#decoded)
[encoded](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#encoded)
[position?](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#position)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#type)
Properties
----------
### `Optional`data[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#data)
data?: [CommonData](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.CommonData.html)
### decoded[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#decoded)
decoded:
| { data: EventPointer; type: "nevent" }
| { data: ProfilePointer; type: "nprofile" }
| { data: AddressPointer; type: "naddr" }
| { data: string; type: "npub" }
| { data: Uint8Array; type: "nsec" }
| { data: string; type: "note" }
### encoded[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#encoded)
encoded: string
### `Optional`position[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#position)
position?: Position
Position of a node in a source document.
Nodes that are generated (not in the original source document) must not have a position.
### type[](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#type)
type: "mention"
Node type.
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Properties
[data](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#data)
[decoded](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#decoded)
[encoded](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#encoded)
[position](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#position)
[type](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-content.Nast.Mention.html#type)
---
# getPackName | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getPackName](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getPackName.html)
Function getPackName
====================
* getPackName(pack: Event): undefined | string[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getPackName.html#getpackname)
Returns the name of a NIP-30 emoji pack
#### Parameters
* pack: Event
#### Returns undefined | string
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# parseBolt11 | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [parseBolt11](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.parseBolt11.html)
Function parseBolt11
====================
* parseBolt11(paymentRequest: string): [ParsedInvoice](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.ParsedInvoice.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.parseBolt11.html#parsebolt11)
Parses a lightning invoice
#### Parameters
* paymentRequest: string
#### Returns [ParsedInvoice](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.ParsedInvoice.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getEmojiTag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getEmojiTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEmojiTag.html)
Function getEmojiTag
====================
* getEmojiTag(
tags: string\[\]\[\] | { tags: string\[\]\[\] },
code: string,
): undefined | \["emoji", string, string\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEmojiTag.html#getemojitag)
Gets an "emoji" tag that matches an emoji code
#### Parameters
* tags: string\[\]\[\] | { tags: string\[\]\[\] }
* code: string
#### Returns undefined | \["emoji", string, string\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getInboxes | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getInboxes](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getInboxes.html)
Function getInboxes
===================
* getInboxes(event: Event): string\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getInboxes.html#getinboxes)
Parses a 10002 event and stores the inboxes in the event using the [MailboxesInboxesSymbol](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-core.Helpers.MailboxesInboxesSymbol.html)
symbol
#### Parameters
* event: Event
#### Returns string\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# useRenderedContent | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
* [Hooks](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Hooks.html)
* [useRenderedContent](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useRenderedContent.html)
Function useRenderedContent
===========================
* useRenderedContent(
event: undefined | string | Event | EventTemplate,
components: [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Helpers.html)
.[ComponentMap](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-react.Helpers.ComponentMap.html)
,
opts?: Options,
): null | Element[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useRenderedContent.html#userenderedcontent)
Returns the parsed and render text content for an event
#### Parameters
* event: undefined | string | Event | EventTemplate
* components: [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Helpers.html)
.[ComponentMap](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-react.Helpers.ComponentMap.html)
* `Optional`opts: Options
#### Returns null | Element
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getURLFilename | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getURLFilename](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getURLFilename.html)
Function getURLFilename
=======================
* getURLFilename(url: URL): undefined | string[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getURLFilename.html#geturlfilename)
#### Parameters
* url: URL
#### Returns undefined | string
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isAudioURL | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isAudioURL](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isAudioURL.html)
Function isAudioURL
===================
* isAudioURL(url: string | URL): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isAudioURL.html#isaudiourl)
Checks if a url is a audio URL
#### Parameters
* url: string | URL
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isImageURL | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isImageURL](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isImageURL.html)
Function isImageURL
===================
* isImageURL(url: string | URL): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isImageURL.html#isimageurl)
Checks if a url is a image URL
#### Parameters
* url: string | URL
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isVideoURL | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isVideoURL](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isVideoURL.html)
Function isVideoURL
===================
* isVideoURL(url: string | URL): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isVideoURL.html#isvideourl)
Checks if a url is a video URL
#### Parameters
* url: string | URL
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# applesauce-wallet | AppleSauce
* [applesauce-wallet](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html)
Module applesauce-wallet
========================
Applesauce Wallet[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#applesauce-wallet)
===================================================================================================================
The `applesauce-wallet` package is a package of helpers, models, blueprints and other useful stuff for [NIP-60](https://github.com/nostr-protocol/nips/blob/master/60.md)
wallets and [NIP-61](https://github.com/nostr-protocol/nips/blob/master/61.md)
nutzaps
Namespaces
----------
[Actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.Actions.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#actions)
[Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.Blueprints.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#blueprints)
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.Helpers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#helpers)
[Models](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.Models.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#models)
[Operations](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.Operations.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#operations)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[Applesauce Wallet](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#applesauce-wallet)
Namespaces
[Actions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#actions)
[Blueprints](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#blueprints)
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#helpers)
[Models](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#models)
[Operations](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-wallet.html#operations)
---
# applesauce-signers | AppleSauce
* [applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
Module applesauce-signers
=========================
applesauce-signer[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#applesauce-signer)
====================================================================================================================
A collection of signer classes for applesauce that are compatible with the [NIP-07](https://github.com/nostr-protocol/nips/blob/master/07.md)
API.
Documentation[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#documentation)
------------------------------------------------------------------------------------------------------------
For detailed documentation and API reference, see:
* [Signers Documentation](https://hzrd149.github.io/applesauce/signers/signers.html)
* [Nostr Connect Documentation](https://hzrd149.github.io/applesauce/signers/nostr-connect.html)
* [API Reference](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
Available Signers[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#available-signers)
--------------------------------------------------------------------------------------------------------------------
### Password Signer (NIP-49)[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#password-signer-nip-49)
A secure signer that encrypts private keys using [NIP-49](https://github.com/nostr-protocol/nips/blob/master/49.md)
.
// Create a new password signerconst signer = new PasswordSigner();// Set up with a new key and passwordconst randomBytes = new Uint8Array(64);window.crypto.getRandomValues(randomBytes);signer.key = randomBytes;signer.setPassword("your-password");// Unlock the signer when neededawait signer.unlock("your-password");
### Simple Signer[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#simple-signer)
A basic signer that holds the secret key in memory with NIP-04 and NIP-44 encryption support.
// Create new signer with random keyconst signer = new SimpleSigner();// Or import existing keyconst key = new Uint8Array(32);window.crypto.getRandomValues(key);const signer = new SimpleSigner(key);
### Nostr Connect Signer (NIP-46)[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostr-connect-signer-nip-46)
A client-side implementation for remote signing using [NIP-46](https://github.com/nostr-protocol/nips/blob/master/46.md)
.
// First, set up the required relay communication methodsimport { Observable } from "rxjs";// Define subscription method for receiving eventsconst subscriptionMethod = (filters, relays) => { return new Observable((observer) => { // Create subscription to relays const cleanup = subscribeToRelays(relays, filters, (event) => { observer.next(event); }); return () => cleanup(); });};// Define publish method for sending eventsconst publishMethod = async (event, relays) => { for (const relay of relays) await publishToRelay(relay, event);};// You can set these methods globally at app initializationNostrConnectSigner.subscriptionMethod = subscriptionMethod;NostrConnectSigner.publishMethod = publishMethod;// Now create and use the signerconst signer = new NostrConnectSigner({ remote: "", relays: ["wss://relay.example.com"], // Or pass methods directly to the constructor subscriptionMethod, publishMethod,});// Create a connection URI for your appconst uri = signer.getNostrConnectURI({ name: "My App", url: "https://example.com", permissions: NostrConnectSigner.buildSigningPermissions([0, 1, 3]),});// Connect using bunker URIconst bunkerSigner = await NostrConnectSigner.fromBunkerURI("bunker://...your-uri-here...", { permissions: NostrConnectSigner.buildSigningPermissions([0, 1, 3]),});
### Other Signers[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#other-signers)
* **Serial Port Signer**: For hardware signing devices (Chrome browsers only)
* **Amber Clipboard Signer**: Integration with Amber wallet's web API
Namespaces
----------
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.Helpers.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#helpers)
Classes
-------
[AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#amberclipboardsigner)
[ExtensionMissingError](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionMissingError.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#extensionmissingerror)
[ExtensionSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ExtensionSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#extensionsigner)
[NostrConnectProvider](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectProvider.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectprovider)
[NostrConnectSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectsigner)
[PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#passwordsigner)
[ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#readonlysigner)
[SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#serialportsigner)
[SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#simplesigner)
Interfaces
----------
[ProviderAuthorization](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-signers.ProviderAuthorization.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#providerauthorization)
Type Aliases
------------
[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#isigner)
[Nip07Interface](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.Nip07Interface.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nip07interface)
[NostrConnectProviderOptions](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.NostrConnectProviderOptions.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectprovideroptions)
[NostrConnectSignerOptions](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.NostrConnectSignerOptions.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectsigneroptions)
[NostrPool](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.NostrPool.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrpool)
[NostrPublishMethod](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.NostrPublishMethod.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrpublishmethod)
[NostrSubscriptionMethod](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.NostrSubscriptionMethod.html)
[](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrsubscriptionmethod)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
[applesauce-signer](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#applesauce-signer)
* [Documentation](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#documentation)
* [Available Signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#available-signers)
* * [Password Signer (NIP-49)](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#password-signer-nip-49)
* [Simple Signer](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#simple-signer)
* [Nostr Connect Signer (NIP-46)](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostr-connect-signer-nip-46)
* [Other Signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#other-signers)
Namespaces
[Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#helpers)
Classes
[AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#amberclipboardsigner)
[ExtensionMissingError](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#extensionmissingerror)
[ExtensionSigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#extensionsigner)
[NostrConnectProvider](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectprovider)
[NostrConnectSigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectsigner)
[PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#passwordsigner)
[ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#readonlysigner)
[SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#serialportsigner)
[SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#simplesigner)
Interfaces
[ProviderAuthorization](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#providerauthorization)
Type Aliases
[ISigner](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#isigner)
[Nip07Interface](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nip07interface)
[NostrConnectProviderOptions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectprovideroptions)
[NostrConnectSignerOptions](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrconnectsigneroptions)
[NostrPool](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrpool)
[NostrPublishMethod](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrpublishmethod)
[NostrSubscriptionMethod](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html#nostrsubscriptionmethod)
---
# getOutboxes | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getOutboxes](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getOutboxes.html)
Function getOutboxes
====================
* getOutboxes(event: Event): string\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getOutboxes.html#getoutboxes)
Parses a 10002 event and stores the outboxes in the event using the [MailboxesOutboxesSymbol](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-core.Helpers.MailboxesOutboxesSymbol.html)
symbol
#### Parameters
* event: Event
#### Returns string\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getCommentRootPointer | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getCommentRootPointer](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentRootPointer.html)
Function getCommentRootPointer
==============================
* getCommentRootPointer(comment: Event): null | [CommentPointer](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.CommentPointer.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentRootPointer.html#getcommentrootpointer)
Returns the root pointer for a comment
#### Parameters
* comment: Event
#### Returns null | [CommentPointer](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.CommentPointer.html)
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getCommentRootPointer.html#throws)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isStreamURL | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isStreamURL](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isStreamURL.html)
Function isStreamURL
====================
* isStreamURL(url: string | URL): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isStreamURL.html#isstreamurl)
Checks if a url is a stream URL
#### Parameters
* url: string | URL
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isETag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isETag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isETag.html)
Function isETag
===============
* isETag(tag: string\[\]): tag is \["e", string, ...string\[\]\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isETag.html#isetag)
Checks if tag is an "e" tag and has at least one value
#### Parameters
* tag: string\[\]
#### Returns tag is \["e", string, ...string\[\]\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# canHaveHiddenTags | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [canHaveHiddenTags](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.canHaveHiddenTags.html)
Function canHaveHiddenTags
==========================
* canHaveHiddenTags(kind: number): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.canHaveHiddenTags.html#canhavehiddentags)
Checks if an event can have hidden tags
#### Parameters
* kind: number
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isRTag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isRTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isRTag.html)
Function isRTag
===============
* isRTag(tag: string\[\]): tag is \["r", string, ...string\[\]\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isRTag.html#isrtag)
Checks if tag is an "r" tag and has at least one value
#### Parameters
* tag: string\[\]
#### Returns tag is \["r", string, ...string\[\]\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isPTag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isPTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isPTag.html)
Function isPTag
===============
* isPTag(tag: string\[\]): tag is \["p", string, ...string\[\]\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isPTag.html#isptag)
Checks if tag is an "p" tag and has at least one value
#### Parameters
* tag: string\[\]
#### Returns tag is \["p", string, ...string\[\]\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isTTag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isTTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isTTag.html)
Function isTTag
===============
* isTTag(tag: string\[\]): tag is \["t", string, ...string\[\]\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isTTag.html#isttag)
Checks if tag is an "a" tag and has at least one value
#### Parameters
* tag: string\[\]
#### Returns tag is \["t", string, ...string\[\]\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isATag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isATag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isATag.html)
Function isATag
===============
* isATag(tag: string\[\]): tag is \["a", string, ...string\[\]\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isATag.html#isatag)
Checks if tag is an "a" tag and has at least one value
#### Parameters
* tag: string\[\]
#### Returns tag is \["a", string, ...string\[\]\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isDTag | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isDTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isDTag.html)
Function isDTag
===============
* isDTag(tag: string\[\]): tag is \["d", string, ...string\[\]\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isDTag.html#isdtag)
Checks if tag is an "d" tag and has at least one value
#### Parameters
* tag: string\[\]
#### Returns tag is \["d", string, ...string\[\]\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getHiddenTags | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getHiddenTags](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getHiddenTags.html)
Function getHiddenTags
======================
* getHiddenTags<[T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getHiddenTags.html#gethiddentagst)
extends { content: string; kind: number }\>(
event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getHiddenTags.html#gethiddentagst)
,
): undefined | string\[\]\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getHiddenTags.html#gethiddentags)
Returns the hidden tags for an event if they are unlocked
#### Type Parameters
* T extends { content: string; kind: number }
#### Parameters
* event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getHiddenTags.html#gethiddentagst)
#### Returns undefined | string\[\]\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# hasHiddenTags | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [hasHiddenTags](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.hasHiddenTags.html)
Function hasHiddenTags
======================
* hasHiddenTags<[T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.hasHiddenTags.html#hashiddentagst)
extends { content: string; kind: number }\>(event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.hasHiddenTags.html#hashiddentagst)
): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.hasHiddenTags.html#hashiddentags)
Checks if an event has hidden tags
#### Type Parameters
* T extends { content: string; kind: number }
#### Parameters
* event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.hasHiddenTags.html#hashiddentagst)
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isHiddenTagsLocked | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isHiddenTagsLocked](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isHiddenTagsLocked.html)
Function isHiddenTagsLocked
===========================
* isHiddenTagsLocked<[T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isHiddenTagsLocked.html#ishiddentagslockedt)
extends object\>(event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isHiddenTagsLocked.html#ishiddentagslockedt)
): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isHiddenTagsLocked.html#ishiddentagslocked)
Checks if the hidden tags are locked
#### Type Parameters
* T extends object
#### Parameters
* event: [T](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isHiddenTagsLocked.html#ishiddentagslockedt)
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# SerialPortAccount | AppleSauce
* [applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
* [Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
* [SerialPortAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html)
Class SerialPortAccount
=================================
An account for SerialPortSigner
#### Type Parameters
* Metadata extends unknown
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-accounts.Accounts.SerialPortAccount)
)
* [BaseAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html)
<[SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
, void, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructorserialportaccountmetadata)
\>
* SerialPortAccount
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructor)
### Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#abort)
[disableQueue?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#type)
### Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#type-1)
### Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#tojson)
[unlock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#unlock)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#fromjson)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#loadcommonfields)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructor)
* new SerialPortAccount<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructorserialportaccountmetadata)
extends unknown\>(
pubkey: string,
signer: [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
,
): [SerialPortAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructorserialportaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructorserialportaccount)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* pubkey: string
* signer: [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
#### Returns [SerialPortAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructorserialportaccountmetadata)
\>
Properties
----------
### `Protected`abort[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#abort)
abort: null | AbortController = null
### `Optional`disableQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#disablequeue)
disableQueue?: boolean
Disable request queueing
### id[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#id)
id: string = ...
### `Protected`lock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#lock)
lock: null | Promise = null
### metadata$[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#metadata-1)
metadata$: BehaviorSubject = ...
### pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#pubkey)
pubkey: string
### `Protected`queueLength[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#queuelength)
queueLength: number = 0
internal queue
### signer[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#signer)
signer: [SerialPortSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SerialPortSigner.html)
### `Static` `Readonly`type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#type)
type: "serial-port"
Accessors
---------
### metadata[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#metadata-2)
* get metadata(): undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
* set metadata(metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
): void
#### Parameters
* metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns void
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#nip04)
* get nip04(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#nip44)
* get nip44(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#type-1)
* get type(): string
#### Returns string
Methods
-------
### abortQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#abortqueue)
* abortQueue(reason: Error): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#abortqueue-1)
Aborts all pending requests in the queue
#### Parameters
* reason: Error
#### Returns void
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#getpublickey-1)
Gets the pubkey from the signer
#### Returns Promise
### `Protected`operation[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#operation)
* operation<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#operationt)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#operation-1)
A method that wraps any signer interaction, this allows the account to wait for unlock or queue requests
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
### `Protected`reduceQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#reducequeue)
* reduceQueue(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#reducequeue-1)
#### Returns void
### `Protected`saveCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#savecommonfields)
* saveCommonFields(
json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>,
): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#savecommonfields-1)
Adds the common fields to the serialized output of a toJSON method
#### Parameters
* json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#signevent)
* signEvent(template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#signevent-1)
sign the event and make sure its signed with the correct pubkey
#### Parameters
* template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
#### Returns Promise
### toJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#tojson)
* toJSON(): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#tojson-1)
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
### unlock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#unlock)
* unlock(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#unlock-1)
#### Returns Promise
### `Protected`waitForQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#waitforqueue)
* waitForQueue<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#waitforqueuet)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#waitforqueue-1)
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
### `Static`fromJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#fromjson)
* fromJSON<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#fromjsonmetadata)
extends unknown\>(
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [SerialPortAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#fromjsonmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#fromjson-1)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [SerialPortAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#fromjsonmetadata)
\>
### `Static`loadCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#loadcommonfields)
* loadCommonFields<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#loadcommonfieldst)
extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>\>(
account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
,
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#loadcommonfields-1)
Sets an accounts id and metadata. NOTE: This should only be used in fromJSON methods
#### Type Parameters
* T extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>
#### Parameters
* account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#constructor)
Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#abort)
[disableQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#type)
Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#type-1)
Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#tojson)
[unlock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#unlock)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#fromjson)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SerialPortAccount.html#loadcommonfields)
---
# isFilterEqual | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isFilterEqual](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isFilterEqual.html)
Function isFilterEqual
======================
* isFilterEqual(a: Filter | Filter\[\], b: Filter | Filter\[\]): boolean[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isFilterEqual.html#isfilterequal)
Check if two filters are equal
#### Parameters
* a: Filter | Filter\[\]
* b: Filter | Filter\[\]
#### Returns boolean
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# unixNow | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [unixNow](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.unixNow.html)
Function unixNow
================
* unixNow(): number[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.unixNow.html#unixnow)
Returns the current unix timestamp
#### Returns number
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# createQTagFromEventPointer | AppleSauce
* [applesauce-factory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Helpers.html)
* [createQTagFromEventPointer](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.createQTagFromEventPointer.html)
Function createQTagFromEventPointer
===================================
* createQTagFromEventPointer(pointer: EventPointer): string\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.createQTagFromEventPointer.html#createqtagfromeventpointer)
Creates a "q" tag for an EventPointer
#### Parameters
* pointer: EventPointer
#### Returns string\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# fillAndTrimTag | AppleSauce
* [applesauce-factory](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-factory.Helpers.html)
* [fillAndTrimTag](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.fillAndTrimTag.html)
Function fillAndTrimTag
=======================
* fillAndTrimTag(tag: (undefined | null | string)\[\], minLength?: number): string\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-factory.Helpers.fillAndTrimTag.html#fillandtrimtag)
Replaces null and undefined with "" in tags and trims them down to a set length if they ends with ""
#### Parameters
* tag: (undefined | null | string)\[\]
* minLength: number = 2
#### Returns string\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getZapPayment | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getZapPayment](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapPayment.html)
Function getZapPayment
======================
* getZapPayment(zap: Event): undefined | [ParsedInvoice](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.ParsedInvoice.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getZapPayment.html#getzappayment)
Returns the parsed bolt11 invoice
#### Parameters
* zap: Event
#### Returns undefined | [ParsedInvoice](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.ParsedInvoice.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# ReadonlyAccount | AppleSauce
* [applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
* [Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
* [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
Class ReadonlyAccount
===============================
An account that cannot sign or encrypt anything
#### Type Parameters
* Metadata extends unknown
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-accounts.Accounts.ReadonlyAccount)
)
* [BaseAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html)
<[ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
, void, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructorreadonlyaccountmetadata)
\>
* ReadonlyAccount
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructor)
### Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#abort)
[disableQueue?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#type)
### Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#type-1)
### Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#tojson)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#fromjson)
[fromPubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#frompubkey)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#loadcommonfields)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructor)
* new ReadonlyAccount<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructorreadonlyaccountmetadata)
extends unknown\>(
pubkey: string,
signer: [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
,
): [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructorreadonlyaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructorreadonlyaccount)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* pubkey: string
* signer: [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
#### Returns [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructorreadonlyaccountmetadata)
\>
Properties
----------
### `Protected`abort[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#abort)
abort: null | AbortController = null
### `Optional`disableQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#disablequeue)
disableQueue?: boolean
Disable request queueing
### id[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#id)
id: string = ...
### `Protected`lock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#lock)
lock: null | Promise = null
### metadata$[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#metadata-1)
metadata$: BehaviorSubject = ...
### pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#pubkey)
pubkey: string
### `Protected`queueLength[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#queuelength)
queueLength: number = 0
internal queue
### signer[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#signer)
signer: [ReadonlySigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.ReadonlySigner.html)
### `Static` `Readonly`type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#type)
type: "readonly"
Accessors
---------
### metadata[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#metadata-2)
* get metadata(): undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
* set metadata(metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
): void
#### Parameters
* metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns void
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#nip04)
* get nip04(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#nip44)
* get nip44(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#type-1)
* get type(): string
#### Returns string
Methods
-------
### abortQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#abortqueue)
* abortQueue(reason: Error): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#abortqueue-1)
Aborts all pending requests in the queue
#### Parameters
* reason: Error
#### Returns void
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#getpublickey-1)
Gets the pubkey from the signer
#### Returns Promise
### `Protected`operation[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#operation)
* operation<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#operationt)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#operation-1)
A method that wraps any signer interaction, this allows the account to wait for unlock or queue requests
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
### `Protected`reduceQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#reducequeue)
* reduceQueue(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#reducequeue-1)
#### Returns void
### `Protected`saveCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#savecommonfields)
* saveCommonFields(
json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>,
): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#savecommonfields-1)
Adds the common fields to the serialized output of a toJSON method
#### Parameters
* json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#signevent)
* signEvent(template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#signevent-1)
sign the event and make sure its signed with the correct pubkey
#### Parameters
* template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
#### Returns Promise
### toJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#tojson)
* toJSON(): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#tojson-1)
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
### `Protected`waitForQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#waitforqueue)
* waitForQueue<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#waitforqueuet)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#waitforqueue-1)
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
### `Static`fromJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#fromjson)
* fromJSON<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#fromjsonmetadata)
extends unknown\>(
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#fromjsonmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#fromjson-1)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#fromjsonmetadata)
\>
### `Static`fromPubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#frompubkey)
* fromPubkey(pubkey: string): [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#frompubkey-1)
Creates a ReadonlyAccount from a hex public key or NIP-19 npub
#### Parameters
* pubkey: string
#### Returns [ReadonlyAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html)
### `Static`loadCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#loadcommonfields)
* loadCommonFields<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#loadcommonfieldst)
extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>\>(
account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
,
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#loadcommonfields-1)
Sets an accounts id and metadata. NOTE: This should only be used in fromJSON methods
#### Type Parameters
* T extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>
#### Parameters
* account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#constructor)
Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#abort)
[disableQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#type)
Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#type-1)
Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#tojson)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#fromjson)
[fromPubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#frompubkey)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.ReadonlyAccount.html#loadcommonfields)
---
# TextNoteContentSymbol | AppleSauce
* [applesauce-content](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.html)
* [Text](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-content.Text.html)
* [TextNoteContentSymbol](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-content.Text.TextNoteContentSymbol.html)
Variable TextNoteContentSymbol`Const`
=====================================
TextNoteContentSymbol: typeof [TextNoteContentSymbol](https://hzrd149.github.io/applesauce/typedoc/variables/applesauce-content.Text.TextNoteContentSymbol.html)
= ...
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# getEmojis | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [getEmojis](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEmojis.html)
Function getEmojis
==================
* getEmojis(pack: Event): [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
.[Emoji](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.Emoji.html)
\[\][](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.getEmojis.html#getemojis)
Returns an array of emojis from a NIP-30 emoji pack
#### Parameters
* pack: Event
#### Returns [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
.[Emoji](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-core.Helpers.Emoji.html)
\[\]
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# AmberClipboardAccount | AppleSauce
* [applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
* [Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
* [AmberClipboardAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html)
Class AmberClipboardAccount
=====================================
An account for the amber clipboard api
#### Type Parameters
* Metadata extends unknown
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-accounts.Accounts.AmberClipboardAccount)
)
* [BaseAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html)
<[AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
, void, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructoramberclipboardaccountmetadata)
\>
* AmberClipboardAccount
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructor)
### Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#abort)
[disableQueue?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#type)
### Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#type-1)
### Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#tojson)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#fromjson)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#loadcommonfields)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructor)
* new AmberClipboardAccount<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructoramberclipboardaccountmetadata)
extends unknown\>(
pubkey: string,
signer: [AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
,
): [AmberClipboardAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructoramberclipboardaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructoramberclipboardaccount)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* pubkey: string
* signer: [AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
#### Returns [AmberClipboardAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructoramberclipboardaccountmetadata)
\>
Properties
----------
### `Protected`abort[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#abort)
abort: null | AbortController = null
### `Optional`disableQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#disablequeue)
disableQueue?: boolean
Disable request queueing
### id[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#id)
id: string = ...
### `Protected`lock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#lock)
lock: null | Promise = null
### metadata$[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#metadata-1)
metadata$: BehaviorSubject = ...
### pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#pubkey)
pubkey: string
### `Protected`queueLength[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#queuelength)
queueLength: number = 0
internal queue
### signer[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#signer)
signer: [AmberClipboardSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.AmberClipboardSigner.html)
### `Static` `Readonly`type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#type)
type: "amber-clipboard"
Accessors
---------
### metadata[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#metadata-2)
* get metadata(): undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
* set metadata(metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
): void
#### Parameters
* metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns void
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#nip04)
* get nip04(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#nip44)
* get nip44(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#type-1)
* get type(): string
#### Returns string
Methods
-------
### abortQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#abortqueue)
* abortQueue(reason: Error): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#abortqueue-1)
Aborts all pending requests in the queue
#### Parameters
* reason: Error
#### Returns void
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#getpublickey-1)
Gets the pubkey from the signer
#### Returns Promise
### `Protected`operation[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#operation)
* operation<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#operationt)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#operation-1)
A method that wraps any signer interaction, this allows the account to wait for unlock or queue requests
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
### `Protected`reduceQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#reducequeue)
* reduceQueue(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#reducequeue-1)
#### Returns void
### `Protected`saveCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#savecommonfields)
* saveCommonFields(
json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>,
): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#savecommonfields-1)
Adds the common fields to the serialized output of a toJSON method
#### Parameters
* json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#signevent)
* signEvent(template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#signevent-1)
sign the event and make sure its signed with the correct pubkey
#### Parameters
* template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
#### Returns Promise
### toJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#tojson)
* toJSON(): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#tojson-1)
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
### `Protected`waitForQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#waitforqueue)
* waitForQueue<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#waitforqueuet)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#waitforqueue-1)
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
### `Static`fromJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#fromjson)
* fromJSON<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#fromjsonmetadata)
extends unknown\>(
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [AmberClipboardAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#fromjsonmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#fromjson-1)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [AmberClipboardAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#fromjsonmetadata)
\>
### `Static`loadCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#loadcommonfields)
* loadCommonFields<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#loadcommonfieldst)
extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>\>(
account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
,
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#loadcommonfields-1)
Sets an accounts id and metadata. NOTE: This should only be used in fromJSON methods
#### Type Parameters
* T extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>
#### Parameters
* account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#constructor)
Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#abort)
[disableQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#type)
Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#type-1)
Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#tojson)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#fromjson)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.AmberClipboardAccount.html#loadcommonfields)
---
# SimpleSigner | AppleSauce
* [applesauce-signers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-signers.html)
* [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
Class SimpleSigner
==================
A Simple NIP-07 signer class
#### Implements
* [ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#constructor)
### Properties
[key](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#key)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#nip44)
### Methods
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#getpublickey)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#signevent)
[fromKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#fromkey)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#constructor)
* new SimpleSigner(key?: Uint8Array): [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#constructorsimplesigner)
#### Parameters
* `Optional`key: Uint8Array
#### Returns [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
Properties
----------
### key[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#key)
key: Uint8Array
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#nip04)
nip04: {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
} = ...
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#nip44)
nip44: {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
} = ...
Methods
-------
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#getpublickey-1)
#### Returns Promise
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#signevent)
* signEvent(event: EventTemplate): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#signevent-1)
#### Parameters
* event: EventTemplate
#### Returns Promise
### `Static`fromKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#fromkey)
* fromKey(privateKey: string | Uint8Array): [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#fromkey-1)
Creates a SimpleSigner from a hex private key or NIP-19 nsec
#### Parameters
* privateKey: string | Uint8Array
#### Returns [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#constructor)
Properties
[key](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#key)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#nip44)
Methods
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#getpublickey)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#signevent)
[fromKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html#fromkey)
---
# markFromCache | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [markFromCache](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.markFromCache.html)
Function markFromCache
======================
* markFromCache(event: Event): void[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.markFromCache.html#markfromcache)
Marks an event as being from a cache
#### Parameters
* event: Event
#### Returns void
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# NostrConnectAccount | AppleSauce
* [applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
* [Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
* [NostrConnectAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html)
Class NostrConnectAccount
===================================
An account type for NIP-46 signers
#### Type Parameters
* Metadata extends unknown
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-accounts.Accounts.NostrConnectAccount)
)
* [BaseAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html)
<[NostrConnectSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectSigner.html)
, [NostrConnectAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.NostrConnectAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
\>
* NostrConnectAccount
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructor)
### Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#abort)
[disableQueue?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#type)
### Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#type-1)
### Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#tojson)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjson)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#loadcommonfields)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructor)
* new NostrConnectAccount<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
extends unknown\>(
pubkey: string,
signer: [NostrConnectSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectSigner.html)
,
): [NostrConnectAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccount)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* pubkey: string
* signer: [NostrConnectSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectSigner.html)
#### Returns [NostrConnectAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
\>
Properties
----------
### `Protected`abort[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#abort)
abort: null | AbortController = null
### `Optional`disableQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#disablequeue)
disableQueue?: boolean
Disable request queueing
### id[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#id)
id: string = ...
### `Protected`lock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#lock)
lock: null | Promise = null
### metadata$[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#metadata-1)
metadata$: BehaviorSubject = ...
### pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#pubkey)
pubkey: string
### `Protected`queueLength[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#queuelength)
queueLength: number = 0
internal queue
### signer[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#signer)
signer: [NostrConnectSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.NostrConnectSigner.html)
### `Static` `Readonly`type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#type)
type: "nostr-connect"
Accessors
---------
### metadata[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#metadata-2)
* get metadata(): undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
* set metadata(metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
): void
#### Parameters
* metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns void
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#nip04)
* get nip04(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#nip44)
* get nip44(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#type-1)
* get type(): string
#### Returns string
Methods
-------
### abortQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#abortqueue)
* abortQueue(reason: Error): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#abortqueue-1)
Aborts all pending requests in the queue
#### Parameters
* reason: Error
#### Returns void
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#getpublickey-1)
Gets the pubkey from the signer
#### Returns Promise
### `Protected`operation[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#operation)
* operation<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#operationt)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#operation-1)
A method that wraps any signer interaction, this allows the account to wait for unlock or queue requests
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
### `Protected`reduceQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#reducequeue)
* reduceQueue(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#reducequeue-1)
#### Returns void
### `Protected`saveCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#savecommonfields)
* saveCommonFields(
json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>,
): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[NostrConnectAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.NostrConnectAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#savecommonfields-1)
Adds the common fields to the serialized output of a toJSON method
#### Parameters
* json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[NostrConnectAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.NostrConnectAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
\>
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#signevent)
* signEvent(template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#signevent-1)
sign the event and make sure its signed with the correct pubkey
#### Parameters
* template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
#### Returns Promise
### toJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#tojson)
* toJSON(): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[NostrConnectAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.NostrConnectAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#tojson-1)
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[NostrConnectAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.NostrConnectAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructornostrconnectaccountmetadata)
\>
### `Protected`waitForQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#waitforqueue)
* waitForQueue<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#waitforqueuet)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#waitforqueue-1)
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
### `Static`fromJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjson)
* fromJSON<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjsonmetadata)
extends unknown\>(
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[NostrConnectAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.NostrConnectAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjsonmetadata)
\>,
): [NostrConnectAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjsonmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjson-1)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[NostrConnectAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.NostrConnectAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjsonmetadata)
\>
#### Returns [NostrConnectAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjsonmetadata)
\>
### `Static`loadCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#loadcommonfields)
* loadCommonFields<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#loadcommonfieldst)
extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>\>(
account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
,
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#loadcommonfields-1)
Sets an accounts id and metadata. NOTE: This should only be used in fromJSON methods
#### Type Parameters
* T extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>
#### Parameters
* account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#constructor)
Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#abort)
[disableQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#type)
Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#type-1)
Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#tojson)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#fromjson)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.NostrConnectAccount.html#loadcommonfields)
---
# PasswordAccount | AppleSauce
* [applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
* [Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
* [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
Class PasswordAccount
===============================
A base class for all accounts
#### Type Parameters
* Metadata extends unknown = unknown
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-accounts.Accounts.PasswordAccount)
)
* [BaseAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html)
<[PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html)
, [PasswordAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.PasswordAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
\>
* PasswordAccount
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructor)
### Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#abort)
[disableQueue?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#signer)
[requestUnlockPassword?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#requestunlockpassword)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#type)
### Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#type-1)
[unlocked](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#unlocked)
### Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#tojson)
[unlock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#unlock)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjson)
[fromNcryptsec](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromncryptsec)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#loadcommonfields)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructor)
* new PasswordAccount<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
extends unknown \= unknown\>(
pubkey: string,
signer: [PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html)
,
): [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccount)
#### Type Parameters
* Metadata extends unknown = unknown
#### Parameters
* pubkey: string
* signer: [PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html)
#### Returns [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
\>
Properties
----------
### `Protected`abort[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#abort)
abort: null | AbortController = null
### `Optional`disableQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#disablequeue)
disableQueue?: boolean
Disable request queueing
### id[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#id)
id: string = ...
### `Protected`lock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#lock)
lock: null | Promise = null
### metadata$[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#metadata-1)
metadata$: BehaviorSubject = ...
### pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#pubkey)
pubkey: string
### `Protected`queueLength[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#queuelength)
queueLength: number = 0
internal queue
### signer[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#signer)
signer: [PasswordSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.PasswordSigner.html)
### `Static` `Optional`requestUnlockPassword[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#requestunlockpassword)
requestUnlockPassword?: (account: [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
) \=> Promise
called when PasswordAccount.unlock is called without a password
### `Static` `Readonly`type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#type)
type: "ncryptsec"
Accessors
---------
### metadata[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#metadata-2)
* get metadata(): undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
* set metadata(metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
): void
#### Parameters
* metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns void
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#nip04)
* get nip04(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#nip44)
* get nip44(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#type-1)
* get type(): string
#### Returns string
### unlocked[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#unlocked)
* get unlocked(): boolean
#### Returns boolean
Methods
-------
### abortQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#abortqueue)
* abortQueue(reason: Error): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#abortqueue-1)
Aborts all pending requests in the queue
#### Parameters
* reason: Error
#### Returns void
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#getpublickey-1)
Gets the pubkey from the signer
#### Returns Promise
### `Protected`operation[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operation)
* operation<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operationt)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operationt)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operationt)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operation-1)
A method that wraps any signer interaction, this allows the account to wait for unlock or queue requests
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operationt)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operationt)
\>
### `Protected`reduceQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#reducequeue)
* reduceQueue(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#reducequeue-1)
#### Returns void
### `Protected`saveCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#savecommonfields)
* saveCommonFields(
json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>,
): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[PasswordAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.PasswordAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#savecommonfields-1)
Adds the common fields to the serialized output of a toJSON method
#### Parameters
* json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[PasswordAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.PasswordAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
\>
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#signevent)
* signEvent(template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#signevent-1)
sign the event and make sure its signed with the correct pubkey
#### Parameters
* template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
#### Returns Promise
### toJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#tojson)
* toJSON(): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[PasswordAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.PasswordAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#tojson-1)
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[PasswordAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.PasswordAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructorpasswordaccountmetadata)
\>
### unlock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#unlock)
* unlock(password?: string): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#unlock-1)
Attempt to unlock the signer with a password
#### Parameters
* `Optional`password: string
#### Returns Promise
#### Throws[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#throws)
### `Protected`waitForQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#waitforqueue)
* waitForQueue<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#waitforqueuet)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#waitforqueue-1)
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#waitforqueuet)
\>
### `Static`fromJSON[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjson)
* fromJSON<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjsonmetadata)
extends unknown\>(
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[PasswordAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.PasswordAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjsonmetadata)
\>,
): [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjsonmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjson-1)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[PasswordAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.PasswordAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjsonmetadata)
\>
#### Returns [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjsonmetadata)
\>
### `Static`fromNcryptsec[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromncryptsec)
* fromNcryptsec<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromncryptsecmetadata)
extends unknown\>(
pubkey: string,
ncryptsec: string,
): [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromncryptsecmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromncryptsec-1)
Creates a new PasswordAccount from a ncryptsec string
#### Type Parameters
* Metadata extends unknown
#### Parameters
* pubkey: string
* ncryptsec: string
#### Returns [PasswordAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromncryptsecmetadata)
\>
### `Static`loadCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#loadcommonfields)
* loadCommonFields<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#loadcommonfieldst)
extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>\>(
account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
,
json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
,
): [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#loadcommonfields-1)
Sets an accounts id and metadata. NOTE: This should only be used in fromJSON methods
#### Type Parameters
* T extends [IAccount](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-accounts.IAccount.html)
<[ISigner](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-signers.ISigner.html)
, any, any\>
#### Parameters
* account: [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
* json: [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
#### Returns [T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#loadcommonfieldst)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
### On This Page
Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#constructor)
Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#abort)
[disableQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#signer)
[requestUnlockPassword](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#requestunlockpassword)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#type)
Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#type-1)
[unlocked](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#unlocked)
Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#tojson)
[unlock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#unlock)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromjson)
[fromNcryptsec](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#fromncryptsec)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.PasswordAccount.html#loadcommonfields)
---
# FactoryProvider | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
* [FactoryProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.FactoryProvider.html)
Function FactoryProvider
========================
* FactoryProvider(
\_\_namedParameters: PropsWithChildren<{ factory?: [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
}\>,
): Element[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.FactoryProvider.html#factoryprovider)
Provides an [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
to the component tree
#### Parameters
* \_\_namedParameters: PropsWithChildren<{ factory?: [EventFactory](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-factory.EventFactory.html)
}\>
#### Returns Element
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# isEvent | AppleSauce
* [applesauce-core](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.html)
* [Helpers](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-core.Helpers.html)
* [isEvent](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isEvent.html)
Function isEvent
================
* isEvent(event: any): event is Event[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-core.Helpers.isEvent.html#isevent)
Checks if an object is a nostr event NOTE: does not validate the signature on the event
#### Parameters
* event: any
#### Returns event is Event
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# useEventStore | AppleSauce
* [applesauce-react](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.html)
* [Hooks](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-react.Hooks.html)
* [useEventStore](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventStore.html)
Function useEventStore
======================
* useEventStore(): [IEventStore](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStore.html)
[](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.Hooks.useEventStore.html#useeventstore)
Gets the EventStore from a parent [EventStoreProvider](https://hzrd149.github.io/applesauce/typedoc/functions/applesauce-react.EventStoreProvider.html)
component If there is none it throws an error
#### Returns [IEventStore](https://hzrd149.github.io/applesauce/typedoc/interfaces/applesauce-core.IEventStore.html)
### Settings
Member Visibility
* Protected
* Inherited
* External
ThemeOSLightDark
---
# SimpleAccount | AppleSauce
* [applesauce-accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.html)
* [Accounts](https://hzrd149.github.io/applesauce/typedoc/modules/applesauce-accounts.Accounts.html)
* [SimpleAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html)
Class SimpleAccount
=============================
A base class for all accounts
#### Type Parameters
* Metadata extends unknown
#### Hierarchy ([View Summary](https://hzrd149.github.io/applesauce/typedoc/hierarchy.html#applesauce-accounts.Accounts.SimpleAccount)
)
* [BaseAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html)
<[SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
, [SimpleAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.SimpleAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructorsimpleaccountmetadata)
\>
* SimpleAccount
##### Index
### Constructors
[constructor](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructor)
### Properties
[abort](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#abort)
[disableQueue?](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#disablequeue)
[id](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#id)
[lock](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#lock)
[metadata$](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#metadata-1)
[pubkey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#pubkey)
[queueLength](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#queuelength)
[signer](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#signer)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#type)
### Accessors
[metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#metadata-2)
[nip04](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#nip04)
[nip44](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#nip44)
[type](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#type-1)
### Methods
[abortQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#abortqueue)
[getPublicKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#getpublickey)
[operation](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#operation)
[reduceQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#reducequeue)
[saveCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#savecommonfields)
[signEvent](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#signevent)
[toJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#tojson)
[waitForQueue](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#waitforqueue)
[fromJSON](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#fromjson)
[fromKey](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#fromkey)
[generateNew](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#generatenew)
[loadCommonFields](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#loadcommonfields)
Constructors
------------
### constructor[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructor)
* new SimpleAccount<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructorsimpleaccountmetadata)
extends unknown\>(
pubkey: string,
signer: [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
,
): [SimpleAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructorsimpleaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructorsimpleaccount)
#### Type Parameters
* Metadata extends unknown
#### Parameters
* pubkey: string
* signer: [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
#### Returns [SimpleAccount](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html)
<[Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructorsimpleaccountmetadata)
\>
Properties
----------
### `Protected`abort[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#abort)
abort: null | AbortController = null
### `Optional`disableQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#disablequeue)
disableQueue?: boolean
Disable request queueing
### id[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#id)
id: string = ...
### `Protected`lock[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#lock)
lock: null | Promise = null
### metadata$[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#metadata-1)
metadata$: BehaviorSubject = ...
### pubkey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#pubkey)
pubkey: string
### `Protected`queueLength[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#queuelength)
queueLength: number = 0
internal queue
### signer[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#signer)
signer: [SimpleSigner](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-signers.SimpleSigner.html)
### `Static` `Readonly`type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#type)
type: "nsec"
Accessors
---------
### metadata[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#metadata-2)
* get metadata(): undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns undefined | [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
* set metadata(metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
): void
#### Parameters
* metadata: [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
#### Returns void
### nip04[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#nip04)
* get nip04(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### nip44[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#nip44)
* get nip44(): | undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
#### Returns
| undefined
| {
decrypt: (pubkey: string, ciphertext: string) \=> Promise;
encrypt: (pubkey: string, plaintext: string) \=> Promise;
}
### type[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#type-1)
* get type(): string
#### Returns string
Methods
-------
### abortQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#abortqueue)
* abortQueue(reason: Error): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#abortqueue-1)
Aborts all pending requests in the queue
#### Parameters
* reason: Error
#### Returns void
### getPublicKey[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#getpublickey)
* getPublicKey(): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#getpublickey-1)
Gets the pubkey from the signer
#### Returns Promise
### `Protected`operation[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#operation)
* operation<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#operationt)
extends unknown\>(operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>): Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#operation-1)
A method that wraps any signer interaction, this allows the account to wait for unlock or queue requests
#### Type Parameters
* T extends unknown
#### Parameters
* operation: () \=> Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
#### Returns Promise<[T](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#operationt)
\>
### `Protected`reduceQueue[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#reducequeue)
* reduceQueue(): void[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#reducequeue-1)
#### Returns void
### `Protected`saveCommonFields[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#savecommonfields)
* saveCommonFields(
json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>,
): [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SimpleAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.SimpleAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructorsimpleaccountmetadata)
\>[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#savecommonfields-1)
Adds the common fields to the serialized output of a toJSON method
#### Parameters
* json: Omit<
[SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SignerData](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountsignerdata)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.BaseAccount.html#constructorbaseaccountmetadata)
\>,
"id" | "type" | "metadata" | "pubkey",
\>
#### Returns [SerializedAccount](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.SerializedAccount.html)
<[SimpleAccountSignerData](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.Accounts.SimpleAccountSignerData.html)
, [Metadata](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#constructorsimpleaccountmetadata)
\>
### signEvent[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#signevent)
* signEvent(template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
): Promise[](https://hzrd149.github.io/applesauce/typedoc/classes/applesauce-accounts.Accounts.SimpleAccount.html#signevent-1)
sign the event and make sure its signed with the correct pubkey
#### Parameters
* template: [EventTemplate](https://hzrd149.github.io/applesauce/typedoc/types/applesauce-accounts.EventTemplate.html)
#### Returns Promise