@reclaimprotocol/js-sdk 5.0.0-dev.2 → 5.0.0-dev.4

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
@@ -195,30 +195,44 @@ async function handleCreateClaim() {
195
195
 
196
196
  The `triggerReclaimFlow()` method supports two verification modes via `verificationMode`:
197
197
 
198
- - **`'portal'` (default)**: Opens the portal URL for remote browser verification on all platforms.
199
- - **`'app'`**: Native app flow via the share page. Uses App Clip on iOS if `useAppClip` is `true`.
198
+ - **`'portal'` (default)**: Opens the portal URL for remote browser verification. Opens in a new tab by default, or embedded in an iframe when `target` is provided.
199
+ - **`'app'`**: Verifier app flow via the share page. Uses App Clip on iOS if `useAppClip` is `true`.
200
+
201
+ The method returns a `FlowHandle` that lets you close the flow programmatically:
200
202
 
201
203
  ```javascript
202
- // Portal flow (default)
203
- await reclaimProofRequest.triggerReclaimFlow();
204
+ // Portal flow (default) — opens in new tab
205
+ const handle = await reclaimProofRequest.triggerReclaimFlow();
206
+ handle.tab; // Window reference to the opened tab
207
+ handle.close(); // close tab and stop polling
208
+
209
+ // Embedded — portal loads inside a DOM element as an iframe
210
+ const handle = await reclaimProofRequest.triggerReclaimFlow({
211
+ target: document.getElementById('reclaim-container')
212
+ });
213
+ handle.iframe; // HTMLIFrameElement reference
214
+ handle.iframe?.style.height = '700px'; // customize the iframe
215
+ handle.close(); // remove iframe and stop polling
204
216
 
205
- // Native app flow
206
- await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
217
+ // Verifier app flow
218
+ const handle = await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
219
+ handle.close(); // stop polling
207
220
  ```
208
221
 
209
222
  #### On Desktop Browsers:
210
223
 
211
- 1. **Browser Extension First**: If the Reclaim browser extension is installed, it will use the extension regardless of verification mode.
212
- 2. **Portal mode** (no extension): Opens the portal in a new tab.
213
- 3. **App mode** (no extension): Shows QR code modal with share page URL.
224
+ 1. **Embedded mode**: If `target` is provided, the portal loads in an iframe inside the target element.
225
+ 2. **Browser Extension**: If the Reclaim browser extension is installed and no `target` is set, it will use the extension.
226
+ 3. **Portal mode** (no extension, no target): Opens the portal in a new tab.
227
+ 4. **App mode** (no extension): Shows QR code modal with share page URL.
214
228
 
215
229
  #### On Mobile Devices (portal mode):
216
230
 
217
- Opens the portal in a new tab.
231
+ Opens the portal in a new tab, or in an iframe if `target` is provided.
218
232
 
219
233
  #### On Mobile Devices (app mode):
220
234
 
221
- 1. **All platforms**: Redirects to the share page.
235
+ 1. **All platforms**: Redirects to the verifier app.
222
236
  2. **iOS with `useAppClip: true`**: Redirects to the Reclaim App Clip instead.
223
237
 
224
238
  The same `verificationMode` option works with `getRequestUrl()`:
@@ -227,7 +241,7 @@ The same `verificationMode` option works with `getRequestUrl()`:
227
241
  // Portal URL (default)
228
242
  const url = await reclaimProofRequest.getRequestUrl();
229
243
 
230
- // Native app URL
244
+ // Verifier app URL
231
245
  const url = await reclaimProofRequest.getRequestUrl({ verificationMode: 'app' });
232
246
  ```
233
247
 
@@ -290,10 +304,10 @@ await reclaimProofRequest.triggerReclaimFlow();
290
304
  ### Benefits of the New Flow:
291
305
 
292
306
  1. **Platform Adaptive**: Automatically chooses the best verification method for each platform
293
- 2. **User-Friendly**: Provides the most seamless experience possible for each user
294
- 3. **Simplified Integration**: Single method call handles all verification scenarios
307
+ 2. **Embeddable**: Embed the portal directly in your page via iframe with `{ target: element }`
308
+ 3. **Controllable**: Returns a `FlowHandle` to close the flow or access the iframe at any time
295
309
  4. **Extension Support**: Leverages browser extension for desktop users when available
296
- 5. **Mobile Optimized**: Native app experiences on mobile devices
310
+ 5. **Mobile Optimized**: Verifier app experiences on mobile devices
297
311
 
298
312
  ## Step 6: Run your application
299
313
 
@@ -350,17 +364,17 @@ Redirection with body:
350
364
 
351
365
  - **url**: The URL where users should be redirected after successful proof generation.
352
366
  - **method** (optional): The redirection method to use. Allowed options: `GET` (default) and `POST`.
353
- *Note: `POST` form redirection is only supported in In-Browser SDK.*
367
+ *Note: `POST` form redirection is only supported in Portal flow.*
354
368
  - **body** (optional): List of name-value pairs to be sent as the body of the form request.
355
369
  - When `method` is `POST`, `body` is sent with `application/x-www-form-urlencoded` content type.
356
370
  - When `method` is `GET`, if `body` is set, it is sent as query parameters.
357
- *Note: Sending `body` on redirection is only supported in In-Browser SDK.*
371
+ *Note: Sending `body` on redirection is only supported in Portal flow.*
358
372
 
359
373
  ```javascript
360
374
  reclaimProofRequest.setRedirectUrl(
361
375
  "https://example.com/redirect",
362
- "POST", // In-Browser SDK only
363
- [{ name: "foo", value: "bar" }] // In-Browser SDK only
376
+ "POST", // Portal flow only
377
+ [{ name: "foo", value: "bar" }] // Portal flow only
364
378
  );
365
379
  ```
366
380
 
@@ -376,17 +390,17 @@ Redirection with body:
376
390
 
377
391
  - **url**: The URL where users should be redirected after an error which aborts the verification process.
378
392
  - **method** (optional): The redirection method to use. Allowed options: `GET` (default) and `POST`.
379
- *Note: `POST` form redirection is only supported in In-Browser SDK.*
393
+ *Note: `POST` form redirection is only supported in Portal flow.*
380
394
  - **body** (optional): List of name-value pairs to be sent as the body of the form request.
381
395
  - When `method` is `POST`, `body` is sent with `application/x-www-form-urlencoded` content type.
382
396
  - When `method` is `GET`, if `body` is set, it is sent as query parameters.
383
- *Note: Sending `body` on redirection is only supported in In-Browser SDK.*
397
+ *Note: Sending `body` on redirection is only supported in Portal flow.*
384
398
 
385
399
  ```javascript
386
400
  reclaimProofRequest.setCancelRedirectUrl(
387
401
  "https://example.com/error-redirect",
388
- "POST", // In-Browser SDK only
389
- [{ name: "error_code", value: "1001" }] // In-Browser SDK only
402
+ "POST", // Portal flow only
403
+ [{ name: "error_code", value: "1001" }] // Portal flow only
390
404
  );
391
405
  ```
392
406
 
@@ -397,6 +411,7 @@ reclaimProofRequest.setCancelRedirectUrl(
397
411
 
398
412
  By default, proofs are sent as HTTP `POST` with `Content-Type` as `application/x-www-form-urlencoded`. Pass function argument `jsonProofResponse` as `true` to send proofs with `Content-Type` as `application/json`.
399
413
 
414
+ ```javascript
400
415
  reclaimProofRequest.setAppCallbackUrl("https://example.com/callback", true);
401
416
  ```
402
417
 
@@ -467,24 +482,40 @@ For more details about response format, check out [official documentation of Err
467
482
 
468
483
  ```javascript
469
484
  const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
470
- portalUrl: "https://your-custom-domain.com/verify", // Custom portal URL
485
+ portalUrl: "https://your-custom-domain.com/verify", // Custom URL for both portal and app modes
471
486
  customAppClipUrl: "https://appclip.apple.com/id?p=your.custom.app.clip", // Custom iOS App Clip URL
472
487
  // ... other options
473
488
  });
474
489
  ```
475
490
 
476
- > **Note:** `portalUrl` defaults to `https://portal.reclaimprotocol.org` and `useAppClip` defaults to `false` when no options are provided. `portalUrl` is the preferred option. The previous `customSharePageUrl` is deprecated but still supported. If both are provided, `portalUrl` takes precedence.
491
+ > **Defaults:**
492
+ > - Portal mode: `https://portal.reclaimprotocol.org` — remote browser verification
493
+ > - App mode: `https://share.reclaimprotocol.org` — redirects to the verifier app
494
+ >
495
+ > Setting `portalUrl` overrides both modes. The previous `customSharePageUrl` is deprecated but still supported — if both are provided, `portalUrl` takes precedence. `useAppClip` defaults to `false`.
477
496
 
478
497
  10. **Platform-Specific Flow Control**:
479
498
  Both `triggerReclaimFlow()` and `getRequestUrl()` support `verificationMode`:
480
499
 
481
500
  ```javascript
482
- // Portal flow (default) — remote browser verification
483
- await reclaimProofRequest.triggerReclaimFlow();
484
- const portalUrl = await reclaimProofRequest.getRequestUrl();
501
+ // Portal flow (default) — opens in new tab
502
+ const handle = await reclaimProofRequest.triggerReclaimFlow();
503
+ handle.tab; // Window reference
504
+ handle.close(); // close tab, stop polling
505
+
506
+ // Embedded portal — loads inside a DOM element
507
+ const handle = await reclaimProofRequest.triggerReclaimFlow({
508
+ target: document.getElementById('container')
509
+ });
510
+ handle.iframe; // HTMLIFrameElement reference
511
+ handle.close(); // remove iframe, stop polling
512
+
513
+ // Verifier app flow
514
+ const handle = await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
515
+ handle.close(); // stop polling
485
516
 
486
- // Native app flow
487
- await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
517
+ // getRequestUrl also supports verificationMode
518
+ const portalUrl = await reclaimProofRequest.getRequestUrl();
488
519
  const appUrl = await reclaimProofRequest.getRequestUrl({ verificationMode: 'app' });
489
520
  ```
490
521
 
@@ -583,26 +614,27 @@ The SDK provides a `verifyProof` function to manually verify proofs cryptographi
583
614
  Here are the possible ways to use `verifyProof`, from beginner to advanced:
584
615
 
585
616
  ### 1. Simple Verification
586
- The easiest way is to let the SDK retrieve the requirements automatically. If you have access to your `ReclaimProofRequest` instance, you can use `request.getProviderVersion()` to automate and simplify verification!
617
+ The easiest way is to use `request.getProviderVersion()` which returns the provider ID and exact version used in the session pass it directly as the config:
587
618
 
588
619
  ```javascript
589
620
  import { verifyProof } from "@reclaimprotocol/js-sdk";
590
621
 
591
- // Verify a single proof
592
- const { isVerified, data } = await verifyProof(proof, { hashes: ['0xAbC...'] });
622
+ // Using getProviderVersion() recommended
623
+ const providerVersion = reclaimProofRequest.getProviderVersion();
624
+ const { isVerified, data, error } = await verifyProof(proof, providerVersion);
593
625
  if (isVerified) {
594
626
  console.log("Proof is valid");
595
627
  console.log("Context:", data[0].context);
596
628
  console.log("Extracted parameters:", data[0].extractedParameters);
597
629
  } else {
598
- console.log("Proof is invalid");
630
+ console.log("Proof is invalid, reason:", error);
599
631
  }
600
632
  ```
601
633
 
602
- Or, by manually providing the details:
634
+ Or, by manually providing the provider details:
603
635
  ```javascript
604
- const { isVerified, data } = await verifyProof(proof, {
605
- providerId: "YOUR_PROVIDER_ID",
636
+ const { isVerified, data } = await verifyProof(proof, {
637
+ providerId: "YOUR_PROVIDER_ID",
606
638
  // The exact provider version used in the session.
607
639
  providerVersion: "1.0.0",
608
640
  // Optionally provide tags. For example, this can be `['ai']` when you want to allow patches from ai.
@@ -610,6 +642,11 @@ const { isVerified, data } = await verifyProof(proof, {
610
642
  });
611
643
  ```
612
644
 
645
+ Or, with a known hash:
646
+ ```javascript
647
+ const { isVerified, data, error } = await verifyProof(proof, { hashes: ['0xAbC...'] });
648
+ ```
649
+
613
650
  ### 2. Intermediate: Strict Hash Verification
614
651
 
615
652
  If you want to avoid network requests, you can manually feed the expected cryptographic hashes your system allows.
@@ -680,18 +717,22 @@ const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER
680
717
 
681
718
  ### Verifying TEE Attestation
682
719
 
683
- Pass `true` as the third argument (`verifyTEE`) to `verifyProof` to require and verify TEE attestation. If TEE data is missing or invalid, verification will fail.
720
+ Set `verifyTEE: true` in the config to require and verify TEE attestation. If TEE data is missing or invalid, verification will fail with a `TeeVerificationError`.
684
721
 
685
722
  ```javascript
686
- import { verifyProof } from "@reclaimprotocol/js-sdk";
723
+ import { verifyProof, TeeVerificationError } from "@reclaimprotocol/js-sdk";
687
724
 
688
- // Pass true as the third argument (verifyTEE) to require TEE verification
689
- const { isVerified, isTeeVerified, data } = await verifyProof(proof, { hashes: ['0xAbC...'] }, true);
725
+ // Set verifyTEE in config to require TEE verification
726
+ const { isVerified, isTeeVerified, data, error } = await verifyProof(proof, { hashes: ['0xAbC...'], verifyTEE: true });
690
727
 
691
728
  if (isVerified) {
692
729
  console.log("Proof is fully verified with hardware attestation");
693
730
  console.log("TEE verified:", isTeeVerified);
694
731
  console.log("Extracted parameters:", data[0].extractedParameters);
732
+ } else if (error instanceof TeeVerificationError) {
733
+ console.log("TEE verification failed:", error.message);
734
+ } else {
735
+ console.log("Proof verification failed:", error);
695
736
  }
696
737
  ```
697
738