@orangecheck/sdk 1.16.1 → 1.16.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/dist/attestation.js +86 -170
- package/dist/attestation.js.map +1 -1
- package/dist/attestation.mjs +86 -170
- package/dist/attestation.mjs.map +1 -1
- package/dist/identity.js.map +1 -1
- package/dist/identity.mjs.map +1 -1
- package/dist/index.js +91 -172
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +91 -172
- package/dist/index.mjs.map +1 -1
- package/dist/nostr.js +86 -170
- package/dist/nostr.js.map +1 -1
- package/dist/nostr.mjs +86 -170
- package/dist/nostr.mjs.map +1 -1
- package/dist/verify.d.mts +1 -0
- package/dist/verify.d.ts +1 -0
- package/dist/verify.js +9 -0
- package/dist/verify.js.map +1 -1
- package/dist/verify.mjs +9 -0
- package/dist/verify.mjs.map +1 -1
- package/package.json +1 -1
package/dist/nostr.mjs
CHANGED
|
@@ -181,11 +181,15 @@ function parseCanonicalMessage(msg) {
|
|
|
181
181
|
"ack"
|
|
182
182
|
]);
|
|
183
183
|
const extensions = {};
|
|
184
|
+
const keys = /* @__PURE__ */ new Set();
|
|
185
|
+
const repeated = [];
|
|
184
186
|
for (const line of lines) {
|
|
185
187
|
const idx = line.indexOf(":");
|
|
186
188
|
if (idx === -1) continue;
|
|
187
189
|
const key = line.slice(0, idx).trim().toLowerCase();
|
|
188
190
|
const val = line.slice(idx + 1).trim();
|
|
191
|
+
if (keys.has(key)) repeated.push(key);
|
|
192
|
+
keys.add(key);
|
|
189
193
|
if (!coreKeys.has(key) && val) extensions[key] = val;
|
|
190
194
|
}
|
|
191
195
|
const network = extensions["network"] || "mainnet";
|
|
@@ -194,6 +198,7 @@ function parseCanonicalMessage(msg) {
|
|
|
194
198
|
return {
|
|
195
199
|
core: { address, identities, issued_at },
|
|
196
200
|
expires,
|
|
201
|
+
repeated,
|
|
197
202
|
network,
|
|
198
203
|
extensions,
|
|
199
204
|
bond: bond !== void 0 && !isNaN(bond) && bond > 0 ? bond : void 0
|
|
@@ -358,188 +363,98 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
|
|
|
358
363
|
log2.info({ successCount: success.length, failedCount: failed.length }, "Publishing complete");
|
|
359
364
|
return { success, failed };
|
|
360
365
|
}
|
|
361
|
-
|
|
366
|
+
var PAGE_LIMIT = 500;
|
|
367
|
+
var MAX_PAGES = 4;
|
|
368
|
+
async function querySubject(filter, relays, label) {
|
|
362
369
|
const events = [];
|
|
363
|
-
log2.info({ attestationId, relayCount: relays.length }, "Querying relays for attestation");
|
|
364
370
|
const deadlineAt = Date.now() + FANOUT_DEADLINE_MS;
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
371
|
+
await Promise.allSettled(
|
|
372
|
+
relays.map(async (relayUrl) => {
|
|
373
|
+
let ws = null;
|
|
374
|
+
try {
|
|
375
|
+
ws = new WebSocket(relayUrl);
|
|
376
|
+
const wsRef = ws;
|
|
377
|
+
await new Promise((resolve, reject) => {
|
|
378
|
+
const timeout = setTimeout(() => {
|
|
379
|
+
wsRef.close();
|
|
380
|
+
reject(new Error("Query timeout"));
|
|
381
|
+
}, budgetFor(deadlineAt));
|
|
382
|
+
const seen = /* @__PURE__ */ new Set();
|
|
383
|
+
let page = 0;
|
|
384
|
+
let inPage = 0;
|
|
385
|
+
let newInPage = 0;
|
|
386
|
+
let oldest = Infinity;
|
|
387
|
+
const ask = () => {
|
|
388
|
+
page++;
|
|
389
|
+
inPage = 0;
|
|
390
|
+
newInPage = 0;
|
|
391
|
+
const until = Number.isFinite(oldest) ? { until: oldest } : {};
|
|
392
|
+
wsRef.send(
|
|
393
|
+
JSON.stringify([
|
|
394
|
+
"REQ",
|
|
395
|
+
`ochk_${label}_${Date.now()}_${page}`,
|
|
396
|
+
{ ...filter, ...until, limit: PAGE_LIMIT }
|
|
397
|
+
])
|
|
398
|
+
);
|
|
399
|
+
};
|
|
400
|
+
wsRef.onopen = ask;
|
|
401
|
+
wsRef.onmessage = (msg) => {
|
|
402
|
+
try {
|
|
403
|
+
const data = JSON.parse(msg.data);
|
|
404
|
+
if (data[0] === "EVENT") {
|
|
405
|
+
const event = data[2];
|
|
406
|
+
const key = event.id ?? JSON.stringify(event);
|
|
407
|
+
inPage++;
|
|
408
|
+
if (!seen.has(key)) {
|
|
409
|
+
seen.add(key);
|
|
410
|
+
newInPage++;
|
|
411
|
+
events.push(event);
|
|
412
|
+
}
|
|
413
|
+
if (typeof event.created_at === "number") {
|
|
414
|
+
oldest = Math.min(oldest, event.created_at);
|
|
415
|
+
}
|
|
416
|
+
} else if (data[0] === "EOSE") {
|
|
417
|
+
wsRef.send(JSON.stringify(["CLOSE", data[1]]));
|
|
418
|
+
if (inPage >= PAGE_LIMIT && newInPage > 0 && page < MAX_PAGES) {
|
|
419
|
+
ask();
|
|
420
|
+
} else {
|
|
421
|
+
clearTimeout(timeout);
|
|
422
|
+
wsRef.close();
|
|
423
|
+
resolve();
|
|
424
|
+
}
|
|
389
425
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
};
|
|
393
|
-
wsRef.onmessage = (msg) => {
|
|
394
|
-
try {
|
|
395
|
-
const data = JSON.parse(msg.data);
|
|
396
|
-
if (data[0] === "EVENT") {
|
|
397
|
-
events.push(data[2]);
|
|
398
|
-
} else if (data[0] === "EOSE") {
|
|
399
|
-
cleanup();
|
|
400
|
-
resolve();
|
|
426
|
+
} catch (err) {
|
|
427
|
+
log2.error({ relay: relayUrl, error: err }, "Failed to parse event");
|
|
401
428
|
}
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
};
|
|
414
|
-
});
|
|
415
|
-
} catch (err) {
|
|
416
|
-
log2.error({ relay: relayUrl, error: err }, "Failed to query relay");
|
|
417
|
-
} finally {
|
|
418
|
-
if (ws && ws.readyState !== WebSocket.CLOSED) {
|
|
419
|
-
ws.close();
|
|
429
|
+
};
|
|
430
|
+
wsRef.onerror = (err) => {
|
|
431
|
+
clearTimeout(timeout);
|
|
432
|
+
log2.error({ relay: relayUrl, error: err }, "WebSocket error during query");
|
|
433
|
+
reject(err);
|
|
434
|
+
};
|
|
435
|
+
});
|
|
436
|
+
} catch (err) {
|
|
437
|
+
log2.error({ relay: relayUrl, error: err }, "Failed to query relay");
|
|
438
|
+
} finally {
|
|
439
|
+
if (ws && ws.readyState !== WebSocket.CLOSED) ws.close();
|
|
420
440
|
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
log2.info({ eventCount: events.length }, "Query complete");
|
|
441
|
+
})
|
|
442
|
+
);
|
|
443
|
+
log2.info({ label, eventCount: events.length }, "Query complete");
|
|
425
444
|
return events;
|
|
426
445
|
}
|
|
446
|
+
async function queryByAttestationId(attestationId, relays = DEFAULT_RELAYS) {
|
|
447
|
+
log2.info({ attestationId, relayCount: relays.length }, "Querying relays for attestation");
|
|
448
|
+
return querySubject({ kinds: [30078], "#d": [attestationId] }, relays, "id");
|
|
449
|
+
}
|
|
427
450
|
async function queryByAddress(address, relays = DEFAULT_RELAYS) {
|
|
428
|
-
const events = [];
|
|
429
451
|
log2.info({ address, relayCount: relays.length }, "Querying relays for address");
|
|
430
|
-
|
|
431
|
-
const queryPromises = relays.map(async (relayUrl) => {
|
|
432
|
-
try {
|
|
433
|
-
const ws = new WebSocket(relayUrl);
|
|
434
|
-
await new Promise((resolve, reject) => {
|
|
435
|
-
const timeout = setTimeout(() => {
|
|
436
|
-
ws.close();
|
|
437
|
-
reject(new Error("Query timeout"));
|
|
438
|
-
}, budgetFor(deadlineAt));
|
|
439
|
-
ws.onopen = () => {
|
|
440
|
-
const subscriptionId = `ochk_addr_${Date.now()}`;
|
|
441
|
-
ws.send(
|
|
442
|
-
JSON.stringify([
|
|
443
|
-
"REQ",
|
|
444
|
-
subscriptionId,
|
|
445
|
-
{
|
|
446
|
-
kinds: [30078],
|
|
447
|
-
// `#t`, NOT `#address`: NIP-12 relays index
|
|
448
|
-
// single-letter tags only, so `#address`
|
|
449
|
-
// matched nothing on any relay and this
|
|
450
|
-
// function returned empty for every real
|
|
451
|
-
// attestation. attest.ochk.io's verifier has
|
|
452
|
-
// queried `#t` since the same fix landed
|
|
453
|
-
// there; this is the back-port.
|
|
454
|
-
"#t": [address],
|
|
455
|
-
limit: 50
|
|
456
|
-
}
|
|
457
|
-
])
|
|
458
|
-
);
|
|
459
|
-
};
|
|
460
|
-
ws.onmessage = (msg) => {
|
|
461
|
-
try {
|
|
462
|
-
const data = JSON.parse(msg.data);
|
|
463
|
-
if (data[0] === "EVENT") {
|
|
464
|
-
events.push(data[2]);
|
|
465
|
-
} else if (data[0] === "EOSE") {
|
|
466
|
-
clearTimeout(timeout);
|
|
467
|
-
ws.close();
|
|
468
|
-
resolve();
|
|
469
|
-
}
|
|
470
|
-
} catch (err) {
|
|
471
|
-
log2.error({ relay: relayUrl, error: err }, "Failed to parse event");
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
ws.onerror = (err) => {
|
|
475
|
-
clearTimeout(timeout);
|
|
476
|
-
log2.error({ relay: relayUrl, error: err }, "WebSocket error during query");
|
|
477
|
-
reject(err);
|
|
478
|
-
};
|
|
479
|
-
});
|
|
480
|
-
} catch (err) {
|
|
481
|
-
log2.error({ relay: relayUrl, error: err }, "Failed to query relay");
|
|
482
|
-
}
|
|
483
|
-
});
|
|
484
|
-
await Promise.allSettled(queryPromises);
|
|
485
|
-
log2.info({ eventCount: events.length }, "Query complete");
|
|
486
|
-
return events;
|
|
452
|
+
return querySubject({ kinds: [30078], "#t": [address] }, relays, "addr");
|
|
487
453
|
}
|
|
488
454
|
async function queryByIdentity(protocol, identifier, relays = DEFAULT_RELAYS) {
|
|
489
|
-
const
|
|
490
|
-
const identityTag = `${protocol}:${identifier}`;
|
|
491
|
-
const identityTags = protocol === "nostr" ? nostrIdentifierForms(identifier).map((f) => `nostr:${f}`) : [identityTag];
|
|
455
|
+
const identityTags = protocol === "nostr" ? nostrIdentifierForms(identifier).map((f) => `nostr:${f}`) : [`${protocol}:${identifier}`];
|
|
492
456
|
log2.info({ protocol, identifier, relayCount: relays.length }, "Querying relays for identity");
|
|
493
|
-
|
|
494
|
-
const queryPromises = relays.map(async (relayUrl) => {
|
|
495
|
-
try {
|
|
496
|
-
const ws = new WebSocket(relayUrl);
|
|
497
|
-
await new Promise((resolve, reject) => {
|
|
498
|
-
const timeout = setTimeout(() => {
|
|
499
|
-
ws.close();
|
|
500
|
-
reject(new Error("Query timeout"));
|
|
501
|
-
}, budgetFor(deadlineAt));
|
|
502
|
-
ws.onopen = () => {
|
|
503
|
-
const subscriptionId = `ochk_identity_${Date.now()}`;
|
|
504
|
-
ws.send(
|
|
505
|
-
JSON.stringify([
|
|
506
|
-
"REQ",
|
|
507
|
-
subscriptionId,
|
|
508
|
-
{
|
|
509
|
-
kinds: [30078],
|
|
510
|
-
"#i": identityTags,
|
|
511
|
-
limit: 10
|
|
512
|
-
}
|
|
513
|
-
])
|
|
514
|
-
);
|
|
515
|
-
};
|
|
516
|
-
ws.onmessage = (msg) => {
|
|
517
|
-
try {
|
|
518
|
-
const data = JSON.parse(msg.data);
|
|
519
|
-
if (data[0] === "EVENT") {
|
|
520
|
-
events.push(data[2]);
|
|
521
|
-
} else if (data[0] === "EOSE") {
|
|
522
|
-
clearTimeout(timeout);
|
|
523
|
-
ws.close();
|
|
524
|
-
resolve();
|
|
525
|
-
}
|
|
526
|
-
} catch (err) {
|
|
527
|
-
log2.error({ relay: relayUrl, error: err }, "Failed to parse event");
|
|
528
|
-
}
|
|
529
|
-
};
|
|
530
|
-
ws.onerror = (err) => {
|
|
531
|
-
clearTimeout(timeout);
|
|
532
|
-
log2.error({ relay: relayUrl, error: err }, "WebSocket error during query");
|
|
533
|
-
reject(err);
|
|
534
|
-
};
|
|
535
|
-
});
|
|
536
|
-
} catch (err) {
|
|
537
|
-
log2.error({ relay: relayUrl, error: err }, "Failed to query relay");
|
|
538
|
-
}
|
|
539
|
-
});
|
|
540
|
-
await Promise.allSettled(queryPromises);
|
|
541
|
-
log2.info({ eventCount: events.length }, "Query complete");
|
|
542
|
-
return events;
|
|
457
|
+
return querySubject({ kinds: [30078], "#i": identityTags }, relays, "identity");
|
|
543
458
|
}
|
|
544
459
|
async function queryRecent(relays = DEFAULT_RELAYS, limit = 200) {
|
|
545
460
|
const events = [];
|
|
@@ -622,6 +537,7 @@ function signedEnvelope(envelope) {
|
|
|
622
537
|
return null;
|
|
623
538
|
}
|
|
624
539
|
if (!parsed.core.address || rfc3339Ms(parsed.core.issued_at) === null) return null;
|
|
540
|
+
if (parsed.repeated.length > 0) return null;
|
|
625
541
|
const { expires_at: _copy, ...rest } = envelope;
|
|
626
542
|
return {
|
|
627
543
|
...rest,
|