nostr-tools 1.14.0 → 1.14.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.
package/lib/esm/nostr.mjs CHANGED
@@ -211,6 +211,7 @@ var Kind = /* @__PURE__ */ ((Kind3) => {
211
211
  Kind3[Kind3["ProfileBadge"] = 30008] = "ProfileBadge";
212
212
  Kind3[Kind3["BadgeDefinition"] = 30009] = "BadgeDefinition";
213
213
  Kind3[Kind3["Article"] = 30023] = "Article";
214
+ Kind3[Kind3["FileMetadata"] = 1063] = "FileMetadata";
214
215
  return Kind3;
215
216
  })(Kind || {});
216
217
  function getBlankEvent(kind = 255 /* Blank */) {
@@ -656,8 +657,8 @@ function relayInit(url, options = {}) {
656
657
  listeners = newListeners();
657
658
  subListeners = {};
658
659
  pubListeners = {};
659
- if (ws.readyState === WebSocket.OPEN) {
660
- ws?.close();
660
+ if (ws?.readyState === WebSocket.OPEN) {
661
+ ws.close();
661
662
  }
662
663
  },
663
664
  get status() {
@@ -670,14 +671,17 @@ function relayInit(url, options = {}) {
670
671
  var SimplePool = class {
671
672
  _conn;
672
673
  _seenOn = {};
674
+ batchedByKey = {};
673
675
  eoseSubTimeout;
674
676
  getTimeout;
675
677
  seenOnEnabled = true;
678
+ batchInterval = 100;
676
679
  constructor(options = {}) {
677
680
  this._conn = {};
678
681
  this.eoseSubTimeout = options.eoseSubTimeout || 3400;
679
682
  this.getTimeout = options.getTimeout || 3400;
680
683
  this.seenOnEnabled = options.seenOnEnabled !== false;
684
+ this.batchInterval = options.batchInterval || 100;
681
685
  }
682
686
  close(relays) {
683
687
  relays.forEach((url) => {
@@ -722,7 +726,7 @@ var SimplePool = class {
722
726
  for (let cb of eoseListeners.values())
723
727
  cb();
724
728
  }, this.eoseSubTimeout);
725
- relays.forEach(async (relay) => {
729
+ relays.filter((r, i, a) => a.indexOf(r) == i).forEach(async (relay) => {
726
730
  let r;
727
731
  try {
728
732
  r = await this.ensureRelay(relay);
@@ -804,6 +808,49 @@ var SimplePool = class {
804
808
  });
805
809
  });
806
810
  }
811
+ batchedList(batchKey, relays, filters) {
812
+ return new Promise((resolve) => {
813
+ if (!this.batchedByKey[batchKey]) {
814
+ this.batchedByKey[batchKey] = [
815
+ {
816
+ filters,
817
+ relays,
818
+ resolve,
819
+ events: []
820
+ }
821
+ ];
822
+ setTimeout(() => {
823
+ Object.keys(this.batchedByKey).forEach(async (batchKey2) => {
824
+ const batchedRequests = this.batchedByKey[batchKey2];
825
+ const filters2 = [];
826
+ const relays2 = [];
827
+ batchedRequests.forEach((br) => {
828
+ filters2.push(...br.filters);
829
+ relays2.push(...br.relays);
830
+ });
831
+ const sub = this.sub(relays2, filters2);
832
+ sub.on("event", (event) => {
833
+ batchedRequests.forEach(
834
+ (br) => matchFilters(br.filters, event) && br.events.push(event)
835
+ );
836
+ });
837
+ sub.on("eose", () => {
838
+ sub.unsub();
839
+ batchedRequests.forEach((br) => br.resolve(br.events));
840
+ });
841
+ delete this.batchedByKey[batchKey2];
842
+ });
843
+ }, this.batchInterval);
844
+ } else {
845
+ this.batchedByKey[batchKey].push({
846
+ filters,
847
+ relays,
848
+ resolve,
849
+ events: []
850
+ });
851
+ }
852
+ });
853
+ }
807
854
  publish(relays, event) {
808
855
  return relays.map(async (relay) => {
809
856
  let r = await this.ensureRelay(relay);
@@ -1684,6 +1731,43 @@ var authenticate = async ({
1684
1731
  return relay.auth(await sign(e));
1685
1732
  };
1686
1733
 
1734
+ // nip44.ts
1735
+ var nip44_exports = {};
1736
+ __export(nip44_exports, {
1737
+ decrypt: () => decrypt2,
1738
+ encrypt: () => encrypt2,
1739
+ getSharedSecret: () => getSharedSecret
1740
+ });
1741
+ import { base64 as base642 } from "@scure/base";
1742
+ import { randomBytes as randomBytes2 } from "@noble/hashes/utils";
1743
+ import { secp256k1 as secp256k12 } from "@noble/curves/secp256k1";
1744
+ import { sha256 as sha2563 } from "@noble/hashes/sha256";
1745
+ import { xchacha20 } from "@noble/ciphers/chacha";
1746
+ var getSharedSecret = (privkey, pubkey) => sha2563(secp256k12.getSharedSecret(privkey, "02" + pubkey).subarray(1, 33));
1747
+ function encrypt2(key, text, v = 1) {
1748
+ if (v !== 1) {
1749
+ throw new Error("NIP44: unknown encryption version");
1750
+ }
1751
+ const nonce = randomBytes2(24);
1752
+ const plaintext = utf8Encoder.encode(text);
1753
+ const ciphertext = xchacha20(key, nonce, plaintext);
1754
+ const payload = new Uint8Array(25 + ciphertext.length);
1755
+ payload.set([v], 0);
1756
+ payload.set(nonce, 1);
1757
+ payload.set(ciphertext, 25);
1758
+ return base642.encode(payload);
1759
+ }
1760
+ function decrypt2(key, payload) {
1761
+ let data = base642.decode(payload);
1762
+ if (data[0] !== 1) {
1763
+ throw new Error(`NIP44: unknown encryption version: ${data[0]}`);
1764
+ }
1765
+ const nonce = data.slice(1, 25);
1766
+ const ciphertext = data.slice(25);
1767
+ const plaintext = xchacha20(key, nonce, ciphertext);
1768
+ return utf8Decoder.decode(plaintext);
1769
+ }
1770
+
1687
1771
  // nip57.ts
1688
1772
  var nip57_exports = {};
1689
1773
  __export(nip57_exports, {
@@ -1805,15 +1889,15 @@ function makeZapReceipt({
1805
1889
  var nip98_exports = {};
1806
1890
  __export(nip98_exports, {
1807
1891
  getToken: () => getToken,
1892
+ unpackEventFromToken: () => unpackEventFromToken,
1893
+ validateEvent: () => validateEvent2,
1808
1894
  validateToken: () => validateToken
1809
1895
  });
1810
- import { base64 as base642 } from "@scure/base";
1896
+ import { base64 as base643 } from "@scure/base";
1811
1897
  var _authorizationScheme = "Nostr ";
1812
1898
  async function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme = false) {
1813
1899
  if (!loginUrl || !httpMethod)
1814
1900
  throw new Error("Missing loginUrl or httpMethod");
1815
- if (httpMethod !== "get" /* Get */ && httpMethod !== "post" /* Post */)
1816
- throw new Error("Unknown httpMethod");
1817
1901
  const event = getBlankEvent(27235 /* HttpAuth */);
1818
1902
  event.tags = [
1819
1903
  ["u", loginUrl],
@@ -1822,18 +1906,30 @@ async function getToken(loginUrl, httpMethod, sign, includeAuthorizationScheme =
1822
1906
  event.created_at = Math.round(new Date().getTime() / 1e3);
1823
1907
  const signedEvent = await sign(event);
1824
1908
  const authorizationScheme = includeAuthorizationScheme ? _authorizationScheme : "";
1825
- return authorizationScheme + base642.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
1909
+ return authorizationScheme + base643.encode(utf8Encoder.encode(JSON.stringify(signedEvent)));
1826
1910
  }
1827
1911
  async function validateToken(token, url, method) {
1912
+ const event = await unpackEventFromToken(token).catch((error) => {
1913
+ throw error;
1914
+ });
1915
+ const valid = await validateEvent2(event, url, method).catch((error) => {
1916
+ throw error;
1917
+ });
1918
+ return valid;
1919
+ }
1920
+ async function unpackEventFromToken(token) {
1828
1921
  if (!token) {
1829
1922
  throw new Error("Missing token");
1830
1923
  }
1831
1924
  token = token.replace(_authorizationScheme, "");
1832
- const eventB64 = utf8Decoder.decode(base642.decode(token));
1925
+ const eventB64 = utf8Decoder.decode(base643.decode(token));
1833
1926
  if (!eventB64 || eventB64.length === 0 || !eventB64.startsWith("{")) {
1834
1927
  throw new Error("Invalid token");
1835
1928
  }
1836
1929
  const event = JSON.parse(eventB64);
1930
+ return event;
1931
+ }
1932
+ async function validateEvent2(event, url, method) {
1837
1933
  if (!event) {
1838
1934
  throw new Error("Invalid nostr event");
1839
1935
  }
@@ -1886,6 +1982,7 @@ export {
1886
1982
  nip28_exports as nip28,
1887
1983
  nip39_exports as nip39,
1888
1984
  nip42_exports as nip42,
1985
+ nip44_exports as nip44,
1889
1986
  nip57_exports as nip57,
1890
1987
  nip98_exports as nip98,
1891
1988
  parseReferences,