@orangecheck/sdk 1.2.0 → 1.4.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/dist/attestation.js +33 -12
- package/dist/attestation.js.map +1 -1
- package/dist/attestation.mjs +33 -12
- package/dist/attestation.mjs.map +1 -1
- package/dist/identity.js +2 -1
- package/dist/identity.js.map +1 -1
- package/dist/identity.mjs +2 -1
- package/dist/identity.mjs.map +1 -1
- package/dist/index.d.mts +1 -68
- package/dist/index.d.ts +1 -68
- package/dist/index.js +38 -263
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +42 -261
- package/dist/index.mjs.map +1 -1
- package/dist/nostr.js +33 -12
- package/dist/nostr.js.map +1 -1
- package/dist/nostr.mjs +33 -12
- package/dist/nostr.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Buffer
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
2
|
import { Verifier } from 'bip322-js';
|
|
3
3
|
import * as bitcoinMessage from 'bitcoinjs-message';
|
|
4
4
|
import { schnorr } from '@noble/curves/secp256k1.js';
|
|
@@ -193,14 +193,19 @@ var DEFAULT_RELAYS = [
|
|
|
193
193
|
"wss://relay.damus.io",
|
|
194
194
|
"wss://relay.nostr.band",
|
|
195
195
|
"wss://nos.lol",
|
|
196
|
-
"wss://relay.snort.social"
|
|
196
|
+
"wss://relay.snort.social",
|
|
197
|
+
"wss://relay.ochk.io"
|
|
197
198
|
];
|
|
198
199
|
function createAttestationEvent(envelope, pubkey) {
|
|
199
200
|
const tags = [
|
|
200
201
|
["d", envelope.attestation_id],
|
|
201
|
-
// Parameterized replaceable event identifier
|
|
202
|
+
// Parameterized replaceable event identifier (indexed)
|
|
203
|
+
["t", envelope.address],
|
|
204
|
+
// Indexed btc-address tag — query with `#t`
|
|
205
|
+
["t", "oc-attest"],
|
|
206
|
+
// Family marker — `#t=["oc-attest"]` for cross-cut discovery
|
|
202
207
|
["address", envelope.address],
|
|
203
|
-
//
|
|
208
|
+
// Diagnostic / legacy — relay won't index this
|
|
204
209
|
["scheme", envelope.scheme],
|
|
205
210
|
// Signature scheme (bip322 or legacy)
|
|
206
211
|
["issued_at", envelope.issued_at]
|
|
@@ -232,6 +237,17 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
|
|
|
232
237
|
log.info({ eventId: event.id, relayCount: relays.length }, "Publishing event to relays");
|
|
233
238
|
const publishPromises = relays.map(async (relayUrl) => {
|
|
234
239
|
let ws = null;
|
|
240
|
+
let settled = false;
|
|
241
|
+
const recordSuccess = () => {
|
|
242
|
+
if (settled) return;
|
|
243
|
+
settled = true;
|
|
244
|
+
success.push(relayUrl);
|
|
245
|
+
};
|
|
246
|
+
const recordFailure = () => {
|
|
247
|
+
if (settled) return;
|
|
248
|
+
settled = true;
|
|
249
|
+
failed.push(relayUrl);
|
|
250
|
+
};
|
|
235
251
|
try {
|
|
236
252
|
ws = new WebSocket(relayUrl);
|
|
237
253
|
const wsRef = ws;
|
|
@@ -252,7 +268,7 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
|
|
|
252
268
|
const data = JSON.parse(msg.data);
|
|
253
269
|
if (data[0] === "OK" && data[1] === event.id) {
|
|
254
270
|
if (data[2] === true) {
|
|
255
|
-
|
|
271
|
+
recordSuccess();
|
|
256
272
|
cleanup();
|
|
257
273
|
resolve();
|
|
258
274
|
} else {
|
|
@@ -260,7 +276,7 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
|
|
|
260
276
|
{ relay: relayUrl, reason: data[3] },
|
|
261
277
|
"Relay rejected event"
|
|
262
278
|
);
|
|
263
|
-
|
|
279
|
+
recordFailure();
|
|
264
280
|
cleanup();
|
|
265
281
|
reject(new Error(data[3] || "Relay rejected event"));
|
|
266
282
|
}
|
|
@@ -270,14 +286,14 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
|
|
|
270
286
|
{ relay: relayUrl, error: err },
|
|
271
287
|
"Failed to parse relay response"
|
|
272
288
|
);
|
|
273
|
-
|
|
289
|
+
recordFailure();
|
|
274
290
|
cleanup();
|
|
275
291
|
reject(err);
|
|
276
292
|
}
|
|
277
293
|
};
|
|
278
294
|
wsRef.onerror = (err) => {
|
|
279
295
|
log.error({ relay: relayUrl, error: err }, "WebSocket error");
|
|
280
|
-
|
|
296
|
+
recordFailure();
|
|
281
297
|
cleanup();
|
|
282
298
|
reject(err);
|
|
283
299
|
};
|
|
@@ -287,9 +303,7 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
|
|
|
287
303
|
});
|
|
288
304
|
} catch (err) {
|
|
289
305
|
log.error({ relay: relayUrl, error: err }, "Failed to publish to relay");
|
|
290
|
-
|
|
291
|
-
failed.push(relayUrl);
|
|
292
|
-
}
|
|
306
|
+
recordFailure();
|
|
293
307
|
} finally {
|
|
294
308
|
if (ws && ws.readyState !== WebSocket.CLOSED) {
|
|
295
309
|
ws.close();
|
|
@@ -384,8 +398,15 @@ async function queryByAddress(address, relays = DEFAULT_RELAYS) {
|
|
|
384
398
|
subscriptionId,
|
|
385
399
|
{
|
|
386
400
|
kinds: [30078],
|
|
387
|
-
|
|
388
|
-
|
|
401
|
+
// `#t`, NOT `#address`: NIP-12 relays index
|
|
402
|
+
// single-letter tags only, so `#address`
|
|
403
|
+
// matched nothing on any relay and this
|
|
404
|
+
// function returned empty for every real
|
|
405
|
+
// attestation. attest.ochk.io's verifier has
|
|
406
|
+
// queried `#t` since the same fix landed
|
|
407
|
+
// there; this is the back-port.
|
|
408
|
+
"#t": [address],
|
|
409
|
+
limit: 50
|
|
389
410
|
}
|
|
390
411
|
])
|
|
391
412
|
);
|
|
@@ -712,7 +733,7 @@ function looksLikeHex(s) {
|
|
|
712
733
|
}
|
|
713
734
|
function toBase64Maybe(sig) {
|
|
714
735
|
if (looksLikeHex(sig)) {
|
|
715
|
-
return Buffer
|
|
736
|
+
return Buffer.from(sig, "hex").toString("base64");
|
|
716
737
|
}
|
|
717
738
|
return sig;
|
|
718
739
|
}
|
|
@@ -1155,246 +1176,6 @@ async function check(params) {
|
|
|
1155
1176
|
...reasons.length ? { reasons } : {}
|
|
1156
1177
|
};
|
|
1157
1178
|
}
|
|
1158
|
-
var HEADER = "orangecheck-binding";
|
|
1159
|
-
var ACK = "I attest the keys named in this message are one principal.";
|
|
1160
|
-
var BINDING_KIND = 30079;
|
|
1161
|
-
function toHex(bytes) {
|
|
1162
|
-
let out = "";
|
|
1163
|
-
for (const b of bytes) out += b.toString(16).padStart(2, "0");
|
|
1164
|
-
return out;
|
|
1165
|
-
}
|
|
1166
|
-
function fromHex(hex) {
|
|
1167
|
-
const clean = hex.toLowerCase();
|
|
1168
|
-
if (clean.length % 2 !== 0 || /[^0-9a-f]/.test(clean)) {
|
|
1169
|
-
throw new Error("invalid hex");
|
|
1170
|
-
}
|
|
1171
|
-
const out = new Uint8Array(clean.length / 2);
|
|
1172
|
-
for (let i = 0; i < out.length; i++) out[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
1173
|
-
return out;
|
|
1174
|
-
}
|
|
1175
|
-
function assertPrintableAscii(field, value) {
|
|
1176
|
-
for (let i = 0; i < value.length; i++) {
|
|
1177
|
-
const c = value.charCodeAt(i);
|
|
1178
|
-
if (c < 32 || c > 126) {
|
|
1179
|
-
throw new Error(
|
|
1180
|
-
`binding ${field} contains an unsafe character (0x${c.toString(16)}) \u2014 line-smuggling defense (SPEC-BINDING \xA73.5)`
|
|
1181
|
-
);
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
|
-
}
|
|
1185
|
-
function buildBindingMessage(input) {
|
|
1186
|
-
assertPrintableAscii("principal", input.principal);
|
|
1187
|
-
assertPrintableAscii("btc", input.btc);
|
|
1188
|
-
assertPrintableAscii("nostr", input.nostr);
|
|
1189
|
-
assertPrintableAscii("nonce", input.nonce);
|
|
1190
|
-
assertPrintableAscii("issued_at", input.issued_at);
|
|
1191
|
-
const core = [
|
|
1192
|
-
HEADER,
|
|
1193
|
-
"v: 1",
|
|
1194
|
-
`principal: ${input.principal}`,
|
|
1195
|
-
`btc: ${input.btc}`,
|
|
1196
|
-
`nostr: ${input.nostr}`,
|
|
1197
|
-
`nonce: ${input.nonce}`,
|
|
1198
|
-
`issued_at: ${input.issued_at}`,
|
|
1199
|
-
`ack: ${ACK}`
|
|
1200
|
-
];
|
|
1201
|
-
const ext = [];
|
|
1202
|
-
if (input.extensions) {
|
|
1203
|
-
for (const key of Object.keys(input.extensions).sort()) {
|
|
1204
|
-
const value = input.extensions[key];
|
|
1205
|
-
if (value == null) continue;
|
|
1206
|
-
if (!/^[a-z]+$/.test(key)) {
|
|
1207
|
-
throw new Error(`binding extension key "${key}" must be lowercase ASCII`);
|
|
1208
|
-
}
|
|
1209
|
-
assertPrintableAscii(`extension ${key}`, value);
|
|
1210
|
-
ext.push(`${key}: ${value}`);
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
return [...core, ...ext].join("\n") + "\n";
|
|
1214
|
-
}
|
|
1215
|
-
function bindingId(message) {
|
|
1216
|
-
return toHex(sha256(new TextEncoder().encode(message)));
|
|
1217
|
-
}
|
|
1218
|
-
function linePrefix(line, prefix) {
|
|
1219
|
-
if (typeof line !== "string" || !line.startsWith(prefix)) return null;
|
|
1220
|
-
return line.slice(prefix.length);
|
|
1221
|
-
}
|
|
1222
|
-
function nostrEventId(ev) {
|
|
1223
|
-
const serialized = JSON.stringify([
|
|
1224
|
-
0,
|
|
1225
|
-
ev.pubkey,
|
|
1226
|
-
ev.created_at,
|
|
1227
|
-
ev.kind,
|
|
1228
|
-
ev.tags,
|
|
1229
|
-
ev.content
|
|
1230
|
-
]);
|
|
1231
|
-
return toHex(sha256(new TextEncoder().encode(serialized)));
|
|
1232
|
-
}
|
|
1233
|
-
function npubToXOnlyHex(npub) {
|
|
1234
|
-
const decoded = bech32.decode(npub, 90);
|
|
1235
|
-
if (decoded.prefix !== "npub") throw new Error("not an npub");
|
|
1236
|
-
const bytes = Uint8Array.from(bech32.fromWords(decoded.words));
|
|
1237
|
-
if (bytes.length !== 32) throw new Error("npub payload is not 32 bytes");
|
|
1238
|
-
return toHex(bytes);
|
|
1239
|
-
}
|
|
1240
|
-
function verifyBinding(envelope) {
|
|
1241
|
-
const fail = (status) => ({
|
|
1242
|
-
valid: false,
|
|
1243
|
-
status
|
|
1244
|
-
});
|
|
1245
|
-
try {
|
|
1246
|
-
const msg = envelope.message;
|
|
1247
|
-
if (typeof msg !== "string" || msg.length === 0) return fail("malformed");
|
|
1248
|
-
const lines = msg.split("\n");
|
|
1249
|
-
if ((lines[0] ?? "") !== HEADER) return fail("bad_header");
|
|
1250
|
-
if (lines.length < 9 || lines[lines.length - 1] !== "") return fail("malformed");
|
|
1251
|
-
const body = lines.slice(0, -1);
|
|
1252
|
-
if (body.length < 8) return fail("malformed");
|
|
1253
|
-
if (body[1] !== "v: 1") return fail("malformed");
|
|
1254
|
-
if (body[7] !== `ack: ${ACK}`) return fail("bad_ack");
|
|
1255
|
-
const principal = linePrefix(body[2], "principal: ");
|
|
1256
|
-
const btc = linePrefix(body[3], "btc: ");
|
|
1257
|
-
const nostr = linePrefix(body[4], "nostr: ");
|
|
1258
|
-
const nonce = linePrefix(body[5], "nonce: ");
|
|
1259
|
-
const issuedAt = linePrefix(body[6], "issued_at: ");
|
|
1260
|
-
if (principal == null || btc == null || nostr == null || nonce == null || issuedAt == null) {
|
|
1261
|
-
return fail("malformed");
|
|
1262
|
-
}
|
|
1263
|
-
for (const value of [principal, btc, nostr, nonce, issuedAt]) {
|
|
1264
|
-
for (let i = 0; i < value.length; i++) {
|
|
1265
|
-
const c = value.charCodeAt(i);
|
|
1266
|
-
if (c < 32 || c > 126) return fail("malformed");
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
if (!/^did:oc:[0-9a-f]{32}$/.test(principal)) return fail("bad_principal");
|
|
1270
|
-
if (!/^[0-9a-f]{32}$/.test(nonce)) return fail("malformed");
|
|
1271
|
-
const ext = {};
|
|
1272
|
-
let prevKey = "";
|
|
1273
|
-
for (const line of body.slice(8)) {
|
|
1274
|
-
const idx = line.indexOf(": ");
|
|
1275
|
-
if (idx <= 0) return fail("malformed");
|
|
1276
|
-
const key = line.slice(0, idx);
|
|
1277
|
-
const value = line.slice(idx + 2);
|
|
1278
|
-
if (!/^[a-z]+$/.test(key)) return fail("malformed");
|
|
1279
|
-
if (key <= prevKey) return fail("ext_unsorted");
|
|
1280
|
-
prevKey = key;
|
|
1281
|
-
ext[key] = value;
|
|
1282
|
-
}
|
|
1283
|
-
const bid = bindingId(msg);
|
|
1284
|
-
if (envelope.binding_id && envelope.binding_id.toLowerCase() !== bid) {
|
|
1285
|
-
return fail("id_mismatch");
|
|
1286
|
-
}
|
|
1287
|
-
if (envelope.btc && envelope.btc !== btc) return fail("field_mismatch");
|
|
1288
|
-
if (envelope.nostr && envelope.nostr !== nostr) return fail("field_mismatch");
|
|
1289
|
-
if (envelope.principal && envelope.principal !== principal) return fail("field_mismatch");
|
|
1290
|
-
if (ext.expires) {
|
|
1291
|
-
const t = Date.parse(ext.expires);
|
|
1292
|
-
if (!Number.isNaN(t) && Date.now() > t) return fail("expired");
|
|
1293
|
-
}
|
|
1294
|
-
if (typeof envelope.btc_signature !== "string" || !envelope.btc_signature) {
|
|
1295
|
-
return fail("btc_sig_invalid");
|
|
1296
|
-
}
|
|
1297
|
-
const scheme = envelope.btc_scheme ?? "bip322";
|
|
1298
|
-
let btcOk = false;
|
|
1299
|
-
try {
|
|
1300
|
-
if (scheme === "bip322") {
|
|
1301
|
-
btcOk = Verifier.verifySignature(btc, msg, envelope.btc_signature);
|
|
1302
|
-
} else if (scheme === "legacy") {
|
|
1303
|
-
btcOk = bitcoinMessage.verify(msg, btc, envelope.btc_signature);
|
|
1304
|
-
} else {
|
|
1305
|
-
return fail("bad_scheme");
|
|
1306
|
-
}
|
|
1307
|
-
} catch {
|
|
1308
|
-
btcOk = false;
|
|
1309
|
-
}
|
|
1310
|
-
if (!btcOk) return fail("btc_sig_invalid");
|
|
1311
|
-
const ev = envelope.nostr_event;
|
|
1312
|
-
if (!ev || ev.kind !== BINDING_KIND || typeof ev.id !== "string") return fail("malformed");
|
|
1313
|
-
if (nostrEventId(ev) !== ev.id.toLowerCase()) return fail("nostr_id_invalid");
|
|
1314
|
-
let nostrSigOk = false;
|
|
1315
|
-
try {
|
|
1316
|
-
nostrSigOk = schnorr.verify(fromHex(ev.sig), fromHex(ev.id), fromHex(ev.pubkey));
|
|
1317
|
-
} catch {
|
|
1318
|
-
nostrSigOk = false;
|
|
1319
|
-
}
|
|
1320
|
-
if (!nostrSigOk) return fail("nostr_sig_invalid");
|
|
1321
|
-
let nostrXOnly;
|
|
1322
|
-
try {
|
|
1323
|
-
nostrXOnly = npubToXOnlyHex(nostr);
|
|
1324
|
-
} catch {
|
|
1325
|
-
return fail("nostr_key_mismatch");
|
|
1326
|
-
}
|
|
1327
|
-
if (nostrXOnly !== ev.pubkey.toLowerCase()) return fail("nostr_key_mismatch");
|
|
1328
|
-
let content;
|
|
1329
|
-
try {
|
|
1330
|
-
content = JSON.parse(ev.content);
|
|
1331
|
-
} catch {
|
|
1332
|
-
return fail("message_mismatch");
|
|
1333
|
-
}
|
|
1334
|
-
if (content.message !== msg) return fail("message_mismatch");
|
|
1335
|
-
if (content.btc_signature !== envelope.btc_signature) return fail("message_mismatch");
|
|
1336
|
-
return { valid: true, status: "binding_ok", binding_id: bid, principal, btc, nostr };
|
|
1337
|
-
} catch {
|
|
1338
|
-
return fail("malformed");
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
function xOnlyHexToNpub(hex) {
|
|
1342
|
-
const bytes = fromHex(hex);
|
|
1343
|
-
if (bytes.length !== 32) throw new Error("x-only Nostr key must be 32 bytes");
|
|
1344
|
-
return bech32.encode("npub", bech32.toWords(bytes), 90);
|
|
1345
|
-
}
|
|
1346
|
-
function buildBindingEventTemplate(params) {
|
|
1347
|
-
const id = bindingId(params.message);
|
|
1348
|
-
return {
|
|
1349
|
-
kind: BINDING_KIND,
|
|
1350
|
-
pubkey: params.nostrPubkeyHex.toLowerCase(),
|
|
1351
|
-
created_at: params.createdAt ?? Math.floor(Date.now() / 1e3),
|
|
1352
|
-
tags: [
|
|
1353
|
-
["d", `oc-attest-binding:${id}`],
|
|
1354
|
-
["btc", params.btc],
|
|
1355
|
-
["oc", "binding-attestation"],
|
|
1356
|
-
["v", "1"]
|
|
1357
|
-
],
|
|
1358
|
-
content: JSON.stringify({ message: params.message, btc_signature: params.btcSignature })
|
|
1359
|
-
};
|
|
1360
|
-
}
|
|
1361
|
-
function parseBindingFields(message) {
|
|
1362
|
-
const body = message.split("\n");
|
|
1363
|
-
const at = (i, prefix) => {
|
|
1364
|
-
const line = body[i];
|
|
1365
|
-
if (typeof line !== "string" || !line.startsWith(prefix)) {
|
|
1366
|
-
throw new Error(`binding message line ${i + 1} is malformed`);
|
|
1367
|
-
}
|
|
1368
|
-
return line.slice(prefix.length);
|
|
1369
|
-
};
|
|
1370
|
-
return {
|
|
1371
|
-
principal: at(2, "principal: "),
|
|
1372
|
-
btc: at(3, "btc: "),
|
|
1373
|
-
nostr: at(4, "nostr: ")
|
|
1374
|
-
};
|
|
1375
|
-
}
|
|
1376
|
-
function toBase64Url(s) {
|
|
1377
|
-
const bytes = new TextEncoder().encode(s);
|
|
1378
|
-
let bin = "";
|
|
1379
|
-
for (const b of bytes) bin += String.fromCharCode(b);
|
|
1380
|
-
const b64 = typeof btoa !== "undefined" ? btoa(bin) : Buffer.from(bytes).toString("base64");
|
|
1381
|
-
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1382
|
-
}
|
|
1383
|
-
function assembleBindingEnvelope(params) {
|
|
1384
|
-
const { principal, btc, nostr } = parseBindingFields(params.message);
|
|
1385
|
-
return {
|
|
1386
|
-
binding_id: bindingId(params.message),
|
|
1387
|
-
v: 1,
|
|
1388
|
-
principal,
|
|
1389
|
-
btc,
|
|
1390
|
-
nostr,
|
|
1391
|
-
message: params.message,
|
|
1392
|
-
message_b64url: toBase64Url(params.message),
|
|
1393
|
-
btc_signature: params.btcSignature,
|
|
1394
|
-
btc_scheme: params.btcScheme ?? "bip322",
|
|
1395
|
-
nostr_event: params.nostrEvent
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1398
1179
|
var AUTH_HEADER = "orangecheck-auth";
|
|
1399
1180
|
var AUTH_ACK = "I authorize this session under the OrangeCheck auth challenge.";
|
|
1400
1181
|
function randomNonce() {
|
|
@@ -1512,7 +1293,7 @@ async function verifyChallenge(opts) {
|
|
|
1512
1293
|
let sigValid = false;
|
|
1513
1294
|
try {
|
|
1514
1295
|
if (scheme === "bip322") {
|
|
1515
|
-
const sigBase64 = /^[0-9a-fA-F]+$/.test(opts.signature) && opts.signature.length % 2 === 0 ? Buffer
|
|
1296
|
+
const sigBase64 = /^[0-9a-fA-F]+$/.test(opts.signature) && opts.signature.length % 2 === 0 ? Buffer.from(opts.signature, "hex").toString("base64") : opts.signature;
|
|
1516
1297
|
sigValid = Verifier.verifySignature(address, opts.message, sigBase64);
|
|
1517
1298
|
} else if (scheme === "legacy") {
|
|
1518
1299
|
if (!/^[1m][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address)) {
|
|
@@ -1850,12 +1631,12 @@ function getGistCreationUrl() {
|
|
|
1850
1631
|
}
|
|
1851
1632
|
var log7 = createLogger("identity-verification/nostr");
|
|
1852
1633
|
var HEX_64_RE = /^[0-9a-f]{64}$/;
|
|
1853
|
-
function
|
|
1634
|
+
function toHex(bytes) {
|
|
1854
1635
|
let out = "";
|
|
1855
1636
|
for (const b of bytes) out += b.toString(16).padStart(2, "0");
|
|
1856
1637
|
return out;
|
|
1857
1638
|
}
|
|
1858
|
-
function
|
|
1639
|
+
function fromHex(hex) {
|
|
1859
1640
|
if (hex.length % 2 !== 0) throw new Error("odd-length hex");
|
|
1860
1641
|
const out = new Uint8Array(hex.length / 2);
|
|
1861
1642
|
for (let i = 0; i < out.length; i++) {
|
|
@@ -1879,7 +1660,7 @@ function npubToHex(npub) {
|
|
|
1879
1660
|
if (bytes.length !== 32) {
|
|
1880
1661
|
throw new Error(`invalid npub payload length: ${bytes.length}`);
|
|
1881
1662
|
}
|
|
1882
|
-
return
|
|
1663
|
+
return toHex(Uint8Array.from(bytes));
|
|
1883
1664
|
}
|
|
1884
1665
|
async function queryNostrEvents(options) {
|
|
1885
1666
|
const { authors, kinds, search, relays = DEFAULT_RELAYS, limit = 100 } = options;
|
|
@@ -1962,7 +1743,7 @@ async function verifyNostrEventSignature(event) {
|
|
|
1962
1743
|
event.tags ?? [],
|
|
1963
1744
|
event.content ?? ""
|
|
1964
1745
|
]);
|
|
1965
|
-
const computedId =
|
|
1746
|
+
const computedId = toHex(sha256(new TextEncoder().encode(preimage)));
|
|
1966
1747
|
if (computedId !== event.id.toLowerCase()) {
|
|
1967
1748
|
log7.warn(
|
|
1968
1749
|
{ eventId: event.id, computedId },
|
|
@@ -1970,7 +1751,7 @@ async function verifyNostrEventSignature(event) {
|
|
|
1970
1751
|
);
|
|
1971
1752
|
return false;
|
|
1972
1753
|
}
|
|
1973
|
-
return schnorr.verify(
|
|
1754
|
+
return schnorr.verify(fromHex(event.sig), fromHex(event.id), fromHex(event.pubkey));
|
|
1974
1755
|
} catch (err) {
|
|
1975
1756
|
log7.warn({ err }, "schnorr verify threw");
|
|
1976
1757
|
return false;
|
|
@@ -2330,6 +2111,6 @@ var STATUS_META = {
|
|
|
2330
2111
|
}
|
|
2331
2112
|
};
|
|
2332
2113
|
|
|
2333
|
-
export { DEFAULT_RELAYS, STATUS_META,
|
|
2114
|
+
export { DEFAULT_RELAYS, STATUS_META, buildCanonicalMessage, check, computeAllScores, computeScore, createAttestation, createAttestationEnvelope, createAttestationEvent, discoverAttestations, extractAttestationIdFromUrl, formatIdentities, formatIdentitiesForDisplay, generateAttestationId, generateGistTemplate, generateTweetText, generateWellKnownContent, getAttestationsForAddress, getAttestationsForIdentity, getDnsVerificationInstructions, getGistCreationUrl, getGitHubVerificationInstructions, getManualVerificationInstructions, getNip07Info, getNostrPublicKey, getNostrVerificationInstructions, getTweetUrl, getTwitterComposeUrl, getTwitterVerificationInstructions, getVerificationInstructions, getVerificationSummary, getVerificationUrl, getWellKnownUrl, isDnsIdentityVerified, isGitHubIdentityVerified, isNip07Available, isNostrIdentityVerified, isValidDomain, isValidTweetUrl, issueChallenge, parseAttestationFromEvent, parseIdentities, publishAttestation, publishToRelays, queryByAddress, queryByAttestationId, queryByIdentity, requiresManualVerification, signNostrEvent, supportsAutomaticVerification, verify2 as verify, verifyAllIdentities, verifyAttestationById, verifyChallenge, verifyDnsIdentity, verifyGitHubIdentity, verifyIdentity, verifyNostrIdentity, verifyTwitterIdentity };
|
|
2334
2115
|
//# sourceMappingURL=index.mjs.map
|
|
2335
2116
|
//# sourceMappingURL=index.mjs.map
|