@proto-kit/common 0.1.1-develop.211 → 0.1.1-develop.2137

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