applesauce-core 4.4.0 → 4.4.2

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.
@@ -1,4 +1,4 @@
1
- import { NostrEvent, VerifiedEvent } from "nostr-tools";
1
+ import { NostrEvent, VerifiedEvent } from "nostr-tools/pure";
2
2
  import { IEventStore } from "../event-store/interface.js";
3
3
  export { NostrEvent, EventTemplate, UnsignedEvent, verifiedSymbol, verifyEvent, VerifiedEvent } from "nostr-tools/pure";
4
4
  export { bytesToHex, hexToBytes, insertEventIntoAscendingList, insertEventIntoDescendingList, binarySearch, } from "nostr-tools/utils";
@@ -36,6 +36,12 @@ export declare function getReplaceableAddress(event: NostrEvent): string;
36
36
  export declare function createReplaceableAddress(kind: number, pubkey: string, identifier?: string): string;
37
37
  /** @deprecated use createReplaceableAddress instead */
38
38
  export declare const getReplaceableUID: typeof createReplaceableAddress;
39
+ /** Method used to verify an events signature */
40
+ export type VerifyEventMethod = (event: NostrEvent) => event is VerifiedEvent;
41
+ /** Sets the internal method used to verify events in helpers (zaps, gift-wraps, etc) */
42
+ export declare function setVerifyWrappedEventMethod(method: VerifyEventMethod): void;
43
+ /** Verifies an internal (wrapped) event using the set internal verification method */
44
+ export declare function verifyWrappedEvent(event: NostrEvent): event is VerifiedEvent;
39
45
  /** Sets events verified flag without checking anything */
40
46
  export declare function fakeVerifyEvent(event: NostrEvent): event is VerifiedEvent;
41
47
  /** Marks an event as being from a cache */
@@ -1,4 +1,4 @@
1
- import { verifiedSymbol } from "nostr-tools";
1
+ import { verifiedSymbol, verifyEvent } from "nostr-tools/pure";
2
2
  import { isAddressableKind, isReplaceableKind } from "nostr-tools/kinds";
3
3
  import { getOrComputeCachedValue } from "./cache.js";
4
4
  // Re-export types from nostr-tools
@@ -43,7 +43,7 @@ export function isReplaceable(kind) {
43
43
  export function getEventUID(event) {
44
44
  let uid = Reflect.get(event, EventUIDSymbol);
45
45
  if (!uid) {
46
- if (isReplaceable(event.kind))
46
+ if (isAddressableKind(event.kind) || isReplaceableKind(event.kind))
47
47
  uid = getReplaceableAddress(event);
48
48
  else
49
49
  uid = event.id;
@@ -53,11 +53,10 @@ export function getEventUID(event) {
53
53
  }
54
54
  /** Returns the replaceable event address for an addressable event */
55
55
  export function getReplaceableAddress(event) {
56
- if (!isReplaceable(event.kind))
56
+ if (!isAddressableKind(event.kind) && !isReplaceableKind(event.kind))
57
57
  throw new Error("Event is not replaceable or addressable");
58
58
  return getOrComputeCachedValue(event, ReplaceableAddressSymbol, () => {
59
- const identifier = isAddressableKind(event.kind) ? getReplaceableIdentifier(event) : undefined;
60
- return createReplaceableAddress(event.kind, event.pubkey, identifier);
59
+ return createReplaceableAddress(event.kind, event.pubkey, getReplaceableIdentifier(event));
61
60
  });
62
61
  }
63
62
  /** Creates a replaceable event address from a kind, pubkey, and identifier */
@@ -66,6 +65,16 @@ export function createReplaceableAddress(kind, pubkey, identifier) {
66
65
  }
67
66
  /** @deprecated use createReplaceableAddress instead */
68
67
  export const getReplaceableUID = createReplaceableAddress;
68
+ // Internal method for verifying events (used by zaps, gift-wraps, etc)
69
+ let verifyWrappedEventMethod = verifyEvent;
70
+ /** Sets the internal method used to verify events in helpers (zaps, gift-wraps, etc) */
71
+ export function setVerifyWrappedEventMethod(method) {
72
+ verifyWrappedEventMethod = method;
73
+ }
74
+ /** Verifies an internal (wrapped) event using the set internal verification method */
75
+ export function verifyWrappedEvent(event) {
76
+ return verifyWrappedEventMethod(event);
77
+ }
69
78
  /** Sets events verified flag without checking anything */
70
79
  export function fakeVerifyEvent(event) {
71
80
  event[verifiedSymbol] = true;
@@ -1,7 +1,7 @@
1
- import { kinds, verifyEvent } from "nostr-tools";
1
+ import { kinds } from "nostr-tools";
2
2
  import { EventMemory } from "../event-store/event-memory.js";
3
3
  import { getEncryptedContent, isEncryptedContentUnlocked, lockEncryptedContent, unlockEncryptedContent, } from "./encrypted-content.js";
4
- import { notifyEventUpdate } from "./event.js";
4
+ import { notifyEventUpdate, verifyWrappedEvent } from "./event.js";
5
5
  /**
6
6
  * An internal event set to keep track of seals and rumors
7
7
  * This is intentionally isolated from the main applications event store so to prevent seals and rumors from being leaked
@@ -130,7 +130,7 @@ export function getGiftWrapSeal(gift) {
130
130
  }
131
131
  else {
132
132
  // Verify the seal event
133
- verifyEvent(seal);
133
+ verifyWrappedEvent(seal);
134
134
  // Add to the internal event set
135
135
  internalGiftWrapEvents.add(seal);
136
136
  // Set the reference to the parent gift wrap event (upstream)
@@ -16,6 +16,8 @@ export declare function parseCoordinate(a: string, requireD: true, silent: true)
16
16
  export declare function parseCoordinate(a: string, requireD: false, silent: true): AddressPointerWithoutD | null;
17
17
  /** Extra a pubkey from the result of nip19.decode */
18
18
  export declare function getPubkeyFromDecodeResult(result?: DecodeResult): string | undefined;
19
+ /** Gets the relays from a decode result */
20
+ export declare function getRelaysFromDecodeResult(result?: DecodeResult): string[] | undefined;
19
21
  /** Encodes the result of nip19.decode */
20
22
  export declare function encodeDecodeResult(result: DecodeResult): "" | `nevent1${string}` | `naddr1${string}` | `nprofile1${string}` | `nsec1${string}` | `npub1${string}` | `note1${string}`;
21
23
  /**
@@ -25,17 +27,17 @@ export declare function encodeDecodeResult(result: DecodeResult): "" | `nevent1$
25
27
  export declare function getEventPointerFromETag(tag: string[]): EventPointer;
26
28
  /**
27
29
  * Gets an EventPointer form a common "q" tag
28
- * @throws
30
+ * @throws if the tag is invalid
29
31
  */
30
32
  export declare function getEventPointerFromQTag(tag: string[]): EventPointer;
31
33
  /**
32
34
  * Get an AddressPointer from a common "a" tag
33
- * @throws
35
+ * @throws if the tag is invalid
34
36
  */
35
37
  export declare function getAddressPointerFromATag(tag: string[]): AddressPointer;
36
38
  /**
37
39
  * Gets a ProfilePointer from a common "p" tag
38
- * @throws
40
+ * @throws if the tag is invalid
39
41
  */
40
42
  export declare function getProfilePointerFromPTag(tag: string[]): ProfilePointer;
41
43
  /** Checks if a pointer is an AddressPointer */
@@ -46,15 +48,12 @@ export declare function isEventPointer(pointer: DecodeResult["data"]): pointer i
46
48
  export declare function getCoordinateFromAddressPointer(pointer: AddressPointer): string;
47
49
  /**
48
50
  * Returns an AddressPointer for a replaceable event
49
- * @throws
51
+ * @throws if the event is not replaceable or addressable
50
52
  */
51
53
  export declare function getAddressPointerForEvent(event: NostrEvent, relays?: string[]): AddressPointer;
52
54
  /** Returns an EventPointer for an event */
53
55
  export declare function getEventPointerForEvent(event: NostrEvent, relays?: string[]): EventPointer;
54
- /**
55
- * Returns a pointer for a given event
56
- * @throws
57
- */
56
+ /** Returns a pointer for a given event */
58
57
  export declare function getPointerForEvent(event: NostrEvent, relays?: string[]): DecodeResult;
59
58
  /** Adds relay hints to a pointer object that has a relays array */
60
59
  export declare function addRelayHintsToPointer<T extends {
@@ -62,6 +61,8 @@ export declare function addRelayHintsToPointer<T extends {
62
61
  }>(pointer: T, relays?: Iterable<string>): T;
63
62
  /** Gets the hex pubkey from any nip-19 encoded string */
64
63
  export declare function normalizeToPubkey(str: string): string;
64
+ /** Gets a ProfilePointer from any nip-19 encoded string */
65
+ export declare function normalizeToProfilePointer(str: string): ProfilePointer;
65
66
  /** Converts hex to nsec strings into Uint8 secret keys */
66
67
  export declare function normalizeToSecretKey(str: string | Uint8Array): Uint8Array;
67
68
  /**
@@ -3,8 +3,8 @@ import { getPublicKey, kinds, nip19 } from "nostr-tools";
3
3
  // export nip-19 helpers
4
4
  export { naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode, decode as decodePointer, } from "nostr-tools/nip19";
5
5
  import { getReplaceableIdentifier } from "./event.js";
6
- import { isAddressableKind } from "nostr-tools/kinds";
7
- import { isSafeRelayURL, mergeRelaySets } from "./relays.js";
6
+ import { isAddressableKind, isReplaceableKind } from "nostr-tools/kinds";
7
+ import { isSafeRelayURL, relaySet } from "./relays.js";
8
8
  import { isHexKey } from "./string.js";
9
9
  import { hexToBytes } from "@noble/hashes/utils";
10
10
  import { normalizeURL } from "./url.js";
@@ -53,6 +53,20 @@ export function getPubkeyFromDecodeResult(result) {
53
53
  return undefined;
54
54
  }
55
55
  }
56
+ /** Gets the relays from a decode result */
57
+ export function getRelaysFromDecodeResult(result) {
58
+ if (!result)
59
+ return;
60
+ switch (result.type) {
61
+ case "naddr":
62
+ return result.data.relays;
63
+ case "nprofile":
64
+ return result.data.relays;
65
+ case "nevent":
66
+ return result.data.relays;
67
+ }
68
+ return undefined;
69
+ }
56
70
  /** Encodes the result of nip19.decode */
57
71
  export function encodeDecodeResult(result) {
58
72
  switch (result.type) {
@@ -85,7 +99,7 @@ export function getEventPointerFromETag(tag) {
85
99
  }
86
100
  /**
87
101
  * Gets an EventPointer form a common "q" tag
88
- * @throws
102
+ * @throws if the tag is invalid
89
103
  */
90
104
  export function getEventPointerFromQTag(tag) {
91
105
  if (!tag[1])
@@ -99,7 +113,7 @@ export function getEventPointerFromQTag(tag) {
99
113
  }
100
114
  /**
101
115
  * Get an AddressPointer from a common "a" tag
102
- * @throws
116
+ * @throws if the tag is invalid
103
117
  */
104
118
  export function getAddressPointerFromATag(tag) {
105
119
  if (!tag[1])
@@ -111,7 +125,7 @@ export function getAddressPointerFromATag(tag) {
111
125
  }
112
126
  /**
113
127
  * Gets a ProfilePointer from a common "p" tag
114
- * @throws
128
+ * @throws if the tag is invalid
115
129
  */
116
130
  export function getProfilePointerFromPTag(tag) {
117
131
  if (!tag[1])
@@ -140,10 +154,10 @@ export function getCoordinateFromAddressPointer(pointer) {
140
154
  }
141
155
  /**
142
156
  * Returns an AddressPointer for a replaceable event
143
- * @throws
157
+ * @throws if the event is not replaceable or addressable
144
158
  */
145
159
  export function getAddressPointerForEvent(event, relays) {
146
- if (!isAddressableKind(event.kind))
160
+ if (!isAddressableKind(event.kind) && !isReplaceableKind(event.kind))
147
161
  throw new Error("Cant get AddressPointer for non-replaceable event");
148
162
  const d = getReplaceableIdentifier(event);
149
163
  return {
@@ -162,12 +176,9 @@ export function getEventPointerForEvent(event, relays) {
162
176
  relays,
163
177
  };
164
178
  }
165
- /**
166
- * Returns a pointer for a given event
167
- * @throws
168
- */
179
+ /** Returns a pointer for a given event */
169
180
  export function getPointerForEvent(event, relays) {
170
- if (kinds.isAddressableKind(event.kind)) {
181
+ if (kinds.isAddressableKind(event.kind) || kinds.isReplaceableKind(event.kind)) {
171
182
  return {
172
183
  type: "naddr",
173
184
  data: getAddressPointerForEvent(event, relays),
@@ -185,7 +196,7 @@ export function addRelayHintsToPointer(pointer, relays) {
185
196
  if (!relays)
186
197
  return pointer;
187
198
  else
188
- return { ...pointer, relays: mergeRelaySets(relays, pointer.relays) };
199
+ return { ...pointer, relays: relaySet(relays, pointer.relays) };
189
200
  }
190
201
  /** Gets the hex pubkey from any nip-19 encoded string */
191
202
  export function normalizeToPubkey(str) {
@@ -199,6 +210,23 @@ export function normalizeToPubkey(str) {
199
210
  return pubkey;
200
211
  }
201
212
  }
213
+ /** Gets a ProfilePointer from any nip-19 encoded string */
214
+ export function normalizeToProfilePointer(str) {
215
+ if (isHexKey(str))
216
+ return { pubkey: str.toLowerCase() };
217
+ else {
218
+ const decode = nip19.decode(str);
219
+ // Return it if it's a profile pointer
220
+ if (decode.type === "nprofile")
221
+ return decode.data;
222
+ // fallback to just getting the pubkey
223
+ const pubkey = getPubkeyFromDecodeResult(decode);
224
+ if (!pubkey)
225
+ throw new Error(`Cant find pubkey in ${decode.type}`);
226
+ const relays = getRelaysFromDecodeResult(decode);
227
+ return { pubkey, relays };
228
+ }
229
+ }
202
230
  /** Converts hex to nsec strings into Uint8 secret keys */
203
231
  export function normalizeToSecretKey(str) {
204
232
  if (str instanceof Uint8Array)
@@ -219,7 +247,7 @@ export function normalizeToSecretKey(str) {
219
247
  export function mergeEventPointers(a, b) {
220
248
  if (a.id !== b.id)
221
249
  throw new Error("Cant merge event pointers with different ids");
222
- const relays = mergeRelaySets(a.relays, b.relays);
250
+ const relays = relaySet(a.relays, b.relays);
223
251
  return { id: a.id, kind: a.kind ?? b.kind, author: a.author ?? b.author, relays };
224
252
  }
225
253
  /**
@@ -229,7 +257,7 @@ export function mergeEventPointers(a, b) {
229
257
  export function mergeAddressPointers(a, b) {
230
258
  if (a.kind !== b.kind || a.pubkey !== b.pubkey || a.identifier !== b.identifier)
231
259
  throw new Error("Cant merge address pointers with different kinds, pubkeys, or identifiers");
232
- const relays = mergeRelaySets(a.relays, b.relays);
260
+ const relays = relaySet(a.relays, b.relays);
233
261
  return { ...a, relays };
234
262
  }
235
263
  /**
@@ -239,6 +267,6 @@ export function mergeAddressPointers(a, b) {
239
267
  export function mergeProfilePointers(a, b) {
240
268
  if (a.pubkey !== b.pubkey)
241
269
  throw new Error("Cant merge profile pointers with different pubkeys");
242
- const relays = mergeRelaySets(a.relays, b.relays);
270
+ const relays = relaySet(a.relays, b.relays);
243
271
  return { ...a, relays };
244
272
  }
@@ -1,7 +1,8 @@
1
- import { kinds, nip57 } from "nostr-tools";
1
+ import { kinds, validateEvent } from "nostr-tools";
2
2
  import { parseBolt11 } from "./bolt11.js";
3
3
  import { getOrComputeCachedValue } from "./cache.js";
4
4
  import { getTagValue } from "./event-tags.js";
5
+ import { verifyWrappedEvent } from "./index.js";
5
6
  import { getAddressPointerFromATag, getEventPointerFromETag } from "./pointers.js";
6
7
  import { isATag, isETag } from "./tags.js";
7
8
  export const ZapRequestSymbol = Symbol.for("zap-request");
@@ -60,10 +61,30 @@ export function getZapRequest(zap) {
60
61
  return;
61
62
  // Attempt to parse the zap request
62
63
  try {
63
- const error = nip57.validateZapRequest(description);
64
- if (error)
65
- return;
66
- return JSON.parse(description);
64
+ // Copied from nostr-tools/nip57 and modified to use the internal verifyZap method and return the zap request event
65
+ let zapRequest;
66
+ try {
67
+ zapRequest = JSON.parse(description);
68
+ }
69
+ catch (err) {
70
+ throw new Error("Invalid zap request JSON.");
71
+ }
72
+ if (!validateEvent(zapRequest))
73
+ throw new Error("Zap request is not a valid Nostr event.");
74
+ if (!verifyWrappedEvent(zapRequest))
75
+ throw new Error("Invalid signature on zap request.");
76
+ let p = zapRequest.tags.find(([t, v]) => t === "p" && v);
77
+ if (!p)
78
+ throw new Error("Zap request doesn't have a 'p' tag.");
79
+ if (!p[1].match(/^[a-f0-9]{64}$/))
80
+ throw new Error("Zap request 'p' tag is not valid hex.");
81
+ let e = zapRequest.tags.find(([t, v]) => t === "e" && v);
82
+ if (e && !e[1].match(/^[a-f0-9]{64}$/))
83
+ throw new Error("Zap request 'e' tag is not valid hex.");
84
+ let relays = zapRequest.tags.find(([t, v]) => t === "relays" && v);
85
+ if (!relays)
86
+ throw new Error("Zap request doesn't have a 'relays' tag.");
87
+ return zapRequest;
67
88
  }
68
89
  catch (error) {
69
90
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-core",
3
- "version": "4.4.0",
3
+ "version": "4.4.2",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",