@aztec/bot 3.0.3 → 4.0.0-devnet.1-patch.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/src/bot.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import type { AztecAddress } from '@aztec/aztec.js/addresses';
2
- import { BatchCall, SentTx } from '@aztec/aztec.js/contracts';
2
+ import { BatchCall, NO_WAIT } from '@aztec/aztec.js/contracts';
3
+ import { TxHash } from '@aztec/aztec.js/tx';
3
4
  import { times } from '@aztec/foundation/collection';
4
5
  import type { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
5
6
  import type { TokenContract } from '@aztec/noir-contracts.js/Token';
6
7
  import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
7
- import type { TestWallet } from '@aztec/test-wallet/server';
8
+ import type { EmbeddedWallet } from '@aztec/wallets/embedded';
8
9
 
9
10
  import { BaseBot } from './base_bot.js';
10
11
  import type { BotConfig } from './config.js';
@@ -17,7 +18,7 @@ const TRANSFER_AMOUNT = 1;
17
18
  export class Bot extends BaseBot {
18
19
  protected constructor(
19
20
  node: AztecNode,
20
- wallet: TestWallet,
21
+ wallet: EmbeddedWallet,
21
22
  defaultAccountAddress: AztecAddress,
22
23
  public readonly token: TokenContract | PrivateTokenContract,
23
24
  public readonly recipient: AztecAddress,
@@ -28,7 +29,7 @@ export class Bot extends BaseBot {
28
29
 
29
30
  static async create(
30
31
  config: BotConfig,
31
- wallet: TestWallet,
32
+ wallet: EmbeddedWallet,
32
33
  aztecNode: AztecNode,
33
34
  aztecNodeAdmin: AztecNodeAdmin | undefined,
34
35
  store: BotStore,
@@ -48,7 +49,7 @@ export class Bot extends BaseBot {
48
49
  this.config = { ...this.config, ...config };
49
50
  }
50
51
 
51
- protected async createAndSendTx(logCtx: object): Promise<SentTx> {
52
+ protected async createAndSendTx(logCtx: object): Promise<TxHash> {
52
53
  const { privateTransfersPerTx, publicTransfersPerTx, feePaymentMethod } = this.config;
53
54
  const { token, recipient, wallet } = this;
54
55
 
@@ -75,7 +76,7 @@ export class Bot extends BaseBot {
75
76
  await batch.simulate({ from: this.defaultAccountAddress });
76
77
 
77
78
  this.log.verbose(`Sending transaction`, logCtx);
78
- return batch.send(opts);
79
+ return batch.send({ ...opts, wait: NO_WAIT });
79
80
  }
80
81
 
81
82
  public async getBalances() {
package/src/config.ts CHANGED
@@ -14,7 +14,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
14
14
  import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
15
15
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
16
16
  import { protocolContractsHash } from '@aztec/protocol-contracts';
17
- import { type ZodFor, schemas } from '@aztec/stdlib/schemas';
17
+ import { schemas, zodFor } from '@aztec/stdlib/schemas';
18
18
  import type { ComponentsVersions } from '@aztec/stdlib/versioning';
19
19
 
20
20
  import { z } from 'zod';
@@ -54,8 +54,8 @@ export type BotConfig = {
54
54
  publicTransfersPerTx: number;
55
55
  /** How to handle fee payments. */
56
56
  feePaymentMethod: 'fee_juice';
57
- /** 'How much is the bot willing to overpay vs. the current base fee' */
58
- baseFeePadding: number;
57
+ /** 'How much is the bot willing to overpay vs. the current min fee' */
58
+ minFeePadding: number;
59
59
  /** True to not automatically setup or start the bot on initialization. */
60
60
  noStart: boolean;
61
61
  /** How long to wait for a tx to be mined before reporting an error. */
@@ -80,50 +80,52 @@ export type BotConfig = {
80
80
  ammTxs: boolean;
81
81
  } & Pick<DataStoreConfig, 'dataDirectory' | 'dataStoreMapSizeKb'>;
82
82
 
83
- export const BotConfigSchema = z
84
- .object({
85
- nodeUrl: z.string().optional(),
86
- nodeAdminUrl: z.string().optional(),
87
- l1RpcUrls: z.array(z.string()).optional(),
88
- l1Mnemonic: schemas.SecretValue(z.string()).optional(),
89
- l1PrivateKey: schemas.SecretValue(z.string()).optional(),
90
- l1ToL2MessageTimeoutSeconds: z.number(),
91
- senderPrivateKey: schemas.SecretValue(schemas.Fr).optional(),
92
- senderSalt: schemas.Fr.optional(),
93
- tokenSalt: schemas.Fr,
94
- txIntervalSeconds: z.number(),
95
- privateTransfersPerTx: z.number().int().nonnegative(),
96
- publicTransfersPerTx: z.number().int().nonnegative(),
97
- feePaymentMethod: z.literal('fee_juice'),
98
- baseFeePadding: z.number().int().nonnegative(),
99
- noStart: z.boolean(),
100
- txMinedWaitSeconds: z.number(),
101
- followChain: z.enum(BotFollowChain),
102
- maxPendingTxs: z.number().int().nonnegative(),
103
- flushSetupTransactions: z.boolean(),
104
- l2GasLimit: z.number().int().nonnegative().optional(),
105
- daGasLimit: z.number().int().nonnegative().optional(),
106
- contract: z.nativeEnum(SupportedTokenContracts),
107
- maxConsecutiveErrors: z.number().int().nonnegative(),
108
- stopWhenUnhealthy: z.boolean(),
109
- ammTxs: z.boolean().default(false),
110
- dataDirectory: z.string().optional(),
111
- dataStoreMapSizeKb: z.number().optional(),
112
- })
113
- .transform(config => ({
114
- nodeUrl: undefined,
115
- nodeAdminUrl: undefined,
116
- l1RpcUrls: undefined,
117
- senderSalt: undefined,
118
- l2GasLimit: undefined,
119
- daGasLimit: undefined,
120
- l1Mnemonic: undefined,
121
- l1PrivateKey: undefined,
122
- senderPrivateKey: undefined,
123
- dataDirectory: undefined,
124
- dataStoreMapSizeKb: 1_024 * 1_024,
125
- ...config,
126
- })) satisfies ZodFor<BotConfig>;
83
+ export const BotConfigSchema = zodFor<BotConfig>()(
84
+ z
85
+ .object({
86
+ nodeUrl: z.string().optional(),
87
+ nodeAdminUrl: z.string().optional(),
88
+ l1RpcUrls: z.array(z.string()).optional(),
89
+ l1Mnemonic: schemas.SecretValue(z.string()).optional(),
90
+ l1PrivateKey: schemas.SecretValue(z.string()).optional(),
91
+ l1ToL2MessageTimeoutSeconds: z.number(),
92
+ senderPrivateKey: schemas.SecretValue(schemas.Fr).optional(),
93
+ senderSalt: schemas.Fr.optional(),
94
+ tokenSalt: schemas.Fr,
95
+ txIntervalSeconds: z.number(),
96
+ privateTransfersPerTx: z.number().int().nonnegative(),
97
+ publicTransfersPerTx: z.number().int().nonnegative(),
98
+ feePaymentMethod: z.literal('fee_juice'),
99
+ minFeePadding: z.number().int().nonnegative(),
100
+ noStart: z.boolean(),
101
+ txMinedWaitSeconds: z.number(),
102
+ followChain: z.enum(BotFollowChain),
103
+ maxPendingTxs: z.number().int().nonnegative(),
104
+ flushSetupTransactions: z.boolean(),
105
+ l2GasLimit: z.number().int().nonnegative().optional(),
106
+ daGasLimit: z.number().int().nonnegative().optional(),
107
+ contract: z.nativeEnum(SupportedTokenContracts),
108
+ maxConsecutiveErrors: z.number().int().nonnegative(),
109
+ stopWhenUnhealthy: z.boolean(),
110
+ ammTxs: z.boolean().default(false),
111
+ dataDirectory: z.string().optional(),
112
+ dataStoreMapSizeKb: z.number().optional(),
113
+ })
114
+ .transform(config => ({
115
+ nodeUrl: undefined,
116
+ nodeAdminUrl: undefined,
117
+ l1RpcUrls: undefined,
118
+ senderSalt: undefined,
119
+ l2GasLimit: undefined,
120
+ daGasLimit: undefined,
121
+ l1Mnemonic: undefined,
122
+ l1PrivateKey: undefined,
123
+ senderPrivateKey: undefined,
124
+ dataDirectory: undefined,
125
+ dataStoreMapSizeKb: 1_024 * 1_024,
126
+ ...config,
127
+ })),
128
+ );
127
129
 
128
130
  export const botConfigMappings: ConfigMappingsType<BotConfig> = {
129
131
  nodeUrl: {
@@ -191,8 +193,8 @@ export const botConfigMappings: ConfigMappingsType<BotConfig> = {
191
193
  parseEnv: val => (val as 'fee_juice') || undefined,
192
194
  defaultValue: 'fee_juice',
193
195
  },
194
- baseFeePadding: {
195
- env: 'BOT_BASE_FEE_PADDING',
196
+ minFeePadding: {
197
+ env: 'BOT_MIN_FEE_PADDING',
196
198
  description: 'How much is the bot willing to overpay vs. the current base fee',
197
199
  ...numberConfigHelper(3),
198
200
  },
package/src/factory.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { SchnorrAccountContract } from '@aztec/accounts/schnorr';
2
1
  import { getInitialTestAccountsData } from '@aztec/accounts/testing';
3
2
  import { AztecAddress } from '@aztec/aztec.js/addresses';
4
3
  import {
@@ -7,12 +6,15 @@ import {
7
6
  ContractFunctionInteraction,
8
7
  type DeployMethod,
9
8
  type DeployOptions,
9
+ NO_WAIT,
10
10
  } from '@aztec/aztec.js/contracts';
11
11
  import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
12
12
  import type { L2AmountClaim } from '@aztec/aztec.js/ethereum';
13
13
  import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
14
+ import { deriveKeys } from '@aztec/aztec.js/keys';
14
15
  import { createLogger } from '@aztec/aztec.js/log';
15
16
  import { waitForL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
17
+ import { waitForTx } from '@aztec/aztec.js/node';
16
18
  import { createEthereumChain } from '@aztec/ethereum/chain';
17
19
  import { createExtendedL1Client } from '@aztec/ethereum/client';
18
20
  import { Fr } from '@aztec/foundation/curves/bn254';
@@ -20,10 +22,11 @@ import { Timer } from '@aztec/foundation/timer';
20
22
  import { AMMContract } from '@aztec/noir-contracts.js/AMM';
21
23
  import { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
22
24
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
25
+ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
23
26
  import { GasSettings } from '@aztec/stdlib/gas';
24
27
  import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
25
28
  import { deriveSigningKey } from '@aztec/stdlib/keys';
26
- import { TestWallet } from '@aztec/test-wallet/server';
29
+ import { EmbeddedWallet } from '@aztec/wallets/embedded';
27
30
 
28
31
  import { type BotConfig, SupportedTokenContracts } from './config.js';
29
32
  import type { BotStore } from './store/index.js';
@@ -37,7 +40,7 @@ export class BotFactory {
37
40
 
38
41
  constructor(
39
42
  private readonly config: BotConfig,
40
- private readonly wallet: TestWallet,
43
+ private readonly wallet: EmbeddedWallet,
41
44
  private readonly store: BotStore,
42
45
  private readonly aztecNode: AztecNode,
43
46
  private readonly aztecNodeAdmin?: AztecNodeAdmin,
@@ -48,21 +51,21 @@ export class BotFactory {
48
51
  * deploying the token contract, and minting tokens if necessary.
49
52
  */
50
53
  public async setup(): Promise<{
51
- wallet: TestWallet;
54
+ wallet: EmbeddedWallet;
52
55
  defaultAccountAddress: AztecAddress;
53
56
  token: TokenContract | PrivateTokenContract;
54
57
  node: AztecNode;
55
58
  recipient: AztecAddress;
56
59
  }> {
57
60
  const defaultAccountAddress = await this.setupAccount();
58
- const recipient = (await this.wallet.createAccount()).address;
61
+ const recipient = (await this.wallet.createSchnorrAccount(Fr.random(), Fr.random())).address;
59
62
  const token = await this.setupToken(defaultAccountAddress);
60
63
  await this.mintTokens(token, defaultAccountAddress);
61
64
  return { wallet: this.wallet, defaultAccountAddress, token, node: this.aztecNode, recipient };
62
65
  }
63
66
 
64
67
  public async setupAmm(): Promise<{
65
- wallet: TestWallet;
68
+ wallet: EmbeddedWallet;
66
69
  defaultAccountAddress: AztecAddress;
67
70
  amm: AMMContract;
68
71
  token0: TokenContract;
@@ -110,14 +113,9 @@ export class BotFactory {
110
113
  private async setupAccountWithPrivateKey(secret: Fr) {
111
114
  const salt = this.config.senderSalt ?? Fr.ONE;
112
115
  const signingKey = deriveSigningKey(secret);
113
- const accountData = {
114
- secret,
115
- salt,
116
- contract: new SchnorrAccountContract(signingKey!),
117
- };
118
- const accountManager = await this.wallet.createAccount(accountData);
119
- const isInit = (await this.wallet.getContractMetadata(accountManager.address)).isContractInitialized;
120
- if (isInit) {
116
+ const accountManager = await this.wallet.createSchnorrAccount(secret, salt, signingKey);
117
+ const metadata = await this.wallet.getContractMetadata(accountManager.address);
118
+ if (metadata.isContractInitialized) {
121
119
  this.log.info(`Account at ${accountManager.address.toString()} already initialized`);
122
120
  const timer = new Timer();
123
121
  const address = accountManager.address;
@@ -132,12 +130,18 @@ export class BotFactory {
132
130
 
133
131
  const paymentMethod = new FeeJuicePaymentMethodWithClaim(accountManager.address, claim);
134
132
  const deployMethod = await accountManager.getDeployMethod();
135
- const maxFeesPerGas = (await this.aztecNode.getCurrentBaseFees()).mul(1 + this.config.baseFeePadding);
133
+ const maxFeesPerGas = (await this.aztecNode.getCurrentMinFees()).mul(1 + this.config.minFeePadding);
136
134
  const gasSettings = GasSettings.default({ maxFeesPerGas });
137
- const sentTx = deployMethod.send({ from: AztecAddress.ZERO, fee: { gasSettings, paymentMethod } });
138
- const txHash = await sentTx.getTxHash();
139
- this.log.info(`Sent tx for account deployment with hash ${txHash.toString()}`);
140
- await this.withNoMinTxsPerBlock(() => sentTx.wait({ timeout: this.config.txMinedWaitSeconds }));
135
+
136
+ await this.withNoMinTxsPerBlock(async () => {
137
+ const txHash = await deployMethod.send({
138
+ from: AztecAddress.ZERO,
139
+ fee: { gasSettings, paymentMethod },
140
+ wait: NO_WAIT,
141
+ });
142
+ this.log.info(`Sent tx for account deployment with hash ${txHash.toString()}`);
143
+ return waitForTx(this.aztecNode, txHash, { timeout: this.config.txMinedWaitSeconds });
144
+ });
141
145
  this.log.info(`Account deployed at ${address}`);
142
146
 
143
147
  // Clean up the consumed bridge claim
@@ -149,12 +153,11 @@ export class BotFactory {
149
153
 
150
154
  private async setupTestAccount() {
151
155
  const [initialAccountData] = await getInitialTestAccountsData();
152
- const accountData = {
153
- secret: initialAccountData.secret,
154
- salt: initialAccountData.salt,
155
- contract: new SchnorrAccountContract(initialAccountData.signingKey),
156
- };
157
- const accountManager = await this.wallet.createAccount(accountData);
156
+ const accountManager = await this.wallet.createSchnorrAccount(
157
+ initialAccountData.secret,
158
+ initialAccountData.salt,
159
+ initialAccountData.signingKey,
160
+ );
158
161
  return accountManager.address;
159
162
  }
160
163
 
@@ -165,33 +168,49 @@ export class BotFactory {
165
168
  */
166
169
  private async setupToken(sender: AztecAddress): Promise<TokenContract | PrivateTokenContract> {
167
170
  let deploy: DeployMethod<TokenContract | PrivateTokenContract>;
171
+ let tokenInstance: ContractInstanceWithAddress | undefined;
168
172
  const deployOpts: DeployOptions = {
169
173
  from: sender,
170
174
  contractAddressSalt: this.config.tokenSalt,
171
175
  universalDeploy: true,
172
176
  };
177
+ let token: TokenContract | PrivateTokenContract;
173
178
  if (this.config.contract === SupportedTokenContracts.TokenContract) {
174
179
  deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18);
180
+ tokenInstance = await deploy.getInstance(deployOpts);
181
+ token = TokenContract.at(tokenInstance.address, this.wallet);
175
182
  } else if (this.config.contract === SupportedTokenContracts.PrivateTokenContract) {
176
- deploy = PrivateTokenContract.deploy(this.wallet, MINT_BALANCE, sender);
183
+ // Generate keys for the contract since PrivateToken uses SinglePrivateMutable which requires keys
184
+ const tokenSecretKey = Fr.random();
185
+ const tokenPublicKeys = (await deriveKeys(tokenSecretKey)).publicKeys;
186
+ deploy = PrivateTokenContract.deployWithPublicKeys(tokenPublicKeys, this.wallet, MINT_BALANCE, sender);
177
187
  deployOpts.skipInstancePublication = true;
178
188
  deployOpts.skipClassPublication = true;
179
189
  deployOpts.skipInitialization = false;
190
+
191
+ // Register the contract with the secret key before deployment
192
+ tokenInstance = await deploy.getInstance(deployOpts);
193
+ token = PrivateTokenContract.at(tokenInstance.address, this.wallet);
194
+ await this.wallet.registerContract(tokenInstance, PrivateTokenContract.artifact, tokenSecretKey);
180
195
  } else {
181
196
  throw new Error(`Unsupported token contract type: ${this.config.contract}`);
182
197
  }
183
198
 
184
- const address = (await deploy.getInstance(deployOpts)).address;
185
- if ((await this.wallet.getContractMetadata(address)).isContractPublished) {
199
+ const address = tokenInstance?.address ?? (await deploy.getInstance(deployOpts)).address;
200
+ const metadata = await this.wallet.getContractMetadata(address);
201
+ if (metadata.isContractPublished) {
186
202
  this.log.info(`Token at ${address.toString()} already deployed`);
187
- return deploy.register();
203
+ await deploy.register();
188
204
  } else {
189
205
  this.log.info(`Deploying token contract at ${address.toString()}`);
190
- const sentTx = deploy.send(deployOpts);
191
- const txHash = await sentTx.getTxHash();
206
+ const txHash = await deploy.send({ ...deployOpts, wait: NO_WAIT });
192
207
  this.log.info(`Sent tx for token setup with hash ${txHash.toString()}`);
193
- return this.withNoMinTxsPerBlock(() => sentTx.deployed({ timeout: this.config.txMinedWaitSeconds }));
208
+ await this.withNoMinTxsPerBlock(async () => {
209
+ await waitForTx(this.aztecNode, txHash, { timeout: this.config.txMinedWaitSeconds });
210
+ return token;
211
+ });
194
212
  }
213
+ return token;
195
214
  }
196
215
 
197
216
  /**
@@ -199,7 +218,7 @@ export class BotFactory {
199
218
  * @param wallet - Wallet to deploy the token contract from.
200
219
  * @returns The TokenContract instance.
201
220
  */
202
- private setupTokenContract(
221
+ private async setupTokenContract(
203
222
  deployer: AztecAddress,
204
223
  contractAddressSalt: Fr,
205
224
  name: string,
@@ -208,7 +227,8 @@ export class BotFactory {
208
227
  ): Promise<TokenContract> {
209
228
  const deployOpts: DeployOptions = { from: deployer, contractAddressSalt, universalDeploy: true };
210
229
  const deploy = TokenContract.deploy(this.wallet, deployer, name, ticker, decimals);
211
- return this.registerOrDeployContract('Token - ' + name, deploy, deployOpts);
230
+ const instance = await this.registerOrDeployContract('Token - ' + name, deploy, deployOpts);
231
+ return TokenContract.at(instance.address, this.wallet);
212
232
  }
213
233
 
214
234
  private async setupAmmContract(
@@ -220,12 +240,14 @@ export class BotFactory {
220
240
  ): Promise<AMMContract> {
221
241
  const deployOpts: DeployOptions = { from: deployer, contractAddressSalt, universalDeploy: true };
222
242
  const deploy = AMMContract.deploy(this.wallet, token0.address, token1.address, lpToken.address);
223
- const amm = await this.registerOrDeployContract('AMM', deploy, deployOpts);
243
+ const instance = await this.registerOrDeployContract('AMM', deploy, deployOpts);
244
+ const amm = AMMContract.at(instance.address, this.wallet);
224
245
 
225
246
  this.log.info(`AMM deployed at ${amm.address}`);
226
- const minterTx = lpToken.methods.set_minter(amm.address, true).send({ from: deployer });
227
- this.log.info(`Set LP token minter to AMM txHash=${(await minterTx.getTxHash()).toString()}`);
228
- await minterTx.wait({ timeout: this.config.txMinedWaitSeconds });
247
+ const minterReceipt = await lpToken.methods
248
+ .set_minter(amm.address, true)
249
+ .send({ from: deployer, wait: { timeout: this.config.txMinedWaitSeconds } });
250
+ this.log.info(`Set LP token minter to AMM txHash=${minterReceipt.txHash.toString()}`);
229
251
  this.log.info(`Liquidity token initialized`);
230
252
 
231
253
  return amm;
@@ -284,23 +306,22 @@ export class BotFactory {
284
306
  .getFunctionCall(),
285
307
  });
286
308
 
287
- const mintTx = new BatchCall(this.wallet, [
309
+ const mintReceipt = await new BatchCall(this.wallet, [
288
310
  token0.methods.mint_to_private(liquidityProvider, MINT_BALANCE),
289
311
  token1.methods.mint_to_private(liquidityProvider, MINT_BALANCE),
290
- ]).send({ from: liquidityProvider });
312
+ ]).send({ from: liquidityProvider, wait: { timeout: this.config.txMinedWaitSeconds } });
291
313
 
292
- this.log.info(`Sent mint tx: ${(await mintTx.getTxHash()).toString()}`);
293
- await mintTx.wait({ timeout: this.config.txMinedWaitSeconds });
314
+ this.log.info(`Sent mint tx: ${mintReceipt.txHash.toString()}`);
294
315
 
295
- const addLiquidityTx = amm.methods
316
+ const addLiquidityReceipt = await amm.methods
296
317
  .add_liquidity(amount0Max, amount1Max, amount0Min, amount1Min, authwitNonce)
297
318
  .send({
298
319
  from: liquidityProvider,
299
320
  authWitnesses: [token0Authwit, token1Authwit],
321
+ wait: { timeout: this.config.txMinedWaitSeconds },
300
322
  });
301
323
 
302
- this.log.info(`Sent tx to add liquidity to the AMM: ${(await addLiquidityTx.getTxHash()).toString()}`);
303
- await addLiquidityTx.wait({ timeout: this.config.txMinedWaitSeconds });
324
+ this.log.info(`Sent tx to add liquidity to the AMM: ${addLiquidityReceipt.txHash.toString()}`);
304
325
  this.log.info(`Liquidity added`);
305
326
 
306
327
  const [newT0Bal, newT1Bal, newLPBal] = await getPrivateBalances();
@@ -313,18 +334,22 @@ export class BotFactory {
313
334
  name: string,
314
335
  deploy: DeployMethod<T>,
315
336
  deployOpts: DeployOptions,
316
- ): Promise<T> {
317
- const address = (await deploy.getInstance(deployOpts)).address;
318
- if ((await this.wallet.getContractMetadata(address)).isContractPublished) {
337
+ ): Promise<ContractInstanceWithAddress> {
338
+ const instance = await deploy.getInstance(deployOpts);
339
+ const address = instance.address;
340
+ const metadata = await this.wallet.getContractMetadata(address);
341
+ if (metadata.isContractPublished) {
319
342
  this.log.info(`Contract ${name} at ${address.toString()} already deployed`);
320
- return deploy.register();
343
+ await deploy.register();
321
344
  } else {
322
345
  this.log.info(`Deploying contract ${name} at ${address.toString()}`);
323
- const sentTx = deploy.send(deployOpts);
324
- const txHash = await sentTx.getTxHash();
325
- this.log.info(`Sent contract ${name} setup tx with hash ${txHash.toString()}`);
326
- return this.withNoMinTxsPerBlock(() => sentTx.deployed({ timeout: this.config.txMinedWaitSeconds }));
346
+ await this.withNoMinTxsPerBlock(async () => {
347
+ const txHash = await deploy.send({ ...deployOpts, wait: NO_WAIT });
348
+ this.log.info(`Sent contract ${name} setup tx with hash ${txHash.toString()}`);
349
+ return waitForTx(this.aztecNode, txHash, { timeout: this.config.txMinedWaitSeconds });
350
+ });
327
351
  }
352
+ return instance;
328
353
  }
329
354
 
330
355
  /**
@@ -360,10 +385,12 @@ export class BotFactory {
360
385
  this.log.info(`Skipping minting as ${minter.toString()} has enough tokens`);
361
386
  return;
362
387
  }
363
- const sentTx = new BatchCall(token.wallet, calls).send({ from: minter });
364
- const txHash = await sentTx.getTxHash();
365
- this.log.info(`Sent token mint tx with hash ${txHash.toString()}`);
366
- await this.withNoMinTxsPerBlock(() => sentTx.wait({ timeout: this.config.txMinedWaitSeconds }));
388
+
389
+ await this.withNoMinTxsPerBlock(async () => {
390
+ const txHash = await new BatchCall(token.wallet, calls).send({ from: minter, wait: NO_WAIT });
391
+ this.log.info(`Sent token mint tx with hash ${txHash.toString()}`);
392
+ return waitForTx(this.aztecNode, txHash, { timeout: this.config.txMinedWaitSeconds });
393
+ });
367
394
  }
368
395
 
369
396
  /**
package/src/runner.ts CHANGED
@@ -4,7 +4,7 @@ import { omit } from '@aztec/foundation/collection';
4
4
  import { RunningPromise } from '@aztec/foundation/running-promise';
5
5
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
6
6
  import { type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
7
- import type { TestWallet } from '@aztec/test-wallet/server';
7
+ import type { EmbeddedWallet } from '@aztec/wallets/embedded';
8
8
 
9
9
  import { AmmBot } from './amm_bot.js';
10
10
  import type { BaseBot } from './base_bot.js';
@@ -24,7 +24,7 @@ export class BotRunner implements BotRunnerApi, Traceable {
24
24
 
25
25
  public constructor(
26
26
  private config: BotConfig,
27
- private readonly wallet: TestWallet,
27
+ private readonly wallet: EmbeddedWallet,
28
28
  private readonly aztecNode: AztecNode,
29
29
  private readonly telemetry: TelemetryClient,
30
30
  private readonly aztecNodeAdmin: AztecNodeAdmin | undefined,