@zkpassport/sdk 0.2.5 → 0.2.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 +35 -35
- package/dist/cjs/encryption.d.ts +4 -4
- package/dist/cjs/encryption.js +17 -7
- package/dist/cjs/index.js +12 -7
- package/dist/esm/encryption.d.ts +4 -4
- package/dist/esm/index.js +5 -0
- package/package.json +4 -2
- package/src/index.ts +7 -1
- package/tsconfig.json +1 -2
package/README.md
CHANGED
|
@@ -15,21 +15,21 @@ npm install @zkpassport/sdk
|
|
|
15
15
|
## How to use
|
|
16
16
|
|
|
17
17
|
```ts
|
|
18
|
-
import { ZKPassport, EU_COUNTRIES } from
|
|
18
|
+
import { ZKPassport, EU_COUNTRIES } from "@zkpassport/sdk"
|
|
19
19
|
|
|
20
20
|
// Replace with your domain
|
|
21
|
-
const zkPassport = new ZKPassport(
|
|
21
|
+
const zkPassport = new ZKPassport("demo.zkpassport.id")
|
|
22
22
|
|
|
23
23
|
// Specify your app name, logo and the purpose of the request
|
|
24
24
|
// you'll send to your visitors or users
|
|
25
25
|
const queryBuilder = await zkPassport.request({
|
|
26
|
-
name:
|
|
27
|
-
logo:
|
|
28
|
-
purpose:
|
|
26
|
+
name: "ZKPassport",
|
|
27
|
+
logo: "https://zkpassport.id/logo.png",
|
|
28
|
+
purpose: "Prove you are an adult from the EU but not from Scandinavia",
|
|
29
29
|
// The scope is optional and can be used to scope the unique identifier
|
|
30
30
|
// of the request to a specific use case
|
|
31
31
|
// By default, the request's unique identifier is scoped to your domain name only
|
|
32
|
-
scope:
|
|
32
|
+
scope: "eu-adult-not-scandinavia",
|
|
33
33
|
})
|
|
34
34
|
|
|
35
35
|
// Specify the data you want to disclose
|
|
@@ -47,10 +47,10 @@ const {
|
|
|
47
47
|
onReject,
|
|
48
48
|
onError,
|
|
49
49
|
} = queryBuilder
|
|
50
|
-
.disclose(
|
|
51
|
-
.gte(
|
|
52
|
-
.in(
|
|
53
|
-
.out(
|
|
50
|
+
.disclose("firstname")
|
|
51
|
+
.gte("age", 18)
|
|
52
|
+
.in("nationality", EU_COUNTRIES)
|
|
53
|
+
.out("nationality", ["Sweden", "Denmark"])
|
|
54
54
|
.done()
|
|
55
55
|
|
|
56
56
|
// Generate a QR Code with the url and let your user scan it
|
|
@@ -60,12 +60,12 @@ onRequestReceived(() => {
|
|
|
60
60
|
// The user scanned the QR code or clicked the link to the request
|
|
61
61
|
// Essentially, this means the request popup is now opened
|
|
62
62
|
// on the user phone
|
|
63
|
-
console.log(
|
|
63
|
+
console.log("Request received")
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
onGeneratingProof(() => {
|
|
67
67
|
// The user accepted the request and the proof is being generated
|
|
68
|
-
console.log(
|
|
68
|
+
console.log("Generating proof")
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
// You probably don't need to use this callback
|
|
@@ -75,10 +75,10 @@ onProofGenerated(({ proof, vkeyHash, version, name }: ProofResult) => {
|
|
|
75
75
|
// Here, you can retrieve the proof manually and verify it
|
|
76
76
|
// But note that the verification of the proofs is handled
|
|
77
77
|
// automatically by the SDK
|
|
78
|
-
console.log(
|
|
79
|
-
console.log(
|
|
80
|
-
console.log(
|
|
81
|
-
console.log(
|
|
78
|
+
console.log("Proof generated", proof)
|
|
79
|
+
console.log("Verification key hash", vkeyHash)
|
|
80
|
+
console.log("Version", version)
|
|
81
|
+
console.log("Name", name)
|
|
82
82
|
})
|
|
83
83
|
|
|
84
84
|
// That's the callback you're looking for
|
|
@@ -93,22 +93,22 @@ onResult(
|
|
|
93
93
|
result: QueryResult
|
|
94
94
|
}) => {
|
|
95
95
|
// All the proofs have been generated and the final result is available
|
|
96
|
-
console.log(
|
|
97
|
-
console.log(
|
|
98
|
-
console.log(
|
|
99
|
-
console.log(
|
|
96
|
+
console.log("firstname", result.firstname.disclose.result)
|
|
97
|
+
console.log("age over 18", result.age.gte.result)
|
|
98
|
+
console.log("nationality in EU", result.nationality.in.result)
|
|
99
|
+
console.log("nationality not from Scandinavia", result.nationality.out.result)
|
|
100
100
|
// You can also retrieved what were the values originally requested
|
|
101
|
-
console.log(
|
|
102
|
-
console.log(
|
|
103
|
-
console.log(
|
|
101
|
+
console.log("age over", result.age.gte.expected)
|
|
102
|
+
console.log("nationality in", result.nationality.in.expected)
|
|
103
|
+
console.log("nationality not in", result.nationality.out.expected)
|
|
104
104
|
// You can make sure the proof are valid by checking verified is set to true
|
|
105
|
-
console.log(
|
|
105
|
+
console.log("proofs are valid", verified)
|
|
106
106
|
// You can also retrieve the unique identifier associated to this request
|
|
107
107
|
// The assumption is that the unique identifier will be the same if coming
|
|
108
108
|
// from the same ID for the same domain name and scope
|
|
109
109
|
// So you can use it to identify if the user has already provided the proof
|
|
110
110
|
// for this specific use case
|
|
111
|
-
console.log(
|
|
111
|
+
console.log("unique identifier", uniqueIdentifier)
|
|
112
112
|
},
|
|
113
113
|
)
|
|
114
114
|
```
|
|
@@ -122,17 +122,17 @@ You can integrate `@zkpassport/sdk` into a Next.js application by creating a bac
|
|
|
122
122
|
**App Router:** `app/api/zkpassport/route.ts`
|
|
123
123
|
|
|
124
124
|
```typescript
|
|
125
|
-
import { NextResponse } from
|
|
126
|
-
import { ZKPassport } from
|
|
125
|
+
import { NextResponse } from "next/server"
|
|
126
|
+
import { ZKPassport } from "@zkpassport/sdk"
|
|
127
127
|
|
|
128
128
|
export async function GET() {
|
|
129
|
-
const zkPassport = new ZKPassport(
|
|
129
|
+
const zkPassport = new ZKPassport("demo.zkpassport.id") // Replace with your domain
|
|
130
130
|
const queryBuilder = await zkPassport.request({
|
|
131
|
-
name:
|
|
132
|
-
logo:
|
|
133
|
-
purpose:
|
|
131
|
+
name: "ZKPassport Demo",
|
|
132
|
+
logo: "https://via.placeholder.com/150",
|
|
133
|
+
purpose: "Verify user nationality and first name",
|
|
134
134
|
})
|
|
135
|
-
const { url } = queryBuilder.disclose(
|
|
135
|
+
const { url } = queryBuilder.disclose("nationality").disclose("firstname").done()
|
|
136
136
|
return NextResponse.json({ url })
|
|
137
137
|
}
|
|
138
138
|
```
|
|
@@ -142,14 +142,14 @@ export async function GET() {
|
|
|
142
142
|
**App Router:** `app/page.tsx`
|
|
143
143
|
|
|
144
144
|
```tsx
|
|
145
|
-
|
|
146
|
-
import { useEffect, useState } from
|
|
145
|
+
"use client"
|
|
146
|
+
import { useEffect, useState } from "react"
|
|
147
147
|
|
|
148
148
|
export default function Home() {
|
|
149
149
|
const [verificationUrl, setVerificationUrl] = useState<string | null>(null)
|
|
150
150
|
|
|
151
151
|
useEffect(() => {
|
|
152
|
-
fetch(
|
|
152
|
+
fetch("/api/zkpassport")
|
|
153
153
|
.then((res) => res.json())
|
|
154
154
|
.then((data) => setVerificationUrl(data.url))
|
|
155
155
|
.catch(console.error)
|
package/dist/cjs/encryption.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare function generateECDHKeyPair(): Promise<{
|
|
2
|
-
privateKey:
|
|
3
|
-
publicKey:
|
|
2
|
+
privateKey: import("@noble/secp256k1").Bytes;
|
|
3
|
+
publicKey: import("@noble/secp256k1").Bytes;
|
|
4
4
|
}>;
|
|
5
|
-
export declare function getSharedSecret(privateKey: string, publicKey: string): Promise<Uint8Array
|
|
6
|
-
export declare function encrypt(message: string, sharedSecret: Uint8Array, topic: string): Promise<Uint8Array
|
|
5
|
+
export declare function getSharedSecret(privateKey: string, publicKey: string): Promise<Uint8Array<ArrayBuffer>>;
|
|
6
|
+
export declare function encrypt(message: string, sharedSecret: Uint8Array, topic: string): Promise<Uint8Array<ArrayBufferLike>>;
|
|
7
7
|
export declare function decrypt(ciphertext: Uint8Array, sharedSecret: Uint8Array, topic: string): Promise<string>;
|
package/dist/cjs/encryption.js
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
exports.generateECDHKeyPair = generateECDHKeyPair;
|
|
27
37
|
exports.getSharedSecret = getSharedSecret;
|
package/dist/cjs/index.js
CHANGED
|
@@ -14,6 +14,11 @@ const node_gzip_1 = require("node-gzip");
|
|
|
14
14
|
//import initNoirC from '@noir-lang/noirc_abi'
|
|
15
15
|
//import initACVM from '@noir-lang/acvm_js'
|
|
16
16
|
const en_json_1 = tslib_1.__importDefault(require("i18n-iso-countries/langs/en.json"));
|
|
17
|
+
const buffer_1 = require("buffer/");
|
|
18
|
+
// If Buffer is not defined, then we use the Buffer from the buffer package
|
|
19
|
+
if (typeof globalThis.Buffer === "undefined") {
|
|
20
|
+
globalThis.Buffer = buffer_1.Buffer;
|
|
21
|
+
}
|
|
17
22
|
(0, i18n_iso_countries_1.registerLocale)(en_json_1.default);
|
|
18
23
|
function hasRequestedAccessToField(credentialsRequest, field) {
|
|
19
24
|
const fieldValue = credentialsRequest[field];
|
|
@@ -172,7 +177,7 @@ class ZKPassport {
|
|
|
172
177
|
else if (request.method === "proof") {
|
|
173
178
|
logger_1.noLogger.debug(`User generated proof`);
|
|
174
179
|
// Uncompress the proof and convert it to a hex string
|
|
175
|
-
const bytesProof = Buffer.from(request.params.proof, "base64");
|
|
180
|
+
const bytesProof = buffer_1.Buffer.from(request.params.proof, "base64");
|
|
176
181
|
const uncompressedProof = await (0, node_gzip_1.ungzip)(bytesProof);
|
|
177
182
|
// The gzip lib in the app compress the proof as ASCII
|
|
178
183
|
// and since the app passes the proof as a hex string, we can
|
|
@@ -276,8 +281,8 @@ class ZKPassport {
|
|
|
276
281
|
return this.getZkPassportRequest(topic)
|
|
277
282
|
},*/
|
|
278
283
|
done: () => {
|
|
279
|
-
const base64Config = Buffer.from(JSON.stringify(this.topicToConfig[topic])).toString("base64");
|
|
280
|
-
const base64Service = Buffer.from(JSON.stringify(this.topicToService[topic])).toString("base64");
|
|
284
|
+
const base64Config = buffer_1.Buffer.from(JSON.stringify(this.topicToConfig[topic])).toString("base64");
|
|
285
|
+
const base64Service = buffer_1.Buffer.from(JSON.stringify(this.topicToService[topic])).toString("base64");
|
|
281
286
|
const pubkey = (0, utils_2.bytesToHex)(this.topicToKeyPair[topic].publicKey);
|
|
282
287
|
this.setExpectedProofCount(topic);
|
|
283
288
|
return {
|
|
@@ -333,7 +338,7 @@ class ZKPassport {
|
|
|
333
338
|
logger_1.noLogger.debug("[frontend] Received handshake:", event.data);
|
|
334
339
|
this.topicToRequestReceived[topic] = true;
|
|
335
340
|
this.topicToSharedSecret[topic] = await (0, encryption_1.getSharedSecret)((0, utils_2.bytesToHex)(keyPair.privateKey), data.params.pubkey);
|
|
336
|
-
logger_1.noLogger.debug("[frontend] Shared secret:", Buffer.from(this.topicToSharedSecret[topic]).toString("hex"));
|
|
341
|
+
logger_1.noLogger.debug("[frontend] Shared secret:", buffer_1.Buffer.from(this.topicToSharedSecret[topic]).toString("hex"));
|
|
337
342
|
const encryptedMessage = await (0, json_rpc_1.createEncryptedJsonRpcRequest)("hello", null, this.topicToSharedSecret[topic], topic);
|
|
338
343
|
logger_1.noLogger.debug("[frontend] Sending encrypted message:", encryptedMessage);
|
|
339
344
|
wsClient.send(JSON.stringify(encryptedMessage));
|
|
@@ -928,7 +933,7 @@ class ZKPassport {
|
|
|
928
933
|
for (const proof of proofsToVerify) {
|
|
929
934
|
const proofData = (0, utils_1.getProofData)(proof.proof, true);
|
|
930
935
|
const hostedPackagedCircuit = await (0, utils_1.getHostedPackagedCircuitByName)(proof.version, proof.name);
|
|
931
|
-
const vkeyBytes = Buffer.from(hostedPackagedCircuit.vkey, "base64");
|
|
936
|
+
const vkeyBytes = buffer_1.Buffer.from(hostedPackagedCircuit.vkey, "base64");
|
|
932
937
|
try {
|
|
933
938
|
verified = await verifier.verifyUltraHonkProof(proofData, new Uint8Array(vkeyBytes));
|
|
934
939
|
}
|
|
@@ -953,8 +958,8 @@ class ZKPassport {
|
|
|
953
958
|
*/
|
|
954
959
|
getUrl(requestId) {
|
|
955
960
|
const pubkey = (0, utils_2.bytesToHex)(this.topicToKeyPair[requestId].publicKey);
|
|
956
|
-
const base64Config = Buffer.from(JSON.stringify(this.topicToConfig[requestId])).toString("base64");
|
|
957
|
-
const base64Service = Buffer.from(JSON.stringify(this.topicToService[requestId])).toString("base64");
|
|
961
|
+
const base64Config = buffer_1.Buffer.from(JSON.stringify(this.topicToConfig[requestId])).toString("base64");
|
|
962
|
+
const base64Service = buffer_1.Buffer.from(JSON.stringify(this.topicToService[requestId])).toString("base64");
|
|
958
963
|
return `https://zkpassport.id/r?d=${this.domain}&t=${requestId}&c=${base64Config}&s=${base64Service}&p=${pubkey}`;
|
|
959
964
|
}
|
|
960
965
|
/**
|
package/dist/esm/encryption.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export declare function generateECDHKeyPair(): Promise<{
|
|
2
|
-
privateKey:
|
|
3
|
-
publicKey:
|
|
2
|
+
privateKey: import("@noble/secp256k1").Bytes;
|
|
3
|
+
publicKey: import("@noble/secp256k1").Bytes;
|
|
4
4
|
}>;
|
|
5
|
-
export declare function getSharedSecret(privateKey: string, publicKey: string): Promise<Uint8Array
|
|
6
|
-
export declare function encrypt(message: string, sharedSecret: Uint8Array, topic: string): Promise<Uint8Array
|
|
5
|
+
export declare function getSharedSecret(privateKey: string, publicKey: string): Promise<Uint8Array<ArrayBuffer>>;
|
|
6
|
+
export declare function encrypt(message: string, sharedSecret: Uint8Array, topic: string): Promise<Uint8Array<ArrayBufferLike>>;
|
|
7
7
|
export declare function decrypt(ciphertext: Uint8Array, sharedSecret: Uint8Array, topic: string): Promise<string>;
|
package/dist/esm/index.js
CHANGED
|
@@ -10,6 +10,11 @@ import { ungzip } from "node-gzip";
|
|
|
10
10
|
//import initNoirC from '@noir-lang/noirc_abi'
|
|
11
11
|
//import initACVM from '@noir-lang/acvm_js'
|
|
12
12
|
import i18en from "i18n-iso-countries/langs/en.json";
|
|
13
|
+
import { Buffer } from "buffer/";
|
|
14
|
+
// If Buffer is not defined, then we use the Buffer from the buffer package
|
|
15
|
+
if (typeof globalThis.Buffer === "undefined") {
|
|
16
|
+
globalThis.Buffer = Buffer;
|
|
17
|
+
}
|
|
13
18
|
registerLocale(i18en);
|
|
14
19
|
function hasRequestedAccessToField(credentialsRequest, field) {
|
|
15
20
|
const fieldValue = credentialsRequest[field];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zkpassport/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Privacy-preserving identity verification using passports and ID cards",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -34,13 +34,15 @@
|
|
|
34
34
|
"@types/node-gzip": "^1.1.3",
|
|
35
35
|
"@types/ws": "^8.5.12",
|
|
36
36
|
"jest": "^29.7.0",
|
|
37
|
+
"ts-node": "^10.9.2",
|
|
37
38
|
"typescript": "^5.6.2"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"@aztec/bb.js": "^0.67.0",
|
|
41
42
|
"@noble/ciphers": "^1.2.1",
|
|
42
43
|
"@noble/secp256k1": "^2.2.3",
|
|
43
|
-
"@zkpassport/utils": "^0.2.
|
|
44
|
+
"@zkpassport/utils": "^0.2.16",
|
|
45
|
+
"buffer": "^6.0.3",
|
|
44
46
|
"i18n-iso-countries": "^7.12.0",
|
|
45
47
|
"node-gzip": "^1.1.2",
|
|
46
48
|
"ws": "^8.18.0"
|
package/src/index.ts
CHANGED
|
@@ -41,6 +41,12 @@ import { ungzip } from "node-gzip"
|
|
|
41
41
|
//import initNoirC from '@noir-lang/noirc_abi'
|
|
42
42
|
//import initACVM from '@noir-lang/acvm_js'
|
|
43
43
|
import i18en from "i18n-iso-countries/langs/en.json"
|
|
44
|
+
import { Buffer } from "buffer/"
|
|
45
|
+
|
|
46
|
+
// If Buffer is not defined, then we use the Buffer from the buffer package
|
|
47
|
+
if (typeof globalThis.Buffer === "undefined") {
|
|
48
|
+
globalThis.Buffer = Buffer as any
|
|
49
|
+
}
|
|
44
50
|
|
|
45
51
|
registerLocale(i18en)
|
|
46
52
|
|
|
@@ -554,7 +560,7 @@ export class ZKPassport {
|
|
|
554
560
|
scope?: string
|
|
555
561
|
topicOverride?: string
|
|
556
562
|
keyPairOverride?: { privateKey: Uint8Array; publicKey: Uint8Array }
|
|
557
|
-
}) {
|
|
563
|
+
}): Promise<QueryBuilder> {
|
|
558
564
|
const topic = topicOverride || randomBytes(16).toString("hex")
|
|
559
565
|
|
|
560
566
|
const keyPair = keyPairOverride || (await generateECDHKeyPair())
|