@zkproofport-app/sdk 0.2.14 → 0.2.16

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/dist/index.js CHANGED
@@ -1480,26 +1480,33 @@ const CIRCUIT_SUPPORT_STATUS = Object.freeze({
1480
1480
  mdl_kr_region: 'planned',
1481
1481
  });
1482
1482
  /**
1483
- * Where each circuit's verification key lives inside the `zkproofport/circuits`
1484
- * repository, relative to its root.
1483
+ * Where each circuit's verification key FILE lives inside the
1484
+ * `zkproofport/circuits` repository, relative to its root.
1485
1485
  *
1486
1486
  * Off-chain verification needs the verification key and nothing else — no
1487
1487
  * circuit bytecode, no witness. The key is public by nature: it is what anyone
1488
1488
  * checking a proof must already have, and the Solidity verifiers deployed
1489
1489
  * on-chain embed the same key.
1490
1490
  *
1491
+ * NOTE THE TRAILING `/vk` TWICE. In that repository `target/vk` is a DIRECTORY
1492
+ * holding `vk`, `vk_hash` and `SHA256SUMS`; the key itself is `target/vk/vk`.
1493
+ * These paths were first copied here from the mobile app, which keeps the
1494
+ * directory and the filename as two fields and joins them — so taking only the
1495
+ * directory produced a URL that answers 404, and the first browser to try
1496
+ * off-chain verification said "Could not fetch the verification key (HTTP 404)".
1497
+ *
1491
1498
  * Exhaustive over {@link CircuitId} on purpose. A new circuit whose key path is
1492
1499
  * not listed here fails to compile rather than failing at verification time,
1493
1500
  * where the only symptom would be a proof that cannot be checked.
1494
1501
  */
1495
1502
  const CIRCUIT_VK_PATHS = Object.freeze({
1496
- coinbase_attestation: 'coinbase-attestation/target/vk',
1497
- coinbase_country_attestation: 'coinbase-country-attestation/target/vk',
1498
- oidc_domain_attestation: 'oidc-domain-attestation/target/vk',
1499
- giwa_attestation: 'giwa-attestation/target/vk',
1500
- mdl_kr_ownership: 'mdl/kr-ownership/target/vk',
1501
- mdl_kr_age: 'mdl/kr-age/target/vk',
1502
- mdl_kr_region: 'mdl/kr-region/target/vk',
1503
+ coinbase_attestation: 'coinbase-attestation/target/vk/vk',
1504
+ coinbase_country_attestation: 'coinbase-country-attestation/target/vk/vk',
1505
+ oidc_domain_attestation: 'oidc-domain-attestation/target/vk/vk',
1506
+ giwa_attestation: 'giwa-attestation/target/vk/vk',
1507
+ mdl_kr_ownership: 'mdl/kr-ownership/target/vk/vk',
1508
+ mdl_kr_age: 'mdl/kr-age/target/vk/vk',
1509
+ mdl_kr_region: 'mdl/kr-region/target/vk/vk',
1503
1510
  });
1504
1511
  /**
1505
1512
  * Every canonical circuit identifier, in declaration order.
@@ -1615,6 +1622,38 @@ const CIRCUITS_VK_BASE = 'https://raw.githubusercontent.com/zkproofport/circuits
1615
1622
  /** How long a fetched verification key is reused. Keys change only on a recompile. */
1616
1623
  const VK_CACHE_TTL_MS = 60 * 60 * 1000;
1617
1624
  const vkCache = new Map();
1625
+ /**
1626
+ * Make sure a Node-shaped `Buffer` exists before Barretenberg is loaded.
1627
+ *
1628
+ * WHY THE SDK DOES THIS RATHER THAN THE CALLER. bb.js's own BROWSER build —
1629
+ * not just its node build — converts field elements through `Buffer.alloc` and
1630
+ * `buf.writeBigUInt64BE`. Browsers have no Buffer, and bundlers stopped
1631
+ * polyfilling Node globals years ago, so in a browser the first verification
1632
+ * dies with "r.writeBigUInt64BE is not a function" — a message that names
1633
+ * nothing a caller could act on. Measured on the demo page, 2026-09-04, against
1634
+ * a real GIWA proof.
1635
+ *
1636
+ * Leaving it to callers would mean every browser customer editing their
1637
+ * bundler config to make an SDK method work, which is the configuration this
1638
+ * SDK promises not to require.
1639
+ *
1640
+ * Deliberately narrow:
1641
+ * - It only fills a GAP. A real Buffer (Node, or a page that already has one)
1642
+ * is left alone, so nothing is shadowed by a lesser implementation.
1643
+ * - It checks for the METHOD, not just the global. A partial Buffer — which is
1644
+ * what several bundlers leave behind, and what the demo page actually had —
1645
+ * passes a `typeof Buffer` test and then fails inside Barretenberg.
1646
+ */
1647
+ async function ensureBufferForBarretenberg() {
1648
+ const existing = globalThis.Buffer;
1649
+ if (existing?.alloc) {
1650
+ const probe = existing.alloc(8);
1651
+ if (typeof probe.writeBigUInt64BE === 'function')
1652
+ return;
1653
+ }
1654
+ const { Buffer } = await import('buffer/');
1655
+ globalThis.Buffer = Buffer;
1656
+ }
1618
1657
  /** @internal Hex string (with or without 0x) to bytes. */
1619
1658
  function hexToBytes(hex) {
1620
1659
  const clean = hex.startsWith('0x') || hex.startsWith('0X') ? hex.slice(2) : hex;
@@ -1724,6 +1763,8 @@ async function verifyProofOffChain(circuit, proof, publicInputs, options = {}) {
1724
1763
  //
1725
1764
  // The dynamic import is what keeps the cost off everyone else — a bundler
1726
1765
  // splits it out, and a caller who never verifies off-chain never loads it.
1766
+ // Before bb.js, not after: its module-level code already reaches for Buffer.
1767
+ await ensureBufferForBarretenberg();
1727
1768
  let bb;
1728
1769
  try {
1729
1770
  bb = await import('@aztec/bb.js');