@notabene/verify-proof 1.0.0-preview.4 → 1.0.0-preview.6
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/README.md +4 -4
- package/dist/bitcoin.d.ts +12 -0
- package/dist/eth.d.ts +2 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -92
- 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/solana.d.ts +2 -0
- package/dist/tests/bitcoin.test.d.ts +1 -0
- package/dist/tests/eth.test.d.ts +1 -0
- package/dist/tests/index.test.d.ts +1 -0
- package/dist/tests/solana.test.d.ts +1 -0
- package/package.json +14 -2
- package/src/bitcoin.ts +61 -0
- package/src/eth.ts +22 -0
- package/src/index.ts +18 -130
- package/src/solana.ts +31 -0
- package/src/tests/bitcoin.test.ts +95 -0
- package/src/tests/eth.test.ts +59 -0
- package/src/{index.test.ts → tests/index.test.ts} +4 -4
- package/src/tests/solana.test.ts +61 -0
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.
|
40
|
-
- Personal Sign EIP712 (`ProofTypes.
|
41
|
-
- Personal Sign BIP137 (`ProofTypes.
|
42
|
-
- Personal Sign XPUB (`ProofTypes.
|
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
package/dist/index.cjs
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
var e,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
|
package/dist/index.cjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import {
|
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":"khBAMYA,mQAAZ,SAAYA,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,yBCHgC,SAC/BC,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,aAAWC,gBACd,OAAAC,QAAAC,QAAAC,KACKN,EAAK,CACRO,OAASP,EAA2BQ,UAChCC,EAAWA,YAACC,SACZD,cAAYE,UAEpB,KAAKT,EAAUA,WAACU,WACd,OAAAR,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,GACHO,OAASP,EAA0Ba,IAC/BJ,EAAWA,YAACK,QACZL,EAAAA,YAAYE,UAEpB,KAAKT,EAAAA,WAAWa,OACd,OAAAX,QAAAC,QCzBwC,SAC5CL,GAAqB,IAErB,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EAAA,GACrB,MAAW,WADFA,EAAA,GACYZ,QAAAC,QAAAC,EAAA,CAAA,EAAYN,EAAK,CAAEO,OAAQE,EAAWA,YAACE,UAASP,QAAAC,QAE9Cc,EAAAA,cAAc,CACnCF,QAASA,EACTG,QAASpB,EAAMqB,YACfC,UAAWtB,EAAMA,SACjBuB,cAJIC,GAKN,OAAAlB,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAAQiB,EAAWf,EAAAA,YAAYC,SAAWD,EAAAA,YAAYE,QACtD,EACJ,CAAC,MAAAc,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA,CDUYE,CAAyB3B,IAClC,KAAKE,EAAAA,WAAW0B,QACd,OAAAxB,QAAAC,QEzBgB,SACpBL,OAEA,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EACrB,GAAA,GAAW,WADFA,EAAA,GACY,OAAAZ,QAAAC,QAAAC,EAAYN,GAAAA,GAAOO,OAAQE,EAAWA,YAACE,UAC5D,IACE,IAAMkB,EAAY,IAAIC,EAAAA,UAAUb,GAC1Bc,GAAe,IAAIC,aAAcC,OAAOjC,EAAMqB,aAC9Ca,EAAiBC,EAAAA,OAAanC,EAAMA,OACpCwB,EAAWY,UAAKC,KAAKC,SAASC,OAClCR,EACAG,EACAL,EAAUW,WAGZ,OAAApC,QAAAC,QAAAC,KACKN,EAAK,CACRO,OAAQiB,EAAWf,EAAWA,YAACC,SAAWD,EAAAA,YAAYE,SAE1D,CAAE,MAAO8B,GACP,OAAArC,QAAAC,QAAAC,EAAA,CAAA,EAAYN,EAAOO,CAAAA,OAAQE,cAAYE,SACzC,CACF,CAAC,MAAAc,UAAArB,QAAAsB,OAAAD,EAAA,CAAA,CFGYiB,CAAsB1C,IAC/B,KAAKE,aAAWyC,OAChB,KAAKzC,EAAAA,WAAW0C,OACd,OAAAxC,QAAAC,QDnBkC,SACtCL,GAAqB,IAErB,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EACrB,GAAA,GAAW,WADFA,KACY,OAAAZ,QAAAC,QAAAC,EAAA,GAAYN,EAAOO,CAAAA,OAAQE,EAAAA,YAAYE,UAC5D,IAEE,IAAMkC,EAAS,CAAC9C,EAAe+C,OAAQ/C,EAAegD,QAAQC,SAoBlE,SAA2B/B,GACzB,GAAIA,EAAQgC,MAAM,qBAChB,OAAOlD,EAAegD,OACb9B,GAAAA,EAAQgC,MAAM,YACvB,OAAOlD,EAAe+C,OACjB,GAAI7B,EAAQgC,MAAM,aACvB,OAAOlD,EAAemD,OACjB,GAAIjC,EAAQgC,MAAM,UACvB,OAAOlD,EAAeoD,SAEtB,MAAU,IAAAC,MACR,oBACGC,OAAOpC,GACPoC,OAAO,0CAGhB,CAnCMC,CAAkBrC,IAEdO,EAAW+B,EAAehB,OAC9BvC,EAAMqB,YACNJ,EACAjB,EAAMA,WACNwD,EACAX,GAGF,OAAAzC,QAAAC,QAAAC,EAAA,CAAA,EACKN,EACHO,CAAAA,OAAQiB,EAAWf,EAAWA,YAACC,SAAWD,EAAAA,YAAYE,SAE1D,CAAE,MAAO8B,GACP,OAAArC,QAAAC,QAAAC,EAAA,CAAA,EAAYN,EAAOO,CAAAA,OAAQE,cAAYE,SACzC,CACF,CAAC,MAAAc,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA,CCNYgC,CAAmBzD,IAI9B,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAyB,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA"}
|
package/dist/index.d.ts
CHANGED
@@ -1,93 +1,2 @@
|
|
1
|
-
|
2
|
-
export type CAIP10 = `${CAIP2}:${string}`;
|
3
|
-
export type CAIP19 = `${CAIP2}/${string}:${string}`;
|
4
|
-
export type CAIP220 = string;
|
5
|
-
export type DTI = string;
|
6
|
-
export type NotabeneAsset = string;
|
7
|
-
/**
|
8
|
-
* The asset of a transaction either a Notabene asset, a CAIP-19 asset, or a DTI.
|
9
|
-
*
|
10
|
-
* @public
|
11
|
-
*/
|
12
|
-
export type TransactionAsset = NotabeneAsset | CAIP19 | DTI;
|
13
|
-
export type BlockchainAddress = string;
|
14
|
-
export type TravelAddress = string;
|
15
|
-
/**
|
16
|
-
* The destination of a transaction either a blockchain address, a CAIP-19 address, or a travel address.
|
17
|
-
* @public
|
18
|
-
*/
|
19
|
-
export type Destination = BlockchainAddress | CAIP10 | TravelAddress;
|
20
|
-
export type Source = BlockchainAddress | CAIP10;
|
21
|
-
export type URI = string;
|
22
|
-
export type DID = `did:${string}:${string}`;
|
23
|
-
/**
|
24
|
-
* Status of the proof
|
25
|
-
* @public
|
26
|
-
*/
|
27
|
-
export declare enum ProofStatus {
|
28
|
-
PENDING = "pending",// Verification is pending
|
29
|
-
FAILED = "rejected",// Rejected
|
30
|
-
FLAGGED = "flagged",// Flagged for manual review
|
31
|
-
VERIFIED = "verified"
|
32
|
-
}
|
33
|
-
/**
|
34
|
-
* The type of Proofs supported
|
35
|
-
* @public
|
36
|
-
**/
|
37
|
-
export declare enum ProofTypes {
|
38
|
-
SelfDeclaration = "self-declaration",
|
39
|
-
PersonalSignEIP191 = "eip-191",
|
40
|
-
PersonalSignEIP712 = "eip-712",
|
41
|
-
PersonalSignBIP137 = "bip-137",
|
42
|
-
PersonalSignXPUB = "xpub",
|
43
|
-
MicroTransfer = "microtransfer",
|
44
|
-
Screenshot = "screenshot"
|
45
|
-
}
|
46
|
-
/**
|
47
|
-
* Ownership Proof
|
48
|
-
* @public
|
49
|
-
*/
|
50
|
-
export interface OwnershipProof {
|
51
|
-
type: ProofTypes;
|
52
|
-
status: ProofStatus;
|
53
|
-
did: DID;
|
54
|
-
address: CAIP10;
|
55
|
-
}
|
56
|
-
/**
|
57
|
-
* Ownership Proof using Message Signature
|
58
|
-
* @public
|
59
|
-
*/
|
60
|
-
export interface SignatureProof extends OwnershipProof {
|
61
|
-
type: ProofTypes.PersonalSignEIP191 | ProofTypes.PersonalSignEIP712 | ProofTypes.PersonalSignBIP137 | ProofTypes.PersonalSignXPUB;
|
62
|
-
proof: string;
|
63
|
-
attestation: string;
|
64
|
-
wallet_provider: string;
|
65
|
-
}
|
66
|
-
/**
|
67
|
-
* Ownership Proof using Self Declaration
|
68
|
-
* @public
|
69
|
-
*/
|
70
|
-
export interface DeclarationProof extends OwnershipProof {
|
71
|
-
type: ProofTypes.SelfDeclaration;
|
72
|
-
attestation: string;
|
73
|
-
confirmed: boolean;
|
74
|
-
}
|
75
|
-
/**
|
76
|
-
* Ownership Proof using Micro Transfer
|
77
|
-
* @public
|
78
|
-
*/
|
79
|
-
export interface MicroTransferProof extends OwnershipProof {
|
80
|
-
type: ProofTypes.MicroTransfer;
|
81
|
-
txhash: string;
|
82
|
-
chain: CAIP2;
|
83
|
-
amount: number;
|
84
|
-
}
|
85
|
-
/**
|
86
|
-
* Ownership Proof using Screenshot
|
87
|
-
* @public
|
88
|
-
*/
|
89
|
-
export interface ScreenshotProof extends OwnershipProof {
|
90
|
-
type: ProofTypes.Screenshot;
|
91
|
-
url: string;
|
92
|
-
}
|
1
|
+
import { type OwnershipProof } from "@notabene/javascript-sdk/src/types";
|
93
2
|
export declare function verifyProof(proof: OwnershipProof): Promise<OwnershipProof>;
|
package/dist/index.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import{
|
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 {
|
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":"keAiBsB,IAXVA,GAAZ,SAAYA,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,KCTqB,ICMAC,EAAW,SAC/BC,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,EAAWC,gBACd,OAAAC,QAAAC,QAAAC,KACKN,EAAK,CACRO,OAASP,EAA2BQ,UAChCC,EAAYC,SACZD,EAAYE,UAEpB,KAAKT,EAAWU,WACd,OAAAR,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,GACHO,OAASP,EAA0Ba,IAC/BJ,EAAYK,QACZL,EAAYE,UAEpB,KAAKT,EAAWa,OACd,OAAAX,QAAAC,QDzBwC,SAC5CL,GAAqB,IAErB,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EAAA,GACrB,MAAW,WADFA,EAAA,GACYZ,QAAAC,QAAAC,EAAA,CAAA,EAAYN,EAAK,CAAEO,OAAQE,EAAYE,UAASP,QAAAC,QAE9Cc,EAAc,CACnCF,QAASA,EACTG,QAASpB,EAAMqB,YACfC,UAAWtB,EAAMA,SACjBuB,cAJIC,GAKN,OAAAlB,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAAQiB,EAAWf,EAAYC,SAAWD,EAAYE,QACtD,EACJ,CAAC,MAAAc,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA,CCUYE,CAAyB3B,IAClC,KAAKE,EAAW0B,QACd,OAAAxB,QAAAC,QCzBgB,SACpBL,OAEA,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EACrB,GAAA,GAAW,WADFA,EAAA,GACY,OAAAZ,QAAAC,QAAAC,EAAYN,GAAAA,GAAOO,OAAQE,EAAYE,UAC5D,IACE,IAAMkB,EAAY,IAAIC,EAAUb,GAC1Bc,GAAe,IAAIC,aAAcC,OAAOjC,EAAMqB,aAC9Ca,EAAiBC,EAAanC,EAAMA,OACpCwB,EAAWY,EAAKC,KAAKC,SAASC,OAClCR,EACAG,EACAL,EAAUW,WAGZ,OAAApC,QAAAC,QAAAC,KACKN,EAAK,CACRO,OAAQiB,EAAWf,EAAYC,SAAWD,EAAYE,SAE1D,CAAE,MAAO8B,GACP,OAAArC,QAAAC,QAAAC,EAAA,CAAA,EAAYN,EAAOO,CAAAA,OAAQE,EAAYE,SACzC,CACF,CAAC,MAAAc,UAAArB,QAAAsB,OAAAD,EAAA,CAAA,CDGYiB,CAAsB1C,IAC/B,KAAKE,EAAWyC,OAChB,KAAKzC,EAAW0C,OACd,OAAAxC,QAAAC,QFnBkC,SACtCL,GAAqB,IAErB,IAAAgB,EAAyBhB,EAAMiB,QAAQC,MAAM,KAA/BD,EAAOD,EACrB,GAAA,GAAW,WADFA,KACY,OAAAZ,QAAAC,QAAAC,EAAA,GAAYN,EAAOO,CAAAA,OAAQE,EAAYE,UAC5D,IAEE,IAAMkC,EAAS,CAAC/C,EAAegD,OAAQhD,EAAeiD,QAAQC,SAoBlE,SAA2B/B,GACzB,GAAIA,EAAQgC,MAAM,qBAChB,OAAOnD,EAAeiD,OACb9B,GAAAA,EAAQgC,MAAM,YACvB,OAAOnD,EAAegD,OACjB,GAAI7B,EAAQgC,MAAM,aACvB,OAAOnD,EAAeoD,OACjB,GAAIjC,EAAQgC,MAAM,UACvB,OAAOnD,EAAeqD,SAEtB,MAAU,IAAAC,MACR,oBACGC,OAAOpC,GACPoC,OAAO,0CAGhB,CAnCMC,CAAkBrC,IAEdO,EAAW+B,EAAehB,OAC9BvC,EAAMqB,YACNJ,EACAjB,EAAMA,WACNwD,EACAX,GAGF,OAAAzC,QAAAC,QAAAC,EAAA,CAAA,EACKN,EACHO,CAAAA,OAAQiB,EAAWf,EAAYC,SAAWD,EAAYE,SAE1D,CAAE,MAAO8B,GACP,OAAArC,QAAAC,QAAAC,EAAA,CAAA,EAAYN,EAAOO,CAAAA,OAAQE,EAAYE,SACzC,CACF,CAAC,MAAAc,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA,CENYgC,CAAmBzD,IAI9B,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAyB,GAAA,OAAArB,QAAAsB,OAAAD,EAAA,CAAA"}
|
package/dist/index.modern.js
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
import{verifyMessage as e}from"viem";function
|
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
|
package/dist/index.modern.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.modern.js","sources":["../src/index.ts"],"sourcesContent":["import {
|
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,
|
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
|
package/dist/index.umd.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import {
|
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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"}
|
package/dist/solana.d.ts
ADDED
@@ -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
|
+
"version": "1.0.0-preview.6",
|
4
4
|
"description": "Verify ownership proofs",
|
5
5
|
"source": "src/index.ts",
|
6
6
|
"type": "module",
|
@@ -22,13 +22,25 @@
|
|
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": {
|
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",
|
31
41
|
"bitcoinjs-message": "^2.2.0",
|
32
|
-
"
|
42
|
+
"ox": "^0.1.4",
|
43
|
+
"tweetnacl": "^1.0.3",
|
44
|
+
"viem": "^2.21.44"
|
33
45
|
}
|
34
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,112 +1,14 @@
|
|
1
|
-
import {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
* The asset of a transaction either a Notabene asset, a CAIP-19 asset, or a DTI.
|
13
|
-
*
|
14
|
-
* @public
|
15
|
-
*/
|
16
|
-
|
17
|
-
export type TransactionAsset = NotabeneAsset | CAIP19 | DTI;
|
18
|
-
|
19
|
-
export type BlockchainAddress = string;
|
20
|
-
export type TravelAddress = string;
|
21
|
-
|
22
|
-
/**
|
23
|
-
* The destination of a transaction either a blockchain address, a CAIP-19 address, or a travel address.
|
24
|
-
* @public
|
25
|
-
*/
|
26
|
-
export type Destination = BlockchainAddress | CAIP10 | TravelAddress;
|
27
|
-
export type Source = BlockchainAddress | CAIP10;
|
28
|
-
export type URI = string;
|
29
|
-
export type DID = `did:${string}:${string}`;
|
30
|
-
|
31
|
-
/**
|
32
|
-
* Status of the proof
|
33
|
-
* @public
|
34
|
-
*/
|
35
|
-
export enum ProofStatus {
|
36
|
-
PENDING = "pending", // Verification is pending
|
37
|
-
FAILED = "rejected", // Rejected
|
38
|
-
FLAGGED = "flagged", // Flagged for manual review
|
39
|
-
VERIFIED = "verified", // Verified
|
40
|
-
}
|
41
|
-
|
42
|
-
/**
|
43
|
-
* The type of Proofs supported
|
44
|
-
* @public
|
45
|
-
**/
|
46
|
-
export enum ProofTypes {
|
47
|
-
SelfDeclaration = "self-declaration",
|
48
|
-
PersonalSignEIP191 = "eip-191",
|
49
|
-
PersonalSignEIP712 = "eip-712",
|
50
|
-
PersonalSignBIP137 = "bip-137",
|
51
|
-
PersonalSignXPUB = "xpub",
|
52
|
-
MicroTransfer = "microtransfer",
|
53
|
-
Screenshot = "screenshot",
|
54
|
-
}
|
55
|
-
/**
|
56
|
-
* Ownership Proof
|
57
|
-
* @public
|
58
|
-
*/
|
59
|
-
export interface OwnershipProof {
|
60
|
-
type: ProofTypes;
|
61
|
-
status: ProofStatus;
|
62
|
-
did: DID;
|
63
|
-
address: CAIP10;
|
64
|
-
}
|
65
|
-
|
66
|
-
/**
|
67
|
-
* Ownership Proof using Message Signature
|
68
|
-
* @public
|
69
|
-
*/
|
70
|
-
export interface SignatureProof extends OwnershipProof {
|
71
|
-
type:
|
72
|
-
| ProofTypes.PersonalSignEIP191
|
73
|
-
| ProofTypes.PersonalSignEIP712
|
74
|
-
| ProofTypes.PersonalSignBIP137
|
75
|
-
| ProofTypes.PersonalSignXPUB;
|
76
|
-
proof: string;
|
77
|
-
attestation: string;
|
78
|
-
wallet_provider: string;
|
79
|
-
}
|
80
|
-
|
81
|
-
/**
|
82
|
-
* Ownership Proof using Self Declaration
|
83
|
-
* @public
|
84
|
-
*/
|
85
|
-
export interface DeclarationProof extends OwnershipProof {
|
86
|
-
type: ProofTypes.SelfDeclaration;
|
87
|
-
attestation: string;
|
88
|
-
confirmed: boolean;
|
89
|
-
}
|
90
|
-
|
91
|
-
/**
|
92
|
-
* Ownership Proof using Micro Transfer
|
93
|
-
* @public
|
94
|
-
*/
|
95
|
-
export interface MicroTransferProof extends OwnershipProof {
|
96
|
-
type: ProofTypes.MicroTransfer;
|
97
|
-
txhash: string;
|
98
|
-
chain: CAIP2;
|
99
|
-
amount: number;
|
100
|
-
}
|
101
|
-
|
102
|
-
/**
|
103
|
-
* Ownership Proof using Screenshot
|
104
|
-
* @public
|
105
|
-
*/
|
106
|
-
export interface ScreenshotProof extends OwnershipProof {
|
107
|
-
type: ProofTypes.Screenshot;
|
108
|
-
url: string;
|
109
|
-
}
|
1
|
+
import {
|
2
|
+
type OwnershipProof,
|
3
|
+
SignatureProof,
|
4
|
+
DeclarationProof,
|
5
|
+
ScreenshotProof,
|
6
|
+
ProofTypes,
|
7
|
+
ProofStatus,
|
8
|
+
} from "@notabene/javascript-sdk/src/types";
|
9
|
+
import { verifyBTCSignature } from "./bitcoin";
|
10
|
+
import { verifyPersonalSignEIP191 } from "./eth";
|
11
|
+
import { verifySolanaSignature } from "./solana";
|
110
12
|
|
111
13
|
export async function verifyProof(
|
112
14
|
proof: OwnershipProof,
|
@@ -126,29 +28,15 @@ export async function verifyProof(
|
|
126
28
|
? ProofStatus.FLAGGED
|
127
29
|
: ProofStatus.FAILED,
|
128
30
|
};
|
129
|
-
case ProofTypes.
|
31
|
+
case ProofTypes.EIP191:
|
130
32
|
return verifyPersonalSignEIP191(proof as SignatureProof);
|
131
|
-
case ProofTypes.
|
132
|
-
|
133
|
-
case ProofTypes.
|
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:
|
134
39
|
case ProofTypes.MicroTransfer:
|
135
40
|
}
|
136
41
|
return proof;
|
137
42
|
}
|
138
|
-
|
139
|
-
async function verifyPersonalSignEIP191(
|
140
|
-
proof: SignatureProof,
|
141
|
-
): Promise<SignatureProof> {
|
142
|
-
const [ns, _, address] = proof.address.split(/:/);
|
143
|
-
if (ns !== "eip155") return { ...proof, status: ProofStatus.FAILED };
|
144
|
-
|
145
|
-
const verified = await verifyMessage({
|
146
|
-
address: address as `0x${string}`,
|
147
|
-
message: proof.attestation,
|
148
|
-
signature: proof.proof as `0x${string}`,
|
149
|
-
});
|
150
|
-
return {
|
151
|
-
...proof,
|
152
|
-
status: verified ? ProofStatus.VERIFIED : ProofStatus.FAILED,
|
153
|
-
};
|
154
|
-
}
|
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 "
|
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.
|
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.
|
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.
|
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
|
+
});
|