@notabene/verify-proof 1.0.0-preview.2
Sign up to get free protection for your applications and to get access to all the features.
- package/.node-version +1 -0
- package/README.md +72 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/index.test.d.ts +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +29 -0
- package/src/index.test.ts +154 -0
- package/src/index.ts +54 -0
- package/tsconfig.json +32 -0
package/.node-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
v20.17.0
|
package/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# @notabene/verify-proof
|
2
|
+
|
3
|
+
This package provides functionality to verify ownership proofs for the Notabene SDK.
|
4
|
+
|
5
|
+
## Description
|
6
|
+
|
7
|
+
The `@notabene/verify-proof` package is designed to work with the Notabene SDK, offering methods to verify various types of ownership proofs used in blockchain transactions and identity verification.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
```bash
|
12
|
+
npm install @notabene/verify-proof
|
13
|
+
```
|
14
|
+
|
15
|
+
or
|
16
|
+
|
17
|
+
```bash
|
18
|
+
yarn add @notabene/verify-proof
|
19
|
+
```
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Here's a basic example of how to use the `verifyProof` function:
|
24
|
+
|
25
|
+
```typescript
|
26
|
+
import { verifyProof } from '@notabene/verify-proof';
|
27
|
+
import { OwnershipProof } from '@notabene/javascript-sdk';
|
28
|
+
|
29
|
+
async function checkProof(proof: OwnershipProof) {
|
30
|
+
const verifiedProof = await verifyProof(proof);
|
31
|
+
console.log(verifiedProof.status);
|
32
|
+
}
|
33
|
+
```
|
34
|
+
|
35
|
+
## Supported Proof Types
|
36
|
+
|
37
|
+
- Checkbox Confirmation (`ProofTypes.CheckboxConfirmation`)
|
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`)
|
43
|
+
- Micro Transfer (`ProofTypes.MicroTransfer`)
|
44
|
+
|
45
|
+
## Development
|
46
|
+
|
47
|
+
To set up the development environment:
|
48
|
+
|
49
|
+
1. Clone the repository
|
50
|
+
2. Install dependencies: `yarn install`
|
51
|
+
3. Run tests: `yarn test`
|
52
|
+
|
53
|
+
## Scripts
|
54
|
+
|
55
|
+
- `yarn dev`: Start development server
|
56
|
+
- `yarn build`: Build the project
|
57
|
+
- `yarn lint`: Run linter
|
58
|
+
- `yarn test`: Run tests
|
59
|
+
|
60
|
+
## Dependencies
|
61
|
+
|
62
|
+
- `@notabene/javascript-sdk`: Notabene JavaScript SDK
|
63
|
+
- `viem`: Ethereum utility library
|
64
|
+
- `bitcoinjs-message`: Bitcoin message signing and verification
|
65
|
+
|
66
|
+
## License
|
67
|
+
|
68
|
+
This project is private and not publicly licensed.
|
69
|
+
|
70
|
+
## Author
|
71
|
+
|
72
|
+
Pelle Braendgaard
|
package/dist/index.cjs
ADDED
@@ -0,0 +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{return Promise.resolve(e.verifyMessage({address:s.address,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)}};
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
@@ -0,0 +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 verified = await verifyMessage({\n address: proof.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","verifyMessage","address","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191"],"mappings":"kTAUsB,SACpBA,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,EAAUA,WAACC,gBACd,OAAAC,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,GACHO,OAASP,EAA2BQ,UAChCC,cAAYC,SACZD,EAAAA,YAAYE,UAEpB,KAAKT,EAAUA,WAACU,WACd,OAAAR,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAASP,EAA0Ba,IAC/BJ,EAAAA,YAAYK,QACZL,EAAWA,YAACE,UAEpB,KAAKT,EAAAA,WAAWa,mBACd,gBAUJf,GAAqB,IAAAI,OAAAA,QAAAC,QAEEW,EAAAA,cAAc,CACnCC,QAASjB,EAAMiB,QACfC,QAASlB,EAAMmB,YACfC,UAAWpB,EAAMA,SACjBqB,KAAA,SAJIC,GAKN,OAAAhB,EACKN,CAAAA,EAAAA,GACHO,OAAQe,EAAWb,EAAAA,YAAYC,SAAWD,EAAWA,YAACE,QACtD,EACJ,CAAC,MAAAY,GAAA,OAAAnB,QAAAoB,OAAAD,IArBYE,CAAyBzB,GAMpC,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAuB,UAAAnB,QAAAoB,OAAAD,EAAA,CAAA"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
@@ -0,0 +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{return Promise.resolve(t({address:r.address,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};
|
2
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +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 verified = await verifyMessage({\n address: proof.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","verifyMessage","address","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191"],"mappings":"8UAQqC,IAEfA,EAAA,SACpBC,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,EAAWC,gBACd,OAAAC,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,GACHO,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,gBAUJf,GAAqB,IAAAI,OAAAA,QAAAC,QAEEW,EAAc,CACnCC,QAASjB,EAAMiB,QACfC,QAASlB,EAAMmB,YACfC,UAAWpB,EAAMA,SACjBqB,KAAA,SAJIC,GAKN,OAAAhB,EACKN,CAAAA,EAAAA,GACHO,OAAQe,EAAWb,EAAYC,SAAWD,EAAYE,QACtD,EACJ,CAAC,MAAAY,GAAA,OAAAnB,QAAAoB,OAAAD,IArBYE,CAAyBzB,GAMpC,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAuB,UAAAnB,QAAAoB,OAAAD,EAAA,CAAA"}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
import{ProofTypes as r,ProofStatus as t}from"@notabene/javascript-sdk/src/types";import{verifyMessage as n}from"viem";function e(){return e=Object.assign?Object.assign.bind():function(r){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var e in n)({}).hasOwnProperty.call(n,e)&&(r[e]=n[e])}return r},e.apply(null,arguments)}async function s(s){switch(s.type){case r.SelfDeclaration:return e({},s,{status:s.confirmed?t.VERIFIED:t.FAILED});case r.Screenshot:return e({},s,{status:s.url?t.FLAGGED:t.FAILED});case r.PersonalSignEIP191:return async function(r){return e({},r,{status:await n({address:r.address,message:r.attestation,signature:r.proof})?t.VERIFIED:t.FAILED})}(s)}return s}export{s as verifyProof};
|
2
|
+
//# sourceMappingURL=index.modern.js.map
|
@@ -0,0 +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 verified = await verifyMessage({\n address: proof.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","verifyMessage","address","message","attestation","signature","verifyPersonalSignEIP191"],"mappings":"8UAUOA,eAAeC,EACpBC,GAEA,OAAQA,EAAMC,MACZ,KAAKC,EAAWC,gBACd,OAAAC,KACKJ,EAAK,CACRK,OAASL,EAA2BM,UAChCC,EAAYC,SACZD,EAAYE,SAEpB,KAAKP,EAAWQ,WACd,OAAAN,EACKJ,GAAAA,GACHK,OAASL,EAA0BW,IAC/BJ,EAAYK,QACZL,EAAYE,SAEpB,KAAKP,EAAWW,mBACd,OASNf,eACEE,GAOA,OAAAI,EACKJ,CAAAA,EAAAA,GACHK,aAPqBS,EAAc,CACnCC,QAASf,EAAMe,QACfC,QAAShB,EAAMiB,YACfC,UAAWlB,EAAMA,QAIEO,EAAYC,SAAWD,EAAYE,QAE1D,CArBaU,CAAyBnB,GAMpC,OAAOA,CACT"}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +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 o(){return o=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},o.apply(null,arguments)}e.verifyProof=function(e){try{switch(e.type){case r.ProofTypes.SelfDeclaration:return Promise.resolve(o({},e,{status:e.confirmed?r.ProofStatus.VERIFIED:r.ProofStatus.FAILED}));case r.ProofTypes.Screenshot:return Promise.resolve(o({},e,{status:e.url?r.ProofStatus.FLAGGED:r.ProofStatus.FAILED}));case r.ProofTypes.PersonalSignEIP191:return function(e){try{return Promise.resolve(t.verifyMessage({address:e.address,message:e.attestation,signature:e.proof})).then(function(t){return o({},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)}}});
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
@@ -0,0 +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 verified = await verifyMessage({\n address: proof.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","verifyMessage","address","message","attestation","signature","then","verified","e","reject","verifyPersonalSignEIP191"],"mappings":"wkBAUsB,SACpBA,GAAqB,IAErB,OAAQA,EAAMC,MACZ,KAAKC,EAAUA,WAACC,gBACd,OAAAC,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,GACHO,OAASP,EAA2BQ,UAChCC,cAAYC,SACZD,EAAAA,YAAYE,UAEpB,KAAKT,EAAUA,WAACU,WACd,OAAAR,QAAAC,QAAAC,EACKN,CAAAA,EAAAA,EACHO,CAAAA,OAASP,EAA0Ba,IAC/BJ,EAAAA,YAAYK,QACZL,EAAWA,YAACE,UAEpB,KAAKT,EAAAA,WAAWa,mBACd,gBAUJf,GAAqB,IAAAI,OAAAA,QAAAC,QAEEW,EAAAA,cAAc,CACnCC,QAASjB,EAAMiB,QACfC,QAASlB,EAAMmB,YACfC,UAAWpB,EAAMA,SACjBqB,KAAA,SAJIC,GAKN,OAAAhB,EACKN,CAAAA,EAAAA,GACHO,OAAQe,EAAWb,EAAAA,YAAYC,SAAWD,EAAWA,YAACE,QACtD,EACJ,CAAC,MAAAY,GAAA,OAAAnB,QAAAoB,OAAAD,IArBYE,CAAyBzB,GAMpC,OAAAI,QAAAC,QAAOL,EACT,CAAC,MAAAuB,UAAAnB,QAAAoB,OAAAD,EAAA,CAAA"}
|
package/package.json
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
{
|
2
|
+
"name": "@notabene/verify-proof",
|
3
|
+
"version": "1.0.0-preview.2",
|
4
|
+
"description": "Verify ownership proofs",
|
5
|
+
"source": "src/index.ts",
|
6
|
+
"type": "module",
|
7
|
+
"module": "dist/index.js",
|
8
|
+
"main": "dist/index.cjs",
|
9
|
+
"author": "Pelle Braendgaard",
|
10
|
+
"license": "Apache-2.0",
|
11
|
+
"scripts": {
|
12
|
+
"build:dev": "yarn build && yarn dev",
|
13
|
+
"build:clean": "rimraf dist/ ts-out",
|
14
|
+
"build": "microbundle",
|
15
|
+
"lint": "eslint .",
|
16
|
+
"test": "vitest"
|
17
|
+
},
|
18
|
+
"devDependencies": {
|
19
|
+
"eslint": "^9.9.0",
|
20
|
+
"microbundle": "^0.15.1",
|
21
|
+
"typescript": "^5.5.4",
|
22
|
+
"vitest": "^2.0.5"
|
23
|
+
},
|
24
|
+
"dependencies": {
|
25
|
+
"@notabene/javascript-sdk": "^2.0.0-next.4",
|
26
|
+
"bitcoinjs-message": "^2.2.0",
|
27
|
+
"viem": "^2.19.8"
|
28
|
+
}
|
29
|
+
}
|
@@ -0,0 +1,154 @@
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
2
|
+
import { verifyProof } from "./index";
|
3
|
+
import {
|
4
|
+
type DeclarationProof,
|
5
|
+
type ScreenshotProof,
|
6
|
+
type SignatureProof,
|
7
|
+
ProofStatus,
|
8
|
+
ProofTypes,
|
9
|
+
} from "@notabene/javascript-sdk/src/types";
|
10
|
+
import { verifyMessage } from "viem";
|
11
|
+
|
12
|
+
// Mock viem's verifyMessage function
|
13
|
+
vi.mock("viem", () => ({
|
14
|
+
verifyMessage: vi.fn(),
|
15
|
+
}));
|
16
|
+
|
17
|
+
describe("verifyProof", () => {
|
18
|
+
it("should verify a confirmed checkbox proof", async () => {
|
19
|
+
const proof: DeclarationProof = {
|
20
|
+
type: ProofTypes.SelfDeclaration,
|
21
|
+
status: ProofStatus.PENDING,
|
22
|
+
attestation: "I solemly swear",
|
23
|
+
did: "did:example:123",
|
24
|
+
address: "eip155:1:0x1234567890123456789012345678901234567890",
|
25
|
+
confirmed: true,
|
26
|
+
};
|
27
|
+
|
28
|
+
const result = await verifyProof(proof);
|
29
|
+
|
30
|
+
expect(result.status).toBe(ProofStatus.VERIFIED);
|
31
|
+
});
|
32
|
+
|
33
|
+
it("should fail an unconfirmed checkbox proof", async () => {
|
34
|
+
const proof: DeclarationProof = {
|
35
|
+
type: ProofTypes.SelfDeclaration,
|
36
|
+
status: ProofStatus.PENDING,
|
37
|
+
attestation: "I solemly swear",
|
38
|
+
did: "did:example:123",
|
39
|
+
address: "eip155:1:0x1234567890123456789012345678901234567890",
|
40
|
+
confirmed: false,
|
41
|
+
};
|
42
|
+
|
43
|
+
const result = await verifyProof(proof);
|
44
|
+
|
45
|
+
expect(result.status).toBe(ProofStatus.FAILED);
|
46
|
+
});
|
47
|
+
|
48
|
+
it("should flag a screenshot proof with a URL", async () => {
|
49
|
+
const proof: ScreenshotProof = {
|
50
|
+
type: ProofTypes.Screenshot,
|
51
|
+
status: ProofStatus.PENDING,
|
52
|
+
did: "did:example:123",
|
53
|
+
address: "eip155:1:0x1234567890123456789012345678901234567890",
|
54
|
+
url: "https://example.com/screenshot.png",
|
55
|
+
};
|
56
|
+
|
57
|
+
const result = await verifyProof(proof);
|
58
|
+
|
59
|
+
expect(result.status).toBe(ProofStatus.FLAGGED);
|
60
|
+
});
|
61
|
+
|
62
|
+
it("should fail a screenshot proof without a URL", async () => {
|
63
|
+
const proof: ScreenshotProof = {
|
64
|
+
type: ProofTypes.Screenshot,
|
65
|
+
status: ProofStatus.PENDING,
|
66
|
+
did: "did:example:123",
|
67
|
+
address: "eip155:1:0x1234567890123456789012345678901234567890",
|
68
|
+
url: "",
|
69
|
+
};
|
70
|
+
|
71
|
+
const result = await verifyProof(proof);
|
72
|
+
|
73
|
+
expect(result.status).toBe(ProofStatus.FAILED);
|
74
|
+
});
|
75
|
+
|
76
|
+
it("should return the original proof for unknown proof types", async () => {
|
77
|
+
const proof = {
|
78
|
+
type: "UnknownProofType",
|
79
|
+
status: ProofStatus.PENDING,
|
80
|
+
did: "did:example:123",
|
81
|
+
address: "eip155:1:0x1234567890123456789012345678901234567890",
|
82
|
+
};
|
83
|
+
|
84
|
+
// @ts-ignore
|
85
|
+
const result = await verifyProof(proof);
|
86
|
+
|
87
|
+
expect(result).toEqual(proof);
|
88
|
+
});
|
89
|
+
|
90
|
+
it("should verify a valid PersonalSignEIP191 proof", async () => {
|
91
|
+
const proof: SignatureProof = {
|
92
|
+
type: ProofTypes.PersonalSignEIP191,
|
93
|
+
status: ProofStatus.PENDING,
|
94
|
+
did: "did:example:123",
|
95
|
+
address: "eip155:1:0x1234567890123456789012345678901234567890",
|
96
|
+
proof: "0x1234567890",
|
97
|
+
attestation: "I own this address",
|
98
|
+
wallet_provider: "MetaMask",
|
99
|
+
};
|
100
|
+
|
101
|
+
// Mock successful verification
|
102
|
+
(verifyMessage as jest.Mock).mockResolvedValue(true);
|
103
|
+
|
104
|
+
const result = await verifyProof(proof);
|
105
|
+
|
106
|
+
expect(result.status).toBe(ProofStatus.VERIFIED);
|
107
|
+
expect(verifyMessage).toHaveBeenCalledWith({
|
108
|
+
address: "0x1234567890123456789012345678901234567890",
|
109
|
+
message: proof.attestation,
|
110
|
+
signature: proof.proof,
|
111
|
+
});
|
112
|
+
});
|
113
|
+
|
114
|
+
it("should fail an invalid PersonalSignEIP191 proof", async () => {
|
115
|
+
const proof: SignatureProof = {
|
116
|
+
type: ProofTypes.PersonalSignEIP191,
|
117
|
+
status: ProofStatus.PENDING,
|
118
|
+
did: "did:example:123",
|
119
|
+
address: "eip155:1:0x1234567890123456789012345678901234567890",
|
120
|
+
proof: "0x1234567890",
|
121
|
+
attestation: "I own this address",
|
122
|
+
wallet_provider: "MetaMask",
|
123
|
+
};
|
124
|
+
|
125
|
+
// Mock failed verification
|
126
|
+
(verifyMessage as jest.Mock).mockResolvedValue(false);
|
127
|
+
|
128
|
+
const result = await verifyProof(proof);
|
129
|
+
|
130
|
+
expect(result.status).toBe(ProofStatus.FAILED);
|
131
|
+
expect(verifyMessage).toHaveBeenCalledWith({
|
132
|
+
address: "0x1234567890123456789012345678901234567890",
|
133
|
+
message: proof.attestation,
|
134
|
+
signature: proof.proof,
|
135
|
+
});
|
136
|
+
});
|
137
|
+
|
138
|
+
it("should fail if not eip155 proof", async () => {
|
139
|
+
const proof: SignatureProof = {
|
140
|
+
type: ProofTypes.PersonalSignEIP191,
|
141
|
+
status: ProofStatus.PENDING,
|
142
|
+
did: "did:example:123",
|
143
|
+
address:
|
144
|
+
"bip122:000000000019d6689c085ae165831e93:128Lkh3S7CkDTBZ8W7BbpsN3YYizJMp8p6",
|
145
|
+
proof: "0x1234567890",
|
146
|
+
attestation: "I own this address",
|
147
|
+
wallet_provider: "MetaMask",
|
148
|
+
};
|
149
|
+
|
150
|
+
const result = await verifyProof(proof);
|
151
|
+
|
152
|
+
expect(result.status).toBe(ProofStatus.FAILED);
|
153
|
+
});
|
154
|
+
});
|
package/src/index.ts
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
import {
|
2
|
+
DeclarationProof,
|
3
|
+
ProofStatus,
|
4
|
+
ProofTypes,
|
5
|
+
ScreenshotProof,
|
6
|
+
SignatureProof,
|
7
|
+
type OwnershipProof,
|
8
|
+
} from "@notabene/javascript-sdk/src/types";
|
9
|
+
import { verifyMessage } from "viem";
|
10
|
+
|
11
|
+
export async function verifyProof(
|
12
|
+
proof: OwnershipProof,
|
13
|
+
): Promise<OwnershipProof> {
|
14
|
+
switch (proof.type) {
|
15
|
+
case ProofTypes.SelfDeclaration:
|
16
|
+
return {
|
17
|
+
...proof,
|
18
|
+
status: (proof as DeclarationProof).confirmed
|
19
|
+
? ProofStatus.VERIFIED
|
20
|
+
: ProofStatus.FAILED,
|
21
|
+
};
|
22
|
+
case ProofTypes.Screenshot:
|
23
|
+
return {
|
24
|
+
...proof,
|
25
|
+
status: (proof as ScreenshotProof).url
|
26
|
+
? ProofStatus.FLAGGED
|
27
|
+
: ProofStatus.FAILED,
|
28
|
+
};
|
29
|
+
case ProofTypes.PersonalSignEIP191:
|
30
|
+
return verifyPersonalSignEIP191(proof as SignatureProof);
|
31
|
+
case ProofTypes.PersonalSignEIP712:
|
32
|
+
case ProofTypes.PersonalSignBIP137:
|
33
|
+
case ProofTypes.PersonalSignXPUB:
|
34
|
+
case ProofTypes.MicroTransfer:
|
35
|
+
}
|
36
|
+
return proof;
|
37
|
+
}
|
38
|
+
|
39
|
+
async function verifyPersonalSignEIP191(
|
40
|
+
proof: SignatureProof,
|
41
|
+
): Promise<SignatureProof> {
|
42
|
+
const [ns, chainId, 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/tsconfig.json
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"target": "ES2020",
|
4
|
+
"useDefineForClassFields": true,
|
5
|
+
"module": "ESNext",
|
6
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
7
|
+
"skipLibCheck": true,
|
8
|
+
|
9
|
+
/* Bundler mode */
|
10
|
+
"moduleResolution": "bundler",
|
11
|
+
"resolveJsonModule": true,
|
12
|
+
"isolatedModules": true,
|
13
|
+
"noEmit": true,
|
14
|
+
|
15
|
+
/* Linting */
|
16
|
+
"strict": true,
|
17
|
+
"noUnusedLocals": true,
|
18
|
+
"noUnusedParameters": true,
|
19
|
+
"noFallthroughCasesInSwitch": true,
|
20
|
+
|
21
|
+
/* Path aliases */
|
22
|
+
"baseUrl": ".",
|
23
|
+
"paths": {
|
24
|
+
"@/*": ["src/*"]
|
25
|
+
},
|
26
|
+
|
27
|
+
/* Additional settings */
|
28
|
+
"esModuleInterop": true,
|
29
|
+
"forceConsistentCasingInFileNames": true
|
30
|
+
},
|
31
|
+
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
32
|
+
}
|