@orangecheck/sdk 1.14.1 → 1.16.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.
@@ -1,9 +1,50 @@
1
1
  import { bech32 } from '@scure/base';
2
+ import { verifySignature as verifySignature$1 } from '@orangecheck/bip322';
3
+ import { Buffer } from 'buffer';
2
4
 
3
5
  // src/canonical.ts
4
6
  function toLowerHex(bytes) {
5
7
  return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
6
8
  }
9
+ var IDENTITY_PROTOCOL_RE = /^[a-z][a-z0-9_-]*$/;
10
+ var IDENTITY_FORBIDDEN_CHARS = /[\r\n,]/;
11
+ function assertSafeIdentity({ protocol, identifier }) {
12
+ if (!IDENTITY_PROTOCOL_RE.test(protocol)) {
13
+ throw new Error(
14
+ `invalid identity protocol: ${JSON.stringify(protocol)} \u2014 must match /^[a-z][a-z0-9_-]*$/`
15
+ );
16
+ }
17
+ if (!identifier || IDENTITY_FORBIDDEN_CHARS.test(identifier)) {
18
+ throw new Error(
19
+ `invalid identity identifier: ${JSON.stringify(identifier)} \u2014 must be non-empty and contain no newlines or commas`
20
+ );
21
+ }
22
+ }
23
+ function parseIdentities(identitiesStr) {
24
+ if (!identitiesStr || identitiesStr.trim() === "") {
25
+ return [];
26
+ }
27
+ if (IDENTITY_FORBIDDEN_CHARS.test(identitiesStr.replace(/,/g, ""))) {
28
+ throw new Error("identities field contains forbidden characters (newline)");
29
+ }
30
+ const bindings = identitiesStr.split(",").map((binding) => {
31
+ const colonIndex = binding.indexOf(":");
32
+ if (colonIndex === -1) {
33
+ throw new Error(`Invalid identity binding format: ${binding}`);
34
+ }
35
+ return {
36
+ protocol: binding.substring(0, colonIndex).trim(),
37
+ identifier: binding.substring(colonIndex + 1).trim()
38
+ };
39
+ });
40
+ for (const b of bindings) {
41
+ if (!b.protocol || !b.identifier) {
42
+ throw new Error(`Invalid identity binding: ${b.protocol}:${b.identifier}`);
43
+ }
44
+ assertSafeIdentity(b);
45
+ }
46
+ return bindings;
47
+ }
7
48
  async function generateAttestationId(message) {
8
49
  const encoder = new TextEncoder();
9
50
  const data = encoder.encode(message);
@@ -107,8 +148,94 @@ function createLogger(namespace) {
107
148
  };
108
149
  }
109
150
 
151
+ // src/utils/time.ts
152
+ var RFC3339 = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
153
+ function rfc3339Ms(value) {
154
+ if (!value || !RFC3339.test(value)) return null;
155
+ const ms = Date.parse(value);
156
+ return Number.isNaN(ms) ? null : ms;
157
+ }
158
+ function toBase64Maybe(sig) {
159
+ if (/^[0-9a-fA-F]+$/.test(sig) && sig.length % 2 === 0) {
160
+ return Buffer.from(sig, "hex").toString("base64");
161
+ }
162
+ return sig;
163
+ }
164
+ function signatureScheme(sigBase64) {
165
+ if (/^(ful|pof)/.test(sigBase64)) return null;
166
+ if (sigBase64.startsWith("smp")) return "bip322";
167
+ return Buffer.from(sigBase64, "base64").length === 65 ? "legacy" : "bip322";
168
+ }
169
+
170
+ // src/verify.ts
171
+ var log = createLogger("ocp/verify");
172
+ async function verifySignature({ addr, msg, sig }) {
173
+ const sigBase64 = toBase64Maybe(sig);
174
+ const scheme = signatureScheme(sigBase64);
175
+ if (!scheme) return "sig_unsupported_script";
176
+ const ok = verifySignature$1(addr, msg, sigBase64);
177
+ log.info({ addr, ok, scheme, msgLength: msg.length }, "Signature verification result");
178
+ if (!ok) return "sig_invalid";
179
+ return scheme === "legacy" ? "sig_ok_legacy" : "sig_ok_bip322";
180
+ }
181
+ async function signatureIsValid(input) {
182
+ try {
183
+ const code = await verifySignature(input);
184
+ return code === "sig_ok_bip322" || code === "sig_ok_legacy";
185
+ } catch {
186
+ return false;
187
+ }
188
+ }
189
+ function parseCanonicalMessage(msg) {
190
+ const lines = msg.split("\n").map((l) => l.trim());
191
+ const getVal = (prefix) => {
192
+ const needle = prefix + ":";
193
+ const hit = lines.find((l) => l.toLowerCase().startsWith(needle));
194
+ if (!hit) return void 0;
195
+ const idx = hit.indexOf(":");
196
+ return hit.slice(idx + 1).trim();
197
+ };
198
+ const address = getVal("address") || "";
199
+ const identitiesStr = getVal("identities") || "";
200
+ const issued_at = getVal("issued_at") || "";
201
+ const expires = getVal("expires");
202
+ let identities = [];
203
+ try {
204
+ identities = parseIdentities(identitiesStr);
205
+ } catch (err) {
206
+ log.warn({ identitiesStr, error: err }, "Failed to parse identities field");
207
+ }
208
+ const coreKeys = /* @__PURE__ */ new Set([
209
+ "orangecheck",
210
+ "identities",
211
+ "address",
212
+ "purpose",
213
+ "nonce",
214
+ "issued_at",
215
+ "ack"
216
+ ]);
217
+ const extensions = {};
218
+ for (const line of lines) {
219
+ const idx = line.indexOf(":");
220
+ if (idx === -1) continue;
221
+ const key = line.slice(0, idx).trim().toLowerCase();
222
+ const val = line.slice(idx + 1).trim();
223
+ if (!coreKeys.has(key) && val) extensions[key] = val;
224
+ }
225
+ const network = extensions["network"] || "mainnet";
226
+ const bondStr = extensions["bond"];
227
+ const bond = bondStr ? parseInt(bondStr, 10) : void 0;
228
+ return {
229
+ core: { address, identities, issued_at },
230
+ expires,
231
+ network,
232
+ extensions,
233
+ bond: bond !== void 0 && !isNaN(bond) && bond > 0 ? bond : void 0
234
+ };
235
+ }
236
+
110
237
  // src/nostr.ts
111
- var log = createLogger("ocp/nostr");
238
+ var log2 = createLogger("ocp/nostr");
112
239
  var ATTESTATION_EVENT_KIND = 30078;
113
240
  var DEFAULT_RELAYS = [
114
241
  "wss://relay.damus.io",
@@ -161,7 +288,7 @@ function createAttestationEvent(envelope, pubkey) {
161
288
  async function publishToRelays(event, relays = DEFAULT_RELAYS) {
162
289
  const success = [];
163
290
  const failed = [];
164
- log.info({ eventId: event.id, relayCount: relays.length }, "Publishing event to relays");
291
+ log2.info({ eventId: event.id, relayCount: relays.length }, "Publishing event to relays");
165
292
  const deadlineAt = Date.now() + FANOUT_DEADLINE_MS;
166
293
  const publishPromises = relays.map(async (relayUrl) => {
167
294
  let ws = null;
@@ -200,7 +327,7 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
200
327
  cleanup();
201
328
  resolve();
202
329
  } else {
203
- log.warn(
330
+ log2.warn(
204
331
  { relay: relayUrl, reason: data[3] },
205
332
  "Relay rejected event"
206
333
  );
@@ -210,7 +337,7 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
210
337
  }
211
338
  }
212
339
  } catch (err) {
213
- log.error(
340
+ log2.error(
214
341
  { relay: relayUrl, error: err },
215
342
  "Failed to parse relay response"
216
343
  );
@@ -220,7 +347,7 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
220
347
  }
221
348
  };
222
349
  wsRef.onerror = (err) => {
223
- log.error({ relay: relayUrl, error: err }, "WebSocket error");
350
+ log2.error({ relay: relayUrl, error: err }, "WebSocket error");
224
351
  recordFailure();
225
352
  cleanup();
226
353
  reject(err);
@@ -230,7 +357,7 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
230
357
  };
231
358
  });
232
359
  } catch (err) {
233
- log.error({ relay: relayUrl, error: err }, "Failed to publish to relay");
360
+ log2.error({ relay: relayUrl, error: err }, "Failed to publish to relay");
234
361
  recordFailure();
235
362
  } finally {
236
363
  if (ws && ws.readyState !== WebSocket.CLOSED) {
@@ -239,12 +366,12 @@ async function publishToRelays(event, relays = DEFAULT_RELAYS) {
239
366
  }
240
367
  });
241
368
  await Promise.allSettled(publishPromises);
242
- log.info({ successCount: success.length, failedCount: failed.length }, "Publishing complete");
369
+ log2.info({ successCount: success.length, failedCount: failed.length }, "Publishing complete");
243
370
  return { success, failed };
244
371
  }
245
372
  async function queryByAttestationId(attestationId, relays = DEFAULT_RELAYS) {
246
373
  const events = [];
247
- log.info({ attestationId, relayCount: relays.length }, "Querying relays for attestation");
374
+ log2.info({ attestationId, relayCount: relays.length }, "Querying relays for attestation");
248
375
  const deadlineAt = Date.now() + FANOUT_DEADLINE_MS;
249
376
  const queryPromises = relays.map(async (relayUrl) => {
250
377
  let ws = null;
@@ -284,11 +411,11 @@ async function queryByAttestationId(attestationId, relays = DEFAULT_RELAYS) {
284
411
  resolve();
285
412
  }
286
413
  } catch (err) {
287
- log.error({ relay: relayUrl, error: err }, "Failed to parse event");
414
+ log2.error({ relay: relayUrl, error: err }, "Failed to parse event");
288
415
  }
289
416
  };
290
417
  wsRef.onerror = (err) => {
291
- log.error({ relay: relayUrl, error: err }, "WebSocket error during query");
418
+ log2.error({ relay: relayUrl, error: err }, "WebSocket error during query");
292
419
  cleanup();
293
420
  reject(err);
294
421
  };
@@ -297,7 +424,7 @@ async function queryByAttestationId(attestationId, relays = DEFAULT_RELAYS) {
297
424
  };
298
425
  });
299
426
  } catch (err) {
300
- log.error({ relay: relayUrl, error: err }, "Failed to query relay");
427
+ log2.error({ relay: relayUrl, error: err }, "Failed to query relay");
301
428
  } finally {
302
429
  if (ws && ws.readyState !== WebSocket.CLOSED) {
303
430
  ws.close();
@@ -305,12 +432,12 @@ async function queryByAttestationId(attestationId, relays = DEFAULT_RELAYS) {
305
432
  }
306
433
  });
307
434
  await Promise.allSettled(queryPromises);
308
- log.info({ eventCount: events.length }, "Query complete");
435
+ log2.info({ eventCount: events.length }, "Query complete");
309
436
  return events;
310
437
  }
311
438
  async function queryByAddress(address, relays = DEFAULT_RELAYS) {
312
439
  const events = [];
313
- log.info({ address, relayCount: relays.length }, "Querying relays for address");
440
+ log2.info({ address, relayCount: relays.length }, "Querying relays for address");
314
441
  const deadlineAt = Date.now() + FANOUT_DEADLINE_MS;
315
442
  const queryPromises = relays.map(async (relayUrl) => {
316
443
  try {
@@ -352,28 +479,28 @@ async function queryByAddress(address, relays = DEFAULT_RELAYS) {
352
479
  resolve();
353
480
  }
354
481
  } catch (err) {
355
- log.error({ relay: relayUrl, error: err }, "Failed to parse event");
482
+ log2.error({ relay: relayUrl, error: err }, "Failed to parse event");
356
483
  }
357
484
  };
358
485
  ws.onerror = (err) => {
359
486
  clearTimeout(timeout);
360
- log.error({ relay: relayUrl, error: err }, "WebSocket error during query");
487
+ log2.error({ relay: relayUrl, error: err }, "WebSocket error during query");
361
488
  reject(err);
362
489
  };
363
490
  });
364
491
  } catch (err) {
365
- log.error({ relay: relayUrl, error: err }, "Failed to query relay");
492
+ log2.error({ relay: relayUrl, error: err }, "Failed to query relay");
366
493
  }
367
494
  });
368
495
  await Promise.allSettled(queryPromises);
369
- log.info({ eventCount: events.length }, "Query complete");
496
+ log2.info({ eventCount: events.length }, "Query complete");
370
497
  return events;
371
498
  }
372
499
  async function queryByIdentity(protocol, identifier, relays = DEFAULT_RELAYS) {
373
500
  const events = [];
374
501
  const identityTag = `${protocol}:${identifier}`;
375
502
  const identityTags = protocol === "nostr" ? nostrIdentifierForms(identifier).map((f) => `nostr:${f}`) : [identityTag];
376
- log.info({ protocol, identifier, relayCount: relays.length }, "Querying relays for identity");
503
+ log2.info({ protocol, identifier, relayCount: relays.length }, "Querying relays for identity");
377
504
  const deadlineAt = Date.now() + FANOUT_DEADLINE_MS;
378
505
  const queryPromises = relays.map(async (relayUrl) => {
379
506
  try {
@@ -408,21 +535,21 @@ async function queryByIdentity(protocol, identifier, relays = DEFAULT_RELAYS) {
408
535
  resolve();
409
536
  }
410
537
  } catch (err) {
411
- log.error({ relay: relayUrl, error: err }, "Failed to parse event");
538
+ log2.error({ relay: relayUrl, error: err }, "Failed to parse event");
412
539
  }
413
540
  };
414
541
  ws.onerror = (err) => {
415
542
  clearTimeout(timeout);
416
- log.error({ relay: relayUrl, error: err }, "WebSocket error during query");
543
+ log2.error({ relay: relayUrl, error: err }, "WebSocket error during query");
417
544
  reject(err);
418
545
  };
419
546
  });
420
547
  } catch (err) {
421
- log.error({ relay: relayUrl, error: err }, "Failed to query relay");
548
+ log2.error({ relay: relayUrl, error: err }, "Failed to query relay");
422
549
  }
423
550
  });
424
551
  await Promise.allSettled(queryPromises);
425
- log.info({ eventCount: events.length }, "Query complete");
552
+ log2.info({ eventCount: events.length }, "Query complete");
426
553
  return events;
427
554
  }
428
555
  async function verifyAttestationEnvelope(envelope) {
@@ -434,22 +561,74 @@ async function verifyAttestationEnvelope(envelope) {
434
561
  const computedId = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
435
562
  return computedId === envelope.attestation_id;
436
563
  } catch (err) {
437
- log.error({ error: err }, "Failed to verify attestation envelope");
564
+ log2.error({ error: err }, "Failed to verify attestation envelope");
438
565
  return false;
439
566
  }
440
567
  }
568
+ function base64Url(text) {
569
+ const base64 = btoa(String.fromCharCode(...new TextEncoder().encode(text)));
570
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
571
+ }
572
+ function signedEnvelope(envelope) {
573
+ let parsed;
574
+ try {
575
+ parsed = parseCanonicalMessage(envelope.message);
576
+ } catch {
577
+ return null;
578
+ }
579
+ if (!parsed.core.address || rfc3339Ms(parsed.core.issued_at) === null) return null;
580
+ const { expires_at: _copy, ...rest } = envelope;
581
+ return {
582
+ ...rest,
583
+ address: parsed.core.address,
584
+ identities: parsed.core.identities,
585
+ issued_at: parsed.core.issued_at,
586
+ ...parsed.expires !== void 0 ? { expires_at: parsed.expires } : {},
587
+ message_b64url: base64Url(envelope.message)
588
+ };
589
+ }
590
+ async function collectSignedEnvelopes(events, accept = () => true) {
591
+ const copies = /* @__PURE__ */ new Map();
592
+ for (const event of events) {
593
+ const raw = parseAttestationFromEvent(event);
594
+ if (!raw || !await verifyAttestationEnvelope(raw)) continue;
595
+ const envelope = signedEnvelope(raw);
596
+ if (!envelope || !accept(event, envelope)) continue;
597
+ const same = copies.get(envelope.attestation_id) ?? [];
598
+ if (!same.some((e) => e.signature === envelope.signature && e.scheme === envelope.scheme)) {
599
+ same.push(envelope);
600
+ }
601
+ copies.set(envelope.attestation_id, same);
602
+ }
603
+ const kept = [];
604
+ for (const same of copies.values()) {
605
+ if (same.length === 1) {
606
+ kept.push(same[0]);
607
+ continue;
608
+ }
609
+ let valid;
610
+ for (const e of same) {
611
+ if (await signatureIsValid({ addr: e.address, msg: e.message, sig: e.signature, scheme: e.scheme })) {
612
+ valid = e;
613
+ break;
614
+ }
615
+ }
616
+ kept.push(valid ?? same[0]);
617
+ }
618
+ return kept;
619
+ }
441
620
  function parseAttestationFromEvent(event) {
442
621
  try {
443
622
  const envelope = JSON.parse(event.content);
444
623
  return envelope;
445
624
  } catch (err) {
446
- log.error({ eventId: event.id, error: err }, "Failed to parse attestation from event");
625
+ log2.error({ eventId: event.id, error: err }, "Failed to parse attestation from event");
447
626
  return null;
448
627
  }
449
628
  }
450
629
 
451
630
  // src/nostr-crypto.ts
452
- var log2 = createLogger("ocp/nostr-crypto");
631
+ var log3 = createLogger("ocp/nostr-crypto");
453
632
  function isNip07Available() {
454
633
  if (typeof window === "undefined") {
455
634
  return false;
@@ -458,22 +637,22 @@ function isNip07Available() {
458
637
  }
459
638
  async function signNostrEvent(event) {
460
639
  if (!isNip07Available()) {
461
- log2.warn("NIP-07 extension not available");
640
+ log3.warn("NIP-07 extension not available");
462
641
  return null;
463
642
  }
464
643
  try {
465
644
  const nostr = window.nostr;
466
645
  const signedEvent = await nostr.signEvent(event);
467
- log2.info({ eventId: signedEvent.id }, "Signed Nostr event with NIP-07");
646
+ log3.info({ eventId: signedEvent.id }, "Signed Nostr event with NIP-07");
468
647
  return signedEvent;
469
648
  } catch (err) {
470
- log2.error({ error: err }, "Failed to sign Nostr event");
649
+ log3.error({ error: err }, "Failed to sign Nostr event");
471
650
  return null;
472
651
  }
473
652
  }
474
653
 
475
654
  // src/attestation.ts
476
- var log3 = createLogger("ocp/attestation");
655
+ var log4 = createLogger("ocp/attestation");
477
656
  var AttestationError = class extends Error {
478
657
  constructor(message, code) {
479
658
  super(message);
@@ -483,7 +662,7 @@ var AttestationError = class extends Error {
483
662
  };
484
663
  async function createAttestation(options) {
485
664
  const { message, signature, scheme, address, identities = [], extensions = {} } = options;
486
- log3.info({ address, identityCount: identities.length }, "Creating attestation");
665
+ log4.info({ address, identityCount: identities.length }, "Creating attestation");
487
666
  const envelope = await createAttestationEnvelope(
488
667
  message,
489
668
  signature,
@@ -499,29 +678,29 @@ async function createAttestation(options) {
499
678
  "INTEGRITY_CHECK_FAILED"
500
679
  );
501
680
  }
502
- log3.info({ attestationId: envelope.attestation_id }, "Attestation created successfully");
681
+ log4.info({ attestationId: envelope.attestation_id }, "Attestation created successfully");
503
682
  return envelope;
504
683
  }
505
684
  async function publishAttestation(options) {
506
685
  const { envelope, npub, relays = DEFAULT_RELAYS } = options;
507
- log3.info(
686
+ log4.info(
508
687
  { attestationId: envelope.attestation_id, relayCount: relays.length },
509
688
  "Publishing attestation"
510
689
  );
511
690
  const unsignedEvent = createAttestationEvent(envelope, npub);
512
691
  if (!isNip07Available()) {
513
- log3.warn("NIP-07 unavailable \u2014 skipping Nostr publish");
692
+ log4.warn("NIP-07 unavailable \u2014 skipping Nostr publish");
514
693
  throw new Error(
515
694
  "nostr_signer_unavailable: install a NIP-07 extension (e.g. nos2x, Alby) to publish"
516
695
  );
517
696
  }
518
- log3.info("Using NIP-07 to sign event");
697
+ log4.info("Using NIP-07 to sign event");
519
698
  const signedEvent = await signNostrEvent(unsignedEvent);
520
699
  if (!signedEvent) {
521
700
  throw new Error("nostr_signing_failed: NIP-07 extension rejected or errored");
522
701
  }
523
702
  const result = await publishToRelays(signedEvent, relays);
524
- log3.info(
703
+ log4.info(
525
704
  {
526
705
  attestationId: envelope.attestation_id,
527
706
  successCount: result.success.length,
@@ -541,49 +720,34 @@ async function discoverAttestations(options) {
541
720
  const { attestationId, address, identity, relays = DEFAULT_RELAYS } = options;
542
721
  let events = [];
543
722
  if (attestationId) {
544
- log3.info({ attestationId }, "Discovering by attestation ID");
723
+ log4.info({ attestationId }, "Discovering by attestation ID");
545
724
  events = await queryByAttestationId(attestationId, relays);
546
725
  } else if (address) {
547
- log3.info({ address }, "Discovering by Bitcoin address");
726
+ log4.info({ address }, "Discovering by Bitcoin address");
548
727
  events = await queryByAddress(address, relays);
549
728
  } else if (identity) {
550
- log3.info({ identity }, "Discovering by identity");
729
+ log4.info({ identity }, "Discovering by identity");
551
730
  events = await queryByIdentity(identity.protocol, identity.identifier, relays);
552
731
  } else {
553
732
  throw new Error("Must provide attestationId, address, or identity");
554
733
  }
555
- const envelopes = [];
556
- const kept = /* @__PURE__ */ new Set();
557
- for (const event of events) {
558
- const envelope = parseAttestationFromEvent(event);
559
- if (envelope && kept.has(envelope.attestation_id)) continue;
560
- if (envelope && !eventIndexesEnvelope(event, envelope)) {
561
- log3.warn({ eventId: event.id }, "Skipping event whose index tags disagree with its envelope");
562
- } else if (envelope) {
563
- const isValid = await verifyAttestationEnvelope(envelope);
564
- if (isValid) {
565
- kept.add(envelope.attestation_id);
566
- envelopes.push(envelope);
567
- } else {
568
- log3.warn(
569
- { attestationId: envelope.attestation_id },
570
- "Skipping invalid attestation envelope"
571
- );
572
- }
573
- }
574
- }
575
- log3.info({ eventCount: events.length, validCount: envelopes.length }, "Discovery complete");
734
+ const envelopes = await collectSignedEnvelopes(events, (event, envelope) => {
735
+ if (eventIndexesEnvelope(event, envelope)) return true;
736
+ log4.warn({ eventId: event.id }, "Skipping event whose index tags disagree with its envelope");
737
+ return false;
738
+ });
739
+ log4.info({ eventCount: events.length, validCount: envelopes.length }, "Discovery complete");
576
740
  return envelopes;
577
741
  }
578
742
  async function verifyAttestationById(attestationId, relays = DEFAULT_RELAYS) {
579
- log3.info({ attestationId }, "Verifying attestation by ID");
743
+ log4.info({ attestationId }, "Verifying attestation by ID");
580
744
  const envelopes = await discoverAttestations({ attestationId, relays });
581
745
  if (envelopes.length === 0) {
582
- log3.warn({ attestationId }, "Attestation not found on any relay");
746
+ log4.warn({ attestationId }, "Attestation not found on any relay");
583
747
  return null;
584
748
  }
585
749
  if (envelopes.length > 1) {
586
- log3.warn(
750
+ log4.warn(
587
751
  { attestationId, count: envelopes.length },
588
752
  "Multiple attestations found with same ID - using first"
589
753
  );
@@ -591,11 +755,11 @@ async function verifyAttestationById(attestationId, relays = DEFAULT_RELAYS) {
591
755
  return envelopes[0] || null;
592
756
  }
593
757
  async function getAttestationsForAddress(address, relays = DEFAULT_RELAYS) {
594
- log3.info({ address }, "Getting all attestations for address");
758
+ log4.info({ address }, "Getting all attestations for address");
595
759
  return discoverAttestations({ address, relays });
596
760
  }
597
761
  async function getAttestationsForIdentity(protocol, identifier, relays = DEFAULT_RELAYS) {
598
- log3.info({ protocol, identifier }, "Getting all attestations for identity");
762
+ log4.info({ protocol, identifier }, "Getting all attestations for identity");
599
763
  return discoverAttestations({ identity: { protocol, identifier }, relays });
600
764
  }
601
765
  function formatIdentitiesForDisplay(identities) {