@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 +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.modern.js +1 -1
- package/dist/index.modern.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +3 -2
- package/src/bitcoin.ts +99 -22
- package/src/tests/bitcoin.test.ts +256 -1
package/dist/index.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
var e=require("@notabene/javascript-sdk"),r=require("varuint-bitcoin"),t=require("@scure/base"),
|
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
|
package/dist/index.cjs.map
CHANGED
@@ -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
|
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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"}
|
package/dist/index.modern.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import{ProofStatus as t,ProofTypes as e}from"@notabene/javascript-sdk";import{encode as
|
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
|
package/dist/index.modern.js.map
CHANGED
@@ -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,
|
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
|
package/dist/index.umd.js.map
CHANGED
@@ -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":"yzBAaKA,EAOAC,mQAPL,SAAKD,GACHA,EAAA,OAAA,SACAA,EAAA,YAAA,cACD,CAHD,CAAKA,IAAAA,EAGJ,CAAA,IAID,SAAKC,GACHA,EAAA,OAAA,SACAA,EAAA,OAAA,gBACAA,EAAA,OAAA,SACAA,EAAA,YAAA,OACAA,EAAA,IAAA,eACAA,EAAA,SAAA,WACAA,EAAA,SAAA,WACAA,EAAA,QAAA,SACD,CATD,CAAKA,IAAAA,EASJ,CAAA,IAmJD,IAAMC,EAAcC,EAAAA,kBAAkBC,EAAAA,KAAKC,QAoB3C,SAASC,EAAoBC,GAC3B,IAAMC,EAASC,EAAMA,OAACC,QAAQH,GAE9B,OADAC,EAAOG,QAAQ,GACRF,EAAAA,OAAOG,OAAO,KAAMJ,EAC7B,eC1LsB,SACpBK,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,aAAWC,gBACd,OAAAC,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAASP,EAA2BQ,UAChCC,EAAAA,YAAYC,SACZD,cAAYE,UAEpB,KAAKT,EAAUA,WAACU,WACd,OAAAR,QAAAC,QAAAC,EAAA,CAAA,EACKN,EAAK,CACRO,OAASP,EAA0Ba,IAC/BJ,EAAAA,YAAYK,QACZL,EAAWA,YAACE,UAEpB,KAAKT,EAAUA,WAACa,KACd,OAAAX,QAAAC,QC9BmC,SACvCL,GAAqB,QAAAgB,EAErBC,EAAwBjB,EAAMkB,QAAQC,MAAM,KAA/BD,EAAOD,EACpB,GAAMG,EAAMJ,OAAHA,EAAGhB,EAAMqB,wBAANL,EAAAA,EAAyBM,eAErC,GAAW,YAHFL,EAAIC,KAGYE,EACvB,OAAAhB,QAAAC,QAAAC,EAAYN,CAAAA,EAAAA,GAAOO,OAAQE,EAAWA,YAACE,UAGzC,IACE,IAAMY,EAAWC,EAAAA,QAAoBxB,EAAMA,MAAOoB,EAAKpB,EAAMyB,YAAaP,GAC1E,OAAAd,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAAQgB,EAAWd,cAAYC,SAAWD,EAAWA,YAACE,SAE1D,CAAE,MAAAe,GACA,OAAAtB,QAAAC,QAAAC,EAAYN,GAAAA,GAAOO,OAAQE,EAAAA,YAAYE,SACzC,CACF,CAAC,MAAAgB,GAAAvB,OAAAA,QAAAwB,OAAAD,EAAA,CAAA,CDWYE,CAAoB7B,IAC7B,KAAKE,EAAAA,WAAW4B,OACd,OAAA1B,QAAAC,QEfwC,SAC5CL,OAEA,IAAAiB,EAAwBjB,EAAMkB,QAAQC,MAAM,KAA/BD,EAAOD,EACpB,GAAA,GAAW,WADFA,EAAA,GACY,OAAAb,QAAAC,QAAAC,KAAYN,EAAK,CAAEO,OAAQE,EAAWA,YAACE,UAE5D,IAAMY,WAtBNL,EACAa,EACA/B,GAEA,IACE,IAAMgC,EAAUC,EAAeA,gBAACC,eAAeC,EAAAA,IAAIC,WAAWL,IACxDM,EAAYC,EAAAA,UAAUC,QAAQvC,GAC9BwC,EAAYC,EAAAA,UAAUC,iBAAiB,CAAEV,QAAAA,EAASK,UAAAA,IAExD,OADkBM,EAAOA,QAACC,SAASD,EAAOA,QAACE,cAAcL,IACxCM,aAAeH,EAAAA,QAAQC,SAAS1B,EAEnD,CAAE,MAAO6B,GACP,OAAO,CACT,CACF,CAQmBC,CACf9B,EACAlB,EAAMyB,YACNzB,EAAMA,OAER,OAAAI,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,GACHO,OAAQgB,EAAWd,EAAAA,YAAYC,SAAWD,EAAWA,YAACE,SAE1D,CAAC,MAAAgB,GAAA,OAAAvB,QAAAwB,OAAAD,EAAA,CAAA,CFAYsB,CAAyBjD,IAClC,KAAKE,EAAAA,WAAWgD,QACd,OAAA9C,QAAAC,QGjCgB,SACpBL,OAEA,IAAAiB,EAAwBjB,EAAMkB,QAAQC,MAAM,KAA/BD,EAAOD,EACpB,GAAA,GAAW,WADFA,EAAA,GACY,OAAAb,QAAAC,QAAAC,EAAYN,CAAAA,EAAAA,GAAOO,OAAQE,cAAYE,UAC5D,IACE,IAAM6B,EAAYW,SAAOC,OAAOlC,GAC1BmC,GAAe,IAAIC,aAAcvD,OAAOC,EAAMyB,aAC9C8B,EAAiBC,EAAMA,OAACJ,OAAOpD,EAAMA,OACrCuB,EAAWkC,EAAI,QAACC,KAAKC,SAASC,OAClCP,EACAE,EACAf,GAGF,OAAApC,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,GACHO,OAAQgB,EAAWd,EAAAA,YAAYC,SAAWD,EAAWA,YAACE,SAG1D,CAAE,MAAOoC,GACP,OAAA3C,QAAAC,QAAAC,EAAYN,CAAAA,EAAAA,GAAOO,OAAQE,EAAAA,YAAYE,SACzC,CACF,CAAC,MAAAgB,GAAA,OAAAvB,QAAAwB,OAAAD,EAAA,CAAA,CHUYkC,CAAsB7D,IAC/B,KAAKE,EAAAA,WAAW4D,OAChB,KAAK5D,EAAAA,WAAW6D,OAChB,KAAK7D,EAAAA,WAAW8D,OACd,OAAA5D,QAAAC,QDVgB,SACpBL,GAAqB,IAErB,IAAAiB,EAAwBjB,EAAMkB,QAAQC,MAAM,KAA/BD,EAAOD,EAAA,GACpB,GAAW,WADFA,EAAA,GACY,OAAAb,QAAAC,QAAAC,EAAA,CAAA,EAAYN,EAAK,CAAEO,OAAQE,EAAAA,YAAYE,UAC5D,IACE,OAAQX,EAAMC,MACZ,KAAKC,EAAAA,WAAW6D,OACd,OAAA3D,QAAAC,QAiCR,SAAsBa,EAAiBlB,GAErC,IAAMiE,EAAS,CAAC7E,EAAe8E,OAAQ9E,EAAe+E,QAAQC,SAWhE,SAA2BlD,GACzB,GAAIA,EAAQmD,MAAM,qBAChB,OAAOjF,EAAe+E,OACjB,GAAIjD,EAAQmD,MAAM,YACvB,OAAOjF,EAAe8E,OACjB,GAAIhD,EAAQmD,MAAM,aACvB,OAAOjF,EAAekF,OACbpD,GAAAA,EAAQmD,MAAM,UACvB,OAAOjF,EAAemF,SAEtB,MAAU,IAAAC,MACR,oBACGC,OAAOvD,GACPuD,OAAO,0CAGhB,CA1BIC,CAAkBxD,IAEdK,EAsDR,SACEE,EACAP,EACAlB,EACA2E,GAEA,IAAAC,EA5BF,SAAyB5E,GACvB,IAAM6E,EAAWrB,EAAAA,OAAOJ,OAAOpD,GAC/B,GAAwB,KAApB6E,EAASC,OAAe,MAAM,IAAIN,MAAM,4BAC5C,IAAMO,EAAWF,EAAS,GAAK,GAC/B,GAAIE,EAAW,IAAMA,EAAW,EAC9B,MAAM,IAAIP,MAAM,+BAElB,IAAMQ,KAA2B,GAAXD,GAChBE,EAAsB,EAAXF,EACX1C,EAAY6C,EAASA,UAAC5C,UAAU6C,YAAYN,EAASO,MAAM,IAEjE,MAAO,CACLJ,WAAAA,EACAK,WAAyB,EAAXN,EAEG,EAAXA,EAEF5F,EAAamG,OADbnG,EAAaoG,iBAFbC,EAIJnD,UAAWA,EAAUoD,eAAeR,GAExC,CAQgDS,CAAgB1F,GAAtDgF,EAAUJ,EAAVI,WAAYK,EAAUT,EAAVS,WAAYhD,EAASuC,EAATvC,UAChC,GAAIsC,IAAsBK,EACxB,MAAU,IAAAR,MACR,kFAGJ,IA+DemB,EA/DTC,EAwCR,SAAmBnE,GACjB,IAAMoE,GAAS,IAAIvC,aAAcvD,OAtKb,8BAuKdgC,GAAU,IAAIuB,aAAcvD,OAAO0B,GACnCqD,EAASgB,EAAY/F,OAACgC,EAAQ+C,QAAQa,OACtCA,EAAS,IAAII,WACjBF,EAAOf,OAASA,EAAOkB,WAAajE,EAAQ+C,QAK9C,OAHAa,EAAOM,IAAIJ,GACXF,EAAOM,IAAI,IAAIF,WAAWjB,GAASe,EAAOf,QAC1Ca,EAAOM,IAAIlE,EAAS8D,EAAOf,OAASA,EAAOkB,YAU7C,SAAiBL,GACf,OAAOpG,EAAAA,KAAKC,OAAOD,EAAAA,KAAKC,OAAOmG,GACjC,CAXSO,CAAQP,EACjB,CAnDeQ,CAAU1E,GAGjB/B,GA4DSiG,EA9DGtD,EAAUK,iBAAiBkD,GACZQ,WAAWpB,GA8DrCzF,EAAIA,KAAC8G,UAAU9G,EAAIA,KAACC,OAAOmG,KA5D9BW,EAAiB,GAErB,GAAIjB,EAEAiB,EAAS7G,EAAoBC,QAQ/B,GAAIiF,EACF,IACE2B,EAAS7G,EAAoBC,EAG/B,CAAE,MAAOiC,GACP2E,EAAS7G,EAAoBC,EAE/B,MAEA4G,EASN,SAAmCC,EAAiB7G,GAClD,IAAMsC,EAAU,IAAI+D,WAAU,CAVS,GAUAtB,OAAK/E,IAC5C,OAAOL,EAAYU,OAAOiC,EAC5B,CAZewE,CAA0B,EAAG9G,GAI1C,OAAO4G,IAAWpF,CACpB,CAjGmB0C,CAAO5D,EAAMyB,YAAaP,EAASlB,EAAMA,MAAOiE,GAEjE,OAAA3D,EAAA,CAAA,EACKN,EAAK,CACRO,OAAQgB,EAAWd,EAAWA,YAACC,SAAWD,EAAWA,YAACE,QAE1D,CA5Ce8F,CAAavF,EAASlB,IAC/B,KAAKE,EAAAA,WAAW8D,OACd,OAAA5D,QAAAC,QAkBR,SAAsBa,EAAiBlB,GAOrC,OAAAM,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAPemG,EAAQA,SAACC,gBACxBzF,EAF6ClB,EAAvCyB,YAAuCzB,EAA1BA,OAQAS,EAAWA,YAACC,SAAWD,EAAWA,YAACE,QAE1D,CA7BeiG,CAAa1F,EAASlB,IAC/B,QACE,OAAAI,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAAQE,EAAAA,YAAYE,UAI5B,CAAE,MAAOoC,GAEP,OAAA3C,QAAAC,QAAAC,EAAA,CAAA,EACKN,EACHO,CAAAA,OAAQE,EAAWA,YAACE,SAGxB,CACF,CAAC,MAAAgB,GAAA,OAAAvB,QAAAwB,OAAAD,EAAA,CAAA,CChBYkF,CAAmB7G,IAC5B,KAAKE,EAAAA,WAAW4G,OACd,OAAA1G,QAAAC,iBIfJL,OAEA,IAAAiB,EAAwBjB,EAAMkB,QAAQC,MAAM,KAA/BD,EAAOD,EAAA,GACpB,GAAW,SADFA,KACU,OAAAb,QAAAC,QAAAC,KAAYN,EAAK,CAAEO,OAAQE,EAAWA,YAACE,UAE1D,IAAMY,EA7BQ,SACdL,EACAa,EACA/B,GAEA,IACE,IAAMgC,GA2CqB+E,EA3CI5E,EAAAA,IAAIC,WAAWL,GA4CzCxC,EAAAA,KAAKyH,UAVE,SAAOD,GACrB,IAAMhF,EAAUI,MAAI8E,KAAKF,GACzB,OAAO5E,MAAIsC,OAET,OACAtC,EAAGA,IAACC,WAAW,yBAA2BD,EAAAA,IAAI+E,KAAKnF,IACnDA,EAEJ,CAEwBhC,CAAOgH,KA3CrB1E,EAAYC,EAAAA,UAAUC,QAAQvC,GAC9BwC,EAAYC,EAAAA,UAAUC,iBAAiB,CAAEV,QAAAA,EAASK,UAAAA,IAClD8E,EAAG,OAAmB5H,EAAIA,KAACyH,eAC1BI,EAAAA,UAAUC,MAAM7E,GAAW4C,MAAM,IACtCkC,UAAU,IACNC,EAAQC,EAAAA,MAAMP,KAAKE,GACnBvE,EAAW4E,EAAAA,MAAMP,KAAK1H,EAAIA,KAACC,OAAOD,EAAAA,KAAKC,OAAO2H,KAAO/B,MAAM,EAAG,GAC9DqC,EAAUD,QAAM/C,OAAO8C,EAAO3E,GAEpC,OADYO,EAAAA,OAAOpD,OAAO0H,KACXvG,CAEjB,CAAE,MAAO6B,GACP,OAAO,CACT,CA6Bc,IAAegE,CA5B/B,CAQmBW,CACfxG,EACAlB,EAAMyB,YACNzB,EAAMA,OAER,OAAAI,QAAAC,QAAAC,KACKN,EAAK,CACRO,OAAQgB,EAAWd,EAAWA,YAACC,SAAWD,cAAYE,SAE1D,CAAC,MAAAgB,GAAAvB,OAAAA,QAAAwB,OAAAD,EAAA,CAAA,CJCYgG,CAAyB3H,IAIpC,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAA2B,GAAA,OAAAvB,QAAAwB,OAAAD,EAAA,CAAA"}
|
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.
|
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
|
-
|
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
|
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
|
-
|
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 =
|
225
|
+
actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);
|
153
226
|
} else {
|
154
227
|
// parsed.segwitType === SEGWIT_TYPES.P2WPKH
|
155
|
-
|
156
|
-
|
157
|
-
|
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 =
|
243
|
+
actual = encodeBase58AddressFormat(chainConfig.scriptHashVersion, publicKeyHash);
|
167
244
|
// base58 can be p2pkh or p2sh-p2wpkh
|
168
245
|
}
|
169
246
|
} else {
|
170
|
-
actual = encodeBase58AddressFormat(
|
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(
|
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({
|
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
|
});
|