@notabene/verify-proof 1.1.2 → 1.2.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.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("@notabene/javascript-sdk"),r=require("varuint-bitcoin"),t=require("@scure/base"),o=require("ox"),s=require("@noble/curves/secp256k1"),a=require("bip322-js"),n=require("tweetnacl"),i=require("@cardano-foundation/cardano-verify-datasignature");function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c,f,P=/*#__PURE__*/u(n),l=/*#__PURE__*/u(i);function d(){return d=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},d.apply(null,arguments)}!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(c||(c={})),function(e){e.LEGACY="Legacy",e.NATIVE="Native SegWit",e.SEGWIT="SegWit",e.P2SH_SEGWIT="p2sh",e.BCH="Bitcoin Cash",e.ETHEREUM="Ethereum",e.DOGECOIN="Dogecoin",e.UNKNOWN="Unknown"}(f||(f={}));var v=t.createBase58check(o.Hash.sha256);function h(e){var r=t.bech32.toWords(e);return r.unshift(0),t.bech32.encode("bc",r)}exports.verifyProof=function(n){try{switch(n.type){case e.ProofTypes.SelfDeclaration:return Promise.resolve(d({},n,{status:n.confirmed?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}));case e.ProofTypes.Screenshot:return Promise.resolve(d({},n,{status:n.url?e.ProofStatus.FLAGGED:e.ProofStatus.FAILED}));case e.ProofTypes.CIP8:return Promise.resolve(function(r){try{var t,o=r.address.split(/:/),s=o[2],a=null==(t=r.chainSpecificData)?void 0:t.cardanoCoseKey;if("cardano"!==o[0]||!a)return Promise.resolve(d({},r,{status:e.ProofStatus.FAILED}));try{var n=l.default(r.proof,a,r.attestation,s);return Promise.resolve(d({},r,{status:n?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(t){return Promise.resolve(d({},r,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case e.ProofTypes.EIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),s=t[2];if("eip155"!==t[0])return Promise.resolve(d({},r,{status:e.ProofStatus.FAILED}));var a=function(e,r,t){try{var s=o.PersonalMessage.getSignPayload(o.Hex.fromString(r)),a=o.Signature.fromHex(t),n=o.Secp256k1.recoverPublicKey({payload:s,signature:a});return o.Address.checksum(o.Address.fromPublicKey(n)).toString()===o.Address.checksum(e)}catch(e){return!1}}(s,r.attestation,r.proof);return Promise.resolve(d({},r,{status:a?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(n));case e.ProofTypes.ED25519:return Promise.resolve(function(r){try{var o=r.address.split(/:/),s=o[2];if("solana"!==o[0])return Promise.resolve(d({},r,{status:e.ProofStatus.FAILED}));try{var a=t.base58.decode(s),n=(new TextEncoder).encode(r.attestation),i=t.base64.decode(r.proof),u=P.default.sign.detached.verify(n,i,a);return Promise.resolve(d({},r,{status:u?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(t){return Promise.resolve(d({},r,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case e.ProofTypes.EIP712:case e.ProofTypes.BIP137:case e.ProofTypes.BIP322:return Promise.resolve(function(n){try{var i=n.address.split(/:/),u=i[2];if("bip122"!==i[0])return Promise.resolve(d({},n,{status:e.ProofStatus.FAILED}));try{switch(n.type){case e.ProofTypes.BIP137:return Promise.resolve(function(a,n){var i=[f.SEGWIT,f.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return f.NATIVE;if(e.match("^[32M].*"))return f.SEGWIT;if(e.match("^[1nmL].*"))return f.LEGACY;if(e.match("^(D).*"))return f.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(a)),u=function(e,a,n,i){var u=function(e){var r=t.base64.decode(e);if(65!==r.length)throw new Error("Invalid signature length");var o=r[0]-27;if(o>15||o<0)throw new Error("Invalid signature parameter");var a=!!(12&o),n=3&o,i=s.secp256k1.Signature.fromCompact(r.slice(1));return{compressed:a,segwitType:8&o?4&o?c.P2WPKH:c.P2SH_P2WPKH:void 0,signature:i.addRecoveryBit(n)}}(n),f=u.compressed,P=u.segwitType,l=u.signature;if(i&&!f)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var d,y=function(e){var t=(new TextEncoder).encode("Bitcoin Signed Message:\n"),s=(new TextEncoder).encode(e),a=r.encode(s.length).buffer,n=new Uint8Array(t.length+a.byteLength+s.length);return n.set(t),n.set(new Uint8Array(a),t.length),n.set(s,t.length+a.byteLength),function(e){return o.Hash.sha256(o.Hash.sha256(e))}(n)}(e),E=(d=l.recoverPublicKey(y).toRawBytes(f),o.Hash.ripemd160(o.Hash.sha256(d))),p="";if(P)p=h(E);else if(i)try{p=h(E)}catch(e){p=h(E)}else p=function(e,r){var t=new Uint8Array([0].concat(r));return v.encode(t)}(0,E);return p===a}(n.attestation,a,n.proof,i);return d({},n,{status:u?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED})}(u,n));case e.ProofTypes.BIP322:return Promise.resolve(function(r,t){return d({},t,{status:a.Verifier.verifySignature(r,t.attestation,t.proof)?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED})}(u,n));default:return Promise.resolve(d({},n,{status:e.ProofStatus.FAILED}))}}catch(r){return Promise.resolve(d({},n,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case e.ProofTypes.TIP191:return Promise.resolve(function(r){try{var s=r.address.split(/:/),a=s[2];if("tron"!==s[0])return Promise.resolve(d({},r,{status:e.ProofStatus.FAILED}));var n=function(e,r,s){try{var a=(l=o.Hex.fromString(r),o.Hash.keccak256(function(e){var r=o.Hex.from(e);return o.Hex.concat("0x19",o.Hex.fromString("TRON Signed Message:\n"+o.Hex.size(r)),r)}(l))),n=o.Signature.fromHex(s),i=o.Secp256k1.recoverPublicKey({payload:a,signature:n}),u="0x41"+o.Hash.keccak256("0x"+o.PublicKey.toHex(i).slice(4)).substring(26),c=o.Bytes.from(u),f=o.Bytes.from(o.Hash.sha256(o.Hash.sha256(u))).slice(0,4),P=o.Bytes.concat(c,f);return t.base58.encode(P)===e}catch(e){return!1}var l}(a,r.attestation,r.proof);return Promise.resolve(d({},r,{status:n?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(n))}return Promise.resolve(n)}catch(e){return Promise.reject(e)}};
1
+ var e=require("@notabene/javascript-sdk"),r=require("varuint-bitcoin"),t=require("@scure/base"),s=require("ox"),o=require("@noble/curves/secp256k1"),a=require("bip322-js"),i=require("tweetnacl"),n=require("@cardano-foundation/cardano-verify-datasignature");function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u,f=/*#__PURE__*/c(i),P=/*#__PURE__*/c(n);function h(){return h=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var s in t)({}).hasOwnProperty.call(t,s)&&(e[s]=t[s])}return e},h.apply(null,arguments)}!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(u||(u={}));var l,d={bitcoin:{messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5,bech32Prefix:"bc"},bitcoincash:{messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5},litecoin:{messagePrefix:"Litecoin Signed Message:\n",pubKeyHashVersion:48,scriptHashVersion:50,bech32Prefix:"ltc"},dogecoin:{messagePrefix:"Dogecoin Signed Message:\n",pubKeyHashVersion:30,scriptHashVersion:22},dash:{messagePrefix:"DarkCoin Signed Message:\n",pubKeyHashVersion:76,scriptHashVersion:16}};!function(e){e.LEGACY="Legacy",e.NATIVE="Native SegWit",e.SEGWIT="SegWit",e.P2SH_SEGWIT="p2sh",e.BCH="Bitcoin Cash",e.ETHEREUM="Ethereum",e.DOGECOIN="Dogecoin",e.UNKNOWN="Unknown"}(l||(l={}));var p=t.createBase58check(s.Hash.sha256);function v(e,r){var t=new Uint8Array([e].concat(r));return p.encode(t)}function y(e,r){void 0===r&&(r="bc");var s=t.bech32.toWords(e);return s.unshift(0),t.bech32.encode(r,s)}exports.verifyProof=function(i){try{switch(i.type){case e.ProofTypes.SelfDeclaration:return Promise.resolve(h({},i,{status:i.confirmed?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}));case e.ProofTypes.Screenshot:return Promise.resolve(h({},i,{status:i.url?e.ProofStatus.FLAGGED:e.ProofStatus.FAILED}));case e.ProofTypes.CIP8:return Promise.resolve(function(r){try{var t,s=r.address.split(/:/),o=s[2],a=null==(t=r.chainSpecificData)?void 0:t.cardanoCoseKey;if("cardano"!==s[0]||!a)return Promise.resolve(h({},r,{status:e.ProofStatus.FAILED}));try{var i=P.default(r.proof,a,r.attestation,o);return Promise.resolve(h({},r,{status:i?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(t){return Promise.resolve(h({},r,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(i));case e.ProofTypes.EIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),o=t[2];if("eip155"!==t[0])return Promise.resolve(h({},r,{status:e.ProofStatus.FAILED}));var a=function(e,r,t){try{var o=s.PersonalMessage.getSignPayload(s.Hex.fromString(r)),a=s.Signature.fromHex(t),i=s.Secp256k1.recoverPublicKey({payload:o,signature:a});return s.Address.checksum(s.Address.fromPublicKey(i)).toString()===s.Address.checksum(e)}catch(e){return!1}}(o,r.attestation,r.proof);return Promise.resolve(h({},r,{status:a?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(i));case e.ProofTypes.ED25519:return Promise.resolve(function(r){try{var s=r.address.split(/:/),o=s[2];if("solana"!==s[0])return Promise.resolve(h({},r,{status:e.ProofStatus.FAILED}));try{var a=t.base58.decode(o),i=(new TextEncoder).encode(r.attestation),n=t.base64.decode(r.proof),c=f.default.sign.detached.verify(i,n,a);return Promise.resolve(h({},r,{status:c?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(t){return Promise.resolve(h({},r,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(i));case e.ProofTypes.EIP712:case e.ProofTypes.BIP137:case e.ProofTypes.BIP322:return Promise.resolve(function(i){try{var n=i.address.split(/:/),c=n[2];if("bip122"!==n[0])return Promise.resolve(h({},i,{status:e.ProofStatus.FAILED}));var f=function(e){return e.startsWith("1")||e.startsWith("3")||e.startsWith("bc1")?d.bitcoin:e.startsWith("L")||e.startsWith("M")||e.startsWith("ltc1")?d.litecoin:e.startsWith("D")||e.startsWith("A")?d.dogecoin:e.startsWith("X")||e.startsWith("7")?d.dash:e.startsWith("q")?d.bitcoincash:d.bitcoin}(c);if(!f)return Promise.resolve(h({},i,{status:e.ProofStatus.FAILED}));try{switch(i.type){case e.ProofTypes.BIP137:return Promise.resolve(function(a,i,n){var c=Boolean(n.bech32Prefix&&[l.SEGWIT,l.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return l.NATIVE;if(e.match("^[32M].*"))return l.SEGWIT;if(e.match("^[1nmL].*"))return l.LEGACY;if(e.match("^(D).*"))return l.DOGECOIN;if(e.match("^(q).*"))return l.BCH;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(a))),f=function(e,a,i,n,c){var f=function(e){var r=t.base64.decode(e);if(65!==r.length)throw new Error("Invalid signature length");var s=r[0]-27;if(s>15||s<0)throw new Error("Invalid signature parameter");var a=!!(12&s),i=3&s,n=o.secp256k1.Signature.fromCompact(r.slice(1));return{compressed:a,segwitType:8&s?4&s?u.P2WPKH:u.P2SH_P2WPKH:void 0,signature:n.addRecoveryBit(i)}}(i),P=f.compressed,h=f.segwitType,l=f.signature;if(n&&!P)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var d,p=function(e,t){var o=(new TextEncoder).encode(t),a=(new TextEncoder).encode(e),i=r.encode(a.length).buffer,n=new Uint8Array(o.length+i.byteLength+a.length);return n.set(o),n.set(new Uint8Array(i),o.length),n.set(a,o.length+i.byteLength),function(e){return s.Hash.sha256(s.Hash.sha256(e))}(n)}(e,c.messagePrefix),g=(d=l.recoverPublicKey(p).toRawBytes(P),s.Hash.ripemd160(s.Hash.sha256(d))),m="";if(a.startsWith("q"))return(m=v(c.pubKeyHashVersion,g)).startsWith("1");if(h)m=h===u.P2SH_P2WPKH?v(c.scriptHashVersion,g):c.bech32Prefix?y(g,c.bech32Prefix):v(c.scriptHashVersion,g);else if(n&&c.bech32Prefix)try{m=y(g,c.bech32Prefix)}catch(e){m=v(c.scriptHashVersion,g)}else m=v(c.pubKeyHashVersion,g);return m===a}(i.attestation,a,i.proof,c,n);return h({},i,{status:f?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED})}(c,i,f));case e.ProofTypes.BIP322:return Promise.resolve(function(r,t){return h({},t,{status:a.Verifier.verifySignature(r,t.attestation,t.proof)?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED})}(c,i));default:return Promise.resolve(h({},i,{status:e.ProofStatus.FAILED}))}}catch(r){return Promise.resolve(h({},i,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(i));case e.ProofTypes.TIP191:return Promise.resolve(function(r){try{var o=r.address.split(/:/),a=o[2];if("tron"!==o[0])return Promise.resolve(h({},r,{status:e.ProofStatus.FAILED}));var i=function(e,r,o){try{var a=(h=s.Hex.fromString(r),s.Hash.keccak256(function(e){var r=s.Hex.from(e);return s.Hex.concat("0x19",s.Hex.fromString("TRON Signed Message:\n"+s.Hex.size(r)),r)}(h))),i=s.Signature.fromHex(o),n=s.Secp256k1.recoverPublicKey({payload:a,signature:i}),c="0x41"+s.Hash.keccak256("0x"+s.PublicKey.toHex(n).slice(4)).substring(26),u=s.Bytes.from(c),f=s.Bytes.from(s.Hash.sha256(s.Hash.sha256(c))).slice(0,4),P=s.Bytes.concat(u,f);return t.base58.encode(P)===e}catch(e){return!1}var h}(a,r.attestation,r.proof);return Promise.resolve(h({},r,{status:i?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(i))}return Promise.resolve(i)}catch(e){return Promise.reject(e)}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/bitcoin.ts","../src/index.ts","../src/cardano.ts","../src/eth.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\nconst messagePrefix = \"\\u0018Bitcoin Signed Message:\\n\";\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof) {\n // const messageToBeSigned = message.replace(/\\s+/g, \" \").trim();\n const segwit = [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n );\n const verified = verify(proof.attestation, address, proof.proof, segwit);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBech32Address(publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n // must be true since we only return null, P2SH_P2WPKH, or P2WPKH\n // from the decodeSignature function.\n actual = encodeBech32Address(publicKeyHash);\n }\n } else {\n if (checkSegwitAlways) {\n try {\n actual = encodeBech32Address(publicKeyHash);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBech32Address(publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(0, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(\"bc\", bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}\n","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","base58check","createBase58check","Hash","sha256","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","_proof$address$split","address","split","key","chainSpecificData","cardanoCoseKey","verified","verifyDataSignature","attestation","_unused","e","reject","verifyCIP8Signature","EIP191","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","sigbytes","length","flagByte","compressed","recovery","secp256k1","fromCompact","slice","segwitType","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","buffer","hash","prefix","encodeLength","Uint8Array","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","version","encodeBase58AddressFormat","verifyBIP137","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","data","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","checked","verifyTIP191","verifyPersonalSignTIP191"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/bitcoin.ts","../src/index.ts","../src/cardano.ts","../src/eth.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\ninterface ChainConfig {\n messagePrefix: string;\n pubKeyHashVersion: number;\n scriptHashVersion: number;\n bech32Prefix?: string;\n}\n\nconst CHAIN_CONFIGS: Record<string, ChainConfig> = {\n bitcoin: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n bech32Prefix: \"bc\"\n },\n bitcoincash: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n },\n litecoin: {\n messagePrefix: \"\\u0019Litecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x30, // L... or M...\n scriptHashVersion: 0x32, // 3... or M...\n bech32Prefix: \"ltc\"\n },\n dogecoin: {\n messagePrefix: \"\\u0019Dogecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x1E, // D...\n scriptHashVersion: 0x16, // A...\n },\n dash: {\n messagePrefix: \"\\u0019DarkCoin Signed Message:\\n\",\n pubKeyHashVersion: 0x4C, // X...\n scriptHashVersion: 0x10, // 7...\n },\n};\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns,, address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n \n // Map chainId to our chain configuration\n const chainConfig = getChainConfig(address);\n if (!chainConfig) return { ...proof, status: ProofStatus.FAILED };\n \n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof, chainConfig);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction getChainConfig(address: string): ChainConfig {\n if (address.startsWith(\"1\") || address.startsWith(\"3\") || address.startsWith(\"bc1\")) {\n return CHAIN_CONFIGS[\"bitcoin\"];\n }\n if (address.startsWith(\"L\") || address.startsWith(\"M\") || address.startsWith(\"ltc1\")) {\n return CHAIN_CONFIGS[\"litecoin\"];\n }\n if (address.startsWith(\"D\") || address.startsWith(\"A\")) {\n return CHAIN_CONFIGS[\"dogecoin\"];\n }\n if (address.startsWith(\"X\") || address.startsWith(\"7\")) {\n return CHAIN_CONFIGS[\"dash\"];\n }\n if (address.startsWith(\"q\")) {\n return CHAIN_CONFIGS[\"bitcoincash\"];\n }\n\n return CHAIN_CONFIGS[\"bitcoin\"];\n}\n\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof, chainConfig: ChainConfig) {\n const segwit = Boolean(chainConfig.bech32Prefix && [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n ));\n const verified = verify(proof.attestation, address, proof.proof, segwit, chainConfig);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else if (address.match(\"^(q).*\")) {\n return DerivationMode.BCH;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n chainConfig: ChainConfig\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation, chainConfig.messagePrefix);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n // Special handling for Bitcoin Cash addresses\n if (address.startsWith('q')) {\n // For BCH, we'll compare the public key hash directly since we're getting a CashAddr\n // Convert the CashAddr to legacy format for comparison\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n // Legacy P2PKH addresses in BCH start with '1' just like BTC\n // Source: https://reference.cash/protocol/blockchain/encoding/cashaddr#legacy-address-format\n return actual.startsWith('1');\n }\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n if (chainConfig.bech32Prefix) {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n } else {\n // Fallback to legacy if bech32 not supported\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n }\n } else {\n if (checkSegwitAlways && chainConfig.bech32Prefix) {\n try {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string, messagePrefix: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array, prefix: string = \"bc\"): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(prefix, bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","CHAIN_CONFIGS","bitcoin","messagePrefix","pubKeyHashVersion","scriptHashVersion","bech32Prefix","bitcoincash","litecoin","dogecoin","dash","base58check","createBase58check","Hash","sha256","encodeBase58AddressFormat","version","publicKeyHash","payload","Uint8Array","concat","encode","encodeBech32Address","prefix","bwords","bech32","toWords","unshift","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","_proof$address$split","address","split","key","chainSpecificData","cardanoCoseKey","verified","verifyDataSignature","attestation","_unused","e","reject","verifyCIP8Signature","EIP191","message","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","chainConfig","startsWith","getChainConfig","segwit","Boolean","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","BCH","Error","getDerivationMode","checkSegwitAlways","_decodeSignature","sigbytes","length","flagByte","compressed","recovery","secp256k1","fromCompact","slice","segwitType","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","buffer","hash","encodeLength","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","verifyBIP137","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","data","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","checked","verifyTIP191","verifyPersonalSignTIP191"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{ProofStatus as e,ProofTypes as r}from"@notabene/javascript-sdk";import{encode as t}from"varuint-bitcoin";import{createBase58check as n,bech32 as o,base64 as s,base58 as a}from"@scure/base";import{Hash as i,PersonalMessage as c,Hex as u,Signature as f,Secp256k1 as l,Address as m,PublicKey as v,Bytes as d}from"ox";import{secp256k1 as E}from"@noble/curves/secp256k1";import{Verifier as P}from"bip322-js";import h from"tweetnacl";import I from"@cardano-foundation/cardano-verify-datasignature";function p(){return p=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},p.apply(null,arguments)}var g,y;!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(g||(g={})),function(e){e.LEGACY="Legacy",e.NATIVE="Native SegWit",e.SEGWIT="SegWit",e.P2SH_SEGWIT="p2sh",e.BCH="Bitcoin Cash",e.ETHEREUM="Ethereum",e.DOGECOIN="Dogecoin",e.UNKNOWN="Unknown"}(y||(y={}));var D=n(i.sha256);function A(e){var r=o.toWords(e);return r.unshift(0),o.encode("bc",r)}var w=function(n){try{switch(n.type){case r.SelfDeclaration:return Promise.resolve(p({},n,{status:n.confirmed?e.VERIFIED:e.FAILED}));case r.Screenshot:return Promise.resolve(p({},n,{status:n.url?e.FLAGGED:e.FAILED}));case r.CIP8:return Promise.resolve(function(r){try{var t,n=r.address.split(/:/),o=n[2],s=null==(t=r.chainSpecificData)?void 0:t.cardanoCoseKey;if("cardano"!==n[0]||!s)return Promise.resolve(p({},r,{status:e.FAILED}));try{var a=I(r.proof,s,r.attestation,o);return Promise.resolve(p({},r,{status:a?e.VERIFIED:e.FAILED}))}catch(t){return Promise.resolve(p({},r,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case r.EIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),n=t[2];if("eip155"!==t[0])return Promise.resolve(p({},r,{status:e.FAILED}));var o=function(e,r,t){try{var n=c.getSignPayload(u.fromString(r)),o=f.fromHex(t),s=l.recoverPublicKey({payload:n,signature:o});return m.checksum(m.fromPublicKey(s)).toString()===m.checksum(e)}catch(e){return!1}}(n,r.attestation,r.proof);return Promise.resolve(p({},r,{status:o?e.VERIFIED:e.FAILED}))}catch(e){return Promise.reject(e)}}(n));case r.ED25519:return Promise.resolve(function(r){try{var t=r.address.split(/:/),n=t[2];if("solana"!==t[0])return Promise.resolve(p({},r,{status:e.FAILED}));try{var o=a.decode(n),i=(new TextEncoder).encode(r.attestation),c=s.decode(r.proof),u=h.sign.detached.verify(i,c,o);return Promise.resolve(p({},r,{status:u?e.VERIFIED:e.FAILED}))}catch(t){return Promise.resolve(p({},r,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case r.EIP712:case r.BIP137:case r.BIP322:return Promise.resolve(function(n){try{var o=n.address.split(/:/),a=o[2];if("bip122"!==o[0])return Promise.resolve(p({},n,{status:e.FAILED}));try{switch(n.type){case r.BIP137:return Promise.resolve(function(r,n){var o=[y.SEGWIT,y.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return y.NATIVE;if(e.match("^[32M].*"))return y.SEGWIT;if(e.match("^[1nmL].*"))return y.LEGACY;if(e.match("^(D).*"))return y.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(r)),a=function(e,r,n,o){var a=function(e){var r=s.decode(e);if(65!==r.length)throw new Error("Invalid signature length");var t=r[0]-27;if(t>15||t<0)throw new Error("Invalid signature parameter");var n=!!(12&t),o=3&t,a=E.Signature.fromCompact(r.slice(1));return{compressed:n,segwitType:8&t?4&t?g.P2WPKH:g.P2SH_P2WPKH:void 0,signature:a.addRecoveryBit(o)}}(n),c=a.compressed,u=a.segwitType,f=a.signature;if(o&&!c)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var l,m=function(e){var r=(new TextEncoder).encode("Bitcoin Signed Message:\n"),n=(new TextEncoder).encode(e),o=t(n.length).buffer,s=new Uint8Array(r.length+o.byteLength+n.length);return s.set(r),s.set(new Uint8Array(o),r.length),s.set(n,r.length+o.byteLength),function(e){return i.sha256(i.sha256(e))}(s)}(e),v=(l=f.recoverPublicKey(m).toRawBytes(c),i.ripemd160(i.sha256(l))),d="";if(u)d=A(v);else if(o)try{d=A(v)}catch(e){d=A(v)}else d=function(e,r){var t=new Uint8Array([0].concat(r));return D.encode(t)}(0,v);return d===r}(n.attestation,r,n.proof,o);return p({},n,{status:a?e.VERIFIED:e.FAILED})}(a,n));case r.BIP322:return Promise.resolve(function(r,t){return p({},t,{status:P.verifySignature(r,t.attestation,t.proof)?e.VERIFIED:e.FAILED})}(a,n));default:return Promise.resolve(p({},n,{status:e.FAILED}))}}catch(r){return Promise.resolve(p({},n,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case r.TIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),n=t[2];if("tron"!==t[0])return Promise.resolve(p({},r,{status:e.FAILED}));var o=function(e,r,t){try{var n=(h=u.fromString(r),i.keccak256(function(e){var r=u.from(e);return u.concat("0x19",u.fromString("TRON Signed Message:\n"+u.size(r)),r)}(h))),o=f.fromHex(t),s=l.recoverPublicKey({payload:n,signature:o}),c="0x41"+i.keccak256("0x"+v.toHex(s).slice(4)).substring(26),m=d.from(c),E=d.from(i.sha256(i.sha256(c))).slice(0,4),P=d.concat(m,E);return a.encode(P)===e}catch(e){return!1}var h}(n,r.attestation,r.proof);return Promise.resolve(p({},r,{status:o?e.VERIFIED:e.FAILED}))}catch(e){return Promise.reject(e)}}(n))}return Promise.resolve(n)}catch(e){return Promise.reject(e)}};export{w as verifyProof};
1
+ import{ProofStatus as e,ProofTypes as r}from"@notabene/javascript-sdk";import{encode as t}from"varuint-bitcoin";import{createBase58check as s,bech32 as i,base64 as n,base58 as o}from"@scure/base";import{Hash as a,PersonalMessage as c,Hex as u,Signature as h,Secp256k1 as f,Address as m,PublicKey as l,Bytes as v}from"ox";import{secp256k1 as P}from"@noble/curves/secp256k1";import{Verifier as d}from"bip322-js";import p from"tweetnacl";import g from"@cardano-foundation/cardano-verify-datasignature";function E(){return E=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var s in t)({}).hasOwnProperty.call(t,s)&&(e[s]=t[s])}return e},E.apply(null,arguments)}var I;!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(I||(I={}));var y,b={bitcoin:{messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5,bech32Prefix:"bc"},bitcoincash:{messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5},litecoin:{messagePrefix:"Litecoin Signed Message:\n",pubKeyHashVersion:48,scriptHashVersion:50,bech32Prefix:"ltc"},dogecoin:{messagePrefix:"Dogecoin Signed Message:\n",pubKeyHashVersion:30,scriptHashVersion:22},dash:{messagePrefix:"DarkCoin Signed Message:\n",pubKeyHashVersion:76,scriptHashVersion:16}};!function(e){e.LEGACY="Legacy",e.NATIVE="Native SegWit",e.SEGWIT="SegWit",e.P2SH_SEGWIT="p2sh",e.BCH="Bitcoin Cash",e.ETHEREUM="Ethereum",e.DOGECOIN="Dogecoin",e.UNKNOWN="Unknown"}(y||(y={}));var D=s(a.sha256);function A(e,r){var t=new Uint8Array([e].concat(r));return D.encode(t)}function H(e,r){void 0===r&&(r="bc");var t=i.toWords(e);return t.unshift(0),i.encode(r,t)}var S=function(s){try{switch(s.type){case r.SelfDeclaration:return Promise.resolve(E({},s,{status:s.confirmed?e.VERIFIED:e.FAILED}));case r.Screenshot:return Promise.resolve(E({},s,{status:s.url?e.FLAGGED:e.FAILED}));case r.CIP8:return Promise.resolve(function(r){try{var t,s=r.address.split(/:/),i=s[2],n=null==(t=r.chainSpecificData)?void 0:t.cardanoCoseKey;if("cardano"!==s[0]||!n)return Promise.resolve(E({},r,{status:e.FAILED}));try{var o=g(r.proof,n,r.attestation,i);return Promise.resolve(E({},r,{status:o?e.VERIFIED:e.FAILED}))}catch(t){return Promise.resolve(E({},r,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(s));case r.EIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),s=t[2];if("eip155"!==t[0])return Promise.resolve(E({},r,{status:e.FAILED}));var i=function(e,r,t){try{var s=c.getSignPayload(u.fromString(r)),i=h.fromHex(t),n=f.recoverPublicKey({payload:s,signature:i});return m.checksum(m.fromPublicKey(n)).toString()===m.checksum(e)}catch(e){return!1}}(s,r.attestation,r.proof);return Promise.resolve(E({},r,{status:i?e.VERIFIED:e.FAILED}))}catch(e){return Promise.reject(e)}}(s));case r.ED25519:return Promise.resolve(function(r){try{var t=r.address.split(/:/),s=t[2];if("solana"!==t[0])return Promise.resolve(E({},r,{status:e.FAILED}));try{var i=o.decode(s),a=(new TextEncoder).encode(r.attestation),c=n.decode(r.proof),u=p.sign.detached.verify(a,c,i);return Promise.resolve(E({},r,{status:u?e.VERIFIED:e.FAILED}))}catch(t){return Promise.resolve(E({},r,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(s));case r.EIP712:case r.BIP137:case r.BIP322:return Promise.resolve(function(s){try{var i=s.address.split(/:/),o=i[2];if("bip122"!==i[0])return Promise.resolve(E({},s,{status:e.FAILED}));var c=function(e){return e.startsWith("1")||e.startsWith("3")||e.startsWith("bc1")?b.bitcoin:e.startsWith("L")||e.startsWith("M")||e.startsWith("ltc1")?b.litecoin:e.startsWith("D")||e.startsWith("A")?b.dogecoin:e.startsWith("X")||e.startsWith("7")?b.dash:e.startsWith("q")?b.bitcoincash:b.bitcoin}(o);if(!c)return Promise.resolve(E({},s,{status:e.FAILED}));try{switch(s.type){case r.BIP137:return Promise.resolve(function(r,s,i){var o=Boolean(i.bech32Prefix&&[y.SEGWIT,y.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return y.NATIVE;if(e.match("^[32M].*"))return y.SEGWIT;if(e.match("^[1nmL].*"))return y.LEGACY;if(e.match("^(D).*"))return y.DOGECOIN;if(e.match("^(q).*"))return y.BCH;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(r))),c=function(e,r,s,i,o){var c=function(e){var r=n.decode(e);if(65!==r.length)throw new Error("Invalid signature length");var t=r[0]-27;if(t>15||t<0)throw new Error("Invalid signature parameter");var s=!!(12&t),i=3&t,o=P.Signature.fromCompact(r.slice(1));return{compressed:s,segwitType:8&t?4&t?I.P2WPKH:I.P2SH_P2WPKH:void 0,signature:o.addRecoveryBit(i)}}(s),u=c.compressed,h=c.segwitType,f=c.signature;if(i&&!u)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var m,l=function(e,r){var s=(new TextEncoder).encode(r),i=(new TextEncoder).encode(e),n=t(i.length).buffer,o=new Uint8Array(s.length+n.byteLength+i.length);return o.set(s),o.set(new Uint8Array(n),s.length),o.set(i,s.length+n.byteLength),function(e){return a.sha256(a.sha256(e))}(o)}(e,o.messagePrefix),v=(m=f.recoverPublicKey(l).toRawBytes(u),a.ripemd160(a.sha256(m))),d="";if(r.startsWith("q"))return(d=A(o.pubKeyHashVersion,v)).startsWith("1");if(h)d=h===I.P2SH_P2WPKH?A(o.scriptHashVersion,v):o.bech32Prefix?H(v,o.bech32Prefix):A(o.scriptHashVersion,v);else if(i&&o.bech32Prefix)try{d=H(v,o.bech32Prefix)}catch(e){d=A(o.scriptHashVersion,v)}else d=A(o.pubKeyHashVersion,v);return d===r}(s.attestation,r,s.proof,o,i);return E({},s,{status:c?e.VERIFIED:e.FAILED})}(o,s,c));case r.BIP322:return Promise.resolve(function(r,t){return E({},t,{status:d.verifySignature(r,t.attestation,t.proof)?e.VERIFIED:e.FAILED})}(o,s));default:return Promise.resolve(E({},s,{status:e.FAILED}))}}catch(r){return Promise.resolve(E({},s,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(s));case r.TIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),s=t[2];if("tron"!==t[0])return Promise.resolve(E({},r,{status:e.FAILED}));var i=function(e,r,t){try{var s=(p=u.fromString(r),a.keccak256(function(e){var r=u.from(e);return u.concat("0x19",u.fromString("TRON Signed Message:\n"+u.size(r)),r)}(p))),i=h.fromHex(t),n=f.recoverPublicKey({payload:s,signature:i}),c="0x41"+a.keccak256("0x"+l.toHex(n).slice(4)).substring(26),m=v.from(c),P=v.from(a.sha256(a.sha256(c))).slice(0,4),d=v.concat(m,P);return o.encode(d)===e}catch(e){return!1}var p}(s,r.attestation,r.proof);return Promise.resolve(E({},r,{status:i?e.VERIFIED:e.FAILED}))}catch(e){return Promise.reject(e)}}(s))}return Promise.resolve(s)}catch(e){return Promise.reject(e)}};export{S as verifyProof};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/bitcoin.ts","../src/eth.ts","../src/index.ts","../src/cardano.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\nconst messagePrefix = \"\\u0018Bitcoin Signed Message:\\n\";\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof) {\n // const messageToBeSigned = message.replace(/\\s+/g, \" \").trim();\n const segwit = [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n );\n const verified = verify(proof.attestation, address, proof.proof, segwit);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBech32Address(publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n // must be true since we only return null, P2SH_P2WPKH, or P2WPKH\n // from the decodeSignature function.\n actual = encodeBech32Address(publicKeyHash);\n }\n } else {\n if (checkSegwitAlways) {\n try {\n actual = encodeBech32Address(publicKeyHash);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBech32Address(publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(0, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(\"bc\", bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","base58check","createBase58check","Hash","sha256","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","verifyProof","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","_proof$address$split","address","split","key","chainSpecificData","cardanoCoseKey","verified","verifyDataSignature","attestation","_unused","e","reject","verifyCIP8Signature","EIP191","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","sigbytes","length","flagByte","compressed","recovery","secp256k1","fromCompact","slice","segwitType","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","buffer","hash","prefix","encodeLength","Uint8Array","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","version","encodeBase58AddressFormat","verifyBIP137","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","data","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","checked","verifyTIP191","verifyPersonalSignTIP191"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/bitcoin.ts","../src/eth.ts","../src/index.ts","../src/cardano.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\ninterface ChainConfig {\n messagePrefix: string;\n pubKeyHashVersion: number;\n scriptHashVersion: number;\n bech32Prefix?: string;\n}\n\nconst CHAIN_CONFIGS: Record<string, ChainConfig> = {\n bitcoin: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n bech32Prefix: \"bc\"\n },\n bitcoincash: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n },\n litecoin: {\n messagePrefix: \"\\u0019Litecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x30, // L... or M...\n scriptHashVersion: 0x32, // 3... or M...\n bech32Prefix: \"ltc\"\n },\n dogecoin: {\n messagePrefix: \"\\u0019Dogecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x1E, // D...\n scriptHashVersion: 0x16, // A...\n },\n dash: {\n messagePrefix: \"\\u0019DarkCoin Signed Message:\\n\",\n pubKeyHashVersion: 0x4C, // X...\n scriptHashVersion: 0x10, // 7...\n },\n};\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns,, address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n \n // Map chainId to our chain configuration\n const chainConfig = getChainConfig(address);\n if (!chainConfig) return { ...proof, status: ProofStatus.FAILED };\n \n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof, chainConfig);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction getChainConfig(address: string): ChainConfig {\n if (address.startsWith(\"1\") || address.startsWith(\"3\") || address.startsWith(\"bc1\")) {\n return CHAIN_CONFIGS[\"bitcoin\"];\n }\n if (address.startsWith(\"L\") || address.startsWith(\"M\") || address.startsWith(\"ltc1\")) {\n return CHAIN_CONFIGS[\"litecoin\"];\n }\n if (address.startsWith(\"D\") || address.startsWith(\"A\")) {\n return CHAIN_CONFIGS[\"dogecoin\"];\n }\n if (address.startsWith(\"X\") || address.startsWith(\"7\")) {\n return CHAIN_CONFIGS[\"dash\"];\n }\n if (address.startsWith(\"q\")) {\n return CHAIN_CONFIGS[\"bitcoincash\"];\n }\n\n return CHAIN_CONFIGS[\"bitcoin\"];\n}\n\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof, chainConfig: ChainConfig) {\n const segwit = Boolean(chainConfig.bech32Prefix && [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n ));\n const verified = verify(proof.attestation, address, proof.proof, segwit, chainConfig);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else if (address.match(\"^(q).*\")) {\n return DerivationMode.BCH;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n chainConfig: ChainConfig\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation, chainConfig.messagePrefix);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n // Special handling for Bitcoin Cash addresses\n if (address.startsWith('q')) {\n // For BCH, we'll compare the public key hash directly since we're getting a CashAddr\n // Convert the CashAddr to legacy format for comparison\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n // Legacy P2PKH addresses in BCH start with '1' just like BTC\n // Source: https://reference.cash/protocol/blockchain/encoding/cashaddr#legacy-address-format\n return actual.startsWith('1');\n }\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n if (chainConfig.bech32Prefix) {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n } else {\n // Fallback to legacy if bech32 not supported\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n }\n } else {\n if (checkSegwitAlways && chainConfig.bech32Prefix) {\n try {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string, messagePrefix: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array, prefix: string = \"bc\"): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(prefix, bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","CHAIN_CONFIGS","bitcoin","messagePrefix","pubKeyHashVersion","scriptHashVersion","bech32Prefix","bitcoincash","litecoin","dogecoin","dash","base58check","createBase58check","Hash","sha256","encodeBase58AddressFormat","version","publicKeyHash","payload","Uint8Array","concat","encode","encodeBech32Address","prefix","bwords","bech32","toWords","unshift","verifyProof","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","_proof$address$split","address","split","key","chainSpecificData","cardanoCoseKey","verified","verifyDataSignature","attestation","_unused","e","reject","verifyCIP8Signature","EIP191","message","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","chainConfig","startsWith","getChainConfig","segwit","Boolean","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","BCH","Error","getDerivationMode","checkSegwitAlways","_decodeSignature","sigbytes","length","flagByte","compressed","recovery","secp256k1","fromCompact","slice","segwitType","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","buffer","hash","encodeLength","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","verifyBIP137","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","data","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","checked","verifyTIP191","verifyPersonalSignTIP191"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{ProofStatus as t,ProofTypes as e}from"@notabene/javascript-sdk";import{encode as n}from"varuint-bitcoin";import{createBase58check as r,bech32 as s,base64 as o,base58 as c}from"@scure/base";import{Hash as a,PersonalMessage as i,Hex as u,Signature as f,Secp256k1 as d,Address as E,PublicKey as I,Bytes as p}from"ox";import{secp256k1 as l}from"@noble/curves/secp256k1";import{Verifier as h}from"bip322-js";import g from"tweetnacl";import m from"@cardano-foundation/cardano-verify-datasignature";function y(){return y=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)({}).hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t},y.apply(null,arguments)}var D,A;!function(t){t.P2WPKH="p2wpkh",t.P2SH_P2WPKH="p2sh(p2wpkh)"}(D||(D={})),function(t){t.LEGACY="Legacy",t.NATIVE="Native SegWit",t.SEGWIT="SegWit",t.P2SH_SEGWIT="p2sh",t.BCH="Bitcoin Cash",t.ETHEREUM="Ethereum",t.DOGECOIN="Dogecoin",t.UNKNOWN="Unknown"}(A||(A={}));const w=r(a.sha256);function F(t){const e=s.toWords(t);return e.unshift(0),s.encode("bc",e)}function L(t,e,n){try{const s=(r=u.fromString(e),a.keccak256(function(t){const e=u.from(t);return u.concat("0x19",u.fromString("TRON Signed Message:\n"+u.size(e)),e)}(r))),o=f.fromHex(n),i=d.recoverPublicKey({payload:s,signature:o}),E=`0x41${a.keccak256(`0x${I.toHex(i).slice(4)}`).substring(26)}`,l=p.from(E),h=p.from(a.sha256(a.sha256(E))).slice(0,4),g=p.concat(l,h);return c.encode(g)===t}catch(t){return!1}var r}async function P(r){switch(r.type){case e.SelfDeclaration:return y({},r,{status:r.confirmed?t.VERIFIED:t.FAILED});case e.Screenshot:return y({},r,{status:r.url?t.FLAGGED:t.FAILED});case e.CIP8:return async function(e){var n;const[r,,s]=e.address.split(/:/),o=null==(n=e.chainSpecificData)?void 0:n.cardanoCoseKey;if("cardano"!==r||!o)return y({},e,{status:t.FAILED});try{return y({},e,{status:m(e.proof,o,e.attestation,s)?t.VERIFIED:t.FAILED})}catch(n){return y({},e,{status:t.FAILED})}}(r);case e.EIP191:return async function(e){const[n,,r]=e.address.split(/:/);if("eip155"!==n)return y({},e,{status:t.FAILED});const s=function(t,e,n){try{const r=i.getSignPayload(u.fromString(e)),s=f.fromHex(n),o=d.recoverPublicKey({payload:r,signature:s});return E.checksum(E.fromPublicKey(o)).toString()===E.checksum(t)}catch(t){return!1}}(r,e.attestation,e.proof);return y({},e,{status:s?t.VERIFIED:t.FAILED})}(r);case e.ED25519:return async function(e){const[n,,r]=e.address.split(/:/);if("solana"!==n)return y({},e,{status:t.FAILED});try{const n=c.decode(r),s=(new TextEncoder).encode(e.attestation),a=o.decode(e.proof);return y({},e,{status:g.sign.detached.verify(s,a,n)?t.VERIFIED:t.FAILED})}catch(n){return y({},e,{status:t.FAILED})}}(r);case e.EIP712:case e.BIP137:case e.BIP322:return async function(r){const[s,,c]=r.address.split(/:/);if("bip122"!==s)return y({},r,{status:t.FAILED});try{switch(r.type){case e.BIP137:return function(e,r){const s=[A.SEGWIT,A.NATIVE].includes(function(t){if(t.match("^(bc1|tb1|ltc1).*"))return A.NATIVE;if(t.match("^[32M].*"))return A.SEGWIT;if(t.match("^[1nmL].*"))return A.LEGACY;if(t.match("^(D).*"))return A.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(t).concat(" is not a valid or a supported address"))}(e)),c=function(t,e,r,s){const{compressed:c,segwitType:i,signature:u}=function(t){const e=o.decode(t);if(65!==e.length)throw new Error("Invalid signature length");const n=e[0]-27;if(n>15||n<0)throw new Error("Invalid signature parameter");const r=!!(12&n),s=3&n,c=l.Signature.fromCompact(e.slice(1));return{compressed:r,segwitType:8&n?4&n?D.P2WPKH:D.P2SH_P2WPKH:void 0,signature:c.addRecoveryBit(s)}}(r);if(s&&!c)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");const f=function(t){const e=(new TextEncoder).encode("Bitcoin Signed Message:\n"),r=(new TextEncoder).encode(t),s=n(r.length).buffer,o=new Uint8Array(e.length+s.byteLength+r.length);return o.set(e),o.set(new Uint8Array(s),e.length),o.set(r,e.length+s.byteLength),function(t){return a.sha256(a.sha256(t))}(o)}(t),d=(E=u.recoverPublicKey(f).toRawBytes(c),a.ripemd160(a.sha256(E)));var E;let I="";if(i)I=F(d);else if(s)try{I=F(d)}catch(t){I=F(d)}else I=function(t,e){const n=new Uint8Array([0,...e]);return w.encode(n)}(0,d);return I===e}(r.attestation,e,r.proof,s);return y({},r,{status:c?t.VERIFIED:t.FAILED})}(c,r);case e.BIP322:return function(e,n){const{attestation:r,proof:s}=n;return y({},n,{status:h.verifySignature(e,r,s)?t.VERIFIED:t.FAILED})}(c,r);default:return y({},r,{status:t.FAILED})}}catch(e){return y({},r,{status:t.FAILED})}}(r);case e.TIP191:return async function(e){const[n,,r]=e.address.split(/:/);return y({},e,"tron"!==n?{status:t.FAILED}:{status:L(r,e.attestation,e.proof)?t.VERIFIED:t.FAILED})}(r)}return r}export{P as verifyProof};
1
+ import{ProofStatus as t,ProofTypes as e}from"@notabene/javascript-sdk";import{encode as r}from"varuint-bitcoin";import{createBase58check as s,bech32 as n,base64 as a,base58 as i}from"@scure/base";import{Hash as o,PersonalMessage as c,Hex as u,Signature as f,Secp256k1 as h,Address as p,PublicKey as d,Bytes as E}from"ox";import{secp256k1 as g}from"@noble/curves/secp256k1";import{Verifier as I}from"bip322-js";import l from"tweetnacl";import m from"@cardano-foundation/cardano-verify-datasignature";function y(){return y=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var r=arguments[e];for(var s in r)({}).hasOwnProperty.call(r,s)&&(t[s]=r[s])}return t},y.apply(null,arguments)}var P;!function(t){t.P2WPKH="p2wpkh",t.P2SH_P2WPKH="p2sh(p2wpkh)"}(P||(P={}));const b={messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5,bech32Prefix:"bc"},D={messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5},A={messagePrefix:"Litecoin Signed Message:\n",pubKeyHashVersion:48,scriptHashVersion:50,bech32Prefix:"ltc"},H={messagePrefix:"Dogecoin Signed Message:\n",pubKeyHashVersion:30,scriptHashVersion:22},S={messagePrefix:"DarkCoin Signed Message:\n",pubKeyHashVersion:76,scriptHashVersion:16};var L;!function(t){t.LEGACY="Legacy",t.NATIVE="Native SegWit",t.SEGWIT="SegWit",t.P2SH_SEGWIT="p2sh",t.BCH="Bitcoin Cash",t.ETHEREUM="Ethereum",t.DOGECOIN="Dogecoin",t.UNKNOWN="Unknown"}(L||(L={}));const w=s(o.sha256);function F(t,e){const r=new Uint8Array([t,...e]);return w.encode(r)}function V(t,e="bc"){const r=n.toWords(t);return r.unshift(0),n.encode(e,r)}function W(t,e,r){try{const n=(s=u.fromString(e),o.keccak256(function(t){const e=u.from(t);return u.concat("0x19",u.fromString("TRON Signed Message:\n"+u.size(e)),e)}(s))),a=f.fromHex(r),c=h.recoverPublicKey({payload:n,signature:a}),p=`0x41${o.keccak256(`0x${d.toHex(c).slice(4)}`).substring(26)}`,g=E.from(p),I=E.from(o.sha256(o.sha256(p))).slice(0,4),l=E.concat(g,I);return i.encode(l)===t}catch(t){return!1}var s}async function v(s){switch(s.type){case e.SelfDeclaration:return y({},s,{status:s.confirmed?t.VERIFIED:t.FAILED});case e.Screenshot:return y({},s,{status:s.url?t.FLAGGED:t.FAILED});case e.CIP8:return async function(e){var r;const[s,,n]=e.address.split(/:/),a=null==(r=e.chainSpecificData)?void 0:r.cardanoCoseKey;if("cardano"!==s||!a)return y({},e,{status:t.FAILED});try{return y({},e,{status:m(e.proof,a,e.attestation,n)?t.VERIFIED:t.FAILED})}catch(r){return y({},e,{status:t.FAILED})}}(s);case e.EIP191:return async function(e){const[r,,s]=e.address.split(/:/);if("eip155"!==r)return y({},e,{status:t.FAILED});const n=function(t,e,r){try{const s=c.getSignPayload(u.fromString(e)),n=f.fromHex(r),a=h.recoverPublicKey({payload:s,signature:n});return p.checksum(p.fromPublicKey(a)).toString()===p.checksum(t)}catch(t){return!1}}(s,e.attestation,e.proof);return y({},e,{status:n?t.VERIFIED:t.FAILED})}(s);case e.ED25519:return async function(e){const[r,,s]=e.address.split(/:/);if("solana"!==r)return y({},e,{status:t.FAILED});try{const r=i.decode(s),n=(new TextEncoder).encode(e.attestation),o=a.decode(e.proof);return y({},e,{status:l.sign.detached.verify(n,o,r)?t.VERIFIED:t.FAILED})}catch(r){return y({},e,{status:t.FAILED})}}(s);case e.EIP712:case e.BIP137:case e.BIP322:return async function(s){const[n,,i]=s.address.split(/:/);if("bip122"!==n)return y({},s,{status:t.FAILED});const c=function(t){return t.startsWith("1")||t.startsWith("3")||t.startsWith("bc1")?b:t.startsWith("L")||t.startsWith("M")||t.startsWith("ltc1")?A:t.startsWith("D")||t.startsWith("A")?H:t.startsWith("X")||t.startsWith("7")?S:t.startsWith("q")?D:b}(i);if(!c)return y({},s,{status:t.FAILED});try{switch(s.type){case e.BIP137:return function(e,s,n){const i=Boolean(n.bech32Prefix&&[L.SEGWIT,L.NATIVE].includes(function(t){if(t.match("^(bc1|tb1|ltc1).*"))return L.NATIVE;if(t.match("^[32M].*"))return L.SEGWIT;if(t.match("^[1nmL].*"))return L.LEGACY;if(t.match("^(D).*"))return L.DOGECOIN;if(t.match("^(q).*"))return L.BCH;throw new Error("INVALID ADDRESS: ".concat(t).concat(" is not a valid or a supported address"))}(e))),c=function(t,e,s,n,i){const{compressed:c,segwitType:u,signature:f}=function(t){const e=a.decode(t);if(65!==e.length)throw new Error("Invalid signature length");const r=e[0]-27;if(r>15||r<0)throw new Error("Invalid signature parameter");const s=!!(12&r),n=3&r,i=g.Signature.fromCompact(e.slice(1));return{compressed:s,segwitType:8&r?4&r?P.P2WPKH:P.P2SH_P2WPKH:void 0,signature:i.addRecoveryBit(n)}}(s);if(n&&!c)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");const h=function(t,e){const s=(new TextEncoder).encode(e),n=(new TextEncoder).encode(t),a=r(n.length).buffer,i=new Uint8Array(s.length+a.byteLength+n.length);return i.set(s),i.set(new Uint8Array(a),s.length),i.set(n,s.length+a.byteLength),function(t){return o.sha256(o.sha256(t))}(i)}(t,i.messagePrefix),p=(d=f.recoverPublicKey(h).toRawBytes(c),o.ripemd160(o.sha256(d)));var d;let E="";if(e.startsWith("q"))return E=F(i.pubKeyHashVersion,p),E.startsWith("1");if(u)E=u===P.P2SH_P2WPKH?F(i.scriptHashVersion,p):i.bech32Prefix?V(p,i.bech32Prefix):F(i.scriptHashVersion,p);else if(n&&i.bech32Prefix)try{E=V(p,i.bech32Prefix)}catch(t){E=F(i.scriptHashVersion,p)}else E=F(i.pubKeyHashVersion,p);return E===e}(s.attestation,e,s.proof,i,n);return y({},s,{status:c?t.VERIFIED:t.FAILED})}(i,s,c);case e.BIP322:return function(e,r){const{attestation:s,proof:n}=r;return y({},r,{status:I.verifySignature(e,s,n)?t.VERIFIED:t.FAILED})}(i,s);default:return y({},s,{status:t.FAILED})}}catch(e){return y({},s,{status:t.FAILED})}}(s);case e.TIP191:return async function(e){const[r,,s]=e.address.split(/:/);return y({},e,"tron"!==r?{status:t.FAILED}:{status:W(s,e.attestation,e.proof)?t.VERIFIED:t.FAILED})}(s)}return s}export{v as verifyProof};
2
2
  //# sourceMappingURL=index.modern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.modern.js","sources":["../src/bitcoin.ts","../src/tron.ts","../src/index.ts","../src/cardano.ts","../src/eth.ts","../src/solana.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\nconst messagePrefix = \"\\u0018Bitcoin Signed Message:\\n\";\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof) {\n // const messageToBeSigned = message.replace(/\\s+/g, \" \").trim();\n const segwit = [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n );\n const verified = verify(proof.attestation, address, proof.proof, segwit);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBech32Address(publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n // must be true since we only return null, P2SH_P2WPKH, or P2WPKH\n // from the decodeSignature function.\n actual = encodeBech32Address(publicKeyHash);\n }\n } else {\n if (checkSegwitAlways) {\n try {\n actual = encodeBech32Address(publicKeyHash);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBech32Address(publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(0, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(\"bc\", bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","base58check","createBase58check","Hash","sha256","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","verifyTIP191","address","message","proof","payload","data","Hex","fromString","keccak256","from","concat","size","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","hex","PublicKey","toHex","slice","substring","bytes","Bytes","checksum","checked","base58","error","async","verifyProof","type","ProofTypes","SelfDeclaration","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","ns","split","key","chainSpecificData","cardanoCoseKey","verifyDataSignature","attestation","_unused","verifyCIP8Signature","EIP191","verified","PersonalMessage","getSignPayload","Address","fromPublicKey","toString","verifyEIP191","verifyPersonalSignEIP191","ED25519","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","getDerivationMode","checkSegwitAlways","compressed","segwitType","sigbytes","length","flagByte","recovery","secp256k1","fromCompact","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","e","version","encodeBase58AddressFormat","verifyBIP137","signatureProof","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","verifyPersonalSignTIP191"],"mappings":"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"}
1
+ {"version":3,"file":"index.modern.js","sources":["../src/bitcoin.ts","../src/tron.ts","../src/index.ts","../src/cardano.ts","../src/eth.ts","../src/solana.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\ninterface ChainConfig {\n messagePrefix: string;\n pubKeyHashVersion: number;\n scriptHashVersion: number;\n bech32Prefix?: string;\n}\n\nconst CHAIN_CONFIGS: Record<string, ChainConfig> = {\n bitcoin: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n bech32Prefix: \"bc\"\n },\n bitcoincash: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n },\n litecoin: {\n messagePrefix: \"\\u0019Litecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x30, // L... or M...\n scriptHashVersion: 0x32, // 3... or M...\n bech32Prefix: \"ltc\"\n },\n dogecoin: {\n messagePrefix: \"\\u0019Dogecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x1E, // D...\n scriptHashVersion: 0x16, // A...\n },\n dash: {\n messagePrefix: \"\\u0019DarkCoin Signed Message:\\n\",\n pubKeyHashVersion: 0x4C, // X...\n scriptHashVersion: 0x10, // 7...\n },\n};\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns,, address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n \n // Map chainId to our chain configuration\n const chainConfig = getChainConfig(address);\n if (!chainConfig) return { ...proof, status: ProofStatus.FAILED };\n \n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof, chainConfig);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction getChainConfig(address: string): ChainConfig {\n if (address.startsWith(\"1\") || address.startsWith(\"3\") || address.startsWith(\"bc1\")) {\n return CHAIN_CONFIGS[\"bitcoin\"];\n }\n if (address.startsWith(\"L\") || address.startsWith(\"M\") || address.startsWith(\"ltc1\")) {\n return CHAIN_CONFIGS[\"litecoin\"];\n }\n if (address.startsWith(\"D\") || address.startsWith(\"A\")) {\n return CHAIN_CONFIGS[\"dogecoin\"];\n }\n if (address.startsWith(\"X\") || address.startsWith(\"7\")) {\n return CHAIN_CONFIGS[\"dash\"];\n }\n if (address.startsWith(\"q\")) {\n return CHAIN_CONFIGS[\"bitcoincash\"];\n }\n\n return CHAIN_CONFIGS[\"bitcoin\"];\n}\n\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof, chainConfig: ChainConfig) {\n const segwit = Boolean(chainConfig.bech32Prefix && [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n ));\n const verified = verify(proof.attestation, address, proof.proof, segwit, chainConfig);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else if (address.match(\"^(q).*\")) {\n return DerivationMode.BCH;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n chainConfig: ChainConfig\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation, chainConfig.messagePrefix);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n // Special handling for Bitcoin Cash addresses\n if (address.startsWith('q')) {\n // For BCH, we'll compare the public key hash directly since we're getting a CashAddr\n // Convert the CashAddr to legacy format for comparison\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n // Legacy P2PKH addresses in BCH start with '1' just like BTC\n // Source: https://reference.cash/protocol/blockchain/encoding/cashaddr#legacy-address-format\n return actual.startsWith('1');\n }\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n if (chainConfig.bech32Prefix) {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n } else {\n // Fallback to legacy if bech32 not supported\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n }\n } else {\n if (checkSegwitAlways && chainConfig.bech32Prefix) {\n try {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string, messagePrefix: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array, prefix: string = \"bc\"): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(prefix, bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"],"names":["SEGWIT_TYPES","CHAIN_CONFIGS","messagePrefix","pubKeyHashVersion","scriptHashVersion","bech32Prefix","DerivationMode","base58check","createBase58check","Hash","sha256","encodeBase58AddressFormat","version","publicKeyHash","payload","Uint8Array","encode","encodeBech32Address","prefix","bwords","bech32","toWords","unshift","verifyTIP191","address","message","proof","data","Hex","fromString","keccak256","from","concat","size","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","hex","PublicKey","toHex","slice","substring","bytes","Bytes","checksum","checked","base58","error","async","verifyProof","type","ProofTypes","SelfDeclaration","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","ns","split","key","chainSpecificData","cardanoCoseKey","verifyDataSignature","attestation","_unused","verifyCIP8Signature","EIP191","verified","PersonalMessage","getSignPayload","Address","fromPublicKey","toString","verifyEIP191","verifyPersonalSignEIP191","ED25519","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","chainConfig","startsWith","getChainConfig","segwit","Boolean","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","BCH","Error","getDerivationMode","checkSegwitAlways","compressed","segwitType","sigbytes","length","flagByte","recovery","secp256k1","fromCompact","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","hash","encodeLength","buffer","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","e","verifyBIP137","signatureProof","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","verifyPersonalSignTIP191"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@notabene/javascript-sdk"),require("varuint-bitcoin"),require("@scure/base"),require("ox"),require("@noble/curves/secp256k1"),require("bip322-js"),require("tweetnacl"),require("@cardano-foundation/cardano-verify-datasignature")):"function"==typeof define&&define.amd?define(["exports","@notabene/javascript-sdk","varuint-bitcoin","@scure/base","ox","@noble/curves/secp256k1","bip322-js","tweetnacl","@cardano-foundation/cardano-verify-datasignature"],r):r((e||self).verifyProof={},e.javascriptSdk,e.varuintBitcoin,e.base,e.ox,e.secp256k1,e.bip322Js,e.tweetnacl,e.verifyDataSignature)}(this,function(e,r,t,o,s,a,n,i,u){function c(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var f,P,d=/*#__PURE__*/c(i),l=/*#__PURE__*/c(u);function v(){return v=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},v.apply(null,arguments)}!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(f||(f={})),function(e){e.LEGACY="Legacy",e.NATIVE="Native SegWit",e.SEGWIT="SegWit",e.P2SH_SEGWIT="p2sh",e.BCH="Bitcoin Cash",e.ETHEREUM="Ethereum",e.DOGECOIN="Dogecoin",e.UNKNOWN="Unknown"}(P||(P={}));var p=o.createBase58check(s.Hash.sha256);function h(e){var r=o.bech32.toWords(e);return r.unshift(0),o.bech32.encode("bc",r)}e.verifyProof=function(e){try{switch(e.type){case r.ProofTypes.SelfDeclaration:return Promise.resolve(v({},e,{status:e.confirmed?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}));case r.ProofTypes.Screenshot:return Promise.resolve(v({},e,{status:e.url?r.ProofStatus.FLAGGED:r.ProofStatus.FAILED}));case r.ProofTypes.CIP8:return Promise.resolve(function(e){try{var t,o=e.address.split(/:/),s=o[2],a=null==(t=e.chainSpecificData)?void 0:t.cardanoCoseKey;if("cardano"!==o[0]||!a)return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}));try{var n=l.default(e.proof,a,e.attestation,s);return Promise.resolve(v({},e,{status:n?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(t){return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.EIP191:return Promise.resolve(function(e){try{var t=e.address.split(/:/),o=t[2];if("eip155"!==t[0])return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}));var a=function(e,r,t){try{var o=s.PersonalMessage.getSignPayload(s.Hex.fromString(r)),a=s.Signature.fromHex(t),n=s.Secp256k1.recoverPublicKey({payload:o,signature:a});return s.Address.checksum(s.Address.fromPublicKey(n)).toString()===s.Address.checksum(e)}catch(e){return!1}}(o,e.attestation,e.proof);return Promise.resolve(v({},e,{status:a?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.ED25519:return Promise.resolve(function(e){try{var t=e.address.split(/:/),s=t[2];if("solana"!==t[0])return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}));try{var a=o.base58.decode(s),n=(new TextEncoder).encode(e.attestation),i=o.base64.decode(e.proof),u=d.default.sign.detached.verify(n,i,a);return Promise.resolve(v({},e,{status:u?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(t){return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.EIP712:case r.ProofTypes.BIP137:case r.ProofTypes.BIP322:return Promise.resolve(function(e){try{var i=e.address.split(/:/),u=i[2];if("bip122"!==i[0])return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}));try{switch(e.type){case r.ProofTypes.BIP137:return Promise.resolve(function(e,n){var i=[P.SEGWIT,P.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return P.NATIVE;if(e.match("^[32M].*"))return P.SEGWIT;if(e.match("^[1nmL].*"))return P.LEGACY;if(e.match("^(D).*"))return P.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(e)),u=function(e,r,n,i){var u=function(e){var r=o.base64.decode(e);if(65!==r.length)throw new Error("Invalid signature length");var t=r[0]-27;if(t>15||t<0)throw new Error("Invalid signature parameter");var s=!!(12&t),n=3&t,i=a.secp256k1.Signature.fromCompact(r.slice(1));return{compressed:s,segwitType:8&t?4&t?f.P2WPKH:f.P2SH_P2WPKH:void 0,signature:i.addRecoveryBit(n)}}(n),c=u.compressed,P=u.segwitType,d=u.signature;if(i&&!c)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var l,v=function(e){var r=(new TextEncoder).encode("Bitcoin Signed Message:\n"),o=(new TextEncoder).encode(e),a=t.encode(o.length).buffer,n=new Uint8Array(r.length+a.byteLength+o.length);return n.set(r),n.set(new Uint8Array(a),r.length),n.set(o,r.length+a.byteLength),function(e){return s.Hash.sha256(s.Hash.sha256(e))}(n)}(e),y=(l=d.recoverPublicKey(v).toRawBytes(c),s.Hash.ripemd160(s.Hash.sha256(l))),E="";if(P)E=h(y);else if(i)try{E=h(y)}catch(e){E=h(y)}else E=function(e,r){var t=new Uint8Array([0].concat(r));return p.encode(t)}(0,y);return E===r}(n.attestation,e,n.proof,i);return v({},n,{status:u?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED})}(u,e));case r.ProofTypes.BIP322:return Promise.resolve(function(e,t){return v({},t,{status:n.Verifier.verifySignature(e,t.attestation,t.proof)?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED})}(u,e));default:return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}))}}catch(t){return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.TIP191:return Promise.resolve(function(e){try{var t=e.address.split(/:/),a=t[2];if("tron"!==t[0])return Promise.resolve(v({},e,{status:r.ProofStatus.FAILED}));var n=function(e,r,t){try{var a=(d=s.Hex.fromString(r),s.Hash.keccak256(function(e){var r=s.Hex.from(e);return s.Hex.concat("0x19",s.Hex.fromString("TRON Signed Message:\n"+s.Hex.size(r)),r)}(d))),n=s.Signature.fromHex(t),i=s.Secp256k1.recoverPublicKey({payload:a,signature:n}),u="0x41"+s.Hash.keccak256("0x"+s.PublicKey.toHex(i).slice(4)).substring(26),c=s.Bytes.from(u),f=s.Bytes.from(s.Hash.sha256(s.Hash.sha256(u))).slice(0,4),P=s.Bytes.concat(c,f);return o.base58.encode(P)===e}catch(e){return!1}var d}(a,e.attestation,e.proof);return Promise.resolve(v({},e,{status:n?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(e))}return Promise.resolve(e)}catch(e){return Promise.reject(e)}}});
1
+ !function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@notabene/javascript-sdk"),require("varuint-bitcoin"),require("@scure/base"),require("ox"),require("@noble/curves/secp256k1"),require("bip322-js"),require("tweetnacl"),require("@cardano-foundation/cardano-verify-datasignature")):"function"==typeof define&&define.amd?define(["exports","@notabene/javascript-sdk","varuint-bitcoin","@scure/base","ox","@noble/curves/secp256k1","bip322-js","tweetnacl","@cardano-foundation/cardano-verify-datasignature"],r):r((e||self).verifyProof={},e.javascriptSdk,e.varuintBitcoin,e.base,e.ox,e.secp256k1,e.bip322Js,e.tweetnacl,e.verifyDataSignature)}(this,function(e,r,t,s,o,a,i,n,c){function u(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var f,P=/*#__PURE__*/u(n),h=/*#__PURE__*/u(c);function d(){return d=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var s in t)({}).hasOwnProperty.call(t,s)&&(e[s]=t[s])}return e},d.apply(null,arguments)}!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(f||(f={}));var l,p={bitcoin:{messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5,bech32Prefix:"bc"},bitcoincash:{messagePrefix:"Bitcoin Signed Message:\n",pubKeyHashVersion:0,scriptHashVersion:5},litecoin:{messagePrefix:"Litecoin Signed Message:\n",pubKeyHashVersion:48,scriptHashVersion:50,bech32Prefix:"ltc"},dogecoin:{messagePrefix:"Dogecoin Signed Message:\n",pubKeyHashVersion:30,scriptHashVersion:22},dash:{messagePrefix:"DarkCoin Signed Message:\n",pubKeyHashVersion:76,scriptHashVersion:16}};!function(e){e.LEGACY="Legacy",e.NATIVE="Native SegWit",e.SEGWIT="SegWit",e.P2SH_SEGWIT="p2sh",e.BCH="Bitcoin Cash",e.ETHEREUM="Ethereum",e.DOGECOIN="Dogecoin",e.UNKNOWN="Unknown"}(l||(l={}));var v=s.createBase58check(o.Hash.sha256);function y(e,r){var t=new Uint8Array([e].concat(r));return v.encode(t)}function g(e,r){void 0===r&&(r="bc");var t=s.bech32.toWords(e);return t.unshift(0),s.bech32.encode(r,t)}e.verifyProof=function(e){try{switch(e.type){case r.ProofTypes.SelfDeclaration:return Promise.resolve(d({},e,{status:e.confirmed?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}));case r.ProofTypes.Screenshot:return Promise.resolve(d({},e,{status:e.url?r.ProofStatus.FLAGGED:r.ProofStatus.FAILED}));case r.ProofTypes.CIP8:return Promise.resolve(function(e){try{var t,s=e.address.split(/:/),o=s[2],a=null==(t=e.chainSpecificData)?void 0:t.cardanoCoseKey;if("cardano"!==s[0]||!a)return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}));try{var i=h.default(e.proof,a,e.attestation,o);return Promise.resolve(d({},e,{status:i?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(t){return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.EIP191:return Promise.resolve(function(e){try{var t=e.address.split(/:/),s=t[2];if("eip155"!==t[0])return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}));var a=function(e,r,t){try{var s=o.PersonalMessage.getSignPayload(o.Hex.fromString(r)),a=o.Signature.fromHex(t),i=o.Secp256k1.recoverPublicKey({payload:s,signature:a});return o.Address.checksum(o.Address.fromPublicKey(i)).toString()===o.Address.checksum(e)}catch(e){return!1}}(s,e.attestation,e.proof);return Promise.resolve(d({},e,{status:a?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.ED25519:return Promise.resolve(function(e){try{var t=e.address.split(/:/),o=t[2];if("solana"!==t[0])return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}));try{var a=s.base58.decode(o),i=(new TextEncoder).encode(e.attestation),n=s.base64.decode(e.proof),c=P.default.sign.detached.verify(i,n,a);return Promise.resolve(d({},e,{status:c?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(t){return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.EIP712:case r.ProofTypes.BIP137:case r.ProofTypes.BIP322:return Promise.resolve(function(e){try{var n=e.address.split(/:/),c=n[2];if("bip122"!==n[0])return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}));var u=function(e){return e.startsWith("1")||e.startsWith("3")||e.startsWith("bc1")?p.bitcoin:e.startsWith("L")||e.startsWith("M")||e.startsWith("ltc1")?p.litecoin:e.startsWith("D")||e.startsWith("A")?p.dogecoin:e.startsWith("X")||e.startsWith("7")?p.dash:e.startsWith("q")?p.bitcoincash:p.bitcoin}(c);if(!u)return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}));try{switch(e.type){case r.ProofTypes.BIP137:return Promise.resolve(function(e,i,n){var c=Boolean(n.bech32Prefix&&[l.SEGWIT,l.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return l.NATIVE;if(e.match("^[32M].*"))return l.SEGWIT;if(e.match("^[1nmL].*"))return l.LEGACY;if(e.match("^(D).*"))return l.DOGECOIN;if(e.match("^(q).*"))return l.BCH;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(e))),u=function(e,r,i,n,c){var u=function(e){var r=s.base64.decode(e);if(65!==r.length)throw new Error("Invalid signature length");var t=r[0]-27;if(t>15||t<0)throw new Error("Invalid signature parameter");var o=!!(12&t),i=3&t,n=a.secp256k1.Signature.fromCompact(r.slice(1));return{compressed:o,segwitType:8&t?4&t?f.P2WPKH:f.P2SH_P2WPKH:void 0,signature:n.addRecoveryBit(i)}}(i),P=u.compressed,h=u.segwitType,d=u.signature;if(n&&!P)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var l,p=function(e,r){var s=(new TextEncoder).encode(r),a=(new TextEncoder).encode(e),i=t.encode(a.length).buffer,n=new Uint8Array(s.length+i.byteLength+a.length);return n.set(s),n.set(new Uint8Array(i),s.length),n.set(a,s.length+i.byteLength),function(e){return o.Hash.sha256(o.Hash.sha256(e))}(n)}(e,c.messagePrefix),v=(l=d.recoverPublicKey(p).toRawBytes(P),o.Hash.ripemd160(o.Hash.sha256(l))),m="";if(r.startsWith("q"))return(m=y(c.pubKeyHashVersion,v)).startsWith("1");if(h)m=h===f.P2SH_P2WPKH?y(c.scriptHashVersion,v):c.bech32Prefix?g(v,c.bech32Prefix):y(c.scriptHashVersion,v);else if(n&&c.bech32Prefix)try{m=g(v,c.bech32Prefix)}catch(e){m=y(c.scriptHashVersion,v)}else m=y(c.pubKeyHashVersion,v);return m===r}(i.attestation,e,i.proof,c,n);return d({},i,{status:u?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED})}(c,e,u));case r.ProofTypes.BIP322:return Promise.resolve(function(e,t){return d({},t,{status:i.Verifier.verifySignature(e,t.attestation,t.proof)?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED})}(c,e));default:return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}))}}catch(t){return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.TIP191:return Promise.resolve(function(e){try{var t=e.address.split(/:/),a=t[2];if("tron"!==t[0])return Promise.resolve(d({},e,{status:r.ProofStatus.FAILED}));var i=function(e,r,t){try{var a=(h=o.Hex.fromString(r),o.Hash.keccak256(function(e){var r=o.Hex.from(e);return o.Hex.concat("0x19",o.Hex.fromString("TRON Signed Message:\n"+o.Hex.size(r)),r)}(h))),i=o.Signature.fromHex(t),n=o.Secp256k1.recoverPublicKey({payload:a,signature:i}),c="0x41"+o.Hash.keccak256("0x"+o.PublicKey.toHex(n).slice(4)).substring(26),u=o.Bytes.from(c),f=o.Bytes.from(o.Hash.sha256(o.Hash.sha256(c))).slice(0,4),P=o.Bytes.concat(u,f);return s.base58.encode(P)===e}catch(e){return!1}var h}(a,e.attestation,e.proof);return Promise.resolve(d({},e,{status:i?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(e))}return Promise.resolve(e)}catch(e){return Promise.reject(e)}}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/bitcoin.ts","../src/index.ts","../src/cardano.ts","../src/eth.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\nconst messagePrefix = \"\\u0018Bitcoin Signed Message:\\n\";\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof) {\n // const messageToBeSigned = message.replace(/\\s+/g, \" \").trim();\n const segwit = [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n );\n const verified = verify(proof.attestation, address, proof.proof, segwit);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBech32Address(publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n // must be true since we only return null, P2SH_P2WPKH, or P2WPKH\n // from the decodeSignature function.\n actual = encodeBech32Address(publicKeyHash);\n }\n } else {\n if (checkSegwitAlways) {\n try {\n actual = encodeBech32Address(publicKeyHash);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBech32Address(publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(0, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(\"bc\", bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}\n","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","base58check","createBase58check","Hash","sha256","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","_proof$address$split","address","split","key","chainSpecificData","cardanoCoseKey","verified","verifyDataSignature","attestation","_unused","e","reject","verifyCIP8Signature","EIP191","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","sigbytes","length","flagByte","compressed","recovery","secp256k1","fromCompact","slice","segwitType","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","buffer","hash","prefix","encodeLength","Uint8Array","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","version","encodeBase58AddressFormat","verifyBIP137","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","data","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","checked","verifyTIP191","verifyPersonalSignTIP191"],"mappings":"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"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/bitcoin.ts","../src/index.ts","../src/cardano.ts","../src/eth.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import {\n ProofStatus,\n ProofTypes,\n SignatureProof,\n} from \"@notabene/javascript-sdk\";\n\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32, createBase58check } from \"@scure/base\";\nimport { Hash } from \"ox\";\nimport { secp256k1 } from \"@noble/curves/secp256k1\";\nimport { SignatureType } from \"@noble/curves/abstract/weierstrass\";\nimport { Verifier } from \"bip322-js\";\n\nenum SEGWIT_TYPES {\n P2WPKH = \"p2wpkh\",\n P2SH_P2WPKH = \"p2sh(p2wpkh)\",\n}\n\ninterface ChainConfig {\n messagePrefix: string;\n pubKeyHashVersion: number;\n scriptHashVersion: number;\n bech32Prefix?: string;\n}\n\nconst CHAIN_CONFIGS: Record<string, ChainConfig> = {\n bitcoin: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n bech32Prefix: \"bc\"\n },\n bitcoincash: {\n messagePrefix: \"\\u0018Bitcoin Signed Message:\\n\",\n pubKeyHashVersion: 0x00, // 1...\n scriptHashVersion: 0x05, // 3...\n },\n litecoin: {\n messagePrefix: \"\\u0019Litecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x30, // L... or M...\n scriptHashVersion: 0x32, // 3... or M...\n bech32Prefix: \"ltc\"\n },\n dogecoin: {\n messagePrefix: \"\\u0019Dogecoin Signed Message:\\n\",\n pubKeyHashVersion: 0x1E, // D...\n scriptHashVersion: 0x16, // A...\n },\n dash: {\n messagePrefix: \"\\u0019DarkCoin Signed Message:\\n\",\n pubKeyHashVersion: 0x4C, // X...\n scriptHashVersion: 0x10, // 7...\n },\n};\n\nenum DerivationMode {\n LEGACY = \"Legacy\",\n NATIVE = \"Native SegWit\",\n SEGWIT = \"SegWit\",\n P2SH_SEGWIT = \"p2sh\",\n BCH = \"Bitcoin Cash\",\n ETHEREUM = \"Ethereum\",\n DOGECOIN = \"Dogecoin\",\n UNKNOWN = \"Unknown\",\n}\n\nexport async function verifyBTCSignature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns,, address] = proof.address.split(/:/);\n if (ns !== \"bip122\") return { ...proof, status: ProofStatus.FAILED };\n \n // Map chainId to our chain configuration\n const chainConfig = getChainConfig(address);\n if (!chainConfig) return { ...proof, status: ProofStatus.FAILED };\n \n try {\n switch (proof.type) {\n case ProofTypes.BIP137:\n return verifyBIP137(address, proof, chainConfig);\n case ProofTypes.BIP322:\n return verifyBIP322(address, proof);\n default:\n return {\n ...proof,\n status: ProofStatus.FAILED,\n };\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n // console.error(\"error verifying proof\", error);\n return {\n ...proof,\n status: ProofStatus.FAILED,\n // error: error.message || error,\n };\n }\n}\n\nfunction getChainConfig(address: string): ChainConfig {\n if (address.startsWith(\"1\") || address.startsWith(\"3\") || address.startsWith(\"bc1\")) {\n return CHAIN_CONFIGS[\"bitcoin\"];\n }\n if (address.startsWith(\"L\") || address.startsWith(\"M\") || address.startsWith(\"ltc1\")) {\n return CHAIN_CONFIGS[\"litecoin\"];\n }\n if (address.startsWith(\"D\") || address.startsWith(\"A\")) {\n return CHAIN_CONFIGS[\"dogecoin\"];\n }\n if (address.startsWith(\"X\") || address.startsWith(\"7\")) {\n return CHAIN_CONFIGS[\"dash\"];\n }\n if (address.startsWith(\"q\")) {\n return CHAIN_CONFIGS[\"bitcoincash\"];\n }\n\n return CHAIN_CONFIGS[\"bitcoin\"];\n}\n\n\nfunction verifyBIP322(address: string, proof: SignatureProof) {\n const { attestation, proof: signatureProof } = proof;\n const verified = Verifier.verifySignature(\n address,\n attestation,\n signatureProof\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction verifyBIP137(address: string, proof: SignatureProof, chainConfig: ChainConfig) {\n const segwit = Boolean(chainConfig.bech32Prefix && [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(\n getDerivationMode(address)\n ));\n const verified = verify(proof.attestation, address, proof.proof, segwit, chainConfig);\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nfunction getDerivationMode(address: string) {\n if (address.match(\"^(bc1|tb1|ltc1).*\")) {\n return DerivationMode.NATIVE;\n } else if (address.match(\"^[32M].*\")) {\n return DerivationMode.SEGWIT;\n } else if (address.match(\"^[1nmL].*\")) {\n return DerivationMode.LEGACY;\n } else if (address.match(\"^(D).*\")) {\n return DerivationMode.DOGECOIN;\n } else if (address.match(\"^(q).*\")) {\n return DerivationMode.BCH;\n } else {\n throw new Error(\n \"INVALID ADDRESS: \"\n .concat(address)\n .concat(\" is not a valid or a supported address\")\n );\n }\n}\n\ntype DecodedSignature = {\n compressed: boolean;\n segwitType?: SEGWIT_TYPES;\n signature: SignatureType;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const sigbytes = base64.decode(proof);\n if (sigbytes.length !== 65) throw new Error(\"Invalid signature length\");\n const flagByte = sigbytes[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n const compressed = !!(flagByte & 12); // Are there cases that aren't compressed?\n const recovery = flagByte & 3;\n const signature = secp256k1.Signature.fromCompact(sigbytes.slice(1));\n\n return {\n compressed,\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n signature: signature.addRecoveryBit(recovery),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n chainConfig: ChainConfig\n) {\n const { compressed, segwitType, signature } = decodeSignature(proof);\n if (checkSegwitAlways && !compressed) {\n throw new Error(\n \"checkSegwitAlways can only be used with a compressed pubkey signature flagbyte\"\n );\n }\n const hash = magicHash(attestation, chainConfig.messagePrefix);\n const publicKey = signature.recoverPublicKey(hash);\n const publicKeyBytes = publicKey.toRawBytes(compressed);\n const publicKeyHash = hash160(publicKeyBytes);\n let actual: string = \"\";\n\n // Special handling for Bitcoin Cash addresses\n if (address.startsWith('q')) {\n // For BCH, we'll compare the public key hash directly since we're getting a CashAddr\n // Convert the CashAddr to legacy format for comparison\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n // Legacy P2PKH addresses in BCH start with '1' just like BTC\n // Source: https://reference.cash/protocol/blockchain/encoding/cashaddr#legacy-address-format\n return actual.startsWith('1');\n }\n\n if (segwitType) {\n if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n } else {\n // parsed.segwitType === SEGWIT_TYPES.P2WPKH\n if (chainConfig.bech32Prefix) {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n } else {\n // Fallback to legacy if bech32 not supported\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n }\n } else {\n if (checkSegwitAlways && chainConfig.bech32Prefix) {\n try {\n actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);\n // if address is bech32 it is not p2sh\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (e) {\n actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);\n // base58 can be p2pkh or p2sh-p2wpkh\n }\n } else {\n actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);\n }\n }\n\n return actual === address;\n}\n\nconst base58check = createBase58check(Hash.sha256);\n\nfunction encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {\n const payload = new Uint8Array([version, ...publicKeyHash]);\n return base58check.encode(payload);\n}\n\nfunction magicHash(attestation: string, messagePrefix: string) {\n const prefix = new TextEncoder().encode(messagePrefix);\n const message = new TextEncoder().encode(attestation);\n const length = encodeLength(message.length).buffer;\n const buffer = new Uint8Array(\n prefix.length + length.byteLength + message.length\n );\n buffer.set(prefix);\n buffer.set(new Uint8Array(length), prefix.length);\n buffer.set(message, prefix.length + length.byteLength);\n return hash256(buffer);\n}\n\nfunction encodeBech32Address(publicKeyHash: Uint8Array, prefix: string = \"bc\"): string {\n const bwords = bech32.toWords(publicKeyHash);\n bwords.unshift(0);\n return bech32.encode(prefix, bwords);\n}\n\nfunction hash256(buffer: Uint8Array): Uint8Array {\n return Hash.sha256(Hash.sha256(buffer));\n}\n\nfunction hash160(buffer: Uint8Array): Uint8Array {\n return Hash.ripemd160(Hash.sha256(buffer));\n}","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk\";\nimport { verifyBTCSignature } from \"./bitcoin\";\nimport { verifyPersonalSignEIP191 } from \"./eth\";\nimport { verifySolanaSignature } from \"./solana\";\nimport { verifyPersonalSignTIP191 } from \"./tron\";\nimport { verifyCIP8Signature } from \"./cardano\";\n\nexport async function verifyProof(\n proof: OwnershipProof\n): Promise<OwnershipProof> {\n switch (proof.type) {\n case ProofTypes.SelfDeclaration:\n return {\n ...proof,\n status: (proof as DeclarationProof).confirmed\n ? ProofStatus.VERIFIED\n : ProofStatus.FAILED,\n };\n case ProofTypes.Screenshot:\n return {\n ...proof,\n status: (proof as ScreenshotProof).url\n ? ProofStatus.FLAGGED\n : ProofStatus.FAILED,\n };\n case ProofTypes.CIP8:\n return verifyCIP8Signature(proof as SignatureProof);\n case ProofTypes.EIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.ED25519:\n return verifySolanaSignature(proof as SignatureProof);\n case ProofTypes.EIP712:\n case ProofTypes.BIP137:\n case ProofTypes.BIP322:\n return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.TIP191:\n return verifyPersonalSignTIP191(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n","import verifyDataSignature from \"@cardano-foundation/cardano-verify-datasignature\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nexport async function verifyCIP8Signature(\n proof: SignatureProof\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n const key = proof.chainSpecificData?.cardanoCoseKey;\n \n if (ns !== \"cardano\" || !key) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n \n try {\n const verified = verifyDataSignature(proof.proof, key, proof.attestation, address);\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED\n };\n } catch {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, PersonalMessage, Signature, Address } from \"ox\";\n\nexport function verifyEIP191(\n address: Hex.Hex,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = PersonalMessage.getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const recovered = Address.checksum(Address.fromPublicKey(publicKey));\n return recovered.toString() === Address.checksum(address);\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignEIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"eip155\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyEIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import nacl from \"tweetnacl\";\nimport { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { base64, base58 } from \"@scure/base\";\n\nexport async function verifySolanaSignature(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"solana\") return { ...proof, status: ProofStatus.FAILED };\n try {\n const publicKey = base58.decode(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = base64.decode(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey,\n );\n\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n","import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\nimport { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from \"ox\";\nimport { base58 } from \"@scure/base\";\n\nexport function verifyTIP191(\n address: string,\n message: string,\n proof: Hex.Hex,\n): boolean {\n try {\n const payload = getSignPayload(Hex.fromString(message));\n const signature = Signature.fromHex(proof);\n const publicKey = Secp256k1.recoverPublicKey({ payload, signature });\n const hex: Hex.Hex = `0x41${Hash.keccak256(\n `0x${PublicKey.toHex(publicKey).slice(4)}`,\n ).substring(26)}`;\n const bytes = Bytes.from(hex);\n const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);\n const checked = Bytes.concat(bytes, checksum);\n const b58 = base58.encode(checked);\n return b58 === address;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error) {\n return false;\n }\n}\n\nexport async function verifyPersonalSignTIP191(\n proof: SignatureProof,\n): Promise<SignatureProof> {\n const [ns, , address] = proof.address.split(/:/);\n if (ns !== \"tron\") return { ...proof, status: ProofStatus.FAILED };\n\n const verified = verifyTIP191(\n address as Hex.Hex,\n proof.attestation,\n proof.proof as Hex.Hex,\n );\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n\nexport function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n const message = Hex.from(data);\n return Hex.concat(\n // Personal Sign Format: `0x19 ‖ \"Ethereum Signed Message:\\n\" ‖ message.length ‖ message`\n \"0x19\",\n Hex.fromString(\"TRON Signed Message:\\n\" + Hex.size(message)),\n message,\n );\n}\nexport function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {\n return Hash.keccak256(encode(data));\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","CHAIN_CONFIGS","bitcoin","messagePrefix","pubKeyHashVersion","scriptHashVersion","bech32Prefix","bitcoincash","litecoin","dogecoin","dash","base58check","createBase58check","Hash","sha256","encodeBase58AddressFormat","version","publicKeyHash","payload","Uint8Array","concat","encode","encodeBech32Address","prefix","bwords","bech32","toWords","unshift","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","CIP8","_proof$chainSpecificD","_proof$address$split","address","split","key","chainSpecificData","cardanoCoseKey","verified","verifyDataSignature","attestation","_unused","e","reject","verifyCIP8Signature","EIP191","message","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","BIP322","chainConfig","startsWith","getChainConfig","segwit","Boolean","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","BCH","Error","getDerivationMode","checkSegwitAlways","_decodeSignature","sigbytes","length","flagByte","compressed","recovery","secp256k1","fromCompact","slice","segwitType","P2WPKH","P2SH_P2WPKH","undefined","addRecoveryBit","decodeSignature","buffer","hash","encodeLength","byteLength","set","hash256","magicHash","toRawBytes","ripemd160","actual","verifyBIP137","Verifier","verifySignature","verifyBIP322","verifyBTCSignature","TIP191","data","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","checked","verifyTIP191","verifyPersonalSignTIP191"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notabene/verify-proof",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Verify ownership proofs",
5
5
  "source": "src/index.ts",
6
6
  "type": "module",
@@ -21,7 +21,8 @@
21
21
  "build:clean": "rm -rf dist",
22
22
  "build": "microbundle",
23
23
  "lint": "eslint ./src",
24
- "test": "vitest"
24
+ "test:unit": "vitest",
25
+ "test:coverage": "vitest --coverage"
25
26
  },
26
27
  "publishConfig": {
27
28
  "access": "public"
package/src/bitcoin.ts CHANGED
@@ -16,7 +16,42 @@ enum SEGWIT_TYPES {
16
16
  P2SH_P2WPKH = "p2sh(p2wpkh)",
17
17
  }
18
18
 
19
- const messagePrefix = "\u0018Bitcoin Signed Message:\n";
19
+ interface ChainConfig {
20
+ messagePrefix: string;
21
+ pubKeyHashVersion: number;
22
+ scriptHashVersion: number;
23
+ bech32Prefix?: string;
24
+ }
25
+
26
+ const CHAIN_CONFIGS: Record<string, ChainConfig> = {
27
+ bitcoin: {
28
+ messagePrefix: "\u0018Bitcoin Signed Message:\n",
29
+ pubKeyHashVersion: 0x00, // 1...
30
+ scriptHashVersion: 0x05, // 3...
31
+ bech32Prefix: "bc"
32
+ },
33
+ bitcoincash: {
34
+ messagePrefix: "\u0018Bitcoin Signed Message:\n",
35
+ pubKeyHashVersion: 0x00, // 1...
36
+ scriptHashVersion: 0x05, // 3...
37
+ },
38
+ litecoin: {
39
+ messagePrefix: "\u0019Litecoin Signed Message:\n",
40
+ pubKeyHashVersion: 0x30, // L... or M...
41
+ scriptHashVersion: 0x32, // 3... or M...
42
+ bech32Prefix: "ltc"
43
+ },
44
+ dogecoin: {
45
+ messagePrefix: "\u0019Dogecoin Signed Message:\n",
46
+ pubKeyHashVersion: 0x1E, // D...
47
+ scriptHashVersion: 0x16, // A...
48
+ },
49
+ dash: {
50
+ messagePrefix: "\u0019DarkCoin Signed Message:\n",
51
+ pubKeyHashVersion: 0x4C, // X...
52
+ scriptHashVersion: 0x10, // 7...
53
+ },
54
+ };
20
55
 
21
56
  enum DerivationMode {
22
57
  LEGACY = "Legacy",
@@ -32,12 +67,17 @@ enum DerivationMode {
32
67
  export async function verifyBTCSignature(
33
68
  proof: SignatureProof
34
69
  ): Promise<SignatureProof> {
35
- const [ns, , address] = proof.address.split(/:/);
70
+ const [ns,, address] = proof.address.split(/:/);
36
71
  if (ns !== "bip122") return { ...proof, status: ProofStatus.FAILED };
72
+
73
+ // Map chainId to our chain configuration
74
+ const chainConfig = getChainConfig(address);
75
+ if (!chainConfig) return { ...proof, status: ProofStatus.FAILED };
76
+
37
77
  try {
38
78
  switch (proof.type) {
39
79
  case ProofTypes.BIP137:
40
- return verifyBIP137(address, proof);
80
+ return verifyBIP137(address, proof, chainConfig);
41
81
  case ProofTypes.BIP322:
42
82
  return verifyBIP322(address, proof);
43
83
  default:
@@ -57,6 +97,27 @@ export async function verifyBTCSignature(
57
97
  }
58
98
  }
59
99
 
100
+ function getChainConfig(address: string): ChainConfig {
101
+ if (address.startsWith("1") || address.startsWith("3") || address.startsWith("bc1")) {
102
+ return CHAIN_CONFIGS["bitcoin"];
103
+ }
104
+ if (address.startsWith("L") || address.startsWith("M") || address.startsWith("ltc1")) {
105
+ return CHAIN_CONFIGS["litecoin"];
106
+ }
107
+ if (address.startsWith("D") || address.startsWith("A")) {
108
+ return CHAIN_CONFIGS["dogecoin"];
109
+ }
110
+ if (address.startsWith("X") || address.startsWith("7")) {
111
+ return CHAIN_CONFIGS["dash"];
112
+ }
113
+ if (address.startsWith("q")) {
114
+ return CHAIN_CONFIGS["bitcoincash"];
115
+ }
116
+
117
+ return CHAIN_CONFIGS["bitcoin"];
118
+ }
119
+
120
+
60
121
  function verifyBIP322(address: string, proof: SignatureProof) {
61
122
  const { attestation, proof: signatureProof } = proof;
62
123
  const verified = Verifier.verifySignature(
@@ -70,12 +131,11 @@ function verifyBIP322(address: string, proof: SignatureProof) {
70
131
  };
71
132
  }
72
133
 
73
- function verifyBIP137(address: string, proof: SignatureProof) {
74
- // const messageToBeSigned = message.replace(/\s+/g, " ").trim();
75
- const segwit = [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(
134
+ function verifyBIP137(address: string, proof: SignatureProof, chainConfig: ChainConfig) {
135
+ const segwit = Boolean(chainConfig.bech32Prefix && [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(
76
136
  getDerivationMode(address)
77
- );
78
- const verified = verify(proof.attestation, address, proof.proof, segwit);
137
+ ));
138
+ const verified = verify(proof.attestation, address, proof.proof, segwit, chainConfig);
79
139
 
80
140
  return {
81
141
  ...proof,
@@ -92,6 +152,8 @@ function getDerivationMode(address: string) {
92
152
  return DerivationMode.LEGACY;
93
153
  } else if (address.match("^(D).*")) {
94
154
  return DerivationMode.DOGECOIN;
155
+ } else if (address.match("^(q).*")) {
156
+ return DerivationMode.BCH;
95
157
  } else {
96
158
  throw new Error(
97
159
  "INVALID ADDRESS: "
@@ -133,7 +195,8 @@ function verify(
133
195
  attestation: string,
134
196
  address: string,
135
197
  proof: string,
136
- checkSegwitAlways: boolean
198
+ checkSegwitAlways: boolean,
199
+ chainConfig: ChainConfig
137
200
  ) {
138
201
  const { compressed, segwitType, signature } = decodeSignature(proof);
139
202
  if (checkSegwitAlways && !compressed) {
@@ -141,33 +204,47 @@ function verify(
141
204
  "checkSegwitAlways can only be used with a compressed pubkey signature flagbyte"
142
205
  );
143
206
  }
144
- const hash = magicHash(attestation);
207
+ const hash = magicHash(attestation, chainConfig.messagePrefix);
145
208
  const publicKey = signature.recoverPublicKey(hash);
146
209
  const publicKeyBytes = publicKey.toRawBytes(compressed);
147
210
  const publicKeyHash = hash160(publicKeyBytes);
148
211
  let actual: string = "";
149
212
 
213
+ // Special handling for Bitcoin Cash addresses
214
+ if (address.startsWith('q')) {
215
+ // For BCH, we'll compare the public key hash directly since we're getting a CashAddr
216
+ // Convert the CashAddr to legacy format for comparison
217
+ actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);
218
+ // Legacy P2PKH addresses in BCH start with '1' just like BTC
219
+ // Source: https://reference.cash/protocol/blockchain/encoding/cashaddr#legacy-address-format
220
+ return actual.startsWith('1');
221
+ }
222
+
150
223
  if (segwitType) {
151
224
  if (segwitType === SEGWIT_TYPES.P2SH_P2WPKH) {
152
- actual = encodeBech32Address(publicKeyHash);
225
+ actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);
153
226
  } else {
154
227
  // parsed.segwitType === SEGWIT_TYPES.P2WPKH
155
- // must be true since we only return null, P2SH_P2WPKH, or P2WPKH
156
- // from the decodeSignature function.
157
- actual = encodeBech32Address(publicKeyHash);
228
+ if (chainConfig.bech32Prefix) {
229
+ actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);
230
+ } else {
231
+ // Fallback to legacy if bech32 not supported
232
+ actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);
233
+ // base58 can be p2pkh or p2sh-p2wpkh
234
+ }
158
235
  }
159
236
  } else {
160
- if (checkSegwitAlways) {
237
+ if (checkSegwitAlways && chainConfig.bech32Prefix) {
161
238
  try {
162
- actual = encodeBech32Address(publicKeyHash);
239
+ actual = encodeBech32Address(publicKeyHash, chainConfig.bech32Prefix);
163
240
  // if address is bech32 it is not p2sh
164
241
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
165
242
  } catch (e) {
166
- actual = encodeBech32Address(publicKeyHash);
243
+ actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);
167
244
  // base58 can be p2pkh or p2sh-p2wpkh
168
245
  }
169
246
  } else {
170
- actual = encodeBase58AddressFormat(0, publicKeyHash);
247
+ actual = encodeBase58AddressFormat(chainConfig.pubKeyHashVersion, publicKeyHash);
171
248
  }
172
249
  }
173
250
 
@@ -181,7 +258,7 @@ function encodeBase58AddressFormat(version: number, publicKeyHash: Uint8Array) {
181
258
  return base58check.encode(payload);
182
259
  }
183
260
 
184
- function magicHash(attestation: string) {
261
+ function magicHash(attestation: string, messagePrefix: string) {
185
262
  const prefix = new TextEncoder().encode(messagePrefix);
186
263
  const message = new TextEncoder().encode(attestation);
187
264
  const length = encodeLength(message.length).buffer;
@@ -194,10 +271,10 @@ function magicHash(attestation: string) {
194
271
  return hash256(buffer);
195
272
  }
196
273
 
197
- function encodeBech32Address(publicKeyHash: Uint8Array): string {
274
+ function encodeBech32Address(publicKeyHash: Uint8Array, prefix: string = "bc"): string {
198
275
  const bwords = bech32.toWords(publicKeyHash);
199
276
  bwords.unshift(0);
200
- return bech32.encode("bc", bwords);
277
+ return bech32.encode(prefix, bwords);
201
278
  }
202
279
 
203
280
  function hash256(buffer: Uint8Array): Uint8Array {
@@ -206,4 +283,4 @@ function hash256(buffer: Uint8Array): Uint8Array {
206
283
 
207
284
  function hash160(buffer: Uint8Array): Uint8Array {
208
285
  return Hash.ripemd160(Hash.sha256(buffer));
209
- }
286
+ }
@@ -56,10 +56,25 @@ const uncompressedProof: SignatureProof = {
56
56
  wallet_provider: "BitMask",
57
57
  };
58
58
 
59
+ const dogeProof: SignatureProof = {
60
+ type: ProofTypes.BIP137,
61
+ address:
62
+ "bip122:1a91e3dace36e2be3bf030a65679fe821:DUPSs55GNRZUUUKJu4zxTJU7oTd7MHRgY6",
63
+ did: "did:pkh:bip122:1a91e3dace36e2be3bf030a65679fe821:DUPSs55GNRZUUUKJu4zxTJU7oTd7MHRgY6",
64
+ attestation: "A message signed by dogecoin address",
65
+ proof:
66
+ "ILY5fRTcA4rss44H+JoHZ7Ab5N6rMGkEAU0Q/Co0zXdcGXDOQLQoy7Tdb1a2oJz1xzFGiyzO1+eDcIG7ebqxvBM=",
67
+ status: ProofStatus.PENDING,
68
+ wallet_provider: "Doge",
69
+ };
70
+
59
71
  describe("verifyBTCSignature", () => {
60
72
  it("handles bip322 segwit addresses", async () => {
61
73
  const result = await verifyBTCSignature(bip322SegwitProof);
62
- expect(result).toEqual({ ...bip322SegwitProof, status: ProofStatus.VERIFIED });
74
+ expect(result).toEqual({
75
+ ...bip322SegwitProof,
76
+ status: ProofStatus.VERIFIED,
77
+ });
63
78
  });
64
79
 
65
80
  it("handles native segwit addresses", async () => {
@@ -72,6 +87,11 @@ describe("verifyBTCSignature", () => {
72
87
  expect(result).toEqual({ ...legacyProof, status: ProofStatus.VERIFIED });
73
88
  });
74
89
 
90
+ it("verifies dogecoin address signature", async () => {
91
+ const result = await verifyBTCSignature(dogeProof);
92
+ expect(result).toEqual({ ...dogeProof, status: ProofStatus.VERIFIED });
93
+ });
94
+
75
95
  it("fails for invalid bitcoin signature", async () => {
76
96
  const proof: SignatureProof = { ...legacyProof, proof: "invalitd" };
77
97
 
@@ -99,4 +119,239 @@ describe("verifyBTCSignature", () => {
99
119
  status: ProofStatus.VERIFIED,
100
120
  });
101
121
  });
122
+
123
+ it("handles litecoin addresses", async () => {
124
+ const litecoinProof: SignatureProof = {
125
+ type: ProofTypes.BIP137,
126
+ address:
127
+ "bip122:12a765e31ffd4059bada1e25190f6e98:ltc1qp3la5p5wf8wnfg7hc3nga8kq0xs6tk5fn6v3r3",
128
+ did: "did:pkh:bip122:12a765e31ffd4059bada1e25190f6e98:ltc1qp3la5p5wf8wnfg7hc3nga8kq0xs6tk5fn6v3r3",
129
+ attestation: "Message signed by Litecoin address",
130
+ proof:
131
+ "HzdyCcPqCIo7288qY/6jBWtnzzcEeO/R3KJtcf099gSVMHqAC7VwmO6pizjguYqwfcZ/M8E98h6UlG7VGjeIoh0=",
132
+ status: ProofStatus.PENDING,
133
+ wallet_provider: "LiteWallet",
134
+ };
135
+
136
+ const result = await verifyBTCSignature(litecoinProof);
137
+ expect(result).toEqual({ ...litecoinProof, status: ProofStatus.VERIFIED });
138
+ });
139
+
140
+ it("handles dash addresses", async () => {
141
+ const dashProof: SignatureProof = {
142
+ type: ProofTypes.BIP137,
143
+ address:
144
+ "bip122:9d4e2ba8a29995befa0e1e04b99c8331:XhUP4tkUy5gwVWxsWTXNMhK5ss7uDHWR2c",
145
+ did: "did:pkh:bip122:9d4e2ba8a29995befa0e1e04b99c8331:XhUP4tkUy5gwVWxsWTXNMhK5ss7uDHWR2c",
146
+ attestation: "Message signed by Dash address",
147
+ proof:
148
+ "HxlEomN4BV/Mg+Gxjzy37UxSwpZtFbb0qcfppoMFK+/NKWqH9X7WMnZAwz6Iti1032Oz0YeHZNk5NUV8rdtPbPc=",
149
+ status: ProofStatus.PENDING,
150
+ wallet_provider: "DashWallet",
151
+ };
152
+
153
+ const result = await verifyBTCSignature(dashProof);
154
+ expect(result).toEqual({ ...dashProof, status: ProofStatus.VERIFIED });
155
+ });
156
+
157
+ it("fails for invalid BIP322 signature", async () => {
158
+ const invalidBip322Proof: SignatureProof = {
159
+ ...bip322SegwitProof,
160
+ proof: "InvalidSignatureFormat",
161
+ };
162
+
163
+ const result = await verifyBTCSignature(invalidBip322Proof);
164
+ expect(result).toEqual({
165
+ ...invalidBip322Proof,
166
+ status: ProofStatus.FAILED,
167
+ });
168
+ });
169
+
170
+ it("fails for invalid signature length", async () => {
171
+ const invalidLengthProof: SignatureProof = {
172
+ ...legacyProof,
173
+ proof: "TooShortSig",
174
+ };
175
+
176
+ const result = await verifyBTCSignature(invalidLengthProof);
177
+ expect(result).toEqual({
178
+ ...invalidLengthProof,
179
+ status: ProofStatus.FAILED,
180
+ });
181
+ });
182
+
183
+ it("fails for invalid signature flag byte", async () => {
184
+ const invalidFlagProof: SignatureProof = {
185
+ ...legacyProof,
186
+ proof:
187
+ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
188
+ };
189
+
190
+ const result = await verifyBTCSignature(invalidFlagProof);
191
+ expect(result).toEqual({ ...invalidFlagProof, status: ProofStatus.FAILED });
192
+ });
193
+
194
+ it("fails for unsupported proof type", async () => {
195
+ const unsupportedProof: SignatureProof = {
196
+ ...legacyProof,
197
+ type: ProofTypes.SIWX,
198
+ };
199
+
200
+ const result = await verifyBTCSignature(unsupportedProof);
201
+ expect(result).toEqual({ ...unsupportedProof, status: ProofStatus.FAILED });
202
+ });
203
+
204
+ it("throws error for unsupported address format", async () => {
205
+ const invalidAddressProof: SignatureProof = {
206
+ ...legacyProof,
207
+ address: "bip122:000000000019d6689c085ae165831e93:Y123456789", // Invalid prefix
208
+ };
209
+
210
+ const result = await verifyBTCSignature(invalidAddressProof);
211
+ expect(result).toEqual({
212
+ ...invalidAddressProof,
213
+ status: ProofStatus.FAILED,
214
+ });
215
+ });
216
+
217
+ it("handles P2WPKH segwit type without bech32 support", async () => {
218
+ const p2wpkhProof: SignatureProof = {
219
+ ...legacyProof,
220
+ proof:
221
+ "INjxKyXqYtsPWqP+zYvZUtADMLR8IC8jBMQ029hutdcoSkss3B1Iv79x5u6Zo6Fn168H8PuiySOtk8cDU4uZUBU=",
222
+ address:
223
+ "bip122:1a91e3dace36e2be3bf030a65679fe821:16qcANyseCYSnSZHJFMSbsD5Z1Qns8jbe4",
224
+ };
225
+
226
+ const result = await verifyBTCSignature(p2wpkhProof);
227
+ expect(result).toEqual({ ...p2wpkhProof, status: ProofStatus.VERIFIED });
228
+ });
229
+
230
+ it("handles bech32 encoding errors", async () => {
231
+ const invalidBech32Proof: SignatureProof = {
232
+ ...segwitProof,
233
+ address:
234
+ "bip122:000000000019d6689c085ae165831e93:bc1qcxm70pg5yk9c8pupj93uys5azw5xpt6qeu2z0u",
235
+ proof:
236
+ "H1234567890123456789012345678901234567890123456789012345678901234567890123456789012345=",
237
+ };
238
+
239
+ const result = await verifyBTCSignature(invalidBech32Proof);
240
+ expect(result).toEqual({
241
+ ...invalidBech32Proof,
242
+ status: ProofStatus.FAILED,
243
+ });
244
+ });
245
+
246
+ it("handles testnet addresses", async () => {
247
+ const testnetProof: SignatureProof = {
248
+ ...legacyProof,
249
+ address:
250
+ "bip122:000000000019d6689c085ae165831e93:17sKZt6r5jrTHMLB5AydhLSdkU4kf5UUPv",
251
+ proof:
252
+ "HLwgqPIywFd8Ukk/XJ1ANwwRXBIFCXVMB6HCwjVaKeCdBuzUS2wOupes+OKIt/t1Y+YMzNVo/rLRyEflDsiF2DY=",
253
+ };
254
+
255
+ const result = await verifyBTCSignature(testnetProof);
256
+ expect(result).toEqual({ ...testnetProof, status: ProofStatus.VERIFIED });
257
+ });
258
+
259
+ it("handles legacy multisig addresses", async () => {
260
+ const multisigProof: SignatureProof = {
261
+ ...legacyProof,
262
+ address:
263
+ "bip122:000000000019d6689c085ae165831e93:1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm",
264
+ proof:
265
+ "G9Em+RLOt1e7afThYiLZ2wd1e6jKfs4PR3BR6IgN2wzDIr65JQCekTXdQ/edzqLvRdpaypsQiHtfvZ1cAt1VR6k=",
266
+ };
267
+
268
+ const result = await verifyBTCSignature(multisigProof);
269
+ expect(result).toEqual({ ...multisigProof, status: ProofStatus.VERIFIED });
270
+ });
271
+
272
+ // it("handles litecoin M addresses", async () => {
273
+ // const litecoinMProof: SignatureProof = {
274
+ // ...legacyProof,
275
+ // address: "bip122:12a765e31ffd4059bada1e25190f6e98:ltc1qp3la5p5wf8wnfg7hc3nga8kq0xs6tk5fn6v3r3",
276
+ // proof: "H8twSn5iDrRY1LZ5C7kEdLAsQoS94LddA9ddmAaEZwI8U2WFZJnccnya2a79+rx5zIWHkZwLlu/HscXAc+XOQ+w=",
277
+ // };
278
+
279
+ // const result = await verifyBTCSignature(litecoinMProof);
280
+ // expect(result).toEqual({ ...litecoinMProof, status: ProofStatus.VERIFIED });
281
+ // });
282
+
283
+ it("handles non-standard signature recovery values", async () => {
284
+ const nonStandardProof: SignatureProof = {
285
+ ...legacyProof,
286
+ proof:
287
+ "H1234567890123456789012345678901234567890123456789012345678901234567890123456789012345=",
288
+ };
289
+
290
+ const result = await verifyBTCSignature(nonStandardProof);
291
+ expect(result).toEqual({ ...nonStandardProof, status: ProofStatus.FAILED });
292
+ });
293
+
294
+ // it("handles zcash addresses", async () => {
295
+ // const zcashProof: SignatureProof = {
296
+ // type: ProofTypes.BIP137,
297
+ // address: "bip122:00000000000000000019d6689c085ae165831e93:520a61f0106fdaf9f0846a0ab5f5acb1734fc8c1",
298
+ // did: "did:pkh:bip122:00000000000000000019d6689c085ae165831e93:520a61f0106fdaf9f0846a0ab5f5acb1734fc8c1",
299
+ // attestation: "This is an example of a signed message.",
300
+ // proof: "MEUCIQCuqL3ms6NwaZIEiP4uDjmqgGG3hhqIZUt7zGe9yxywbQIgbFjjTZmsMm5tq0PB4SKTt9xbI5U1V6O3sROe4OoiP44",
301
+ // status: ProofStatus.PENDING,
302
+ // wallet_provider: "Electron Cash ZEC"
303
+ // };
304
+
305
+ // const result = await verifyBTCSignature(zcashProof);
306
+ // expect(result).toEqual({ ...zcashProof, status: ProofStatus.VERIFIED });
307
+ // });
308
+
309
+ it("handles bitcoin cash addresses", async () => {
310
+ const bchProof: SignatureProof = {
311
+ type: ProofTypes.BIP137,
312
+ address:
313
+ "bip122:00000000000000000019d6689c085ae165831e93:qrxxxgvmsqa7qzhd6dsnne3udc7u34fg8g56pzx2hy",
314
+ did: "did:pkh:bip122:00000000000000000019d6689c085ae165831e93:qrxxxgvmsqa7qzhd6dsnne3udc7u34fg8g56pzx2hy",
315
+ attestation: "This is an example of a signed message.",
316
+ proof:
317
+ "H0qNIXAv3YA5+Y6I4p/lD03v8VEHZzTw+JAzfeoSKHydXhKsXgtPDaftjr3h3Bs8R2FqS9C6GOBvk+RISJK5lcU=",
318
+ status: ProofStatus.PENDING,
319
+ wallet_provider: "Electron Cash BCH",
320
+ };
321
+
322
+ const result = await verifyBTCSignature(bchProof);
323
+ expect(result).toEqual({ ...bchProof, status: ProofStatus.VERIFIED });
324
+ });
325
+
326
+ it("handles unknown address formats", async () => {
327
+ const unknownProof: SignatureProof = {
328
+ type: ProofTypes.BIP137,
329
+ address: "bip122:000000000019d6689c085ae165831e93:x123456789", // Unknown prefix
330
+ did: "did:pkh:bip122:000000000019d6689c085ae165831e93:x123456789",
331
+ attestation: "Message signed by unknown address",
332
+ proof:
333
+ "H1234567890123456789012345678901234567890123456789012345678901234567890123456789012345=",
334
+ status: ProofStatus.PENDING,
335
+ wallet_provider: "Unknown",
336
+ };
337
+
338
+ const result = await verifyBTCSignature(unknownProof);
339
+ expect(result).toEqual({ ...unknownProof, status: ProofStatus.FAILED });
340
+ });
341
+
342
+ it("handles P2SH-P2WPKH segwit type", async () => {
343
+ const p2shP2wpkhProof: SignatureProof = {
344
+ ...legacyProof,
345
+ proof:
346
+ "G0/EqZbcoZgrrLO09k8cK7MzTjrw5mHM4EiXWLCDgnH4d+rvMc1X2rGTPbHCKn8GGRLi7JDiTJflX+pxxCwtebA=",
347
+ address:
348
+ "bip122:000000000019d6689c085ae165831e93:18vqVNQi9fobKZcJWCjZNoDzBxronENfZr",
349
+ };
350
+
351
+ const result = await verifyBTCSignature(p2shP2wpkhProof);
352
+ expect(result).toEqual({
353
+ ...p2shP2wpkhProof,
354
+ status: ProofStatus.VERIFIED,
355
+ });
356
+ });
102
357
  });