@notabene/verify-proof 1.0.0-preview.3 → 1.0.0-preview.6

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -36,10 +36,10 @@ async function checkProof(proof: OwnershipProof) {
36
36
 
37
37
  - Checkbox Confirmation (`ProofTypes.CheckboxConfirmation`)
38
38
  - Screenshot (`ProofTypes.Screenshot`)
39
- - Personal Sign EIP191 (`ProofTypes.PersonalSignEIP191`)
40
- - Personal Sign EIP712 (`ProofTypes.PersonalSignEIP712`)
41
- - Personal Sign BIP137 (`ProofTypes.PersonalSignBIP137`)
42
- - Personal Sign XPUB (`ProofTypes.PersonalSignXPUB`)
39
+ - Personal Sign EIP191 (`ProofTypes.EIP191`)
40
+ - Personal Sign EIP712 (`ProofTypes.EIP712`)
41
+ - Personal Sign BIP137 (`ProofTypes.BIP137`)
42
+ - Personal Sign XPUB (`ProofTypes.XPUB`)
43
43
  - Micro Transfer (`ProofTypes.MicroTransfer`)
44
44
 
45
45
  ## Development
@@ -0,0 +1,12 @@
1
+ import { SignatureProof } from "@notabene/javascript-sdk/src/types";
2
+ export declare enum DerivationMode {
3
+ LEGACY = "Legacy",
4
+ NATIVE = "Native SegWit",
5
+ SEGWIT = "SegWit",
6
+ P2SH_SEGWIT = "p2sh",
7
+ BCH = "Bitcoin Cash",
8
+ ETHEREUM = "Ethereum",
9
+ DOGECOIN = "Dogecoin",
10
+ UNKNOWN = "Unknown"
11
+ }
12
+ export declare function verifyBTCSignature(proof: SignatureProof): Promise<SignatureProof>;
package/dist/eth.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { SignatureProof } from "@notabene/javascript-sdk/src/types";
2
+ export declare function verifyPersonalSignEIP191(proof: SignatureProof): Promise<SignatureProof>;
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var r=require("@notabene/javascript-sdk/src/types"),e=require("viem");function t(){return t=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var s in t)({}).hasOwnProperty.call(t,s)&&(r[s]=t[s])}return r},t.apply(null,arguments)}exports.verifyProof=function(s){try{switch(s.type){case r.ProofTypes.SelfDeclaration:return Promise.resolve(t({},s,{status:s.confirmed?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}));case r.ProofTypes.Screenshot:return Promise.resolve(t({},s,{status:s.url?r.ProofStatus.FLAGGED:r.ProofStatus.FAILED}));case r.ProofTypes.PersonalSignEIP191:return function(s){try{var o=s.address.split(/:/),a=o[2];return"eip155"!==o[0]?Promise.resolve(t({},s,{status:r.ProofStatus.FAILED})):Promise.resolve(e.verifyMessage({address:a,message:s.attestation,signature:s.proof})).then(function(e){return t({},s,{status:e?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED})})}catch(r){return Promise.reject(r)}}(s)}return Promise.resolve(s)}catch(r){return Promise.reject(r)}};
1
+ var e=require("@notabene/javascript-sdk/src/types"),r=require("bitcoinjs-message"),t=require("viem"),o=require("@solana/web3.js"),s=require("tweetnacl"),a=require("@stablelib/base64");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var o=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,o.get?o:{enumerable:!0,get:function(){return e[t]}})}}),r.default=e,r}var i,c=/*#__PURE__*/u(r),f=/*#__PURE__*/n(s);function P(){return P=Object.assign?Object.assign.bind():function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)({}).hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e},P.apply(null,arguments)}!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(r){try{switch(r.type){case e.ProofTypes.SelfDeclaration:return Promise.resolve(P({},r,{status:r.confirmed?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}));case e.ProofTypes.Screenshot:return Promise.resolve(P({},r,{status:r.url?e.ProofStatus.FLAGGED:e.ProofStatus.FAILED}));case e.ProofTypes.EIP191:return Promise.resolve(function(r){try{var o=r.address.split(/:/),s=o[2];return"eip155"!==o[0]?Promise.resolve(P({},r,{status:e.ProofStatus.FAILED})):Promise.resolve(t.verifyMessage({address:s,message:r.attestation,signature:r.proof})).then(function(t){return P({},r,{status:t?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED})})}catch(e){return Promise.reject(e)}}(r));case e.ProofTypes.ED25519:return Promise.resolve(function(r){try{var t=r.address.split(/:/),s=t[2];if("solana"!==t[0])return Promise.resolve(P({},r,{status:e.ProofStatus.FAILED}));try{var n=new o.PublicKey(s),u=(new TextEncoder).encode(r.attestation),i=a.decode(r.proof),c=f.default.sign.detached.verify(u,i,n.toBytes());return Promise.resolve(P({},r,{status:c?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(t){return Promise.resolve(P({},r,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(r));case e.ProofTypes.EIP712:case e.ProofTypes.BIP137:return Promise.resolve(function(r){try{var t=r.address.split(/:/),o=t[2];if("bip122"!==t[0])return Promise.resolve(P({},r,{status:e.ProofStatus.FAILED}));try{var s=[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"))}(o)),a=c.verify(r.attestation,o,r.proof,void 0,s);return Promise.resolve(P({},r,{status:a?e.ProofStatus.VERIFIED:e.ProofStatus.FAILED}))}catch(t){return Promise.resolve(P({},r,{status:e.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(r))}return Promise.resolve(r)}catch(e){return Promise.reject(e)}};
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import {\n DeclarationProof,\n ProofStatus,\n ProofTypes,\n ScreenshotProof,\n SignatureProof,\n type OwnershipProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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.PersonalSignEIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.PersonalSignEIP712:\n case ProofTypes.PersonalSignBIP137:\n case ProofTypes.PersonalSignXPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n\nasync 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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\n });\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n"],"names":["proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","PersonalSignEIP191","_proof$address$split","address","split","verifyMessage","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191"],"mappings":"kTAUiC,SAC/BA,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,EAAAA,WAAWC,gBACd,OAAAC,QAAAC,QAAAC,EAAA,CAAA,EACKN,EAAK,CACRO,OAASP,EAA2BQ,UAChCC,EAAAA,YAAYC,SACZD,EAAAA,YAAYE,UAEpB,KAAKT,EAAUA,WAACU,WACd,OAAAR,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAASP,EAA0Ba,IAC/BJ,EAAWA,YAACK,QACZL,EAAWA,YAACE,UAEpB,KAAKT,EAAAA,WAAWa,mBACd,OASiC,SACrCf,GAAqB,IAErB,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EAAA,GACrB,MAAW,WADFA,EAAA,GACYZ,QAAAC,QAAAC,EAAA,GAAYN,EAAK,CAAEO,OAAQE,EAAWA,YAACE,UAASP,QAAAC,QAE9Cc,EAAAA,cAAc,CACnCF,QAASA,EACTG,QAASpB,EAAMqB,YACfC,UAAWtB,EAAMA,SACjBuB,KAJIC,SAAAA,GAKN,OAAAlB,EAAA,CAAA,EACKN,EAAK,CACRO,OAAQiB,EAAWf,EAAWA,YAACC,SAAWD,EAAAA,YAAYE,QACtD,EACJ,CAAC,MAAAc,GAAArB,OAAAA,QAAAsB,OAAAD,EA3CD,CAAA,CAmBaE,CAAyB3B,GAMpC,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAyB,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/bitcoin.ts","../src/index.ts","../src/eth.ts","../src/solana.ts"],"sourcesContent":["import {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport * as bitcoinMessage from \"bitcoinjs-message\";\n\nexport enum 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 = bitcoinMessage.verify(\n proof.attestation,\n address,\n proof.proof,\n undefined,\n segwit,\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\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","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk/src/types\";\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 {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\n });\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport nacl from \"tweetnacl\";\nimport {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { decode as decodeBase64 } from \"@stablelib/base64\";\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 = new PublicKey(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = decodeBase64(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey.toBytes(),\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":["DerivationMode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","verifyMessage","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191","ED25519","publicKey","PublicKey","messageBytes","TextEncoder","encode","signatureBytes","decodeBase64","nacl","sign","detached","verify","toBytes","error","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","bitcoinMessage","undefined","verifyBTCSignature"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{ProofTypes as r,ProofStatus as e}from"@notabene/javascript-sdk/src/types";import{verifyMessage as t}from"viem";function s(){return s=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var s in t)({}).hasOwnProperty.call(t,s)&&(r[s]=t[s])}return r},s.apply(null,arguments)}var n=function(n){try{switch(n.type){case r.SelfDeclaration:return Promise.resolve(s({},n,{status:n.confirmed?e.VERIFIED:e.FAILED}));case r.Screenshot:return Promise.resolve(s({},n,{status:n.url?e.FLAGGED:e.FAILED}));case r.PersonalSignEIP191:return function(r){try{var n=r.address.split(/:/),o=n[2];return"eip155"!==n[0]?Promise.resolve(s({},r,{status:e.FAILED})):Promise.resolve(t({address:o,message:r.attestation,signature:r.proof})).then(function(t){return s({},r,{status:t?e.VERIFIED:e.FAILED})})}catch(r){return Promise.reject(r)}}(n)}return Promise.resolve(n)}catch(r){return Promise.reject(r)}};export{n as verifyProof};
1
+ import{ProofStatus as r,ProofTypes as e}from"@notabene/javascript-sdk/src/types";import*as t from"bitcoinjs-message";import{verifyMessage as s}from"viem";import{PublicKey as o}from"@solana/web3.js";import n from"tweetnacl";import{decode as a}from"@stablelib/base64";function i(){return i=Object.assign?Object.assign.bind():function(r){for(var e=1;e<arguments.length;e++){var t=arguments[e];for(var s in t)({}).hasOwnProperty.call(t,s)&&(r[s]=t[s])}return r},i.apply(null,arguments)}var c;!function(r){r.LEGACY="Legacy",r.NATIVE="Native SegWit",r.SEGWIT="SegWit",r.P2SH_SEGWIT="p2sh",r.BCH="Bitcoin Cash",r.ETHEREUM="Ethereum",r.DOGECOIN="Dogecoin",r.UNKNOWN="Unknown"}(c||(c={}));var u=function(u){try{switch(u.type){case e.SelfDeclaration:return Promise.resolve(i({},u,{status:u.confirmed?r.VERIFIED:r.FAILED}));case e.Screenshot:return Promise.resolve(i({},u,{status:u.url?r.FLAGGED:r.FAILED}));case e.EIP191:return Promise.resolve(function(e){try{var t=e.address.split(/:/),o=t[2];return"eip155"!==t[0]?Promise.resolve(i({},e,{status:r.FAILED})):Promise.resolve(s({address:o,message:e.attestation,signature:e.proof})).then(function(t){return i({},e,{status:t?r.VERIFIED:r.FAILED})})}catch(r){return Promise.reject(r)}}(u));case e.ED25519:return Promise.resolve(function(e){try{var t=e.address.split(/:/),s=t[2];if("solana"!==t[0])return Promise.resolve(i({},e,{status:r.FAILED}));try{var c=new o(s),u=(new TextEncoder).encode(e.attestation),m=a(e.proof),E=n.sign.detached.verify(u,m,c.toBytes());return Promise.resolve(i({},e,{status:E?r.VERIFIED:r.FAILED}))}catch(t){return Promise.resolve(i({},e,{status:r.FAILED}))}}catch(r){return Promise.reject(r)}}(u));case e.EIP712:case e.BIP137:return Promise.resolve(function(e){try{var s=e.address.split(/:/),o=s[2];if("bip122"!==s[0])return Promise.resolve(i({},e,{status:r.FAILED}));try{var n=[c.SEGWIT,c.NATIVE].includes(function(r){if(r.match("^(bc1|tb1|ltc1).*"))return c.NATIVE;if(r.match("^[32M].*"))return c.SEGWIT;if(r.match("^[1nmL].*"))return c.LEGACY;if(r.match("^(D).*"))return c.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(r).concat(" is not a valid or a supported address"))}(o)),a=t.verify(e.attestation,o,e.proof,void 0,n);return Promise.resolve(i({},e,{status:a?r.VERIFIED:r.FAILED}))}catch(t){return Promise.resolve(i({},e,{status:r.FAILED}))}}catch(r){return Promise.reject(r)}}(u))}return Promise.resolve(u)}catch(r){return Promise.reject(r)}};export{u as verifyProof};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import {\n DeclarationProof,\n ProofStatus,\n ProofTypes,\n ScreenshotProof,\n SignatureProof,\n type OwnershipProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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.PersonalSignEIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.PersonalSignEIP712:\n case ProofTypes.PersonalSignBIP137:\n case ProofTypes.PersonalSignXPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n\nasync 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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\n });\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n"],"names":["verifyProof","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","PersonalSignEIP191","_proof$address$split","address","split","verifyMessage","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191"],"mappings":"8UAQqC,IAEfA,EAAW,SAC/BC,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,EAAWC,gBACd,OAAAC,QAAAC,QAAAC,EAAA,CAAA,EACKN,EAAK,CACRO,OAASP,EAA2BQ,UAChCC,EAAYC,SACZD,EAAYE,UAEpB,KAAKT,EAAWU,WACd,OAAAR,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAASP,EAA0Ba,IAC/BJ,EAAYK,QACZL,EAAYE,UAEpB,KAAKT,EAAWa,mBACd,OASiC,SACrCf,GAAqB,IAErB,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EAAA,GACrB,MAAW,WADFA,EAAA,GACYZ,QAAAC,QAAAC,EAAA,GAAYN,EAAK,CAAEO,OAAQE,EAAYE,UAASP,QAAAC,QAE9Cc,EAAc,CACnCF,QAASA,EACTG,QAASpB,EAAMqB,YACfC,UAAWtB,EAAMA,SACjBuB,KAJIC,SAAAA,GAKN,OAAAlB,EAAA,CAAA,EACKN,EAAK,CACRO,OAAQiB,EAAWf,EAAYC,SAAWD,EAAYE,QACtD,EACJ,CAAC,MAAAc,GAAArB,OAAAA,QAAAsB,OAAAD,EA3CD,CAAA,CAmBaE,CAAyB3B,GAMpC,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAyB,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA"}
1
+ {"version":3,"file":"index.js","sources":["../src/bitcoin.ts","../src/eth.ts","../src/index.ts","../src/solana.ts"],"sourcesContent":["import {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport * as bitcoinMessage from \"bitcoinjs-message\";\n\nexport enum 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 = bitcoinMessage.verify(\n proof.attestation,\n address,\n proof.proof,\n undefined,\n segwit,\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\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","import {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\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/src/types\";\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 { PublicKey } from \"@solana/web3.js\";\nimport nacl from \"tweetnacl\";\nimport {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { decode as decodeBase64 } from \"@stablelib/base64\";\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 = new PublicKey(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = decodeBase64(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey.toBytes(),\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":["DerivationMode","verifyProof","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","verifyMessage","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191","ED25519","publicKey","PublicKey","messageBytes","TextEncoder","encode","signatureBytes","decodeBase64","nacl","sign","detached","verify","toBytes","error","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","bitcoinMessage","undefined","verifyBTCSignature"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{ProofTypes as t,ProofStatus as r}from"@notabene/javascript-sdk/src/types";import{verifyMessage as s}from"viem";function n(){return n=Object.assign?Object.assign.bind():function(t){for(var r=1;r<arguments.length;r++){var s=arguments[r];for(var n in s)({}).hasOwnProperty.call(s,n)&&(t[n]=s[n])}return t},n.apply(null,arguments)}async function e(e){switch(e.type){case t.SelfDeclaration:return n({},e,{status:e.confirmed?r.VERIFIED:r.FAILED});case t.Screenshot:return n({},e,{status:e.url?r.FLAGGED:r.FAILED});case t.PersonalSignEIP191:return async function(t){const[e,a,i]=t.address.split(/:/);return n({},t,"eip155"!==e?{status:r.FAILED}:{status:await s({address:i,message:t.attestation,signature:t.proof})?r.VERIFIED:r.FAILED})}(e)}return e}export{e as verifyProof};
1
+ import{ProofStatus as t,ProofTypes as r}from"@notabene/javascript-sdk/src/types";import*as s from"bitcoinjs-message";import{verifyMessage as e}from"viem";import{PublicKey as n}from"@solana/web3.js";import a from"tweetnacl";import{decode as o}from"@stablelib/base64";function c(){return c=Object.assign?Object.assign.bind():function(t){for(var r=1;r<arguments.length;r++){var s=arguments[r];for(var e in s)({}).hasOwnProperty.call(s,e)&&(t[e]=s[e])}return t},c.apply(null,arguments)}var i;async function u(u){switch(u.type){case r.SelfDeclaration:return c({},u,{status:u.confirmed?t.VERIFIED:t.FAILED});case r.Screenshot:return c({},u,{status:u.url?t.FLAGGED:t.FAILED});case r.EIP191:return async function(r){const[s,n,a]=r.address.split(/:/);return c({},r,"eip155"!==s?{status:t.FAILED}:{status:await e({address:a,message:r.attestation,signature:r.proof})?t.VERIFIED:t.FAILED})}(u);case r.ED25519:return async function(r){const[s,e,i]=r.address.split(/:/);if("solana"!==s)return c({},r,{status:t.FAILED});try{const s=new n(i),e=(new TextEncoder).encode(r.attestation),u=o(r.proof);return c({},r,{status:a.sign.detached.verify(e,u,s.toBytes())?t.VERIFIED:t.FAILED})}catch(s){return c({},r,{status:t.FAILED})}}(u);case r.EIP712:case r.BIP137:return async function(r){const[e,n,a]=r.address.split(/:/);if("bip122"!==e)return c({},r,{status:t.FAILED});try{const e=[i.SEGWIT,i.NATIVE].includes(function(t){if(t.match("^(bc1|tb1|ltc1).*"))return i.NATIVE;if(t.match("^[32M].*"))return i.SEGWIT;if(t.match("^[1nmL].*"))return i.LEGACY;if(t.match("^(D).*"))return i.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(t).concat(" is not a valid or a supported address"))}(a));return c({},r,{status:s.verify(r.attestation,a,r.proof,void 0,e)?t.VERIFIED:t.FAILED})}catch(s){return c({},r,{status:t.FAILED})}}(u)}return u}!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"}(i||(i={}));export{u as verifyProof};
2
2
  //# sourceMappingURL=index.modern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.modern.js","sources":["../src/index.ts"],"sourcesContent":["import {\n DeclarationProof,\n ProofStatus,\n ProofTypes,\n ScreenshotProof,\n SignatureProof,\n type OwnershipProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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.PersonalSignEIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.PersonalSignEIP712:\n case ProofTypes.PersonalSignBIP137:\n case ProofTypes.PersonalSignXPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n\nasync 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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\n });\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n"],"names":["async","verifyProof","proof","type","ProofTypes","SelfDeclaration","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","PersonalSignEIP191","ns","_","address","split","verifyMessage","message","attestation","signature","verifyPersonalSignEIP191"],"mappings":"8UAUOA,eAAeC,EACpBC,GAEA,OAAQA,EAAMC,MACZ,KAAKC,EAAWC,gBACd,OAAAC,EACKJ,CAAAA,EAAAA,EACHK,CAAAA,OAASL,EAA2BM,UAChCC,EAAYC,SACZD,EAAYE,SAEpB,KAAKP,EAAWQ,WACd,OAAAN,EAAA,GACKJ,EACHK,CAAAA,OAASL,EAA0BW,IAC/BJ,EAAYK,QACZL,EAAYE,SAEpB,KAAKP,EAAWW,mBACd,OASNf,eACEE,GAEA,MAAOc,EAAIC,EAAGC,GAAWhB,EAAMgB,QAAQC,MAAM,KAC7C,OAAqBb,EAAA,CAAA,EAAYJ,EAAtB,WAAPc,EAAkC,CAAET,OAAQE,EAAYE,QAQlD,CACRJ,aAPqBa,EAAc,CACnCF,QAASA,EACTG,QAASnB,EAAMoB,YACfC,UAAWrB,EAAMA,QAIEO,EAAYC,SAAWD,EAAYE,QAE1D,CAxBaa,CAAyBtB,GAMpC,OAAOA,CACT"}
1
+ {"version":3,"file":"index.modern.js","sources":["../src/bitcoin.ts","../src/index.ts","../src/eth.ts","../src/solana.ts"],"sourcesContent":["import {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport * as bitcoinMessage from \"bitcoinjs-message\";\n\nexport enum 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 = bitcoinMessage.verify(\n proof.attestation,\n address,\n proof.proof,\n undefined,\n segwit,\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\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","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk/src/types\";\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 {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\n });\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport nacl from \"tweetnacl\";\nimport {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { decode as decodeBase64 } from \"@stablelib/base64\";\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 = new PublicKey(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = decodeBase64(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey.toBytes(),\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":["DerivationMode","verifyProof","proof","type","ProofTypes","SelfDeclaration","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","ns","_","address","split","verifyMessage","message","attestation","signature","verifyPersonalSignEIP191","ED25519","async","publicKey","PublicKey","messageBytes","TextEncoder","encode","signatureBytes","decodeBase64","nacl","sign","detached","verify","toBytes","error","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","bitcoinMessage","undefined","verifyBTCSignature"],"mappings":"keAMY,IAAAA,iBCMUC,EACpBC,GAEA,OAAQA,EAAMC,MACZ,KAAKC,EAAWC,gBACd,OAAAC,EACKJ,CAAAA,EAAAA,EACHK,CAAAA,OAASL,EAA2BM,UAChCC,EAAYC,SACZD,EAAYE,SAEpB,KAAKP,EAAWQ,WACd,OAAAN,EACKJ,GAAAA,GACHK,OAASL,EAA0BW,IAC/BJ,EAAYK,QACZL,EAAYE,SAEpB,KAAKP,EAAWW,OACd,sBCxBJb,GAEA,MAAOc,EAAIC,EAAGC,GAAWhB,EAAMgB,QAAQC,MAAM,KAC7C,OAAqBb,EAAA,CAAA,EAAYJ,EAAtB,WAAPc,EAAkC,CAAET,OAAQE,EAAYE,QAQlD,CACRJ,aAPqBa,EAAc,CACnCF,QAASA,EACTG,QAASnB,EAAMoB,YACfC,UAAWrB,EAAMA,QAIEO,EAAYC,SAAWD,EAAYE,QAE1D,CDUaa,CAAyBtB,GAClC,KAAKE,EAAWqB,QACd,OEzBCC,eACLxB,GAEA,MAAOc,EAAIC,EAAGC,GAAWhB,EAAMgB,QAAQC,MAAM,KAC7C,GAAW,WAAPH,EAAiB,OAAAV,EAAA,GAAYJ,EAAOK,CAAAA,OAAQE,EAAYE,SAC5D,IACE,MAAMgB,EAAY,IAAIC,EAAUV,GAC1BW,GAAe,IAAIC,aAAcC,OAAO7B,EAAMoB,aAC9CU,EAAiBC,EAAa/B,EAAMA,OAO1C,OAAAI,EAAA,GACKJ,EAAK,CACRK,OARe2B,EAAKC,KAAKC,SAASC,OAClCR,EACAG,EACAL,EAAUW,WAKS7B,EAAYC,SAAWD,EAAYE,QAE1D,CAAE,MAAO4B,GACP,OAAAjC,EAAYJ,CAAAA,EAAAA,GAAOK,OAAQE,EAAYE,QACzC,CACF,CFGa6B,CAAsBtC,GAC/B,KAAKE,EAAWqC,OAChB,KAAKrC,EAAWsC,OACd,ODnBgBhB,eACpBxB,GAEA,MAAOc,EAAIC,EAAGC,GAAWhB,EAAMgB,QAAQC,MAAM,KAC7C,GAAW,WAAPH,EAAiB,OAAAV,EAAA,GAAYJ,EAAK,CAAEK,OAAQE,EAAYE,SAC5D,IAEE,MAAMgC,EAAS,CAAC3C,EAAe4C,OAAQ5C,EAAe6C,QAAQC,SAoBlE,SAA2B5B,GACzB,GAAIA,EAAQ6B,MAAM,qBAChB,OAAO/C,EAAe6C,OACjB,GAAI3B,EAAQ6B,MAAM,YACvB,OAAO/C,EAAe4C,OACjB,GAAI1B,EAAQ6B,MAAM,aACvB,OAAO/C,EAAegD,OACb9B,GAAAA,EAAQ6B,MAAM,UACvB,OAAO/C,EAAeiD,SAEtB,MAAM,IAAIC,MACR,oBACGC,OAAOjC,GACPiC,OAAO,0CAGhB,CAnCMC,CAAkBlC,IAUpB,OAAAZ,EACKJ,CAAAA,EAAAA,GACHK,OAVe8C,EAAehB,OAC9BnC,EAAMoB,YACNJ,EACAhB,EAAMA,WACNoD,EACAX,GAKmBlC,EAAYC,SAAWD,EAAYE,QAE1D,CAAE,MAAO4B,GACP,OAAAjC,EAAYJ,CAAAA,EAAAA,EAAOK,CAAAA,OAAQE,EAAYE,QACzC,CACF,CCNa4C,CAAmBrD,GAI9B,OAAOA,CACT,EDnCA,SAAYF,GACVA,EAAA,OAAA,SACAA,EAAA,OAAA,gBACAA,EAAA,OAAA,SACAA,EAAA,YAAA,OACAA,EAAA,IAAA,eACAA,EAAA,SAAA,WACAA,EAAA,SAAA,WACAA,EAAA,QAAA,SACD,CATD,CAAYA,IAAAA,EASX"}
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/src/types"),require("viem")):"function"==typeof define&&define.amd?define(["exports","@notabene/javascript-sdk/src/types","viem"],r):r((e||self).verifyProof={},e.types,e.viem)}(this,function(e,r,t){function s(){return s=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},s.apply(null,arguments)}e.verifyProof=function(e){try{switch(e.type){case r.ProofTypes.SelfDeclaration:return Promise.resolve(s({},e,{status:e.confirmed?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}));case r.ProofTypes.Screenshot:return Promise.resolve(s({},e,{status:e.url?r.ProofStatus.FLAGGED:r.ProofStatus.FAILED}));case r.ProofTypes.PersonalSignEIP191:return function(e){try{var o=e.address.split(/:/),n=o[2];return"eip155"!==o[0]?Promise.resolve(s({},e,{status:r.ProofStatus.FAILED})):Promise.resolve(t.verifyMessage({address:n,message:e.attestation,signature:e.proof})).then(function(t){return s({},e,{status:t?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED})})}catch(e){return Promise.reject(e)}}(e)}return Promise.resolve(e)}catch(e){return Promise.reject(e)}}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@notabene/javascript-sdk/src/types"),require("bitcoinjs-message"),require("viem"),require("@solana/web3.js"),require("tweetnacl"),require("@stablelib/base64")):"function"==typeof define&&define.amd?define(["exports","@notabene/javascript-sdk/src/types","bitcoinjs-message","viem","@solana/web3.js","tweetnacl","@stablelib/base64"],t):t((e||self).verifyProof={},e.types,e.bitcoinjsMessage,e.viem,e.web3_js,e.tweetnacl,e.base64)}(this,function(e,t,r,s,o,a,n){function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function u(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,t}var c,f=/*#__PURE__*/u(r),l=/*#__PURE__*/i(a);function P(){return P=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var s in r)({}).hasOwnProperty.call(r,s)&&(e[s]=r[s])}return e},P.apply(null,arguments)}!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"}(c||(c={})),e.verifyProof=function(e){try{switch(e.type){case t.ProofTypes.SelfDeclaration:return Promise.resolve(P({},e,{status:e.confirmed?t.ProofStatus.VERIFIED:t.ProofStatus.FAILED}));case t.ProofTypes.Screenshot:return Promise.resolve(P({},e,{status:e.url?t.ProofStatus.FLAGGED:t.ProofStatus.FAILED}));case t.ProofTypes.EIP191:return Promise.resolve(function(e){try{var r=e.address.split(/:/),o=r[2];return"eip155"!==r[0]?Promise.resolve(P({},e,{status:t.ProofStatus.FAILED})):Promise.resolve(s.verifyMessage({address:o,message:e.attestation,signature:e.proof})).then(function(r){return P({},e,{status:r?t.ProofStatus.VERIFIED:t.ProofStatus.FAILED})})}catch(e){return Promise.reject(e)}}(e));case t.ProofTypes.ED25519:return Promise.resolve(function(e){try{var r=e.address.split(/:/),s=r[2];if("solana"!==r[0])return Promise.resolve(P({},e,{status:t.ProofStatus.FAILED}));try{var a=new o.PublicKey(s),i=(new TextEncoder).encode(e.attestation),u=n.decode(e.proof),c=l.default.sign.detached.verify(i,u,a.toBytes());return Promise.resolve(P({},e,{status:c?t.ProofStatus.VERIFIED:t.ProofStatus.FAILED}))}catch(r){return Promise.resolve(P({},e,{status:t.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e));case t.ProofTypes.EIP712:case t.ProofTypes.BIP137:return Promise.resolve(function(e){try{var r=e.address.split(/:/),s=r[2];if("bip122"!==r[0])return Promise.resolve(P({},e,{status:t.ProofStatus.FAILED}));try{var o=[c.SEGWIT,c.NATIVE].includes(function(e){if(e.match("^(bc1|tb1|ltc1).*"))return c.NATIVE;if(e.match("^[32M].*"))return c.SEGWIT;if(e.match("^[1nmL].*"))return c.LEGACY;if(e.match("^(D).*"))return c.DOGECOIN;throw new Error("INVALID ADDRESS: ".concat(e).concat(" is not a valid or a supported address"))}(s)),a=f.verify(e.attestation,s,e.proof,void 0,o);return Promise.resolve(P({},e,{status:a?t.ProofStatus.VERIFIED:t.ProofStatus.FAILED}))}catch(r){return Promise.resolve(P({},e,{status:t.ProofStatus.FAILED}))}}catch(e){return Promise.reject(e)}}(e))}return Promise.resolve(e)}catch(e){return Promise.reject(e)}}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import {\n DeclarationProof,\n ProofStatus,\n ProofTypes,\n ScreenshotProof,\n SignatureProof,\n type OwnershipProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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.PersonalSignEIP191:\n return verifyPersonalSignEIP191(proof as SignatureProof);\n case ProofTypes.PersonalSignEIP712:\n case ProofTypes.PersonalSignBIP137:\n case ProofTypes.PersonalSignXPUB:\n case ProofTypes.MicroTransfer:\n }\n return proof;\n}\n\nasync 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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\n });\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n"],"names":["proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","PersonalSignEIP191","_proof$address$split","address","split","verifyMessage","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191"],"mappings":"wkBAUiC,SAC/BA,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,EAAAA,WAAWC,gBACd,OAAAC,QAAAC,QAAAC,EAAA,CAAA,EACKN,EAAK,CACRO,OAASP,EAA2BQ,UAChCC,EAAAA,YAAYC,SACZD,EAAAA,YAAYE,UAEpB,KAAKT,EAAUA,WAACU,WACd,OAAAR,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAASP,EAA0Ba,IAC/BJ,EAAWA,YAACK,QACZL,EAAWA,YAACE,UAEpB,KAAKT,EAAAA,WAAWa,mBACd,OASiC,SACrCf,GAAqB,IAErB,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EAAA,GACrB,MAAW,WADFA,EAAA,GACYZ,QAAAC,QAAAC,EAAA,GAAYN,EAAK,CAAEO,OAAQE,EAAWA,YAACE,UAASP,QAAAC,QAE9Cc,EAAAA,cAAc,CACnCF,QAASA,EACTG,QAASpB,EAAMqB,YACfC,UAAWtB,EAAMA,SACjBuB,KAJIC,SAAAA,GAKN,OAAAlB,EAAA,CAAA,EACKN,EAAK,CACRO,OAAQiB,EAAWf,EAAWA,YAACC,SAAWD,EAAAA,YAAYE,QACtD,EACJ,CAAC,MAAAc,GAAArB,OAAAA,QAAAsB,OAAAD,EA3CD,CAAA,CAmBaE,CAAyB3B,GAMpC,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAyB,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/bitcoin.ts","../src/index.ts","../src/eth.ts","../src/solana.ts"],"sourcesContent":["import {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport * as bitcoinMessage from \"bitcoinjs-message\";\n\nexport enum 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 = bitcoinMessage.verify(\n proof.attestation,\n address,\n proof.proof,\n undefined,\n segwit,\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\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","import {\n type OwnershipProof,\n SignatureProof,\n DeclarationProof,\n ScreenshotProof,\n ProofTypes,\n ProofStatus,\n} from \"@notabene/javascript-sdk/src/types\";\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 {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { verifyMessage } from \"viem\";\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 = await verifyMessage({\n address: address as `0x${string}`,\n message: proof.attestation,\n signature: proof.proof as `0x${string}`,\n });\n return {\n ...proof,\n status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,\n };\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport nacl from \"tweetnacl\";\nimport {\n ProofStatus,\n SignatureProof,\n} from \"@notabene/javascript-sdk/src/types\";\nimport { decode as decodeBase64 } from \"@stablelib/base64\";\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 = new PublicKey(address);\n const messageBytes = new TextEncoder().encode(proof.attestation);\n const signatureBytes = decodeBase64(proof.proof);\n const verified = nacl.sign.detached.verify(\n messageBytes,\n signatureBytes,\n publicKey.toBytes(),\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":["DerivationMode","proof","type","ProofTypes","SelfDeclaration","Promise","resolve","_extends","status","confirmed","ProofStatus","VERIFIED","FAILED","Screenshot","url","FLAGGED","EIP191","_proof$address$split","address","split","verifyMessage","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191","ED25519","publicKey","PublicKey","messageBytes","TextEncoder","encode","signatureBytes","decodeBase64","nacl","sign","detached","verify","toBytes","error","verifySolanaSignature","EIP712","BIP137","segwit","SEGWIT","NATIVE","includes","match","LEGACY","DOGECOIN","Error","concat","getDerivationMode","bitcoinMessage","undefined","verifyBTCSignature"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { SignatureProof } from "@notabene/javascript-sdk/src/types";
2
+ export declare function verifySolanaSignature(proof: SignatureProof): Promise<SignatureProof>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notabene/verify-proof",
3
- "version": "1.0.0-preview.3",
3
+ "version": "1.0.0-preview.6",
4
4
  "description": "Verify ownership proofs",
5
5
  "source": "src/index.ts",
6
6
  "type": "module",
@@ -16,20 +16,31 @@
16
16
  ],
17
17
  "scripts": {
18
18
  "build:dev": "yarn build && yarn dev",
19
- "build:clean": "rimraf dist/ ts-out",
19
+ "build:clean": "rm -rf dist",
20
20
  "build": "microbundle",
21
21
  "lint": "eslint .",
22
22
  "test": "vitest"
23
23
  },
24
24
  "devDependencies": {
25
+ "@types/bitcoinjs-lib": "3.4.0",
26
+ "@types/node": "^22.9.0",
27
+ "bitcoinjs-lib": "^3.2.0",
28
+ "buffer": "^6.0.3",
29
+ "ecpair": "^3.0.0-rc.0",
25
30
  "eslint": "^9.9.0",
26
31
  "microbundle": "^0.15.1",
32
+ "tiny-secp256k1": "^2.2.3",
27
33
  "typescript": "^5.5.4",
28
34
  "vitest": "^2.0.5"
29
35
  },
30
36
  "dependencies": {
31
- "@notabene/javascript-sdk": "^2.0.0-next.5",
37
+ "@notabene/javascript-sdk": "^2.0.2",
38
+ "@solana/web3.js": "^1.95.4",
39
+ "@stablelib/base64": "^2.0.0",
40
+ "bigi": "^1.4.2",
32
41
  "bitcoinjs-message": "^2.2.0",
33
- "viem": "^2.19.8"
42
+ "ox": "^0.1.4",
43
+ "tweetnacl": "^1.0.3",
44
+ "viem": "^2.21.44"
34
45
  }
35
46
  }
package/src/bitcoin.ts ADDED
@@ -0,0 +1,61 @@
1
+ import {
2
+ ProofStatus,
3
+ SignatureProof,
4
+ } from "@notabene/javascript-sdk/src/types";
5
+ import * as bitcoinMessage from "bitcoinjs-message";
6
+
7
+ export enum DerivationMode {
8
+ LEGACY = "Legacy",
9
+ NATIVE = "Native SegWit",
10
+ SEGWIT = "SegWit",
11
+ P2SH_SEGWIT = "p2sh",
12
+ BCH = "Bitcoin Cash",
13
+ ETHEREUM = "Ethereum",
14
+ DOGECOIN = "Dogecoin",
15
+ UNKNOWN = "Unknown",
16
+ }
17
+
18
+ export async function verifyBTCSignature(
19
+ proof: SignatureProof,
20
+ ): Promise<SignatureProof> {
21
+ const [ns, _, address] = proof.address.split(/:/);
22
+ if (ns !== "bip122") return { ...proof, status: ProofStatus.FAILED };
23
+ try {
24
+ // const messageToBeSigned = message.replace(/\s+/g, " ").trim();
25
+ const segwit = [DerivationMode.SEGWIT, DerivationMode.NATIVE].includes(
26
+ getDerivationMode(address),
27
+ );
28
+ const verified = bitcoinMessage.verify(
29
+ proof.attestation,
30
+ address,
31
+ proof.proof,
32
+ undefined,
33
+ segwit,
34
+ );
35
+
36
+ return {
37
+ ...proof,
38
+ status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,
39
+ };
40
+ } catch (error) {
41
+ return { ...proof, status: ProofStatus.FAILED };
42
+ }
43
+ }
44
+
45
+ function getDerivationMode(address: string) {
46
+ if (address.match("^(bc1|tb1|ltc1).*")) {
47
+ return DerivationMode.NATIVE;
48
+ } else if (address.match("^[32M].*")) {
49
+ return DerivationMode.SEGWIT;
50
+ } else if (address.match("^[1nmL].*")) {
51
+ return DerivationMode.LEGACY;
52
+ } else if (address.match("^(D).*")) {
53
+ return DerivationMode.DOGECOIN;
54
+ } else {
55
+ throw new Error(
56
+ "INVALID ADDRESS: "
57
+ .concat(address)
58
+ .concat(" is not a valid or a supported address"),
59
+ );
60
+ }
61
+ }
package/src/eth.ts ADDED
@@ -0,0 +1,22 @@
1
+ import {
2
+ ProofStatus,
3
+ SignatureProof,
4
+ } from "@notabene/javascript-sdk/src/types";
5
+ import { verifyMessage } from "viem";
6
+
7
+ export async function verifyPersonalSignEIP191(
8
+ proof: SignatureProof,
9
+ ): Promise<SignatureProof> {
10
+ const [ns, _, address] = proof.address.split(/:/);
11
+ if (ns !== "eip155") return { ...proof, status: ProofStatus.FAILED };
12
+
13
+ const verified = await verifyMessage({
14
+ address: address as `0x${string}`,
15
+ message: proof.attestation,
16
+ signature: proof.proof as `0x${string}`,
17
+ });
18
+ return {
19
+ ...proof,
20
+ status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,
21
+ };
22
+ }
package/src/index.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  import {
2
+ type OwnershipProof,
3
+ SignatureProof,
2
4
  DeclarationProof,
3
- ProofStatus,
4
- ProofTypes,
5
5
  ScreenshotProof,
6
- SignatureProof,
7
- type OwnershipProof,
6
+ ProofTypes,
7
+ ProofStatus,
8
8
  } from "@notabene/javascript-sdk/src/types";
9
- import { verifyMessage } from "viem";
9
+ import { verifyBTCSignature } from "./bitcoin";
10
+ import { verifyPersonalSignEIP191 } from "./eth";
11
+ import { verifySolanaSignature } from "./solana";
10
12
 
11
13
  export async function verifyProof(
12
14
  proof: OwnershipProof,
@@ -26,29 +28,15 @@ export async function verifyProof(
26
28
  ? ProofStatus.FLAGGED
27
29
  : ProofStatus.FAILED,
28
30
  };
29
- case ProofTypes.PersonalSignEIP191:
31
+ case ProofTypes.EIP191:
30
32
  return verifyPersonalSignEIP191(proof as SignatureProof);
31
- case ProofTypes.PersonalSignEIP712:
32
- case ProofTypes.PersonalSignBIP137:
33
- case ProofTypes.PersonalSignXPUB:
33
+ case ProofTypes.ED25519:
34
+ return verifySolanaSignature(proof as SignatureProof);
35
+ case ProofTypes.EIP712:
36
+ case ProofTypes.BIP137:
37
+ return verifyBTCSignature(proof as SignatureProof);
38
+ case ProofTypes.BIP137_XPUB:
34
39
  case ProofTypes.MicroTransfer:
35
40
  }
36
41
  return proof;
37
42
  }
38
-
39
- async function verifyPersonalSignEIP191(
40
- proof: SignatureProof,
41
- ): Promise<SignatureProof> {
42
- const [ns, _, address] = proof.address.split(/:/);
43
- if (ns !== "eip155") return { ...proof, status: ProofStatus.FAILED };
44
-
45
- const verified = await verifyMessage({
46
- address: address as `0x${string}`,
47
- message: proof.attestation,
48
- signature: proof.proof as `0x${string}`,
49
- });
50
- return {
51
- ...proof,
52
- status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,
53
- };
54
- }
package/src/solana.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import nacl from "tweetnacl";
3
+ import {
4
+ ProofStatus,
5
+ SignatureProof,
6
+ } from "@notabene/javascript-sdk/src/types";
7
+ import { decode as decodeBase64 } from "@stablelib/base64";
8
+
9
+ export async function verifySolanaSignature(
10
+ proof: SignatureProof,
11
+ ): Promise<SignatureProof> {
12
+ const [ns, _, address] = proof.address.split(/:/);
13
+ if (ns !== "solana") return { ...proof, status: ProofStatus.FAILED };
14
+ try {
15
+ const publicKey = new PublicKey(address);
16
+ const messageBytes = new TextEncoder().encode(proof.attestation);
17
+ const signatureBytes = decodeBase64(proof.proof);
18
+ const verified = nacl.sign.detached.verify(
19
+ messageBytes,
20
+ signatureBytes,
21
+ publicKey.toBytes(),
22
+ );
23
+
24
+ return {
25
+ ...proof,
26
+ status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,
27
+ };
28
+ } catch (error) {
29
+ return { ...proof, status: ProofStatus.FAILED };
30
+ }
31
+ }
@@ -0,0 +1,95 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import * as bitcoin from "bitcoinjs-lib";
3
+ import * as bitcoinMessage from "bitcoinjs-message";
4
+ import { Buffer } from "node:buffer";
5
+
6
+ import { verifyBTCSignature } from "../bitcoin";
7
+ import {
8
+ type SignatureProof,
9
+ ProofStatus,
10
+ ProofTypes,
11
+ } from "@notabene/javascript-sdk/src/types";
12
+
13
+ function rng() {
14
+ return Buffer.from("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
15
+ }
16
+
17
+ function signMessage(
18
+ toAddress: (kp: bitcoin.ECPair) => string,
19
+ ): SignatureProof {
20
+ const keyPair = bitcoin.ECPair.makeRandom({ rng: rng });
21
+ const address = toAddress(keyPair);
22
+ const privateKey = keyPair.d.toBuffer(32);
23
+ var attestation = "This is an example of a signed message.";
24
+ var proof = bitcoinMessage
25
+ .sign(attestation, privateKey, keyPair.compressed)
26
+ .toString("base64");
27
+ // console.log("signMessage", { proof, address });
28
+ return {
29
+ type: ProofTypes.BIP137,
30
+ address: `bip122:000000000019d6689c085ae165831e93:${address}`,
31
+ did: `did:pkh:bip122:000000000019d6689c085ae165831e93:${address}`,
32
+ attestation,
33
+ proof,
34
+ status: ProofStatus.PENDING,
35
+ wallet_provider: "MetaMask",
36
+ };
37
+ }
38
+
39
+ function signP2PKHMessage(): SignatureProof {
40
+ return signMessage((kp) => kp.getAddress());
41
+ }
42
+
43
+ function signSegWitMessage(): SignatureProof {
44
+ return signMessage((kp) =>
45
+ bitcoin.address.toBech32(
46
+ bitcoin.crypto.hash160(kp.getPublicKeyBuffer()),
47
+ 0,
48
+ kp.network.bech32 || "bc",
49
+ ),
50
+ );
51
+ }
52
+
53
+ describe("verifyBTCSignature", () => {
54
+ it("handles native segwit addresses", async () => {
55
+ const proof: SignatureProof = signSegWitMessage();
56
+ const result = await verifyBTCSignature(proof);
57
+ expect(result.status).toBe(ProofStatus.VERIFIED);
58
+ });
59
+
60
+ it("verifies legacy bitcoin address signature", async () => {
61
+ const proof: SignatureProof = signP2PKHMessage();
62
+ const result = await verifyBTCSignature(proof);
63
+ expect(result.status).toBe(ProofStatus.VERIFIED);
64
+ });
65
+
66
+ it("fails for invalid bitcoin signature", async () => {
67
+ const proof: SignatureProof = {
68
+ type: ProofTypes.BIP137,
69
+ did: "did:pkh:bip122:000000000019d6689c085ae165831e93:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
70
+ address:
71
+ "bip122:000000000019d6689c085ae165831e93:1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
72
+ attestation: "test message",
73
+ proof: "invalid_signature",
74
+ status: ProofStatus.PENDING,
75
+ };
76
+
77
+ const result = await verifyBTCSignature(proof);
78
+ expect(result.status).toBe(ProofStatus.FAILED);
79
+ });
80
+
81
+ it("returns failed proof for non-BIP122 address", async () => {
82
+ const proof: SignatureProof = {
83
+ type: ProofTypes.EIP191,
84
+ status: ProofStatus.PENDING,
85
+ did: "did:example:123",
86
+ address: "eip155:1:0x1234567890123456789012345678901234567890",
87
+ proof: "0x1234567890",
88
+ attestation: "I own this address",
89
+ wallet_provider: "MetaMask",
90
+ };
91
+
92
+ const result = await verifyBTCSignature(proof);
93
+ expect(result.status).toBe(ProofStatus.FAILED);
94
+ });
95
+ });
@@ -0,0 +1,59 @@
1
+ import { describe, it, expect, vi } from "vitest";
2
+ import { verifyPersonalSignEIP191 } from "../eth";
3
+ import {
4
+ type SignatureProof,
5
+ ProofStatus,
6
+ ProofTypes,
7
+ } from "@notabene/javascript-sdk/src/types";
8
+
9
+ import { Hex, Address, PersonalMessage, Secp256k1, Signature } from "ox";
10
+
11
+ const privateKey = Secp256k1.randomPrivateKey();
12
+ const address = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey }));
13
+
14
+ function personalSign(): SignatureProof {
15
+ const attestation = "I agree";
16
+ const payload = PersonalMessage.getSignPayload(Hex.fromString(attestation));
17
+ const proof = Signature.toHex(Secp256k1.sign({ payload, privateKey }));
18
+ return {
19
+ type: ProofTypes.EIP191,
20
+ address: `eip155:1:${address}`,
21
+ did: `did:pkh:eip155:1:${address}`,
22
+ attestation,
23
+ proof,
24
+ status: ProofStatus.PENDING,
25
+ wallet_provider: "MetaMask",
26
+ };
27
+ }
28
+
29
+ describe("verifyPersonalSignEIP191", () => {
30
+ it("returns verified proof when valid message and address", async () => {
31
+ const proof = personalSign();
32
+ const result = await verifyPersonalSignEIP191(proof);
33
+
34
+ expect(result.status).toBe(ProofStatus.VERIFIED);
35
+ });
36
+
37
+ it("returns failed proof when invalid message or address", async () => {
38
+ const proof = { ...personalSign(), attestation: "evil text" };
39
+ const result = await verifyPersonalSignEIP191(proof);
40
+
41
+ expect(result.status).toBe(ProofStatus.FAILED);
42
+ });
43
+
44
+ it("returns failed proof for non-EIP155 address", async () => {
45
+ const proof: SignatureProof = {
46
+ type: ProofTypes.EIP191,
47
+ did: `did:pkh:bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6`,
48
+ address:
49
+ "bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6",
50
+ attestation: "test message",
51
+ proof: "0xabcd",
52
+ status: ProofStatus.PENDING,
53
+ };
54
+
55
+ const result = await verifyPersonalSignEIP191(proof);
56
+
57
+ expect(result.status).toBe(ProofStatus.FAILED);
58
+ });
59
+ });
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect, vi } from "vitest";
2
- import { verifyProof } from "./index";
2
+ import { verifyProof } from "../index";
3
3
  import {
4
4
  type DeclarationProof,
5
5
  type ScreenshotProof,
@@ -89,7 +89,7 @@ describe("verifyProof", () => {
89
89
 
90
90
  it("should verify a valid PersonalSignEIP191 proof", async () => {
91
91
  const proof: SignatureProof = {
92
- type: ProofTypes.PersonalSignEIP191,
92
+ type: ProofTypes.EIP191,
93
93
  status: ProofStatus.PENDING,
94
94
  did: "did:example:123",
95
95
  address: "eip155:1:0x1234567890123456789012345678901234567890",
@@ -113,7 +113,7 @@ describe("verifyProof", () => {
113
113
 
114
114
  it("should fail an invalid PersonalSignEIP191 proof", async () => {
115
115
  const proof: SignatureProof = {
116
- type: ProofTypes.PersonalSignEIP191,
116
+ type: ProofTypes.EIP191,
117
117
  status: ProofStatus.PENDING,
118
118
  did: "did:example:123",
119
119
  address: "eip155:1:0x1234567890123456789012345678901234567890",
@@ -137,7 +137,7 @@ describe("verifyProof", () => {
137
137
 
138
138
  it("should fail if not eip155 proof", async () => {
139
139
  const proof: SignatureProof = {
140
- type: ProofTypes.PersonalSignEIP191,
140
+ type: ProofTypes.EIP191,
141
141
  status: ProofStatus.PENDING,
142
142
  did: "did:example:123",
143
143
  address:
@@ -0,0 +1,61 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { Keypair } from "@solana/web3.js";
3
+ import nacl from "tweetnacl";
4
+ import {
5
+ ProofStatus,
6
+ ProofTypes,
7
+ SignatureProof,
8
+ } from "@notabene/javascript-sdk/src/types";
9
+ import { verifySolanaSignature } from "../solana";
10
+
11
+ describe("verifySolanaSignature", () => {
12
+ it("verifies valid Solana signature", async () => {
13
+ // Generate a test keypair
14
+ const keypair = Keypair.generate();
15
+ const message = "Test message";
16
+ const messageBytes = new TextEncoder().encode(message);
17
+ const signature = nacl.sign.detached(messageBytes, keypair.secretKey);
18
+ const proof: SignatureProof = {
19
+ type: ProofTypes.ED25519,
20
+ status: ProofStatus.PENDING,
21
+ did: `did:pkh:solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:${keypair.publicKey.toString()}`,
22
+ address: `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:${keypair.publicKey.toString()}`,
23
+ attestation: message,
24
+ proof: Buffer.from(signature).toString("base64"),
25
+ wallet_provider: "Phantom",
26
+ };
27
+ const result = await verifySolanaSignature(proof);
28
+ expect(result.status).toBe(ProofStatus.VERIFIED);
29
+ });
30
+
31
+ it("fails for invalid signature", async () => {
32
+ const keypair = Keypair.generate();
33
+ const proof: SignatureProof = {
34
+ type: ProofTypes.ED25519,
35
+ status: ProofStatus.PENDING,
36
+ did: `did:pkh:solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:${keypair.publicKey.toString()}`,
37
+ address: `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp:${keypair.publicKey.toString()}`,
38
+ attestation: "Test message",
39
+ proof: "invalid_signature",
40
+ wallet_provider: "Phantom",
41
+ };
42
+
43
+ const result = await verifySolanaSignature(proof);
44
+ expect(result.status).toBe(ProofStatus.FAILED);
45
+ });
46
+
47
+ it("fails for non-Solana address", async () => {
48
+ const proof: SignatureProof = {
49
+ type: ProofTypes.ED25519,
50
+ status: ProofStatus.PENDING,
51
+ did: "did:pkh:eth:0x1234567890123456789012345678901234567890",
52
+ address: "eth:1:0x1234567890123456789012345678901234567890",
53
+ attestation: "Test message",
54
+ proof: "some_signature",
55
+ wallet_provider: "MetaMask",
56
+ };
57
+
58
+ const result = await verifySolanaSignature(proof);
59
+ expect(result.status).toBe(ProofStatus.FAILED);
60
+ });
61
+ });