@aztec/ethereum 1.0.0-nightly.20250708 → 1.0.0-nightly.20250709

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.
@@ -1,7 +1,6 @@
1
1
  import { Signature } from '@aztec/foundation/eth-signature';
2
- import { type Hex, type WalletClient } from 'viem';
2
+ import { type Hex } from 'viem';
3
3
  import type { L1TxRequest } from '../l1_tx_utils.js';
4
- import type { ExtendedViemWalletClient } from '../types.js';
5
4
  export interface IEmpireBase {
6
5
  getRoundInfo(rollupAddress: Hex, round: bigint): Promise<{
7
6
  lastVote: bigint;
@@ -10,7 +9,7 @@ export interface IEmpireBase {
10
9
  }>;
11
10
  computeRound(slot: bigint): Promise<bigint>;
12
11
  createVoteRequest(payload: Hex): L1TxRequest;
13
- createVoteRequestWithSignature(payload: Hex, wallet: ExtendedViemWalletClient): Promise<L1TxRequest>;
12
+ createVoteRequestWithSignature(payload: Hex, chainId: number, signerAddress: Hex, signer: (msg: Hex) => Promise<Hex>): Promise<L1TxRequest>;
14
13
  }
15
14
  export declare function encodeVote(payload: Hex): Hex;
16
15
  export declare function encodeVoteWithSignature(payload: Hex, signature: Signature): `0x${string}`;
@@ -23,5 +22,5 @@ export declare function encodeVoteWithSignature(payload: Hex, signature: Signatu
23
22
  * @param account - The account to sign with (optional if hoisted on wallet client)
24
23
  * @returns The EIP-712 signature
25
24
  */
26
- export declare function signVoteWithSig(walletClient: WalletClient, proposal: Hex, nonce: bigint, verifyingContract: Hex, chainId: number): Promise<Signature>;
25
+ export declare function signVoteWithSig(signer: (msg: Hex) => Promise<Hex>, proposal: Hex, nonce: bigint, verifyingContract: Hex, chainId: number): Promise<Signature>;
27
26
  //# sourceMappingURL=empire_base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"empire_base.d.ts","sourceRoot":"","sources":["../../src/contracts/empire_base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK,YAAY,EAAsB,MAAM,MAAM,CAAC;AAEvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/G,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,CAAC;IAC7C,8BAA8B,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CACtG;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,CAM5C;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,iBAMzE;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,GAAG,EACb,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,GAAG,EACtB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAAC,CAgCpB"}
1
+ {"version":3,"file":"empire_base.d.ts","sourceRoot":"","sources":["../../src/contracts/empire_base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAG5D,OAAO,EAAE,KAAK,GAAG,EAAqC,MAAM,MAAM,CAAC;AAEnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC/G,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW,CAAC;IAC7C,8BAA8B,CAC5B,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,GAAG,EAClB,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GACjC,OAAO,CAAC,WAAW,CAAC,CAAC;CACzB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,GAAG,CAM5C;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,iBAMzE;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,EAClC,QAAQ,EAAE,GAAG,EACb,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,GAAG,EACtB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,SAAS,CAAC,CAsBpB"}
@@ -1,6 +1,6 @@
1
1
  import { Signature } from '@aztec/foundation/eth-signature';
2
2
  import { EmpireBaseAbi } from '@aztec/l1-artifacts/EmpireBaseAbi';
3
- import { encodeFunctionData } from 'viem';
3
+ import { encodeFunctionData, hashTypedData } from 'viem';
4
4
  export function encodeVote(payload) {
5
5
  return encodeFunctionData({
6
6
  abi: EmpireBaseAbi,
@@ -28,7 +28,7 @@ export function encodeVoteWithSignature(payload, signature) {
28
28
  * @param chainId - The chain ID where the contract is deployed
29
29
  * @param account - The account to sign with (optional if hoisted on wallet client)
30
30
  * @returns The EIP-712 signature
31
- */ export async function signVoteWithSig(walletClient, proposal, nonce, verifyingContract, chainId) {
31
+ */ export async function signVoteWithSig(signer, proposal, nonce, verifyingContract, chainId) {
32
32
  const domain = {
33
33
  name: 'EmpireBase',
34
34
  version: '1',
@@ -51,15 +51,11 @@ export function encodeVoteWithSignature(payload, signature) {
51
51
  proposal,
52
52
  nonce
53
53
  };
54
- if (!walletClient.account) {
55
- throw new Error('Wallet client must be connected to an account');
56
- }
57
- const signatureHex = await walletClient.signTypedData({
58
- account: walletClient.account.address,
54
+ const msg = hashTypedData({
59
55
  domain,
60
56
  types,
61
57
  primaryType: 'Vote',
62
58
  message
63
59
  });
64
- return Signature.fromString(signatureHex);
60
+ return Signature.fromString(await signer(msg));
65
61
  }
@@ -1,7 +1,7 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import { type Hex, type TransactionReceipt } from 'viem';
3
3
  import type { GasPrice, L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
4
- import type { ExtendedViemWalletClient, ViemClient } from '../types.js';
4
+ import type { ViemClient } from '../types.js';
5
5
  import { type IEmpireBase } from './empire_base.js';
6
6
  export declare class GovernanceProposerContract implements IEmpireBase {
7
7
  readonly client: ViemClient;
@@ -21,7 +21,7 @@ export declare class GovernanceProposerContract implements IEmpireBase {
21
21
  }>;
22
22
  getProposalVotes(rollupAddress: Hex, round: bigint, proposal: Hex): Promise<bigint>;
23
23
  createVoteRequest(payload: Hex): L1TxRequest;
24
- createVoteRequestWithSignature(payload: Hex, wallet: ExtendedViemWalletClient): Promise<L1TxRequest>;
24
+ createVoteRequestWithSignature(payload: Hex, chainId: number, signerAddress: Hex, signer: (msg: Hex) => Promise<Hex>): Promise<L1TxRequest>;
25
25
  executeProposal(round: bigint, l1TxUtils: L1TxUtils): Promise<{
26
26
  receipt: TransactionReceipt;
27
27
  gasPrice: GasPrice;
@@ -1 +1 @@
1
- {"version":3,"file":"governance_proposer.d.ts","sourceRoot":"","sources":["../../src/contracts/governance_proposer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAA8B,KAAK,GAAG,EAAE,KAAK,kBAAkB,EAAmC,MAAM,MAAM,CAAC;AAEtH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,KAAK,WAAW,EAAwD,MAAM,kBAAkB,CAAC;AAG1G,qBAAa,0BAA2B,YAAW,WAAW;aAI1C,MAAM,EAAE,UAAU;IAHpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkE;gBAGzE,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG;IAKd,IAAW,OAAO,eAEjB;IAEY,gBAAgB;IAKhB,kBAAkB;IAIxB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAIhC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3C,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlC,YAAY,CACvB,aAAa,EAAE,GAAG,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAIzD,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAInF,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW;IAOtC,8BAA8B,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,WAAW,CAAC;IASpG,eAAe,CAC1B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC;QACT,OAAO,EAAE,kBAAkB,CAAC;QAC5B,QAAQ,EAAE,QAAQ,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CAYH"}
1
+ {"version":3,"file":"governance_proposer.d.ts","sourceRoot":"","sources":["../../src/contracts/governance_proposer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAA8B,KAAK,GAAG,EAAE,KAAK,kBAAkB,EAAmC,MAAM,MAAM,CAAC;AAEtH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,KAAK,WAAW,EAAwD,MAAM,kBAAkB,CAAC;AAG1G,qBAAa,0BAA2B,YAAW,WAAW;aAI1C,MAAM,EAAE,UAAU;IAHpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkE;gBAGzE,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG;IAKd,IAAW,OAAO,eAEjB;IAEY,gBAAgB;IAKhB,kBAAkB;IAIxB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAIhC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3C,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlC,YAAY,CACvB,aAAa,EAAE,GAAG,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAIzD,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAInF,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW;IAOtC,8BAA8B,CACzC,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,GAAG,EAClB,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GACjC,OAAO,CAAC,WAAW,CAAC;IASV,eAAe,CAC1B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC;QACT,OAAO,EAAE,kBAAkB,CAAC;QAC5B,QAAQ,EAAE,QAAQ,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CAYH"}
@@ -65,9 +65,9 @@ export class GovernanceProposerContract {
65
65
  data: encodeVote(payload)
66
66
  };
67
67
  }
68
- async createVoteRequestWithSignature(payload, wallet) {
69
- const nonce = await this.getNonce(wallet.account.address);
70
- const signature = await signVoteWithSig(wallet, payload, nonce, this.address.toString(), wallet.chain.id);
68
+ async createVoteRequestWithSignature(payload, chainId, signerAddress, signer) {
69
+ const nonce = await this.getNonce(signerAddress);
70
+ const signature = await signVoteWithSig(signer, payload, nonce, this.address.toString(), chainId);
71
71
  return {
72
72
  to: this.address.toString(),
73
73
  data: encodeVoteWithSignature(payload, signature)
@@ -2,13 +2,14 @@ import { EthAddress } from '@aztec/foundation/eth-address';
2
2
  import EventEmitter from 'events';
3
3
  import { type Hex } from 'viem';
4
4
  import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
5
- import type { ExtendedViemWalletClient, ViemClient } from '../types.js';
5
+ import type { ViemClient } from '../types.js';
6
6
  import { type IEmpireBase } from './empire_base.js';
7
7
  export declare class ProposalAlreadyExecutedError extends Error {
8
8
  constructor(round: bigint);
9
9
  }
10
10
  export declare class SlashingProposerContract extends EventEmitter implements IEmpireBase {
11
11
  readonly client: ViemClient;
12
+ private readonly logger;
12
13
  private readonly proposer;
13
14
  constructor(client: ViemClient, address: Hex);
14
15
  get address(): EthAddress;
@@ -23,7 +24,7 @@ export declare class SlashingProposerContract extends EventEmitter implements IE
23
24
  }>;
24
25
  getProposalVotes(rollupAddress: Hex, round: bigint, proposal: Hex): Promise<bigint>;
25
26
  createVoteRequest(payload: Hex): L1TxRequest;
26
- createVoteRequestWithSignature(payload: Hex, wallet: ExtendedViemWalletClient): Promise<L1TxRequest>;
27
+ createVoteRequestWithSignature(payload: Hex, chainId: number, signerAddress: Hex, signer: (msg: Hex) => Promise<Hex>): Promise<L1TxRequest>;
27
28
  listenToExecutableProposals(callback: (args: {
28
29
  proposal: `0x${string}`;
29
30
  round: bigint;
@@ -32,6 +33,13 @@ export declare class SlashingProposerContract extends EventEmitter implements IE
32
33
  round: bigint;
33
34
  proposal: `0x${string}`;
34
35
  }) => unknown): import("viem").WatchContractEventReturnType;
36
+ /**
37
+ * Wait for a round to be reached.
38
+ *
39
+ * @param round - The round to wait for.
40
+ * @param pollingIntervalSeconds - The interval in seconds to poll for the round.
41
+ * @returns True if the round was reached, false otherwise.
42
+ */
35
43
  waitForRound(round: bigint, pollingIntervalSeconds?: number): Promise<boolean>;
36
44
  executeRound(txUtils: L1TxUtils, round: bigint | number): ReturnType<typeof txUtils.sendAndMonitorTransaction>;
37
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"slashing_proposer.d.ts","sourceRoot":"","sources":["../../src/contracts/slashing_proposer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAI3D,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAGL,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExE,OAAO,EAAE,KAAK,WAAW,EAAwD,MAAM,kBAAkB,CAAC;AAE1G,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,KAAK,EAAE,MAAM;CAG1B;AAED,qBAAa,wBAAyB,SAAQ,YAAa,YAAW,WAAW;aAI7D,MAAM,EAAE,UAAU;IAHpC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgE;gBAGvE,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG;IAMd,IAAW,OAAO,eAEjB;IAEM,aAAa;IAIb,YAAY;IAIZ,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3C,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlC,YAAY,CACvB,aAAa,EAAE,GAAG,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAIzD,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAInF,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW;IAOtC,8BAA8B,CAAC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,wBAAwB,GAAG,OAAO,CAAC,WAAW,CAAC;IAS1G,2BAA2B,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO;IAiBnG,wBAAwB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO;IAgBhG,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,sBAAsB,GAAE,MAAU;IAYxD,YAAY,CACvB,OAAO,EAAE,SAAS,EAClB,KAAK,EAAE,MAAM,GAAG,MAAM,GACrB,UAAU,CAAC,OAAO,OAAO,CAAC,yBAAyB,CAAC;CA+CxD"}
1
+ {"version":3,"file":"slashing_proposer.d.ts","sourceRoot":"","sources":["../../src/contracts/slashing_proposer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAK3D,OAAO,YAAY,MAAM,QAAQ,CAAC;AAClC,OAAO,EAGL,KAAK,GAAG,EAGT,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,KAAK,WAAW,EAAwD,MAAM,kBAAkB,CAAC;AAE1G,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,KAAK,EAAE,MAAM;CAG1B;AAED,qBAAa,wBAAyB,SAAQ,YAAa,YAAW,WAAW;aAK7D,MAAM,EAAE,UAAU;IAJpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;IACnE,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgE;gBAGvE,MAAM,EAAE,UAAU,EAClC,OAAO,EAAE,GAAG;IAMd,IAAW,OAAO,eAEjB;IAEM,aAAa;IAIb,YAAY;IAIZ,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI3C,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlC,YAAY,CACvB,aAAa,EAAE,GAAG,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IAIzD,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;IAInF,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,WAAW;IAOtC,8BAA8B,CACzC,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,GAAG,EAClB,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GACjC,OAAO,CAAC,WAAW,CAAC;IAShB,2BAA2B,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO;IAiBnG,wBAAwB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,KAAK,MAAM,EAAE,CAAA;KAAE,KAAK,OAAO;IAgBvG;;;;;;OAMG;IACI,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,sBAAsB,GAAE,MAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAe3E,YAAY,CACvB,OAAO,EAAE,SAAS,EAClB,KAAK,EAAE,MAAM,GAAG,MAAM,GACrB,UAAU,CAAC,OAAO,OAAO,CAAC,yBAAyB,CAAC;CA+CxD"}
@@ -1,4 +1,5 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { createLogger } from '@aztec/foundation/log';
2
3
  import { retryUntil } from '@aztec/foundation/retry';
3
4
  import { SlashingProposerAbi } from '@aztec/l1-artifacts/SlashingProposerAbi';
4
5
  import EventEmitter from 'events';
@@ -12,9 +13,10 @@ export class ProposalAlreadyExecutedError extends Error {
12
13
  }
13
14
  export class SlashingProposerContract extends EventEmitter {
14
15
  client;
16
+ logger;
15
17
  proposer;
16
18
  constructor(client, address){
17
- super(), this.client = client;
19
+ super(), this.client = client, this.logger = createLogger('SlashingProposerContract');
18
20
  this.proposer = getContract({
19
21
  address,
20
22
  abi: SlashingProposerAbi,
@@ -59,9 +61,9 @@ export class SlashingProposerContract extends EventEmitter {
59
61
  data: encodeVote(payload)
60
62
  };
61
63
  }
62
- async createVoteRequestWithSignature(payload, wallet) {
63
- const nonce = await this.getNonce(wallet.account.address);
64
- const signature = await signVoteWithSig(wallet, payload, nonce, this.address.toString(), wallet.chain.id);
64
+ async createVoteRequestWithSignature(payload, chainId, signerAddress, signer) {
65
+ const nonce = await this.getNonce(signerAddress);
66
+ const signature = await signVoteWithSig(signer, payload, nonce, this.address.toString(), chainId);
65
67
  return {
66
68
  to: this.address.toString(),
67
69
  data: encodeVoteWithSignature(payload, signature)
@@ -92,11 +94,20 @@ export class SlashingProposerContract extends EventEmitter {
92
94
  }
93
95
  });
94
96
  }
95
- waitForRound(round, pollingIntervalSeconds = 1) {
97
+ /**
98
+ * Wait for a round to be reached.
99
+ *
100
+ * @param round - The round to wait for.
101
+ * @param pollingIntervalSeconds - The interval in seconds to poll for the round.
102
+ * @returns True if the round was reached, false otherwise.
103
+ */ waitForRound(round, pollingIntervalSeconds = 1) {
96
104
  return retryUntil(async ()=>{
97
- const currentRound = await this.proposer.read.getCurrentRound();
98
- return currentRound >= round;
99
- }, `Waiting for round ${round} to be reached`, 0, pollingIntervalSeconds);
105
+ const currentRound = await this.proposer.read.getCurrentRound().catch((e)=>{
106
+ this.logger.error('Error getting current round', e);
107
+ return undefined;
108
+ });
109
+ return currentRound !== undefined && currentRound >= round;
110
+ }, `Waiting for round ${round} to be reached`, 0, pollingIntervalSeconds).catch(()=>false);
100
111
  }
101
112
  async executeRound(txUtils, round) {
102
113
  if (typeof round === 'number') {
@@ -6,8 +6,10 @@ export declare function startAnvil(opts?: {
6
6
  port?: number;
7
7
  l1BlockTime?: number;
8
8
  log?: boolean;
9
+ captureMethodCalls?: boolean;
9
10
  }): Promise<{
10
11
  anvil: Anvil;
12
+ methodCalls?: string[];
11
13
  rpcUrl: string;
12
14
  stop: () => Promise<void>;
13
15
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"start_anvil.d.ts","sourceRoot":"","sources":["../../src/test/start_anvil.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,EAAe,MAAM,aAAa,CAAC;AAGtD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,GAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;CACV,GACL,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CA2CtE"}
1
+ {"version":3,"file":"start_anvil.d.ts","sourceRoot":"","sources":["../../src/test/start_anvil.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,KAAK,EAAe,MAAM,aAAa,CAAC;AAGtD;;GAEG;AACH,wBAAsB,UAAU,CAC9B,IAAI,GAAE;IACJ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,kBAAkB,CAAC,EAAE,OAAO,CAAC;CACzB,GACL,OAAO,CAAC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CA8C9F"}
@@ -8,6 +8,7 @@ import { dirname, resolve } from 'path';
8
8
  */ export async function startAnvil(opts = {}) {
9
9
  const anvilBinary = resolve(dirname(fileURLToPath(import.meta.url)), '../../', 'scripts/anvil_kill_wrapper.sh');
10
10
  const logger = opts.log ? createLogger('ethereum:anvil') : undefined;
11
+ const methodCalls = opts.captureMethodCalls ? [] : undefined;
11
12
  let port;
12
13
  // Start anvil.
13
14
  // We go via a wrapper script to ensure if the parent dies, anvil dies.
@@ -22,12 +23,13 @@ import { dirname, resolve } from 'path';
22
23
  // Listen to the anvil output to get the port.
23
24
  const removeHandler = anvil.on('message', (message)=>{
24
25
  logger?.debug(message);
26
+ methodCalls?.push(...message.match(/eth_[^\s]+/g) || []);
25
27
  if (port === undefined && message.includes('Listening on')) {
26
28
  port = parseInt(message.match(/Listening on ([^:]+):(\d+)/)[2]);
27
29
  }
28
30
  });
29
31
  await anvil.start();
30
- if (!logger) {
32
+ if (!logger && !opts.captureMethodCalls) {
31
33
  removeHandler();
32
34
  }
33
35
  return anvil;
@@ -43,6 +45,7 @@ import { dirname, resolve } from 'path';
43
45
  // Object.defineProperty(anvil, 'port', { value: port, writable: false });
44
46
  return {
45
47
  anvil,
48
+ methodCalls,
46
49
  stop: ()=>anvil.stop(),
47
50
  rpcUrl: `http://127.0.0.1:${port}`
48
51
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/ethereum",
3
- "version": "1.0.0-nightly.20250708",
3
+ "version": "1.0.0-nightly.20250709",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -31,9 +31,9 @@
31
31
  "../package.common.json"
32
32
  ],
33
33
  "dependencies": {
34
- "@aztec/blob-lib": "1.0.0-nightly.20250708",
35
- "@aztec/foundation": "1.0.0-nightly.20250708",
36
- "@aztec/l1-artifacts": "1.0.0-nightly.20250708",
34
+ "@aztec/blob-lib": "1.0.0-nightly.20250709",
35
+ "@aztec/foundation": "1.0.0-nightly.20250709",
36
+ "@aztec/l1-artifacts": "1.0.0-nightly.20250709",
37
37
  "@viem/anvil": "^0.0.10",
38
38
  "dotenv": "^16.0.3",
39
39
  "tslib": "^2.4.0",
@@ -1,16 +1,20 @@
1
1
  import { Signature } from '@aztec/foundation/eth-signature';
2
2
  import { EmpireBaseAbi } from '@aztec/l1-artifacts/EmpireBaseAbi';
3
3
 
4
- import { type Hex, type WalletClient, encodeFunctionData } from 'viem';
4
+ import { type Hex, encodeFunctionData, hashTypedData } from 'viem';
5
5
 
6
6
  import type { L1TxRequest } from '../l1_tx_utils.js';
7
- import type { ExtendedViemWalletClient } from '../types.js';
8
7
 
9
8
  export interface IEmpireBase {
10
9
  getRoundInfo(rollupAddress: Hex, round: bigint): Promise<{ lastVote: bigint; leader: Hex; executed: boolean }>;
11
10
  computeRound(slot: bigint): Promise<bigint>;
12
11
  createVoteRequest(payload: Hex): L1TxRequest;
13
- createVoteRequestWithSignature(payload: Hex, wallet: ExtendedViemWalletClient): Promise<L1TxRequest>;
12
+ createVoteRequestWithSignature(
13
+ payload: Hex,
14
+ chainId: number,
15
+ signerAddress: Hex,
16
+ signer: (msg: Hex) => Promise<Hex>,
17
+ ): Promise<L1TxRequest>;
14
18
  }
15
19
 
16
20
  export function encodeVote(payload: Hex): Hex {
@@ -39,7 +43,7 @@ export function encodeVoteWithSignature(payload: Hex, signature: Signature) {
39
43
  * @returns The EIP-712 signature
40
44
  */
41
45
  export async function signVoteWithSig(
42
- walletClient: WalletClient,
46
+ signer: (msg: Hex) => Promise<Hex>,
43
47
  proposal: Hex,
44
48
  nonce: bigint,
45
49
  verifyingContract: Hex,
@@ -64,16 +68,6 @@ export async function signVoteWithSig(
64
68
  nonce,
65
69
  };
66
70
 
67
- if (!walletClient.account) {
68
- throw new Error('Wallet client must be connected to an account');
69
- }
70
-
71
- const signatureHex = await walletClient.signTypedData({
72
- account: walletClient.account.address,
73
- domain,
74
- types,
75
- primaryType: 'Vote',
76
- message,
77
- });
78
- return Signature.fromString(signatureHex);
71
+ const msg = hashTypedData({ domain, types, primaryType: 'Vote', message });
72
+ return Signature.fromString(await signer(msg));
79
73
  }
@@ -5,7 +5,7 @@ import { GovernanceProposerAbi } from '@aztec/l1-artifacts/GovernanceProposerAbi
5
5
  import { type GetContractReturnType, type Hex, type TransactionReceipt, encodeFunctionData, getContract } from 'viem';
6
6
 
7
7
  import type { GasPrice, L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
8
- import type { ExtendedViemWalletClient, ViemClient } from '../types.js';
8
+ import type { ViemClient } from '../types.js';
9
9
  import { type IEmpireBase, encodeVote, encodeVoteWithSignature, signVoteWithSig } from './empire_base.js';
10
10
  import { extractProposalIdFromLogs } from './governance.js';
11
11
 
@@ -66,9 +66,14 @@ export class GovernanceProposerContract implements IEmpireBase {
66
66
  };
67
67
  }
68
68
 
69
- public async createVoteRequestWithSignature(payload: Hex, wallet: ExtendedViemWalletClient): Promise<L1TxRequest> {
70
- const nonce = await this.getNonce(wallet.account.address);
71
- const signature = await signVoteWithSig(wallet, payload, nonce, this.address.toString(), wallet.chain.id);
69
+ public async createVoteRequestWithSignature(
70
+ payload: Hex,
71
+ chainId: number,
72
+ signerAddress: Hex,
73
+ signer: (msg: Hex) => Promise<Hex>,
74
+ ): Promise<L1TxRequest> {
75
+ const nonce = await this.getNonce(signerAddress);
76
+ const signature = await signVoteWithSig(signer, payload, nonce, this.address.toString(), chainId);
72
77
  return {
73
78
  to: this.address.toString(),
74
79
  data: encodeVoteWithSignature(payload, signature),
@@ -1,4 +1,5 @@
1
1
  import { EthAddress } from '@aztec/foundation/eth-address';
2
+ import { createLogger } from '@aztec/foundation/log';
2
3
  import { retryUntil } from '@aztec/foundation/retry';
3
4
  import { SlashingProposerAbi } from '@aztec/l1-artifacts/SlashingProposerAbi';
4
5
 
@@ -12,7 +13,7 @@ import {
12
13
  } from 'viem';
13
14
 
14
15
  import type { L1TxRequest, L1TxUtils } from '../l1_tx_utils.js';
15
- import type { ExtendedViemWalletClient, ViemClient } from '../types.js';
16
+ import type { ViemClient } from '../types.js';
16
17
  import { FormattedViemError } from '../utils.js';
17
18
  import { type IEmpireBase, encodeVote, encodeVoteWithSignature, signVoteWithSig } from './empire_base.js';
18
19
 
@@ -23,6 +24,7 @@ export class ProposalAlreadyExecutedError extends Error {
23
24
  }
24
25
 
25
26
  export class SlashingProposerContract extends EventEmitter implements IEmpireBase {
27
+ private readonly logger = createLogger('SlashingProposerContract');
26
28
  private readonly proposer: GetContractReturnType<typeof SlashingProposerAbi, ViemClient>;
27
29
 
28
30
  constructor(
@@ -71,9 +73,14 @@ export class SlashingProposerContract extends EventEmitter implements IEmpireBas
71
73
  };
72
74
  }
73
75
 
74
- public async createVoteRequestWithSignature(payload: Hex, wallet: ExtendedViemWalletClient): Promise<L1TxRequest> {
75
- const nonce = await this.getNonce(wallet.account.address);
76
- const signature = await signVoteWithSig(wallet, payload, nonce, this.address.toString(), wallet.chain.id);
76
+ public async createVoteRequestWithSignature(
77
+ payload: Hex,
78
+ chainId: number,
79
+ signerAddress: Hex,
80
+ signer: (msg: Hex) => Promise<Hex>,
81
+ ): Promise<L1TxRequest> {
82
+ const nonce = await this.getNonce(signerAddress);
83
+ const signature = await signVoteWithSig(signer, payload, nonce, this.address.toString(), chainId);
77
84
  return {
78
85
  to: this.address.toString(),
79
86
  data: encodeVoteWithSignature(payload, signature),
@@ -113,16 +120,26 @@ export class SlashingProposerContract extends EventEmitter implements IEmpireBas
113
120
  );
114
121
  }
115
122
 
116
- public waitForRound(round: bigint, pollingIntervalSeconds: number = 1) {
123
+ /**
124
+ * Wait for a round to be reached.
125
+ *
126
+ * @param round - The round to wait for.
127
+ * @param pollingIntervalSeconds - The interval in seconds to poll for the round.
128
+ * @returns True if the round was reached, false otherwise.
129
+ */
130
+ public waitForRound(round: bigint, pollingIntervalSeconds: number = 1): Promise<boolean> {
117
131
  return retryUntil(
118
132
  async () => {
119
- const currentRound = await this.proposer.read.getCurrentRound();
120
- return currentRound >= round;
133
+ const currentRound = await this.proposer.read.getCurrentRound().catch(e => {
134
+ this.logger.error('Error getting current round', e);
135
+ return undefined;
136
+ });
137
+ return currentRound !== undefined && currentRound >= round;
121
138
  },
122
139
  `Waiting for round ${round} to be reached`,
123
140
  0, // no timeout
124
141
  pollingIntervalSeconds,
125
- );
142
+ ).catch(() => false);
126
143
  }
127
144
 
128
145
  public async executeRound(
@@ -13,10 +13,12 @@ export async function startAnvil(
13
13
  port?: number;
14
14
  l1BlockTime?: number;
15
15
  log?: boolean;
16
+ captureMethodCalls?: boolean;
16
17
  } = {},
17
- ): Promise<{ anvil: Anvil; rpcUrl: string; stop: () => Promise<void> }> {
18
+ ): Promise<{ anvil: Anvil; methodCalls?: string[]; rpcUrl: string; stop: () => Promise<void> }> {
18
19
  const anvilBinary = resolve(dirname(fileURLToPath(import.meta.url)), '../../', 'scripts/anvil_kill_wrapper.sh');
19
20
  const logger = opts.log ? createLogger('ethereum:anvil') : undefined;
21
+ const methodCalls = opts.captureMethodCalls ? ([] as string[]) : undefined;
20
22
 
21
23
  let port: number | undefined;
22
24
 
@@ -35,12 +37,14 @@ export async function startAnvil(
35
37
  // Listen to the anvil output to get the port.
36
38
  const removeHandler = anvil.on('message', (message: string) => {
37
39
  logger?.debug(message);
40
+
41
+ methodCalls?.push(...(message.match(/eth_[^\s]+/g) || []));
38
42
  if (port === undefined && message.includes('Listening on')) {
39
43
  port = parseInt(message.match(/Listening on ([^:]+):(\d+)/)![2]);
40
44
  }
41
45
  });
42
46
  await anvil.start();
43
- if (!logger) {
47
+ if (!logger && !opts.captureMethodCalls) {
44
48
  removeHandler();
45
49
  }
46
50
 
@@ -56,5 +60,5 @@ export async function startAnvil(
56
60
 
57
61
  // Monkeypatch the anvil instance to include the actually assigned port
58
62
  // Object.defineProperty(anvil, 'port', { value: port, writable: false });
59
- return { anvil, stop: () => anvil.stop(), rpcUrl: `http://127.0.0.1:${port}` };
63
+ return { anvil, methodCalls, stop: () => anvil.stop(), rpcUrl: `http://127.0.0.1:${port}` };
60
64
  }