@zkproofport-app/sdk 0.5.0-beta.7 → 0.5.0-beta.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 +34 -1
- package/dist/ProofportSDK.d.ts +19 -0
- package/dist/constants.d.ts +4 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.esm.js +112 -6
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +137 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +112 -6
- package/dist/index.mjs.map +1 -1
- package/dist/offChainVerifier.d.ts +6 -0
- package/dist/types.d.ts +18 -1
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { countryListError, checkProofIssuer, parseProofForOnChain, verifyProofOnChain, getPinnedVerifier, extractScopeFromPublicInputs, extractNullifierFromPublicInputs, extractDomainFromPublicInputs } from '@zkproofport-app/core';
|
|
2
|
-
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_COUNT, COINBASE_COUNTRY_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_VARIANT_VERIFIERS, PINNED_VERIFIERS, checkOidcPolicy, deriveOidcNonceBinding, extractDomainFromPublicInputs, extractNullifierFromPublicInputs, extractScopeFromPublicInputs, getPinnedVariantVerifier, getPinnedVerifier, oidcAudienceHash } from '@zkproofport-app/core';
|
|
3
|
-
import { isCircuitId, ALL_CIRCUIT_IDS, circuitActionBinding, resolveSignerVariant, getCircuitPackage, CIRCUIT_NEEDS_WALLET_SIGNATURE } from '@zkproofport-app/core/circuits';
|
|
4
|
-
export { ALL_CIRCUIT_IDS, CIRCUIT_ACTION_BINDING, CIRCUIT_IDS, CIRCUIT_PACKAGES, CIRCUIT_SUPPORT_STATUS, CIRCUIT_VK_PATHS, EXPERIMENTAL_CIRCUIT_IDS, PLANNED_CIRCUIT_IDS, SIGNER_VARIANTS, SUPPORTED_CIRCUIT_IDS, circuitActionBinding, evmProofByteLength, getCircuitPackage, getCircuitSupportStatus, isCircuitId, isSignerVariant, isSupportedCircuitId, resolveSignerVariant, signerVariantsOf } from '@zkproofport-app/core/circuits';
|
|
2
|
+
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_COUNT, COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT, HUMAN_PASSPORT_SCORE_PUBLIC_INPUT_COUNT, HUMAN_PASSPORT_SCORE_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_VARIANT_VERIFIERS, PINNED_VERIFIERS, checkOidcPolicy, deriveOidcNonceBinding, extractDomainFromPublicInputs, extractNullifierFromPublicInputs, extractScopeFromPublicInputs, getPinnedVariantVerifier, getPinnedVerifier, oidcAudienceHash } from '@zkproofport-app/core';
|
|
3
|
+
import { isCircuitId, ALL_CIRCUIT_IDS, humanPassportScoreUnits, circuitActionBinding, resolveSignerVariant, getCircuitPackage, CIRCUIT_NEEDS_WALLET_SIGNATURE } from '@zkproofport-app/core/circuits';
|
|
4
|
+
export { ALL_CIRCUIT_IDS, CIRCUIT_ACTION_BINDING, CIRCUIT_IDS, CIRCUIT_PACKAGES, CIRCUIT_SUPPORT_STATUS, CIRCUIT_VK_PATHS, EXPERIMENTAL_CIRCUIT_IDS, HUMAN_PASSPORT_ISSUER, HUMAN_PASSPORT_ISSUER_ROOT, HUMAN_PASSPORT_SCORER_ID, HUMAN_PASSPORT_SCORE_SCHEMA, PLANNED_CIRCUIT_IDS, SIGNER_VARIANTS, SUPPORTED_CIRCUIT_IDS, circuitActionBinding, evmProofByteLength, getCircuitPackage, getCircuitSupportStatus, humanPassportScoreUnits, isCircuitId, isSignerVariant, isSupportedCircuitId, resolveSignerVariant, signerVariantsOf } from '@zkproofport-app/core/circuits';
|
|
5
5
|
import { validateTypedAction } from '@zkproofport-app/core/typedAction';
|
|
6
6
|
export { parseTypedAction, validateTypedAction } from '@zkproofport-app/core/typedAction';
|
|
7
7
|
|
|
@@ -41,6 +41,7 @@ const VERIFICATION_CHAINS = {
|
|
|
41
41
|
oidc_domain_attestation: 8453,
|
|
42
42
|
giwa_attestation: 91342,
|
|
43
43
|
dojang_playground: 91342,
|
|
44
|
+
human_passport_score: 8453,
|
|
44
45
|
},
|
|
45
46
|
staging: {
|
|
46
47
|
coinbase_attestation: 84532,
|
|
@@ -48,6 +49,7 @@ const VERIFICATION_CHAINS = {
|
|
|
48
49
|
oidc_domain_attestation: 84532,
|
|
49
50
|
giwa_attestation: 91342,
|
|
50
51
|
dojang_playground: 91342,
|
|
52
|
+
human_passport_score: 84532,
|
|
51
53
|
},
|
|
52
54
|
local: {
|
|
53
55
|
coinbase_attestation: 84532,
|
|
@@ -55,6 +57,7 @@ const VERIFICATION_CHAINS = {
|
|
|
55
57
|
oidc_domain_attestation: 84532,
|
|
56
58
|
giwa_attestation: 91342,
|
|
57
59
|
dojang_playground: 91342,
|
|
60
|
+
human_passport_score: 84532,
|
|
58
61
|
},
|
|
59
62
|
};
|
|
60
63
|
/**
|
|
@@ -156,6 +159,14 @@ const CIRCUIT_METADATA = {
|
|
|
156
159
|
publicInputsCount: 160,
|
|
157
160
|
publicInputNames: ['signal_hash', 'domain_separator', 'action_hash', 'scope', 'nullifier'],
|
|
158
161
|
},
|
|
162
|
+
// human-passport-score/src/main.nr: GIWA's six `pub [u8; 32]`, then
|
|
163
|
+
// min_score (u32, score x 10^4), scorer_id and now (u64) = 195 fields.
|
|
164
|
+
human_passport_score: {
|
|
165
|
+
name: 'Human Passport',
|
|
166
|
+
description: 'Prove a Human Passport score at or above a threshold, optionally authorizing one EIP-712 action',
|
|
167
|
+
publicInputsCount: 195,
|
|
168
|
+
publicInputNames: ['signal_hash', 'domain_separator', 'action_hash', 'signer_list_merkle_root', 'scope', 'nullifier', 'min_score', 'scorer_id', 'now'],
|
|
169
|
+
},
|
|
159
170
|
};
|
|
160
171
|
/**
|
|
161
172
|
* Default proof request expiration time in milliseconds.
|
|
@@ -652,6 +663,21 @@ function validateProofRequest(request) {
|
|
|
652
663
|
return { valid: false, error: 'isIncluded is required and must be a boolean' };
|
|
653
664
|
}
|
|
654
665
|
}
|
|
666
|
+
else if (request.circuit === 'human_passport_score') {
|
|
667
|
+
const inputs = request.inputs;
|
|
668
|
+
if (inputs.userAddress && !/^0x[a-fA-F0-9]{40}$/.test(inputs.userAddress)) {
|
|
669
|
+
return { valid: false, error: 'Invalid userAddress format' };
|
|
670
|
+
}
|
|
671
|
+
if (!inputs.scope || typeof inputs.scope !== 'string' || inputs.scope.trim() === '') {
|
|
672
|
+
return { valid: false, error: 'scope is required and must be a non-empty string' };
|
|
673
|
+
}
|
|
674
|
+
try {
|
|
675
|
+
humanPassportScoreUnits(inputs.minScore);
|
|
676
|
+
}
|
|
677
|
+
catch (error) {
|
|
678
|
+
return { valid: false, error: error instanceof Error ? error.message : String(error) };
|
|
679
|
+
}
|
|
680
|
+
}
|
|
655
681
|
else if (request.circuit === 'oidc_domain_attestation') {
|
|
656
682
|
const inputs = request.inputs;
|
|
657
683
|
if (!inputs.domain || typeof inputs.domain !== 'string' || inputs.domain.trim() === '') {
|
|
@@ -3940,7 +3966,7 @@ async function verifyProofOffChain(circuit, proof, publicInputs, options = {}) {
|
|
|
3940
3966
|
// their trust anchor as a public input the prover chooses. For OIDC that is
|
|
3941
3967
|
// the RSA key -- see core's oidcProviderKeys. Checked here so a dApp that
|
|
3942
3968
|
// verifies off-chain gets the same answer as one that verifies on-chain.
|
|
3943
|
-
const issuer = await checkProofIssuer(circuit, publicInputs, { request: options.request, countryCondition: options.countryCondition });
|
|
3969
|
+
const issuer = await checkProofIssuer(circuit, publicInputs, { request: options.request, countryCondition: options.countryCondition, minScore: options.minScore });
|
|
3944
3970
|
if (!issuer.ok) {
|
|
3945
3971
|
return { valid: false, error: issuer.error };
|
|
3946
3972
|
}
|
|
@@ -4106,6 +4132,12 @@ class ProofportSDK {
|
|
|
4106
4132
|
* them. Bounded like {@link relayRequests}.
|
|
4107
4133
|
*/
|
|
4108
4134
|
this.countryRequests = new Map();
|
|
4135
|
+
/**
|
|
4136
|
+
* requestId -> the score threshold of the Human Passport relay requests this
|
|
4137
|
+
* instance created, so verifyResponse* can hold the proof's min_score to it.
|
|
4138
|
+
* Bounded like {@link relayRequests}.
|
|
4139
|
+
*/
|
|
4140
|
+
this.passportRequests = new Map();
|
|
4109
4141
|
this.signer = null;
|
|
4110
4142
|
this.socket = null;
|
|
4111
4143
|
/**
|
|
@@ -4298,6 +4330,16 @@ class ProofportSDK {
|
|
|
4298
4330
|
switch (builder) {
|
|
4299
4331
|
case 'country':
|
|
4300
4332
|
return this.createCoinbaseCountryRequest(inputs, options);
|
|
4333
|
+
case 'passport': {
|
|
4334
|
+
const minScore = inputs.minScore;
|
|
4335
|
+
try {
|
|
4336
|
+
humanPassportScoreUnits(minScore);
|
|
4337
|
+
}
|
|
4338
|
+
catch (error) {
|
|
4339
|
+
throw new Error(`${error instanceof Error ? error.message : String(error)} (circuit: ${circuit})`);
|
|
4340
|
+
}
|
|
4341
|
+
return this.createScopedRequest(circuit, inputs, options);
|
|
4342
|
+
}
|
|
4301
4343
|
case 'scoped':
|
|
4302
4344
|
return this.createScopedRequest(circuit, inputs, options);
|
|
4303
4345
|
}
|
|
@@ -4647,6 +4689,7 @@ class ProofportSDK {
|
|
|
4647
4689
|
request: options.request,
|
|
4648
4690
|
signerVariant: options.signerVariant,
|
|
4649
4691
|
countryCondition: options.countryCondition,
|
|
4692
|
+
minScore: options.minScore,
|
|
4650
4693
|
});
|
|
4651
4694
|
}
|
|
4652
4695
|
/**
|
|
@@ -4712,6 +4755,42 @@ class ProofportSDK {
|
|
|
4712
4755
|
'isIncluded } } -- the list and direction of the request you created.',
|
|
4713
4756
|
};
|
|
4714
4757
|
}
|
|
4758
|
+
/**
|
|
4759
|
+
* The score threshold a `human_passport_score` response must carry: the one
|
|
4760
|
+
* the caller passed, else the relay request this instance created under the
|
|
4761
|
+
* response's requestId, else the deep-link request still pending under it.
|
|
4762
|
+
* `{ error }` when there is none: the proof's threshold is the prover's
|
|
4763
|
+
* choice, so a response this SDK cannot place is refused rather than
|
|
4764
|
+
* accepted for whatever threshold it carries.
|
|
4765
|
+
*/
|
|
4766
|
+
passportMinScoreFor(response, explicit) {
|
|
4767
|
+
if (explicit !== undefined)
|
|
4768
|
+
return { minScore: explicit };
|
|
4769
|
+
const remembered = this.passportRequests.get(response.requestId);
|
|
4770
|
+
if (remembered !== undefined)
|
|
4771
|
+
return { minScore: remembered };
|
|
4772
|
+
const pending = this.pendingRequests.get(response.requestId);
|
|
4773
|
+
const inputs = pending?.circuit === 'human_passport_score' ? pending.inputs : undefined;
|
|
4774
|
+
if (inputs && typeof inputs.minScore === 'number')
|
|
4775
|
+
return { minScore: inputs.minScore };
|
|
4776
|
+
return {
|
|
4777
|
+
error: `No Human Passport request ${JSON.stringify(response.requestId)} was created by this SDK instance, so the ` +
|
|
4778
|
+
"proof's score threshold cannot be checked against what was asked. Pass { minScore } -- the threshold of " +
|
|
4779
|
+
'the request you created.',
|
|
4780
|
+
};
|
|
4781
|
+
}
|
|
4782
|
+
/** @internal Remember a Human Passport relay request's threshold for verifyResponse*. */
|
|
4783
|
+
rememberPassportRequest(requestId, inputs) {
|
|
4784
|
+
const minScore = inputs?.minScore;
|
|
4785
|
+
if (typeof requestId !== 'string' || typeof minScore !== 'number')
|
|
4786
|
+
return;
|
|
4787
|
+
this.passportRequests.delete(requestId);
|
|
4788
|
+
this.passportRequests.set(requestId, minScore);
|
|
4789
|
+
while (this.passportRequests.size > ProofportSDK.MAX_REMEMBERED_RELAY_REQUESTS) {
|
|
4790
|
+
const oldest = this.passportRequests.keys().next().value;
|
|
4791
|
+
this.passportRequests.delete(oldest);
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4715
4794
|
/** @internal Remember a Coinbase Country relay request's list and direction for verifyResponse*. */
|
|
4716
4795
|
rememberCountryRequest(requestId, inputs) {
|
|
4717
4796
|
const i = inputs;
|
|
@@ -4800,6 +4879,13 @@ class ProofportSDK {
|
|
|
4800
4879
|
return { valid: false, error: found.error };
|
|
4801
4880
|
countryCondition = found.condition;
|
|
4802
4881
|
}
|
|
4882
|
+
let minScore;
|
|
4883
|
+
if (response.circuit === 'human_passport_score') {
|
|
4884
|
+
const found = this.passportMinScoreFor(response, options.minScore);
|
|
4885
|
+
if ('error' in found)
|
|
4886
|
+
return { valid: false, error: found.error };
|
|
4887
|
+
minScore = found.minScore;
|
|
4888
|
+
}
|
|
4803
4889
|
const parsedProof = parseProofForOnChain(response.proof, response.publicInputs, response.publicInputs.length);
|
|
4804
4890
|
// The response's verifierAddress and chainId are a claim to check, never
|
|
4805
4891
|
// the contract to call: whoever wrote the response would otherwise pick
|
|
@@ -4808,7 +4894,7 @@ class ProofportSDK {
|
|
|
4808
4894
|
return verifyProofOnChain(response.circuit, parsedProof, providerOrSigner, this.verifierTarget(response.circuit), {
|
|
4809
4895
|
verifierAddress: response.verifierAddress,
|
|
4810
4896
|
chainId: response.chainId,
|
|
4811
|
-
}, { request, signerVariant: response.signerVariant, countryCondition });
|
|
4897
|
+
}, { request, signerVariant: response.signerVariant, countryCondition, minScore });
|
|
4812
4898
|
}
|
|
4813
4899
|
/**
|
|
4814
4900
|
* Verifies a proof response off-chain, against the circuit's verification key.
|
|
@@ -4852,7 +4938,14 @@ class ProofportSDK {
|
|
|
4852
4938
|
return { valid: false, error: found.error };
|
|
4853
4939
|
countryCondition = found.condition;
|
|
4854
4940
|
}
|
|
4855
|
-
|
|
4941
|
+
let minScore;
|
|
4942
|
+
if (response.circuit === 'human_passport_score') {
|
|
4943
|
+
const found = this.passportMinScoreFor(response, options?.minScore);
|
|
4944
|
+
if ('error' in found)
|
|
4945
|
+
return { valid: false, error: found.error };
|
|
4946
|
+
minScore = found.minScore;
|
|
4947
|
+
}
|
|
4948
|
+
return verifyProofOffChain(response.circuit, response.proof, response.publicInputs, { ...options, request, countryCondition, minScore, signerVariant: response.signerVariant });
|
|
4856
4949
|
}
|
|
4857
4950
|
// ============ Utility Methods ============
|
|
4858
4951
|
/**
|
|
@@ -5230,6 +5323,15 @@ class ProofportSDK {
|
|
|
5230
5323
|
}
|
|
5231
5324
|
}
|
|
5232
5325
|
}
|
|
5326
|
+
// A Human Passport threshold the circuit cannot carry is refused here too.
|
|
5327
|
+
if (circuit === 'human_passport_score') {
|
|
5328
|
+
try {
|
|
5329
|
+
humanPassportScoreUnits(inputs.minScore);
|
|
5330
|
+
}
|
|
5331
|
+
catch (error) {
|
|
5332
|
+
throw new Error(`${error instanceof Error ? error.message : String(error)} (circuit: ${circuit})`);
|
|
5333
|
+
}
|
|
5334
|
+
}
|
|
5233
5335
|
// A Coinbase Country list the circuit would refuse is refused here, before a
|
|
5234
5336
|
// challenge is burned, as createProofRequest does.
|
|
5235
5337
|
if (circuit === 'coinbase_country_attestation') {
|
|
@@ -5297,6 +5399,8 @@ class ProofportSDK {
|
|
|
5297
5399
|
this.rememberRelayRequest(created.requestId, scope);
|
|
5298
5400
|
if (circuit === 'coinbase_country_attestation')
|
|
5299
5401
|
this.rememberCountryRequest(created.requestId, inputs);
|
|
5402
|
+
if (circuit === 'human_passport_score')
|
|
5403
|
+
this.rememberPassportRequest(created.requestId, inputs);
|
|
5300
5404
|
return created;
|
|
5301
5405
|
}
|
|
5302
5406
|
/**
|
|
@@ -5593,6 +5697,8 @@ ProofportSDK.REQUEST_BUILDERS = {
|
|
|
5593
5697
|
oidc_domain_attestation: 'scoped',
|
|
5594
5698
|
giwa_attestation: 'scoped',
|
|
5595
5699
|
dojang_playground: 'scoped',
|
|
5700
|
+
// Scoped, plus the score threshold the proof must carry.
|
|
5701
|
+
human_passport_score: 'passport',
|
|
5596
5702
|
};
|
|
5597
5703
|
|
|
5598
5704
|
export { DEFAULT_RELAY_WAIT_MS, ProofportSDK, RELAY_TERMINAL_STATUSES, ProofportSDK as default, isTerminalRelayStatus, verifyProofOffChain };
|