@proto-kit/module 0.1.1-develop.457 → 0.1.1-develop.651

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.
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export * from "./runtime/RuntimeEnvironment";
5
5
  export * from "./runtime/Runtime";
6
6
  export * from "./state/InMemoryStateService";
7
7
  export * from "./state/decorator";
8
- export * from "./method/MethodParameterDecoder";
8
+ export * from "./method/MethodParameterEncoder";
9
9
  export * from "./runtime/MethodIdResolver";
10
10
  export * from "./factories/MethodIdFactory";
11
11
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -5,6 +5,6 @@ export * from "./runtime/RuntimeEnvironment";
5
5
  export * from "./runtime/Runtime";
6
6
  export * from "./state/InMemoryStateService";
7
7
  export * from "./state/decorator";
8
- export * from "./method/MethodParameterDecoder";
8
+ export * from "./method/MethodParameterEncoder";
9
9
  export * from "./runtime/MethodIdResolver";
10
10
  export * from "./factories/MethodIdFactory";
@@ -0,0 +1,17 @@
1
+ import { Field, FlexibleProvable, ProvableExtended } from "o1js";
2
+ import { ArgumentTypes } from "@proto-kit/common";
3
+ import type { RuntimeModule } from "../runtime/RuntimeModule";
4
+ export declare class MethodParameterEncoder {
5
+ private readonly types;
6
+ static fromMethod(target: RuntimeModule<unknown>, methodName: string): MethodParameterEncoder;
7
+ static fieldSize(type: ProvableExtended<unknown>): number | undefined;
8
+ private constructor();
9
+ decode(argsJSON: string[]): FlexibleProvable<unknown>[];
10
+ decodeFields(fields: Field[]): ArgumentTypes;
11
+ encode(args: ArgumentTypes): {
12
+ argsFields: Field[];
13
+ argsJSON: string[];
14
+ };
15
+ get fieldSize(): number;
16
+ }
17
+ //# sourceMappingURL=MethodParameterEncoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MethodParameterEncoder.d.ts","sourceRoot":"","sources":["../../src/method/MethodParameterEncoder.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,EACL,gBAAgB,EAGhB,gBAAgB,EACjB,MAAM,MAAM,CAAC;AACd,OAAO,EACL,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAgB9D,qBAAa,sBAAsB;IAuBb,OAAO,CAAC,QAAQ,CAAC,KAAK;WAtB5B,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM;WAiB7D,SAAS,CAAC,IAAI,EAAE,gBAAgB,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,SAAS;IAK5E,OAAO;IAEA,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,EAAE;IAsBvD,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,aAAa;IAkB5C,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG;QAClC,UAAU,EAAE,KAAK,EAAE,CAAC;QACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IA4CD,IAAW,SAAS,IAAI,MAAM,CAI7B;CACF"}
@@ -0,0 +1,93 @@
1
+ /* eslint-disable no-underscore-dangle */
2
+ import { Proof, Provable, } from "o1js";
3
+ const errors = {
4
+ fieldLengthNotMatching: (expected, actual) => new Error(`Expected ${expected} field elements, got ${actual}`),
5
+ typeNotCompatible: (name, error) => new Error(`Cannot decode type ${name}, it has to be either a Struct, CircuitValue or built-in snarkyjs type.${error !== undefined ? `Caused by: ${error}` : ""}`),
6
+ };
7
+ export class MethodParameterEncoder {
8
+ static fromMethod(target, methodName) {
9
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
10
+ const paramtypes = Reflect.getMetadata("design:paramtypes", target, methodName);
11
+ if (paramtypes === undefined) {
12
+ throw new Error(`Method with name ${methodName} doesn't exist on this module`);
13
+ }
14
+ return new MethodParameterEncoder(paramtypes);
15
+ }
16
+ static fieldSize(type) {
17
+ // as any, since we shouldn't be using this workaround in the first place
18
+ return type.prototype._fields?.length ?? type.sizeInFields?.();
19
+ }
20
+ constructor(types) {
21
+ this.types = types;
22
+ }
23
+ decode(argsJSON) {
24
+ return this.types.map((type, index) => {
25
+ // eslint-disable-next-line @typescript-eslint/init-declarations
26
+ let value;
27
+ try {
28
+ // eslint-disable-next-line max-len
29
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
30
+ value = type.fromJSON(JSON.parse(argsJSON[index]));
31
+ }
32
+ catch (e) {
33
+ if (e instanceof Error) {
34
+ throw errors.typeNotCompatible(type.constructor.name, e.message);
35
+ }
36
+ throw errors.typeNotCompatible(type.constructor.name);
37
+ }
38
+ return value;
39
+ });
40
+ }
41
+ decodeFields(fields) {
42
+ if (fields.length < this.fieldSize) {
43
+ throw errors.fieldLengthNotMatching(this.fieldSize, fields.length);
44
+ }
45
+ let stack = fields.slice();
46
+ return this.types.map((type) => {
47
+ const numberFieldsNeeded = MethodParameterEncoder.fieldSize(type) ?? -1;
48
+ if (numberFieldsNeeded === -1) {
49
+ throw errors.typeNotCompatible(type.constructor.name);
50
+ }
51
+ const structFields = stack.slice(0, numberFieldsNeeded);
52
+ stack = stack.slice(numberFieldsNeeded);
53
+ return type.fromFields(structFields, []);
54
+ });
55
+ }
56
+ encode(args) {
57
+ /**
58
+ * Use the type info obtained previously to convert
59
+ * the args passed to fields
60
+ */
61
+ const argsFields = args.flatMap((argument, index) => {
62
+ if (argument instanceof Proof) {
63
+ const argumentType = this.types[index];
64
+ const publicOutputType = argumentType?.publicOutputType;
65
+ const publicInputType = argumentType?.publicInputType;
66
+ const inputFields = publicInputType?.toFields(argument.publicInput) ?? [];
67
+ const outputFields = publicOutputType?.toFields(argument.publicOutput) ?? [];
68
+ return [...inputFields, ...outputFields];
69
+ }
70
+ const argumentType = this.types[index];
71
+ return argumentType.toFields(argument);
72
+ });
73
+ let argsJSON = [];
74
+ Provable.asProver(() => {
75
+ argsJSON = args.map((argument, index) => {
76
+ if (argument instanceof Proof) {
77
+ return JSON.stringify(argument.toJSON());
78
+ }
79
+ const argumentType = this.types[index];
80
+ return JSON.stringify(argumentType.toJSON(argument));
81
+ });
82
+ });
83
+ return {
84
+ argsFields,
85
+ argsJSON,
86
+ };
87
+ }
88
+ get fieldSize() {
89
+ return this.types
90
+ .map((type) => MethodParameterEncoder.fieldSize(type) ?? 0)
91
+ .reduce((a, b) => a + b, 0);
92
+ }
93
+ }
@@ -3,10 +3,13 @@ import { ArgumentTypes } from "@proto-kit/common";
3
3
  import type { RuntimeModule } from "../runtime/RuntimeModule.js";
4
4
  export declare function toStateTransitionsHash(stateTransitions: StateTransition<any>[]): import("o1js/dist/node/lib/field.js").Field;
5
5
  export type WrappedMethod = (...args: ArgumentTypes) => MethodPublicOutput;
6
- export declare function toWrappedMethod(this: RuntimeModule<unknown>, methodName: string, moduleMethod: (...args: ArgumentTypes) => unknown, methodArguments: ArgumentTypes): WrappedMethod;
6
+ export declare function toWrappedMethod(this: RuntimeModule<unknown>, methodName: string, moduleMethod: (...args: ArgumentTypes) => unknown, options: {
7
+ invocationType: RuntimeMethodInvocationType;
8
+ }): WrappedMethod;
7
9
  export declare function combineMethodName(runtimeModuleName: string, methodName: string): string;
8
10
  export declare const runtimeMethodMetadataKey = "yab-method";
9
11
  export declare const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods";
12
+ export declare const runtimeMethodTypeMetadataKey = "proto-kit-runtime-method-type";
10
13
  /**
11
14
  * Checks the metadata of the provided runtime module and its method,
12
15
  * to see if it has been decorated with @runtimeMethod()
@@ -16,5 +19,7 @@ export declare const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods"
16
19
  * @returns - If the provided method name is a runtime method or not
17
20
  */
18
21
  export declare function isRuntimeMethod(target: RuntimeModule<unknown>, propertyKey: string): boolean;
22
+ export type RuntimeMethodInvocationType = "SIGNATURE" | "INCOMING_MESSAGE";
23
+ export declare function runtimeMessage(): (target: RuntimeModule<unknown>, methodName: string, descriptor: PropertyDescriptor) => void;
19
24
  export declare function runtimeMethod(): (target: RuntimeModule<unknown>, methodName: string, descriptor: PropertyDescriptor) => void;
20
25
  //# sourceMappingURL=runtimeMethod.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"runtimeMethod.d.ts","sourceRoot":"","sources":["../../src/method/runtimeMethod.ts"],"names":[],"mappings":"AASA,OAAO,EACL,eAAe,EAGf,kBAAkB,EAEnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAOL,aAAa,EAGd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAoBjE,wBAAgB,sBAAsB,CAEpC,gBAAgB,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,+CAczC;AAGD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,EAAE,aAAa,KAAK,kBAAkB,CAAC;AAE3E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,EAC5B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,aAAa,KAAK,OAAO,EACjD,eAAe,EAAE,aAAa,iBAqG/B;AAED,wBAAgB,iBAAiB,CAC/B,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,MAAM,UAGnB;AAED,eAAO,MAAM,wBAAwB,eAAe,CAAC;AACrD,eAAO,MAAM,6BAA6B,8BAA8B,CAAC;AAEzE;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAC9B,WAAW,EAAE,MAAM,WAKpB;AAED,wBAAgB,aAAa,aAEjB,cAAc,OAAO,CAAC,cAClB,MAAM,cACN,kBAAkB,UAwFjC"}
1
+ {"version":3,"file":"runtimeMethod.d.ts","sourceRoot":"","sources":["../../src/method/runtimeMethod.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,eAAe,EAEf,kBAAkB,EAKnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAOL,aAAa,EAGd,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAsBjE,wBAAgB,sBAAsB,CAEpC,gBAAgB,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,+CAczC;AAGD,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,EAAE,aAAa,KAAK,kBAAkB,CAAC;AAE3E,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,EAC5B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,aAAa,KAAK,OAAO,EACjD,OAAO,EAAE;IACP,cAAc,EAAE,2BAA2B,CAAC;CAC7C,iBAiFF;AAED,wBAAgB,iBAAiB,CAC/B,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,MAAM,UAGnB;AAED,eAAO,MAAM,wBAAwB,eAAe,CAAC;AACrD,eAAO,MAAM,6BAA6B,8BAA8B,CAAC;AACzE,eAAO,MAAM,4BAA4B,kCAAkC,CAAC;AAE5E;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAC9B,WAAW,EAAE,MAAM,WAKpB;AAED,MAAM,MAAM,2BAA2B,GAAG,WAAW,GAAG,kBAAkB,CAAC;AAyG3E,wBAAgB,cAAc,iGAI7B;AAED,wBAAgB,aAAa,iGAI5B"}
@@ -1,8 +1,9 @@
1
1
  /* eslint-disable max-statements */
2
- import { Field, Poseidon, Proof, } from "o1js";
2
+ import { Bool, Field, Poseidon } from "o1js";
3
3
  import { container } from "tsyringe";
4
- import { DefaultProvableHashList, ProvableStateTransition, MethodPublicOutput, RuntimeMethodExecutionContext, } from "@proto-kit/protocol";
4
+ import { ProvableStateTransition, MethodPublicOutput, RuntimeMethodExecutionContext, StateTransitionReductionList, } from "@proto-kit/protocol";
5
5
  import { toProver, } from "@proto-kit/common";
6
+ import { MethodParameterEncoder } from "./MethodParameterEncoder";
6
7
  const errors = {
7
8
  runtimeNotProvided: (name) => new Error(`Runtime was not provided for module: ${name}`),
8
9
  methodInputsNotProvided: () => new Error("Method execution inputs not provided, provide them via context.inputs"),
@@ -12,21 +13,19 @@ const errors = {
12
13
  export function toStateTransitionsHash(
13
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
15
  stateTransitions) {
15
- const stateTransitionsHashList = new DefaultProvableHashList(ProvableStateTransition);
16
+ const stateTransitionsHashList = new StateTransitionReductionList(ProvableStateTransition);
16
17
  return stateTransitions
17
18
  .map((stateTransition) => stateTransition.toProvable())
18
19
  .reduce((allStateTransitionsHashList, stateTransition) => allStateTransitionsHashList.push(stateTransition), stateTransitionsHashList)
19
20
  .toField();
20
21
  }
21
- export function toWrappedMethod(methodName, moduleMethod, methodArguments) {
22
+ export function toWrappedMethod(methodName, moduleMethod, options) {
22
23
  const executionContext = container.resolve(RuntimeMethodExecutionContext);
23
24
  const wrappedMethod = (...args) => {
24
25
  Reflect.apply(moduleMethod, this, args);
25
- const { result: { stateTransitions, status }, input, } = executionContext.current();
26
+ const { result: { stateTransitions, status }, } = executionContext.current();
26
27
  const stateTransitionsHash = toStateTransitionsHash(stateTransitions);
27
- if (input === undefined) {
28
- throw errors.methodInputsNotProvided();
29
- }
28
+ const input = this.getInputs();
30
29
  const { name, runtime } = this;
31
30
  if (name === undefined) {
32
31
  throw errors.runtimeNameNotSet();
@@ -34,47 +33,35 @@ export function toWrappedMethod(methodName, moduleMethod, methodArguments) {
34
33
  if (runtime === undefined) {
35
34
  throw errors.runtimeNotProvided(name);
36
35
  }
37
- // Assert that the given transaction has the correct methodId
36
+ const { transaction, networkState } = executionContext.witnessInput();
38
37
  const { methodIdResolver } = runtime;
38
+ // Assert that the given transaction has the correct methodId
39
39
  const thisMethodId = Field(methodIdResolver.getMethodId(name, methodName));
40
40
  if (!thisMethodId.isConstant()) {
41
41
  throw errors.fieldNotConstant("methodId");
42
42
  }
43
- input.transaction.methodId.assertEquals(thisMethodId, "Runtimemethod called with wrong methodId on the transaction object");
44
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
45
- const parameterTypes = Reflect.getMetadata("design:paramtypes", this, methodName);
43
+ transaction.methodId.assertEquals(thisMethodId, "Runtimemethod called with wrong methodId on the transaction object");
46
44
  /**
47
45
  * Use the type info obtained previously to convert
48
46
  * the args passed to fields
49
47
  */
50
- const argsFields = args.flatMap((argument, index) => {
51
- if (argument instanceof Proof) {
52
- // eslint-disable-next-line max-len
53
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
54
- const argumentType = parameterTypes[index];
55
- const publicOutputType = argumentType?.publicOutputType;
56
- const publicInputType = argumentType?.publicInputType;
57
- const inputFields = publicInputType?.toFields(argument.publicInput) ?? [];
58
- const outputFields = publicOutputType?.toFields(argument.publicOutput) ?? [];
59
- return [...inputFields, ...outputFields];
60
- }
61
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62
- const argumentType = parameterTypes[index];
63
- return argumentType.toFields(argument);
64
- });
48
+ const { argsFields } = MethodParameterEncoder.fromMethod(this, methodName).encode(args);
65
49
  // Assert that the argsHash that has been signed matches the given arguments
66
- // We can use js-if here, because methodArguments is statically sizes
50
+ // We can use js-if here, because args are statically sized
67
51
  // i.e. the result of the if-statement will be the same for all executions
68
52
  // of this method
69
- const argsHash = methodArguments.length > 0 ? Poseidon.hash(argsFields) : Field(0);
70
- input.transaction.argsHash.assertEquals(argsHash, "argsHash and therefore arguments of transaction and runtime call does not match");
71
- const transactionHash = input.transaction.hash();
72
- const networkStateHash = input.networkState.hash();
53
+ const argsHash = (args ?? []).length > 0 ? Poseidon.hash(argsFields) : Field(0);
54
+ transaction.argsHash.assertEquals(argsHash, "argsHash and therefore arguments of transaction and runtime call does not match");
55
+ const isMessage = Bool(options.invocationType === "INCOMING_MESSAGE");
56
+ transaction.assertTransactionType(Bool(isMessage));
57
+ const transactionHash = transaction.hash();
58
+ const networkStateHash = networkState.hash();
73
59
  return new MethodPublicOutput({
74
60
  stateTransitionsHash,
75
61
  status,
76
62
  transactionHash,
77
63
  networkStateHash,
64
+ isMessage,
78
65
  });
79
66
  };
80
67
  Object.defineProperty(wrappedMethod, "name", {
@@ -88,6 +75,7 @@ export function combineMethodName(runtimeModuleName, methodName) {
88
75
  }
89
76
  export const runtimeMethodMetadataKey = "yab-method";
90
77
  export const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods";
78
+ export const runtimeMethodTypeMetadataKey = "proto-kit-runtime-method-type";
91
79
  /**
92
80
  * Checks the metadata of the provided runtime module and its method,
93
81
  * to see if it has been decorated with @runtimeMethod()
@@ -99,7 +87,7 @@ export const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods";
99
87
  export function isRuntimeMethod(target, propertyKey) {
100
88
  return Boolean(Reflect.getMetadata(runtimeMethodMetadataKey, target, propertyKey));
101
89
  }
102
- export function runtimeMethod() {
90
+ function runtimeMethodInternal(options) {
103
91
  return (target, methodName, descriptor) => {
104
92
  const executionContext = container.resolve(RuntimeMethodExecutionContext);
105
93
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
@@ -112,10 +100,11 @@ export function runtimeMethod() {
112
100
  }
113
101
  Reflect.defineMetadata(runtimeMethodNamesMetadataKey, data, target);
114
102
  Reflect.defineMetadata(runtimeMethodMetadataKey, true, target, methodName);
103
+ Reflect.defineMetadata(runtimeMethodTypeMetadataKey, options.invocationType, target, methodName);
115
104
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
116
105
  const simulatedMethod = descriptor.value;
117
106
  descriptor.value = function value(...args) {
118
- const constructorName = this.constructor.name;
107
+ const constructorName = this.name;
119
108
  /**
120
109
  * If its a top level method call, wrap it into a wrapped method,
121
110
  * since it'll be turned into a real/mock prover in provableMethod().
@@ -126,7 +115,7 @@ export function runtimeMethod() {
126
115
  const simulatedWrappedMethod = Reflect.apply(toWrappedMethod, this, [
127
116
  methodName,
128
117
  simulatedMethod,
129
- args,
118
+ options,
130
119
  ]);
131
120
  /**
132
121
  * Before the prover runs, make sure it is operating on the correct
@@ -167,3 +156,13 @@ export function runtimeMethod() {
167
156
  };
168
157
  };
169
158
  }
159
+ export function runtimeMessage() {
160
+ return runtimeMethodInternal({
161
+ invocationType: "INCOMING_MESSAGE",
162
+ });
163
+ }
164
+ export function runtimeMethod() {
165
+ return runtimeMethodInternal({
166
+ invocationType: "SIGNATURE",
167
+ });
168
+ }
@@ -1,3 +1,4 @@
1
+ import { RuntimeMethodIdMapping } from "@proto-kit/protocol";
1
2
  import type { Runtime, RuntimeModulesRecord } from "./Runtime";
2
3
  /**
3
4
  * Please see `getMethodId` to learn more about
@@ -7,6 +8,12 @@ export declare class MethodIdResolver {
7
8
  private readonly runtime;
8
9
  private readonly dictionary;
9
10
  constructor(runtime: Runtime<RuntimeModulesRecord>);
11
+ /**
12
+ * The purpose of this method is to provide a dictionary where
13
+ * we can look up properties like methodId and invocationType
14
+ * for each runtimeMethod using their module name and method name
15
+ */
16
+ methodIdMap(): RuntimeMethodIdMapping;
10
17
  getMethodNameFromId(methodId: bigint): [string, string] | undefined;
11
18
  getMethodId(moduleName: string, methodName: string): bigint;
12
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MethodIdResolver.d.ts","sourceRoot":"","sources":["../../src/runtime/MethodIdResolver.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAE/D;;;GAGG;AACH,qBACa,gBAAgB;IAMN,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAEpB;gBAG+B,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAoBrE,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAiBnE,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;CAWnE"}
1
+ {"version":3,"file":"MethodIdResolver.d.ts","sourceRoot":"","sources":["../../src/runtime/MethodIdResolver.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAS5E,OAAO,KAAK,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAE/D;;;GAGG;AACH,qBACa,gBAAgB;IAMN,OAAO,CAAC,QAAQ,CAAC,OAAO;IAL7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAEpB;gBAG+B,OAAO,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAkB5E;;;;OAIG;IACI,WAAW,IAAI,sBAAsB;IAsCrC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;IAcnE,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;CAQnE"}
@@ -10,9 +10,11 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  var __param = (this && this.__param) || function (paramIndex, decorator) {
11
11
  return function (target, key) { decorator(target, key, paramIndex); }
12
12
  };
13
+ import { filterNonUndefined } from "@proto-kit/common";
13
14
  import { stringToField } from "@proto-kit/protocol";
14
15
  import { Poseidon } from "o1js";
15
16
  import { inject, injectable } from "tsyringe";
17
+ import { runtimeMethodTypeMetadataKey, } from "../method/runtimeMethod";
16
18
  /**
17
19
  * Please see `getMethodId` to learn more about
18
20
  * methodId encoding
@@ -21,9 +23,8 @@ let MethodIdResolver = class MethodIdResolver {
21
23
  constructor(runtime) {
22
24
  this.runtime = runtime;
23
25
  this.dictionary = {};
24
- const { modules } = runtime.definition;
25
26
  this.dictionary = runtime.runtimeModuleNames.reduce((dict, moduleName) => {
26
- this.runtime.assertIsValidModuleName(modules, moduleName);
27
+ this.runtime.assertIsValidModuleName(moduleName);
27
28
  runtime.resolve(moduleName).runtimeMethodNames.forEach((methodName) => {
28
29
  dict[this.getMethodId(moduleName, methodName).toString()] = {
29
30
  moduleName,
@@ -33,17 +34,48 @@ let MethodIdResolver = class MethodIdResolver {
33
34
  return dict;
34
35
  }, {});
35
36
  }
37
+ /**
38
+ * The purpose of this method is to provide a dictionary where
39
+ * we can look up properties like methodId and invocationType
40
+ * for each runtimeMethod using their module name and method name
41
+ */
42
+ methodIdMap() {
43
+ const methodIdResolver = this.runtime.dependencyContainer.resolve("MethodIdResolver");
44
+ const rawMappings = this.runtime.moduleNames.flatMap((moduleName) => {
45
+ const module = this.runtime.resolve(moduleName);
46
+ return module.runtimeMethodNames.map((method) => {
47
+ const type = Reflect.getMetadata(runtimeMethodTypeMetadataKey, module, method);
48
+ if (type !== undefined) {
49
+ return {
50
+ name: `${moduleName}.${method}`,
51
+ methodId: methodIdResolver.getMethodId(moduleName, method),
52
+ type,
53
+ };
54
+ }
55
+ return undefined;
56
+ });
57
+ });
58
+ return rawMappings
59
+ .filter(filterNonUndefined)
60
+ .reduce((acc, entry) => {
61
+ acc[entry.name] = {
62
+ methodId: entry.methodId,
63
+ type: entry.type,
64
+ };
65
+ return acc;
66
+ }, {});
67
+ }
36
68
  getMethodNameFromId(methodId) {
37
69
  const methodPath = this.dictionary[methodId.toString()];
38
70
  if (methodPath === undefined) {
39
71
  return undefined;
40
72
  }
41
73
  const { moduleName, methodName } = methodPath;
42
- this.runtime.assertIsValidModuleName(this.runtime.definition.modules, moduleName);
74
+ this.runtime.assertIsValidModuleName(moduleName);
43
75
  return [moduleName, methodName];
44
76
  }
45
77
  getMethodId(moduleName, methodName) {
46
- this.runtime.assertIsValidModuleName(this.runtime.definition.modules, moduleName);
78
+ this.runtime.assertIsValidModuleName(moduleName);
47
79
  return Poseidon.hash([
48
80
  stringToField(moduleName),
49
81
  stringToField(methodName),
@@ -5,6 +5,7 @@ import { MethodPublicOutput, StateServiceProvider, StateService } from "@proto-k
5
5
  import { RuntimeModule } from "./RuntimeModule";
6
6
  import { MethodIdResolver } from "./MethodIdResolver";
7
7
  import { RuntimeEnvironment } from "./RuntimeEnvironment";
8
+ export declare function getAllPropertyNames(obj: any): (string | symbol)[];
8
9
  /**
9
10
  * Record of modules accepted by the Runtime module container.
10
11
  *
@@ -1 +1 @@
1
- {"version":3,"file":"Runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/Runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAc,MAAM,UAAU,CAAC;AAC3D,OAAO,EACL,WAAW,EACX,eAAe,EACf,aAAa,EACb,aAAa,EACb,UAAU,EACV,cAAc,EACd,cAAc,EAEd,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACb,MAAM,qBAAqB,CAAC;AAU7B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAC9C,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CACnC,CAAC;AAOF;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,OAAO,SAAS,oBAAoB;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACjC;AAED,qBAAa,qBAAqB,CAChC,OAAO,SAAS,oBAAoB,CACpC,SAAQ,cAAc,CAAC,SAAS,EAAE,kBAAkB,CAAC;IAE3B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;gBAAzB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IAInD,IAAW,QAAQ,iCAElB;IAEM,gBAAgB,IAAI,cAAc,CAAC,SAAS,EAAE,kBAAkB,CAAC;CAgHzE;AAED;;;GAGG;AACH,qBACa,OAAO,CAAC,OAAO,SAAS,oBAAoB,CACvD,SAAQ,eAAe,CAAC,OAAO,CAC/B,YAAW,kBAAkB;WAEf,IAAI,CAAC,OAAO,SAAS,oBAAoB,EACrD,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,GACrC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IASxB,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;IAEpD,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEvC,cAAc,EAAE,cAAc,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAErE;;;;OAIG;gBACgB,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC;IAQlD,MAAM,CAAC,sBAAsB,EAAE,sBAAsB;IAM5D,IAAW,QAAQ,IAAI,gBAAgB,GAAG,SAAS,CAElD;IAED,IAAW,oBAAoB,IAAI,oBAAoB,CAItD;IAED,IAAW,YAAY,IAAI,YAAY,CAEtC;IAED,IAAW,gBAAgB,IAAI,gBAAgB,CAE9C;IAED;;OAEG;IACH,IAAW,mBAAmB,IAAI,mBAAmB,CAEpD;IAED;;;OAGG;IACI,aAAa,CAClB,QAAQ,EAAE,MAAM,GACf,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GAAG,SAAS;IAuBhD;;;;;;OAMG;IACI,cAAc,CACnB,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAChC,eAAe,EAAE,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAQ9D;;OAEG;IACH,IAAW,kBAAkB,aAE5B;CACF"}
1
+ {"version":3,"file":"Runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/Runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAc,MAAM,UAAU,CAAC;AAC3D,OAAO,EACL,WAAW,EACX,eAAe,EACf,aAAa,EACb,aAAa,EACb,UAAU,EACV,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACb,MAAM,qBAAqB,CAAC;AAW7B,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,GAAG,uBAW3C;AAED;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAC9C,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CACnC,CAAC;AAOF;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,OAAO,SAAS,oBAAoB;IACrE,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CACjC;AAED,qBAAa,qBAAqB,CAChC,OAAO,SAAS,oBAAoB,CACpC,SAAQ,cAAc,CAAC,SAAS,EAAE,kBAAkB,CAAC;IAE3B,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;gBAAzB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC;IAInD,IAAW,QAAQ,iCAElB;IAEM,gBAAgB,IAAI,cAAc,CAAC,SAAS,EAAE,kBAAkB,CAAC;CAwHzE;AAED;;;GAGG;AACH,qBACa,OAAO,CAAC,OAAO,SAAS,oBAAoB,CACvD,SAAQ,eAAe,CAAC,OAAO,CAC/B,YAAW,kBAAkB;WAEf,IAAI,CAAC,OAAO,SAAS,oBAAoB,EACrD,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,GACrC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IASxB,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;IAEpD,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEvC,cAAc,EAAE,cAAc,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAErE;;;;OAIG;gBACgB,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC;IAQlD,MAAM,CAAC,sBAAsB,EAAE,sBAAsB;IAM5D,IAAW,QAAQ,IAAI,gBAAgB,GAAG,SAAS,CAElD;IAED,IAAW,oBAAoB,IAAI,oBAAoB,CAItD;IAED,IAAW,YAAY,IAAI,YAAY,CAEtC;IAED,IAAW,gBAAgB,IAAI,gBAAgB,CAE9C;IAED;;OAEG;IACH,IAAW,mBAAmB,IAAI,mBAAmB,CAEpD;IAED;;;OAGG;IACI,aAAa,CAClB,QAAQ,EAAE,MAAM,GACf,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,GAAG,SAAS;IAuBhD;;;;;;OAMG;IACI,cAAc,CACnB,UAAU,EAAE,WAAW,CAAC,OAAO,CAAC,EAChC,eAAe,EAAE,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IAQ9D;;OAEG;IACH,IAAW,kBAAkB,aAE5B;CACF"}
@@ -14,8 +14,20 @@ import { Experimental } from "o1js";
14
14
  import { injectable } from "tsyringe";
15
15
  import { ModuleContainer, ZkProgrammable, } from "@proto-kit/common";
16
16
  import { MethodPublicOutput, } from "@proto-kit/protocol";
17
- import { combineMethodName, isRuntimeMethod, toWrappedMethod, } from "../method/runtimeMethod";
17
+ import { combineMethodName, isRuntimeMethod, runtimeMethodTypeMetadataKey, toWrappedMethod, } from "../method/runtimeMethod";
18
18
  import { MethodIdFactory } from "../factories/MethodIdFactory";
19
+ export function getAllPropertyNames(obj) {
20
+ let keys = [];
21
+ // if primitive (primitives still have keys) skip the first iteration
22
+ if (!(obj instanceof Object)) {
23
+ obj = Object.getPrototypeOf(obj);
24
+ }
25
+ while (obj) {
26
+ keys = keys.concat(Reflect.ownKeys(obj));
27
+ obj = Object.getPrototypeOf(obj);
28
+ }
29
+ return keys;
30
+ }
19
31
  const errors = {
20
32
  methodNotFound: (methodKey) => new Error(`Unable to find method with id ${methodKey}`),
21
33
  };
@@ -47,12 +59,13 @@ export class RuntimeZkProgrammable extends ZkProgrammable {
47
59
  // eslint-disable-next-line max-len
48
60
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
49
61
  const modulePrototype = Object.getPrototypeOf(runtimeModule);
50
- const modulePrototypeMethods = Object.getOwnPropertyNames(modulePrototype);
62
+ const modulePrototypeMethods = getAllPropertyNames(runtimeModule).map((method) => method.toString());
51
63
  const moduleMethods = modulePrototypeMethods.reduce((allModuleMethods, methodName) => {
52
64
  if (isRuntimeMethod(runtimeModule, methodName)) {
53
65
  const combinedMethodName = combineMethodName(runtimeModuleName, methodName);
54
66
  const method = modulePrototype[methodName];
55
- const wrappedMethod = Reflect.apply(toWrappedMethod, runtimeModule, [methodName, method]);
67
+ const invocationType = Reflect.getMetadata(runtimeMethodTypeMetadataKey, runtimeModule, methodName);
68
+ const wrappedMethod = Reflect.apply(toWrappedMethod, runtimeModule, [methodName, method, { invocationType }]);
56
69
  // eslint-disable-next-line no-warning-comments
57
70
  // TODO: find out how to import the Tuple type
58
71
  const privateInputs = Reflect.getMetadata("design:paramtypes", runtimeModule, methodName);
@@ -86,6 +99,7 @@ export class RuntimeZkProgrammable extends ZkProgrammable {
86
99
  return {
87
100
  compile: program.compile.bind(program),
88
101
  verify: program.verify.bind(program),
102
+ analyzeMethods: program.analyzeMethods.bind(program),
89
103
  Proof: SelfProof,
90
104
  methods,
91
105
  };
@@ -147,7 +161,7 @@ let Runtime = Runtime_1 = class Runtime extends ModuleContainer {
147
161
  return undefined;
148
162
  }
149
163
  const [moduleName, methodName] = methodDescriptor;
150
- this.assertIsValidModuleName(this.definition.modules, moduleName);
164
+ this.assertIsValidModuleName(moduleName);
151
165
  const module = this.resolve(moduleName);
152
166
  // eslint-disable-next-line max-len
153
167
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions,@typescript-eslint/no-unsafe-member-access
@@ -1,5 +1,5 @@
1
1
  import { ConfigurableModule, NoConfig, Presets } from "@proto-kit/common";
2
- import { NetworkState, RuntimeTransaction } from "@proto-kit/protocol";
2
+ import { NetworkState, RuntimeTransaction, RuntimeMethodExecutionData } from "@proto-kit/protocol";
3
3
  import { RuntimeEnvironment } from "./RuntimeEnvironment";
4
4
  /**
5
5
  * Base class for runtime modules providing the necessary utilities.
@@ -19,7 +19,7 @@ export declare class RuntimeModule<Config = NoConfig> extends ConfigurableModule
19
19
  name?: string;
20
20
  runtime?: RuntimeEnvironment;
21
21
  constructor();
22
- private getInputs;
22
+ getInputs(): RuntimeMethodExecutionData;
23
23
  get transaction(): RuntimeTransaction;
24
24
  get network(): NetworkState;
25
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"RuntimeModule.d.ts","sourceRoot":"","sources":["../../src/runtime/RuntimeModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE1E,OAAO,EACL,YAAY,EACZ,kBAAkB,EAInB,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAM1D;;GAEG;AACH,qBACa,aAAa,CACxB,MAAM,GAAG,QAAQ,CACjB,SAAQ,kBAAkB,CAAC,MAAM,CAAC;IAClC,OAAc,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAM;IAE7C;;OAEG;IACH,SAAgB,kBAAkB,EAAE,MAAM,EAAE,CAAM;IAElD;;;;OAIG;IACI,eAAe,UAAQ;IAEvB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,OAAO,CAAC,EAAE,kBAAkB,CAAC;;IAYpC,OAAO,CAAC,SAAS;IAWjB,IAAW,WAAW,IAAI,kBAAkB,CAE3C;IAED,IAAW,OAAO,IAAI,YAAY,CAEjC;CACF"}
1
+ {"version":3,"file":"RuntimeModule.d.ts","sourceRoot":"","sources":["../../src/runtime/RuntimeModule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE1E,OAAO,EACL,YAAY,EACZ,kBAAkB,EAGlB,0BAA0B,EAE3B,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAO1D;;GAEG;AACH,qBACa,aAAa,CACxB,MAAM,GAAG,QAAQ,CACjB,SAAQ,kBAAkB,CAAC,MAAM,CAAC;IAClC,OAAc,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAM;IAE7C;;OAEG;IACH,SAAgB,kBAAkB,EAAE,MAAM,EAAE,CAAM;IAElD;;;;OAIG;IACI,eAAe,UAAQ;IAEvB,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,OAAO,CAAC,EAAE,kBAAkB,CAAC;;IAY7B,SAAS,IAAI,0BAA0B;IAa9C,IAAW,WAAW,IAAI,kBAAkB,CAE3C;IAED,IAAW,OAAO,IAAI,YAAY,CAEjC;CACF"}
@@ -9,8 +9,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  };
10
10
  import { ConfigurableModule } from "@proto-kit/common";
11
11
  import { container, injectable } from "tsyringe";
12
- import { RuntimeMethodExecutionContext, } from "@proto-kit/protocol";
12
+ import { RuntimeMethodExecutionContext, RuntimeMethodExecutionDataStruct, } from "@proto-kit/protocol";
13
13
  import { runtimeMethodNamesMetadataKey } from "../method/runtimeMethod";
14
+ import { Provable } from "o1js";
14
15
  const errors = {
15
16
  inputDataNotSet: () => new Error("Input data for runtime execution not set"),
16
17
  };
@@ -35,11 +36,13 @@ let RuntimeModule = class RuntimeModule extends ConfigurableModule {
35
36
  this.runtimeMethodNames = methodNames ?? [];
36
37
  }
37
38
  getInputs() {
38
- const { input } = container.resolve(RuntimeMethodExecutionContext);
39
- if (input === undefined) {
40
- throw errors.inputDataNotSet();
41
- }
42
- return input;
39
+ return Provable.witness(RuntimeMethodExecutionDataStruct, () => {
40
+ const { input } = container.resolve(RuntimeMethodExecutionContext);
41
+ if (input === undefined) {
42
+ throw errors.inputDataNotSet();
43
+ }
44
+ return input;
45
+ });
43
46
  }
44
47
  get transaction() {
45
48
  return this.getInputs().transaction;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@proto-kit/module",
3
3
  "license": "MIT",
4
4
  "private": false,
5
- "version": "0.1.1-develop.457+467a974",
5
+ "version": "0.1.1-develop.651+7591cb6",
6
6
  "type": "module",
7
7
  "scripts": {
8
8
  "build": "tsc -p tsconfig.json",
@@ -31,5 +31,5 @@
31
31
  "o1js": "0.13.1",
32
32
  "tsyringe": "^4.7.0"
33
33
  },
34
- "gitHead": "467a974c8dddb9f57ecf37caf34d3e1e5eb33f2a"
34
+ "gitHead": "7591cb6bdf58a6cd525a10902c25bc292efcfc6b"
35
35
  }
package/src/index.ts CHANGED
@@ -5,6 +5,6 @@ export * from "./runtime/RuntimeEnvironment";
5
5
  export * from "./runtime/Runtime";
6
6
  export * from "./state/InMemoryStateService";
7
7
  export * from "./state/decorator";
8
- export * from "./method/MethodParameterDecoder";
8
+ export * from "./method/MethodParameterEncoder";
9
9
  export * from "./runtime/MethodIdResolver";
10
10
  export * from "./factories/MethodIdFactory";
@@ -0,0 +1,150 @@
1
+ /* eslint-disable no-underscore-dangle */
2
+ import {
3
+ Field,
4
+ FlexibleProvable,
5
+ Proof,
6
+ Provable,
7
+ ProvableExtended,
8
+ } from "o1js";
9
+ import {
10
+ ArgumentTypes,
11
+ ProofTypes,
12
+ ToFieldable,
13
+ ToFieldableStatic,
14
+ ToJSONableStatic,
15
+ } from "@proto-kit/common";
16
+
17
+ import type { RuntimeModule } from "../runtime/RuntimeModule";
18
+
19
+ const errors = {
20
+ fieldLengthNotMatching: (expected: number, actual: number) =>
21
+ new Error(`Expected ${expected} field elements, got ${actual}`),
22
+
23
+ typeNotCompatible: (name: string, error?: string) =>
24
+ new Error(
25
+ `Cannot decode type ${name}, it has to be either a Struct, CircuitValue or built-in snarkyjs type.${
26
+ error !== undefined ? `Caused by: ${error}` : ""
27
+ }`
28
+ ),
29
+ };
30
+
31
+ type ArgsArray = ProvableExtended<unknown>[];
32
+
33
+ export class MethodParameterEncoder {
34
+ public static fromMethod(target: RuntimeModule<unknown>, methodName: string) {
35
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
36
+ const paramtypes: ArgsArray = Reflect.getMetadata(
37
+ "design:paramtypes",
38
+ target,
39
+ methodName
40
+ );
41
+
42
+ if (paramtypes === undefined) {
43
+ throw new Error(
44
+ `Method with name ${methodName} doesn't exist on this module`
45
+ );
46
+ }
47
+
48
+ return new MethodParameterEncoder(paramtypes);
49
+ }
50
+
51
+ public static fieldSize(type: ProvableExtended<unknown>): number | undefined {
52
+ // as any, since we shouldn't be using this workaround in the first place
53
+ return (type as any).prototype._fields?.length ?? type.sizeInFields?.();
54
+ }
55
+
56
+ private constructor(private readonly types: ArgsArray) {}
57
+
58
+ public decode(argsJSON: string[]): FlexibleProvable<unknown>[] {
59
+ return this.types.map((type, index) => {
60
+ // eslint-disable-next-line @typescript-eslint/init-declarations
61
+ let value: FlexibleProvable<unknown>;
62
+
63
+ try {
64
+ // eslint-disable-next-line max-len
65
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
66
+ value = type.fromJSON(
67
+ JSON.parse(argsJSON[index])
68
+ ) as FlexibleProvable<unknown>;
69
+ } catch (e: unknown) {
70
+ if (e instanceof Error) {
71
+ throw errors.typeNotCompatible(type.constructor.name, e.message);
72
+ }
73
+ throw errors.typeNotCompatible(type.constructor.name);
74
+ }
75
+
76
+ return value;
77
+ });
78
+ }
79
+
80
+ public decodeFields(fields: Field[]): ArgumentTypes {
81
+ if (fields.length < this.fieldSize) {
82
+ throw errors.fieldLengthNotMatching(this.fieldSize, fields.length);
83
+ }
84
+
85
+ let stack = fields.slice();
86
+
87
+ return this.types.map((type) => {
88
+ const numberFieldsNeeded = MethodParameterEncoder.fieldSize(type) ?? -1;
89
+ if (numberFieldsNeeded === -1) {
90
+ throw errors.typeNotCompatible(type.constructor.name);
91
+ }
92
+ const structFields = stack.slice(0, numberFieldsNeeded);
93
+ stack = stack.slice(numberFieldsNeeded);
94
+ return type.fromFields(structFields, []) as ToFieldable;
95
+ });
96
+ }
97
+
98
+ public encode(args: ArgumentTypes): {
99
+ argsFields: Field[];
100
+ argsJSON: string[];
101
+ } {
102
+ /**
103
+ * Use the type info obtained previously to convert
104
+ * the args passed to fields
105
+ */
106
+ const argsFields = args.flatMap((argument, index) => {
107
+ if (argument instanceof Proof) {
108
+ const argumentType = this.types[index] as ProofTypes;
109
+
110
+ const publicOutputType = argumentType?.publicOutputType;
111
+
112
+ const publicInputType = argumentType?.publicInputType;
113
+
114
+ const inputFields =
115
+ publicInputType?.toFields(argument.publicInput) ?? [];
116
+
117
+ const outputFields =
118
+ publicOutputType?.toFields(argument.publicOutput) ?? [];
119
+
120
+ return [...inputFields, ...outputFields];
121
+ }
122
+
123
+ const argumentType = this.types[index] as ToFieldableStatic;
124
+ return argumentType.toFields(argument);
125
+ });
126
+
127
+ let argsJSON: string[] = [];
128
+ Provable.asProver(() => {
129
+ argsJSON = args.map((argument, index) => {
130
+ if (argument instanceof Proof) {
131
+ return JSON.stringify(argument.toJSON());
132
+ }
133
+
134
+ const argumentType = this.types[index] as ToJSONableStatic;
135
+ return JSON.stringify(argumentType.toJSON(argument));
136
+ });
137
+ });
138
+
139
+ return {
140
+ argsFields,
141
+ argsJSON,
142
+ };
143
+ }
144
+
145
+ public get fieldSize(): number {
146
+ return this.types
147
+ .map((type) => MethodParameterEncoder.fieldSize(type) ?? 0)
148
+ .reduce((a, b) => a + b, 0);
149
+ }
150
+ }
@@ -1,18 +1,14 @@
1
1
  /* eslint-disable max-statements */
2
- import {
3
- Field,
4
- FlexibleProvable,
5
- Poseidon,
6
- Proof,
7
- ProvableExtended,
8
- } from "o1js";
2
+ import { Bool, Field, Poseidon } from "o1js";
9
3
  import { container } from "tsyringe";
10
4
  import {
11
5
  StateTransition,
12
- DefaultProvableHashList,
13
6
  ProvableStateTransition,
14
7
  MethodPublicOutput,
15
8
  RuntimeMethodExecutionContext,
9
+ RuntimeMethodExecutionDataStruct,
10
+ SignedTransaction,
11
+ StateTransitionReductionList,
16
12
  } from "@proto-kit/protocol";
17
13
  import {
18
14
  DecoratedMethod,
@@ -28,6 +24,8 @@ import {
28
24
 
29
25
  import type { RuntimeModule } from "../runtime/RuntimeModule.js";
30
26
  import { MethodIdResolver } from "../runtime/MethodIdResolver";
27
+ import { state } from "../state/decorator.js";
28
+ import { MethodParameterEncoder } from "./MethodParameterEncoder";
31
29
 
32
30
  const errors = {
33
31
  runtimeNotProvided: (name: string) =>
@@ -50,7 +48,7 @@ export function toStateTransitionsHash(
50
48
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
49
  stateTransitions: StateTransition<any>[]
52
50
  ) {
53
- const stateTransitionsHashList = new DefaultProvableHashList(
51
+ const stateTransitionsHashList = new StateTransitionReductionList(
54
52
  ProvableStateTransition
55
53
  );
56
54
 
@@ -71,7 +69,9 @@ export function toWrappedMethod(
71
69
  this: RuntimeModule<unknown>,
72
70
  methodName: string,
73
71
  moduleMethod: (...args: ArgumentTypes) => unknown,
74
- methodArguments: ArgumentTypes
72
+ options: {
73
+ invocationType: RuntimeMethodInvocationType;
74
+ }
75
75
  ) {
76
76
  const executionContext = container.resolve<RuntimeMethodExecutionContext>(
77
77
  RuntimeMethodExecutionContext
@@ -81,14 +81,11 @@ export function toWrappedMethod(
81
81
  Reflect.apply(moduleMethod, this, args);
82
82
  const {
83
83
  result: { stateTransitions, status },
84
- input,
85
84
  } = executionContext.current();
86
85
 
87
86
  const stateTransitionsHash = toStateTransitionsHash(stateTransitions);
88
87
 
89
- if (input === undefined) {
90
- throw errors.methodInputsNotProvided();
91
- }
88
+ const input = this.getInputs();
92
89
 
93
90
  const { name, runtime } = this;
94
91
 
@@ -99,70 +96,53 @@ export function toWrappedMethod(
99
96
  throw errors.runtimeNotProvided(name);
100
97
  }
101
98
 
102
- // Assert that the given transaction has the correct methodId
99
+ const { transaction, networkState } = executionContext.witnessInput();
103
100
  const { methodIdResolver } = runtime;
101
+
102
+ // Assert that the given transaction has the correct methodId
104
103
  const thisMethodId = Field(methodIdResolver.getMethodId(name, methodName));
105
104
  if (!thisMethodId.isConstant()) {
106
105
  throw errors.fieldNotConstant("methodId");
107
106
  }
108
107
 
109
- input.transaction.methodId.assertEquals(
108
+ transaction.methodId.assertEquals(
110
109
  thisMethodId,
111
110
  "Runtimemethod called with wrong methodId on the transaction object"
112
111
  );
113
112
 
114
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
115
- const parameterTypes: ProofTypes[] | ToFieldableStatic[] =
116
- Reflect.getMetadata("design:paramtypes", this, methodName);
117
-
118
113
  /**
119
114
  * Use the type info obtained previously to convert
120
115
  * the args passed to fields
121
116
  */
122
- const argsFields = args.flatMap((argument, index) => {
123
- if (argument instanceof Proof) {
124
- // eslint-disable-next-line max-len
125
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
126
- const argumentType = parameterTypes[index] as ProofTypes;
127
-
128
- const publicOutputType = argumentType?.publicOutputType;
129
-
130
- const publicInputType = argumentType?.publicInputType;
131
-
132
- const inputFields =
133
- publicInputType?.toFields(argument.publicInput) ?? [];
134
-
135
- const outputFields =
136
- publicOutputType?.toFields(argument.publicOutput) ?? [];
137
-
138
- return [...inputFields, ...outputFields];
139
- }
140
-
141
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
142
- const argumentType = parameterTypes[index] as ToFieldableStatic;
143
- return argumentType.toFields(argument);
144
- });
117
+ const { argsFields } = MethodParameterEncoder.fromMethod(
118
+ this,
119
+ methodName
120
+ ).encode(args);
145
121
 
146
122
  // Assert that the argsHash that has been signed matches the given arguments
147
- // We can use js-if here, because methodArguments is statically sizes
123
+ // We can use js-if here, because args are statically sized
148
124
  // i.e. the result of the if-statement will be the same for all executions
149
125
  // of this method
150
126
  const argsHash =
151
- methodArguments.length > 0 ? Poseidon.hash(argsFields) : Field(0);
127
+ (args ?? []).length > 0 ? Poseidon.hash(argsFields) : Field(0);
152
128
 
153
- input.transaction.argsHash.assertEquals(
129
+ transaction.argsHash.assertEquals(
154
130
  argsHash,
155
131
  "argsHash and therefore arguments of transaction and runtime call does not match"
156
132
  );
157
133
 
158
- const transactionHash = input.transaction.hash();
159
- const networkStateHash = input.networkState.hash();
134
+ const isMessage = Bool(options.invocationType === "INCOMING_MESSAGE");
135
+ transaction.assertTransactionType(Bool(isMessage));
136
+
137
+ const transactionHash = transaction.hash();
138
+ const networkStateHash = networkState.hash();
160
139
 
161
140
  return new MethodPublicOutput({
162
141
  stateTransitionsHash,
163
142
  status,
164
143
  transactionHash,
165
144
  networkStateHash,
145
+ isMessage,
166
146
  });
167
147
  };
168
148
 
@@ -183,6 +163,7 @@ export function combineMethodName(
183
163
 
184
164
  export const runtimeMethodMetadataKey = "yab-method";
185
165
  export const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods";
166
+ export const runtimeMethodTypeMetadataKey = "proto-kit-runtime-method-type";
186
167
 
187
168
  /**
188
169
  * Checks the metadata of the provided runtime module and its method,
@@ -201,7 +182,11 @@ export function isRuntimeMethod(
201
182
  );
202
183
  }
203
184
 
204
- export function runtimeMethod() {
185
+ export type RuntimeMethodInvocationType = "SIGNATURE" | "INCOMING_MESSAGE";
186
+
187
+ function runtimeMethodInternal(options: {
188
+ invocationType: RuntimeMethodInvocationType;
189
+ }) {
205
190
  return (
206
191
  target: RuntimeModule<unknown>,
207
192
  methodName: string,
@@ -225,6 +210,13 @@ export function runtimeMethod() {
225
210
 
226
211
  Reflect.defineMetadata(runtimeMethodMetadataKey, true, target, methodName);
227
212
 
213
+ Reflect.defineMetadata(
214
+ runtimeMethodTypeMetadataKey,
215
+ options.invocationType,
216
+ target,
217
+ methodName
218
+ );
219
+
228
220
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
229
221
  const simulatedMethod = descriptor.value as DecoratedMethod;
230
222
 
@@ -232,7 +224,7 @@ export function runtimeMethod() {
232
224
  this: RuntimeModule<unknown>,
233
225
  ...args: ArgumentTypes
234
226
  ) {
235
- const constructorName = this.constructor.name;
227
+ const constructorName = this.name!;
236
228
 
237
229
  /**
238
230
  * If its a top level method call, wrap it into a wrapped method,
@@ -244,7 +236,7 @@ export function runtimeMethod() {
244
236
  const simulatedWrappedMethod = Reflect.apply(toWrappedMethod, this, [
245
237
  methodName,
246
238
  simulatedMethod,
247
- args,
239
+ options,
248
240
  ]);
249
241
 
250
242
  /**
@@ -294,3 +286,15 @@ export function runtimeMethod() {
294
286
  };
295
287
  };
296
288
  }
289
+
290
+ export function runtimeMessage() {
291
+ return runtimeMethodInternal({
292
+ invocationType: "INCOMING_MESSAGE",
293
+ });
294
+ }
295
+
296
+ export function runtimeMethod() {
297
+ return runtimeMethodInternal({
298
+ invocationType: "SIGNATURE",
299
+ });
300
+ }
@@ -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
  /**
@@ -17,12 +23,10 @@ export class MethodIdResolver {
17
23
  public constructor(
18
24
  @inject("Runtime") private readonly runtime: Runtime<RuntimeModulesRecord>
19
25
  ) {
20
- const { modules } = runtime.definition;
21
-
22
26
  this.dictionary = runtime.runtimeModuleNames.reduce<
23
27
  Record<string, { moduleName: string; methodName: string }>
24
28
  >((dict, moduleName) => {
25
- this.runtime.assertIsValidModuleName(modules, moduleName);
29
+ this.runtime.assertIsValidModuleName(moduleName);
26
30
 
27
31
  runtime.resolve(moduleName).runtimeMethodNames.forEach((methodName) => {
28
32
  dict[this.getMethodId(moduleName, methodName).toString()] = {
@@ -35,6 +39,49 @@ export class MethodIdResolver {
35
39
  }, {});
36
40
  }
37
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
+ const type = Reflect.getMetadata(
57
+ runtimeMethodTypeMetadataKey,
58
+ module,
59
+ method
60
+ ) as RuntimeMethodInvocationType | undefined;
61
+
62
+ if (type !== undefined) {
63
+ return {
64
+ name: `${moduleName}.${method}`,
65
+ methodId: methodIdResolver.getMethodId(moduleName, method),
66
+ type,
67
+ } as const;
68
+ }
69
+
70
+ return undefined;
71
+ });
72
+ });
73
+
74
+ return rawMappings
75
+ .filter(filterNonUndefined)
76
+ .reduce<RuntimeMethodIdMapping>((acc, entry) => {
77
+ acc[entry.name] = {
78
+ methodId: entry.methodId,
79
+ type: entry.type,
80
+ };
81
+ return acc;
82
+ }, {});
83
+ }
84
+
38
85
  public getMethodNameFromId(methodId: bigint): [string, string] | undefined {
39
86
  const methodPath = this.dictionary[methodId.toString()];
40
87
 
@@ -44,19 +91,13 @@ export class MethodIdResolver {
44
91
 
45
92
  const { moduleName, methodName } = methodPath;
46
93
 
47
- this.runtime.assertIsValidModuleName(
48
- this.runtime.definition.modules,
49
- moduleName
50
- );
94
+ this.runtime.assertIsValidModuleName(moduleName);
51
95
 
52
96
  return [moduleName, methodName];
53
97
  }
54
98
 
55
99
  public getMethodId(moduleName: string, methodName: string): bigint {
56
- this.runtime.assertIsValidModuleName(
57
- this.runtime.definition.modules,
58
- moduleName
59
- );
100
+ this.runtime.assertIsValidModuleName(moduleName);
60
101
 
61
102
  return Poseidon.hash([
62
103
  stringToField(moduleName),
@@ -10,7 +10,6 @@ import {
10
10
  TypedClass,
11
11
  ZkProgrammable,
12
12
  PlainZkProgram,
13
- WithZkProgrammable,
14
13
  AreProofsEnabled,
15
14
  ChildContainerProvider,
16
15
  } from "@proto-kit/common";
@@ -23,6 +22,7 @@ import {
23
22
  import {
24
23
  combineMethodName,
25
24
  isRuntimeMethod,
25
+ runtimeMethodTypeMetadataKey,
26
26
  toWrappedMethod,
27
27
  WrappedMethod,
28
28
  } from "../method/runtimeMethod";
@@ -32,6 +32,19 @@ import { RuntimeModule } from "./RuntimeModule";
32
32
  import { MethodIdResolver } from "./MethodIdResolver";
33
33
  import { RuntimeEnvironment } from "./RuntimeEnvironment";
34
34
 
35
+ export function getAllPropertyNames(obj: any) {
36
+ let keys: (string | symbol)[] = [];
37
+ // if primitive (primitives still have keys) skip the first iteration
38
+ if (!(obj instanceof Object)) {
39
+ obj = Object.getPrototypeOf(obj);
40
+ }
41
+ while (obj) {
42
+ keys = keys.concat(Reflect.ownKeys(obj));
43
+ obj = Object.getPrototypeOf(obj);
44
+ }
45
+ return keys;
46
+ }
47
+
35
48
  /**
36
49
  * Record of modules accepted by the Runtime module container.
37
50
  *
@@ -104,8 +117,9 @@ export class RuntimeZkProgrammable<
104
117
  (...args: unknown[]) => unknown
105
118
  >;
106
119
 
107
- const modulePrototypeMethods =
108
- Object.getOwnPropertyNames(modulePrototype);
120
+ const modulePrototypeMethods = getAllPropertyNames(runtimeModule).map(
121
+ (method) => method.toString()
122
+ );
109
123
 
110
124
  const moduleMethods = modulePrototypeMethods.reduce<Methods>(
111
125
  (allModuleMethods, methodName) => {
@@ -115,10 +129,16 @@ export class RuntimeZkProgrammable<
115
129
  methodName
116
130
  );
117
131
  const method = modulePrototype[methodName];
132
+ const invocationType = Reflect.getMetadata(
133
+ runtimeMethodTypeMetadataKey,
134
+ runtimeModule,
135
+ methodName
136
+ );
137
+
118
138
  const wrappedMethod = Reflect.apply(
119
139
  toWrappedMethod,
120
140
  runtimeModule,
121
- [methodName, method]
141
+ [methodName, method, { invocationType }]
122
142
  );
123
143
 
124
144
  // eslint-disable-next-line no-warning-comments
@@ -175,6 +195,7 @@ export class RuntimeZkProgrammable<
175
195
  return {
176
196
  compile: program.compile.bind(program),
177
197
  verify: program.verify.bind(program),
198
+ analyzeMethods: program.analyzeMethods.bind(program),
178
199
  Proof: SelfProof,
179
200
  methods,
180
201
  };
@@ -266,7 +287,7 @@ export class Runtime<Modules extends RuntimeModulesRecord>
266
287
  }
267
288
  const [moduleName, methodName] = methodDescriptor;
268
289
 
269
- this.assertIsValidModuleName(this.definition.modules, moduleName);
290
+ this.assertIsValidModuleName(moduleName);
270
291
  const module = this.resolve(moduleName);
271
292
 
272
293
  // eslint-disable-next-line max-len
@@ -6,6 +6,7 @@ import {
6
6
  StateService,
7
7
  RuntimeMethodExecutionContext,
8
8
  RuntimeMethodExecutionData,
9
+ RuntimeMethodExecutionDataStruct,
9
10
  } from "@proto-kit/protocol";
10
11
 
11
12
  import { runtimeMethodNamesMetadataKey } from "../method/runtimeMethod";
@@ -16,6 +17,7 @@ import type {
16
17
  RuntimeModulesRecord,
17
18
  } from "./Runtime";
18
19
  import { RuntimeEnvironment } from "./RuntimeEnvironment";
20
+ import { Provable } from "o1js";
19
21
 
20
22
  const errors = {
21
23
  inputDataNotSet: () => new Error("Input data for runtime execution not set"),
@@ -56,15 +58,17 @@ export class RuntimeModule<
56
58
  this.runtimeMethodNames = methodNames ?? [];
57
59
  }
58
60
 
59
- private getInputs(): RuntimeMethodExecutionData {
60
- const { input } = container.resolve<RuntimeMethodExecutionContext>(
61
- RuntimeMethodExecutionContext
62
- );
61
+ public getInputs(): RuntimeMethodExecutionData {
62
+ return Provable.witness(RuntimeMethodExecutionDataStruct, () => {
63
+ const { input } = container.resolve<RuntimeMethodExecutionContext>(
64
+ RuntimeMethodExecutionContext
65
+ );
66
+ if (input === undefined) {
67
+ throw errors.inputDataNotSet();
68
+ }
63
69
 
64
- if (input === undefined) {
65
- throw errors.inputDataNotSet();
66
- }
67
- return input;
70
+ return input;
71
+ });
68
72
  }
69
73
 
70
74
  public get transaction(): RuntimeTransaction {
@@ -9,7 +9,7 @@ import { container } from "tsyringe";
9
9
  import { AreProofsEnabled, log } from "@proto-kit/common";
10
10
 
11
11
  import { InMemoryStateService, MethodIdResolver, Runtime } from "../src";
12
- import { MethodParameterDecoder } from "../src/method/MethodParameterDecoder";
12
+ import { MethodParameterEncoder } from "../src/method/MethodParameterEncoder";
13
13
 
14
14
  import { Balances } from "./modules/Balances";
15
15
 
@@ -42,7 +42,7 @@ describe("runtimeMethod", () => {
42
42
 
43
43
  const module = runtime.resolve("Balances");
44
44
 
45
- const decoder = MethodParameterDecoder.fromMethod(module, "getBalance");
45
+ const decoder = MethodParameterEncoder.fromMethod(module, "getBalance");
46
46
  const recodedParameters = decoder.fromFields(
47
47
  parameters.flatMap((x) => x.toFields())
48
48
  );
@@ -1,62 +0,0 @@
1
- /* eslint-disable no-underscore-dangle */
2
- import { FlexibleProvable, ProvableExtended } from "o1js";
3
-
4
- import { RuntimeModule } from "../runtime/RuntimeModule";
5
-
6
- const errors = {
7
- typeNotCompatible: (name: string) =>
8
- new Error(
9
- `Cannot decode type ${name}, it has to be either a Struct, CircuitValue or built-in snarkyjs type`
10
- ),
11
- };
12
-
13
- export class MethodParameterDecoder {
14
- public static fromMethod(target: RuntimeModule<unknown>, methodName: string) {
15
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
16
- const paramtypes: ProvableExtended<unknown>[] = Reflect.getMetadata(
17
- "design:paramtypes",
18
- target,
19
- methodName
20
- );
21
-
22
- if (paramtypes === undefined) {
23
- throw new Error(
24
- `Method with name ${methodName} doesn't exist on this module`
25
- );
26
- }
27
-
28
- return new MethodParameterDecoder(paramtypes);
29
- }
30
-
31
- public static fieldSize(type: ProvableExtended<unknown>): number | undefined {
32
- // as any, since we shouldn't be using this workaround in the first place
33
- return (type as any).prototype._fields?.length ?? type.sizeInFields?.();
34
- }
35
-
36
- private constructor(private readonly types: ProvableExtended<unknown>[]) {}
37
-
38
- public fromJSON(argsJSON: string[]): FlexibleProvable<unknown>[] {
39
- return this.types.map((type, index) => {
40
- // eslint-disable-next-line @typescript-eslint/init-declarations
41
- let value: FlexibleProvable<unknown>;
42
-
43
- try {
44
- // eslint-disable-next-line max-len
45
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
46
- value = type.fromJSON(
47
- JSON.parse(argsJSON[index])
48
- ) as FlexibleProvable<unknown>;
49
- } catch {
50
- throw errors.typeNotCompatible(type.constructor.name);
51
- }
52
-
53
- return value;
54
- });
55
- }
56
-
57
- public get fieldSize(): number {
58
- return this.types
59
- .map((type) => MethodParameterDecoder.fieldSize(type) ?? 0)
60
- .reduce((a, b) => a + b, 0);
61
- }
62
- }