@aztec/bot 5.0.0-private.20260319 → 5.0.0-rc.1

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.
package/dest/runner.js CHANGED
@@ -386,6 +386,7 @@ export class BotRunner {
386
386
  telemetry;
387
387
  aztecNodeAdmin;
388
388
  store;
389
+ syncChainTip;
389
390
  static{
390
391
  ({ e: [_call_work, _initProto] } = _apply_decs_2203_r(this, [
391
392
  [
@@ -428,13 +429,14 @@ export class BotRunner {
428
429
  consecutiveErrors;
429
430
  healthy;
430
431
  tracer;
431
- constructor(config, wallet, aztecNode, telemetry, aztecNodeAdmin, store){
432
+ constructor(config, wallet, aztecNode, telemetry, aztecNodeAdmin, store, syncChainTip){
432
433
  this.config = config;
433
434
  this.wallet = wallet;
434
435
  this.aztecNode = aztecNode;
435
436
  this.telemetry = telemetry;
436
437
  this.aztecNodeAdmin = aztecNodeAdmin;
437
438
  this.store = store;
439
+ this.syncChainTip = syncChainTip;
438
440
  this.log = (_initProto(this), createLogger('bot'));
439
441
  this.consecutiveErrors = 0;
440
442
  this.healthy = true;
@@ -538,13 +540,13 @@ export class BotRunner {
538
540
  try {
539
541
  switch(this.config.botMode){
540
542
  case 'crosschain':
541
- this.bot = CrossChainBot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store);
543
+ this.bot = CrossChainBot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store, this.syncChainTip);
542
544
  break;
543
545
  case 'amm':
544
- this.bot = AmmBot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store);
546
+ this.bot = AmmBot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store, this.syncChainTip);
545
547
  break;
546
548
  case 'transfer':
547
- this.bot = Bot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store);
549
+ this.bot = Bot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store, this.syncChainTip);
548
550
  break;
549
551
  default:
550
552
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/bot",
3
- "version": "5.0.0-private.20260319",
3
+ "version": "5.0.0-rc.1",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -54,24 +54,24 @@
54
54
  ]
55
55
  },
56
56
  "dependencies": {
57
- "@aztec/accounts": "5.0.0-private.20260319",
58
- "@aztec/aztec.js": "5.0.0-private.20260319",
59
- "@aztec/entrypoints": "5.0.0-private.20260319",
60
- "@aztec/ethereum": "5.0.0-private.20260319",
61
- "@aztec/foundation": "5.0.0-private.20260319",
62
- "@aztec/kv-store": "5.0.0-private.20260319",
63
- "@aztec/l1-artifacts": "5.0.0-private.20260319",
64
- "@aztec/noir-contracts.js": "5.0.0-private.20260319",
65
- "@aztec/noir-protocol-circuits-types": "5.0.0-private.20260319",
66
- "@aztec/noir-test-contracts.js": "5.0.0-private.20260319",
67
- "@aztec/protocol-contracts": "5.0.0-private.20260319",
68
- "@aztec/stdlib": "5.0.0-private.20260319",
69
- "@aztec/telemetry-client": "5.0.0-private.20260319",
70
- "@aztec/wallets": "5.0.0-private.20260319",
57
+ "@aztec/accounts": "5.0.0-rc.1",
58
+ "@aztec/aztec.js": "5.0.0-rc.1",
59
+ "@aztec/entrypoints": "5.0.0-rc.1",
60
+ "@aztec/ethereum": "5.0.0-rc.1",
61
+ "@aztec/foundation": "5.0.0-rc.1",
62
+ "@aztec/kv-store": "5.0.0-rc.1",
63
+ "@aztec/l1-artifacts": "5.0.0-rc.1",
64
+ "@aztec/noir-contracts.js": "5.0.0-rc.1",
65
+ "@aztec/noir-protocol-circuits-types": "5.0.0-rc.1",
66
+ "@aztec/noir-test-contracts.js": "5.0.0-rc.1",
67
+ "@aztec/protocol-contracts": "5.0.0-rc.1",
68
+ "@aztec/stdlib": "5.0.0-rc.1",
69
+ "@aztec/telemetry-client": "5.0.0-rc.1",
70
+ "@aztec/wallets": "5.0.0-rc.1",
71
71
  "source-map-support": "^0.5.21",
72
72
  "tslib": "^2.4.0",
73
73
  "viem": "npm:@aztec/viem@2.38.2",
74
- "zod": "^3.23.8"
74
+ "zod": "^4"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@jest/globals": "^30.0.0",
package/src/amm_bot.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { AztecAddress } from '@aztec/aztec.js/addresses';
2
2
  import { NO_WAIT } from '@aztec/aztec.js/contracts';
3
3
  import { Fr } from '@aztec/aztec.js/fields';
4
- import { TxHash, TxReceipt } from '@aztec/aztec.js/tx';
4
+ import type { TxHash, TxReceipt } from '@aztec/aztec.js/tx';
5
5
  import { jsonStringify } from '@aztec/foundation/json-rpc';
6
6
  import type { AMMContract } from '@aztec/noir-contracts.js/AMM';
7
7
  import type { TokenContract } from '@aztec/noir-contracts.js/Token';
8
+ import type { BlockTag } from '@aztec/stdlib/block';
8
9
  import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
9
10
  import type { EmbeddedWallet } from '@aztec/wallets/embedded';
10
11
 
@@ -37,6 +38,7 @@ export class AmmBot extends BaseBot {
37
38
  aztecNode: AztecNode,
38
39
  aztecNodeAdmin: AztecNodeAdmin | undefined,
39
40
  store: BotStore,
41
+ syncChainTip?: BlockTag,
40
42
  ): Promise<AmmBot> {
41
43
  const { defaultAccountAddress, token0, token1, amm } = await new BotFactory(
42
44
  config,
@@ -44,6 +46,7 @@ export class AmmBot extends BaseBot {
44
46
  store,
45
47
  aztecNode,
46
48
  aztecNodeAdmin,
49
+ syncChainTip,
47
50
  ).setupAmm();
48
51
  return new AmmBot(aztecNode, wallet, defaultAccountAddress, amm, token0, token1, config);
49
52
  }
@@ -87,7 +90,7 @@ export class AmmBot extends BaseBot {
87
90
  authWitnesses: [swapAuthwit],
88
91
  });
89
92
 
90
- const opts = await this.getSendMethodOpts(swapExactTokensInteraction);
93
+ const opts = this.getSendMethodOpts();
91
94
 
92
95
  this.log.verbose(`Sending transaction`, logCtx);
93
96
  this.log.info(`Tx. Balances: ${jsonStringify(balances)}`, { ...logCtx, balances });
package/src/base_bot.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  import { AztecAddress } from '@aztec/aztec.js/addresses';
2
- import { BatchCall, ContractFunctionInteraction, type SendInteractionOptions } from '@aztec/aztec.js/contracts';
2
+ import type { SendInteractionOptions } from '@aztec/aztec.js/contracts';
3
3
  import { createLogger } from '@aztec/aztec.js/log';
4
4
  import { waitForTx } from '@aztec/aztec.js/node';
5
- import { TxHash, TxReceipt, TxStatus } from '@aztec/aztec.js/tx';
5
+ import { TxStatus } from '@aztec/aztec.js/tx';
6
+ import type { TxHash, TxReceipt } from '@aztec/aztec.js/tx';
6
7
  import { Gas } from '@aztec/stdlib/gas';
7
8
  import type { AztecNode } from '@aztec/stdlib/interfaces/client';
8
9
  import type { EmbeddedWallet } from '@aztec/wallets/embedded';
@@ -56,27 +57,19 @@ export abstract class BaseBot {
56
57
  return Promise.resolve();
57
58
  }
58
59
 
59
- protected async getSendMethodOpts(
60
- interaction: ContractFunctionInteraction | BatchCall,
61
- ): Promise<SendInteractionOptions> {
60
+ protected getSendMethodOpts(): SendInteractionOptions {
62
61
  const { l2GasLimit, daGasLimit, minFeePadding } = this.config;
63
62
 
64
63
  this.wallet.setMinFeePadding(minFeePadding);
65
64
 
66
- let gasSettings;
67
- if (l2GasLimit !== undefined && l2GasLimit > 0 && daGasLimit !== undefined && daGasLimit > 0) {
68
- gasSettings = { gasLimits: Gas.from({ l2Gas: l2GasLimit, daGas: daGasLimit }) };
69
- this.log.verbose(`Using gas limits ${l2GasLimit} L2 gas ${daGasLimit} DA gas`);
70
- } else {
71
- this.log.verbose(`Estimating gas for transaction`);
72
- ({ estimatedGas: gasSettings } = await interaction.simulate({
73
- fee: { estimateGas: true },
74
- from: this.defaultAccountAddress,
75
- }));
76
- }
65
+ const gasSettings =
66
+ l2GasLimit !== undefined && l2GasLimit > 0 && daGasLimit !== undefined && daGasLimit > 0
67
+ ? { gasLimits: Gas.from({ l2Gas: l2GasLimit, daGas: daGasLimit }) }
68
+ : undefined;
69
+
77
70
  return {
78
71
  from: this.defaultAccountAddress,
79
- fee: { gasSettings },
72
+ ...(gasSettings ? { fee: { gasSettings } } : {}),
80
73
  };
81
74
  }
82
75
  }
package/src/bot.ts CHANGED
@@ -4,6 +4,7 @@ import { TxHash } from '@aztec/aztec.js/tx';
4
4
  import { times } from '@aztec/foundation/collection';
5
5
  import type { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
6
6
  import type { TokenContract } from '@aztec/noir-contracts.js/Token';
7
+ import type { BlockTag } from '@aztec/stdlib/block';
7
8
  import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
8
9
  import type { EmbeddedWallet } from '@aztec/wallets/embedded';
9
10
 
@@ -33,6 +34,7 @@ export class Bot extends BaseBot {
33
34
  aztecNode: AztecNode,
34
35
  aztecNodeAdmin: AztecNodeAdmin | undefined,
35
36
  store: BotStore,
37
+ syncChainTip?: BlockTag,
36
38
  ): Promise<Bot> {
37
39
  const { defaultAccountAddress, token, recipient } = await new BotFactory(
38
40
  config,
@@ -40,6 +42,7 @@ export class Bot extends BaseBot {
40
42
  store,
41
43
  aztecNode,
42
44
  aztecNodeAdmin,
45
+ syncChainTip,
43
46
  ).setup();
44
47
  return new Bot(aztecNode, wallet, defaultAccountAddress, token, recipient, config);
45
48
  }
@@ -70,10 +73,7 @@ export class Bot extends BaseBot {
70
73
  );
71
74
 
72
75
  const batch = new BatchCall(wallet, calls);
73
- const opts = await this.getSendMethodOpts(batch);
74
-
75
- this.log.verbose(`Simulating transaction with ${calls.length}`, logCtx);
76
- await batch.simulate({ from: this.defaultAccountAddress });
76
+ const opts = this.getSendMethodOpts();
77
77
 
78
78
  this.log.verbose(`Sending transaction`, logCtx);
79
79
  const { txHash } = await batch.send({ ...opts, wait: NO_WAIT });
package/src/config.ts CHANGED
@@ -69,9 +69,9 @@ export type BotConfig = {
69
69
  maxPendingTxs: number;
70
70
  /** Whether to flush after sending each 'setup' transaction */
71
71
  flushSetupTransactions: boolean;
72
- /** L2 gas limit for the tx (empty to have the bot trigger an estimate gas). */
72
+ /** L2 gas limit for the tx (empty to let the bot's wallet estimate). */
73
73
  l2GasLimit: number | undefined;
74
- /** DA gas limit for the tx (empty to have the bot trigger an estimate gas). */
74
+ /** DA gas limit for the tx (empty to let the bot's wallet estimate). */
75
75
  daGasLimit: number | undefined;
76
76
  /** Token contract to use */
77
77
  contract: SupportedTokenContracts;
@@ -243,12 +243,12 @@ export const botConfigMappings: ConfigMappingsType<BotConfig> = {
243
243
  },
244
244
  l2GasLimit: {
245
245
  env: 'BOT_L2_GAS_LIMIT',
246
- description: 'L2 gas limit for the tx (empty to have the bot trigger an estimate gas).',
246
+ description: "L2 gas limit for the tx (empty to let the bot's wallet estimate).",
247
247
  ...optionalNumberConfigHelper(),
248
248
  },
249
249
  daGasLimit: {
250
250
  env: 'BOT_DA_GAS_LIMIT',
251
- description: 'DA gas limit for the tx (empty to have the bot trigger an estimate gas).',
251
+ description: "DA gas limit for the tx (empty to let the bot's wallet estimate).",
252
252
  ...optionalNumberConfigHelper(),
253
253
  },
254
254
  contract: {
@@ -26,11 +26,12 @@
26
26
  import { AztecAddress } from '@aztec/aztec.js/addresses';
27
27
  import { BatchCall, NO_WAIT } from '@aztec/aztec.js/contracts';
28
28
  import { isL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
29
- import { TxHash, TxReceipt } from '@aztec/aztec.js/tx';
29
+ import type { TxHash, TxReceipt } from '@aztec/aztec.js/tx';
30
30
  import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
31
31
  import { Fr } from '@aztec/foundation/curves/bn254';
32
32
  import { EthAddress } from '@aztec/foundation/eth-address';
33
33
  import type { TestContract } from '@aztec/noir-test-contracts.js/Test';
34
+ import type { BlockTag } from '@aztec/stdlib/block';
34
35
  import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
35
36
  import type { EmbeddedWallet } from '@aztec/wallets/embedded';
36
37
 
@@ -60,6 +61,7 @@ export class CrossChainBot extends BaseBot {
60
61
  private readonly rollupVersion: bigint,
61
62
  private readonly store: BotStore,
62
63
  config: BotConfig,
64
+ private readonly syncChainTip?: BlockTag,
63
65
  ) {
64
66
  super(node, wallet, defaultAccountAddress, config);
65
67
  }
@@ -70,11 +72,12 @@ export class CrossChainBot extends BaseBot {
70
72
  aztecNode: AztecNode,
71
73
  aztecNodeAdmin: AztecNodeAdmin | undefined,
72
74
  store: BotStore,
75
+ syncChainTip?: BlockTag,
73
76
  ): Promise<CrossChainBot> {
74
77
  if (config.followChain === 'NONE') {
75
78
  throw new Error(`CrossChainBot requires followChain to be set (got NONE)`);
76
79
  }
77
- const factory = new BotFactory(config, wallet, store, aztecNode, aztecNodeAdmin);
80
+ const factory = new BotFactory(config, wallet, store, aztecNode, aztecNodeAdmin, syncChainTip);
78
81
  const { defaultAccountAddress, contract, l1Client, rollupVersion } = await factory.setupCrossChain();
79
82
  const l1Recipient = EthAddress.fromString(l1Client.account!.address);
80
83
  const { l1ContractAddresses } = await aztecNode.getNodeInfo();
@@ -90,6 +93,7 @@ export class CrossChainBot extends BaseBot {
90
93
  rollupVersion,
91
94
  store,
92
95
  config,
96
+ syncChainTip,
93
97
  );
94
98
  }
95
99
 
@@ -137,7 +141,7 @@ export class CrossChainBot extends BaseBot {
137
141
  }
138
142
 
139
143
  const batch = new BatchCall(this.wallet, calls);
140
- const opts = await this.getSendMethodOpts(batch);
144
+ const opts = this.getSendMethodOpts();
141
145
 
142
146
  this.log.verbose(`Sending cross-chain batch with ${calls.length} calls`, logCtx);
143
147
  const { txHash } = await batch.send({ ...opts, wait: NO_WAIT });
@@ -146,9 +150,10 @@ export class CrossChainBot extends BaseBot {
146
150
 
147
151
  protected override async onTxMined(receipt: TxReceipt, logCtx: object): Promise<void> {
148
152
  // Verify L2→L1 messages appeared in this tx's effects
149
- const indexed = await this.node.getTxEffect(receipt.txHash);
150
- if (indexed) {
151
- const l2ToL1Msgs = indexed.data.l2ToL1Msgs.filter(m => !m.isZero());
153
+ const minedReceipt = await this.node.getTxReceipt(receipt.txHash, { includeTxEffect: true });
154
+ const l2ToL1MsgsRaw = minedReceipt.txEffect?.l2ToL1Msgs;
155
+ if (l2ToL1MsgsRaw) {
156
+ const l2ToL1Msgs = l2ToL1MsgsRaw.filter(m => !m.isZero());
152
157
  if (l2ToL1Msgs.length >= this.config.l2ToL1MessagesPerTx) {
153
158
  this.l2ToL1Sent += l2ToL1Msgs.length;
154
159
  } else {
@@ -175,7 +180,7 @@ export class CrossChainBot extends BaseBot {
175
180
  ): Promise<PendingL1ToL2Message | undefined> {
176
181
  const now = Date.now();
177
182
  for (const msg of pendingMessages) {
178
- const ready = await isL1ToL2MessageReady(this.node, Fr.fromHexString(msg.msgHash));
183
+ const ready = await isL1ToL2MessageReady(this.node, Fr.fromHexString(msg.msgHash), this.syncChainTip);
179
184
  if (ready) {
180
185
  return msg;
181
186
  }