@proto-kit/protocol 0.1.1-develop.1087 → 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
@@ -3,40 +3,36 @@ import {
3
3
  RollupMerkleTree,
4
4
  TypedClass,
5
5
  mapSequential,
6
+ ChildVerificationKeyService,
6
7
  } from "@proto-kit/common";
7
8
  import {
8
9
  AccountUpdate,
9
10
  Bool,
10
11
  Field,
11
12
  method,
12
- Mina,
13
- Poseidon,
14
- Proof,
15
- Provable,
16
13
  PublicKey,
17
14
  Signature,
18
15
  SmartContract,
19
16
  State,
20
17
  state,
21
- TokenId,
22
18
  UInt32,
23
- UInt64,
24
- TokenContract,
25
19
  AccountUpdateForest,
20
+ TokenContractV2,
21
+ PrivateKey,
22
+ VerificationKey,
23
+ Permissions,
24
+ Struct,
25
+ Provable,
26
+ TokenId,
27
+ DynamicProof,
26
28
  } from "o1js";
27
29
 
28
30
  import { NetworkState } from "../../model/network/NetworkState";
29
- import { Path } from "../../model/Path";
30
31
  import { BlockHashMerkleTree } from "../../prover/block/accummulators/BlockHashMerkleTree";
31
32
  import {
32
33
  BlockProverPublicInput,
33
34
  BlockProverPublicOutput,
34
35
  } from "../../prover/block/BlockProvable";
35
- import {
36
- OUTGOING_MESSAGE_BATCH_SIZE,
37
- OutgoingMessageArgumentBatch,
38
- } from "../messages/OutgoingMessageArgument";
39
- import { Withdrawal } from "../messages/Withdrawal";
40
36
  import {
41
37
  ProvableSettlementHook,
42
38
  SettlementHookInputs,
@@ -44,10 +40,13 @@ import {
44
40
  } from "../modularity/ProvableSettlementHook";
45
41
 
46
42
  import { DispatchContractType } from "./DispatchSmartContract";
43
+ import { BridgeContractType } from "./BridgeContract";
44
+ import { TokenBridgeDeploymentAuth } from "./authorizations/TokenBridgeDeploymentAuth";
45
+ import { UpdateMessagesHashAuth } from "./authorizations/UpdateMessagesHashAuth";
47
46
 
48
47
  /* eslint-disable @typescript-eslint/lines-between-class-members */
49
48
 
50
- export class LazyBlockProof extends Proof<
49
+ export class DynamicBlockProof extends DynamicProof<
51
50
  BlockProverPublicInput,
52
51
  BlockProverPublicOutput
53
52
  > {
@@ -55,18 +54,26 @@ export class LazyBlockProof extends Proof<
55
54
 
56
55
  public static publicOutputType = BlockProverPublicOutput;
57
56
 
58
- public static tag: () => { name: string } = () => {
59
- throw new Error("Tag not initialized yet");
60
- };
57
+ public static maxProofsVerified = 2 as const;
61
58
  }
62
59
 
60
+ export class TokenMapping extends Struct({
61
+ tokenId: Field,
62
+ publicKey: PublicKey,
63
+ }) {}
64
+
63
65
  export interface SettlementContractType {
66
+ authorizationField: State<Field>;
67
+
64
68
  initialize: (
65
69
  sequencer: PublicKey,
66
- dispatchContract: PublicKey
70
+ dispatchContract: PublicKey,
71
+ bridgeContract: PublicKey,
72
+ contractKey: PrivateKey
67
73
  ) => Promise<void>;
74
+ assertStateRoot: (root: Field) => AccountUpdate;
68
75
  settle: (
69
- blockProof: LazyBlockProof,
76
+ blockProof: DynamicBlockProof,
70
77
  signature: Signature,
71
78
  dispatchContractAddress: PublicKey,
72
79
  publicKey: PublicKey,
@@ -74,45 +81,174 @@ export interface SettlementContractType {
74
81
  outputNetworkState: NetworkState,
75
82
  newPromisedMessagesHash: Field
76
83
  ) => Promise<void>;
77
- rollupOutgoingMessages: (
78
- batch: OutgoingMessageArgumentBatch
84
+ addTokenBridge: (
85
+ tokenId: Field,
86
+ address: PublicKey,
87
+ dispatchContract: PublicKey
79
88
  ) => Promise<void>;
80
- redeem: (additionUpdate: AccountUpdate) => Promise<void>;
81
89
  }
82
90
 
83
91
  // Some random prefix for the sequencer signature
84
92
  export const BATCH_SIGNATURE_PREFIX = prefixToField("pk-batchSignature");
85
93
 
86
- export class SettlementSmartContract
87
- extends TokenContract
88
- implements SettlementContractType
89
- {
94
+ // @singleton()
95
+ // export class SettlementSmartContractStaticArgs {
96
+ // public args?: {
97
+ // DispatchContract: TypedClass<DispatchContractType & SmartContract>;
98
+ // hooks: ProvableSettlementHook<unknown>[];
99
+ // escapeHatchSlotsInterval: number;
100
+ // BridgeContract: TypedClass<BridgeContractType> & typeof SmartContract;
101
+ // // Lazily initialized
102
+ // BridgeContractVerificationKey: VerificationKey | undefined;
103
+ // BridgeContractPermissions: Permissions | undefined;
104
+ // signedSettlements: boolean | undefined;
105
+ // };
106
+ // }
107
+
108
+ export abstract class SettlementSmartContractBase extends TokenContractV2 {
90
109
  // This pattern of injecting args into a smartcontract is currently the only
91
110
  // viable solution that works given the inheritance issues of o1js
111
+ // public static args = container.resolve(SettlementSmartContractStaticArgs);
92
112
  public static args: {
93
113
  DispatchContract: TypedClass<DispatchContractType & SmartContract>;
94
114
  hooks: ProvableSettlementHook<unknown>[];
95
- withdrawalStatePath: [string, string];
96
115
  escapeHatchSlotsInterval: number;
116
+ BridgeContract: TypedClass<BridgeContractType> & typeof SmartContract;
117
+ // Lazily initialized
118
+ BridgeContractVerificationKey: VerificationKey | undefined;
119
+ BridgeContractPermissions: Permissions | undefined;
120
+ signedSettlements: boolean | undefined;
121
+ ChildVerificationKeyService: ChildVerificationKeyService;
97
122
  };
98
123
 
99
- @state(Field) public sequencerKey = State<Field>();
100
- @state(UInt32) public lastSettlementL1BlockHeight = State<UInt32>();
124
+ events = {
125
+ "token-bridge-deployed": TokenMapping,
126
+ };
101
127
 
102
- @state(Field) public stateRoot = State<Field>();
103
- @state(Field) public networkStateHash = State<Field>();
104
- @state(Field) public blockHashRoot = State<Field>();
128
+ abstract sequencerKey: State<Field>;
129
+ abstract lastSettlementL1BlockHeight: State<UInt32>;
130
+ abstract stateRoot: State<Field>;
131
+ abstract networkStateHash: State<Field>;
132
+ abstract blockHashRoot: State<Field>;
133
+ abstract dispatchContractAddressX: State<Field>;
105
134
 
106
- @state(Field) public dispatchContractAddressX = State<Field>();
135
+ abstract authorizationField: State<Field>;
107
136
 
108
- @state(Field) public outgoingMessageCursor = State<Field>();
137
+ // Not @state
138
+ // abstract offchainStateCommitmentsHash: State<Field>;
109
139
 
110
- @method async approveBase(forest: AccountUpdateForest) {
111
- this.checkZeroBalanceChange(forest);
140
+ public assertStateRoot(root: Field): AccountUpdate {
141
+ this.stateRoot.requireEquals(root);
142
+ return this.self;
112
143
  }
113
144
 
114
- @method
115
- public async initialize(sequencer: PublicKey, dispatchContract: PublicKey) {
145
+ // TODO Like these properties, I am too lazy to properly infer the types here
146
+ private assertLazyConfigsInitialized() {
147
+ const uninitializedProperties: string[] = [];
148
+ const { args } = SettlementSmartContractBase;
149
+ if (args.BridgeContractPermissions === undefined) {
150
+ uninitializedProperties.push("BridgeContractPermissions");
151
+ }
152
+ if (args.signedSettlements === undefined) {
153
+ uninitializedProperties.push("signedSettlements");
154
+ }
155
+ if (uninitializedProperties.length > 0) {
156
+ throw new Error(
157
+ `Lazy configs of SettlementSmartContract haven't been initialized ${uninitializedProperties.reduce(
158
+ (a, b) => `${a},${b}`
159
+ )}`
160
+ );
161
+ }
162
+ }
163
+
164
+ protected async deployTokenBridge(
165
+ tokenId: Field,
166
+ address: PublicKey,
167
+ dispatchContractAddress: PublicKey,
168
+ dispatchContractPreconditionEnforced = false
169
+ ) {
170
+ Provable.asProver(() => {
171
+ this.assertLazyConfigsInitialized();
172
+ });
173
+
174
+ const { args } = SettlementSmartContractBase;
175
+ const BridgeContractClass = args.BridgeContract;
176
+ const bridgeContract = new BridgeContractClass(address, tokenId);
177
+
178
+ const {
179
+ BridgeContractVerificationKey,
180
+ signedSettlements,
181
+ BridgeContractPermissions,
182
+ } = args;
183
+
184
+ if (
185
+ signedSettlements === undefined ||
186
+ BridgeContractPermissions === undefined
187
+ ) {
188
+ throw new Error(
189
+ "Static arguments for SettlementSmartContract not initialized"
190
+ );
191
+ }
192
+
193
+ if (
194
+ BridgeContractVerificationKey !== undefined &&
195
+ !BridgeContractVerificationKey.hash.isConstant()
196
+ ) {
197
+ throw new Error("Bridge contract verification key has to be constants");
198
+ }
199
+
200
+ // This function is not a zkapps method, therefore it will be part of this methods execution
201
+ // The returning account update (owner.self) is therefore part of this circuit and is assertable
202
+ const deploymentAccountUpdate = await bridgeContract.deployProvable(
203
+ args.BridgeContractVerificationKey,
204
+ args.signedSettlements!,
205
+ args.BridgeContractPermissions!,
206
+ this.address
207
+ );
208
+
209
+ this.approve(deploymentAccountUpdate);
210
+
211
+ this.self.body.mayUseToken = {
212
+ // Only set this if we deploy a custom token
213
+ parentsOwnToken: tokenId.equals(TokenId.default).not(),
214
+ inheritFromParent: Bool(false),
215
+ };
216
+
217
+ this.emitEvent(
218
+ "token-bridge-deployed",
219
+ new TokenMapping({
220
+ tokenId: tokenId,
221
+ publicKey: address,
222
+ })
223
+ );
224
+
225
+ // We can't set a precondition twice, for the $mina bridge deployment that
226
+ // would be the case, so we disable it in this case
227
+ if (!dispatchContractPreconditionEnforced) {
228
+ this.dispatchContractAddressX.requireEquals(dispatchContractAddress.x);
229
+ }
230
+
231
+ // Set authorization for the auth callback, that we need
232
+ this.authorizationField.set(
233
+ new TokenBridgeDeploymentAuth({
234
+ target: dispatchContractAddress,
235
+ tokenId,
236
+ address,
237
+ }).hash()
238
+ );
239
+ const dispatchContract =
240
+ new SettlementSmartContractBase.args.DispatchContract(
241
+ dispatchContractAddress
242
+ );
243
+ await dispatchContract.enableTokenDeposits(tokenId, address, this.address);
244
+ }
245
+
246
+ protected async initializeBase(
247
+ sequencer: PublicKey,
248
+ dispatchContract: PublicKey,
249
+ bridgeContract: PublicKey,
250
+ contractKey: PrivateKey
251
+ ) {
116
252
  this.sequencerKey.getAndRequireEquals().assertEquals(Field(0));
117
253
  this.stateRoot.getAndRequireEquals().assertEquals(Field(0));
118
254
  this.blockHashRoot.getAndRequireEquals().assertEquals(Field(0));
@@ -125,14 +261,23 @@ export class SettlementSmartContract
125
261
  this.networkStateHash.set(NetworkState.empty().hash());
126
262
  this.dispatchContractAddressX.set(dispatchContract.x);
127
263
 
128
- const { DispatchContract } = SettlementSmartContract.args;
264
+ const { DispatchContract } = SettlementSmartContractBase.args;
129
265
  const contractInstance = new DispatchContract(dispatchContract);
130
266
  await contractInstance.initialize(this.address);
267
+
268
+ // Deploy bridge contract for $Mina
269
+ await this.deployTokenBridge(
270
+ this.tokenId,
271
+ bridgeContract,
272
+ dispatchContract,
273
+ true
274
+ );
275
+
276
+ contractKey.toPublicKey().assertEquals(this.address);
131
277
  }
132
278
 
133
- @method
134
- public async settle(
135
- blockProof: LazyBlockProof,
279
+ protected async settleBase(
280
+ blockProof: DynamicBlockProof,
136
281
  signature: Signature,
137
282
  dispatchContractAddress: PublicKey,
138
283
  publicKey: PublicKey,
@@ -140,8 +285,17 @@ export class SettlementSmartContract
140
285
  outputNetworkState: NetworkState,
141
286
  newPromisedMessagesHash: Field
142
287
  ) {
288
+ // Brought in as a constant
289
+ const blockProofVk =
290
+ SettlementSmartContractBase.args.ChildVerificationKeyService.getVerificationKey(
291
+ "BlockProver"
292
+ );
293
+ if (!blockProofVk.hash.isConstant()) {
294
+ throw new Error("Sanity check - vk hash has to be constant");
295
+ }
296
+
143
297
  // Verify the blockproof
144
- blockProof.verify();
298
+ blockProof.verify(blockProofVk);
145
299
 
146
300
  // Get and assert on-chain values
147
301
  const stateRoot = this.stateRoot.getAndRequireEquals();
@@ -159,7 +313,7 @@ export class SettlementSmartContract
159
313
  );
160
314
 
161
315
  const { DispatchContract, escapeHatchSlotsInterval, hooks } =
162
- SettlementSmartContract.args;
316
+ SettlementSmartContractBase.args;
163
317
 
164
318
  // Get dispatch contract values
165
319
  // These values are witnesses but will be checked later on the AU
@@ -253,6 +407,15 @@ export class SettlementSmartContract
253
407
  "Promised messages not honored"
254
408
  );
255
409
 
410
+ // Set authorization for the dispatchContract to verify the messages hash update
411
+ this.authorizationField.set(
412
+ new UpdateMessagesHashAuth({
413
+ target: dispatchContract.address,
414
+ executedMessagesHash: promisedMessagesHash,
415
+ newPromisedMessagesHash,
416
+ }).hash()
417
+ );
418
+
256
419
  // Call DispatchContract
257
420
  // This call checks that the promisedMessagesHash, which is already proven
258
421
  // to be the blockProofs publicoutput, is actually the current on-chain
@@ -265,79 +428,70 @@ export class SettlementSmartContract
265
428
 
266
429
  this.lastSettlementL1BlockHeight.set(minBlockHeightIncluded);
267
430
  }
431
+ }
268
432
 
269
- @method
270
- public async rollupOutgoingMessages(batch: OutgoingMessageArgumentBatch) {
271
- let counter = this.outgoingMessageCursor.getAndRequireEquals();
272
- const stateRoot = this.stateRoot.getAndRequireEquals();
433
+ export class SettlementSmartContract
434
+ extends SettlementSmartContractBase
435
+ implements SettlementContractType
436
+ {
437
+ @state(Field) public sequencerKey = State<Field>();
438
+ @state(UInt32) public lastSettlementL1BlockHeight = State<UInt32>();
273
439
 
274
- const [withdrawalModule, withdrawalStateName] =
275
- SettlementSmartContract.args.withdrawalStatePath;
276
- const mapPath = Path.fromProperty(withdrawalModule, withdrawalStateName);
277
-
278
- let accountCreationFeePaid = Field(0);
279
-
280
- for (let i = 0; i < OUTGOING_MESSAGE_BATCH_SIZE; i++) {
281
- const args = batch.arguments[i];
282
-
283
- // Check witness
284
- const path = Path.fromKey(mapPath, Field, counter);
285
-
286
- args.witness
287
- .checkMembership(
288
- stateRoot,
289
- path,
290
- Poseidon.hash(Withdrawal.toFields(args.value))
291
- )
292
- .assertTrue("Provided Withdrawal witness not valid");
293
-
294
- // Process message
295
- const { address, amount } = args.value;
296
- const isDummy = address.equals(this.address);
297
-
298
- const tokenAu = this.internal.mint({ address, amount });
299
- const isNewAccount = tokenAu.account.isNew.getAndRequireEquals();
300
- tokenAu.body.balanceChange.magnitude =
301
- tokenAu.body.balanceChange.magnitude.sub(
302
- Provable.if(
303
- isNewAccount,
304
- Mina.getNetworkConstants().accountCreationFee.toConstant(),
305
- UInt64.zero
306
- )
307
- );
308
-
309
- accountCreationFeePaid = accountCreationFeePaid.add(
310
- Provable.if(isNewAccount, Field(1e9), Field(0))
311
- );
440
+ @state(Field) public stateRoot = State<Field>();
441
+ @state(Field) public networkStateHash = State<Field>();
442
+ @state(Field) public blockHashRoot = State<Field>();
312
443
 
313
- counter = counter.add(Provable.if(isDummy, Field(0), Field(1)));
314
- }
444
+ @state(Field) public dispatchContractAddressX = State<Field>();
315
445
 
316
- this.balance.subInPlace(UInt64.Unsafe.fromField(accountCreationFeePaid));
446
+ @state(Field) public authorizationField = State<Field>();
317
447
 
318
- this.outgoingMessageCursor.set(counter);
448
+ @method async approveBase(forest: AccountUpdateForest) {
449
+ this.checkZeroBalanceChange(forest);
319
450
  }
320
451
 
321
452
  @method
322
- public async redeem(additionUpdate: AccountUpdate) {
323
- additionUpdate.body.tokenId.assertEquals(
324
- TokenId.default,
325
- "Tokenid not default token"
453
+ public async initialize(
454
+ sequencer: PublicKey,
455
+ dispatchContract: PublicKey,
456
+ bridgeContract: PublicKey,
457
+ contractKey: PrivateKey
458
+ ) {
459
+ await this.initializeBase(
460
+ sequencer,
461
+ dispatchContract,
462
+ bridgeContract,
463
+ contractKey
326
464
  );
327
- additionUpdate.body.balanceChange.sgn
328
- .isPositive()
329
- .assertTrue("Sign not correct");
330
- const amount = additionUpdate.body.balanceChange.magnitude;
331
-
332
- // Burn tokens
333
- this.internal.burn({
334
- address: additionUpdate.publicKey,
335
- amount,
336
- });
465
+ }
466
+
467
+ @method
468
+ public async addTokenBridge(
469
+ tokenId: Field,
470
+ address: PublicKey,
471
+ dispatchContract: PublicKey
472
+ ) {
473
+ await this.deployTokenBridge(tokenId, address, dispatchContract);
474
+ }
337
475
 
338
- // Send mina
339
- this.approve(additionUpdate);
340
- this.balance.subInPlace(amount);
476
+ @method
477
+ public async settle(
478
+ blockProof: DynamicBlockProof,
479
+ signature: Signature,
480
+ dispatchContractAddress: PublicKey,
481
+ publicKey: PublicKey,
482
+ inputNetworkState: NetworkState,
483
+ outputNetworkState: NetworkState,
484
+ newPromisedMessagesHash: Field
485
+ ) {
486
+ return await this.settleBase(
487
+ blockProof,
488
+ signature,
489
+ dispatchContractAddress,
490
+ publicKey,
491
+ inputNetworkState,
492
+ outputNetworkState,
493
+ newPromisedMessagesHash
494
+ );
341
495
  }
342
496
  }
343
497
 
@@ -0,0 +1,73 @@
1
+ import {
2
+ createMerkleTree,
3
+ InMemoryMerkleTreeStorage,
4
+ log,
5
+ } from "@proto-kit/common";
6
+ import { Field, Poseidon, PublicKey, SmartContract, Struct } from "o1js";
7
+
8
+ /**
9
+ * Merkle tree that contains all the deployed token bridges as a mapping of
10
+ * tokenId => PublicKey
11
+ *
12
+ * It should be used as an append-only tree with incremental indizes - this allows
13
+ * us to reduce the height of it
14
+ */
15
+ export class TokenBridgeTree extends createMerkleTree(256) {
16
+ public indizes: Record<string, bigint> = {};
17
+
18
+ /**
19
+ * Initializes and fills the tree based on all on-chain events that have been
20
+ * emitted by every emit
21
+ */
22
+ public static async buildTreeFromEvents(
23
+ contract: SmartContract & {
24
+ events: { "token-bridge-added": typeof TokenBridgeTreeAddition };
25
+ }
26
+ ) {
27
+ const events = await contract.fetchEvents();
28
+
29
+ log.debug(`Found ${events.length} token bridge add events`);
30
+
31
+ const tree = new TokenBridgeTree(new InMemoryMerkleTreeStorage());
32
+ const indizes: Record<string, bigint> = {};
33
+
34
+ events.forEach(({ type, event }) => {
35
+ if (type === "token-bridge-added") {
36
+ const addition =
37
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
38
+ event.data as unknown as TokenBridgeTreeAddition;
39
+
40
+ tree.setLeaf(addition.index.toBigInt(), addition.value.hash());
41
+
42
+ indizes[addition.value.tokenId.toString()] = addition.index.toBigInt();
43
+ }
44
+ });
45
+ tree.indizes = indizes;
46
+ return tree;
47
+ }
48
+
49
+ public getIndex(tokenId: Field): bigint {
50
+ return this.indizes[tokenId.toString()];
51
+ }
52
+ }
53
+
54
+ export class TokenBridgeTreeWitness extends TokenBridgeTree.WITNESS {}
55
+
56
+ export class TokenBridgeEntry extends Struct({
57
+ address: PublicKey,
58
+ tokenId: Field,
59
+ }) {
60
+ public hash() {
61
+ return Poseidon.hash(TokenBridgeEntry.toFields(this));
62
+ }
63
+ }
64
+
65
+ export class TokenBridgeAttestation extends Struct({
66
+ witness: TokenBridgeTreeWitness,
67
+ index: Field,
68
+ }) {}
69
+
70
+ export class TokenBridgeTreeAddition extends Struct({
71
+ index: Field,
72
+ value: TokenBridgeEntry,
73
+ }) {}
@@ -0,0 +1,11 @@
1
+ import { Field, PublicKey } from "o1js";
2
+
3
+ /**
4
+ * Interface for cross-contract call authorization
5
+ * See https://github.com/proto-kit/framework/issues/202#issuecomment-2407263173
6
+ */
7
+ export interface ContractAuthorization {
8
+ target: PublicKey;
9
+
10
+ hash: () => Field;
11
+ }
@@ -0,0 +1,16 @@
1
+ import { Field, Poseidon, PublicKey, Struct } from "o1js";
2
+
3
+ import { ContractAuthorization } from "./ContractAuthorization";
4
+
5
+ export class TokenBridgeDeploymentAuth
6
+ extends Struct({
7
+ target: PublicKey,
8
+ tokenId: Field,
9
+ address: PublicKey,
10
+ })
11
+ implements ContractAuthorization
12
+ {
13
+ public hash() {
14
+ return Poseidon.hash(TokenBridgeDeploymentAuth.toFields(this));
15
+ }
16
+ }
@@ -0,0 +1,16 @@
1
+ import { Field, Poseidon, PublicKey, Struct } from "o1js";
2
+
3
+ import { ContractAuthorization } from "./ContractAuthorization";
4
+
5
+ export class UpdateMessagesHashAuth
6
+ extends Struct({
7
+ target: PublicKey,
8
+ executedMessagesHash: Field,
9
+ newPromisedMessagesHash: Field,
10
+ })
11
+ implements ContractAuthorization
12
+ {
13
+ public hash() {
14
+ return Poseidon.hash(UpdateMessagesHashAuth.toFields(this));
15
+ }
16
+ }
@@ -1,6 +1,7 @@
1
- import { PublicKey, Struct, UInt64 } from "o1js";
1
+ import { Field, PublicKey, Struct, UInt64 } from "o1js";
2
2
 
3
3
  export class Deposit extends Struct({
4
+ tokenId: Field,
4
5
  address: PublicKey,
5
6
  amount: UInt64,
6
7
  }) {}
@@ -1,12 +1,14 @@
1
- import { PublicKey, Struct, UInt64 } from "o1js";
1
+ import { Field, PublicKey, Struct, UInt64 } from "o1js";
2
2
  import { EMPTY_PUBLICKEY } from "@proto-kit/common";
3
3
 
4
4
  export class Withdrawal extends Struct({
5
+ tokenId: Field,
5
6
  address: PublicKey,
6
7
  amount: UInt64,
7
8
  }) {
8
9
  public static dummy() {
9
10
  return new Withdrawal({
11
+ tokenId: Field(0),
10
12
  address: EMPTY_PUBLICKEY,
11
13
  amount: UInt64.from(0),
12
14
  });
@@ -1,9 +1,12 @@
1
1
  import { Field, PublicKey, UInt32 } from "o1js";
2
+ import { InferProofBase } from "@proto-kit/common";
2
3
 
3
4
  import { ProtocolModule } from "../../protocol/ProtocolModule";
4
5
  import { NetworkState } from "../../model/network/NetworkState";
5
6
  import type { BlockProof } from "../../prover/block/BlockProver";
6
- import type { SettlementSmartContract } from "../contracts/SettlementSmartContract";
7
+ import type { SettlementSmartContractBase } from "../contracts/SettlementSmartContract";
8
+
9
+ export type InputBlockProof = InferProofBase<BlockProof>;
7
10
 
8
11
  export type SettlementStateRecord = {
9
12
  sequencerKey: PublicKey;
@@ -15,7 +18,7 @@ export type SettlementStateRecord = {
15
18
  };
16
19
 
17
20
  export type SettlementHookInputs = {
18
- blockProof: BlockProof;
21
+ blockProof: InputBlockProof;
19
22
  fromNetworkState: NetworkState;
20
23
  toNetworkState: NetworkState;
21
24
  newPromisedMessagesHash: Field;
@@ -27,7 +30,7 @@ export abstract class ProvableSettlementHook<
27
30
  Config,
28
31
  > extends ProtocolModule<Config> {
29
32
  public abstract beforeSettlement(
30
- smartContract: SettlementSmartContract,
33
+ smartContract: SettlementSmartContractBase,
31
34
  inputs: SettlementHookInputs
32
35
  ): Promise<void>;
33
36
  }