@zkproofport-app/sdk 0.2.13 → 0.2.15

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
@@ -1581,19 +1581,22 @@ function getCircuitSupportStatus(circuit) {
1581
1581
  * (through mopro's native Barretenberg); it was only the JavaScript side that
1582
1582
  * had no such thing.
1583
1583
  *
1584
- * HOW IT WORKS. `bb` proofs are checked by `acirVerifyUltraKeccakHonk(proof,
1585
- * vk)` — the keccak variant, matching how these proofs are produced. Two things
1584
+ * HOW IT WORKS. Proofs here are made with `--oracle_hash keccak` and ZK on, so
1585
+ * the matching check is `acirVerifyUltraKeccakZkHonk(proof, vk)`. Two things
1586
1586
  * have to line up:
1587
1587
  *
1588
- * The version. The verification key format is not stable across bb releases:
1589
- * the pinned build emits a 1816-byte key where bb 0.87.0 and 1.2.0 emit 1760.
1590
- * `@aztec/bb.js@1.0.0-nightly.20250723` is the WASM build of the same bb the
1591
- * circuits were compiled with. A different one will reject valid proofs.
1588
+ * The version. `@aztec/bb.js@1.0.0-nightly.20250723` is the WASM build of the
1589
+ * same bb the circuits are compiled with. Versions are not interchangeable:
1590
+ * measured on the Korea Mobile ID age circuit, the pinned bb writes a 16256-
1591
+ * byte proof where bb 1.2.0 writes 16224 for the identical circuit and
1592
+ * witness — and the verification key comes out the SAME either way, so the
1593
+ * key cannot warn you. A mismatch shows up only as verification failing.
1592
1594
  *
1593
- * The oracle hash. Proofs are generated with `--oracle_hash keccak` so the
1594
- * Solidity verifiers can check them, so the poseidon-flavoured verify — which
1595
- * is what `BarretenbergVerifier.verifyUltraHonkProof` uses — says false for a
1596
- * perfectly good proof.
1595
+ * The flavour. There are four verify entry points and picking the wrong one
1596
+ * is not a polite false. `acirVerifyUltraZKHonk` (poseidon) answers false for
1597
+ * a perfectly good proof, and `acirVerifyUltraKeccakHonk` — keccak without ZK
1598
+ * — TRAPS the WebAssembly with a bare "unreachable", which looks exactly like
1599
+ * a corrupt proof, a mismatched key, or a missing SRS.
1597
1600
  *
1598
1601
  * THE PROOF ARRIVES IN TWO PIECES. The mobile app splits what Barretenberg
1599
1602
  * produced into `proof` and `publicInputs` before sending it, because the
@@ -1612,6 +1615,38 @@ const CIRCUITS_VK_BASE = 'https://raw.githubusercontent.com/zkproofport/circuits
1612
1615
  /** How long a fetched verification key is reused. Keys change only on a recompile. */
1613
1616
  const VK_CACHE_TTL_MS = 60 * 60 * 1000;
1614
1617
  const vkCache = new Map();
1618
+ /**
1619
+ * Make sure a Node-shaped `Buffer` exists before Barretenberg is loaded.
1620
+ *
1621
+ * WHY THE SDK DOES THIS RATHER THAN THE CALLER. bb.js's own BROWSER build —
1622
+ * not just its node build — converts field elements through `Buffer.alloc` and
1623
+ * `buf.writeBigUInt64BE`. Browsers have no Buffer, and bundlers stopped
1624
+ * polyfilling Node globals years ago, so in a browser the first verification
1625
+ * dies with "r.writeBigUInt64BE is not a function" — a message that names
1626
+ * nothing a caller could act on. Measured on the demo page, 2026-09-04, against
1627
+ * a real GIWA proof.
1628
+ *
1629
+ * Leaving it to callers would mean every browser customer editing their
1630
+ * bundler config to make an SDK method work, which is the configuration this
1631
+ * SDK promises not to require.
1632
+ *
1633
+ * Deliberately narrow:
1634
+ * - It only fills a GAP. A real Buffer (Node, or a page that already has one)
1635
+ * is left alone, so nothing is shadowed by a lesser implementation.
1636
+ * - It checks for the METHOD, not just the global. A partial Buffer — which is
1637
+ * what several bundlers leave behind, and what the demo page actually had —
1638
+ * passes a `typeof Buffer` test and then fails inside Barretenberg.
1639
+ */
1640
+ async function ensureBufferForBarretenberg() {
1641
+ const existing = globalThis.Buffer;
1642
+ if (existing?.alloc) {
1643
+ const probe = existing.alloc(8);
1644
+ if (typeof probe.writeBigUInt64BE === 'function')
1645
+ return;
1646
+ }
1647
+ const { Buffer } = await import('buffer/');
1648
+ globalThis.Buffer = Buffer;
1649
+ }
1615
1650
  /** @internal Hex string (with or without 0x) to bytes. */
1616
1651
  function hexToBytes(hex) {
1617
1652
  const clean = hex.startsWith('0x') || hex.startsWith('0X') ? hex.slice(2) : hex;
@@ -1690,9 +1725,8 @@ async function fetchVerificationKey(circuit, timeoutMs) {
1690
1725
  /**
1691
1726
  * Verify a proof off-chain, against its verification key.
1692
1727
  *
1693
- * Needs `@aztec/bb.js` at the pinned version. It is an optional peer dependency
1694
- * — the WASM is large and most callers verify on-chain — so the failure to have
1695
- * it installed says so plainly rather than surfacing as a module-not-found.
1728
+ * Needs no setup from the caller: the verifier ships with this SDK and is
1729
+ * loaded on first use.
1696
1730
  *
1697
1731
  * @param circuit - Canonical circuit identifier
1698
1732
  * @param proof - Proof bytes as hex, WITHOUT public inputs (as the relay sends it)
@@ -1712,15 +1746,31 @@ async function fetchVerificationKey(circuit, timeoutMs) {
1712
1746
  */
1713
1747
  async function verifyProofOffChain(circuit, proof, publicInputs, options = {}) {
1714
1748
  const timeoutMs = options.timeoutMs ?? 30000;
1749
+ // A REQUIRED dependency, loaded lazily.
1750
+ //
1751
+ // It was briefly an optional peer dependency, on the reasoning that the WASM
1752
+ // is 16MB and most callers verify on-chain. That was wrong: it would have
1753
+ // meant a customer calling this method got an error telling them to install
1754
+ // something, and "works with zero customer configuration" is the SDK's rule.
1755
+ // A caller should never have to know this is implemented with Barretenberg.
1756
+ //
1757
+ // The dynamic import is what keeps the cost off everyone else — a bundler
1758
+ // splits it out, and a caller who never verifies off-chain never loads it.
1759
+ // Before bb.js, not after: its module-level code already reaches for Buffer.
1760
+ await ensureBufferForBarretenberg();
1715
1761
  let bb;
1716
1762
  try {
1717
1763
  bb = await import('@aztec/bb.js');
1718
1764
  }
1719
- catch {
1765
+ catch (error) {
1766
+ // Reaching here means the install is broken, not that something is missing
1767
+ // by design. Say so, rather than sending the caller off to install a
1768
+ // package they should never have had to hear about.
1720
1769
  return {
1721
1770
  valid: false,
1722
- error: 'Off-chain verification needs @aztec/bb.js. Install the pinned version: ' +
1723
- 'npm install @aztec/bb.js@1.0.0-nightly.20250723',
1771
+ error: 'Could not load the proof verifier (@aztec/bb.js), which ships with this ' +
1772
+ 'SDK. This usually means a broken or partial install — try reinstalling ' +
1773
+ `@zkproofport-app/sdk. Underlying error: ${error instanceof Error ? error.message : String(error)}`,
1724
1774
  };
1725
1775
  }
1726
1776
  let api;
@@ -2432,10 +2482,8 @@ class ProofportSDK {
2432
2482
  * chain's own opinion: use {@link verifyResponseOnChain} when the answer has
2433
2483
  * to be one a contract will agree with.
2434
2484
  *
2435
- * Requires the optional peer dependency:
2436
- * `npm install @aztec/bb.js@1.0.0-nightly.20250723`. The version is exact —
2437
- * verification keys are not portable across bb releases, so a different build
2438
- * rejects valid proofs.
2485
+ * Needs no setup: the verifier ships with this SDK. It is loaded on first
2486
+ * use, so a caller who only verifies on-chain never pays for it.
2439
2487
  *
2440
2488
  * @param response - Proof response from the relay
2441
2489
  * @param options - Optional verification key (skips the fetch) and timeout