@worldcoin/idkit-core 2.0.2 → 2.1.0

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/build/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(src_exports, {
25
25
  DEFAULT_VERIFICATION_LEVEL: () => DEFAULT_VERIFICATION_LEVEL,
26
26
  VerificationLevel: () => VerificationLevel,
27
27
  VerificationState: () => VerificationState,
28
+ createWorldBridgeStore: () => createWorldBridgeStore,
28
29
  useWorldBridgeStore: () => useWorldBridgeStore,
29
30
  verification_level_to_credential_types: () => verification_level_to_credential_types
30
31
  });
@@ -149,6 +150,28 @@ var encodeAction = (action) => {
149
150
  return action.types.map((type, index) => `${type}(${action.values[index]})`).join(",");
150
151
  };
151
152
 
153
+ // src/lib/platform.ts
154
+ var import_browser_or_node = require("browser-or-node");
155
+ var isReactNative = () => {
156
+ return typeof navigator !== "undefined" && navigator.product === "ReactNative";
157
+ };
158
+ var isWeb = () => {
159
+ return import_browser_or_node.isBrowser;
160
+ };
161
+ var getGlobalObject = () => {
162
+ if (typeof globalThis !== "undefined") return globalThis;
163
+ if (typeof self !== "undefined") return self;
164
+ if (typeof window !== "undefined") return window;
165
+ throw new Error("Unable to locate global object");
166
+ };
167
+ var getCrypto = () => {
168
+ const globalObj = getGlobalObject();
169
+ if (typeof globalObj.crypto !== "undefined") {
170
+ return globalObj.crypto;
171
+ }
172
+ throw new Error("Crypto API not available. For React Native, ensure polyfills are set up properly.");
173
+ };
174
+
152
175
  // src/lib/utils.ts
153
176
  var import_buffer2 = require("buffer/index.js");
154
177
  var DEFAULT_VERIFICATION_LEVEL = "orb" /* Orb */;
@@ -187,33 +210,100 @@ var credential_type_to_verification_level = (credential_type) => {
187
210
  }
188
211
  };
189
212
 
213
+ // src/lib/adapters/web-crypto-adapter.ts
214
+ var WebCryptoAdapter = class {
215
+ constructor() {
216
+ this.encoder = new TextEncoder();
217
+ this.decoder = new TextDecoder();
218
+ }
219
+ async generateKey() {
220
+ return {
221
+ iv: window.crypto.getRandomValues(new Uint8Array(12)),
222
+ key: await window.crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"])
223
+ };
224
+ }
225
+ async exportKey(key) {
226
+ return buffer_encode(await window.crypto.subtle.exportKey("raw", key));
227
+ }
228
+ async encryptRequest(key, iv, request) {
229
+ return {
230
+ iv: buffer_encode(iv),
231
+ payload: buffer_encode(
232
+ await window.crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, this.encoder.encode(request))
233
+ )
234
+ };
235
+ }
236
+ async decryptResponse(key, iv, payload) {
237
+ return this.decoder.decode(
238
+ await window.crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, buffer_decode(payload))
239
+ );
240
+ }
241
+ };
242
+
243
+ // src/lib/adapters/react-native-crypto-adapter.ts
244
+ var ReactNativeCryptoAdapter = class {
245
+ constructor() {
246
+ this.encoder = new TextEncoder();
247
+ this.decoder = new TextDecoder();
248
+ }
249
+ async generateKey() {
250
+ const crypto = getCrypto();
251
+ return {
252
+ iv: crypto.getRandomValues(new Uint8Array(12)),
253
+ key: await crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"])
254
+ };
255
+ }
256
+ async exportKey(key) {
257
+ const crypto = getCrypto();
258
+ return buffer_encode(await crypto.subtle.exportKey("raw", key));
259
+ }
260
+ async encryptRequest(key, iv, request) {
261
+ const crypto = getCrypto();
262
+ return {
263
+ iv: buffer_encode(iv),
264
+ payload: buffer_encode(
265
+ await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, this.encoder.encode(request))
266
+ )
267
+ };
268
+ }
269
+ async decryptResponse(key, iv, payload) {
270
+ const crypto = getCrypto();
271
+ return this.decoder.decode(await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, buffer_decode(payload)));
272
+ }
273
+ };
274
+
190
275
  // src/lib/crypto.ts
191
- var encoder = new TextEncoder();
192
- var decoder = new TextDecoder();
276
+ var cryptoAdapterInstance = null;
277
+ var getCryptoAdapter = () => {
278
+ if (cryptoAdapterInstance) {
279
+ return cryptoAdapterInstance;
280
+ }
281
+ if (isWeb()) {
282
+ cryptoAdapterInstance = new WebCryptoAdapter();
283
+ return cryptoAdapterInstance;
284
+ }
285
+ if (isReactNative()) {
286
+ cryptoAdapterInstance = new ReactNativeCryptoAdapter();
287
+ return cryptoAdapterInstance;
288
+ }
289
+ throw new Error("Unsupported platform");
290
+ };
193
291
  var generateKey = async () => {
194
- return {
195
- iv: window.crypto.getRandomValues(new Uint8Array(12)),
196
- key: await window.crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"])
197
- };
292
+ return getCryptoAdapter().generateKey();
198
293
  };
199
294
  var exportKey = async (key) => {
200
- return buffer_encode(await window.crypto.subtle.exportKey("raw", key));
295
+ return getCryptoAdapter().exportKey(key);
201
296
  };
202
297
  var encryptRequest = async (key, iv, request) => {
203
- return {
204
- iv: buffer_encode(iv),
205
- payload: buffer_encode(
206
- await window.crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, encoder.encode(request))
207
- )
208
- };
298
+ return getCryptoAdapter().encryptRequest(key, iv, request);
209
299
  };
210
300
  var decryptResponse = async (key, iv, payload) => {
211
- return decoder.decode(await window.crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, buffer_decode(payload)));
301
+ return getCryptoAdapter().decryptResponse(key, iv, payload);
212
302
  };
213
303
 
214
304
  // src/bridge.ts
215
305
  var DEFAULT_BRIDGE_URL = "https://bridge.worldcoin.org";
216
- var useWorldBridgeStore = (0, import_zustand.create)((set, get) => ({
306
+ var createStoreImplementation = (set, get) => ({
217
307
  iv: null,
218
308
  key: null,
219
309
  result: null,
@@ -318,7 +408,9 @@ var useWorldBridgeStore = (0, import_zustand.create)((set, get) => ({
318
408
  verificationState: "loading_widget" /* PreparingClient */
319
409
  });
320
410
  }
321
- }));
411
+ });
412
+ var useWorldBridgeStore = (0, import_zustand.create)(createStoreImplementation);
413
+ var createWorldBridgeStore = () => (0, import_zustand.create)(createStoreImplementation);
322
414
  // Annotate the CommonJS export names for ESM import in node:
323
415
  0 && (module.exports = {
324
416
  AppErrorCodes,
@@ -326,6 +418,7 @@ var useWorldBridgeStore = (0, import_zustand.create)((set, get) => ({
326
418
  DEFAULT_VERIFICATION_LEVEL,
327
419
  VerificationLevel,
328
420
  VerificationState,
421
+ createWorldBridgeStore,
329
422
  useWorldBridgeStore,
330
423
  verification_level_to_credential_types
331
424
  });
package/build/index.d.cts CHANGED
@@ -17,7 +17,14 @@ type WorldBridgeStore = {
17
17
  pollForUpdates: () => Promise<void>;
18
18
  reset: () => void;
19
19
  };
20
+ /**
21
+ * Single instance of the store
22
+ */
20
23
  declare const useWorldBridgeStore: zustand.UseBoundStore<zustand.StoreApi<WorldBridgeStore>>;
24
+ /**
25
+ * Factory function to create a new instance of the store
26
+ */
27
+ declare const createWorldBridgeStore: () => zustand.UseBoundStore<zustand.StoreApi<WorldBridgeStore>>;
21
28
 
22
29
  declare const DEFAULT_VERIFICATION_LEVEL = VerificationLevel.Orb;
23
30
  /**
@@ -27,4 +34,4 @@ declare const DEFAULT_VERIFICATION_LEVEL = VerificationLevel.Orb;
27
34
  */
28
35
  declare const verification_level_to_credential_types: (verification_level: VerificationLevel) => string[];
29
36
 
30
- export { AppErrorCodes, DEFAULT_VERIFICATION_LEVEL, IDKitConfig, ISuccessResult, VerificationLevel, VerificationState, type WorldBridgeStore, useWorldBridgeStore, verification_level_to_credential_types };
37
+ export { AppErrorCodes, DEFAULT_VERIFICATION_LEVEL, IDKitConfig, ISuccessResult, VerificationLevel, VerificationState, type WorldBridgeStore, createWorldBridgeStore, useWorldBridgeStore, verification_level_to_credential_types };
package/build/index.d.ts CHANGED
@@ -17,7 +17,14 @@ type WorldBridgeStore = {
17
17
  pollForUpdates: () => Promise<void>;
18
18
  reset: () => void;
19
19
  };
20
+ /**
21
+ * Single instance of the store
22
+ */
20
23
  declare const useWorldBridgeStore: zustand.UseBoundStore<zustand.StoreApi<WorldBridgeStore>>;
24
+ /**
25
+ * Factory function to create a new instance of the store
26
+ */
27
+ declare const createWorldBridgeStore: () => zustand.UseBoundStore<zustand.StoreApi<WorldBridgeStore>>;
21
28
 
22
29
  declare const DEFAULT_VERIFICATION_LEVEL = VerificationLevel.Orb;
23
30
  /**
@@ -27,4 +34,4 @@ declare const DEFAULT_VERIFICATION_LEVEL = VerificationLevel.Orb;
27
34
  */
28
35
  declare const verification_level_to_credential_types: (verification_level: VerificationLevel) => string[];
29
36
 
30
- export { AppErrorCodes, DEFAULT_VERIFICATION_LEVEL, IDKitConfig, ISuccessResult, VerificationLevel, VerificationState, type WorldBridgeStore, useWorldBridgeStore, verification_level_to_credential_types };
37
+ export { AppErrorCodes, DEFAULT_VERIFICATION_LEVEL, IDKitConfig, ISuccessResult, VerificationLevel, VerificationState, type WorldBridgeStore, createWorldBridgeStore, useWorldBridgeStore, verification_level_to_credential_types };
package/build/index.js CHANGED
@@ -85,6 +85,28 @@ function validate_bridge_url(bridge_url, is_staging) {
85
85
  return { valid: true };
86
86
  }
87
87
 
88
+ // src/lib/platform.ts
89
+ import { isBrowser, isNode as isNodeBoolean } from "browser-or-node";
90
+ var isReactNative = () => {
91
+ return typeof navigator !== "undefined" && navigator.product === "ReactNative";
92
+ };
93
+ var isWeb = () => {
94
+ return isBrowser;
95
+ };
96
+ var getGlobalObject = () => {
97
+ if (typeof globalThis !== "undefined") return globalThis;
98
+ if (typeof self !== "undefined") return self;
99
+ if (typeof window !== "undefined") return window;
100
+ throw new Error("Unable to locate global object");
101
+ };
102
+ var getCrypto = () => {
103
+ const globalObj = getGlobalObject();
104
+ if (typeof globalObj.crypto !== "undefined") {
105
+ return globalObj.crypto;
106
+ }
107
+ throw new Error("Crypto API not available. For React Native, ensure polyfills are set up properly.");
108
+ };
109
+
88
110
  // src/lib/utils.ts
89
111
  import { Buffer } from "buffer/index.js";
90
112
  var DEFAULT_VERIFICATION_LEVEL = "orb" /* Orb */;
@@ -123,33 +145,100 @@ var credential_type_to_verification_level = (credential_type) => {
123
145
  }
124
146
  };
125
147
 
148
+ // src/lib/adapters/web-crypto-adapter.ts
149
+ var WebCryptoAdapter = class {
150
+ constructor() {
151
+ this.encoder = new TextEncoder();
152
+ this.decoder = new TextDecoder();
153
+ }
154
+ async generateKey() {
155
+ return {
156
+ iv: window.crypto.getRandomValues(new Uint8Array(12)),
157
+ key: await window.crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"])
158
+ };
159
+ }
160
+ async exportKey(key) {
161
+ return buffer_encode(await window.crypto.subtle.exportKey("raw", key));
162
+ }
163
+ async encryptRequest(key, iv, request) {
164
+ return {
165
+ iv: buffer_encode(iv),
166
+ payload: buffer_encode(
167
+ await window.crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, this.encoder.encode(request))
168
+ )
169
+ };
170
+ }
171
+ async decryptResponse(key, iv, payload) {
172
+ return this.decoder.decode(
173
+ await window.crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, buffer_decode(payload))
174
+ );
175
+ }
176
+ };
177
+
178
+ // src/lib/adapters/react-native-crypto-adapter.ts
179
+ var ReactNativeCryptoAdapter = class {
180
+ constructor() {
181
+ this.encoder = new TextEncoder();
182
+ this.decoder = new TextDecoder();
183
+ }
184
+ async generateKey() {
185
+ const crypto = getCrypto();
186
+ return {
187
+ iv: crypto.getRandomValues(new Uint8Array(12)),
188
+ key: await crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"])
189
+ };
190
+ }
191
+ async exportKey(key) {
192
+ const crypto = getCrypto();
193
+ return buffer_encode(await crypto.subtle.exportKey("raw", key));
194
+ }
195
+ async encryptRequest(key, iv, request) {
196
+ const crypto = getCrypto();
197
+ return {
198
+ iv: buffer_encode(iv),
199
+ payload: buffer_encode(
200
+ await crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, this.encoder.encode(request))
201
+ )
202
+ };
203
+ }
204
+ async decryptResponse(key, iv, payload) {
205
+ const crypto = getCrypto();
206
+ return this.decoder.decode(await crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, buffer_decode(payload)));
207
+ }
208
+ };
209
+
126
210
  // src/lib/crypto.ts
127
- var encoder = new TextEncoder();
128
- var decoder = new TextDecoder();
211
+ var cryptoAdapterInstance = null;
212
+ var getCryptoAdapter = () => {
213
+ if (cryptoAdapterInstance) {
214
+ return cryptoAdapterInstance;
215
+ }
216
+ if (isWeb()) {
217
+ cryptoAdapterInstance = new WebCryptoAdapter();
218
+ return cryptoAdapterInstance;
219
+ }
220
+ if (isReactNative()) {
221
+ cryptoAdapterInstance = new ReactNativeCryptoAdapter();
222
+ return cryptoAdapterInstance;
223
+ }
224
+ throw new Error("Unsupported platform");
225
+ };
129
226
  var generateKey = async () => {
130
- return {
131
- iv: window.crypto.getRandomValues(new Uint8Array(12)),
132
- key: await window.crypto.subtle.generateKey({ name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"])
133
- };
227
+ return getCryptoAdapter().generateKey();
134
228
  };
135
229
  var exportKey = async (key) => {
136
- return buffer_encode(await window.crypto.subtle.exportKey("raw", key));
230
+ return getCryptoAdapter().exportKey(key);
137
231
  };
138
232
  var encryptRequest = async (key, iv, request) => {
139
- return {
140
- iv: buffer_encode(iv),
141
- payload: buffer_encode(
142
- await window.crypto.subtle.encrypt({ name: "AES-GCM", iv }, key, encoder.encode(request))
143
- )
144
- };
233
+ return getCryptoAdapter().encryptRequest(key, iv, request);
145
234
  };
146
235
  var decryptResponse = async (key, iv, payload) => {
147
- return decoder.decode(await window.crypto.subtle.decrypt({ name: "AES-GCM", iv }, key, buffer_decode(payload)));
236
+ return getCryptoAdapter().decryptResponse(key, iv, payload);
148
237
  };
149
238
 
150
239
  // src/bridge.ts
151
240
  var DEFAULT_BRIDGE_URL = "https://bridge.worldcoin.org";
152
- var useWorldBridgeStore = create((set, get) => ({
241
+ var createStoreImplementation = (set, get) => ({
153
242
  iv: null,
154
243
  key: null,
155
244
  result: null,
@@ -254,13 +343,16 @@ var useWorldBridgeStore = create((set, get) => ({
254
343
  verificationState: "loading_widget" /* PreparingClient */
255
344
  });
256
345
  }
257
- }));
346
+ });
347
+ var useWorldBridgeStore = create(createStoreImplementation);
348
+ var createWorldBridgeStore = () => create(createStoreImplementation);
258
349
  export {
259
350
  AppErrorCodes,
260
351
  CredentialType,
261
352
  DEFAULT_VERIFICATION_LEVEL,
262
353
  VerificationLevel,
263
354
  VerificationState,
355
+ createWorldBridgeStore,
264
356
  useWorldBridgeStore,
265
357
  verification_level_to_credential_types
266
358
  };
@@ -43,13 +43,14 @@ function hashEncodedBytes(input) {
43
43
 
44
44
  // src/lib/backend.ts
45
45
  var import_browser_or_node = require("browser-or-node");
46
- async function verifyCloudProof(proof, app_id, action, signal, endpoint) {
46
+ async function verifyCloudProof(proof, app_id, action, signal, endpoint, headers) {
47
47
  if (import_browser_or_node.isBrowser) {
48
48
  throw new Error("verifyCloudProof can only be used in the backend.");
49
49
  }
50
50
  const response = await fetch(endpoint ?? `https://developer.worldcoin.org/api/v2/verify/${app_id}`, {
51
51
  method: "POST",
52
52
  headers: {
53
+ ...headers ?? {},
53
54
  "Content-Type": "application/json"
54
55
  },
55
56
  body: JSON.stringify({
@@ -7,6 +7,6 @@ interface IVerifyResponse {
7
7
  detail?: string;
8
8
  attribute?: string | null;
9
9
  }
10
- declare function verifyCloudProof(proof: ISuccessResult, app_id: `app_${string}`, action: string, signal?: string, endpoint?: URL | string): Promise<IVerifyResponse>;
10
+ declare function verifyCloudProof(proof: ISuccessResult, app_id: `app_${string}`, action: string, signal?: string, endpoint?: URL | string, headers?: Record<string, string>): Promise<IVerifyResponse>;
11
11
 
12
12
  export { type IVerifyResponse, verifyCloudProof };
@@ -7,6 +7,6 @@ interface IVerifyResponse {
7
7
  detail?: string;
8
8
  attribute?: string | null;
9
9
  }
10
- declare function verifyCloudProof(proof: ISuccessResult, app_id: `app_${string}`, action: string, signal?: string, endpoint?: URL | string): Promise<IVerifyResponse>;
10
+ declare function verifyCloudProof(proof: ISuccessResult, app_id: `app_${string}`, action: string, signal?: string, endpoint?: URL | string, headers?: Record<string, string>): Promise<IVerifyResponse>;
11
11
 
12
12
  export { type IVerifyResponse, verifyCloudProof };
@@ -4,13 +4,14 @@ import {
4
4
 
5
5
  // src/lib/backend.ts
6
6
  import { isBrowser } from "browser-or-node";
7
- async function verifyCloudProof(proof, app_id, action, signal, endpoint) {
7
+ async function verifyCloudProof(proof, app_id, action, signal, endpoint, headers) {
8
8
  if (isBrowser) {
9
9
  throw new Error("verifyCloudProof can only be used in the backend.");
10
10
  }
11
11
  const response = await fetch(endpoint ?? `https://developer.worldcoin.org/api/v2/verify/${app_id}`, {
12
12
  method: "POST",
13
13
  headers: {
14
+ ...headers ?? {},
14
15
  "Content-Type": "application/json"
15
16
  },
16
17
  body: JSON.stringify({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@worldcoin/idkit-core",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "homepage": "https://docs.world.org/id/idkit",
5
5
  "license": "MIT",
6
6
  "private": false,