@proto-kit/module 0.1.1-develop.153

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 (75) hide show
  1. package/LICENSE.md +201 -0
  2. package/README.md +114 -0
  3. package/dist/chain/Chain.d.ts +109 -0
  4. package/dist/chain/Chain.d.ts.map +1 -0
  5. package/dist/chain/Chain.js +229 -0
  6. package/dist/index.d.ts +13 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +12 -0
  9. package/dist/method/MethodExecutionContext.d.ts +73 -0
  10. package/dist/method/MethodExecutionContext.d.ts.map +1 -0
  11. package/dist/method/MethodExecutionContext.js +112 -0
  12. package/dist/method/MethodParameterDecoder.d.ts +20 -0
  13. package/dist/method/MethodParameterDecoder.d.ts.map +1 -0
  14. package/dist/method/MethodParameterDecoder.js +30 -0
  15. package/dist/method/RuntimeMethodExecutionContext.d.ts +57 -0
  16. package/dist/method/RuntimeMethodExecutionContext.d.ts.map +1 -0
  17. package/dist/method/RuntimeMethodExecutionContext.js +92 -0
  18. package/dist/method/assert.d.ts +12 -0
  19. package/dist/method/assert.d.ts.map +1 -0
  20. package/dist/method/assert.js +20 -0
  21. package/dist/method/decorator.d.ts +45 -0
  22. package/dist/method/decorator.d.ts.map +1 -0
  23. package/dist/method/decorator.js +140 -0
  24. package/dist/method/runtimeMethod.d.ts +18 -0
  25. package/dist/method/runtimeMethod.d.ts.map +1 -0
  26. package/dist/method/runtimeMethod.js +114 -0
  27. package/dist/module/decorator.d.ts +8 -0
  28. package/dist/module/decorator.d.ts.map +1 -0
  29. package/dist/module/decorator.js +15 -0
  30. package/dist/runtime/Runtime.d.ts +71 -0
  31. package/dist/runtime/Runtime.d.ts.map +1 -0
  32. package/dist/runtime/Runtime.js +185 -0
  33. package/dist/runtime/RuntimeModule.d.ts +30 -0
  34. package/dist/runtime/RuntimeModule.d.ts.map +1 -0
  35. package/dist/runtime/RuntimeModule.js +44 -0
  36. package/dist/state/InMemoryStateService.d.ts +14 -0
  37. package/dist/state/InMemoryStateService.d.ts.map +1 -0
  38. package/dist/state/InMemoryStateService.js +21 -0
  39. package/dist/state/State.d.ts +65 -0
  40. package/dist/state/State.d.ts.map +1 -0
  41. package/dist/state/State.js +114 -0
  42. package/dist/state/StateMap.d.ts +37 -0
  43. package/dist/state/StateMap.d.ts.map +1 -0
  44. package/dist/state/StateMap.js +56 -0
  45. package/dist/state/StateServiceProvider.d.ts +10 -0
  46. package/dist/state/StateServiceProvider.d.ts.map +1 -0
  47. package/dist/state/StateServiceProvider.js +34 -0
  48. package/dist/state/decorator.d.ts +7 -0
  49. package/dist/state/decorator.d.ts.map +1 -0
  50. package/dist/state/decorator.js +42 -0
  51. package/jest.config.cjs +1 -0
  52. package/package.json +36 -0
  53. package/src/index.ts +12 -0
  54. package/src/method/MethodParameterDecoder.ts +55 -0
  55. package/src/method/RuntimeMethodExecutionContext.ts +111 -0
  56. package/src/method/assert.test.ts +49 -0
  57. package/src/method/assert.ts +23 -0
  58. package/src/method/decorator.test.ts +46 -0
  59. package/src/method/runtimeMethod.ts +192 -0
  60. package/src/module/decorator.ts +21 -0
  61. package/src/runtime/Runtime.ts +304 -0
  62. package/src/runtime/RuntimeModule.ts +68 -0
  63. package/src/state/InMemoryStateService.ts +29 -0
  64. package/src/state/State.ts +154 -0
  65. package/src/state/StateMap.ts +69 -0
  66. package/src/state/StateServiceProvider.ts +24 -0
  67. package/src/state/decorator.ts +65 -0
  68. package/test/Runtime.test.ts +37 -0
  69. package/test/modules/Admin.ts +19 -0
  70. package/test/modules/Balances.test.ts +340 -0
  71. package/test/modules/Balances.ts +51 -0
  72. package/test/runtimeMethod.test.ts +43 -0
  73. package/test/transaction.test.ts +82 -0
  74. package/tsconfig.json +8 -0
  75. package/tsconfig.test.json +9 -0
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export * from "./method/RuntimeMethodExecutionContext";
2
+ export * from "./method/assert";
3
+ export * from "./method/runtimeMethod";
4
+ export * from "./module/decorator";
5
+ export * from "./runtime/RuntimeModule";
6
+ export * from "./runtime/Runtime";
7
+ export * from "./state/InMemoryStateService";
8
+ export * from "./state/State";
9
+ export * from "./state/StateMap";
10
+ export * from "./state/StateServiceProvider";
11
+ export * from "./state/decorator";
12
+ export * from "./method/MethodParameterDecoder";
@@ -0,0 +1,73 @@
1
+ import { Bool, type Proof } from "snarkyjs";
2
+ import type { StateTransition, MethodPublicInput } from "@yab/protocol";
3
+ export declare class MethodExecutionResult<ResultValue> {
4
+ stateTransitions: StateTransition<any>[];
5
+ status: Bool;
6
+ statusMessage?: string;
7
+ value?: ResultValue;
8
+ publicInput?: MethodPublicInput;
9
+ prove?: () => Promise<Proof<MethodPublicInput>>;
10
+ }
11
+ /**
12
+ * Execution context used to wrap runtime module methods,
13
+ * allowing them to post relevant information (such as execution status)
14
+ * into the context without any unnecessary 'prop drilling'.
15
+ */
16
+ export declare class MethodExecutionContext<ResultValue> {
17
+ result: MethodExecutionResult<ResultValue>;
18
+ methods: string[];
19
+ constructor(result?: MethodExecutionResult<ResultValue>);
20
+ /**
21
+ * Adds an in-method generated state transition to the current context
22
+ * @param stateTransition - State transition to add to the context
23
+ */
24
+ addStateTransition<Value>(stateTransition: StateTransition<Value>): void;
25
+ /**
26
+ * @param message - Status message to acompany the current status
27
+ */
28
+ setStatusMessage(message?: string): void;
29
+ /**
30
+ * @param status - Execution status of the current method
31
+ */
32
+ setStatus(status: Bool): void;
33
+ /**
34
+ * @param value = Return value of the executed method
35
+ */
36
+ setValue(value: ResultValue): void;
37
+ /**
38
+ * Adds a method prover to the current execution context,
39
+ * which can be collected and ran asynchronously at a later point in time.
40
+ *
41
+ * @param prove - Prover function to be ran later,
42
+ * when the method execution needs to be proven
43
+ */
44
+ setProve(prove: () => Promise<Proof<MethodPublicInput>>): void;
45
+ setPublicInput(publicInput: MethodPublicInput): void;
46
+ /**
47
+ * Adds a method to the method execution stack, reseting the execution context
48
+ * in a case a new top-level (non nested) method call is made.
49
+ *
50
+ * @param methodName - Name of the method being captured in the context
51
+ */
52
+ beforeMethod(methodName: string): void;
53
+ /**
54
+ * Removes the latest method from the execution context stack,
55
+ * keeping track of the amount of 'unfinished' methods. Allowing
56
+ * for the context to distinguish between top-level and nested method calls.
57
+ */
58
+ afterMethod(): void;
59
+ get isTopLevel(): boolean;
60
+ get isFinished(): boolean;
61
+ /**
62
+ * @returns - Current execution context state
63
+ */
64
+ current(): {
65
+ isFinished: boolean;
66
+ result: MethodExecutionResult<ResultValue>;
67
+ };
68
+ /**
69
+ * Manually clears/resets the execution context
70
+ */
71
+ clear(): void;
72
+ }
73
+ //# sourceMappingURL=MethodExecutionContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MethodExecutionContext.d.ts","sourceRoot":"","sources":["../../src/method/MethodExecutionContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,KAAK,KAAK,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAExE,qBAAa,qBAAqB,CAAC,WAAW;IAErC,gBAAgB,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAM;IAE9C,MAAM,EAAE,IAAI,CAAc;IAE1B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,KAAK,CAAC,EAAE,WAAW,CAAC;IAEpB,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAEhC,KAAK,CAAC,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;CACxD;AAED;;;;GAIG;AACH,qBACa,sBAAsB,CAAC,WAAW;IAIpC,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC;IAH5C,OAAO,EAAE,MAAM,EAAE,CAAM;gBAGrB,MAAM,GAAE,qBAAqB,CAAC,WAAW,CAA+B;IAGjF;;;OAGG;IACI,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,eAAe,CAAC,KAAK,CAAC;IAIxE;;OAEG;IACI,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM;IAIxC;;OAEG;IACI,SAAS,CAAC,MAAM,EAAE,IAAI;IAI7B;;OAEG;IACI,QAAQ,CAAC,KAAK,EAAE,WAAW;IAIlC;;;;;;OAMG;IACI,QAAQ,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAIvD,cAAc,CAAC,WAAW,EAAE,iBAAiB;IAEpD;;;;;OAKG;IACI,YAAY,CAAC,UAAU,EAAE,MAAM;IAOtC;;;;OAIG;IACI,WAAW;IAIlB,IAAW,UAAU,YAEpB;IAED,IAAW,UAAU,YAEpB;IAED;;OAEG;IACI,OAAO,IAAI;QAChB,UAAU,EAAE,OAAO,CAAC;QACpB,MAAM,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAC;KAC5C;IAOD;;OAEG;IACI,KAAK;CAGb"}
@@ -0,0 +1,112 @@
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 { Bool } from "snarkyjs";
11
+ import { singleton } from "tsyringe";
12
+ export class MethodExecutionResult {
13
+ constructor() {
14
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15
+ this.stateTransitions = [];
16
+ this.status = Bool(true);
17
+ }
18
+ }
19
+ /**
20
+ * Execution context used to wrap runtime module methods,
21
+ * allowing them to post relevant information (such as execution status)
22
+ * into the context without any unnecessary 'prop drilling'.
23
+ */
24
+ let MethodExecutionContext = class MethodExecutionContext {
25
+ constructor(result = new MethodExecutionResult()) {
26
+ this.result = result;
27
+ this.methods = [];
28
+ }
29
+ /**
30
+ * Adds an in-method generated state transition to the current context
31
+ * @param stateTransition - State transition to add to the context
32
+ */
33
+ addStateTransition(stateTransition) {
34
+ this.result.stateTransitions.push(stateTransition);
35
+ }
36
+ /**
37
+ * @param message - Status message to acompany the current status
38
+ */
39
+ setStatusMessage(message) {
40
+ var _a;
41
+ (_a = this.result).statusMessage ?? (_a.statusMessage = message);
42
+ }
43
+ /**
44
+ * @param status - Execution status of the current method
45
+ */
46
+ setStatus(status) {
47
+ this.result.status = status;
48
+ }
49
+ /**
50
+ * @param value = Return value of the executed method
51
+ */
52
+ setValue(value) {
53
+ this.result.value = value;
54
+ }
55
+ /**
56
+ * Adds a method prover to the current execution context,
57
+ * which can be collected and ran asynchronously at a later point in time.
58
+ *
59
+ * @param prove - Prover function to be ran later,
60
+ * when the method execution needs to be proven
61
+ */
62
+ setProve(prove) {
63
+ this.result.prove = prove;
64
+ }
65
+ setPublicInput(publicInput) { }
66
+ /**
67
+ * Adds a method to the method execution stack, reseting the execution context
68
+ * in a case a new top-level (non nested) method call is made.
69
+ *
70
+ * @param methodName - Name of the method being captured in the context
71
+ */
72
+ beforeMethod(methodName) {
73
+ if (this.isFinished) {
74
+ this.result = new MethodExecutionResult();
75
+ }
76
+ this.methods.push(methodName);
77
+ }
78
+ /**
79
+ * Removes the latest method from the execution context stack,
80
+ * keeping track of the amount of 'unfinished' methods. Allowing
81
+ * for the context to distinguish between top-level and nested method calls.
82
+ */
83
+ afterMethod() {
84
+ this.methods.pop();
85
+ }
86
+ get isTopLevel() {
87
+ return this.isFinished;
88
+ }
89
+ get isFinished() {
90
+ return this.methods.length === 0;
91
+ }
92
+ /**
93
+ * @returns - Current execution context state
94
+ */
95
+ current() {
96
+ return {
97
+ isFinished: this.isFinished,
98
+ result: this.result,
99
+ };
100
+ }
101
+ /**
102
+ * Manually clears/resets the execution context
103
+ */
104
+ clear() {
105
+ this.result = new MethodExecutionResult();
106
+ }
107
+ };
108
+ MethodExecutionContext = __decorate([
109
+ singleton(),
110
+ __metadata("design:paramtypes", [MethodExecutionResult])
111
+ ], MethodExecutionContext);
112
+ export { MethodExecutionContext };
@@ -0,0 +1,20 @@
1
+ import { Field } from "snarkyjs";
2
+ import { RuntimeModule } from "../runtime/RuntimeModule";
3
+ export interface Fieldable {
4
+ toFields: () => Field[];
5
+ }
6
+ export interface FromFieldClass {
7
+ new: (...args: any[]) => any;
8
+ fromFields: (fields: Field[]) => Fieldable;
9
+ prototype: {
10
+ _fields: any[];
11
+ };
12
+ }
13
+ export declare class MethodParameterDecoder {
14
+ private readonly types;
15
+ static fromMethod(target: RuntimeModule<unknown>, methodName: string): MethodParameterDecoder;
16
+ private constructor();
17
+ fromFields(fields: Field[]): Fieldable[];
18
+ get fieldSize(): number;
19
+ }
20
+ //# sourceMappingURL=MethodParameterDecoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MethodParameterDecoder.d.ts","sourceRoot":"","sources":["../../src/method/MethodParameterDecoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAEzD,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,KAAK,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,CAAC;IAC7B,UAAU,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,SAAS,CAAC;IAE3C,SAAS,EAAE;QACT,OAAO,EAAE,GAAG,EAAE,CAAC;KAChB,CAAC;CACH;AAOD,qBAAa,sBAAsB;IAWb,OAAO,CAAC,QAAQ,CAAC,KAAK;WAV5B,UAAU,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM;IAU3E,OAAO;IAEA,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE;IAc/C,IAAW,SAAS,IAAI,MAAM,CAI7B;CACF"}
@@ -0,0 +1,30 @@
1
+ const errors = {
2
+ fieldLengthNotMatching: (expected, actual) => new Error(`Expected ${expected} field elements, got ${actual}`),
3
+ };
4
+ export class MethodParameterDecoder {
5
+ static fromMethod(target, methodName) {
6
+ const paramtypes = Reflect.getMetadata("design:paramtypes", target, methodName);
7
+ return new MethodParameterDecoder(paramtypes);
8
+ }
9
+ constructor(types) {
10
+ this.types = types;
11
+ }
12
+ fromFields(fields) {
13
+ if (fields.length < this.fieldSize) {
14
+ throw errors.fieldLengthNotMatching(this.fieldSize, fields.length);
15
+ }
16
+ let stack = fields.slice();
17
+ return this.types.map((type) => {
18
+ // eslint-disable-next-line no-underscore-dangle
19
+ const numberFieldsNeeded = type.prototype._fields.length;
20
+ const structFields = stack.slice(0, numberFieldsNeeded);
21
+ stack = stack.slice(numberFieldsNeeded);
22
+ return type.fromFields(structFields);
23
+ });
24
+ }
25
+ get fieldSize() {
26
+ return this.types
27
+ .map((type) => type.prototype._fields.length)
28
+ .reduce((a, b) => a + b);
29
+ }
30
+ }
@@ -0,0 +1,57 @@
1
+ import { Bool } from "snarkyjs";
2
+ import type { StateTransition, NetworkState } from "@proto-kit/protocol";
3
+ import { ProvableMethodExecutionContext, ProvableMethodExecutionResult } from "@proto-kit/common";
4
+ import { RuntimeTransaction } from "@proto-kit/protocol/src/model/transaction/RuntimeTransaction";
5
+ export declare class RuntimeProvableMethodExecutionResult extends ProvableMethodExecutionResult {
6
+ stateTransitions: StateTransition<any>[];
7
+ status: Bool;
8
+ statusMessage?: string;
9
+ }
10
+ export interface RuntimeMethodExecutionData {
11
+ transaction: RuntimeTransaction;
12
+ networkState: NetworkState;
13
+ }
14
+ /**
15
+ * Execution context used to wrap runtime module methods,
16
+ * allowing them to post relevant information (such as execution status)
17
+ * into the context without any unnecessary 'prop drilling'.
18
+ */
19
+ export declare class RuntimeMethodExecutionContext extends ProvableMethodExecutionContext {
20
+ methods: string[];
21
+ input: RuntimeMethodExecutionData | undefined;
22
+ private lastInput;
23
+ result: RuntimeProvableMethodExecutionResult;
24
+ private assertSetupCalled;
25
+ /**
26
+ * Adds an in-method generated state transition to the current context
27
+ * @param stateTransition - State transition to add to the context
28
+ */
29
+ addStateTransition<Value>(stateTransition: StateTransition<Value>): void;
30
+ /**
31
+ * @param message - Status message to acompany the current status
32
+ */
33
+ setStatusMessage(message?: string): void;
34
+ /**
35
+ * @param status - Execution status of the current method
36
+ */
37
+ setStatus(status: Bool): void;
38
+ /**
39
+ * @param input Input witness data required for a runtime execution
40
+ */
41
+ setup(input: RuntimeMethodExecutionData): void;
42
+ /**
43
+ * Manually clears/resets the execution context
44
+ */
45
+ clear(): void;
46
+ afterMethod(): void;
47
+ /**
48
+ * Had to override current() otherwise it would not infer
49
+ * the type of result correctly (parent type would be reused)
50
+ */
51
+ current(): {
52
+ isFinished: boolean;
53
+ result: RuntimeProvableMethodExecutionResult;
54
+ input: RuntimeMethodExecutionData | undefined;
55
+ };
56
+ }
57
+ //# sourceMappingURL=RuntimeMethodExecutionContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RuntimeMethodExecutionContext.d.ts","sourceRoot":"","sources":["../../src/method/RuntimeMethodExecutionContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,EACL,8BAA8B,EAC9B,6BAA6B,EAC9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,8DAA8D,CAAC;AASlG,qBAAa,oCAAqC,SAAQ,6BAA6B;IAE9E,gBAAgB,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,CAAM;IAE9C,MAAM,EAAE,IAAI,CAAc;IAE1B,aAAa,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,kBAAkB,CAAC;IAChC,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED;;;;GAIG;AACH,qBACa,6BAA8B,SAAQ,8BAA8B;IACxE,OAAO,EAAE,MAAM,EAAE,CAAM;IAEvB,KAAK,EAAE,0BAA0B,GAAG,SAAS,CAAC;IAGrD,OAAO,CAAC,SAAS,CAAyC;IAE1C,MAAM,uCAA8C;IAEpE,OAAO,CAAC,iBAAiB;IAQzB;;;OAGG;IACI,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,eAAe,CAAC,KAAK,CAAC;IAKxE;;OAEG;IACI,gBAAgB,CAAC,OAAO,CAAC,EAAE,MAAM;IAKxC;;OAEG;IACI,SAAS,CAAC,MAAM,EAAE,IAAI;IAK7B;;OAEG;IACI,KAAK,CAAC,KAAK,EAAE,0BAA0B;IAI9C;;OAEG;IACI,KAAK;IAIL,WAAW;IAMlB;;;OAGG;IACI,OAAO;;;;;CAOf"}
@@ -0,0 +1,92 @@
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
+ import { Bool } from "snarkyjs";
8
+ import { singleton } from "tsyringe";
9
+ import { ProvableMethodExecutionContext, ProvableMethodExecutionResult, } from "@proto-kit/common";
10
+ const errors = {
11
+ setupNotCalled: () => new Error("Setup has not been called prior to executing a runtime method. Be sure to do that so that the Runtime is setup property for execution"),
12
+ };
13
+ export class RuntimeProvableMethodExecutionResult extends ProvableMethodExecutionResult {
14
+ constructor() {
15
+ super(...arguments);
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ this.stateTransitions = [];
18
+ this.status = Bool(true);
19
+ }
20
+ }
21
+ /**
22
+ * Execution context used to wrap runtime module methods,
23
+ * allowing them to post relevant information (such as execution status)
24
+ * into the context without any unnecessary 'prop drilling'.
25
+ */
26
+ let RuntimeMethodExecutionContext = class RuntimeMethodExecutionContext extends ProvableMethodExecutionContext {
27
+ constructor() {
28
+ super(...arguments);
29
+ this.methods = [];
30
+ this.result = new RuntimeProvableMethodExecutionResult();
31
+ }
32
+ assertSetupCalled() {
33
+ if (this.input === undefined) {
34
+ throw errors.setupNotCalled();
35
+ }
36
+ }
37
+ /**
38
+ * Adds an in-method generated state transition to the current context
39
+ * @param stateTransition - State transition to add to the context
40
+ */
41
+ addStateTransition(stateTransition) {
42
+ this.assertSetupCalled();
43
+ this.result.stateTransitions.push(stateTransition);
44
+ }
45
+ /**
46
+ * @param message - Status message to acompany the current status
47
+ */
48
+ setStatusMessage(message) {
49
+ var _a;
50
+ this.assertSetupCalled();
51
+ (_a = this.result).statusMessage ?? (_a.statusMessage = message);
52
+ }
53
+ /**
54
+ * @param status - Execution status of the current method
55
+ */
56
+ setStatus(status) {
57
+ this.assertSetupCalled();
58
+ this.result.status = status;
59
+ }
60
+ /**
61
+ * @param input Input witness data required for a runtime execution
62
+ */
63
+ setup(input) {
64
+ this.input = input;
65
+ }
66
+ /**
67
+ * Manually clears/resets the execution context
68
+ */
69
+ clear() {
70
+ this.result = new RuntimeProvableMethodExecutionResult();
71
+ }
72
+ afterMethod() {
73
+ super.afterMethod();
74
+ this.lastInput = this.input;
75
+ this.input = undefined;
76
+ }
77
+ /**
78
+ * Had to override current() otherwise it would not infer
79
+ * the type of result correctly (parent type would be reused)
80
+ */
81
+ current() {
82
+ return {
83
+ isFinished: this.isFinished,
84
+ result: this.result,
85
+ input: this.lastInput,
86
+ };
87
+ }
88
+ };
89
+ RuntimeMethodExecutionContext = __decorate([
90
+ singleton()
91
+ ], RuntimeMethodExecutionContext);
92
+ export { RuntimeMethodExecutionContext };
@@ -0,0 +1,12 @@
1
+ import { Bool } from "snarkyjs";
2
+ /**
3
+ * Maintains an execution status of the current runtime module method,
4
+ * while prioritizing one-time failures. The assertion won't change the
5
+ * execution status if it has previously failed at least once within the
6
+ * same method execution context.
7
+ *
8
+ * @param condition - Result of the assertion made about the execution status
9
+ * @param message - Optional message describing the prior status
10
+ */
11
+ export declare function assert(condition: Bool, message?: string): void;
12
+ //# sourceMappingURL=assert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../src/method/assert.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAY,MAAM,UAAU,CAAC;AAK1C;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,EAAE,MAAM,QAQvD"}
@@ -0,0 +1,20 @@
1
+ import { Bool, Provable } from "snarkyjs";
2
+ import { container } from "tsyringe";
3
+ import { RuntimeMethodExecutionContext } from "./RuntimeMethodExecutionContext";
4
+ /**
5
+ * Maintains an execution status of the current runtime module method,
6
+ * while prioritizing one-time failures. The assertion won't change the
7
+ * execution status if it has previously failed at least once within the
8
+ * same method execution context.
9
+ *
10
+ * @param condition - Result of the assertion made about the execution status
11
+ * @param message - Optional message describing the prior status
12
+ */
13
+ export function assert(condition, message) {
14
+ const executionContext = container.resolve(RuntimeMethodExecutionContext);
15
+ const previousStatus = executionContext.current().result.status;
16
+ const status = Provable.if(previousStatus, Bool, condition, previousStatus);
17
+ // const status = previousStatus.and(condition);
18
+ executionContext.setStatus(status);
19
+ executionContext.setStatusMessage(message);
20
+ }
@@ -0,0 +1,45 @@
1
+ import { Field } from "snarkyjs";
2
+ import { StateTransition, MethodPublicInput } from "@yab/protocol";
3
+ import type { RuntimeModule } from "../runtime/RuntimeModule.js";
4
+ /**
5
+ * Runs a method wrapped in a method execution context.
6
+ */
7
+ export declare function runInContext(this: RuntimeModule<unknown>, methodName: string, moduleMethod: (...args: unknown[]) => unknown, args: unknown[]): {
8
+ isFinished: boolean;
9
+ result: import("./MethodExecutionContext.js").MethodExecutionResult<unknown>;
10
+ };
11
+ export declare function toStateTransitionsHash(stateTransitions: StateTransition<any>[]): Field;
12
+ export type WrappedMethod = (publicInput: MethodPublicInput, ...args: unknown[]) => unknown;
13
+ export declare function toWrappedMethod(this: RuntimeModule<unknown>, methodName: string, moduleMethod: (...args: unknown[]) => unknown): WrappedMethod;
14
+ export declare function combineMethodName(runtimeModuleName: string, methodName: string): string;
15
+ /**
16
+ * Precomputes the public inputs required to run
17
+ * an actual wrapped method, produced from the provided moduleMethod.
18
+ *
19
+ * Execute the wrapped method with the precomputed public inputs.
20
+ */
21
+ export declare function runWithCommitments(this: RuntimeModule<unknown>, methodName: string, moduleMethod: (...args: unknown[]) => unknown, args: unknown[]): unknown;
22
+ export declare const methodMetadataKey = "yab-method";
23
+ /**
24
+ * Checks the metadata of the provided runtime module and its method,
25
+ * to see if it has been decorated with @method()
26
+ *
27
+ * @param target - Runtime module to check
28
+ * @param propertyKey - Name of the method to check in the prior runtime module
29
+ * @returns - If the provided method name is a runtime method or not
30
+ */
31
+ export declare function isMethod(target: RuntimeModule<unknown>, propertyKey: string): boolean;
32
+ export type DecoratedMethod = (...args: unknown[]) => unknown;
33
+ /**
34
+ * Decorates a runtime module method and toggles execution of
35
+ * either of its variants, depending on the state of the current
36
+ * method execution context. If the method is called at the 'top-level',
37
+ * it is executed 'with commitments'. If the method is called from another
38
+ * method, it's executed directly.
39
+ *
40
+ * Additionally the method is marked with metadata as a 'runtime module method'.
41
+ *
42
+ * @returns A decorated runtime module method
43
+ */
44
+ export declare function method(): (target: RuntimeModule<unknown>, propertyKey: string, descriptor: PropertyDescriptor) => void;
45
+ //# sourceMappingURL=decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorator.d.ts","sourceRoot":"","sources":["../../src/method/decorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC,OAAO,EACL,eAAe,EAGf,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAqBjE;;GAEG;AAEH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,EAC5B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAC7C,IAAI,EAAE,OAAO,EAAE;;;EAuBhB;AAED,wBAAgB,sBAAsB,CAEpC,gBAAgB,EAAE,eAAe,CAAC,GAAG,CAAC,EAAE,SAczC;AAGD,MAAM,MAAM,aAAa,GAAG,CAC1B,WAAW,EAAE,iBAAiB,EAC9B,GAAG,IAAI,EAAE,OAAO,EAAE,KACf,OAAO,CAAC;AAEb,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,EAC5B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,iBAiC9C;AAED,wBAAgB,iBAAiB,CAC/B,iBAAiB,EAAE,MAAM,EACzB,UAAU,EAAE,MAAM,UAGnB;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,EAC5B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAC7C,IAAI,EAAE,OAAO,EAAE,WA4ChB;AAED,eAAO,MAAM,iBAAiB,eAAe,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE,WAAW,EAAE,MAAM,WAE3E;AAGD,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAE9D;;;;;;;;;;GAUG;AACH,wBAAgB,MAAM,aAEV,cAAc,OAAO,CAAC,eACjB,MAAM,cACP,kBAAkB,UAyBjC"}
@@ -0,0 +1,140 @@
1
+ import { Field } from "snarkyjs";
2
+ import { container } from "tsyringe";
3
+ import { DefaultProvableHashList, ProvableStateTransition, } from "@yab/protocol";
4
+ import { MethodExecutionContext } from "./MethodExecutionContext.js";
5
+ const errors = {
6
+ inconsistentStateTransitions: (methodName) => `State transitions produced by '@method ${methodName}' are not consistent
7
+ through multiple method executions, does your method contain
8
+ any circuit-unfriendly conditional logic?`,
9
+ inconsistentExecutionStatus: (methodName) => `Execution status of '@method ${methodName}' differs across multiple method executions,
10
+ does your status change by any circuit-unfriendly conditional logic?`,
11
+ proverMissing: (methodName) => new Error(`Unable to find a provable method for '@method ${methodName}',
12
+ did you forget to run chain.compile()?`),
13
+ };
14
+ /**
15
+ * Runs a method wrapped in a method execution context.
16
+ */
17
+ export function runInContext(methodName, moduleMethod, args) {
18
+ const executionContext = container.resolve(MethodExecutionContext);
19
+ // eslint-disable-next-line @typescript-eslint/init-declarations
20
+ let resultValue;
21
+ executionContext.beforeMethod(methodName);
22
+ try {
23
+ resultValue = Reflect.apply(moduleMethod, this, args);
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ }
26
+ catch (error) {
27
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
28
+ throw new Error(error);
29
+ }
30
+ finally {
31
+ executionContext.afterMethod();
32
+ }
33
+ executionContext.setValue(resultValue);
34
+ return executionContext.current();
35
+ }
36
+ export function toStateTransitionsHash(
37
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
38
+ stateTransitions) {
39
+ const stateTransitionsHashList = new DefaultProvableHashList(ProvableStateTransition);
40
+ return stateTransitions
41
+ .map((stateTransition) => stateTransition.toProvable())
42
+ .reduce((allStateTransitionsHashList, stateTransition) => allStateTransitionsHashList.push(stateTransition), stateTransitionsHashList)
43
+ .toField();
44
+ }
45
+ export function toWrappedMethod(methodName, moduleMethod) {
46
+ const wrappedMethod = (publicInput, ...args) => {
47
+ const { result: { stateTransitions, status, value }, } = Reflect.apply(runInContext, this, [methodName, moduleMethod, args]);
48
+ const stateTransitionsHash = toStateTransitionsHash(stateTransitions);
49
+ publicInput.stateTransitionsHash.assertEquals(stateTransitionsHash, errors.inconsistentStateTransitions(methodName));
50
+ // eslint-disable-next-line no-warning-comments
51
+ // TODO: implement the transactionHash commitment
52
+ publicInput.transactionHash.assertEquals(Field(0));
53
+ publicInput.status.assertEquals(status, errors.inconsistentExecutionStatus(methodName));
54
+ return value;
55
+ };
56
+ Object.defineProperty(wrappedMethod, "name", {
57
+ value: `wrapped_${methodName}`,
58
+ writable: false,
59
+ });
60
+ return wrappedMethod;
61
+ }
62
+ export function combineMethodName(runtimeModuleName, methodName) {
63
+ return `${runtimeModuleName}.${methodName}`;
64
+ }
65
+ /**
66
+ * Precomputes the public inputs required to run
67
+ * an actual wrapped method, produced from the provided moduleMethod.
68
+ *
69
+ * Execute the wrapped method with the precomputed public inputs.
70
+ */
71
+ export function runWithCommitments(methodName, moduleMethod, args) {
72
+ const executionContext = container.resolve(MethodExecutionContext);
73
+ const wrappedMethod = Reflect.apply(toWrappedMethod, this, [
74
+ methodName,
75
+ moduleMethod,
76
+ ]);
77
+ const { result: { stateTransitions, status }, } = Reflect.apply(runInContext, this, [methodName, moduleMethod, args]);
78
+ const stateTransitionsHash = toStateTransitionsHash(stateTransitions);
79
+ const methodPublicInput = {
80
+ stateTransitionsHash,
81
+ transactionHash: Field(0),
82
+ status,
83
+ };
84
+ executionContext.setPublicInput(methodPublicInput);
85
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
86
+ if (this.runtime?.areProofsEnabled) {
87
+ const runtimeModuleName = this.constructor.name;
88
+ const combinedMethodName = combineMethodName(runtimeModuleName, methodName);
89
+ const provableMethod = this.runtime.program?.[combinedMethodName];
90
+ if (!provableMethod) {
91
+ throw errors.proverMissing(methodName);
92
+ }
93
+ const prove = async () => await Reflect.apply(provableMethod, this, [methodPublicInput, ...args]);
94
+ const result = wrappedMethod(methodPublicInput, ...args);
95
+ executionContext.setProve(prove);
96
+ return result;
97
+ }
98
+ return wrappedMethod(methodPublicInput, ...args);
99
+ }
100
+ export const methodMetadataKey = "yab-method";
101
+ /**
102
+ * Checks the metadata of the provided runtime module and its method,
103
+ * to see if it has been decorated with @method()
104
+ *
105
+ * @param target - Runtime module to check
106
+ * @param propertyKey - Name of the method to check in the prior runtime module
107
+ * @returns - If the provided method name is a runtime method or not
108
+ */
109
+ export function isMethod(target, propertyKey) {
110
+ return Boolean(Reflect.getMetadata(methodMetadataKey, target, propertyKey));
111
+ }
112
+ /**
113
+ * Decorates a runtime module method and toggles execution of
114
+ * either of its variants, depending on the state of the current
115
+ * method execution context. If the method is called at the 'top-level',
116
+ * it is executed 'with commitments'. If the method is called from another
117
+ * method, it's executed directly.
118
+ *
119
+ * Additionally the method is marked with metadata as a 'runtime module method'.
120
+ *
121
+ * @returns A decorated runtime module method
122
+ */
123
+ export function method() {
124
+ return (target, propertyKey, descriptor) => {
125
+ const executionContext = container.resolve(MethodExecutionContext);
126
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
127
+ const originalFunction = descriptor.value;
128
+ Reflect.defineMetadata(methodMetadataKey, true, target, propertyKey);
129
+ descriptor.value = function value(...args) {
130
+ if (executionContext.isTopLevel) {
131
+ return Reflect.apply(runWithCommitments, this, [
132
+ propertyKey,
133
+ originalFunction,
134
+ args,
135
+ ]);
136
+ }
137
+ return Reflect.apply(originalFunction, this, args);
138
+ };
139
+ };
140
+ }
@@ -0,0 +1,18 @@
1
+ import { StateTransition, MethodPublicOutput } from "@proto-kit/protocol";
2
+ import type { RuntimeModule } from "../runtime/RuntimeModule.js";
3
+ export declare function toStateTransitionsHash(stateTransitions: StateTransition<any>[]): import("snarkyjs/dist/node/lib/field.js").Field;
4
+ export type WrappedMethod = (...args: unknown[]) => MethodPublicOutput;
5
+ export declare function toWrappedMethod(this: RuntimeModule<unknown>, methodName: string, moduleMethod: (...args: unknown[]) => unknown): WrappedMethod;
6
+ export declare function combineMethodName(runtimeModuleName: string, methodName: string): string;
7
+ export declare const runtimeMethodMetadataKey = "yab-method";
8
+ /**
9
+ * Checks the metadata of the provided runtime module and its method,
10
+ * to see if it has been decorated with @runtimeMethod()
11
+ *
12
+ * @param target - Runtime module to check
13
+ * @param propertyKey - Name of the method to check in the prior runtime module
14
+ * @returns - If the provided method name is a runtime method or not
15
+ */
16
+ export declare function isRuntimeMethod(target: RuntimeModule<unknown>, propertyKey: string): boolean;
17
+ export declare function runtimeMethod(): (target: RuntimeModule<unknown>, methodName: string, descriptor: PropertyDescriptor) => void;
18
+ //# sourceMappingURL=runtimeMethod.d.ts.map