@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.js
CHANGED
|
@@ -126,8 +126,10 @@ const CIRCUIT_METADATA = {
|
|
|
126
126
|
oidc_domain_attestation: {
|
|
127
127
|
name: 'OIDC Domain',
|
|
128
128
|
description: 'Prove email domain affiliation via OIDC JWT',
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
// v2: 148 v1 fields, then aud_hash (32), nonce_mode (1), nonce_binding
|
|
130
|
+
// (32), now (1). oidc-domain-attestation/src/main.nr.
|
|
131
|
+
publicInputsCount: 214,
|
|
132
|
+
publicInputNames: ['pubkey_modulus_limbs', 'domain', 'scope', 'nullifier', 'provider', 'aud_hash', 'nonce_mode', 'nonce_binding', 'now'],
|
|
131
133
|
},
|
|
132
134
|
// Planned circuit — the identifier is reserved and the circuit exists, but it
|
|
133
135
|
// is not officially supported yet. See CIRCUIT_SUPPORT_STATUS in ./circuits.
|
|
@@ -1141,9 +1143,11 @@ async function fetchVerificationKey(circuit, timeoutMs) {
|
|
|
1141
1143
|
* Needs no setup from the caller: the verifier ships with this SDK and is
|
|
1142
1144
|
* loaded on first use.
|
|
1143
1145
|
*
|
|
1144
|
-
* For `oidc_domain_attestation` it first checks the
|
|
1145
|
-
*
|
|
1146
|
-
*
|
|
1146
|
+
* For `oidc_domain_attestation` it first checks the token's audience, nonce and
|
|
1147
|
+
* time (core's `checkOidcPolicy`, against `options.request` when given) and the
|
|
1148
|
+
* proof's RSA key against the provider's published JWKS (core's
|
|
1149
|
+
* `checkOidcProviderKey`); any refusal, or a JWKS that cannot be fetched, is
|
|
1150
|
+
* `{ valid: false }`.
|
|
1147
1151
|
*
|
|
1148
1152
|
* @param circuit - Canonical circuit identifier
|
|
1149
1153
|
* @param proof - Proof bytes as hex, WITHOUT public inputs (as the relay sends it)
|
|
@@ -1171,7 +1175,7 @@ async function verifyProofOffChain(circuit, proof, publicInputs, options = {}) {
|
|
|
1171
1175
|
// their trust anchor as a public input the prover chooses. For OIDC that is
|
|
1172
1176
|
// the RSA key -- see core's oidcProviderKeys. Checked here so a dApp that
|
|
1173
1177
|
// verifies off-chain gets the same answer as one that verifies on-chain.
|
|
1174
|
-
const issuer = await core.checkProofIssuer(circuit, publicInputs);
|
|
1178
|
+
const issuer = await core.checkProofIssuer(circuit, publicInputs, { request: options.request });
|
|
1175
1179
|
if (!issuer.ok) {
|
|
1176
1180
|
return { valid: false, error: issuer.error };
|
|
1177
1181
|
}
|
|
@@ -1313,6 +1317,13 @@ class ProofportSDK {
|
|
|
1313
1317
|
*/
|
|
1314
1318
|
constructor(config = {}) {
|
|
1315
1319
|
this.pendingRequests = new Map();
|
|
1320
|
+
/**
|
|
1321
|
+
* requestId -> scope of the relay requests this instance created, so that
|
|
1322
|
+
* verifyResponse* can check an OIDC proof's request-bound nonce without the
|
|
1323
|
+
* dApp passing the request back in. Oldest entries go first past
|
|
1324
|
+
* {@link ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS}.
|
|
1325
|
+
*/
|
|
1326
|
+
this.relayRequests = new Map();
|
|
1316
1327
|
this.signer = null;
|
|
1317
1328
|
this.socket = null;
|
|
1318
1329
|
/**
|
|
@@ -1874,9 +1885,49 @@ class ProofportSDK {
|
|
|
1874
1885
|
* }
|
|
1875
1886
|
* ```
|
|
1876
1887
|
*/
|
|
1877
|
-
async verifyOnChain(circuit, proof, publicInputs, providerOrSigner) {
|
|
1888
|
+
async verifyOnChain(circuit, proof, publicInputs, providerOrSigner, options = {}) {
|
|
1878
1889
|
const parsedProof = core.parseProofForOnChain(proof, publicInputs, publicInputs.length);
|
|
1879
|
-
return core.verifyProofOnChain(circuit, parsedProof, providerOrSigner, this.verifierTarget(circuit)
|
|
1890
|
+
return core.verifyProofOnChain(circuit, parsedProof, providerOrSigner, this.verifierTarget(circuit), undefined, {
|
|
1891
|
+
request: options.request,
|
|
1892
|
+
});
|
|
1893
|
+
}
|
|
1894
|
+
/**
|
|
1895
|
+
* The request an `oidc_domain_attestation` response answers: the one the
|
|
1896
|
+
* caller passed, else the relay request this instance created under the
|
|
1897
|
+
* response's requestId. `{ error }` when there is none, or when the two
|
|
1898
|
+
* disagree -- an OIDC proof made with a request-bound nonce is only
|
|
1899
|
+
* meaningful against the request it was bound to, so a response this SDK
|
|
1900
|
+
* cannot place is refused rather than checked without it.
|
|
1901
|
+
*/
|
|
1902
|
+
oidcRequestFor(response, explicit) {
|
|
1903
|
+
if (explicit !== undefined) {
|
|
1904
|
+
if (explicit === null || typeof explicit !== 'object' || explicit.requestId !== response.requestId) {
|
|
1905
|
+
return {
|
|
1906
|
+
error: `The request passed in (${JSON.stringify(explicit?.requestId)}) is not the one this response answers (${JSON.stringify(response.requestId)}).`,
|
|
1907
|
+
};
|
|
1908
|
+
}
|
|
1909
|
+
return { request: explicit };
|
|
1910
|
+
}
|
|
1911
|
+
const remembered = this.relayRequests.get(response.requestId);
|
|
1912
|
+
if (!remembered) {
|
|
1913
|
+
return {
|
|
1914
|
+
error: `No request ${JSON.stringify(response.requestId)} was created by this SDK instance, so the OIDC proof's ` +
|
|
1915
|
+
'nonce cannot be checked against it. Pass { request: { scope, requestId } } -- the scope and relay ' +
|
|
1916
|
+
'requestId of the request you created.',
|
|
1917
|
+
};
|
|
1918
|
+
}
|
|
1919
|
+
return { request: remembered };
|
|
1920
|
+
}
|
|
1921
|
+
/** @internal Remember a relay request's scope for verifyResponse*. */
|
|
1922
|
+
rememberRelayRequest(requestId, scope) {
|
|
1923
|
+
if (typeof requestId !== 'string' || typeof scope !== 'string')
|
|
1924
|
+
return;
|
|
1925
|
+
this.relayRequests.delete(requestId);
|
|
1926
|
+
this.relayRequests.set(requestId, { scope, requestId });
|
|
1927
|
+
while (this.relayRequests.size > ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS) {
|
|
1928
|
+
const oldest = this.relayRequests.keys().next().value;
|
|
1929
|
+
this.relayRequests.delete(oldest);
|
|
1930
|
+
}
|
|
1880
1931
|
}
|
|
1881
1932
|
/**
|
|
1882
1933
|
* The verifier for a circuit: the one the dApp configured, otherwise the
|
|
@@ -1903,6 +1954,9 @@ class ProofportSDK {
|
|
|
1903
1954
|
*
|
|
1904
1955
|
* @param response - ProofResponse object from parseResponse()
|
|
1905
1956
|
* @param providerOrSigner - ethers v6 Provider or Signer (defaults to base mainnet public RPC)
|
|
1957
|
+
* @param options.request - For `oidc_domain_attestation`: the `{ scope, requestId }`
|
|
1958
|
+
* the response answers. Not needed for a relay request this SDK instance
|
|
1959
|
+
* created; an OIDC response this instance cannot place is refused without it.
|
|
1906
1960
|
*
|
|
1907
1961
|
* @returns Promise resolving to verification result with valid boolean and optional error message
|
|
1908
1962
|
*
|
|
@@ -1929,10 +1983,17 @@ class ProofportSDK {
|
|
|
1929
1983
|
* });
|
|
1930
1984
|
* ```
|
|
1931
1985
|
*/
|
|
1932
|
-
async verifyResponseOnChain(response, providerOrSigner) {
|
|
1986
|
+
async verifyResponseOnChain(response, providerOrSigner, options = {}) {
|
|
1933
1987
|
if (response.status !== 'completed' || !response.proof || !response.publicInputs) {
|
|
1934
1988
|
return { valid: false, error: 'Invalid or incomplete response' };
|
|
1935
1989
|
}
|
|
1990
|
+
let request;
|
|
1991
|
+
if (response.circuit === 'oidc_domain_attestation') {
|
|
1992
|
+
const found = this.oidcRequestFor(response, options.request);
|
|
1993
|
+
if ('error' in found)
|
|
1994
|
+
return { valid: false, error: found.error };
|
|
1995
|
+
request = found.request;
|
|
1996
|
+
}
|
|
1936
1997
|
const parsedProof = core.parseProofForOnChain(response.proof, response.publicInputs, response.publicInputs.length);
|
|
1937
1998
|
// The response's verifierAddress and chainId are a claim to check, never
|
|
1938
1999
|
// the contract to call: whoever wrote the response would otherwise pick
|
|
@@ -1941,7 +2002,7 @@ class ProofportSDK {
|
|
|
1941
2002
|
return core.verifyProofOnChain(response.circuit, parsedProof, providerOrSigner, this.verifierTarget(response.circuit), {
|
|
1942
2003
|
verifierAddress: response.verifierAddress,
|
|
1943
2004
|
chainId: response.chainId,
|
|
1944
|
-
});
|
|
2005
|
+
}, { request });
|
|
1945
2006
|
}
|
|
1946
2007
|
/**
|
|
1947
2008
|
* Verifies a proof response off-chain, against the circuit's verification key.
|
|
@@ -1971,7 +2032,14 @@ class ProofportSDK {
|
|
|
1971
2032
|
if (response.status !== 'completed' || !response.proof || !response.publicInputs) {
|
|
1972
2033
|
return { valid: false, error: 'Invalid or incomplete response' };
|
|
1973
2034
|
}
|
|
1974
|
-
|
|
2035
|
+
let request;
|
|
2036
|
+
if (response.circuit === 'oidc_domain_attestation') {
|
|
2037
|
+
const found = this.oidcRequestFor(response, options?.request);
|
|
2038
|
+
if ('error' in found)
|
|
2039
|
+
return { valid: false, error: found.error };
|
|
2040
|
+
request = found.request;
|
|
2041
|
+
}
|
|
2042
|
+
return verifyProofOffChain(response.circuit, response.proof, response.publicInputs, { ...options, request });
|
|
1975
2043
|
}
|
|
1976
2044
|
// ============ Utility Methods ============
|
|
1977
2045
|
/**
|
|
@@ -2410,7 +2478,9 @@ class ProofportSDK {
|
|
|
2410
2478
|
const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
|
|
2411
2479
|
throw new Error(error.error || `Relay request failed: HTTP ${response.status}`);
|
|
2412
2480
|
}
|
|
2413
|
-
|
|
2481
|
+
const created = await response.json();
|
|
2482
|
+
this.rememberRelayRequest(created.requestId, scope);
|
|
2483
|
+
return created;
|
|
2414
2484
|
}
|
|
2415
2485
|
/**
|
|
2416
2486
|
* Polls the relay for proof result status.
|
|
@@ -2693,6 +2763,8 @@ class ProofportSDK {
|
|
|
2693
2763
|
return core.extractDomainFromPublicInputs(publicInputs, circuit);
|
|
2694
2764
|
}
|
|
2695
2765
|
}
|
|
2766
|
+
/** Bound on {@link relayRequests}; a dApp that verifies later can pass the request explicitly. */
|
|
2767
|
+
ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS = 1000;
|
|
2696
2768
|
/**
|
|
2697
2769
|
* How each circuit's request is built and checked. Keyed by circuit id and
|
|
2698
2770
|
* exhaustive over it, so a new circuit is a compile error here instead of
|
|
@@ -2721,14 +2793,46 @@ Object.defineProperty(exports, "MDL_KR_PUBLIC_INPUT_LAYOUT", {
|
|
|
2721
2793
|
enumerable: true,
|
|
2722
2794
|
get: function () { return core.MDL_KR_PUBLIC_INPUT_LAYOUT; }
|
|
2723
2795
|
});
|
|
2796
|
+
Object.defineProperty(exports, "OIDC_ALLOWED_AUDIENCES", {
|
|
2797
|
+
enumerable: true,
|
|
2798
|
+
get: function () { return core.OIDC_ALLOWED_AUDIENCES; }
|
|
2799
|
+
});
|
|
2724
2800
|
Object.defineProperty(exports, "OIDC_DOMAIN_ATTESTATION_PUBLIC_INPUT_LAYOUT", {
|
|
2725
2801
|
enumerable: true,
|
|
2726
2802
|
get: function () { return core.OIDC_DOMAIN_ATTESTATION_PUBLIC_INPUT_LAYOUT; }
|
|
2727
2803
|
});
|
|
2804
|
+
Object.defineProperty(exports, "OIDC_NONCE_DOMAIN", {
|
|
2805
|
+
enumerable: true,
|
|
2806
|
+
get: function () { return core.OIDC_NONCE_DOMAIN; }
|
|
2807
|
+
});
|
|
2808
|
+
Object.defineProperty(exports, "OIDC_NOW_MAX_AGE_SECONDS", {
|
|
2809
|
+
enumerable: true,
|
|
2810
|
+
get: function () { return core.OIDC_NOW_MAX_AGE_SECONDS; }
|
|
2811
|
+
});
|
|
2812
|
+
Object.defineProperty(exports, "OIDC_NOW_MAX_FUTURE_SECONDS", {
|
|
2813
|
+
enumerable: true,
|
|
2814
|
+
get: function () { return core.OIDC_NOW_MAX_FUTURE_SECONDS; }
|
|
2815
|
+
});
|
|
2816
|
+
Object.defineProperty(exports, "OIDC_V1_PUBLIC_INPUT_COUNT", {
|
|
2817
|
+
enumerable: true,
|
|
2818
|
+
get: function () { return core.OIDC_V1_PUBLIC_INPUT_COUNT; }
|
|
2819
|
+
});
|
|
2820
|
+
Object.defineProperty(exports, "OIDC_V2_PUBLIC_INPUT_COUNT", {
|
|
2821
|
+
enumerable: true,
|
|
2822
|
+
get: function () { return core.OIDC_V2_PUBLIC_INPUT_COUNT; }
|
|
2823
|
+
});
|
|
2728
2824
|
Object.defineProperty(exports, "PINNED_VERIFIERS", {
|
|
2729
2825
|
enumerable: true,
|
|
2730
2826
|
get: function () { return core.PINNED_VERIFIERS; }
|
|
2731
2827
|
});
|
|
2828
|
+
Object.defineProperty(exports, "checkOidcPolicy", {
|
|
2829
|
+
enumerable: true,
|
|
2830
|
+
get: function () { return core.checkOidcPolicy; }
|
|
2831
|
+
});
|
|
2832
|
+
Object.defineProperty(exports, "deriveOidcNonceBinding", {
|
|
2833
|
+
enumerable: true,
|
|
2834
|
+
get: function () { return core.deriveOidcNonceBinding; }
|
|
2835
|
+
});
|
|
2732
2836
|
Object.defineProperty(exports, "extractDomainFromPublicInputs", {
|
|
2733
2837
|
enumerable: true,
|
|
2734
2838
|
get: function () { return core.extractDomainFromPublicInputs; }
|
|
@@ -2745,6 +2849,10 @@ Object.defineProperty(exports, "getPinnedVerifier", {
|
|
|
2745
2849
|
enumerable: true,
|
|
2746
2850
|
get: function () { return core.getPinnedVerifier; }
|
|
2747
2851
|
});
|
|
2852
|
+
Object.defineProperty(exports, "oidcAudienceHash", {
|
|
2853
|
+
enumerable: true,
|
|
2854
|
+
get: function () { return core.oidcAudienceHash; }
|
|
2855
|
+
});
|
|
2748
2856
|
Object.defineProperty(exports, "ALL_CIRCUIT_IDS", {
|
|
2749
2857
|
enumerable: true,
|
|
2750
2858
|
get: function () { return circuits.ALL_CIRCUIT_IDS; }
|