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

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
@@ -99,7 +99,7 @@ function App() {
99
99
  setProofs(proofs);
100
100
  }
101
101
  },
102
- onFailure: (error) => {
102
+ onError: (error) => {
103
103
  console.error("Verification failed", error);
104
104
  },
105
105
  });
@@ -181,7 +181,7 @@ async function handleCreateClaim() {
181
181
  setProofs(proofs);
182
182
  }
183
183
  },
184
- onFailure: (error) => {
184
+ onError: (error) => {
185
185
  console.error("Verification failed", error);
186
186
  },
187
187
  });
@@ -193,17 +193,43 @@ async function handleCreateClaim() {
193
193
 
194
194
  ### How triggerReclaimFlow() Works
195
195
 
196
- The `triggerReclaimFlow()` method automatically detects the user's environment and chooses the optimal verification method:
196
+ The `triggerReclaimFlow()` method supports two verification modes via `verificationMode`:
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`.
200
+
201
+ ```javascript
202
+ // Portal flow (default)
203
+ await reclaimProofRequest.triggerReclaimFlow();
204
+
205
+ // Native app flow
206
+ await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
207
+ ```
197
208
 
198
209
  #### On Desktop Browsers:
199
210
 
200
- 1. **Browser Extension First**: If the Reclaim browser extension is installed, it will use the extension for a seamless in-browser verification experience.
201
- 2. **QR Code Fallback**: If the extension is not available, it automatically displays a QR code modal for mobile scanning.
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.
214
+
215
+ #### On Mobile Devices (portal mode):
216
+
217
+ Opens the portal in a new tab.
218
+
219
+ #### On Mobile Devices (app mode):
202
220
 
203
- #### On Mobile Devices:
221
+ 1. **All platforms**: Redirects to the share page.
222
+ 2. **iOS with `useAppClip: true`**: Redirects to the Reclaim App Clip instead.
204
223
 
205
- 1. **iOS Devices**: Automatically redirects to the Reclaim App Clip for native iOS verification.
206
- 2. **Android Devices**: Automatically redirects to the Reclaim Instant App for native Android verification.
224
+ The same `verificationMode` option works with `getRequestUrl()`:
225
+
226
+ ```javascript
227
+ // Portal URL (default)
228
+ const url = await reclaimProofRequest.getRequestUrl();
229
+
230
+ // Native app URL
231
+ const url = await reclaimProofRequest.getRequestUrl({ verificationMode: 'app' });
232
+ ```
207
233
 
208
234
  ### Browser Extension Support
209
235
 
@@ -289,7 +315,7 @@ Your Reclaim SDK demo should now be running. Click the "Create Claim" button to
289
315
 
290
316
  4. **Verification**: The `onSuccess` is called when verification is successful, providing the proof data. When using a custom callback url, the proof is returned to the callback url and we get an empty array instead of a proof.
291
317
 
292
- 5. **Handling Failures**: The `onFailure` is called if verification fails, allowing you to handle errors gracefully.
318
+ 5. **Handling Failures**: The `onError` is called if verification fails, allowing you to handle errors gracefully.
293
319
 
294
320
  ## Advanced Configuration
295
321
 
@@ -431,33 +457,35 @@ For more details about response format, check out [official documentation of Err
431
457
  const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
432
458
  useBrowserExtension: true, // Enable browser extension support (default: true)
433
459
  extensionID: "custom-extension-id", // Custom extension identifier
434
- useAppClip: true, // Enable mobile app clips (default: true)
460
+ useAppClip: false, // Enable mobile app clips (default: false)
435
461
  log: true, // Enable troubleshooting mode and more verbose logging for debugging
436
462
  });
437
463
  ```
438
464
 
439
- 9. **Custom Share Page and App Clip URLs**:
440
- You can customize the share page and app clip URLs for your app:
465
+ 9. **Custom Portal URL and App Clip URLs**:
466
+ You can customize the portal/share page and app clip URLs for your app:
441
467
 
442
468
  ```javascript
443
469
  const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
444
- customSharePageUrl: "https://your-custom-domain.com/verify", // Custom share page URL
470
+ portalUrl: "https://your-custom-domain.com/verify", // Custom portal URL
445
471
  customAppClipUrl: "https://appclip.apple.com/id?p=your.custom.app.clip", // Custom iOS App Clip URL
446
472
  // ... other options
447
473
  });
448
474
  ```
449
475
 
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.
477
+
450
478
  10. **Platform-Specific Flow Control**:
451
- The `triggerReclaimFlow()` method provides intelligent platform detection, but you can still use traditional methods for custom flows:
479
+ Both `triggerReclaimFlow()` and `getRequestUrl()` support `verificationMode`:
452
480
 
453
481
  ```javascript
454
- // Traditional approach with manual QR code handling
455
- const requestUrl = await reclaimProofRequest.getRequestUrl();
456
- // Display your own QR code implementation
457
-
458
- // Or use the new streamlined approach
482
+ // Portal flow (default) remote browser verification
459
483
  await reclaimProofRequest.triggerReclaimFlow();
460
- // Automatically handles platform detection and optimal user experience
484
+ const portalUrl = await reclaimProofRequest.getRequestUrl();
485
+
486
+ // Native app flow
487
+ await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
488
+ const appUrl = await reclaimProofRequest.getRequestUrl({ verificationMode: 'app' });
461
489
  ```
462
490
 
463
491
  11. **Exporting and Importing SDK Configuration**:
@@ -550,34 +578,143 @@ These options allow you to securely process proofs or cancellations on your serv
550
578
 
551
579
  ## Proof Verification
552
580
 
553
- The SDK provides a `verifyProof` function to manually verify proofs. This is useful when you need to validate proofs outside of the normal flow:
581
+ The SDK provides a `verifyProof` function to manually verify proofs cryptographically on your backend. This involves validating the attestor signatures and enforcing that the proof matches the expected requirements.
582
+
583
+ Here are the possible ways to use `verifyProof`, from beginner to advanced:
584
+
585
+ ### 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!
554
587
 
555
588
  ```javascript
556
589
  import { verifyProof } from "@reclaimprotocol/js-sdk";
557
590
 
558
591
  // Verify a single proof
559
- const isValid = await verifyProof(proof);
560
- if (isValid) {
592
+ const { isVerified, data } = await verifyProof(proof, { hashes: ['0xAbC...'] });
593
+ if (isVerified) {
561
594
  console.log("Proof is valid");
595
+ console.log("Context:", data[0].context);
596
+ console.log("Extracted parameters:", data[0].extractedParameters);
562
597
  } else {
563
598
  console.log("Proof is invalid");
564
599
  }
600
+ ```
565
601
 
566
- // Verify multiple proofs
567
- const areValid = await verifyProof([proof1, proof2, proof3]);
568
- if (areValid) {
569
- console.log("All proofs are valid");
570
- } else {
571
- console.log("One or more proofs are invalid");
602
+ Or, by manually providing the details:
603
+ ```javascript
604
+ const { isVerified, data } = await verifyProof(proof, {
605
+ providerId: "YOUR_PROVIDER_ID",
606
+ // The exact provider version used in the session.
607
+ providerVersion: "1.0.0",
608
+ // Optionally provide tags. For example, this can be `['ai']` when you want to allow patches from ai.
609
+ allowedTags: ["ai"]
610
+ });
611
+ ```
612
+
613
+ ### 2. Intermediate: Strict Hash Verification
614
+
615
+ If you want to avoid network requests, you can manually feed the expected cryptographic hashes your system allows.
616
+
617
+ ```javascript
618
+ // Verify a proof against a known, strict expected hash
619
+ const { isVerified, data } = await verifyProof(proof, {
620
+ hashes: ['0x1abc2def3456...']
621
+ });
622
+ ```
623
+
624
+ ### 3. Advanced: Multiple Proofs and Optional Matches
625
+ When building advanced use-cases, you might process multiple distinct proofs at once or deal with providers that yield a few valid hash possibilities (e.g., due to optional data fields).
626
+
627
+ ```javascript
628
+ const result = await verifyProof([proof1, proof2, sameAsProof2], {
629
+ hashes: [
630
+ // A string hash is equivalent to an object with { value: '...', required: true, multiple: true }.
631
+ '0xStrictHash123...',
632
+ {
633
+ // An array 'value' means that 1 proof can have any 1 matching hash
634
+ // from this list, typically because of optional variables in the original request.
635
+ value: ['0xOptHash1...', '0xOptHashA...'],
636
+ // 'multiple' being true (which is the default) means any proof matching this hash
637
+ // is allowed to appear multiple times in the list of proofs you are verifying.
638
+ multiple: true
639
+ },
640
+ {
641
+ value: '0xE33...',
642
+ // 'required: false' means there can be 0 proofs matching this hash.
643
+ // Such proofs may be optionally present in the list of proofs.
644
+ // (By default, 'required' is true).
645
+ required: false
646
+ }
647
+ ]
648
+ });
649
+
650
+ if (result.isVerified) {
651
+ result.data.forEach((d, i) => {
652
+ console.log(`Proof ${i + 1} context:`, d.context);
653
+ console.log(`Proof ${i + 1} params:`, d.extractedParameters);
654
+ });
655
+ }
656
+ ```
657
+
658
+ ### 4. Danger Zone: Disabled Content Validation
659
+ If you only want to verify the attestor signature but wish to dangerously bypass the parameter/content match (Not Recommended):
660
+
661
+ ```javascript
662
+ const { isVerified } = await verifyProof(proof, {
663
+ dangerouslyDisableContentValidation: true
664
+ });
665
+ ```
666
+
667
+ ## TEE Attestation Verification
668
+
669
+ The SDK supports verifying TEE (Trusted Execution Environment) attestations included in proofs. This provides hardware-level assurance that the proof was generated inside a secure enclave (AMD SEV-SNP).
670
+
671
+ ### Enabling TEE Attestation
672
+
673
+ To request TEE attestation during proof generation, enable it during initialization:
674
+
675
+ ```javascript
676
+ const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
677
+ acceptTeeAttestation: true,
678
+ });
679
+ ```
680
+
681
+ ### Verifying TEE Attestation
682
+
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.
684
+
685
+ ```javascript
686
+ import { verifyProof } from "@reclaimprotocol/js-sdk";
687
+
688
+ // Pass true as the third argument (verifyTEE) to require TEE verification
689
+ const { isVerified, isTeeVerified, data } = await verifyProof(proof, { hashes: ['0xAbC...'] }, true);
690
+
691
+ if (isVerified) {
692
+ console.log("Proof is fully verified with hardware attestation");
693
+ console.log("TEE verified:", isTeeVerified);
694
+ console.log("Extracted parameters:", data[0].extractedParameters);
572
695
  }
573
696
  ```
574
697
 
575
- The `verifyProof` function:
698
+ When `verifyTEE` is `true`, the result includes `isTeeVerified`. The overall `isVerified` will be `false` if TEE data is missing or TEE verification fails.
576
699
 
577
- - Accepts either a single proof or an array of proofs
578
- - Returns a boolean indicating if the proof(s) are valid
579
- - Verifies signatures, witness integrity, and claim data
580
- - Handles both standalone and blockchain-based proofs
700
+ The TEE verification validates:
701
+ - **Nonce binding**: Ensures the attestation nonce matches the proof context
702
+ - **Application ID**: Confirms the attestation was generated for your application (optional)
703
+ - **Timestamp**: Verifies the attestation timestamp is within an acceptable range of the proof timestamp
704
+ - **SNP report**: Validates the AMD SEV-SNP hardware attestation report
705
+ - **VLEK certificate**: Verifies the certificate chain against AMD's root of trust
706
+ - **Report data**: Confirms the workload and verifier digests match the attestation
707
+
708
+ You can also verify TEE attestation separately using the lower-level `verifyTeeAttestation` function:
709
+
710
+ ```javascript
711
+ import { verifyTeeAttestation } from "@reclaimprotocol/js-sdk";
712
+
713
+ const isTeeValid = await verifyTeeAttestation(proof, APP_ID);
714
+ if (isTeeValid) {
715
+ console.log("TEE attestation verified — proof was generated in a secure enclave");
716
+ }
717
+ ```
581
718
 
582
719
  ## Error Handling
583
720
 
@@ -628,6 +765,10 @@ try {
628
765
  - `ProofSubmissionFailedError`: Proof submission to callback failed
629
766
  - `ErrorDuringVerificationError`: An abort error during verification which was caused by the user aborting the verification process or provider's JS script raising a validation error
630
767
 
768
+ ## Example Repos
769
+
770
+ - [Reclaim Demo Website](https://github.com/reclaimprotocol/reclaim-demo-website-v3)
771
+
631
772
  ## Next Steps
632
773
 
633
774
  Explore the [Reclaim Protocol documentation](https://docs.reclaimprotocol.org/) for more advanced features and best practices for integrating the SDK into your production applications.