@proto-kit/module 0.1.1-develop.600 → 0.1.1-develop.833

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 (108) hide show
  1. package/LICENSE.md +201 -201
  2. package/dist/method/MethodParameterDecoder.d.ts +10 -10
  3. package/dist/method/MethodParameterDecoder.js +40 -40
  4. package/dist/method/MethodParameterEncoder.d.ts +15 -8
  5. package/dist/method/MethodParameterEncoder.d.ts.map +1 -1
  6. package/dist/method/MethodParameterEncoder.js +122 -48
  7. package/dist/method/runtimeMethod.d.ts +6 -5
  8. package/dist/method/runtimeMethod.d.ts.map +1 -1
  9. package/dist/method/runtimeMethod.js +13 -26
  10. package/dist/runtime/MethodIdResolver.d.ts +7 -0
  11. package/dist/runtime/MethodIdResolver.d.ts.map +1 -1
  12. package/dist/runtime/MethodIdResolver.js +35 -2
  13. package/dist/runtime/Runtime.d.ts +6 -5
  14. package/dist/runtime/Runtime.d.ts.map +1 -1
  15. package/dist/runtime/Runtime.js +29 -22
  16. package/dist/runtime/RuntimeEnvironment.d.ts +2 -2
  17. package/dist/runtime/RuntimeEnvironment.d.ts.map +1 -1
  18. package/dist/runtime/RuntimeModule.d.ts +2 -2
  19. package/dist/runtime/RuntimeModule.d.ts.map +1 -1
  20. package/dist/runtime/RuntimeModule.js +10 -8
  21. package/dist/src/factories/MethodIdFactory.d.ts +10 -0
  22. package/dist/src/factories/MethodIdFactory.d.ts.map +1 -0
  23. package/dist/src/factories/MethodIdFactory.js +10 -0
  24. package/dist/src/index.d.ts +11 -0
  25. package/dist/src/index.d.ts.map +1 -0
  26. package/dist/src/index.js +10 -0
  27. package/dist/src/method/MethodParameterEncoder.d.ts +22 -0
  28. package/dist/src/method/MethodParameterEncoder.d.ts.map +1 -0
  29. package/dist/src/method/MethodParameterEncoder.js +103 -0
  30. package/dist/src/method/runtimeMethod.d.ts +26 -0
  31. package/dist/src/method/runtimeMethod.d.ts.map +1 -0
  32. package/dist/src/method/runtimeMethod.js +164 -0
  33. package/dist/src/module/decorator.d.ts +8 -0
  34. package/dist/src/module/decorator.d.ts.map +1 -0
  35. package/dist/src/module/decorator.js +15 -0
  36. package/dist/src/runtime/MethodIdResolver.d.ts +20 -0
  37. package/dist/src/runtime/MethodIdResolver.d.ts.map +1 -0
  38. package/dist/src/runtime/MethodIdResolver.js +100 -0
  39. package/dist/src/runtime/Runtime.d.ts +71 -0
  40. package/dist/src/runtime/Runtime.d.ts.map +1 -0
  41. package/dist/src/runtime/Runtime.js +215 -0
  42. package/dist/src/runtime/RuntimeEnvironment.d.ts +10 -0
  43. package/dist/src/runtime/RuntimeEnvironment.d.ts.map +1 -0
  44. package/dist/src/runtime/RuntimeEnvironment.js +1 -0
  45. package/dist/src/runtime/RuntimeModule.d.ts +26 -0
  46. package/dist/src/runtime/RuntimeModule.d.ts.map +1 -0
  47. package/dist/src/runtime/RuntimeModule.js +85 -0
  48. package/dist/src/state/InMemoryStateService.d.ts +15 -0
  49. package/dist/src/state/InMemoryStateService.d.ts.map +1 -0
  50. package/dist/src/state/InMemoryStateService.js +28 -0
  51. package/dist/src/state/decorator.d.ts +7 -0
  52. package/dist/src/state/decorator.d.ts.map +1 -0
  53. package/dist/src/state/decorator.js +39 -0
  54. package/dist/state/InMemoryStateService.d.ts +10 -6
  55. package/dist/state/InMemoryStateService.d.ts.map +1 -1
  56. package/dist/state/InMemoryStateService.js +10 -8
  57. package/dist/state/decorator.d.ts.map +1 -1
  58. package/dist/state/decorator.js +0 -3
  59. package/dist/test/Runtime.test.d.ts +2 -0
  60. package/dist/test/Runtime.test.d.ts.map +1 -0
  61. package/dist/test/Runtime.test.js +24 -0
  62. package/dist/test/TestingRuntime.d.ts +7 -0
  63. package/dist/test/TestingRuntime.d.ts.map +1 -0
  64. package/dist/test/TestingRuntime.js +29 -0
  65. package/dist/test/method/runtimeMethod.test.d.ts +2 -0
  66. package/dist/test/method/runtimeMethod.test.d.ts.map +1 -0
  67. package/dist/test/method/runtimeMethod.test.js +30 -0
  68. package/dist/test/modules/Admin.d.ts +10 -0
  69. package/dist/test/modules/Admin.d.ts.map +1 -0
  70. package/dist/test/modules/Admin.js +29 -0
  71. package/dist/test/modules/Balances.d.ts +23 -0
  72. package/dist/test/modules/Balances.d.ts.map +1 -0
  73. package/dist/test/modules/Balances.js +98 -0
  74. package/dist/test/modules/Balances.test.d.ts +2 -0
  75. package/dist/test/modules/Balances.test.d.ts.map +1 -0
  76. package/dist/test/modules/Balances.test.js +201 -0
  77. package/dist/test/modules/MethodIdResolver.test.d.ts +2 -0
  78. package/dist/test/modules/MethodIdResolver.test.d.ts.map +1 -0
  79. package/dist/test/modules/MethodIdResolver.test.js +67 -0
  80. package/dist/test/modules/State.test.d.ts +2 -0
  81. package/dist/test/modules/State.test.d.ts.map +1 -0
  82. package/dist/test/modules/State.test.js +42 -0
  83. package/dist/test/runtimeMethod.test.d.ts +2 -0
  84. package/dist/test/runtimeMethod.test.d.ts.map +1 -0
  85. package/dist/test/runtimeMethod.test.js +50 -0
  86. package/package.json +5 -5
  87. package/src/method/MethodParameterEncoder.ts +192 -81
  88. package/src/method/runtimeMethod.ts +29 -44
  89. package/src/runtime/MethodIdResolver.ts +51 -1
  90. package/src/runtime/Runtime.ts +48 -29
  91. package/src/runtime/RuntimeEnvironment.ts +4 -7
  92. package/src/runtime/RuntimeModule.ts +13 -15
  93. package/src/state/InMemoryStateService.ts +13 -13
  94. package/src/state/decorator.ts +1 -3
  95. package/test/Runtime.test.ts +68 -41
  96. package/test/TestingRuntime.ts +45 -0
  97. package/test/method/MethodParameterEncoder.test.ts +152 -0
  98. package/{src/method/decorator.test.ts → test/method/runtimeMethod.test.ts} +2 -2
  99. package/test/modules/Admin.ts +3 -3
  100. package/test/modules/Balances.test.ts +57 -61
  101. package/test/modules/Balances.ts +15 -18
  102. package/test/modules/{methodId.test.ts → MethodIdResolver.test.ts} +14 -23
  103. package/test/modules/State.test.ts +41 -50
  104. package/test/runtimeMethod.test.ts +19 -32
  105. package/test/tsconfig.json +7 -0
  106. package/tsconfig.json +2 -2
  107. package/test/transaction.test.ts +0 -82
  108. package/tsconfig.test.json +0 -9
package/package.json CHANGED
@@ -2,15 +2,15 @@
2
2
  "name": "@proto-kit/module",
3
3
  "license": "MIT",
4
4
  "private": false,
5
- "version": "0.1.1-develop.600+699a7df",
5
+ "version": "0.1.1-develop.833+397881ed",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "build": "tsc -p tsconfig.json",
9
9
  "dev": "tsc -p tsconfig.json --watch",
10
10
  "lint": "eslint ./src ./test",
11
11
  "test:file": "node --experimental-vm-modules --experimental-wasm-modules --experimental-wasm-threads ../../node_modules/jest/bin/jest.js",
12
- "test": "npm run test:file -- ./src/** ./test/**",
13
- "test:watch": "npm run test:file -- ./src/** ./test/** --watch"
12
+ "test": "npm run test:file -- ./test/**",
13
+ "test:watch": "npm run test:file -- ./test/** --watch"
14
14
  },
15
15
  "main": "dist/index.js",
16
16
  "publishConfig": {
@@ -28,8 +28,8 @@
28
28
  "peerDependencies": {
29
29
  "@proto-kit/common": "*",
30
30
  "@proto-kit/protocol": "*",
31
- "o1js": "0.13.1",
31
+ "o1js": "^1.1.0",
32
32
  "tsyringe": "^4.7.0"
33
33
  },
34
- "gitHead": "699a7dfa3b5d3415ab4500f0cd495d6781365c6a"
34
+ "gitHead": "397881ed5d8f98f5005bcd7be7f5a12b3bc6f956"
35
35
  }
@@ -1,11 +1,17 @@
1
- /* eslint-disable no-underscore-dangle */
2
- import { Field, FlexibleProvable, Proof, ProvableExtended } from "o1js";
1
+ /* eslint-disable @typescript-eslint/consistent-type-assertions */
2
+ import {
3
+ Field,
4
+ Proof,
5
+ Provable,
6
+ DynamicProof,
7
+ FlexibleProvablePure,
8
+ } from "o1js";
3
9
  import {
4
10
  ArgumentTypes,
5
11
  ProofTypes,
6
- ToFieldable,
7
12
  ToFieldableStatic,
8
- ToJSONableStatic,
13
+ TypedClass,
14
+ filterNonUndefined,
9
15
  } from "@proto-kit/common";
10
16
 
11
17
  import type { RuntimeModule } from "../runtime/RuntimeModule";
@@ -22,12 +28,55 @@ const errors = {
22
28
  ),
23
29
  };
24
30
 
25
- type ArgsArray = ProvableExtended<unknown>[];
31
+ type ArgumentType =
32
+ | FlexibleProvablePure<any>
33
+ | typeof Proof<unknown, unknown>
34
+ | typeof DynamicProof<unknown, unknown>;
35
+
36
+ type ArgTypeArray = ArgumentType[];
37
+
38
+ type ArgArray = ArgumentTypes[];
39
+
40
+ function isProofType(type: unknown): type is typeof Proof {
41
+ return (type as unknown as TypedClass<unknown>).prototype instanceof Proof;
42
+ }
43
+
44
+ function isDynamicProofType(type: unknown): type is typeof DynamicProof {
45
+ return (
46
+ (type as unknown as TypedClass<unknown>).prototype instanceof DynamicProof
47
+ );
48
+ }
49
+
50
+ function isProofBaseType(
51
+ type: unknown
52
+ ): type is typeof Proof | typeof DynamicProof {
53
+ return isProofType(type) || isDynamicProofType(type);
54
+ }
55
+
56
+ function getAllPropertyNamesOfPrototypeChain(type: unknown): string[] {
57
+ if (type === undefined || type === null) {
58
+ return [];
59
+ }
60
+ return Object.getOwnPropertyNames(type).concat(
61
+ ...getAllPropertyNamesOfPrototypeChain(Object.getPrototypeOf(type))
62
+ );
63
+ }
64
+
65
+ function isFlexibleProvablePure(
66
+ type: unknown
67
+ ): type is FlexibleProvablePure<unknown> {
68
+ // The required properties are defined on the prototype for Structs and CircuitValues
69
+ // but on the constructor function itself for Field and Bool
70
+ // For aliases like Balance in library, it can even be 2 steps upwards the prototype chain
71
+ const props = getAllPropertyNamesOfPrototypeChain(type);
72
+ const mandatory = ["toFields", "fromFields", "sizeInFields"];
73
+ return mandatory.every((prop) => props.includes(prop));
74
+ }
26
75
 
27
76
  export class MethodParameterEncoder {
28
77
  public static fromMethod(target: RuntimeModule<unknown>, methodName: string) {
29
78
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
30
- const paramtypes: ArgsArray = Reflect.getMetadata(
79
+ const paramtypes: ArgTypeArray = Reflect.getMetadata(
31
80
  "design:paramtypes",
32
81
  target,
33
82
  methodName
@@ -39,103 +88,165 @@ export class MethodParameterEncoder {
39
88
  );
40
89
  }
41
90
 
91
+ const indizes = paramtypes
92
+ .map((type, index) => {
93
+ if (isProofBaseType(type) || isFlexibleProvablePure(type)) {
94
+ return undefined;
95
+ }
96
+ return `${index}`;
97
+ })
98
+ .filter(filterNonUndefined);
99
+ if (indizes.length > 0) {
100
+ const indexString = indizes.reduce((a, b) => `${a}, ${b}`);
101
+ throw new Error(
102
+ `Not all arguments of method '${target.name}.${methodName}' are provable types or proofs (indizes: [${indexString}])`
103
+ );
104
+ }
105
+
42
106
  return new MethodParameterEncoder(paramtypes);
43
107
  }
44
108
 
45
- public static fieldSize(type: ProvableExtended<unknown>): number | undefined {
109
+ public static fieldSize(type: ArgumentType): number | undefined {
110
+ if (isProofBaseType(type)) {
111
+ return (
112
+ (MethodParameterEncoder.fieldSize(type.publicInputType) ?? 0) +
113
+ (MethodParameterEncoder.fieldSize(type.publicOutputType) ?? 0)
114
+ );
115
+ }
46
116
  // as any, since we shouldn't be using this workaround in the first place
47
- return (type as any).prototype._fields?.length ?? type.sizeInFields?.();
117
+ return (type as FlexibleProvablePure<unknown>).sizeInFields();
48
118
  }
49
119
 
50
- private constructor(private readonly types: ArgsArray) {}
51
-
52
- public decode(argsJSON: string[]): FlexibleProvable<unknown>[] {
53
- return this.types.map((type, index) => {
54
- // eslint-disable-next-line @typescript-eslint/init-declarations
55
- let value: FlexibleProvable<unknown>;
56
-
57
- try {
58
- // eslint-disable-next-line max-len
59
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
60
- value = type.fromJSON(
61
- JSON.parse(argsJSON[index])
62
- ) as FlexibleProvable<unknown>;
63
- } catch (e: unknown) {
64
- if (e instanceof Error) {
65
- throw errors.typeNotCompatible(type.constructor.name, e.message);
66
- }
67
- throw errors.typeNotCompatible(type.constructor.name);
68
- }
69
-
70
- return value;
71
- });
72
- }
120
+ public constructor(private readonly types: ArgTypeArray) {}
73
121
 
74
- public decodeFields(fields: Field[]): ArgumentTypes {
75
- if (fields.length < this.fieldSize) {
76
- throw errors.fieldLengthNotMatching(this.fieldSize, fields.length);
122
+ public decode(fields: Field[], auxiliary: string[]): Promise<ArgArray> {
123
+ if (fields.length < this.fieldSize()) {
124
+ throw errors.fieldLengthNotMatching(this.fieldSize(), fields.length);
77
125
  }
78
126
 
79
127
  let stack = fields.slice();
128
+ const auxiliaryStack = auxiliary.slice();
80
129
 
81
- return this.types.map((type) => {
82
- const numberFieldsNeeded = MethodParameterEncoder.fieldSize(type) ?? -1;
83
- if (numberFieldsNeeded === -1) {
84
- throw errors.typeNotCompatible(type.constructor.name);
85
- }
86
- const structFields = stack.slice(0, numberFieldsNeeded);
87
- stack = stack.slice(numberFieldsNeeded);
88
- return type.fromFields(structFields, []) as ToFieldable;
89
- });
130
+ return Promise.all(
131
+ this.types.map((type) => {
132
+ const numberFieldsNeeded = MethodParameterEncoder.fieldSize(type) ?? -1;
133
+ if (numberFieldsNeeded === -1) {
134
+ throw errors.typeNotCompatible(type.constructor.name);
135
+ }
136
+ const structFields = stack.slice(0, numberFieldsNeeded);
137
+ stack = stack.slice(numberFieldsNeeded);
138
+
139
+ // Decode proof
140
+ if (isProofBaseType(type)) {
141
+ const auxiliaryData = auxiliaryStack.shift();
142
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
143
+ const proofData: { proof: string; maxProofsVerified: 0 | 1 | 2 } =
144
+ JSON.parse(auxiliaryData!);
145
+
146
+ const inputFieldSize = MethodParameterEncoder.fieldSize(
147
+ type.publicInputType
148
+ )!;
149
+ const input = structFields
150
+ .slice(0, inputFieldSize)
151
+ .map((x) => x.toString());
152
+ const output = structFields
153
+ .slice(inputFieldSize)
154
+ .map((x) => x.toString());
155
+
156
+ // fromJSON has incompatible signature for Proof and DynamicProof
157
+ if (isProofType(type)) {
158
+ return type.fromJSON({
159
+ ...proofData,
160
+ publicInput: input,
161
+ publicOutput: output,
162
+ });
163
+ }
164
+ if (isDynamicProofType(type)) {
165
+ return type.fromJSON({
166
+ ...proofData,
167
+ publicInput: input,
168
+ publicOutput: output,
169
+ });
170
+ }
171
+ }
172
+
173
+ return (type as FlexibleProvablePure<unknown>).fromFields(
174
+ structFields
175
+ ) as any;
176
+ })
177
+ );
90
178
  }
91
179
 
92
- public encode(args: ArgumentTypes): {
93
- argsFields: Field[];
94
- argsJSON: string[];
95
- } {
180
+ /**
181
+ * Variant of encode() for provable code that skips the unprovable
182
+ * json encoding
183
+ */
184
+ public encode(args: ArgumentTypes) {
96
185
  /**
97
186
  * Use the type info obtained previously to convert
98
187
  * the args passed to fields
99
188
  */
100
- const argsFields = args.flatMap((argument, index) => {
101
- if (argument instanceof Proof) {
102
- const argumentType = this.types[index] as ProofTypes;
103
-
104
- const publicOutputType = argumentType?.publicOutputType;
105
-
106
- const publicInputType = argumentType?.publicInputType;
107
-
108
- const inputFields =
109
- publicInputType?.toFields(argument.publicInput) ?? [];
110
-
111
- const outputFields =
112
- publicOutputType?.toFields(argument.publicOutput) ?? [];
113
-
114
- return [...inputFields, ...outputFields];
115
- }
116
-
117
- const argumentType = this.types[index] as ToFieldableStatic;
118
- return argumentType.toFields(argument);
119
- });
120
-
121
- const argsJSON = args.map((argument, index) => {
122
- if (argument instanceof Proof) {
123
- return JSON.stringify(argument.toJSON());
124
- }
125
-
126
- const argumentType = this.types[index] as ToJSONableStatic;
127
- return JSON.stringify(argumentType.toJSON(argument));
128
- });
189
+ return args
190
+ .map((argument, index) => {
191
+ if (argument instanceof Proof || argument instanceof DynamicProof) {
192
+ const argumentType = this.types[index] as ProofTypes;
193
+
194
+ const { publicOutputType, publicInputType } = argumentType;
195
+
196
+ const inputFields =
197
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
198
+ publicInputType?.toFields(argument.publicInput as any) ?? [];
199
+
200
+ const outputFields =
201
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
202
+ publicOutputType?.toFields(argument.publicOutput as any) ?? [];
203
+
204
+ let auxiliary = "";
205
+
206
+ // Has to be asProver, because this function will be called by runtimeMethod
207
+ // to transform the args into a Field[] to compute the argsHash
208
+ // In this case, the auxiliary might be empty, but it isn't used by that method anyways
209
+ Provable.asProver(() => {
210
+ const jsonProof = argument.toJSON();
211
+ auxiliary = JSON.stringify({
212
+ proof: jsonProof.proof,
213
+ maxProofsVerified: jsonProof.maxProofsVerified,
214
+ });
215
+ });
216
+
217
+ return {
218
+ fields: [...inputFields, ...outputFields],
219
+ auxiliary,
220
+ };
221
+ }
129
222
 
130
- return {
131
- argsFields,
132
- argsJSON,
133
- };
223
+ const argumentType = this.types[index] as ToFieldableStatic;
224
+ return {
225
+ fields: argumentType.toFields(argument),
226
+ auxiliary: undefined,
227
+ };
228
+ })
229
+ .reduce<{
230
+ fields: Field[];
231
+ auxiliary: string[];
232
+ }>(
233
+ (a, b) => {
234
+ return {
235
+ fields: [...a.fields, ...b.fields],
236
+ auxiliary:
237
+ b.auxiliary !== undefined
238
+ ? [...a.auxiliary, b.auxiliary]
239
+ : a.auxiliary,
240
+ };
241
+ },
242
+ { fields: [], auxiliary: [] }
243
+ );
134
244
  }
135
245
 
136
- public get fieldSize(): number {
246
+ public fieldSize(): number {
137
247
  return this.types
138
248
  .map((type) => MethodParameterEncoder.fieldSize(type) ?? 0)
139
249
  .reduce((a, b) => a + b, 0);
140
250
  }
141
251
  }
252
+ /* eslint-enable @typescript-eslint/consistent-type-assertions */
@@ -1,34 +1,21 @@
1
- /* eslint-disable max-statements */
2
- import {
3
- Bool,
4
- Field,
5
- FlexibleProvable,
6
- Poseidon,
7
- Proof,
8
- ProvableExtended,
9
- } from "o1js";
1
+ import { Bool, Field, Poseidon } from "o1js";
10
2
  import { container } from "tsyringe";
11
3
  import {
12
4
  StateTransition,
13
- DefaultProvableHashList,
14
5
  ProvableStateTransition,
15
6
  MethodPublicOutput,
16
7
  RuntimeMethodExecutionContext,
17
- SignedTransaction,
8
+ StateTransitionReductionList,
18
9
  } from "@proto-kit/protocol";
19
10
  import {
20
11
  DecoratedMethod,
21
12
  toProver,
22
13
  ZkProgrammable,
23
- ToFieldable,
24
- ToFieldableStatic,
25
- ProofTypes,
26
14
  ArgumentTypes,
27
- TypedClass,
28
- O1JSPrimitive,
29
15
  } from "@proto-kit/common";
30
16
 
31
17
  import type { RuntimeModule } from "../runtime/RuntimeModule.js";
18
+
32
19
  import { MethodParameterEncoder } from "./MethodParameterEncoder";
33
20
 
34
21
  const errors = {
@@ -49,10 +36,9 @@ const errors = {
49
36
  };
50
37
 
51
38
  export function toStateTransitionsHash(
52
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
53
39
  stateTransitions: StateTransition<any>[]
54
40
  ) {
55
- const stateTransitionsHashList = new DefaultProvableHashList(
41
+ const stateTransitionsHashList = new StateTransitionReductionList(
56
42
  ProvableStateTransition
57
43
  );
58
44
 
@@ -66,35 +52,33 @@ export function toStateTransitionsHash(
66
52
  .toField();
67
53
  }
68
54
 
69
- // eslint-disable-next-line etc/prefer-interface
70
55
  export type WrappedMethod = (...args: ArgumentTypes) => MethodPublicOutput;
56
+ export type AsyncWrappedMethod = (
57
+ ...args: ArgumentTypes
58
+ ) => Promise<MethodPublicOutput>;
71
59
 
72
60
  export function toWrappedMethod(
73
61
  this: RuntimeModule<unknown>,
74
62
  methodName: string,
75
- moduleMethod: (...args: ArgumentTypes) => unknown,
76
- methodArguments: ArgumentTypes,
63
+ moduleMethod: (...args: ArgumentTypes) => Promise<any>,
77
64
  options: {
78
65
  invocationType: RuntimeMethodInvocationType;
79
66
  }
80
- ) {
67
+ ): AsyncWrappedMethod {
81
68
  const executionContext = container.resolve<RuntimeMethodExecutionContext>(
82
69
  RuntimeMethodExecutionContext
83
70
  );
84
71
 
85
- const wrappedMethod: WrappedMethod = (...args): MethodPublicOutput => {
86
- Reflect.apply(moduleMethod, this, args);
72
+ const wrappedMethod: AsyncWrappedMethod = async (
73
+ ...args
74
+ ): Promise<MethodPublicOutput> => {
75
+ await Reflect.apply(moduleMethod, this, args);
87
76
  const {
88
77
  result: { stateTransitions, status },
89
- input,
90
78
  } = executionContext.current();
91
79
 
92
80
  const stateTransitionsHash = toStateTransitionsHash(stateTransitions);
93
81
 
94
- if (input === undefined) {
95
- throw errors.methodInputsNotProvided();
96
- }
97
-
98
82
  const { name, runtime } = this;
99
83
 
100
84
  if (name === undefined) {
@@ -122,14 +106,13 @@ export function toWrappedMethod(
122
106
  * Use the type info obtained previously to convert
123
107
  * the args passed to fields
124
108
  */
125
- const { argsFields } = MethodParameterEncoder.fromMethod(this, methodName).encode(args);
109
+ const { fields } = MethodParameterEncoder.fromMethod(
110
+ this,
111
+ methodName
112
+ ).encode(args);
126
113
 
127
114
  // Assert that the argsHash that has been signed matches the given arguments
128
- // We can use js-if here, because methodArguments is statically sizes
129
- // i.e. the result of the if-statement will be the same for all executions
130
- // of this method
131
- const argsHash =
132
- methodArguments.length > 0 ? Poseidon.hash(argsFields) : Field(0);
115
+ const argsHash = Poseidon.hash(fields);
133
116
 
134
117
  transaction.argsHash.assertEquals(
135
118
  argsHash,
@@ -189,11 +172,16 @@ export function isRuntimeMethod(
189
172
 
190
173
  export type RuntimeMethodInvocationType = "SIGNATURE" | "INCOMING_MESSAGE";
191
174
 
192
- function runtimeMethodInternal(options: { invocationType: RuntimeMethodInvocationType }) {
175
+ function runtimeMethodInternal(options: {
176
+ invocationType: RuntimeMethodInvocationType;
177
+ }) {
193
178
  return (
194
179
  target: RuntimeModule<unknown>,
195
180
  methodName: string,
196
- descriptor: PropertyDescriptor
181
+ descriptor: TypedPropertyDescriptor<
182
+ // TODO Limit possible parameter types
183
+ (...args: any[]) => Promise<any>
184
+ >
197
185
  ) => {
198
186
  const executionContext = container.resolve<RuntimeMethodExecutionContext>(
199
187
  RuntimeMethodExecutionContext
@@ -223,11 +211,11 @@ function runtimeMethodInternal(options: { invocationType: RuntimeMethodInvocatio
223
211
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
224
212
  const simulatedMethod = descriptor.value as DecoratedMethod;
225
213
 
226
- descriptor.value = function value(
214
+ descriptor.value = async function value(
227
215
  this: RuntimeModule<unknown>,
228
216
  ...args: ArgumentTypes
229
217
  ) {
230
- const constructorName = this.constructor.name;
218
+ const constructorName = this.name!;
231
219
 
232
220
  /**
233
221
  * If its a top level method call, wrap it into a wrapped method,
@@ -239,7 +227,6 @@ function runtimeMethodInternal(options: { invocationType: RuntimeMethodInvocatio
239
227
  const simulatedWrappedMethod = Reflect.apply(toWrappedMethod, this, [
240
228
  methodName,
241
229
  simulatedMethod,
242
- args,
243
230
  options,
244
231
  ]);
245
232
 
@@ -248,7 +235,7 @@ function runtimeMethodInternal(options: { invocationType: RuntimeMethodInvocatio
248
235
  * RuntimeMethodExecutionContext state, meaning it enters and exits
249
236
  * the context properly.
250
237
  */
251
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
238
+
252
239
  async function prover(this: ZkProgrammable<any, any>) {
253
240
  executionContext.beforeMethod(constructorName, methodName, args);
254
241
  const innerProver = toProver(
@@ -257,7 +244,6 @@ function runtimeMethodInternal(options: { invocationType: RuntimeMethodInvocatio
257
244
  false,
258
245
  ...args
259
246
  ).bind(this);
260
- // eslint-disable-next-line @typescript-eslint/init-declarations
261
247
  let result: Awaited<ReturnType<typeof innerProver>>;
262
248
  try {
263
249
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
@@ -278,10 +264,9 @@ function runtimeMethodInternal(options: { invocationType: RuntimeMethodInvocatio
278
264
  executionContext.setProver(prover.bind(this.runtime.zkProgrammable));
279
265
  }
280
266
 
281
- // eslint-disable-next-line @typescript-eslint/init-declarations
282
267
  let result: unknown;
283
268
  try {
284
- result = Reflect.apply(simulatedMethod, this, args);
269
+ result = await Reflect.apply(simulatedMethod, this, args);
285
270
  } finally {
286
271
  executionContext.afterMethod();
287
272
  }
@@ -1,7 +1,13 @@
1
- import { stringToField } from "@proto-kit/protocol";
1
+ import { filterNonUndefined } from "@proto-kit/common";
2
+ import { stringToField, RuntimeMethodIdMapping } from "@proto-kit/protocol";
2
3
  import { Poseidon } from "o1js";
3
4
  import { inject, injectable } from "tsyringe";
4
5
 
6
+ import {
7
+ RuntimeMethodInvocationType,
8
+ runtimeMethodTypeMetadataKey,
9
+ } from "../method/runtimeMethod";
10
+
5
11
  import type { Runtime, RuntimeModulesRecord } from "./Runtime";
6
12
 
7
13
  /**
@@ -33,6 +39,50 @@ export class MethodIdResolver {
33
39
  }, {});
34
40
  }
35
41
 
42
+ /**
43
+ * The purpose of this method is to provide a dictionary where
44
+ * we can look up properties like methodId and invocationType
45
+ * for each runtimeMethod using their module name and method name
46
+ */
47
+ public methodIdMap(): RuntimeMethodIdMapping {
48
+ const methodIdResolver =
49
+ this.runtime.dependencyContainer.resolve<MethodIdResolver>(
50
+ "MethodIdResolver"
51
+ );
52
+
53
+ const rawMappings = this.runtime.moduleNames.flatMap((moduleName) => {
54
+ const module = this.runtime.resolve(moduleName);
55
+ return module.runtimeMethodNames.map((method) => {
56
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
57
+ const type = Reflect.getMetadata(
58
+ runtimeMethodTypeMetadataKey,
59
+ module,
60
+ method
61
+ ) as RuntimeMethodInvocationType | undefined;
62
+
63
+ if (type !== undefined) {
64
+ return {
65
+ name: `${moduleName}.${method}`,
66
+ methodId: methodIdResolver.getMethodId(moduleName, method),
67
+ type,
68
+ } as const;
69
+ }
70
+
71
+ return undefined;
72
+ });
73
+ });
74
+
75
+ return rawMappings
76
+ .filter(filterNonUndefined)
77
+ .reduce<RuntimeMethodIdMapping>((acc, entry) => {
78
+ acc[entry.name] = {
79
+ methodId: entry.methodId,
80
+ type: entry.type,
81
+ };
82
+ return acc;
83
+ }, {});
84
+ }
85
+
36
86
  public getMethodNameFromId(methodId: bigint): [string, string] | undefined {
37
87
  const methodPath = this.dictionary[methodId.toString()];
38
88