applesauce-core 0.0.0-next-20250916134023 → 0.0.0-next-20250919114711
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/event-store/async-event-store.d.ts +1 -1
- package/dist/event-store/async-event-store.js +8 -8
- package/dist/event-store/event-memory.d.ts +2 -2
- package/dist/event-store/event-memory.js +2 -2
- package/dist/event-store/event-store.d.ts +1 -1
- package/dist/event-store/event-store.js +7 -7
- package/dist/event-store/interface.d.ts +1 -1
- package/dist/event-store/model-mixin.d.ts +1 -1
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/mailboxes.d.ts +2 -6
- package/dist/helpers/mailboxes.js +26 -20
- package/dist/helpers/pointers.js +2 -1
- package/dist/helpers/relay-selection.d.ts +13 -0
- package/dist/helpers/relay-selection.js +84 -0
- package/dist/helpers/url.js +3 -3
- package/dist/models/contacts.d.ts +1 -1
- package/dist/models/contacts.js +1 -1
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.js +1 -0
- package/dist/models/outbox.d.ts +13 -0
- package/dist/models/outbox.js +18 -0
- package/dist/observable/index.d.ts +3 -2
- package/dist/observable/index.js +4 -3
- package/dist/observable/map-events-to-store.d.ts +3 -3
- package/dist/observable/map-events-to-store.js +12 -3
- package/dist/observable/relay-selection.d.ts +7 -0
- package/dist/observable/relay-selection.js +38 -0
- package/package.json +3 -1
- package/dist/__tests__/exports.test.d.ts +0 -1
- package/dist/__tests__/exports.test.js +0 -27
- package/dist/__tests__/fixtures.d.ts +0 -17
- package/dist/__tests__/fixtures.js +0 -28
- package/dist/event-store/__tests__/event-store.test.d.ts +0 -1
- package/dist/event-store/__tests__/event-store.test.js +0 -386
- package/dist/event-store/common.d.ts +0 -1
- package/dist/event-store/common.js +0 -2
- package/dist/event-store/database.d.ts +0 -67
- package/dist/event-store/database.js +0 -316
- package/dist/event-store/event-database.d.ts +0 -74
- package/dist/event-store/event-database.js +0 -339
- package/dist/event-store/event-set.d.ts +0 -75
- package/dist/event-store/event-set.js +0 -341
- package/dist/event-store/event-store.test.d.ts +0 -1
- package/dist/event-store/event-store.test.js +0 -74
- package/dist/helpers/__tests__/app-handlers.test.d.ts +0 -1
- package/dist/helpers/__tests__/app-handlers.test.js +0 -184
- package/dist/helpers/__tests__/blossom.test.d.ts +0 -1
- package/dist/helpers/__tests__/blossom.test.js +0 -13
- package/dist/helpers/__tests__/bookmarks.test.d.ts +0 -1
- package/dist/helpers/__tests__/bookmarks.test.js +0 -88
- package/dist/helpers/__tests__/comment.test.d.ts +0 -1
- package/dist/helpers/__tests__/comment.test.js +0 -249
- package/dist/helpers/__tests__/contacts.test.d.ts +0 -1
- package/dist/helpers/__tests__/contacts.test.js +0 -34
- package/dist/helpers/__tests__/emoji.test.d.ts +0 -1
- package/dist/helpers/__tests__/emoji.test.js +0 -110
- package/dist/helpers/__tests__/encrypted-content-cache.test.d.ts +0 -1
- package/dist/helpers/__tests__/encrypted-content-cache.test.js +0 -65
- package/dist/helpers/__tests__/encryption.test.d.ts +0 -1
- package/dist/helpers/__tests__/encryption.test.js +0 -21
- package/dist/helpers/__tests__/event.test.d.ts +0 -1
- package/dist/helpers/__tests__/event.test.js +0 -36
- package/dist/helpers/__tests__/events.test.d.ts +0 -1
- package/dist/helpers/__tests__/events.test.js +0 -32
- package/dist/helpers/__tests__/exports.test.d.ts +0 -1
- package/dist/helpers/__tests__/exports.test.js +0 -293
- package/dist/helpers/__tests__/file-metadata.test.d.ts +0 -1
- package/dist/helpers/__tests__/file-metadata.test.js +0 -103
- package/dist/helpers/__tests__/groups.test.d.ts +0 -1
- package/dist/helpers/__tests__/groups.test.js +0 -61
- package/dist/helpers/__tests__/hidden-tags.test.d.ts +0 -1
- package/dist/helpers/__tests__/hidden-tags.test.js +0 -29
- package/dist/helpers/__tests__/mailboxes.test.d.ts +0 -1
- package/dist/helpers/__tests__/mailboxes.test.js +0 -81
- package/dist/helpers/__tests__/messages.test.d.ts +0 -1
- package/dist/helpers/__tests__/messages.test.js +0 -91
- package/dist/helpers/__tests__/mutes.test.d.ts +0 -1
- package/dist/helpers/__tests__/mutes.test.js +0 -55
- package/dist/helpers/__tests__/nip-19.test.d.ts +0 -1
- package/dist/helpers/__tests__/nip-19.test.js +0 -42
- package/dist/helpers/__tests__/pointers.test.d.ts +0 -1
- package/dist/helpers/__tests__/pointers.test.js +0 -118
- package/dist/helpers/__tests__/profile.test.d.ts +0 -1
- package/dist/helpers/__tests__/profile.test.js +0 -72
- package/dist/helpers/__tests__/reactions.test.d.ts +0 -1
- package/dist/helpers/__tests__/reactions.test.js +0 -88
- package/dist/helpers/__tests__/relays.test.d.ts +0 -1
- package/dist/helpers/__tests__/relays.test.js +0 -21
- package/dist/helpers/__tests__/tags.test.d.ts +0 -1
- package/dist/helpers/__tests__/tags.test.js +0 -24
- package/dist/helpers/__tests__/threading.test.d.ts +0 -1
- package/dist/helpers/__tests__/threading.test.js +0 -41
- package/dist/helpers/direct-messages.d.ts +0 -4
- package/dist/helpers/direct-messages.js +0 -5
- package/dist/helpers/file-metadata.test.d.ts +0 -1
- package/dist/helpers/file-metadata.test.js +0 -103
- package/dist/helpers/hidden-tags.test.d.ts +0 -1
- package/dist/helpers/hidden-tags.test.js +0 -29
- package/dist/helpers/legacy-direct-messages.d.ts +0 -8
- package/dist/helpers/legacy-direct-messages.js +0 -17
- package/dist/helpers/mailboxes.test.d.ts +0 -1
- package/dist/helpers/mailboxes.test.js +0 -81
- package/dist/helpers/nip-19.d.ts +0 -4
- package/dist/helpers/nip-19.js +0 -27
- package/dist/helpers/tags.test.d.ts +0 -1
- package/dist/helpers/tags.test.js +0 -16
- package/dist/helpers/threading.test.d.ts +0 -1
- package/dist/helpers/threading.test.js +0 -41
- package/dist/helpers/wrapped-direct-messages.d.ts +0 -6
- package/dist/helpers/wrapped-direct-messages.js +0 -11
- package/dist/models/__tests__/comments.test.d.ts +0 -1
- package/dist/models/__tests__/comments.test.js +0 -36
- package/dist/models/__tests__/exports.test.d.ts +0 -1
- package/dist/models/__tests__/exports.test.js +0 -53
- package/dist/observable/__tests__/claim-events.test.d.ts +0 -1
- package/dist/observable/__tests__/claim-events.test.js +0 -23
- package/dist/observable/__tests__/claim-latest.test.d.ts +0 -1
- package/dist/observable/__tests__/claim-latest.test.js +0 -37
- package/dist/observable/__tests__/exports.test.d.ts +0 -1
- package/dist/observable/__tests__/exports.test.js +0 -21
- package/dist/observable/__tests__/map-events-to-store.test.d.ts +0 -1
- package/dist/observable/__tests__/map-events-to-store.test.js +0 -38
- package/dist/observable/__tests__/simple-timeout.test.d.ts +0 -1
- package/dist/observable/__tests__/simple-timeout.test.js +0 -34
- package/dist/observable/__tests__/watch-event-updates.test.d.ts +0 -1
- package/dist/observable/__tests__/watch-event-updates.test.js +0 -55
- package/dist/observable/getValue.d.ts +0 -2
- package/dist/observable/getValue.js +0 -13
- package/dist/observable/map-events-timeline.d.ts +0 -7
- package/dist/observable/map-events-timeline.js +0 -9
- package/dist/observable/share-behavior.d.ts +0 -2
- package/dist/observable/share-behavior.js +0 -7
- package/dist/observable/share-latest-value.d.ts +0 -6
- package/dist/observable/share-latest-value.js +0 -24
- package/dist/observable/stateful.d.ts +0 -10
- package/dist/observable/stateful.js +0 -60
- package/dist/observable/throttle.d.ts +0 -3
- package/dist/observable/throttle.js +0 -23
- package/dist/promise/__tests__/exports.test.d.ts +0 -1
- package/dist/promise/__tests__/exports.test.js +0 -11
- package/dist/queries/blossom.d.ts +0 -2
- package/dist/queries/blossom.js +0 -10
- package/dist/queries/bookmarks.d.ts +0 -8
- package/dist/queries/bookmarks.js +0 -23
- package/dist/queries/channels.d.ts +0 -11
- package/dist/queries/channels.js +0 -73
- package/dist/queries/comments.d.ts +0 -4
- package/dist/queries/comments.js +0 -14
- package/dist/queries/contacts.d.ts +0 -3
- package/dist/queries/contacts.js +0 -12
- package/dist/queries/index.d.ts +0 -13
- package/dist/queries/index.js +0 -13
- package/dist/queries/mailboxes.d.ts +0 -6
- package/dist/queries/mailboxes.js +0 -13
- package/dist/queries/mutes.d.ts +0 -8
- package/dist/queries/mutes.js +0 -23
- package/dist/queries/pins.d.ts +0 -3
- package/dist/queries/pins.js +0 -12
- package/dist/queries/profile.d.ts +0 -4
- package/dist/queries/profile.js +0 -12
- package/dist/queries/reactions.d.ts +0 -4
- package/dist/queries/reactions.js +0 -19
- package/dist/queries/simple.d.ts +0 -16
- package/dist/queries/simple.js +0 -38
- package/dist/queries/thread.d.ts +0 -25
- package/dist/queries/thread.js +0 -92
- package/dist/queries/user-status.d.ts +0 -11
- package/dist/queries/user-status.js +0 -39
- package/dist/queries/zaps.d.ts +0 -5
- package/dist/queries/zaps.js +0 -21
- package/dist/query-store/__tests__/query-store.test.d.ts +0 -1
- package/dist/query-store/__tests__/query-store.test.js +0 -63
- package/dist/query-store/index.d.ts +0 -1
- package/dist/query-store/index.js +0 -1
- package/dist/query-store/query-store.d.ts +0 -53
- package/dist/query-store/query-store.js +0 -97
- package/dist/query-store/query-store.test.d.ts +0 -1
- package/dist/query-store/query-store.test.js +0 -33
- package/dist/utils/lru.d.ts +0 -32
- package/dist/utils/lru.js +0 -148
|
@@ -17,7 +17,7 @@ declare const AsyncEventStore_base: {
|
|
|
17
17
|
addressable(pointer: AddressPointer): Observable<NostrEvent | undefined>;
|
|
18
18
|
timeline(filters: Filter | Filter[], includeOldVersion?: boolean): Observable<NostrEvent[]>;
|
|
19
19
|
profile(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("../helpers/profile.js").ProfileContent | undefined>;
|
|
20
|
-
contacts(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("nostr-tools/nip19").ProfilePointer[]
|
|
20
|
+
contacts(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("nostr-tools/nip19").ProfilePointer[]>;
|
|
21
21
|
mutes(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("../helpers/mutes.js").Mutes | undefined>;
|
|
22
22
|
mailboxes(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<{
|
|
23
23
|
inboxes: string[];
|
|
@@ -214,7 +214,7 @@ export class AsyncEventStore extends EventStoreModelMixin(class {
|
|
|
214
214
|
// remove all old version of the replaceable event
|
|
215
215
|
if (!this.keepOldVersions && isReplaceable(event.kind)) {
|
|
216
216
|
const existing = await this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
217
|
-
if (existing) {
|
|
217
|
+
if (existing && existing.length > 0) {
|
|
218
218
|
const older = Array.from(existing).filter((e) => e.created_at < event.created_at);
|
|
219
219
|
for (const old of older)
|
|
220
220
|
await this.remove(old);
|
|
@@ -231,16 +231,16 @@ export class AsyncEventStore extends EventStoreModelMixin(class {
|
|
|
231
231
|
}
|
|
232
232
|
/** Removes an event from the store and updates subscriptions */
|
|
233
233
|
async remove(event) {
|
|
234
|
-
|
|
235
|
-
const e = await this.database.getEvent(typeof event === "string" ? event : event.id);
|
|
236
|
-
if (!e)
|
|
237
|
-
return false;
|
|
234
|
+
let instance = this.memory?.getEvent(typeof event === "string" ? event : event.id);
|
|
238
235
|
// Remove from memory if available
|
|
239
236
|
if (this.memory)
|
|
240
|
-
this.memory.remove(
|
|
237
|
+
this.memory.remove(event);
|
|
238
|
+
// Remove the event from the database
|
|
241
239
|
const removed = await this.database.remove(event);
|
|
242
|
-
|
|
243
|
-
|
|
240
|
+
// If the event was removed, notify the subscriptions
|
|
241
|
+
if (removed && instance) {
|
|
242
|
+
this.remove$.next(instance);
|
|
243
|
+
}
|
|
244
244
|
return removed;
|
|
245
245
|
}
|
|
246
246
|
/** Add an event to the store and notifies all subscribes it has updated */
|
|
@@ -66,9 +66,9 @@ export declare class EventMemory implements IEventMemory {
|
|
|
66
66
|
/** Iterates over all events by id */
|
|
67
67
|
iterateIds(ids: Iterable<string>): Generator<NostrEvent>;
|
|
68
68
|
/** Returns all events that match the filter */
|
|
69
|
-
getEventsForFilter(filter: Filter): Set<NostrEvent>;
|
|
69
|
+
protected getEventsForFilter(filter: Filter): Set<NostrEvent>;
|
|
70
70
|
/** Returns all events that match the filters */
|
|
71
|
-
getEventsForFilters(filters: Filter[]): Set<NostrEvent>;
|
|
71
|
+
protected getEventsForFilters(filters: Filter[]): Set<NostrEvent>;
|
|
72
72
|
/** Resets the event set */
|
|
73
73
|
reset(): void;
|
|
74
74
|
}
|
|
@@ -90,7 +90,7 @@ export class EventMemory {
|
|
|
90
90
|
remove(eventOrId) {
|
|
91
91
|
let event = typeof eventOrId === "string" ? this.events.get(eventOrId) : eventOrId;
|
|
92
92
|
if (!event)
|
|
93
|
-
|
|
93
|
+
return false;
|
|
94
94
|
const id = event.id;
|
|
95
95
|
// only remove events that are known
|
|
96
96
|
if (!this.events.has(id))
|
|
@@ -327,7 +327,7 @@ export class EventMemory {
|
|
|
327
327
|
/** Returns all events that match the filters */
|
|
328
328
|
getEventsForFilters(filters) {
|
|
329
329
|
if (filters.length === 0)
|
|
330
|
-
|
|
330
|
+
return new Set();
|
|
331
331
|
let events = new Set();
|
|
332
332
|
for (const filter of filters) {
|
|
333
333
|
const filtered = this.getEventsForFilter(filter);
|
|
@@ -17,7 +17,7 @@ declare const EventStore_base: {
|
|
|
17
17
|
addressable(pointer: AddressPointer): Observable<NostrEvent | undefined>;
|
|
18
18
|
timeline(filters: Filter | Filter[], includeOldVersion?: boolean): Observable<NostrEvent[]>;
|
|
19
19
|
profile(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("../helpers/profile.js").ProfileContent | undefined>;
|
|
20
|
-
contacts(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("nostr-tools/nip19").ProfilePointer[]
|
|
20
|
+
contacts(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("nostr-tools/nip19").ProfilePointer[]>;
|
|
21
21
|
mutes(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<import("../helpers/mutes.js").Mutes | undefined>;
|
|
22
22
|
mailboxes(user: string | import("nostr-tools/nip19").ProfilePointer): Observable<{
|
|
23
23
|
inboxes: string[];
|
|
@@ -218,7 +218,7 @@ export class EventStore extends EventStoreModelMixin(class {
|
|
|
218
218
|
// remove all old version of the replaceable event
|
|
219
219
|
if (!this.keepOldVersions && isReplaceable(event.kind)) {
|
|
220
220
|
const existing = this.database.getReplaceableHistory(event.kind, event.pubkey, identifier);
|
|
221
|
-
if (existing) {
|
|
221
|
+
if (existing && existing.length > 0) {
|
|
222
222
|
const older = Array.from(existing).filter((e) => e.created_at < event.created_at);
|
|
223
223
|
for (const old of older)
|
|
224
224
|
this.remove(old);
|
|
@@ -235,16 +235,16 @@ export class EventStore extends EventStoreModelMixin(class {
|
|
|
235
235
|
}
|
|
236
236
|
/** Removes an event from the store and updates subscriptions */
|
|
237
237
|
remove(event) {
|
|
238
|
-
|
|
239
|
-
const e = this.database.getEvent(typeof event === "string" ? event : event.id);
|
|
240
|
-
if (!e)
|
|
241
|
-
return false;
|
|
238
|
+
let instance = this.memory?.getEvent(typeof event === "string" ? event : event.id);
|
|
242
239
|
// Remove from memory if available
|
|
243
240
|
if (this.memory)
|
|
244
241
|
this.memory.remove(event);
|
|
242
|
+
// Remove the event from the database
|
|
245
243
|
const removed = this.database.remove(event);
|
|
246
|
-
|
|
247
|
-
|
|
244
|
+
// If the event was removed, notify the subscriptions
|
|
245
|
+
if (removed && instance) {
|
|
246
|
+
this.remove$.next(instance);
|
|
247
|
+
}
|
|
248
248
|
return removed;
|
|
249
249
|
}
|
|
250
250
|
/** Add an event to the store and notifies all subscribes it has updated */
|
|
@@ -112,7 +112,7 @@ export interface IEventHelpfulSubscriptions {
|
|
|
112
112
|
/** Subscribe to a users profile */
|
|
113
113
|
profile(user: string | ProfilePointer): Observable<ProfileContent | undefined>;
|
|
114
114
|
/** Subscribe to a users contacts */
|
|
115
|
-
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]
|
|
115
|
+
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]>;
|
|
116
116
|
/** Subscribe to a users mutes */
|
|
117
117
|
mutes(user: string | ProfilePointer): Observable<Mutes | undefined>;
|
|
118
118
|
/** Subscribe to a users NIP-65 mailboxes */
|
|
@@ -31,7 +31,7 @@ export declare function EventStoreModelMixin<T extends new (...args: any[]) => a
|
|
|
31
31
|
/** Subscribe to a users profile */
|
|
32
32
|
profile(user: string | ProfilePointer): Observable<import("../helpers/profile.js").ProfileContent | undefined>;
|
|
33
33
|
/** Subscribe to a users contacts */
|
|
34
|
-
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]
|
|
34
|
+
contacts(user: string | ProfilePointer): Observable<ProfilePointer[]>;
|
|
35
35
|
/** Subscribe to a users mutes */
|
|
36
36
|
mutes(user: string | ProfilePointer): Observable<import("../helpers/mutes.js").Mutes | undefined>;
|
|
37
37
|
/** Subscribe to a users NIP-65 mailboxes */
|
package/dist/helpers/index.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ export * from "./pointers.js";
|
|
|
43
43
|
export * from "./poll.js";
|
|
44
44
|
export * from "./profile.js";
|
|
45
45
|
export * from "./reactions.js";
|
|
46
|
+
export * from "./relay-selection.js";
|
|
46
47
|
export * from "./relays.js";
|
|
47
48
|
export * from "./reports.js";
|
|
48
49
|
export * from "./share.js";
|
package/dist/helpers/index.js
CHANGED
|
@@ -43,6 +43,7 @@ export * from "./pointers.js";
|
|
|
43
43
|
export * from "./poll.js";
|
|
44
44
|
export * from "./profile.js";
|
|
45
45
|
export * from "./reactions.js";
|
|
46
|
+
export * from "./relay-selection.js";
|
|
46
47
|
export * from "./relays.js";
|
|
47
48
|
export * from "./reports.js";
|
|
48
49
|
export * from "./share.js";
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import { NostrEvent } from "nostr-tools";
|
|
2
2
|
export declare const MailboxesInboxesSymbol: unique symbol;
|
|
3
3
|
export declare const MailboxesOutboxesSymbol: unique symbol;
|
|
4
|
-
/**
|
|
5
|
-
* Parses a 10002 event and stores the inboxes in the event using the {@link MailboxesInboxesSymbol} symbol
|
|
6
|
-
*/
|
|
4
|
+
/** Parses a 10002 event and stores the inboxes in the event using the {@link MailboxesInboxesSymbol} symbol */
|
|
7
5
|
export declare function getInboxes(event: NostrEvent): string[];
|
|
8
|
-
/**
|
|
9
|
-
* Parses a 10002 event and stores the outboxes in the event using the {@link MailboxesOutboxesSymbol} symbol
|
|
10
|
-
*/
|
|
6
|
+
/** Parses a 10002 event and stores the outboxes in the event using the {@link MailboxesOutboxesSymbol} symbol */
|
|
11
7
|
export declare function getOutboxes(event: NostrEvent): string[];
|
|
@@ -1,41 +1,47 @@
|
|
|
1
1
|
import { getOrComputeCachedValue } from "./cache.js";
|
|
2
2
|
import { isSafeRelayURL } from "./relays.js";
|
|
3
|
+
import { isRTag } from "./tags.js";
|
|
3
4
|
import { normalizeURL } from "./url.js";
|
|
4
5
|
export const MailboxesInboxesSymbol = Symbol.for("mailboxes-inboxes");
|
|
5
6
|
export const MailboxesOutboxesSymbol = Symbol.for("mailboxes-outboxes");
|
|
6
|
-
/**
|
|
7
|
-
* Parses a 10002 event and stores the inboxes in the event using the {@link MailboxesInboxesSymbol} symbol
|
|
8
|
-
*/
|
|
7
|
+
/** Parses a 10002 event and stores the inboxes in the event using the {@link MailboxesInboxesSymbol} symbol */
|
|
9
8
|
export function getInboxes(event) {
|
|
10
9
|
return getOrComputeCachedValue(event, MailboxesInboxesSymbol, () => {
|
|
11
10
|
const inboxes = [];
|
|
12
11
|
for (const tag of event.tags) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
!inboxes.includes(url) &&
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
if (!isRTag(tag))
|
|
13
|
+
continue;
|
|
14
|
+
try {
|
|
15
|
+
const [, url, mode] = tag;
|
|
16
|
+
if (url && isSafeRelayURL(url) && !inboxes.includes(url) && (mode === "read" || mode === undefined)) {
|
|
17
|
+
inboxes.push(normalizeURL(url));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// Ignore invalid url tags
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
24
|
return inboxes;
|
|
23
25
|
});
|
|
24
26
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Parses a 10002 event and stores the outboxes in the event using the {@link MailboxesOutboxesSymbol} symbol
|
|
27
|
-
*/
|
|
27
|
+
/** Parses a 10002 event and stores the outboxes in the event using the {@link MailboxesOutboxesSymbol} symbol */
|
|
28
28
|
export function getOutboxes(event) {
|
|
29
29
|
return getOrComputeCachedValue(event, MailboxesOutboxesSymbol, () => {
|
|
30
30
|
const outboxes = [];
|
|
31
31
|
for (const tag of event.tags) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
if (!isRTag(tag))
|
|
33
|
+
continue;
|
|
34
|
+
try {
|
|
35
|
+
const [name, url, mode] = tag;
|
|
36
|
+
if (name === "r" &&
|
|
37
|
+
isSafeRelayURL(url) &&
|
|
38
|
+
!outboxes.includes(url) &&
|
|
39
|
+
(mode === "write" || mode === undefined)) {
|
|
40
|
+
outboxes.push(normalizeURL(url));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Ignore invalid url tags
|
|
39
45
|
}
|
|
40
46
|
}
|
|
41
47
|
return outboxes;
|
package/dist/helpers/pointers.js
CHANGED
|
@@ -5,6 +5,7 @@ import { isAddressableKind } from "nostr-tools/kinds";
|
|
|
5
5
|
import { isSafeRelayURL, mergeRelaySets } from "./relays.js";
|
|
6
6
|
import { isHexKey } from "./string.js";
|
|
7
7
|
import { hexToBytes } from "@noble/hashes/utils";
|
|
8
|
+
import { normalizeURL } from "./url.js";
|
|
8
9
|
export function parseCoordinate(a, requireD = false, silent = true) {
|
|
9
10
|
const parts = a.split(":");
|
|
10
11
|
const kind = parts[0] ? parseInt(parts[0]) : undefined;
|
|
@@ -117,7 +118,7 @@ export function getProfilePointerFromPTag(tag) {
|
|
|
117
118
|
throw new Error("Invalid pubkey");
|
|
118
119
|
const pointer = { pubkey: tag[1] };
|
|
119
120
|
if (tag[2] && isSafeRelayURL(tag[2]))
|
|
120
|
-
pointer.relays = [tag[2]];
|
|
121
|
+
pointer.relays = [normalizeURL(tag[2])];
|
|
121
122
|
return pointer;
|
|
122
123
|
}
|
|
123
124
|
/** Checks if a pointer is an AddressPointer */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProfilePointer } from "nostr-tools/nip19";
|
|
2
|
+
export type SelectOptimalRelaysOptions = {
|
|
3
|
+
/** Maximum number of connections (relays) to select */
|
|
4
|
+
maxConnections: number;
|
|
5
|
+
/** Cap the number of relays a user can have */
|
|
6
|
+
maxRelaysPerUser?: number;
|
|
7
|
+
};
|
|
8
|
+
/** Selects the optimal relays for a list of ProfilePointers */
|
|
9
|
+
export declare function selectOptimalRelays(users: ProfilePointer[], { maxConnections, maxRelaysPerUser }: SelectOptimalRelaysOptions): ProfilePointer[];
|
|
10
|
+
/** A map of pubkeys by relay */
|
|
11
|
+
export type OutboxMap = Record<string, ProfilePointer[]>;
|
|
12
|
+
/** RxJS operator that aggregates contacts with outboxes into a relay -> pubkeys map */
|
|
13
|
+
export declare function groupPubkeysByRelay(pointers: ProfilePointer[]): OutboxMap;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/** Selects the optimal relays for a list of ProfilePointers */
|
|
2
|
+
export function selectOptimalRelays(users, { maxConnections, maxRelaysPerUser }) {
|
|
3
|
+
const usersWithRelays = users.filter((user) => user.relays && user.relays.length > 0);
|
|
4
|
+
// create map of popular relays
|
|
5
|
+
const popular = new Map();
|
|
6
|
+
for (const user of usersWithRelays) {
|
|
7
|
+
if (!user.relays)
|
|
8
|
+
continue;
|
|
9
|
+
for (const relay of user.relays)
|
|
10
|
+
popular.set(relay, (popular.get(relay) || 0) + 1);
|
|
11
|
+
}
|
|
12
|
+
// sort users relays by popularity
|
|
13
|
+
for (const user of usersWithRelays) {
|
|
14
|
+
if (!user.relays)
|
|
15
|
+
continue;
|
|
16
|
+
user.relays = Array.from(user.relays).sort((a, b) => popular.get(b) - popular.get(a));
|
|
17
|
+
}
|
|
18
|
+
// Create a pool of users to calculate relay coverage from
|
|
19
|
+
let selectionPool = Array.from(usersWithRelays);
|
|
20
|
+
// Create map of times a users relay has been selected
|
|
21
|
+
const selectionCount = new Map();
|
|
22
|
+
let selection = new Set();
|
|
23
|
+
while (selectionPool.length > 0 && selection.size < maxConnections) {
|
|
24
|
+
// Create map of number of pool users per relay
|
|
25
|
+
const relayUserCount = new Map();
|
|
26
|
+
for (const user of selectionPool) {
|
|
27
|
+
if (!user.relays)
|
|
28
|
+
continue;
|
|
29
|
+
for (const relay of user.relays) {
|
|
30
|
+
// Skip relays that are already selected
|
|
31
|
+
if (selection.has(relay))
|
|
32
|
+
continue;
|
|
33
|
+
// Increment relay user count
|
|
34
|
+
relayUserCount.set(relay, (relayUserCount.get(relay) || 0) + 1);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Sort relays by coverage
|
|
38
|
+
const byCoverage = Array.from(relayUserCount.entries()).sort((a, b) => b[1] - a[1]);
|
|
39
|
+
// No more relays to select, exit loop
|
|
40
|
+
if (byCoverage.length === 0)
|
|
41
|
+
break;
|
|
42
|
+
// Pick the most popular relay
|
|
43
|
+
const relay = byCoverage[0][0];
|
|
44
|
+
// Add relay to selection
|
|
45
|
+
selection.add(relay);
|
|
46
|
+
// Increment user relay count and remove users over the limit
|
|
47
|
+
selectionPool = selectionPool.filter((user) => {
|
|
48
|
+
// Ignore users that don't have the relay
|
|
49
|
+
if (!user.relays || !user.relays.includes(relay))
|
|
50
|
+
return true;
|
|
51
|
+
// Increment user relay count
|
|
52
|
+
let count = selectionCount.get(relay) || 0;
|
|
53
|
+
selectionCount.set(relay, count++);
|
|
54
|
+
// Remove user if they their relay has been selected more than minRelaysPerUser times
|
|
55
|
+
if (count >= 1)
|
|
56
|
+
return false;
|
|
57
|
+
return true;
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// Take the original users and only include relays that where selected
|
|
61
|
+
return users.map((user) => ({
|
|
62
|
+
...user,
|
|
63
|
+
relays: maxRelaysPerUser
|
|
64
|
+
? user.relays
|
|
65
|
+
?.filter((relay) => selection.has(relay))
|
|
66
|
+
.sort((a, b) => (popular.get(a) ?? 0) - (popular.get(b) ?? 0))
|
|
67
|
+
.slice(0, maxRelaysPerUser)
|
|
68
|
+
: user.relays?.filter((relay) => selection.has(relay)),
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
/** RxJS operator that aggregates contacts with outboxes into a relay -> pubkeys map */
|
|
72
|
+
export function groupPubkeysByRelay(pointers) {
|
|
73
|
+
const outbox = {};
|
|
74
|
+
for (const pointer of pointers) {
|
|
75
|
+
if (!pointer.relays)
|
|
76
|
+
continue;
|
|
77
|
+
for (const relay of pointer.relays) {
|
|
78
|
+
if (!outbox[relay])
|
|
79
|
+
outbox[relay] = [];
|
|
80
|
+
outbox[relay].push(pointer);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return outbox;
|
|
84
|
+
}
|
package/dist/helpers/url.js
CHANGED
|
@@ -78,13 +78,13 @@ export function ensureHttpURL(url) {
|
|
|
78
78
|
*/
|
|
79
79
|
export function normalizeURL(url) {
|
|
80
80
|
let p = new URL(url);
|
|
81
|
-
//
|
|
81
|
+
// Remove any double slashes
|
|
82
82
|
p.pathname = p.pathname.replace(/\/+/g, "/");
|
|
83
|
-
//
|
|
83
|
+
// Remove the port if its not needed
|
|
84
84
|
if ((p.port === "80" && (p.protocol === "ws:" || p.protocol === "http:")) ||
|
|
85
85
|
(p.port === "443" && (p.protocol === "wss:" || p.protocol === "https:")))
|
|
86
86
|
p.port = "";
|
|
87
|
-
//
|
|
87
|
+
// Return a string if a string was passed in
|
|
88
88
|
// @ts-expect-error
|
|
89
89
|
return typeof url === "string" ? p.toString() : p;
|
|
90
90
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ProfilePointer } from "nostr-tools/nip19";
|
|
2
2
|
import { Model } from "../event-store/interface.js";
|
|
3
3
|
/** A model that returns all contacts for a user */
|
|
4
|
-
export declare function ContactsModel(user: string | ProfilePointer): Model<ProfilePointer[]
|
|
4
|
+
export declare function ContactsModel(user: string | ProfilePointer): Model<ProfilePointer[]>;
|
|
5
5
|
/** A model that returns all public contacts for a user */
|
|
6
6
|
export declare function PublicContactsModel(pubkey: string): Model<ProfilePointer[] | undefined>;
|
|
7
7
|
/** A model that returns all hidden contacts for a user */
|
package/dist/models/contacts.js
CHANGED
|
@@ -10,7 +10,7 @@ export function ContactsModel(user) {
|
|
|
10
10
|
// listen for event updates (hidden tags unlocked)
|
|
11
11
|
watchEventUpdates(events),
|
|
12
12
|
// Get all contacts
|
|
13
|
-
map((e) => (e ? getContacts(e) :
|
|
13
|
+
map((e) => (e ? getContacts(e) : [])));
|
|
14
14
|
}
|
|
15
15
|
/** A model that returns all public contacts for a user */
|
|
16
16
|
export function PublicContactsModel(pubkey) {
|
package/dist/models/index.d.ts
CHANGED
package/dist/models/index.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ProfilePointer } from "nostr-tools/nip19";
|
|
2
|
+
import { Model } from "../event-store/interface.js";
|
|
3
|
+
import { SelectOptimalRelaysOptions } from "../helpers/relay-selection.js";
|
|
4
|
+
import { ignoreBlacklistedRelays } from "../observable/relay-selection.js";
|
|
5
|
+
export type OutboxModelOptions = SelectOptimalRelaysOptions & {
|
|
6
|
+
type?: "inbox" | "outbox";
|
|
7
|
+
blacklist?: Parameters<typeof ignoreBlacklistedRelays>[0];
|
|
8
|
+
};
|
|
9
|
+
/** A model that returns the users contacts with the relays to connect to */
|
|
10
|
+
export declare function OutboxModel(user: string | ProfilePointer, opts: OutboxModelOptions): Model<ProfilePointer[]>;
|
|
11
|
+
export declare namespace OutboxModel {
|
|
12
|
+
var getKey: (user: string | ProfilePointer, opts: OutboxModelOptions) => string;
|
|
13
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import hash_sum from "hash-sum";
|
|
2
|
+
import { identity, map } from "rxjs";
|
|
3
|
+
import { selectOptimalRelays } from "../helpers/relay-selection.js";
|
|
4
|
+
import { ignoreBlacklistedRelays, includeMailboxes } from "../observable/relay-selection.js";
|
|
5
|
+
/** A model that returns the users contacts with the relays to connect to */
|
|
6
|
+
export function OutboxModel(user, opts) {
|
|
7
|
+
return (store) => store.contacts(user).pipe(
|
|
8
|
+
/** Ignore blacklisted relays */
|
|
9
|
+
opts?.blacklist ? ignoreBlacklistedRelays(opts.blacklist) : identity,
|
|
10
|
+
/** Include mailboxes */
|
|
11
|
+
includeMailboxes(store, opts.type),
|
|
12
|
+
/** Select the optimal relays */
|
|
13
|
+
map((users) => selectOptimalRelays(users, opts)));
|
|
14
|
+
}
|
|
15
|
+
OutboxModel.getKey = (user, opts) => {
|
|
16
|
+
const p = typeof user === "string" ? user : user.pubkey;
|
|
17
|
+
return hash_sum([p, opts.type, opts.maxConnections, opts.maxRelaysPerUser]);
|
|
18
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
export { firstValueFrom, lastValueFrom, combineLatest, merge } from "rxjs";
|
|
2
|
+
export { Observable, Subject, BehaviorSubject, ReplaySubject } from "rxjs";
|
|
2
3
|
export * from "./defined.js";
|
|
3
4
|
export * from "./get-observable-value.js";
|
|
4
5
|
export * from "./map-events-to-timeline.js";
|
|
@@ -6,4 +7,4 @@ export * from "./map-events-to-store.js";
|
|
|
6
7
|
export * from "./simple-timeout.js";
|
|
7
8
|
export * from "./watch-event-updates.js";
|
|
8
9
|
export * from "./with-immediate-value.js";
|
|
9
|
-
export
|
|
10
|
+
export * from "./relay-selection.js";
|
package/dist/observable/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// Re-export some useful rxjs functions
|
|
2
|
+
export { firstValueFrom, lastValueFrom, combineLatest, merge } from "rxjs";
|
|
3
|
+
export { Observable, Subject, BehaviorSubject, ReplaySubject } from "rxjs";
|
|
2
4
|
export * from "./defined.js";
|
|
3
5
|
export * from "./get-observable-value.js";
|
|
4
6
|
export * from "./map-events-to-timeline.js";
|
|
@@ -6,5 +8,4 @@ export * from "./map-events-to-store.js";
|
|
|
6
8
|
export * from "./simple-timeout.js";
|
|
7
9
|
export * from "./watch-event-updates.js";
|
|
8
10
|
export * from "./with-immediate-value.js";
|
|
9
|
-
|
|
10
|
-
export { firstValueFrom, lastValueFrom };
|
|
11
|
+
export * from "./relay-selection.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NostrEvent } from "nostr-tools";
|
|
2
2
|
import { MonoTypeOperatorFunction } from "rxjs";
|
|
3
|
-
import { IEventStoreActions } from "../event-store/interface.js";
|
|
3
|
+
import { IAsyncEventStoreActions, IEventStoreActions } from "../event-store/interface.js";
|
|
4
4
|
/** Saves all events to an event store and filters out invalid events */
|
|
5
|
-
export declare function mapEventsToStore(store: IEventStoreActions, removeDuplicates?: boolean): MonoTypeOperatorFunction<NostrEvent>;
|
|
5
|
+
export declare function mapEventsToStore(store: IEventStoreActions | IAsyncEventStoreActions, removeDuplicates?: boolean): MonoTypeOperatorFunction<NostrEvent>;
|
|
6
6
|
/** Alias for {@link mapEventsToStore} */
|
|
7
|
-
export declare const filterDuplicateEvents: (store: IEventStoreActions) => MonoTypeOperatorFunction<import("nostr-tools").Event>;
|
|
7
|
+
export declare const filterDuplicateEvents: (store: IEventStoreActions | IAsyncEventStoreActions) => MonoTypeOperatorFunction<import("nostr-tools").Event>;
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import { distinct, filter, identity,
|
|
1
|
+
import { catchError, distinct, filter, from, identity, mergeMap, of } from "rxjs";
|
|
2
2
|
/** Saves all events to an event store and filters out invalid events */
|
|
3
3
|
export function mapEventsToStore(store, removeDuplicates = true) {
|
|
4
4
|
return (source) => source.pipe(
|
|
5
5
|
// Map all events to the store
|
|
6
|
-
// NOTE:
|
|
7
|
-
|
|
6
|
+
// NOTE: mergeMap is used here because we want to return the single instance of the event so that distinct() can be used later
|
|
7
|
+
mergeMap((event) => {
|
|
8
|
+
const r = store.add(event);
|
|
9
|
+
// Unwrap the promise from the async store
|
|
10
|
+
if (r instanceof Promise)
|
|
11
|
+
return from(r);
|
|
12
|
+
else
|
|
13
|
+
return of(r);
|
|
14
|
+
}),
|
|
15
|
+
// Ignore errors when inserting events into the store
|
|
16
|
+
catchError(() => of(null)),
|
|
8
17
|
// Ignore invalid events
|
|
9
18
|
filter((e) => e !== null),
|
|
10
19
|
// Remove duplicates if requested
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ProfilePointer } from "nostr-tools/nip19";
|
|
2
|
+
import { type MonoTypeOperatorFunction, type Observable, type OperatorFunction } from "rxjs";
|
|
3
|
+
import { IEventSubscriptions } from "../event-store/interface.js";
|
|
4
|
+
/** RxJS operator that fetches outboxes for profile pointers from the event store */
|
|
5
|
+
export declare function includeMailboxes(store: IEventSubscriptions, type?: "inbox" | "outbox"): OperatorFunction<ProfilePointer[], ProfilePointer[]>;
|
|
6
|
+
/** Removes blacklisted relays from the user's relays */
|
|
7
|
+
export declare function ignoreBlacklistedRelays(blacklist: string[] | Observable<string[]>): MonoTypeOperatorFunction<ProfilePointer[]>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { combineLatest, combineLatestWith, isObservable, map, of, pipe, switchMap, } from "rxjs";
|
|
2
|
+
import { getInboxes, getOutboxes } from "../helpers/mailboxes.js";
|
|
3
|
+
import { addRelayHintsToPointer } from "../helpers/pointers.js";
|
|
4
|
+
/** RxJS operator that fetches outboxes for profile pointers from the event store */
|
|
5
|
+
export function includeMailboxes(store, type = "outbox") {
|
|
6
|
+
// Get the outboxes for all contacts
|
|
7
|
+
return switchMap((contacts) => combineLatest(contacts.map((user) =>
|
|
8
|
+
// Subscribe to the outboxes for the user
|
|
9
|
+
store
|
|
10
|
+
.replaceable({
|
|
11
|
+
kind: 10002,
|
|
12
|
+
pubkey: user.pubkey,
|
|
13
|
+
})
|
|
14
|
+
.pipe(
|
|
15
|
+
// Add the relays to the user
|
|
16
|
+
map((event) => {
|
|
17
|
+
if (!event)
|
|
18
|
+
return user;
|
|
19
|
+
// Get the relays from the event
|
|
20
|
+
const relays = type === "outbox" ? getOutboxes(event) : getInboxes(event);
|
|
21
|
+
if (!relays)
|
|
22
|
+
return user;
|
|
23
|
+
// Add the relays to the user
|
|
24
|
+
return addRelayHintsToPointer(user, relays);
|
|
25
|
+
})))));
|
|
26
|
+
}
|
|
27
|
+
/** Removes blacklisted relays from the user's relays */
|
|
28
|
+
export function ignoreBlacklistedRelays(blacklist) {
|
|
29
|
+
return pipe(
|
|
30
|
+
// Combine with the observable so it re-emits when the blacklist changes
|
|
31
|
+
combineLatestWith(isObservable(blacklist) ? blacklist : of(blacklist)),
|
|
32
|
+
// Filter the relays for the user
|
|
33
|
+
map(([users, blacklist]) => users.map((user) => {
|
|
34
|
+
if (!user.relays)
|
|
35
|
+
return user;
|
|
36
|
+
return { ...user, relays: user.relays.filter((relay) => !blacklist.includes(relay)) };
|
|
37
|
+
})));
|
|
38
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-core",
|
|
3
|
-
"version": "0.0.0-next-
|
|
3
|
+
"version": "0.0.0-next-20250919114711",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"@hirez_io/observer-spy": "^2.2.0",
|
|
72
72
|
"@types/debug": "^4.1.12",
|
|
73
73
|
"@types/hash-sum": "^1.0.2",
|
|
74
|
+
"rimraf": "^6.0.1",
|
|
74
75
|
"typescript": "^5.8.3",
|
|
75
76
|
"vitest": "^3.2.4"
|
|
76
77
|
},
|
|
@@ -79,6 +80,7 @@
|
|
|
79
80
|
"url": "lightning:nostrudel@geyser.fund"
|
|
80
81
|
},
|
|
81
82
|
"scripts": {
|
|
83
|
+
"prebuild": "rimraf dist",
|
|
82
84
|
"build": "tsc",
|
|
83
85
|
"watch:build": "tsc --watch > /dev/null",
|
|
84
86
|
"test": "vitest run --passWithNoTests",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import * as exports from "../index.js";
|
|
3
|
-
describe("exports", () => {
|
|
4
|
-
it("should export the expected functions", () => {
|
|
5
|
-
expect(Object.keys(exports).sort()).toMatchInlineSnapshot(`
|
|
6
|
-
[
|
|
7
|
-
"EventSet",
|
|
8
|
-
"EventStore",
|
|
9
|
-
"EventStoreSymbol",
|
|
10
|
-
"Helpers",
|
|
11
|
-
"Models",
|
|
12
|
-
"TimeoutError",
|
|
13
|
-
"defined",
|
|
14
|
-
"firstValueFrom",
|
|
15
|
-
"getObservableValue",
|
|
16
|
-
"lastValueFrom",
|
|
17
|
-
"logger",
|
|
18
|
-
"mapEventsToStore",
|
|
19
|
-
"mapEventsToTimeline",
|
|
20
|
-
"simpleTimeout",
|
|
21
|
-
"watchEventUpdates",
|
|
22
|
-
"watchEventsUpdates",
|
|
23
|
-
"withImmediateValueOrDefault",
|
|
24
|
-
]
|
|
25
|
-
`);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { NostrEvent } from "nostr-tools";
|
|
2
|
-
import { EncryptedContentSigner } from "../helpers/encrypted-content.js";
|
|
3
|
-
export declare class FakeUser implements EncryptedContentSigner {
|
|
4
|
-
key: Uint8Array<ArrayBufferLike>;
|
|
5
|
-
pubkey: string;
|
|
6
|
-
nip04: {
|
|
7
|
-
encrypt: (pubkey: string, plaintext: string) => string;
|
|
8
|
-
decrypt: (pubkey: string, ciphertext: string) => string;
|
|
9
|
-
};
|
|
10
|
-
nip44: {
|
|
11
|
-
encrypt: (pubkey: string, plaintext: string) => string;
|
|
12
|
-
decrypt: (pubkey: string, ciphertext: string) => string;
|
|
13
|
-
};
|
|
14
|
-
event(data?: Partial<NostrEvent>): NostrEvent;
|
|
15
|
-
note(content?: string, extra?: Partial<NostrEvent>): import("nostr-tools").Event;
|
|
16
|
-
profile(profile: any, extra?: Partial<NostrEvent>): import("nostr-tools").Event;
|
|
17
|
-
}
|