@zkpassport/sdk 0.2.5 → 0.2.7

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 CHANGED
@@ -4,7 +4,7 @@ Privacy-preserving identity verification using passports and ID cards.
4
4
 
5
5
  _⚠️ Warning ⚠️_
6
6
 
7
- _This version of the SDK is only compatible with the version 0.5 and above of ZKPassport mobile app._
7
+ _This is experimental software that has not been audited yet. Use at your own risk._
8
8
 
9
9
  ## Installation
10
10
 
@@ -15,21 +15,21 @@ npm install @zkpassport/sdk
15
15
  ## How to use
16
16
 
17
17
  ```ts
18
- import { ZKPassport, EU_COUNTRIES } from '@zkpassport/sdk'
18
+ import { ZKPassport, EU_COUNTRIES } from "@zkpassport/sdk"
19
19
 
20
20
  // Replace with your domain
21
- const zkPassport = new ZKPassport('demo.zkpassport.id')
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: 'ZKPassport',
27
- logo: 'https://zkpassport.id/logo.png',
28
- purpose: 'Prove you are an adult from the EU but not from Scandinavia',
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: 'eu-adult-not-scandinavia',
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('firstname')
51
- .gte('age', 18)
52
- .in('nationality', EU_COUNTRIES)
53
- .out('nationality', ['Sweden', 'Denmark'])
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('Request received')
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('Generating proof')
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('Proof generated', proof)
79
- console.log('Verification key hash', vkeyHash)
80
- console.log('Version', version)
81
- console.log('Name', name)
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('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)
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('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)
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('proofs are valid', verified)
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('unique identifier', uniqueIdentifier)
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 'next/server'
126
- import { ZKPassport } from '@zkpassport/sdk'
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('demo.zkpassport.id') // Replace with your domain
129
+ const zkPassport = new ZKPassport("demo.zkpassport.id") // Replace with your domain
130
130
  const queryBuilder = await zkPassport.request({
131
- name: 'ZKPassport Demo',
132
- logo: 'https://via.placeholder.com/150',
133
- purpose: 'Verify user nationality and first name',
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('nationality').disclose('firstname').done()
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
- 'use client'
146
- import { useEffect, useState } from 'react'
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('/api/zkpassport')
152
+ fetch("/api/zkpassport")
153
153
  .then((res) => res.json())
154
154
  .then((data) => setVerificationUrl(data.url))
155
155
  .catch(console.error)
@@ -1,7 +1,7 @@
1
1
  export declare function generateECDHKeyPair(): Promise<{
2
- privateKey: Uint8Array;
3
- publicKey: Uint8Array;
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>;
@@ -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 (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
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
@@ -10,10 +10,18 @@ const websocket_1 = require("./websocket");
10
10
  const json_rpc_1 = require("./json-rpc");
11
11
  const encryption_1 = require("./encryption");
12
12
  const logger_1 = require("./logger");
13
- const node_gzip_1 = require("node-gzip");
13
+ const pako_1 = require("pako");
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
+ if (typeof window !== "undefined") {
22
+ window.Buffer = buffer_1.Buffer;
23
+ }
24
+ }
17
25
  (0, i18n_iso_countries_1.registerLocale)(en_json_1.default);
18
26
  function hasRequestedAccessToField(credentialsRequest, field) {
19
27
  const fieldValue = credentialsRequest[field];
@@ -172,8 +180,8 @@ class ZKPassport {
172
180
  else if (request.method === "proof") {
173
181
  logger_1.noLogger.debug(`User generated proof`);
174
182
  // Uncompress the proof and convert it to a hex string
175
- const bytesProof = Buffer.from(request.params.proof, "base64");
176
- const uncompressedProof = await (0, node_gzip_1.ungzip)(bytesProof);
183
+ const bytesProof = buffer_1.Buffer.from(request.params.proof, "base64");
184
+ const uncompressedProof = (0, pako_1.inflate)(bytesProof);
177
185
  // The gzip lib in the app compress the proof as ASCII
178
186
  // and since the app passes the proof as a hex string, we can
179
187
  // just decode the bytes as hex characters using the TextDecoder
@@ -276,8 +284,8 @@ class ZKPassport {
276
284
  return this.getZkPassportRequest(topic)
277
285
  },*/
278
286
  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");
287
+ const base64Config = buffer_1.Buffer.from(JSON.stringify(this.topicToConfig[topic])).toString("base64");
288
+ const base64Service = buffer_1.Buffer.from(JSON.stringify(this.topicToService[topic])).toString("base64");
281
289
  const pubkey = (0, utils_2.bytesToHex)(this.topicToKeyPair[topic].publicKey);
282
290
  this.setExpectedProofCount(topic);
283
291
  return {
@@ -333,7 +341,7 @@ class ZKPassport {
333
341
  logger_1.noLogger.debug("[frontend] Received handshake:", event.data);
334
342
  this.topicToRequestReceived[topic] = true;
335
343
  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"));
344
+ logger_1.noLogger.debug("[frontend] Shared secret:", buffer_1.Buffer.from(this.topicToSharedSecret[topic]).toString("hex"));
337
345
  const encryptedMessage = await (0, json_rpc_1.createEncryptedJsonRpcRequest)("hello", null, this.topicToSharedSecret[topic], topic);
338
346
  logger_1.noLogger.debug("[frontend] Sending encrypted message:", encryptedMessage);
339
347
  wsClient.send(JSON.stringify(encryptedMessage));
@@ -928,7 +936,7 @@ class ZKPassport {
928
936
  for (const proof of proofsToVerify) {
929
937
  const proofData = (0, utils_1.getProofData)(proof.proof, true);
930
938
  const hostedPackagedCircuit = await (0, utils_1.getHostedPackagedCircuitByName)(proof.version, proof.name);
931
- const vkeyBytes = Buffer.from(hostedPackagedCircuit.vkey, "base64");
939
+ const vkeyBytes = buffer_1.Buffer.from(hostedPackagedCircuit.vkey, "base64");
932
940
  try {
933
941
  verified = await verifier.verifyUltraHonkProof(proofData, new Uint8Array(vkeyBytes));
934
942
  }
@@ -953,8 +961,8 @@ class ZKPassport {
953
961
  */
954
962
  getUrl(requestId) {
955
963
  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");
964
+ const base64Config = buffer_1.Buffer.from(JSON.stringify(this.topicToConfig[requestId])).toString("base64");
965
+ const base64Service = buffer_1.Buffer.from(JSON.stringify(this.topicToService[requestId])).toString("base64");
958
966
  return `https://zkpassport.id/r?d=${this.domain}&t=${requestId}&c=${base64Config}&s=${base64Service}&p=${pubkey}`;
959
967
  }
960
968
  /**
@@ -1,7 +1,7 @@
1
1
  export declare function generateECDHKeyPair(): Promise<{
2
- privateKey: Uint8Array;
3
- publicKey: Uint8Array;
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
@@ -6,10 +6,18 @@ import { getWebSocketClient } from "./websocket";
6
6
  import { createEncryptedJsonRpcRequest } from "./json-rpc";
7
7
  import { decrypt, generateECDHKeyPair, getSharedSecret } from "./encryption";
8
8
  import { noLogger as logger } from "./logger";
9
- import { ungzip } from "node-gzip";
9
+ import { inflate } from "pako";
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
+ if (typeof window !== "undefined") {
18
+ window.Buffer = Buffer;
19
+ }
20
+ }
13
21
  registerLocale(i18en);
14
22
  function hasRequestedAccessToField(credentialsRequest, field) {
15
23
  const fieldValue = credentialsRequest[field];
@@ -163,7 +171,7 @@ export class ZKPassport {
163
171
  logger.debug(`User generated proof`);
164
172
  // Uncompress the proof and convert it to a hex string
165
173
  const bytesProof = Buffer.from(request.params.proof, "base64");
166
- const uncompressedProof = await ungzip(bytesProof);
174
+ const uncompressedProof = inflate(bytesProof);
167
175
  // The gzip lib in the app compress the proof as ASCII
168
176
  // and since the app passes the proof as a hex string, we can
169
177
  // just decode the bytes as hex characters using the TextDecoder
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkpassport/sdk",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
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",
@@ -31,18 +31,20 @@
31
31
  "@jest/globals": "^29.7.0",
32
32
  "@types/jest": "^29.5.14",
33
33
  "@types/node": "^22.10.9",
34
- "@types/node-gzip": "^1.1.3",
34
+ "@types/pako": "^2.0.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.12",
44
+ "@zkpassport/utils": "^0.2.16",
45
+ "buffer": "^6.0.3",
44
46
  "i18n-iso-countries": "^7.12.0",
45
- "node-gzip": "^1.1.2",
47
+ "pako": "^2.1.0",
46
48
  "ws": "^8.18.0"
47
49
  },
48
50
  "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
package/src/index.ts CHANGED
@@ -37,10 +37,19 @@ import { getWebSocketClient, WebSocketClient } from "./websocket"
37
37
  import { createEncryptedJsonRpcRequest } from "./json-rpc"
38
38
  import { decrypt, generateECDHKeyPair, getSharedSecret } from "./encryption"
39
39
  import { noLogger as logger } from "./logger"
40
- import { ungzip } from "node-gzip"
40
+ import { inflate } from "pako"
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
+ if (typeof window !== "undefined") {
50
+ window.Buffer = Buffer as any
51
+ }
52
+ }
44
53
 
45
54
  registerLocale(i18en)
46
55
 
@@ -389,7 +398,7 @@ export class ZKPassport {
389
398
  logger.debug(`User generated proof`)
390
399
  // Uncompress the proof and convert it to a hex string
391
400
  const bytesProof = Buffer.from(request.params.proof, "base64")
392
- const uncompressedProof = await ungzip(bytesProof)
401
+ const uncompressedProof = inflate(bytesProof)
393
402
  // The gzip lib in the app compress the proof as ASCII
394
403
  // and since the app passes the proof as a hex string, we can
395
404
  // just decode the bytes as hex characters using the TextDecoder
@@ -554,7 +563,7 @@ export class ZKPassport {
554
563
  scope?: string
555
564
  topicOverride?: string
556
565
  keyPairOverride?: { privateKey: Uint8Array; publicKey: Uint8Array }
557
- }) {
566
+ }): Promise<QueryBuilder> {
558
567
  const topic = topicOverride || randomBytes(16).toString("hex")
559
568
 
560
569
  const keyPair = keyPairOverride || (await generateECDHKeyPair())
package/tsconfig.json CHANGED
@@ -12,8 +12,7 @@
12
12
  "rootDir": "./src",
13
13
  "baseUrl": ".",
14
14
  "paths": {
15
- "@/*": ["./src/*"],
16
- "@/types": ["src/types/index.ts"]
15
+ "@/*": ["./src/*"]
17
16
  },
18
17
  "declaration": true,
19
18
  "isolatedModules": true,