@zkproofport-app/sdk 0.5.0-beta.1 → 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 +32 -17
- package/dist/ProofportSDK.d.ts +59 -10
- package/dist/constants.d.ts +43 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.esm.js +255 -45
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +297 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +255 -45
- package/dist/index.mjs.map +1 -1
- package/dist/offChainVerifier.d.ts +13 -0
- package/dist/types.d.ts +8 -0
- package/package.json +2 -2
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseProofForOnChain, verifyProofOnChain,
|
|
2
|
-
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT, MDL_KR_PUBLIC_INPUT_LAYOUT, OIDC_DOMAIN_ATTESTATION_PUBLIC_INPUT_LAYOUT, extractDomainFromPublicInputs, extractNullifierFromPublicInputs, extractScopeFromPublicInputs } from '@zkproofport-app/core';
|
|
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_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';
|
|
@@ -23,6 +23,49 @@ const RELAY_URLS = {
|
|
|
23
23
|
staging: 'https://stg-relay.zkproofport.app',
|
|
24
24
|
local: 'http://localhost:4001',
|
|
25
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* The chain each circuit is verified on, per environment. Complete: a circuit
|
|
28
|
+
* added to the SDK is a compile error here until somebody names its chain.
|
|
29
|
+
*
|
|
30
|
+
* Mirrors the mobile app's `CIRCUIT_NETWORKS` (proofport-app
|
|
31
|
+
* src/config/contracts.ts), because a proof is checked where the app said its
|
|
32
|
+
* verifier is: Base for the Coinbase and OIDC circuits, GIWA Sepolia for GIWA
|
|
33
|
+
* and Dojang (testnet-only), Base Sepolia for Korea Mobile ID (testnet-only).
|
|
34
|
+
* The ADDRESS on that chain always comes from core's pinned table, never from
|
|
35
|
+
* a proof response.
|
|
36
|
+
*/
|
|
37
|
+
const VERIFICATION_CHAINS = {
|
|
38
|
+
production: {
|
|
39
|
+
coinbase_attestation: 8453,
|
|
40
|
+
coinbase_country_attestation: 8453,
|
|
41
|
+
oidc_domain_attestation: 8453,
|
|
42
|
+
giwa_attestation: 91342,
|
|
43
|
+
dojang_playground: 91342,
|
|
44
|
+
mdl_kr_ownership: 84532,
|
|
45
|
+
mdl_kr_age: 84532,
|
|
46
|
+
mdl_kr_region: 84532,
|
|
47
|
+
},
|
|
48
|
+
staging: {
|
|
49
|
+
coinbase_attestation: 84532,
|
|
50
|
+
coinbase_country_attestation: 84532,
|
|
51
|
+
oidc_domain_attestation: 84532,
|
|
52
|
+
giwa_attestation: 91342,
|
|
53
|
+
dojang_playground: 91342,
|
|
54
|
+
mdl_kr_ownership: 84532,
|
|
55
|
+
mdl_kr_age: 84532,
|
|
56
|
+
mdl_kr_region: 84532,
|
|
57
|
+
},
|
|
58
|
+
local: {
|
|
59
|
+
coinbase_attestation: 84532,
|
|
60
|
+
coinbase_country_attestation: 84532,
|
|
61
|
+
oidc_domain_attestation: 84532,
|
|
62
|
+
giwa_attestation: 91342,
|
|
63
|
+
dojang_playground: 91342,
|
|
64
|
+
mdl_kr_ownership: 84532,
|
|
65
|
+
mdl_kr_age: 84532,
|
|
66
|
+
mdl_kr_region: 84532,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
26
69
|
/**
|
|
27
70
|
* Default deep link URL scheme for ZKProofport mobile app.
|
|
28
71
|
* Used to construct deep link URLs that open the mobile app.
|
|
@@ -81,8 +124,10 @@ const CIRCUIT_METADATA = {
|
|
|
81
124
|
oidc_domain_attestation: {
|
|
82
125
|
name: 'OIDC Domain',
|
|
83
126
|
description: 'Prove email domain affiliation via OIDC JWT',
|
|
84
|
-
|
|
85
|
-
|
|
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'],
|
|
86
131
|
},
|
|
87
132
|
// Planned circuit — the identifier is reserved and the circuit exists, but it
|
|
88
133
|
// is not officially supported yet. See CIRCUIT_SUPPORT_STATUS in ./circuits.
|
|
@@ -3963,6 +4008,12 @@ async function fetchVerificationKey(circuit, timeoutMs) {
|
|
|
3963
4008
|
* Needs no setup from the caller: the verifier ships with this SDK and is
|
|
3964
4009
|
* loaded on first use.
|
|
3965
4010
|
*
|
|
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 }`.
|
|
4016
|
+
*
|
|
3966
4017
|
* @param circuit - Canonical circuit identifier
|
|
3967
4018
|
* @param proof - Proof bytes as hex, WITHOUT public inputs (as the relay sends it)
|
|
3968
4019
|
* @param publicInputs - Public inputs as hex strings, in circuit order
|
|
@@ -3981,6 +4032,18 @@ async function fetchVerificationKey(circuit, timeoutMs) {
|
|
|
3981
4032
|
*/
|
|
3982
4033
|
async function verifyProofOffChain(circuit, proof, publicInputs, options = {}) {
|
|
3983
4034
|
const timeoutMs = options.timeoutMs ?? 30000;
|
|
4035
|
+
if (!isCircuitId(circuit)) {
|
|
4036
|
+
return { valid: false, error: `Unknown circuit '${circuit}'. Known: ${ALL_CIRCUIT_IDS.join(', ')}.` };
|
|
4037
|
+
}
|
|
4038
|
+
// Before Barretenberg, and for the same reason as on-chain: a proof can be
|
|
4039
|
+
// mathematically valid and still mean nothing, because some circuits take
|
|
4040
|
+
// their trust anchor as a public input the prover chooses. For OIDC that is
|
|
4041
|
+
// the RSA key -- see core's oidcProviderKeys. Checked here so a dApp that
|
|
4042
|
+
// verifies off-chain gets the same answer as one that verifies on-chain.
|
|
4043
|
+
const issuer = await checkProofIssuer(circuit, publicInputs, { request: options.request });
|
|
4044
|
+
if (!issuer.ok) {
|
|
4045
|
+
return { valid: false, error: issuer.error };
|
|
4046
|
+
}
|
|
3984
4047
|
// A REQUIRED dependency, loaded lazily.
|
|
3985
4048
|
//
|
|
3986
4049
|
// It was briefly an optional peer dependency, on the reasoning that the WASM
|
|
@@ -4119,24 +4182,41 @@ class ProofportSDK {
|
|
|
4119
4182
|
*/
|
|
4120
4183
|
constructor(config = {}) {
|
|
4121
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();
|
|
4122
4192
|
this.signer = null;
|
|
4123
4193
|
this.socket = null;
|
|
4194
|
+
/**
|
|
4195
|
+
* Set by {@link ProofportSDK.create} from its environment preset. It decides
|
|
4196
|
+
* which chain a proof is verified on when the dApp configured no verifier
|
|
4197
|
+
* for the circuit; a custom-config SDK has none and must configure one.
|
|
4198
|
+
*/
|
|
4199
|
+
this.environment = null;
|
|
4124
4200
|
this.config = {
|
|
4125
4201
|
scheme: config.scheme || DEFAULT_SCHEME,
|
|
4126
4202
|
verifiers: config.verifiers || {},
|
|
4127
4203
|
};
|
|
4128
4204
|
this.relayUrl = config.relayUrl || '';
|
|
4205
|
+
if (config.environment !== undefined) {
|
|
4206
|
+
if (!Object.prototype.hasOwnProperty.call(VERIFICATION_CHAINS, config.environment)) {
|
|
4207
|
+
throw new Error(`Unknown environment '${config.environment}'. Known: ${Object.keys(VERIFICATION_CHAINS).join(', ')}.`);
|
|
4208
|
+
}
|
|
4209
|
+
this.environment = config.environment;
|
|
4210
|
+
}
|
|
4129
4211
|
}
|
|
4130
4212
|
// ============ Request Creation ============
|
|
4131
4213
|
/**
|
|
4132
4214
|
* @internal
|
|
4133
|
-
* Creates a
|
|
4134
|
-
*
|
|
4135
|
-
* Generates a proof request for verifying Coinbase KYC status without revealing
|
|
4136
|
-
* the actual attestation data. The proof confirms the user has passed Coinbase KYC
|
|
4137
|
-
* while maintaining privacy through zero-knowledge proofs.
|
|
4215
|
+
* Creates a proof request for a circuit whose dapp-side input is a scope
|
|
4216
|
+
* (Coinbase KYC, OIDC domain, GIWA, Dojang), keeping that circuit's id.
|
|
4138
4217
|
*
|
|
4139
|
-
* @param
|
|
4218
|
+
* @param circuit - The circuit requested; it is the request's circuit
|
|
4219
|
+
* @param inputs - Circuit inputs; `scope` is required (and `domain` for OIDC)
|
|
4140
4220
|
* @param inputs.scope - Application-specific scope (e.g., domain name)
|
|
4141
4221
|
* @param options - Request configuration options
|
|
4142
4222
|
|
|
@@ -4151,7 +4231,7 @@ class ProofportSDK {
|
|
|
4151
4231
|
*
|
|
4152
4232
|
* @example
|
|
4153
4233
|
* ```typescript
|
|
4154
|
-
* const request = sdk.
|
|
4234
|
+
* const request = sdk.createScopedRequest('coinbase_attestation', {
|
|
4155
4235
|
* scope: 'myapp.com'
|
|
4156
4236
|
* }, {
|
|
4157
4237
|
* dappName: 'My DApp',
|
|
@@ -4161,13 +4241,34 @@ class ProofportSDK {
|
|
|
4161
4241
|
* const deepLink = sdk.getDeepLinkUrl(request);
|
|
4162
4242
|
* ```
|
|
4163
4243
|
*/
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4244
|
+
createScopedRequest(circuit, inputs, options = {}) {
|
|
4245
|
+
const scope = inputs.scope;
|
|
4246
|
+
if (typeof scope !== 'string' || scope.trim() === '') {
|
|
4247
|
+
throw new Error(`scope is required for ${circuit} circuit`);
|
|
4248
|
+
}
|
|
4249
|
+
if (circuit === 'oidc_domain_attestation') {
|
|
4250
|
+
const domain = inputs.domain;
|
|
4251
|
+
if (typeof domain !== 'string' || domain.trim() === '') {
|
|
4252
|
+
throw new Error('domain is required for oidc_domain_attestation circuit');
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
const action = inputs.action;
|
|
4256
|
+
const binding = circuitActionBinding(circuit);
|
|
4257
|
+
if (binding === 'none' && action !== undefined) {
|
|
4258
|
+
throw new Error(`${circuit} has no action inputs, so an action sent with it would not be proved.`);
|
|
4259
|
+
}
|
|
4260
|
+
if (binding === 'required' || (binding === 'optional' && action !== undefined)) {
|
|
4261
|
+
const actionError = validateTypedAction(action);
|
|
4262
|
+
if (actionError)
|
|
4263
|
+
throw new Error(`${actionError} (circuit: ${circuit})`);
|
|
4167
4264
|
}
|
|
4168
4265
|
const request = {
|
|
4169
4266
|
requestId: generateRequestId(),
|
|
4170
|
-
circuit
|
|
4267
|
+
// The circuit asked for, always. This used to be the literal
|
|
4268
|
+
// 'coinbase_attestation', and every circuit that was not country or mDL
|
|
4269
|
+
// was routed here -- a GIWA, Dojang or OIDC request silently became a
|
|
4270
|
+
// Coinbase KYC request.
|
|
4271
|
+
circuit,
|
|
4171
4272
|
inputs,
|
|
4172
4273
|
message: options.message,
|
|
4173
4274
|
dappName: options.dappName,
|
|
@@ -4264,16 +4365,17 @@ class ProofportSDK {
|
|
|
4264
4365
|
* ```
|
|
4265
4366
|
*/
|
|
4266
4367
|
createProofRequest(circuit, inputs, options = {}) {
|
|
4267
|
-
if (circuit
|
|
4268
|
-
|
|
4269
|
-
}
|
|
4270
|
-
else if (circuit === 'mdl_kr_ownership' ||
|
|
4271
|
-
circuit === 'mdl_kr_age' ||
|
|
4272
|
-
circuit === 'mdl_kr_region') {
|
|
4273
|
-
return this.createMdlKrRequest(circuit, inputs, options);
|
|
4368
|
+
if (!isCircuitId(circuit)) {
|
|
4369
|
+
throw new Error(`Unknown circuit '${circuit}'. Known: ${ALL_CIRCUIT_IDS.join(', ')}.`);
|
|
4274
4370
|
}
|
|
4275
|
-
|
|
4276
|
-
|
|
4371
|
+
const builder = ProofportSDK.REQUEST_BUILDERS[circuit];
|
|
4372
|
+
switch (builder) {
|
|
4373
|
+
case 'country':
|
|
4374
|
+
return this.createCoinbaseCountryRequest(inputs, options);
|
|
4375
|
+
case 'mdl':
|
|
4376
|
+
return this.createMdlKrRequest(circuit, inputs, options);
|
|
4377
|
+
case 'scoped':
|
|
4378
|
+
return this.createScopedRequest(circuit, inputs, options);
|
|
4277
4379
|
}
|
|
4278
4380
|
}
|
|
4279
4381
|
/**
|
|
@@ -4648,10 +4750,66 @@ class ProofportSDK {
|
|
|
4648
4750
|
* }
|
|
4649
4751
|
* ```
|
|
4650
4752
|
*/
|
|
4651
|
-
async verifyOnChain(circuit, proof, publicInputs, providerOrSigner) {
|
|
4753
|
+
async verifyOnChain(circuit, proof, publicInputs, providerOrSigner, options = {}) {
|
|
4652
4754
|
const parsedProof = parseProofForOnChain(proof, publicInputs, publicInputs.length);
|
|
4653
|
-
|
|
4654
|
-
|
|
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
|
+
}
|
|
4796
|
+
}
|
|
4797
|
+
/**
|
|
4798
|
+
* The verifier for a circuit: the one the dApp configured, otherwise the
|
|
4799
|
+
* pinned deployment on the chain this SDK's environment verifies that
|
|
4800
|
+
* circuit on. `undefined` when neither exists, which core reports as an
|
|
4801
|
+
* error. Never anything a proof response said.
|
|
4802
|
+
*/
|
|
4803
|
+
verifierTarget(circuit) {
|
|
4804
|
+
const configured = this.config.verifiers[circuit];
|
|
4805
|
+
if (configured)
|
|
4806
|
+
return configured;
|
|
4807
|
+
if (this.environment === null)
|
|
4808
|
+
return undefined;
|
|
4809
|
+
const chains = VERIFICATION_CHAINS[this.environment];
|
|
4810
|
+
if (!Object.prototype.hasOwnProperty.call(chains, circuit))
|
|
4811
|
+
return undefined;
|
|
4812
|
+
return { chainId: chains[circuit] };
|
|
4655
4813
|
}
|
|
4656
4814
|
/**
|
|
4657
4815
|
* Verifies a proof response on-chain using the deployed verifier contract.
|
|
@@ -4661,6 +4819,9 @@ class ProofportSDK {
|
|
|
4661
4819
|
*
|
|
4662
4820
|
* @param response - ProofResponse object from parseResponse()
|
|
4663
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.
|
|
4664
4825
|
*
|
|
4665
4826
|
* @returns Promise resolving to verification result with valid boolean and optional error message
|
|
4666
4827
|
*
|
|
@@ -4687,17 +4848,26 @@ class ProofportSDK {
|
|
|
4687
4848
|
* });
|
|
4688
4849
|
* ```
|
|
4689
4850
|
*/
|
|
4690
|
-
async verifyResponseOnChain(response, providerOrSigner) {
|
|
4851
|
+
async verifyResponseOnChain(response, providerOrSigner, options = {}) {
|
|
4691
4852
|
if (response.status !== 'completed' || !response.proof || !response.publicInputs) {
|
|
4692
4853
|
return { valid: false, error: 'Invalid or incomplete response' };
|
|
4693
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
|
+
}
|
|
4694
4862
|
const parsedProof = parseProofForOnChain(response.proof, response.publicInputs, response.publicInputs.length);
|
|
4695
|
-
|
|
4696
|
-
|
|
4863
|
+
// The response's verifierAddress and chainId are a claim to check, never
|
|
4864
|
+
// the contract to call: whoever wrote the response would otherwise pick
|
|
4865
|
+
// the judge. A claim that differs from the pinned or configured verifier
|
|
4866
|
+
// is refused.
|
|
4867
|
+
return verifyProofOnChain(response.circuit, parsedProof, providerOrSigner, this.verifierTarget(response.circuit), {
|
|
4697
4868
|
verifierAddress: response.verifierAddress,
|
|
4698
4869
|
chainId: response.chainId,
|
|
4699
|
-
};
|
|
4700
|
-
return verifyProofOnChain(response.circuit, parsedProof, providerOrSigner, customVerifier, responseVerifier);
|
|
4870
|
+
}, { request });
|
|
4701
4871
|
}
|
|
4702
4872
|
/**
|
|
4703
4873
|
* Verifies a proof response off-chain, against the circuit's verification key.
|
|
@@ -4727,7 +4897,14 @@ class ProofportSDK {
|
|
|
4727
4897
|
if (response.status !== 'completed' || !response.proof || !response.publicInputs) {
|
|
4728
4898
|
return { valid: false, error: 'Invalid or incomplete response' };
|
|
4729
4899
|
}
|
|
4730
|
-
|
|
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 });
|
|
4731
4908
|
}
|
|
4732
4909
|
// ============ Utility Methods ============
|
|
4733
4910
|
/**
|
|
@@ -4748,8 +4925,17 @@ class ProofportSDK {
|
|
|
4748
4925
|
* ```
|
|
4749
4926
|
*/
|
|
4750
4927
|
getVerifierAddress(circuit) {
|
|
4751
|
-
|
|
4752
|
-
|
|
4928
|
+
return this.requireVerifier(circuit).address;
|
|
4929
|
+
}
|
|
4930
|
+
/** The configured or pinned verifier, or an error saying why there is none. */
|
|
4931
|
+
requireVerifier(circuit) {
|
|
4932
|
+
const target = this.verifierTarget(circuit);
|
|
4933
|
+
if (!target) {
|
|
4934
|
+
throw new Error(`No verifier configured for circuit '${circuit}'. Configure one in the SDK's verifiers option, or create the SDK with ProofportSDK.create() to use the pinned deployment.`);
|
|
4935
|
+
}
|
|
4936
|
+
if ('address' in target)
|
|
4937
|
+
return { address: target.address, chainId: target.chainId };
|
|
4938
|
+
return { address: getPinnedVerifier(circuit, target.chainId).address, chainId: target.chainId };
|
|
4753
4939
|
}
|
|
4754
4940
|
/**
|
|
4755
4941
|
* Gets the blockchain chain ID where the verifier contract is deployed.
|
|
@@ -4769,8 +4955,7 @@ class ProofportSDK {
|
|
|
4769
4955
|
* ```
|
|
4770
4956
|
*/
|
|
4771
4957
|
getVerifierChainId(circuit) {
|
|
4772
|
-
|
|
4773
|
-
return getVerifierChainId(circuit, customVerifier);
|
|
4958
|
+
return this.requireVerifier(circuit).chainId;
|
|
4774
4959
|
}
|
|
4775
4960
|
/**
|
|
4776
4961
|
* Gets metadata for a specific circuit type.
|
|
@@ -4917,17 +5102,20 @@ class ProofportSDK {
|
|
|
4917
5102
|
*/
|
|
4918
5103
|
static create(envOrConfig) {
|
|
4919
5104
|
if (typeof envOrConfig === 'undefined') {
|
|
4920
|
-
return
|
|
5105
|
+
return ProofportSDK.forEnvironment('production');
|
|
4921
5106
|
}
|
|
4922
5107
|
if (typeof envOrConfig === 'string') {
|
|
4923
|
-
|
|
4924
|
-
if (!relayUrl) {
|
|
4925
|
-
throw new Error(`Unknown environment: ${envOrConfig}. Use 'production', 'staging', or 'local'.`);
|
|
4926
|
-
}
|
|
4927
|
-
return new ProofportSDK({ relayUrl });
|
|
5108
|
+
return ProofportSDK.forEnvironment(envOrConfig);
|
|
4928
5109
|
}
|
|
4929
5110
|
return new ProofportSDK(envOrConfig);
|
|
4930
5111
|
}
|
|
5112
|
+
/** @internal An SDK on an environment preset's relay, verifying on that environment's chains. */
|
|
5113
|
+
static forEnvironment(env) {
|
|
5114
|
+
if (!Object.prototype.hasOwnProperty.call(RELAY_URLS, env)) {
|
|
5115
|
+
throw new Error(`Unknown environment: ${env}. Use 'production', 'staging', or 'local'.`);
|
|
5116
|
+
}
|
|
5117
|
+
return new ProofportSDK({ relayUrl: RELAY_URLS[env], environment: env });
|
|
5118
|
+
}
|
|
4931
5119
|
/**
|
|
4932
5120
|
* Detects if the code is running on a mobile device.
|
|
4933
5121
|
*
|
|
@@ -5061,7 +5249,10 @@ class ProofportSDK {
|
|
|
5061
5249
|
// calling createRelayRequest() for it with no signer got no local error and
|
|
5062
5250
|
// a relay 401 two round trips later.
|
|
5063
5251
|
static needsWalletSignature(circuit) {
|
|
5064
|
-
|
|
5252
|
+
if (!isCircuitId(circuit)) {
|
|
5253
|
+
throw new Error(`Unknown circuit '${circuit}'. Expected: ${ALL_CIRCUIT_IDS.join(', ')}`);
|
|
5254
|
+
}
|
|
5255
|
+
return CIRCUIT_NEEDS_WALLET_SIGNATURE[circuit];
|
|
5065
5256
|
}
|
|
5066
5257
|
async createRelayRequest(circuit, inputs, options = {}) {
|
|
5067
5258
|
if (!this.relayUrl) {
|
|
@@ -5152,7 +5343,9 @@ class ProofportSDK {
|
|
|
5152
5343
|
const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
|
|
5153
5344
|
throw new Error(error.error || `Relay request failed: HTTP ${response.status}`);
|
|
5154
5345
|
}
|
|
5155
|
-
|
|
5346
|
+
const created = await response.json();
|
|
5347
|
+
this.rememberRelayRequest(created.requestId, scope);
|
|
5348
|
+
return created;
|
|
5156
5349
|
}
|
|
5157
5350
|
/**
|
|
5158
5351
|
* Polls the relay for proof result status.
|
|
@@ -5435,6 +5628,23 @@ class ProofportSDK {
|
|
|
5435
5628
|
return extractDomainFromPublicInputs(publicInputs, circuit);
|
|
5436
5629
|
}
|
|
5437
5630
|
}
|
|
5631
|
+
/** Bound on {@link relayRequests}; a dApp that verifies later can pass the request explicitly. */
|
|
5632
|
+
ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS = 1000;
|
|
5633
|
+
/**
|
|
5634
|
+
* How each circuit's request is built and checked. Keyed by circuit id and
|
|
5635
|
+
* exhaustive over it, so a new circuit is a compile error here instead of
|
|
5636
|
+
* falling through to another circuit's builder.
|
|
5637
|
+
*/
|
|
5638
|
+
ProofportSDK.REQUEST_BUILDERS = {
|
|
5639
|
+
coinbase_attestation: 'scoped',
|
|
5640
|
+
coinbase_country_attestation: 'country',
|
|
5641
|
+
oidc_domain_attestation: 'scoped',
|
|
5642
|
+
giwa_attestation: 'scoped',
|
|
5643
|
+
dojang_playground: 'scoped',
|
|
5644
|
+
mdl_kr_ownership: 'mdl',
|
|
5645
|
+
mdl_kr_age: 'mdl',
|
|
5646
|
+
mdl_kr_region: 'mdl',
|
|
5647
|
+
};
|
|
5438
5648
|
|
|
5439
5649
|
export { ProofportSDK, RELAY_TERMINAL_STATUSES, ProofportSDK as default, isTerminalRelayStatus, verifyProofOffChain };
|
|
5440
5650
|
//# sourceMappingURL=index.esm.js.map
|