applesauce-core 0.0.0-next-20250221172959 → 0.0.0-next-20250308144838
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/__tests__/event-store.test.js +14 -1
- package/dist/event-store/database.d.ts +1 -1
- package/dist/event-store/database.js +1 -1
- package/dist/event-store/event-store.d.ts +2 -0
- package/dist/event-store/event-store.js +6 -2
- package/dist/helpers/__tests__/nip-19.test.d.ts +1 -0
- package/dist/helpers/__tests__/nip-19.test.js +42 -0
- package/dist/helpers/hidden-tags.js +1 -1
- package/dist/helpers/nip-19.d.ts +4 -0
- package/dist/helpers/nip-19.js +27 -0
- package/dist/query-store/query-store.d.ts +2 -0
- package/dist/query-store/query-store.js +4 -0
- package/package.json +2 -1
|
@@ -69,7 +69,7 @@ describe("verifyEvent", () => {
|
|
|
69
69
|
expect(verifyEvent).toHaveBeenCalledTimes(1);
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
|
-
describe("
|
|
72
|
+
describe("removed", () => {
|
|
73
73
|
it("should complete when event is removed", () => {
|
|
74
74
|
eventStore.add(profile);
|
|
75
75
|
const spy = subscribeSpyTo(eventStore.removed(profile.id));
|
|
@@ -223,6 +223,19 @@ describe("timeline", () => {
|
|
|
223
223
|
eventStore.add(user.profile({ name: "old-name" }, { created_at: profile.created_at - 1000 }));
|
|
224
224
|
expect(spy.getValues()).toEqual([[profile]]);
|
|
225
225
|
});
|
|
226
|
+
it("should return new array for every value", () => {
|
|
227
|
+
const first = user.note("first note");
|
|
228
|
+
const second = user.note("second note");
|
|
229
|
+
const third = user.note("third note");
|
|
230
|
+
eventStore.add(first);
|
|
231
|
+
const spy = subscribeSpyTo(eventStore.timeline({ kinds: [0] }));
|
|
232
|
+
eventStore.add(second);
|
|
233
|
+
eventStore.add(third);
|
|
234
|
+
const hasDuplicates = (arr) => {
|
|
235
|
+
return new Set(arr).size !== arr.length;
|
|
236
|
+
};
|
|
237
|
+
expect(hasDuplicates(spy.getValues())).toBe(false);
|
|
238
|
+
});
|
|
226
239
|
});
|
|
227
240
|
describe("replaceableSet", () => {
|
|
228
241
|
it("should not emit if there are not events", () => {
|
|
@@ -60,7 +60,7 @@ export declare class Database {
|
|
|
60
60
|
iterateIds(ids: Iterable<string>): Generator<NostrEvent>;
|
|
61
61
|
/** Returns all events that match the filter */
|
|
62
62
|
getEventsForFilter(filter: Filter): Set<NostrEvent>;
|
|
63
|
-
|
|
63
|
+
getEventsForFilters(filters: Filter[]): Set<NostrEvent>;
|
|
64
64
|
/** Remove the oldest events that are not claimed */
|
|
65
65
|
prune(limit?: number): number;
|
|
66
66
|
}
|
|
@@ -36,6 +36,8 @@ export declare class EventStore {
|
|
|
36
36
|
getReplaceable(kind: number, pubkey: string, d?: string): NostrEvent | undefined;
|
|
37
37
|
/** Returns all versions of a replaceable event */
|
|
38
38
|
getReplaceableHistory(kind: number, pubkey: string, d?: string): NostrEvent[] | undefined;
|
|
39
|
+
/** Returns a timeline of events that match filters */
|
|
40
|
+
getTimeline(filters: Filter | Filter[]): NostrEvent[];
|
|
39
41
|
/**
|
|
40
42
|
* Creates an observable that streams all events that match the filter and remains open
|
|
41
43
|
* @param filters
|
|
@@ -117,7 +117,7 @@ export class EventStore {
|
|
|
117
117
|
}
|
|
118
118
|
/** Get all events matching a filter */
|
|
119
119
|
getAll(filters) {
|
|
120
|
-
return this.database.
|
|
120
|
+
return this.database.getEventsForFilters(filters);
|
|
121
121
|
}
|
|
122
122
|
/** Check if the store has an event */
|
|
123
123
|
hasEvent(uid) {
|
|
@@ -138,6 +138,10 @@ export class EventStore {
|
|
|
138
138
|
getReplaceableHistory(kind, pubkey, d) {
|
|
139
139
|
return this.database.getReplaceable(kind, pubkey, d);
|
|
140
140
|
}
|
|
141
|
+
/** Returns a timeline of events that match filters */
|
|
142
|
+
getTimeline(filters) {
|
|
143
|
+
return Array.from(this.database.getEventsForFilters(Array.isArray(filters) ? filters : [filters])).sort(sortDesc);
|
|
144
|
+
}
|
|
141
145
|
/**
|
|
142
146
|
* Creates an observable that streams all events that match the filter and remains open
|
|
143
147
|
* @param filters
|
|
@@ -278,7 +282,7 @@ export class EventStore {
|
|
|
278
282
|
filters = Array.isArray(filters) ? filters : [filters];
|
|
279
283
|
const seen = new Map();
|
|
280
284
|
// get current events
|
|
281
|
-
return defer(() => of(Array.from(this.database.
|
|
285
|
+
return defer(() => of(Array.from(this.database.getEventsForFilters(filters)).sort(sortDesc))).pipe(
|
|
282
286
|
// claim existing events
|
|
283
287
|
claimEvents(this.database),
|
|
284
288
|
// subscribe to newer events
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { bytesToHex } from "@noble/hashes/utils";
|
|
3
|
+
import { normalizeToPubkey, normalizeToSecretKey } from "../nip-19.js";
|
|
4
|
+
describe("normalizeToPubkey", () => {
|
|
5
|
+
it("should get pubkey from npub", () => {
|
|
6
|
+
expect(normalizeToPubkey("npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
|
|
7
|
+
});
|
|
8
|
+
it("should get pubkey from nprofile", () => {
|
|
9
|
+
expect(normalizeToPubkey("nprofile1qyw8wumn8ghj7umpw3jkcmrfw3jju6r6wfjrzdpe9e3k7mf0qyf8wumn8ghj7mn0wd68yat99e3k7mf0qqszv6q4uryjzr06xfxxew34wwc5hmjfmfpqn229d72gfegsdn2q3fg5g7lja")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
|
|
10
|
+
});
|
|
11
|
+
it("should return hex pubkey", () => {
|
|
12
|
+
expect(normalizeToPubkey("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5")).toEqual("266815e0c9210dfa324c6cba3573b14bee49da4209a9456f9484e5106cd408a5");
|
|
13
|
+
});
|
|
14
|
+
it("should throw on invalid hex pubkey", () => {
|
|
15
|
+
expect(() => {
|
|
16
|
+
normalizeToPubkey("5028372");
|
|
17
|
+
}).toThrow();
|
|
18
|
+
});
|
|
19
|
+
it("should throw on invalid string", () => {
|
|
20
|
+
expect(() => {
|
|
21
|
+
normalizeToPubkey("testing");
|
|
22
|
+
}).toThrow();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe("normalizeToSecretKey", () => {
|
|
26
|
+
it("should get secret key from nsec", () => {
|
|
27
|
+
expect(bytesToHex(normalizeToSecretKey("nsec1xe7znq745x5n68566l32ru72aajz3pk2cys9lnf3tuexvkw0dldsj8v2lm"))).toEqual("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb");
|
|
28
|
+
});
|
|
29
|
+
it("should get secret key from raw hex", () => {
|
|
30
|
+
expect(bytesToHex(normalizeToSecretKey("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb"))).toEqual("367c2983d5a1a93d1e9ad7e2a1f3caef642886cac1205fcd315f326659cf6fdb");
|
|
31
|
+
});
|
|
32
|
+
it("should throw on invalid hex key", () => {
|
|
33
|
+
expect(() => {
|
|
34
|
+
normalizeToSecretKey("209573290");
|
|
35
|
+
}).toThrow();
|
|
36
|
+
});
|
|
37
|
+
it("should throw on npub", () => {
|
|
38
|
+
expect(() => {
|
|
39
|
+
normalizeToSecretKey("npub1ye5ptcxfyyxl5vjvdjar2ua3f0hynkjzpx552mu5snj3qmx5pzjscpknpr");
|
|
40
|
+
}).toThrow();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -6,7 +6,7 @@ export const HiddenTagsSymbol = Symbol.for("hidden-tags");
|
|
|
6
6
|
/** Various event kinds that can have encrypted tags in their content and which encryption method they use */
|
|
7
7
|
export const EventEncryptionMethod = {
|
|
8
8
|
// NIP-60 wallet
|
|
9
|
-
|
|
9
|
+
17375: "nip44",
|
|
10
10
|
// NIP-51 lists
|
|
11
11
|
[kinds.BookmarkList]: "nip04",
|
|
12
12
|
[kinds.InterestsList]: "nip04",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { nip19 } from "nostr-tools";
|
|
2
|
+
import { hexToBytes } from "@noble/hashes/utils";
|
|
3
|
+
import { isHexKey } from "./string.js";
|
|
4
|
+
import { getPubkeyFromDecodeResult } from "./pointers.js";
|
|
5
|
+
/** Gets the hex pubkey from any nip-19 encoded string */
|
|
6
|
+
export function normalizeToPubkey(str) {
|
|
7
|
+
if (isHexKey(str))
|
|
8
|
+
return str;
|
|
9
|
+
else {
|
|
10
|
+
const decode = nip19.decode(str);
|
|
11
|
+
const pubkey = getPubkeyFromDecodeResult(decode);
|
|
12
|
+
if (!pubkey)
|
|
13
|
+
throw new Error(`Cant find pubkey in ${decode.type}`);
|
|
14
|
+
return pubkey;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Converts hex to nsec strings into Uint8 secret keys */
|
|
18
|
+
export function normalizeToSecretKey(str) {
|
|
19
|
+
if (isHexKey(str))
|
|
20
|
+
return hexToBytes(str);
|
|
21
|
+
else {
|
|
22
|
+
const decode = nip19.decode(str);
|
|
23
|
+
if (decode.type !== "nsec")
|
|
24
|
+
throw new Error(`Cant get secret key from ${decode.type}`);
|
|
25
|
+
return decode.data;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -45,6 +45,8 @@ export declare class QueryStore {
|
|
|
45
45
|
inboxes: string[];
|
|
46
46
|
outboxes: string[];
|
|
47
47
|
} | undefined>;
|
|
48
|
+
/** Creates a query for a users blossom servers */
|
|
49
|
+
blossomServers(pubkey: string): Observable<URL[] | undefined>;
|
|
48
50
|
/** Creates a ThreadQuery */
|
|
49
51
|
thread(root: string | EventPointer | AddressPointer): Observable<Queries.Thread | undefined>;
|
|
50
52
|
}
|
|
@@ -80,6 +80,10 @@ export class QueryStore {
|
|
|
80
80
|
mailboxes(pubkey) {
|
|
81
81
|
return this.createQuery(Queries.MailboxesQuery, pubkey);
|
|
82
82
|
}
|
|
83
|
+
/** Creates a query for a users blossom servers */
|
|
84
|
+
blossomServers(pubkey) {
|
|
85
|
+
return this.createQuery(Queries.UserBlossomServersQuery, pubkey);
|
|
86
|
+
}
|
|
83
87
|
/** Creates a ThreadQuery */
|
|
84
88
|
thread(root) {
|
|
85
89
|
return this.createQuery(Queries.ThreadQuery, root);
|
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-20250308144838",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
+
"@noble/hashes": "^1.7.1",
|
|
65
66
|
"@scure/base": "^1.2.4",
|
|
66
67
|
"debug": "^4.4.0",
|
|
67
68
|
"fast-deep-equal": "^3.1.3",
|