@zkproofport-ai/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 CHANGED
@@ -390,6 +390,52 @@ const result = await generateProof(
390
390
 
391
391
  > **Note:** For OIDC circuits, the `attestation` signer field is only used as a payment fallback. Pass your payment wallet — no EAS-attested wallet needed.
392
392
 
393
+ ## Extracting Data from Proofs
394
+
395
+ For OIDC domain proofs, use helper functions to extract the domain and nullifier from public inputs:
396
+
397
+ ```typescript
398
+ import { generateProof, createConfig, fromPrivateKey, extractDomainFromPublicInputs, extractNullifierFromPublicInputs } from '@zkproofport-ai/sdk';
399
+
400
+ const config = createConfig();
401
+ const paymentSigner = fromPrivateKey(process.env.PAYMENT_KEY);
402
+
403
+ const result = await generateProof(
404
+ config,
405
+ { attestation: paymentSigner },
406
+ {
407
+ circuit: 'oidc_domain',
408
+ jwt: googleIdToken,
409
+ scope: 'myapp:verify-domain',
410
+ },
411
+ );
412
+
413
+ // Extract domain and nullifier from proof
414
+ const domain = extractDomainFromPublicInputs(result.publicInputs);
415
+ const nullifier = extractNullifierFromPublicInputs(result.publicInputs);
416
+
417
+ console.log('Verified domain:', domain);
418
+ console.log('Nullifier:', nullifier);
419
+ ```
420
+
421
+ **Public Input Layout (oidc_domain_attestation):**
422
+
423
+ The proof contains 148 public input fields (32 bytes each):
424
+
425
+ | Fields | Description |
426
+ |--------|-------------|
427
+ | 0-17 | RSA pubkey modulus limbs (18 x u128) |
428
+ | 18-81 | Domain storage (BoundedVec<u8, 64>) |
429
+ | 82 | Domain length |
430
+ | 83-114 | Scope (32 bytes) |
431
+ | 115-146 | Nullifier (32 bytes) |
432
+ | 147 | Provider identifier (u8) |
433
+
434
+ **Functions:**
435
+
436
+ - `extractDomainFromPublicInputs(publicInputs: string): string | null` — Extracts the email domain (e.g., "google.com") from public inputs. Returns null if extraction fails.
437
+ - `extractNullifierFromPublicInputs(publicInputs: string): string | null` — Extracts the 32-byte nullifier as a 0x-prefixed hex string. Returns null if extraction fails.
438
+
393
439
  ## Types Reference
394
440
 
395
441
  **Circuit Types:**
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Extract structured data from oidc_domain_attestation proof publicInputs.
3
+ *
4
+ * Layout (148 fields, each 32 bytes):
5
+ * Index 0-17: pubkey_modulus_limbs (18 x u128)
6
+ * Index 18-81: domain storage (BoundedVec<u8, 64> storage, 64 bytes)
7
+ * Index 82: domain len (BoundedVec len field)
8
+ * Index 83-114: scope (32 bytes)
9
+ * Index 115-146: nullifier (32 bytes)
10
+ * Index 147: provider (u8)
11
+ */
12
+ /**
13
+ * Extract domain from oidc_domain_attestation proof publicInputs.
14
+ *
15
+ * Noir BoundedVec<u8, 64> layout: storage[0..64] at field indices 18-81, len at field index 82.
16
+ * Each field's lower byte is the ASCII character.
17
+ *
18
+ * @param publicInputs - Single hex string (0x prefixed) of concatenated public inputs
19
+ * @returns The domain string, or null if extraction fails
20
+ */
21
+ export declare function extractDomainFromPublicInputs(publicInputs: string): string | null;
22
+ /**
23
+ * Extract nullifier from oidc_domain_attestation proof publicInputs.
24
+ *
25
+ * Nullifier is stored at field indices 115-146 (32 bytes).
26
+ * The result is a hex string representing the 32-byte nullifier.
27
+ *
28
+ * @param publicInputs - Single hex string (0x prefixed) of concatenated public inputs
29
+ * @returns The nullifier as a 0x-prefixed hex string, or null if extraction fails
30
+ */
31
+ export declare function extractNullifierFromPublicInputs(publicInputs: string): string | null;
32
+ //# sourceMappingURL=extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAcH;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0BjF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBpF"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Extract structured data from oidc_domain_attestation proof publicInputs.
3
+ *
4
+ * Layout (148 fields, each 32 bytes):
5
+ * Index 0-17: pubkey_modulus_limbs (18 x u128)
6
+ * Index 18-81: domain storage (BoundedVec<u8, 64> storage, 64 bytes)
7
+ * Index 82: domain len (BoundedVec len field)
8
+ * Index 83-114: scope (32 bytes)
9
+ * Index 115-146: nullifier (32 bytes)
10
+ * Index 147: provider (u8)
11
+ */
12
+ /**
13
+ * Split a concatenated hex string into 32-byte (64 hex char) fields.
14
+ */
15
+ function splitFields(publicInputsHex) {
16
+ const hex = publicInputsHex.startsWith('0x') ? publicInputsHex.slice(2) : publicInputsHex;
17
+ const fields = [];
18
+ for (let i = 0; i < hex.length; i += 64) {
19
+ fields.push('0x' + hex.slice(i, i + 64));
20
+ }
21
+ return fields;
22
+ }
23
+ /**
24
+ * Extract domain from oidc_domain_attestation proof publicInputs.
25
+ *
26
+ * Noir BoundedVec<u8, 64> layout: storage[0..64] at field indices 18-81, len at field index 82.
27
+ * Each field's lower byte is the ASCII character.
28
+ *
29
+ * @param publicInputs - Single hex string (0x prefixed) of concatenated public inputs
30
+ * @returns The domain string, or null if extraction fails
31
+ */
32
+ export function extractDomainFromPublicInputs(publicInputs) {
33
+ try {
34
+ const fields = splitFields(publicInputs);
35
+ // Need at least 83 fields (indices 0-82)
36
+ if (fields.length < 83) {
37
+ return null;
38
+ }
39
+ // Read domain length from field index 82
40
+ const domainLen = Number(BigInt(fields[82]));
41
+ if (domainLen <= 0 || domainLen > 64) {
42
+ return null;
43
+ }
44
+ // Read domain bytes from field indices 18..18+domainLen
45
+ const chars = [];
46
+ for (let i = 0; i < domainLen; i++) {
47
+ const byte = Number(BigInt(fields[18 + i]) & 0xffn);
48
+ chars.push(String.fromCharCode(byte));
49
+ }
50
+ return chars.join('');
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ }
56
+ /**
57
+ * Extract nullifier from oidc_domain_attestation proof publicInputs.
58
+ *
59
+ * Nullifier is stored at field indices 115-146 (32 bytes).
60
+ * The result is a hex string representing the 32-byte nullifier.
61
+ *
62
+ * @param publicInputs - Single hex string (0x prefixed) of concatenated public inputs
63
+ * @returns The nullifier as a 0x-prefixed hex string, or null if extraction fails
64
+ */
65
+ export function extractNullifierFromPublicInputs(publicInputs) {
66
+ try {
67
+ const fields = splitFields(publicInputs);
68
+ // Need at least 147 fields (indices 0-146)
69
+ if (fields.length < 147) {
70
+ return null;
71
+ }
72
+ // Read nullifier bytes from field indices 115..147
73
+ const bytes = [];
74
+ for (let i = 115; i < 147; i++) {
75
+ const byte = (BigInt(fields[i]) & 0xffn).toString(16).padStart(2, '0');
76
+ bytes.push(byte);
77
+ }
78
+ return '0x' + bytes.join('');
79
+ }
80
+ catch {
81
+ return null;
82
+ }
83
+ }
84
+ //# sourceMappingURL=extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;GAEG;AACH,SAAS,WAAW,CAAC,eAAuB;IAC1C,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC;IAC1F,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,6BAA6B,CAAC,YAAoB;IAChE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QAEzC,yCAAyC;QACzC,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,yCAAyC;QACzC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,SAAS,IAAI,CAAC,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,wDAAwD;QACxD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;YACpD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gCAAgC,CAAC,YAAoB;IACnE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;QAEzC,2CAA2C;QAC3C,IAAI,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mDAAmD;QACnD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACvE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;QAED,OAAO,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
package/dist/index.d.ts CHANGED
@@ -15,5 +15,6 @@ export type { ProofportSigner } from './signer.js';
15
15
  export { EthersWalletSigner, fromEthersWallet, fromPrivateKey } from './signer.js';
16
16
  export { CdpWalletSigner, fromExternalWallet } from './cdp.js';
17
17
  export type { ExternalWallet } from './cdp.js';
18
+ export { extractDomainFromPublicInputs, extractNullifierFromPublicInputs, } from './extract.js';
18
19
  export { fetchAttestation, getSignerAddress, } from './attestation.js';
19
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,EACf,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG9D,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACzE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG/F,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGnF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG/C,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,cAAc,EACd,eAAe,EACf,WAAW,EACX,WAAW,EACX,UAAU,GACX,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAG9D,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACzE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAG/F,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGnF,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG/C,OAAO,EACL,6BAA6B,EAC7B,gCAAgC,GACjC,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -17,6 +17,8 @@ export { prepareOidcInputs, prepareOidcPayload } from './oidc-inputs.js';
17
17
  export { EthersWalletSigner, fromEthersWallet, fromPrivateKey } from './signer.js';
18
18
  // CDP (Coinbase Developer Platform) signer
19
19
  export { CdpWalletSigner, fromExternalWallet } from './cdp.js';
20
+ // Extraction helpers (parse publicInputs from proof results)
21
+ export { extractDomainFromPublicInputs, extractNullifierFromPublicInputs, } from './extract.js';
20
22
  // Attestation (customer-facing helpers)
21
23
  export { fetchAttestation, getSignerAddress, } from './attestation.js';
22
24
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9D,YAAY;AACZ,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,0BAA0B;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,4CAA4C;AAC5C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,8CAA8C;AAC9C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAKzE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnF,2CAA2C;AAC3C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG/D,wCAAwC;AACxC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE9D,YAAY;AACZ,OAAO,EACL,QAAQ,EACR,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,gBAAgB;AAChB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,0BAA0B;AAC1B,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,4CAA4C;AAC5C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,8CAA8C;AAC9C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,oEAAoE;AACpE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAKzE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnF,2CAA2C;AAC3C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAG/D,6DAA6D;AAC7D,OAAO,EACL,6BAA6B,EAC7B,gCAAgC,GACjC,MAAM,cAAc,CAAC;AAEtB,wCAAwC;AACxC,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zkproofport-ai/sdk",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Client SDK for ZKProofport proof generation",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",