@zkproofport-app/sdk 0.1.2-beta.1 → 0.2.0
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 +67 -98
- package/dist/ProofportSDK.d.ts +24 -138
- package/dist/constants.d.ts +0 -42
- package/dist/index.d.ts +3 -3
- package/dist/index.esm.js +42 -354
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +42 -354
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +42 -354
- package/dist/index.mjs.map +1 -1
- package/dist/types.d.ts +22 -104
- package/dist/verifier.d.ts +0 -77
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -135,51 +135,6 @@ const DEFAULT_REQUEST_EXPIRY_MS = 10 * 60 * 1000;
|
|
|
135
135
|
* ```
|
|
136
136
|
*/
|
|
137
137
|
const MAX_QR_DATA_SIZE = 2953; // Version 40 with L error correction
|
|
138
|
-
/**
|
|
139
|
-
* ZKProofportNullifierRegistry contract ABI (V2).
|
|
140
|
-
*
|
|
141
|
-
* This is the current nullifier registry interface with relayer-only registration.
|
|
142
|
-
* Public view functions allow checking nullifier status and verifying proofs without registration.
|
|
143
|
-
*
|
|
144
|
-
* Key functions:
|
|
145
|
-
* - `isNullifierRegistered`: Check if a nullifier has been used
|
|
146
|
-
* - `getNullifierInfo`: Get registration details for a nullifier
|
|
147
|
-
* - `verifyOnly`: Verify a proof without registering the nullifier
|
|
148
|
-
*
|
|
149
|
-
* Note: Registration functions (verifyAndRegister) are relayer-only and not exposed in this ABI.
|
|
150
|
-
*
|
|
151
|
-
* @example
|
|
152
|
-
* ```typescript
|
|
153
|
-
* import { Contract } from 'ethers';
|
|
154
|
-
*
|
|
155
|
-
* const registry = new Contract(
|
|
156
|
-
* registryAddress,
|
|
157
|
-
* ZKPROOFPORT_NULLIFIER_REGISTRY_ABI,
|
|
158
|
-
* provider
|
|
159
|
-
* );
|
|
160
|
-
*
|
|
161
|
-
* const isUsed = await registry.isNullifierRegistered(nullifier);
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
|
-
const ZKPROOFPORT_NULLIFIER_REGISTRY_ABI = [
|
|
165
|
-
'function isNullifierRegistered(bytes32 _nullifier) external view returns (bool)',
|
|
166
|
-
'function getNullifierInfo(bytes32 _nullifier) external view returns (uint64 registeredAt, bytes32 scope, bytes32 circuitId)',
|
|
167
|
-
'function verifyOnly(bytes32 _circuitId, bytes calldata _proof, bytes32[] calldata _publicInputs) external view returns (bool)',
|
|
168
|
-
'event NullifierRegistered(bytes32 indexed nullifier, bytes32 indexed scope, bytes32 indexed circuitId)',
|
|
169
|
-
];
|
|
170
|
-
|
|
171
|
-
var constants = /*#__PURE__*/Object.freeze({
|
|
172
|
-
__proto__: null,
|
|
173
|
-
CIRCUIT_METADATA: CIRCUIT_METADATA,
|
|
174
|
-
DEEP_LINK_HOSTS: DEEP_LINK_HOSTS,
|
|
175
|
-
DEFAULT_REQUEST_EXPIRY_MS: DEFAULT_REQUEST_EXPIRY_MS,
|
|
176
|
-
DEFAULT_SCHEME: DEFAULT_SCHEME,
|
|
177
|
-
MAX_QR_DATA_SIZE: MAX_QR_DATA_SIZE,
|
|
178
|
-
RELAY_URLS: RELAY_URLS,
|
|
179
|
-
RPC_ENDPOINTS: RPC_ENDPOINTS,
|
|
180
|
-
VERIFIER_ABI: VERIFIER_ABI,
|
|
181
|
-
ZKPROOFPORT_NULLIFIER_REGISTRY_ABI: ZKPROOFPORT_NULLIFIER_REGISTRY_ABI
|
|
182
|
-
});
|
|
183
138
|
|
|
184
139
|
/**
|
|
185
140
|
* Deep Link utilities for ZKProofport SDK
|
|
@@ -378,7 +333,6 @@ function parseProofResponseUrl(url) {
|
|
|
378
333
|
if (timestamp) {
|
|
379
334
|
response.timestamp = parseInt(timestamp, 10);
|
|
380
335
|
}
|
|
381
|
-
response.nullifier = urlObj.searchParams.get('nullifier') || undefined;
|
|
382
336
|
}
|
|
383
337
|
else if (status === 'error') {
|
|
384
338
|
response.error = urlObj.searchParams.get('error') || undefined;
|
|
@@ -3773,41 +3727,6 @@ function extractScopeFromPublicInputs(publicInputsHex, circuit) {
|
|
|
3773
3727
|
const scopeFields = publicInputsHex.slice(start, end + 1);
|
|
3774
3728
|
return reconstructBytes32FromFields(scopeFields);
|
|
3775
3729
|
}
|
|
3776
|
-
/**
|
|
3777
|
-
* Extract nullifier value from public inputs array.
|
|
3778
|
-
*
|
|
3779
|
-
* The nullifier is a bytes32 value encoded across 32 consecutive field elements
|
|
3780
|
-
* in the public inputs. The exact position depends on the circuit type.
|
|
3781
|
-
* Nullifiers are used for duplicate proof detection and must be unique per user+scope.
|
|
3782
|
-
*
|
|
3783
|
-
* @param publicInputsHex - Array of public input hex strings (zero-padded to 32 bytes)
|
|
3784
|
-
* @param circuit - Optional circuit identifier to determine field positions
|
|
3785
|
-
* @returns Reconstructed nullifier as hex string with 0x prefix, or null if inputs are insufficient
|
|
3786
|
-
*
|
|
3787
|
-
* @example
|
|
3788
|
-
* ```typescript
|
|
3789
|
-
* const nullifier = extractNullifierFromPublicInputs(publicInputsHex, 'coinbase_attestation');
|
|
3790
|
-
* console.log(nullifier); // '0xabcd1234...'
|
|
3791
|
-
*
|
|
3792
|
-
* // Check if nullifier is already registered
|
|
3793
|
-
* const isRegistered = await isNullifierRegistered(nullifier, registryAddress, provider);
|
|
3794
|
-
* ```
|
|
3795
|
-
*/
|
|
3796
|
-
function extractNullifierFromPublicInputs(publicInputsHex, circuit) {
|
|
3797
|
-
let start, end;
|
|
3798
|
-
if (circuit === 'coinbase_country_attestation') {
|
|
3799
|
-
start = 118;
|
|
3800
|
-
end = 149;
|
|
3801
|
-
}
|
|
3802
|
-
else {
|
|
3803
|
-
start = 96;
|
|
3804
|
-
end = 127;
|
|
3805
|
-
}
|
|
3806
|
-
if (publicInputsHex.length <= end)
|
|
3807
|
-
return null;
|
|
3808
|
-
const nullifierFields = publicInputsHex.slice(start, end + 1);
|
|
3809
|
-
return reconstructBytes32FromFields(nullifierFields);
|
|
3810
|
-
}
|
|
3811
3730
|
/** @internal Reconstruct a bytes32 value from 32 individual field elements */
|
|
3812
3731
|
function reconstructBytes32FromFields(fields) {
|
|
3813
3732
|
if (fields.length !== 32) {
|
|
@@ -3819,83 +3738,6 @@ function reconstructBytes32FromFields(fields) {
|
|
|
3819
3738
|
}).join('');
|
|
3820
3739
|
return '0x' + bytes;
|
|
3821
3740
|
}
|
|
3822
|
-
/**
|
|
3823
|
-
* Check if a nullifier is already registered on-chain in the ZKProofport nullifier registry.
|
|
3824
|
-
*
|
|
3825
|
-
* This function queries the on-chain nullifier registry contract to determine if a nullifier
|
|
3826
|
-
* has been used before. This is used to prevent duplicate proof submissions from the same user
|
|
3827
|
-
* for the same scope.
|
|
3828
|
-
*
|
|
3829
|
-
* @param nullifier - The nullifier hash as hex string with 0x prefix
|
|
3830
|
-
* @param registryAddress - ZKProofportNullifierRegistry contract address
|
|
3831
|
-
* @param provider - ethers.js Provider instance (v5 or v6 compatible)
|
|
3832
|
-
* @returns Promise resolving to true if nullifier is registered, false otherwise
|
|
3833
|
-
*
|
|
3834
|
-
* @example
|
|
3835
|
-
* ```typescript
|
|
3836
|
-
* const nullifier = extractNullifierFromPublicInputs(publicInputsHex, circuit);
|
|
3837
|
-
* const isRegistered = await isNullifierRegistered(
|
|
3838
|
-
* nullifier,
|
|
3839
|
-
* '0x...',
|
|
3840
|
-
* provider
|
|
3841
|
-
* );
|
|
3842
|
-
*
|
|
3843
|
-
* if (isRegistered) {
|
|
3844
|
-
* console.log('This nullifier has already been used');
|
|
3845
|
-
* }
|
|
3846
|
-
* ```
|
|
3847
|
-
*/
|
|
3848
|
-
async function isNullifierRegistered(nullifier, registryAddress, provider) {
|
|
3849
|
-
const { ZKPROOFPORT_NULLIFIER_REGISTRY_ABI } = await Promise.resolve().then(function () { return constants; });
|
|
3850
|
-
const contract = new ethers.Contract(registryAddress, ZKPROOFPORT_NULLIFIER_REGISTRY_ABI, provider);
|
|
3851
|
-
try {
|
|
3852
|
-
return await contract.isNullifierRegistered(nullifier);
|
|
3853
|
-
}
|
|
3854
|
-
catch {
|
|
3855
|
-
return false;
|
|
3856
|
-
}
|
|
3857
|
-
}
|
|
3858
|
-
/**
|
|
3859
|
-
* Get detailed information about a registered nullifier from the on-chain registry.
|
|
3860
|
-
*
|
|
3861
|
-
* This function retrieves the registration timestamp, scope, and circuit ID for a nullifier
|
|
3862
|
-
* that has been registered on-chain. This metadata is useful for auditing and analytics.
|
|
3863
|
-
*
|
|
3864
|
-
* @param nullifier - The nullifier hash as hex string with 0x prefix
|
|
3865
|
-
* @param registryAddress - ZKProofportNullifierRegistry contract address
|
|
3866
|
-
* @param provider - ethers.js Provider instance (v5 or v6 compatible)
|
|
3867
|
-
* @returns Promise resolving to nullifier info object, or null if not registered
|
|
3868
|
-
*
|
|
3869
|
-
* @example
|
|
3870
|
-
* ```typescript
|
|
3871
|
-
* const info = await getNullifierInfo(nullifier, registryAddress, provider);
|
|
3872
|
-
*
|
|
3873
|
-
* if (info) {
|
|
3874
|
-
* console.log('Registered at:', new Date(info.registeredAt * 1000));
|
|
3875
|
-
* console.log('Scope:', info.scope);
|
|
3876
|
-
* console.log('Circuit:', info.circuitId);
|
|
3877
|
-
* } else {
|
|
3878
|
-
* console.log('Nullifier not registered');
|
|
3879
|
-
* }
|
|
3880
|
-
* ```
|
|
3881
|
-
*/
|
|
3882
|
-
async function getNullifierInfo(nullifier, registryAddress, provider) {
|
|
3883
|
-
const { ZKPROOFPORT_NULLIFIER_REGISTRY_ABI } = await Promise.resolve().then(function () { return constants; });
|
|
3884
|
-
const contract = new ethers.Contract(registryAddress, ZKPROOFPORT_NULLIFIER_REGISTRY_ABI, provider);
|
|
3885
|
-
try {
|
|
3886
|
-
const [registeredAt, scope, circuitId] = await contract.getNullifierInfo(nullifier);
|
|
3887
|
-
if (BigInt(registeredAt) === 0n)
|
|
3888
|
-
return null;
|
|
3889
|
-
return {
|
|
3890
|
-
registeredAt: Number(registeredAt),
|
|
3891
|
-
scope: scope,
|
|
3892
|
-
circuitId: circuitId,
|
|
3893
|
-
};
|
|
3894
|
-
}
|
|
3895
|
-
catch {
|
|
3896
|
-
return null;
|
|
3897
|
-
}
|
|
3898
|
-
}
|
|
3899
3741
|
|
|
3900
3742
|
/**
|
|
3901
3743
|
* Proofport SDK - Main class
|
|
@@ -3909,12 +3751,15 @@ async function getNullifierInfo(nullifier, registryAddress, provider) {
|
|
|
3909
3751
|
* @example
|
|
3910
3752
|
* ```typescript
|
|
3911
3753
|
* import { ProofportSDK } from '@zkproofport-app/sdk';
|
|
3754
|
+
* import { BrowserProvider } from 'ethers';
|
|
3912
3755
|
*
|
|
3913
3756
|
* // Initialize SDK (uses production relay by default)
|
|
3914
3757
|
* const sdk = ProofportSDK.create();
|
|
3915
3758
|
*
|
|
3916
|
-
* //
|
|
3917
|
-
*
|
|
3759
|
+
* // Set wallet signer for challenge-signature auth
|
|
3760
|
+
* const provider = new BrowserProvider(window.ethereum);
|
|
3761
|
+
* const signer = await provider.getSigner();
|
|
3762
|
+
* sdk.setSigner(signer);
|
|
3918
3763
|
*
|
|
3919
3764
|
* // Create proof request via relay
|
|
3920
3765
|
* const relay = await sdk.createRelayRequest('coinbase_attestation', {
|
|
@@ -3960,14 +3805,13 @@ class ProofportSDK {
|
|
|
3960
3805
|
*/
|
|
3961
3806
|
constructor(config = {}) {
|
|
3962
3807
|
this.pendingRequests = new Map();
|
|
3963
|
-
this.
|
|
3808
|
+
this.signer = null;
|
|
3964
3809
|
this.socket = null;
|
|
3965
3810
|
this.config = {
|
|
3966
3811
|
scheme: config.scheme || DEFAULT_SCHEME,
|
|
3967
3812
|
verifiers: config.verifiers || {},
|
|
3968
3813
|
};
|
|
3969
3814
|
this.relayUrl = config.relayUrl || '';
|
|
3970
|
-
this.nullifierRegistry = config.nullifierRegistry;
|
|
3971
3815
|
}
|
|
3972
3816
|
// ============ Request Creation ============
|
|
3973
3817
|
/**
|
|
@@ -4728,115 +4572,42 @@ class ProofportSDK {
|
|
|
4728
4572
|
return false;
|
|
4729
4573
|
return /Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
4730
4574
|
}
|
|
4575
|
+
// ============ Relay Integration ============
|
|
4731
4576
|
/**
|
|
4732
|
-
*
|
|
4577
|
+
* Sets the wallet signer for challenge-signature authentication.
|
|
4578
|
+
* The signer will be used to sign challenges from the relay server.
|
|
4733
4579
|
*
|
|
4734
|
-
*
|
|
4735
|
-
* that can be used to authenticate relay requests.
|
|
4736
|
-
*
|
|
4737
|
-
* @param credentials - Client ID and API key
|
|
4738
|
-
* @param relayUrl - Relay server URL (e.g., 'https://relay.zkproofport.app')
|
|
4739
|
-
* @returns Promise resolving to AuthToken with JWT token and metadata
|
|
4740
|
-
* @throws Error if authentication fails
|
|
4580
|
+
* @param signer - Wallet signer (ethers v6 Signer or compatible object with signMessage/getAddress)
|
|
4741
4581
|
*
|
|
4742
4582
|
* @example
|
|
4743
4583
|
* ```typescript
|
|
4744
|
-
*
|
|
4745
|
-
* { clientId: 'your-client-id', apiKey: 'your-api-key' },
|
|
4746
|
-
* 'https://relay.zkproofport.app'
|
|
4747
|
-
* );
|
|
4748
|
-
* console.log('Token:', auth.token);
|
|
4749
|
-
* console.log('Expires in:', auth.expiresIn, 'seconds');
|
|
4750
|
-
* ```
|
|
4751
|
-
*/
|
|
4752
|
-
static async authenticate(credentials, relayUrl) {
|
|
4753
|
-
if (!credentials.clientId || !credentials.apiKey) {
|
|
4754
|
-
throw new Error('clientId and apiKey are required');
|
|
4755
|
-
}
|
|
4756
|
-
if (!relayUrl) {
|
|
4757
|
-
throw new Error('relayUrl is required');
|
|
4758
|
-
}
|
|
4759
|
-
const response = await fetch(`${relayUrl}/api/v1/auth/token`, {
|
|
4760
|
-
method: 'POST',
|
|
4761
|
-
headers: { 'Content-Type': 'application/json' },
|
|
4762
|
-
body: JSON.stringify({
|
|
4763
|
-
client_id: credentials.clientId,
|
|
4764
|
-
api_key: credentials.apiKey,
|
|
4765
|
-
}),
|
|
4766
|
-
});
|
|
4767
|
-
if (!response.ok) {
|
|
4768
|
-
const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
|
|
4769
|
-
throw new Error(error.error || `Authentication failed: HTTP ${response.status}`);
|
|
4770
|
-
}
|
|
4771
|
-
const data = await response.json();
|
|
4772
|
-
return {
|
|
4773
|
-
token: data.token,
|
|
4774
|
-
clientId: data.client_id,
|
|
4775
|
-
dappId: data.dapp_id,
|
|
4776
|
-
tier: data.tier,
|
|
4777
|
-
expiresIn: data.expires_in,
|
|
4778
|
-
expiresAt: Date.now() + (data.expires_in * 1000),
|
|
4779
|
-
};
|
|
4780
|
-
}
|
|
4781
|
-
/**
|
|
4782
|
-
* Checks if an auth token is still valid (not expired).
|
|
4783
|
-
*
|
|
4784
|
-
* @param auth - AuthToken to check
|
|
4785
|
-
* @returns True if the token has not expired
|
|
4584
|
+
* import { BrowserProvider } from 'ethers';
|
|
4786
4585
|
*
|
|
4787
|
-
*
|
|
4788
|
-
*
|
|
4789
|
-
*
|
|
4790
|
-
* auth = await ProofportSDK.authenticate(credentials, relayUrl);
|
|
4791
|
-
* }
|
|
4586
|
+
* const provider = new BrowserProvider(window.ethereum);
|
|
4587
|
+
* const signer = await provider.getSigner();
|
|
4588
|
+
* sdk.setSigner(signer);
|
|
4792
4589
|
* ```
|
|
4793
4590
|
*/
|
|
4794
|
-
|
|
4795
|
-
|
|
4591
|
+
setSigner(signer) {
|
|
4592
|
+
this.signer = signer;
|
|
4796
4593
|
}
|
|
4797
|
-
// ============ Relay Integration ============
|
|
4798
4594
|
/**
|
|
4799
|
-
*
|
|
4800
|
-
*
|
|
4801
|
-
* Instance method that authenticates via the relay server and stores
|
|
4802
|
-
* the JWT token internally, so subsequent relay requests are automatically authenticated.
|
|
4803
|
-
*
|
|
4804
|
-
* @param credentials - Client ID and API key
|
|
4805
|
-
* @returns Promise resolving to AuthToken
|
|
4806
|
-
* @throws Error if authentication fails or relayUrl is not configured
|
|
4807
|
-
*
|
|
4808
|
-
* @example
|
|
4809
|
-
* ```typescript
|
|
4810
|
-
* const sdk = ProofportSDK.create('production');
|
|
4595
|
+
* Fetches a random challenge from the relay server.
|
|
4596
|
+
* The challenge must be signed and included in proof requests.
|
|
4811
4597
|
*
|
|
4812
|
-
*
|
|
4813
|
-
*
|
|
4814
|
-
* ```
|
|
4598
|
+
* @returns Promise resolving to ChallengeResponse with challenge hex and expiry
|
|
4599
|
+
* @throws Error if relayUrl is not configured
|
|
4815
4600
|
*/
|
|
4816
|
-
async
|
|
4601
|
+
async getChallenge() {
|
|
4817
4602
|
if (!this.relayUrl) {
|
|
4818
|
-
throw new Error('relayUrl is required
|
|
4603
|
+
throw new Error('relayUrl is required. Set it in ProofportSDK config.');
|
|
4819
4604
|
}
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
logout() {
|
|
4827
|
-
this.authToken = null;
|
|
4828
|
-
}
|
|
4829
|
-
/**
|
|
4830
|
-
* Returns whether the SDK instance is currently authenticated with a valid token.
|
|
4831
|
-
*/
|
|
4832
|
-
isAuthenticated() {
|
|
4833
|
-
return this.authToken !== null && ProofportSDK.isTokenValid(this.authToken);
|
|
4834
|
-
}
|
|
4835
|
-
/**
|
|
4836
|
-
* Returns the current auth token, or null if not authenticated.
|
|
4837
|
-
*/
|
|
4838
|
-
getAuthToken() {
|
|
4839
|
-
return this.authToken;
|
|
4605
|
+
const response = await fetch(`${this.relayUrl}/api/v1/challenge`);
|
|
4606
|
+
if (!response.ok) {
|
|
4607
|
+
const error = await response.json().catch(() => ({ error: `HTTP ${response.status}` }));
|
|
4608
|
+
throw new Error(error.error || `Failed to get challenge: HTTP ${response.status}`);
|
|
4609
|
+
}
|
|
4610
|
+
return await response.json();
|
|
4840
4611
|
}
|
|
4841
4612
|
/**
|
|
4842
4613
|
* Creates a proof request through the relay server.
|
|
@@ -4844,19 +4615,19 @@ class ProofportSDK {
|
|
|
4844
4615
|
* This is the recommended way to create proof requests. The relay server:
|
|
4845
4616
|
* - Issues a server-side requestId (validated by the mobile app)
|
|
4846
4617
|
* - Tracks request status in Redis
|
|
4847
|
-
* - Handles credit deduction and tier enforcement
|
|
4848
4618
|
* - Builds the deep link with relay callback URL
|
|
4619
|
+
* - Stores inputs hash for deep link integrity verification
|
|
4849
4620
|
*
|
|
4850
4621
|
* @param circuit - Circuit type identifier
|
|
4851
4622
|
* @param inputs - Circuit-specific inputs
|
|
4852
4623
|
* @param options - Request options (message, dappName, dappIcon, nonce)
|
|
4853
4624
|
* @returns Promise resolving to RelayProofRequest with requestId, deepLink, pollUrl
|
|
4854
|
-
* @throws Error if not
|
|
4625
|
+
* @throws Error if signer not set or relay request fails
|
|
4855
4626
|
*
|
|
4856
4627
|
* @example
|
|
4857
4628
|
* ```typescript
|
|
4858
4629
|
* const sdk = ProofportSDK.create();
|
|
4859
|
-
*
|
|
4630
|
+
* sdk.setSigner(signer);
|
|
4860
4631
|
*
|
|
4861
4632
|
* const relay = await sdk.createRelayRequest('coinbase_attestation', {
|
|
4862
4633
|
* scope: 'myapp.com'
|
|
@@ -4870,15 +4641,20 @@ class ProofportSDK {
|
|
|
4870
4641
|
* ```
|
|
4871
4642
|
*/
|
|
4872
4643
|
async createRelayRequest(circuit, inputs, options = {}) {
|
|
4873
|
-
if (!this.
|
|
4874
|
-
throw new Error('
|
|
4644
|
+
if (!this.signer) {
|
|
4645
|
+
throw new Error('Signer not set. Call setSigner() first.');
|
|
4875
4646
|
}
|
|
4876
4647
|
if (!this.relayUrl) {
|
|
4877
4648
|
throw new Error('relayUrl is required. Set it in ProofportSDK config.');
|
|
4878
4649
|
}
|
|
4650
|
+
// Get challenge from relay and sign it
|
|
4651
|
+
const { challenge } = await this.getChallenge();
|
|
4652
|
+
const signature = await this.signer.signMessage(challenge);
|
|
4879
4653
|
const body = {
|
|
4880
4654
|
circuitId: circuit,
|
|
4881
4655
|
inputs,
|
|
4656
|
+
challenge,
|
|
4657
|
+
signature,
|
|
4882
4658
|
};
|
|
4883
4659
|
if (options.message)
|
|
4884
4660
|
body.message = options.message;
|
|
@@ -4892,7 +4668,6 @@ class ProofportSDK {
|
|
|
4892
4668
|
method: 'POST',
|
|
4893
4669
|
headers: {
|
|
4894
4670
|
'Content-Type': 'application/json',
|
|
4895
|
-
'Authorization': `Bearer ${this.authToken.token}`,
|
|
4896
4671
|
},
|
|
4897
4672
|
body: JSON.stringify(body),
|
|
4898
4673
|
});
|
|
@@ -4975,7 +4750,7 @@ class ProofportSDK {
|
|
|
4975
4750
|
* @param callbacks.onResult - Called when proof is completed or failed
|
|
4976
4751
|
* @param callbacks.onError - Called on errors
|
|
4977
4752
|
* @returns Unsubscribe function to clean up the connection
|
|
4978
|
-
* @throws Error if
|
|
4753
|
+
* @throws Error if relayUrl not set or socket.io-client not installed
|
|
4979
4754
|
*
|
|
4980
4755
|
* @example
|
|
4981
4756
|
* ```typescript
|
|
@@ -4996,9 +4771,6 @@ class ProofportSDK {
|
|
|
4996
4771
|
* ```
|
|
4997
4772
|
*/
|
|
4998
4773
|
async subscribe(requestId, callbacks) {
|
|
4999
|
-
if (!this.authToken || !ProofportSDK.isTokenValid(this.authToken)) {
|
|
5000
|
-
throw new Error('Not authenticated. Call login() first.');
|
|
5001
|
-
}
|
|
5002
4774
|
if (!this.relayUrl) {
|
|
5003
4775
|
throw new Error('relayUrl is required. Set it in ProofportSDK config.');
|
|
5004
4776
|
}
|
|
@@ -5013,10 +4785,9 @@ class ProofportSDK {
|
|
|
5013
4785
|
if (typeof ioConnect !== 'function') {
|
|
5014
4786
|
throw new Error('Failed to load socket.io-client: io function not found');
|
|
5015
4787
|
}
|
|
5016
|
-
// Connect to relay /proof namespace
|
|
4788
|
+
// Connect to relay /proof namespace (no JWT — open connections)
|
|
5017
4789
|
const socket = ioConnect(`${this.relayUrl}/proof`, {
|
|
5018
4790
|
path: '/socket.io',
|
|
5019
|
-
auth: { token: this.authToken.token },
|
|
5020
4791
|
transports: ['websocket', 'polling'],
|
|
5021
4792
|
});
|
|
5022
4793
|
this.socket = socket;
|
|
@@ -5065,7 +4836,7 @@ class ProofportSDK {
|
|
|
5065
4836
|
async waitForProof(requestId, options = {}) {
|
|
5066
4837
|
const timeout = options.timeoutMs || 300000;
|
|
5067
4838
|
// Try Socket.IO first
|
|
5068
|
-
if (this.
|
|
4839
|
+
if (this.relayUrl) {
|
|
5069
4840
|
try {
|
|
5070
4841
|
return await new Promise((resolve, reject) => {
|
|
5071
4842
|
const timer = setTimeout(() => {
|
|
@@ -5113,30 +4884,7 @@ class ProofportSDK {
|
|
|
5113
4884
|
this.socket = null;
|
|
5114
4885
|
}
|
|
5115
4886
|
}
|
|
5116
|
-
// ============
|
|
5117
|
-
/**
|
|
5118
|
-
* Extracts the nullifier from proof public inputs.
|
|
5119
|
-
*
|
|
5120
|
-
* The nullifier is a bytes32 value derived from the user's address and scope,
|
|
5121
|
-
* used to prevent duplicate proof submissions. Each user+scope combination
|
|
5122
|
-
* produces a unique nullifier.
|
|
5123
|
-
*
|
|
5124
|
-
* @param publicInputs - Array of public input hex strings from proof response
|
|
5125
|
-
* @param circuit - Circuit type to determine field positions
|
|
5126
|
-
* @returns Nullifier as hex string (0x...), or null if inputs are insufficient
|
|
5127
|
-
*
|
|
5128
|
-
* @example
|
|
5129
|
-
* ```typescript
|
|
5130
|
-
* const result = await sdk.waitForProof(relay.requestId);
|
|
5131
|
-
* if (result.status === 'completed') {
|
|
5132
|
-
* const nullifier = sdk.extractNullifier(result.publicInputs, result.circuit);
|
|
5133
|
-
* console.log('Nullifier:', nullifier);
|
|
5134
|
-
* }
|
|
5135
|
-
* ```
|
|
5136
|
-
*/
|
|
5137
|
-
extractNullifier(publicInputs, circuit) {
|
|
5138
|
-
return extractNullifierFromPublicInputs(publicInputs, circuit);
|
|
5139
|
-
}
|
|
4887
|
+
// ============ Public Input Utilities ============
|
|
5140
4888
|
/**
|
|
5141
4889
|
* Extracts the scope from proof public inputs.
|
|
5142
4890
|
*
|
|
@@ -5159,66 +4907,6 @@ class ProofportSDK {
|
|
|
5159
4907
|
extractScope(publicInputs, circuit) {
|
|
5160
4908
|
return extractScopeFromPublicInputs(publicInputs, circuit);
|
|
5161
4909
|
}
|
|
5162
|
-
/**
|
|
5163
|
-
* Checks if a nullifier is already registered on-chain.
|
|
5164
|
-
*
|
|
5165
|
-
* Queries the ZKProofportNullifierRegistry contract to determine if the
|
|
5166
|
-
* nullifier has been used before. Used to prevent duplicate proof submissions.
|
|
5167
|
-
*
|
|
5168
|
-
* Requires `nullifierRegistry` in SDK config.
|
|
5169
|
-
*
|
|
5170
|
-
* @param nullifier - Nullifier hex string from extractNullifier()
|
|
5171
|
-
* @param provider - Optional ethers provider (defaults to public RPC for configured chain)
|
|
5172
|
-
* @returns True if nullifier is already registered
|
|
5173
|
-
* @throws Error if nullifierRegistry is not configured
|
|
5174
|
-
*
|
|
5175
|
-
* @example
|
|
5176
|
-
* ```typescript
|
|
5177
|
-
* const sdk = ProofportSDK.create({
|
|
5178
|
-
* relayUrl: 'https://relay.zkproofport.app',
|
|
5179
|
-
* nullifierRegistry: { address: '0x...', chainId: 8453 }
|
|
5180
|
-
* });
|
|
5181
|
-
*
|
|
5182
|
-
* const nullifier = sdk.extractNullifier(publicInputs, circuit);
|
|
5183
|
-
* const isDuplicate = await sdk.checkNullifier(nullifier);
|
|
5184
|
-
* ```
|
|
5185
|
-
*/
|
|
5186
|
-
async checkNullifier(nullifier, provider) {
|
|
5187
|
-
if (!this.nullifierRegistry) {
|
|
5188
|
-
throw new Error('nullifierRegistry is required. Set it in ProofportSDK config.');
|
|
5189
|
-
}
|
|
5190
|
-
const p = provider || getDefaultProvider(this.nullifierRegistry.chainId);
|
|
5191
|
-
return isNullifierRegistered(nullifier, this.nullifierRegistry.address, p);
|
|
5192
|
-
}
|
|
5193
|
-
/**
|
|
5194
|
-
* Gets detailed information about a registered nullifier from on-chain registry.
|
|
5195
|
-
*
|
|
5196
|
-
* Retrieves the registration timestamp, scope, and circuit ID for a nullifier.
|
|
5197
|
-
* Returns null if the nullifier is not registered.
|
|
5198
|
-
*
|
|
5199
|
-
* Requires `nullifierRegistry` in SDK config.
|
|
5200
|
-
*
|
|
5201
|
-
* @param nullifier - Nullifier hex string from extractNullifier()
|
|
5202
|
-
* @param provider - Optional ethers provider (defaults to public RPC for configured chain)
|
|
5203
|
-
* @returns Nullifier info or null if not registered
|
|
5204
|
-
* @throws Error if nullifierRegistry is not configured
|
|
5205
|
-
*
|
|
5206
|
-
* @example
|
|
5207
|
-
* ```typescript
|
|
5208
|
-
* const info = await sdk.getNullifierDetails(nullifier);
|
|
5209
|
-
* if (info) {
|
|
5210
|
-
* console.log('Registered at:', new Date(info.registeredAt * 1000));
|
|
5211
|
-
* console.log('Circuit:', info.circuitId);
|
|
5212
|
-
* }
|
|
5213
|
-
* ```
|
|
5214
|
-
*/
|
|
5215
|
-
async getNullifierDetails(nullifier, provider) {
|
|
5216
|
-
if (!this.nullifierRegistry) {
|
|
5217
|
-
throw new Error('nullifierRegistry is required. Set it in ProofportSDK config.');
|
|
5218
|
-
}
|
|
5219
|
-
const p = provider || getDefaultProvider(this.nullifierRegistry.chainId);
|
|
5220
|
-
return getNullifierInfo(nullifier, this.nullifierRegistry.address, p);
|
|
5221
|
-
}
|
|
5222
4910
|
}
|
|
5223
4911
|
|
|
5224
4912
|
export { ProofportSDK, ProofportSDK as default };
|