@proto-kit/module 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 (155) hide show
  1. package/dist/factories/MethodIdFactory.d.ts +6 -6
  2. package/dist/factories/MethodIdFactory.d.ts.map +1 -1
  3. package/dist/factories/MethodIdFactory.js +10 -34
  4. package/dist/factories/MethodIdFactory.js.map +1 -0
  5. package/dist/index.d.ts +4 -7
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +5 -7
  8. package/dist/index.js.map +1 -0
  9. package/dist/messages/OutgoingMessage.d.ts +96 -0
  10. package/dist/messages/OutgoingMessage.d.ts.map +1 -0
  11. package/dist/messages/OutgoingMessage.js +68 -0
  12. package/dist/messages/OutgoingMessage.js.map +1 -0
  13. package/dist/messages/OutgoingMessages.d.ts +231 -0
  14. package/dist/messages/OutgoingMessages.d.ts.map +1 -0
  15. package/dist/messages/OutgoingMessages.js +67 -0
  16. package/dist/messages/OutgoingMessages.js.map +1 -0
  17. package/dist/method/MethodParameterEncoder.d.ts +26 -0
  18. package/dist/method/MethodParameterEncoder.d.ts.map +1 -0
  19. package/dist/method/MethodParameterEncoder.js +169 -0
  20. package/dist/method/MethodParameterEncoder.js.map +1 -0
  21. package/dist/method/runtimeMethod.d.ts +21 -5
  22. package/dist/method/runtimeMethod.d.ts.map +1 -1
  23. package/dist/method/runtimeMethod.js +69 -25
  24. package/dist/method/runtimeMethod.js.map +1 -0
  25. package/dist/module/decorator.js +1 -0
  26. package/dist/module/decorator.js.map +1 -0
  27. package/dist/runtime/MethodIdResolver.d.ts +10 -8
  28. package/dist/runtime/MethodIdResolver.d.ts.map +1 -1
  29. package/dist/runtime/MethodIdResolver.js +75 -33
  30. package/dist/runtime/MethodIdResolver.js.map +1 -0
  31. package/dist/runtime/Runtime.d.ts +20 -26
  32. package/dist/runtime/Runtime.d.ts.map +1 -1
  33. package/dist/runtime/Runtime.js +117 -62
  34. package/dist/runtime/Runtime.js.map +1 -0
  35. package/dist/runtime/RuntimeEnvironment.d.ts +10 -0
  36. package/dist/runtime/RuntimeEnvironment.d.ts.map +1 -0
  37. package/dist/runtime/RuntimeEnvironment.js +2 -0
  38. package/dist/runtime/RuntimeEnvironment.js.map +1 -0
  39. package/dist/runtime/RuntimeModule.d.ts +18 -15
  40. package/dist/runtime/RuntimeModule.d.ts.map +1 -1
  41. package/dist/runtime/RuntimeModule.js +33 -8
  42. package/dist/runtime/RuntimeModule.js.map +1 -0
  43. package/dist/state/InMemoryStateService.d.ts +11 -10
  44. package/dist/state/InMemoryStateService.d.ts.map +1 -1
  45. package/dist/state/InMemoryStateService.js +11 -8
  46. package/dist/state/InMemoryStateService.js.map +1 -0
  47. package/dist/state/decorator.d.ts.map +1 -1
  48. package/dist/state/decorator.js +2 -4
  49. package/dist/state/decorator.js.map +1 -0
  50. package/dist/testing/TestingRuntime.d.ts +8 -0
  51. package/dist/testing/TestingRuntime.d.ts.map +1 -0
  52. package/dist/testing/TestingRuntime.js +31 -0
  53. package/dist/testing/TestingRuntime.js.map +1 -0
  54. package/jest.config.cjs +12 -1
  55. package/package.json +9 -9
  56. package/src/factories/MethodIdFactory.ts +10 -17
  57. package/src/index.ts +4 -4
  58. package/src/messages/OutgoingMessages.ts +124 -0
  59. package/src/method/MethodParameterEncoder.ts +262 -0
  60. package/src/method/runtimeMethod.ts +131 -33
  61. package/src/runtime/MethodIdResolver.ts +85 -46
  62. package/src/runtime/Runtime.ts +187 -96
  63. package/src/runtime/RuntimeEnvironment.ts +16 -0
  64. package/src/runtime/RuntimeModule.ts +58 -27
  65. package/src/state/InMemoryStateService.ts +14 -14
  66. package/test/Runtime.test.ts +68 -42
  67. package/test/TestingRuntime.ts +43 -0
  68. package/test/messages/message.test.ts +42 -0
  69. package/test/method/MethodParameterEncoder.test.ts +124 -0
  70. package/test/method/runtimeMethod-fail.test.ts +53 -0
  71. package/{src/method/decorator.test.ts → test/method/runtimeMethod.test.ts} +3 -3
  72. package/test/modules/Admin.ts +4 -4
  73. package/test/modules/Balances.test.ts +88 -79
  74. package/test/modules/Balances.ts +15 -21
  75. package/test/modules/{methodId.test.ts → MethodIdResolver.test.ts} +24 -35
  76. package/test/modules/State.test.ts +46 -53
  77. package/test/runtimeMethod.test.ts +192 -20
  78. package/test/tsconfig.json +7 -0
  79. package/tsconfig.json +2 -2
  80. package/LICENSE.md +0 -201
  81. package/dist/method/MethodParameterDecoder.d.ts +0 -22
  82. package/dist/method/MethodParameterDecoder.d.ts.map +0 -1
  83. package/dist/method/MethodParameterDecoder.js +0 -33
  84. package/dist/method/RuntimeMethodExecutionContext.d.ts +0 -57
  85. package/dist/method/RuntimeMethodExecutionContext.d.ts.map +0 -1
  86. package/dist/method/RuntimeMethodExecutionContext.js +0 -92
  87. package/dist/method/assert.d.ts +0 -12
  88. package/dist/method/assert.d.ts.map +0 -1
  89. package/dist/method/assert.js +0 -23
  90. package/dist/module/src/factories/MethodIdFactory.d.ts +0 -9
  91. package/dist/module/src/factories/MethodIdFactory.d.ts.map +0 -1
  92. package/dist/module/src/factories/MethodIdFactory.js +0 -36
  93. package/dist/module/src/index.d.ts +0 -11
  94. package/dist/module/src/index.d.ts.map +0 -1
  95. package/dist/module/src/index.js +0 -10
  96. package/dist/module/src/method/MethodParameterDecoder.d.ts +0 -22
  97. package/dist/module/src/method/MethodParameterDecoder.d.ts.map +0 -1
  98. package/dist/module/src/method/MethodParameterDecoder.js +0 -33
  99. package/dist/module/src/method/runtimeMethod.d.ts +0 -19
  100. package/dist/module/src/method/runtimeMethod.d.ts.map +0 -1
  101. package/dist/module/src/method/runtimeMethod.js +0 -123
  102. package/dist/module/src/module/decorator.d.ts +0 -8
  103. package/dist/module/src/module/decorator.d.ts.map +0 -1
  104. package/dist/module/src/module/decorator.js +0 -15
  105. package/dist/module/src/runtime/MethodIdResolver.d.ts +0 -18
  106. package/dist/module/src/runtime/MethodIdResolver.d.ts.map +0 -1
  107. package/dist/module/src/runtime/MethodIdResolver.js +0 -50
  108. package/dist/module/src/runtime/Runtime.d.ts +0 -72
  109. package/dist/module/src/runtime/Runtime.d.ts.map +0 -1
  110. package/dist/module/src/runtime/Runtime.js +0 -184
  111. package/dist/module/src/runtime/RuntimeModule.d.ts +0 -35
  112. package/dist/module/src/runtime/RuntimeModule.d.ts.map +0 -1
  113. package/dist/module/src/runtime/RuntimeModule.js +0 -56
  114. package/dist/module/src/state/InMemoryStateService.d.ts +0 -11
  115. package/dist/module/src/state/InMemoryStateService.d.ts.map +0 -1
  116. package/dist/module/src/state/InMemoryStateService.js +0 -21
  117. package/dist/module/src/state/decorator.d.ts +0 -7
  118. package/dist/module/src/state/decorator.d.ts.map +0 -1
  119. package/dist/module/src/state/decorator.js +0 -42
  120. package/dist/protocol/src/model/Option.d.ts +0 -98
  121. package/dist/protocol/src/model/Option.d.ts.map +0 -1
  122. package/dist/protocol/src/model/Option.js +0 -98
  123. package/dist/protocol/src/model/StateTransition.d.ts +0 -96
  124. package/dist/protocol/src/model/StateTransition.d.ts.map +0 -1
  125. package/dist/protocol/src/model/StateTransition.js +0 -65
  126. package/dist/protocol/src/model/network/NetworkState.d.ts +0 -64
  127. package/dist/protocol/src/model/network/NetworkState.d.ts.map +0 -1
  128. package/dist/protocol/src/model/network/NetworkState.js +0 -12
  129. package/dist/protocol/src/model/transaction/ProtocolTransaction.d.ts +0 -70
  130. package/dist/protocol/src/model/transaction/ProtocolTransaction.d.ts.map +0 -1
  131. package/dist/protocol/src/model/transaction/ProtocolTransaction.js +0 -18
  132. package/dist/protocol/src/model/transaction/RuntimeTransaction.d.ts +0 -63
  133. package/dist/protocol/src/model/transaction/RuntimeTransaction.d.ts.map +0 -1
  134. package/dist/protocol/src/model/transaction/RuntimeTransaction.js +0 -29
  135. package/dist/protocol/src/state/assert/assert.d.ts +0 -12
  136. package/dist/protocol/src/state/assert/assert.d.ts.map +0 -1
  137. package/dist/protocol/src/state/assert/assert.js +0 -23
  138. package/dist/protocol/src/state/context/RuntimeMethodExecutionContext.d.ts +0 -60
  139. package/dist/protocol/src/state/context/RuntimeMethodExecutionContext.d.ts.map +0 -1
  140. package/dist/protocol/src/state/context/RuntimeMethodExecutionContext.js +0 -105
  141. package/dist/state/State.d.ts +0 -65
  142. package/dist/state/State.d.ts.map +0 -1
  143. package/dist/state/State.js +0 -114
  144. package/dist/state/StateMap.d.ts +0 -37
  145. package/dist/state/StateMap.d.ts.map +0 -1
  146. package/dist/state/StateMap.js +0 -56
  147. package/dist/state/StateServiceProvider.d.ts +0 -10
  148. package/dist/state/StateServiceProvider.d.ts.map +0 -1
  149. package/dist/state/StateServiceProvider.js +0 -34
  150. package/src/method/MethodParameterDecoder.ts +0 -70
  151. package/src/state/decorator.ts +0 -63
  152. package/test/state/MerkleTree.test.ts +0 -95
  153. package/test/state/MockAsyncMerkleStore.ts +0 -28
  154. package/test/transaction.test.ts +0 -82
  155. package/tsconfig.test.json +0 -9
@@ -1,34 +1,54 @@
1
- // eslint-disable-next-line max-len
2
- /* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment,max-lines */
3
- import { Experimental } from "snarkyjs";
4
- import { DependencyContainer, injectable } from "tsyringe";
1
+ /* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument */
2
+ import { ZkProgram } from "o1js";
3
+ import { container, DependencyContainer, injectable } from "tsyringe";
5
4
  import {
6
5
  StringKeyOf,
7
6
  ModuleContainer,
8
- ModulesConfig,
9
7
  ModulesRecord,
10
8
  TypedClass,
11
9
  ZkProgrammable,
12
10
  PlainZkProgram,
13
- WithZkProgrammable,
14
11
  AreProofsEnabled,
12
+ ChildContainerProvider,
13
+ CompilableModule,
14
+ CompileRegistry,
15
15
  } from "@proto-kit/common";
16
16
  import {
17
17
  MethodPublicOutput,
18
18
  StateServiceProvider,
19
- StateService,
19
+ SimpleAsyncStateService,
20
+ RuntimeMethodExecutionContext,
21
+ RuntimeTransaction,
22
+ NetworkState,
20
23
  } from "@proto-kit/protocol";
21
24
 
22
25
  import {
23
26
  combineMethodName,
24
27
  isRuntimeMethod,
28
+ runtimeMethodTypeMetadataKey,
25
29
  toWrappedMethod,
26
- WrappedMethod,
30
+ AsyncWrappedMethod,
27
31
  } from "../method/runtimeMethod";
28
32
  import { MethodIdFactory } from "../factories/MethodIdFactory";
29
33
 
30
34
  import { RuntimeModule } from "./RuntimeModule";
31
35
  import { MethodIdResolver } from "./MethodIdResolver";
36
+ import { RuntimeEnvironment } from "./RuntimeEnvironment";
37
+
38
+ export function getAllPropertyNames(obj: any) {
39
+ let currentPrototype: any | undefined = obj;
40
+ let keys: (string | symbol)[] = [];
41
+ // if primitive (primitives still have keys) skip the first iteration
42
+ if (!(obj instanceof Object)) {
43
+ currentPrototype = Object.getPrototypeOf(obj);
44
+ }
45
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
46
+ while (currentPrototype) {
47
+ keys = keys.concat(Reflect.ownKeys(currentPrototype));
48
+ currentPrototype = Object.getPrototypeOf(currentPrototype);
49
+ }
50
+ return keys;
51
+ }
32
52
 
33
53
  /**
34
54
  * Record of modules accepted by the Runtime module container.
@@ -45,69 +65,56 @@ const errors = {
45
65
  new Error(`Unable to find method with id ${methodKey}`),
46
66
  };
47
67
 
48
- /**
49
- * Definition / required arguments for the Runtime class
50
- */
51
- export interface RuntimeDefinition<Modules extends RuntimeModulesRecord> {
52
- /**
53
- * @deprecated
54
- */
55
- state?: StateService;
56
- modules: Modules;
57
- config?: ModulesConfig<Modules>;
58
- }
59
-
60
68
  export class RuntimeZkProgrammable<
61
- Modules extends RuntimeModulesRecord
69
+ Modules extends RuntimeModulesRecord,
62
70
  > extends ZkProgrammable<undefined, MethodPublicOutput> {
63
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
64
71
  public constructor(public runtime: Runtime<Modules>) {
65
72
  super();
66
73
  }
67
74
 
68
- public get appChain() {
69
- return this.runtime.appChain;
75
+ public get areProofsEnabled() {
76
+ return this.runtime.areProofsEnabled;
70
77
  }
71
78
 
72
- public zkProgramFactory(): PlainZkProgram<undefined, MethodPublicOutput> {
79
+ public zkProgramFactory(): PlainZkProgram<undefined, MethodPublicOutput>[] {
73
80
  type Methods = Record<
74
81
  string,
75
82
  {
76
83
  privateInputs: any;
77
- method: WrappedMethod;
84
+ method: AsyncWrappedMethod;
78
85
  }
79
86
  >;
80
87
  // We need to use explicit type annotations here,
81
88
  // therefore we can't use destructuring
82
- // eslint-disable-next-line max-len
83
- // eslint-disable-next-line @typescript-eslint/no-use-before-define,prefer-destructuring,putout/putout
89
+
90
+ // eslint-disable-next-line prefer-destructuring
84
91
  const runtime: Runtime<Modules> = this.runtime;
85
92
 
93
+ const MAXIMUM_METHODS_PER_ZK_PROGRAM = 8;
94
+
86
95
  const runtimeMethods = runtime.runtimeModuleNames.reduce<Methods>(
87
96
  (allMethods, runtimeModuleName) => {
88
- runtime.isValidModuleName(
89
- runtime.definition.modules,
90
- runtimeModuleName
91
- );
97
+ runtime.isValidModuleName(runtime.definition, runtimeModuleName);
92
98
 
93
99
  /**
94
100
  * Couldnt find a better way to circumvent the type assertion
95
101
  * regarding resolving only known modules. We assert in the line above
96
102
  * but we cast it to any anyways to satisfy the proof system.
97
103
  */
98
- // eslint-disable-next-line max-len
104
+
99
105
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
100
106
  const runtimeModule = runtime.resolve(runtimeModuleName as any);
101
107
 
102
- // eslint-disable-next-line max-len
103
108
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
104
109
  const modulePrototype = Object.getPrototypeOf(runtimeModule) as Record<
105
110
  string,
106
- (...args: unknown[]) => unknown
111
+ // Technically not all methods have to be async, but for this context it's ok
112
+ (...args: unknown[]) => Promise<unknown>
107
113
  >;
108
114
 
109
- const modulePrototypeMethods =
110
- Object.getOwnPropertyNames(modulePrototype);
115
+ const modulePrototypeMethods = getAllPropertyNames(runtimeModule).map(
116
+ (method) => method.toString()
117
+ );
111
118
 
112
119
  const moduleMethods = modulePrototypeMethods.reduce<Methods>(
113
120
  (allModuleMethods, methodName) => {
@@ -117,14 +124,17 @@ export class RuntimeZkProgrammable<
117
124
  methodName
118
125
  );
119
126
  const method = modulePrototype[methodName];
120
- const wrappedMethod = Reflect.apply(
121
- toWrappedMethod,
127
+ const invocationType = Reflect.getMetadata(
128
+ runtimeMethodTypeMetadataKey,
122
129
  runtimeModule,
123
- [methodName, method]
130
+ methodName
124
131
  );
125
132
 
126
- // eslint-disable-next-line no-warning-comments
127
- // TODO: find out how to import the Tuple type
133
+ const wrappedMethod: AsyncWrappedMethod = Reflect.apply(
134
+ toWrappedMethod,
135
+ runtimeModule,
136
+ [methodName, method, { invocationType }]
137
+ );
128
138
 
129
139
  const privateInputs = Reflect.getMetadata(
130
140
  "design:paramtypes",
@@ -156,30 +166,100 @@ export class RuntimeZkProgrammable<
156
166
  );
157
167
 
158
168
  const sortedRuntimeMethods = Object.fromEntries(
159
- // eslint-disable-next-line @typescript-eslint/require-array-sort-compare
160
169
  Object.entries(runtimeMethods).sort()
161
170
  );
162
171
 
163
- const program = Experimental.ZkProgram({
164
- publicOutput: MethodPublicOutput,
165
- methods: sortedRuntimeMethods,
166
- });
167
-
168
- const SelfProof = Experimental.ZkProgram.Proof(program);
169
-
170
- const methods = Object.keys(sortedRuntimeMethods).reduce<
171
- Record<string, any>
172
- >((boundMethods, methodName) => {
173
- boundMethods[methodName] = program[methodName].bind(program);
174
- return boundMethods;
175
- }, {});
176
-
177
- return {
178
- compile: program.compile.bind(program),
179
- verify: program.verify.bind(program),
180
- Proof: SelfProof,
181
- methods,
172
+ const splitRuntimeMethods = () => {
173
+ const buckets: Array<
174
+ Record<
175
+ string,
176
+ {
177
+ privateInputs: any;
178
+ method: AsyncWrappedMethod;
179
+ }
180
+ >
181
+ > = [];
182
+ Object.entries(sortedRuntimeMethods).forEach(
183
+ async ([methodName, method]) => {
184
+ let methodAdded = false;
185
+ for (const bucket of buckets) {
186
+ if (buckets.length === 0) {
187
+ const record: Record<
188
+ string,
189
+ {
190
+ privateInputs: any;
191
+ method: AsyncWrappedMethod;
192
+ }
193
+ > = {};
194
+ record[methodName] = method;
195
+ buckets.push(record);
196
+ methodAdded = true;
197
+ break;
198
+ } else if (
199
+ Object.keys(bucket).length <=
200
+ MAXIMUM_METHODS_PER_ZK_PROGRAM - 1
201
+ ) {
202
+ bucket[methodName] = method;
203
+ methodAdded = true;
204
+ break;
205
+ }
206
+ }
207
+ if (!methodAdded) {
208
+ const record: Record<
209
+ string,
210
+ {
211
+ privateInputs: any;
212
+ method: AsyncWrappedMethod;
213
+ }
214
+ > = {};
215
+ record[methodName] = method;
216
+ buckets.push(record);
217
+ }
218
+ }
219
+ );
220
+ return buckets;
182
221
  };
222
+
223
+ return splitRuntimeMethods().map((bucket, index) => {
224
+ const name = `RuntimeProgram-${index}`;
225
+ const wrappedBucket = Object.fromEntries(
226
+ Object.entries(bucket).map(([methodName, methodDef]) => [
227
+ methodName,
228
+ {
229
+ privateInputs: methodDef.privateInputs,
230
+ method: async (...args: any[]) => {
231
+ const publicOutput = await methodDef.method(...args);
232
+ return { publicOutput };
233
+ },
234
+ },
235
+ ])
236
+ );
237
+
238
+ const program = ZkProgram({
239
+ name,
240
+ publicOutput: MethodPublicOutput,
241
+ methods: wrappedBucket,
242
+ });
243
+
244
+ const SelfProof = ZkProgram.Proof(program);
245
+
246
+ const methods = Object.keys(bucket).reduce<Record<string, any>>(
247
+ (boundMethods, methodName) => {
248
+ boundMethods[methodName] = program[methodName].bind(program);
249
+ return boundMethods;
250
+ },
251
+ {}
252
+ );
253
+
254
+ return {
255
+ name,
256
+ compile: program.compile.bind(program),
257
+ verify: program.verify.bind(program),
258
+ analyzeMethods: program.analyzeMethods.bind(program),
259
+ Proof: SelfProof,
260
+ methods,
261
+ };
262
+ });
183
263
  }
184
264
  }
185
265
 
@@ -190,56 +270,59 @@ export class RuntimeZkProgrammable<
190
270
  @injectable()
191
271
  export class Runtime<Modules extends RuntimeModulesRecord>
192
272
  extends ModuleContainer<Modules>
193
- implements WithZkProgrammable<undefined, MethodPublicOutput>
273
+ implements RuntimeEnvironment, CompilableModule
194
274
  {
195
275
  public static from<Modules extends RuntimeModulesRecord>(
196
- definition: RuntimeDefinition<Modules>
197
- ) {
198
- return new Runtime(definition);
276
+ definition: Modules
277
+ ): TypedClass<Runtime<Modules>> {
278
+ return class RuntimeScoped extends Runtime<Modules> {
279
+ public constructor() {
280
+ super(definition);
281
+ }
282
+ };
199
283
  }
200
284
 
201
285
  // runtime modules composed into a ZkProgram
202
- public program?: ReturnType<typeof Experimental.ZkProgram>;
286
+ public program?: ReturnType<typeof ZkProgram>;
203
287
 
204
- public definition: RuntimeDefinition<Modules>;
288
+ // No idea why we have to do this, but if we don't re-define it here,
289
+ // js can't access it from the superclass somehow
290
+ public definition: Modules;
205
291
 
206
292
  public zkProgrammable: ZkProgrammable<undefined, MethodPublicOutput>;
207
293
 
208
- private readonly stateServiceProviderInstance = new StateServiceProvider(
209
- // eslint-disable-next-line etc/no-deprecated
210
- this.definition.state
211
- );
212
-
213
294
  /**
214
295
  * Creates a new Runtime from the provided config
215
296
  *
216
297
  * @param modules - Configuration object for the constructed Runtime
217
298
  */
218
- public constructor(definition: RuntimeDefinition<Modules>) {
299
+ public constructor(definition: Modules) {
219
300
  super(definition);
220
301
  this.definition = definition;
221
302
  this.zkProgrammable = new RuntimeZkProgrammable<Modules>(this);
222
303
  }
223
304
 
224
- // eslint-disable-next-line no-warning-comments
225
305
  // TODO Remove after changing DFs to type-based approach
226
- public start() {
227
- this.registerValue({
228
- Runtime: this,
229
- });
230
- this.registerDependencyFactories([MethodIdFactory]);
231
- }
306
+ public create(childContainerProvider: ChildContainerProvider) {
307
+ super.create(childContainerProvider);
232
308
 
233
- public get appChain(): AreProofsEnabled | undefined {
234
- return this.container.resolve<AreProofsEnabled>("AppChain");
309
+ this.useDependencyFactory(MethodIdFactory);
235
310
  }
236
311
 
237
- public get stateService(): StateService {
238
- return this.stateServiceProviderInstance.stateService;
312
+ public get areProofsEnabled(): AreProofsEnabled | undefined {
313
+ return this.container.resolve<AreProofsEnabled>("AreProofsEnabled");
239
314
  }
240
315
 
241
316
  public get stateServiceProvider(): StateServiceProvider {
242
- return this.stateServiceProviderInstance;
317
+ return this.container.resolve<StateServiceProvider>("StateServiceProvider");
318
+ }
319
+
320
+ public get stateService(): SimpleAsyncStateService {
321
+ return this.stateServiceProvider.stateService;
322
+ }
323
+
324
+ public get methodIdResolver(): MethodIdResolver {
325
+ return this.container.resolve<MethodIdResolver>("MethodIdResolver");
243
326
  }
244
327
 
245
328
  /**
@@ -255,28 +338,26 @@ export class Runtime<Modules extends RuntimeModulesRecord>
255
338
  */
256
339
  public getMethodById(
257
340
  methodId: bigint
258
- ): ((...args: unknown[]) => unknown) | undefined {
259
- const methodDescriptor = this.container
260
- .resolve<MethodIdResolver>("MethodIdResolver")
261
- .getMethodNameFromId(methodId);
341
+ ): ((...args: unknown[]) => Promise<unknown>) | undefined {
342
+ const methodDescriptor =
343
+ this.methodIdResolver.getMethodNameFromId(methodId);
262
344
 
263
345
  if (methodDescriptor === undefined) {
264
346
  return undefined;
265
347
  }
266
348
  const [moduleName, methodName] = methodDescriptor;
267
349
 
268
- this.isValidModuleName(this.definition.modules, moduleName);
350
+ this.assertIsValidModuleName(moduleName);
269
351
  const module = this.resolve(moduleName);
270
352
 
271
- // eslint-disable-next-line max-len
272
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions,@typescript-eslint/no-unsafe-member-access
353
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
273
354
  const method = (module as any)[methodName];
274
355
  if (method === undefined) {
275
356
  throw errors.methodNotFound(`${moduleName}.${methodName}`);
276
357
  }
277
358
 
278
359
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
279
- return (method as (...args: unknown[]) => unknown).bind(module);
360
+ return (method as (...args: unknown[]) => Promise<unknown>).bind(module);
280
361
  }
281
362
 
282
363
  /**
@@ -291,7 +372,7 @@ export class Runtime<Modules extends RuntimeModulesRecord>
291
372
  containedModule: InstanceType<Modules[StringKeyOf<Modules>]>
292
373
  ) {
293
374
  containedModule.name = moduleName;
294
- containedModule.runtime = this;
375
+ containedModule.parent = this;
295
376
 
296
377
  super.decorateModule(moduleName, containedModule);
297
378
  }
@@ -300,6 +381,16 @@ export class Runtime<Modules extends RuntimeModulesRecord>
300
381
  * @returns A list of names of all the registered module names
301
382
  */
302
383
  public get runtimeModuleNames() {
303
- return Object.keys(this.definition.modules);
384
+ return this.moduleNames;
385
+ }
386
+
387
+ public async compile(registry: CompileRegistry) {
388
+ const context = container.resolve(RuntimeMethodExecutionContext);
389
+ context.setup({
390
+ transaction: RuntimeTransaction.dummyTransaction(),
391
+ networkState: NetworkState.empty(),
392
+ });
393
+ return await this.zkProgrammable.compile(registry);
304
394
  }
305
395
  }
396
+ /* eslint-enable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument */
@@ -0,0 +1,16 @@
1
+ import { AreProofsEnabled, WithZkProgrammable } from "@proto-kit/common";
2
+ import {
3
+ MethodPublicOutput,
4
+ SimpleAsyncStateService,
5
+ StateServiceProvider,
6
+ } from "@proto-kit/protocol";
7
+
8
+ import { MethodIdResolver } from "./MethodIdResolver";
9
+
10
+ export interface RuntimeEnvironment
11
+ extends WithZkProgrammable<undefined, MethodPublicOutput> {
12
+ get areProofsEnabled(): AreProofsEnabled | undefined;
13
+ get stateService(): SimpleAsyncStateService;
14
+ get stateServiceProvider(): StateServiceProvider;
15
+ get methodIdResolver(): MethodIdResolver;
16
+ }
@@ -1,41 +1,68 @@
1
- import { ConfigurableModule, Presets } from "@proto-kit/common";
1
+ import { ConfigurableModule, NoConfig, Presets } from "@proto-kit/common";
2
2
  import { container, injectable } from "tsyringe";
3
3
  import {
4
4
  NetworkState,
5
5
  RuntimeTransaction,
6
- StateService,
7
6
  RuntimeMethodExecutionContext,
8
7
  RuntimeMethodExecutionData,
8
+ RuntimeMethodExecutionDataStruct,
9
9
  } from "@proto-kit/protocol";
10
+ import { FlexibleProvablePure, Provable, Bool } from "o1js";
10
11
 
11
12
  import { runtimeMethodNamesMetadataKey } from "../method/runtimeMethod";
13
+ import {
14
+ OutgoingMessages,
15
+ OutgoingMessagesRecord,
16
+ } from "../messages/OutgoingMessages";
12
17
 
13
- import type {
14
- Runtime,
15
- RuntimeDefinition,
16
- RuntimeModulesRecord,
17
- } from "./Runtime";
18
+ import { RuntimeEnvironment } from "./RuntimeEnvironment";
18
19
 
19
20
  const errors = {
20
21
  inputDataNotSet: () => new Error("Input data for runtime execution not set"),
21
22
  };
22
23
 
23
- /**
24
- * This type exists to carry over certain runtime properties
25
- * to runtime modules, until we can inject them through DI.
26
- */
27
- export interface PartialRuntime
28
- extends Pick<Runtime<RuntimeModulesRecord>, "zkProgrammable"> {
29
- definition: Pick<RuntimeDefinition<RuntimeModulesRecord>, "state">;
24
+ type EventRecord = Record<string, FlexibleProvablePure<any>>;
25
+
26
+ type InferProvable<T extends FlexibleProvablePure<any>> =
27
+ T extends Provable<infer U> ? U : never;
28
+
29
+ export class RuntimeEvents<Events extends EventRecord> {
30
+ public constructor(private readonly events: Events) {}
31
+
32
+ public emitIf<Key extends keyof Events>(
33
+ condition: Bool,
34
+ eventName: Key,
35
+ event: InferProvable<Events[Key]>
36
+ ) {
37
+ if (this.events === undefined) {
38
+ throw new Error(
39
+ "'events' property not defined, make sure to define the event types on your runtimemodule"
40
+ );
41
+ }
42
+ const eventType: FlexibleProvablePure<any> = this.events[eventName];
43
+ if (typeof eventName !== "string") {
44
+ throw new Error("Only string");
45
+ }
46
+ return container
47
+ .resolve(RuntimeMethodExecutionContext)
48
+ .addEvent(eventType, event, eventName, condition);
49
+ }
30
50
 
31
- get stateService(): StateService;
51
+ public emit<Key extends keyof Events>(
52
+ eventName: Key,
53
+ event: InferProvable<Events[Key]>
54
+ ) {
55
+ this.emitIf(Bool(true), eventName, event);
56
+ }
32
57
  }
33
58
 
34
59
  /**
35
60
  * Base class for runtime modules providing the necessary utilities.
36
61
  */
37
62
  @injectable()
38
- export class RuntimeModule<Config> extends ConfigurableModule<Config> {
63
+ export class RuntimeModule<
64
+ Config = NoConfig,
65
+ > extends ConfigurableModule<Config> {
39
66
  public static presets: Presets<unknown> = {};
40
67
 
41
68
  /**
@@ -52,9 +79,11 @@ export class RuntimeModule<Config> extends ConfigurableModule<Config> {
52
79
 
53
80
  public name?: string;
54
81
 
55
- public test?: number;
82
+ public parent?: RuntimeEnvironment;
83
+
84
+ public events?: RuntimeEvents<any> = undefined;
56
85
 
57
- public runtime?: Runtime<RuntimeModulesRecord>;
86
+ public messages?: OutgoingMessages<OutgoingMessagesRecord> = undefined;
58
87
 
59
88
  public constructor() {
60
89
  super();
@@ -66,15 +95,17 @@ export class RuntimeModule<Config> extends ConfigurableModule<Config> {
66
95
  this.runtimeMethodNames = methodNames ?? [];
67
96
  }
68
97
 
69
- private getInputs(): RuntimeMethodExecutionData {
70
- const { input } = container.resolve<RuntimeMethodExecutionContext>(
71
- RuntimeMethodExecutionContext
72
- );
73
-
74
- if (input === undefined) {
75
- throw errors.inputDataNotSet();
76
- }
77
- return input;
98
+ public getInputs(): RuntimeMethodExecutionData {
99
+ return Provable.witness(RuntimeMethodExecutionDataStruct, () => {
100
+ const { input } = container.resolve<RuntimeMethodExecutionContext>(
101
+ RuntimeMethodExecutionContext
102
+ );
103
+ if (input === undefined) {
104
+ throw errors.inputDataNotSet();
105
+ }
106
+
107
+ return input;
108
+ });
78
109
  }
79
110
 
80
111
  public get transaction(): RuntimeTransaction {
@@ -1,23 +1,23 @@
1
- import { Field } from "snarkyjs";
2
- import { StateService } from "@proto-kit/protocol";
1
+ import { Field } from "o1js";
2
+ import { SimpleAsyncStateService } from "@proto-kit/protocol";
3
3
 
4
4
  /**
5
- * Naive implementation of a StateService for testing purposes
5
+ * Naive implementation of an in-memory variant of the StateService interface
6
6
  */
7
- export class InMemoryStateService implements StateService {
8
- public values: Record<string, Field[] | undefined> = {};
7
+ export class InMemoryStateService implements SimpleAsyncStateService {
8
+ /**
9
+ * This mapping container null values if the specific entry has been deleted.
10
+ * This is used by the CachedState service to keep track of deletions
11
+ */
12
+ public values: Record<string, Field[] | null> = {};
9
13
 
10
- public get(key: Field): Field[] | undefined {
11
- return this.values[key.toString()];
14
+ public async get(key: Field): Promise<Field[] | undefined> {
15
+ return this.values[key.toString()] ?? undefined;
12
16
  }
13
17
 
14
- public set(key: Field, value: Field[] | undefined) {
15
- if (
16
- value === undefined &&
17
- Object.prototype.hasOwnProperty.call(this.values, key.toString())
18
- ) {
19
- // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
20
- delete this.values[key.toString()];
18
+ public async set(key: Field, value: Field[] | undefined) {
19
+ if (value === undefined) {
20
+ this.values[key.toString()] = null;
21
21
  } else {
22
22
  this.values[key.toString()] = value;
23
23
  }