@zkproofport-app/sdk 0.2.1 → 0.2.2
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 +35 -0
- package/dist/ProofportSDK.d.ts +22 -0
- package/dist/constants.d.ts +4 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +121 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +124 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +121 -1
- package/dist/index.mjs.map +1 -1
- package/dist/verifier.d.ts +19 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -294,6 +294,41 @@ if (result.status === 'completed') {
|
|
|
294
294
|
const verification = await sdk.verifyResponseOnChain(response);
|
|
295
295
|
```
|
|
296
296
|
|
|
297
|
+
### Step 7: Extract Scope and Nullifier
|
|
298
|
+
|
|
299
|
+
After verification, extract the scope and nullifier from the public inputs:
|
|
300
|
+
|
|
301
|
+
```typescript
|
|
302
|
+
if (result.status === 'completed') {
|
|
303
|
+
// Extract scope — the keccak256 hash of the scope string you provided
|
|
304
|
+
const scope = sdk.extractScope(result.publicInputs, result.circuit);
|
|
305
|
+
|
|
306
|
+
// Extract nullifier — a unique, deterministic hash per user + scope
|
|
307
|
+
// Same user with the same scope always produces the same nullifier
|
|
308
|
+
const nullifier = sdk.extractNullifier(result.publicInputs, result.circuit);
|
|
309
|
+
|
|
310
|
+
console.log('Scope:', scope); // '0x7a6b70726f...'
|
|
311
|
+
console.log('Nullifier:', nullifier); // '0xabc123...'
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
The **nullifier** serves as a privacy-preserving user identifier:
|
|
316
|
+
- Deterministic: same user + same scope = same nullifier (enables duplicate detection)
|
|
317
|
+
- Privacy-preserving: the wallet address is never revealed
|
|
318
|
+
- Scope-bound: different scopes produce different nullifiers for the same user
|
|
319
|
+
|
|
320
|
+
**Standalone utility functions** are also available for use outside the SDK class:
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
import {
|
|
324
|
+
extractScopeFromPublicInputs,
|
|
325
|
+
extractNullifierFromPublicInputs,
|
|
326
|
+
} from '@zkproofport-app/sdk';
|
|
327
|
+
|
|
328
|
+
const scope = extractScopeFromPublicInputs(publicInputs, 'coinbase_attestation');
|
|
329
|
+
const nullifier = extractNullifierFromPublicInputs(publicInputs, 'coinbase_attestation');
|
|
330
|
+
```
|
|
331
|
+
|
|
297
332
|
## Complete Example
|
|
298
333
|
|
|
299
334
|
End-to-end integration using the relay flow:
|
package/dist/ProofportSDK.d.ts
CHANGED
|
@@ -893,5 +893,27 @@ export declare class ProofportSDK {
|
|
|
893
893
|
* ```
|
|
894
894
|
*/
|
|
895
895
|
extractScope(publicInputs: string[], circuit: CircuitType): string | null;
|
|
896
|
+
/**
|
|
897
|
+
* Extracts the nullifier (bytes32) from proof public inputs.
|
|
898
|
+
*
|
|
899
|
+
* The nullifier is a unique, deterministic hash derived from the user's attestation
|
|
900
|
+
* and scope. It serves as a privacy-preserving user identifier — the same user
|
|
901
|
+
* with the same scope always produces the same nullifier, enabling duplicate
|
|
902
|
+
* detection without revealing the wallet address.
|
|
903
|
+
*
|
|
904
|
+
* @param publicInputs - Array of hex-encoded field elements from proof result
|
|
905
|
+
* @param circuit - Circuit type that produced the public inputs
|
|
906
|
+
* @returns Nullifier as hex string (bytes32), or null if publicInputs too short
|
|
907
|
+
*
|
|
908
|
+
* @example
|
|
909
|
+
* ```typescript
|
|
910
|
+
* const result = await sdk.waitForProof(relay.requestId);
|
|
911
|
+
* if (result.status === 'completed') {
|
|
912
|
+
* const nullifier = sdk.extractNullifier(result.publicInputs, result.circuit);
|
|
913
|
+
* console.log('Nullifier:', nullifier); // '0xabc123...'
|
|
914
|
+
* }
|
|
915
|
+
* ```
|
|
916
|
+
*/
|
|
917
|
+
extractNullifier(publicInputs: string[], circuit: CircuitType): string | null;
|
|
896
918
|
}
|
|
897
919
|
export default ProofportSDK;
|
package/dist/constants.d.ts
CHANGED
|
@@ -145,6 +145,8 @@ export declare const COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT: {
|
|
|
145
145
|
readonly MERKLE_ROOT_END: 63;
|
|
146
146
|
readonly SCOPE_START: 64;
|
|
147
147
|
readonly SCOPE_END: 95;
|
|
148
|
+
readonly NULLIFIER_START: 96;
|
|
149
|
+
readonly NULLIFIER_END: 127;
|
|
148
150
|
};
|
|
149
151
|
/**
|
|
150
152
|
* Coinbase Country Attestation circuit public input layout (byte offsets).
|
|
@@ -178,4 +180,6 @@ export declare const COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT: {
|
|
|
178
180
|
readonly IS_INCLUDED: 85;
|
|
179
181
|
readonly SCOPE_START: 86;
|
|
180
182
|
readonly SCOPE_END: 117;
|
|
183
|
+
readonly NULLIFIER_START: 118;
|
|
184
|
+
readonly NULLIFIER_END: 149;
|
|
181
185
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -26,4 +26,6 @@
|
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
28
|
export { ProofportSDK, default } from './ProofportSDK';
|
|
29
|
+
export { extractScopeFromPublicInputs, extractNullifierFromPublicInputs, } from './verifier';
|
|
30
|
+
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT, } from './constants';
|
|
29
31
|
export type { CircuitType, ProofRequestStatus, CoinbaseKycInputs, CoinbaseCountryInputs, CircuitInputs, ProofRequest, ProofResponse, QRCodeOptions, VerifierContract, ProofportConfig, ChallengeResponse, WalletSigner, RelayProofRequest, RelayProofResult, SDKEnvironment, } from './types';
|
package/dist/index.esm.js
CHANGED
|
@@ -135,6 +135,69 @@ 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
|
+
* Coinbase Attestation circuit public input layout (byte offsets).
|
|
140
|
+
* Defines the byte positions of each field in the flattened public inputs array.
|
|
141
|
+
*
|
|
142
|
+
* Public inputs are packed as bytes32 values:
|
|
143
|
+
* - signal_hash: bytes 0-31
|
|
144
|
+
* - merkle_root: bytes 32-63
|
|
145
|
+
* - scope: bytes 64-95
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* const publicInputs = response.publicInputs;
|
|
150
|
+
* const signalHash = publicInputs.slice(
|
|
151
|
+
* COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT.SIGNAL_HASH_START,
|
|
152
|
+
* COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT.SIGNAL_HASH_END + 1
|
|
153
|
+
* );
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
const COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT = {
|
|
157
|
+
SIGNAL_HASH_START: 0,
|
|
158
|
+
SIGNAL_HASH_END: 31,
|
|
159
|
+
MERKLE_ROOT_START: 32,
|
|
160
|
+
MERKLE_ROOT_END: 63,
|
|
161
|
+
SCOPE_START: 64,
|
|
162
|
+
SCOPE_END: 95,
|
|
163
|
+
NULLIFIER_START: 96,
|
|
164
|
+
NULLIFIER_END: 127,
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Coinbase Country Attestation circuit public input layout (byte offsets).
|
|
168
|
+
* Defines the byte positions of each field in the flattened public inputs array.
|
|
169
|
+
*
|
|
170
|
+
* Public inputs are packed as bytes32 values:
|
|
171
|
+
* - signal_hash: bytes 0-31
|
|
172
|
+
* - merkle_root: bytes 32-63
|
|
173
|
+
* - country_list: bytes 64-83 (20 bytes for 10 countries)
|
|
174
|
+
* - country_list_length: byte 84
|
|
175
|
+
* - is_included: byte 85
|
|
176
|
+
* - scope: bytes 86-117
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const publicInputs = response.publicInputs;
|
|
181
|
+
* const countryList = publicInputs.slice(
|
|
182
|
+
* COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT.COUNTRY_LIST_START,
|
|
183
|
+
* COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT.COUNTRY_LIST_END + 1
|
|
184
|
+
* );
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
const COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT = {
|
|
188
|
+
SIGNAL_HASH_START: 0,
|
|
189
|
+
SIGNAL_HASH_END: 31,
|
|
190
|
+
MERKLE_ROOT_START: 32,
|
|
191
|
+
MERKLE_ROOT_END: 63,
|
|
192
|
+
COUNTRY_LIST_START: 64,
|
|
193
|
+
COUNTRY_LIST_END: 83,
|
|
194
|
+
COUNTRY_LIST_LENGTH: 84,
|
|
195
|
+
IS_INCLUDED: 85,
|
|
196
|
+
SCOPE_START: 86,
|
|
197
|
+
SCOPE_END: 117,
|
|
198
|
+
NULLIFIER_START: 118,
|
|
199
|
+
NULLIFIER_END: 149,
|
|
200
|
+
};
|
|
138
201
|
|
|
139
202
|
/**
|
|
140
203
|
* Deep Link utilities for ZKProofport SDK
|
|
@@ -3727,6 +3790,39 @@ function extractScopeFromPublicInputs(publicInputsHex, circuit) {
|
|
|
3727
3790
|
const scopeFields = publicInputsHex.slice(start, end + 1);
|
|
3728
3791
|
return reconstructBytes32FromFields(scopeFields);
|
|
3729
3792
|
}
|
|
3793
|
+
/**
|
|
3794
|
+
* Extracts the nullifier (bytes32) from public inputs based on circuit type.
|
|
3795
|
+
*
|
|
3796
|
+
* The nullifier is a unique, deterministic hash derived from the user's attestation
|
|
3797
|
+
* and scope. It serves as a privacy-preserving user identifier — the same user
|
|
3798
|
+
* with the same scope always produces the same nullifier, enabling duplicate
|
|
3799
|
+
* detection without revealing the wallet address.
|
|
3800
|
+
*
|
|
3801
|
+
* @param publicInputsHex - Array of hex-encoded field elements
|
|
3802
|
+
* @param circuit - Circuit type (defaults to coinbase_attestation)
|
|
3803
|
+
* @returns Nullifier as hex string (bytes32), or null if publicInputs too short
|
|
3804
|
+
*
|
|
3805
|
+
* @example
|
|
3806
|
+
* ```typescript
|
|
3807
|
+
* const nullifier = extractNullifierFromPublicInputs(publicInputs, 'coinbase_attestation');
|
|
3808
|
+
* console.log(nullifier); // '0xabc123...'
|
|
3809
|
+
* ```
|
|
3810
|
+
*/
|
|
3811
|
+
function extractNullifierFromPublicInputs(publicInputsHex, circuit) {
|
|
3812
|
+
let start, end;
|
|
3813
|
+
if (circuit === 'coinbase_country_attestation') {
|
|
3814
|
+
start = 118;
|
|
3815
|
+
end = 149;
|
|
3816
|
+
}
|
|
3817
|
+
else {
|
|
3818
|
+
start = 96;
|
|
3819
|
+
end = 127;
|
|
3820
|
+
}
|
|
3821
|
+
if (publicInputsHex.length <= end)
|
|
3822
|
+
return null;
|
|
3823
|
+
const nullifierFields = publicInputsHex.slice(start, end + 1);
|
|
3824
|
+
return reconstructBytes32FromFields(nullifierFields);
|
|
3825
|
+
}
|
|
3730
3826
|
/** @internal Reconstruct a bytes32 value from 32 individual field elements */
|
|
3731
3827
|
function reconstructBytes32FromFields(fields) {
|
|
3732
3828
|
if (fields.length !== 32) {
|
|
@@ -4907,7 +5003,31 @@ class ProofportSDK {
|
|
|
4907
5003
|
extractScope(publicInputs, circuit) {
|
|
4908
5004
|
return extractScopeFromPublicInputs(publicInputs, circuit);
|
|
4909
5005
|
}
|
|
5006
|
+
/**
|
|
5007
|
+
* Extracts the nullifier (bytes32) from proof public inputs.
|
|
5008
|
+
*
|
|
5009
|
+
* The nullifier is a unique, deterministic hash derived from the user's attestation
|
|
5010
|
+
* and scope. It serves as a privacy-preserving user identifier — the same user
|
|
5011
|
+
* with the same scope always produces the same nullifier, enabling duplicate
|
|
5012
|
+
* detection without revealing the wallet address.
|
|
5013
|
+
*
|
|
5014
|
+
* @param publicInputs - Array of hex-encoded field elements from proof result
|
|
5015
|
+
* @param circuit - Circuit type that produced the public inputs
|
|
5016
|
+
* @returns Nullifier as hex string (bytes32), or null if publicInputs too short
|
|
5017
|
+
*
|
|
5018
|
+
* @example
|
|
5019
|
+
* ```typescript
|
|
5020
|
+
* const result = await sdk.waitForProof(relay.requestId);
|
|
5021
|
+
* if (result.status === 'completed') {
|
|
5022
|
+
* const nullifier = sdk.extractNullifier(result.publicInputs, result.circuit);
|
|
5023
|
+
* console.log('Nullifier:', nullifier); // '0xabc123...'
|
|
5024
|
+
* }
|
|
5025
|
+
* ```
|
|
5026
|
+
*/
|
|
5027
|
+
extractNullifier(publicInputs, circuit) {
|
|
5028
|
+
return extractNullifierFromPublicInputs(publicInputs, circuit);
|
|
5029
|
+
}
|
|
4910
5030
|
}
|
|
4911
5031
|
|
|
4912
|
-
export { ProofportSDK, ProofportSDK as default };
|
|
5032
|
+
export { COINBASE_ATTESTATION_PUBLIC_INPUT_LAYOUT, COINBASE_COUNTRY_PUBLIC_INPUT_LAYOUT, ProofportSDK, ProofportSDK as default, extractNullifierFromPublicInputs, extractScopeFromPublicInputs };
|
|
4913
5033
|
//# sourceMappingURL=index.esm.js.map
|