@zkproofport-app/sdk 0.5.0-beta.2 → 0.5.0-beta.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 +11 -3
- package/dist/ProofportSDK.d.ts +30 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +85 -13
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +120 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +85 -13
- package/dist/index.mjs.map +1 -1
- package/dist/offChainVerifier.d.ts +12 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -784,7 +784,9 @@ Verify the proof cryptographically by calling the deployed Solidity verifier con
|
|
|
784
784
|
|
|
785
785
|
`verifyResponseOnChain` checks the proof against the verifier contract the SDK ships with for that circuit. Which contract judges a proof is never taken from the proof's own response: the SDK carries the deployed verifiers, generated from the circuits' deployment records, and a response whose `verifierAddress` or `chainId` differs from them is refused rather than checked elsewhere. If you configure your own verifier in the SDK's `verifiers` option, that one is used instead.
|
|
786
786
|
|
|
787
|
-
For OIDC domain proofs the SDK
|
|
787
|
+
For OIDC domain proofs the SDK first checks what the proof says about the sign-in token: it must have been issued to a ZKProofport sign-in client (not to some other website), the proof must have been made within the last 15 minutes (and not more than 5 minutes ahead of your clock), and a proof made by the ZKProofport app must carry the nonce of **your** request — so a proof made for another request cannot be replayed as the answer to yours. For a request you created with `createRelayRequest` on the same SDK instance this happens automatically. If you verify in a different process (or after a restart), pass the request back: `sdk.verifyResponseOnChain(response, provider, { request: { scope, requestId } })`, with the scope you requested and the `requestId` the relay returned; without it an OIDC response is refused. `verifyOnChain` and `verifyResponseOffChain` take the same `request` option.
|
|
788
|
+
|
|
789
|
+
The SDK also checks that the proof was made with a signing key Google or Microsoft actually publishes. That key is part of the proof's public inputs, so a proof made with a self-generated key would otherwise pass the contract. The SDK fetches the provider's published keys, caches them as the provider's own cache headers allow, and returns `{ valid: false, error }` when the key is not among them or the keys cannot be fetched. Every verify method does this; there is nothing to call separately.
|
|
788
790
|
|
|
789
791
|
For Coinbase KYC, Coinbase country and GIWA proofs the SDK checks that the attestation's signer belongs to the published signer set: the proof carries the root of the signer list it was made against, and a proof made against any other list is refused with `{ valid: false, error }`. This too runs in every verify method.
|
|
790
792
|
|
|
@@ -932,7 +934,7 @@ import {
|
|
|
932
934
|
const scope = extractScopeFromPublicInputs(publicInputs, 'coinbase_attestation');
|
|
933
935
|
const nullifier = extractNullifierFromPublicInputs(publicInputs, 'coinbase_attestation');
|
|
934
936
|
|
|
935
|
-
// OIDC domain attestation uses a different public input layout (
|
|
937
|
+
// OIDC domain attestation uses a different public input layout (214 fields)
|
|
936
938
|
const oidcScope = extractScopeFromPublicInputs(publicInputs, 'oidc_domain_attestation');
|
|
937
939
|
const oidcNullifier = extractNullifierFromPublicInputs(publicInputs, 'oidc_domain_attestation');
|
|
938
940
|
|
|
@@ -1156,7 +1158,7 @@ const signalHash = toBytes32(publicInputs.slice(L.SIGNAL_HASH_START, L.SIGNAL_HA
|
|
|
1156
1158
|
|
|
1157
1159
|
The country list and the `is_included` flag are public inputs, which means the proof is only as strong as the list it was proved against. Read indices 64–85 back and confirm they are the list and the direction you asked for; a valid proof against a different list is still a valid proof.
|
|
1158
1160
|
|
|
1159
|
-
### `oidc_domain_attestation` —
|
|
1161
|
+
### `oidc_domain_attestation` — 214 entries
|
|
1160
1162
|
|
|
1161
1163
|
| Index | Constants | Circuit field | What it is |
|
|
1162
1164
|
|-------|-----------|---------------|------------|
|
|
@@ -1166,6 +1168,12 @@ The country list and the `is_included` flag are public inputs, which means the p
|
|
|
1166
1168
|
| 83–114 | `SCOPE_START` / `_END` | `scope` | `bytes32` scope hash |
|
|
1167
1169
|
| 115–146 | `NULLIFIER_START` / `_END` | `nullifier` | `bytes32` over the user's email and the scope |
|
|
1168
1170
|
| 147 | `PROVIDER` | `provider` | `0` = Google, `1` = Microsoft. The circuit accepts no other value |
|
|
1171
|
+
| 148–179 | `AUD_HASH_START` / `_END` | `aud_hash` | keccak256 of the ID token's `aud` (the sign-in client it was issued to) |
|
|
1172
|
+
| 180 | `NONCE_MODE` | `nonce_mode` | `1` = the token's nonce is bound to your request, `0` = no nonce (agent device sign-in) |
|
|
1173
|
+
| 181–212 | `NONCE_BINDING_START` / `_END` | `nonce_binding` | In mode `1`, keccak256("zkproofport-oidc-v1" ‖ keccak256(scope) ‖ requestId); all zero in mode `0` |
|
|
1174
|
+
| 213 | `NOW` | `now` | Unix seconds the proof was made at; the circuit proves the token was valid then |
|
|
1175
|
+
|
|
1176
|
+
Proofs from the earlier 148-entry version of this circuit bind no audience, expiry or nonce and are refused by every verify method.
|
|
1169
1177
|
|
|
1170
1178
|
`DOMAIN_START` and `DOMAIN_END` are kept as deprecated aliases of `DOMAIN_STORAGE_START` and `DOMAIN_LEN`. Use the current names — the old pair reads as a range and is not one.
|
|
1171
1179
|
|
package/dist/ProofportSDK.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import type { ProofRequest, ProofResponse, CircuitType, CircuitInputs, ProofportConfig, QRCodeOptions, ChallengeResponse, WalletSigner, RelayProofRequest, RelayProofResult } from './types';
|
|
5
5
|
import { type OffChainVerifyOptions } from './offChainVerifier';
|
|
6
|
+
import { type OidcRequestContext } from './verifier';
|
|
6
7
|
import type { SDKEnvironment } from './types';
|
|
7
8
|
/**
|
|
8
9
|
* Main SDK class for interacting with the ZKProofport mobile app.
|
|
@@ -41,6 +42,15 @@ import type { SDKEnvironment } from './types';
|
|
|
41
42
|
export declare class ProofportSDK {
|
|
42
43
|
private config;
|
|
43
44
|
private pendingRequests;
|
|
45
|
+
/**
|
|
46
|
+
* requestId -> scope of the relay requests this instance created, so that
|
|
47
|
+
* verifyResponse* can check an OIDC proof's request-bound nonce without the
|
|
48
|
+
* dApp passing the request back in. Oldest entries go first past
|
|
49
|
+
* {@link ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS}.
|
|
50
|
+
*/
|
|
51
|
+
private relayRequests;
|
|
52
|
+
/** Bound on {@link relayRequests}; a dApp that verifies later can pass the request explicitly. */
|
|
53
|
+
static readonly MAX_REMEMBERED_RELAY_REQUESTS = 1000;
|
|
44
54
|
private signer;
|
|
45
55
|
private relayUrl;
|
|
46
56
|
private socket;
|
|
@@ -497,10 +507,23 @@ export declare class ProofportSDK {
|
|
|
497
507
|
* }
|
|
498
508
|
* ```
|
|
499
509
|
*/
|
|
500
|
-
verifyOnChain(circuit: CircuitType, proof: string, publicInputs: string[], providerOrSigner?: any
|
|
510
|
+
verifyOnChain(circuit: CircuitType, proof: string, publicInputs: string[], providerOrSigner?: any, options?: {
|
|
511
|
+
request?: OidcRequestContext;
|
|
512
|
+
}): Promise<{
|
|
501
513
|
valid: boolean;
|
|
502
514
|
error?: string;
|
|
503
515
|
}>;
|
|
516
|
+
/**
|
|
517
|
+
* The request an `oidc_domain_attestation` response answers: the one the
|
|
518
|
+
* caller passed, else the relay request this instance created under the
|
|
519
|
+
* response's requestId. `{ error }` when there is none, or when the two
|
|
520
|
+
* disagree -- an OIDC proof made with a request-bound nonce is only
|
|
521
|
+
* meaningful against the request it was bound to, so a response this SDK
|
|
522
|
+
* cannot place is refused rather than checked without it.
|
|
523
|
+
*/
|
|
524
|
+
private oidcRequestFor;
|
|
525
|
+
/** @internal Remember a relay request's scope for verifyResponse*. */
|
|
526
|
+
private rememberRelayRequest;
|
|
504
527
|
/**
|
|
505
528
|
* The verifier for a circuit: the one the dApp configured, otherwise the
|
|
506
529
|
* pinned deployment on the chain this SDK's environment verifies that
|
|
@@ -516,6 +539,9 @@ export declare class ProofportSDK {
|
|
|
516
539
|
*
|
|
517
540
|
* @param response - ProofResponse object from parseResponse()
|
|
518
541
|
* @param providerOrSigner - ethers v6 Provider or Signer (defaults to base mainnet public RPC)
|
|
542
|
+
* @param options.request - For `oidc_domain_attestation`: the `{ scope, requestId }`
|
|
543
|
+
* the response answers. Not needed for a relay request this SDK instance
|
|
544
|
+
* created; an OIDC response this instance cannot place is refused without it.
|
|
519
545
|
*
|
|
520
546
|
* @returns Promise resolving to verification result with valid boolean and optional error message
|
|
521
547
|
*
|
|
@@ -542,7 +568,9 @@ export declare class ProofportSDK {
|
|
|
542
568
|
* });
|
|
543
569
|
* ```
|
|
544
570
|
*/
|
|
545
|
-
verifyResponseOnChain(response: ProofResponse, providerOrSigner?: any
|
|
571
|
+
verifyResponseOnChain(response: ProofResponse, providerOrSigner?: any, options?: {
|
|
572
|
+
request?: OidcRequestContext;
|
|
573
|
+
}): Promise<{
|
|
546
574
|
valid: boolean;
|
|
547
575
|
error?: string;
|
|
548
576
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export { verifyProofOffChain } from './offChainVerifier';
|
|
|
32
32
|
export type { OffChainVerifyResult, OffChainVerifyOptions, } from './offChainVerifier';
|
|
33
33
|
export { PINNED_VERIFIERS, getPinnedVerifier } from './verifier';
|
|
34
34
|
export type { PinnedVerifier } from './verifier';
|
|
35
|
+
export { checkOidcPolicy, deriveOidcNonceBinding, oidcAudienceHash, OIDC_ALLOWED_AUDIENCES, OIDC_NONCE_DOMAIN, OIDC_NOW_MAX_AGE_SECONDS, OIDC_NOW_MAX_FUTURE_SECONDS, OIDC_V1_PUBLIC_INPUT_COUNT, OIDC_V2_PUBLIC_INPUT_COUNT, } from './verifier';
|
|
36
|
+
export type { OidcRequestContext, OidcAudience, OidcNonceMode } from './verifier';
|
|
35
37
|
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT, OIDC_DOMAIN_ATTESTATION_PUBLIC_INPUT_LAYOUT, MDL_KR_PUBLIC_INPUT_LAYOUT, } from './constants';
|
|
36
38
|
export type { CircuitId, CircuitSupportStatus } from './circuits';
|
|
37
39
|
export { CIRCUIT_ACTION_BINDING, circuitActionBinding, } from './circuits';
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { checkProofIssuer, parseProofForOnChain, verifyProofOnChain, getPinnedVerifier, extractScopeFromPublicInputs, extractNullifierFromPublicInputs, extractDomainFromPublicInputs } from '@zkproofport-app/core';
|
|
2
|
-
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT, MDL_KR_PUBLIC_INPUT_LAYOUT, OIDC_DOMAIN_ATTESTATION_PUBLIC_INPUT_LAYOUT, PINNED_VERIFIERS, extractDomainFromPublicInputs, extractNullifierFromPublicInputs, extractScopeFromPublicInputs, getPinnedVerifier } from '@zkproofport-app/core';
|
|
2
|
+
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT, MDL_KR_PUBLIC_INPUT_LAYOUT, OIDC_ALLOWED_AUDIENCES, OIDC_DOMAIN_ATTESTATION_PUBLIC_INPUT_LAYOUT, OIDC_NONCE_DOMAIN, OIDC_NOW_MAX_AGE_SECONDS, OIDC_NOW_MAX_FUTURE_SECONDS, OIDC_V1_PUBLIC_INPUT_COUNT, OIDC_V2_PUBLIC_INPUT_COUNT, PINNED_VERIFIERS, checkOidcPolicy, deriveOidcNonceBinding, extractDomainFromPublicInputs, extractNullifierFromPublicInputs, extractScopeFromPublicInputs, getPinnedVerifier, oidcAudienceHash } from '@zkproofport-app/core';
|
|
3
3
|
import { isCircuitId, ALL_CIRCUIT_IDS, circuitActionBinding, CIRCUIT_VK_PATHS, CIRCUIT_NEEDS_WALLET_SIGNATURE } from '@zkproofport-app/core/circuits';
|
|
4
4
|
export { ALL_CIRCUIT_IDS, CIRCUIT_ACTION_BINDING, CIRCUIT_IDS, CIRCUIT_SUPPORT_STATUS, CIRCUIT_VK_PATHS, EXPERIMENTAL_CIRCUIT_IDS, PLANNED_CIRCUIT_IDS, SUPPORTED_CIRCUIT_IDS, circuitActionBinding, getCircuitSupportStatus, isCircuitId, isSupportedCircuitId } from '@zkproofport-app/core/circuits';
|
|
5
5
|
import { validateTypedAction } from '@zkproofport-app/core/typedAction';
|
|
@@ -124,8 +124,10 @@ const CIRCUIT_METADATA = {
|
|
|
124
124
|
oidc_domain_attestation: {
|
|
125
125
|
name: 'OIDC Domain',
|
|
126
126
|
description: 'Prove email domain affiliation via OIDC JWT',
|
|
127
|
-
|
|
128
|
-
|
|
127
|
+
// v2: 148 v1 fields, then aud_hash (32), nonce_mode (1), nonce_binding
|
|
128
|
+
// (32), now (1). oidc-domain-attestation/src/main.nr.
|
|
129
|
+
publicInputsCount: 214,
|
|
130
|
+
publicInputNames: ['pubkey_modulus_limbs', 'domain', 'scope', 'nullifier', 'provider', 'aud_hash', 'nonce_mode', 'nonce_binding', 'now'],
|
|
129
131
|
},
|
|
130
132
|
// Planned circuit — the identifier is reserved and the circuit exists, but it
|
|
131
133
|
// is not officially supported yet. See CIRCUIT_SUPPORT_STATUS in ./circuits.
|
|
@@ -4006,9 +4008,11 @@ async function fetchVerificationKey(circuit, timeoutMs) {
|
|
|
4006
4008
|
* Needs no setup from the caller: the verifier ships with this SDK and is
|
|
4007
4009
|
* loaded on first use.
|
|
4008
4010
|
*
|
|
4009
|
-
* For `oidc_domain_attestation` it first checks the
|
|
4010
|
-
*
|
|
4011
|
-
*
|
|
4011
|
+
* For `oidc_domain_attestation` it first checks the token's audience, nonce and
|
|
4012
|
+
* time (core's `checkOidcPolicy`, against `options.request` when given) and the
|
|
4013
|
+
* proof's RSA key against the provider's published JWKS (core's
|
|
4014
|
+
* `checkOidcProviderKey`); any refusal, or a JWKS that cannot be fetched, is
|
|
4015
|
+
* `{ valid: false }`.
|
|
4012
4016
|
*
|
|
4013
4017
|
* @param circuit - Canonical circuit identifier
|
|
4014
4018
|
* @param proof - Proof bytes as hex, WITHOUT public inputs (as the relay sends it)
|
|
@@ -4036,7 +4040,7 @@ async function verifyProofOffChain(circuit, proof, publicInputs, options = {}) {
|
|
|
4036
4040
|
// their trust anchor as a public input the prover chooses. For OIDC that is
|
|
4037
4041
|
// the RSA key -- see core's oidcProviderKeys. Checked here so a dApp that
|
|
4038
4042
|
// verifies off-chain gets the same answer as one that verifies on-chain.
|
|
4039
|
-
const issuer = await checkProofIssuer(circuit, publicInputs);
|
|
4043
|
+
const issuer = await checkProofIssuer(circuit, publicInputs, { request: options.request });
|
|
4040
4044
|
if (!issuer.ok) {
|
|
4041
4045
|
return { valid: false, error: issuer.error };
|
|
4042
4046
|
}
|
|
@@ -4178,6 +4182,13 @@ class ProofportSDK {
|
|
|
4178
4182
|
*/
|
|
4179
4183
|
constructor(config = {}) {
|
|
4180
4184
|
this.pendingRequests = new Map();
|
|
4185
|
+
/**
|
|
4186
|
+
* requestId -> scope of the relay requests this instance created, so that
|
|
4187
|
+
* verifyResponse* can check an OIDC proof's request-bound nonce without the
|
|
4188
|
+
* dApp passing the request back in. Oldest entries go first past
|
|
4189
|
+
* {@link ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS}.
|
|
4190
|
+
*/
|
|
4191
|
+
this.relayRequests = new Map();
|
|
4181
4192
|
this.signer = null;
|
|
4182
4193
|
this.socket = null;
|
|
4183
4194
|
/**
|
|
@@ -4739,9 +4750,49 @@ class ProofportSDK {
|
|
|
4739
4750
|
* }
|
|
4740
4751
|
* ```
|
|
4741
4752
|
*/
|
|
4742
|
-
async verifyOnChain(circuit, proof, publicInputs, providerOrSigner) {
|
|
4753
|
+
async verifyOnChain(circuit, proof, publicInputs, providerOrSigner, options = {}) {
|
|
4743
4754
|
const parsedProof = parseProofForOnChain(proof, publicInputs, publicInputs.length);
|
|
4744
|
-
return verifyProofOnChain(circuit, parsedProof, providerOrSigner, this.verifierTarget(circuit)
|
|
4755
|
+
return verifyProofOnChain(circuit, parsedProof, providerOrSigner, this.verifierTarget(circuit), undefined, {
|
|
4756
|
+
request: options.request,
|
|
4757
|
+
});
|
|
4758
|
+
}
|
|
4759
|
+
/**
|
|
4760
|
+
* The request an `oidc_domain_attestation` response answers: the one the
|
|
4761
|
+
* caller passed, else the relay request this instance created under the
|
|
4762
|
+
* response's requestId. `{ error }` when there is none, or when the two
|
|
4763
|
+
* disagree -- an OIDC proof made with a request-bound nonce is only
|
|
4764
|
+
* meaningful against the request it was bound to, so a response this SDK
|
|
4765
|
+
* cannot place is refused rather than checked without it.
|
|
4766
|
+
*/
|
|
4767
|
+
oidcRequestFor(response, explicit) {
|
|
4768
|
+
if (explicit !== undefined) {
|
|
4769
|
+
if (explicit === null || typeof explicit !== 'object' || explicit.requestId !== response.requestId) {
|
|
4770
|
+
return {
|
|
4771
|
+
error: `The request passed in (${JSON.stringify(explicit?.requestId)}) is not the one this response answers (${JSON.stringify(response.requestId)}).`,
|
|
4772
|
+
};
|
|
4773
|
+
}
|
|
4774
|
+
return { request: explicit };
|
|
4775
|
+
}
|
|
4776
|
+
const remembered = this.relayRequests.get(response.requestId);
|
|
4777
|
+
if (!remembered) {
|
|
4778
|
+
return {
|
|
4779
|
+
error: `No request ${JSON.stringify(response.requestId)} was created by this SDK instance, so the OIDC proof's ` +
|
|
4780
|
+
'nonce cannot be checked against it. Pass { request: { scope, requestId } } -- the scope and relay ' +
|
|
4781
|
+
'requestId of the request you created.',
|
|
4782
|
+
};
|
|
4783
|
+
}
|
|
4784
|
+
return { request: remembered };
|
|
4785
|
+
}
|
|
4786
|
+
/** @internal Remember a relay request's scope for verifyResponse*. */
|
|
4787
|
+
rememberRelayRequest(requestId, scope) {
|
|
4788
|
+
if (typeof requestId !== 'string' || typeof scope !== 'string')
|
|
4789
|
+
return;
|
|
4790
|
+
this.relayRequests.delete(requestId);
|
|
4791
|
+
this.relayRequests.set(requestId, { scope, requestId });
|
|
4792
|
+
while (this.relayRequests.size > ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS) {
|
|
4793
|
+
const oldest = this.relayRequests.keys().next().value;
|
|
4794
|
+
this.relayRequests.delete(oldest);
|
|
4795
|
+
}
|
|
4745
4796
|
}
|
|
4746
4797
|
/**
|
|
4747
4798
|
* The verifier for a circuit: the one the dApp configured, otherwise the
|
|
@@ -4768,6 +4819,9 @@ class ProofportSDK {
|
|
|
4768
4819
|
*
|
|
4769
4820
|
* @param response - ProofResponse object from parseResponse()
|
|
4770
4821
|
* @param providerOrSigner - ethers v6 Provider or Signer (defaults to base mainnet public RPC)
|
|
4822
|
+
* @param options.request - For `oidc_domain_attestation`: the `{ scope, requestId }`
|
|
4823
|
+
* the response answers. Not needed for a relay request this SDK instance
|
|
4824
|
+
* created; an OIDC response this instance cannot place is refused without it.
|
|
4771
4825
|
*
|
|
4772
4826
|
* @returns Promise resolving to verification result with valid boolean and optional error message
|
|
4773
4827
|
*
|
|
@@ -4794,10 +4848,17 @@ class ProofportSDK {
|
|
|
4794
4848
|
* });
|
|
4795
4849
|
* ```
|
|
4796
4850
|
*/
|
|
4797
|
-
async verifyResponseOnChain(response, providerOrSigner) {
|
|
4851
|
+
async verifyResponseOnChain(response, providerOrSigner, options = {}) {
|
|
4798
4852
|
if (response.status !== 'completed' || !response.proof || !response.publicInputs) {
|
|
4799
4853
|
return { valid: false, error: 'Invalid or incomplete response' };
|
|
4800
4854
|
}
|
|
4855
|
+
let request;
|
|
4856
|
+
if (response.circuit === 'oidc_domain_attestation') {
|
|
4857
|
+
const found = this.oidcRequestFor(response, options.request);
|
|
4858
|
+
if ('error' in found)
|
|
4859
|
+
return { valid: false, error: found.error };
|
|
4860
|
+
request = found.request;
|
|
4861
|
+
}
|
|
4801
4862
|
const parsedProof = parseProofForOnChain(response.proof, response.publicInputs, response.publicInputs.length);
|
|
4802
4863
|
// The response's verifierAddress and chainId are a claim to check, never
|
|
4803
4864
|
// the contract to call: whoever wrote the response would otherwise pick
|
|
@@ -4806,7 +4867,7 @@ class ProofportSDK {
|
|
|
4806
4867
|
return verifyProofOnChain(response.circuit, parsedProof, providerOrSigner, this.verifierTarget(response.circuit), {
|
|
4807
4868
|
verifierAddress: response.verifierAddress,
|
|
4808
4869
|
chainId: response.chainId,
|
|
4809
|
-
});
|
|
4870
|
+
}, { request });
|
|
4810
4871
|
}
|
|
4811
4872
|
/**
|
|
4812
4873
|
* Verifies a proof response off-chain, against the circuit's verification key.
|
|
@@ -4836,7 +4897,14 @@ class ProofportSDK {
|
|
|
4836
4897
|
if (response.status !== 'completed' || !response.proof || !response.publicInputs) {
|
|
4837
4898
|
return { valid: false, error: 'Invalid or incomplete response' };
|
|
4838
4899
|
}
|
|
4839
|
-
|
|
4900
|
+
let request;
|
|
4901
|
+
if (response.circuit === 'oidc_domain_attestation') {
|
|
4902
|
+
const found = this.oidcRequestFor(response, options?.request);
|
|
4903
|
+
if ('error' in found)
|
|
4904
|
+
return { valid: false, error: found.error };
|
|
4905
|
+
request = found.request;
|
|
4906
|
+
}
|
|
4907
|
+
return verifyProofOffChain(response.circuit, response.proof, response.publicInputs, { ...options, request });
|
|
4840
4908
|
}
|
|
4841
4909
|
// ============ Utility Methods ============
|
|
4842
4910
|
/**
|
|
@@ -5275,7 +5343,9 @@ class ProofportSDK {
|
|
|
5275
5343
|
const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
|
|
5276
5344
|
throw new Error(error.error || `Relay request failed: HTTP ${response.status}`);
|
|
5277
5345
|
}
|
|
5278
|
-
|
|
5346
|
+
const created = await response.json();
|
|
5347
|
+
this.rememberRelayRequest(created.requestId, scope);
|
|
5348
|
+
return created;
|
|
5279
5349
|
}
|
|
5280
5350
|
/**
|
|
5281
5351
|
* Polls the relay for proof result status.
|
|
@@ -5558,6 +5628,8 @@ class ProofportSDK {
|
|
|
5558
5628
|
return extractDomainFromPublicInputs(publicInputs, circuit);
|
|
5559
5629
|
}
|
|
5560
5630
|
}
|
|
5631
|
+
/** Bound on {@link relayRequests}; a dApp that verifies later can pass the request explicitly. */
|
|
5632
|
+
ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS = 1000;
|
|
5561
5633
|
/**
|
|
5562
5634
|
* How each circuit's request is built and checked. Keyed by circuit id and
|
|
5563
5635
|
* exhaustive over it, so a new circuit is a compile error here instead of
|