@worldcoin/idkit-core 4.0.1-dev.fe98789 → 4.0.2-dev.a907be3

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/dist/index.cjs CHANGED
@@ -1,5 +1,11 @@
1
1
  'use strict';
2
2
 
3
+ var sha3 = require('@noble/hashes/sha3');
4
+ var utils = require('@noble/hashes/utils');
5
+ var hmac = require('@noble/hashes/hmac');
6
+ var sha2 = require('@noble/hashes/sha2');
7
+ var secp256k1 = require('@noble/secp256k1');
8
+
3
9
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
4
10
  var __defProp = Object.defineProperty;
5
11
  var __export = (target, all2) => {
@@ -388,12 +394,12 @@ function hashSignal(signal) {
388
394
  wasm.__wbindgen_export4(deferred2_0, deferred2_1, 1);
389
395
  }
390
396
  }
391
- function __wasm_bindgen_func_elem_597(arg0, arg1) {
392
- wasm.__wasm_bindgen_func_elem_597(arg0, arg1);
393
- }
394
397
  function __wasm_bindgen_func_elem_960(arg0, arg1, arg2) {
395
398
  wasm.__wasm_bindgen_func_elem_960(arg0, arg1, addHeapObject(arg2));
396
399
  }
400
+ function __wasm_bindgen_func_elem_597(arg0, arg1) {
401
+ wasm.__wasm_bindgen_func_elem_597(arg0, arg1);
402
+ }
397
403
  function __wasm_bindgen_func_elem_1345(arg0, arg1, arg2, arg3) {
398
404
  wasm.__wasm_bindgen_func_elem_1345(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));
399
405
  }
@@ -772,6 +778,34 @@ var IDKitBuilder = class _IDKitBuilder {
772
778
  const ret = wasm.idkitbuilder_constraints(ptr, addHeapObject(constraints_json));
773
779
  return takeObject(ret);
774
780
  }
781
+ /**
782
+ * Builds the native payload for constraints (synchronous, no bridge connection).
783
+ *
784
+ * Used by the native transport to get the same payload format as the bridge
785
+ * without creating a network connection.
786
+ *
787
+ * # Errors
788
+ *
789
+ * Returns an error if constraints are invalid or payload construction fails.
790
+ * @param {any} constraints_json
791
+ * @returns {any}
792
+ */
793
+ nativePayload(constraints_json) {
794
+ try {
795
+ const ptr = this.__destroy_into_raw();
796
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
797
+ wasm.idkitbuilder_nativePayload(retptr, ptr, addHeapObject(constraints_json));
798
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
799
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
800
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
801
+ if (r2) {
802
+ throw takeObject(r1);
803
+ }
804
+ return takeObject(r0);
805
+ } finally {
806
+ wasm.__wbindgen_add_to_stack_pointer(16);
807
+ }
808
+ }
775
809
  /**
776
810
  * Creates a new builder for proving an existing session
777
811
  * @param {string} session_id
@@ -827,6 +861,34 @@ var IDKitBuilder = class _IDKitBuilder {
827
861
  const ret = wasm.createSession(ptr0, len0, ptr1, ptr2, len2, ptr3, len3, ptr4, len4, ptr5, len5);
828
862
  return _IDKitBuilder.__wrap(ret);
829
863
  }
864
+ /**
865
+ * Builds the native payload from a preset (synchronous, no bridge connection).
866
+ *
867
+ * Used by the native transport to get the same payload format as the bridge
868
+ * without creating a network connection.
869
+ *
870
+ * # Errors
871
+ *
872
+ * Returns an error if the preset is invalid or payload construction fails.
873
+ * @param {any} preset_json
874
+ * @returns {any}
875
+ */
876
+ nativePayloadFromPreset(preset_json) {
877
+ try {
878
+ const ptr = this.__destroy_into_raw();
879
+ const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
880
+ wasm.idkitbuilder_nativePayloadFromPreset(retptr, ptr, addHeapObject(preset_json));
881
+ var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
882
+ var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
883
+ var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);
884
+ if (r2) {
885
+ throw takeObject(r1);
886
+ }
887
+ return takeObject(r0);
888
+ } finally {
889
+ wasm.__wbindgen_add_to_stack_pointer(16);
890
+ }
891
+ }
830
892
  /**
831
893
  * Creates a new builder for uniqueness requests
832
894
  * @param {string} app_id
@@ -1796,10 +1858,6 @@ var idkit_wasm_default = __wbg_init;
1796
1858
  // src/lib/wasm.ts
1797
1859
  var wasmInitialized = false;
1798
1860
  var wasmInitPromise = null;
1799
- async function importNodeModule(specifier) {
1800
- const dynamicImport = Function("moduleName", "return import(moduleName)");
1801
- return dynamicImport(specifier);
1802
- }
1803
1861
  async function initIDKit() {
1804
1862
  if (wasmInitialized) {
1805
1863
  return;
@@ -1818,35 +1876,230 @@ async function initIDKit() {
1818
1876
  })();
1819
1877
  return wasmInitPromise;
1820
1878
  }
1821
- async function initIDKitServer() {
1822
- if (wasmInitialized) {
1823
- return;
1879
+
1880
+ // src/transports/native.ts
1881
+ var MINIAPP_VERIFY_ACTION = "miniapp-verify-action";
1882
+ function isInWorldApp() {
1883
+ return typeof window !== "undefined" && Boolean(window.WorldApp);
1884
+ }
1885
+ var _requestCounter = 0;
1886
+ var _activeNativeRequest = null;
1887
+ function createNativeRequest(wasmPayload, config) {
1888
+ if (_activeNativeRequest?.isPending()) {
1889
+ console.warn(
1890
+ "IDKit native request already in flight. Reusing active request."
1891
+ );
1892
+ return _activeNativeRequest;
1824
1893
  }
1825
- if (wasmInitPromise) {
1826
- return wasmInitPromise;
1894
+ const request2 = new NativeIDKitRequest(wasmPayload, config);
1895
+ _activeNativeRequest = request2;
1896
+ return request2;
1897
+ }
1898
+ var NativeIDKitRequest = class {
1899
+ constructor(wasmPayload, config) {
1900
+ this.connectorURI = "";
1901
+ this.resolved = false;
1902
+ this.cancelled = false;
1903
+ this.settled = false;
1904
+ this.resolvedResult = null;
1905
+ this.messageHandler = null;
1906
+ this.miniKitHandler = null;
1907
+ this.rejectFn = null;
1908
+ this.requestId = crypto.randomUUID?.() ?? `native-${Date.now()}-${++_requestCounter}`;
1909
+ this.resultPromise = new Promise((resolve, reject) => {
1910
+ this.rejectFn = reject;
1911
+ const handleIncomingPayload = (responsePayload) => {
1912
+ if (this.cancelled || this.resolved || this.settled) return;
1913
+ if (responsePayload?.status === "error") {
1914
+ this.cleanup();
1915
+ reject(
1916
+ new NativeVerifyError(
1917
+ responsePayload.error_code ?? "generic_error" /* GenericError */
1918
+ )
1919
+ );
1920
+ return;
1921
+ }
1922
+ this.resolved = true;
1923
+ const result = nativeResultToIDKitResult(responsePayload, config);
1924
+ this.resolvedResult = result;
1925
+ this.cleanup();
1926
+ resolve(result);
1927
+ };
1928
+ const handler = (event) => {
1929
+ const data = event.data;
1930
+ if (data?.type === MINIAPP_VERIFY_ACTION || data?.command === MINIAPP_VERIFY_ACTION) {
1931
+ handleIncomingPayload(data.payload ?? data);
1932
+ }
1933
+ };
1934
+ this.messageHandler = handler;
1935
+ window.addEventListener("message", handler);
1936
+ try {
1937
+ const miniKit = window.MiniKit;
1938
+ if (typeof miniKit?.subscribe === "function") {
1939
+ const miniKitHandler = (payload) => {
1940
+ handleIncomingPayload(payload?.payload ?? payload);
1941
+ };
1942
+ this.miniKitHandler = miniKitHandler;
1943
+ miniKit.subscribe(MINIAPP_VERIFY_ACTION, miniKitHandler);
1944
+ }
1945
+ } catch {
1946
+ }
1947
+ const sendPayload = {
1948
+ command: "verify",
1949
+ version: 2,
1950
+ payload: wasmPayload
1951
+ };
1952
+ const w = window;
1953
+ if (w.webkit?.messageHandlers?.minikit) {
1954
+ w.webkit.messageHandlers.minikit.postMessage(sendPayload);
1955
+ } else if (w.Android) {
1956
+ w.Android.postMessage(JSON.stringify(sendPayload));
1957
+ } else {
1958
+ this.cleanup();
1959
+ reject(new Error("No WebView bridge available"));
1960
+ }
1961
+ });
1962
+ this.resultPromise.catch(() => {
1963
+ }).finally(() => {
1964
+ this.settled = true;
1965
+ this.cleanup();
1966
+ if (_activeNativeRequest === this) {
1967
+ _activeNativeRequest = null;
1968
+ }
1969
+ });
1827
1970
  }
1828
- wasmInitPromise = (async () => {
1971
+ /**
1972
+ * Cancel this request. Removes the message listener so it cannot consume
1973
+ * a response meant for a later request, and rejects the pending promise.
1974
+ */
1975
+ cancel() {
1976
+ if (this.resolved || this.cancelled) return;
1977
+ this.cancelled = true;
1978
+ this.cleanup();
1979
+ this.rejectFn?.(new NativeVerifyError("cancelled" /* Cancelled */));
1980
+ if (_activeNativeRequest === this) {
1981
+ _activeNativeRequest = null;
1982
+ }
1983
+ }
1984
+ cleanup() {
1985
+ if (this.messageHandler) {
1986
+ window.removeEventListener("message", this.messageHandler);
1987
+ this.messageHandler = null;
1988
+ }
1989
+ if (this.miniKitHandler) {
1990
+ try {
1991
+ const miniKit = window.MiniKit;
1992
+ miniKit?.unsubscribe?.(MINIAPP_VERIFY_ACTION);
1993
+ } catch {
1994
+ }
1995
+ this.miniKitHandler = null;
1996
+ }
1997
+ }
1998
+ isPending() {
1999
+ return !this.settled && !this.cancelled;
2000
+ }
2001
+ async pollOnce() {
2002
+ if (this.resolved && this.resolvedResult) {
2003
+ return { type: "confirmed", result: this.resolvedResult };
2004
+ }
2005
+ return { type: "awaiting_confirmation" };
2006
+ }
2007
+ async pollUntilCompletion(options) {
2008
+ const timeout = options?.timeout ?? 3e5;
2009
+ let timeoutId;
2010
+ let abortHandler = null;
2011
+ let waiterTerminationCode = null;
1829
2012
  try {
1830
- const { readFile } = await importNodeModule(
1831
- "node:fs/promises"
1832
- );
1833
- const { fileURLToPath } = await importNodeModule(
1834
- "node:url"
1835
- );
1836
- const { dirname, join } = await importNodeModule(
1837
- "node:path"
1838
- );
1839
- const modulePath = fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
1840
- const wasmPath = join(dirname(modulePath), "idkit_wasm_bg.wasm");
1841
- const wasmBuffer = await readFile(wasmPath);
1842
- await idkit_wasm_default({ module_or_path: wasmBuffer });
1843
- wasmInitialized = true;
2013
+ const result = await Promise.race([
2014
+ this.resultPromise,
2015
+ new Promise((_, reject) => {
2016
+ if (options?.signal) {
2017
+ abortHandler = () => {
2018
+ waiterTerminationCode = "cancelled" /* Cancelled */;
2019
+ reject(new NativeVerifyError("cancelled" /* Cancelled */));
2020
+ };
2021
+ if (options.signal.aborted) {
2022
+ abortHandler();
2023
+ return;
2024
+ }
2025
+ options.signal.addEventListener("abort", abortHandler, {
2026
+ once: true
2027
+ });
2028
+ }
2029
+ timeoutId = setTimeout(() => {
2030
+ waiterTerminationCode = "timeout" /* Timeout */;
2031
+ reject(new NativeVerifyError("timeout" /* Timeout */));
2032
+ }, timeout);
2033
+ })
2034
+ ]);
2035
+ return { success: true, result };
1844
2036
  } catch (error) {
1845
- wasmInitPromise = null;
1846
- throw new Error(`Failed to initialize IDKit WASM for server: ${error}`);
2037
+ if (error instanceof NativeVerifyError) {
2038
+ if (waiterTerminationCode === error.code && this.isPending()) {
2039
+ this.cancel();
2040
+ }
2041
+ return { success: false, error: error.code };
2042
+ }
2043
+ return { success: false, error: "generic_error" /* GenericError */ };
2044
+ } finally {
2045
+ if (timeoutId) {
2046
+ clearTimeout(timeoutId);
2047
+ }
2048
+ if (options?.signal && abortHandler) {
2049
+ options.signal.removeEventListener("abort", abortHandler);
2050
+ }
1847
2051
  }
1848
- })();
1849
- return wasmInitPromise;
2052
+ }
2053
+ };
2054
+ var NativeVerifyError = class extends Error {
2055
+ constructor(code) {
2056
+ super(code);
2057
+ this.code = code;
2058
+ }
2059
+ };
2060
+ function nativeResultToIDKitResult(payload, config) {
2061
+ const rpNonce = config.rp_context?.nonce ?? "";
2062
+ if ("responses" in payload && Array.isArray(payload.responses)) {
2063
+ return {
2064
+ protocol_version: payload.protocol_version ?? "4.0",
2065
+ nonce: payload.nonce ?? rpNonce,
2066
+ action: payload.action ?? config.action ?? "",
2067
+ action_description: payload.action_description,
2068
+ session_id: payload.session_id,
2069
+ responses: payload.responses,
2070
+ environment: payload.environment ?? config.environment ?? "production"
2071
+ };
2072
+ }
2073
+ if ("verifications" in payload) {
2074
+ return {
2075
+ protocol_version: "4.0",
2076
+ nonce: rpNonce,
2077
+ action: config.action ?? "",
2078
+ responses: payload.verifications.map((v) => ({
2079
+ identifier: v.verification_level,
2080
+ proof: [v.proof],
2081
+ nullifier: v.nullifier_hash,
2082
+ merkle_root: v.merkle_root,
2083
+ issuer_schema_id: 0,
2084
+ expires_at_min: 0
2085
+ })),
2086
+ environment: "production"
2087
+ };
2088
+ }
2089
+ return {
2090
+ protocol_version: "3.0",
2091
+ nonce: rpNonce,
2092
+ action: config.action ?? "",
2093
+ responses: [
2094
+ {
2095
+ identifier: payload.verification_level,
2096
+ proof: payload.proof,
2097
+ merkle_root: payload.merkle_root,
2098
+ nullifier: payload.nullifier_hash
2099
+ }
2100
+ ],
2101
+ environment: "production"
2102
+ };
1850
2103
  }
1851
2104
 
1852
2105
  // src/request.ts
@@ -1913,9 +2166,52 @@ function secureDocumentLegacy(opts = {}) {
1913
2166
  function documentLegacy(opts = {}) {
1914
2167
  return { type: "DocumentLegacy", signal: opts.signal };
1915
2168
  }
2169
+ function createWasmBuilderFromConfig(config) {
2170
+ if (!config.rp_context) {
2171
+ throw new Error("rp_context is required for WASM bridge transport");
2172
+ }
2173
+ const rpContext = new idkit_wasm_exports.RpContextWasm(
2174
+ config.rp_context.rp_id,
2175
+ config.rp_context.nonce,
2176
+ BigInt(config.rp_context.created_at),
2177
+ BigInt(config.rp_context.expires_at),
2178
+ config.rp_context.signature
2179
+ );
2180
+ if (config.type === "request") {
2181
+ return idkit_wasm_exports.request(
2182
+ config.app_id,
2183
+ String(config.action ?? ""),
2184
+ rpContext,
2185
+ config.action_description ?? null,
2186
+ config.bridge_url ?? null,
2187
+ config.allow_legacy_proofs ?? false,
2188
+ config.override_connect_base_url ?? null,
2189
+ config.environment ?? null
2190
+ );
2191
+ }
2192
+ if (config.type === "proveSession") {
2193
+ return idkit_wasm_exports.proveSession(
2194
+ config.session_id,
2195
+ config.app_id,
2196
+ rpContext,
2197
+ config.action_description ?? null,
2198
+ config.bridge_url ?? null,
2199
+ config.override_connect_base_url ?? null,
2200
+ config.environment ?? null
2201
+ );
2202
+ }
2203
+ return idkit_wasm_exports.createSession(
2204
+ config.app_id,
2205
+ rpContext,
2206
+ config.action_description ?? null,
2207
+ config.bridge_url ?? null,
2208
+ config.override_connect_base_url ?? null,
2209
+ config.environment ?? null
2210
+ );
2211
+ }
1916
2212
  var IDKitBuilder2 = class {
1917
- constructor(wasmBuilder) {
1918
- this.wasmBuilder = wasmBuilder;
2213
+ constructor(config) {
2214
+ this.config = config;
1919
2215
  }
1920
2216
  /**
1921
2217
  * Creates an IDKit request with the given constraints
@@ -1925,36 +2221,45 @@ var IDKitBuilder2 = class {
1925
2221
  *
1926
2222
  * @example
1927
2223
  * ```typescript
1928
- * const builder = await IDKit.request({ app_id, action, rp_context });
1929
- * const request = await builder.constraints(any(CredentialRequest('orb'), CredentialRequest('face')));
2224
+ * const request = await IDKit.request({ app_id, action, rp_context, allow_legacy_proofs: false })
2225
+ * .constraints(any(CredentialRequest('orb'), CredentialRequest('face')));
1930
2226
  * ```
1931
2227
  */
1932
- //TODO: re-enable once this is supported and World ID 4.0 is rolled out live
1933
- // async constraints(constraints: ConstraintNode): Promise<IDKitRequest> {
1934
- // await initIDKit();
1935
- // const wasmRequest = (await this.wasmBuilder.constraints(
1936
- // constraints,
1937
- // )) as unknown as WasmModule.IDKitRequest;
1938
- // return new IDKitRequestImpl(wasmRequest);
1939
- // }
2228
+ async constraints(constraints) {
2229
+ await initIDKit();
2230
+ const wasmBuilder = createWasmBuilderFromConfig(this.config);
2231
+ if (isInWorldApp()) {
2232
+ const payload = wasmBuilder.nativePayload(constraints);
2233
+ return createNativeRequest(payload, this.config);
2234
+ }
2235
+ const wasmRequest = await wasmBuilder.constraints(
2236
+ constraints
2237
+ );
2238
+ return new IDKitRequestImpl(wasmRequest);
2239
+ }
1940
2240
  /**
1941
2241
  * Creates an IDKit request from a preset (works for all request types)
1942
2242
  *
1943
2243
  * Presets provide a simplified way to create requests with predefined
1944
2244
  * credential configurations.
1945
2245
  *
1946
- * @param preset - A preset object from orbLegacy()
2246
+ * @param preset - A preset object from orbLegacy(), secureDocumentLegacy(), or documentLegacy()
1947
2247
  * @returns A new IDKitRequest instance
1948
2248
  *
1949
2249
  * @example
1950
2250
  * ```typescript
1951
- * const builder = await IDKit.request({ app_id, action, rp_context });
1952
- * const request = await builder.preset(orbLegacy({ signal: 'user-123' }));
2251
+ * const request = await IDKit.request({ app_id, action, rp_context, allow_legacy_proofs: true })
2252
+ * .preset(orbLegacy({ signal: 'user-123' }));
1953
2253
  * ```
1954
2254
  */
1955
2255
  async preset(preset) {
1956
2256
  await initIDKit();
1957
- const wasmRequest = await this.wasmBuilder.preset(
2257
+ const wasmBuilder = createWasmBuilderFromConfig(this.config);
2258
+ if (isInWorldApp()) {
2259
+ const payload = wasmBuilder.nativePayloadFromPreset(preset);
2260
+ return createNativeRequest(payload, this.config);
2261
+ }
2262
+ const wasmRequest = await wasmBuilder.preset(
1958
2263
  preset
1959
2264
  );
1960
2265
  return new IDKitRequestImpl(wasmRequest);
@@ -1968,55 +2273,45 @@ function createRequest(config) {
1968
2273
  throw new Error("action is required");
1969
2274
  }
1970
2275
  if (!config.rp_context) {
1971
- throw new Error("rp_context is required");
2276
+ throw new Error(
2277
+ "rp_context is required. Generate it on your backend using signRequest()."
2278
+ );
1972
2279
  }
1973
2280
  if (typeof config.allow_legacy_proofs !== "boolean") {
1974
2281
  throw new Error(
1975
2282
  "allow_legacy_proofs is required. Set to true to accept v3 proofs during migration, or false to only accept v4 proofs."
1976
2283
  );
1977
2284
  }
1978
- const rpContext = new idkit_wasm_exports.RpContextWasm(
1979
- config.rp_context.rp_id,
1980
- config.rp_context.nonce,
1981
- BigInt(config.rp_context.created_at),
1982
- BigInt(config.rp_context.expires_at),
1983
- config.rp_context.signature
1984
- );
1985
- const wasmBuilder = idkit_wasm_exports.request(
1986
- config.app_id,
1987
- String(config.action),
1988
- rpContext,
1989
- config.action_description ?? null,
1990
- config.bridge_url ?? null,
1991
- config.allow_legacy_proofs,
1992
- config.override_connect_base_url ?? null,
1993
- config.environment ?? null
1994
- );
1995
- return new IDKitBuilder2(wasmBuilder);
2285
+ return new IDKitBuilder2({
2286
+ type: "request",
2287
+ app_id: config.app_id,
2288
+ action: String(config.action),
2289
+ rp_context: config.rp_context,
2290
+ action_description: config.action_description,
2291
+ bridge_url: config.bridge_url,
2292
+ allow_legacy_proofs: config.allow_legacy_proofs,
2293
+ override_connect_base_url: config.override_connect_base_url,
2294
+ environment: config.environment
2295
+ });
1996
2296
  }
1997
2297
  function createSession2(config) {
1998
2298
  if (!config.app_id) {
1999
2299
  throw new Error("app_id is required");
2000
2300
  }
2001
2301
  if (!config.rp_context) {
2002
- throw new Error("rp_context is required");
2302
+ throw new Error(
2303
+ "rp_context is required. Generate it on your backend using signRequest()."
2304
+ );
2003
2305
  }
2004
- const rpContext = new idkit_wasm_exports.RpContextWasm(
2005
- config.rp_context.rp_id,
2006
- config.rp_context.nonce,
2007
- BigInt(config.rp_context.created_at),
2008
- BigInt(config.rp_context.expires_at),
2009
- config.rp_context.signature
2010
- );
2011
- const wasmBuilder = idkit_wasm_exports.createSession(
2012
- config.app_id,
2013
- rpContext,
2014
- config.action_description ?? null,
2015
- config.bridge_url ?? null,
2016
- config.override_connect_base_url ?? null,
2017
- config.environment ?? null
2018
- );
2019
- return new IDKitBuilder2(wasmBuilder);
2306
+ return new IDKitBuilder2({
2307
+ type: "session",
2308
+ app_id: config.app_id,
2309
+ rp_context: config.rp_context,
2310
+ action_description: config.action_description,
2311
+ bridge_url: config.bridge_url,
2312
+ override_connect_base_url: config.override_connect_base_url,
2313
+ environment: config.environment
2314
+ });
2020
2315
  }
2021
2316
  function proveSession2(sessionId, config) {
2022
2317
  if (!sessionId) {
@@ -2026,31 +2321,22 @@ function proveSession2(sessionId, config) {
2026
2321
  throw new Error("app_id is required");
2027
2322
  }
2028
2323
  if (!config.rp_context) {
2029
- throw new Error("rp_context is required");
2324
+ throw new Error(
2325
+ "rp_context is required. Generate it on your backend using signRequest()."
2326
+ );
2030
2327
  }
2031
- const rpContext = new idkit_wasm_exports.RpContextWasm(
2032
- config.rp_context.rp_id,
2033
- config.rp_context.nonce,
2034
- BigInt(config.rp_context.created_at),
2035
- BigInt(config.rp_context.expires_at),
2036
- config.rp_context.signature
2037
- );
2038
- const wasmBuilder = idkit_wasm_exports.proveSession(
2039
- sessionId,
2040
- config.app_id,
2041
- rpContext,
2042
- config.action_description ?? null,
2043
- config.bridge_url ?? null,
2044
- config.override_connect_base_url ?? null,
2045
- config.environment ?? null
2046
- );
2047
- return new IDKitBuilder2(wasmBuilder);
2328
+ return new IDKitBuilder2({
2329
+ type: "proveSession",
2330
+ session_id: sessionId,
2331
+ app_id: config.app_id,
2332
+ rp_context: config.rp_context,
2333
+ action_description: config.action_description,
2334
+ bridge_url: config.bridge_url,
2335
+ override_connect_base_url: config.override_connect_base_url,
2336
+ environment: config.environment
2337
+ });
2048
2338
  }
2049
2339
  var IDKit = {
2050
- /** Initialize WASM for browser environments */
2051
- init: initIDKit,
2052
- /** Initialize WASM for Node.js/server environments */
2053
- initServer: initIDKitServer,
2054
2340
  /** Create a new verification request */
2055
2341
  request: createRequest,
2056
2342
  /** Create a new session (no action, no existing session_id) */
@@ -2093,21 +2379,71 @@ var isServerEnvironment = () => {
2093
2379
  }
2094
2380
  return false;
2095
2381
  };
2382
+ function hashToField(input) {
2383
+ const hash = BigInt("0x" + utils.bytesToHex(sha3.keccak_256(input))) >> 8n;
2384
+ return utils.hexToBytes(hash.toString(16).padStart(64, "0"));
2385
+ }
2386
+ function hashSignal2(signal) {
2387
+ let input;
2388
+ if (signal instanceof Uint8Array) {
2389
+ input = signal;
2390
+ } else if (signal.startsWith("0x") && isValidHex(signal.slice(2))) {
2391
+ input = utils.hexToBytes(signal.slice(2));
2392
+ } else {
2393
+ input = new TextEncoder().encode(signal);
2394
+ }
2395
+ return "0x" + utils.bytesToHex(hashToField(input));
2396
+ }
2397
+ function isValidHex(s) {
2398
+ if (s.length === 0) return false;
2399
+ if (s.length % 2 !== 0) return false;
2400
+ return /^[0-9a-fA-F]+$/.test(s);
2401
+ }
2096
2402
 
2097
- // src/lib/rp-signature.ts
2098
- function signRequest2(action, signingKeyHex, ttlSeconds) {
2403
+ // src/lib/signing.ts
2404
+ secp256k1.etc.hmacSha256Sync = (key, ...msgs) => hmac.hmac(sha2.sha256, key, secp256k1.etc.concatBytes(...msgs));
2405
+ var DEFAULT_TTL_SEC = 300;
2406
+ function computeRpSignatureMessage(nonceBytes, createdAt, expiresAt) {
2407
+ const message = new Uint8Array(48);
2408
+ message.set(nonceBytes, 0);
2409
+ const view = new DataView(message.buffer);
2410
+ view.setBigUint64(32, BigInt(createdAt), false);
2411
+ view.setBigUint64(40, BigInt(expiresAt), false);
2412
+ return message;
2413
+ }
2414
+ function signRequest2(_action, signingKeyHex, ttl = DEFAULT_TTL_SEC) {
2099
2415
  if (!isServerEnvironment()) {
2100
2416
  throw new Error(
2101
2417
  "signRequest can only be used in Node.js environments. This function requires access to signing keys and should never be called from browser/client-side code."
2102
2418
  );
2103
2419
  }
2104
- const ttlBigInt = ttlSeconds !== void 0 ? BigInt(ttlSeconds) : void 0;
2105
- return idkit_wasm_exports.signRequest(action, signingKeyHex, ttlBigInt);
2106
- }
2107
-
2108
- // src/lib/hashing.ts
2109
- function hashSignal2(signal) {
2110
- return idkit_wasm_exports.hashSignal(signal);
2420
+ const keyHex = signingKeyHex.startsWith("0x") ? signingKeyHex.slice(2) : signingKeyHex;
2421
+ if (!/^[0-9a-fA-F]+$/.test(keyHex)) {
2422
+ throw new Error("Invalid signing key: contains non-hex characters");
2423
+ }
2424
+ if (keyHex.length !== 64) {
2425
+ throw new Error(
2426
+ `Invalid signing key: expected 32 bytes (64 hex chars), got ${keyHex.length / 2} bytes`
2427
+ );
2428
+ }
2429
+ const privKey = secp256k1.etc.hexToBytes(keyHex);
2430
+ const randomBytes = crypto.getRandomValues(new Uint8Array(32));
2431
+ const nonceBytes = hashToField(randomBytes);
2432
+ const createdAt = Math.floor(Date.now() / 1e3);
2433
+ const expiresAt = createdAt + ttl;
2434
+ const message = computeRpSignatureMessage(nonceBytes, createdAt, expiresAt);
2435
+ const msgHash = sha3.keccak_256(message);
2436
+ const recSig = secp256k1.sign(msgHash, privKey);
2437
+ const compact = recSig.toCompactRawBytes();
2438
+ const sig65 = new Uint8Array(65);
2439
+ sig65.set(compact, 0);
2440
+ sig65[64] = recSig.recovery + 27;
2441
+ return {
2442
+ sig: "0x" + utils.bytesToHex(sig65),
2443
+ nonce: "0x" + utils.bytesToHex(nonceBytes),
2444
+ createdAt,
2445
+ expiresAt
2446
+ };
2111
2447
  }
2112
2448
 
2113
2449
  exports.CredentialRequest = CredentialRequest;