nostr-tools 1.7.5 → 1.8.0
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/README.md +20 -0
- package/lib/esm/nostr.mjs +241 -147
- package/lib/esm/nostr.mjs.map +3 -3
- package/lib/index.d.ts +1 -0
- package/lib/nip19.d.ts +1 -0
- package/lib/nostr.bundle.js +249 -152
- package/lib/nostr.bundle.js.map +4 -4
- package/lib/nostr.cjs.js +248 -154
- package/lib/nostr.cjs.js.map +4 -4
- package/lib/references.d.ts +10 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -170,6 +170,26 @@ let relaysForEvent = pool.seenOn(
|
|
|
170
170
|
// relaysForEvent will be an array of URLs from relays a given event was seen on
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
+
### Parsing references (mentions) from a content using NIP-10 and NIP-27
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
import {parseReferences} from 'nostr-tools'
|
|
177
|
+
|
|
178
|
+
let references = parseReferences(event)
|
|
179
|
+
let simpleAugmentedContent = event.content
|
|
180
|
+
for (let i = 0; i < references.length; i++) {
|
|
181
|
+
let {text, profile, event, address} = references[i]
|
|
182
|
+
let augmentedReference = profile
|
|
183
|
+
? `<strong>@${profilesCache[profile.pubkey].name}</strong>`
|
|
184
|
+
: event
|
|
185
|
+
? `<em>${eventsCache[event.id].content.slice(0, 5)}</em>`
|
|
186
|
+
: address
|
|
187
|
+
? `<a href="${text}">[link]</a>`
|
|
188
|
+
: text
|
|
189
|
+
simpleAugmentedContent.replaceAll(text, augmentedReference)
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
173
193
|
### Querying profile data from a NIP-05 address
|
|
174
194
|
|
|
175
195
|
```js
|
package/lib/esm/nostr.mjs
CHANGED
|
@@ -569,6 +569,7 @@ var SimplePool = class {
|
|
|
569
569
|
let set = this._seenOn[id] || /* @__PURE__ */ new Set();
|
|
570
570
|
set.add(url);
|
|
571
571
|
this._seenOn[id] = set;
|
|
572
|
+
_knownIds.add(id);
|
|
572
573
|
return _knownIds.has(id);
|
|
573
574
|
};
|
|
574
575
|
let subs = [];
|
|
@@ -593,7 +594,6 @@ var SimplePool = class {
|
|
|
593
594
|
return;
|
|
594
595
|
let s = r.sub(filters, modifiedOpts);
|
|
595
596
|
s.on("event", (event) => {
|
|
596
|
-
_knownIds.add(event.id);
|
|
597
597
|
for (let cb of eventListeners.values())
|
|
598
598
|
cb(event);
|
|
599
599
|
});
|
|
@@ -688,139 +688,6 @@ var SimplePool = class {
|
|
|
688
688
|
}
|
|
689
689
|
};
|
|
690
690
|
|
|
691
|
-
// nip04.ts
|
|
692
|
-
var nip04_exports = {};
|
|
693
|
-
__export(nip04_exports, {
|
|
694
|
-
decrypt: () => decrypt,
|
|
695
|
-
encrypt: () => encrypt
|
|
696
|
-
});
|
|
697
|
-
import { randomBytes } from "@noble/hashes/utils";
|
|
698
|
-
import * as secp256k13 from "@noble/secp256k1";
|
|
699
|
-
import { base64 } from "@scure/base";
|
|
700
|
-
async function encrypt(privkey, pubkey, text) {
|
|
701
|
-
const key = secp256k13.getSharedSecret(privkey, "02" + pubkey);
|
|
702
|
-
const normalizedKey = getNormalizedX(key);
|
|
703
|
-
let iv = Uint8Array.from(randomBytes(16));
|
|
704
|
-
let plaintext = utf8Encoder.encode(text);
|
|
705
|
-
let cryptoKey = await crypto.subtle.importKey(
|
|
706
|
-
"raw",
|
|
707
|
-
normalizedKey,
|
|
708
|
-
{ name: "AES-CBC" },
|
|
709
|
-
false,
|
|
710
|
-
["encrypt"]
|
|
711
|
-
);
|
|
712
|
-
let ciphertext = await crypto.subtle.encrypt(
|
|
713
|
-
{ name: "AES-CBC", iv },
|
|
714
|
-
cryptoKey,
|
|
715
|
-
plaintext
|
|
716
|
-
);
|
|
717
|
-
let ctb64 = base64.encode(new Uint8Array(ciphertext));
|
|
718
|
-
let ivb64 = base64.encode(new Uint8Array(iv.buffer));
|
|
719
|
-
return `${ctb64}?iv=${ivb64}`;
|
|
720
|
-
}
|
|
721
|
-
async function decrypt(privkey, pubkey, data) {
|
|
722
|
-
let [ctb64, ivb64] = data.split("?iv=");
|
|
723
|
-
let key = secp256k13.getSharedSecret(privkey, "02" + pubkey);
|
|
724
|
-
let normalizedKey = getNormalizedX(key);
|
|
725
|
-
let cryptoKey = await crypto.subtle.importKey(
|
|
726
|
-
"raw",
|
|
727
|
-
normalizedKey,
|
|
728
|
-
{ name: "AES-CBC" },
|
|
729
|
-
false,
|
|
730
|
-
["decrypt"]
|
|
731
|
-
);
|
|
732
|
-
let ciphertext = base64.decode(ctb64);
|
|
733
|
-
let iv = base64.decode(ivb64);
|
|
734
|
-
let plaintext = await crypto.subtle.decrypt(
|
|
735
|
-
{ name: "AES-CBC", iv },
|
|
736
|
-
cryptoKey,
|
|
737
|
-
ciphertext
|
|
738
|
-
);
|
|
739
|
-
let text = utf8Decoder.decode(plaintext);
|
|
740
|
-
return text;
|
|
741
|
-
}
|
|
742
|
-
function getNormalizedX(key) {
|
|
743
|
-
return key.slice(1, 33);
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
// nip05.ts
|
|
747
|
-
var nip05_exports = {};
|
|
748
|
-
__export(nip05_exports, {
|
|
749
|
-
queryProfile: () => queryProfile,
|
|
750
|
-
searchDomain: () => searchDomain,
|
|
751
|
-
useFetchImplementation: () => useFetchImplementation
|
|
752
|
-
});
|
|
753
|
-
var _fetch;
|
|
754
|
-
try {
|
|
755
|
-
_fetch = fetch;
|
|
756
|
-
} catch {
|
|
757
|
-
}
|
|
758
|
-
function useFetchImplementation(fetchImplementation) {
|
|
759
|
-
_fetch = fetchImplementation;
|
|
760
|
-
}
|
|
761
|
-
async function searchDomain(domain, query = "") {
|
|
762
|
-
try {
|
|
763
|
-
let res = await (await _fetch(`https://${domain}/.well-known/nostr.json?name=${query}`)).json();
|
|
764
|
-
return res.names;
|
|
765
|
-
} catch (_) {
|
|
766
|
-
return {};
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
async function queryProfile(fullname) {
|
|
770
|
-
let [name, domain] = fullname.split("@");
|
|
771
|
-
if (!domain) {
|
|
772
|
-
domain = name;
|
|
773
|
-
name = "_";
|
|
774
|
-
}
|
|
775
|
-
if (!name.match(/^[A-Za-z0-9-_]+$/))
|
|
776
|
-
return null;
|
|
777
|
-
if (!domain.includes("."))
|
|
778
|
-
return null;
|
|
779
|
-
let res;
|
|
780
|
-
try {
|
|
781
|
-
res = await (await _fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)).json();
|
|
782
|
-
} catch (err) {
|
|
783
|
-
return null;
|
|
784
|
-
}
|
|
785
|
-
if (!res?.names?.[name])
|
|
786
|
-
return null;
|
|
787
|
-
let pubkey = res.names[name];
|
|
788
|
-
let relays = res.relays?.[pubkey] || [];
|
|
789
|
-
return {
|
|
790
|
-
pubkey,
|
|
791
|
-
relays
|
|
792
|
-
};
|
|
793
|
-
}
|
|
794
|
-
|
|
795
|
-
// nip06.ts
|
|
796
|
-
var nip06_exports = {};
|
|
797
|
-
__export(nip06_exports, {
|
|
798
|
-
generateSeedWords: () => generateSeedWords,
|
|
799
|
-
privateKeyFromSeedWords: () => privateKeyFromSeedWords,
|
|
800
|
-
validateWords: () => validateWords
|
|
801
|
-
});
|
|
802
|
-
import * as secp256k14 from "@noble/secp256k1";
|
|
803
|
-
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
804
|
-
import {
|
|
805
|
-
generateMnemonic,
|
|
806
|
-
mnemonicToSeedSync,
|
|
807
|
-
validateMnemonic
|
|
808
|
-
} from "@scure/bip39";
|
|
809
|
-
import { HDKey } from "@scure/bip32";
|
|
810
|
-
function privateKeyFromSeedWords(mnemonic, passphrase) {
|
|
811
|
-
let root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic, passphrase));
|
|
812
|
-
let privateKey = root.derive(`m/44'/1237'/0'/0/0`).privateKey;
|
|
813
|
-
if (!privateKey)
|
|
814
|
-
throw new Error("could not derive private key");
|
|
815
|
-
return secp256k14.utils.bytesToHex(privateKey);
|
|
816
|
-
}
|
|
817
|
-
function generateSeedWords() {
|
|
818
|
-
return generateMnemonic(wordlist);
|
|
819
|
-
}
|
|
820
|
-
function validateWords(words) {
|
|
821
|
-
return validateMnemonic(words, wordlist);
|
|
822
|
-
}
|
|
823
|
-
|
|
824
691
|
// nip19.ts
|
|
825
692
|
var nip19_exports = {};
|
|
826
693
|
__export(nip19_exports, {
|
|
@@ -832,7 +699,7 @@ __export(nip19_exports, {
|
|
|
832
699
|
npubEncode: () => npubEncode,
|
|
833
700
|
nsecEncode: () => nsecEncode
|
|
834
701
|
});
|
|
835
|
-
import * as
|
|
702
|
+
import * as secp256k13 from "@noble/secp256k1";
|
|
836
703
|
import { bech32 } from "@scure/base";
|
|
837
704
|
var Bech32MaxSize = 5e3;
|
|
838
705
|
function decode(nip19) {
|
|
@@ -848,7 +715,7 @@ function decode(nip19) {
|
|
|
848
715
|
return {
|
|
849
716
|
type: "nprofile",
|
|
850
717
|
data: {
|
|
851
|
-
pubkey:
|
|
718
|
+
pubkey: secp256k13.utils.bytesToHex(tlv[0][0]),
|
|
852
719
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
|
853
720
|
}
|
|
854
721
|
};
|
|
@@ -859,11 +726,14 @@ function decode(nip19) {
|
|
|
859
726
|
throw new Error("missing TLV 0 for nevent");
|
|
860
727
|
if (tlv[0][0].length !== 32)
|
|
861
728
|
throw new Error("TLV 0 should be 32 bytes");
|
|
729
|
+
if (tlv[2] && tlv[2][0].length !== 32)
|
|
730
|
+
throw new Error("TLV 2 should be 32 bytes");
|
|
862
731
|
return {
|
|
863
732
|
type: "nevent",
|
|
864
733
|
data: {
|
|
865
|
-
id:
|
|
866
|
-
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
|
734
|
+
id: secp256k13.utils.bytesToHex(tlv[0][0]),
|
|
735
|
+
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
|
736
|
+
author: tlv[2]?.[0] ? secp256k13.utils.bytesToHex(tlv[2][0]) : void 0
|
|
867
737
|
}
|
|
868
738
|
};
|
|
869
739
|
}
|
|
@@ -883,8 +753,8 @@ function decode(nip19) {
|
|
|
883
753
|
type: "naddr",
|
|
884
754
|
data: {
|
|
885
755
|
identifier: utf8Decoder.decode(tlv[0][0]),
|
|
886
|
-
pubkey:
|
|
887
|
-
kind: parseInt(
|
|
756
|
+
pubkey: secp256k13.utils.bytesToHex(tlv[2][0]),
|
|
757
|
+
kind: parseInt(secp256k13.utils.bytesToHex(tlv[3][0]), 16),
|
|
888
758
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
|
889
759
|
}
|
|
890
760
|
};
|
|
@@ -892,7 +762,7 @@ function decode(nip19) {
|
|
|
892
762
|
case "nsec":
|
|
893
763
|
case "npub":
|
|
894
764
|
case "note":
|
|
895
|
-
return { type: prefix, data:
|
|
765
|
+
return { type: prefix, data: secp256k13.utils.bytesToHex(data) };
|
|
896
766
|
default:
|
|
897
767
|
throw new Error(`unknown prefix ${prefix}`);
|
|
898
768
|
}
|
|
@@ -922,13 +792,13 @@ function noteEncode(hex) {
|
|
|
922
792
|
return encodeBytes("note", hex);
|
|
923
793
|
}
|
|
924
794
|
function encodeBytes(prefix, hex) {
|
|
925
|
-
let data =
|
|
795
|
+
let data = secp256k13.utils.hexToBytes(hex);
|
|
926
796
|
let words = bech32.toWords(data);
|
|
927
797
|
return bech32.encode(prefix, words, Bech32MaxSize);
|
|
928
798
|
}
|
|
929
799
|
function nprofileEncode(profile) {
|
|
930
800
|
let data = encodeTLV({
|
|
931
|
-
0: [
|
|
801
|
+
0: [secp256k13.utils.hexToBytes(profile.pubkey)],
|
|
932
802
|
1: (profile.relays || []).map((url) => utf8Encoder.encode(url))
|
|
933
803
|
});
|
|
934
804
|
let words = bech32.toWords(data);
|
|
@@ -936,8 +806,9 @@ function nprofileEncode(profile) {
|
|
|
936
806
|
}
|
|
937
807
|
function neventEncode(event) {
|
|
938
808
|
let data = encodeTLV({
|
|
939
|
-
0: [
|
|
940
|
-
1: (event.relays || []).map((url) => utf8Encoder.encode(url))
|
|
809
|
+
0: [secp256k13.utils.hexToBytes(event.id)],
|
|
810
|
+
1: (event.relays || []).map((url) => utf8Encoder.encode(url)),
|
|
811
|
+
2: event.author ? [secp256k13.utils.hexToBytes(event.author)] : []
|
|
941
812
|
});
|
|
942
813
|
let words = bech32.toWords(data);
|
|
943
814
|
return bech32.encode("nevent", words, Bech32MaxSize);
|
|
@@ -948,7 +819,7 @@ function naddrEncode(addr) {
|
|
|
948
819
|
let data = encodeTLV({
|
|
949
820
|
0: [utf8Encoder.encode(addr.identifier)],
|
|
950
821
|
1: (addr.relays || []).map((url) => utf8Encoder.encode(url)),
|
|
951
|
-
2: [
|
|
822
|
+
2: [secp256k13.utils.hexToBytes(addr.pubkey)],
|
|
952
823
|
3: [new Uint8Array(kind)]
|
|
953
824
|
});
|
|
954
825
|
let words = bech32.toWords(data);
|
|
@@ -965,7 +836,229 @@ function encodeTLV(tlv) {
|
|
|
965
836
|
entries.push(entry);
|
|
966
837
|
});
|
|
967
838
|
});
|
|
968
|
-
return
|
|
839
|
+
return secp256k13.utils.concatBytes(...entries);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// references.ts
|
|
843
|
+
var mentionRegex = /\bnostr:((note|npub|naddr|nevent|nprofile)1\w+)\b|#\[(\d+)\]/g;
|
|
844
|
+
function parseReferences(evt) {
|
|
845
|
+
let references = [];
|
|
846
|
+
for (let ref of evt.content.matchAll(mentionRegex)) {
|
|
847
|
+
if (ref[2]) {
|
|
848
|
+
try {
|
|
849
|
+
let { type, data } = decode(ref[1]);
|
|
850
|
+
switch (type) {
|
|
851
|
+
case "npub": {
|
|
852
|
+
references.push({
|
|
853
|
+
text: ref[0],
|
|
854
|
+
profile: { pubkey: data, relays: [] }
|
|
855
|
+
});
|
|
856
|
+
break;
|
|
857
|
+
}
|
|
858
|
+
case "nprofile": {
|
|
859
|
+
references.push({
|
|
860
|
+
text: ref[0],
|
|
861
|
+
profile: data
|
|
862
|
+
});
|
|
863
|
+
break;
|
|
864
|
+
}
|
|
865
|
+
case "note": {
|
|
866
|
+
references.push({
|
|
867
|
+
text: ref[0],
|
|
868
|
+
event: { id: data, relays: [] }
|
|
869
|
+
});
|
|
870
|
+
break;
|
|
871
|
+
}
|
|
872
|
+
case "nevent": {
|
|
873
|
+
references.push({
|
|
874
|
+
text: ref[0],
|
|
875
|
+
event: data
|
|
876
|
+
});
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
879
|
+
case "naddr": {
|
|
880
|
+
references.push({
|
|
881
|
+
text: ref[0],
|
|
882
|
+
address: data
|
|
883
|
+
});
|
|
884
|
+
break;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
} catch (err) {
|
|
888
|
+
}
|
|
889
|
+
} else if (ref[3]) {
|
|
890
|
+
let idx = parseInt(ref[3], 10);
|
|
891
|
+
let tag = evt.tags[idx];
|
|
892
|
+
if (!tag)
|
|
893
|
+
continue;
|
|
894
|
+
switch (tag[0]) {
|
|
895
|
+
case "p": {
|
|
896
|
+
references.push({
|
|
897
|
+
text: ref[0],
|
|
898
|
+
profile: { pubkey: tag[1], relays: tag[2] ? [tag[2]] : [] }
|
|
899
|
+
});
|
|
900
|
+
break;
|
|
901
|
+
}
|
|
902
|
+
case "e": {
|
|
903
|
+
references.push({
|
|
904
|
+
text: ref[0],
|
|
905
|
+
event: { id: tag[1], relays: tag[2] ? [tag[2]] : [] }
|
|
906
|
+
});
|
|
907
|
+
break;
|
|
908
|
+
}
|
|
909
|
+
case "a": {
|
|
910
|
+
try {
|
|
911
|
+
let [kind, pubkey, identifier] = ref[1].split(":");
|
|
912
|
+
references.push({
|
|
913
|
+
text: ref[0],
|
|
914
|
+
address: {
|
|
915
|
+
identifier,
|
|
916
|
+
pubkey,
|
|
917
|
+
kind: parseInt(kind, 10),
|
|
918
|
+
relays: tag[2] ? [tag[2]] : []
|
|
919
|
+
}
|
|
920
|
+
});
|
|
921
|
+
} catch (err) {
|
|
922
|
+
}
|
|
923
|
+
break;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return references;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// nip04.ts
|
|
932
|
+
var nip04_exports = {};
|
|
933
|
+
__export(nip04_exports, {
|
|
934
|
+
decrypt: () => decrypt,
|
|
935
|
+
encrypt: () => encrypt
|
|
936
|
+
});
|
|
937
|
+
import { randomBytes } from "@noble/hashes/utils";
|
|
938
|
+
import * as secp256k14 from "@noble/secp256k1";
|
|
939
|
+
import { base64 } from "@scure/base";
|
|
940
|
+
async function encrypt(privkey, pubkey, text) {
|
|
941
|
+
const key = secp256k14.getSharedSecret(privkey, "02" + pubkey);
|
|
942
|
+
const normalizedKey = getNormalizedX(key);
|
|
943
|
+
let iv = Uint8Array.from(randomBytes(16));
|
|
944
|
+
let plaintext = utf8Encoder.encode(text);
|
|
945
|
+
let cryptoKey = await crypto.subtle.importKey(
|
|
946
|
+
"raw",
|
|
947
|
+
normalizedKey,
|
|
948
|
+
{ name: "AES-CBC" },
|
|
949
|
+
false,
|
|
950
|
+
["encrypt"]
|
|
951
|
+
);
|
|
952
|
+
let ciphertext = await crypto.subtle.encrypt(
|
|
953
|
+
{ name: "AES-CBC", iv },
|
|
954
|
+
cryptoKey,
|
|
955
|
+
plaintext
|
|
956
|
+
);
|
|
957
|
+
let ctb64 = base64.encode(new Uint8Array(ciphertext));
|
|
958
|
+
let ivb64 = base64.encode(new Uint8Array(iv.buffer));
|
|
959
|
+
return `${ctb64}?iv=${ivb64}`;
|
|
960
|
+
}
|
|
961
|
+
async function decrypt(privkey, pubkey, data) {
|
|
962
|
+
let [ctb64, ivb64] = data.split("?iv=");
|
|
963
|
+
let key = secp256k14.getSharedSecret(privkey, "02" + pubkey);
|
|
964
|
+
let normalizedKey = getNormalizedX(key);
|
|
965
|
+
let cryptoKey = await crypto.subtle.importKey(
|
|
966
|
+
"raw",
|
|
967
|
+
normalizedKey,
|
|
968
|
+
{ name: "AES-CBC" },
|
|
969
|
+
false,
|
|
970
|
+
["decrypt"]
|
|
971
|
+
);
|
|
972
|
+
let ciphertext = base64.decode(ctb64);
|
|
973
|
+
let iv = base64.decode(ivb64);
|
|
974
|
+
let plaintext = await crypto.subtle.decrypt(
|
|
975
|
+
{ name: "AES-CBC", iv },
|
|
976
|
+
cryptoKey,
|
|
977
|
+
ciphertext
|
|
978
|
+
);
|
|
979
|
+
let text = utf8Decoder.decode(plaintext);
|
|
980
|
+
return text;
|
|
981
|
+
}
|
|
982
|
+
function getNormalizedX(key) {
|
|
983
|
+
return key.slice(1, 33);
|
|
984
|
+
}
|
|
985
|
+
|
|
986
|
+
// nip05.ts
|
|
987
|
+
var nip05_exports = {};
|
|
988
|
+
__export(nip05_exports, {
|
|
989
|
+
queryProfile: () => queryProfile,
|
|
990
|
+
searchDomain: () => searchDomain,
|
|
991
|
+
useFetchImplementation: () => useFetchImplementation
|
|
992
|
+
});
|
|
993
|
+
var _fetch;
|
|
994
|
+
try {
|
|
995
|
+
_fetch = fetch;
|
|
996
|
+
} catch {
|
|
997
|
+
}
|
|
998
|
+
function useFetchImplementation(fetchImplementation) {
|
|
999
|
+
_fetch = fetchImplementation;
|
|
1000
|
+
}
|
|
1001
|
+
async function searchDomain(domain, query = "") {
|
|
1002
|
+
try {
|
|
1003
|
+
let res = await (await _fetch(`https://${domain}/.well-known/nostr.json?name=${query}`)).json();
|
|
1004
|
+
return res.names;
|
|
1005
|
+
} catch (_) {
|
|
1006
|
+
return {};
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
async function queryProfile(fullname) {
|
|
1010
|
+
let [name, domain] = fullname.split("@");
|
|
1011
|
+
if (!domain) {
|
|
1012
|
+
domain = name;
|
|
1013
|
+
name = "_";
|
|
1014
|
+
}
|
|
1015
|
+
if (!name.match(/^[A-Za-z0-9-_]+$/))
|
|
1016
|
+
return null;
|
|
1017
|
+
if (!domain.includes("."))
|
|
1018
|
+
return null;
|
|
1019
|
+
let res;
|
|
1020
|
+
try {
|
|
1021
|
+
res = await (await _fetch(`https://${domain}/.well-known/nostr.json?name=${name}`)).json();
|
|
1022
|
+
} catch (err) {
|
|
1023
|
+
return null;
|
|
1024
|
+
}
|
|
1025
|
+
if (!res?.names?.[name])
|
|
1026
|
+
return null;
|
|
1027
|
+
let pubkey = res.names[name];
|
|
1028
|
+
let relays = res.relays?.[pubkey] || [];
|
|
1029
|
+
return {
|
|
1030
|
+
pubkey,
|
|
1031
|
+
relays
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
// nip06.ts
|
|
1036
|
+
var nip06_exports = {};
|
|
1037
|
+
__export(nip06_exports, {
|
|
1038
|
+
generateSeedWords: () => generateSeedWords,
|
|
1039
|
+
privateKeyFromSeedWords: () => privateKeyFromSeedWords,
|
|
1040
|
+
validateWords: () => validateWords
|
|
1041
|
+
});
|
|
1042
|
+
import * as secp256k15 from "@noble/secp256k1";
|
|
1043
|
+
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
1044
|
+
import {
|
|
1045
|
+
generateMnemonic,
|
|
1046
|
+
mnemonicToSeedSync,
|
|
1047
|
+
validateMnemonic
|
|
1048
|
+
} from "@scure/bip39";
|
|
1049
|
+
import { HDKey } from "@scure/bip32";
|
|
1050
|
+
function privateKeyFromSeedWords(mnemonic, passphrase) {
|
|
1051
|
+
let root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic, passphrase));
|
|
1052
|
+
let privateKey = root.derive(`m/44'/1237'/0'/0/0`).privateKey;
|
|
1053
|
+
if (!privateKey)
|
|
1054
|
+
throw new Error("could not derive private key");
|
|
1055
|
+
return secp256k15.utils.bytesToHex(privateKey);
|
|
1056
|
+
}
|
|
1057
|
+
function generateSeedWords() {
|
|
1058
|
+
return generateMnemonic(wordlist);
|
|
1059
|
+
}
|
|
1060
|
+
function validateWords(words) {
|
|
1061
|
+
return validateMnemonic(words, wordlist);
|
|
969
1062
|
}
|
|
970
1063
|
|
|
971
1064
|
// nip26.ts
|
|
@@ -1191,6 +1284,7 @@ export {
|
|
|
1191
1284
|
nip26_exports as nip26,
|
|
1192
1285
|
nip39_exports as nip39,
|
|
1193
1286
|
nip57_exports as nip57,
|
|
1287
|
+
parseReferences,
|
|
1194
1288
|
relayInit,
|
|
1195
1289
|
serializeEvent,
|
|
1196
1290
|
signEvent,
|