@proto-kit/common 0.1.1-develop.165 → 0.1.1-develop.1665

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 (249) hide show
  1. package/dist/compiling/AtomicCompileHelper.d.ts +13 -0
  2. package/dist/compiling/AtomicCompileHelper.d.ts.map +1 -0
  3. package/dist/compiling/AtomicCompileHelper.js +40 -0
  4. package/dist/compiling/AtomicCompileHelper.js.map +1 -0
  5. package/dist/compiling/CompilableModule.d.ts +6 -0
  6. package/dist/compiling/CompilableModule.d.ts.map +1 -0
  7. package/dist/compiling/CompilableModule.js +2 -0
  8. package/dist/compiling/CompilableModule.js.map +1 -0
  9. package/dist/compiling/CompileRegistry.d.ts +26 -0
  10. package/dist/compiling/CompileRegistry.d.ts.map +1 -0
  11. package/dist/compiling/CompileRegistry.js +69 -0
  12. package/dist/compiling/CompileRegistry.js.map +1 -0
  13. package/dist/compiling/services/ChildVerificationKeyService.d.ts +10 -0
  14. package/dist/compiling/services/ChildVerificationKeyService.d.ts.map +1 -0
  15. package/dist/compiling/services/ChildVerificationKeyService.js +27 -0
  16. package/dist/compiling/services/ChildVerificationKeyService.js.map +1 -0
  17. package/dist/config/ChildContainerCreatable.d.ts +5 -0
  18. package/dist/config/ChildContainerCreatable.d.ts.map +1 -0
  19. package/dist/config/ChildContainerCreatable.js +2 -0
  20. package/dist/config/ChildContainerCreatable.js.map +1 -0
  21. package/dist/config/ChildContainerProvider.d.ts +5 -0
  22. package/dist/config/ChildContainerProvider.d.ts.map +1 -0
  23. package/dist/config/ChildContainerProvider.js +2 -0
  24. package/dist/config/ChildContainerProvider.js.map +1 -0
  25. package/dist/config/ConfigurableModule.d.ts +6 -2
  26. package/dist/config/ConfigurableModule.d.ts.map +1 -1
  27. package/dist/config/ConfigurableModule.js +5 -0
  28. package/dist/config/ConfigurableModule.js.map +1 -0
  29. package/dist/config/ModuleContainer.d.ts +70 -17
  30. package/dist/config/ModuleContainer.d.ts.map +1 -1
  31. package/dist/config/ModuleContainer.js +164 -22
  32. package/dist/config/ModuleContainer.js.map +1 -0
  33. package/dist/config/Startable.d.ts +4 -0
  34. package/dist/config/Startable.d.ts.map +1 -0
  35. package/dist/config/Startable.js +2 -0
  36. package/dist/config/Startable.js.map +1 -0
  37. package/dist/config/injectAlias.d.ts +18 -0
  38. package/dist/config/injectAlias.d.ts.map +1 -0
  39. package/dist/config/injectAlias.js +47 -0
  40. package/dist/config/injectAlias.js.map +1 -0
  41. package/dist/dependencyFactory/DependencyFactory.d.ts +29 -0
  42. package/dist/dependencyFactory/DependencyFactory.d.ts.map +1 -0
  43. package/dist/dependencyFactory/DependencyFactory.js +2 -0
  44. package/dist/dependencyFactory/DependencyFactory.js.map +1 -0
  45. package/dist/dummyVerificationKey.d.ts +3 -0
  46. package/dist/dummyVerificationKey.d.ts.map +1 -0
  47. package/dist/dummyVerificationKey.js +8 -0
  48. package/dist/dummyVerificationKey.js.map +1 -0
  49. package/dist/events/EventEmitter.d.ts +19 -0
  50. package/dist/events/EventEmitter.d.ts.map +1 -0
  51. package/dist/events/EventEmitter.js +35 -0
  52. package/dist/events/EventEmitter.js.map +1 -0
  53. package/dist/events/EventEmitterProxy.d.ts +18 -0
  54. package/dist/events/EventEmitterProxy.d.ts.map +1 -0
  55. package/dist/events/EventEmitterProxy.js +35 -0
  56. package/dist/events/EventEmitterProxy.js.map +1 -0
  57. package/dist/events/EventEmittingComponent.d.ts +9 -0
  58. package/dist/events/EventEmittingComponent.d.ts.map +1 -0
  59. package/dist/events/EventEmittingComponent.js +2 -0
  60. package/dist/events/EventEmittingComponent.js.map +1 -0
  61. package/dist/events/ReplayingSingleUseEventEmitter.d.ts +17 -0
  62. package/dist/events/ReplayingSingleUseEventEmitter.d.ts.map +1 -0
  63. package/dist/events/ReplayingSingleUseEventEmitter.js +34 -0
  64. package/dist/events/ReplayingSingleUseEventEmitter.js.map +1 -0
  65. package/dist/index.d.ts +24 -1
  66. package/dist/index.d.ts.map +1 -1
  67. package/dist/index.js +25 -2
  68. package/dist/index.js.map +1 -0
  69. package/dist/log.d.ts +37 -0
  70. package/dist/log.d.ts.map +1 -0
  71. package/dist/log.js +114 -0
  72. package/dist/log.js.map +1 -0
  73. package/dist/trees/lmt/AbstractLinkedMerkleTree.d.ts +288 -0
  74. package/dist/trees/lmt/AbstractLinkedMerkleTree.d.ts.map +1 -0
  75. package/dist/trees/lmt/AbstractLinkedMerkleTree.js +22 -0
  76. package/dist/trees/lmt/AbstractLinkedMerkleTree.js.map +1 -0
  77. package/dist/trees/lmt/InMemoryLinkedLeafStore.d.ts +21 -0
  78. package/dist/trees/lmt/InMemoryLinkedLeafStore.d.ts.map +1 -0
  79. package/dist/trees/lmt/InMemoryLinkedLeafStore.js +26 -0
  80. package/dist/trees/lmt/InMemoryLinkedLeafStore.js.map +1 -0
  81. package/dist/trees/lmt/LinkedLeafStore.d.ts +16 -0
  82. package/dist/trees/lmt/LinkedLeafStore.d.ts.map +1 -0
  83. package/dist/trees/lmt/LinkedLeafStore.js +2 -0
  84. package/dist/trees/lmt/LinkedLeafStore.js.map +1 -0
  85. package/dist/trees/lmt/LinkedMerkleTree.d.ts +11 -0
  86. package/dist/trees/lmt/LinkedMerkleTree.d.ts.map +1 -0
  87. package/dist/trees/lmt/LinkedMerkleTree.js +241 -0
  88. package/dist/trees/lmt/LinkedMerkleTree.js.map +1 -0
  89. package/dist/trees/lmt/LinkedMerkleTreeCircuitOps.d.ts +113 -0
  90. package/dist/trees/lmt/LinkedMerkleTreeCircuitOps.d.ts.map +1 -0
  91. package/dist/trees/lmt/LinkedMerkleTreeCircuitOps.js +113 -0
  92. package/dist/trees/lmt/LinkedMerkleTreeCircuitOps.js.map +1 -0
  93. package/dist/trees/lmt/LinkedMerkleTreeTypes.d.ts +74 -0
  94. package/dist/trees/lmt/LinkedMerkleTreeTypes.d.ts.map +1 -0
  95. package/dist/trees/lmt/LinkedMerkleTreeTypes.js +50 -0
  96. package/dist/trees/lmt/LinkedMerkleTreeTypes.js.map +1 -0
  97. package/dist/trees/sparse/InMemoryMerkleTreeStorage.d.ts +11 -0
  98. package/dist/trees/sparse/InMemoryMerkleTreeStorage.d.ts.map +1 -0
  99. package/dist/trees/sparse/InMemoryMerkleTreeStorage.js +13 -0
  100. package/dist/trees/sparse/InMemoryMerkleTreeStorage.js.map +1 -0
  101. package/dist/trees/sparse/MerkleTreeStore.d.ts +5 -0
  102. package/dist/trees/sparse/MerkleTreeStore.d.ts.map +1 -0
  103. package/dist/trees/sparse/MerkleTreeStore.js +2 -0
  104. package/dist/trees/sparse/MerkleTreeStore.js.map +1 -0
  105. package/dist/trees/sparse/MockAsyncMerkleStore.d.ts +9 -0
  106. package/dist/trees/sparse/MockAsyncMerkleStore.d.ts.map +1 -0
  107. package/dist/trees/sparse/MockAsyncMerkleStore.js +20 -0
  108. package/dist/trees/sparse/MockAsyncMerkleStore.js.map +1 -0
  109. package/dist/trees/sparse/RollupMerkleTree.d.ts +157 -0
  110. package/dist/trees/sparse/RollupMerkleTree.d.ts.map +1 -0
  111. package/dist/trees/sparse/RollupMerkleTree.js +272 -0
  112. package/dist/trees/sparse/RollupMerkleTree.js.map +1 -0
  113. package/dist/types.d.ts +16 -0
  114. package/dist/types.d.ts.map +1 -1
  115. package/dist/types.js +12 -1
  116. package/dist/types.js.map +1 -0
  117. package/dist/utils.d.ts +62 -0
  118. package/dist/utils.d.ts.map +1 -1
  119. package/dist/utils.js +155 -0
  120. package/dist/utils.js.map +1 -0
  121. package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts +4 -3
  122. package/dist/zkProgrammable/ProvableMethodExecutionContext.d.ts.map +1 -1
  123. package/dist/zkProgrammable/ProvableMethodExecutionContext.js +2 -3
  124. package/dist/zkProgrammable/ProvableMethodExecutionContext.js.map +1 -0
  125. package/dist/zkProgrammable/ZkProgrammable.d.ts +15 -7
  126. package/dist/zkProgrammable/ZkProgrammable.d.ts.map +1 -1
  127. package/dist/zkProgrammable/ZkProgrammable.js +34 -15
  128. package/dist/zkProgrammable/ZkProgrammable.js.map +1 -0
  129. package/dist/zkProgrammable/provableMethod.d.ts +8 -5
  130. package/dist/zkProgrammable/provableMethod.d.ts.map +1 -1
  131. package/dist/zkProgrammable/provableMethod.js +15 -13
  132. package/dist/zkProgrammable/provableMethod.js.map +1 -0
  133. package/jest.config.cjs +12 -1
  134. package/package.json +8 -7
  135. package/src/compiling/AtomicCompileHelper.ts +62 -0
  136. package/src/compiling/CompilableModule.ts +6 -0
  137. package/src/compiling/CompileRegistry.ts +79 -0
  138. package/src/compiling/services/ChildVerificationKeyService.ts +26 -0
  139. package/src/config/ChildContainerCreatable.ts +5 -0
  140. package/src/config/ChildContainerProvider.ts +5 -0
  141. package/src/config/ConfigurableModule.ts +15 -2
  142. package/src/config/ModuleContainer.ts +287 -46
  143. package/src/config/Startable.ts +3 -0
  144. package/src/config/injectAlias.ts +70 -0
  145. package/src/dependencyFactory/DependencyFactory.ts +57 -0
  146. package/src/dummyVerificationKey.ts +10 -0
  147. package/src/events/EventEmitter.ts +61 -0
  148. package/src/events/EventEmitterProxy.ts +81 -0
  149. package/src/events/EventEmittingComponent.ts +11 -0
  150. package/src/events/ReplayingSingleUseEventEmitter.ts +42 -0
  151. package/src/index.ts +24 -2
  152. package/src/log.ts +143 -0
  153. package/src/trees/lmt/AbstractLinkedMerkleTree.ts +102 -0
  154. package/src/trees/lmt/InMemoryLinkedLeafStore.ts +42 -0
  155. package/src/trees/lmt/LinkedLeafStore.ts +13 -0
  156. package/src/trees/lmt/LinkedMerkleTree.ts +335 -0
  157. package/src/trees/lmt/LinkedMerkleTreeCircuitOps.ts +188 -0
  158. package/src/trees/lmt/LinkedMerkleTreeTypes.ts +53 -0
  159. package/src/trees/sparse/InMemoryMerkleTreeStorage.ts +17 -0
  160. package/src/trees/sparse/MerkleTreeStore.ts +5 -0
  161. package/src/trees/sparse/MockAsyncMerkleStore.ts +30 -0
  162. package/src/trees/sparse/RollupMerkleTree.ts +427 -0
  163. package/src/types.ts +43 -2
  164. package/src/utils.ts +287 -0
  165. package/src/zkProgrammable/ProvableMethodExecutionContext.ts +6 -6
  166. package/src/zkProgrammable/ZkProgrammable.ts +61 -29
  167. package/src/zkProgrammable/provableMethod.ts +38 -21
  168. package/test/config/ContainerEvents.test.ts +65 -0
  169. package/test/config/ModuleContainer.test.ts +146 -15
  170. package/test/config/injectAlias.test.ts +28 -0
  171. package/test/trees/LinkedMerkleTree.test.ts +124 -0
  172. package/test/trees/LinkedMerkleTreeCircuitOps.test.ts +147 -0
  173. package/test/trees/MerkleTree.test.ts +220 -0
  174. package/test/tsconfig.json +5 -2
  175. package/test/zkProgrammable/ZkProgrammable.test.ts +135 -114
  176. package/tsconfig.json +1 -1
  177. package/dist/Constants.d.ts +0 -4
  178. package/dist/Constants.d.ts.map +0 -1
  179. package/dist/Constants.js +0 -3
  180. package/dist/config/ConfigurationAggregator.d.ts +0 -10
  181. package/dist/config/ConfigurationAggregator.d.ts.map +0 -1
  182. package/dist/config/ConfigurationAggregator.js +0 -35
  183. package/dist/config/ConfigurationReceiver.d.ts +0 -25
  184. package/dist/config/ConfigurationReceiver.d.ts.map +0 -1
  185. package/dist/config/ConfigurationReceiver.js +0 -36
  186. package/dist/config/types.d.ts +0 -2
  187. package/dist/config/types.d.ts.map +0 -1
  188. package/dist/config/types.js +0 -1
  189. package/dist/model/MethodPublicInput.d.ts +0 -51
  190. package/dist/model/MethodPublicInput.d.ts.map +0 -1
  191. package/dist/model/MethodPublicInput.js +0 -11
  192. package/dist/model/Option.d.ts +0 -89
  193. package/dist/model/Option.d.ts.map +0 -1
  194. package/dist/model/Option.js +0 -86
  195. package/dist/model/Path.d.ts +0 -31
  196. package/dist/model/Path.d.ts.map +0 -1
  197. package/dist/model/Path.js +0 -44
  198. package/dist/model/StateTransition.d.ts +0 -85
  199. package/dist/model/StateTransition.d.ts.map +0 -1
  200. package/dist/model/StateTransition.js +0 -58
  201. package/dist/model/StateTransitionProvableBatch.d.ts +0 -56
  202. package/dist/model/StateTransitionProvableBatch.d.ts.map +0 -1
  203. package/dist/model/StateTransitionProvableBatch.js +0 -20
  204. package/dist/prover/block/BlockProver.d.ts +0 -199
  205. package/dist/prover/block/BlockProver.d.ts.map +0 -1
  206. package/dist/prover/block/BlockProver.js +0 -119
  207. package/dist/prover/block/BlockScopedModule.d.ts +0 -3
  208. package/dist/prover/block/BlockScopedModule.d.ts.map +0 -1
  209. package/dist/prover/block/BlockScopedModule.js +0 -6
  210. package/dist/prover/statetransition/StateTransitionProver.d.ts +0 -92
  211. package/dist/prover/statetransition/StateTransitionProver.d.ts.map +0 -1
  212. package/dist/prover/statetransition/StateTransitionProver.js +0 -127
  213. package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts +0 -16
  214. package/dist/prover/statetransition/StateTransitionWitnessProvider.d.ts.map +0 -1
  215. package/dist/prover/statetransition/StateTransitionWitnessProvider.js +0 -17
  216. package/dist/src/model/Option.d.ts +0 -158
  217. package/dist/src/model/Option.d.ts.map +0 -1
  218. package/dist/src/model/Option.js +0 -53
  219. package/dist/src/model/Path.d.ts +0 -35
  220. package/dist/src/model/Path.d.ts.map +0 -1
  221. package/dist/src/model/Path.js +0 -51
  222. package/dist/src/model/StateTransition.d.ts +0 -201
  223. package/dist/src/model/StateTransition.d.ts.map +0 -1
  224. package/dist/src/model/StateTransition.js +0 -43
  225. package/dist/src/utils/PrefixedHashList.d.ts +0 -15
  226. package/dist/src/utils/PrefixedHashList.d.ts.map +0 -1
  227. package/dist/src/utils/PrefixedHashList.js +0 -28
  228. package/dist/src/utils/ProvableHashList.d.ts +0 -30
  229. package/dist/src/utils/ProvableHashList.d.ts.map +0 -1
  230. package/dist/src/utils/ProvableHashList.js +0 -43
  231. package/dist/utils/PrefixedHashList.d.ts +0 -14
  232. package/dist/utils/PrefixedHashList.d.ts.map +0 -1
  233. package/dist/utils/PrefixedHashList.js +0 -12
  234. package/dist/utils/PrefixedProvableHashList.d.ts +0 -8
  235. package/dist/utils/PrefixedProvableHashList.d.ts.map +0 -1
  236. package/dist/utils/PrefixedProvableHashList.js +0 -12
  237. package/dist/utils/ProvableHashList.d.ts +0 -26
  238. package/dist/utils/ProvableHashList.d.ts.map +0 -1
  239. package/dist/utils/ProvableHashList.js +0 -35
  240. package/dist/utils/Utils.d.ts +0 -22
  241. package/dist/utils/Utils.d.ts.map +0 -1
  242. package/dist/utils/Utils.js +0 -41
  243. package/dist/utils/merkletree/MemoryMerkleTreeStorage.d.ts +0 -26
  244. package/dist/utils/merkletree/MemoryMerkleTreeStorage.d.ts.map +0 -1
  245. package/dist/utils/merkletree/MemoryMerkleTreeStorage.js +0 -79
  246. package/dist/utils/merkletree/RollupMerkleTree.d.ts +0 -143
  247. package/dist/utils/merkletree/RollupMerkleTree.d.ts.map +0 -1
  248. package/dist/utils/merkletree/RollupMerkleTree.js +0 -246
  249. package/tsconfig.test.json +0 -9
@@ -0,0 +1,427 @@
1
+ import { Bool, Field, Poseidon, Provable, Struct } from "o1js";
2
+ import uniqBy from "lodash/uniqBy";
3
+
4
+ import { range } from "../../utils";
5
+ import { TypedClass } from "../../types";
6
+
7
+ import { MerkleTreeStore } from "./MerkleTreeStore";
8
+ import { InMemoryMerkleTreeStorage } from "./InMemoryMerkleTreeStorage";
9
+
10
+ export class StructTemplate extends Struct({
11
+ path: Provable.Array(Field, 0),
12
+ isLeft: Provable.Array(Bool, 0),
13
+ }) {}
14
+
15
+ export interface AbstractMerkleWitness extends StructTemplate {
16
+ height(): number;
17
+
18
+ /**
19
+ * Calculates a root depending on the leaf value.
20
+ * @param hash Value of the leaf node that belongs to this Witness.
21
+ * @returns The calculated root.
22
+ */
23
+ calculateRoot(hash: Field): Field;
24
+
25
+ /**
26
+ * Calculates the index of the leaf node that belongs to this Witness.
27
+ * @returns Index of the leaf.
28
+ */
29
+ calculateIndex(): Field;
30
+
31
+ checkMembership(root: Field, key: Field, value: Field): Bool;
32
+
33
+ checkMembershipSimple(root: Field, value: Field): Bool;
34
+
35
+ checkMembershipGetRoots(
36
+ root: Field,
37
+ key: Field,
38
+ value: Field
39
+ ): [Bool, Field, Field];
40
+
41
+ toShortenedEntries(): string[];
42
+ }
43
+
44
+ export interface AbstractMerkleTree {
45
+ store: MerkleTreeStore;
46
+ readonly leafCount: bigint;
47
+
48
+ assertIndexRange(index: bigint): void;
49
+
50
+ /**
51
+ * Returns a node which lives at a given index and level.
52
+ * @param level Level of the node.
53
+ * @param index Index of the node.
54
+ * @returns The data of the node.
55
+ */
56
+ getNode(level: number, index: bigint): Field;
57
+
58
+ /**
59
+ * Returns the root of the [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree).
60
+ * @returns The root of the Merkle Tree.
61
+ */
62
+ getRoot(): Field;
63
+
64
+ /**
65
+ * Sets the value of a leaf node at a given index to a given value.
66
+ * @param index Position of the leaf node.
67
+ * @param leaf New value.
68
+ */
69
+ setLeaf(index: bigint, leaf: Field): void;
70
+
71
+ setLeaves(updates: { index: bigint; leaf: Field }[]): void;
72
+
73
+ /**
74
+ * Returns the witness (also known as
75
+ * [Merkle Proof or Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof))
76
+ * for the leaf at the given index.
77
+ * @param index Position of the leaf node.
78
+ * @returns The witness that belongs to the leaf.
79
+ */
80
+ getWitness(index: bigint): AbstractMerkleWitness;
81
+
82
+ /**
83
+ * Fills all leaves of the tree.
84
+ * @param leaves Values to fill the leaves with.
85
+ */
86
+ fill(leaves: Field[]): void;
87
+ }
88
+
89
+ export interface AbstractMerkleTreeClass {
90
+ new (store: MerkleTreeStore): AbstractMerkleTree;
91
+
92
+ WITNESS: TypedClass<AbstractMerkleWitness> &
93
+ typeof StructTemplate & { dummy: () => AbstractMerkleWitness };
94
+
95
+ HEIGHT: number;
96
+
97
+ EMPTY_ROOT: bigint;
98
+
99
+ get leafCount(): bigint;
100
+ }
101
+
102
+ /**
103
+ * A [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree) is a binary tree in
104
+ * which every leaf is the cryptography hash of a piece of data,
105
+ * and every node is the hash of the concatenation of its two child nodes.
106
+ *
107
+ * A Merkle Tree allows developers to easily and securely verify
108
+ * the integrity of large amounts of data.
109
+ *
110
+ * Take a look at our [documentation](https://docs.minaprotocol.com/en/zkapps)
111
+ * on how to use Merkle Trees in combination with zkApps and
112
+ * zero knowledge programming!
113
+ *
114
+ * Levels are indexed from leaves (level 0) to root (level N - 1).
115
+ *
116
+ * This function takes a height as argument and returns a class
117
+ * that implements a merkletree with that specified height.
118
+ *
119
+ * It also holds the Witness class under tree.WITNESS
120
+ */
121
+ export function createMerkleTree(height: number): AbstractMerkleTreeClass {
122
+ /**
123
+ * The {@link RollupMerkleWitness} class defines a circuit-compatible base class
124
+ * for [Merkle Witness'](https://computersciencewiki.org/index.php/Merkle_proof).
125
+ */
126
+ class RollupMerkleWitness
127
+ extends Struct({
128
+ path: Provable.Array(Field, height - 1),
129
+ isLeft: Provable.Array(Bool, height - 1),
130
+ })
131
+ implements AbstractMerkleWitness
132
+ {
133
+ public static height = height;
134
+
135
+ public height(): number {
136
+ return RollupMerkleWitness.height;
137
+ }
138
+
139
+ /**
140
+ * Calculates a root depending on the leaf value.
141
+ * @param leaf Value of the leaf node that belongs to this Witness.
142
+ * @returns The calculated root.
143
+ */
144
+ public calculateRoot(leaf: Field): Field {
145
+ let hash = leaf;
146
+ const n = this.height();
147
+
148
+ for (let index = 1; index < n; ++index) {
149
+ const isLeft = this.isLeft[index - 1];
150
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
151
+ const [left, right] = maybeSwap(isLeft, hash, this.path[index - 1]);
152
+ hash = Poseidon.hash([left, right]);
153
+ }
154
+
155
+ return hash;
156
+ }
157
+
158
+ /**
159
+ * Calculates the index of the leaf node that belongs to this Witness.
160
+ * @returns Index of the leaf.
161
+ */
162
+ public calculateIndex(): Field {
163
+ let powerOfTwo = Field(1);
164
+ let index = Field(0);
165
+ const n = this.height();
166
+
167
+ for (let i = 1; i < n; ++i) {
168
+ index = Provable.if(this.isLeft[i - 1], index, index.add(powerOfTwo));
169
+ powerOfTwo = powerOfTwo.mul(2);
170
+ }
171
+
172
+ return index;
173
+ }
174
+
175
+ public checkMembership(root: Field, key: Field, value: Field): Bool {
176
+ const calculatedRoot = this.calculateRoot(value);
177
+ const calculatedKey = this.calculateIndex();
178
+ // We don't have to range-check the key, because if it would be greater
179
+ // than leafCount, it would not match the computedKey
180
+ key.assertEquals(calculatedKey, "Keys of MerkleWitness does not match");
181
+ return root.equals(calculatedRoot);
182
+ }
183
+
184
+ public checkMembershipSimple(root: Field, value: Field): Bool {
185
+ const calculatedRoot = this.calculateRoot(value);
186
+ return root.equals(calculatedRoot);
187
+ }
188
+
189
+ public checkMembershipGetRoots(
190
+ root: Field,
191
+ key: Field,
192
+ value: Field
193
+ ): [Bool, Field, Field] {
194
+ const calculatedRoot = this.calculateRoot(value);
195
+ const calculatedKey = this.calculateIndex();
196
+ key.assertEquals(calculatedKey, "Keys of MerkleWitness does not match");
197
+ return [root.equals(calculatedRoot), root, calculatedRoot];
198
+ }
199
+
200
+ public toShortenedEntries() {
201
+ return range(0, 5)
202
+ .concat(range(this.height() - 4, this.height()))
203
+ .map((index) =>
204
+ [
205
+ this.path[index].toString(),
206
+ this.isLeft[index].toString(),
207
+ ].toString()
208
+ );
209
+ }
210
+
211
+ public static dummy() {
212
+ return new RollupMerkleWitness({
213
+ isLeft: Array<Bool>(this.height - 1).fill(Bool(true)),
214
+ path: Array<Field>(this.height - 1).fill(Field(0)),
215
+ });
216
+ }
217
+ }
218
+ return class AbstractRollupMerkleTree implements AbstractMerkleTree {
219
+ public static HEIGHT = height;
220
+
221
+ public static EMPTY_ROOT = new AbstractRollupMerkleTree(
222
+ new InMemoryMerkleTreeStorage()
223
+ )
224
+ .getRoot()
225
+ .toBigInt();
226
+
227
+ public static get leafCount(): bigint {
228
+ return 2n ** BigInt(AbstractRollupMerkleTree.HEIGHT - 1);
229
+ }
230
+
231
+ public static WITNESS = RollupMerkleWitness;
232
+
233
+ // private in interface
234
+ // TODO Cache this in some static variable so that we don't recompute it every time
235
+ readonly zeroes: bigint[];
236
+
237
+ readonly store: MerkleTreeStore;
238
+
239
+ public constructor(store: MerkleTreeStore) {
240
+ this.store = store;
241
+ this.zeroes = [0n];
242
+ for (let index = 1; index < AbstractRollupMerkleTree.HEIGHT; index += 1) {
243
+ const previousLevel = Field(this.zeroes[index - 1]);
244
+ this.zeroes.push(
245
+ Poseidon.hash([previousLevel, previousLevel]).toBigInt()
246
+ );
247
+ }
248
+ }
249
+
250
+ public assertIndexRange(index: bigint) {
251
+ if (index > this.leafCount) {
252
+ throw new Error("Index greater than maximum leaf number");
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Returns a node which lives at a given index and level.
258
+ * @param level Level of the node.
259
+ * @param index Index of the node.
260
+ * @returns The data of the node.
261
+ */
262
+ public getNode(level: number, index: bigint): Field {
263
+ this.assertIndexRange(index);
264
+ return Field(this.store.getNode(index, level) ?? this.zeroes[level]);
265
+ }
266
+
267
+ /**
268
+ * Returns the root of the [Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree).
269
+ * @returns The root of the Merkle Tree.
270
+ */
271
+ public getRoot(): Field {
272
+ return this.getNode(AbstractRollupMerkleTree.HEIGHT - 1, 0n).toConstant();
273
+ }
274
+
275
+ // private in interface
276
+ private setNode(level: number, index: bigint, value: Field) {
277
+ this.store.setNode(index, level, value.toBigInt());
278
+ }
279
+
280
+ /**
281
+ * Sets the value of a leaf node at a given index to a given value.
282
+ * @param index Position of the leaf node.
283
+ * @param leaf New value.
284
+ */
285
+ public setLeaf(index: bigint, leaf: Field) {
286
+ this.assertIndexRange(index);
287
+
288
+ this.setNode(0, index, leaf);
289
+ let currentIndex = index;
290
+ for (let level = 1; level < AbstractRollupMerkleTree.HEIGHT; level += 1) {
291
+ currentIndex /= 2n;
292
+
293
+ const left = this.getNode(level - 1, currentIndex * 2n);
294
+ const right = this.getNode(level - 1, currentIndex * 2n + 1n);
295
+
296
+ this.setNode(level, currentIndex, Poseidon.hash([left, right]));
297
+ }
298
+ }
299
+
300
+ public setLeaves(updates: { index: bigint; leaf: Field }[]) {
301
+ updates.forEach(({ index }) => this.assertIndexRange(index));
302
+
303
+ type Change = { level: number; index: bigint; value: Field };
304
+ const changes: Change[] = [];
305
+
306
+ // We have to reverse here, because uniqBy only takes the first occurrence of every entry,
307
+ // but we need the last one (since that semantically overwrites the previous one,
308
+ // so we can ignore it)
309
+ let levelChanges = uniqBy(updates.reverse(), "index")
310
+ // we can assume no index is in this list twice, so we don't care about the 0 case
311
+ // This is in reverse order, so its a queue
312
+ .sort((a, b) => (a.index < b.index ? 1 : -1));
313
+
314
+ changes.push(
315
+ ...levelChanges
316
+ .map(({ leaf, index }) => ({
317
+ level: 0,
318
+ index,
319
+ value: leaf,
320
+ }))
321
+ .reverse()
322
+ );
323
+
324
+ for (let level = 1; level < AbstractRollupMerkleTree.HEIGHT; level += 1) {
325
+ const nextLevelChanges: typeof levelChanges = [];
326
+ while (levelChanges.length > 0) {
327
+ const node = levelChanges.pop()!;
328
+
329
+ let newNode;
330
+ if (node.index % 2n === 0n) {
331
+ let sibling;
332
+ const potentialSibling = levelChanges.at(-1);
333
+ if (
334
+ potentialSibling !== undefined &&
335
+ potentialSibling.index === node.index + 1n
336
+ ) {
337
+ sibling = potentialSibling.leaf;
338
+ levelChanges.pop();
339
+ } else {
340
+ sibling = Field(this.getNode(level - 1, node.index + 1n));
341
+ }
342
+ newNode = Poseidon.hash([node.leaf, sibling]);
343
+ } else {
344
+ const sibling = Field(this.getNode(level - 1, node.index - 1n));
345
+ newNode = Poseidon.hash([sibling, node.leaf]);
346
+ }
347
+
348
+ const nextLevelIndex = node.index / 2n;
349
+ changes.push({ level, index: nextLevelIndex, value: newNode });
350
+ nextLevelChanges.push({ index: nextLevelIndex, leaf: newNode });
351
+ }
352
+
353
+ levelChanges = nextLevelChanges.reverse();
354
+ }
355
+
356
+ changes.forEach(({ level, index, value }) => {
357
+ this.setNode(level, index, value);
358
+ });
359
+ }
360
+
361
+ /**
362
+ * Returns the witness (also known as
363
+ * [Merkle Proof or Merkle Witness](https://computersciencewiki.org/index.php/Merkle_proof))
364
+ * for the leaf at the given index.
365
+ * @param index Position of the leaf node.
366
+ * @returns The witness that belongs to the leaf.
367
+ */
368
+ public getWitness(index: bigint): RollupMerkleWitness {
369
+ this.assertIndexRange(index);
370
+
371
+ const path = [];
372
+ const isLefts = [];
373
+ let currentIndex = index;
374
+ for (
375
+ let level = 0;
376
+ level < AbstractRollupMerkleTree.HEIGHT - 1;
377
+ level += 1
378
+ ) {
379
+ const isLeft = currentIndex % 2n === 0n;
380
+ const sibling = this.getNode(
381
+ level,
382
+ isLeft ? currentIndex + 1n : currentIndex - 1n
383
+ );
384
+ isLefts.push(Bool(isLeft));
385
+ path.push(sibling);
386
+ currentIndex /= 2n;
387
+ }
388
+ return new RollupMerkleWitness({
389
+ isLeft: isLefts,
390
+ path,
391
+ });
392
+ }
393
+
394
+ // TODO: should this take an optional offset? should it fail if the array is too long?
395
+ /**
396
+ * Fills all leaves of the tree.
397
+ * @param leaves Values to fill the leaves with.
398
+ */
399
+ public fill(leaves: Field[]) {
400
+ leaves.forEach((value, index) => {
401
+ this.setLeaf(BigInt(index), value);
402
+ });
403
+ }
404
+
405
+ /**
406
+ * Returns the amount of leaf nodes.
407
+ * @returns Amount of leaf nodes.
408
+ */
409
+ public get leafCount(): bigint {
410
+ return AbstractRollupMerkleTree.leafCount;
411
+ }
412
+ };
413
+ }
414
+
415
+ export class RollupMerkleTree extends createMerkleTree(256) {}
416
+ export class RollupMerkleTreeWitness extends RollupMerkleTree.WITNESS {}
417
+
418
+ /**
419
+ * More efficient version of `maybeSwapBad` which
420
+ * reuses an intermediate variable
421
+ */
422
+ export function maybeSwap(b: Bool, x: Field, y: Field): [Field, Field] {
423
+ const m = b.toField().mul(x.sub(y)); // b*(x - y)
424
+ const x1 = y.add(m); // y + b*(x - y)
425
+ const y2 = x.sub(m); // x - b*(x - y) = x + b*(y - x)
426
+ return [x1, y2];
427
+ }
package/src/types.ts CHANGED
@@ -1,17 +1,58 @@
1
1
  // allows to reference interfaces as 'classes' rather than instances
2
+ import { Bool, DynamicProof, Field, Proof, ProofBase, PublicKey } from "o1js";
3
+
2
4
  export type TypedClass<Class> = new (...args: any[]) => Class;
3
5
 
6
+ export type UnTypedClass = new (...args: any[]) => unknown;
7
+
4
8
  /**
5
9
  * Using simple `keyof Target` would result into the key
6
10
  * being `string | number | symbol`, but we want just a `string`
7
11
  */
8
12
  export type StringKeyOf<Target extends object> = Extract<keyof Target, string> &
9
13
  string;
10
- // export type StringKeyOf<Target extends object> = keyof Target
11
14
 
12
15
  /**
13
16
  * Utility type to infer element type from an array type
14
17
  */
15
18
  export type ArrayElement<ArrayType extends readonly unknown[]> =
16
- // eslint-disable-next-line putout/putout
17
19
  ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
20
+
21
+ /**
22
+ * Transforms X | Y => X & Y
23
+ */
24
+ export type UnionToIntersection<Union> = (
25
+ Union extends any ? (x: Union) => void : never
26
+ ) extends (x: infer Intersection) => void
27
+ ? Intersection
28
+ : never;
29
+
30
+ export type MergeObjects<Input extends Record<string, unknown>> =
31
+ UnionToIntersection<Input[keyof Input]>;
32
+
33
+ export type OmitKeys<Record, Keys> = {
34
+ [Key in keyof Record as Key extends Keys ? never : Key]: Record[Key];
35
+ };
36
+
37
+ // Because Publickey.empty() is not usable in combination with real
38
+ // cryptographic operations because it's group evaluation isn't defined in Fp,
39
+ // we use some other arbitrary point which we treat as "empty" in our circuits
40
+ // other arbitrary point
41
+ export const EMPTY_PUBLICKEY_X = Field(4600);
42
+ export const EMPTY_PUBLICKEY = PublicKey.fromObject({
43
+ x: EMPTY_PUBLICKEY_X,
44
+ isOdd: Bool(true),
45
+ });
46
+
47
+ export type OverwriteObjectType<Base, New> = {
48
+ [Key in keyof Base]: Key extends keyof New ? New[Key] : Base[Key];
49
+ } & New;
50
+
51
+ export type InferProofBase<
52
+ ProofType extends Proof<any, any> | DynamicProof<any, any>,
53
+ > =
54
+ ProofType extends Proof<infer PI, infer PO>
55
+ ? ProofBase<PI, PO>
56
+ : ProofType extends DynamicProof<infer PI, infer PO>
57
+ ? ProofBase<PI, PO>
58
+ : undefined;