@notabene/verify-proof 1.0.3 → 1.0.4
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/dist/tests/tron.test.d.ts +1 -0
- package/dist/tron.d.ts +6 -0
- package/package.json +3 -2
- package/src/index.ts +3 -0
- package/src/tests/eth.test.ts +0 -1
- package/src/tests/index.test.ts +27 -0
- package/src/tests/tron.test.ts +59 -0
- package/src/tron.ts +55 -0
package/dist/index.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
var e=require("@notabene/javascript-sdk"),r=require("@bitauth/libauth"),t=require("varuint-bitcoin"),
|
1
|
+
var e=require("@notabene/javascript-sdk"),r=require("@bitauth/libauth"),t=require("varuint-bitcoin"),s=require("@scure/base"),o=require("ox");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var a,i,c=/*#__PURE__*/n(require("tweetnacl"));function u(){return u=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},u.apply(null,arguments)}function f(e){var r=s.bech32.toWords(e);return r.unshift(0),s.bech32.encode("bc",r)}!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(a||(a={})),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"}(i||(i={})),exports.verifyProof=function(n){try{switch(n.type){case e.ProofTypes.SelfDeclaration:return Promise.resolve(u({},n,{status:n.confirmed?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}));case e.ProofTypes.Screenshot:return Promise.resolve(u({},n,{status:n.url?e.ProofStatus.FLAGGED:e.ProofStatus.FAILED}));case e.ProofTypes.EIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),s=t[2];if("eip155"!==t[0])return Promise.resolve(u({},r,{status:e.ProofStatus.FAILED}));var n=function(e,r,t){try{var s=o.PersonalMessage.getSignPayload(o.Hex.fromString(r)),n=o.Signature.fromHex(t),a=o.Secp256k1.recoverPublicKey({payload:s,signature:n});return o.Address.checksum(o.Address.fromPublicKey(a)).toString()===o.Address.checksum(e)}catch(e){return!1}}(s,r.attestation,r.proof);return Promise.resolve(u({},r,{status:n?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(n));case e.ProofTypes.ED25519:return Promise.resolve(function(r){try{var t=r.address.split(/:/),o=t[2];if("solana"!==t[0])return Promise.resolve(u({},r,{status:e.ProofStatus.FAILED}));try{var n=s.base58.decode(o),a=(new TextEncoder).encode(r.attestation),i=s.base64.decode(r.proof),f=c.default.sign.detached.verify(a,i,n);return Promise.resolve(u({},r,{status:f?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(t){return Promise.resolve(u({},r,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case e.ProofTypes.EIP712:case e.ProofTypes.BIP137:return Promise.resolve(function(o){try{var n=o.address.split(/:/),c=n[2];if("bip122"!==n[0])return Promise.resolve(u({},o,{status:e.ProofStatus.FAILED}));try{var P=[i.SEGWIT,i.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return i.NATIVE;if(e.match("^[32M].*"))return i.SEGWIT;if(e.match("^[1nmL].*"))return i.LEGACY;if(e.match("^(D).*"))return i.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(c)),l=function(e,o,n,i){var c=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");return{compressed:!!(12&t),segwitType:8&t?4&t?a.P2WPKH:a.P2SH_P2WPKH:void 0,recovery:3&t,signature:r.slice(1)}}(n),u=c.compressed,P=c.segwitType,l=c.recovery,d=c.signature;if(i&&!u)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var h=function(e){var s=(new TextEncoder).encode("Bitcoin Signed Message:\n"),o=(new TextEncoder).encode(e),n=t.encode(o.length).buffer,a=new Uint8Array(s.length+n.byteLength+o.length);return a.set(s),a.set(new Uint8Array(n),s.length),a.set(o,s.length+n.byteLength),r.hash256(a)}(e),v=u?r.secp256k1.recoverPublicKeyCompressed(d,l,h):r.secp256k1.recoverPublicKeyUncompressed(d,l,h);if("string"==typeof v)throw new Error(v);var E=r.hash160(v),y="";if(P)y=f(E);else if(i)try{y=f(E)}catch(e){y=f(E)}else y=r.encodeBase58AddressFormat(0,E);return y===o}(o.attestation,c,o.proof,P);return Promise.resolve(u({},o,{status:l?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(r){return Promise.resolve(u({},o,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(n));case e.ProofTypes.TIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),n=t[2];if("tron"!==t[0])return Promise.resolve(u({},r,{status:e.ProofStatus.FAILED}));var a=function(e,r,t){try{var n=(l=o.Hex.fromString(r),o.Hash.keccak256(function(e){var r=o.Hex.from(e);return o.Hex.concat("0x19",o.Hex.fromString("TRON Signed Message:\n"+o.Hex.size(r)),r)}(l))),a=o.Signature.fromHex(t),i=o.Secp256k1.recoverPublicKey({payload:n,signature:a}),c="0x41"+o.Hash.keccak256("0x"+o.PublicKey.toHex(i).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 l}(n,r.attestation,r.proof);return Promise.resolve(u({},r,{status:a?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(e){return Promise.reject(e)}}(n))}return Promise.resolve(n)}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/eth.ts","../src/solana.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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\";\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.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 return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\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 } 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 } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","_","verified","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","attestation","e","reject","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","length","flagByte","compressed","segwitType","P2WPKH","P2SH_P2WPKH","undefined","recovery","slice","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","encodeBase58AddressFormat","verifyBTCSignature"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/bitcoin.ts","../src/index.ts","../src/eth.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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\";\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.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 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 { 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 } 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 } 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 } 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","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","_","verified","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","attestation","e","reject","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","length","flagByte","compressed","segwitType","P2WPKH","P2SH_P2WPKH","undefined","recovery","slice","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","encodeBase58AddressFormat","verifyBTCSignature","TIP191","data","Hash","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","sha256","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{secp256k1 as t,hash160 as n,encodeBase58AddressFormat as o,hash256 as s}from"@bitauth/libauth";import{encode as i}from"varuint-bitcoin";import{bech32 as a,base64 as c,base58 as u}from"@scure/base";import{PersonalMessage as l,Hex as f,Signature as m,Secp256k1 as v,Address as E}from"ox";import
|
1
|
+
import{ProofStatus as e,ProofTypes as r}from"@notabene/javascript-sdk";import{secp256k1 as t,hash160 as n,encodeBase58AddressFormat as o,hash256 as s}from"@bitauth/libauth";import{encode as i}from"varuint-bitcoin";import{bech32 as a,base64 as c,base58 as u}from"@scure/base";import{PersonalMessage as l,Hex as f,Signature as m,Secp256k1 as v,Address as E,Hash as d,PublicKey as h,Bytes as P}from"ox";import p from"tweetnacl";function g(){return g=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var n in t)({}).hasOwnProperty.call(t,n)&&(e[n]=t[n])}return e},g.apply(null,arguments)}var I,y;function D(e){var r=a.toWords(e);return r.unshift(0),a.encode("bc",r)}!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(I||(I={})),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 w=function(a){try{switch(a.type){case r.SelfDeclaration:return Promise.resolve(g({},a,{status:a.confirmed?e.VERIFIED:e.FAILED}));case r.Screenshot:return Promise.resolve(g({},a,{status:a.url?e.FLAGGED:e.FAILED}));case r.EIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),n=t[2];if("eip155"!==t[0])return Promise.resolve(g({},r,{status:e.FAILED}));var o=function(e,r,t){try{var n=l.getSignPayload(f.fromString(r)),o=m.fromHex(t),s=v.recoverPublicKey({payload:n,signature:o});return E.checksum(E.fromPublicKey(s)).toString()===E.checksum(e)}catch(e){return!1}}(n,r.attestation,r.proof);return Promise.resolve(g({},r,{status:o?e.VERIFIED:e.FAILED}))}catch(e){return Promise.reject(e)}}(a));case r.ED25519:return Promise.resolve(function(r){try{var t=r.address.split(/:/),n=t[2];if("solana"!==t[0])return Promise.resolve(g({},r,{status:e.FAILED}));try{var o=u.decode(n),s=(new TextEncoder).encode(r.attestation),i=c.decode(r.proof),a=p.sign.detached.verify(s,i,o);return Promise.resolve(g({},r,{status:a?e.VERIFIED:e.FAILED}))}catch(t){return Promise.resolve(g({},r,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(a));case r.EIP712:case r.BIP137:return Promise.resolve(function(r){try{var a=r.address.split(/:/),u=a[2];if("bip122"!==a[0])return Promise.resolve(g({},r,{status:e.FAILED}));try{var l=[y.SEGWIT,y.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return y.NATIVE;if(e.match("^[32M].*"))return y.SEGWIT;if(e.match("^[1nmL].*"))return y.LEGACY;if(e.match("^(D).*"))return y.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(u)),f=function(e,r,a,u){var l=function(e){var r=c.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");return{compressed:!!(12&t),segwitType:8&t?4&t?I.P2WPKH:I.P2SH_P2WPKH:void 0,recovery:3&t,signature:r.slice(1)}}(a),f=l.compressed,m=l.segwitType,v=l.recovery,E=l.signature;if(u&&!f)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var d=function(e){var r=(new TextEncoder).encode("Bitcoin Signed Message:\n"),t=(new TextEncoder).encode(e),n=i(t.length).buffer,o=new Uint8Array(r.length+n.byteLength+t.length);return o.set(r),o.set(new Uint8Array(n),r.length),o.set(t,r.length+n.byteLength),s(o)}(e),h=f?t.recoverPublicKeyCompressed(E,v,d):t.recoverPublicKeyUncompressed(E,v,d);if("string"==typeof h)throw new Error(h);var P=n(h),p="";if(m)p=D(P);else if(u)try{p=D(P)}catch(e){p=D(P)}else p=o(0,P);return p===r}(r.attestation,u,r.proof,l);return Promise.resolve(g({},r,{status:f?e.VERIFIED:e.FAILED}))}catch(t){return Promise.resolve(g({},r,{status:e.FAILED}))}}catch(e){return Promise.reject(e)}}(a));case r.TIP191:return Promise.resolve(function(r){try{var t=r.address.split(/:/),n=t[2];if("tron"!==t[0])return Promise.resolve(g({},r,{status:e.FAILED}));var o=function(e,r,t){try{var n=(E=f.fromString(r),d.keccak256(function(e){var r=f.from(e);return f.concat("0x19",f.fromString("TRON Signed Message:\n"+f.size(r)),r)}(E))),o=m.fromHex(t),s=v.recoverPublicKey({payload:n,signature:o}),i="0x41"+d.keccak256("0x"+h.toHex(s).slice(4)).substring(26),a=P.from(i),c=P.from(d.sha256(d.sha256(i))).slice(0,4),l=P.concat(a,c);return u.encode(l)===e}catch(e){return!1}var E}(n,r.attestation,r.proof);return Promise.resolve(g({},r,{status:o?e.VERIFIED:e.FAILED}))}catch(e){return Promise.reject(e)}}(a))}return Promise.resolve(a)}catch(e){return Promise.reject(e)}};export{w 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/solana.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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 } 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\";\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.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 return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\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 } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","verifyProof","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","_","verified","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","attestation","e","reject","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","length","flagByte","compressed","segwitType","P2WPKH","P2SH_P2WPKH","undefined","recovery","slice","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","encodeBase58AddressFormat","verifyBTCSignature"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/bitcoin.ts","../src/eth.ts","../src/index.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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 } 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\";\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.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 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 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 } 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 } 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","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","verifyProof","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","_","verified","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","attestation","e","reject","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","length","flagByte","compressed","segwitType","P2WPKH","P2SH_P2WPKH","undefined","recovery","slice","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","encodeBase58AddressFormat","verifyBTCSignature","TIP191","data","Hash","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","sha256","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{secp256k1 as r,hash160 as n,encodeBase58AddressFormat as o,hash256 as s}from"@bitauth/libauth";import{encode as c}from"varuint-bitcoin";import{bech32 as
|
1
|
+
import{ProofStatus as t,ProofTypes as e}from"@notabene/javascript-sdk";import{secp256k1 as r,hash160 as n,encodeBase58AddressFormat as o,hash256 as s}from"@bitauth/libauth";import{encode as c}from"varuint-bitcoin";import{bech32 as a,base64 as i,base58 as u}from"@scure/base";import{PersonalMessage as f,Hex as E,Signature as d,Secp256k1 as l,Address as h,Hash as p,PublicKey as g,Bytes as I}from"ox";import m from"tweetnacl";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 n in r)({}).hasOwnProperty.call(r,n)&&(t[n]=r[n])}return t},y.apply(null,arguments)}var D,w;function b(t){const e=a.toWords(t);return e.unshift(0),a.encode("bc",e)}function A(t,e,r){try{const o=(n=E.fromString(e),p.keccak256(function(t){const e=E.from(t);return E.concat("0x19",E.fromString("TRON Signed Message:\n"+E.size(e)),e)}(n))),s=d.fromHex(r),c=l.recoverPublicKey({payload:o,signature:s}),a=`0x41${p.keccak256(`0x${g.toHex(c).slice(4)}`).substring(26)}`,i=I.from(a),f=I.from(p.sha256(p.sha256(a))).slice(0,4),h=I.concat(i,f);return u.encode(h)===t}catch(t){return!1}var n}async function P(a){switch(a.type){case e.SelfDeclaration:return y({},a,{status:a.confirmed?t.VERIFIED:t.FAILED});case e.Screenshot:return y({},a,{status:a.url?t.FLAGGED:t.FAILED});case e.EIP191:return async function(e){const[r,n,o]=e.address.split(/:/);if("eip155"!==r)return y({},e,{status:t.FAILED});const s=function(t,e,r){try{const n=f.getSignPayload(E.fromString(e)),o=d.fromHex(r),s=l.recoverPublicKey({payload:n,signature:o});return h.checksum(h.fromPublicKey(s)).toString()===h.checksum(t)}catch(t){return!1}}(o,e.attestation,e.proof);return y({},e,{status:s?t.VERIFIED:t.FAILED})}(a);case e.ED25519:return async function(e){const[r,n,o]=e.address.split(/:/);if("solana"!==r)return y({},e,{status:t.FAILED});try{const r=u.decode(o),n=(new TextEncoder).encode(e.attestation),s=i.decode(e.proof);return y({},e,{status:m.sign.detached.verify(n,s,r)?t.VERIFIED:t.FAILED})}catch(r){return y({},e,{status:t.FAILED})}}(a);case e.EIP712:case e.BIP137:return async function(e){const[a,u,f]=e.address.split(/:/);if("bip122"!==a)return y({},e,{status:t.FAILED});try{const a=[w.SEGWIT,w.NATIVE].includes(function(t){if(t.match("^(bc1|tb1|ltc1).*"))return w.NATIVE;if(t.match("^[32M].*"))return w.SEGWIT;if(t.match("^[1nmL].*"))return w.LEGACY;if(t.match("^(D).*"))return w.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(t).concat(" is not a valid or a supported address"))}(f)),u=function(t,e,a,u){const{compressed:f,segwitType:E,recovery:d,signature:l}=function(t){const e=i.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");return{compressed:!!(12&r),segwitType:8&r?4&r?D.P2WPKH:D.P2SH_P2WPKH:void 0,recovery:3&r,signature:e.slice(1)}}(a);if(u&&!f)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");const h=function(t){const e=(new TextEncoder).encode("Bitcoin Signed Message:\n"),r=(new TextEncoder).encode(t),n=c(r.length).buffer,o=new Uint8Array(e.length+n.byteLength+r.length);return o.set(e),o.set(new Uint8Array(n),e.length),o.set(r,e.length+n.byteLength),s(o)}(t),p=f?r.recoverPublicKeyCompressed(l,d,h):r.recoverPublicKeyUncompressed(l,d,h);if("string"==typeof p)throw new Error(p);const g=n(p);let I="";if(E)I=b(g);else if(u)try{I=b(g)}catch(t){I=b(g)}else I=o(0,g);return I===e}(e.attestation,f,e.proof,a);return y({},e,{status:u?t.VERIFIED:t.FAILED})}catch(r){return y({},e,{status:t.FAILED})}}(a);case e.TIP191:return async function(e){const[r,n,o]=e.address.split(/:/);return y({},e,"tron"!==r?{status:t.FAILED}:{status:A(o,e.attestation,e.proof)?t.VERIFIED:t.FAILED})}(a)}return a}!function(t){t.P2WPKH="p2wpkh",t.P2SH_P2WPKH="p2sh(p2wpkh)"}(D||(D={})),function(t){t.LEGACY="Legacy",t.NATIVE="Native SegWit",t.SEGWIT="SegWit",t.P2SH_SEGWIT="p2sh",t.BCH="Bitcoin Cash",t.ETHEREUM="Ethereum",t.DOGECOIN="Dogecoin",t.UNKNOWN="Unknown"}(w||(w={}));export{P 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/index.ts","../src/eth.ts","../src/solana.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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\";\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.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 return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\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 } 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 } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","verifyProof","proof","type","ProofTypes","SelfDeclaration","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","async","ns","_","address","split","verified","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","attestation","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","compressed","segwitType","recovery","length","flagByte","P2WPKH","P2SH_P2WPKH","undefined","slice","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","e","encodeBase58AddressFormat","verifyBTCSignature"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.modern.js","sources":["../src/bitcoin.ts","../src/tron.ts","../src/index.ts","../src/eth.ts","../src/solana.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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 } 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\";\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.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 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 { 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 } 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 } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","verifyTIP191","address","message","proof","payload","data","Hex","fromString","Hash","keccak256","from","concat","size","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","hex","PublicKey","toHex","slice","substring","bytes","Bytes","checksum","sha256","checked","base58","error","async","verifyProof","type","ProofTypes","SelfDeclaration","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","ns","_","split","verified","PersonalMessage","getSignPayload","Address","fromPublicKey","toString","verifyEIP191","attestation","verifyPersonalSignEIP191","ED25519","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","getDerivationMode","checkSegwitAlways","compressed","segwitType","recovery","length","flagByte","P2WPKH","P2SH_P2WPKH","undefined","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","e","encodeBase58AddressFormat","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("@bitauth/libauth"),require("varuint-bitcoin"),require("@scure/base"),require("ox"),require("tweetnacl")):"function"==typeof define&&define.amd?define(["exports","@notabene/javascript-sdk","@bitauth/libauth","varuint-bitcoin","@scure/base","ox","tweetnacl"],r):r((e||self).verifyProof={},e.javascriptSdk,e.libauth,e.varuintBitcoin,e.base,e.ox,e.tweetnacl)}(this,function(e,r,t,o,s,n,a){function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c,u,f=/*#__PURE__*/i(a);function l(){return l=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},l.apply(null,arguments)}function
|
1
|
+
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@notabene/javascript-sdk"),require("@bitauth/libauth"),require("varuint-bitcoin"),require("@scure/base"),require("ox"),require("tweetnacl")):"function"==typeof define&&define.amd?define(["exports","@notabene/javascript-sdk","@bitauth/libauth","varuint-bitcoin","@scure/base","ox","tweetnacl"],r):r((e||self).verifyProof={},e.javascriptSdk,e.libauth,e.varuintBitcoin,e.base,e.ox,e.tweetnacl)}(this,function(e,r,t,o,s,n,a){function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var c,u,f=/*#__PURE__*/i(a);function l(){return l=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},l.apply(null,arguments)}function P(e){var r=s.bech32.toWords(e);return r.unshift(0),s.bech32.encode("bc",r)}!function(e){e.P2WPKH="p2wpkh",e.P2SH_P2WPKH="p2sh(p2wpkh)"}(c||(c={})),function(e){e.LEGACY="Legacy",e.NATIVE="Native SegWit",e.SEGWIT="SegWit",e.P2SH_SEGWIT="p2sh",e.BCH="Bitcoin Cash",e.ETHEREUM="Ethereum",e.DOGECOIN="Dogecoin",e.UNKNOWN="Unknown"}(u||(u={})),e.verifyProof=function(e){try{switch(e.type){case r.ProofTypes.SelfDeclaration:return Promise.resolve(l({},e,{status:e.confirmed?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}));case r.ProofTypes.Screenshot:return Promise.resolve(l({},e,{status:e.url?r.ProofStatus.FLAGGED:r.ProofStatus.FAILED}));case r.ProofTypes.EIP191:return Promise.resolve(function(e){try{var t=e.address.split(/:/),o=t[2];if("eip155"!==t[0])return Promise.resolve(l({},e,{status:r.ProofStatus.FAILED}));var s=function(e,r,t){try{var o=n.PersonalMessage.getSignPayload(n.Hex.fromString(r)),s=n.Signature.fromHex(t),a=n.Secp256k1.recoverPublicKey({payload:o,signature:s});return n.Address.checksum(n.Address.fromPublicKey(a)).toString()===n.Address.checksum(e)}catch(e){return!1}}(o,e.attestation,e.proof);return Promise.resolve(l({},e,{status:s?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(l({},e,{status:r.ProofStatus.FAILED}));try{var n=s.base58.decode(o),a=(new TextEncoder).encode(e.attestation),i=s.base64.decode(e.proof),c=f.default.sign.detached.verify(a,i,n);return Promise.resolve(l({},e,{status:c?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(t){return Promise.resolve(l({},e,{status:r.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case r.ProofTypes.EIP712:case r.ProofTypes.BIP137:return Promise.resolve(function(e){try{var n=e.address.split(/:/),a=n[2];if("bip122"!==n[0])return Promise.resolve(l({},e,{status:r.ProofStatus.FAILED}));try{var i=[u.SEGWIT,u.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return u.NATIVE;if(e.match("^[32M].*"))return u.SEGWIT;if(e.match("^[1nmL].*"))return u.LEGACY;if(e.match("^(D).*"))return u.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(a)),f=function(e,r,n,a){var i=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");return{compressed:!!(12&t),segwitType:8&t?4&t?c.P2WPKH:c.P2SH_P2WPKH:void 0,recovery:3&t,signature:r.slice(1)}}(n),u=i.compressed,f=i.segwitType,l=i.recovery,d=i.signature;if(a&&!u)throw new Error("checkSegwitAlways can only be used with a compressed pubkey signature flagbyte");var h=function(e){var r=(new TextEncoder).encode("Bitcoin Signed Message:\n"),s=(new TextEncoder).encode(e),n=o.encode(s.length).buffer,a=new Uint8Array(r.length+n.byteLength+s.length);return a.set(r),a.set(new Uint8Array(n),r.length),a.set(s,r.length+n.byteLength),t.hash256(a)}(e),v=u?t.secp256k1.recoverPublicKeyCompressed(d,l,h):t.secp256k1.recoverPublicKeyUncompressed(d,l,h);if("string"==typeof v)throw new Error(v);var p=t.hash160(v),y="";if(f)y=P(p);else if(a)try{y=P(p)}catch(e){y=P(p)}else y=t.encodeBase58AddressFormat(0,p);return y===r}(e.attestation,a,e.proof,i);return Promise.resolve(l({},e,{status:f?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}))}catch(t){return Promise.resolve(l({},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(/:/),o=t[2];if("tron"!==t[0])return Promise.resolve(l({},e,{status:r.ProofStatus.FAILED}));var a=function(e,r,t){try{var o=(P=n.Hex.fromString(r),n.Hash.keccak256(function(e){var r=n.Hex.from(e);return n.Hex.concat("0x19",n.Hex.fromString("TRON Signed Message:\n"+n.Hex.size(r)),r)}(P))),a=n.Signature.fromHex(t),i=n.Secp256k1.recoverPublicKey({payload:o,signature:a}),c="0x41"+n.Hash.keccak256("0x"+n.PublicKey.toHex(i).slice(4)).substring(26),u=n.Bytes.from(c),f=n.Bytes.from(n.Hash.sha256(n.Hash.sha256(c))).slice(0,4),l=n.Bytes.concat(u,f);return s.base58.encode(l)===e}catch(e){return!1}var P}(o,e.attestation,e.proof);return Promise.resolve(l({},e,{status:a?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/eth.ts","../src/solana.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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\";\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.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 return verifyBTCSignature(proof as SignatureProof);\n case ProofTypes.BIP137_XPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\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 } 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 } catch (error) {\n return { ...proof, status: ProofStatus.FAILED };\n }\n}\n"],"names":["SEGWIT_TYPES","DerivationMode","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","_","verified","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","attestation","e","reject","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","length","flagByte","compressed","segwitType","P2WPKH","P2SH_P2WPKH","undefined","recovery","slice","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","encodeBase58AddressFormat","verifyBTCSignature"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/bitcoin.ts","../src/index.ts","../src/eth.ts","../src/solana.ts","../src/tron.ts"],"sourcesContent":["import { ProofStatus, SignatureProof } from \"@notabene/javascript-sdk\";\n\nimport {\n secp256k1,\n hash160,\n hash256,\n RecoveryId,\n encodeBase58AddressFormat,\n} from \"@bitauth/libauth\";\nimport { encode as encodeLength } from \"varuint-bitcoin\";\nimport { base64, bech32 } from \"@scure/base\";\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 // 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 } catch (error) {\n return { ...proof, status: 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 recovery: RecoveryId;\n signature: Uint8Array;\n};\n\nfunction decodeSignature(proof: string): DecodedSignature {\n const signature = base64.decode(proof);\n if (signature.length !== 65) throw new Error(\"Invalid signature length\");\n\n const flagByte = signature[0] - 27;\n if (flagByte > 15 || flagByte < 0) {\n throw new Error(\"Invalid signature parameter\");\n }\n\n return {\n compressed: !!(flagByte & 12),\n segwitType: !(flagByte & 8)\n ? undefined\n : !(flagByte & 4)\n ? SEGWIT_TYPES.P2SH_P2WPKH\n : SEGWIT_TYPES.P2WPKH,\n recovery: (flagByte & 3) as RecoveryId,\n signature: signature.slice(1),\n };\n}\n\nfunction verify(\n attestation: string,\n address: string,\n proof: string,\n checkSegwitAlways: boolean,\n) {\n const { compressed, segwitType, recovery, signature } =\n 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\n const hash = magicHash(attestation);\n const publicKey: Uint8Array | string = compressed\n ? secp256k1.recoverPublicKeyCompressed(signature, recovery, hash)\n : secp256k1.recoverPublicKeyUncompressed(signature, recovery, hash);\n if (typeof publicKey === \"string\") throw new Error(publicKey);\n const publicKeyHash = hash160(publicKey);\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 } 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\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","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\";\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.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 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 { 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 } 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 } 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 } 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","encodeBech32Address","publicKeyHash","bwords","bech32","toWords","unshift","encode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","_","verified","message","payload","PersonalMessage","getSignPayload","Hex","fromString","signature","Signature","fromHex","publicKey","Secp256k1","recoverPublicKey","Address","checksum","fromPublicKey","toString","error","verifyEIP191","attestation","e","reject","verifyPersonalSignEIP191","ED25519","base58","decode","messageBytes","TextEncoder","signatureBytes","base64","nacl","sign","detached","verify","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","checkSegwitAlways","_decodeSignature","length","flagByte","compressed","segwitType","P2WPKH","P2SH_P2WPKH","undefined","recovery","slice","decodeSignature","hash","prefix","encodeLength","buffer","Uint8Array","byteLength","set","hash256","magicHash","secp256k1","recoverPublicKeyCompressed","recoverPublicKeyUncompressed","hash160","actual","encodeBase58AddressFormat","verifyBTCSignature","TIP191","data","Hash","keccak256","from","size","hex","PublicKey","toHex","substring","bytes","Bytes","sha256","checked","verifyTIP191","verifyPersonalSignTIP191"],"mappings":"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"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/dist/tron.d.ts
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
import { SignatureProof } from "@notabene/javascript-sdk";
|
2
|
+
import { Hex, Bytes } from "ox";
|
3
|
+
export declare function verifyTIP191(address: string, message: string, proof: Hex.Hex): boolean;
|
4
|
+
export declare function verifyPersonalSignTIP191(proof: SignatureProof): Promise<SignatureProof>;
|
5
|
+
export declare function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex;
|
6
|
+
export declare function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@notabene/verify-proof",
|
3
|
-
"version": "1.0.
|
3
|
+
"version": "1.0.4",
|
4
4
|
"description": "Verify ownership proofs",
|
5
5
|
"source": "src/index.ts",
|
6
6
|
"type": "module",
|
@@ -25,13 +25,14 @@
|
|
25
25
|
"devDependencies": {
|
26
26
|
"eslint": "^9.9.0",
|
27
27
|
"microbundle": "^0.15.1",
|
28
|
+
"tronweb": "^6.0.0",
|
28
29
|
"typescript": "^5.5.4",
|
29
30
|
"vite": "^5.4.11",
|
30
31
|
"vitest": "^2.0.5"
|
31
32
|
},
|
32
33
|
"dependencies": {
|
33
34
|
"@bitauth/libauth": "^3.0.0",
|
34
|
-
"@notabene/javascript-sdk": "^2.0
|
35
|
+
"@notabene/javascript-sdk": "^2.3.0",
|
35
36
|
"@scure/base": "^1.2.1",
|
36
37
|
"ox": "^0.2.2",
|
37
38
|
"tweetnacl": "^1.0.3",
|
package/src/index.ts
CHANGED
@@ -9,6 +9,7 @@ import {
|
|
9
9
|
import { verifyBTCSignature } from "./bitcoin";
|
10
10
|
import { verifyPersonalSignEIP191 } from "./eth";
|
11
11
|
import { verifySolanaSignature } from "./solana";
|
12
|
+
import { verifyPersonalSignTIP191 } from "./tron";
|
12
13
|
|
13
14
|
export async function verifyProof(
|
14
15
|
proof: OwnershipProof,
|
@@ -35,6 +36,8 @@ export async function verifyProof(
|
|
35
36
|
case ProofTypes.EIP712:
|
36
37
|
case ProofTypes.BIP137:
|
37
38
|
return verifyBTCSignature(proof as SignatureProof);
|
39
|
+
case ProofTypes.TIP191:
|
40
|
+
return verifyPersonalSignTIP191(proof as SignatureProof);
|
38
41
|
case ProofTypes.BIP137_XPUB:
|
39
42
|
case ProofTypes.MicroTransfer:
|
40
43
|
}
|
package/src/tests/eth.test.ts
CHANGED
@@ -39,7 +39,6 @@ describe("verifyPersonalSignEIP191", () => {
|
|
39
39
|
|
40
40
|
it("returns verified proof even when address is not the correct case", async () => {
|
41
41
|
const proof = personalSign();
|
42
|
-
console.log(proof.address);
|
43
42
|
const result = await verifyPersonalSignEIP191({
|
44
43
|
...proof,
|
45
44
|
address: proof.address.toLowerCase() as CAIP10,
|
package/src/tests/index.test.ts
CHANGED
@@ -163,4 +163,31 @@ describe("verifyProof", () => {
|
|
163
163
|
expect(result.status).toBe(ProofStatus.FAILED);
|
164
164
|
});
|
165
165
|
});
|
166
|
+
|
167
|
+
describe("TRON", () => {
|
168
|
+
const proof: SignatureProof = {
|
169
|
+
type: ProofTypes.TIP191,
|
170
|
+
address: "tron:0x2b6653dc:TGLpk9KB2fsxSy3Yn8zLQywfFHSUtbx4tS",
|
171
|
+
did: "did:pkh:tron:0x2b6653dc:TGLpk9KB2fsxSy3Yn8zLQywfFHSUtbx4tS",
|
172
|
+
attestation: "I agree",
|
173
|
+
proof:
|
174
|
+
"0x65edeed02c254c7a39d255453aa48775576fdbcb8af2e9497bed31fa159451897320cf5feac42f87fa36aa0a5da9b24380712cc00809df989be8c4c6d42604e01b",
|
175
|
+
status: ProofStatus.PENDING,
|
176
|
+
wallet_provider: "MetaMask",
|
177
|
+
};
|
178
|
+
|
179
|
+
it("should verify proof", async () => {
|
180
|
+
const result = await verifyProof(proof);
|
181
|
+
expect(result.status).toBe(ProofStatus.VERIFIED);
|
182
|
+
});
|
183
|
+
|
184
|
+
it("should fail if not invalid proof", async () => {
|
185
|
+
const result = await verifyProof({
|
186
|
+
...proof,
|
187
|
+
proof: "0x",
|
188
|
+
} as SignatureProof);
|
189
|
+
|
190
|
+
expect(result.status).toBe(ProofStatus.FAILED);
|
191
|
+
});
|
192
|
+
});
|
166
193
|
});
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
2
|
+
import { verifyPersonalSignTIP191 } from "../tron";
|
3
|
+
import {
|
4
|
+
type SignatureProof,
|
5
|
+
ProofStatus,
|
6
|
+
ProofTypes,
|
7
|
+
} from "@notabene/javascript-sdk";
|
8
|
+
import { TronWeb, Trx } from "tronweb";
|
9
|
+
const account = await TronWeb.createAccount();
|
10
|
+
const privateKey = account.privateKey;
|
11
|
+
const address = account.address.base58;
|
12
|
+
|
13
|
+
function personalSign(): SignatureProof {
|
14
|
+
const attestation = "I agree";
|
15
|
+
const proof = Trx.signMessageV2(attestation, privateKey);
|
16
|
+
|
17
|
+
return {
|
18
|
+
type: ProofTypes.TIP191,
|
19
|
+
address: `tron:0x2b6653dc:${address}`,
|
20
|
+
did: `did:pkh:tron:0x2b6653dc:${address}`,
|
21
|
+
attestation,
|
22
|
+
proof,
|
23
|
+
status: ProofStatus.PENDING,
|
24
|
+
wallet_provider: "MetaMask",
|
25
|
+
};
|
26
|
+
}
|
27
|
+
|
28
|
+
describe("verifyPersonalSignTIP191", () => {
|
29
|
+
it("returns verified proof when valid message and address", async () => {
|
30
|
+
const proof = personalSign();
|
31
|
+
const result = await verifyPersonalSignTIP191(proof);
|
32
|
+
|
33
|
+
expect(result.status).toBe(ProofStatus.VERIFIED);
|
34
|
+
});
|
35
|
+
|
36
|
+
it("returns failed proof when invalid message or address", async () => {
|
37
|
+
const proof = { ...personalSign(), attestation: "evil text" };
|
38
|
+
const result = await verifyPersonalSignTIP191(proof);
|
39
|
+
|
40
|
+
expect(result.status).toBe(ProofStatus.FAILED);
|
41
|
+
});
|
42
|
+
|
43
|
+
it("returns failed proof for non-TRON address", async () => {
|
44
|
+
const proof: SignatureProof = {
|
45
|
+
type: ProofTypes.TIP191,
|
46
|
+
did: `did:pkh:bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6`,
|
47
|
+
wallet_provider: "metamask",
|
48
|
+
address:
|
49
|
+
"bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6",
|
50
|
+
attestation: "test message",
|
51
|
+
proof: "0xabcd",
|
52
|
+
status: ProofStatus.PENDING,
|
53
|
+
};
|
54
|
+
|
55
|
+
const result = await verifyPersonalSignTIP191(proof);
|
56
|
+
|
57
|
+
expect(result.status).toBe(ProofStatus.FAILED);
|
58
|
+
});
|
59
|
+
});
|
package/src/tron.ts
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
import { ProofStatus, SignatureProof } from "@notabene/javascript-sdk";
|
2
|
+
import { Secp256k1, Hex, Signature, Hash, Bytes, PublicKey } from "ox";
|
3
|
+
import { base58 } from "@scure/base";
|
4
|
+
|
5
|
+
export function verifyTIP191(
|
6
|
+
address: string,
|
7
|
+
message: string,
|
8
|
+
proof: Hex.Hex,
|
9
|
+
): boolean {
|
10
|
+
try {
|
11
|
+
const payload = getSignPayload(Hex.fromString(message));
|
12
|
+
const signature = Signature.fromHex(proof);
|
13
|
+
const publicKey = Secp256k1.recoverPublicKey({ payload, signature });
|
14
|
+
const hex: Hex.Hex = `0x41${Hash.keccak256(
|
15
|
+
`0x${PublicKey.toHex(publicKey).slice(4)}`,
|
16
|
+
).substring(26)}`;
|
17
|
+
const bytes = Bytes.from(hex);
|
18
|
+
const checksum = Bytes.from(Hash.sha256(Hash.sha256(hex))).slice(0, 4);
|
19
|
+
const checked = Bytes.concat(bytes, checksum);
|
20
|
+
const b58 = base58.encode(checked);
|
21
|
+
return b58 === address;
|
22
|
+
} catch (error) {
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
export async function verifyPersonalSignTIP191(
|
28
|
+
proof: SignatureProof,
|
29
|
+
): Promise<SignatureProof> {
|
30
|
+
const [ns, _, address] = proof.address.split(/:/);
|
31
|
+
if (ns !== "tron") return { ...proof, status: ProofStatus.FAILED };
|
32
|
+
|
33
|
+
const verified = verifyTIP191(
|
34
|
+
address as Hex.Hex,
|
35
|
+
proof.attestation,
|
36
|
+
proof.proof as Hex.Hex,
|
37
|
+
);
|
38
|
+
return {
|
39
|
+
...proof,
|
40
|
+
status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,
|
41
|
+
};
|
42
|
+
}
|
43
|
+
|
44
|
+
export function encode(data: Hex.Hex | Bytes.Bytes): Hex.Hex {
|
45
|
+
const message = Hex.from(data);
|
46
|
+
return Hex.concat(
|
47
|
+
// Personal Sign Format: `0x19 ‖ "Ethereum Signed Message:\n" ‖ message.length ‖ message`
|
48
|
+
"0x19",
|
49
|
+
Hex.fromString("TRON Signed Message:\n" + Hex.size(message)),
|
50
|
+
message,
|
51
|
+
);
|
52
|
+
}
|
53
|
+
export function getSignPayload(data: Hex.Hex | Bytes.Bytes): Hex.Hex {
|
54
|
+
return Hash.keccak256(encode(data));
|
55
|
+
}
|