@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/dist/index.mjs
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
|