@proto-kit/module 0.1.1-develop.651 → 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.
- package/LICENSE.md +201 -201
- package/dist/method/MethodParameterDecoder.d.ts +10 -10
- package/dist/method/MethodParameterDecoder.js +40 -40
- package/dist/method/MethodParameterEncoder.d.ts +15 -8
- package/dist/method/MethodParameterEncoder.d.ts.map +1 -1
- package/dist/method/MethodParameterEncoder.js +122 -51
- package/dist/method/runtimeMethod.d.ts +6 -5
- package/dist/method/runtimeMethod.d.ts.map +1 -1
- package/dist/method/runtimeMethod.js +7 -17
- package/dist/runtime/MethodIdResolver.d.ts.map +1 -1
- package/dist/runtime/MethodIdResolver.js +2 -2
- package/dist/runtime/Runtime.d.ts +5 -5
- package/dist/runtime/Runtime.d.ts.map +1 -1
- package/dist/runtime/Runtime.js +16 -23
- package/dist/runtime/RuntimeEnvironment.d.ts +2 -2
- package/dist/runtime/RuntimeEnvironment.d.ts.map +1 -1
- package/dist/runtime/RuntimeModule.d.ts.map +1 -1
- package/dist/runtime/RuntimeModule.js +2 -3
- package/dist/src/factories/MethodIdFactory.d.ts +10 -0
- package/dist/src/factories/MethodIdFactory.d.ts.map +1 -0
- package/dist/src/factories/MethodIdFactory.js +10 -0
- package/dist/src/index.d.ts +11 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +10 -0
- package/dist/src/method/MethodParameterEncoder.d.ts +22 -0
- package/dist/src/method/MethodParameterEncoder.d.ts.map +1 -0
- package/dist/src/method/MethodParameterEncoder.js +103 -0
- package/dist/src/method/runtimeMethod.d.ts +26 -0
- package/dist/src/method/runtimeMethod.d.ts.map +1 -0
- package/dist/src/method/runtimeMethod.js +164 -0
- package/dist/src/module/decorator.d.ts +8 -0
- package/dist/src/module/decorator.d.ts.map +1 -0
- package/dist/src/module/decorator.js +15 -0
- package/dist/src/runtime/MethodIdResolver.d.ts +20 -0
- package/dist/src/runtime/MethodIdResolver.d.ts.map +1 -0
- package/dist/src/runtime/MethodIdResolver.js +100 -0
- package/dist/src/runtime/Runtime.d.ts +71 -0
- package/dist/src/runtime/Runtime.d.ts.map +1 -0
- package/dist/src/runtime/Runtime.js +215 -0
- package/dist/src/runtime/RuntimeEnvironment.d.ts +10 -0
- package/dist/src/runtime/RuntimeEnvironment.d.ts.map +1 -0
- package/dist/src/runtime/RuntimeEnvironment.js +1 -0
- package/dist/src/runtime/RuntimeModule.d.ts +26 -0
- package/dist/src/runtime/RuntimeModule.d.ts.map +1 -0
- package/dist/src/runtime/RuntimeModule.js +85 -0
- package/dist/src/state/InMemoryStateService.d.ts +15 -0
- package/dist/src/state/InMemoryStateService.d.ts.map +1 -0
- package/dist/src/state/InMemoryStateService.js +28 -0
- package/dist/src/state/decorator.d.ts +7 -0
- package/dist/src/state/decorator.d.ts.map +1 -0
- package/dist/src/state/decorator.js +39 -0
- package/dist/state/InMemoryStateService.d.ts +10 -6
- package/dist/state/InMemoryStateService.d.ts.map +1 -1
- package/dist/state/InMemoryStateService.js +10 -8
- package/dist/state/decorator.d.ts.map +1 -1
- package/dist/state/decorator.js +0 -3
- package/dist/test/Runtime.test.d.ts +2 -0
- package/dist/test/Runtime.test.d.ts.map +1 -0
- package/dist/test/Runtime.test.js +24 -0
- package/dist/test/TestingRuntime.d.ts +7 -0
- package/dist/test/TestingRuntime.d.ts.map +1 -0
- package/dist/test/TestingRuntime.js +29 -0
- package/dist/test/method/runtimeMethod.test.d.ts +2 -0
- package/dist/test/method/runtimeMethod.test.d.ts.map +1 -0
- package/dist/test/method/runtimeMethod.test.js +30 -0
- package/dist/test/modules/Admin.d.ts +10 -0
- package/dist/test/modules/Admin.d.ts.map +1 -0
- package/dist/test/modules/Admin.js +29 -0
- package/dist/test/modules/Balances.d.ts +23 -0
- package/dist/test/modules/Balances.d.ts.map +1 -0
- package/dist/test/modules/Balances.js +98 -0
- package/dist/test/modules/Balances.test.d.ts +2 -0
- package/dist/test/modules/Balances.test.d.ts.map +1 -0
- package/dist/test/modules/Balances.test.js +201 -0
- package/dist/test/modules/MethodIdResolver.test.d.ts +2 -0
- package/dist/test/modules/MethodIdResolver.test.d.ts.map +1 -0
- package/dist/test/modules/MethodIdResolver.test.js +67 -0
- package/dist/test/modules/State.test.d.ts +2 -0
- package/dist/test/modules/State.test.d.ts.map +1 -0
- package/dist/test/modules/State.test.js +42 -0
- package/dist/test/runtimeMethod.test.d.ts +2 -0
- package/dist/test/runtimeMethod.test.d.ts.map +1 -0
- package/dist/test/runtimeMethod.test.js +50 -0
- package/package.json +5 -5
- package/src/method/MethodParameterEncoder.ts +186 -84
- package/src/method/runtimeMethod.ts +19 -30
- package/src/runtime/MethodIdResolver.ts +1 -0
- package/src/runtime/Runtime.ts +27 -29
- package/src/runtime/RuntimeEnvironment.ts +4 -7
- package/src/runtime/RuntimeModule.ts +2 -8
- package/src/state/InMemoryStateService.ts +13 -13
- package/src/state/decorator.ts +1 -3
- package/test/Runtime.test.ts +68 -41
- package/test/TestingRuntime.ts +45 -0
- package/test/method/MethodParameterEncoder.test.ts +152 -0
- package/{src/method/decorator.test.ts → test/method/runtimeMethod.test.ts} +2 -2
- package/test/modules/Admin.ts +3 -3
- package/test/modules/Balances.test.ts +57 -61
- package/test/modules/Balances.ts +15 -18
- package/test/modules/{methodId.test.ts → MethodIdResolver.test.ts} +14 -23
- package/test/modules/State.test.ts +41 -50
- package/test/runtimeMethod.test.ts +19 -32
- package/test/tsconfig.json +7 -0
- package/tsconfig.json +2 -2
- package/test/transaction.test.ts +0 -82
- package/tsconfig.test.json +0 -9
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
/* eslint-disable
|
|
1
|
+
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
|
2
2
|
import {
|
|
3
3
|
Field,
|
|
4
|
-
FlexibleProvable,
|
|
5
4
|
Proof,
|
|
6
5
|
Provable,
|
|
7
|
-
|
|
6
|
+
DynamicProof,
|
|
7
|
+
FlexibleProvablePure,
|
|
8
8
|
} from "o1js";
|
|
9
9
|
import {
|
|
10
10
|
ArgumentTypes,
|
|
11
11
|
ProofTypes,
|
|
12
|
-
ToFieldable,
|
|
13
12
|
ToFieldableStatic,
|
|
14
|
-
|
|
13
|
+
TypedClass,
|
|
14
|
+
filterNonUndefined,
|
|
15
15
|
} from "@proto-kit/common";
|
|
16
16
|
|
|
17
17
|
import type { RuntimeModule } from "../runtime/RuntimeModule";
|
|
@@ -28,12 +28,55 @@ const errors = {
|
|
|
28
28
|
),
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
type
|
|
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
|
+
}
|
|
32
75
|
|
|
33
76
|
export class MethodParameterEncoder {
|
|
34
77
|
public static fromMethod(target: RuntimeModule<unknown>, methodName: string) {
|
|
35
78
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
36
|
-
const paramtypes:
|
|
79
|
+
const paramtypes: ArgTypeArray = Reflect.getMetadata(
|
|
37
80
|
"design:paramtypes",
|
|
38
81
|
target,
|
|
39
82
|
methodName
|
|
@@ -45,106 +88,165 @@ export class MethodParameterEncoder {
|
|
|
45
88
|
);
|
|
46
89
|
}
|
|
47
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
|
+
|
|
48
106
|
return new MethodParameterEncoder(paramtypes);
|
|
49
107
|
}
|
|
50
108
|
|
|
51
|
-
public static fieldSize(type:
|
|
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
|
+
}
|
|
52
116
|
// as any, since we shouldn't be using this workaround in the first place
|
|
53
|
-
return (type as
|
|
117
|
+
return (type as FlexibleProvablePure<unknown>).sizeInFields();
|
|
54
118
|
}
|
|
55
119
|
|
|
56
|
-
|
|
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
|
-
}
|
|
120
|
+
public constructor(private readonly types: ArgTypeArray) {}
|
|
79
121
|
|
|
80
|
-
public
|
|
81
|
-
if (fields.length < this.fieldSize) {
|
|
82
|
-
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);
|
|
83
125
|
}
|
|
84
126
|
|
|
85
127
|
let stack = fields.slice();
|
|
128
|
+
const auxiliaryStack = auxiliary.slice();
|
|
86
129
|
|
|
87
|
-
return
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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
|
+
);
|
|
96
178
|
}
|
|
97
179
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Variant of encode() for provable code that skips the unprovable
|
|
182
|
+
* json encoding
|
|
183
|
+
*/
|
|
184
|
+
public encode(args: ArgumentTypes) {
|
|
102
185
|
/**
|
|
103
186
|
* Use the type info obtained previously to convert
|
|
104
187
|
* the args passed to fields
|
|
105
188
|
*/
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
+
};
|
|
132
221
|
}
|
|
133
222
|
|
|
134
|
-
const argumentType = this.types[index] as
|
|
135
|
-
return
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
+
);
|
|
143
244
|
}
|
|
144
245
|
|
|
145
|
-
public
|
|
246
|
+
public fieldSize(): number {
|
|
146
247
|
return this.types
|
|
147
248
|
.map((type) => MethodParameterEncoder.fieldSize(type) ?? 0)
|
|
148
249
|
.reduce((a, b) => a + b, 0);
|
|
149
250
|
}
|
|
150
251
|
}
|
|
252
|
+
/* eslint-enable @typescript-eslint/consistent-type-assertions */
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable max-statements */
|
|
2
1
|
import { Bool, Field, Poseidon } from "o1js";
|
|
3
2
|
import { container } from "tsyringe";
|
|
4
3
|
import {
|
|
@@ -6,25 +5,17 @@ import {
|
|
|
6
5
|
ProvableStateTransition,
|
|
7
6
|
MethodPublicOutput,
|
|
8
7
|
RuntimeMethodExecutionContext,
|
|
9
|
-
RuntimeMethodExecutionDataStruct,
|
|
10
|
-
SignedTransaction,
|
|
11
8
|
StateTransitionReductionList,
|
|
12
9
|
} from "@proto-kit/protocol";
|
|
13
10
|
import {
|
|
14
11
|
DecoratedMethod,
|
|
15
12
|
toProver,
|
|
16
13
|
ZkProgrammable,
|
|
17
|
-
ToFieldable,
|
|
18
|
-
ToFieldableStatic,
|
|
19
|
-
ProofTypes,
|
|
20
14
|
ArgumentTypes,
|
|
21
|
-
TypedClass,
|
|
22
|
-
O1JSPrimitive,
|
|
23
15
|
} from "@proto-kit/common";
|
|
24
16
|
|
|
25
17
|
import type { RuntimeModule } from "../runtime/RuntimeModule.js";
|
|
26
|
-
|
|
27
|
-
import { state } from "../state/decorator.js";
|
|
18
|
+
|
|
28
19
|
import { MethodParameterEncoder } from "./MethodParameterEncoder";
|
|
29
20
|
|
|
30
21
|
const errors = {
|
|
@@ -45,7 +36,6 @@ const errors = {
|
|
|
45
36
|
};
|
|
46
37
|
|
|
47
38
|
export function toStateTransitionsHash(
|
|
48
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
49
39
|
stateTransitions: StateTransition<any>[]
|
|
50
40
|
) {
|
|
51
41
|
const stateTransitionsHashList = new StateTransitionReductionList(
|
|
@@ -62,31 +52,33 @@ export function toStateTransitionsHash(
|
|
|
62
52
|
.toField();
|
|
63
53
|
}
|
|
64
54
|
|
|
65
|
-
// eslint-disable-next-line etc/prefer-interface
|
|
66
55
|
export type WrappedMethod = (...args: ArgumentTypes) => MethodPublicOutput;
|
|
56
|
+
export type AsyncWrappedMethod = (
|
|
57
|
+
...args: ArgumentTypes
|
|
58
|
+
) => Promise<MethodPublicOutput>;
|
|
67
59
|
|
|
68
60
|
export function toWrappedMethod(
|
|
69
61
|
this: RuntimeModule<unknown>,
|
|
70
62
|
methodName: string,
|
|
71
|
-
moduleMethod: (...args: ArgumentTypes) =>
|
|
63
|
+
moduleMethod: (...args: ArgumentTypes) => Promise<any>,
|
|
72
64
|
options: {
|
|
73
65
|
invocationType: RuntimeMethodInvocationType;
|
|
74
66
|
}
|
|
75
|
-
) {
|
|
67
|
+
): AsyncWrappedMethod {
|
|
76
68
|
const executionContext = container.resolve<RuntimeMethodExecutionContext>(
|
|
77
69
|
RuntimeMethodExecutionContext
|
|
78
70
|
);
|
|
79
71
|
|
|
80
|
-
const wrappedMethod:
|
|
81
|
-
|
|
72
|
+
const wrappedMethod: AsyncWrappedMethod = async (
|
|
73
|
+
...args
|
|
74
|
+
): Promise<MethodPublicOutput> => {
|
|
75
|
+
await Reflect.apply(moduleMethod, this, args);
|
|
82
76
|
const {
|
|
83
77
|
result: { stateTransitions, status },
|
|
84
78
|
} = executionContext.current();
|
|
85
79
|
|
|
86
80
|
const stateTransitionsHash = toStateTransitionsHash(stateTransitions);
|
|
87
81
|
|
|
88
|
-
const input = this.getInputs();
|
|
89
|
-
|
|
90
82
|
const { name, runtime } = this;
|
|
91
83
|
|
|
92
84
|
if (name === undefined) {
|
|
@@ -114,17 +106,13 @@ export function toWrappedMethod(
|
|
|
114
106
|
* Use the type info obtained previously to convert
|
|
115
107
|
* the args passed to fields
|
|
116
108
|
*/
|
|
117
|
-
const {
|
|
109
|
+
const { fields } = MethodParameterEncoder.fromMethod(
|
|
118
110
|
this,
|
|
119
111
|
methodName
|
|
120
112
|
).encode(args);
|
|
121
113
|
|
|
122
114
|
// Assert that the argsHash that has been signed matches the given arguments
|
|
123
|
-
|
|
124
|
-
// i.e. the result of the if-statement will be the same for all executions
|
|
125
|
-
// of this method
|
|
126
|
-
const argsHash =
|
|
127
|
-
(args ?? []).length > 0 ? Poseidon.hash(argsFields) : Field(0);
|
|
115
|
+
const argsHash = Poseidon.hash(fields);
|
|
128
116
|
|
|
129
117
|
transaction.argsHash.assertEquals(
|
|
130
118
|
argsHash,
|
|
@@ -190,7 +178,10 @@ function runtimeMethodInternal(options: {
|
|
|
190
178
|
return (
|
|
191
179
|
target: RuntimeModule<unknown>,
|
|
192
180
|
methodName: string,
|
|
193
|
-
descriptor:
|
|
181
|
+
descriptor: TypedPropertyDescriptor<
|
|
182
|
+
// TODO Limit possible parameter types
|
|
183
|
+
(...args: any[]) => Promise<any>
|
|
184
|
+
>
|
|
194
185
|
) => {
|
|
195
186
|
const executionContext = container.resolve<RuntimeMethodExecutionContext>(
|
|
196
187
|
RuntimeMethodExecutionContext
|
|
@@ -220,7 +211,7 @@ function runtimeMethodInternal(options: {
|
|
|
220
211
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
221
212
|
const simulatedMethod = descriptor.value as DecoratedMethod;
|
|
222
213
|
|
|
223
|
-
descriptor.value = function value(
|
|
214
|
+
descriptor.value = async function value(
|
|
224
215
|
this: RuntimeModule<unknown>,
|
|
225
216
|
...args: ArgumentTypes
|
|
226
217
|
) {
|
|
@@ -244,7 +235,7 @@ function runtimeMethodInternal(options: {
|
|
|
244
235
|
* RuntimeMethodExecutionContext state, meaning it enters and exits
|
|
245
236
|
* the context properly.
|
|
246
237
|
*/
|
|
247
|
-
|
|
238
|
+
|
|
248
239
|
async function prover(this: ZkProgrammable<any, any>) {
|
|
249
240
|
executionContext.beforeMethod(constructorName, methodName, args);
|
|
250
241
|
const innerProver = toProver(
|
|
@@ -253,7 +244,6 @@ function runtimeMethodInternal(options: {
|
|
|
253
244
|
false,
|
|
254
245
|
...args
|
|
255
246
|
).bind(this);
|
|
256
|
-
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
257
247
|
let result: Awaited<ReturnType<typeof innerProver>>;
|
|
258
248
|
try {
|
|
259
249
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
@@ -274,10 +264,9 @@ function runtimeMethodInternal(options: {
|
|
|
274
264
|
executionContext.setProver(prover.bind(this.runtime.zkProgrammable));
|
|
275
265
|
}
|
|
276
266
|
|
|
277
|
-
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
278
267
|
let result: unknown;
|
|
279
268
|
try {
|
|
280
|
-
result = Reflect.apply(simulatedMethod, this, args);
|
|
269
|
+
result = await Reflect.apply(simulatedMethod, this, args);
|
|
281
270
|
} finally {
|
|
282
271
|
executionContext.afterMethod();
|
|
283
272
|
}
|
|
@@ -53,6 +53,7 @@ export class MethodIdResolver {
|
|
|
53
53
|
const rawMappings = this.runtime.moduleNames.flatMap((moduleName) => {
|
|
54
54
|
const module = this.runtime.resolve(moduleName);
|
|
55
55
|
return module.runtimeMethodNames.map((method) => {
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
56
57
|
const type = Reflect.getMetadata(
|
|
57
58
|
runtimeMethodTypeMetadataKey,
|
|
58
59
|
module,
|
package/src/runtime/Runtime.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { Experimental } from "o1js";
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument */
|
|
2
|
+
import { ZkProgram } from "o1js";
|
|
4
3
|
import { DependencyContainer, injectable } from "tsyringe";
|
|
5
4
|
import {
|
|
6
5
|
StringKeyOf,
|
|
@@ -16,7 +15,7 @@ import {
|
|
|
16
15
|
import {
|
|
17
16
|
MethodPublicOutput,
|
|
18
17
|
StateServiceProvider,
|
|
19
|
-
|
|
18
|
+
SimpleAsyncStateService,
|
|
20
19
|
} from "@proto-kit/protocol";
|
|
21
20
|
|
|
22
21
|
import {
|
|
@@ -24,7 +23,7 @@ import {
|
|
|
24
23
|
isRuntimeMethod,
|
|
25
24
|
runtimeMethodTypeMetadataKey,
|
|
26
25
|
toWrappedMethod,
|
|
27
|
-
|
|
26
|
+
AsyncWrappedMethod,
|
|
28
27
|
} from "../method/runtimeMethod";
|
|
29
28
|
import { MethodIdFactory } from "../factories/MethodIdFactory";
|
|
30
29
|
|
|
@@ -33,14 +32,16 @@ import { MethodIdResolver } from "./MethodIdResolver";
|
|
|
33
32
|
import { RuntimeEnvironment } from "./RuntimeEnvironment";
|
|
34
33
|
|
|
35
34
|
export function getAllPropertyNames(obj: any) {
|
|
35
|
+
let currentPrototype: any | undefined = obj;
|
|
36
36
|
let keys: (string | symbol)[] = [];
|
|
37
37
|
// if primitive (primitives still have keys) skip the first iteration
|
|
38
38
|
if (!(obj instanceof Object)) {
|
|
39
|
-
|
|
39
|
+
currentPrototype = Object.getPrototypeOf(obj);
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
42
|
+
while (currentPrototype) {
|
|
43
|
+
keys = keys.concat(Reflect.ownKeys(currentPrototype));
|
|
44
|
+
currentPrototype = Object.getPrototypeOf(currentPrototype);
|
|
44
45
|
}
|
|
45
46
|
return keys;
|
|
46
47
|
}
|
|
@@ -69,9 +70,8 @@ export interface RuntimeDefinition<Modules extends RuntimeModulesRecord> {
|
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
export class RuntimeZkProgrammable<
|
|
72
|
-
Modules extends RuntimeModulesRecord
|
|
73
|
+
Modules extends RuntimeModulesRecord,
|
|
73
74
|
> extends ZkProgrammable<undefined, MethodPublicOutput> {
|
|
74
|
-
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
|
75
75
|
public constructor(public runtime: Runtime<Modules>) {
|
|
76
76
|
super();
|
|
77
77
|
}
|
|
@@ -85,13 +85,13 @@ export class RuntimeZkProgrammable<
|
|
|
85
85
|
string,
|
|
86
86
|
{
|
|
87
87
|
privateInputs: any;
|
|
88
|
-
method:
|
|
88
|
+
method: AsyncWrappedMethod;
|
|
89
89
|
}
|
|
90
90
|
>;
|
|
91
91
|
// We need to use explicit type annotations here,
|
|
92
92
|
// therefore we can't use destructuring
|
|
93
|
-
|
|
94
|
-
// eslint-disable-next-line
|
|
93
|
+
|
|
94
|
+
// eslint-disable-next-line prefer-destructuring
|
|
95
95
|
const runtime: Runtime<Modules> = this.runtime;
|
|
96
96
|
|
|
97
97
|
const runtimeMethods = runtime.runtimeModuleNames.reduce<Methods>(
|
|
@@ -106,15 +106,15 @@ export class RuntimeZkProgrammable<
|
|
|
106
106
|
* regarding resolving only known modules. We assert in the line above
|
|
107
107
|
* but we cast it to any anyways to satisfy the proof system.
|
|
108
108
|
*/
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
111
111
|
const runtimeModule = runtime.resolve(runtimeModuleName as any);
|
|
112
112
|
|
|
113
|
-
// eslint-disable-next-line max-len
|
|
114
113
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
115
114
|
const modulePrototype = Object.getPrototypeOf(runtimeModule) as Record<
|
|
116
115
|
string,
|
|
117
|
-
|
|
116
|
+
// Technically not all methods have to be async, but for this context it's ok
|
|
117
|
+
(...args: unknown[]) => Promise<unknown>
|
|
118
118
|
>;
|
|
119
119
|
|
|
120
120
|
const modulePrototypeMethods = getAllPropertyNames(runtimeModule).map(
|
|
@@ -135,13 +135,12 @@ export class RuntimeZkProgrammable<
|
|
|
135
135
|
methodName
|
|
136
136
|
);
|
|
137
137
|
|
|
138
|
-
const wrappedMethod = Reflect.apply(
|
|
138
|
+
const wrappedMethod: AsyncWrappedMethod = Reflect.apply(
|
|
139
139
|
toWrappedMethod,
|
|
140
140
|
runtimeModule,
|
|
141
141
|
[methodName, method, { invocationType }]
|
|
142
142
|
);
|
|
143
143
|
|
|
144
|
-
// eslint-disable-next-line no-warning-comments
|
|
145
144
|
// TODO: find out how to import the Tuple type
|
|
146
145
|
|
|
147
146
|
const privateInputs = Reflect.getMetadata(
|
|
@@ -174,16 +173,16 @@ export class RuntimeZkProgrammable<
|
|
|
174
173
|
);
|
|
175
174
|
|
|
176
175
|
const sortedRuntimeMethods = Object.fromEntries(
|
|
177
|
-
// eslint-disable-next-line @typescript-eslint/require-array-sort-compare
|
|
178
176
|
Object.entries(runtimeMethods).sort()
|
|
179
177
|
);
|
|
180
178
|
|
|
181
|
-
const program =
|
|
179
|
+
const program = ZkProgram({
|
|
180
|
+
name: "RuntimeProgram",
|
|
182
181
|
publicOutput: MethodPublicOutput,
|
|
183
182
|
methods: sortedRuntimeMethods,
|
|
184
183
|
});
|
|
185
184
|
|
|
186
|
-
const SelfProof =
|
|
185
|
+
const SelfProof = ZkProgram.Proof(program);
|
|
187
186
|
|
|
188
187
|
const methods = Object.keys(sortedRuntimeMethods).reduce<
|
|
189
188
|
Record<string, any>
|
|
@@ -222,7 +221,7 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
222
221
|
}
|
|
223
222
|
|
|
224
223
|
// runtime modules composed into a ZkProgram
|
|
225
|
-
public program?: ReturnType<typeof
|
|
224
|
+
public program?: ReturnType<typeof ZkProgram>;
|
|
226
225
|
|
|
227
226
|
public definition: RuntimeDefinition<Modules>;
|
|
228
227
|
|
|
@@ -239,7 +238,6 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
239
238
|
this.zkProgrammable = new RuntimeZkProgrammable<Modules>(this);
|
|
240
239
|
}
|
|
241
240
|
|
|
242
|
-
// eslint-disable-next-line no-warning-comments
|
|
243
241
|
// TODO Remove after changing DFs to type-based approach
|
|
244
242
|
public create(childContainerProvider: ChildContainerProvider) {
|
|
245
243
|
super.create(childContainerProvider);
|
|
@@ -257,7 +255,7 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
257
255
|
);
|
|
258
256
|
}
|
|
259
257
|
|
|
260
|
-
public get stateService():
|
|
258
|
+
public get stateService(): SimpleAsyncStateService {
|
|
261
259
|
return this.stateServiceProvider.stateService;
|
|
262
260
|
}
|
|
263
261
|
|
|
@@ -278,7 +276,7 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
278
276
|
*/
|
|
279
277
|
public getMethodById(
|
|
280
278
|
methodId: bigint
|
|
281
|
-
): ((...args: unknown[]) => unknown) | undefined {
|
|
279
|
+
): ((...args: unknown[]) => Promise<unknown>) | undefined {
|
|
282
280
|
const methodDescriptor =
|
|
283
281
|
this.methodIdResolver.getMethodNameFromId(methodId);
|
|
284
282
|
|
|
@@ -290,15 +288,14 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
290
288
|
this.assertIsValidModuleName(moduleName);
|
|
291
289
|
const module = this.resolve(moduleName);
|
|
292
290
|
|
|
293
|
-
// eslint-disable-next-line
|
|
294
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions,@typescript-eslint/no-unsafe-member-access
|
|
291
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
295
292
|
const method = (module as any)[methodName];
|
|
296
293
|
if (method === undefined) {
|
|
297
294
|
throw errors.methodNotFound(`${moduleName}.${methodName}`);
|
|
298
295
|
}
|
|
299
296
|
|
|
300
297
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
301
|
-
return (method as (...args: unknown[]) => unknown).bind(module);
|
|
298
|
+
return (method as (...args: unknown[]) => Promise<unknown>).bind(module);
|
|
302
299
|
}
|
|
303
300
|
|
|
304
301
|
/**
|
|
@@ -325,3 +322,4 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
325
322
|
return Object.keys(this.definition.modules);
|
|
326
323
|
}
|
|
327
324
|
}
|
|
325
|
+
/* eslint-enable @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-argument */
|