@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.
- package/dest/amm_bot.d.ts +33 -0
- package/dest/amm_bot.d.ts.map +1 -0
- package/dest/amm_bot.js +94 -0
- package/dest/base_bot.d.ts +18 -0
- package/dest/base_bot.d.ts.map +1 -0
- package/dest/base_bot.js +80 -0
- package/dest/bot.d.ts +10 -14
- package/dest/bot.d.ts.map +1 -1
- package/dest/bot.js +21 -82
- package/dest/config.d.ts +51 -30
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +40 -19
- package/dest/factory.d.ts +27 -6
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +200 -75
- package/dest/index.d.ts +2 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -1
- package/dest/interface.d.ts +11 -0
- package/dest/interface.d.ts.map +1 -1
- package/dest/interface.js +5 -0
- package/dest/rpc.d.ts +0 -6
- package/dest/rpc.d.ts.map +1 -1
- package/dest/rpc.js +0 -11
- package/dest/runner.d.ts +6 -1
- package/dest/runner.d.ts.map +1 -1
- package/dest/runner.js +31 -9
- package/dest/utils.d.ts +6 -3
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +12 -3
- package/package.json +22 -21
- package/src/amm_bot.ts +116 -0
- package/src/base_bot.ts +94 -0
- package/src/bot.ts +36 -98
- package/src/config.ts +52 -22
- package/src/factory.ts +256 -78
- package/src/index.ts +2 -1
- package/src/interface.ts +9 -0
- package/src/rpc.ts +0 -13
- package/src/runner.ts +32 -11
- package/src/utils.ts +12 -6
package/dest/interface.d.ts.map
CHANGED
|
@@ -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;
|
|
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;
|
|
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
|
package/dest/runner.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
|
136
|
-
if (
|
|
137
|
-
this.log.verbose(`Not sending bot tx since node has ${
|
|
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
|
|
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 {
|
|
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:
|
|
15
|
-
export declare function isStandardTokenContract(token:
|
|
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
|
package/dest/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
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
|
-
|
|
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.
|
|
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.
|
|
56
|
-
"@aztec/aztec.js": "0.0.
|
|
57
|
-
"@aztec/entrypoints": "0.0.
|
|
58
|
-
"@aztec/ethereum": "0.0.
|
|
59
|
-
"@aztec/foundation": "0.0.
|
|
60
|
-
"@aztec/noir-contracts.js": "0.0.
|
|
61
|
-
"@aztec/noir-protocol-circuits-types": "0.0.
|
|
62
|
-
"@aztec/protocol-contracts": "0.0.
|
|
63
|
-
"@aztec/stdlib": "0.0.
|
|
64
|
-
"@aztec/telemetry-client": "0.0.
|
|
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": "^
|
|
71
|
-
"@types/jest": "^
|
|
72
|
-
"@types/
|
|
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": "^
|
|
76
|
-
"jest-mock-extended": "^
|
|
76
|
+
"jest": "^30.0.0",
|
|
77
|
+
"jest-mock-extended": "^4.0.0",
|
|
77
78
|
"ts-node": "^10.9.1",
|
|
78
|
-
"typescript": "^5.
|
|
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": ">=
|
|
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
|
+
}
|
package/src/base_bot.ts
ADDED
|
@@ -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
|
+
}
|