@orangecheck/sdk 1.10.0 → 1.12.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/index.js CHANGED
@@ -2,30 +2,10 @@
2
2
 
3
3
  var base = require('@scure/base');
4
4
  var buffer = require('buffer');
5
- var bip322Js = require('bip322-js');
6
- var bitcoinMessage = require('bitcoinjs-message');
7
- var secp256k1_js = require('@noble/curves/secp256k1.js');
5
+ var bip322 = require('@orangecheck/bip322');
8
6
  var sha2_js = require('@noble/hashes/sha2.js');
9
-
10
- function _interopNamespace(e) {
11
- if (e && e.__esModule) return e;
12
- var n = Object.create(null);
13
- if (e) {
14
- Object.keys(e).forEach(function (k) {
15
- if (k !== 'default') {
16
- var d = Object.getOwnPropertyDescriptor(e, k);
17
- Object.defineProperty(n, k, d.get ? d : {
18
- enumerable: true,
19
- get: function () { return e[k]; }
20
- });
21
- }
22
- });
23
- }
24
- n.default = e;
25
- return Object.freeze(n);
26
- }
27
-
28
- var bitcoinMessage__namespace = /*#__PURE__*/_interopNamespace(bitcoinMessage);
7
+ var utils_js = require('@noble/hashes/utils.js');
8
+ var secp256k1_js = require('@noble/curves/secp256k1.js');
29
9
 
30
10
  // src/canonical.ts
31
11
  function toLowerHex(bytes) {
@@ -883,87 +863,79 @@ async function verifySignature({
883
863
  sig,
884
864
  scheme
885
865
  }) {
886
- try {
887
- const detectedScheme = scheme || detectSignatureScheme(addr, sig);
866
+ const detectedScheme = scheme || detectSignatureScheme(addr, sig);
867
+ log4.debug(
868
+ { addr, msgLength: msg.length, sigLength: sig.length, scheme: detectedScheme },
869
+ "Verifying signature"
870
+ );
871
+ if (detectedScheme === "bip322") {
872
+ const sigBase64 = toBase64Maybe(sig);
888
873
  log4.debug(
889
- { addr, msgLength: msg.length, sigLength: sig.length, scheme: detectedScheme },
890
- "Verifying signature"
874
+ { sigBase64: sigBase64.substring(0, 50) + "..." },
875
+ "Signature converted to base64"
891
876
  );
892
- if (detectedScheme === "bip322") {
893
- const sigBase64 = toBase64Maybe(sig);
894
- log4.debug(
895
- { sigBase64: sigBase64.substring(0, 50) + "..." },
896
- "Signature converted to base64"
897
- );
898
- log4.debug(
899
- {
900
- msgFull: msg,
901
- msgLines: msg.split("\n").length,
902
- msgFirstLine: msg.split("\n")[0],
903
- msgLastLine: msg.split("\n")[msg.split("\n").length - 1]
904
- },
905
- "Message being verified"
906
- );
907
- const ok = bip322Js.Verifier.verifySignature(addr, msg, sigBase64);
908
- log4.info({ addr, ok }, "BIP-322 verification result");
909
- if (!ok) {
910
- const isSegWit = addr.startsWith("bc1") || addr.startsWith("tb1");
911
- if (isSegWit && sigBase64.length === 88) {
912
- log4.warn(
913
- { addr, wallet: "possibly Electrum", sigLength: sigBase64.length },
914
- "BIP-322 verification failed - likely Electrum wallet (does not support BIP-322 for SegWit)"
915
- );
916
- } else {
917
- log4.error(
918
- {
919
- addr,
920
- sigLength: sigBase64.length,
921
- msgLength: msg.length,
922
- msgPreview: msg.substring(0, 200)
923
- },
924
- "BIP-322 verification failed - signature does not match message"
925
- );
926
- }
927
- }
928
- return ok ? "sig_ok_bip322" : "sig_invalid";
929
- }
930
- if (detectedScheme === "legacy") {
931
- const sigBase64 = toBase64Maybe(sig);
932
- if (!addr.startsWith("1") && !addr.startsWith("m") && !addr.startsWith("n")) {
933
- log4.warn({ addr }, "Legacy signature attempted on non-P2PKH address");
934
- return "sig_unsupported_script";
935
- }
936
- log4.debug(
937
- {
938
- addr,
939
- sigBase64: sigBase64.substring(0, 50) + "...",
940
- msgPreview: msg.substring(0, 100) + "...",
941
- msgLength: msg.length
942
- },
943
- "Verifying legacy signature"
944
- );
945
- const ok = bitcoinMessage__namespace.verify(msg, addr, sigBase64);
946
- log4.info({ addr, ok, sigBase64Length: sigBase64.length }, "Legacy verification result");
947
- if (!ok) {
877
+ log4.debug(
878
+ {
879
+ msgFull: msg,
880
+ msgLines: msg.split("\n").length,
881
+ msgFirstLine: msg.split("\n")[0],
882
+ msgLastLine: msg.split("\n")[msg.split("\n").length - 1]
883
+ },
884
+ "Message being verified"
885
+ );
886
+ const ok = bip322.verifySignature(addr, msg, sigBase64);
887
+ log4.info({ addr, ok }, "BIP-322 verification result");
888
+ if (!ok) {
889
+ const isSegWit = addr.startsWith("bc1") || addr.startsWith("tb1");
890
+ if (isSegWit && sigBase64.length === 88) {
891
+ log4.warn(
892
+ { addr, wallet: "possibly Electrum", sigLength: sigBase64.length },
893
+ "BIP-322 verification failed - likely Electrum wallet (does not support BIP-322 for SegWit)"
894
+ );
895
+ } else {
948
896
  log4.error(
949
897
  {
950
898
  addr,
951
- msgFirstLine: msg.split("\n")[0],
952
- sigFormat: sigBase64.substring(0, 10)
899
+ sigLength: sigBase64.length,
900
+ msgLength: msg.length,
901
+ msgPreview: msg.substring(0, 200)
953
902
  },
954
- "Legacy signature verification failed - check message format and signature"
903
+ "BIP-322 verification failed - signature does not match message"
955
904
  );
956
905
  }
957
- return ok ? "sig_ok_legacy" : "sig_invalid";
958
906
  }
959
- return "invalid_scheme";
960
- } catch (err) {
961
- log4.error(
962
- { addr, error: err instanceof Error ? err.message : String(err) },
963
- "Signature verification error"
907
+ return ok ? "sig_ok_bip322" : "sig_invalid";
908
+ }
909
+ if (detectedScheme === "legacy") {
910
+ const sigBase64 = toBase64Maybe(sig);
911
+ if (!addr.startsWith("1") && !addr.startsWith("m") && !addr.startsWith("n")) {
912
+ log4.warn({ addr }, "Legacy signature attempted on non-P2PKH address");
913
+ return "sig_unsupported_script";
914
+ }
915
+ log4.debug(
916
+ {
917
+ addr,
918
+ sigBase64: sigBase64.substring(0, 50) + "...",
919
+ msgPreview: msg.substring(0, 100) + "...",
920
+ msgLength: msg.length
921
+ },
922
+ "Verifying legacy signature"
964
923
  );
965
- return "sig_invalid";
924
+ const ok = bip322.verifySignature(addr, msg, sigBase64);
925
+ log4.info({ addr, ok, sigBase64Length: sigBase64.length }, "Legacy verification result");
926
+ if (!ok) {
927
+ log4.error(
928
+ {
929
+ addr,
930
+ msgFirstLine: msg.split("\n")[0],
931
+ sigFormat: sigBase64.substring(0, 10)
932
+ },
933
+ "Legacy signature verification failed - check message format and signature"
934
+ );
935
+ }
936
+ return ok ? "sig_ok_legacy" : "sig_invalid";
966
937
  }
938
+ return "invalid_scheme";
967
939
  }
968
940
  function parseCanonicalMessage(msg) {
969
941
  const lines = msg.split("\n").map((l) => l.trim());
@@ -1055,7 +1027,7 @@ async function getAddressUtxos(address, network, opts) {
1055
1027
  log4.error({ endpoints, error: lastError?.message, network }, "All Esplora endpoints failed");
1056
1028
  throw new Error(`esplora_all_failed: ${lastError?.message || "unknown"}`);
1057
1029
  }
1058
- function computeMetrics(utxos, bondAmount) {
1030
+ function computeMetrics(utxos, bondAmount, coverSats) {
1059
1031
  const confirmedUtxos = utxos.filter((u) => u.status.confirmed);
1060
1032
  if (confirmedUtxos.length === 0) {
1061
1033
  return { sats_bonded: 0, days_unspent: 0, confirmed_balance: 0 };
@@ -1088,13 +1060,30 @@ function computeMetrics(utxos, bondAmount) {
1088
1060
  };
1089
1061
  }
1090
1062
  const sats_bonded = confirmed_balance;
1063
+ if (coverSats !== void 0 && coverSats > 0) {
1064
+ const sorted = [...confirmedUtxos].sort(
1065
+ (a, b) => (a.status.block_height ?? Infinity) - (b.status.block_height ?? Infinity)
1066
+ );
1067
+ let sum = 0;
1068
+ let youngestTime = 0;
1069
+ for (const utxo of sorted) {
1070
+ sum += utxo.value;
1071
+ youngestTime = Math.max(youngestTime, utxo.status.block_time || Date.now() / 1e3);
1072
+ if (sum >= coverSats) break;
1073
+ }
1074
+ const days_unspent2 = Math.max(
1075
+ 0,
1076
+ Math.floor((Date.now() / 1e3 - youngestTime) / (24 * 60 * 60))
1077
+ );
1078
+ return { sats_bonded, days_unspent: days_unspent2, confirmed_balance };
1079
+ }
1091
1080
  const oldestTime = Math.min(
1092
1081
  ...confirmedUtxos.map((u) => u.status.block_time || Date.now() / 1e3)
1093
1082
  );
1094
1083
  const days_unspent = Math.max(0, Math.floor((Date.now() / 1e3 - oldestTime) / (24 * 60 * 60)));
1095
1084
  return { sats_bonded, days_unspent, confirmed_balance };
1096
1085
  }
1097
- async function verify2(input, opts = {}) {
1086
+ async function verify(input, opts = {}) {
1098
1087
  const codes = [];
1099
1088
  let network = "mainnet";
1100
1089
  try {
@@ -1151,7 +1140,8 @@ async function verify2(input, opts = {}) {
1151
1140
  });
1152
1141
  const { sats_bonded, days_unspent, confirmed_balance } = computeMetrics(
1153
1142
  utxos,
1154
- parsed.bond
1143
+ parsed.bond,
1144
+ opts.coverSats
1155
1145
  );
1156
1146
  if (parsed.bond !== void 0 && parsed.bond > 0) {
1157
1147
  if (confirmed_balance < parsed.bond) {
@@ -1249,14 +1239,14 @@ async function check(params) {
1249
1239
  return { ok: false, sats: 0, days: 0, score: 0, reasons: ["not_found"] };
1250
1240
  }
1251
1241
  const shared = identity ? await backsOtherIdentity(env, identity, relays) : false;
1252
- const outcome = await verify2(
1242
+ const outcome = await verify(
1253
1243
  {
1254
1244
  addr: env.address,
1255
1245
  msg: env.message,
1256
1246
  sig: env.signature,
1257
1247
  scheme: env.scheme
1258
1248
  },
1259
- verifyOptions
1249
+ { ...verifyOptions, coverSats: minSats > 0 ? minSats : void 0 }
1260
1250
  );
1261
1251
  const sats = outcome.metrics?.sats_bonded ?? 0;
1262
1252
  const days = outcome.metrics?.days_unspent ?? 0;
@@ -1437,21 +1427,17 @@ async function verifyChallenge(opts) {
1437
1427
  return { ok: false, reason: "purpose_mismatch" };
1438
1428
  }
1439
1429
  const scheme = opts.scheme ?? "bip322";
1440
- let sigValid = false;
1441
- try {
1442
- if (scheme === "bip322") {
1443
- const sigBase64 = /^[0-9a-fA-F]+$/.test(opts.signature) && opts.signature.length % 2 === 0 ? buffer.Buffer.from(opts.signature, "hex").toString("base64") : opts.signature;
1444
- sigValid = bip322Js.Verifier.verifySignature(address, opts.message, sigBase64);
1445
- } else if (scheme === "legacy") {
1446
- if (!/^[1m][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address)) {
1447
- return { ok: false, reason: "sig_unsupported_scheme" };
1448
- }
1449
- sigValid = bitcoinMessage__namespace.verify(opts.message, address, opts.signature);
1450
- } else {
1430
+ let sigValid;
1431
+ if (scheme === "bip322") {
1432
+ const sigBase64 = /^[0-9a-fA-F]+$/.test(opts.signature) && opts.signature.length % 2 === 0 ? buffer.Buffer.from(opts.signature, "hex").toString("base64") : opts.signature;
1433
+ sigValid = bip322.verifySignature(address, opts.message, sigBase64);
1434
+ } else if (scheme === "legacy") {
1435
+ if (!/^[1m][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address)) {
1451
1436
  return { ok: false, reason: "sig_unsupported_scheme" };
1452
1437
  }
1453
- } catch {
1454
- sigValid = false;
1438
+ sigValid = bip322.verifySignature(address, opts.message, opts.signature);
1439
+ } else {
1440
+ return { ok: false, reason: "sig_unsupported_scheme" };
1455
1441
  }
1456
1442
  if (!sigValid) return { ok: false, reason: "sig_invalid" };
1457
1443
  return {
@@ -1464,6 +1450,164 @@ async function verifyChallenge(opts) {
1464
1450
  ...purpose !== void 0 ? { purpose } : {}
1465
1451
  };
1466
1452
  }
1453
+ var HEADER = "orangecheck-bond";
1454
+ var ACK = "I pledge this coin to back this subject. It stays in my wallet.";
1455
+ var FIELDS = ["address", "outpoint", "subject", "nonce", "issued_at", "expires_at"];
1456
+ var BOND_SATS_FLOORS = [1e3, 1e4, 1e5, 1e6, 1e7];
1457
+ var BOND_DAYS_FLOORS = [7, 30, 90, 365];
1458
+ var BOND_MIN_CONFIRMATIONS = 6;
1459
+ var OUTPOINT_RE = /^[0-9a-f]{64}:(0|[1-9][0-9]{0,9})$/;
1460
+ var NONCE_RE = /^[0-9a-f]{32}$/;
1461
+ var TIME_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/;
1462
+ var SUBJECT_RE = /^[\x21-\x7e]{1,256}$/;
1463
+ function iso2(d) {
1464
+ return d.toISOString().replace(/\.\d{3}Z$/, "Z");
1465
+ }
1466
+ function randomNonce2() {
1467
+ const b = new Uint8Array(16);
1468
+ globalThis.crypto.getRandomValues(b);
1469
+ return utils_js.bytesToHex(b);
1470
+ }
1471
+ function wellFormed(f) {
1472
+ return bip322.decodeAddress(f.address) !== null && OUTPOINT_RE.test(f.outpoint) && SUBJECT_RE.test(f.subject) && NONCE_RE.test(f.nonce) && TIME_RE.test(f.issued_at) && TIME_RE.test(f.expires_at) && Date.parse(f.expires_at) > Date.parse(f.issued_at);
1473
+ }
1474
+ function buildBondMessage(fields) {
1475
+ if (!wellFormed(fields)) throw new Error("bond fields are malformed");
1476
+ return [HEADER, ...FIELDS.map((k) => `${k}: ${fields[k]}`), `ack: ${ACK}`].join("\n") + "\n";
1477
+ }
1478
+ function issueBondMessage(opts) {
1479
+ const now = opts.now ?? /* @__PURE__ */ new Date();
1480
+ const expires = new Date(now.getTime() + (opts.ttlSeconds ?? 600) * 1e3);
1481
+ const nonce = randomNonce2();
1482
+ const message = buildBondMessage({
1483
+ address: opts.address,
1484
+ outpoint: opts.outpoint,
1485
+ subject: opts.subject,
1486
+ nonce,
1487
+ issued_at: iso2(now),
1488
+ expires_at: iso2(expires)
1489
+ });
1490
+ return { message, nonce, expiresAt: expires.getTime() };
1491
+ }
1492
+ function parseBondMessage(message) {
1493
+ if (!message.endsWith("\n") || message.includes("\r")) return null;
1494
+ const lines = message.slice(0, -1).split("\n");
1495
+ if (lines.length !== FIELDS.length + 2 || lines[0] !== HEADER) return null;
1496
+ if (lines[lines.length - 1] !== `ack: ${ACK}`) return null;
1497
+ const out = {};
1498
+ for (const [i, key] of FIELDS.entries()) {
1499
+ const line = lines[i + 1];
1500
+ const prefix = `${key}: `;
1501
+ if (!line.startsWith(prefix)) return null;
1502
+ out[key] = line.slice(prefix.length);
1503
+ }
1504
+ const fields = out;
1505
+ return wellFormed(fields) && buildBondMessage(fields) === message ? fields : null;
1506
+ }
1507
+ function bondId(message) {
1508
+ return utils_js.bytesToHex(sha2_js.sha256(utils_js.utf8ToBytes(message)));
1509
+ }
1510
+ function bondNullifier(audience, outpoint) {
1511
+ return utils_js.bytesToHex(sha2_js.sha256(utils_js.utf8ToBytes(`orangecheck-bond-nullifier
1512
+ ${audience}
1513
+ ${outpoint}`)));
1514
+ }
1515
+ function bondFloors(sats, ageBlocks) {
1516
+ const days = Math.floor(ageBlocks / 144);
1517
+ const floor = (ladder, v) => ladder.filter((f) => v >= f).reduce((a, b) => Math.max(a, b), 0);
1518
+ return { sats_floor: floor(BOND_SATS_FLOORS, sats), days_floor: floor(BOND_DAYS_FLOORS, days) };
1519
+ }
1520
+ function verifyBondSignature(opts) {
1521
+ const fields = parseBondMessage(opts.message);
1522
+ if (!fields) return { ok: false, reason: "bond_malformed" };
1523
+ if (opts.subject !== void 0 && fields.subject !== opts.subject) {
1524
+ return { ok: false, reason: "bond_subject_mismatch" };
1525
+ }
1526
+ const now = (opts.now ?? /* @__PURE__ */ new Date()).getTime();
1527
+ const skew = (opts.skewSeconds ?? 60) * 1e3;
1528
+ if (Date.parse(fields.issued_at) - skew > now) return { ok: false, reason: "bond_not_yet_valid" };
1529
+ if (Date.parse(fields.expires_at) + skew < now) return { ok: false, reason: "bond_expired" };
1530
+ if (!bip322.verifySignature(fields.address, opts.message, opts.signature)) {
1531
+ return { ok: false, reason: "sig_invalid" };
1532
+ }
1533
+ return { ok: true, fields, bond_id: bondId(opts.message) };
1534
+ }
1535
+ async function checkBondCoin(opts) {
1536
+ const decoded = bip322.decodeAddress(opts.address);
1537
+ if (!decoded || !OUTPOINT_RE.test(opts.outpoint)) return { ok: false, reason: "bond_malformed" };
1538
+ let coin;
1539
+ let tip;
1540
+ try {
1541
+ [coin, tip] = await Promise.all([opts.source.coin(opts.outpoint), opts.source.tip()]);
1542
+ } catch {
1543
+ return { ok: false, reason: "chain_unavailable" };
1544
+ }
1545
+ if (!coin) return { ok: false, reason: "coin_not_found" };
1546
+ if (coin.scriptPubKey !== utils_js.bytesToHex(decoded.scriptPubKey)) {
1547
+ return { ok: false, reason: "coin_address_mismatch" };
1548
+ }
1549
+ if (coin.confirmedHeight === null) return { ok: false, reason: "coin_unconfirmed" };
1550
+ if (coin.spent) return { ok: false, reason: "coin_spent" };
1551
+ const confirmations = tip.height - coin.confirmedHeight + 1;
1552
+ if (confirmations < (opts.minConfirmations ?? BOND_MIN_CONFIRMATIONS)) {
1553
+ return { ok: false, reason: "coin_too_recent" };
1554
+ }
1555
+ return { ok: true, sats: coin.sats, confirmed_height: coin.confirmedHeight, tip };
1556
+ }
1557
+ async function verifyBond(opts) {
1558
+ const sig = verifyBondSignature(opts);
1559
+ if (!sig.ok) return sig;
1560
+ const coin = await checkBondCoin({
1561
+ address: sig.fields.address,
1562
+ outpoint: sig.fields.outpoint,
1563
+ source: opts.source,
1564
+ minConfirmations: opts.minConfirmations
1565
+ });
1566
+ if (!coin.ok) return coin;
1567
+ return {
1568
+ ok: true,
1569
+ bond: {
1570
+ bond_id: sig.bond_id,
1571
+ subject: sig.fields.subject,
1572
+ address: sig.fields.address,
1573
+ outpoint: sig.fields.outpoint,
1574
+ sats: coin.sats,
1575
+ confirmed_height: coin.confirmed_height,
1576
+ tip: coin.tip
1577
+ }
1578
+ };
1579
+ }
1580
+ function esploraSource(base = "https://mempool.space/api", opts = {}) {
1581
+ const get = async (path) => {
1582
+ const r = await (opts.fetch ?? fetch)(`${base}${path}`, {
1583
+ signal: AbortSignal.timeout(opts.timeoutMs ?? 5e3)
1584
+ });
1585
+ if (!r.ok && r.status !== 404) throw new Error(`esplora ${path}: HTTP ${r.status}`);
1586
+ return r;
1587
+ };
1588
+ return {
1589
+ async tip() {
1590
+ const [h, hash] = await Promise.all([get("/blocks/tip/height"), get("/blocks/tip/hash")]);
1591
+ return { height: Number(await h.text()), hash: (await hash.text()).trim() };
1592
+ },
1593
+ async coin(outpoint) {
1594
+ const [txid, voutStr] = outpoint.split(":");
1595
+ const vout = Number(voutStr);
1596
+ const txr = await get(`/tx/${txid}`);
1597
+ if (txr.status === 404) return null;
1598
+ const tx = await txr.json();
1599
+ const out = tx.vout[vout];
1600
+ if (!out) return null;
1601
+ const spend = await (await get(`/tx/${txid}/outspend/${vout}`)).json();
1602
+ return {
1603
+ sats: out.value,
1604
+ scriptPubKey: out.scriptpubkey.toLowerCase(),
1605
+ confirmedHeight: tx.status.confirmed ? tx.status.block_height ?? null : null,
1606
+ spent: spend.spent
1607
+ };
1608
+ }
1609
+ };
1610
+ }
1467
1611
 
1468
1612
  // src/utils/rate-limiter.ts
1469
1613
  var RateLimitError = class extends Error {
@@ -2253,17 +2397,26 @@ var STATUS_META = {
2253
2397
  }
2254
2398
  };
2255
2399
 
2400
+ exports.BOND_DAYS_FLOORS = BOND_DAYS_FLOORS;
2401
+ exports.BOND_MIN_CONFIRMATIONS = BOND_MIN_CONFIRMATIONS;
2402
+ exports.BOND_SATS_FLOORS = BOND_SATS_FLOORS;
2256
2403
  exports.DEFAULT_RELAYS = DEFAULT_RELAYS;
2257
2404
  exports.FANOUT_DEADLINE_MS = FANOUT_DEADLINE_MS;
2258
2405
  exports.STATUS_META = STATUS_META;
2406
+ exports.bondFloors = bondFloors;
2407
+ exports.bondId = bondId;
2408
+ exports.bondNullifier = bondNullifier;
2409
+ exports.buildBondMessage = buildBondMessage;
2259
2410
  exports.buildCanonicalMessage = buildCanonicalMessage;
2260
2411
  exports.check = check;
2412
+ exports.checkBondCoin = checkBondCoin;
2261
2413
  exports.computeAllScores = computeAllScores;
2262
2414
  exports.computeScore = computeScore;
2263
2415
  exports.createAttestation = createAttestation;
2264
2416
  exports.createAttestationEnvelope = createAttestationEnvelope;
2265
2417
  exports.createAttestationEvent = createAttestationEvent;
2266
2418
  exports.discoverAttestations = discoverAttestations;
2419
+ exports.esploraSource = esploraSource;
2267
2420
  exports.extractAttestationIdFromUrl = extractAttestationIdFromUrl;
2268
2421
  exports.formatIdentities = formatIdentities;
2269
2422
  exports.formatIdentitiesForDisplay = formatIdentitiesForDisplay;
@@ -2293,10 +2446,12 @@ exports.isNip07Available = isNip07Available;
2293
2446
  exports.isNostrIdentityVerified = isNostrIdentityVerified;
2294
2447
  exports.isValidDomain = isValidDomain;
2295
2448
  exports.isValidTweetUrl = isValidTweetUrl;
2449
+ exports.issueBondMessage = issueBondMessage;
2296
2450
  exports.issueChallenge = issueChallenge;
2297
2451
  exports.nostrIdentifierForms = nostrIdentifierForms;
2298
2452
  exports.nostrPubkeyToHex = nostrPubkeyToHex;
2299
2453
  exports.parseAttestationFromEvent = parseAttestationFromEvent;
2454
+ exports.parseBondMessage = parseBondMessage;
2300
2455
  exports.parseIdentities = parseIdentities;
2301
2456
  exports.publishAttestation = publishAttestation;
2302
2457
  exports.publishToRelays = publishToRelays;
@@ -2307,9 +2462,11 @@ exports.queryRecent = queryRecent;
2307
2462
  exports.requiresManualVerification = requiresManualVerification;
2308
2463
  exports.signNostrEvent = signNostrEvent;
2309
2464
  exports.supportsAutomaticVerification = supportsAutomaticVerification;
2310
- exports.verify = verify2;
2465
+ exports.verify = verify;
2311
2466
  exports.verifyAllIdentities = verifyAllIdentities;
2312
2467
  exports.verifyAttestationById = verifyAttestationById;
2468
+ exports.verifyBond = verifyBond;
2469
+ exports.verifyBondSignature = verifyBondSignature;
2313
2470
  exports.verifyChallenge = verifyChallenge;
2314
2471
  exports.verifyDnsIdentity = verifyDnsIdentity;
2315
2472
  exports.verifyGitHubIdentity = verifyGitHubIdentity;