@zkproofport-app/sdk 0.2.8 → 0.2.9
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 +250 -95
- package/dist/ProofportSDK.d.ts +24 -3
- package/dist/deeplink.d.ts +16 -0
- package/dist/index.esm.js +97 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +97 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +97 -3
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
package/dist/ProofportSDK.d.ts
CHANGED
|
@@ -759,9 +759,29 @@ export declare class ProofportSDK {
|
|
|
759
759
|
*
|
|
760
760
|
* @param circuit - Circuit type identifier
|
|
761
761
|
* @param inputs - Circuit-specific inputs
|
|
762
|
-
* @param options - Request options (message, dappName, dappIcon, nonce)
|
|
762
|
+
* @param options - Request options (message, dappName, dappIcon, nonce, returnScheme)
|
|
763
|
+
* @param options.returnScheme - Which app the ZKProofport app should switch back
|
|
764
|
+
* to once it has finished. Put **your own** deep link scheme here — the bare
|
|
765
|
+
* scheme your app registers, e.g. `'mydapp://'`. A web app can instead pass its
|
|
766
|
+
* own https origin, e.g. `'https://myapp.com'`.
|
|
767
|
+
*
|
|
768
|
+
* This is intentionally **not** a URL and not a return address: no path, query
|
|
769
|
+
* string or fragment is accepted, and the ZKProofport app never sends the proof
|
|
770
|
+
* there. The proof still comes back to you the same way it always did — over the
|
|
771
|
+
* relay, via `waitForProof()` / `waitForResult()`. `returnScheme` only answers
|
|
772
|
+
* "which app should come back to the foreground", exactly like the
|
|
773
|
+
* `redirect.native` value a wallet uses to hand control back after signing.
|
|
774
|
+
*
|
|
775
|
+
* **Omit it and nothing changes** — the user simply stays in the ZKProofport app
|
|
776
|
+
* after the proof and switches back manually. There is no auto-switch on proof
|
|
777
|
+
* failure either; only on success and on the user declining the request.
|
|
778
|
+
*
|
|
779
|
+
* Rejected with an error before the request is sent: empty or whitespace values,
|
|
780
|
+
* anything longer than 128 characters, values containing a path/query/fragment,
|
|
781
|
+
* and the `http:`, `file:`, `data:`, `javascript:`, `intent:`, `tel:`, `sms:`,
|
|
782
|
+
* `mailto:` families.
|
|
763
783
|
* @returns Promise resolving to RelayProofRequest with requestId, deepLink, pollUrl
|
|
764
|
-
* @throws Error if signer not set or relay request fails
|
|
784
|
+
* @throws Error if signer not set, returnScheme is malformed, or the relay request fails
|
|
765
785
|
*
|
|
766
786
|
* @example
|
|
767
787
|
* ```typescript
|
|
@@ -770,7 +790,7 @@ export declare class ProofportSDK {
|
|
|
770
790
|
*
|
|
771
791
|
* const relay = await sdk.createRelayRequest('coinbase_attestation', {
|
|
772
792
|
* scope: 'myapp.com'
|
|
773
|
-
* }, { dappName: 'My DApp' });
|
|
793
|
+
* }, { dappName: 'My DApp', returnScheme: 'mydapp://' });
|
|
774
794
|
*
|
|
775
795
|
* // Generate QR code from relay deep link
|
|
776
796
|
* const qr = await sdk.generateQRCode(relay.deepLink);
|
|
@@ -785,6 +805,7 @@ export declare class ProofportSDK {
|
|
|
785
805
|
dappName?: string;
|
|
786
806
|
dappIcon?: string;
|
|
787
807
|
nonce?: string;
|
|
808
|
+
returnScheme?: string;
|
|
788
809
|
}): Promise<RelayProofRequest>;
|
|
789
810
|
/**
|
|
790
811
|
* Polls the relay for proof result status.
|
package/dist/deeplink.d.ts
CHANGED
|
@@ -187,6 +187,22 @@ export declare function isProofportDeepLink(url: string, scheme?: string): boole
|
|
|
187
187
|
* @returns Error message string, or null when the inputs are valid
|
|
188
188
|
*/
|
|
189
189
|
export declare function validateMdlInputs(circuit: 'mdl_kr_ownership' | 'mdl_kr_age' | 'mdl_kr_region', inputs: CircuitInputs): string | null;
|
|
190
|
+
/**
|
|
191
|
+
* Longest accepted `returnScheme` value.
|
|
192
|
+
* Kept in sync with proofport-relay `src/returnScheme.ts`.
|
|
193
|
+
*/
|
|
194
|
+
export declare const MAX_RETURN_SCHEME_LENGTH = 128;
|
|
195
|
+
/**
|
|
196
|
+
* Validates a `returnScheme` before it is sent to the relay, so a malformed
|
|
197
|
+
* value fails fast in the integrator's own code instead of coming back as a
|
|
198
|
+
* relay 400. The relay re-validates and is the authority.
|
|
199
|
+
*
|
|
200
|
+
* @param value - Candidate return target
|
|
201
|
+
* @returns `null` when acceptable, otherwise a human-readable error message
|
|
202
|
+
*
|
|
203
|
+
* @internal
|
|
204
|
+
*/
|
|
205
|
+
export declare function validateReturnScheme(value: unknown): string | null;
|
|
190
206
|
export declare function validateProofRequest(request: ProofRequest): {
|
|
191
207
|
valid: boolean;
|
|
192
208
|
error?: string;
|
package/dist/index.esm.js
CHANGED
|
@@ -606,6 +606,70 @@ function validateMdlInputs(circuit, inputs) {
|
|
|
606
606
|
}
|
|
607
607
|
return null;
|
|
608
608
|
}
|
|
609
|
+
/**
|
|
610
|
+
* Longest accepted `returnScheme` value.
|
|
611
|
+
* Kept in sync with proofport-relay `src/returnScheme.ts`.
|
|
612
|
+
*/
|
|
613
|
+
const MAX_RETURN_SCHEME_LENGTH = 128;
|
|
614
|
+
/** RFC 3986 scheme (`ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )`) followed by exactly `://`. */
|
|
615
|
+
const BARE_SCHEME_RE = /^[a-z][a-z0-9+.-]*:\/\/$/;
|
|
616
|
+
/** `https://host[:port]` with no userinfo, path, query or fragment. */
|
|
617
|
+
const HTTPS_ORIGIN_RE = /^https:\/\/[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+(:[0-9]{1,5})?$/;
|
|
618
|
+
const DENIED_RETURN_SCHEMES = new Set([
|
|
619
|
+
'about',
|
|
620
|
+
'blob',
|
|
621
|
+
'content',
|
|
622
|
+
'data',
|
|
623
|
+
'facetime',
|
|
624
|
+
'facetime-audio',
|
|
625
|
+
'file',
|
|
626
|
+
'ftp',
|
|
627
|
+
'http',
|
|
628
|
+
'intent',
|
|
629
|
+
'javascript',
|
|
630
|
+
'jar',
|
|
631
|
+
'mailto',
|
|
632
|
+
'sms',
|
|
633
|
+
'tel',
|
|
634
|
+
'vbscript',
|
|
635
|
+
]);
|
|
636
|
+
/**
|
|
637
|
+
* Validates a `returnScheme` before it is sent to the relay, so a malformed
|
|
638
|
+
* value fails fast in the integrator's own code instead of coming back as a
|
|
639
|
+
* relay 400. The relay re-validates and is the authority.
|
|
640
|
+
*
|
|
641
|
+
* @param value - Candidate return target
|
|
642
|
+
* @returns `null` when acceptable, otherwise a human-readable error message
|
|
643
|
+
*
|
|
644
|
+
* @internal
|
|
645
|
+
*/
|
|
646
|
+
function validateReturnScheme(value) {
|
|
647
|
+
if (typeof value !== 'string') {
|
|
648
|
+
return 'returnScheme must be a string';
|
|
649
|
+
}
|
|
650
|
+
if (value.length === 0) {
|
|
651
|
+
return 'returnScheme must not be empty';
|
|
652
|
+
}
|
|
653
|
+
// Length is checked before any regex so a huge string never reaches the matcher.
|
|
654
|
+
if (value.length > MAX_RETURN_SCHEME_LENGTH) {
|
|
655
|
+
return `returnScheme must be at most ${MAX_RETURN_SCHEME_LENGTH} characters`;
|
|
656
|
+
}
|
|
657
|
+
if (/\s/.test(value)) {
|
|
658
|
+
return 'returnScheme must not contain whitespace';
|
|
659
|
+
}
|
|
660
|
+
const normalized = value.toLowerCase();
|
|
661
|
+
if (HTTPS_ORIGIN_RE.test(normalized)) {
|
|
662
|
+
return null;
|
|
663
|
+
}
|
|
664
|
+
if (!BARE_SCHEME_RE.test(normalized)) {
|
|
665
|
+
return 'returnScheme must be a bare custom scheme such as "mydapp://" or an https origin such as "https://myapp.com" — paths, query strings and fragments are not accepted';
|
|
666
|
+
}
|
|
667
|
+
const schemeName = normalized.slice(0, normalized.indexOf(':'));
|
|
668
|
+
if (DENIED_RETURN_SCHEMES.has(schemeName)) {
|
|
669
|
+
return `returnScheme "${schemeName}" is not allowed`;
|
|
670
|
+
}
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
609
673
|
function validateProofRequest(request) {
|
|
610
674
|
if (!request.requestId) {
|
|
611
675
|
return { valid: false, error: 'Missing requestId' };
|
|
@@ -4999,6 +5063,14 @@ class ProofportSDK {
|
|
|
4999
5063
|
throw new Error(`${mdlError} (circuit: ${circuit})`);
|
|
5000
5064
|
}
|
|
5001
5065
|
}
|
|
5066
|
+
// Return target: validated before we burn a challenge, so a typo surfaces
|
|
5067
|
+
// as a local error instead of a relay 400 on the second round trip.
|
|
5068
|
+
if (options.returnScheme !== undefined) {
|
|
5069
|
+
const returnSchemeError = validateReturnScheme(options.returnScheme);
|
|
5070
|
+
if (returnSchemeError) {
|
|
5071
|
+
throw new Error(returnSchemeError);
|
|
5072
|
+
}
|
|
5073
|
+
}
|
|
5002
5074
|
// Get challenge + requestId from relay
|
|
5003
5075
|
const { requestId, challenge } = await this.getChallenge();
|
|
5004
5076
|
const body = {
|
|
@@ -5019,6 +5091,8 @@ class ProofportSDK {
|
|
|
5019
5091
|
body.dappIcon = options.dappIcon;
|
|
5020
5092
|
if (options.nonce)
|
|
5021
5093
|
body.nonce = options.nonce;
|
|
5094
|
+
if (options.returnScheme)
|
|
5095
|
+
body.returnScheme = options.returnScheme;
|
|
5022
5096
|
const response = await fetch(`${this.relayUrl}/api/v1/proof/request`, {
|
|
5023
5097
|
method: 'POST',
|
|
5024
5098
|
headers: {
|
|
@@ -5319,9 +5393,29 @@ class ProofportSDK {
|
|
|
5319
5393
|
*
|
|
5320
5394
|
* @param circuit - Circuit type identifier
|
|
5321
5395
|
* @param inputs - Circuit-specific inputs
|
|
5322
|
-
* @param options - Request options (message, dappName, dappIcon, nonce)
|
|
5396
|
+
* @param options - Request options (message, dappName, dappIcon, nonce, returnScheme)
|
|
5397
|
+
* @param options.returnScheme - Which app the ZKProofport app should switch back
|
|
5398
|
+
* to once it has finished. Put **your own** deep link scheme here — the bare
|
|
5399
|
+
* scheme your app registers, e.g. `'mydapp://'`. A web app can instead pass its
|
|
5400
|
+
* own https origin, e.g. `'https://myapp.com'`.
|
|
5401
|
+
*
|
|
5402
|
+
* This is intentionally **not** a URL and not a return address: no path, query
|
|
5403
|
+
* string or fragment is accepted, and the ZKProofport app never sends the proof
|
|
5404
|
+
* there. The proof still comes back to you the same way it always did — over the
|
|
5405
|
+
* relay, via `waitForProof()` / `waitForResult()`. `returnScheme` only answers
|
|
5406
|
+
* "which app should come back to the foreground", exactly like the
|
|
5407
|
+
* `redirect.native` value a wallet uses to hand control back after signing.
|
|
5408
|
+
*
|
|
5409
|
+
* **Omit it and nothing changes** — the user simply stays in the ZKProofport app
|
|
5410
|
+
* after the proof and switches back manually. There is no auto-switch on proof
|
|
5411
|
+
* failure either; only on success and on the user declining the request.
|
|
5412
|
+
*
|
|
5413
|
+
* Rejected with an error before the request is sent: empty or whitespace values,
|
|
5414
|
+
* anything longer than 128 characters, values containing a path/query/fragment,
|
|
5415
|
+
* and the `http:`, `file:`, `data:`, `javascript:`, `intent:`, `tel:`, `sms:`,
|
|
5416
|
+
* `mailto:` families.
|
|
5323
5417
|
* @returns Promise resolving to RelayProofRequest with requestId, deepLink, pollUrl
|
|
5324
|
-
* @throws Error if signer not set or relay request fails
|
|
5418
|
+
* @throws Error if signer not set, returnScheme is malformed, or the relay request fails
|
|
5325
5419
|
*
|
|
5326
5420
|
* @example
|
|
5327
5421
|
* ```typescript
|
|
@@ -5330,7 +5424,7 @@ class ProofportSDK {
|
|
|
5330
5424
|
*
|
|
5331
5425
|
* const relay = await sdk.createRelayRequest('coinbase_attestation', {
|
|
5332
5426
|
* scope: 'myapp.com'
|
|
5333
|
-
* }, { dappName: 'My DApp' });
|
|
5427
|
+
* }, { dappName: 'My DApp', returnScheme: 'mydapp://' });
|
|
5334
5428
|
*
|
|
5335
5429
|
* // Generate QR code from relay deep link
|
|
5336
5430
|
* const qr = await sdk.generateQRCode(relay.deepLink);
|