@reclaimprotocol/js-sdk 5.0.0-dev.1 → 5.0.0-dev.3
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 +228 -46
- package/dist/index.d.ts +360 -60
- package/dist/index.js +1427 -270
- package/dist/index.js.map +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -99,7 +99,7 @@ function App() {
|
|
|
99
99
|
setProofs(proofs);
|
|
100
100
|
}
|
|
101
101
|
},
|
|
102
|
-
|
|
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
|
-
|
|
184
|
+
onError: (error) => {
|
|
185
185
|
console.error("Verification failed", error);
|
|
186
186
|
},
|
|
187
187
|
});
|
|
@@ -193,17 +193,57 @@ async function handleCreateClaim() {
|
|
|
193
193
|
|
|
194
194
|
### How triggerReclaimFlow() Works
|
|
195
195
|
|
|
196
|
-
The `triggerReclaimFlow()` method
|
|
196
|
+
The `triggerReclaimFlow()` method supports two verification modes via `verificationMode`:
|
|
197
|
+
|
|
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:
|
|
202
|
+
|
|
203
|
+
```javascript
|
|
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
|
|
216
|
+
|
|
217
|
+
// Verifier app flow
|
|
218
|
+
const handle = await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
|
|
219
|
+
handle.close(); // stop polling
|
|
220
|
+
```
|
|
197
221
|
|
|
198
222
|
#### On Desktop Browsers:
|
|
199
223
|
|
|
200
|
-
1. **
|
|
201
|
-
2. **
|
|
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.
|
|
228
|
+
|
|
229
|
+
#### On Mobile Devices (portal mode):
|
|
230
|
+
|
|
231
|
+
Opens the portal in a new tab, or in an iframe if `target` is provided.
|
|
202
232
|
|
|
203
|
-
#### On Mobile Devices:
|
|
233
|
+
#### On Mobile Devices (app mode):
|
|
204
234
|
|
|
205
|
-
1. **
|
|
206
|
-
2. **
|
|
235
|
+
1. **All platforms**: Redirects to the verifier app.
|
|
236
|
+
2. **iOS with `useAppClip: true`**: Redirects to the Reclaim App Clip instead.
|
|
237
|
+
|
|
238
|
+
The same `verificationMode` option works with `getRequestUrl()`:
|
|
239
|
+
|
|
240
|
+
```javascript
|
|
241
|
+
// Portal URL (default)
|
|
242
|
+
const url = await reclaimProofRequest.getRequestUrl();
|
|
243
|
+
|
|
244
|
+
// Verifier app URL
|
|
245
|
+
const url = await reclaimProofRequest.getRequestUrl({ verificationMode: 'app' });
|
|
246
|
+
```
|
|
207
247
|
|
|
208
248
|
### Browser Extension Support
|
|
209
249
|
|
|
@@ -264,10 +304,10 @@ await reclaimProofRequest.triggerReclaimFlow();
|
|
|
264
304
|
### Benefits of the New Flow:
|
|
265
305
|
|
|
266
306
|
1. **Platform Adaptive**: Automatically chooses the best verification method for each platform
|
|
267
|
-
2. **
|
|
268
|
-
3. **
|
|
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
|
|
269
309
|
4. **Extension Support**: Leverages browser extension for desktop users when available
|
|
270
|
-
5. **Mobile Optimized**:
|
|
310
|
+
5. **Mobile Optimized**: Verifier app experiences on mobile devices
|
|
271
311
|
|
|
272
312
|
## Step 6: Run your application
|
|
273
313
|
|
|
@@ -289,7 +329,7 @@ Your Reclaim SDK demo should now be running. Click the "Create Claim" button to
|
|
|
289
329
|
|
|
290
330
|
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
331
|
|
|
292
|
-
5. **Handling Failures**: The `
|
|
332
|
+
5. **Handling Failures**: The `onError` is called if verification fails, allowing you to handle errors gracefully.
|
|
293
333
|
|
|
294
334
|
## Advanced Configuration
|
|
295
335
|
|
|
@@ -324,17 +364,17 @@ Redirection with body:
|
|
|
324
364
|
|
|
325
365
|
- **url**: The URL where users should be redirected after successful proof generation.
|
|
326
366
|
- **method** (optional): The redirection method to use. Allowed options: `GET` (default) and `POST`.
|
|
327
|
-
*Note: `POST` form redirection is only supported in
|
|
367
|
+
*Note: `POST` form redirection is only supported in Portal flow.*
|
|
328
368
|
- **body** (optional): List of name-value pairs to be sent as the body of the form request.
|
|
329
369
|
- When `method` is `POST`, `body` is sent with `application/x-www-form-urlencoded` content type.
|
|
330
370
|
- When `method` is `GET`, if `body` is set, it is sent as query parameters.
|
|
331
|
-
*Note: Sending `body` on redirection is only supported in
|
|
371
|
+
*Note: Sending `body` on redirection is only supported in Portal flow.*
|
|
332
372
|
|
|
333
373
|
```javascript
|
|
334
374
|
reclaimProofRequest.setRedirectUrl(
|
|
335
375
|
"https://example.com/redirect",
|
|
336
|
-
"POST", //
|
|
337
|
-
[{ name: "foo", value: "bar" }] //
|
|
376
|
+
"POST", // Portal flow only
|
|
377
|
+
[{ name: "foo", value: "bar" }] // Portal flow only
|
|
338
378
|
);
|
|
339
379
|
```
|
|
340
380
|
|
|
@@ -350,17 +390,17 @@ Redirection with body:
|
|
|
350
390
|
|
|
351
391
|
- **url**: The URL where users should be redirected after an error which aborts the verification process.
|
|
352
392
|
- **method** (optional): The redirection method to use. Allowed options: `GET` (default) and `POST`.
|
|
353
|
-
*Note: `POST` form redirection is only supported in
|
|
393
|
+
*Note: `POST` form redirection is only supported in Portal flow.*
|
|
354
394
|
- **body** (optional): List of name-value pairs to be sent as the body of the form request.
|
|
355
395
|
- When `method` is `POST`, `body` is sent with `application/x-www-form-urlencoded` content type.
|
|
356
396
|
- When `method` is `GET`, if `body` is set, it is sent as query parameters.
|
|
357
|
-
*Note: Sending `body` on redirection is only supported in
|
|
397
|
+
*Note: Sending `body` on redirection is only supported in Portal flow.*
|
|
358
398
|
|
|
359
399
|
```javascript
|
|
360
400
|
reclaimProofRequest.setCancelRedirectUrl(
|
|
361
401
|
"https://example.com/error-redirect",
|
|
362
|
-
"POST", //
|
|
363
|
-
[{ name: "error_code", value: "1001" }] //
|
|
402
|
+
"POST", // Portal flow only
|
|
403
|
+
[{ name: "error_code", value: "1001" }] // Portal flow only
|
|
364
404
|
);
|
|
365
405
|
```
|
|
366
406
|
|
|
@@ -371,6 +411,7 @@ reclaimProofRequest.setCancelRedirectUrl(
|
|
|
371
411
|
|
|
372
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`.
|
|
373
413
|
|
|
414
|
+
```javascript
|
|
374
415
|
reclaimProofRequest.setAppCallbackUrl("https://example.com/callback", true);
|
|
375
416
|
```
|
|
376
417
|
|
|
@@ -431,33 +472,51 @@ For more details about response format, check out [official documentation of Err
|
|
|
431
472
|
const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
|
|
432
473
|
useBrowserExtension: true, // Enable browser extension support (default: true)
|
|
433
474
|
extensionID: "custom-extension-id", // Custom extension identifier
|
|
434
|
-
useAppClip:
|
|
475
|
+
useAppClip: false, // Enable mobile app clips (default: false)
|
|
435
476
|
log: true, // Enable troubleshooting mode and more verbose logging for debugging
|
|
436
477
|
});
|
|
437
478
|
```
|
|
438
479
|
|
|
439
|
-
9. **Custom
|
|
440
|
-
You can customize the share page and app clip URLs for your app:
|
|
480
|
+
9. **Custom Portal URL and App Clip URLs**:
|
|
481
|
+
You can customize the portal/share page and app clip URLs for your app:
|
|
441
482
|
|
|
442
483
|
```javascript
|
|
443
484
|
const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
|
|
444
|
-
|
|
485
|
+
portalUrl: "https://your-custom-domain.com/verify", // Custom URL for both portal and app modes
|
|
445
486
|
customAppClipUrl: "https://appclip.apple.com/id?p=your.custom.app.clip", // Custom iOS App Clip URL
|
|
446
487
|
// ... other options
|
|
447
488
|
});
|
|
448
489
|
```
|
|
449
490
|
|
|
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`.
|
|
496
|
+
|
|
450
497
|
10. **Platform-Specific Flow Control**:
|
|
451
|
-
|
|
498
|
+
Both `triggerReclaimFlow()` and `getRequestUrl()` support `verificationMode`:
|
|
452
499
|
|
|
453
500
|
```javascript
|
|
454
|
-
//
|
|
455
|
-
const
|
|
456
|
-
//
|
|
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
|
|
457
512
|
|
|
458
|
-
//
|
|
459
|
-
await reclaimProofRequest.triggerReclaimFlow();
|
|
460
|
-
//
|
|
513
|
+
// Verifier app flow
|
|
514
|
+
const handle = await reclaimProofRequest.triggerReclaimFlow({ verificationMode: 'app' });
|
|
515
|
+
handle.close(); // stop polling
|
|
516
|
+
|
|
517
|
+
// getRequestUrl also supports verificationMode
|
|
518
|
+
const portalUrl = await reclaimProofRequest.getRequestUrl();
|
|
519
|
+
const appUrl = await reclaimProofRequest.getRequestUrl({ verificationMode: 'app' });
|
|
461
520
|
```
|
|
462
521
|
|
|
463
522
|
11. **Exporting and Importing SDK Configuration**:
|
|
@@ -550,34 +609,153 @@ These options allow you to securely process proofs or cancellations on your serv
|
|
|
550
609
|
|
|
551
610
|
## Proof Verification
|
|
552
611
|
|
|
553
|
-
The SDK provides a `verifyProof` function to manually verify proofs. This
|
|
612
|
+
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.
|
|
613
|
+
|
|
614
|
+
Here are the possible ways to use `verifyProof`, from beginner to advanced:
|
|
615
|
+
|
|
616
|
+
### 1. Simple 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:
|
|
554
618
|
|
|
555
619
|
```javascript
|
|
556
620
|
import { verifyProof } from "@reclaimprotocol/js-sdk";
|
|
557
621
|
|
|
558
|
-
//
|
|
559
|
-
const
|
|
560
|
-
|
|
622
|
+
// Using getProviderVersion() — recommended
|
|
623
|
+
const providerVersion = reclaimProofRequest.getProviderVersion();
|
|
624
|
+
const { isVerified, data, error } = await verifyProof(proof, providerVersion);
|
|
625
|
+
if (isVerified) {
|
|
561
626
|
console.log("Proof is valid");
|
|
627
|
+
console.log("Context:", data[0].context);
|
|
628
|
+
console.log("Extracted parameters:", data[0].extractedParameters);
|
|
562
629
|
} else {
|
|
563
|
-
console.log("Proof is invalid");
|
|
630
|
+
console.log("Proof is invalid, reason:", error);
|
|
631
|
+
}
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
Or, by manually providing the provider details:
|
|
635
|
+
```javascript
|
|
636
|
+
const { isVerified, data } = await verifyProof(proof, {
|
|
637
|
+
providerId: "YOUR_PROVIDER_ID",
|
|
638
|
+
// The exact provider version used in the session.
|
|
639
|
+
providerVersion: "1.0.0",
|
|
640
|
+
// Optionally provide tags. For example, this can be `['ai']` when you want to allow patches from ai.
|
|
641
|
+
allowedTags: ["ai"]
|
|
642
|
+
});
|
|
643
|
+
```
|
|
644
|
+
|
|
645
|
+
Or, with a known hash:
|
|
646
|
+
```javascript
|
|
647
|
+
const { isVerified, data, error } = await verifyProof(proof, { hashes: ['0xAbC...'] });
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### 2. Intermediate: Strict Hash Verification
|
|
651
|
+
|
|
652
|
+
If you want to avoid network requests, you can manually feed the expected cryptographic hashes your system allows.
|
|
653
|
+
|
|
654
|
+
```javascript
|
|
655
|
+
// Verify a proof against a known, strict expected hash
|
|
656
|
+
const { isVerified, data } = await verifyProof(proof, {
|
|
657
|
+
hashes: ['0x1abc2def3456...']
|
|
658
|
+
});
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### 3. Advanced: Multiple Proofs and Optional Matches
|
|
662
|
+
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).
|
|
663
|
+
|
|
664
|
+
```javascript
|
|
665
|
+
const result = await verifyProof([proof1, proof2, sameAsProof2], {
|
|
666
|
+
hashes: [
|
|
667
|
+
// A string hash is equivalent to an object with { value: '...', required: true, multiple: true }.
|
|
668
|
+
'0xStrictHash123...',
|
|
669
|
+
{
|
|
670
|
+
// An array 'value' means that 1 proof can have any 1 matching hash
|
|
671
|
+
// from this list, typically because of optional variables in the original request.
|
|
672
|
+
value: ['0xOptHash1...', '0xOptHashA...'],
|
|
673
|
+
// 'multiple' being true (which is the default) means any proof matching this hash
|
|
674
|
+
// is allowed to appear multiple times in the list of proofs you are verifying.
|
|
675
|
+
multiple: true
|
|
676
|
+
},
|
|
677
|
+
{
|
|
678
|
+
value: '0xE33...',
|
|
679
|
+
// 'required: false' means there can be 0 proofs matching this hash.
|
|
680
|
+
// Such proofs may be optionally present in the list of proofs.
|
|
681
|
+
// (By default, 'required' is true).
|
|
682
|
+
required: false
|
|
683
|
+
}
|
|
684
|
+
]
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
if (result.isVerified) {
|
|
688
|
+
result.data.forEach((d, i) => {
|
|
689
|
+
console.log(`Proof ${i + 1} context:`, d.context);
|
|
690
|
+
console.log(`Proof ${i + 1} params:`, d.extractedParameters);
|
|
691
|
+
});
|
|
564
692
|
}
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### 4. Danger Zone: Disabled Content Validation
|
|
696
|
+
If you only want to verify the attestor signature but wish to dangerously bypass the parameter/content match (Not Recommended):
|
|
697
|
+
|
|
698
|
+
```javascript
|
|
699
|
+
const { isVerified } = await verifyProof(proof, {
|
|
700
|
+
dangerouslyDisableContentValidation: true
|
|
701
|
+
});
|
|
702
|
+
```
|
|
703
|
+
|
|
704
|
+
## TEE Attestation Verification
|
|
705
|
+
|
|
706
|
+
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).
|
|
707
|
+
|
|
708
|
+
### Enabling TEE Attestation
|
|
709
|
+
|
|
710
|
+
To request TEE attestation during proof generation, enable it during initialization:
|
|
565
711
|
|
|
566
|
-
|
|
567
|
-
const
|
|
568
|
-
|
|
569
|
-
|
|
712
|
+
```javascript
|
|
713
|
+
const proofRequest = await ReclaimProofRequest.init(APP_ID, APP_SECRET, PROVIDER_ID, {
|
|
714
|
+
acceptTeeAttestation: true,
|
|
715
|
+
});
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### Verifying TEE Attestation
|
|
719
|
+
|
|
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`.
|
|
721
|
+
|
|
722
|
+
```javascript
|
|
723
|
+
import { verifyProof, TeeVerificationError } from "@reclaimprotocol/js-sdk";
|
|
724
|
+
|
|
725
|
+
// Set verifyTEE in config to require TEE verification
|
|
726
|
+
const { isVerified, isTeeVerified, data, error } = await verifyProof(proof, { hashes: ['0xAbC...'], verifyTEE: true });
|
|
727
|
+
|
|
728
|
+
if (isVerified) {
|
|
729
|
+
console.log("Proof is fully verified with hardware attestation");
|
|
730
|
+
console.log("TEE verified:", isTeeVerified);
|
|
731
|
+
console.log("Extracted parameters:", data[0].extractedParameters);
|
|
732
|
+
} else if (error instanceof TeeVerificationError) {
|
|
733
|
+
console.log("TEE verification failed:", error.message);
|
|
570
734
|
} else {
|
|
571
|
-
console.log("
|
|
735
|
+
console.log("Proof verification failed:", error);
|
|
572
736
|
}
|
|
573
737
|
```
|
|
574
738
|
|
|
575
|
-
The `
|
|
739
|
+
When `verifyTEE` is `true`, the result includes `isTeeVerified`. The overall `isVerified` will be `false` if TEE data is missing or TEE verification fails.
|
|
740
|
+
|
|
741
|
+
The TEE verification validates:
|
|
742
|
+
- **Nonce binding**: Ensures the attestation nonce matches the proof context
|
|
743
|
+
- **Application ID**: Confirms the attestation was generated for your application (optional)
|
|
744
|
+
- **Timestamp**: Verifies the attestation timestamp is within an acceptable range of the proof timestamp
|
|
745
|
+
- **SNP report**: Validates the AMD SEV-SNP hardware attestation report
|
|
746
|
+
- **VLEK certificate**: Verifies the certificate chain against AMD's root of trust
|
|
747
|
+
- **Report data**: Confirms the workload and verifier digests match the attestation
|
|
576
748
|
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
749
|
+
You can also verify TEE attestation separately using the lower-level `verifyTeeAttestation` function:
|
|
750
|
+
|
|
751
|
+
```javascript
|
|
752
|
+
import { verifyTeeAttestation } from "@reclaimprotocol/js-sdk";
|
|
753
|
+
|
|
754
|
+
const isTeeValid = await verifyTeeAttestation(proof, APP_ID);
|
|
755
|
+
if (isTeeValid) {
|
|
756
|
+
console.log("TEE attestation verified — proof was generated in a secure enclave");
|
|
757
|
+
}
|
|
758
|
+
```
|
|
581
759
|
|
|
582
760
|
## Error Handling
|
|
583
761
|
|
|
@@ -628,6 +806,10 @@ try {
|
|
|
628
806
|
- `ProofSubmissionFailedError`: Proof submission to callback failed
|
|
629
807
|
- `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
808
|
|
|
809
|
+
## Example Repos
|
|
810
|
+
|
|
811
|
+
- [Reclaim Demo Website](https://github.com/reclaimprotocol/reclaim-demo-website-v3)
|
|
812
|
+
|
|
631
813
|
## Next Steps
|
|
632
814
|
|
|
633
815
|
Explore the [Reclaim Protocol documentation](https://docs.reclaimprotocol.org/) for more advanced features and best practices for integrating the SDK into your production applications.
|