@proto-kit/module 0.1.1-develop.456 → 0.1.1-develop.600
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 +1 -1
- package/dist/index.js +1 -1
- package/dist/method/MethodParameterEncoder.d.ts +17 -0
- package/dist/method/MethodParameterEncoder.d.ts.map +1 -0
- package/dist/method/MethodParameterEncoder.js +90 -0
- package/dist/method/runtimeMethod.d.ts +6 -1
- package/dist/method/runtimeMethod.d.ts.map +1 -1
- package/dist/method/runtimeMethod.js +27 -25
- package/dist/runtime/MethodIdResolver.d.ts.map +1 -1
- package/dist/runtime/MethodIdResolver.js +3 -4
- package/dist/runtime/Runtime.js +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -1
- package/src/method/MethodParameterEncoder.ts +141 -0
- package/src/method/runtimeMethod.ts +43 -35
- package/src/runtime/MethodIdResolver.ts +3 -11
- package/src/runtime/Runtime.ts +1 -1
- package/test/runtimeMethod.test.ts +2 -2
- package/src/method/MethodParameterDecoder.ts +0 -62
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/
|
|
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/
|
|
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,EAAE,KAAK,EAAE,gBAAgB,EAAS,gBAAgB,EAAE,MAAM,MAAM,CAAC;AACxE,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;IAyCD,IAAW,SAAS,IAAI,MAAM,CAI7B;CACF"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
|
2
|
+
import { Proof } 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
|
+
const argsJSON = args.map((argument, index) => {
|
|
74
|
+
if (argument instanceof Proof) {
|
|
75
|
+
return JSON.stringify(argument.toJSON());
|
|
76
|
+
}
|
|
77
|
+
const argumentType = this.types[index];
|
|
78
|
+
return JSON.stringify(argumentType.toJSON(argument));
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
argsFields,
|
|
82
|
+
argsJSON,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
get fieldSize() {
|
|
86
|
+
return this.types
|
|
87
|
+
.map((type) => MethodParameterEncoder.fieldSize(type) ?? 0)
|
|
88
|
+
.reduce((a, b) => a + b, 0);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -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
|
|
6
|
+
export declare function toWrappedMethod(this: RuntimeModule<unknown>, methodName: string, moduleMethod: (...args: ArgumentTypes) => unknown, methodArguments: ArgumentTypes, 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":"
|
|
1
|
+
{"version":3,"file":"runtimeMethod.d.ts","sourceRoot":"","sources":["../../src/method/runtimeMethod.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,eAAe,EAGf,kBAAkB,EAGnB,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,EAC9B,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;AAwG3E,wBAAgB,cAAc,iGAI7B;AAED,wBAAgB,aAAa,iGAI5B"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/* eslint-disable max-statements */
|
|
2
|
-
import { Field, Poseidon,
|
|
2
|
+
import { Bool, Field, Poseidon, } from "o1js";
|
|
3
3
|
import { container } from "tsyringe";
|
|
4
4
|
import { DefaultProvableHashList, ProvableStateTransition, MethodPublicOutput, RuntimeMethodExecutionContext, } 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"),
|
|
@@ -18,7 +19,7 @@ stateTransitions) {
|
|
|
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, methodArguments, options) {
|
|
22
23
|
const executionContext = container.resolve(RuntimeMethodExecutionContext);
|
|
23
24
|
const wrappedMethod = (...args) => {
|
|
24
25
|
Reflect.apply(moduleMethod, this, args);
|
|
@@ -34,47 +35,35 @@ export function toWrappedMethod(methodName, moduleMethod, methodArguments) {
|
|
|
34
35
|
if (runtime === undefined) {
|
|
35
36
|
throw errors.runtimeNotProvided(name);
|
|
36
37
|
}
|
|
37
|
-
|
|
38
|
+
const { transaction, networkState } = executionContext.witnessInput();
|
|
38
39
|
const { methodIdResolver } = runtime;
|
|
40
|
+
// Assert that the given transaction has the correct methodId
|
|
39
41
|
const thisMethodId = Field(methodIdResolver.getMethodId(name, methodName));
|
|
40
42
|
if (!thisMethodId.isConstant()) {
|
|
41
43
|
throw errors.fieldNotConstant("methodId");
|
|
42
44
|
}
|
|
43
|
-
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
45
|
-
const parameterTypes = Reflect.getMetadata("design:paramtypes", this, methodName);
|
|
45
|
+
transaction.methodId.assertEquals(thisMethodId, "Runtimemethod called with wrong methodId on the transaction object");
|
|
46
46
|
/**
|
|
47
47
|
* Use the type info obtained previously to convert
|
|
48
48
|
* the args passed to fields
|
|
49
49
|
*/
|
|
50
|
-
const argsFields =
|
|
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
|
-
});
|
|
50
|
+
const { argsFields } = MethodParameterEncoder.fromMethod(this, methodName).encode(args);
|
|
65
51
|
// Assert that the argsHash that has been signed matches the given arguments
|
|
66
52
|
// We can use js-if here, because methodArguments is statically sizes
|
|
67
53
|
// i.e. the result of the if-statement will be the same for all executions
|
|
68
54
|
// of this method
|
|
69
55
|
const argsHash = methodArguments.length > 0 ? Poseidon.hash(argsFields) : Field(0);
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
56
|
+
transaction.argsHash.assertEquals(argsHash, "argsHash and therefore arguments of transaction and runtime call does not match");
|
|
57
|
+
const isMessage = Bool(options.invocationType === "INCOMING_MESSAGE");
|
|
58
|
+
transaction.assertTransactionType(Bool(isMessage));
|
|
59
|
+
const transactionHash = transaction.hash();
|
|
60
|
+
const networkStateHash = networkState.hash();
|
|
73
61
|
return new MethodPublicOutput({
|
|
74
62
|
stateTransitionsHash,
|
|
75
63
|
status,
|
|
76
64
|
transactionHash,
|
|
77
65
|
networkStateHash,
|
|
66
|
+
isMessage,
|
|
78
67
|
});
|
|
79
68
|
};
|
|
80
69
|
Object.defineProperty(wrappedMethod, "name", {
|
|
@@ -88,6 +77,7 @@ export function combineMethodName(runtimeModuleName, methodName) {
|
|
|
88
77
|
}
|
|
89
78
|
export const runtimeMethodMetadataKey = "yab-method";
|
|
90
79
|
export const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods";
|
|
80
|
+
export const runtimeMethodTypeMetadataKey = "proto-kit-runtime-method-type";
|
|
91
81
|
/**
|
|
92
82
|
* Checks the metadata of the provided runtime module and its method,
|
|
93
83
|
* to see if it has been decorated with @runtimeMethod()
|
|
@@ -99,7 +89,7 @@ export const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods";
|
|
|
99
89
|
export function isRuntimeMethod(target, propertyKey) {
|
|
100
90
|
return Boolean(Reflect.getMetadata(runtimeMethodMetadataKey, target, propertyKey));
|
|
101
91
|
}
|
|
102
|
-
|
|
92
|
+
function runtimeMethodInternal(options) {
|
|
103
93
|
return (target, methodName, descriptor) => {
|
|
104
94
|
const executionContext = container.resolve(RuntimeMethodExecutionContext);
|
|
105
95
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
@@ -112,6 +102,7 @@ export function runtimeMethod() {
|
|
|
112
102
|
}
|
|
113
103
|
Reflect.defineMetadata(runtimeMethodNamesMetadataKey, data, target);
|
|
114
104
|
Reflect.defineMetadata(runtimeMethodMetadataKey, true, target, methodName);
|
|
105
|
+
Reflect.defineMetadata(runtimeMethodTypeMetadataKey, options.invocationType, target, methodName);
|
|
115
106
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
116
107
|
const simulatedMethod = descriptor.value;
|
|
117
108
|
descriptor.value = function value(...args) {
|
|
@@ -127,6 +118,7 @@ export function runtimeMethod() {
|
|
|
127
118
|
methodName,
|
|
128
119
|
simulatedMethod,
|
|
129
120
|
args,
|
|
121
|
+
options,
|
|
130
122
|
]);
|
|
131
123
|
/**
|
|
132
124
|
* Before the prover runs, make sure it is operating on the correct
|
|
@@ -167,3 +159,13 @@ export function runtimeMethod() {
|
|
|
167
159
|
};
|
|
168
160
|
};
|
|
169
161
|
}
|
|
162
|
+
export function runtimeMessage() {
|
|
163
|
+
return runtimeMethodInternal({
|
|
164
|
+
invocationType: "INCOMING_MESSAGE",
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
export function runtimeMethod() {
|
|
168
|
+
return runtimeMethodInternal({
|
|
169
|
+
invocationType: "SIGNATURE",
|
|
170
|
+
});
|
|
171
|
+
}
|
|
@@ -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;
|
|
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;IAkBrE,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"}
|
|
@@ -21,9 +21,8 @@ let MethodIdResolver = class MethodIdResolver {
|
|
|
21
21
|
constructor(runtime) {
|
|
22
22
|
this.runtime = runtime;
|
|
23
23
|
this.dictionary = {};
|
|
24
|
-
const { modules } = runtime.definition;
|
|
25
24
|
this.dictionary = runtime.runtimeModuleNames.reduce((dict, moduleName) => {
|
|
26
|
-
this.runtime.assertIsValidModuleName(
|
|
25
|
+
this.runtime.assertIsValidModuleName(moduleName);
|
|
27
26
|
runtime.resolve(moduleName).runtimeMethodNames.forEach((methodName) => {
|
|
28
27
|
dict[this.getMethodId(moduleName, methodName).toString()] = {
|
|
29
28
|
moduleName,
|
|
@@ -39,11 +38,11 @@ let MethodIdResolver = class MethodIdResolver {
|
|
|
39
38
|
return undefined;
|
|
40
39
|
}
|
|
41
40
|
const { moduleName, methodName } = methodPath;
|
|
42
|
-
this.runtime.assertIsValidModuleName(
|
|
41
|
+
this.runtime.assertIsValidModuleName(moduleName);
|
|
43
42
|
return [moduleName, methodName];
|
|
44
43
|
}
|
|
45
44
|
getMethodId(moduleName, methodName) {
|
|
46
|
-
this.runtime.assertIsValidModuleName(
|
|
45
|
+
this.runtime.assertIsValidModuleName(moduleName);
|
|
47
46
|
return Poseidon.hash([
|
|
48
47
|
stringToField(moduleName),
|
|
49
48
|
stringToField(methodName),
|
package/dist/runtime/Runtime.js
CHANGED
|
@@ -147,7 +147,7 @@ let Runtime = Runtime_1 = class Runtime extends ModuleContainer {
|
|
|
147
147
|
return undefined;
|
|
148
148
|
}
|
|
149
149
|
const [moduleName, methodName] = methodDescriptor;
|
|
150
|
-
this.assertIsValidModuleName(
|
|
150
|
+
this.assertIsValidModuleName(moduleName);
|
|
151
151
|
const module = this.resolve(moduleName);
|
|
152
152
|
// eslint-disable-next-line max-len
|
|
153
153
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions,@typescript-eslint/no-unsafe-member-access
|
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.
|
|
5
|
+
"version": "0.1.1-develop.600+699a7df",
|
|
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": "
|
|
34
|
+
"gitHead": "699a7dfa3b5d3415ab4500f0cd495d6781365c6a"
|
|
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/
|
|
8
|
+
export * from "./method/MethodParameterEncoder";
|
|
9
9
|
export * from "./runtime/MethodIdResolver";
|
|
10
10
|
export * from "./factories/MethodIdFactory";
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
|
2
|
+
import { Field, FlexibleProvable, Proof, ProvableExtended } from "o1js";
|
|
3
|
+
import {
|
|
4
|
+
ArgumentTypes,
|
|
5
|
+
ProofTypes,
|
|
6
|
+
ToFieldable,
|
|
7
|
+
ToFieldableStatic,
|
|
8
|
+
ToJSONableStatic,
|
|
9
|
+
} from "@proto-kit/common";
|
|
10
|
+
|
|
11
|
+
import type { RuntimeModule } from "../runtime/RuntimeModule";
|
|
12
|
+
|
|
13
|
+
const errors = {
|
|
14
|
+
fieldLengthNotMatching: (expected: number, actual: number) =>
|
|
15
|
+
new Error(`Expected ${expected} field elements, got ${actual}`),
|
|
16
|
+
|
|
17
|
+
typeNotCompatible: (name: string, error?: string) =>
|
|
18
|
+
new Error(
|
|
19
|
+
`Cannot decode type ${name}, it has to be either a Struct, CircuitValue or built-in snarkyjs type.${
|
|
20
|
+
error !== undefined ? `Caused by: ${error}` : ""
|
|
21
|
+
}`
|
|
22
|
+
),
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type ArgsArray = ProvableExtended<unknown>[];
|
|
26
|
+
|
|
27
|
+
export class MethodParameterEncoder {
|
|
28
|
+
public static fromMethod(target: RuntimeModule<unknown>, methodName: string) {
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
30
|
+
const paramtypes: ArgsArray = Reflect.getMetadata(
|
|
31
|
+
"design:paramtypes",
|
|
32
|
+
target,
|
|
33
|
+
methodName
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
if (paramtypes === undefined) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Method with name ${methodName} doesn't exist on this module`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return new MethodParameterEncoder(paramtypes);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public static fieldSize(type: ProvableExtended<unknown>): number | undefined {
|
|
46
|
+
// as any, since we shouldn't be using this workaround in the first place
|
|
47
|
+
return (type as any).prototype._fields?.length ?? type.sizeInFields?.();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private constructor(private readonly types: ArgsArray) {}
|
|
51
|
+
|
|
52
|
+
public decode(argsJSON: string[]): FlexibleProvable<unknown>[] {
|
|
53
|
+
return this.types.map((type, index) => {
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/init-declarations
|
|
55
|
+
let value: FlexibleProvable<unknown>;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
// eslint-disable-next-line max-len
|
|
59
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
60
|
+
value = type.fromJSON(
|
|
61
|
+
JSON.parse(argsJSON[index])
|
|
62
|
+
) as FlexibleProvable<unknown>;
|
|
63
|
+
} catch (e: unknown) {
|
|
64
|
+
if (e instanceof Error) {
|
|
65
|
+
throw errors.typeNotCompatible(type.constructor.name, e.message);
|
|
66
|
+
}
|
|
67
|
+
throw errors.typeNotCompatible(type.constructor.name);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return value;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
public decodeFields(fields: Field[]): ArgumentTypes {
|
|
75
|
+
if (fields.length < this.fieldSize) {
|
|
76
|
+
throw errors.fieldLengthNotMatching(this.fieldSize, fields.length);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
let stack = fields.slice();
|
|
80
|
+
|
|
81
|
+
return this.types.map((type) => {
|
|
82
|
+
const numberFieldsNeeded = MethodParameterEncoder.fieldSize(type) ?? -1;
|
|
83
|
+
if (numberFieldsNeeded === -1) {
|
|
84
|
+
throw errors.typeNotCompatible(type.constructor.name);
|
|
85
|
+
}
|
|
86
|
+
const structFields = stack.slice(0, numberFieldsNeeded);
|
|
87
|
+
stack = stack.slice(numberFieldsNeeded);
|
|
88
|
+
return type.fromFields(structFields, []) as ToFieldable;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public encode(args: ArgumentTypes): {
|
|
93
|
+
argsFields: Field[];
|
|
94
|
+
argsJSON: string[];
|
|
95
|
+
} {
|
|
96
|
+
/**
|
|
97
|
+
* Use the type info obtained previously to convert
|
|
98
|
+
* the args passed to fields
|
|
99
|
+
*/
|
|
100
|
+
const argsFields = args.flatMap((argument, index) => {
|
|
101
|
+
if (argument instanceof Proof) {
|
|
102
|
+
const argumentType = this.types[index] as ProofTypes;
|
|
103
|
+
|
|
104
|
+
const publicOutputType = argumentType?.publicOutputType;
|
|
105
|
+
|
|
106
|
+
const publicInputType = argumentType?.publicInputType;
|
|
107
|
+
|
|
108
|
+
const inputFields =
|
|
109
|
+
publicInputType?.toFields(argument.publicInput) ?? [];
|
|
110
|
+
|
|
111
|
+
const outputFields =
|
|
112
|
+
publicOutputType?.toFields(argument.publicOutput) ?? [];
|
|
113
|
+
|
|
114
|
+
return [...inputFields, ...outputFields];
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const argumentType = this.types[index] as ToFieldableStatic;
|
|
118
|
+
return argumentType.toFields(argument);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const argsJSON = args.map((argument, index) => {
|
|
122
|
+
if (argument instanceof Proof) {
|
|
123
|
+
return JSON.stringify(argument.toJSON());
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const argumentType = this.types[index] as ToJSONableStatic;
|
|
127
|
+
return JSON.stringify(argumentType.toJSON(argument));
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
argsFields,
|
|
132
|
+
argsJSON,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
public get fieldSize(): number {
|
|
137
|
+
return this.types
|
|
138
|
+
.map((type) => MethodParameterEncoder.fieldSize(type) ?? 0)
|
|
139
|
+
.reduce((a, b) => a + b, 0);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/* eslint-disable max-statements */
|
|
2
2
|
import {
|
|
3
|
+
Bool,
|
|
3
4
|
Field,
|
|
4
5
|
FlexibleProvable,
|
|
5
6
|
Poseidon,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
ProvableStateTransition,
|
|
14
15
|
MethodPublicOutput,
|
|
15
16
|
RuntimeMethodExecutionContext,
|
|
17
|
+
SignedTransaction,
|
|
16
18
|
} from "@proto-kit/protocol";
|
|
17
19
|
import {
|
|
18
20
|
DecoratedMethod,
|
|
@@ -27,7 +29,7 @@ import {
|
|
|
27
29
|
} from "@proto-kit/common";
|
|
28
30
|
|
|
29
31
|
import type { RuntimeModule } from "../runtime/RuntimeModule.js";
|
|
30
|
-
import {
|
|
32
|
+
import { MethodParameterEncoder } from "./MethodParameterEncoder";
|
|
31
33
|
|
|
32
34
|
const errors = {
|
|
33
35
|
runtimeNotProvided: (name: string) =>
|
|
@@ -71,7 +73,10 @@ export function toWrappedMethod(
|
|
|
71
73
|
this: RuntimeModule<unknown>,
|
|
72
74
|
methodName: string,
|
|
73
75
|
moduleMethod: (...args: ArgumentTypes) => unknown,
|
|
74
|
-
methodArguments: ArgumentTypes
|
|
76
|
+
methodArguments: ArgumentTypes,
|
|
77
|
+
options: {
|
|
78
|
+
invocationType: RuntimeMethodInvocationType;
|
|
79
|
+
}
|
|
75
80
|
) {
|
|
76
81
|
const executionContext = container.resolve<RuntimeMethodExecutionContext>(
|
|
77
82
|
RuntimeMethodExecutionContext
|
|
@@ -99,49 +104,25 @@ export function toWrappedMethod(
|
|
|
99
104
|
throw errors.runtimeNotProvided(name);
|
|
100
105
|
}
|
|
101
106
|
|
|
102
|
-
|
|
107
|
+
const { transaction, networkState } = executionContext.witnessInput();
|
|
103
108
|
const { methodIdResolver } = runtime;
|
|
109
|
+
|
|
110
|
+
// Assert that the given transaction has the correct methodId
|
|
104
111
|
const thisMethodId = Field(methodIdResolver.getMethodId(name, methodName));
|
|
105
112
|
if (!thisMethodId.isConstant()) {
|
|
106
113
|
throw errors.fieldNotConstant("methodId");
|
|
107
114
|
}
|
|
108
115
|
|
|
109
|
-
|
|
116
|
+
transaction.methodId.assertEquals(
|
|
110
117
|
thisMethodId,
|
|
111
118
|
"Runtimemethod called with wrong methodId on the transaction object"
|
|
112
119
|
);
|
|
113
120
|
|
|
114
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
115
|
-
const parameterTypes: ProofTypes[] | ToFieldableStatic[] =
|
|
116
|
-
Reflect.getMetadata("design:paramtypes", this, methodName);
|
|
117
|
-
|
|
118
121
|
/**
|
|
119
122
|
* Use the type info obtained previously to convert
|
|
120
123
|
* the args passed to fields
|
|
121
124
|
*/
|
|
122
|
-
const argsFields =
|
|
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
|
-
});
|
|
125
|
+
const { argsFields } = MethodParameterEncoder.fromMethod(this, methodName).encode(args);
|
|
145
126
|
|
|
146
127
|
// Assert that the argsHash that has been signed matches the given arguments
|
|
147
128
|
// We can use js-if here, because methodArguments is statically sizes
|
|
@@ -150,19 +131,23 @@ export function toWrappedMethod(
|
|
|
150
131
|
const argsHash =
|
|
151
132
|
methodArguments.length > 0 ? Poseidon.hash(argsFields) : Field(0);
|
|
152
133
|
|
|
153
|
-
|
|
134
|
+
transaction.argsHash.assertEquals(
|
|
154
135
|
argsHash,
|
|
155
136
|
"argsHash and therefore arguments of transaction and runtime call does not match"
|
|
156
137
|
);
|
|
157
138
|
|
|
158
|
-
const
|
|
159
|
-
|
|
139
|
+
const isMessage = Bool(options.invocationType === "INCOMING_MESSAGE");
|
|
140
|
+
transaction.assertTransactionType(Bool(isMessage));
|
|
141
|
+
|
|
142
|
+
const transactionHash = transaction.hash();
|
|
143
|
+
const networkStateHash = networkState.hash();
|
|
160
144
|
|
|
161
145
|
return new MethodPublicOutput({
|
|
162
146
|
stateTransitionsHash,
|
|
163
147
|
status,
|
|
164
148
|
transactionHash,
|
|
165
149
|
networkStateHash,
|
|
150
|
+
isMessage,
|
|
166
151
|
});
|
|
167
152
|
};
|
|
168
153
|
|
|
@@ -183,6 +168,7 @@ export function combineMethodName(
|
|
|
183
168
|
|
|
184
169
|
export const runtimeMethodMetadataKey = "yab-method";
|
|
185
170
|
export const runtimeMethodNamesMetadataKey = "proto-kit-runtime-methods";
|
|
171
|
+
export const runtimeMethodTypeMetadataKey = "proto-kit-runtime-method-type";
|
|
186
172
|
|
|
187
173
|
/**
|
|
188
174
|
* Checks the metadata of the provided runtime module and its method,
|
|
@@ -201,7 +187,9 @@ export function isRuntimeMethod(
|
|
|
201
187
|
);
|
|
202
188
|
}
|
|
203
189
|
|
|
204
|
-
export
|
|
190
|
+
export type RuntimeMethodInvocationType = "SIGNATURE" | "INCOMING_MESSAGE";
|
|
191
|
+
|
|
192
|
+
function runtimeMethodInternal(options: { invocationType: RuntimeMethodInvocationType }) {
|
|
205
193
|
return (
|
|
206
194
|
target: RuntimeModule<unknown>,
|
|
207
195
|
methodName: string,
|
|
@@ -225,6 +213,13 @@ export function runtimeMethod() {
|
|
|
225
213
|
|
|
226
214
|
Reflect.defineMetadata(runtimeMethodMetadataKey, true, target, methodName);
|
|
227
215
|
|
|
216
|
+
Reflect.defineMetadata(
|
|
217
|
+
runtimeMethodTypeMetadataKey,
|
|
218
|
+
options.invocationType,
|
|
219
|
+
target,
|
|
220
|
+
methodName
|
|
221
|
+
);
|
|
222
|
+
|
|
228
223
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
229
224
|
const simulatedMethod = descriptor.value as DecoratedMethod;
|
|
230
225
|
|
|
@@ -245,6 +240,7 @@ export function runtimeMethod() {
|
|
|
245
240
|
methodName,
|
|
246
241
|
simulatedMethod,
|
|
247
242
|
args,
|
|
243
|
+
options,
|
|
248
244
|
]);
|
|
249
245
|
|
|
250
246
|
/**
|
|
@@ -294,3 +290,15 @@ export function runtimeMethod() {
|
|
|
294
290
|
};
|
|
295
291
|
};
|
|
296
292
|
}
|
|
293
|
+
|
|
294
|
+
export function runtimeMessage() {
|
|
295
|
+
return runtimeMethodInternal({
|
|
296
|
+
invocationType: "INCOMING_MESSAGE",
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function runtimeMethod() {
|
|
301
|
+
return runtimeMethodInternal({
|
|
302
|
+
invocationType: "SIGNATURE",
|
|
303
|
+
});
|
|
304
|
+
}
|
|
@@ -17,12 +17,10 @@ export class MethodIdResolver {
|
|
|
17
17
|
public constructor(
|
|
18
18
|
@inject("Runtime") private readonly runtime: Runtime<RuntimeModulesRecord>
|
|
19
19
|
) {
|
|
20
|
-
const { modules } = runtime.definition;
|
|
21
|
-
|
|
22
20
|
this.dictionary = runtime.runtimeModuleNames.reduce<
|
|
23
21
|
Record<string, { moduleName: string; methodName: string }>
|
|
24
22
|
>((dict, moduleName) => {
|
|
25
|
-
this.runtime.assertIsValidModuleName(
|
|
23
|
+
this.runtime.assertIsValidModuleName(moduleName);
|
|
26
24
|
|
|
27
25
|
runtime.resolve(moduleName).runtimeMethodNames.forEach((methodName) => {
|
|
28
26
|
dict[this.getMethodId(moduleName, methodName).toString()] = {
|
|
@@ -44,19 +42,13 @@ export class MethodIdResolver {
|
|
|
44
42
|
|
|
45
43
|
const { moduleName, methodName } = methodPath;
|
|
46
44
|
|
|
47
|
-
this.runtime.assertIsValidModuleName(
|
|
48
|
-
this.runtime.definition.modules,
|
|
49
|
-
moduleName
|
|
50
|
-
);
|
|
45
|
+
this.runtime.assertIsValidModuleName(moduleName);
|
|
51
46
|
|
|
52
47
|
return [moduleName, methodName];
|
|
53
48
|
}
|
|
54
49
|
|
|
55
50
|
public getMethodId(moduleName: string, methodName: string): bigint {
|
|
56
|
-
this.runtime.assertIsValidModuleName(
|
|
57
|
-
this.runtime.definition.modules,
|
|
58
|
-
moduleName
|
|
59
|
-
);
|
|
51
|
+
this.runtime.assertIsValidModuleName(moduleName);
|
|
60
52
|
|
|
61
53
|
return Poseidon.hash([
|
|
62
54
|
stringToField(moduleName),
|
package/src/runtime/Runtime.ts
CHANGED
|
@@ -266,7 +266,7 @@ export class Runtime<Modules extends RuntimeModulesRecord>
|
|
|
266
266
|
}
|
|
267
267
|
const [moduleName, methodName] = methodDescriptor;
|
|
268
268
|
|
|
269
|
-
this.assertIsValidModuleName(
|
|
269
|
+
this.assertIsValidModuleName(moduleName);
|
|
270
270
|
const module = this.resolve(moduleName);
|
|
271
271
|
|
|
272
272
|
// eslint-disable-next-line max-len
|
|
@@ -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 {
|
|
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 =
|
|
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
|
-
}
|