@proto-kit/module 0.1.1-develop.190 → 0.1.1-develop.211

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 (78) hide show
  1. package/dist/method/MethodParameterDecoder.d.ts.map +1 -1
  2. package/dist/method/MethodParameterDecoder.js +1 -1
  3. package/dist/method/RuntimeMethodExecutionContext.d.ts +2 -2
  4. package/dist/method/RuntimeMethodExecutionContext.d.ts.map +1 -1
  5. package/dist/module/src/factories/MethodIdFactory.d.ts +9 -0
  6. package/dist/module/src/factories/MethodIdFactory.d.ts.map +1 -0
  7. package/dist/module/src/factories/MethodIdFactory.js +36 -0
  8. package/dist/module/src/index.d.ts +11 -0
  9. package/dist/module/src/index.d.ts.map +1 -0
  10. package/dist/module/src/index.js +10 -0
  11. package/dist/module/src/method/MethodParameterDecoder.d.ts +22 -0
  12. package/dist/module/src/method/MethodParameterDecoder.d.ts.map +1 -0
  13. package/dist/module/src/method/MethodParameterDecoder.js +33 -0
  14. package/dist/module/src/method/runtimeMethod.d.ts +19 -0
  15. package/dist/module/src/method/runtimeMethod.d.ts.map +1 -0
  16. package/dist/module/src/method/runtimeMethod.js +123 -0
  17. package/dist/module/src/module/decorator.d.ts +8 -0
  18. package/dist/module/src/module/decorator.d.ts.map +1 -0
  19. package/dist/module/src/module/decorator.js +15 -0
  20. package/dist/module/src/runtime/MethodIdResolver.d.ts +18 -0
  21. package/dist/module/src/runtime/MethodIdResolver.d.ts.map +1 -0
  22. package/dist/module/src/runtime/MethodIdResolver.js +50 -0
  23. package/dist/module/src/runtime/Runtime.d.ts +72 -0
  24. package/dist/module/src/runtime/Runtime.d.ts.map +1 -0
  25. package/dist/module/src/runtime/Runtime.js +184 -0
  26. package/dist/module/src/runtime/RuntimeModule.d.ts +35 -0
  27. package/dist/module/src/runtime/RuntimeModule.d.ts.map +1 -0
  28. package/dist/module/src/runtime/RuntimeModule.js +56 -0
  29. package/dist/module/src/state/InMemoryStateService.d.ts +11 -0
  30. package/dist/module/src/state/InMemoryStateService.d.ts.map +1 -0
  31. package/dist/module/src/state/InMemoryStateService.js +21 -0
  32. package/dist/module/src/state/decorator.d.ts +7 -0
  33. package/dist/module/src/state/decorator.d.ts.map +1 -0
  34. package/dist/module/src/state/decorator.js +42 -0
  35. package/dist/protocol/src/model/Option.d.ts +98 -0
  36. package/dist/protocol/src/model/Option.d.ts.map +1 -0
  37. package/dist/protocol/src/model/Option.js +98 -0
  38. package/dist/protocol/src/model/StateTransition.d.ts +96 -0
  39. package/dist/protocol/src/model/StateTransition.d.ts.map +1 -0
  40. package/dist/protocol/src/model/StateTransition.js +65 -0
  41. package/dist/protocol/src/model/network/NetworkState.d.ts +64 -0
  42. package/dist/protocol/src/model/network/NetworkState.d.ts.map +1 -0
  43. package/dist/protocol/src/model/network/NetworkState.js +12 -0
  44. package/dist/protocol/src/model/transaction/ProtocolTransaction.d.ts +70 -0
  45. package/dist/protocol/src/model/transaction/ProtocolTransaction.d.ts.map +1 -0
  46. package/dist/protocol/src/model/transaction/ProtocolTransaction.js +18 -0
  47. package/dist/protocol/src/model/transaction/RuntimeTransaction.d.ts +63 -0
  48. package/dist/protocol/src/model/transaction/RuntimeTransaction.d.ts.map +1 -0
  49. package/dist/protocol/src/model/transaction/RuntimeTransaction.js +29 -0
  50. package/dist/protocol/src/state/assert/assert.d.ts +12 -0
  51. package/dist/protocol/src/state/assert/assert.d.ts.map +1 -0
  52. package/dist/protocol/src/state/assert/assert.js +23 -0
  53. package/dist/protocol/src/state/context/RuntimeMethodExecutionContext.d.ts +60 -0
  54. package/dist/protocol/src/state/context/RuntimeMethodExecutionContext.d.ts.map +1 -0
  55. package/dist/protocol/src/state/context/RuntimeMethodExecutionContext.js +105 -0
  56. package/dist/state/StateMap.d.ts +3 -3
  57. package/dist/state/StateMap.d.ts.map +1 -1
  58. package/package.json +3 -4
  59. package/src/index.ts +2 -5
  60. package/src/method/MethodParameterDecoder.ts +3 -1
  61. package/src/method/runtimeMethod.ts +1 -2
  62. package/src/runtime/Runtime.ts +12 -10
  63. package/src/runtime/RuntimeModule.ts +5 -4
  64. package/src/state/InMemoryStateService.ts +1 -5
  65. package/src/state/decorator.ts +2 -4
  66. package/test/Runtime.test.ts +2 -2
  67. package/test/modules/Admin.ts +1 -1
  68. package/test/modules/Balances.test.ts +13 -8
  69. package/test/modules/Balances.ts +7 -3
  70. package/test/modules/State.test.ts +88 -0
  71. package/test/modules/methodId.test.ts +0 -1
  72. package/test/transaction.test.ts +1 -1
  73. package/src/method/RuntimeMethodExecutionContext.ts +0 -111
  74. package/src/method/assert.test.ts +0 -49
  75. package/src/method/assert.ts +0 -27
  76. package/src/state/State.ts +0 -154
  77. package/src/state/StateMap.ts +0 -69
  78. package/src/state/StateServiceProvider.ts +0 -24
@@ -13,19 +13,21 @@ import {
13
13
  WithZkProgrammable,
14
14
  AreProofsEnabled,
15
15
  } from "@proto-kit/common";
16
- import { MethodPublicOutput } from "@proto-kit/protocol";
16
+ import {
17
+ MethodPublicOutput,
18
+ StateServiceProvider,
19
+ StateService,
20
+ } from "@proto-kit/protocol";
17
21
 
18
22
  import {
19
23
  combineMethodName,
20
24
  isRuntimeMethod,
21
25
  toWrappedMethod,
22
26
  WrappedMethod,
23
- } from "../method/runtimeMethod.js";
24
- import { StateService } from "../state/InMemoryStateService.js";
25
- import { StateServiceProvider } from "../state/StateServiceProvider";
27
+ } from "../method/runtimeMethod";
26
28
  import { MethodIdFactory } from "../factories/MethodIdFactory";
27
29
 
28
- import { RuntimeModule } from "./RuntimeModule.js";
30
+ import { RuntimeModule } from "./RuntimeModule";
29
31
  import { MethodIdResolver } from "./MethodIdResolver";
30
32
 
31
33
  /**
@@ -47,7 +49,10 @@ const errors = {
47
49
  * Definition / required arguments for the Runtime class
48
50
  */
49
51
  export interface RuntimeDefinition<Modules extends RuntimeModulesRecord> {
50
- state: StateService;
52
+ /**
53
+ * @deprecated
54
+ */
55
+ state?: StateService;
51
56
  modules: Modules;
52
57
  config?: ModulesConfig<Modules>;
53
58
  }
@@ -200,9 +205,8 @@ export class Runtime<Modules extends RuntimeModulesRecord>
200
205
 
201
206
  public zkProgrammable: ZkProgrammable<undefined, MethodPublicOutput>;
202
207
 
203
- // eslint-disable-next-line no-warning-comments
204
- // TODO DI
205
208
  private readonly stateServiceProviderInstance = new StateServiceProvider(
209
+ // eslint-disable-next-line etc/no-deprecated
206
210
  this.definition.state
207
211
  );
208
212
 
@@ -215,8 +219,6 @@ export class Runtime<Modules extends RuntimeModulesRecord>
215
219
  super(definition);
216
220
  this.definition = definition;
217
221
  this.zkProgrammable = new RuntimeZkProgrammable<Modules>(this);
218
-
219
- // this.registerDependencyFactories([MethodIdFactory]);
220
222
  }
221
223
 
222
224
  // eslint-disable-next-line no-warning-comments
@@ -1,12 +1,13 @@
1
1
  import { ConfigurableModule, Presets } from "@proto-kit/common";
2
2
  import { container, injectable } from "tsyringe";
3
- import { NetworkState, RuntimeTransaction } from "@proto-kit/protocol";
4
-
5
3
  import {
4
+ NetworkState,
5
+ RuntimeTransaction,
6
+ StateService,
6
7
  RuntimeMethodExecutionContext,
7
8
  RuntimeMethodExecutionData,
8
- } from "../method/RuntimeMethodExecutionContext";
9
- import { StateService } from "../state/InMemoryStateService";
9
+ } from "@proto-kit/protocol";
10
+
10
11
  import { runtimeMethodNamesMetadataKey } from "../method/runtimeMethod";
11
12
 
12
13
  import type {
@@ -1,9 +1,5 @@
1
1
  import { Field } from "snarkyjs";
2
-
3
- export interface StateService {
4
- get: (key: Field) => Field[] | undefined;
5
- set: (key: Field, value: Field[] | undefined) => void;
6
- }
2
+ import { StateService } from "@proto-kit/protocol";
7
3
 
8
4
  /**
9
5
  * Naive implementation of a StateService for testing purposes
@@ -1,9 +1,7 @@
1
- import { Path } from "@proto-kit/protocol";
1
+ import { Path, State } from "@proto-kit/protocol";
2
2
 
3
3
  import type { RuntimeModule } from "../runtime/RuntimeModule.js";
4
4
 
5
- import type { State } from "./State.js";
6
-
7
5
  const errors = {
8
6
  missingName: (className: string) =>
9
7
  new Error(
@@ -52,7 +50,7 @@ export function state() {
52
50
  // eslint-disable-next-line no-warning-comments
53
51
  // TODO: why is this complaining about `any`?
54
52
 
55
- value.runtime = self.runtime;
53
+ value.stateServiceProvider = self.runtime.stateServiceProvider;
56
54
  }
57
55
  return value;
58
56
  },
@@ -1,6 +1,6 @@
1
1
  import { Bool } from "snarkyjs";
2
2
 
3
- import { InMemoryStateService, Runtime } from "../src";
3
+ import { InMemoryStateService, MethodIdResolver, Runtime } from "../src";
4
4
 
5
5
  import { Balances } from "./modules/Balances";
6
6
 
@@ -32,7 +32,7 @@ describe("runtime", () => {
32
32
  const moduleName = "Balances";
33
33
  const methodName = "getTotalSupply";
34
34
 
35
- const methodId = runtime.methodIdResolver.getMethodId(
35
+ const methodId = runtime.dependencyContainer.resolve<MethodIdResolver>("MethodIdResolver").getMethodId(
36
36
  moduleName,
37
37
  methodName
38
38
  );
@@ -3,7 +3,7 @@ import { PublicKey } from "snarkyjs";
3
3
  import { runtimeModule } from "../../src/module/decorator.js";
4
4
  import { RuntimeModule } from "../../src/runtime/RuntimeModule.js";
5
5
  import { runtimeMethod } from "../../src/method/runtimeMethod.js";
6
- import { assert } from "../../src/method/assert.js";
6
+ import { assert } from "@proto-kit/protocol";
7
7
 
8
8
  interface AdminConfig {
9
9
  publicKey: string;
@@ -10,14 +10,17 @@ import {
10
10
  UInt64,
11
11
  } from "snarkyjs";
12
12
  import { container } from "tsyringe";
13
- import { type ProvableStateTransition, Path } from "@proto-kit/protocol";
13
+ import {
14
+ type ProvableStateTransition,
15
+ Path,
16
+ MethodPublicOutput,
17
+ StateService, NetworkState, RuntimeTransaction
18
+ } from "@proto-kit/protocol";
14
19
 
15
20
  import {
16
21
  InMemoryStateService,
17
- StateService,
18
22
  } from "../../src/state/InMemoryStateService.js";
19
23
  import {
20
- MethodPublicOutput,
21
24
  Runtime,
22
25
  RuntimeMethodExecutionContext,
23
26
  } from "../../src";
@@ -61,13 +64,15 @@ describe("balances", () => {
61
64
  },
62
65
  });
63
66
 
64
- runtime.appChain = {
65
- areProofsEnabled: false,
67
+ runtime.dependencyContainer.register("AppChain", {
68
+ useValue: {
69
+ areProofsEnabled: false,
66
70
 
67
- setProofsEnabled(areProofsEnabled) {
68
- this.areProofsEnabled = areProofsEnabled;
71
+ setProofsEnabled(areProofsEnabled: boolean) {
72
+ this.areProofsEnabled = areProofsEnabled;
73
+ },
69
74
  },
70
- };
75
+ });
71
76
 
72
77
  runtime.configure({
73
78
  Admin: {
@@ -2,9 +2,9 @@ import { Bool, PublicKey, UInt64 } from "snarkyjs";
2
2
  import { Option } from "@proto-kit/protocol";
3
3
  import { Presets } from "@proto-kit/common";
4
4
 
5
- import { State } from "../../src/state/State.js";
5
+ import { State } from "../../../protocol/src/state/State.js";
6
6
  import { state } from "../../src/state/decorator.js";
7
- import { StateMap } from "../../src/state/StateMap.js";
7
+ import { StateMap } from "../../../protocol/src/state/StateMap.js";
8
8
  import { RuntimeModule, runtimeMethod, runtimeModule } from "../../src";
9
9
 
10
10
  import { Admin } from "./Admin.js";
@@ -50,7 +50,11 @@ export class Balances extends RuntimeModule<BalancesConfig> {
50
50
  }
51
51
 
52
52
  @runtimeMethod()
53
- public setBalanceIf() {
53
+ public transientState() {
54
+ const totalSupply = this.totalSupply.get();
55
+ this.totalSupply.set(totalSupply.orElse(UInt64.zero).add(100));
54
56
 
57
+ const totalSupply2 = this.totalSupply.get();
58
+ this.totalSupply.set(totalSupply2.orElse(UInt64.zero).add(100));
55
59
  }
56
60
  }
@@ -0,0 +1,88 @@
1
+ import "reflect-metadata";
2
+ import { Bool, PublicKey, UInt64 } from "snarkyjs";
3
+ import { container } from "tsyringe";
4
+ import { NetworkState, Option, RuntimeTransaction, StateService } from "@proto-kit/protocol";
5
+
6
+ import {
7
+ InMemoryStateService,
8
+ Runtime,
9
+ RuntimeMethodExecutionContext,
10
+ } from "../../src";
11
+
12
+ import { Admin } from "./Admin";
13
+ import { Balances } from "./Balances";
14
+
15
+ describe("transient state", () => {
16
+ let balances: Balances;
17
+
18
+ let state: StateService;
19
+
20
+ let runtime: Runtime<{
21
+ Admin: typeof Admin;
22
+ Balances: typeof Balances;
23
+ }>;
24
+
25
+ function createChain() {
26
+ state = new InMemoryStateService();
27
+
28
+ runtime = Runtime.from({
29
+ state,
30
+
31
+ modules: {
32
+ Admin,
33
+ Balances,
34
+ },
35
+ });
36
+
37
+ runtime.dependencyContainer.register("AppChain", {
38
+ useValue: {
39
+ areProofsEnabled: false,
40
+
41
+ setProofsEnabled(areProofsEnabled: boolean) {
42
+ this.areProofsEnabled = areProofsEnabled;
43
+ },
44
+ },
45
+ });
46
+
47
+ runtime.configure({
48
+ Admin: {
49
+ publicKey: PublicKey.empty().toBase58(),
50
+ },
51
+
52
+ Balances: {
53
+ test: Bool(true),
54
+ },
55
+ });
56
+
57
+ balances = runtime.resolve("Balances");
58
+ }
59
+
60
+ beforeEach(() => {
61
+ createChain();
62
+ });
63
+
64
+ it("should track previously set state", () => {
65
+ const executionContext = container.resolve(RuntimeMethodExecutionContext);
66
+ executionContext.setup({
67
+ networkState: new NetworkState({ block: { height: UInt64.zero } }),
68
+ transaction: undefined as unknown as RuntimeTransaction,
69
+ });
70
+ balances.transientState();
71
+
72
+ const stateTransitions = executionContext
73
+ .current()
74
+ .result.stateTransitions.map((stateTransition) =>
75
+ stateTransition.toProvable()
76
+ );
77
+
78
+ const expectedLastOption = Option.fromValue(
79
+ UInt64.from(200),
80
+ UInt64
81
+ ).toProvable();
82
+
83
+ const last = stateTransitions.at(-1);
84
+
85
+ expect(last).toBeDefined();
86
+ expect(last!.to.value).toStrictEqual(expectedLastOption.value);
87
+ });
88
+ });
@@ -56,7 +56,6 @@ describe("methodId", () => {
56
56
  ["Admin", "isAdminWithAVeryVeryVeryVeryLongName"],
57
57
  ["Balance", "getTotalSupply"],
58
58
  ["Balance", "getBalance"],
59
- ["Balance", "setBalanceIf"],
60
59
  ])(
61
60
  "should pass and encode correctly",
62
61
  (givenModuleName, givenMethodName) => {
@@ -11,7 +11,7 @@ import {
11
11
  import { runtimeModule } from "../src/module/decorator";
12
12
  import { RuntimeModule } from "../src/runtime/RuntimeModule";
13
13
  import { state } from "../src/state/decorator";
14
- import { StateMap } from "../src/state/StateMap";
14
+ import { StateMap } from "@proto-kit/protocol";
15
15
 
16
16
  interface BalancesConfig {}
17
17
  @runtimeModule()
@@ -1,111 +0,0 @@
1
- import { Bool } from "snarkyjs";
2
- import { singleton } from "tsyringe";
3
- import type { StateTransition, NetworkState } from "@proto-kit/protocol";
4
- import {
5
- ProvableMethodExecutionContext,
6
- ProvableMethodExecutionResult,
7
- } from "@proto-kit/common";
8
- import { RuntimeTransaction } from "@proto-kit/protocol/src/model/transaction/RuntimeTransaction";
9
-
10
- const errors = {
11
- setupNotCalled: () =>
12
- new Error(
13
- "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"
14
- ),
15
- };
16
-
17
- export class RuntimeProvableMethodExecutionResult extends ProvableMethodExecutionResult {
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- public stateTransitions: StateTransition<any>[] = [];
20
-
21
- public status: Bool = Bool(true);
22
-
23
- public statusMessage?: string;
24
- }
25
-
26
- export interface RuntimeMethodExecutionData {
27
- transaction: RuntimeTransaction;
28
- networkState: NetworkState;
29
- }
30
-
31
- /**
32
- * Execution context used to wrap runtime module methods,
33
- * allowing them to post relevant information (such as execution status)
34
- * into the context without any unnecessary 'prop drilling'.
35
- */
36
- @singleton()
37
- export class RuntimeMethodExecutionContext extends ProvableMethodExecutionContext {
38
- public methods: string[] = [];
39
-
40
- public input: RuntimeMethodExecutionData | undefined;
41
-
42
- // The input corresponding to the current result
43
- private lastInput: RuntimeMethodExecutionData | undefined;
44
-
45
- public override result = new RuntimeProvableMethodExecutionResult();
46
-
47
- private assertSetupCalled(): asserts this is {
48
- input: RuntimeMethodExecutionData;
49
- } {
50
- if (this.input === undefined) {
51
- throw errors.setupNotCalled();
52
- }
53
- }
54
-
55
- /**
56
- * Adds an in-method generated state transition to the current context
57
- * @param stateTransition - State transition to add to the context
58
- */
59
- public addStateTransition<Value>(stateTransition: StateTransition<Value>) {
60
- this.assertSetupCalled();
61
- this.result.stateTransitions.push(stateTransition);
62
- }
63
-
64
- /**
65
- * @param message - Status message to acompany the current status
66
- */
67
- public setStatusMessage(message?: string) {
68
- this.assertSetupCalled();
69
- this.result.statusMessage ??= message;
70
- }
71
-
72
- /**
73
- * @param status - Execution status of the current method
74
- */
75
- public setStatus(status: Bool) {
76
- this.assertSetupCalled();
77
- this.result.status = status;
78
- }
79
-
80
- /**
81
- * @param input Input witness data required for a runtime execution
82
- */
83
- public setup(input: RuntimeMethodExecutionData) {
84
- this.input = input;
85
- }
86
-
87
- /**
88
- * Manually clears/resets the execution context
89
- */
90
- public clear() {
91
- this.result = new RuntimeProvableMethodExecutionResult();
92
- }
93
-
94
- public afterMethod() {
95
- super.afterMethod();
96
- this.lastInput = this.input;
97
- this.input = undefined;
98
- }
99
-
100
- /**
101
- * Had to override current() otherwise it would not infer
102
- * the type of result correctly (parent type would be reused)
103
- */
104
- public current() {
105
- return {
106
- isFinished: this.isFinished,
107
- result: this.result,
108
- input: this.lastInput,
109
- };
110
- }
111
- }
@@ -1,49 +0,0 @@
1
- import "reflect-metadata";
2
-
3
- import { Bool } from "snarkyjs";
4
- import { container } from "tsyringe";
5
-
6
- import { assert } from "./assert.js";
7
- import { RuntimeMethodExecutionContext } from "./RuntimeMethodExecutionContext.js";
8
-
9
- describe("assert", () => {
10
- const defaultStatusMessage = "something went wrong";
11
- const executionContext = container.resolve(RuntimeMethodExecutionContext);
12
-
13
- beforeEach(() => {
14
- executionContext.beforeMethod("testConstructor", "test");
15
- });
16
-
17
- afterEach(() => {
18
- executionContext.afterMethod();
19
- });
20
-
21
- describe.each([
22
- [true, undefined],
23
- [false, undefined],
24
- [false, defaultStatusMessage],
25
- ])("status and message propagation", (status, statusMessage) => {
26
- it("should propagate the assertion status and message", () => {
27
- expect.assertions(2);
28
-
29
- assert(Bool(status), statusMessage);
30
-
31
- const { status: resultStatus, statusMessage: resultStatusMessage } =
32
- executionContext.current().result;
33
-
34
- expect(status).toBe(resultStatus.toBoolean());
35
- expect(statusMessage).toBe(resultStatusMessage);
36
- });
37
- });
38
-
39
- it("should keep a false status, once it was already set", () => {
40
- expect.assertions(1);
41
-
42
- assert(Bool(false));
43
- assert(Bool(true));
44
-
45
- const { status } = executionContext.current().result;
46
-
47
- expect(status.toBoolean()).toBe(false);
48
- });
49
- });
@@ -1,27 +0,0 @@
1
- import { Bool, Provable } from "snarkyjs";
2
- import { container } from "tsyringe";
3
-
4
- import { RuntimeMethodExecutionContext } from "./RuntimeMethodExecutionContext";
5
- import { log } from "@proto-kit/common";
6
-
7
- /**
8
- * Maintains an execution status of the current runtime module method,
9
- * while prioritizing one-time failures. The assertion won't change the
10
- * execution status if it has previously failed at least once within the
11
- * same method execution context.
12
- *
13
- * @param condition - Result of the assertion made about the execution status
14
- * @param message - Optional message describing the prior status
15
- */
16
- export function assert(condition: Bool, message?: string) {
17
- const executionContext = container.resolve(RuntimeMethodExecutionContext);
18
- const previousStatus = executionContext.current().result.status;
19
- const status = Provable.if(previousStatus, Bool, condition, previousStatus);
20
-
21
- if (!condition.toBoolean()) {
22
- log.debug("Assertion failed: ", message);
23
- executionContext.setStatusMessage(message);
24
- }
25
-
26
- executionContext.setStatus(status);
27
- }
@@ -1,154 +0,0 @@
1
- /* eslint-disable new-cap */
2
-
3
- import { Mixin } from "ts-mixer";
4
- import { Bool, Field, Provable, type FlexibleProvablePure } from "snarkyjs";
5
- import { container } from "tsyringe";
6
- import { Option, StateTransition, type Path } from "@proto-kit/protocol";
7
-
8
- import { PartialRuntime } from "../runtime/RuntimeModule.js";
9
- import { RuntimeMethodExecutionContext } from "../method/RuntimeMethodExecutionContext.js";
10
-
11
- export class WithPath {
12
- public path?: Field;
13
-
14
- public hasPathOrFail(): asserts this is { path: Path } {
15
- if (!this.path) {
16
- throw new Error(
17
- "Could not find 'path', did you forget to add '@state' to your state property?"
18
- );
19
- }
20
- }
21
- }
22
-
23
- export class WithRuntime {
24
- public runtime?: PartialRuntime;
25
-
26
- public hasRuntimeOrFail(): asserts this is {
27
- runtime: PartialRuntime;
28
- } {
29
- if (!this.runtime) {
30
- throw new Error(
31
- "Could not find 'runtime', did you forget to add '@state' to your state property?"
32
- );
33
- }
34
- }
35
- }
36
-
37
- /**
38
- * Utilities for runtime module state, such as get/set
39
- */
40
- export class State<Value> extends Mixin(WithPath, WithRuntime) {
41
- /**
42
- * Creates a new state wrapper for the provided value type.
43
- *
44
- * @param valueType - Type of value to be stored (e.g. UInt64, Struct, ...)
45
- * @returns New state for the given value type.
46
- */
47
- public static from<Value>(valueType: FlexibleProvablePure<Value>) {
48
- return new State<Value>(valueType);
49
- }
50
-
51
- /**
52
- * Computes a dummy value for the given value type.
53
- *
54
- * @param valueType - Value type to generate the dummy value for
55
- * @returns Dummy value for the given value type
56
- */
57
- public static dummyValue<Value>(
58
- valueType: FlexibleProvablePure<Value>
59
- ): Value {
60
- const length = valueType.sizeInFields();
61
- const fields = Array.from({ length }, () => Field(0));
62
-
63
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
64
- return valueType.fromFields(fields) as Value;
65
- }
66
-
67
- public constructor(public valueType: FlexibleProvablePure<Value>) {
68
- super();
69
- }
70
-
71
- /**
72
- * Provides an in-circuit witness for the current state representation,
73
- * and constructs an Option out of it.
74
- *
75
- * @returns Optional value of the current state
76
- */
77
- private witnessState() {
78
- // get the value from storage, or return a dummy value instead
79
- const value = Provable.witness(this.valueType, () => {
80
- this.hasRuntimeOrFail();
81
- this.hasPathOrFail();
82
-
83
- const fields = this.runtime.stateService.get(this.path);
84
- if (fields) {
85
- // eslint-disable-next-line max-len
86
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
87
- return this.valueType.fromFields(fields) as Value;
88
- }
89
-
90
- return State.dummyValue(this.valueType);
91
- });
92
-
93
- // check if the value exists in the storage or not
94
- const isSome = Provable.witness(Bool, () => {
95
- this.hasRuntimeOrFail();
96
- this.hasPathOrFail();
97
-
98
- const fields = this.runtime.stateService.get(this.path);
99
-
100
- return Bool(fields !== undefined);
101
- });
102
-
103
- return Option.from(isSome, value, this.valueType);
104
- }
105
-
106
- /**
107
- * Retrieves the current state and creates a state transition
108
- * anchoring the use of the current state value in the circuit.
109
- *
110
- * @returns Option representation of the current state.
111
- */
112
- public get(): Option<Value> {
113
- const option = this.witnessState();
114
-
115
- this.hasPathOrFail();
116
-
117
- const stateTransition = StateTransition.from(this.path, option);
118
-
119
- container
120
- .resolve(RuntimeMethodExecutionContext)
121
- .addStateTransition(stateTransition);
122
-
123
- return option;
124
- }
125
-
126
- /**
127
- * Sets a new state value by creating a state transition from
128
- * the current value to the newly set value.
129
- *
130
- * The newly set value isn't available via state.get(), since the
131
- * state transitions are not applied within the same circuit.
132
- * You can however store and access your new value in
133
- * a separate circuit variable.
134
- *
135
- * @param value - Value to be set as the current state
136
- */
137
- public set(value: Value) {
138
- // link the transition to the current state
139
- const fromOption = this.witnessState();
140
- const toOption = Option.from(Bool(true), value, this.valueType);
141
-
142
- this.hasPathOrFail();
143
-
144
- const stateTransition = StateTransition.fromTo(
145
- this.path,
146
- fromOption,
147
- toOption
148
- );
149
-
150
- container
151
- .resolve(RuntimeMethodExecutionContext)
152
- .addStateTransition(stateTransition);
153
- }
154
- }