@aztec/bot 2.1.0-rc.9 → 3.0.0-devnet.2

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 (45) hide show
  1. package/dest/amm_bot.d.ts +8 -8
  2. package/dest/amm_bot.d.ts.map +1 -1
  3. package/dest/amm_bot.js +23 -20
  4. package/dest/base_bot.d.ts +10 -7
  5. package/dest/base_bot.d.ts.map +1 -1
  6. package/dest/base_bot.js +18 -18
  7. package/dest/bot.d.ts +7 -8
  8. package/dest/bot.d.ts.map +1 -1
  9. package/dest/bot.js +11 -12
  10. package/dest/config.d.ts +19 -15
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +22 -20
  13. package/dest/factory.d.ts +18 -17
  14. package/dest/factory.d.ts.map +1 -1
  15. package/dest/factory.js +122 -102
  16. package/dest/index.d.ts +1 -0
  17. package/dest/index.d.ts.map +1 -1
  18. package/dest/index.js +1 -0
  19. package/dest/interface.d.ts +1 -1
  20. package/dest/interface.d.ts.map +1 -1
  21. package/dest/interface.js +1 -1
  22. package/dest/runner.d.ts +11 -12
  23. package/dest/runner.d.ts.map +1 -1
  24. package/dest/runner.js +18 -32
  25. package/dest/store/bot_store.d.ts +44 -0
  26. package/dest/store/bot_store.d.ts.map +1 -0
  27. package/dest/store/bot_store.js +107 -0
  28. package/dest/store/index.d.ts +2 -0
  29. package/dest/store/index.d.ts.map +1 -0
  30. package/dest/store/index.js +1 -0
  31. package/dest/utils.d.ts +3 -3
  32. package/dest/utils.d.ts.map +1 -1
  33. package/dest/utils.js +5 -5
  34. package/package.json +13 -11
  35. package/src/amm_bot.ts +39 -31
  36. package/src/base_bot.ts +24 -22
  37. package/src/bot.ts +25 -14
  38. package/src/config.ts +20 -22
  39. package/src/factory.ts +138 -140
  40. package/src/index.ts +1 -0
  41. package/src/interface.ts +1 -1
  42. package/src/runner.ts +19 -23
  43. package/src/store/bot_store.ts +141 -0
  44. package/src/store/index.ts +1 -0
  45. package/src/utils.ts +10 -5
package/dest/factory.d.ts CHANGED
@@ -1,38 +1,37 @@
1
- import { AztecAddress, type PXE } from '@aztec/aztec.js';
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
2
  import { AMMContract } from '@aztec/noir-contracts.js/AMM';
3
3
  import { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
4
4
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
5
5
  import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
6
+ import { TestWallet } from '@aztec/test-wallet/server';
6
7
  import { type BotConfig } from './config.js';
8
+ import type { BotStore } from './store/index.js';
7
9
  export declare class BotFactory {
8
10
  private readonly config;
9
- private pxe;
10
- private node?;
11
- private nodeAdmin?;
11
+ private readonly wallet;
12
+ private readonly store;
13
+ private readonly aztecNode;
14
+ private readonly aztecNodeAdmin?;
12
15
  private log;
13
- constructor(config: BotConfig, dependencies: {
14
- pxe?: PXE;
15
- nodeAdmin?: AztecNodeAdmin;
16
- node?: AztecNode;
17
- });
16
+ constructor(config: BotConfig, wallet: TestWallet, store: BotStore, aztecNode: AztecNode, aztecNodeAdmin?: AztecNodeAdmin | undefined);
18
17
  /**
19
18
  * Initializes a new bot by setting up the sender account, registering the recipient,
20
19
  * deploying the token contract, and minting tokens if necessary.
21
20
  */
22
21
  setup(): Promise<{
23
- wallet: import("@aztec/aztec.js").AccountWalletWithSecretKey;
22
+ wallet: TestWallet;
24
23
  defaultAccountAddress: AztecAddress;
25
24
  token: TokenContract | PrivateTokenContract;
26
- pxe: PXE;
25
+ node: AztecNode;
27
26
  recipient: AztecAddress;
28
27
  }>;
29
28
  setupAmm(): Promise<{
30
- wallet: import("@aztec/aztec.js").AccountWalletWithSecretKey;
29
+ wallet: TestWallet;
31
30
  defaultAccountAddress: AztecAddress;
32
31
  amm: AMMContract;
33
32
  token0: TokenContract;
34
33
  token1: TokenContract;
35
- pxe: PXE;
34
+ node: AztecNode;
36
35
  }>;
37
36
  /**
38
37
  * Checks if the sender account contract is initialized, and initializes it if necessary.
@@ -41,10 +40,6 @@ export declare class BotFactory {
41
40
  private setupAccount;
42
41
  private setupAccountWithPrivateKey;
43
42
  private setupTestAccount;
44
- /**
45
- * Registers the recipient for txs in the pxe.
46
- */
47
- private registerRecipient;
48
43
  /**
49
44
  * Checks if the token contract is deployed and deploys it if necessary.
50
45
  * @param wallet - Wallet to deploy the token contract from.
@@ -65,6 +60,12 @@ export declare class BotFactory {
65
60
  * @param token - Token contract.
66
61
  */
67
62
  private mintTokens;
63
+ /**
64
+ * Gets or creates a bridge claim for the recipient.
65
+ * Checks if a claim already exists in the store and reuses it if valid.
66
+ * Only creates a new bridge if fee juice balance is below threshold.
67
+ */
68
+ private getOrCreateBridgeClaim;
68
69
  private bridgeL1FeeJuice;
69
70
  private withNoMinTxsPerBlock;
70
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,YAAY,EAQZ,KAAK,GAAG,EAIT,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAIjF,OAAO,EAAE,KAAK,SAAS,EAAwC,MAAM,aAAa,CAAC;AAMnF,qBAAa,UAAU;IAOnB,OAAO,CAAC,QAAQ,CAAC,MAAM;IANzB,OAAO,CAAC,GAAG,CAAM;IACjB,OAAO,CAAC,IAAI,CAAC,CAAY;IACzB,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,GAAG,CAAuB;gBAGf,MAAM,EAAE,SAAS,EAClC,YAAY,EAAE;QAAE,GAAG,CAAC,EAAE,GAAG,CAAC;QAAC,SAAS,CAAC,EAAE,cAAc,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAA;KAAE;IA4B3E;;;OAGG;IACU,KAAK;;;;;;;IASL,QAAQ;;;;;;;;IAuCrB;;;OAGG;YACW,YAAY;YASZ,0BAA0B;YA8B1B,gBAAgB;IAc9B;;OAEG;YACW,iBAAiB;IAK/B;;;;OAIG;YACW,UAAU;IA+BxB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;YAaZ,gBAAgB;YAqBhB,OAAO;YA0EP,wBAAwB;IAkBtC;;;OAGG;YACW,UAAU;YAmCV,gBAAgB;YAgChB,oBAAoB;CAYnC"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAgBzD,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAC7E,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAEjF,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEvD,OAAO,EAAE,KAAK,SAAS,EAA2B,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAMjD,qBAAa,UAAU;IAInB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAPlC,OAAO,CAAC,GAAG,CAAuB;gBAGf,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,SAAS,EACpB,cAAc,CAAC,EAAE,cAAc,YAAA;IAGlD;;;OAGG;IACU,KAAK;;;;;;;IAQL,QAAQ;;;;;;;;IAwBrB;;;OAGG;YACW,YAAY;YAWZ,0BAA0B;YAwC1B,gBAAgB;IAW9B;;;;OAIG;YACW,UAAU;IA+BxB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;YAYZ,gBAAgB;YAoBhB,OAAO;YA8EP,wBAAwB;IAkBtC;;;OAGG;YACW,UAAU;IAmCxB;;;;OAIG;YACW,sBAAsB;YA4BtB,gBAAgB;YAgChB,oBAAoB;CAenC"}
package/dest/factory.js CHANGED
@@ -1,83 +1,69 @@
1
- import { getSchnorrAccount } from '@aztec/accounts/schnorr';
2
- import { getDeployedTestAccountsWallets, getInitialTestAccounts } from '@aztec/accounts/testing';
3
- import { BatchCall, FeeJuicePaymentMethodWithClaim, L1FeeJuicePortalManager, createLogger, createPXEClient, waitForL1ToL2MessageReady } from '@aztec/aztec.js';
1
+ import { SchnorrAccountContract } from '@aztec/accounts/schnorr';
2
+ import { getInitialTestAccountsData } from '@aztec/accounts/testing';
3
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
4
+ import { BatchCall } from '@aztec/aztec.js/contracts';
5
+ import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
6
+ import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
7
+ import { createLogger } from '@aztec/aztec.js/log';
8
+ import { waitForL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
4
9
  import { createEthereumChain, createExtendedL1Client } from '@aztec/ethereum';
5
10
  import { Fr } from '@aztec/foundation/fields';
6
11
  import { Timer } from '@aztec/foundation/timer';
7
12
  import { AMMContract } from '@aztec/noir-contracts.js/AMM';
8
13
  import { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
9
14
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
15
+ import { GasSettings } from '@aztec/stdlib/gas';
10
16
  import { deriveSigningKey } from '@aztec/stdlib/keys';
11
- import { makeTracedFetch } from '@aztec/telemetry-client';
12
- import { SupportedTokenContracts, getVersions } from './config.js';
17
+ import { SupportedTokenContracts } from './config.js';
13
18
  import { getBalances, getPrivateBalance, isStandardTokenContract } from './utils.js';
14
19
  const MINT_BALANCE = 1e12;
15
20
  const MIN_BALANCE = 1e3;
16
21
  export class BotFactory {
17
22
  config;
18
- pxe;
19
- node;
20
- nodeAdmin;
23
+ wallet;
24
+ store;
25
+ aztecNode;
26
+ aztecNodeAdmin;
21
27
  log;
22
- constructor(config, dependencies){
28
+ constructor(config, wallet, store, aztecNode, aztecNodeAdmin){
23
29
  this.config = config;
30
+ this.wallet = wallet;
31
+ this.store = store;
32
+ this.aztecNode = aztecNode;
33
+ this.aztecNodeAdmin = aztecNodeAdmin;
24
34
  this.log = createLogger('bot');
25
- if (config.flushSetupTransactions && !dependencies.nodeAdmin) {
26
- throw new Error(`Either a node admin client or node admin url must be provided if transaction flushing is requested`);
27
- }
28
- if (config.senderPrivateKey && config.senderPrivateKey.getValue() && !dependencies.node) {
29
- throw new Error(`Either a node client or node url must be provided for bridging L1 fee juice to deploy an account with private key`);
30
- }
31
- if (!dependencies.pxe && !config.pxeUrl) {
32
- throw new Error(`Either a PXE client or a PXE URL must be provided`);
33
- }
34
- this.node = dependencies.node;
35
- this.nodeAdmin = dependencies.nodeAdmin;
36
- if (dependencies.pxe) {
37
- this.log.info(`Using local PXE`);
38
- this.pxe = dependencies.pxe;
39
- return;
40
- }
41
- this.log.info(`Using remote PXE at ${config.pxeUrl}`);
42
- this.pxe = createPXEClient(config.pxeUrl, getVersions(), makeTracedFetch([
43
- 1,
44
- 2,
45
- 3
46
- ], false));
47
35
  }
48
36
  /**
49
37
  * Initializes a new bot by setting up the sender account, registering the recipient,
50
38
  * deploying the token contract, and minting tokens if necessary.
51
39
  */ async setup() {
52
- const recipient = await this.registerRecipient();
53
- const wallet = await this.setupAccount();
54
- const defaultAccountAddress = wallet.getAddress();
55
- const token = await this.setupToken(wallet, defaultAccountAddress);
40
+ const recipient = (await this.wallet.createAccount()).address;
41
+ const defaultAccountAddress = await this.setupAccount();
42
+ const token = await this.setupToken(defaultAccountAddress);
56
43
  await this.mintTokens(token, defaultAccountAddress);
57
44
  return {
58
- wallet,
45
+ wallet: this.wallet,
59
46
  defaultAccountAddress,
60
47
  token,
61
- pxe: this.pxe,
48
+ node: this.aztecNode,
62
49
  recipient
63
50
  };
64
51
  }
65
52
  async setupAmm() {
66
- const wallet = await this.setupAccount();
67
- const defaultAccountAddress = wallet.getAddress();
68
- const token0 = await this.setupTokenContract(wallet, wallet.getAddress(), this.config.tokenSalt, 'BotToken0', 'BOT0');
69
- const token1 = await this.setupTokenContract(wallet, wallet.getAddress(), this.config.tokenSalt, 'BotToken1', 'BOT1');
70
- const liquidityToken = await this.setupTokenContract(wallet, wallet.getAddress(), this.config.tokenSalt, 'BotLPToken', 'BOTLP');
71
- const amm = await this.setupAmmContract(wallet, wallet.getAddress(), this.config.tokenSalt, token0, token1, liquidityToken);
72
- await this.fundAmm(wallet, wallet.getAddress(), amm, token0, token1, liquidityToken);
53
+ const defaultAccountAddress = await this.setupAccount();
54
+ const token0 = await this.setupTokenContract(defaultAccountAddress, this.config.tokenSalt, 'BotToken0', 'BOT0');
55
+ const token1 = await this.setupTokenContract(defaultAccountAddress, this.config.tokenSalt, 'BotToken1', 'BOT1');
56
+ const liquidityToken = await this.setupTokenContract(defaultAccountAddress, this.config.tokenSalt, 'BotLPToken', 'BOTLP');
57
+ const amm = await this.setupAmmContract(defaultAccountAddress, this.config.tokenSalt, token0, token1, liquidityToken);
58
+ await this.fundAmm(defaultAccountAddress, defaultAccountAddress, amm, token0, token1, liquidityToken);
73
59
  this.log.info(`AMM initialized and funded`);
74
60
  return {
75
- wallet,
61
+ wallet: this.wallet,
76
62
  defaultAccountAddress,
77
63
  amm,
78
64
  token0,
79
65
  token1,
80
- pxe: this.pxe
66
+ node: this.aztecNode
81
67
  };
82
68
  }
83
69
  /**
@@ -86,68 +72,73 @@ export class BotFactory {
86
72
  */ async setupAccount() {
87
73
  const privateKey = this.config.senderPrivateKey?.getValue();
88
74
  if (privateKey) {
75
+ this.log.info(`Setting up account with provided private key`);
89
76
  return await this.setupAccountWithPrivateKey(privateKey);
90
77
  } else {
78
+ this.log.info(`Setting up test account`);
91
79
  return await this.setupTestAccount();
92
80
  }
93
81
  }
94
- async setupAccountWithPrivateKey(privateKey) {
82
+ async setupAccountWithPrivateKey(secret) {
95
83
  const salt = this.config.senderSalt ?? Fr.ONE;
96
- const signingKey = deriveSigningKey(privateKey);
97
- const account = await getSchnorrAccount(this.pxe, privateKey, signingKey, salt);
98
- const isInit = (await this.pxe.getContractMetadata(account.getAddress())).isContractInitialized;
84
+ const signingKey = deriveSigningKey(secret);
85
+ const accountData = {
86
+ secret,
87
+ salt,
88
+ contract: new SchnorrAccountContract(signingKey)
89
+ };
90
+ const accountManager = await this.wallet.createAccount(accountData);
91
+ const isInit = (await this.wallet.getContractMetadata(accountManager.address)).isContractInitialized;
99
92
  if (isInit) {
100
- this.log.info(`Account at ${account.getAddress().toString()} already initialized`);
93
+ this.log.info(`Account at ${accountManager.address.toString()} already initialized`);
101
94
  const timer = new Timer();
102
- const wallet = await account.register();
103
- this.log.info(`Account at ${account.getAddress()} registered. duration=${timer.ms()}`);
104
- return wallet;
95
+ const address = accountManager.address;
96
+ this.log.info(`Account at ${address} registered. duration=${timer.ms()}`);
97
+ await this.store.deleteBridgeClaim(address);
98
+ return address;
105
99
  } else {
106
- const address = account.getAddress();
100
+ const address = accountManager.address;
107
101
  this.log.info(`Deploying account at ${address}`);
108
- const claim = await this.bridgeL1FeeJuice(address);
109
- // docs:start:claim_and_deploy
110
- const wallet = await account.getWallet();
111
- const paymentMethod = new FeeJuicePaymentMethodWithClaim(wallet, claim);
112
- const sentTx = account.deploy({
102
+ const claim = await this.getOrCreateBridgeClaim(address);
103
+ const paymentMethod = new FeeJuicePaymentMethodWithClaim(accountManager.address, claim);
104
+ const deployMethod = await accountManager.getDeployMethod();
105
+ const maxFeesPerGas = (await this.aztecNode.getCurrentBaseFees()).mul(1 + this.config.baseFeePadding);
106
+ const gasSettings = GasSettings.default({
107
+ maxFeesPerGas
108
+ });
109
+ const sentTx = deployMethod.send({
110
+ from: AztecAddress.ZERO,
113
111
  fee: {
112
+ gasSettings,
114
113
  paymentMethod
115
114
  }
116
115
  });
117
116
  const txHash = await sentTx.getTxHash();
118
- // docs:end:claim_and_deploy
119
117
  this.log.info(`Sent tx for account deployment with hash ${txHash.toString()}`);
120
118
  await this.withNoMinTxsPerBlock(()=>sentTx.wait({
121
119
  timeout: this.config.txMinedWaitSeconds
122
120
  }));
123
121
  this.log.info(`Account deployed at ${address}`);
124
- return wallet;
122
+ // Clean up the consumed bridge claim
123
+ await this.store.deleteBridgeClaim(address);
124
+ return accountManager.address;
125
125
  }
126
126
  }
127
127
  async setupTestAccount() {
128
- let [wallet] = await getDeployedTestAccountsWallets(this.pxe);
129
- if (wallet) {
130
- this.log.info(`Using funded test account: ${wallet.getAddress()}`);
131
- } else {
132
- this.log.info('Registering funded test account');
133
- const [account] = await getInitialTestAccounts();
134
- const manager = await getSchnorrAccount(this.pxe, account.secret, account.signingKey, account.salt);
135
- wallet = await manager.register();
136
- this.log.info(`Funded test account registered: ${wallet.getAddress()}`);
137
- }
138
- return wallet;
139
- }
140
- /**
141
- * Registers the recipient for txs in the pxe.
142
- */ async registerRecipient() {
143
- const recipient = await this.pxe.registerAccount(this.config.recipientEncryptionSecret.getValue(), Fr.ONE);
144
- return recipient.address;
128
+ const [initialAccountData] = await getInitialTestAccountsData();
129
+ const accountData = {
130
+ secret: initialAccountData.secret,
131
+ salt: initialAccountData.salt,
132
+ contract: new SchnorrAccountContract(initialAccountData.signingKey)
133
+ };
134
+ const accountManager = await this.wallet.createAccount(accountData);
135
+ return accountManager.address;
145
136
  }
146
137
  /**
147
138
  * Checks if the token contract is deployed and deploys it if necessary.
148
139
  * @param wallet - Wallet to deploy the token contract from.
149
140
  * @returns The TokenContract instance.
150
- */ async setupToken(wallet, sender) {
141
+ */ async setupToken(sender) {
151
142
  let deploy;
152
143
  const deployOpts = {
153
144
  from: sender,
@@ -155,9 +146,9 @@ export class BotFactory {
155
146
  universalDeploy: true
156
147
  };
157
148
  if (this.config.contract === SupportedTokenContracts.TokenContract) {
158
- deploy = TokenContract.deploy(wallet, sender, 'BotToken', 'BOT', 18);
149
+ deploy = TokenContract.deploy(this.wallet, sender, 'BotToken', 'BOT', 18);
159
150
  } else if (this.config.contract === SupportedTokenContracts.PrivateTokenContract) {
160
- deploy = PrivateTokenContract.deploy(wallet, MINT_BALANCE, sender);
151
+ deploy = PrivateTokenContract.deploy(this.wallet, MINT_BALANCE, sender);
161
152
  deployOpts.skipInstancePublication = true;
162
153
  deployOpts.skipClassPublication = true;
163
154
  deployOpts.skipInitialization = false;
@@ -165,7 +156,7 @@ export class BotFactory {
165
156
  throw new Error(`Unsupported token contract type: ${this.config.contract}`);
166
157
  }
167
158
  const address = (await deploy.getInstance(deployOpts)).address;
168
- if ((await this.pxe.getContractMetadata(address)).isContractPublished) {
159
+ if ((await this.wallet.getContractMetadata(address)).isContractPublished) {
169
160
  this.log.info(`Token at ${address.toString()} already deployed`);
170
161
  return deploy.register();
171
162
  } else {
@@ -182,22 +173,22 @@ export class BotFactory {
182
173
  * Checks if the token contract is deployed and deploys it if necessary.
183
174
  * @param wallet - Wallet to deploy the token contract from.
184
175
  * @returns The TokenContract instance.
185
- */ setupTokenContract(wallet, deployer, contractAddressSalt, name, ticker, decimals = 18) {
176
+ */ setupTokenContract(deployer, contractAddressSalt, name, ticker, decimals = 18) {
186
177
  const deployOpts = {
187
178
  from: deployer,
188
179
  contractAddressSalt,
189
180
  universalDeploy: true
190
181
  };
191
- const deploy = TokenContract.deploy(wallet, deployer, name, ticker, decimals);
182
+ const deploy = TokenContract.deploy(this.wallet, deployer, name, ticker, decimals);
192
183
  return this.registerOrDeployContract('Token - ' + name, deploy, deployOpts);
193
184
  }
194
- async setupAmmContract(wallet, deployer, contractAddressSalt, token0, token1, lpToken) {
185
+ async setupAmmContract(deployer, contractAddressSalt, token0, token1, lpToken) {
195
186
  const deployOpts = {
196
187
  from: deployer,
197
188
  contractAddressSalt,
198
189
  universalDeploy: true
199
190
  };
200
- const deploy = AMMContract.deploy(wallet, token0.address, token1.address, lpToken.address);
191
+ const deploy = AMMContract.deploy(this.wallet, token0.address, token1.address, lpToken.address);
201
192
  const amm = await this.registerOrDeployContract('AMM', deploy, deployOpts);
202
193
  this.log.info(`AMM deployed at ${amm.address}`);
203
194
  const minterTx = lpToken.methods.set_minter(amm.address, true).send({
@@ -210,7 +201,7 @@ export class BotFactory {
210
201
  this.log.info(`Liquidity token initialized`);
211
202
  return amm;
212
203
  }
213
- async fundAmm(wallet, liquidityProvider, amm, token0, token1, lpToken) {
204
+ async fundAmm(defaultAccountAddress, liquidityProvider, amm, token0, token1, lpToken) {
214
205
  const getPrivateBalances = ()=>Promise.all([
215
206
  token0.methods.balance_of_private(liquidityProvider).simulate({
216
207
  from: liquidityProvider
@@ -231,15 +222,15 @@ export class BotFactory {
231
222
  const [t0Bal, t1Bal, lpBal] = await getPrivateBalances();
232
223
  this.log.info(`Minting ${MINT_BALANCE} tokens of each BotToken0 and BotToken1. Current private balances of ${liquidityProvider}: token0=${t0Bal}, token1=${t1Bal}, lp=${lpBal}`);
233
224
  // Add authwitnesses for the transfers in AMM::add_liquidity function
234
- const token0Authwit = await wallet.createAuthWit({
225
+ const token0Authwit = await this.wallet.createAuthWit(defaultAccountAddress, {
235
226
  caller: amm.address,
236
- action: token0.methods.transfer_to_public_and_prepare_private_balance_increase(liquidityProvider, amm.address, amount0Max, authwitNonce)
227
+ call: await token0.methods.transfer_to_public_and_prepare_private_balance_increase(liquidityProvider, amm.address, amount0Max, authwitNonce).getFunctionCall()
237
228
  });
238
- const token1Authwit = await wallet.createAuthWit({
229
+ const token1Authwit = await this.wallet.createAuthWit(defaultAccountAddress, {
239
230
  caller: amm.address,
240
- action: token1.methods.transfer_to_public_and_prepare_private_balance_increase(liquidityProvider, amm.address, amount1Max, authwitNonce)
231
+ call: await token1.methods.transfer_to_public_and_prepare_private_balance_increase(liquidityProvider, amm.address, amount1Max, authwitNonce).getFunctionCall()
241
232
  });
242
- const mintTx = new BatchCall(wallet, [
233
+ const mintTx = new BatchCall(this.wallet, [
243
234
  token0.methods.mint_to_private(liquidityProvider, MINT_BALANCE),
244
235
  token1.methods.mint_to_private(liquidityProvider, MINT_BALANCE)
245
236
  ]).send({
@@ -262,11 +253,11 @@ export class BotFactory {
262
253
  });
263
254
  this.log.info(`Liquidity added`);
264
255
  const [newT0Bal, newT1Bal, newLPBal] = await getPrivateBalances();
265
- this.log.info(`Updated private balances of ${wallet.getAddress()} after minting and funding AMM: token0=${newT0Bal}, token1=${newT1Bal}, lp=${newLPBal}`);
256
+ this.log.info(`Updated private balances of ${defaultAccountAddress} after minting and funding AMM: token0=${newT0Bal}, token1=${newT1Bal}, lp=${newLPBal}`);
266
257
  }
267
258
  async registerOrDeployContract(name, deploy, deployOpts) {
268
259
  const address = (await deploy.getInstance(deployOpts)).address;
269
- if ((await this.pxe.getContractMetadata(address)).isContractPublished) {
260
+ if ((await this.wallet.getContractMetadata(address)).isContractPublished) {
270
261
  this.log.info(`Contract ${name} at ${address.toString()} already deployed`);
271
262
  return deploy.register();
272
263
  } else {
@@ -313,6 +304,32 @@ export class BotFactory {
313
304
  timeout: this.config.txMinedWaitSeconds
314
305
  }));
315
306
  }
307
+ /**
308
+ * Gets or creates a bridge claim for the recipient.
309
+ * Checks if a claim already exists in the store and reuses it if valid.
310
+ * Only creates a new bridge if fee juice balance is below threshold.
311
+ */ async getOrCreateBridgeClaim(recipient) {
312
+ // Check if we have an existing claim in the store
313
+ const existingClaim = await this.store.getBridgeClaim(recipient);
314
+ if (existingClaim) {
315
+ this.log.info(`Found existing bridge claim for ${recipient.toString()}, checking validity...`);
316
+ // Check if the message is ready on L2
317
+ try {
318
+ const messageHash = Fr.fromHexString(existingClaim.claim.messageHash);
319
+ await this.withNoMinTxsPerBlock(()=>waitForL1ToL2MessageReady(this.aztecNode, messageHash, {
320
+ timeoutSeconds: this.config.l1ToL2MessageTimeoutSeconds,
321
+ forPublicConsumption: false
322
+ }));
323
+ return existingClaim.claim;
324
+ } catch (err) {
325
+ this.log.warn(`Failed to verify existing claim, creating new one: ${err}`);
326
+ await this.store.deleteBridgeClaim(recipient);
327
+ }
328
+ }
329
+ const claim = await this.bridgeL1FeeJuice(recipient);
330
+ await this.store.saveBridgeClaim(recipient, claim);
331
+ return claim;
332
+ }
316
333
  async bridgeL1FeeJuice(recipient) {
317
334
  const l1RpcUrls = this.config.l1RpcUrls;
318
335
  if (!l1RpcUrls?.length) {
@@ -322,13 +339,13 @@ export class BotFactory {
322
339
  if (!mnemonicOrPrivateKey) {
323
340
  throw new Error('Either a mnemonic or private key of an L1 account is required to bridge the fee juice to fund the deployment of the account.');
324
341
  }
325
- const { l1ChainId } = await this.pxe.getNodeInfo();
342
+ const { l1ChainId } = await this.aztecNode.getNodeInfo();
326
343
  const chain = createEthereumChain(l1RpcUrls, l1ChainId);
327
344
  const extendedClient = createExtendedL1Client(chain.rpcUrls, mnemonicOrPrivateKey, chain.chainInfo);
328
- const portal = await L1FeeJuicePortalManager.new(this.pxe, extendedClient, this.log);
345
+ const portal = await L1FeeJuicePortalManager.new(this.aztecNode, extendedClient, this.log);
329
346
  const mintAmount = await portal.getTokenManager().getMintAmount();
330
347
  const claim = await portal.bridgeTokensPublic(recipient, mintAmount, true);
331
- await this.withNoMinTxsPerBlock(()=>waitForL1ToL2MessageReady(this.pxe, Fr.fromHexString(claim.messageHash), {
348
+ await this.withNoMinTxsPerBlock(()=>waitForL1ToL2MessageReady(this.aztecNode, Fr.fromHexString(claim.messageHash), {
332
349
  timeoutSeconds: this.config.l1ToL2MessageTimeoutSeconds,
333
350
  forPublicConsumption: false
334
351
  }));
@@ -336,17 +353,20 @@ export class BotFactory {
336
353
  return claim;
337
354
  }
338
355
  async withNoMinTxsPerBlock(fn) {
339
- if (!this.nodeAdmin || !this.config.flushSetupTransactions) {
356
+ if (!this.aztecNodeAdmin || !this.config.flushSetupTransactions) {
357
+ this.log.verbose(`No node admin client or flushing not requested (not setting minTxsPerBlock to 0)`);
340
358
  return fn();
341
359
  }
342
- const { minTxsPerBlock } = await this.nodeAdmin.getConfig();
343
- await this.nodeAdmin.setConfig({
360
+ const { minTxsPerBlock } = await this.aztecNodeAdmin.getConfig();
361
+ this.log.warn(`Setting sequencer minTxsPerBlock to 0 from ${minTxsPerBlock} to flush setup transactions`);
362
+ await this.aztecNodeAdmin.setConfig({
344
363
  minTxsPerBlock: 0
345
364
  });
346
365
  try {
347
366
  return await fn();
348
367
  } finally{
349
- await this.nodeAdmin.setConfig({
368
+ this.log.warn(`Restoring sequencer minTxsPerBlock to ${minTxsPerBlock}`);
369
+ await this.aztecNodeAdmin.setConfig({
350
370
  minTxsPerBlock
351
371
  });
352
372
  }
package/dest/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { Bot } from './bot.js';
2
2
  export { AmmBot } from './amm_bot.js';
3
3
  export { BotRunner } from './runner.js';
4
+ export { BotStore } from './store/bot_store.js';
4
5
  export { type BotConfig, getBotConfigFromEnv, getBotDefaultConfig, botConfigMappings, SupportedTokenContracts, } from './config.js';
5
6
  export { getBotRunnerApiHandler } from './rpc.js';
6
7
  export * from './interface.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EACL,KAAK,SAAS,EACd,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EACL,KAAK,SAAS,EACd,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAClD,cAAc,gBAAgB,CAAC"}
package/dest/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  export { Bot } from './bot.js';
2
2
  export { AmmBot } from './amm_bot.js';
3
3
  export { BotRunner } from './runner.js';
4
+ export { BotStore } from './store/bot_store.js';
4
5
  export { getBotConfigFromEnv, getBotDefaultConfig, botConfigMappings, SupportedTokenContracts } from './config.js';
5
6
  export { getBotRunnerApiHandler } from './rpc.js';
6
7
  export * from './interface.js';
@@ -1,4 +1,4 @@
1
- import { AztecAddress } from '@aztec/aztec.js';
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
2
  import type { ApiSchemaFor } from '@aztec/stdlib/schemas';
3
3
  import { z } from 'zod';
4
4
  import { type BotConfig } from './config.js';
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,aAAa,CAAC;AAE9D,eAAO,MAAM,aAAa;;;;;;EAExB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,YAAY,CAQzD,CAAC"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,aAAa,CAAC;AAE9D,eAAO,MAAM,aAAa;;;;;;EAExB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,YAAY,CAQzD,CAAC"}
package/dest/interface.js CHANGED
@@ -1,4 +1,4 @@
1
- import { AztecAddress } from '@aztec/aztec.js';
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
2
  import { z } from 'zod';
3
3
  import { BotConfigSchema } from './config.js';
4
4
  export const BotInfoSchema = z.object({
package/dest/runner.d.ts CHANGED
@@ -1,26 +1,25 @@
1
- import { type AztecNode, type PXE } from '@aztec/aztec.js';
2
- import { type AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
1
+ import type { AztecNode } from '@aztec/aztec.js/node';
2
+ import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
3
3
  import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
4
- import { type BotConfig } from './config.js';
4
+ import type { TestWallet } from '@aztec/test-wallet/server';
5
+ import type { BotConfig } from './config.js';
5
6
  import type { BotInfo, BotRunnerApi } from './interface.js';
7
+ import { BotStore } from './store/index.js';
6
8
  export declare class BotRunner implements BotRunnerApi, Traceable {
7
9
  #private;
8
10
  private config;
11
+ private readonly wallet;
12
+ private readonly aztecNode;
13
+ private readonly telemetry;
14
+ private readonly aztecNodeAdmin;
15
+ private readonly store;
9
16
  private log;
10
17
  private bot?;
11
- private pxe?;
12
- private node;
13
- private nodeAdmin?;
14
18
  private runningPromise;
15
19
  private consecutiveErrors;
16
20
  private healthy;
17
21
  readonly tracer: Tracer;
18
- constructor(config: BotConfig, dependencies: {
19
- pxe?: PXE;
20
- node?: AztecNode;
21
- nodeAdmin?: AztecNodeAdmin;
22
- telemetry: TelemetryClient;
23
- });
22
+ constructor(config: BotConfig, wallet: TestWallet, aztecNode: AztecNode, telemetry: TelemetryClient, aztecNodeAdmin: AztecNodeAdmin | undefined, store: BotStore);
24
23
  /** Initializes the bot if needed. Blocks until the bot setup is finished. */
25
24
  setup(): Promise<void>;
26
25
  private doSetup;
@@ -1 +1 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,GAAG,EAAuC,MAAM,iBAAiB,CAAC;AAGhG,OAAO,EAAE,KAAK,cAAc,EAA8B,MAAM,iCAAiC,CAAC;AAClG,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM,EAA8B,MAAM,yBAAyB,CAAC;AAKxH,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE5D,qBAAa,SAAU,YAAW,YAAY,EAAE,SAAS;;IAarD,OAAO,CAAC,MAAM;IAZhB,OAAO,CAAC,GAAG,CAAuB;IAClC,OAAO,CAAC,GAAG,CAAC,CAAmB;IAC/B,OAAO,CAAC,GAAG,CAAC,CAAM;IAClB,OAAO,CAAC,IAAI,CAAY;IACxB,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,OAAO,CAAQ;IAEvB,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAGrB,MAAM,EAAE,SAAS,EACzB,YAAY,EAAE;QAAE,GAAG,CAAC,EAAE,GAAG,CAAC;QAAC,IAAI,CAAC,EAAE,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,cAAc,CAAC;QAAC,SAAS,EAAE,eAAe,CAAA;KAAE;IAgBvG,6EAA6E;IAChE,KAAK;YAOJ,OAAO;IAMrB;;;OAGG;IACU,KAAK;IAQlB;;OAEG;IACU,IAAI;IAQV,SAAS;IAIhB,0CAA0C;IACnC,SAAS;IAIhB;;;OAGG;IACU,MAAM,CAAC,MAAM,EAAE,SAAS;IAerC;;;OAGG;IACU,GAAG;IAwBhB,qDAAqD;IAC9C,SAAS;IAKhB,sCAAsC;IACzB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;CA6CzC"}
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM,EAAa,MAAM,yBAAyB,CAAC;AACvG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAK5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,qBAAa,SAAU,YAAW,YAAY,EAAE,SAAS;;IAUrD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAdxB,OAAO,CAAC,GAAG,CAAuB;IAClC,OAAO,CAAC,GAAG,CAAC,CAAmB;IAC/B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,OAAO,CAAQ;IAEvB,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAGrB,MAAM,EAAE,SAAS,EACR,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,eAAe,EAC1B,cAAc,EAAE,cAAc,GAAG,SAAS,EAC1C,KAAK,EAAE,QAAQ;IAOlC,6EAA6E;IAChE,KAAK;YAOJ,OAAO;IAMrB;;;OAGG;IACU,KAAK;IAQlB;;OAEG;IACU,IAAI;IASV,SAAS;IAIhB,0CAA0C;IACnC,SAAS;IAIhB;;;OAGG;IACU,MAAM,CAAC,MAAM,EAAE,SAAS;IAerC;;;OAGG;IACU,GAAG;IAwBhB,qDAAqD;IAC9C,SAAS;IAKhB,sCAAsC;IACzB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;CA6CzC"}