@aztec/bot 0.0.0-test.1 → 0.0.1-fake-ceab37513c

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 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../src/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAI1D,OAAO,EAAE,KAAK,SAAS,EAAmB,MAAM,aAAa,CAAC;AAE9D,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,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,eAAO,MAAM,kBAAkB,EAAE,YAAY,CAAC,YAAY,CAOzD,CAAC"}
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"}
package/dest/interface.js CHANGED
@@ -1,10 +1,15 @@
1
+ import { AztecAddress } from '@aztec/aztec.js';
1
2
  import { z } from 'zod';
2
3
  import { BotConfigSchema } from './config.js';
4
+ export const BotInfoSchema = z.object({
5
+ botAddress: AztecAddress.schema
6
+ });
3
7
  export const BotRunnerApiSchema = {
4
8
  start: z.function().args().returns(z.void()),
5
9
  stop: z.function().args().returns(z.void()),
6
10
  run: z.function().args().returns(z.void()),
7
11
  setup: z.function().args().returns(z.void()),
12
+ getInfo: z.function().args().returns(BotInfoSchema),
8
13
  getConfig: z.function().args().returns(BotConfigSchema),
9
14
  update: z.function().args(BotConfigSchema).returns(z.void())
10
15
  };
package/dest/rpc.d.ts CHANGED
@@ -1,10 +1,4 @@
1
1
  import type { ApiHandler } from '@aztec/foundation/json-rpc/server';
2
2
  import type { BotRunner } from './runner.js';
3
- /**
4
- * Wraps a bot runner with a JSON RPC HTTP server.
5
- * @param botRunner - The BotRunner.
6
- * @returns An JSON-RPC HTTP server
7
- */
8
- export declare function createBotRunnerRpcServer(botRunner: BotRunner): void;
9
3
  export declare function getBotRunnerApiHandler(botRunner: BotRunner): ApiHandler;
10
4
  //# sourceMappingURL=rpc.d.ts.map
package/dest/rpc.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAIpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,QAK5D;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,CAEvE"}
1
+ {"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAGpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,UAAU,CAEvE"}
package/dest/rpc.js CHANGED
@@ -1,15 +1,4 @@
1
- import { createTracedJsonRpcServer } from '@aztec/telemetry-client';
2
1
  import { BotRunnerApiSchema } from './interface.js';
3
- /**
4
- * Wraps a bot runner with a JSON RPC HTTP server.
5
- * @param botRunner - The BotRunner.
6
- * @returns An JSON-RPC HTTP server
7
- */ export function createBotRunnerRpcServer(botRunner) {
8
- createTracedJsonRpcServer(botRunner, BotRunnerApiSchema, {
9
- http200OnError: false,
10
- healthCheck: botRunner.isHealthy.bind(botRunner)
11
- });
12
- }
13
2
  export function getBotRunnerApiHandler(botRunner) {
14
3
  return [
15
4
  botRunner,
package/dest/runner.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import { type AztecNode, type PXE } from '@aztec/aztec.js';
2
+ import { type AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
2
3
  import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
3
4
  import { type BotConfig } from './config.js';
4
- import type { BotRunnerApi } from './interface.js';
5
+ import type { BotInfo, BotRunnerApi } from './interface.js';
5
6
  export declare class BotRunner implements BotRunnerApi, Traceable {
6
7
  #private;
7
8
  private config;
@@ -9,6 +10,7 @@ export declare class BotRunner implements BotRunnerApi, Traceable {
9
10
  private bot?;
10
11
  private pxe?;
11
12
  private node;
13
+ private nodeAdmin?;
12
14
  private runningPromise;
13
15
  private consecutiveErrors;
14
16
  private healthy;
@@ -16,6 +18,7 @@ export declare class BotRunner implements BotRunnerApi, Traceable {
16
18
  constructor(config: BotConfig, dependencies: {
17
19
  pxe?: PXE;
18
20
  node?: AztecNode;
21
+ nodeAdmin?: AztecNodeAdmin;
19
22
  telemetry: TelemetryClient;
20
23
  });
21
24
  /** Initializes the bot if needed. Blocks until the bot setup is finished. */
@@ -45,5 +48,7 @@ export declare class BotRunner implements BotRunnerApi, Traceable {
45
48
  run(): Promise<void>;
46
49
  /** Returns the current configuration for the bot. */
47
50
  getConfig(): Promise<BotConfig>;
51
+ /** Returns the bot sender address. */
52
+ getInfo(): Promise<BotInfo>;
48
53
  }
49
54
  //# sourceMappingURL=runner.d.ts.map
@@ -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;AAEhG,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM,EAA8B,MAAM,yBAAyB,CAAC;AAGxH,OAAO,EAAE,KAAK,SAAS,EAAe,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,qBAAa,SAAU,YAAW,YAAY,EAAE,SAAS;;IAYrD,OAAO,CAAC,MAAM;IAXhB,OAAO,CAAC,GAAG,CAAuB;IAClC,OAAO,CAAC,GAAG,CAAC,CAAe;IAC3B,OAAO,CAAC,GAAG,CAAC,CAAM;IAClB,OAAO,CAAC,IAAI,CAAY;IACxB,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,EAAE,eAAe,CAAA;KAAE;IAY3E,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;CAuCjB"}
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"}
package/dest/runner.js CHANGED
@@ -5,8 +5,11 @@ function _ts_decorate(decorators, target, key, desc) {
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  }
7
7
  import { createAztecNodeClient, createLogger } from '@aztec/aztec.js';
8
+ import { omit } from '@aztec/foundation/collection';
8
9
  import { RunningPromise } from '@aztec/foundation/running-promise';
10
+ import { createAztecNodeAdminClient } from '@aztec/stdlib/interfaces/client';
9
11
  import { makeTracedFetch, trackSpan } from '@aztec/telemetry-client';
12
+ import { AmmBot } from './amm_bot.js';
10
13
  import { Bot } from './bot.js';
11
14
  import { getVersions } from './config.js';
12
15
  export class BotRunner {
@@ -15,6 +18,7 @@ export class BotRunner {
15
18
  bot;
16
19
  pxe;
17
20
  node;
21
+ nodeAdmin;
18
22
  runningPromise;
19
23
  consecutiveErrors;
20
24
  healthy;
@@ -29,11 +33,14 @@ export class BotRunner {
29
33
  if (!dependencies.node && !config.nodeUrl) {
30
34
  throw new Error(`Missing node URL in config or dependencies`);
31
35
  }
32
- this.node = dependencies.node ?? createAztecNodeClient(config.nodeUrl, getVersions(), makeTracedFetch([
36
+ const versions = getVersions();
37
+ const fetch = makeTracedFetch([
33
38
  1,
34
39
  2,
35
40
  3
36
- ], true));
41
+ ], true);
42
+ this.node = dependencies.node ?? createAztecNodeClient(config.nodeUrl, versions, fetch);
43
+ this.nodeAdmin = dependencies.nodeAdmin ?? (config.nodeAdminUrl ? createAztecNodeAdminClient(config.nodeAdminUrl, versions, fetch) : undefined);
37
44
  this.runningPromise = new RunningPromise(()=>this.#work(), this.log, config.txIntervalSeconds * 1000);
38
45
  }
39
46
  /** Initializes the bot if needed. Blocks until the bot setup is finished. */ async setup() {
@@ -116,13 +123,28 @@ export class BotRunner {
116
123
  }
117
124
  }
118
125
  /** Returns the current configuration for the bot. */ getConfig() {
119
- return Promise.resolve(this.config);
126
+ const redacted = omit(this.config, 'l1Mnemonic', 'l1PrivateKey', 'senderPrivateKey');
127
+ return Promise.resolve(redacted);
128
+ }
129
+ /** Returns the bot sender address. */ async getInfo() {
130
+ if (!this.bot) {
131
+ throw new Error(`Bot is not initialized`);
132
+ }
133
+ const botAddress = await this.bot.then((b)=>b.wallet.getAddress());
134
+ return {
135
+ botAddress
136
+ };
120
137
  }
121
138
  async #createBot() {
122
139
  try {
123
- this.bot = Bot.create(this.config, {
140
+ this.bot = this.config.ammTxs ? AmmBot.create(this.config, {
141
+ pxe: this.pxe,
142
+ node: this.node,
143
+ nodeAdmin: this.nodeAdmin
144
+ }) : Bot.create(this.config, {
124
145
  pxe: this.pxe,
125
- node: this.node
146
+ node: this.node,
147
+ nodeAdmin: this.nodeAdmin
126
148
  });
127
149
  await this.bot;
128
150
  } catch (err) {
@@ -132,15 +154,15 @@ export class BotRunner {
132
154
  }
133
155
  async #work() {
134
156
  if (this.config.maxPendingTxs > 0) {
135
- const pendingTxs = await this.node.getPendingTxs();
136
- if (pendingTxs.length >= this.config.maxPendingTxs) {
137
- this.log.verbose(`Not sending bot tx since node has ${pendingTxs.length} pending txs`);
157
+ const pendingTxCount = await this.node.getPendingTxCount();
158
+ if (pendingTxCount >= this.config.maxPendingTxs) {
159
+ this.log.verbose(`Not sending bot tx since node has ${pendingTxCount} pending txs`);
138
160
  return;
139
161
  }
140
162
  }
141
163
  try {
142
164
  await this.run();
143
- } catch (err) {
165
+ } catch {
144
166
  // Already logged in run()
145
167
  if (this.config.maxConsecutiveErrors > 0 && this.consecutiveErrors >= this.config.maxConsecutiveErrors) {
146
168
  this.log.error(`Too many errors bot is unhealthy`);
package/dest/utils.d.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { EasyPrivateTokenContract } from '@aztec/noir-contracts.js/EasyPrivateToken';
1
+ import type { ContractBase } from '@aztec/aztec.js';
2
+ import type { AMMContract } from '@aztec/noir-contracts.js/AMM';
3
+ import type { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
2
4
  import type { TokenContract } from '@aztec/noir-contracts.js/Token';
3
5
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
4
6
  /**
@@ -11,6 +13,7 @@ export declare function getBalances(token: TokenContract, who: AztecAddress): Pr
11
13
  privateBalance: bigint;
12
14
  publicBalance: bigint;
13
15
  }>;
14
- export declare function getPrivateBalance(token: EasyPrivateTokenContract, who: AztecAddress): Promise<bigint>;
15
- export declare function isStandardTokenContract(token: TokenContract | EasyPrivateTokenContract): token is TokenContract;
16
+ export declare function getPrivateBalance(token: PrivateTokenContract, who: AztecAddress): Promise<bigint>;
17
+ export declare function isStandardTokenContract(token: ContractBase): token is TokenContract;
18
+ export declare function isAMMContract(contract: ContractBase): contract is AMMContract;
16
19
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2CAA2C,CAAC;AAC1F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAI5D;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,wBAAwB,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAG3G;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,aAAa,GAAG,wBAAwB,GAAG,KAAK,IAAI,aAAa,CAE/G"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAI5D;AAED,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,oBAAoB,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvG;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,IAAI,aAAa,CAEnF;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,QAAQ,IAAI,WAAW,CAE7E"}
package/dest/utils.js CHANGED
@@ -4,17 +4,26 @@
4
4
  * @param who - Address to get the balance for.
5
5
  * @returns - Private and public token balances as bigints.
6
6
  */ export async function getBalances(token, who) {
7
- const privateBalance = await token.methods.balance_of_private(who).simulate();
8
- const publicBalance = await token.methods.balance_of_public(who).simulate();
7
+ const privateBalance = await token.methods.balance_of_private(who).simulate({
8
+ from: who
9
+ });
10
+ const publicBalance = await token.methods.balance_of_public(who).simulate({
11
+ from: who
12
+ });
9
13
  return {
10
14
  privateBalance,
11
15
  publicBalance
12
16
  };
13
17
  }
14
18
  export async function getPrivateBalance(token, who) {
15
- const privateBalance = await token.methods.get_balance(who).simulate();
19
+ const privateBalance = await token.methods.get_balance(who).simulate({
20
+ from: who
21
+ });
16
22
  return privateBalance;
17
23
  }
18
24
  export function isStandardTokenContract(token) {
19
25
  return 'mint_to_public' in token.methods;
20
26
  }
27
+ export function isAMMContract(contract) {
28
+ return 'add_liquidity' in contract.methods;
29
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/bot",
3
- "version": "0.0.0-test.1",
3
+ "version": "0.0.1-fake-ceab37513c",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./dest/index.js",
@@ -13,8 +13,6 @@
13
13
  "build": "yarn clean && tsc -b",
14
14
  "build:dev": "tsc -b --watch",
15
15
  "clean": "rm -rf ./dest .tsbuildinfo",
16
- "formatting": "run -T prettier --check ./src && run -T eslint ./src",
17
- "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src",
18
16
  "bb": "node --no-warnings ./dest/bb/index.js",
19
17
  "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
20
18
  },
@@ -49,33 +47,36 @@
49
47
  "testTimeout": 120000,
50
48
  "setupFiles": [
51
49
  "../../foundation/src/jest/setup.mjs"
50
+ ],
51
+ "testEnvironment": "../../foundation/src/jest/env.mjs",
52
+ "setupFilesAfterEnv": [
53
+ "../../foundation/src/jest/setupAfterEnv.mjs"
52
54
  ]
53
55
  },
54
56
  "dependencies": {
55
- "@aztec/accounts": "0.0.0-test.1",
56
- "@aztec/aztec.js": "0.0.0-test.1",
57
- "@aztec/entrypoints": "0.0.0-test.1",
58
- "@aztec/ethereum": "0.0.0-test.1",
59
- "@aztec/foundation": "0.0.0-test.1",
60
- "@aztec/noir-contracts.js": "0.0.0-test.1",
61
- "@aztec/noir-protocol-circuits-types": "0.0.0-test.1",
62
- "@aztec/protocol-contracts": "0.0.0-test.1",
63
- "@aztec/stdlib": "0.0.0-test.1",
64
- "@aztec/telemetry-client": "0.0.0-test.1",
57
+ "@aztec/accounts": "0.0.1-fake-ceab37513c",
58
+ "@aztec/aztec.js": "0.0.1-fake-ceab37513c",
59
+ "@aztec/entrypoints": "0.0.1-fake-ceab37513c",
60
+ "@aztec/ethereum": "0.0.1-fake-ceab37513c",
61
+ "@aztec/foundation": "0.0.1-fake-ceab37513c",
62
+ "@aztec/noir-contracts.js": "0.0.1-fake-ceab37513c",
63
+ "@aztec/noir-protocol-circuits-types": "0.0.1-fake-ceab37513c",
64
+ "@aztec/protocol-contracts": "0.0.1-fake-ceab37513c",
65
+ "@aztec/stdlib": "0.0.1-fake-ceab37513c",
66
+ "@aztec/telemetry-client": "0.0.1-fake-ceab37513c",
65
67
  "source-map-support": "^0.5.21",
66
68
  "tslib": "^2.4.0",
67
69
  "zod": "^3.23.8"
68
70
  },
69
71
  "devDependencies": {
70
- "@jest/globals": "^29.5.0",
71
- "@types/jest": "^29.5.0",
72
- "@types/memdown": "^3.0.0",
73
- "@types/node": "^18.7.23",
72
+ "@jest/globals": "^30.0.0",
73
+ "@types/jest": "^30.0.0",
74
+ "@types/node": "^22.15.17",
74
75
  "@types/source-map-support": "^0.5.10",
75
- "jest": "^29.5.0",
76
- "jest-mock-extended": "^3.0.3",
76
+ "jest": "^30.0.0",
77
+ "jest-mock-extended": "^4.0.0",
77
78
  "ts-node": "^10.9.1",
78
- "typescript": "^5.0.4"
79
+ "typescript": "^5.3.3"
79
80
  },
80
81
  "files": [
81
82
  "dest",
@@ -84,6 +85,6 @@
84
85
  ],
85
86
  "types": "./dest/index.d.ts",
86
87
  "engines": {
87
- "node": ">=18"
88
+ "node": ">=20.10"
88
89
  }
89
90
  }
package/src/amm_bot.ts ADDED
@@ -0,0 +1,116 @@
1
+ import { AztecAddress, Fr, SentTx, TxReceipt, type Wallet } from '@aztec/aztec.js';
2
+ import { jsonStringify } from '@aztec/foundation/json-rpc';
3
+ import type { AMMContract } from '@aztec/noir-contracts.js/AMM';
4
+ import type { TokenContract } from '@aztec/noir-contracts.js/Token';
5
+ import type { AztecNode, AztecNodeAdmin, PXE } from '@aztec/stdlib/interfaces/client';
6
+
7
+ import { BaseBot } from './base_bot.js';
8
+ import type { BotConfig } from './config.js';
9
+ import { BotFactory } from './factory.js';
10
+
11
+ const TRANSFER_BASE_AMOUNT = 1_000;
12
+ const TRANSFER_VARIANCE = 200;
13
+
14
+ type Balances = { token0: bigint; token1: bigint };
15
+
16
+ export class AmmBot extends BaseBot {
17
+ protected constructor(
18
+ pxe: PXE,
19
+ wallet: Wallet,
20
+ defaultAccountAddress: AztecAddress,
21
+ public readonly amm: AMMContract,
22
+ public readonly token0: TokenContract,
23
+ public readonly token1: TokenContract,
24
+ config: BotConfig,
25
+ ) {
26
+ super(pxe, wallet, defaultAccountAddress, config);
27
+ }
28
+
29
+ static async create(
30
+ config: BotConfig,
31
+ dependencies: { pxe?: PXE; node?: AztecNode; nodeAdmin?: AztecNodeAdmin },
32
+ ): Promise<AmmBot> {
33
+ const { pxe, wallet, defaultAccountAddress, token0, token1, amm } = await new BotFactory(
34
+ config,
35
+ dependencies,
36
+ ).setupAmm();
37
+ return new AmmBot(pxe, wallet, defaultAccountAddress, amm, token0, token1, config);
38
+ }
39
+
40
+ protected async createAndSendTx(logCtx: object): Promise<SentTx> {
41
+ const { feePaymentMethod } = this.config;
42
+ const { wallet, amm, token0, token1 } = this;
43
+
44
+ const balances = this.getBalances();
45
+ this.log.info(`Preparing tx with ${feePaymentMethod} fee to swap tokens. Balances: ${jsonStringify(balances)}`, {
46
+ ...logCtx,
47
+ balances,
48
+ });
49
+
50
+ // 1000 ± 200
51
+ const amountIn = Math.floor(TRANSFER_BASE_AMOUNT + (Math.random() - 0.5) * TRANSFER_VARIANCE);
52
+ const authwitNonce = Fr.random();
53
+
54
+ const [tokenIn, tokenOut] = Math.random() < 0.5 ? [token0, token1] : [token1, token0];
55
+
56
+ const swapAuthwit = await wallet.createAuthWit({
57
+ caller: amm.address,
58
+ action: tokenIn.methods.transfer_to_public(this.defaultAccountAddress, amm.address, amountIn, authwitNonce),
59
+ });
60
+
61
+ const amountOutMin = await amm.methods
62
+ .get_amount_out_for_exact_in(
63
+ await tokenIn.methods.balance_of_public(amm.address).simulate({ from: this.defaultAccountAddress }),
64
+ await tokenOut.methods.balance_of_public(amm.address).simulate({ from: this.defaultAccountAddress }),
65
+ amountIn,
66
+ )
67
+ .simulate({ from: this.defaultAccountAddress });
68
+
69
+ const swapExactTokensInteraction = amm.methods.swap_exact_tokens_for_tokens(
70
+ tokenIn.address,
71
+ tokenOut.address,
72
+ amountIn,
73
+ amountOutMin,
74
+ authwitNonce,
75
+ );
76
+
77
+ const opts = this.getSendMethodOpts(swapAuthwit);
78
+
79
+ this.log.verbose(`Proving transaction`, logCtx);
80
+ const tx = await swapExactTokensInteraction.prove(opts);
81
+
82
+ this.log.info(`Tx. Balances: ${jsonStringify(balances)}`, { ...logCtx, balances });
83
+
84
+ return tx.send();
85
+ }
86
+
87
+ protected override async onTxMined(receipt: TxReceipt, logCtx: object): Promise<void> {
88
+ const balances = await this.getBalances();
89
+ this.log.info(`Balances after swap in tx ${receipt.txHash}: ${jsonStringify(balances)}`, { ...logCtx, balances });
90
+ }
91
+
92
+ public getAmmBalances(): Promise<Balances> {
93
+ return this.getPublicBalanceFor(this.amm.address);
94
+ }
95
+
96
+ public async getBalances(): Promise<{ senderPublic: Balances; senderPrivate: Balances; amm: Balances }> {
97
+ return {
98
+ senderPublic: await this.getPublicBalanceFor(this.defaultAccountAddress),
99
+ senderPrivate: await this.getPrivateBalanceFor(this.defaultAccountAddress),
100
+ amm: await this.getPublicBalanceFor(this.amm.address),
101
+ };
102
+ }
103
+
104
+ private async getPublicBalanceFor(address: AztecAddress): Promise<Balances> {
105
+ return {
106
+ token0: await this.token0.methods.balance_of_public(address).simulate({ from: address }),
107
+ token1: await this.token1.methods.balance_of_public(address).simulate({ from: address }),
108
+ };
109
+ }
110
+ private async getPrivateBalanceFor(address: AztecAddress): Promise<Balances> {
111
+ return {
112
+ token0: await this.token0.methods.balance_of_private(address).simulate({ from: address }),
113
+ token1: await this.token1.methods.balance_of_private(address).simulate({ from: address }),
114
+ };
115
+ }
116
+ }
@@ -0,0 +1,94 @@
1
+ import {
2
+ AuthWitness,
3
+ AztecAddress,
4
+ FeeJuicePaymentMethod,
5
+ type SendMethodOptions,
6
+ SentTx,
7
+ TxHash,
8
+ TxReceipt,
9
+ type Wallet,
10
+ createLogger,
11
+ waitForProven,
12
+ } from '@aztec/aztec.js';
13
+ import { Gas } from '@aztec/stdlib/gas';
14
+ import type { PXE } from '@aztec/stdlib/interfaces/client';
15
+
16
+ import type { BotConfig } from './config.js';
17
+
18
+ export abstract class BaseBot {
19
+ protected log = createLogger('bot');
20
+
21
+ protected attempts: number = 0;
22
+ protected successes: number = 0;
23
+
24
+ protected constructor(
25
+ public readonly pxe: PXE,
26
+ public readonly wallet: Wallet,
27
+ public readonly defaultAccountAddress: AztecAddress,
28
+ public config: BotConfig,
29
+ ) {}
30
+
31
+ public async run(): Promise<TxReceipt | TxHash> {
32
+ this.attempts++;
33
+ const logCtx = { runId: Date.now() * 1000 + Math.floor(Math.random() * 1000) };
34
+ const { followChain, txMinedWaitSeconds } = this.config;
35
+
36
+ this.log.verbose(`Creating tx`, logCtx);
37
+ const tx = await this.createAndSendTx(logCtx);
38
+
39
+ const txHash = await tx.getTxHash();
40
+
41
+ if (followChain === 'NONE') {
42
+ this.log.info(`Transaction ${txHash.toString()} sent, not waiting for it to be mined`);
43
+ return txHash;
44
+ }
45
+
46
+ this.log.verbose(
47
+ `Awaiting tx ${txHash.toString()} to be on the ${followChain} chain (timeout ${txMinedWaitSeconds}s)`,
48
+ logCtx,
49
+ );
50
+ const receipt = await tx.wait({
51
+ timeout: txMinedWaitSeconds,
52
+ });
53
+ if (followChain === 'PROVEN') {
54
+ await waitForProven(this.pxe, receipt, { provenTimeout: txMinedWaitSeconds });
55
+ }
56
+ this.successes++;
57
+ this.log.info(
58
+ `Tx #${this.attempts} ${receipt.txHash} successfully mined in block ${receipt.blockNumber} (stats: ${this.successes}/${this.attempts} success)`,
59
+ logCtx,
60
+ );
61
+
62
+ await this.onTxMined(receipt, logCtx);
63
+
64
+ return receipt;
65
+ }
66
+
67
+ protected abstract createAndSendTx(logCtx: object): Promise<SentTx>;
68
+
69
+ protected onTxMined(_receipt: TxReceipt, _logCtx: object): Promise<void> {
70
+ // no-op
71
+ return Promise.resolve();
72
+ }
73
+
74
+ protected getSendMethodOpts(...authWitnesses: AuthWitness[]): SendMethodOptions {
75
+ const { l2GasLimit, daGasLimit } = this.config;
76
+ const paymentMethod = new FeeJuicePaymentMethod(this.defaultAccountAddress);
77
+
78
+ let gasSettings, estimateGas;
79
+ if (l2GasLimit !== undefined && l2GasLimit > 0 && daGasLimit !== undefined && daGasLimit > 0) {
80
+ gasSettings = { gasLimits: Gas.from({ l2Gas: l2GasLimit, daGas: daGasLimit }) };
81
+ estimateGas = false;
82
+ this.log.verbose(`Using gas limits ${l2GasLimit} L2 gas ${daGasLimit} DA gas`);
83
+ } else {
84
+ estimateGas = true;
85
+ this.log.verbose(`Estimating gas for transaction`);
86
+ }
87
+ const baseFeePadding = 2; // Send 3x the current base fee
88
+ return {
89
+ from: this.defaultAccountAddress,
90
+ fee: { estimateGas, paymentMethod, gasSettings, baseFeePadding },
91
+ authWitnesses,
92
+ };
93
+ }
94
+ }