@proto-kit/module 0.1.1-develop.1086

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 (60) hide show
  1. package/LICENSE.md +201 -0
  2. package/README.md +114 -0
  3. package/dist/factories/MethodIdFactory.d.ts +10 -0
  4. package/dist/factories/MethodIdFactory.d.ts.map +1 -0
  5. package/dist/factories/MethodIdFactory.js +10 -0
  6. package/dist/index.d.ts +11 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +10 -0
  9. package/dist/method/MethodParameterEncoder.d.ts +24 -0
  10. package/dist/method/MethodParameterEncoder.d.ts.map +1 -0
  11. package/dist/method/MethodParameterEncoder.js +164 -0
  12. package/dist/method/runtimeMethod.d.ts +33 -0
  13. package/dist/method/runtimeMethod.d.ts.map +1 -0
  14. package/dist/method/runtimeMethod.js +167 -0
  15. package/dist/module/decorator.d.ts +8 -0
  16. package/dist/module/decorator.d.ts.map +1 -0
  17. package/dist/module/decorator.js +15 -0
  18. package/dist/runtime/MethodIdResolver.d.ts +20 -0
  19. package/dist/runtime/MethodIdResolver.d.ts.map +1 -0
  20. package/dist/runtime/MethodIdResolver.js +90 -0
  21. package/dist/runtime/Runtime.d.ts +71 -0
  22. package/dist/runtime/Runtime.d.ts.map +1 -0
  23. package/dist/runtime/Runtime.js +220 -0
  24. package/dist/runtime/RuntimeEnvironment.d.ts +10 -0
  25. package/dist/runtime/RuntimeEnvironment.d.ts.map +1 -0
  26. package/dist/runtime/RuntimeEnvironment.js +1 -0
  27. package/dist/runtime/RuntimeModule.d.ts +37 -0
  28. package/dist/runtime/RuntimeModule.d.ts.map +1 -0
  29. package/dist/runtime/RuntimeModule.js +79 -0
  30. package/dist/state/InMemoryStateService.d.ts +15 -0
  31. package/dist/state/InMemoryStateService.d.ts.map +1 -0
  32. package/dist/state/InMemoryStateService.js +23 -0
  33. package/dist/state/decorator.d.ts +7 -0
  34. package/dist/state/decorator.d.ts.map +1 -0
  35. package/dist/state/decorator.js +39 -0
  36. package/jest.config.cjs +1 -0
  37. package/package.json +35 -0
  38. package/src/factories/MethodIdFactory.ts +13 -0
  39. package/src/index.ts +10 -0
  40. package/src/method/MethodParameterEncoder.ts +252 -0
  41. package/src/method/runtimeMethod.ts +307 -0
  42. package/src/module/decorator.ts +21 -0
  43. package/src/runtime/MethodIdResolver.ts +108 -0
  44. package/src/runtime/Runtime.ts +379 -0
  45. package/src/runtime/RuntimeEnvironment.ts +16 -0
  46. package/src/runtime/RuntimeModule.ts +112 -0
  47. package/src/state/InMemoryStateService.ts +25 -0
  48. package/src/state/decorator.ts +61 -0
  49. package/test/Runtime.test.ts +70 -0
  50. package/test/TestingRuntime.ts +45 -0
  51. package/test/method/MethodParameterEncoder.test.ts +152 -0
  52. package/test/method/runtimeMethod.test.ts +46 -0
  53. package/test/modules/Admin.ts +19 -0
  54. package/test/modules/Balances.test.ts +337 -0
  55. package/test/modules/Balances.ts +54 -0
  56. package/test/modules/MethodIdResolver.test.ts +73 -0
  57. package/test/modules/State.test.ts +81 -0
  58. package/test/runtimeMethod.test.ts +215 -0
  59. package/test/tsconfig.json +7 -0
  60. package/tsconfig.json +8 -0
@@ -0,0 +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,EAElB,0BAA0B,EAE3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAM1D,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC;AAE7D,KAAK,aAAa,CAAC,CAAC,SAAS,oBAAoB,CAAC,GAAG,CAAC,IACpD,CAAC,SAAS,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAE1C,qBAAa,aAAa,CAAC,MAAM,SAAS,WAAW;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAE3C,MAAM,CAAC,GAAG,SAAS,MAAM,MAAM,EACpC,SAAS,EAAE,IAAI,EACf,SAAS,EAAE,GAAG,EACd,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAgB5B,IAAI,CAAC,GAAG,SAAS,MAAM,MAAM,EAClC,SAAS,EAAE,GAAG,EACd,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;CAIpC;AAED;;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;IAE7B,MAAM,CAAC,EAAE,aAAa,CAAC,GAAG,CAAC,CAAa;;IAYxC,SAAS,IAAI,0BAA0B;IAa9C,IAAW,WAAW,IAAI,kBAAkB,CAE3C;IAED,IAAW,OAAO,IAAI,YAAY,CAEjC;CACF"}
@@ -0,0 +1,79 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { ConfigurableModule } from "@proto-kit/common";
11
+ import { container, injectable } from "tsyringe";
12
+ import { RuntimeMethodExecutionContext, RuntimeMethodExecutionDataStruct, } from "@proto-kit/protocol";
13
+ import { Provable, Bool } from "o1js";
14
+ import { runtimeMethodNamesMetadataKey } from "../method/runtimeMethod";
15
+ const errors = {
16
+ inputDataNotSet: () => new Error("Input data for runtime execution not set"),
17
+ };
18
+ export class RuntimeEvents {
19
+ constructor(events) {
20
+ this.events = events;
21
+ }
22
+ emitIf(condition, eventName, event) {
23
+ if (this.events === undefined) {
24
+ throw new Error("'events' property not defined, make sure to define the event types on your runtimemodule");
25
+ }
26
+ const eventType = this.events[eventName];
27
+ if (typeof eventName !== "string") {
28
+ throw new Error("Only string");
29
+ }
30
+ return container
31
+ .resolve(RuntimeMethodExecutionContext)
32
+ .addEvent(eventType, event, eventName, condition);
33
+ }
34
+ emit(eventName, event) {
35
+ this.emitIf(Bool(true), eventName, event);
36
+ }
37
+ }
38
+ /**
39
+ * Base class for runtime modules providing the necessary utilities.
40
+ */
41
+ export let RuntimeModule = class RuntimeModule extends ConfigurableModule {
42
+ constructor() {
43
+ super();
44
+ /**
45
+ * Holds all method names that are callable throw transactions
46
+ */
47
+ this.runtimeMethodNames = [];
48
+ /**
49
+ * This property exists only to typecheck that the RuntimeModule
50
+ * was extended correctly in e.g. a decorator. We need at least
51
+ * one non-optional property in this class to make the typechecking work.
52
+ */
53
+ this.isRuntimeModule = true;
54
+ this.events = undefined;
55
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
56
+ const methodNames = Reflect.getMetadata(runtimeMethodNamesMetadataKey, this);
57
+ this.runtimeMethodNames = methodNames ?? [];
58
+ }
59
+ getInputs() {
60
+ return Provable.witness(RuntimeMethodExecutionDataStruct, () => {
61
+ const { input } = container.resolve(RuntimeMethodExecutionContext);
62
+ if (input === undefined) {
63
+ throw errors.inputDataNotSet();
64
+ }
65
+ return input;
66
+ });
67
+ }
68
+ get transaction() {
69
+ return this.getInputs().transaction;
70
+ }
71
+ get network() {
72
+ return this.getInputs().networkState;
73
+ }
74
+ };
75
+ RuntimeModule.presets = {};
76
+ RuntimeModule = __decorate([
77
+ injectable(),
78
+ __metadata("design:paramtypes", [])
79
+ ], RuntimeModule);
@@ -0,0 +1,15 @@
1
+ import { Field } from "o1js";
2
+ import { SimpleAsyncStateService } from "@proto-kit/protocol";
3
+ /**
4
+ * Naive implementation of an in-memory variant of the StateService interface
5
+ */
6
+ export declare class InMemoryStateService implements SimpleAsyncStateService {
7
+ /**
8
+ * This mapping container null values if the specific entry has been deleted.
9
+ * This is used by the CachedState service to keep track of deletions
10
+ */
11
+ values: Record<string, Field[] | null>;
12
+ get(key: Field): Promise<Field[] | undefined>;
13
+ set(key: Field, value: Field[] | undefined): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=InMemoryStateService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InMemoryStateService.d.ts","sourceRoot":"","sources":["../../src/state/InMemoryStateService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;GAEG;AACH,qBAAa,oBAAqB,YAAW,uBAAuB;IAClE;;;OAGG;IACI,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,CAAM;IAEtC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,SAAS,CAAC;IAI7C,GAAG,CAAC,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,SAAS;CAOxD"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Naive implementation of an in-memory variant of the StateService interface
3
+ */
4
+ export class InMemoryStateService {
5
+ constructor() {
6
+ /**
7
+ * This mapping container null values if the specific entry has been deleted.
8
+ * This is used by the CachedState service to keep track of deletions
9
+ */
10
+ this.values = {};
11
+ }
12
+ async get(key) {
13
+ return this.values[key.toString()] ?? undefined;
14
+ }
15
+ async set(key, value) {
16
+ if (value === undefined) {
17
+ this.values[key.toString()] = null;
18
+ }
19
+ else {
20
+ this.values[key.toString()] = value;
21
+ }
22
+ }
23
+ }
@@ -0,0 +1,7 @@
1
+ import type { RuntimeModule } from "../runtime/RuntimeModule.js";
2
+ /**
3
+ * Decorates a runtime module property as state, passing down some
4
+ * underlying values to improve developer experience.
5
+ */
6
+ export declare function state(): <TargetRuntimeModule extends RuntimeModule<unknown>>(target: TargetRuntimeModule, propertyKey: string) => void;
7
+ //# sourceMappingURL=decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator.d.ts","sourceRoot":"","sources":["../../src/state/decorator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAgBjE;;;GAGG;AACH,wBAAgB,KAAK,mGAGJ,MAAM,UAmCtB"}
@@ -0,0 +1,39 @@
1
+ import { Path } from "@proto-kit/protocol";
2
+ const errors = {
3
+ missingName: (className) => new Error(`Unable to provide a unique identifier for state, ${className} is missing a name.
4
+ Did you forget to extend your runtime module with 'extends RuntimeModule'?`),
5
+ missingRuntime: (className) => new Error(`Unable to provide 'runtime' for state, ${className} is missing a name.
6
+ Did you forget to extend your runtime module with 'extends RuntimeModule'?`),
7
+ };
8
+ /**
9
+ * Decorates a runtime module property as state, passing down some
10
+ * underlying values to improve developer experience.
11
+ */
12
+ export function state() {
13
+ return (target, propertyKey) => {
14
+ let value;
15
+ Object.defineProperty(target, propertyKey, {
16
+ enumerable: true,
17
+ get: function get() {
18
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
19
+ const self = this;
20
+ if (self.name === undefined) {
21
+ throw errors.missingName(self.constructor.name);
22
+ }
23
+ if (!self.runtime) {
24
+ throw errors.missingRuntime(self.constructor.name);
25
+ }
26
+ const path = Path.fromProperty(self.name, propertyKey);
27
+ if (value) {
28
+ value.path = path;
29
+ // TODO: why is this complaining about `any`?
30
+ value.stateServiceProvider = self.runtime.stateServiceProvider;
31
+ }
32
+ return value;
33
+ },
34
+ set: (newValue) => {
35
+ value = newValue;
36
+ },
37
+ });
38
+ };
39
+ }
@@ -0,0 +1 @@
1
+ module.exports = require("../../jest.config.cjs");
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@proto-kit/module",
3
+ "license": "MIT",
4
+ "private": false,
5
+ "version": "0.1.1-develop.1086+eeb4563a",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "tsc -p tsconfig.json",
9
+ "dev": "tsc -p tsconfig.json --watch",
10
+ "lint": "eslint ./src ./test",
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 -- ./test/**",
13
+ "test:watch": "npm run test:file -- ./test/** --watch"
14
+ },
15
+ "main": "dist/index.js",
16
+ "publishConfig": {
17
+ "access": "public"
18
+ },
19
+ "dependencies": {
20
+ "lodash": "^4.17.21",
21
+ "loglevel": "^1.8.1",
22
+ "reflect-metadata": "^0.1.13"
23
+ },
24
+ "devDependencies": {
25
+ "@jest/globals": "^29.5.0",
26
+ "@types/lodash": "^4.14.194"
27
+ },
28
+ "peerDependencies": {
29
+ "@proto-kit/common": "*",
30
+ "@proto-kit/protocol": "*",
31
+ "o1js": "^1.1.0",
32
+ "tsyringe": "^4.7.0"
33
+ },
34
+ "gitHead": "eeb4563a685b29525358ec7404fa9f0251d258d4"
35
+ }
@@ -0,0 +1,13 @@
1
+ import { DependencyFactory, DependencyRecord } from "@proto-kit/common";
2
+
3
+ import { MethodIdResolver } from "../runtime/MethodIdResolver";
4
+
5
+ export class MethodIdFactory implements DependencyFactory {
6
+ public dependencies() {
7
+ return {
8
+ methodIdResolver: {
9
+ useClass: MethodIdResolver,
10
+ },
11
+ } satisfies DependencyRecord;
12
+ }
13
+ }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ export * from "./method/runtimeMethod";
2
+ export * from "./module/decorator";
3
+ export * from "./runtime/RuntimeModule";
4
+ export * from "./runtime/RuntimeEnvironment";
5
+ export * from "./runtime/Runtime";
6
+ export * from "./state/InMemoryStateService";
7
+ export * from "./state/decorator";
8
+ export * from "./method/MethodParameterEncoder";
9
+ export * from "./runtime/MethodIdResolver";
10
+ export * from "./factories/MethodIdFactory";
@@ -0,0 +1,252 @@
1
+ /* eslint-disable @typescript-eslint/consistent-type-assertions */
2
+ import {
3
+ Field,
4
+ Proof,
5
+ Provable,
6
+ DynamicProof,
7
+ FlexibleProvablePure,
8
+ } from "o1js";
9
+ import {
10
+ ArgumentTypes,
11
+ ProofTypes,
12
+ ToFieldableStatic,
13
+ TypedClass,
14
+ filterNonUndefined,
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 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
+ }
75
+
76
+ export class MethodParameterEncoder {
77
+ public static fromMethod(target: RuntimeModule<unknown>, methodName: string) {
78
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
79
+ const paramtypes: ArgTypeArray = Reflect.getMetadata(
80
+ "design:paramtypes",
81
+ target,
82
+ methodName
83
+ );
84
+
85
+ if (paramtypes === undefined) {
86
+ throw new Error(
87
+ `Method with name ${methodName} doesn't exist on this module`
88
+ );
89
+ }
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
+
106
+ return new MethodParameterEncoder(paramtypes);
107
+ }
108
+
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
+ }
116
+ // as any, since we shouldn't be using this workaround in the first place
117
+ return (type as FlexibleProvablePure<unknown>).sizeInFields();
118
+ }
119
+
120
+ public constructor(private readonly types: ArgTypeArray) {}
121
+
122
+ public decode(fields: Field[], auxiliary: string[]): Promise<ArgArray> {
123
+ if (fields.length < this.fieldSize()) {
124
+ throw errors.fieldLengthNotMatching(this.fieldSize(), fields.length);
125
+ }
126
+
127
+ let stack = fields.slice();
128
+ const auxiliaryStack = auxiliary.slice();
129
+
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
+ );
178
+ }
179
+
180
+ /**
181
+ * Variant of encode() for provable code that skips the unprovable
182
+ * json encoding
183
+ */
184
+ public encode(args: ArgumentTypes) {
185
+ /**
186
+ * Use the type info obtained previously to convert
187
+ * the args passed to fields
188
+ */
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
+ }
222
+
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
+ );
244
+ }
245
+
246
+ public fieldSize(): number {
247
+ return this.types
248
+ .map((type) => MethodParameterEncoder.fieldSize(type) ?? 0)
249
+ .reduce((a, b) => a + b, 0);
250
+ }
251
+ }
252
+ /* eslint-enable @typescript-eslint/consistent-type-assertions */