nostr-tools 1.8.3 → 1.9.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/lib/esm/nostr.mjs +88 -39
- package/lib/esm/nostr.mjs.map +4 -4
- package/lib/event.d.ts +3 -0
- package/lib/index.d.ts +1 -0
- package/lib/nip13.d.ts +2 -0
- package/lib/nip19.d.ts +1 -0
- package/lib/nostr.bundle.js +2097 -1473
- package/lib/nostr.bundle.js.map +4 -4
- package/lib/nostr.cjs.js +90 -47
- package/lib/nostr.cjs.js.map +4 -4
- package/package.json +5 -5
package/lib/esm/nostr.mjs
CHANGED
|
@@ -5,17 +5,19 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// keys.ts
|
|
8
|
-
import
|
|
8
|
+
import { schnorr } from "@noble/curves/secp256k1";
|
|
9
|
+
import { bytesToHex } from "@noble/hashes/utils";
|
|
9
10
|
function generatePrivateKey() {
|
|
10
|
-
return
|
|
11
|
+
return bytesToHex(schnorr.utils.randomPrivateKey());
|
|
11
12
|
}
|
|
12
13
|
function getPublicKey(privateKey) {
|
|
13
|
-
return
|
|
14
|
+
return bytesToHex(schnorr.getPublicKey(privateKey));
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
// event.ts
|
|
17
|
-
import
|
|
18
|
+
import { schnorr as schnorr2 } from "@noble/curves/secp256k1";
|
|
18
19
|
import { sha256 } from "@noble/hashes/sha256";
|
|
20
|
+
import { bytesToHex as bytesToHex2 } from "@noble/hashes/utils";
|
|
19
21
|
|
|
20
22
|
// utils.ts
|
|
21
23
|
var utils_exports = {};
|
|
@@ -121,6 +123,7 @@ var Kind = /* @__PURE__ */ ((Kind2) => {
|
|
|
121
123
|
Kind2[Kind2["EncryptedDirectMessage"] = 4] = "EncryptedDirectMessage";
|
|
122
124
|
Kind2[Kind2["EventDeletion"] = 5] = "EventDeletion";
|
|
123
125
|
Kind2[Kind2["Reaction"] = 7] = "Reaction";
|
|
126
|
+
Kind2[Kind2["BadgeAward"] = 8] = "BadgeAward";
|
|
124
127
|
Kind2[Kind2["ChannelCreation"] = 40] = "ChannelCreation";
|
|
125
128
|
Kind2[Kind2["ChannelMetadata"] = 41] = "ChannelMetadata";
|
|
126
129
|
Kind2[Kind2["ChannelMessage"] = 42] = "ChannelMessage";
|
|
@@ -131,6 +134,8 @@ var Kind = /* @__PURE__ */ ((Kind2) => {
|
|
|
131
134
|
Kind2[Kind2["Zap"] = 9735] = "Zap";
|
|
132
135
|
Kind2[Kind2["RelayList"] = 10002] = "RelayList";
|
|
133
136
|
Kind2[Kind2["ClientAuth"] = 22242] = "ClientAuth";
|
|
137
|
+
Kind2[Kind2["BadgeDefinition"] = 30008] = "BadgeDefinition";
|
|
138
|
+
Kind2[Kind2["ProfileBadge"] = 30009] = "ProfileBadge";
|
|
134
139
|
Kind2[Kind2["Article"] = 30023] = "Article";
|
|
135
140
|
return Kind2;
|
|
136
141
|
})(Kind || {});
|
|
@@ -163,10 +168,11 @@ function serializeEvent(evt) {
|
|
|
163
168
|
}
|
|
164
169
|
function getEventHash(event) {
|
|
165
170
|
let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));
|
|
166
|
-
return
|
|
171
|
+
return bytesToHex2(eventHash);
|
|
167
172
|
}
|
|
173
|
+
var isRecord = (obj) => obj instanceof Object;
|
|
168
174
|
function validateEvent(event) {
|
|
169
|
-
if (
|
|
175
|
+
if (!isRecord(event))
|
|
170
176
|
return false;
|
|
171
177
|
if (typeof event.kind !== "number")
|
|
172
178
|
return false;
|
|
@@ -192,15 +198,15 @@ function validateEvent(event) {
|
|
|
192
198
|
return true;
|
|
193
199
|
}
|
|
194
200
|
function verifySignature(event) {
|
|
195
|
-
return
|
|
201
|
+
return schnorr2.verify(
|
|
196
202
|
event.sig,
|
|
197
203
|
getEventHash(event),
|
|
198
204
|
event.pubkey
|
|
199
205
|
);
|
|
200
206
|
}
|
|
201
207
|
function signEvent(event, key) {
|
|
202
|
-
return
|
|
203
|
-
|
|
208
|
+
return bytesToHex2(
|
|
209
|
+
schnorr2.sign(getEventHash(event), key)
|
|
204
210
|
);
|
|
205
211
|
}
|
|
206
212
|
|
|
@@ -717,9 +723,10 @@ __export(nip19_exports, {
|
|
|
717
723
|
noteEncode: () => noteEncode,
|
|
718
724
|
nprofileEncode: () => nprofileEncode,
|
|
719
725
|
npubEncode: () => npubEncode,
|
|
726
|
+
nrelayEncode: () => nrelayEncode,
|
|
720
727
|
nsecEncode: () => nsecEncode
|
|
721
728
|
});
|
|
722
|
-
import
|
|
729
|
+
import { bytesToHex as bytesToHex3, concatBytes, hexToBytes } from "@noble/hashes/utils";
|
|
723
730
|
import { bech32 } from "@scure/base";
|
|
724
731
|
var Bech32MaxSize = 5e3;
|
|
725
732
|
function decode(nip19) {
|
|
@@ -735,7 +742,7 @@ function decode(nip19) {
|
|
|
735
742
|
return {
|
|
736
743
|
type: "nprofile",
|
|
737
744
|
data: {
|
|
738
|
-
pubkey:
|
|
745
|
+
pubkey: bytesToHex3(tlv[0][0]),
|
|
739
746
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
|
740
747
|
}
|
|
741
748
|
};
|
|
@@ -751,9 +758,9 @@ function decode(nip19) {
|
|
|
751
758
|
return {
|
|
752
759
|
type: "nevent",
|
|
753
760
|
data: {
|
|
754
|
-
id:
|
|
761
|
+
id: bytesToHex3(tlv[0][0]),
|
|
755
762
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
|
|
756
|
-
author: tlv[2]?.[0] ?
|
|
763
|
+
author: tlv[2]?.[0] ? bytesToHex3(tlv[2][0]) : void 0
|
|
757
764
|
}
|
|
758
765
|
};
|
|
759
766
|
}
|
|
@@ -773,16 +780,25 @@ function decode(nip19) {
|
|
|
773
780
|
type: "naddr",
|
|
774
781
|
data: {
|
|
775
782
|
identifier: utf8Decoder.decode(tlv[0][0]),
|
|
776
|
-
pubkey:
|
|
777
|
-
kind: parseInt(
|
|
783
|
+
pubkey: bytesToHex3(tlv[2][0]),
|
|
784
|
+
kind: parseInt(bytesToHex3(tlv[3][0]), 16),
|
|
778
785
|
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
|
|
779
786
|
}
|
|
780
787
|
};
|
|
781
788
|
}
|
|
789
|
+
case "nrelay": {
|
|
790
|
+
let tlv = parseTLV(data);
|
|
791
|
+
if (!tlv[0]?.[0])
|
|
792
|
+
throw new Error("missing TLV 0 for nrelay");
|
|
793
|
+
return {
|
|
794
|
+
type: "nrelay",
|
|
795
|
+
data: utf8Decoder.decode(tlv[0][0])
|
|
796
|
+
};
|
|
797
|
+
}
|
|
782
798
|
case "nsec":
|
|
783
799
|
case "npub":
|
|
784
800
|
case "note":
|
|
785
|
-
return { type: prefix, data:
|
|
801
|
+
return { type: prefix, data: bytesToHex3(data) };
|
|
786
802
|
default:
|
|
787
803
|
throw new Error(`unknown prefix ${prefix}`);
|
|
788
804
|
}
|
|
@@ -812,13 +828,13 @@ function noteEncode(hex) {
|
|
|
812
828
|
return encodeBytes("note", hex);
|
|
813
829
|
}
|
|
814
830
|
function encodeBytes(prefix, hex) {
|
|
815
|
-
let data =
|
|
831
|
+
let data = hexToBytes(hex);
|
|
816
832
|
let words = bech32.toWords(data);
|
|
817
833
|
return bech32.encode(prefix, words, Bech32MaxSize);
|
|
818
834
|
}
|
|
819
835
|
function nprofileEncode(profile) {
|
|
820
836
|
let data = encodeTLV({
|
|
821
|
-
0: [
|
|
837
|
+
0: [hexToBytes(profile.pubkey)],
|
|
822
838
|
1: (profile.relays || []).map((url) => utf8Encoder.encode(url))
|
|
823
839
|
});
|
|
824
840
|
let words = bech32.toWords(data);
|
|
@@ -826,9 +842,9 @@ function nprofileEncode(profile) {
|
|
|
826
842
|
}
|
|
827
843
|
function neventEncode(event) {
|
|
828
844
|
let data = encodeTLV({
|
|
829
|
-
0: [
|
|
845
|
+
0: [hexToBytes(event.id)],
|
|
830
846
|
1: (event.relays || []).map((url) => utf8Encoder.encode(url)),
|
|
831
|
-
2: event.author ? [
|
|
847
|
+
2: event.author ? [hexToBytes(event.author)] : []
|
|
832
848
|
});
|
|
833
849
|
let words = bech32.toWords(data);
|
|
834
850
|
return bech32.encode("nevent", words, Bech32MaxSize);
|
|
@@ -839,12 +855,19 @@ function naddrEncode(addr) {
|
|
|
839
855
|
let data = encodeTLV({
|
|
840
856
|
0: [utf8Encoder.encode(addr.identifier)],
|
|
841
857
|
1: (addr.relays || []).map((url) => utf8Encoder.encode(url)),
|
|
842
|
-
2: [
|
|
858
|
+
2: [hexToBytes(addr.pubkey)],
|
|
843
859
|
3: [new Uint8Array(kind)]
|
|
844
860
|
});
|
|
845
861
|
let words = bech32.toWords(data);
|
|
846
862
|
return bech32.encode("naddr", words, Bech32MaxSize);
|
|
847
863
|
}
|
|
864
|
+
function nrelayEncode(url) {
|
|
865
|
+
let data = encodeTLV({
|
|
866
|
+
0: [utf8Encoder.encode(url)]
|
|
867
|
+
});
|
|
868
|
+
let words = bech32.toWords(data);
|
|
869
|
+
return bech32.encode("nrelay", words, Bech32MaxSize);
|
|
870
|
+
}
|
|
848
871
|
function encodeTLV(tlv) {
|
|
849
872
|
let entries = [];
|
|
850
873
|
Object.entries(tlv).forEach(([t, vs]) => {
|
|
@@ -856,7 +879,7 @@ function encodeTLV(tlv) {
|
|
|
856
879
|
entries.push(entry);
|
|
857
880
|
});
|
|
858
881
|
});
|
|
859
|
-
return
|
|
882
|
+
return concatBytes(...entries);
|
|
860
883
|
}
|
|
861
884
|
|
|
862
885
|
// references.ts
|
|
@@ -955,10 +978,10 @@ __export(nip04_exports, {
|
|
|
955
978
|
encrypt: () => encrypt
|
|
956
979
|
});
|
|
957
980
|
import { randomBytes } from "@noble/hashes/utils";
|
|
958
|
-
import
|
|
981
|
+
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
959
982
|
import { base64 } from "@scure/base";
|
|
960
983
|
async function encrypt(privkey, pubkey, text) {
|
|
961
|
-
const key =
|
|
984
|
+
const key = secp256k1.getSharedSecret(privkey, "02" + pubkey);
|
|
962
985
|
const normalizedKey = getNormalizedX(key);
|
|
963
986
|
let iv = Uint8Array.from(randomBytes(16));
|
|
964
987
|
let plaintext = utf8Encoder.encode(text);
|
|
@@ -980,7 +1003,7 @@ async function encrypt(privkey, pubkey, text) {
|
|
|
980
1003
|
}
|
|
981
1004
|
async function decrypt(privkey, pubkey, data) {
|
|
982
1005
|
let [ctb64, ivb64] = data.split("?iv=");
|
|
983
|
-
let key =
|
|
1006
|
+
let key = secp256k1.getSharedSecret(privkey, "02" + pubkey);
|
|
984
1007
|
let normalizedKey = getNormalizedX(key);
|
|
985
1008
|
let cryptoKey = await crypto.subtle.importKey(
|
|
986
1009
|
"raw",
|
|
@@ -1032,7 +1055,7 @@ async function queryProfile(fullname) {
|
|
|
1032
1055
|
domain = name;
|
|
1033
1056
|
name = "_";
|
|
1034
1057
|
}
|
|
1035
|
-
if (!name.match(/^[A-Za-z0-9-_]+$/))
|
|
1058
|
+
if (!name.match(/^[A-Za-z0-9-_.]+$/))
|
|
1036
1059
|
return null;
|
|
1037
1060
|
if (!domain.includes("."))
|
|
1038
1061
|
return null;
|
|
@@ -1059,7 +1082,7 @@ __export(nip06_exports, {
|
|
|
1059
1082
|
privateKeyFromSeedWords: () => privateKeyFromSeedWords,
|
|
1060
1083
|
validateWords: () => validateWords
|
|
1061
1084
|
});
|
|
1062
|
-
import
|
|
1085
|
+
import { bytesToHex as bytesToHex4 } from "@noble/hashes/utils";
|
|
1063
1086
|
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
1064
1087
|
import {
|
|
1065
1088
|
generateMnemonic,
|
|
@@ -1072,7 +1095,7 @@ function privateKeyFromSeedWords(mnemonic, passphrase) {
|
|
|
1072
1095
|
let privateKey = root.derive(`m/44'/1237'/0'/0/0`).privateKey;
|
|
1073
1096
|
if (!privateKey)
|
|
1074
1097
|
throw new Error("could not derive private key");
|
|
1075
|
-
return
|
|
1098
|
+
return bytesToHex4(privateKey);
|
|
1076
1099
|
}
|
|
1077
1100
|
function generateSeedWords() {
|
|
1078
1101
|
return generateMnemonic(wordlist);
|
|
@@ -1139,13 +1162,45 @@ function parse(event) {
|
|
|
1139
1162
|
return result;
|
|
1140
1163
|
}
|
|
1141
1164
|
|
|
1165
|
+
// nip13.ts
|
|
1166
|
+
var nip13_exports = {};
|
|
1167
|
+
__export(nip13_exports, {
|
|
1168
|
+
getPow: () => getPow
|
|
1169
|
+
});
|
|
1170
|
+
import { hexToBytes as hexToBytes2 } from "@noble/hashes/utils";
|
|
1171
|
+
function getPow(id) {
|
|
1172
|
+
return getLeadingZeroBits(hexToBytes2(id));
|
|
1173
|
+
}
|
|
1174
|
+
function getLeadingZeroBits(hash) {
|
|
1175
|
+
let total, i, bits;
|
|
1176
|
+
for (i = 0, total = 0; i < hash.length; i++) {
|
|
1177
|
+
bits = msb(hash[i]);
|
|
1178
|
+
total += bits;
|
|
1179
|
+
if (bits !== 8) {
|
|
1180
|
+
break;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
return total;
|
|
1184
|
+
}
|
|
1185
|
+
function msb(b) {
|
|
1186
|
+
let n = 0;
|
|
1187
|
+
if (b === 0) {
|
|
1188
|
+
return 8;
|
|
1189
|
+
}
|
|
1190
|
+
while (b >>= 1) {
|
|
1191
|
+
n++;
|
|
1192
|
+
}
|
|
1193
|
+
return 7 - n;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1142
1196
|
// nip26.ts
|
|
1143
1197
|
var nip26_exports = {};
|
|
1144
1198
|
__export(nip26_exports, {
|
|
1145
1199
|
createDelegation: () => createDelegation,
|
|
1146
1200
|
getDelegator: () => getDelegator
|
|
1147
1201
|
});
|
|
1148
|
-
import
|
|
1202
|
+
import { schnorr as schnorr3 } from "@noble/curves/secp256k1";
|
|
1203
|
+
import { bytesToHex as bytesToHex5 } from "@noble/hashes/utils";
|
|
1149
1204
|
import { sha256 as sha2562 } from "@noble/hashes/sha256";
|
|
1150
1205
|
function createDelegation(privateKey, parameters) {
|
|
1151
1206
|
let conditions = [];
|
|
@@ -1161,8 +1216,8 @@ function createDelegation(privateKey, parameters) {
|
|
|
1161
1216
|
let sighash = sha2562(
|
|
1162
1217
|
utf8Encoder.encode(`nostr:delegation:${parameters.pubkey}:${cond}`)
|
|
1163
1218
|
);
|
|
1164
|
-
let sig =
|
|
1165
|
-
|
|
1219
|
+
let sig = bytesToHex5(
|
|
1220
|
+
schnorr3.sign(sighash, privateKey)
|
|
1166
1221
|
);
|
|
1167
1222
|
return {
|
|
1168
1223
|
from: getPublicKey(privateKey),
|
|
@@ -1193,7 +1248,7 @@ function getDelegator(event) {
|
|
|
1193
1248
|
let sighash = sha2562(
|
|
1194
1249
|
utf8Encoder.encode(`nostr:delegation:${event.pubkey}:${cond}`)
|
|
1195
1250
|
);
|
|
1196
|
-
if (!
|
|
1251
|
+
if (!schnorr3.verify(sig, sighash, pubkey))
|
|
1197
1252
|
return null;
|
|
1198
1253
|
return pubkey;
|
|
1199
1254
|
}
|
|
@@ -1337,13 +1392,6 @@ function makeZapReceipt({
|
|
|
1337
1392
|
}
|
|
1338
1393
|
return zap;
|
|
1339
1394
|
}
|
|
1340
|
-
|
|
1341
|
-
// index.ts
|
|
1342
|
-
import * as secp256k17 from "@noble/secp256k1";
|
|
1343
|
-
import { hmac } from "@noble/hashes/hmac";
|
|
1344
|
-
import { sha256 as sha2563 } from "@noble/hashes/sha256";
|
|
1345
|
-
secp256k17.utils.hmacSha256Sync = (key, ...msgs) => hmac(sha2563, key, secp256k17.utils.concatBytes(...msgs));
|
|
1346
|
-
secp256k17.utils.sha256Sync = (...msgs) => sha2563(secp256k17.utils.concatBytes(...msgs));
|
|
1347
1395
|
export {
|
|
1348
1396
|
Kind,
|
|
1349
1397
|
SimplePool,
|
|
@@ -1359,6 +1407,7 @@ export {
|
|
|
1359
1407
|
nip05_exports as nip05,
|
|
1360
1408
|
nip06_exports as nip06,
|
|
1361
1409
|
nip10_exports as nip10,
|
|
1410
|
+
nip13_exports as nip13,
|
|
1362
1411
|
nip19_exports as nip19,
|
|
1363
1412
|
nip26_exports as nip26,
|
|
1364
1413
|
nip39_exports as nip39,
|