o1js 1.3.0 → 1.3.1

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.
Files changed (145) hide show
  1. package/dist/node/index.cjs +1082 -493
  2. package/dist/node/index.d.ts +3 -0
  3. package/dist/node/index.js +4 -0
  4. package/dist/node/index.js.map +1 -1
  5. package/dist/node/lib/mina/account-update.d.ts +149 -31
  6. package/dist/node/lib/mina/account-update.js +23 -1
  7. package/dist/node/lib/mina/account-update.js.map +1 -1
  8. package/dist/node/lib/mina/account.d.ts +1 -1
  9. package/dist/node/lib/mina/account.js +1 -1
  10. package/dist/node/lib/mina/account.js.map +1 -1
  11. package/dist/node/lib/mina/actions/offchain-state-rollup.d.ts +202 -31
  12. package/dist/node/lib/mina/actions/offchain-state-rollup.js +56 -74
  13. package/dist/node/lib/mina/actions/offchain-state-rollup.js.map +1 -1
  14. package/dist/node/lib/mina/actions/offchain-state-serialization.d.ts +4 -4
  15. package/dist/node/lib/mina/actions/offchain-state-serialization.js +10 -10
  16. package/dist/node/lib/mina/actions/offchain-state-serialization.js.map +1 -1
  17. package/dist/node/lib/mina/actions/offchain-state.d.ts +32 -1
  18. package/dist/node/lib/mina/actions/offchain-state.js +30 -20
  19. package/dist/node/lib/mina/actions/offchain-state.js.map +1 -1
  20. package/dist/node/lib/mina/fetch.js +4 -1
  21. package/dist/node/lib/mina/fetch.js.map +1 -1
  22. package/dist/node/lib/mina/graphql.d.ts +48 -47
  23. package/dist/node/lib/mina/graphql.js.map +1 -1
  24. package/dist/node/lib/mina/token/forest-iterator.d.ts +16 -4
  25. package/dist/node/lib/mina/zkapp.d.ts +10 -4
  26. package/dist/node/lib/provable/bytes.d.ts +8 -0
  27. package/dist/node/lib/provable/bytes.js.map +1 -1
  28. package/dist/node/lib/provable/core/provable-context.d.ts +2 -1
  29. package/dist/node/lib/provable/core/provable-context.js +12 -8
  30. package/dist/node/lib/provable/core/provable-context.js.map +1 -1
  31. package/dist/node/lib/provable/crypto/foreign-curve.d.ts +6 -0
  32. package/dist/node/lib/provable/crypto/foreign-curve.js.map +1 -1
  33. package/dist/node/lib/provable/crypto/foreign-ecdsa.d.ts +16 -2
  34. package/dist/node/lib/provable/crypto/foreign-ecdsa.js +20 -4
  35. package/dist/node/lib/provable/crypto/foreign-ecdsa.js.map +1 -1
  36. package/dist/node/lib/provable/field.d.ts +2 -2
  37. package/dist/node/lib/provable/field.js +2 -2
  38. package/dist/node/lib/provable/gadgets/elliptic-curve.d.ts +17 -2
  39. package/dist/node/lib/provable/gadgets/elliptic-curve.js +70 -40
  40. package/dist/node/lib/provable/gadgets/elliptic-curve.js.map +1 -1
  41. package/dist/node/lib/provable/int.d.ts +31 -4
  42. package/dist/node/lib/provable/int.js +70 -11
  43. package/dist/node/lib/provable/int.js.map +1 -1
  44. package/dist/node/lib/provable/merkle-tree-indexed.d.ts +615 -0
  45. package/dist/node/lib/provable/merkle-tree-indexed.js +614 -0
  46. package/dist/node/lib/provable/merkle-tree-indexed.js.map +1 -0
  47. package/dist/node/lib/provable/merkle-tree.d.ts +2 -2
  48. package/dist/node/lib/provable/merkle-tree.js +4 -3
  49. package/dist/node/lib/provable/merkle-tree.js.map +1 -1
  50. package/dist/node/lib/provable/option.d.ts +4 -1
  51. package/dist/node/lib/provable/option.js.map +1 -1
  52. package/dist/node/lib/provable/types/provable-derivers.d.ts +3 -3
  53. package/dist/node/lib/provable/types/unconstrained.d.ts +3 -3
  54. package/dist/node/lib/provable/types/unconstrained.js +2 -0
  55. package/dist/node/lib/provable/types/unconstrained.js.map +1 -1
  56. package/dist/node/lib/util/errors.d.ts +5 -1
  57. package/dist/node/lib/util/errors.js +9 -1
  58. package/dist/node/lib/util/errors.js.map +1 -1
  59. package/dist/web/index.d.ts +3 -0
  60. package/dist/web/index.js +65 -65
  61. package/dist/web/index.js.map +1 -1
  62. package/dist/web/lib/mina/account-update.d.ts +149 -31
  63. package/dist/web/lib/mina/account-update.js +23 -1
  64. package/dist/web/lib/mina/account-update.js.map +1 -1
  65. package/dist/web/lib/mina/account.d.ts +1 -1
  66. package/dist/web/lib/mina/account.js +1 -1
  67. package/dist/web/lib/mina/account.js.map +1 -1
  68. package/dist/web/lib/mina/actions/offchain-state-rollup.d.ts +202 -31
  69. package/dist/web/lib/mina/actions/offchain-state-rollup.js +56 -74
  70. package/dist/web/lib/mina/actions/offchain-state-rollup.js.map +1 -1
  71. package/dist/web/lib/mina/actions/offchain-state-serialization.d.ts +4 -4
  72. package/dist/web/lib/mina/actions/offchain-state-serialization.js +10 -10
  73. package/dist/web/lib/mina/actions/offchain-state-serialization.js.map +1 -1
  74. package/dist/web/lib/mina/actions/offchain-state.d.ts +32 -1
  75. package/dist/web/lib/mina/actions/offchain-state.js +30 -20
  76. package/dist/web/lib/mina/actions/offchain-state.js.map +1 -1
  77. package/dist/web/lib/mina/fetch.js +4 -1
  78. package/dist/web/lib/mina/fetch.js.map +1 -1
  79. package/dist/web/lib/mina/graphql.d.ts +48 -47
  80. package/dist/web/lib/mina/graphql.js.map +1 -1
  81. package/dist/web/lib/mina/token/forest-iterator.d.ts +16 -4
  82. package/dist/web/lib/mina/zkapp.d.ts +10 -4
  83. package/dist/web/lib/provable/bytes.d.ts +8 -0
  84. package/dist/web/lib/provable/bytes.js.map +1 -1
  85. package/dist/web/lib/provable/core/provable-context.d.ts +2 -1
  86. package/dist/web/lib/provable/core/provable-context.js +12 -8
  87. package/dist/web/lib/provable/core/provable-context.js.map +1 -1
  88. package/dist/web/lib/provable/crypto/foreign-curve.d.ts +6 -0
  89. package/dist/web/lib/provable/crypto/foreign-curve.js.map +1 -1
  90. package/dist/web/lib/provable/crypto/foreign-ecdsa.d.ts +16 -2
  91. package/dist/web/lib/provable/crypto/foreign-ecdsa.js +20 -4
  92. package/dist/web/lib/provable/crypto/foreign-ecdsa.js.map +1 -1
  93. package/dist/web/lib/provable/field.d.ts +2 -2
  94. package/dist/web/lib/provable/field.js +2 -2
  95. package/dist/web/lib/provable/gadgets/elliptic-curve.d.ts +17 -2
  96. package/dist/web/lib/provable/gadgets/elliptic-curve.js +70 -40
  97. package/dist/web/lib/provable/gadgets/elliptic-curve.js.map +1 -1
  98. package/dist/web/lib/provable/int.d.ts +31 -4
  99. package/dist/web/lib/provable/int.js +70 -11
  100. package/dist/web/lib/provable/int.js.map +1 -1
  101. package/dist/web/lib/provable/merkle-tree-indexed.d.ts +615 -0
  102. package/dist/web/lib/provable/merkle-tree-indexed.js +614 -0
  103. package/dist/web/lib/provable/merkle-tree-indexed.js.map +1 -0
  104. package/dist/web/lib/provable/merkle-tree.d.ts +2 -2
  105. package/dist/web/lib/provable/merkle-tree.js +4 -3
  106. package/dist/web/lib/provable/merkle-tree.js.map +1 -1
  107. package/dist/web/lib/provable/option.d.ts +4 -1
  108. package/dist/web/lib/provable/option.js.map +1 -1
  109. package/dist/web/lib/provable/types/provable-derivers.d.ts +3 -3
  110. package/dist/web/lib/provable/types/unconstrained.d.ts +3 -3
  111. package/dist/web/lib/provable/types/unconstrained.js +2 -0
  112. package/dist/web/lib/provable/types/unconstrained.js.map +1 -1
  113. package/dist/web/lib/util/errors.d.ts +5 -1
  114. package/dist/web/lib/util/errors.js +9 -1
  115. package/dist/web/lib/util/errors.js.map +1 -1
  116. package/package.json +1 -1
  117. package/src/examples/crypto/ecdsa/ecdsa.ts +2 -2
  118. package/src/examples/zkapps/voting/run-berkeley.ts +2 -2
  119. package/src/index.ts +9 -0
  120. package/src/lib/mina/account-update.ts +27 -2
  121. package/src/lib/mina/account.ts +1 -1
  122. package/src/lib/mina/actions/offchain-contract.unit-test.ts +9 -11
  123. package/src/lib/mina/actions/offchain-state-rollup.ts +71 -95
  124. package/src/lib/mina/actions/offchain-state-serialization.ts +19 -13
  125. package/src/lib/mina/actions/offchain-state.ts +75 -25
  126. package/src/lib/mina/fetch.ts +6 -3
  127. package/src/lib/mina/graphql.ts +41 -39
  128. package/src/lib/provable/bytes.ts +1 -0
  129. package/src/lib/provable/core/provable-context.ts +14 -7
  130. package/src/lib/provable/crypto/foreign-curve.ts +1 -0
  131. package/src/lib/provable/crypto/foreign-ecdsa.ts +31 -4
  132. package/src/lib/provable/field.ts +2 -2
  133. package/src/lib/provable/gadgets/elliptic-curve.ts +137 -48
  134. package/src/lib/provable/int.ts +85 -12
  135. package/src/lib/provable/merkle-tree-indexed.ts +795 -0
  136. package/src/lib/provable/merkle-tree.ts +4 -3
  137. package/src/lib/provable/option.ts +17 -13
  138. package/src/lib/provable/test/custom-gates-recursion.unit-test.ts +1 -1
  139. package/src/lib/provable/test/ecdsa.unit-test.ts +31 -2
  140. package/src/lib/provable/test/merkle-tree.unit-test.ts +280 -3
  141. package/src/lib/provable/types/provable-derivers.ts +3 -3
  142. package/src/lib/provable/types/unconstrained.ts +4 -3
  143. package/src/lib/testing/constraint-system.ts +6 -0
  144. package/src/lib/testing/equivalent.ts +6 -1
  145. package/src/lib/util/errors.ts +12 -0
@@ -4584,13 +4584,7 @@ function constraintSystemToJS(cs) {
4584
4584
  printGates(gates);
4585
4585
  },
4586
4586
  summary() {
4587
- let gateTypes = {};
4588
- gateTypes["Total rows"] = rows;
4589
- for (let gate of gates) {
4590
- gateTypes[gate.type] ??= 0;
4591
- gateTypes[gate.type]++;
4592
- }
4593
- return gateTypes;
4587
+ return summarizeGates(gates);
4594
4588
  }
4595
4589
  };
4596
4590
  }
@@ -4601,6 +4595,15 @@ function gatesFromJson(cs) {
4601
4595
  });
4602
4596
  return { publicInputSize: cs.public_input_size, gates };
4603
4597
  }
4598
+ function summarizeGates(gates) {
4599
+ let gateTypes = {};
4600
+ gateTypes["Total rows"] = gates.length;
4601
+ for (let gate of gates) {
4602
+ gateTypes[gate.type] ??= 0;
4603
+ gateTypes[gate.type]++;
4604
+ }
4605
+ return gateTypes;
4606
+ }
4604
4607
  function printGates(gates) {
4605
4608
  for (let i = 0, n = gates.length; i < n; i++) {
4606
4609
  let { type, wires, coeffs } = gates[i];
@@ -6131,6 +6134,8 @@ and Provable.asProver() blocks, which execute outside the proof.
6131
6134
  * ```
6132
6135
  */
6133
6136
  static from(value) {
6137
+ if (value instanceof _Unconstrained)
6138
+ return value;
6134
6139
  return new _Unconstrained(true, value);
6135
6140
  }
6136
6141
  /**
@@ -7259,7 +7264,7 @@ var Field3 = class _Field {
7259
7264
  * ```ts
7260
7265
  * const someField = Field(42);
7261
7266
  * const inverse = someField.inv();
7262
- * inverse.assertEquals(Field(1).div(example)); // This statement is always true regardless of the value of `someField`
7267
+ * inverse.assertEquals(Field(1).div(someField)); // This statement is always true regardless of the value of `someField`
7263
7268
  * ```
7264
7269
  *
7265
7270
  * **Warning**: This is a modular inverse. See {@link div} method for more details.
@@ -7493,7 +7498,7 @@ var Field3 = class _Field {
7493
7498
  * Assert that this {@link Field} is less than another "field-like" value.
7494
7499
  *
7495
7500
  * Note: This uses fewer constraints than `x.lessThan(y).assertTrue()`.
7496
- * See {@link Field.lessThan} for more details.
7501
+ * See {@link lessThan} for more details.
7497
7502
  *
7498
7503
  * **Important**: If an assertion fails, the code throws an error.
7499
7504
  *
@@ -11424,7 +11429,7 @@ var Sign3 = class _Sign extends CircuitValue {
11424
11429
  return new _Sign(Field4(-1));
11425
11430
  }
11426
11431
  static check(x) {
11427
- x.value.square().assertEquals(Field4(1));
11432
+ x.value.square().assertEquals(1);
11428
11433
  }
11429
11434
  static empty() {
11430
11435
  return _Sign.one;
@@ -11449,7 +11454,10 @@ var Sign3 = class _Sign extends CircuitValue {
11449
11454
  return new _Sign(this.value.mul(y.value));
11450
11455
  }
11451
11456
  isPositive() {
11452
- return this.value.equals(Field4(1));
11457
+ return this.value.equals(1);
11458
+ }
11459
+ isNegative() {
11460
+ return this.value.equals(-1);
11453
11461
  }
11454
11462
  toString() {
11455
11463
  return this.value.toString();
@@ -11502,9 +11510,9 @@ var Int64 = class _Int64 extends CircuitValue {
11502
11510
  let isValidNegative = Field4.ORDER - xBigInt < TWO64;
11503
11511
  if (!isValidPositive && !isValidNegative)
11504
11512
  throw Error(`Int64: Expected a value between (-2^64, 2^64), got ${x}`);
11505
- let magnitude = Field4(isValidPositive ? x.toString() : x.neg().toString());
11513
+ let magnitude = (isValidPositive ? x : x.neg()).toConstant();
11506
11514
  let sign3 = isValidPositive ? Sign3.one : Sign3.minusOne;
11507
- return new _Int64(new UInt642(magnitude.value), sign3);
11515
+ return new _Int64(UInt642.Unsafe.fromField(magnitude), sign3);
11508
11516
  }
11509
11517
  // this doesn't check ranges because we assume they're already checked on UInts
11510
11518
  /**
@@ -11578,13 +11586,20 @@ var Int64 = class _Int64 extends CircuitValue {
11578
11586
  xInt.toField().assertEquals(x);
11579
11587
  return xInt;
11580
11588
  }
11589
+ /**
11590
+ * @deprecated Use {@link negV2()} instead.
11591
+ * The current implementation will not be backwards-compatible with v2.
11592
+ */
11593
+ neg() {
11594
+ return new _Int64(this.magnitude, this.sgn.neg());
11595
+ }
11581
11596
  /**
11582
11597
  * Negates the value.
11583
11598
  *
11584
11599
  * `Int64.from(5).neg()` will turn into `Int64.from(-5)`
11585
11600
  */
11586
- neg() {
11587
- return new _Int64(this.magnitude, this.sgn.neg());
11601
+ negV2() {
11602
+ return Provable.if(this.magnitude.value.equals(0), _Int64.zero, new _Int64(this.magnitude, this.sgn.neg()));
11588
11603
  }
11589
11604
  /**
11590
11605
  * Addition with overflow checking.
@@ -11612,7 +11627,7 @@ var Int64 = class _Int64 extends CircuitValue {
11612
11627
  *
11613
11628
  * `x.div(y)` returns the floor of `x / y`, that is, the greatest
11614
11629
  * `z` such that `z * y <= x`.
11615
- *
11630
+ * On negative numbers, this rounds towards zero.
11616
11631
  */
11617
11632
  div(y) {
11618
11633
  let y_ = _Int64.from(y);
@@ -11620,16 +11635,28 @@ var Int64 = class _Int64 extends CircuitValue {
11620
11635
  let sign3 = this.sgn.mul(y_.sgn);
11621
11636
  return new _Int64(quotient, sign3);
11622
11637
  }
11638
+ /**
11639
+ * @deprecated Use {@link modV2()} instead.
11640
+ * This implementation is vulnerable whenever `this` is zero.
11641
+ * It allows the prover to return `y` instead of 0 as the result.
11642
+ */
11643
+ mod(y) {
11644
+ let y_ = UInt642.from(y);
11645
+ let rest = this.magnitude.divMod(y_).rest.value;
11646
+ rest = Provable.if(this.isPositive(), rest, y_.value.sub(rest));
11647
+ return new _Int64(new UInt642(rest.value));
11648
+ }
11623
11649
  /**
11624
11650
  * Integer remainder.
11625
11651
  *
11626
11652
  * `x.mod(y)` returns the value `z` such that `0 <= z < y` and
11627
11653
  * `x - z` is divisible by `y`.
11628
11654
  */
11629
- mod(y) {
11655
+ modV2(y) {
11630
11656
  let y_ = UInt642.from(y);
11631
11657
  let rest = this.magnitude.divMod(y_).rest.value;
11632
- rest = Provable.if(this.isPositive(), rest, y_.value.sub(rest));
11658
+ let isNonNegative = this.magnitude.equals(UInt642.zero).or(this.sgn.isPositive());
11659
+ rest = Provable.if(isNonNegative, rest, y_.value.sub(rest));
11633
11660
  return new _Int64(new UInt642(rest.value));
11634
11661
  }
11635
11662
  /**
@@ -11647,11 +11674,40 @@ var Int64 = class _Int64 extends CircuitValue {
11647
11674
  this.toField().assertEquals(y_.toField(), message);
11648
11675
  }
11649
11676
  /**
11650
- * Checks if the value is positive.
11677
+ * @deprecated Use {@link isPositiveV2} instead.
11678
+ * The current implementation actually tests for non-negativity, but is wrong for the negative representation of 0.
11651
11679
  */
11652
11680
  isPositive() {
11653
11681
  return this.sgn.isPositive();
11654
11682
  }
11683
+ /**
11684
+ * Checks if the value is positive (x > 0).
11685
+ */
11686
+ isPositiveV2() {
11687
+ return this.magnitude.equals(UInt642.zero).not().and(this.sgn.isPositive());
11688
+ }
11689
+ // TODO add this when `checkV2` is enabled
11690
+ // then it will be the correct logic; right now it would be misleading
11691
+ /**
11692
+ * Checks if the value is non-negative (x >= 0).
11693
+ */
11694
+ // isNonNegativeV2() {
11695
+ // return this.sgn.isPositive();
11696
+ // }
11697
+ // TODO add this when `checkV2` is enabled
11698
+ // then it will be the correct logic; right now it would be misleading
11699
+ /**
11700
+ * Checks if the value is negative (x < 0).
11701
+ */
11702
+ // isNegative() {
11703
+ // return this.sgn.isNegative();
11704
+ // }
11705
+ // TODO enable this check method in v2, to force a unique representation of 0
11706
+ static checkV2({ magnitude, sgn }) {
11707
+ UInt642.check(magnitude);
11708
+ Sign3.check(sgn);
11709
+ magnitude.value.add(sgn.value).assertNotEquals(-1, "Int64: 0 must have positive sign");
11710
+ }
11655
11711
  };
11656
11712
  (0, import_tslib3.__decorate)([
11657
11713
  prop,
@@ -14116,7 +14172,7 @@ function equals2(p1, p22, Curve) {
14116
14172
  let yEquals = ForeignField.equals(p1.y, p22.y, Curve.modulus);
14117
14173
  return xEquals.and(yEquals);
14118
14174
  }
14119
- function verifyEcdsa(Curve, signature, msgHash, publicKey, config = { G: { windowSize: 4 }, P: { windowSize: 4 } }) {
14175
+ function verifyEcdsaGeneric(Curve, signature, msgHash, publicKey, multiScalarMul2, config = { G: { windowSize: 4 }, P: { windowSize: 4 } }) {
14120
14176
  if (EcdsaSignature.isConstant(signature) && Field32.isConstant(msgHash) && Point.isConstant(publicKey)) {
14121
14177
  let isValid = verifyEcdsaConstant(Curve, EcdsaSignature.toBigint(signature), Field32.toBigint(msgHash), Point.toBigint(publicKey));
14122
14178
  return new Bool3(isValid);
@@ -14127,11 +14183,17 @@ function verifyEcdsa(Curve, signature, msgHash, publicKey, config = { G: { windo
14127
14183
  let u1 = ForeignField.mul(msgHash, sInv, Curve.order);
14128
14184
  let u2 = ForeignField.mul(r, sInv, Curve.order);
14129
14185
  let G = Point.from(Curve.one);
14130
- let R = multiScalarMul([u1, u2], [G, publicKey], Curve, config && [config.G, config.P], "assert-nonzero", config?.ia);
14186
+ let R = multiScalarMul2([u1, u2], [G, publicKey], Curve, config && [config.G, config.P], "assert-nonzero", config?.ia);
14131
14187
  let Rx = ForeignField.mul(R.x, Field32.from(1n), Curve.order);
14132
14188
  ForeignField.assertLessThan(Rx, Curve.order);
14133
14189
  return Provable.equal(Field32.provable, Rx, r);
14134
14190
  }
14191
+ function verifyEcdsa(Curve, signature, msgHash, publicKey, config = { G: { windowSize: 4 }, P: { windowSize: 4 } }) {
14192
+ return verifyEcdsaGeneric(Curve, signature, msgHash, publicKey, (scalars, points, Curve2, configs, mode, ia) => multiScalarMul(scalars, points, Curve2, configs, mode, ia, true), config);
14193
+ }
14194
+ function verifyEcdsaV2(Curve, signature, msgHash, publicKey, config = { G: { windowSize: 4 }, P: { windowSize: 3 } }) {
14195
+ return verifyEcdsaGeneric(Curve, signature, msgHash, publicKey, (scalars, points, Curve2, configs, mode, ia) => multiScalarMul(scalars, points, Curve2, configs, mode, ia, false), config);
14196
+ }
14135
14197
  function verifyEcdsaConstant(Curve, { r, s }, msgHash, publicKey) {
14136
14198
  let pk = Curve.from(publicKey);
14137
14199
  if (Curve.equal(pk, Curve.zero))
@@ -14151,28 +14213,35 @@ function verifyEcdsaConstant(Curve, { r, s }, msgHash, publicKey) {
14151
14213
  return false;
14152
14214
  return Curve.Scalar.equal(R.x, r);
14153
14215
  }
14154
- function multiScalarMul(scalars, points, Curve, tableConfigs = [], mode = "assert-nonzero", ia) {
14216
+ function multiScalarMulConstant(scalars, points, Curve, mode = "assert-nonzero") {
14155
14217
  let n = points.length;
14156
14218
  assert3(scalars.length === n, "Points and scalars lengths must match");
14157
14219
  assertPositiveInteger(n, "Expected at least 1 point and scalar");
14158
14220
  let useGlv = Curve.hasEndomorphism;
14159
- if (scalars.every(Field32.isConstant) && points.every(Point.isConstant)) {
14160
- let s = scalars.map(Field32.toBigint);
14161
- let P = points.map(Point.toBigint);
14162
- let sum3 = Curve.zero;
14163
- for (let i = 0; i < n; i++) {
14164
- if (useGlv) {
14165
- sum3 = Curve.add(sum3, Curve.Endo.scale(P[i], s[i]));
14166
- } else {
14167
- sum3 = Curve.add(sum3, Curve.scale(P[i], s[i]));
14168
- }
14169
- }
14170
- if (mode === "assert-zero") {
14171
- assert3(sum3.infinity, "scalar multiplication: expected zero result");
14172
- return Point.from(Curve.zero);
14221
+ let s = scalars.map(Field32.toBigint);
14222
+ let P = points.map(Point.toBigint);
14223
+ let sum2 = Curve.zero;
14224
+ for (let i = 0; i < n; i++) {
14225
+ if (useGlv) {
14226
+ sum2 = Curve.add(sum2, Curve.Endo.scale(P[i], s[i]));
14227
+ } else {
14228
+ sum2 = Curve.add(sum2, Curve.scale(P[i], s[i]));
14173
14229
  }
14174
- assert3(!sum3.infinity, "scalar multiplication: expected non-zero result");
14175
- return Point.from(sum3);
14230
+ }
14231
+ if (mode === "assert-zero") {
14232
+ assert3(sum2.infinity, "scalar multiplication: expected zero result");
14233
+ return Point.from(Curve.zero);
14234
+ }
14235
+ assert3(!sum2.infinity, "scalar multiplication: expected non-zero result");
14236
+ return Point.from(sum2);
14237
+ }
14238
+ function multiScalarMul(scalars, points, Curve, tableConfigs = [], mode = "assert-nonzero", ia, hashed = true) {
14239
+ let n = points.length;
14240
+ assert3(scalars.length === n, "Points and scalars lengths must match");
14241
+ assertPositiveInteger(n, "Expected at least 1 point and scalar");
14242
+ let useGlv = Curve.hasEndomorphism;
14243
+ if (scalars.every(Field32.isConstant) && points.every(Point.isConstant)) {
14244
+ return multiScalarMulConstant(scalars, points, Curve, mode);
14176
14245
  }
14177
14246
  let windowSizes = points.map((_, i) => tableConfigs[i]?.windowSize ?? 1);
14178
14247
  let tables = points.map((P, i) => getPointTable(Curve, P, windowSizes[i], tableConfigs[i]?.multiples));
@@ -14212,15 +14281,23 @@ function multiScalarMul(scalars, points, Curve, tableConfigs = [], mode = "asser
14212
14281
  }
14213
14282
  let scalarChunks = scalars.map((s, i) => sliceField3(s, { maxBits, chunkSize: windowSizes[i] }));
14214
14283
  const HashedPoint = Hashed.create(Point.provable);
14215
- let hashedTables = tables.map((table) => table.map((point) => HashedPoint.hash(point)));
14216
14284
  ia ??= initialAggregator(Curve);
14217
14285
  let sum2 = Point.from(ia);
14286
+ let hashedTables = [];
14287
+ if (hashed) {
14288
+ hashedTables = tables.map((table) => table.map((point) => HashedPoint.hash(point)));
14289
+ }
14218
14290
  for (let i = maxBits - 1; i >= 0; i--) {
14219
14291
  for (let j = 0; j < n; j++) {
14220
14292
  let windowSize = windowSizes[j];
14221
14293
  if (i % windowSize === 0) {
14222
14294
  let sj = scalarChunks[j][i / windowSize];
14223
- let sjP = windowSize === 1 ? points[j] : arrayGetGeneric(HashedPoint.provable, hashedTables[j], sj).unhash();
14295
+ let sjP;
14296
+ if (hashed) {
14297
+ sjP = windowSize === 1 ? points[j] : arrayGetGeneric(HashedPoint.provable, hashedTables[j], sj).unhash();
14298
+ } else {
14299
+ sjP = windowSize === 1 ? points[j] : arrayGetGeneric(Point.provable, tables[j], sj);
14300
+ }
14224
14301
  let added = add2(sum2, sjP, Curve);
14225
14302
  sum2 = Provable.if(sj.equals(0), Point.provable, sum2, added);
14226
14303
  }
@@ -14389,6 +14466,7 @@ var EcdsaSignature = {
14389
14466
  var Ecdsa = {
14390
14467
  sign: signEcdsa,
14391
14468
  verify: verifyEcdsa,
14469
+ verifyV2: verifyEcdsaV2,
14392
14470
  Signature: EcdsaSignature
14393
14471
  };
14394
14472
  function reduceMrcStack(xs) {
@@ -14967,6 +15045,14 @@ var EcdsaSignature2 = class {
14967
15045
  toBigInt() {
14968
15046
  return { r: this.r.toBigInt(), s: this.s.toBigInt() };
14969
15047
  }
15048
+ /**
15049
+ * @deprecated There is a security vulnerability in this method. Use {@link verifyV2} instead.
15050
+ */
15051
+ verify(message, publicKey) {
15052
+ let msgHashBytes = Keccak.ethereum(message);
15053
+ let msgHash = keccakOutputToScalar(msgHashBytes, this.Constructor.Curve);
15054
+ return this.verifySignedHash(msgHash, publicKey);
15055
+ }
14970
15056
  /**
14971
15057
  * Verify the ECDSA signature given the message (an array of bytes) and public key (a {@link Curve} point).
14972
15058
  *
@@ -15001,10 +15087,18 @@ var EcdsaSignature2 = class {
15001
15087
  * isValid.assertTrue('signature verifies');
15002
15088
  * ```
15003
15089
  */
15004
- verify(message, publicKey) {
15090
+ verifyV2(message, publicKey) {
15005
15091
  let msgHashBytes = Keccak.ethereum(message);
15006
15092
  let msgHash = keccakOutputToScalar(msgHashBytes, this.Constructor.Curve);
15007
- return this.verifySignedHash(msgHash, publicKey);
15093
+ return this.verifySignedHashV2(msgHash, publicKey);
15094
+ }
15095
+ /**
15096
+ * @deprecated There is a security vulnerability in this method. Use {@link verifySignedHashV2} instead.
15097
+ */
15098
+ verifySignedHash(msgHash, publicKey) {
15099
+ let msgHash_ = this.Constructor.Curve.Scalar.from(msgHash);
15100
+ let publicKey_ = this.Constructor.Curve.from(publicKey);
15101
+ return Ecdsa.verify(this.Constructor.Curve.Bigint, toObject(this), msgHash_.value, toPoint(publicKey_));
15008
15102
  }
15009
15103
  /**
15010
15104
  * Verify the ECDSA signature given the message hash (a {@link Scalar}) and public key (a {@link Curve} point).
@@ -15013,10 +15107,10 @@ var EcdsaSignature2 = class {
15013
15107
  * In contrast, this method just takes the message hash (a curve scalar) as input, giving you flexibility in
15014
15108
  * choosing the hashing algorithm.
15015
15109
  */
15016
- verifySignedHash(msgHash, publicKey) {
15110
+ verifySignedHashV2(msgHash, publicKey) {
15017
15111
  let msgHash_ = this.Constructor.Curve.Scalar.from(msgHash);
15018
15112
  let publicKey_ = this.Constructor.Curve.from(publicKey);
15019
- return Ecdsa.verify(this.Constructor.Curve.Bigint, toObject(this), msgHash_.value, toPoint(publicKey_));
15113
+ return Ecdsa.verifyV2(this.Constructor.Curve.Bigint, toObject(this), msgHash_.value, toPoint(publicKey_));
15020
15114
  }
15021
15115
  /**
15022
15116
  * Create an {@link EcdsaSignature} by signing a message with a private key.
@@ -15878,7 +15972,7 @@ function createEvents({ Field: Field5, Poseidon: Poseidon3 }) {
15878
15972
  function emptyHashWithPrefix2(prefix) {
15879
15973
  return salt2(prefix)[0];
15880
15974
  }
15881
- const Events3 = {
15975
+ const Events4 = {
15882
15976
  empty() {
15883
15977
  let hash3 = emptyHashWithPrefix2("MinaZkappEventsEmpty");
15884
15978
  return { hash: hash3, data: [] };
@@ -15889,16 +15983,16 @@ function createEvents({ Field: Field5, Poseidon: Poseidon3 }) {
15889
15983
  return { hash: hash3, data: [event, ...events.data] };
15890
15984
  },
15891
15985
  fromList(events) {
15892
- return [...events].reverse().reduce(Events3.pushEvent, Events3.empty());
15986
+ return [...events].reverse().reduce(Events4.pushEvent, Events4.empty());
15893
15987
  },
15894
15988
  hash(events) {
15895
- return Events3.fromList(events).hash;
15989
+ return Events4.fromList(events).hash;
15896
15990
  }
15897
15991
  };
15898
15992
  const EventsProvable = {
15899
- ...Events3,
15993
+ ...Events4,
15900
15994
  ...dataAsHash({
15901
- empty: Events3.empty,
15995
+ empty: Events4.empty,
15902
15996
  toValue(data) {
15903
15997
  return data.map((row) => row.map((e) => Field5.toBigint(e)));
15904
15998
  },
@@ -15910,13 +16004,13 @@ function createEvents({ Field: Field5, Poseidon: Poseidon3 }) {
15910
16004
  },
15911
16005
  fromJSON(json) {
15912
16006
  let data = json.map((row) => row.map((e) => Field5.fromJSON(e)));
15913
- let hash3 = Events3.hash(data);
16007
+ let hash3 = Events4.hash(data);
15914
16008
  return { data, hash: hash3 };
15915
16009
  },
15916
16010
  Field: Field5
15917
16011
  })
15918
16012
  };
15919
- const Actions3 = {
16013
+ const Actions4 = {
15920
16014
  // same as events but w/ different hash prefixes
15921
16015
  empty() {
15922
16016
  let hash3 = emptyHashWithPrefix2("MinaZkappActionsEmpty");
@@ -15931,7 +16025,7 @@ function createEvents({ Field: Field5, Poseidon: Poseidon3 }) {
15931
16025
  return { hash: hash3, data: [event, ...actions.data] };
15932
16026
  },
15933
16027
  fromList(events) {
15934
- return [...events].reverse().reduce(Actions3.pushEvent, Actions3.empty());
16028
+ return [...events].reverse().reduce(Actions4.pushEvent, Actions4.empty());
15935
16029
  },
15936
16030
  hash(events) {
15937
16031
  return this.fromList(events).hash;
@@ -15948,9 +16042,9 @@ function createEvents({ Field: Field5, Poseidon: Poseidon3 }) {
15948
16042
  }
15949
16043
  };
15950
16044
  const ActionsProvable = {
15951
- ...Actions3,
16045
+ ...Actions4,
15952
16046
  ...dataAsHash({
15953
- empty: Actions3.empty,
16047
+ empty: Actions4.empty,
15954
16048
  toValue(data) {
15955
16049
  return data.map((row) => row.map((e) => Field5.toBigint(e)));
15956
16050
  },
@@ -15962,7 +16056,7 @@ function createEvents({ Field: Field5, Poseidon: Poseidon3 }) {
15962
16056
  },
15963
16057
  fromJSON(json) {
15964
16058
  let data = json.map((row) => row.map((e) => Field5.fromJSON(e)));
15965
- let hash3 = Actions3.hash(data);
16059
+ let hash3 = Actions4.hash(data);
15966
16060
  return { data, hash: hash3 };
15967
16061
  },
15968
16062
  Field: Field5
@@ -18949,157 +19043,815 @@ function Option(type) {
18949
19043
  };
18950
19044
  }
18951
19045
 
18952
- // dist/node/lib/mina/mina.js
18953
- var mina_exports = {};
18954
- __export(mina_exports, {
18955
- LocalBlockchain: () => LocalBlockchain,
18956
- Network: () => Network2,
18957
- TestPublicKey: () => TestPublicKey,
18958
- Transaction: () => Transaction,
18959
- activeInstance: () => activeInstance,
18960
- currentSlot: () => currentSlot,
18961
- currentTransaction: () => currentTransaction,
18962
- faucet: () => faucet,
18963
- fetchActions: () => fetchActions,
18964
- fetchEvents: () => fetchEvents,
18965
- filterGroups: () => filterGroups,
18966
- getAccount: () => getAccount,
18967
- getActions: () => getActions,
18968
- getBalance: () => getBalance,
18969
- getNetworkConstants: () => getNetworkConstants,
18970
- getNetworkId: () => getNetworkId,
18971
- getNetworkState: () => getNetworkState,
18972
- getProofsEnabled: () => getProofsEnabled,
18973
- hasAccount: () => hasAccount,
18974
- sender: () => sender,
18975
- setActiveInstance: () => setActiveInstance,
18976
- transaction: () => transaction,
18977
- waitForFunding: () => waitForFunding
18978
- });
18979
-
18980
- // dist/node/lib/mina/mina-instance.js
18981
- var defaultAccountCreationFee = 1e9;
18982
- var defaultNetworkConstants = {
18983
- genesisTimestamp: UInt642.from(0),
18984
- slotTime: UInt642.from(3 * 60 * 1e3),
18985
- accountCreationFee: UInt642.from(defaultAccountCreationFee)
18986
- };
18987
- var ZkappStateLength = 8;
18988
- var activeInstance = {
18989
- getNetworkConstants: () => defaultNetworkConstants,
18990
- currentSlot: noActiveInstance,
18991
- hasAccount: noActiveInstance,
18992
- getAccount: noActiveInstance,
18993
- getNetworkState: noActiveInstance,
18994
- sendTransaction: noActiveInstance,
18995
- transaction: noActiveInstance,
18996
- fetchEvents: noActiveInstance,
18997
- fetchActions: noActiveInstance,
18998
- getActions: noActiveInstance,
18999
- proofsEnabled: true,
19000
- getNetworkId: () => "testnet"
19001
- };
19002
- function setActiveInstance(m) {
19003
- activeInstance = m;
19004
- }
19005
- function noActiveInstance() {
19006
- throw Error("Must call Mina.setActiveInstance first");
19007
- }
19008
- function currentSlot() {
19009
- return activeInstance.currentSlot();
19010
- }
19011
- function getAccount(publicKey, tokenId) {
19012
- return activeInstance.getAccount(publicKey, tokenId);
19013
- }
19014
- function hasAccount(publicKey, tokenId) {
19015
- return activeInstance.hasAccount(publicKey, tokenId);
19016
- }
19017
- function getNetworkId() {
19018
- return activeInstance.getNetworkId();
19019
- }
19020
- function getNetworkConstants() {
19021
- return activeInstance.getNetworkConstants();
19022
- }
19023
- function getNetworkState() {
19024
- return activeInstance.getNetworkState();
19025
- }
19026
- function getBalance(publicKey, tokenId) {
19027
- return activeInstance.getAccount(publicKey, tokenId).balance;
19028
- }
19029
- async function fetchEvents(publicKey, tokenId, filterOptions = {}) {
19030
- return await activeInstance.fetchEvents(publicKey, tokenId, filterOptions);
19031
- }
19032
- async function fetchActions(publicKey, actionStates, tokenId) {
19033
- return await activeInstance.fetchActions(publicKey, actionStates, tokenId);
19034
- }
19035
- function getActions(publicKey, actionStates, tokenId) {
19036
- return activeInstance.getActions(publicKey, actionStates, tokenId);
19037
- }
19038
- function getProofsEnabled() {
19039
- return activeInstance.proofsEnabled;
19040
- }
19041
-
19042
- // dist/node/lib/mina/precondition.js
19043
- var NetworkPrecondition = {
19044
- ignoreAll() {
19045
- let stakingEpochData = {
19046
- ledger: { hash: ignore(Field4(0)), totalCurrency: ignore(uint64()) },
19047
- seed: ignore(Field4(0)),
19048
- startCheckpoint: ignore(Field4(0)),
19049
- lockCheckpoint: ignore(Field4(0)),
19050
- epochLength: ignore(uint32())
19051
- };
19052
- let nextEpochData = cloneCircuitValue(stakingEpochData);
19053
- return {
19054
- snarkedLedgerHash: ignore(Field4(0)),
19055
- blockchainLength: ignore(uint32()),
19056
- minWindowDensity: ignore(uint32()),
19057
- totalCurrency: ignore(uint64()),
19058
- globalSlotSinceGenesis: ignore(uint32()),
19059
- stakingEpochData,
19060
- nextEpochData
19061
- };
19046
+ // dist/node/lib/provable/merkle-tree.js
19047
+ var MerkleTree = class _MerkleTree {
19048
+ /**
19049
+ * Creates a new, empty [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree).
19050
+ * @param height The height of Merkle Tree.
19051
+ * @returns A new MerkleTree
19052
+ */
19053
+ constructor(height) {
19054
+ this.height = height;
19055
+ this.nodes = {};
19056
+ this.zeroes = new Array(height);
19057
+ this.zeroes[0] = Field4(0);
19058
+ for (let i = 1; i < height; i += 1) {
19059
+ this.zeroes[i] = Poseidon2.hash([this.zeroes[i - 1], this.zeroes[i - 1]]);
19060
+ }
19062
19061
  }
19063
- };
19064
- function ignore(dummy) {
19065
- return { isSome: Bool4(false), value: dummy };
19066
- }
19067
- var uint32 = () => ({ lower: UInt322.from(0), upper: UInt322.MAXINT() });
19068
- var uint64 = () => ({ lower: UInt642.from(0), upper: UInt642.MAXINT() });
19069
- var AccountPrecondition = {
19070
- ignoreAll() {
19071
- let appState = [];
19072
- for (let i = 0; i < ZkappStateLength; ++i) {
19073
- appState.push(ignore(Field4(0)));
19062
+ /**
19063
+ * Return a new MerkleTree with the same contents as this one.
19064
+ */
19065
+ clone() {
19066
+ let newTree = new _MerkleTree(this.height);
19067
+ for (let [level, nodes] of Object.entries(this.nodes)) {
19068
+ newTree.nodes[level] = { ...nodes };
19074
19069
  }
19075
- return {
19076
- balance: ignore(uint64()),
19077
- nonce: ignore(uint32()),
19078
- receiptChainHash: ignore(Field4(0)),
19079
- delegate: ignore(PublicKey2.empty()),
19080
- state: appState,
19081
- actionState: ignore(Actions.emptyActionState()),
19082
- provedState: ignore(Bool4(false)),
19083
- isNew: ignore(Bool4(false))
19084
- };
19070
+ return newTree;
19085
19071
  }
19086
- };
19087
- var GlobalSlotPrecondition = {
19088
- ignoreAll() {
19089
- return ignore(uint32());
19072
+ /**
19073
+ * Returns a node which lives at a given index and level.
19074
+ * @param level Level of the node.
19075
+ * @param index Index of the node.
19076
+ * @returns The data of the node.
19077
+ */
19078
+ getNode(level, index) {
19079
+ return this.nodes[level]?.[index.toString()] ?? this.zeroes[level];
19090
19080
  }
19091
- };
19092
- var Preconditions = {
19093
- ignoreAll() {
19094
- return {
19095
- account: AccountPrecondition.ignoreAll(),
19096
- network: NetworkPrecondition.ignoreAll(),
19097
- validWhile: GlobalSlotPrecondition.ignoreAll()
19098
- };
19081
+ /**
19082
+ * Returns a leaf at a given index.
19083
+ * @param index Index of the leaf.
19084
+ * @returns The data of the leaf.
19085
+ */
19086
+ getLeaf(key) {
19087
+ return this.getNode(0, key);
19099
19088
  }
19100
- };
19101
- function preconditions(accountUpdate, isSelf) {
19102
- initializePreconditions(accountUpdate, isSelf);
19089
+ /**
19090
+ * Returns the root of the [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree).
19091
+ * @returns The root of the Merkle Tree.
19092
+ */
19093
+ getRoot() {
19094
+ return this.getNode(this.height - 1, 0n);
19095
+ }
19096
+ // TODO: this allows to set a node at an index larger than the size. OK?
19097
+ setNode(level, index, value) {
19098
+ (this.nodes[level] ??= {})[index.toString()] = value;
19099
+ }
19100
+ // TODO: if this is passed an index bigger than the max, it will set a couple of out-of-bounds nodes but not affect the real Merkle root. OK?
19101
+ /**
19102
+ * Sets the value of a leaf node at a given index to a given value.
19103
+ * @param index Position of the leaf node.
19104
+ * @param leaf New value.
19105
+ */
19106
+ setLeaf(index, leaf) {
19107
+ if (index >= this.leafCount) {
19108
+ throw new Error(`index ${index} is out of range for ${this.leafCount} leaves.`);
19109
+ }
19110
+ this.setNode(0, index, leaf);
19111
+ let currIndex = index;
19112
+ for (let level = 1; level < this.height; level++) {
19113
+ currIndex /= 2n;
19114
+ const left = this.getNode(level - 1, currIndex * 2n);
19115
+ const right = this.getNode(level - 1, currIndex * 2n + 1n);
19116
+ this.setNode(level, currIndex, Poseidon2.hash([left, right]));
19117
+ }
19118
+ }
19119
+ /**
19120
+ * Returns the witness (also known as [Merkle Proof or Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof)) for the leaf at the given index.
19121
+ * @param index Position of the leaf node.
19122
+ * @returns The witness that belongs to the leaf.
19123
+ */
19124
+ getWitness(index) {
19125
+ if (index >= this.leafCount) {
19126
+ throw new Error(`index ${index} is out of range for ${this.leafCount} leaves.`);
19127
+ }
19128
+ const witness2 = [];
19129
+ for (let level = 0; level < this.height - 1; level++) {
19130
+ const isLeft = index % 2n === 0n;
19131
+ const sibling = this.getNode(level, isLeft ? index + 1n : index - 1n);
19132
+ witness2.push({ isLeft, sibling });
19133
+ index /= 2n;
19134
+ }
19135
+ return witness2;
19136
+ }
19137
+ // TODO: this will always return true if the merkle tree was constructed normally; seems to be only useful for testing. remove?
19138
+ /**
19139
+ * Checks if the witness that belongs to the leaf at the given index is a valid witness.
19140
+ * @param index Position of the leaf node.
19141
+ * @returns True if the witness for the leaf node is valid.
19142
+ */
19143
+ validate(index) {
19144
+ const path = this.getWitness(index);
19145
+ let hash3 = this.getNode(0, index);
19146
+ for (const node of path) {
19147
+ hash3 = Poseidon2.hash(node.isLeft ? [hash3, node.sibling] : [node.sibling, hash3]);
19148
+ }
19149
+ return hash3.toString() === this.getRoot().toString();
19150
+ }
19151
+ // TODO: should this take an optional offset? should it fail if the array is too long?
19152
+ /**
19153
+ * Fills all leaves of the tree.
19154
+ * @param leaves Values to fill the leaves with.
19155
+ */
19156
+ fill(leaves) {
19157
+ leaves.forEach((value, index) => {
19158
+ this.setLeaf(BigInt(index), value);
19159
+ });
19160
+ }
19161
+ /**
19162
+ * Returns the amount of leaf nodes.
19163
+ * @returns Amount of leaf nodes.
19164
+ */
19165
+ get leafCount() {
19166
+ return 2n ** BigInt(this.height - 1);
19167
+ }
19168
+ };
19169
+ var BaseMerkleWitness = class extends CircuitValue {
19170
+ height() {
19171
+ return this.constructor.height;
19172
+ }
19173
+ /**
19174
+ * Takes a {@link Witness} and turns it into a circuit-compatible Witness.
19175
+ * @param witness Witness.
19176
+ * @returns A circuit-compatible Witness.
19177
+ */
19178
+ constructor(witness2) {
19179
+ super();
19180
+ let height = witness2.length + 1;
19181
+ if (height !== this.height()) {
19182
+ throw Error(`Length of witness ${height}-1 doesn't match static tree height ${this.height()}.`);
19183
+ }
19184
+ this.path = witness2.map((item) => item.sibling);
19185
+ this.isLeft = witness2.map((item) => Bool4(item.isLeft));
19186
+ }
19187
+ /**
19188
+ * Calculates a root depending on the leaf value.
19189
+ * @param leaf Value of the leaf node that belongs to this Witness.
19190
+ * @returns The calculated root.
19191
+ */
19192
+ calculateRoot(leaf) {
19193
+ let hash3 = leaf;
19194
+ let n = this.height();
19195
+ for (let i = 1; i < n; ++i) {
19196
+ let isLeft = this.isLeft[i - 1];
19197
+ const [left, right] = conditionalSwap(isLeft, hash3, this.path[i - 1]);
19198
+ hash3 = Poseidon2.hash([left, right]);
19199
+ }
19200
+ return hash3;
19201
+ }
19202
+ /**
19203
+ * Calculates the index of the leaf node that belongs to this Witness.
19204
+ * @returns Index of the leaf.
19205
+ */
19206
+ calculateIndex() {
19207
+ let powerOfTwo = Field4(1);
19208
+ let index = Field4(0);
19209
+ let n = this.height();
19210
+ for (let i = 1; i < n; ++i) {
19211
+ index = Provable.if(this.isLeft[i - 1], index, index.add(powerOfTwo));
19212
+ powerOfTwo = powerOfTwo.mul(2);
19213
+ }
19214
+ return index;
19215
+ }
19216
+ };
19217
+ function MerkleWitness(height) {
19218
+ class MerkleWitness_ extends BaseMerkleWitness {
19219
+ }
19220
+ MerkleWitness_.height = height;
19221
+ arrayProp(Field4, height - 1)(MerkleWitness_.prototype, "path");
19222
+ arrayProp(Bool4, height - 1)(MerkleWitness_.prototype, "isLeft");
19223
+ return MerkleWitness_;
19224
+ }
19225
+ function conditionalSwap(b2, x, y) {
19226
+ let m = b2.toField().mul(x.sub(y));
19227
+ const x_ = y.add(m);
19228
+ const y_ = x.sub(m);
19229
+ return [x_, y_];
19230
+ }
19231
+
19232
+ // dist/node/lib/provable/merkle-tree-indexed.js
19233
+ function IndexedMerkleMap(height) {
19234
+ var _a;
19235
+ assert3(height > 0, "height must be positive");
19236
+ assert3(height < 53, "height must be less than 53, so that we can use 64-bit floats to represent indices.");
19237
+ return _a = class IndexedMerkleMap extends IndexedMerkleMapBase {
19238
+ get height() {
19239
+ return height;
19240
+ }
19241
+ }, _a.provable = provableFromClass(_a, provableBase), _a;
19242
+ }
19243
+ var provableBase = {
19244
+ root: Field4,
19245
+ length: Field4,
19246
+ data: Unconstrained.provableWithEmpty({
19247
+ nodes: [],
19248
+ sortedLeaves: []
19249
+ })
19250
+ };
19251
+ var IndexedMerkleMapBase = class _IndexedMerkleMapBase {
19252
+ // static data defining constraints
19253
+ get height() {
19254
+ throw Error("Height must be defined in a subclass");
19255
+ }
19256
+ /**
19257
+ * Creates a new, empty Indexed Merkle Map.
19258
+ */
19259
+ constructor() {
19260
+ let height = this.height;
19261
+ let nodes = Array(height);
19262
+ for (let level = 0; level < height; level++) {
19263
+ nodes[level] = [];
19264
+ }
19265
+ let firstLeaf = _IndexedMerkleMapBase._firstLeaf;
19266
+ let firstNode = Leaf.hashNode(firstLeaf).toBigInt();
19267
+ let root = Nodes.setLeaf(nodes, 0, firstNode);
19268
+ this.root = Field4(root);
19269
+ this.length = Field4(1);
19270
+ this.data = Unconstrained.from({ nodes, sortedLeaves: [firstLeaf] });
19271
+ }
19272
+ /**
19273
+ * Clone the entire Merkle map.
19274
+ *
19275
+ * This method is provable.
19276
+ */
19277
+ clone() {
19278
+ let cloned = new this.constructor();
19279
+ cloned.root = this.root;
19280
+ cloned.length = this.length;
19281
+ cloned.data.updateAsProver(() => {
19282
+ let { nodes, sortedLeaves } = this.data.get();
19283
+ return {
19284
+ nodes: nodes.map((row) => [...row]),
19285
+ sortedLeaves: [...sortedLeaves]
19286
+ };
19287
+ });
19288
+ return cloned;
19289
+ }
19290
+ /**
19291
+ * Overwrite the entire Merkle map with another one.
19292
+ *
19293
+ * This method is provable.
19294
+ */
19295
+ overwrite(other) {
19296
+ this.overwriteIf(true, other);
19297
+ }
19298
+ /**
19299
+ * Overwrite the entire Merkle map with another one, if the condition is true.
19300
+ *
19301
+ * This method is provable.
19302
+ */
19303
+ overwriteIf(condition, other) {
19304
+ condition = Bool4(condition);
19305
+ this.root = Provable.if(condition, other.root, this.root);
19306
+ this.length = Provable.if(condition, other.length, this.length);
19307
+ this.data.updateAsProver(() => Bool4(condition).toBoolean() ? other.clone().data.get() : this.data.get());
19308
+ }
19309
+ /**
19310
+ * Insert a new leaf `(key, value)`.
19311
+ *
19312
+ * Proves that `key` doesn't exist yet.
19313
+ */
19314
+ insert(key, value) {
19315
+ key = Field4(key);
19316
+ value = Field4(value);
19317
+ let index = this.length;
19318
+ let indexBits = index.toBits(this.height - 1);
19319
+ let low = Provable.witness(Leaf, () => this._findLeaf(key).low);
19320
+ let lowPath = this._proveInclusion(low, "Invalid low node (root)");
19321
+ assertStrictlyBetween(low.key, key, low.nextKey, "Key already exists in the tree");
19322
+ let newLow = { ...low, nextKey: key };
19323
+ this.root = this._proveUpdate(newLow, lowPath);
19324
+ this._setLeafUnconstrained(true, newLow);
19325
+ let leaf = Leaf.nextAfter(newLow, index, {
19326
+ key,
19327
+ value,
19328
+ nextKey: low.nextKey
19329
+ });
19330
+ let path = this._proveEmpty(indexBits);
19331
+ this.root = this._proveUpdate(leaf, path);
19332
+ this.length = this.length.add(1);
19333
+ this._setLeafUnconstrained(false, leaf);
19334
+ }
19335
+ /**
19336
+ * Update an existing leaf `(key, value)`.
19337
+ *
19338
+ * Proves that the `key` exists.
19339
+ *
19340
+ * Returns the previous value.
19341
+ */
19342
+ update(key, value) {
19343
+ key = Field4(key);
19344
+ value = Field4(value);
19345
+ let self = Provable.witness(Leaf, () => this._findLeaf(key).self);
19346
+ let path = this._proveInclusion(self, "Key does not exist in the tree");
19347
+ self.key.assertEquals(key, "Invalid leaf (key)");
19348
+ let newSelf = { ...self, value };
19349
+ this.root = this._proveUpdate(newSelf, path);
19350
+ this._setLeafUnconstrained(true, newSelf);
19351
+ return self.value;
19352
+ }
19353
+ /**
19354
+ * Perform _either_ an insertion or update, depending on whether the key exists.
19355
+ *
19356
+ * Note: This method is handling both the `insert()` and `update()` case at the same time, so you
19357
+ * can use it if you don't know whether the key exists or not.
19358
+ *
19359
+ * However, this comes at an efficiency cost, so prefer to use `insert()` or `update()` if you know whether the key exists.
19360
+ *
19361
+ * Returns the previous value, as an option (which is `None` if the key didn't exist before).
19362
+ */
19363
+ set(key, value) {
19364
+ key = Field4(key);
19365
+ value = Field4(value);
19366
+ let { low, self } = Provable.witness(LeafPair, () => this._findLeaf(key));
19367
+ let lowPath = this._proveInclusion(low, "Invalid low node (root)");
19368
+ assertBetween(low.key, key, low.nextKey, "Invalid low node (key)");
19369
+ let keyExists = low.nextKey.equals(key);
19370
+ let index = Provable.witness(Field4, () => self.index.get());
19371
+ index = Provable.if(keyExists, index, this.length);
19372
+ let indexBits = index.toBits(this.height - 1);
19373
+ let newLow = { ...low, nextKey: key };
19374
+ this.root = this._proveUpdate(newLow, lowPath);
19375
+ this._setLeafUnconstrained(true, newLow);
19376
+ let path = this._proveInclusionOrEmpty(keyExists, indexBits, self, "Invalid leaf (root)");
19377
+ assert3(keyExists.implies(self.key.equals(key)), "Invalid leaf (key)");
19378
+ let newLeaf = Leaf.nextAfter(newLow, index, {
19379
+ key,
19380
+ value,
19381
+ nextKey: Provable.if(keyExists, self.nextKey, low.nextKey)
19382
+ });
19383
+ this.root = this._proveUpdate(newLeaf, path);
19384
+ this.length = Provable.if(keyExists, this.length, this.length.add(1));
19385
+ this._setLeafUnconstrained(keyExists, newLeaf);
19386
+ return new OptionField({ isSome: keyExists, value: self.value });
19387
+ }
19388
+ /**
19389
+ * Get a value from a key.
19390
+ *
19391
+ * Proves that the key already exists in the map yet and fails otherwise.
19392
+ */
19393
+ get(key) {
19394
+ key = Field4(key);
19395
+ let self = Provable.witness(Leaf, () => this._findLeaf(key).self);
19396
+ this._proveInclusion(self, "Key does not exist in the tree");
19397
+ self.key.assertEquals(key, "Invalid leaf (key)");
19398
+ return self.value;
19399
+ }
19400
+ /**
19401
+ * Get a value from a key.
19402
+ *
19403
+ * Returns an option which is `None` if the key doesn't exist. (In that case, the option's value is unconstrained.)
19404
+ *
19405
+ * Note that this is more flexible than `get()` and allows you to handle the case where the key doesn't exist.
19406
+ * However, it uses about twice as many constraints for that reason.
19407
+ */
19408
+ getOption(key) {
19409
+ key = Field4(key);
19410
+ let { low, self } = Provable.witness(LeafPair, () => this._findLeaf(key));
19411
+ this._proveInclusion(low, "Invalid low node (root)");
19412
+ assertBetween(low.key, key, low.nextKey, "Invalid low node (key)");
19413
+ let keyExists = low.nextKey.equals(key);
19414
+ this._proveInclusionIf(keyExists, self, "Invalid leaf (root)");
19415
+ assert3(keyExists.implies(self.key.equals(key)), "Invalid leaf (key)");
19416
+ return new OptionField({ isSome: keyExists, value: self.value });
19417
+ }
19418
+ // methods to check for inclusion for a key without being concerned about the value
19419
+ /**
19420
+ * Prove that the given key exists in the map.
19421
+ */
19422
+ assertIncluded(key, message) {
19423
+ key = Field4(key);
19424
+ let self = Provable.witness(Leaf, () => this._findLeaf(key).self);
19425
+ this._proveInclusion(self, message ?? "Key does not exist in the tree");
19426
+ self.key.assertEquals(key, "Invalid leaf (key)");
19427
+ }
19428
+ /**
19429
+ * Prove that the given key does not exist in the map.
19430
+ */
19431
+ assertNotIncluded(key, message) {
19432
+ key = Field4(key);
19433
+ let low = Provable.witness(Leaf, () => this._findLeaf(key).low);
19434
+ this._proveInclusion(low, "Invalid low node (root)");
19435
+ assertStrictlyBetween(low.key, key, low.nextKey, message ?? "Key already exists in the tree");
19436
+ }
19437
+ /**
19438
+ * Check whether the given key exists in the map.
19439
+ */
19440
+ isIncluded(key) {
19441
+ key = Field4(key);
19442
+ let low = Provable.witness(Leaf, () => this._findLeaf(key).low);
19443
+ this._proveInclusion(low, "Invalid low node (root)");
19444
+ assertBetween(low.key, key, low.nextKey, "Invalid low node (key)");
19445
+ return low.nextKey.equals(key);
19446
+ }
19447
+ // helper methods
19448
+ /**
19449
+ * Helper method to prove inclusion of a leaf in the tree.
19450
+ */
19451
+ _proveInclusion(leaf, message) {
19452
+ let node = Leaf.hashNode(leaf);
19453
+ let { root, path } = this._computeRoot(node, leaf.index);
19454
+ root.assertEquals(this.root, message ?? "Leaf is not included in the tree");
19455
+ return path;
19456
+ }
19457
+ /**
19458
+ * Helper method to conditionally prove inclusion of a leaf in the tree.
19459
+ */
19460
+ _proveInclusionIf(condition, leaf, message) {
19461
+ let node = Leaf.hashNode(leaf);
19462
+ let { root } = this._computeRoot(node, leaf.index);
19463
+ assert3(condition.implies(root.equals(this.root)), message ?? "Leaf is not included in the tree");
19464
+ }
19465
+ /**
19466
+ * Helper method to prove inclusion of an empty leaf in the tree.
19467
+ *
19468
+ * This validates the path against the current root, so that we can use it to insert a new leaf.
19469
+ */
19470
+ _proveEmpty(index) {
19471
+ let node = Field4(0n);
19472
+ let { root, path } = this._computeRoot(node, index);
19473
+ root.assertEquals(this.root, "Leaf is not empty");
19474
+ return path;
19475
+ }
19476
+ /**
19477
+ * Helper method to conditionally prove inclusion of a leaf in the tree.
19478
+ *
19479
+ * If the condition is false, we prove that the tree contains an empty leaf instead.
19480
+ */
19481
+ _proveInclusionOrEmpty(condition, index, leaf, message) {
19482
+ let node = Provable.if(condition, Leaf.hashNode(leaf), Field4(0n));
19483
+ let { root, path } = this._computeRoot(node, index);
19484
+ root.assertEquals(this.root, message ?? "Leaf is not included in the tree");
19485
+ return path;
19486
+ }
19487
+ /**
19488
+ * Helper method to update the root against a previously validated path.
19489
+ *
19490
+ * Returns the new root.
19491
+ */
19492
+ _proveUpdate(leaf, path) {
19493
+ let node = Leaf.hashNode(leaf);
19494
+ let { root } = this._computeRoot(node, path.index, path.witness);
19495
+ return root;
19496
+ }
19497
+ /**
19498
+ * Helper method to compute the root given a leaf node and its index.
19499
+ *
19500
+ * The index can be given as a `Field` or as an array of bits.
19501
+ */
19502
+ _computeRoot(node, index, witness2) {
19503
+ let indexBits = index instanceof Unconstrained ? Provable.witness(Provable.Array(Bool4, this.height - 1), () => Field4(index.get()).toBits(this.height - 1)) : index;
19504
+ let witness_ = witness2 ?? Provable.witnessFields(this.height - 1, () => {
19505
+ let witness3 = [];
19506
+ let index2 = Number(Field4.fromBits(indexBits));
19507
+ let { nodes } = this.data.get();
19508
+ for (let level = 0; level < this.height - 1; level++) {
19509
+ let i = index2 % 2 === 0 ? index2 + 1 : index2 - 1;
19510
+ let sibling = Nodes.getNode(nodes, level, i, false);
19511
+ witness3.push(sibling);
19512
+ index2 >>= 1;
19513
+ }
19514
+ return witness3;
19515
+ });
19516
+ assert3(indexBits.length === this.height - 1, "Invalid index size");
19517
+ assert3(witness_.length === this.height - 1, "Invalid witness size");
19518
+ for (let level = 0; level < this.height - 1; level++) {
19519
+ let isRight = indexBits[level];
19520
+ let sibling = witness_[level];
19521
+ let [right, left] = conditionalSwap(isRight, node, sibling);
19522
+ node = Poseidon2.hash([left, right]);
19523
+ }
19524
+ return { root: node, path: { witness: witness_, index: indexBits } };
19525
+ }
19526
+ /**
19527
+ * Given a key, returns both the low node and the leaf that contains the key.
19528
+ *
19529
+ * If the key does not exist, a dummy value is returned for the leaf.
19530
+ *
19531
+ * Can only be called outside provable code.
19532
+ */
19533
+ _findLeaf(key_) {
19534
+ let key = typeof key_ === "bigint" ? key_ : key_.toBigInt();
19535
+ assert3(key >= 0n, "key must be positive");
19536
+ let leaves = this.data.get().sortedLeaves;
19537
+ if (key === 0n)
19538
+ return {
19539
+ low: Leaf.fromStored(leaves[leaves.length - 1], leaves.length - 1),
19540
+ self: Leaf.fromStored(leaves[0], 0)
19541
+ };
19542
+ let { lowIndex, foundValue } = bisectUnique(key, (i) => leaves[i].key, leaves.length);
19543
+ let iLow = foundValue ? lowIndex - 1 : lowIndex;
19544
+ let low = Leaf.fromStored(leaves[iLow], iLow);
19545
+ let iSelf = foundValue ? lowIndex : 0;
19546
+ let selfBase = foundValue ? leaves[lowIndex] : Leaf.toStored(Leaf.empty());
19547
+ let self = Leaf.fromStored(selfBase, iSelf);
19548
+ return { low, self };
19549
+ }
19550
+ /**
19551
+ * Update or append a leaf in our internal data structures
19552
+ */
19553
+ _setLeafUnconstrained(leafExists, leaf) {
19554
+ Provable.asProver(() => {
19555
+ let { nodes, sortedLeaves } = this.data.get();
19556
+ let i = leaf.index.get();
19557
+ Nodes.setLeaf(nodes, i, Leaf.hashNode(leaf).toBigInt());
19558
+ let leafValue = Leaf.toStored(leaf);
19559
+ let iSorted = leaf.sortedIndex.get();
19560
+ if (Bool4(leafExists).toBoolean()) {
19561
+ sortedLeaves[iSorted % sortedLeaves.length] = leafValue;
19562
+ } else {
19563
+ sortedLeaves.splice(iSorted, 0, leafValue);
19564
+ }
19565
+ });
19566
+ }
19567
+ };
19568
+ IndexedMerkleMapBase.provable = void 0;
19569
+ IndexedMerkleMapBase._firstLeaf = {
19570
+ key: 0n,
19571
+ value: 0n,
19572
+ // the 0 key encodes the minimum and maximum at the same time
19573
+ // so, if a second node is inserted, it will get `nextKey = 0`, and thus point to the first node
19574
+ nextKey: 0n,
19575
+ index: 0
19576
+ };
19577
+ var Nodes;
19578
+ (function(Nodes2) {
19579
+ function setLeaf(nodes, index, leaf) {
19580
+ nodes[0][index] = leaf;
19581
+ let height = nodes.length;
19582
+ for (let level = 0; level < height - 1; level++) {
19583
+ let isLeft = index % 2 === 0;
19584
+ index = Math.floor(index / 2);
19585
+ let left = getNode(nodes, level, index * 2, isLeft);
19586
+ let right = getNode(nodes, level, index * 2 + 1, !isLeft);
19587
+ nodes[level + 1][index] = Poseidon.hash([left, right]);
19588
+ }
19589
+ return getNode(nodes, height - 1, 0, true);
19590
+ }
19591
+ Nodes2.setLeaf = setLeaf;
19592
+ function getNode(nodes, level, index, nonEmpty) {
19593
+ let node = nodes[level]?.[index];
19594
+ if (node === void 0) {
19595
+ if (nonEmpty)
19596
+ throw Error(`node at level=${level}, index=${index} was expected to be known, but isn't.`);
19597
+ node = empty4(level);
19598
+ }
19599
+ return node;
19600
+ }
19601
+ Nodes2.getNode = getNode;
19602
+ const emptyNodes = [0n];
19603
+ function empty4(level) {
19604
+ for (let i = emptyNodes.length; i <= level; i++) {
19605
+ let zero2 = emptyNodes[i - 1];
19606
+ emptyNodes[i] = Poseidon.hash([zero2, zero2]);
19607
+ }
19608
+ return emptyNodes[level];
19609
+ }
19610
+ Nodes2.empty = empty4;
19611
+ })(Nodes || (Nodes = {}));
19612
+ var BaseLeaf = class extends Struct({
19613
+ key: Field4,
19614
+ value: Field4,
19615
+ nextKey: Field4
19616
+ }) {
19617
+ };
19618
+ var Leaf = class extends Struct({
19619
+ value: Field4,
19620
+ key: Field4,
19621
+ nextKey: Field4,
19622
+ // auxiliary data that tells us where the leaf is stored
19623
+ index: Unconstrained.provableWithEmpty(0),
19624
+ sortedIndex: Unconstrained.provableWithEmpty(0)
19625
+ }) {
19626
+ /**
19627
+ * Compute a leaf node: the hash of a leaf that becomes part of the Merkle tree.
19628
+ */
19629
+ static hashNode(leaf) {
19630
+ return Poseidon2.hashPacked(BaseLeaf, BaseLeaf.fromValue(leaf));
19631
+ }
19632
+ /**
19633
+ * Create a new leaf, given its low node and index.
19634
+ */
19635
+ static nextAfter(low, index, leaf) {
19636
+ return {
19637
+ key: leaf.key,
19638
+ value: leaf.value,
19639
+ nextKey: leaf.nextKey,
19640
+ index: Unconstrained.witness(() => Number(index)),
19641
+ sortedIndex: Unconstrained.witness(() => low.sortedIndex.get() + 1)
19642
+ };
19643
+ }
19644
+ // convert to/from internally stored format
19645
+ static toStored(leaf) {
19646
+ return {
19647
+ key: leaf.key.toBigInt(),
19648
+ value: leaf.value.toBigInt(),
19649
+ nextKey: leaf.nextKey.toBigInt(),
19650
+ index: leaf.index.get()
19651
+ };
19652
+ }
19653
+ static fromStored(leaf, sortedIndex) {
19654
+ return {
19655
+ ...leaf,
19656
+ index: Unconstrained.from(leaf.index),
19657
+ sortedIndex: Unconstrained.from(sortedIndex)
19658
+ };
19659
+ }
19660
+ };
19661
+ var LeafPair = class extends Struct({ low: Leaf, self: Leaf }) {
19662
+ };
19663
+ var OptionField = class extends Option(Field4) {
19664
+ };
19665
+ function bisectUnique(target, getValue, length) {
19666
+ let [iLow, iHigh] = [0, length - 1];
19667
+ if (getValue(iLow) > target)
19668
+ return { lowIndex: -1, foundValue: false };
19669
+ if (getValue(iHigh) < target)
19670
+ return { lowIndex: iHigh, foundValue: false };
19671
+ while (iHigh !== iLow) {
19672
+ let iMid = Math.ceil((iLow + iHigh) / 2);
19673
+ if (getValue(iMid) <= target) {
19674
+ iLow = iMid;
19675
+ } else {
19676
+ iHigh = iMid - 1;
19677
+ }
19678
+ }
19679
+ return { lowIndex: iLow, foundValue: getValue(iLow) === target };
19680
+ }
19681
+ function assertStrictlyBetween(low, x, high, message) {
19682
+ x.assertNotEquals(0n, message ?? "0 is not in any strict range");
19683
+ low.assertLessThan(x, message);
19684
+ let highIsZero = high.equals(0n);
19685
+ let xSafe = Provable.witness(Field4, () => highIsZero.toBoolean() ? 0n : x);
19686
+ let highSafe = Provable.witness(Field4, () => highIsZero.toBoolean() ? 1n : high);
19687
+ xSafe.assertLessThan(highSafe, message);
19688
+ assert3(xSafe.equals(x).or(highIsZero), message);
19689
+ assert3(highSafe.equals(high).or(highIsZero), message);
19690
+ }
19691
+ function assertBetween(low, x, high, message) {
19692
+ let xIsZero = x.equals(0n);
19693
+ let lowSafe = Provable.witness(Field4, () => xIsZero.toBoolean() ? 0n : low);
19694
+ let xSafe1 = Provable.witness(Field4, () => xIsZero.toBoolean() ? 1n : x);
19695
+ lowSafe.assertLessThan(xSafe1, message);
19696
+ assert3(lowSafe.equals(low).or(xIsZero), message);
19697
+ assert3(xSafe1.equals(x).or(xIsZero), message);
19698
+ let highIsZero = high.equals(0n);
19699
+ let xSafe0 = Provable.witness(Field4, () => highIsZero.toBoolean() ? 0n : x);
19700
+ xSafe0.assertLessThanOrEqual(high, message);
19701
+ assert3(xSafe0.equals(x).or(highIsZero), message);
19702
+ }
19703
+
19704
+ // dist/node/lib/mina/mina.js
19705
+ var mina_exports = {};
19706
+ __export(mina_exports, {
19707
+ LocalBlockchain: () => LocalBlockchain,
19708
+ Network: () => Network2,
19709
+ TestPublicKey: () => TestPublicKey,
19710
+ Transaction: () => Transaction,
19711
+ activeInstance: () => activeInstance,
19712
+ currentSlot: () => currentSlot,
19713
+ currentTransaction: () => currentTransaction,
19714
+ faucet: () => faucet,
19715
+ fetchActions: () => fetchActions,
19716
+ fetchEvents: () => fetchEvents,
19717
+ filterGroups: () => filterGroups,
19718
+ getAccount: () => getAccount,
19719
+ getActions: () => getActions,
19720
+ getBalance: () => getBalance,
19721
+ getNetworkConstants: () => getNetworkConstants,
19722
+ getNetworkId: () => getNetworkId,
19723
+ getNetworkState: () => getNetworkState,
19724
+ getProofsEnabled: () => getProofsEnabled,
19725
+ hasAccount: () => hasAccount,
19726
+ sender: () => sender,
19727
+ setActiveInstance: () => setActiveInstance,
19728
+ transaction: () => transaction,
19729
+ waitForFunding: () => waitForFunding
19730
+ });
19731
+
19732
+ // dist/node/lib/mina/mina-instance.js
19733
+ var defaultAccountCreationFee = 1e9;
19734
+ var defaultNetworkConstants = {
19735
+ genesisTimestamp: UInt642.from(0),
19736
+ slotTime: UInt642.from(3 * 60 * 1e3),
19737
+ accountCreationFee: UInt642.from(defaultAccountCreationFee)
19738
+ };
19739
+ var ZkappStateLength = 8;
19740
+ var activeInstance = {
19741
+ getNetworkConstants: () => defaultNetworkConstants,
19742
+ currentSlot: noActiveInstance,
19743
+ hasAccount: noActiveInstance,
19744
+ getAccount: noActiveInstance,
19745
+ getNetworkState: noActiveInstance,
19746
+ sendTransaction: noActiveInstance,
19747
+ transaction: noActiveInstance,
19748
+ fetchEvents: noActiveInstance,
19749
+ fetchActions: noActiveInstance,
19750
+ getActions: noActiveInstance,
19751
+ proofsEnabled: true,
19752
+ getNetworkId: () => "testnet"
19753
+ };
19754
+ function setActiveInstance(m) {
19755
+ activeInstance = m;
19756
+ }
19757
+ function noActiveInstance() {
19758
+ throw Error("Must call Mina.setActiveInstance first");
19759
+ }
19760
+ function currentSlot() {
19761
+ return activeInstance.currentSlot();
19762
+ }
19763
+ function getAccount(publicKey, tokenId) {
19764
+ return activeInstance.getAccount(publicKey, tokenId);
19765
+ }
19766
+ function hasAccount(publicKey, tokenId) {
19767
+ return activeInstance.hasAccount(publicKey, tokenId);
19768
+ }
19769
+ function getNetworkId() {
19770
+ return activeInstance.getNetworkId();
19771
+ }
19772
+ function getNetworkConstants() {
19773
+ return activeInstance.getNetworkConstants();
19774
+ }
19775
+ function getNetworkState() {
19776
+ return activeInstance.getNetworkState();
19777
+ }
19778
+ function getBalance(publicKey, tokenId) {
19779
+ return activeInstance.getAccount(publicKey, tokenId).balance;
19780
+ }
19781
+ async function fetchEvents(publicKey, tokenId, filterOptions = {}) {
19782
+ return await activeInstance.fetchEvents(publicKey, tokenId, filterOptions);
19783
+ }
19784
+ async function fetchActions(publicKey, actionStates, tokenId) {
19785
+ return await activeInstance.fetchActions(publicKey, actionStates, tokenId);
19786
+ }
19787
+ function getActions(publicKey, actionStates, tokenId) {
19788
+ return activeInstance.getActions(publicKey, actionStates, tokenId);
19789
+ }
19790
+ function getProofsEnabled() {
19791
+ return activeInstance.proofsEnabled;
19792
+ }
19793
+
19794
+ // dist/node/lib/mina/precondition.js
19795
+ var NetworkPrecondition = {
19796
+ ignoreAll() {
19797
+ let stakingEpochData = {
19798
+ ledger: { hash: ignore(Field4(0)), totalCurrency: ignore(uint64()) },
19799
+ seed: ignore(Field4(0)),
19800
+ startCheckpoint: ignore(Field4(0)),
19801
+ lockCheckpoint: ignore(Field4(0)),
19802
+ epochLength: ignore(uint32())
19803
+ };
19804
+ let nextEpochData = cloneCircuitValue(stakingEpochData);
19805
+ return {
19806
+ snarkedLedgerHash: ignore(Field4(0)),
19807
+ blockchainLength: ignore(uint32()),
19808
+ minWindowDensity: ignore(uint32()),
19809
+ totalCurrency: ignore(uint64()),
19810
+ globalSlotSinceGenesis: ignore(uint32()),
19811
+ stakingEpochData,
19812
+ nextEpochData
19813
+ };
19814
+ }
19815
+ };
19816
+ function ignore(dummy) {
19817
+ return { isSome: Bool4(false), value: dummy };
19818
+ }
19819
+ var uint32 = () => ({ lower: UInt322.from(0), upper: UInt322.MAXINT() });
19820
+ var uint64 = () => ({ lower: UInt642.from(0), upper: UInt642.MAXINT() });
19821
+ var AccountPrecondition = {
19822
+ ignoreAll() {
19823
+ let appState = [];
19824
+ for (let i = 0; i < ZkappStateLength; ++i) {
19825
+ appState.push(ignore(Field4(0)));
19826
+ }
19827
+ return {
19828
+ balance: ignore(uint64()),
19829
+ nonce: ignore(uint32()),
19830
+ receiptChainHash: ignore(Field4(0)),
19831
+ delegate: ignore(PublicKey2.empty()),
19832
+ state: appState,
19833
+ actionState: ignore(Actions.emptyActionState()),
19834
+ provedState: ignore(Bool4(false)),
19835
+ isNew: ignore(Bool4(false))
19836
+ };
19837
+ }
19838
+ };
19839
+ var GlobalSlotPrecondition = {
19840
+ ignoreAll() {
19841
+ return ignore(uint32());
19842
+ }
19843
+ };
19844
+ var Preconditions = {
19845
+ ignoreAll() {
19846
+ return {
19847
+ account: AccountPrecondition.ignoreAll(),
19848
+ network: NetworkPrecondition.ignoreAll(),
19849
+ validWhile: GlobalSlotPrecondition.ignoreAll()
19850
+ };
19851
+ }
19852
+ };
19853
+ function preconditions(accountUpdate, isSelf) {
19854
+ initializePreconditions(accountUpdate, isSelf);
19103
19855
  return {
19104
19856
  account: Account3(accountUpdate),
19105
19857
  network: Network(accountUpdate),
@@ -19599,6 +20351,26 @@ var TransactionVersion3 = {
19599
20351
  current: () => UInt322.from(protocolVersions.txnVersion)
19600
20352
  };
19601
20353
  var zkAppProver = Prover();
20354
+ var Events3 = {
20355
+ ...Events,
20356
+ pushEvent(events, event) {
20357
+ events = Events.pushEvent(events, event);
20358
+ Provable.asProver(() => {
20359
+ events.data[0] = events.data[0].map((e) => Field4(Field4.toBigint(e)));
20360
+ });
20361
+ return events;
20362
+ }
20363
+ };
20364
+ var Actions3 = {
20365
+ ...Actions,
20366
+ pushEvent(actions, action) {
20367
+ actions = Actions.pushEvent(actions, action);
20368
+ Provable.asProver(() => {
20369
+ actions.data[0] = actions.data[0].map((e) => Field4(Field4.toBigint(e)));
20370
+ });
20371
+ return actions;
20372
+ }
20373
+ };
19602
20374
  var True = () => Bool4(true);
19603
20375
  var False = () => Bool4(false);
19604
20376
  var VerificationKeyPermission = class _VerificationKeyPermission {
@@ -20337,8 +21109,8 @@ var AccountUpdate3 = class _AccountUpdate {
20337
21109
  return pretty;
20338
21110
  }
20339
21111
  };
20340
- AccountUpdate3.Actions = Actions;
20341
- AccountUpdate3.Events = Events;
21112
+ AccountUpdate3.Actions = Actions3;
21113
+ AccountUpdate3.Events = Events3;
20342
21114
  AccountUpdate3.signingInfo = provable({
20343
21115
  isSameAsFeePayer: Bool4,
20344
21116
  nonce: UInt322
@@ -20878,7 +21650,7 @@ function newAccount(accountId2) {
20878
21650
  account.permissions = Permissions.initial();
20879
21651
  return account;
20880
21652
  }
20881
- function parseFetchedAccount({ account }) {
21653
+ function parseFetchedAccount(account) {
20882
21654
  const { publicKey, nonce, zkappState, balance, permissions, timing: { cliffAmount, cliffTime, initialMinimumBalance, vestingIncrement, vestingPeriod }, delegateAccount, receiptChainHash, actionState, token, tokenSymbol, verificationKey, provedState, zkappUri } = account;
20883
21655
  let hasZkapp = zkappState !== null || verificationKey !== null || actionState !== null || zkappUri !== null || provedState;
20884
21656
  let partialAccount = {
@@ -21214,7 +21986,7 @@ async function fetchAccountInternal(accountInfo, graphqlEndpoint = networkConfig
21214
21986
  let [response, error] = await makeGraphqlRequest(accountQuery(publicKey, tokenId ?? TokenId4.toBase58(TokenId4.default)), graphqlEndpoint, networkConfig.minaFallbackEndpoints, config);
21215
21987
  if (error !== void 0)
21216
21988
  return { account: void 0, error };
21217
- let fetchedAccount = response?.data;
21989
+ let fetchedAccount = response?.data?.account;
21218
21990
  if (!fetchedAccount) {
21219
21991
  return {
21220
21992
  account: void 0,
@@ -21239,8 +22011,11 @@ var accountsToFetch = {};
21239
22011
  var networksToFetch = {};
21240
22012
  var actionsToFetch = {};
21241
22013
  var genesisConstantsCache = {};
22014
+ var emptyKey = PublicKey2.empty().toBase58();
21242
22015
  function markAccountToBeFetched(publicKey, tokenId, graphqlEndpoint) {
21243
22016
  let publicKeyBase58 = publicKey.toBase58();
22017
+ if (publicKeyBase58 === emptyKey)
22018
+ return;
21244
22019
  let tokenBase58 = TokenId4.toBase58(tokenId);
21245
22020
  accountsToFetch[`${publicKeyBase58};${tokenBase58};${graphqlEndpoint}`] = {
21246
22021
  publicKey: publicKeyBase58,
@@ -21587,8 +22362,8 @@ var Lightnet;
21587
22362
  Lightnet2.listAcquiredKeyPairs = listAcquiredKeyPairs;
21588
22363
  })(Lightnet || (Lightnet = {}));
21589
22364
  function updateActionState(actions, actionState) {
21590
- let actionHash = Actions.fromJSON(actions).hash;
21591
- return Actions.updateSequenceState(actionState, actionHash);
22365
+ let actionHash = Actions3.fromJSON(actions).hash;
22366
+ return Actions3.updateSequenceState(actionState, actionHash);
21592
22367
  }
21593
22368
  async function makeGraphqlRequest(query, graphqlEndpoint = networkConfig.minaEndpoint, fallbackEndpoints, { timeout = defaultTimeout } = {}) {
21594
22369
  if (graphqlEndpoint === "none")
@@ -22430,10 +23205,10 @@ async function LocalBlockchain({ proofsEnabled = true, enforceTransactionLimits
22430
23205
  }
22431
23206
  let storedActions = actions[addr]?.[tokenId];
22432
23207
  let latestActionState_ = storedActions?.[storedActions.length - 1]?.hash;
22433
- let latestActionState = latestActionState_ !== void 0 ? Field4(latestActionState_) : Actions.emptyActionState();
23208
+ let latestActionState = latestActionState_ !== void 0 ? Field4(latestActionState_) : Actions3.emptyActionState();
22434
23209
  actions[addr] ??= {};
22435
23210
  if (p3.body.actions.data.length > 0) {
22436
- let newActionState = Actions.updateSequenceState(latestActionState, p3.body.actions.hash);
23211
+ let newActionState = Actions3.updateSequenceState(latestActionState, p3.body.actions.hash);
22437
23212
  actions[addr][tokenId] ??= [];
22438
23213
  actions[addr][tokenId].push({
22439
23214
  actions: pJson.body.actions,
@@ -22499,7 +23274,7 @@ ${pendingTransaction2.errors.join("\n")}`);
22499
23274
  getActions(publicKey, actionStates, tokenId = TokenId4.default) {
22500
23275
  let currentActions = actions?.[publicKey.toBase58()]?.[TokenId4.toBase58(tokenId)] ?? [];
22501
23276
  let { fromActionState, endActionState } = actionStates ?? {};
22502
- let emptyState = Actions.emptyActionState();
23277
+ let emptyState = Actions3.emptyActionState();
22503
23278
  if (endActionState?.equals(emptyState).toBoolean())
22504
23279
  return [];
22505
23280
  let start = fromActionState?.equals(emptyState).toBoolean() ? void 0 : fromActionState?.toString();
@@ -23197,7 +23972,7 @@ function getStateContexts(sc) {
23197
23972
  // dist/node/lib/mina/actions/reducer.js
23198
23973
  var Reducer = Object.defineProperty(function(reducer) {
23199
23974
  return reducer;
23200
- }, "initialActionState", { get: Actions.emptyActionState });
23975
+ }, "initialActionState", { get: Actions3.emptyActionState });
23201
23976
  function getReducer(contract) {
23202
23977
  let reducer = (contract._ ??= {}).reducer;
23203
23978
  if (reducer === void 0)
@@ -23210,7 +23985,7 @@ class ${contract.constructor.name} extends SmartContract {
23210
23985
  dispatch(action) {
23211
23986
  let accountUpdate = contract.self;
23212
23987
  let eventFields = reducer.actionType.toFields(action);
23213
- accountUpdate.body.actions = Actions.pushEvent(accountUpdate.body.actions, eventFields);
23988
+ accountUpdate.body.actions = Actions3.pushEvent(accountUpdate.body.actions, eventFields);
23214
23989
  },
23215
23990
  reduce(actionLists, stateType, reduce, state3, { maxUpdatesWithActions = 32, maxActionsPerUpdate = 1, skipActionStatePrecondition = false } = {}) {
23216
23991
  Provable.asProver(() => {
@@ -23255,17 +24030,17 @@ class ${contract.constructor.name} extends SmartContract {
23255
24030
  },
23256
24031
  getActions(config) {
23257
24032
  const Action = reducer.actionType;
23258
- const emptyHash2 = Actions.empty().hash;
23259
- const nextHash = (hash3, action) => Actions.pushEvent({ hash: hash3, data: [] }, Action.toFields(action)).hash;
24033
+ const emptyHash2 = Actions3.empty().hash;
24034
+ const nextHash = (hash3, action) => Actions3.pushEvent({ hash: hash3, data: [] }, Action.toFields(action)).hash;
23260
24035
  class ActionList2 extends MerkleList.create(Action, nextHash, emptyHash2) {
23261
24036
  }
23262
24037
  class MerkleActions extends MerkleList.create(
23263
24038
  ActionList2.provable,
23264
- (hash3, actions2) => Actions.updateSequenceState(hash3, actions2.hash),
24039
+ (hash3, actions2) => Actions3.updateSequenceState(hash3, actions2.hash),
23265
24040
  // if no "start" action hash was specified, this means we are fetching the entire history of actions, which started from the empty action state hash
23266
24041
  // otherwise we are only fetching a part of the history, which starts at `fromActionState`
23267
24042
  // TODO does this show that `emptyHash` should be part of the instance, not the class? that would make the provable representation bigger though
23268
- config?.fromActionState ?? Actions.emptyActionState()
24043
+ config?.fromActionState ?? Actions3.emptyActionState()
23269
24044
  ) {
23270
24045
  }
23271
24046
  let actions = Provable.witness(MerkleActions.provable, () => {
@@ -23860,7 +24635,7 @@ class ${this.constructor.name} extends SmartContract {
23860
24635
  } else {
23861
24636
  eventFields = [Field4(eventNumber), ...eventType.toFields(event)];
23862
24637
  }
23863
- accountUpdate.body.events = Events.pushEvent(accountUpdate.body.events, eventFields);
24638
+ accountUpdate.body.events = Events3.pushEvent(accountUpdate.body.events, eventFields);
23864
24639
  }
23865
24640
  /**
23866
24641
  * Asynchronously fetches events emitted by this {@link SmartContract} and returns an array of events with their corresponding types.
@@ -24485,192 +25260,6 @@ function fillWithNull([...values], length) {
24485
25260
  return values;
24486
25261
  }
24487
25262
 
24488
- // dist/node/lib/provable/merkle-tree.js
24489
- var MerkleTree = class _MerkleTree {
24490
- /**
24491
- * Creates a new, empty [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree).
24492
- * @param height The height of Merkle Tree.
24493
- * @returns A new MerkleTree
24494
- */
24495
- constructor(height) {
24496
- this.height = height;
24497
- this.nodes = {};
24498
- this.zeroes = new Array(height);
24499
- this.zeroes[0] = Field4(0);
24500
- for (let i = 1; i < height; i += 1) {
24501
- this.zeroes[i] = Poseidon2.hash([this.zeroes[i - 1], this.zeroes[i - 1]]);
24502
- }
24503
- }
24504
- /**
24505
- * Return a new MerkleTree with the same contents as this one.
24506
- */
24507
- clone() {
24508
- let newTree = new _MerkleTree(this.height);
24509
- for (let [level, nodes] of Object.entries(this.nodes)) {
24510
- newTree.nodes[level] = { ...nodes };
24511
- }
24512
- return newTree;
24513
- }
24514
- /**
24515
- * Returns a node which lives at a given index and level.
24516
- * @param level Level of the node.
24517
- * @param index Index of the node.
24518
- * @returns The data of the node.
24519
- */
24520
- getNode(level, index) {
24521
- return this.nodes[level]?.[index.toString()] ?? this.zeroes[level];
24522
- }
24523
- /**
24524
- * Returns a leaf at a given index.
24525
- * @param index Index of the leaf.
24526
- * @returns The data of the leaf.
24527
- */
24528
- getLeaf(key) {
24529
- return this.getNode(0, key);
24530
- }
24531
- /**
24532
- * Returns the root of the [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree).
24533
- * @returns The root of the Merkle Tree.
24534
- */
24535
- getRoot() {
24536
- return this.getNode(this.height - 1, 0n);
24537
- }
24538
- // TODO: this allows to set a node at an index larger than the size. OK?
24539
- setNode(level, index, value) {
24540
- (this.nodes[level] ??= {})[index.toString()] = value;
24541
- }
24542
- // TODO: if this is passed an index bigger than the max, it will set a couple of out-of-bounds nodes but not affect the real Merkle root. OK?
24543
- /**
24544
- * Sets the value of a leaf node at a given index to a given value.
24545
- * @param index Position of the leaf node.
24546
- * @param leaf New value.
24547
- */
24548
- setLeaf(index, leaf) {
24549
- if (index >= this.leafCount) {
24550
- throw new Error(`index ${index} is out of range for ${this.leafCount} leaves.`);
24551
- }
24552
- this.setNode(0, index, leaf);
24553
- let currIndex = index;
24554
- for (let level = 1; level < this.height; level++) {
24555
- currIndex /= 2n;
24556
- const left = this.getNode(level - 1, currIndex * 2n);
24557
- const right = this.getNode(level - 1, currIndex * 2n + 1n);
24558
- this.setNode(level, currIndex, Poseidon2.hash([left, right]));
24559
- }
24560
- }
24561
- /**
24562
- * Returns the witness (also known as [Merkle Proof or Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof)) for the leaf at the given index.
24563
- * @param index Position of the leaf node.
24564
- * @returns The witness that belongs to the leaf.
24565
- */
24566
- getWitness(index) {
24567
- if (index >= this.leafCount) {
24568
- throw new Error(`index ${index} is out of range for ${this.leafCount} leaves.`);
24569
- }
24570
- const witness2 = [];
24571
- for (let level = 0; level < this.height - 1; level++) {
24572
- const isLeft = index % 2n === 0n;
24573
- const sibling = this.getNode(level, isLeft ? index + 1n : index - 1n);
24574
- witness2.push({ isLeft, sibling });
24575
- index /= 2n;
24576
- }
24577
- return witness2;
24578
- }
24579
- // TODO: this will always return true if the merkle tree was constructed normally; seems to be only useful for testing. remove?
24580
- /**
24581
- * Checks if the witness that belongs to the leaf at the given index is a valid witness.
24582
- * @param index Position of the leaf node.
24583
- * @returns True if the witness for the leaf node is valid.
24584
- */
24585
- validate(index) {
24586
- const path = this.getWitness(index);
24587
- let hash3 = this.getNode(0, index);
24588
- for (const node of path) {
24589
- hash3 = Poseidon2.hash(node.isLeft ? [hash3, node.sibling] : [node.sibling, hash3]);
24590
- }
24591
- return hash3.toString() === this.getRoot().toString();
24592
- }
24593
- // TODO: should this take an optional offset? should it fail if the array is too long?
24594
- /**
24595
- * Fills all leaves of the tree.
24596
- * @param leaves Values to fill the leaves with.
24597
- */
24598
- fill(leaves) {
24599
- leaves.forEach((value, index) => {
24600
- this.setLeaf(BigInt(index), value);
24601
- });
24602
- }
24603
- /**
24604
- * Returns the amount of leaf nodes.
24605
- * @returns Amount of leaf nodes.
24606
- */
24607
- get leafCount() {
24608
- return 2n ** BigInt(this.height - 1);
24609
- }
24610
- };
24611
- var BaseMerkleWitness = class extends CircuitValue {
24612
- height() {
24613
- return this.constructor.height;
24614
- }
24615
- /**
24616
- * Takes a {@link Witness} and turns it into a circuit-compatible Witness.
24617
- * @param witness Witness.
24618
- * @returns A circuit-compatible Witness.
24619
- */
24620
- constructor(witness2) {
24621
- super();
24622
- let height = witness2.length + 1;
24623
- if (height !== this.height()) {
24624
- throw Error(`Length of witness ${height}-1 doesn't match static tree height ${this.height()}.`);
24625
- }
24626
- this.path = witness2.map((item) => item.sibling);
24627
- this.isLeft = witness2.map((item) => Bool4(item.isLeft));
24628
- }
24629
- /**
24630
- * Calculates a root depending on the leaf value.
24631
- * @param leaf Value of the leaf node that belongs to this Witness.
24632
- * @returns The calculated root.
24633
- */
24634
- calculateRoot(leaf) {
24635
- let hash3 = leaf;
24636
- let n = this.height();
24637
- for (let i = 1; i < n; ++i) {
24638
- let isLeft = this.isLeft[i - 1];
24639
- const [left, right] = maybeSwap(isLeft, hash3, this.path[i - 1]);
24640
- hash3 = Poseidon2.hash([left, right]);
24641
- }
24642
- return hash3;
24643
- }
24644
- /**
24645
- * Calculates the index of the leaf node that belongs to this Witness.
24646
- * @returns Index of the leaf.
24647
- */
24648
- calculateIndex() {
24649
- let powerOfTwo = Field4(1);
24650
- let index = Field4(0);
24651
- let n = this.height();
24652
- for (let i = 1; i < n; ++i) {
24653
- index = Provable.if(this.isLeft[i - 1], index, index.add(powerOfTwo));
24654
- powerOfTwo = powerOfTwo.mul(2);
24655
- }
24656
- return index;
24657
- }
24658
- };
24659
- function MerkleWitness(height) {
24660
- class MerkleWitness_ extends BaseMerkleWitness {
24661
- }
24662
- MerkleWitness_.height = height;
24663
- arrayProp(Field4, height - 1)(MerkleWitness_.prototype, "path");
24664
- arrayProp(Bool4, height - 1)(MerkleWitness_.prototype, "isLeft");
24665
- return MerkleWitness_;
24666
- }
24667
- function maybeSwap(b2, x, y) {
24668
- let m = b2.toField().mul(x.sub(y));
24669
- const x_ = y.add(m);
24670
- const y_ = x.sub(m);
24671
- return [x_, y_];
24672
- }
24673
-
24674
25263
  // dist/node/lib/provable/merkle-map.js
24675
25264
  var import_tslib6 = require("tslib");
24676
25265
  var MerkleMap = class {
@@ -25080,7 +25669,7 @@ function pushAction(actionsHash, action) {
25080
25669
  MerkleLeaf.hash(action)
25081
25670
  ]);
25082
25671
  }
25083
- var ActionList = class extends MerkleList.create(MerkleLeaf, pushAction, Actions.empty().hash) {
25672
+ var ActionList = class extends MerkleList.create(MerkleLeaf, pushAction, Actions3.empty().hash) {
25084
25673
  };
25085
25674
  var LinearizedAction = class extends Struct({
25086
25675
  action: MerkleLeaf,
@@ -25110,15 +25699,15 @@ var LinearizedAction = class extends Struct({
25110
25699
  ])[0];
25111
25700
  }
25112
25701
  };
25113
- var LinearizedActionList = class extends MerkleList.create(LinearizedAction, (hash3, action) => Poseidon2.hash([hash3, LinearizedAction.hash(action)]), Actions.empty().hash) {
25702
+ var LinearizedActionList = class extends MerkleList.create(LinearizedAction, (hash3, action) => Poseidon2.hash([hash3, LinearizedAction.hash(action)]), Actions3.empty().hash) {
25114
25703
  };
25115
25704
  async function fetchMerkleLeaves(contract, config) {
25116
25705
  class MerkleActions extends MerkleList.create(
25117
25706
  ActionList.provable,
25118
- (hash3, actions) => Actions.updateSequenceState(hash3, actions.hash),
25707
+ (hash3, actions) => Actions3.updateSequenceState(hash3, actions.hash),
25119
25708
  // if no "start" action hash was specified, this means we are fetching the entire history of actions, which started from the empty action state hash
25120
25709
  // otherwise we are only fetching a part of the history, which starts at `fromActionState`
25121
- config?.fromActionState ?? Actions.emptyActionState()
25710
+ config?.fromActionState ?? Actions3.emptyActionState()
25122
25711
  ) {
25123
25712
  }
25124
25713
  let result = await fetchActions(contract.address, config, contract.tokenId);
@@ -25127,12 +25716,12 @@ async function fetchMerkleLeaves(contract, config) {
25127
25716
  let merkleLeafs = result.map((event) => event.actions.map((action) => MerkleLeaf.fromAction(action.map(Field4))));
25128
25717
  return MerkleActions.from(merkleLeafs.map((a2) => ActionList.fromReverse(a2)));
25129
25718
  }
25130
- async function fetchMerkleMap(contract, endActionState) {
25719
+ async function fetchMerkleMap(height, contract, endActionState) {
25131
25720
  let result = await fetchActions(contract.address, { endActionState }, contract.tokenId);
25132
25721
  if ("error" in result)
25133
25722
  throw Error(JSON.stringify(result));
25134
25723
  let leaves = result.map((event) => event.actions.map((action) => MerkleLeaf.fromAction(action.map(Field4))).reverse());
25135
- let merkleMap = new MerkleTree(256);
25724
+ let merkleMap = new (IndexedMerkleMap(height))();
25136
25725
  let valueMap = /* @__PURE__ */ new Map();
25137
25726
  updateMerkleMap(leaves, merkleMap, valueMap);
25138
25727
  return { merkleMap, valueMap };
@@ -25144,22 +25733,23 @@ function updateMerkleMap(updates, tree, valueMap) {
25144
25733
  let updates2 = [];
25145
25734
  for (let leaf of leaves) {
25146
25735
  let { key, value, usesPreviousValue, previousValue, prefix } = MerkleLeaf.toValue(leaf);
25147
- let isValidAction = !usesPreviousValue || intermediateTree.getLeaf(key).toBigInt() === previousValue;
25736
+ let previous = intermediateTree.getOption(key).orElse(0n);
25737
+ let isValidAction = !usesPreviousValue || previous.toBigInt() === previousValue;
25148
25738
  if (!isValidAction) {
25149
25739
  isValidUpdate = false;
25150
25740
  break;
25151
25741
  }
25152
- intermediateTree.setLeaf(key, Field4(value));
25153
- updates2.push({ key, value, fullValue: prefix.get() });
25742
+ intermediateTree.set(key, value);
25743
+ updates2.push({ key, fullValue: prefix.get() });
25154
25744
  }
25155
25745
  if (isValidUpdate) {
25156
- for (let { key, value, fullValue } of updates2) {
25157
- tree.setLeaf(key, Field4(value));
25746
+ tree.overwrite(intermediateTree);
25747
+ for (let { key, fullValue } of updates2) {
25158
25748
  if (valueMap)
25159
25749
  valueMap.set(key, fullValue);
25160
25750
  }
25161
25751
  } else {
25162
- intermediateTree = tree.clone();
25752
+ intermediateTree.overwrite(tree);
25163
25753
  }
25164
25754
  }
25165
25755
  }
@@ -25179,21 +25769,18 @@ var OffchainStateCommitments = class _OffchainStateCommitments extends Struct({
25179
25769
  // actionState: ActionIterator.provable,
25180
25770
  actionState: Field4
25181
25771
  }) {
25182
- static empty() {
25183
- let emptyMerkleRoot = new MerkleMap().getRoot();
25772
+ static emptyFromHeight(height) {
25773
+ let emptyMerkleRoot = new (IndexedMerkleMap(height))().root;
25184
25774
  return new _OffchainStateCommitments({
25185
25775
  root: emptyMerkleRoot,
25186
25776
  actionState: Actions.emptyActionState()
25187
25777
  });
25188
25778
  }
25189
25779
  };
25190
- var TREE_HEIGHT = 256;
25191
- var MerkleMapWitness2 = class extends MerkleWitness(TREE_HEIGHT) {
25192
- };
25193
- function merkleUpdateBatch({ maxActionsPerBatch, maxActionsPerUpdate }, stateA, actions, tree) {
25780
+ function merkleUpdateBatch({ maxActionsPerProof, maxActionsPerUpdate }, stateA, actions, tree) {
25194
25781
  actions.currentHash.assertEquals(stateA.actionState);
25195
25782
  let linearActions = LinearizedActionList.empty();
25196
- for (let i = 0; i < maxActionsPerBatch; i++) {
25783
+ for (let i = 0; i < maxActionsPerProof; i++) {
25197
25784
  let inner = actions.next().startIterating();
25198
25785
  let isAtEnd = Bool4(false);
25199
25786
  for (let i2 = 0; i2 < maxActionsPerUpdate; i2++) {
@@ -25208,55 +25795,43 @@ function merkleUpdateBatch({ maxActionsPerBatch, maxActionsPerUpdate }, stateA,
25208
25795
  inner.assertAtEnd(`Expected at most ${maxActionsPerUpdate} actions per account update.`);
25209
25796
  }
25210
25797
  actions.assertAtEnd();
25211
- let root = stateA.root;
25212
- let intermediateRoot = root;
25213
- let intermediateUpdates = [];
25214
- let intermediateTree = Unconstrained.witness(() => tree.get().clone());
25798
+ stateA.root.assertEquals(tree.root);
25799
+ let intermediateTree = tree.clone();
25215
25800
  let isValidUpdate = Bool4(true);
25216
- linearActions.forEach(maxActionsPerBatch, (element, isDummy) => {
25801
+ linearActions.forEach(maxActionsPerProof, (element, isDummy) => {
25217
25802
  let { action, isCheckPoint } = element;
25218
25803
  let { key, value, usesPreviousValue, previousValue } = action;
25219
- let witness2 = Provable.witness(MerkleMapWitness2, () => new MerkleMapWitness2(intermediateTree.get().getWitness(key.toBigInt())));
25220
- let actualPreviousValue = Provable.witness(Field4, () => intermediateTree.get().getLeaf(key.toBigInt()));
25221
- witness2.calculateIndex().assertEquals(key, "key mismatch");
25222
- witness2.calculateRoot(actualPreviousValue).assertEquals(intermediateRoot, "root mismatch");
25223
- let matchesPreviousValue = actualPreviousValue.equals(previousValue);
25804
+ key = Provable.if(isDummy, Field4(0n), key);
25805
+ value = Provable.if(isDummy, Field4(0n), value);
25806
+ let actualPreviousValue = intermediateTree.set(key, value);
25807
+ let matchesPreviousValue = actualPreviousValue.orElse(0n).equals(previousValue);
25224
25808
  let isValidAction = usesPreviousValue.implies(matchesPreviousValue);
25225
25809
  isValidUpdate = isValidUpdate.and(isValidAction);
25226
- let newRoot = witness2.calculateRoot(value);
25227
- intermediateRoot = Provable.if(isDummy, intermediateRoot, newRoot);
25228
- root = Provable.if(isCheckPoint.and(isValidUpdate), intermediateRoot, root);
25229
- let wasValidUpdate = isValidUpdate;
25810
+ tree.overwriteIf(isCheckPoint.and(isValidUpdate), intermediateTree);
25230
25811
  isValidUpdate = Provable.if(isCheckPoint, Bool4(true), isValidUpdate);
25231
- intermediateRoot = Provable.if(isCheckPoint, root, intermediateRoot);
25232
- Provable.asProver(() => {
25233
- if (isDummy.toBoolean())
25234
- return;
25235
- intermediateTree.get().setLeaf(key.toBigInt(), value.toConstant());
25236
- intermediateUpdates.push({ key, value });
25237
- if (isCheckPoint.toBoolean()) {
25238
- if (wasValidUpdate.toBoolean()) {
25239
- intermediateUpdates.forEach(({ key: key2, value: value2 }) => {
25240
- tree.get().setLeaf(key2.toBigInt(), value2.toConstant());
25241
- });
25242
- } else {
25243
- intermediateTree.set(tree.get().clone());
25244
- }
25245
- intermediateUpdates = [];
25246
- }
25247
- });
25812
+ intermediateTree.overwriteIf(isCheckPoint, tree);
25248
25813
  });
25249
- return { root, actionState: actions.currentHash };
25814
+ return { root: tree.root, actionState: actions.currentHash };
25250
25815
  }
25251
25816
  function OffchainStateRollup({
25252
- // 1 action uses about 7.5k constraints
25253
- // we can fit at most 7 * 7.5k = 52.5k constraints in one method next to proof verification
25254
- // => we use `maxActionsPerBatch = 6` to safely stay below the constraint limit
25255
- // the second parameter `maxActionsPerUpdate` only weakly affects # constraints, but has to be <= `maxActionsPerBatch`
25256
- // => so we set it to the same value
25257
- maxActionsPerBatch = 6,
25258
- maxActionsPerUpdate = 6
25817
+ /**
25818
+ * the constraints used in one batch proof with a height-31 tree are:
25819
+ *
25820
+ * 1967*A + 87*A*U + 2
25821
+ *
25822
+ * where A = maxActionsPerProof and U = maxActionsPerUpdate.
25823
+ *
25824
+ * To determine defaults, we set U=4 which should cover most use cases while ensuring
25825
+ * that the main loop which is independent of U dominates.
25826
+ *
25827
+ * Targeting ~50k constraints, to leave room for recursive verification, yields A=22.
25828
+ */
25829
+ maxActionsPerProof = 22,
25830
+ maxActionsPerUpdate = 4,
25831
+ logTotalCapacity = 30
25259
25832
  } = {}) {
25833
+ class IndexedMerkleMapN extends IndexedMerkleMap(logTotalCapacity + 1) {
25834
+ }
25260
25835
  let offchainStateRollup = ZkProgram({
25261
25836
  name: "merkle-map-rollup",
25262
25837
  publicInput: OffchainStateCommitments,
@@ -25267,9 +25842,9 @@ function OffchainStateRollup({
25267
25842
  */
25268
25843
  firstBatch: {
25269
25844
  // [actions, tree]
25270
- privateInputs: [ActionIterator.provable, Unconstrained.provable],
25845
+ privateInputs: [ActionIterator.provable, IndexedMerkleMapN.provable],
25271
25846
  async method(stateA, actions, tree) {
25272
- return merkleUpdateBatch({ maxActionsPerBatch, maxActionsPerUpdate }, stateA, actions, tree);
25847
+ return merkleUpdateBatch({ maxActionsPerProof, maxActionsPerUpdate }, stateA, actions, tree);
25273
25848
  }
25274
25849
  },
25275
25850
  /**
@@ -25279,14 +25854,14 @@ function OffchainStateRollup({
25279
25854
  // [actions, tree, proof]
25280
25855
  privateInputs: [
25281
25856
  ActionIterator.provable,
25282
- Unconstrained.provable,
25857
+ IndexedMerkleMapN.provable,
25283
25858
  SelfProof
25284
25859
  ],
25285
25860
  async method(stateA, actions, tree, recursiveProof) {
25286
25861
  recursiveProof.verify();
25287
25862
  Provable.assertEqual(OffchainStateCommitments, recursiveProof.publicInput, stateA);
25288
25863
  let stateB = recursiveProof.publicOutput;
25289
- return merkleUpdateBatch({ maxActionsPerBatch, maxActionsPerUpdate }, stateB, actions, tree);
25864
+ return merkleUpdateBatch({ maxActionsPerProof, maxActionsPerUpdate }, stateB, actions, tree);
25290
25865
  }
25291
25866
  }
25292
25867
  }
@@ -25304,34 +25879,38 @@ function OffchainStateRollup({
25304
25879
  return result;
25305
25880
  },
25306
25881
  async prove(tree, actions) {
25307
- assert3(tree.height === TREE_HEIGHT, "Tree height must match");
25882
+ assert3(tree.height === logTotalCapacity + 1, "Tree height must match");
25308
25883
  if (getProofsEnabled())
25309
25884
  await this.compile();
25310
25885
  tree = tree.clone();
25311
25886
  let iterator = actions.startIterating();
25312
25887
  let inputState = new OffchainStateCommitments({
25313
- root: tree.getRoot(),
25888
+ root: tree.root,
25314
25889
  actionState: iterator.currentHash
25315
25890
  });
25316
25891
  if (!getProofsEnabled()) {
25317
25892
  let actionsList = actions.data.get().map(({ element: actionsList2 }) => actionsList2.data.get().map(({ element }) => element).reverse()).reverse();
25318
25893
  updateMerkleMap(actionsList, tree);
25319
25894
  let finalState = new OffchainStateCommitments({
25320
- root: tree.getRoot(),
25895
+ root: tree.root,
25321
25896
  actionState: iterator.hash
25322
25897
  });
25323
25898
  let proof2 = await RollupProof.dummy(inputState, finalState, 2, 15);
25324
25899
  return { proof: proof2, tree, nProofs: 0 };
25325
25900
  }
25326
- let slice = sliceActions(iterator, maxActionsPerBatch);
25327
- let proof = await offchainStateRollup.firstBatch(inputState, slice, Unconstrained.from(tree));
25901
+ let slice = sliceActions(iterator, maxActionsPerProof);
25902
+ let proof = await offchainStateRollup.firstBatch(inputState, slice, tree);
25903
+ tree.root = proof.publicOutput.root;
25904
+ tree.length = Field4(tree.data.get().sortedLeaves.length);
25328
25905
  let nProofs = 1;
25329
25906
  for (let i = 1; ; i++) {
25330
25907
  if (iterator.isAtEnd().toBoolean())
25331
25908
  break;
25332
25909
  nProofs++;
25333
- let slice2 = sliceActions(iterator, maxActionsPerBatch);
25334
- proof = await offchainStateRollup.nextBatch(inputState, slice2, Unconstrained.from(tree), proof);
25910
+ let slice2 = sliceActions(iterator, maxActionsPerProof);
25911
+ proof = await offchainStateRollup.nextBatch(inputState, slice2, tree, proof);
25912
+ tree.root = proof.publicOutput.root;
25913
+ tree.length = Field4(tree.data.get().sortedLeaves.length);
25335
25914
  }
25336
25915
  return { proof, tree, nProofs };
25337
25916
  }
@@ -25358,14 +25937,17 @@ function sliceActions(actions, batchSize) {
25358
25937
  }
25359
25938
 
25360
25939
  // dist/node/lib/mina/actions/offchain-state.js
25361
- var MerkleWitness256 = MerkleWitness(256);
25362
- function OffchainState(config) {
25940
+ function OffchainState(config, options) {
25941
+ let { logTotalCapacity = 30, maxActionsPerUpdate = 4, maxActionsPerProof } = options ?? {};
25942
+ const height = logTotalCapacity + 1;
25943
+ class IndexedMerkleMapN extends IndexedMerkleMap(height) {
25944
+ }
25363
25945
  let internal = {
25364
25946
  _contract: void 0,
25365
25947
  _merkleMap: void 0,
25366
25948
  _valueMap: void 0,
25367
25949
  get contract() {
25368
- assert3(internal._contract !== void 0, "Must call `setContractAccount()` first");
25950
+ assert3(internal._contract !== void 0, "Must call `setContractInstance()` first");
25369
25951
  return internal._contract;
25370
25952
  }
25371
25953
  };
@@ -25379,12 +25961,16 @@ function OffchainState(config) {
25379
25961
  return { merkleMap: internal._merkleMap, valueMap: internal._valueMap };
25380
25962
  }
25381
25963
  let actionState = await onchainActionState();
25382
- let { merkleMap, valueMap } = await fetchMerkleMap(internal.contract, actionState);
25964
+ let { merkleMap, valueMap } = await fetchMerkleMap(height, internal.contract, actionState);
25383
25965
  internal._merkleMap = merkleMap;
25384
25966
  internal._valueMap = valueMap;
25385
25967
  return { merkleMap, valueMap };
25386
25968
  };
25387
- let rollup = OffchainStateRollup();
25969
+ let rollup = OffchainStateRollup({
25970
+ logTotalCapacity,
25971
+ maxActionsPerProof,
25972
+ maxActionsPerUpdate
25973
+ });
25388
25974
  function contract() {
25389
25975
  let ctx = smartContractContext.get();
25390
25976
  assert3(ctx !== null, "Offchain state methods must be called within a contract method");
@@ -25393,6 +25979,9 @@ function OffchainState(config) {
25393
25979
  }
25394
25980
  async function get2(key, valueType) {
25395
25981
  let stateRoot = contract().offchainState.getAndRequireEquals().root;
25982
+ let map2 = await Provable.witnessAsync(IndexedMerkleMapN.provable, async () => (await merkleMaps()).merkleMap);
25983
+ map2.root.assertEquals(stateRoot, "root mismatch");
25984
+ let valueHash = map2.getOption(key);
25396
25985
  const optionType = Option(valueType);
25397
25986
  let value = await Provable.witnessAsync(optionType, async () => {
25398
25987
  let { valueMap } = await merkleMaps();
@@ -25403,15 +25992,9 @@ function OffchainState(config) {
25403
25992
  let value2 = fromActionWithoutHashes(valueType, valueFields);
25404
25993
  return optionType.from(value2);
25405
25994
  });
25406
- let witness2 = await Provable.witnessAsync(MerkleWitness256, async () => {
25407
- let { merkleMap } = await merkleMaps();
25408
- return new MerkleWitness256(merkleMap.getWitness(key.toBigInt()));
25409
- });
25410
- let valueHash = Provable.if(value.isSome, Poseidon2.hashPacked(valueType, value.value), Field4(0));
25411
- let actualKey = witness2.calculateIndex();
25412
- let actualRoot = witness2.calculateRoot(valueHash);
25413
- key.assertEquals(actualKey, "key mismatch");
25414
- stateRoot.assertEquals(actualRoot, "root mismatch");
25995
+ let hashMatches = Poseidon2.hashPacked(valueType, value.value).equals(valueHash.value);
25996
+ let bothNone = value.isSome.or(valueHash.isSome).not();
25997
+ assert3(hashMatches.or(bothNone), "value hash mismatch");
25415
25998
  return value;
25416
25999
  }
25417
26000
  function field(index, type) {
@@ -25427,7 +26010,7 @@ function OffchainState(config) {
25427
26010
  value: type.fromValue(value)
25428
26011
  });
25429
26012
  let update = contract().self;
25430
- update.body.actions = Actions.pushEvent(update.body.actions, action);
26013
+ update.body.actions = Actions3.pushEvent(update.body.actions, action);
25431
26014
  },
25432
26015
  update({ from, to }) {
25433
26016
  let action = toAction({
@@ -25439,7 +26022,7 @@ function OffchainState(config) {
25439
26022
  previousValue: optionType.fromValue(from)
25440
26023
  });
25441
26024
  let update = contract().self;
25442
- update.body.actions = Actions.pushEvent(update.body.actions, action);
26025
+ update.body.actions = Actions3.pushEvent(update.body.actions, action);
25443
26026
  },
25444
26027
  async get() {
25445
26028
  let key = toKeyHash(prefix, void 0, void 0);
@@ -25460,7 +26043,7 @@ function OffchainState(config) {
25460
26043
  value: valueType.fromValue(value)
25461
26044
  });
25462
26045
  let update = contract().self;
25463
- update.body.actions = Actions.pushEvent(update.body.actions, action);
26046
+ update.body.actions = Actions3.pushEvent(update.body.actions, action);
25464
26047
  },
25465
26048
  update(key, { from, to }) {
25466
26049
  let action = toAction({
@@ -25472,7 +26055,7 @@ function OffchainState(config) {
25472
26055
  previousValue: optionType.fromValue(from)
25473
26056
  });
25474
26057
  let update = contract().self;
25475
- update.body.actions = Actions.pushEvent(update.body.actions, action);
26058
+ update.body.actions = Actions3.pushEvent(update.body.actions, action);
25476
26059
  },
25477
26060
  async get(key) {
25478
26061
  let keyHash = toKeyHash(prefix, keyType, key);
@@ -25494,7 +26077,7 @@ function OffchainState(config) {
25494
26077
  fromActionState: actionState
25495
26078
  });
25496
26079
  let result = await rollup.prove(merkleMap, actions);
25497
- let { merkleMap: newMerkleMap, valueMap: newValueMap } = await fetchMerkleMap(internal.contract);
26080
+ let { merkleMap: newMerkleMap, valueMap: newValueMap } = await fetchMerkleMap(height, internal.contract);
25498
26081
  internal._merkleMap = newMerkleMap;
25499
26082
  internal._valueMap = newValueMap;
25500
26083
  return result.proof;
@@ -25510,11 +26093,15 @@ function OffchainState(config) {
25510
26093
  fields: Object.fromEntries(Object.entries(config).map(([key, kind], i) => [
25511
26094
  key,
25512
26095
  kind.kind === "offchain-field" ? field(i, kind.type) : map(i, kind.keyType, kind.valueType)
25513
- ]))
26096
+ ])),
26097
+ commitments() {
26098
+ return State2(OffchainStateCommitments.emptyFromHeight(height));
26099
+ }
25514
26100
  };
25515
26101
  }
25516
26102
  OffchainState.Map = OffchainMap;
25517
26103
  OffchainState.Field = OffchainField;
26104
+ OffchainState.Commitments = OffchainStateCommitments;
25518
26105
  function OffchainField(type) {
25519
26106
  return { kind: "offchain-field", type };
25520
26107
  }
@@ -25524,11 +26111,13 @@ function OffchainMap(key, value) {
25524
26111
 
25525
26112
  // dist/node/index.js
25526
26113
  var Experimental_ = {
25527
- memoizeWitness
26114
+ memoizeWitness,
26115
+ IndexedMerkleMap
25528
26116
  };
25529
26117
  var Experimental;
25530
26118
  (function(Experimental2) {
25531
26119
  Experimental2.memoizeWitness = Experimental_.memoizeWitness;
26120
+ Experimental2.IndexedMerkleMap = Experimental_.IndexedMerkleMap;
25532
26121
  Experimental2.OffchainState = OffchainState;
25533
26122
  class OffchainStateCommitments2 extends OffchainStateCommitments {
25534
26123
  }