@proto-kit/protocol 0.1.1-develop.1088 → 0.1.1-develop.1309

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 (211) hide show
  1. package/dist/Constants.js +1 -0
  2. package/dist/Constants.js.map +1 -0
  3. package/dist/hooks/AccountStateHook.js +1 -0
  4. package/dist/hooks/AccountStateHook.js.map +1 -0
  5. package/dist/hooks/BlockHeightHook.js +1 -0
  6. package/dist/hooks/BlockHeightHook.js.map +1 -0
  7. package/dist/hooks/LastStateRootBlockHook.js +1 -0
  8. package/dist/hooks/LastStateRootBlockHook.js.map +1 -0
  9. package/dist/hooks/NoopBlockHook.js +1 -0
  10. package/dist/hooks/NoopBlockHook.js.map +1 -0
  11. package/dist/hooks/NoopSettlementHook.d.ts +2 -2
  12. package/dist/hooks/NoopSettlementHook.d.ts.map +1 -1
  13. package/dist/hooks/NoopSettlementHook.js +1 -0
  14. package/dist/hooks/NoopSettlementHook.js.map +1 -0
  15. package/dist/hooks/NoopTransactionHook.js +1 -0
  16. package/dist/hooks/NoopTransactionHook.js.map +1 -0
  17. package/dist/index.d.ts +6 -2
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +7 -2
  20. package/dist/index.js.map +1 -0
  21. package/dist/model/MethodPublicOutput.js +1 -0
  22. package/dist/model/MethodPublicOutput.js.map +1 -0
  23. package/dist/model/Option.js +1 -0
  24. package/dist/model/Option.js.map +1 -0
  25. package/dist/model/Path.js +1 -0
  26. package/dist/model/Path.js.map +1 -0
  27. package/dist/model/RuntimeLike.js +1 -0
  28. package/dist/model/RuntimeLike.js.map +1 -0
  29. package/dist/model/StateTransition.js +1 -0
  30. package/dist/model/StateTransition.js.map +1 -0
  31. package/dist/model/StateTransitionProvableBatch.d.ts +28 -2
  32. package/dist/model/StateTransitionProvableBatch.d.ts.map +1 -1
  33. package/dist/model/StateTransitionProvableBatch.js +9 -3
  34. package/dist/model/StateTransitionProvableBatch.js.map +1 -0
  35. package/dist/model/network/NetworkState.js +1 -0
  36. package/dist/model/network/NetworkState.js.map +1 -0
  37. package/dist/model/transaction/RuntimeTransaction.js +1 -0
  38. package/dist/model/transaction/RuntimeTransaction.js.map +1 -0
  39. package/dist/model/transaction/SignedTransaction.js +1 -0
  40. package/dist/model/transaction/SignedTransaction.js.map +1 -0
  41. package/dist/model/transaction/ValueOption.js +1 -0
  42. package/dist/model/transaction/ValueOption.js.map +1 -0
  43. package/dist/protocol/Protocol.d.ts.map +1 -1
  44. package/dist/protocol/Protocol.js +31 -6
  45. package/dist/protocol/Protocol.js.map +1 -0
  46. package/dist/protocol/ProtocolEnvironment.js +1 -0
  47. package/dist/protocol/ProtocolEnvironment.js.map +1 -0
  48. package/dist/protocol/ProtocolModule.d.ts +1 -1
  49. package/dist/protocol/ProtocolModule.d.ts.map +1 -1
  50. package/dist/protocol/ProtocolModule.js +2 -1
  51. package/dist/protocol/ProtocolModule.js.map +1 -0
  52. package/dist/protocol/ProvableBlockHook.js +1 -0
  53. package/dist/protocol/ProvableBlockHook.js.map +1 -0
  54. package/dist/protocol/ProvableTransactionHook.js +1 -0
  55. package/dist/protocol/ProvableTransactionHook.js.map +1 -0
  56. package/dist/protocol/TransitioningProtocolModule.js +1 -0
  57. package/dist/protocol/TransitioningProtocolModule.js.map +1 -0
  58. package/dist/prover/block/BlockProvable.d.ts +19 -5
  59. package/dist/prover/block/BlockProvable.d.ts.map +1 -1
  60. package/dist/prover/block/BlockProvable.js +5 -2
  61. package/dist/prover/block/BlockProvable.js.map +1 -0
  62. package/dist/prover/block/BlockProver.d.ts +11 -9
  63. package/dist/prover/block/BlockProver.d.ts.map +1 -1
  64. package/dist/prover/block/BlockProver.js +79 -41
  65. package/dist/prover/block/BlockProver.js.map +1 -0
  66. package/dist/prover/block/accummulators/BlockHashMerkleTree.js +1 -0
  67. package/dist/prover/block/accummulators/BlockHashMerkleTree.js.map +1 -0
  68. package/dist/prover/block/accummulators/RuntimeVerificationKeyTree.d.ts +2 -2
  69. package/dist/prover/block/accummulators/RuntimeVerificationKeyTree.js +1 -0
  70. package/dist/prover/block/accummulators/RuntimeVerificationKeyTree.js.map +1 -0
  71. package/dist/prover/block/services/RuntimeVerificationKeyRootService.js +1 -0
  72. package/dist/prover/block/services/RuntimeVerificationKeyRootService.js.map +1 -0
  73. package/dist/prover/statetransition/StateTransitionProvable.d.ts +2 -4
  74. package/dist/prover/statetransition/StateTransitionProvable.d.ts.map +1 -1
  75. package/dist/prover/statetransition/StateTransitionProvable.js +1 -0
  76. package/dist/prover/statetransition/StateTransitionProvable.js.map +1 -0
  77. package/dist/prover/statetransition/StateTransitionProver.d.ts +7 -10
  78. package/dist/prover/statetransition/StateTransitionProver.d.ts.map +1 -1
  79. package/dist/prover/statetransition/StateTransitionProver.js +27 -28
  80. package/dist/prover/statetransition/StateTransitionProver.js.map +1 -0
  81. package/dist/settlement/ContractModule.d.ts +4 -3
  82. package/dist/settlement/ContractModule.d.ts.map +1 -1
  83. package/dist/settlement/ContractModule.js +2 -1
  84. package/dist/settlement/ContractModule.js.map +1 -0
  85. package/dist/settlement/SettlementContractModule.d.ts +25 -12
  86. package/dist/settlement/SettlementContractModule.d.ts.map +1 -1
  87. package/dist/settlement/SettlementContractModule.js +29 -20
  88. package/dist/settlement/SettlementContractModule.js.map +1 -0
  89. package/dist/settlement/contracts/BridgeContract.d.ts +97 -0
  90. package/dist/settlement/contracts/BridgeContract.d.ts.map +1 -0
  91. package/dist/settlement/contracts/BridgeContract.js +164 -0
  92. package/dist/settlement/contracts/BridgeContract.js.map +1 -0
  93. package/dist/settlement/contracts/BridgeContractProtocolModule.d.ts +14 -0
  94. package/dist/settlement/contracts/BridgeContractProtocolModule.d.ts.map +1 -0
  95. package/dist/settlement/contracts/BridgeContractProtocolModule.js +30 -0
  96. package/dist/settlement/contracts/BridgeContractProtocolModule.js.map +1 -0
  97. package/dist/settlement/contracts/DispatchContractProtocolModule.d.ts +10 -1
  98. package/dist/settlement/contracts/DispatchContractProtocolModule.d.ts.map +1 -1
  99. package/dist/settlement/contracts/DispatchContractProtocolModule.js +24 -2
  100. package/dist/settlement/contracts/DispatchContractProtocolModule.js.map +1 -0
  101. package/dist/settlement/contracts/DispatchSmartContract.d.ts +26 -4
  102. package/dist/settlement/contracts/DispatchSmartContract.d.ts.map +1 -1
  103. package/dist/settlement/contracts/DispatchSmartContract.js +139 -19
  104. package/dist/settlement/contracts/DispatchSmartContract.js.map +1 -0
  105. package/dist/settlement/contracts/SettlementContractProtocolModule.d.ts +10 -8
  106. package/dist/settlement/contracts/SettlementContractProtocolModule.d.ts.map +1 -1
  107. package/dist/settlement/contracts/SettlementContractProtocolModule.js +47 -9
  108. package/dist/settlement/contracts/SettlementContractProtocolModule.js.map +1 -0
  109. package/dist/settlement/contracts/SettlementSmartContract.d.ts +98 -17
  110. package/dist/settlement/contracts/SettlementSmartContract.d.ts.map +1 -1
  111. package/dist/settlement/contracts/SettlementSmartContract.js +147 -79
  112. package/dist/settlement/contracts/SettlementSmartContract.js.map +1 -0
  113. package/dist/settlement/contracts/TokenBridgeTree.d.ts +228 -0
  114. package/dist/settlement/contracts/TokenBridgeTree.d.ts.map +1 -0
  115. package/dist/settlement/contracts/TokenBridgeTree.js +60 -0
  116. package/dist/settlement/contracts/TokenBridgeTree.js.map +1 -0
  117. package/dist/settlement/contracts/authorizations/ContractAuthorization.d.ts +10 -0
  118. package/dist/settlement/contracts/authorizations/ContractAuthorization.d.ts.map +1 -0
  119. package/dist/settlement/contracts/authorizations/ContractAuthorization.js +2 -0
  120. package/dist/settlement/contracts/authorizations/ContractAuthorization.js.map +1 -0
  121. package/dist/settlement/contracts/authorizations/TokenBridgeDeploymentAuth.d.ts +85 -0
  122. package/dist/settlement/contracts/authorizations/TokenBridgeDeploymentAuth.d.ts.map +1 -0
  123. package/dist/settlement/contracts/authorizations/TokenBridgeDeploymentAuth.js +11 -0
  124. package/dist/settlement/contracts/authorizations/TokenBridgeDeploymentAuth.js.map +1 -0
  125. package/dist/settlement/contracts/authorizations/UpdateMessagesHashAuth.d.ts +79 -0
  126. package/dist/settlement/contracts/authorizations/UpdateMessagesHashAuth.d.ts.map +1 -0
  127. package/dist/settlement/contracts/authorizations/UpdateMessagesHashAuth.js +11 -0
  128. package/dist/settlement/contracts/authorizations/UpdateMessagesHashAuth.js.map +1 -0
  129. package/dist/settlement/messages/Deposit.d.ts +13 -0
  130. package/dist/settlement/messages/Deposit.d.ts.map +1 -1
  131. package/dist/settlement/messages/Deposit.js +3 -1
  132. package/dist/settlement/messages/Deposit.js.map +1 -0
  133. package/dist/settlement/messages/OutgoingMessageArgument.d.ts +8 -0
  134. package/dist/settlement/messages/OutgoingMessageArgument.d.ts.map +1 -1
  135. package/dist/settlement/messages/OutgoingMessageArgument.js +1 -0
  136. package/dist/settlement/messages/OutgoingMessageArgument.js.map +1 -0
  137. package/dist/settlement/messages/Withdrawal.d.ts +13 -0
  138. package/dist/settlement/messages/Withdrawal.d.ts.map +1 -1
  139. package/dist/settlement/messages/Withdrawal.js +4 -1
  140. package/dist/settlement/messages/Withdrawal.js.map +1 -0
  141. package/dist/settlement/modularity/ProvableSettlementHook.d.ts +5 -3
  142. package/dist/settlement/modularity/ProvableSettlementHook.d.ts.map +1 -1
  143. package/dist/settlement/modularity/ProvableSettlementHook.js +1 -0
  144. package/dist/settlement/modularity/ProvableSettlementHook.js.map +1 -0
  145. package/dist/settlement/modularity/types.d.ts +8 -0
  146. package/dist/settlement/modularity/types.d.ts.map +1 -0
  147. package/dist/settlement/modularity/types.js +2 -0
  148. package/dist/settlement/modularity/types.js.map +1 -0
  149. package/dist/settlement/modules/NetworkStateSettlementModule.js +1 -0
  150. package/dist/settlement/modules/NetworkStateSettlementModule.js.map +1 -0
  151. package/dist/state/State.js +1 -0
  152. package/dist/state/State.js.map +1 -0
  153. package/dist/state/StateMap.js +1 -0
  154. package/dist/state/StateMap.js.map +1 -0
  155. package/dist/state/StateService.js +1 -0
  156. package/dist/state/StateService.js.map +1 -0
  157. package/dist/state/StateServiceProvider.js +1 -0
  158. package/dist/state/StateServiceProvider.js.map +1 -0
  159. package/dist/state/assert/assert.js +1 -0
  160. package/dist/state/assert/assert.js.map +1 -0
  161. package/dist/state/context/RuntimeMethodExecutionContext.js +1 -0
  162. package/dist/state/context/RuntimeMethodExecutionContext.js.map +1 -0
  163. package/dist/state/context/TransitionMethodExecutionContext.js +1 -0
  164. package/dist/state/context/TransitionMethodExecutionContext.js.map +1 -0
  165. package/dist/state/protocol/ProtocolState.js +1 -0
  166. package/dist/state/protocol/ProtocolState.js.map +1 -0
  167. package/dist/utils/MinaPrefixedProvableHashList.js +1 -0
  168. package/dist/utils/MinaPrefixedProvableHashList.js.map +1 -0
  169. package/dist/utils/PrefixedProvableHashList.js +1 -0
  170. package/dist/utils/PrefixedProvableHashList.js.map +1 -0
  171. package/dist/utils/ProvableHashList.js +1 -0
  172. package/dist/utils/ProvableHashList.js.map +1 -0
  173. package/dist/utils/ProvableReductionHashList.js +1 -0
  174. package/dist/utils/ProvableReductionHashList.js.map +1 -0
  175. package/dist/utils/StateTransitionReductionList.js +1 -0
  176. package/dist/utils/StateTransitionReductionList.js.map +1 -0
  177. package/dist/utils/utils.js +1 -0
  178. package/dist/utils/utils.js.map +1 -0
  179. package/jest.config.cjs +12 -1
  180. package/package.json +4 -4
  181. package/src/hooks/NoopSettlementHook.ts +2 -2
  182. package/src/index.ts +6 -2
  183. package/src/model/StateTransitionProvableBatch.ts +24 -4
  184. package/src/protocol/Protocol.ts +36 -7
  185. package/src/protocol/ProtocolModule.ts +1 -1
  186. package/src/prover/block/BlockProvable.ts +9 -9
  187. package/src/prover/block/BlockProver.ts +94 -58
  188. package/src/prover/statetransition/StateTransitionProvable.ts +5 -8
  189. package/src/prover/statetransition/StateTransitionProver.ts +46 -40
  190. package/src/settlement/ContractModule.ts +17 -10
  191. package/src/settlement/SettlementContractModule.ts +54 -41
  192. package/src/settlement/contracts/BridgeContract.ts +237 -0
  193. package/src/settlement/contracts/BridgeContractProtocolModule.ts +43 -0
  194. package/src/settlement/contracts/DispatchContractProtocolModule.ts +37 -3
  195. package/src/settlement/contracts/DispatchSmartContract.ts +213 -23
  196. package/src/settlement/contracts/SettlementContractProtocolModule.ts +61 -20
  197. package/src/settlement/contracts/SettlementSmartContract.ts +261 -107
  198. package/src/settlement/contracts/TokenBridgeTree.ts +73 -0
  199. package/src/settlement/contracts/authorizations/ContractAuthorization.ts +11 -0
  200. package/src/settlement/contracts/authorizations/TokenBridgeDeploymentAuth.ts +16 -0
  201. package/src/settlement/contracts/authorizations/UpdateMessagesHashAuth.ts +16 -0
  202. package/src/settlement/messages/Deposit.ts +2 -1
  203. package/src/settlement/messages/Withdrawal.ts +3 -1
  204. package/src/settlement/modularity/ProvableSettlementHook.ts +6 -3
  205. package/src/settlement/modularity/types.ts +22 -0
  206. package/test/BlockProver.test.ts +2 -1
  207. package/test/TestingProtocol.ts +17 -12
  208. package/test/compiling/types.ts +28 -0
  209. package/test/modularity/types.ts +35 -0
  210. package/src/prover/statetransition/StateTransitionWitnessProvider.ts +0 -23
  211. package/src/prover/statetransition/StateTransitionWitnessProviderReference.ts +0 -17
@@ -1,6 +1,8 @@
1
1
  import { inject, injectable } from "tsyringe";
2
+ import { PublicKey } from "o1js";
3
+ import { CompileRegistry } from "@proto-kit/common";
2
4
 
3
- import { RuntimeLike } from "../../model/RuntimeLike";
5
+ import { RuntimeLike, RuntimeMethodIdMapping } from "../../model/RuntimeLike";
4
6
  import {
5
7
  ContractModule,
6
8
  SmartContractClassFromInterface,
@@ -9,6 +11,7 @@ import {
9
11
  import {
10
12
  DispatchSmartContract,
11
13
  DispatchContractType,
14
+ DispatchSmartContractBase,
12
15
  } from "./DispatchSmartContract";
13
16
 
14
17
  export type DispatchContractConfig = {
@@ -18,22 +21,53 @@ export type DispatchContractConfig = {
18
21
  @injectable()
19
22
  export class DispatchContractProtocolModule extends ContractModule<
20
23
  DispatchContractType,
21
- undefined,
22
24
  DispatchContractConfig
23
25
  > {
24
26
  public constructor(@inject("Runtime") private readonly runtime: RuntimeLike) {
25
27
  super();
26
28
  }
27
29
 
30
+ public eventsDefinition() {
31
+ return new DispatchSmartContract(PublicKey.empty<typeof PublicKey>())
32
+ .events;
33
+ }
34
+
35
+ private checkConfigIntegrity(
36
+ incomingMessagesMethods: Record<string, `${string}.${string}`>,
37
+ runtimeMethodIds: RuntimeMethodIdMapping
38
+ ) {
39
+ const missing = Object.values(incomingMessagesMethods).filter(
40
+ (method) => runtimeMethodIds[method] === undefined
41
+ );
42
+ if (missing.length > 0) {
43
+ throw new Error(
44
+ `Incoming messages config references a unknown methods: [${missing}]`
45
+ );
46
+ }
47
+ }
48
+
28
49
  public contractFactory(): SmartContractClassFromInterface<DispatchContractType> {
29
50
  const { incomingMessagesMethods } = this.config;
30
51
  const methodIdMappings = this.runtime.methodIdResolver.methodIdMap();
31
52
 
32
- DispatchSmartContract.args = {
53
+ this.checkConfigIntegrity(incomingMessagesMethods, methodIdMappings);
54
+
55
+ DispatchSmartContractBase.args = {
33
56
  incomingMessagesPaths: incomingMessagesMethods,
34
57
  methodIdMappings,
58
+ settlementContractClass:
59
+ DispatchSmartContractBase.args?.settlementContractClass,
35
60
  };
36
61
 
37
62
  return DispatchSmartContract;
38
63
  }
64
+
65
+ public async compile(registry: CompileRegistry) {
66
+ if (DispatchSmartContractBase.args.settlementContractClass === undefined) {
67
+ throw new Error("Reference to Settlement Contract not set");
68
+ }
69
+ return {
70
+ DispatchSmartContract: await registry.compile(DispatchSmartContract),
71
+ };
72
+ }
39
73
  }
@@ -1,16 +1,20 @@
1
1
  import {
2
2
  AccountUpdate,
3
+ Bool,
3
4
  Field,
4
5
  method,
5
6
  Poseidon,
7
+ Provable,
6
8
  ProvableExtended,
7
9
  PublicKey,
8
10
  Reducer,
9
11
  SmartContract,
10
12
  State,
11
13
  state,
14
+ TokenId,
12
15
  UInt64,
13
16
  } from "o1js";
17
+ import { InMemoryMerkleTreeStorage, TypedClass } from "@proto-kit/common";
14
18
 
15
19
  import { RuntimeMethodIdMapping } from "../../model/RuntimeLike";
16
20
  import { RuntimeTransaction } from "../../model/transaction/RuntimeTransaction";
@@ -20,6 +24,17 @@ import {
20
24
  } from "../../utils/MinaPrefixedProvableHashList";
21
25
  import { Deposit } from "../messages/Deposit";
22
26
 
27
+ import type { SettlementContractType } from "./SettlementSmartContract";
28
+ import { TokenBridgeDeploymentAuth } from "./authorizations/TokenBridgeDeploymentAuth";
29
+ import { UpdateMessagesHashAuth } from "./authorizations/UpdateMessagesHashAuth";
30
+ import {
31
+ TokenBridgeAttestation,
32
+ TokenBridgeEntry,
33
+ TokenBridgeTree,
34
+ TokenBridgeTreeAddition,
35
+ TokenBridgeTreeWitness,
36
+ } from "./TokenBridgeTree";
37
+
23
38
  export const ACTIONS_EMPTY_HASH = Reducer.initialActionState;
24
39
 
25
40
  export interface DispatchContractType {
@@ -28,27 +43,46 @@ export interface DispatchContractType {
28
43
  newPromisedMessagesHash: Field
29
44
  ) => Promise<void>;
30
45
  initialize: (settlementContract: PublicKey) => Promise<void>;
46
+ enableTokenDeposits: (
47
+ tokenId: Field,
48
+ bridgeContractAddress: PublicKey,
49
+ settlementContractAddress: PublicKey
50
+ ) => Promise<void>;
31
51
 
32
52
  promisedMessagesHash: State<Field>;
33
53
  }
34
54
 
35
- export class DispatchSmartContract
36
- extends SmartContract
37
- implements DispatchContractType
38
- {
55
+ const tokenBridgeRoot = new TokenBridgeTree(
56
+ new InMemoryMerkleTreeStorage()
57
+ ).getRoot();
58
+
59
+ export abstract class DispatchSmartContractBase extends SmartContract {
39
60
  public static args: {
40
61
  methodIdMappings: RuntimeMethodIdMapping;
41
62
  incomingMessagesPaths: Record<string, `${string}.${string}`>;
63
+ settlementContractClass?: TypedClass<SettlementContractType> &
64
+ typeof SmartContract;
42
65
  };
43
66
 
44
- @state(Field) public promisedMessagesHash = State<Field>();
67
+ events = {
68
+ "token-bridge-added": TokenBridgeTreeAddition,
69
+ // We need a placeholder event here, so that o1js internally adds a identifier to the
70
+ // emitted event-fields. That will lead to the o1js API being able to distinguish the
71
+ // TokenBridgeEvents from the manually emitted events for the incoming messages
72
+ "incoming-message-placeholder": Field,
73
+ };
45
74
 
46
- @state(Field) public honoredMessagesHash = State<Field>();
75
+ abstract promisedMessagesHash: State<Field>;
47
76
 
48
- @state(PublicKey) public settlementContract = State<PublicKey>();
77
+ abstract honoredMessagesHash: State<Field>;
49
78
 
50
- @method
51
- public async updateMessagesHash(
79
+ abstract settlementContract: State<PublicKey>;
80
+
81
+ abstract tokenBridgeRoot: State<Field>;
82
+
83
+ abstract tokenBridgeCount: State<Field>;
84
+
85
+ protected updateMessagesHashBase(
52
86
  executedMessagesHash: Field,
53
87
  newPromisedMessagesHash: Field
54
88
  ) {
@@ -63,10 +97,25 @@ export class DispatchSmartContract
63
97
  // Assert and apply new promisedMessagesHash
64
98
  this.self.account.actionState.requireEquals(newPromisedMessagesHash);
65
99
  this.promisedMessagesHash.set(newPromisedMessagesHash);
100
+
101
+ const settlementContractAddress =
102
+ this.settlementContract.getAndRequireEquals();
103
+ const settlementContract =
104
+ new DispatchSmartContractBase.args.settlementContractClass!(
105
+ settlementContractAddress
106
+ );
107
+
108
+ settlementContract.authorizationField.requireEquals(
109
+ new UpdateMessagesHashAuth({
110
+ target: this.address,
111
+ executedMessagesHash,
112
+ newPromisedMessagesHash,
113
+ }).hash()
114
+ );
115
+ this.approve(settlementContract.self);
66
116
  }
67
117
 
68
- @method
69
- public async initialize(settlementContract: PublicKey) {
118
+ protected initializeBase(settlementContract: PublicKey) {
70
119
  this.promisedMessagesHash.getAndRequireEquals().assertEquals(Field(0));
71
120
  this.honoredMessagesHash.getAndRequireEquals().assertEquals(Field(0));
72
121
  this.settlementContract
@@ -78,7 +127,7 @@ export class DispatchSmartContract
78
127
  this.settlementContract.set(settlementContract);
79
128
  }
80
129
 
81
- private dispatchMessage<Type>(
130
+ protected dispatchMessage<Type>(
82
131
  methodId: Field,
83
132
  value: Type,
84
133
  valueType: ProvableExtended<Type>
@@ -100,37 +149,178 @@ export class DispatchSmartContract
100
149
  data: [actionData],
101
150
  };
102
151
 
103
- const eventHash = MinaEvents.eventHash(args);
152
+ // Find event index of placeholder event that we can use for manual event dispatching
153
+ const eventIndex = Object.keys(this.events)
154
+ .sort()
155
+ .indexOf("incoming-message-placeholder");
156
+ if (eventIndex === -1) {
157
+ throw new Error("Unknown event type for placeholder event");
158
+ }
159
+ const paddedArgs = [Field(eventIndex), ...args];
160
+
161
+ const eventHash = MinaEvents.eventHash(paddedArgs);
104
162
  this.self.body.events = {
105
163
  hash: eventHash,
106
- data: [args],
164
+ data: [paddedArgs],
107
165
  };
108
166
  }
109
167
 
168
+ protected async enableTokenDepositsBase(
169
+ tokenId: Field,
170
+ bridgeContractAddress: PublicKey,
171
+ // Witness it here, since o1js doesn't fetch this state correctly since
172
+ // its updated in a parent AU
173
+ settlementContractAddress: PublicKey
174
+ // treeWitness: TokenBridgeTreeWitness
175
+ ) {
176
+ this.settlementContract.requireEquals(settlementContractAddress);
177
+ const settlementContract =
178
+ new DispatchSmartContractBase.args.settlementContractClass!(
179
+ settlementContractAddress
180
+ );
181
+
182
+ // Append bridge address to the tree
183
+ // TODO This not concurrent and will fail if multiple users deploy bridges at the same time
184
+ const counter = this.tokenBridgeCount.getAndRequireEquals();
185
+ const root = this.tokenBridgeRoot.getAndRequireEquals();
186
+
187
+ const treeWitness = await Provable.witnessAsync(
188
+ TokenBridgeTreeWitness,
189
+ async () => {
190
+ const tree = await TokenBridgeTree.buildTreeFromEvents(this);
191
+ return tree.getWitness(counter.toBigInt());
192
+ }
193
+ );
194
+
195
+ Provable.log(root);
196
+ treeWitness
197
+ .checkMembership(root, counter, Field(0))
198
+ .assertTrue("Bridge Tree Witness not valid");
199
+
200
+ const entry = new TokenBridgeEntry({
201
+ tokenId,
202
+ address: bridgeContractAddress,
203
+ });
204
+ const newRoot = treeWitness.calculateRoot(entry.hash());
205
+ this.tokenBridgeRoot.set(newRoot);
206
+ this.tokenBridgeCount.set(counter.add(1));
207
+
208
+ this.emitEvent(
209
+ "token-bridge-added",
210
+ new TokenBridgeTreeAddition({
211
+ index: counter,
212
+ value: entry,
213
+ })
214
+ );
215
+
216
+ // Authenticate call via callback
217
+ settlementContract.authorizationField.requireEquals(
218
+ new TokenBridgeDeploymentAuth({
219
+ target: this.address,
220
+ tokenId,
221
+ address: bridgeContractAddress,
222
+ }).hash()
223
+ );
224
+
225
+ this.approve(settlementContract.self);
226
+ }
227
+ }
228
+
229
+ export class DispatchSmartContract
230
+ extends DispatchSmartContractBase
231
+ implements DispatchContractType
232
+ {
233
+ @state(Field) public promisedMessagesHash = State<Field>();
234
+
235
+ @state(Field) public honoredMessagesHash = State<Field>();
236
+
237
+ @state(PublicKey) public settlementContract = State<PublicKey>();
238
+
239
+ @state(Field) public tokenBridgeRoot = State<Field>(tokenBridgeRoot);
240
+
241
+ @state(Field) public tokenBridgeCount = State<Field>();
242
+
243
+ @method
244
+ public async enableTokenDeposits(
245
+ tokenId: Field,
246
+ bridgeContractAddress: PublicKey,
247
+ settlementContractAddress: PublicKey
248
+ ) {
249
+ await this.enableTokenDepositsBase(
250
+ tokenId,
251
+ bridgeContractAddress,
252
+ settlementContractAddress
253
+ );
254
+ }
255
+
256
+ @method
257
+ public async updateMessagesHash(
258
+ executedMessagesHash: Field,
259
+ newPromisedMessagesHash: Field
260
+ ) {
261
+ return this.updateMessagesHashBase(
262
+ executedMessagesHash,
263
+ newPromisedMessagesHash
264
+ );
265
+ }
266
+
267
+ @method
268
+ public async initialize(settlementContract: PublicKey) {
269
+ return this.initializeBase(settlementContract);
270
+ }
271
+
110
272
  @method
111
- public async deposit(amount: UInt64) {
112
- // Save this, since otherwise it would be a second witness later,
113
- // which could be a different values than the first
114
- const sender = this.sender.getUnconstrained();
273
+ public async deposit(
274
+ amount: UInt64,
275
+ tokenId: Field,
276
+ bridgingContract: PublicKey,
277
+ bridgingContractAttestation: TokenBridgeAttestation,
278
+ l2Receiver: PublicKey
279
+ ) {
280
+ const childrenMayUseToken: AccountUpdate["body"]["mayUseToken"] = {
281
+ parentsOwnToken: Bool(false),
282
+ // MayUseToken has to be set only for custom tokens
283
+ inheritFromParent: tokenId.equals(TokenId.default).not(),
284
+ };
115
285
 
116
- const settlementContract = this.settlementContract.getAndRequireEquals();
286
+ // Check that the bridgingContract parameter is valid => is in the offchain tree
287
+ const bridgeTreeRoot = this.tokenBridgeRoot.getAndRequireEquals();
288
+ const entry = new TokenBridgeEntry({
289
+ tokenId,
290
+ address: bridgingContract,
291
+ });
292
+
293
+ bridgingContractAttestation.witness
294
+ .checkMembership(
295
+ bridgeTreeRoot,
296
+ bridgingContractAttestation.index,
297
+ entry.hash()
298
+ )
299
+ .assertTrue("Bridging Contract Attestation not valid");
117
300
 
118
301
  // Credit the amount to the settlement contract
119
- const balanceAU = AccountUpdate.create(settlementContract);
302
+ const balanceAU = AccountUpdate.create(bridgingContract, tokenId);
120
303
  balanceAU.balance.addInPlace(amount);
121
- this.self.approve(balanceAU);
304
+ balanceAU.body.mayUseToken = childrenMayUseToken;
305
+ this.approve(balanceAU);
122
306
 
123
307
  const action = new Deposit({
124
- address: sender,
308
+ tokenId,
309
+ address: l2Receiver,
125
310
  amount,
126
311
  });
127
312
 
128
313
  const { methodIdMappings, incomingMessagesPaths } =
129
- DispatchSmartContract.args;
314
+ DispatchSmartContractBase.args;
130
315
 
131
316
  const methodId = Field(
132
317
  methodIdMappings[incomingMessagesPaths.deposit].methodId
133
318
  ).toConstant();
134
319
  this.dispatchMessage(methodId.toConstant(), action, Deposit);
320
+
321
+ this.self.body.mayUseToken = {
322
+ parentsOwnToken: tokenId.equals(TokenId.default).not(),
323
+ inheritFromParent: Bool(false),
324
+ };
135
325
  }
136
326
  }
@@ -1,6 +1,10 @@
1
- import { TypedClass } from "@proto-kit/common";
2
- import { SmartContract } from "o1js";
3
1
  import { inject, injectable, injectAll } from "tsyringe";
2
+ import {
3
+ ArtifactRecord,
4
+ ChildVerificationKeyService,
5
+ CompileRegistry,
6
+ log,
7
+ } from "@proto-kit/common";
4
8
 
5
9
  import { BlockProvable } from "../../prover/block/BlockProvable";
6
10
  import {
@@ -9,17 +13,18 @@ import {
9
13
  } from "../ContractModule";
10
14
  import { ProvableSettlementHook } from "../modularity/ProvableSettlementHook";
11
15
 
12
- import { DispatchContractType } from "./DispatchSmartContract";
16
+ import { DispatchSmartContractBase } from "./DispatchSmartContract";
13
17
  import {
14
- LazyBlockProof,
15
18
  SettlementContractType,
16
19
  SettlementSmartContract,
20
+ SettlementSmartContractBase,
17
21
  } from "./SettlementSmartContract";
22
+ import { BridgeContractBase } from "./BridgeContract";
23
+ import { DispatchContractProtocolModule } from "./DispatchContractProtocolModule";
24
+ import { BridgeContractProtocolModule } from "./BridgeContractProtocolModule";
18
25
 
19
26
  export type SettlementContractConfig = {
20
27
  escapeHatchSlotsInterval?: number;
21
- withdrawalStatePath: `${string}.${string}`;
22
- withdrawalMethodPath: `${string}.${string}`;
23
28
  };
24
29
 
25
30
  // 24 hours
@@ -28,40 +33,76 @@ const DEFAULT_ESCAPE_HATCH = (60 / 3) * 24;
28
33
  @injectable()
29
34
  export class SettlementContractProtocolModule extends ContractModule<
30
35
  SettlementContractType,
31
- TypedClass<DispatchContractType & SmartContract>,
32
36
  SettlementContractConfig
33
37
  > {
34
38
  public constructor(
35
39
  @injectAll("ProvableSettlementHook")
36
40
  private readonly hooks: ProvableSettlementHook<unknown>[],
37
41
  @inject("BlockProver")
38
- private readonly blockProver: BlockProvable
42
+ private readonly blockProver: BlockProvable,
43
+ @inject("DispatchContract")
44
+ private readonly dispatchContractModule: DispatchContractProtocolModule,
45
+ @inject("BridgeContract")
46
+ private readonly bridgeContractModule: BridgeContractProtocolModule,
47
+ private readonly childVerificationKeyService: ChildVerificationKeyService
39
48
  ) {
40
- LazyBlockProof.tag = blockProver.zkProgrammable.zkProgram[0].Proof.tag;
41
49
  super();
42
50
  }
43
51
 
44
- public contractFactory(
45
- dispatchContract: TypedClass<DispatchContractType & SmartContract>
46
- ): SmartContractClassFromInterface<SettlementContractType> {
52
+ public contractFactory(): SmartContractClassFromInterface<SettlementContractType> {
47
53
  const { hooks, config } = this;
48
-
49
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
50
- const withdrawalStatePathSplit = config.withdrawalStatePath.split(".") as [
51
- string,
52
- string,
53
- ];
54
+ const dispatchContract = this.dispatchContractModule.contractFactory();
55
+ const bridgeContract = this.bridgeContractModule.contractFactory();
54
56
 
55
57
  const escapeHatchSlotsInterval =
56
58
  config.escapeHatchSlotsInterval ?? DEFAULT_ESCAPE_HATCH;
57
59
 
58
- SettlementSmartContract.args = {
60
+ const { args } = SettlementSmartContractBase;
61
+ SettlementSmartContractBase.args = {
59
62
  DispatchContract: dispatchContract,
60
63
  hooks,
61
- withdrawalStatePath: withdrawalStatePathSplit,
62
64
  escapeHatchSlotsInterval,
65
+ BridgeContract: bridgeContract,
66
+ BridgeContractVerificationKey: args?.BridgeContractVerificationKey,
67
+ BridgeContractPermissions: args?.BridgeContractPermissions,
68
+ signedSettlements: args?.signedSettlements,
69
+ ChildVerificationKeyService: this.childVerificationKeyService,
63
70
  };
64
71
 
72
+ // Ideally we don't want to have this cyclic dependency, but we have it in the protocol,
73
+ // So its logical that we can't avoid that here
74
+ BridgeContractBase.args.SettlementContract = SettlementSmartContract;
75
+
76
+ DispatchSmartContractBase.args.settlementContractClass =
77
+ SettlementSmartContract;
78
+
65
79
  return SettlementSmartContract;
66
80
  }
81
+
82
+ public async compile(
83
+ registry: CompileRegistry
84
+ ): Promise<ArtifactRecord | undefined> {
85
+ // Dependencies
86
+ const bridgeArtifact = await this.bridgeContractModule.compile(registry);
87
+
88
+ await this.blockProver.compile(registry);
89
+
90
+ // Init params
91
+ SettlementSmartContractBase.args.BridgeContractVerificationKey =
92
+ bridgeArtifact.BridgeContract.verificationKey;
93
+
94
+ if (SettlementSmartContractBase.args.signedSettlements === undefined) {
95
+ throw new Error(
96
+ "Args not fully initialized - make sure to also include the SettlementModule in the sequencer"
97
+ );
98
+ }
99
+
100
+ log.debug("Compiling Settlement Contract");
101
+
102
+ const artifact = await registry.compile(SettlementSmartContract);
103
+
104
+ return {
105
+ SettlementSmartContract: artifact,
106
+ };
107
+ }
67
108
  }