@orangecheck/sdk 1.9.0 → 1.11.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,31 +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');
5
+ var bip322 = require('@orangecheck/bip322');
7
6
  var secp256k1_js = require('@noble/curves/secp256k1.js');
8
7
  var sha2_js = require('@noble/hashes/sha2.js');
9
8
 
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);
29
-
30
9
  // src/canonical.ts
31
10
  function toLowerHex(bytes) {
32
11
  return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
@@ -883,87 +862,79 @@ async function verifySignature({
883
862
  sig,
884
863
  scheme
885
864
  }) {
886
- try {
887
- const detectedScheme = scheme || detectSignatureScheme(addr, sig);
865
+ const detectedScheme = scheme || detectSignatureScheme(addr, sig);
866
+ log4.debug(
867
+ { addr, msgLength: msg.length, sigLength: sig.length, scheme: detectedScheme },
868
+ "Verifying signature"
869
+ );
870
+ if (detectedScheme === "bip322") {
871
+ const sigBase64 = toBase64Maybe(sig);
888
872
  log4.debug(
889
- { addr, msgLength: msg.length, sigLength: sig.length, scheme: detectedScheme },
890
- "Verifying signature"
873
+ { sigBase64: sigBase64.substring(0, 50) + "..." },
874
+ "Signature converted to base64"
891
875
  );
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) {
876
+ log4.debug(
877
+ {
878
+ msgFull: msg,
879
+ msgLines: msg.split("\n").length,
880
+ msgFirstLine: msg.split("\n")[0],
881
+ msgLastLine: msg.split("\n")[msg.split("\n").length - 1]
882
+ },
883
+ "Message being verified"
884
+ );
885
+ const ok = bip322.verifySignature(addr, msg, sigBase64);
886
+ log4.info({ addr, ok }, "BIP-322 verification result");
887
+ if (!ok) {
888
+ const isSegWit = addr.startsWith("bc1") || addr.startsWith("tb1");
889
+ if (isSegWit && sigBase64.length === 88) {
890
+ log4.warn(
891
+ { addr, wallet: "possibly Electrum", sigLength: sigBase64.length },
892
+ "BIP-322 verification failed - likely Electrum wallet (does not support BIP-322 for SegWit)"
893
+ );
894
+ } else {
948
895
  log4.error(
949
896
  {
950
897
  addr,
951
- msgFirstLine: msg.split("\n")[0],
952
- sigFormat: sigBase64.substring(0, 10)
898
+ sigLength: sigBase64.length,
899
+ msgLength: msg.length,
900
+ msgPreview: msg.substring(0, 200)
953
901
  },
954
- "Legacy signature verification failed - check message format and signature"
902
+ "BIP-322 verification failed - signature does not match message"
955
903
  );
956
904
  }
957
- return ok ? "sig_ok_legacy" : "sig_invalid";
958
905
  }
959
- return "invalid_scheme";
960
- } catch (err) {
961
- log4.error(
962
- { addr, error: err instanceof Error ? err.message : String(err) },
963
- "Signature verification error"
906
+ return ok ? "sig_ok_bip322" : "sig_invalid";
907
+ }
908
+ if (detectedScheme === "legacy") {
909
+ const sigBase64 = toBase64Maybe(sig);
910
+ if (!addr.startsWith("1") && !addr.startsWith("m") && !addr.startsWith("n")) {
911
+ log4.warn({ addr }, "Legacy signature attempted on non-P2PKH address");
912
+ return "sig_unsupported_script";
913
+ }
914
+ log4.debug(
915
+ {
916
+ addr,
917
+ sigBase64: sigBase64.substring(0, 50) + "...",
918
+ msgPreview: msg.substring(0, 100) + "...",
919
+ msgLength: msg.length
920
+ },
921
+ "Verifying legacy signature"
964
922
  );
965
- return "sig_invalid";
923
+ const ok = bip322.verifySignature(addr, msg, sigBase64);
924
+ log4.info({ addr, ok, sigBase64Length: sigBase64.length }, "Legacy verification result");
925
+ if (!ok) {
926
+ log4.error(
927
+ {
928
+ addr,
929
+ msgFirstLine: msg.split("\n")[0],
930
+ sigFormat: sigBase64.substring(0, 10)
931
+ },
932
+ "Legacy signature verification failed - check message format and signature"
933
+ );
934
+ }
935
+ return ok ? "sig_ok_legacy" : "sig_invalid";
966
936
  }
937
+ return "invalid_scheme";
967
938
  }
968
939
  function parseCanonicalMessage(msg) {
969
940
  const lines = msg.split("\n").map((l) => l.trim());
@@ -1094,7 +1065,7 @@ function computeMetrics(utxos, bondAmount) {
1094
1065
  const days_unspent = Math.max(0, Math.floor((Date.now() / 1e3 - oldestTime) / (24 * 60 * 60)));
1095
1066
  return { sats_bonded, days_unspent, confirmed_balance };
1096
1067
  }
1097
- async function verify2(input, opts = {}) {
1068
+ async function verify(input, opts = {}) {
1098
1069
  const codes = [];
1099
1070
  let network = "mainnet";
1100
1071
  try {
@@ -1249,7 +1220,7 @@ async function check(params) {
1249
1220
  return { ok: false, sats: 0, days: 0, score: 0, reasons: ["not_found"] };
1250
1221
  }
1251
1222
  const shared = identity ? await backsOtherIdentity(env, identity, relays) : false;
1252
- const outcome = await verify2(
1223
+ const outcome = await verify(
1253
1224
  {
1254
1225
  addr: env.address,
1255
1226
  msg: env.message,
@@ -1437,21 +1408,17 @@ async function verifyChallenge(opts) {
1437
1408
  return { ok: false, reason: "purpose_mismatch" };
1438
1409
  }
1439
1410
  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 {
1411
+ let sigValid;
1412
+ if (scheme === "bip322") {
1413
+ const sigBase64 = /^[0-9a-fA-F]+$/.test(opts.signature) && opts.signature.length % 2 === 0 ? buffer.Buffer.from(opts.signature, "hex").toString("base64") : opts.signature;
1414
+ sigValid = bip322.verifySignature(address, opts.message, sigBase64);
1415
+ } else if (scheme === "legacy") {
1416
+ if (!/^[1m][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(address)) {
1451
1417
  return { ok: false, reason: "sig_unsupported_scheme" };
1452
1418
  }
1453
- } catch {
1454
- sigValid = false;
1419
+ sigValid = bip322.verifySignature(address, opts.message, opts.signature);
1420
+ } else {
1421
+ return { ok: false, reason: "sig_unsupported_scheme" };
1455
1422
  }
1456
1423
  if (!sigValid) return { ok: false, reason: "sig_invalid" };
1457
1424
  return {
@@ -1617,11 +1584,14 @@ function isValidDomain(domain) {
1617
1584
  const domainPattern = /^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}$/i;
1618
1585
  return domainPattern.test(cleanDomain);
1619
1586
  }
1620
- function isDnsIdentityVerified(attestationId, _domain, cachedContent) {
1621
- if (!cachedContent) {
1587
+ function isDnsIdentityVerified(attestationId, domain, cachedContent) {
1588
+ if (!cachedContent || !cachedContent.includes(attestationId)) {
1622
1589
  return false;
1623
1590
  }
1624
- return cachedContent.includes(attestationId);
1591
+ const named = /^Domain:\s*(\S+)\s*$/im.exec(cachedContent);
1592
+ if (!named) return true;
1593
+ const cleanDomain = domain.replace(/^https?:\/\//, "").replace(/\/$/, "").toLowerCase();
1594
+ return named[1].toLowerCase() === cleanDomain;
1625
1595
  }
1626
1596
 
1627
1597
  // src/identity/github.ts
@@ -1765,8 +1735,10 @@ This gist proves that I control both:
1765
1735
  Learn more about OrangeCheck: https://ochk.io
1766
1736
  `;
1767
1737
  }
1768
- function isGitHubIdentityVerified(attestationId, _username, cachedGists) {
1738
+ function isGitHubIdentityVerified(attestationId, username, cachedGists) {
1739
+ const login = username.replace(/^@/, "").toLowerCase();
1769
1740
  return cachedGists.some((gist) => {
1741
+ if (gist.owner?.login?.toLowerCase() !== login) return false;
1770
1742
  if (gist.description?.includes(attestationId)) {
1771
1743
  return true;
1772
1744
  }
@@ -1865,6 +1837,9 @@ async function queryNostrEvents(options) {
1865
1837
  return events;
1866
1838
  }
1867
1839
  async function verifyNostrEventSignature(event) {
1840
+ return nostrEventSignatureValid(event);
1841
+ }
1842
+ function nostrEventSignatureValid(event) {
1868
1843
  try {
1869
1844
  if (!event.id || !event.sig || !event.pubkey || typeof event.id !== "string" || typeof event.sig !== "string" || typeof event.pubkey !== "string" || event.sig.length !== 128 || !HEX_64_RE2.test(event.id) || !HEX_64_RE2.test(event.pubkey)) {
1870
1845
  return false;
@@ -1951,7 +1926,7 @@ The verification will search Nostr relays for your note and confirm you control
1951
1926
  function isNostrIdentityVerified(attestationId, npub, cachedEvents) {
1952
1927
  const pubkeyHex = npubToHex(npub);
1953
1928
  return cachedEvents.some(
1954
- (event) => event.pubkey === pubkeyHex && event.kind === 1 && event.content.includes(attestationId)
1929
+ (event) => event.pubkey === pubkeyHex && event.kind === 1 && event.content.includes(attestationId) && nostrEventSignatureValid(event)
1955
1930
  );
1956
1931
  }
1957
1932
 
@@ -2299,7 +2274,7 @@ exports.queryRecent = queryRecent;
2299
2274
  exports.requiresManualVerification = requiresManualVerification;
2300
2275
  exports.signNostrEvent = signNostrEvent;
2301
2276
  exports.supportsAutomaticVerification = supportsAutomaticVerification;
2302
- exports.verify = verify2;
2277
+ exports.verify = verify;
2303
2278
  exports.verifyAllIdentities = verifyAllIdentities;
2304
2279
  exports.verifyAttestationById = verifyAttestationById;
2305
2280
  exports.verifyChallenge = verifyChallenge;