@aztec/ethereum 1.2.1 → 2.0.0-nightly.20250813

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 (98) hide show
  1. package/dest/config.d.ts +22 -7
  2. package/dest/config.d.ts.map +1 -1
  3. package/dest/config.js +49 -14
  4. package/dest/contracts/empire_base.d.ts +12 -10
  5. package/dest/contracts/empire_base.d.ts.map +1 -1
  6. package/dest/contracts/empire_base.js +21 -16
  7. package/dest/contracts/governance.d.ts +4 -4
  8. package/dest/contracts/governance.js +2 -2
  9. package/dest/contracts/governance_proposer.d.ts +7 -7
  10. package/dest/contracts/governance_proposer.d.ts.map +1 -1
  11. package/dest/contracts/governance_proposer.js +13 -13
  12. package/dest/contracts/gse.d.ts +29 -0
  13. package/dest/contracts/gse.d.ts.map +1 -0
  14. package/dest/contracts/gse.js +56 -0
  15. package/dest/contracts/index.d.ts +1 -0
  16. package/dest/contracts/index.d.ts.map +1 -1
  17. package/dest/contracts/index.js +1 -0
  18. package/dest/contracts/multicall.d.ts +3 -1
  19. package/dest/contracts/multicall.d.ts.map +1 -1
  20. package/dest/contracts/multicall.js +11 -2
  21. package/dest/contracts/registry.d.ts +1 -0
  22. package/dest/contracts/registry.d.ts.map +1 -1
  23. package/dest/contracts/registry.js +3 -0
  24. package/dest/contracts/rollup.d.ts +39 -5
  25. package/dest/contracts/rollup.d.ts.map +1 -1
  26. package/dest/contracts/rollup.js +92 -14
  27. package/dest/contracts/slashing_proposer.d.ts +21 -10
  28. package/dest/contracts/slashing_proposer.d.ts.map +1 -1
  29. package/dest/contracts/slashing_proposer.js +43 -23
  30. package/dest/deploy_l1_contracts.d.ts +11 -36664
  31. package/dest/deploy_l1_contracts.d.ts.map +1 -1
  32. package/dest/deploy_l1_contracts.js +92 -177
  33. package/dest/index.d.ts +1 -1
  34. package/dest/index.d.ts.map +1 -1
  35. package/dest/index.js +1 -1
  36. package/dest/l1_artifacts.d.ts +51869 -0
  37. package/dest/l1_artifacts.d.ts.map +1 -0
  38. package/dest/l1_artifacts.js +141 -0
  39. package/dest/l1_tx_utils.d.ts +4 -2
  40. package/dest/l1_tx_utils.d.ts.map +1 -1
  41. package/dest/l1_tx_utils.js +46 -21
  42. package/dest/queries.d.ts +1 -8
  43. package/dest/queries.d.ts.map +1 -1
  44. package/dest/queries.js +20 -15
  45. package/dest/test/chain_monitor.d.ts +4 -2
  46. package/dest/test/chain_monitor.d.ts.map +1 -1
  47. package/dest/test/chain_monitor.js +12 -3
  48. package/dest/test/delayed_tx_utils.js +2 -2
  49. package/dest/{eth_cheat_codes.d.ts → test/eth_cheat_codes.d.ts} +8 -4
  50. package/dest/test/eth_cheat_codes.d.ts.map +1 -0
  51. package/dest/{eth_cheat_codes.js → test/eth_cheat_codes.js} +27 -11
  52. package/dest/test/eth_cheat_codes_with_state.d.ts +1 -1
  53. package/dest/test/eth_cheat_codes_with_state.d.ts.map +1 -1
  54. package/dest/test/eth_cheat_codes_with_state.js +1 -1
  55. package/dest/test/index.d.ts +2 -0
  56. package/dest/test/index.d.ts.map +1 -1
  57. package/dest/test/index.js +2 -0
  58. package/dest/test/rollup_cheat_codes.d.ts +81 -0
  59. package/dest/test/rollup_cheat_codes.d.ts.map +1 -0
  60. package/dest/test/rollup_cheat_codes.js +234 -0
  61. package/dest/test/start_anvil.d.ts +1 -0
  62. package/dest/test/start_anvil.d.ts.map +1 -1
  63. package/dest/test/start_anvil.js +6 -1
  64. package/dest/test/tx_delayer.d.ts +8 -1
  65. package/dest/test/tx_delayer.d.ts.map +1 -1
  66. package/dest/test/tx_delayer.js +51 -11
  67. package/dest/test/upgrade_utils.d.ts.map +1 -1
  68. package/dest/test/upgrade_utils.js +1 -1
  69. package/dest/utils.d.ts +1 -0
  70. package/dest/utils.d.ts.map +1 -1
  71. package/dest/utils.js +1 -1
  72. package/package.json +5 -5
  73. package/src/config.ts +62 -18
  74. package/src/contracts/empire_base.ts +28 -19
  75. package/src/contracts/governance.ts +2 -2
  76. package/src/contracts/governance_proposer.ts +23 -15
  77. package/src/contracts/gse.ts +73 -0
  78. package/src/contracts/index.ts +1 -0
  79. package/src/contracts/multicall.ts +8 -1
  80. package/src/contracts/registry.ts +4 -0
  81. package/src/contracts/rollup.ts +115 -9
  82. package/src/contracts/slashing_proposer.ts +55 -27
  83. package/src/deploy_l1_contracts.ts +151 -238
  84. package/src/index.ts +1 -1
  85. package/src/l1_artifacts.ts +216 -0
  86. package/src/l1_tx_utils.ts +52 -26
  87. package/src/queries.ts +20 -31
  88. package/src/test/chain_monitor.ts +9 -2
  89. package/src/test/delayed_tx_utils.ts +2 -2
  90. package/src/{eth_cheat_codes.ts → test/eth_cheat_codes.ts} +20 -14
  91. package/src/test/eth_cheat_codes_with_state.ts +1 -1
  92. package/src/test/index.ts +2 -0
  93. package/src/test/rollup_cheat_codes.ts +257 -0
  94. package/src/test/start_anvil.ts +9 -1
  95. package/src/test/tx_delayer.ts +55 -9
  96. package/src/test/upgrade_utils.ts +1 -1
  97. package/src/utils.ts +1 -1
  98. package/dest/eth_cheat_codes.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"tx_delayer.d.ts","sourceRoot":"","sources":["../../src/test/tx_delayer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAIlE,OAAO,EACL,KAAK,MAAM,EACX,KAAK,GAAG,EAQT,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,aAAa,CAAC;AAEhE,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,oBAgBxG;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,oBAuB5G;AAED,MAAM,WAAW,OAAO;IACtB,sDAAsD;IACtD,eAAe,IAAI,GAAG,EAAE,CAAC;IACzB,iDAAiD;IACjD,eAAe,IAAI,GAAG,EAAE,CAAC;IACzB,8EAA8E;IAC9E,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACxE,wEAAwE;IACxE,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1E,kDAAkD;IAClD,YAAY,IAAI,IAAI,CAAC;CACtB;AAiCD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,UAAU,EAC9C,MAAM,EAAE,CAAC,EACT,IAAI,EAAE;IAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA6EjC"}
1
+ {"version":3,"file":"tx_delayer.d.ts","sourceRoot":"","sources":["../../src/test/tx_delayer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAElE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EACL,KAAK,MAAM,EACX,KAAK,GAAG,EAQT,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,KAAK,UAAU,EAAoB,MAAM,aAAa,CAAC;AAEhE,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,oBAgBxG;AAED,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,oBAuB5G;AAED,MAAM,WAAW,OAAO;IACtB,sDAAsD;IACtD,eAAe,IAAI,GAAG,EAAE,CAAC;IACzB,iDAAiD;IACjD,eAAe,IAAI,GAAG,EAAE,CAAC;IACzB,8EAA8E;IAC9E,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IACxE,wEAAwE;IACxE,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1E,kDAAkD;IAClD,YAAY,IAAI,IAAI,CAAC;IACrB;;;;OAIG;IACH,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CACzE;AA0CD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,UAAU,EAC9C,MAAM,EAAE,CAAC,EACT,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE;IAAE,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAC9C;IAAE,MAAM,EAAE,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA0GjC"}
@@ -35,13 +35,22 @@ export function waitUntilL1Timestamp(client, timestamp, logger) {
35
35
  }, `Wait until L1 timestamp ${timestamp}`, 120, 0.1);
36
36
  }
37
37
  class DelayerImpl {
38
- constructor(opts){
38
+ dateProvider;
39
+ logger;
40
+ constructor(dateProvider, opts){
41
+ this.dateProvider = dateProvider;
42
+ this.logger = createLogger('ethereum:tx_delayer');
43
+ this.maxInclusionTimeIntoSlot = undefined;
44
+ this.nextWait = undefined;
45
+ this.sentTxHashes = [];
46
+ this.cancelledTxs = [];
39
47
  this.ethereumSlotDuration = BigInt(opts.ethereumSlotDuration);
40
48
  }
49
+ maxInclusionTimeIntoSlot;
41
50
  ethereumSlotDuration;
42
- nextWait = undefined;
43
- sentTxHashes = [];
44
- cancelledTxs = [];
51
+ nextWait;
52
+ sentTxHashes;
53
+ cancelledTxs;
45
54
  getSentTxHashes() {
46
55
  return this.sentTxHashes;
47
56
  }
@@ -63,41 +72,72 @@ class DelayerImpl {
63
72
  indefinitely: true
64
73
  };
65
74
  }
75
+ setMaxInclusionTimeIntoSlot(seconds) {
76
+ this.maxInclusionTimeIntoSlot = seconds;
77
+ }
66
78
  }
67
79
  /**
68
80
  * Returns a new client (without modifying the one passed in) with an injected tx delayer.
69
81
  * The delayer can be used to hold off the next tx to be sent until a given block number.
70
82
  * TODO(#10824): This doesn't play along well with blob txs for some reason.
71
- */ export function withDelayer(client, opts) {
83
+ */ export function withDelayer(client, dateProvider, opts) {
72
84
  if (!isExtendedClient(client)) {
73
85
  throw new Error('withDelayer has to be instantiated with a wallet viem client.');
74
86
  }
75
87
  const logger = createLogger('ethereum:tx_delayer');
76
- const delayer = new DelayerImpl(opts);
88
+ const delayer = new DelayerImpl(dateProvider, opts);
77
89
  const extended = client// Tweak sendRawTransaction so it uses the delay defined in the delayer.
78
90
  // Note that this will only work with local accounts (ie accounts for which we have the private key).
79
91
  // Transactions signed by the node will not be delayed since they use sendTransaction directly,
80
92
  // but we do not use them in our codebase at all.
81
93
  .extend((client)=>({
82
94
  async sendRawTransaction (...args) {
95
+ let wait;
96
+ let txHash;
97
+ const { serializedTransaction } = args[0];
98
+ const publicClient = client;
83
99
  if (delayer.nextWait !== undefined) {
100
+ // Check if we have been instructed to delay the next tx.
84
101
  const waitUntil = delayer.nextWait;
85
102
  delayer.nextWait = undefined;
86
103
  // Compute the tx hash manually so we emulate sendRawTransaction response
87
- const { serializedTransaction } = args[0];
88
- const txHash = computeTxHash(serializedTransaction);
104
+ txHash = computeTxHash(serializedTransaction);
89
105
  // Cancel tx outright if instructed
90
106
  if ('indefinitely' in waitUntil && waitUntil.indefinitely) {
91
107
  logger.info(`Cancelling tx ${txHash}`);
92
108
  delayer.cancelledTxs.push(serializedTransaction);
93
109
  return Promise.resolve(txHash);
94
110
  }
95
- const publicClient = client;
96
- const wait = 'l1BlockNumber' in waitUntil ? waitUntilBlock(publicClient, waitUntil.l1BlockNumber - 1n, logger) : 'l1Timestamp' in waitUntil ? waitUntilL1Timestamp(publicClient, waitUntil.l1Timestamp - delayer.ethereumSlotDuration, logger) : undefined;
111
+ // Or wait until the desired block number or timestamp
112
+ wait = 'l1BlockNumber' in waitUntil ? waitUntilBlock(publicClient, waitUntil.l1BlockNumber - 1n, logger) : 'l1Timestamp' in waitUntil ? waitUntilL1Timestamp(publicClient, waitUntil.l1Timestamp - delayer.ethereumSlotDuration, logger) : undefined;
97
113
  logger.info(`Delaying tx ${txHash} until ${inspect(waitUntil)}`, {
98
114
  argsLen: args.length,
99
115
  ...omit(parseTransaction(serializedTransaction), 'data', 'sidecars')
100
116
  });
117
+ } else if (delayer.maxInclusionTimeIntoSlot !== undefined) {
118
+ // Check if we need to delay txs sent too close to the end of the slot.
119
+ const currentBlock = await publicClient.getBlock({
120
+ includeTransactions: false
121
+ });
122
+ const { timestamp: lastBlockTimestamp, number } = currentBlock;
123
+ const now = delayer.dateProvider.now();
124
+ txHash = computeTxHash(serializedTransaction);
125
+ const logData = {
126
+ ...omit(parseTransaction(serializedTransaction), 'data', 'sidecars'),
127
+ lastBlockTimestamp,
128
+ now,
129
+ maxInclusionTimeIntoSlot: delayer.maxInclusionTimeIntoSlot
130
+ };
131
+ if (now / 1000 - Number(lastBlockTimestamp) > delayer.maxInclusionTimeIntoSlot) {
132
+ // If the last block was mined more than `maxInclusionTimeIntoSlot` seconds ago, then we cannot include
133
+ // any txs in the current slot, so we delay the tx until the next slot.
134
+ logger.info(`Delaying inclusion of tx ${txHash} until the next slot since it was sent too late`, logData);
135
+ wait = waitUntilBlock(publicClient, number + 1n, logger);
136
+ } else {
137
+ logger.debug(`Immediately sending tx ${txHash} as it was received early enough in the slot`, logData);
138
+ }
139
+ }
140
+ if (wait !== undefined) {
101
141
  // Do not await here so we can return the tx hash immediately as if it had been sent on the spot.
102
142
  // Instead, delay it so it lands on the desired block number or timestamp, assuming anvil will
103
143
  // mine it immediately.
@@ -109,7 +149,7 @@ class DelayerImpl {
109
149
  computedTxHash: txHash
110
150
  });
111
151
  }
112
- logger.info(`Sent previously delayed tx ${clientTxHash} to land on ${inspect(waitUntil)}`);
152
+ logger.info(`Sent previously delayed tx ${clientTxHash}`);
113
153
  delayer.sentTxHashes.push(clientTxHash);
114
154
  }).catch((err)=>logger.error(`Error sending tx after delay`, err));
115
155
  return Promise.resolve(txHash);
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade_utils.d.ts","sourceRoot":"","sources":["../../src/test/upgrade_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGlE,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAe,MAAM,MAAM,CAAC;AAIvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE9E,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,qBAAqB,CAAC,OAAO,aAAa,EAAE,gBAAgB,CAAC,EACzE,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,iBAmCf;AAED,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,KAAK,MAAM,EAAE,EAC7B,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,iBAAiB,EAC7B,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,UAAU,EAAE,qBAAqB,CAAC,OAAO,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAyCD"}
1
+ {"version":3,"file":"upgrade_utils.d.ts","sourceRoot":"","sources":["../../src/test/upgrade_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAGlE,OAAO,EAAE,KAAK,qBAAqB,EAAE,KAAK,iBAAiB,EAAe,MAAM,MAAM,CAAC;AAGvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE,OAAO,KAAK,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAG9E,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,qBAAqB,CAAC,OAAO,aAAa,EAAE,gBAAgB,CAAC,EACzE,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,EAAE,wBAAwB,EAClC,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,iBAmCf;AAED,wBAAsB,wBAAwB,CAC5C,cAAc,EAAE,KAAK,MAAM,EAAE,EAC7B,SAAS,EAAE,mBAAmB,EAC9B,UAAU,EAAE,iBAAiB,EAC7B,YAAY,EAAE,gBAAgB,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IACT,UAAU,EAAE,qBAAqB,CAAC,OAAO,aAAa,EAAE,gBAAgB,CAAC,CAAC;IAC1E,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CAyCD"}
@@ -2,8 +2,8 @@ import { GovernanceAbi } from '@aztec/l1-artifacts/GovernanceAbi';
2
2
  import { TestERC20Abi as StakingAssetAbi } from '@aztec/l1-artifacts/TestERC20Abi';
3
3
  import { getContract } from 'viem';
4
4
  import { extractProposalIdFromLogs } from '../contracts/governance.js';
5
- import { EthCheatCodes } from '../eth_cheat_codes.js';
6
5
  import { L1TxUtils } from '../l1_tx_utils.js';
6
+ import { EthCheatCodes } from './eth_cheat_codes.js';
7
7
  export async function executeGovernanceProposal(proposalId, governance, voteAmount, privateKey, l1Client, rpcUrls, logger) {
8
8
  const proposal = await governance.read.getProposal([
9
9
  proposalId
package/dest/utils.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare class FormattedViemError extends Error {
12
12
  constructor(message: string, metaMessages?: any[]);
13
13
  }
14
14
  export declare function extractEvent<const TAbi extends Abi | readonly unknown[], TEventName extends ContractEventName<TAbi>, TEventType = DecodeEventLogReturnType<TAbi, TEventName, Hex[], undefined, true>>(logs: Log[], address: Hex, abi: TAbi, eventName: TEventName, filter?: (log: TEventType) => boolean, logger?: Logger): TEventType;
15
+ export declare function tryExtractEvent<const TAbi extends Abi | readonly unknown[], TEventName extends ContractEventName<TAbi>, TEventType = DecodeEventLogReturnType<TAbi, TEventName, Hex[], undefined, true>>(logs: Log[], address: Hex, abi: TAbi, eventName: TEventName, filter?: (log: TEventType) => boolean, logger?: Logger): TEventType | undefined;
15
16
  export declare function prettyLogViemErrorMsg(err: any): any;
16
17
  /**
17
18
  * Formats a Viem error into a FormattedViemError instance.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;gBAET,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE;CAKlD;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AA+BD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,CA8FpF;AA+KD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,sBAa7C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EACL,KAAK,GAAG,EAER,KAAK,iBAAiB,EAEtB,KAAK,wBAAwB,EAC7B,KAAK,GAAG,EACR,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,MAAM,WAAW,OAAO;IACtB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,EAAE,CAAC;IAChB,WAAW,EAAE,GAAG,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;gBAET,OAAO,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE;CAKlD;AAED,wBAAgB,YAAY,CAC1B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,CAMZ;AAED,wBAAgB,eAAe,CAC7B,KAAK,CAAC,IAAI,SAAS,GAAG,GAAG,SAAS,OAAO,EAAE,EAC3C,UAAU,SAAS,iBAAiB,CAAC,IAAI,CAAC,EAC1C,UAAU,GAAG,wBAAwB,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAE/E,IAAI,EAAE,GAAG,EAAE,EACX,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,IAAI,EACT,SAAS,EAAE,UAAU,EACrB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACrC,MAAM,CAAC,EAAE,MAAM,GACd,UAAU,GAAG,SAAS,CAgBxB;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,OAW7C;AA0BD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,GAAE,GAAe,GAAG,kBAAkB,CA8FpF;AA+KD,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,GAAG,sBAa7C"}
package/dest/utils.js CHANGED
@@ -15,7 +15,7 @@ export function extractEvent(logs, address, abi, eventName, filter, logger) {
15
15
  }
16
16
  return event;
17
17
  }
18
- function tryExtractEvent(logs, address, abi, eventName, filter, logger) {
18
+ export function tryExtractEvent(logs, address, abi, eventName, filter, logger) {
19
19
  for (const log of logs){
20
20
  if (log.address.toLowerCase() === address.toLowerCase()) {
21
21
  try {
package/package.json CHANGED
@@ -1,10 +1,9 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "1.2.1",
3
+ "version": "2.0.0-nightly.20250813",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
7
- "./eth-cheatcodes": "./dest/eth_cheat_codes.js",
8
7
  "./test": "./dest/test/index.js",
9
8
  "./contracts": "./dest/contracts/index.js",
10
9
  "./deploy-l1-contracts": "./dest/deploy_l1_contracts.js",
@@ -32,9 +31,9 @@
32
31
  "../package.common.json"
33
32
  ],
34
33
  "dependencies": {
35
- "@aztec/blob-lib": "1.2.1",
36
- "@aztec/foundation": "1.2.1",
37
- "@aztec/l1-artifacts": "1.2.1",
34
+ "@aztec/blob-lib": "2.0.0-nightly.20250813",
35
+ "@aztec/foundation": "2.0.0-nightly.20250813",
36
+ "@aztec/l1-artifacts": "2.0.0-nightly.20250813",
38
37
  "@viem/anvil": "^0.0.10",
39
38
  "dotenv": "^16.0.3",
40
39
  "lodash.pickby": "^4.5.0",
@@ -44,6 +43,7 @@
44
43
  },
45
44
  "devDependencies": {
46
45
  "@jest/globals": "^30.0.0",
46
+ "@noble/curves": "=1.7.0",
47
47
  "@types/jest": "^30.0.0",
48
48
  "@types/lodash.pickby": "^4",
49
49
  "@types/node": "^22.15.17",
package/src/config.ts CHANGED
@@ -29,13 +29,19 @@ export type L1ContractsConfig = {
29
29
  /** The number of epochs after an epoch ends that proofs are still accepted. */
30
30
  aztecProofSubmissionEpochs: number;
31
31
  /** The deposit amount for a validator */
32
- depositAmount: bigint;
32
+ activationThreshold: bigint;
33
33
  /** The minimum stake for a validator. */
34
- minimumStake: bigint;
35
- /** The slashing quorum */
34
+ ejectionThreshold: bigint;
35
+ /** The slashing quorum, i.e. how many slots must signal for the same payload in a round for it to be submittable to the Slasher */
36
36
  slashingQuorum: number;
37
- /** The slashing round size */
37
+ /** The slashing round size, i.e. how many slots are in a round */
38
38
  slashingRoundSize: number;
39
+ /** The slashing lifetime in rounds. I.e., if 1, round N must be submitted before round N + 2 */
40
+ slashingLifetimeInRounds: number;
41
+ /** The slashing execution delay in rounds. I.e., if 1, round N may not be submitted until round N + 2 */
42
+ slashingExecutionDelayInRounds: number;
43
+ /** The slashing vetoer. May blacklist a payload from being submitted. */
44
+ slashingVetoer: EthAddress;
39
45
  /** Governance proposing quorum */
40
46
  governanceProposerQuorum: number;
41
47
  /** Governance proposing round size */
@@ -54,10 +60,13 @@ export const DefaultL1ContractsConfig = {
54
60
  aztecEpochDuration: 32,
55
61
  aztecTargetCommitteeSize: 48,
56
62
  aztecProofSubmissionEpochs: 1, // you have a full epoch to submit a proof after the epoch to prove ends
57
- depositAmount: BigInt(100e18),
58
- minimumStake: BigInt(50e18),
63
+ activationThreshold: BigInt(100e18),
64
+ ejectionThreshold: BigInt(50e18),
59
65
  slashingQuorum: 101,
60
66
  slashingRoundSize: 200,
67
+ slashingLifetimeInRounds: 5,
68
+ slashingExecutionDelayInRounds: 0, // round N may be submitted in round N + 1
69
+ slashingVetoer: EthAddress.ZERO,
61
70
  governanceProposerQuorum: 151,
62
71
  governanceProposerRoundSize: 300,
63
72
  manaTarget: BigInt(1e10),
@@ -74,23 +83,23 @@ const LocalGovernanceConfiguration = {
74
83
  votingDuration: 60n * 60n,
75
84
  executionDelay: 60n,
76
85
  gracePeriod: 60n * 60n * 24n * 7n,
77
- quorum: 1n * 10n ** 17n,
78
- voteDifferential: 4n * 10n ** 16n,
86
+ quorum: 1n * 10n ** 17n, // 10%
87
+ requiredYeaMargin: 4n * 10n ** 16n, // 4%
79
88
  minimumVotes: 400n * 10n ** 18n,
80
89
  };
81
90
 
82
91
  const TestnetGovernanceConfiguration = {
83
92
  proposeConfig: {
84
93
  lockDelay: 60n * 60n * 24n,
85
- lockAmount: DefaultL1ContractsConfig.depositAmount * 100n,
94
+ lockAmount: DefaultL1ContractsConfig.activationThreshold * 100n,
86
95
  },
87
96
  votingDelay: 60n,
88
97
  votingDuration: 60n * 60n,
89
98
  executionDelay: 60n * 60n * 24n,
90
99
  gracePeriod: 60n * 60n * 24n * 7n,
91
- quorum: 3n * 10n ** 17n,
92
- voteDifferential: 4n * 10n ** 16n,
93
- minimumVotes: DefaultL1ContractsConfig.minimumStake * 200n,
100
+ quorum: 3n * 10n ** 17n, // 30%
101
+ requiredYeaMargin: 4n * 10n ** 16n, // 4%
102
+ minimumVotes: DefaultL1ContractsConfig.ejectionThreshold * 200n,
94
103
  };
95
104
 
96
105
  export const getGovernanceConfiguration = (networkName: NetworkNames) => {
@@ -100,6 +109,23 @@ export const getGovernanceConfiguration = (networkName: NetworkNames) => {
100
109
  return LocalGovernanceConfiguration;
101
110
  };
102
111
 
112
+ const TestnetGSEConfiguration = {
113
+ activationThreshold: BigInt(100e18),
114
+ ejectionThreshold: BigInt(50e18),
115
+ };
116
+
117
+ const LocalGSEConfiguration = {
118
+ activationThreshold: BigInt(100e18),
119
+ ejectionThreshold: BigInt(50e18),
120
+ };
121
+
122
+ export const getGSEConfiguration = (networkName: NetworkNames) => {
123
+ if (networkName === 'alpha-testnet' || networkName === 'testnet') {
124
+ return TestnetGSEConfiguration;
125
+ }
126
+ return LocalGSEConfiguration;
127
+ };
128
+
103
129
  // Making a default config here as we are only using it thought the deployment
104
130
  // and do not expect to be using different setups, so having environment variables
105
131
  // for it seems overkill
@@ -107,12 +133,14 @@ const LocalRewardConfig = {
107
133
  sequencerBps: 5000,
108
134
  rewardDistributor: EthAddress.ZERO.toString(),
109
135
  booster: EthAddress.ZERO.toString(),
136
+ blockReward: BigInt(50e18),
110
137
  };
111
138
 
112
139
  const TestnetRewardConfig = {
113
140
  sequencerBps: 5000,
114
141
  rewardDistributor: EthAddress.ZERO.toString(),
115
142
  booster: EthAddress.ZERO.toString(),
143
+ blockReward: BigInt(50e18),
116
144
  };
117
145
 
118
146
  export const getRewardConfig = (networkName: NetworkNames) => {
@@ -193,15 +221,15 @@ export const l1ContractsConfigMappings: ConfigMappingsType<L1ContractsConfig> =
193
221
  description: 'The number of epochs after an epoch ends that proofs are still accepted.',
194
222
  ...numberConfigHelper(DefaultL1ContractsConfig.aztecProofSubmissionEpochs),
195
223
  },
196
- depositAmount: {
197
- env: 'AZTEC_DEPOSIT_AMOUNT',
224
+ activationThreshold: {
225
+ env: 'AZTEC_ACTIVATION_THRESHOLD',
198
226
  description: 'The deposit amount for a validator',
199
- ...bigintConfigHelper(DefaultL1ContractsConfig.depositAmount),
227
+ ...bigintConfigHelper(DefaultL1ContractsConfig.activationThreshold),
200
228
  },
201
- minimumStake: {
202
- env: 'AZTEC_MINIMUM_STAKE',
229
+ ejectionThreshold: {
230
+ env: 'AZTEC_EJECTION_THRESHOLD',
203
231
  description: 'The minimum stake for a validator.',
204
- ...bigintConfigHelper(DefaultL1ContractsConfig.minimumStake),
232
+ ...bigintConfigHelper(DefaultL1ContractsConfig.ejectionThreshold),
205
233
  },
206
234
  slashingQuorum: {
207
235
  env: 'AZTEC_SLASHING_QUORUM',
@@ -213,6 +241,22 @@ export const l1ContractsConfigMappings: ConfigMappingsType<L1ContractsConfig> =
213
241
  description: 'The slashing round size',
214
242
  ...numberConfigHelper(DefaultL1ContractsConfig.slashingRoundSize),
215
243
  },
244
+ slashingLifetimeInRounds: {
245
+ env: 'AZTEC_SLASHING_LIFETIME_IN_ROUNDS',
246
+ description: 'The slashing lifetime in rounds',
247
+ ...numberConfigHelper(DefaultL1ContractsConfig.slashingLifetimeInRounds),
248
+ },
249
+ slashingExecutionDelayInRounds: {
250
+ env: 'AZTEC_SLASHING_EXECUTION_DELAY_IN_ROUNDS',
251
+ description: 'The slashing execution delay in rounds',
252
+ ...numberConfigHelper(DefaultL1ContractsConfig.slashingExecutionDelayInRounds),
253
+ },
254
+ slashingVetoer: {
255
+ env: 'AZTEC_SLASHING_VETOER',
256
+ description: 'The slashing vetoer',
257
+ parseEnv: (val: string) => EthAddress.fromString(val),
258
+ defaultValue: DefaultL1ContractsConfig.slashingVetoer,
259
+ },
216
260
  governanceProposerQuorum: {
217
261
  env: 'AZTEC_GOVERNANCE_PROPOSER_QUORUM',
218
262
  description: 'The governance proposing quorum',
@@ -1,51 +1,58 @@
1
+ import type { EthAddress } from '@aztec/foundation/eth-address';
1
2
  import { Signature } from '@aztec/foundation/eth-signature';
2
3
  import { EmpireBaseAbi } from '@aztec/l1-artifacts/EmpireBaseAbi';
3
4
 
4
- import { type Hex, encodeFunctionData, hashTypedData } from 'viem';
5
+ import { type Hex, type TypedDataDefinition, encodeFunctionData } from 'viem';
5
6
 
6
7
  import type { L1TxRequest } from '../l1_tx_utils.js';
7
8
 
8
9
  export interface IEmpireBase {
9
- getRoundInfo(rollupAddress: Hex, round: bigint): Promise<{ lastVote: bigint; leader: Hex; executed: boolean }>;
10
+ get address(): EthAddress;
11
+ getRoundInfo(
12
+ rollupAddress: Hex,
13
+ round: bigint,
14
+ ): Promise<{ lastSignalSlot: bigint; payloadWithMostSignals: Hex; executed: boolean }>;
10
15
  computeRound(slot: bigint): Promise<bigint>;
11
- createVoteRequest(payload: Hex): L1TxRequest;
12
- createVoteRequestWithSignature(
16
+ createSignalRequest(payload: Hex): L1TxRequest;
17
+ createSignalRequestWithSignature(
13
18
  payload: Hex,
19
+ round: bigint,
14
20
  chainId: number,
15
21
  signerAddress: Hex,
16
- signer: (msg: Hex) => Promise<Hex>,
22
+ signer: (msg: TypedDataDefinition) => Promise<Hex>,
17
23
  ): Promise<L1TxRequest>;
18
24
  }
19
25
 
20
- export function encodeVote(payload: Hex): Hex {
26
+ export function encodeSignal(payload: Hex): Hex {
21
27
  return encodeFunctionData({
22
28
  abi: EmpireBaseAbi,
23
- functionName: 'vote',
29
+ functionName: 'signal',
24
30
  args: [payload],
25
31
  });
26
32
  }
27
33
 
28
- export function encodeVoteWithSignature(payload: Hex, signature: Signature) {
34
+ export function encodeSignalWithSignature(payload: Hex, signature: Signature) {
29
35
  return encodeFunctionData({
30
36
  abi: EmpireBaseAbi,
31
- functionName: 'voteWithSig',
37
+ functionName: 'signalWithSig',
32
38
  args: [payload, signature.toViemSignature()],
33
39
  });
34
40
  }
35
41
 
36
42
  /**
37
- * Signs a vote proposal using EIP-712 typed data for use with voteWithSig
43
+ * Signs a signal proposal using EIP-712 typed data for use with signalWithSig
38
44
  * @param walletClient - The viem wallet client to sign with
39
- * @param proposal - The proposal address to vote on
45
+ * @param payload - The payload address to signal
40
46
  * @param verifyingContract - The address of the EmpireBase contract
41
47
  * @param chainId - The chain ID where the contract is deployed
42
48
  * @param account - The account to sign with (optional if hoisted on wallet client)
43
49
  * @returns The EIP-712 signature
44
50
  */
45
- export async function signVoteWithSig(
46
- signer: (msg: Hex) => Promise<Hex>,
47
- proposal: Hex,
51
+ export async function signSignalWithSig(
52
+ signer: (msg: TypedDataDefinition) => Promise<Hex>,
53
+ payload: Hex,
48
54
  nonce: bigint,
55
+ round: bigint,
49
56
  verifyingContract: Hex,
50
57
  chainId: number,
51
58
  ): Promise<Signature> {
@@ -57,17 +64,19 @@ export async function signVoteWithSig(
57
64
  };
58
65
 
59
66
  const types = {
60
- Vote: [
61
- { name: 'proposal', type: 'address' },
67
+ Signal: [
68
+ { name: 'payload', type: 'address' },
62
69
  { name: 'nonce', type: 'uint256' },
70
+ { name: 'round', type: 'uint256' },
63
71
  ],
64
72
  };
65
73
 
66
74
  const message = {
67
- proposal,
75
+ payload,
68
76
  nonce,
77
+ round,
69
78
  };
70
79
 
71
- const msg = hashTypedData({ domain, types, primaryType: 'Vote', message });
72
- return Signature.fromString(await signer(msg));
80
+ const typedData = { domain, types, primaryType: 'Signal', message };
81
+ return Signature.fromString(await signer(typedData));
73
82
  }
@@ -227,9 +227,9 @@ export class GovernanceContract extends ReadOnlyGovernanceContract {
227
227
  }
228
228
  logger.info(`Voted [${inFavor ? 'yea' : 'nay'}] on proposal [${proposalId}]`);
229
229
  const proposal = await this.getProposal(proposalId);
230
- logger.info(`Proposal [${proposalId}] has state [${proposal.state}]`);
230
+ logger.info(`Proposal [${proposalId}] has cached state [${proposal.cachedState}]`);
231
231
  logger.info(`Proposal [${proposalId}] has summedBallot yea [${proposal.summedBallot.yea}]`);
232
- logger.info(`Proposal [${proposalId}] has summedBallot nea [${proposal.summedBallot.nea}]`);
232
+ logger.info(`Proposal [${proposalId}] has summedBallot nay [${proposal.summedBallot.nay}]`);
233
233
  }
234
234
 
235
235
  public async executeProposal({
@@ -2,11 +2,18 @@ import { memoize } from '@aztec/foundation/decorators';
2
2
  import { EthAddress } from '@aztec/foundation/eth-address';
3
3
  import { GovernanceProposerAbi } from '@aztec/l1-artifacts/GovernanceProposerAbi';
4
4
 
5
- import { type GetContractReturnType, type Hex, type TransactionReceipt, encodeFunctionData, getContract } from 'viem';
5
+ import {
6
+ type GetContractReturnType,
7
+ type Hex,
8
+ type TransactionReceipt,
9
+ type TypedDataDefinition,
10
+ encodeFunctionData,
11
+ getContract,
12
+ } from 'viem';
6
13
 
7
14
  import type { GasPrice, L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
8
15
  import type { ViemClient } from '../types.js';
9
- import { type IEmpireBase, encodeVote, encodeVoteWithSignature, signVoteWithSig } from './empire_base.js';
16
+ import { type IEmpireBase, encodeSignal, encodeSignalWithSignature, signSignalWithSig } from './empire_base.js';
10
17
  import { extractProposalIdFromLogs } from './governance.js';
11
18
 
12
19
  export class GovernanceProposerContract implements IEmpireBase {
@@ -33,11 +40,11 @@ export class GovernanceProposerContract implements IEmpireBase {
33
40
  }
34
41
 
35
42
  public getQuorumSize(): Promise<bigint> {
36
- return this.proposer.read.N();
43
+ return this.proposer.read.QUORUM_SIZE();
37
44
  }
38
45
 
39
46
  public getRoundSize(): Promise<bigint> {
40
- return this.proposer.read.M();
47
+ return this.proposer.read.ROUND_SIZE();
41
48
  }
42
49
 
43
50
  public computeRound(slot: bigint): Promise<bigint> {
@@ -51,36 +58,37 @@ export class GovernanceProposerContract implements IEmpireBase {
51
58
  public async getRoundInfo(
52
59
  rollupAddress: Hex,
53
60
  round: bigint,
54
- ): Promise<{ lastVote: bigint; leader: Hex; executed: boolean }> {
61
+ ): Promise<{ lastSignalSlot: bigint; payloadWithMostSignals: Hex; executed: boolean }> {
55
62
  return await this.proposer.read.getRoundData([rollupAddress, round]);
56
63
  }
57
64
 
58
- public getProposalVotes(rollupAddress: Hex, round: bigint, proposal: Hex): Promise<bigint> {
59
- return this.proposer.read.yeaCount([rollupAddress, round, proposal]);
65
+ public getPayloadSignals(rollupAddress: Hex, round: bigint, payload: Hex): Promise<bigint> {
66
+ return this.proposer.read.signalCount([rollupAddress, round, payload]);
60
67
  }
61
68
 
62
- public createVoteRequest(payload: Hex): L1TxRequest {
69
+ public createSignalRequest(payload: Hex): L1TxRequest {
63
70
  return {
64
71
  to: this.address.toString(),
65
- data: encodeVote(payload),
72
+ data: encodeSignal(payload),
66
73
  };
67
74
  }
68
75
 
69
- public async createVoteRequestWithSignature(
76
+ public async createSignalRequestWithSignature(
70
77
  payload: Hex,
78
+ round: bigint,
71
79
  chainId: number,
72
80
  signerAddress: Hex,
73
- signer: (msg: Hex) => Promise<Hex>,
81
+ signer: (msg: TypedDataDefinition) => Promise<Hex>,
74
82
  ): Promise<L1TxRequest> {
75
83
  const nonce = await this.getNonce(signerAddress);
76
- const signature = await signVoteWithSig(signer, payload, nonce, this.address.toString(), chainId);
84
+ const signature = await signSignalWithSig(signer, payload, nonce, round, this.address.toString(), chainId);
77
85
  return {
78
86
  to: this.address.toString(),
79
- data: encodeVoteWithSignature(payload, signature),
87
+ data: encodeSignalWithSignature(payload, signature),
80
88
  };
81
89
  }
82
90
 
83
- public async executeProposal(
91
+ public async submitRoundWinner(
84
92
  round: bigint,
85
93
  l1TxUtils: L1TxUtils,
86
94
  ): Promise<{
@@ -92,7 +100,7 @@ export class GovernanceProposerContract implements IEmpireBase {
92
100
  to: this.address.toString(),
93
101
  data: encodeFunctionData({
94
102
  abi: this.proposer.abi,
95
- functionName: 'executeProposal',
103
+ functionName: 'submitRoundWinner',
96
104
  args: [round],
97
105
  }),
98
106
  });
@@ -0,0 +1,73 @@
1
+ import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { GSEAbi } from '@aztec/l1-artifacts/GSEAbi';
3
+
4
+ import type { ProjPointType } from '@noble/curves/abstract/weierstrass';
5
+ import { bn254 } from '@noble/curves/bn254';
6
+ import { type GetContractReturnType, type Hex, getContract } from 'viem';
7
+
8
+ import type { ViemClient } from '../types.js';
9
+
10
+ export type RegistrationTuple = {
11
+ publicKeyInG1: {
12
+ x: bigint;
13
+ y: bigint;
14
+ };
15
+ publicKeyInG2: {
16
+ x0: bigint;
17
+ x1: bigint;
18
+ y0: bigint;
19
+ y1: bigint;
20
+ };
21
+ proofOfPossession: {
22
+ x: bigint;
23
+ y: bigint;
24
+ };
25
+ };
26
+
27
+ export class GSEContract {
28
+ public address: EthAddress;
29
+ private readonly gse: GetContractReturnType<typeof GSEAbi, ViemClient>;
30
+
31
+ constructor(
32
+ public readonly client: ViemClient,
33
+ address: Hex | EthAddress,
34
+ ) {
35
+ if (address instanceof EthAddress) {
36
+ address = address.toString();
37
+ }
38
+ this.address = EthAddress.fromString(address);
39
+ this.gse = getContract({ address, abi: GSEAbi, client });
40
+ }
41
+
42
+ public async getRegistrationDigest(publicKey: ProjPointType<bigint>): Promise<ProjPointType<bigint>> {
43
+ const affinePublicKey = publicKey.toAffine();
44
+ const g1PointDigest = await this.gse.read.getRegistrationDigest([{ x: affinePublicKey.x, y: affinePublicKey.y }]);
45
+ return bn254.G1.ProjectivePoint.fromAffine(g1PointDigest);
46
+ }
47
+
48
+ public async makeRegistrationTuple(privateKey: bigint): Promise<RegistrationTuple> {
49
+ const publicKeyG1 = bn254.G1.ProjectivePoint.BASE.multiply(privateKey);
50
+ const digest = await this.getRegistrationDigest(publicKeyG1);
51
+ const signature = digest.multiply(privateKey);
52
+ const publicKeyG2 = bn254.G2.ProjectivePoint.BASE.multiply(privateKey);
53
+ const publicKeyG1Affine = publicKeyG1.toAffine();
54
+ const signatureAffine = signature.toAffine();
55
+ const publicKeyG2Affine = publicKeyG2.toAffine();
56
+ return {
57
+ publicKeyInG1: {
58
+ x: publicKeyG1Affine.x,
59
+ y: publicKeyG1Affine.y,
60
+ },
61
+ publicKeyInG2: {
62
+ x0: publicKeyG2Affine.x.c0,
63
+ x1: publicKeyG2Affine.x.c1,
64
+ y0: publicKeyG2Affine.y.c0,
65
+ y1: publicKeyG2Affine.y.c1,
66
+ },
67
+ proofOfPossession: {
68
+ x: signatureAffine.x,
69
+ y: signatureAffine.y,
70
+ },
71
+ };
72
+ }
73
+ }
@@ -4,6 +4,7 @@ export * from './fee_asset_handler.js';
4
4
  export * from './fee_juice.js';
5
5
  export * from './governance.js';
6
6
  export * from './governance_proposer.js';
7
+ export * from './gse.js';
7
8
  export * from './inbox.js';
8
9
  export * from './multicall.js';
9
10
  export * from './registry.js';