@aztec/bot 0.81.0 → 0.82.0
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 +32 -0
- package/dest/amm_bot.d.ts.map +1 -0
- package/dest/amm_bot.js +56 -0
- package/dest/base_bot.d.ts +16 -0
- package/dest/base_bot.d.ts.map +1 -0
- package/dest/base_bot.js +74 -0
- package/dest/bot.d.ts +8 -12
- package/dest/bot.d.ts.map +1 -1
- package/dest/bot.js +11 -70
- package/dest/config.d.ts +21 -0
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +20 -1
- package/dest/factory.d.ts +22 -2
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +112 -9
- package/dest/index.d.ts +1 -0
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -0
- package/dest/runner.d.ts +3 -0
- package/dest/runner.d.ts.map +1 -1
- package/dest/runner.js +15 -4
- package/dest/utils.d.ts +4 -1
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +3 -0
- package/package.json +11 -11
- package/src/amm_bot.ts +93 -0
- package/src/base_bot.ts +75 -0
- package/src/bot.ts +19 -71
- package/src/config.ts +25 -0
- package/src/factory.ts +133 -10
- package/src/index.ts +1 -0
- package/src/runner.ts +15 -5
- package/src/utils.ts +7 -1
package/src/config.ts
CHANGED
|
@@ -25,6 +25,8 @@ export enum SupportedTokenContracts {
|
|
|
25
25
|
export type BotConfig = {
|
|
26
26
|
/** The URL to the Aztec node to check for tx pool status. */
|
|
27
27
|
nodeUrl: string | undefined;
|
|
28
|
+
/** The URL to the Aztec node admin API to force-flush txs if configured. */
|
|
29
|
+
nodeAdminUrl: string | undefined;
|
|
28
30
|
/** URL to the PXE for sending txs, or undefined if an in-proc PXE is used. */
|
|
29
31
|
pxeUrl: string | undefined;
|
|
30
32
|
/** Url of the ethereum host. */
|
|
@@ -35,6 +37,8 @@ export type BotConfig = {
|
|
|
35
37
|
l1PrivateKey: string | undefined;
|
|
36
38
|
/** Signing private key for the sender account. */
|
|
37
39
|
senderPrivateKey: Fr | undefined;
|
|
40
|
+
/** Optional salt to use to deploy the sender account */
|
|
41
|
+
senderSalt: Fr | undefined;
|
|
38
42
|
/** Encryption secret for a recipient account. */
|
|
39
43
|
recipientEncryptionSecret: Fr;
|
|
40
44
|
/** Salt for the token contract deployment. */
|
|
@@ -69,16 +73,20 @@ export type BotConfig = {
|
|
|
69
73
|
maxConsecutiveErrors: number;
|
|
70
74
|
/** Stops the bot if service becomes unhealthy */
|
|
71
75
|
stopWhenUnhealthy: boolean;
|
|
76
|
+
/** Deploy an AMM contract and do swaps instead of transfers */
|
|
77
|
+
ammTxs: boolean;
|
|
72
78
|
};
|
|
73
79
|
|
|
74
80
|
export const BotConfigSchema = z
|
|
75
81
|
.object({
|
|
76
82
|
nodeUrl: z.string().optional(),
|
|
83
|
+
nodeAdminUrl: z.string().optional(),
|
|
77
84
|
pxeUrl: z.string().optional(),
|
|
78
85
|
l1RpcUrls: z.array(z.string()).optional(),
|
|
79
86
|
l1Mnemonic: z.string().optional(),
|
|
80
87
|
l1PrivateKey: z.string().optional(),
|
|
81
88
|
senderPrivateKey: schemas.Fr.optional(),
|
|
89
|
+
senderSalt: schemas.Fr.optional(),
|
|
82
90
|
recipientEncryptionSecret: schemas.Fr,
|
|
83
91
|
tokenSalt: schemas.Fr,
|
|
84
92
|
txIntervalSeconds: z.number(),
|
|
@@ -96,14 +104,17 @@ export const BotConfigSchema = z
|
|
|
96
104
|
contract: z.nativeEnum(SupportedTokenContracts),
|
|
97
105
|
maxConsecutiveErrors: z.number().int().nonnegative(),
|
|
98
106
|
stopWhenUnhealthy: z.boolean(),
|
|
107
|
+
ammTxs: z.boolean().default(false),
|
|
99
108
|
})
|
|
100
109
|
.transform(config => ({
|
|
101
110
|
nodeUrl: undefined,
|
|
111
|
+
nodeAdminUrl: undefined,
|
|
102
112
|
pxeUrl: undefined,
|
|
103
113
|
l1RpcUrls: undefined,
|
|
104
114
|
l1Mnemonic: undefined,
|
|
105
115
|
l1PrivateKey: undefined,
|
|
106
116
|
senderPrivateKey: undefined,
|
|
117
|
+
senderSalt: undefined,
|
|
107
118
|
l2GasLimit: undefined,
|
|
108
119
|
daGasLimit: undefined,
|
|
109
120
|
...config,
|
|
@@ -114,6 +125,10 @@ export const botConfigMappings: ConfigMappingsType<BotConfig> = {
|
|
|
114
125
|
env: 'AZTEC_NODE_URL',
|
|
115
126
|
description: 'The URL to the Aztec node to check for tx pool status.',
|
|
116
127
|
},
|
|
128
|
+
nodeAdminUrl: {
|
|
129
|
+
env: 'AZTEC_NODE_ADMIN_URL',
|
|
130
|
+
description: 'The URL to the Aztec node admin API to force-flush txs if configured.',
|
|
131
|
+
},
|
|
117
132
|
pxeUrl: {
|
|
118
133
|
env: 'BOT_PXE_URL',
|
|
119
134
|
description: 'URL to the PXE for sending txs, or undefined if an in-proc PXE is used.',
|
|
@@ -136,6 +151,11 @@ export const botConfigMappings: ConfigMappingsType<BotConfig> = {
|
|
|
136
151
|
description: 'Signing private key for the sender account.',
|
|
137
152
|
parseEnv: (val: string) => (val ? Fr.fromHexString(val) : undefined),
|
|
138
153
|
},
|
|
154
|
+
senderSalt: {
|
|
155
|
+
env: 'BOT_ACCOUNT_SALT',
|
|
156
|
+
description: 'The salt to use to deploys the sender account.',
|
|
157
|
+
parseEnv: (val: string) => (val ? Fr.fromHexString(val) : undefined),
|
|
158
|
+
},
|
|
139
159
|
recipientEncryptionSecret: {
|
|
140
160
|
env: 'BOT_RECIPIENT_ENCRYPTION_SECRET',
|
|
141
161
|
description: 'Encryption secret for a recipient account.',
|
|
@@ -240,6 +260,11 @@ export const botConfigMappings: ConfigMappingsType<BotConfig> = {
|
|
|
240
260
|
description: 'Stops the bot if service becomes unhealthy',
|
|
241
261
|
...booleanConfigHelper(false),
|
|
242
262
|
},
|
|
263
|
+
ammTxs: {
|
|
264
|
+
env: 'BOT_AMM_TXS',
|
|
265
|
+
description: 'Deploy an AMM and send swaps to it',
|
|
266
|
+
...booleanConfigHelper(false),
|
|
267
|
+
},
|
|
243
268
|
};
|
|
244
269
|
|
|
245
270
|
export function getBotConfigFromEnv(): BotConfig {
|
package/src/factory.ts
CHANGED
|
@@ -3,8 +3,8 @@ import { getDeployedTestAccountsWallets, getInitialTestAccounts } from '@aztec/a
|
|
|
3
3
|
import {
|
|
4
4
|
type AccountWallet,
|
|
5
5
|
AztecAddress,
|
|
6
|
-
type AztecNode,
|
|
7
6
|
BatchCall,
|
|
7
|
+
ContractBase,
|
|
8
8
|
ContractFunctionInteraction,
|
|
9
9
|
type DeployMethod,
|
|
10
10
|
type DeployOptions,
|
|
@@ -17,8 +17,10 @@ import {
|
|
|
17
17
|
} from '@aztec/aztec.js';
|
|
18
18
|
import { createEthereumChain, createL1Clients } from '@aztec/ethereum';
|
|
19
19
|
import { Fr } from '@aztec/foundation/fields';
|
|
20
|
+
import { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
20
21
|
import { EasyPrivateTokenContract } from '@aztec/noir-contracts.js/EasyPrivateToken';
|
|
21
22
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
23
|
+
import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
22
24
|
import { deriveSigningKey } from '@aztec/stdlib/keys';
|
|
23
25
|
import { makeTracedFetch } from '@aztec/telemetry-client';
|
|
24
26
|
|
|
@@ -31,11 +33,17 @@ const MIN_BALANCE = 1e3;
|
|
|
31
33
|
export class BotFactory {
|
|
32
34
|
private pxe: PXE;
|
|
33
35
|
private node?: AztecNode;
|
|
36
|
+
private nodeAdmin?: AztecNodeAdmin;
|
|
34
37
|
private log = createLogger('bot');
|
|
35
38
|
|
|
36
|
-
constructor(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
+
constructor(
|
|
40
|
+
private readonly config: BotConfig,
|
|
41
|
+
dependencies: { pxe?: PXE; nodeAdmin?: AztecNodeAdmin; node?: AztecNode },
|
|
42
|
+
) {
|
|
43
|
+
if (config.flushSetupTransactions && !dependencies.nodeAdmin) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`Either a node admin client or node admin url must be provided if transaction flushing is requested`,
|
|
46
|
+
);
|
|
39
47
|
}
|
|
40
48
|
if (config.senderPrivateKey && !dependencies.node) {
|
|
41
49
|
throw new Error(
|
|
@@ -47,6 +55,7 @@ export class BotFactory {
|
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
this.node = dependencies.node;
|
|
58
|
+
this.nodeAdmin = dependencies.nodeAdmin;
|
|
50
59
|
|
|
51
60
|
if (dependencies.pxe) {
|
|
52
61
|
this.log.info(`Using local PXE`);
|
|
@@ -69,6 +78,19 @@ export class BotFactory {
|
|
|
69
78
|
return { wallet, token, pxe: this.pxe, recipient };
|
|
70
79
|
}
|
|
71
80
|
|
|
81
|
+
public async setupAmm() {
|
|
82
|
+
const wallet = await this.setupAccount();
|
|
83
|
+
const token0 = await this.setupTokenContract(wallet, this.config.tokenSalt, 'BotToken0', 'BOT0');
|
|
84
|
+
const token1 = await this.setupTokenContract(wallet, this.config.tokenSalt, 'BotToken1', 'BOT1');
|
|
85
|
+
const liquidityToken = await this.setupTokenContract(wallet, this.config.tokenSalt, 'BotLPToken', 'BOTLP');
|
|
86
|
+
const amm = await this.setupAmmContract(wallet, this.config.tokenSalt, token0, token1, liquidityToken);
|
|
87
|
+
|
|
88
|
+
await this.fundAmm(wallet, amm, token0, token1);
|
|
89
|
+
this.log.info(`AMM initialized and funded`);
|
|
90
|
+
|
|
91
|
+
return { wallet, amm, token0, token1, pxe: this.pxe };
|
|
92
|
+
}
|
|
93
|
+
|
|
72
94
|
/**
|
|
73
95
|
* Checks if the sender account contract is initialized, and initializes it if necessary.
|
|
74
96
|
* @returns The sender wallet.
|
|
@@ -82,7 +104,7 @@ export class BotFactory {
|
|
|
82
104
|
}
|
|
83
105
|
|
|
84
106
|
private async setupAccountWithPrivateKey(privateKey: Fr) {
|
|
85
|
-
const salt = Fr.ONE;
|
|
107
|
+
const salt = this.config.senderSalt ?? Fr.ONE;
|
|
86
108
|
const signingKey = deriveSigningKey(privateKey);
|
|
87
109
|
const account = await getSchnorrAccount(this.pxe, privateKey, signingKey, salt);
|
|
88
110
|
const isInit = (await this.pxe.getContractMetadata(account.getAddress())).isContractInitialized;
|
|
@@ -94,12 +116,14 @@ export class BotFactory {
|
|
|
94
116
|
const address = account.getAddress();
|
|
95
117
|
this.log.info(`Deploying account at ${address}`);
|
|
96
118
|
|
|
97
|
-
const claim = await this.bridgeL1FeeJuice(address
|
|
119
|
+
const claim = await this.bridgeL1FeeJuice(address);
|
|
98
120
|
|
|
121
|
+
// docs:start:claim_and_deploy
|
|
99
122
|
const wallet = await account.getWallet();
|
|
100
123
|
const paymentMethod = new FeeJuicePaymentMethodWithClaim(wallet, claim);
|
|
101
124
|
const sentTx = account.deploy({ fee: { paymentMethod } });
|
|
102
125
|
const txHash = await sentTx.getTxHash();
|
|
126
|
+
// docs:end:claim_and_deploy
|
|
103
127
|
this.log.info(`Sent tx with hash ${txHash.toString()}`);
|
|
104
128
|
await this.tryFlushTxs();
|
|
105
129
|
this.log.verbose('Waiting for account deployment to settle');
|
|
@@ -166,6 +190,104 @@ export class BotFactory {
|
|
|
166
190
|
}
|
|
167
191
|
}
|
|
168
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Checks if the token contract is deployed and deploys it if necessary.
|
|
195
|
+
* @param wallet - Wallet to deploy the token contract from.
|
|
196
|
+
* @returns The TokenContract instance.
|
|
197
|
+
*/
|
|
198
|
+
private setupTokenContract(
|
|
199
|
+
wallet: AccountWallet,
|
|
200
|
+
contractAddressSalt: Fr,
|
|
201
|
+
name: string,
|
|
202
|
+
ticker: string,
|
|
203
|
+
decimals = 18,
|
|
204
|
+
): Promise<TokenContract> {
|
|
205
|
+
const deployOpts: DeployOptions = { contractAddressSalt, universalDeploy: true };
|
|
206
|
+
const deploy = TokenContract.deploy(wallet, wallet.getAddress(), name, ticker, decimals);
|
|
207
|
+
return this.registerOrDeployContract('Token - ' + name, deploy, deployOpts);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
private async setupAmmContract(
|
|
211
|
+
wallet: AccountWallet,
|
|
212
|
+
contractAddressSalt: Fr,
|
|
213
|
+
token0: TokenContract,
|
|
214
|
+
token1: TokenContract,
|
|
215
|
+
lpToken: TokenContract,
|
|
216
|
+
): Promise<AMMContract> {
|
|
217
|
+
const deployOpts: DeployOptions = { contractAddressSalt, universalDeploy: true };
|
|
218
|
+
const deploy = AMMContract.deploy(wallet, token0.address, token1.address, lpToken.address);
|
|
219
|
+
const amm = await this.registerOrDeployContract('AMM', deploy, deployOpts);
|
|
220
|
+
|
|
221
|
+
this.log.info(`AMM deployed at ${amm.address}`);
|
|
222
|
+
const minterTx = lpToken.methods.set_minter(amm.address, true).send();
|
|
223
|
+
this.log.info(`Set LP token minter to AMM txHash=${await minterTx.getTxHash()}`);
|
|
224
|
+
await minterTx.wait({ timeout: this.config.txMinedWaitSeconds });
|
|
225
|
+
this.log.info(`Liquidity token initialized`);
|
|
226
|
+
|
|
227
|
+
return amm;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private async fundAmm(
|
|
231
|
+
wallet: AccountWallet,
|
|
232
|
+
amm: AMMContract,
|
|
233
|
+
token0: TokenContract,
|
|
234
|
+
token1: TokenContract,
|
|
235
|
+
): Promise<void> {
|
|
236
|
+
const nonce = Fr.random();
|
|
237
|
+
|
|
238
|
+
// keep some tokens for swapping
|
|
239
|
+
const amount0Max = MINT_BALANCE / 2;
|
|
240
|
+
const amount0Min = MINT_BALANCE / 4;
|
|
241
|
+
const amount1Max = MINT_BALANCE / 2;
|
|
242
|
+
const amount1Min = MINT_BALANCE / 4;
|
|
243
|
+
|
|
244
|
+
const token0Authwit = await wallet.createAuthWit({
|
|
245
|
+
caller: amm.address,
|
|
246
|
+
action: token0.methods.transfer_to_public(wallet.getAddress(), amm.address, amount0Max, nonce),
|
|
247
|
+
});
|
|
248
|
+
const token1Authwit = await wallet.createAuthWit({
|
|
249
|
+
caller: amm.address,
|
|
250
|
+
action: token1.methods.transfer_to_public(wallet.getAddress(), amm.address, amount1Max, nonce),
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
this.log.info(`Minting tokens`);
|
|
254
|
+
const mintTx = new BatchCall(wallet, [
|
|
255
|
+
token0.methods.mint_to_private(wallet.getAddress(), wallet.getAddress(), MINT_BALANCE),
|
|
256
|
+
token1.methods.mint_to_private(wallet.getAddress(), wallet.getAddress(), MINT_BALANCE),
|
|
257
|
+
]).send();
|
|
258
|
+
|
|
259
|
+
this.log.info(`Sent mint tx: ${await mintTx.getTxHash()}`);
|
|
260
|
+
await mintTx.wait({ timeout: this.config.txMinedWaitSeconds });
|
|
261
|
+
|
|
262
|
+
this.log.info(`Funding AMM`);
|
|
263
|
+
const addLiquidityTx = amm.methods.add_liquidity(amount0Max, amount1Max, amount0Min, amount1Min, nonce).send({
|
|
264
|
+
authWitnesses: [token0Authwit, token1Authwit],
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
this.log.info(`Sent tx to add liquidity to the AMM: ${await addLiquidityTx.getTxHash()}`);
|
|
268
|
+
await addLiquidityTx.wait({ timeout: this.config.txMinedWaitSeconds });
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private async registerOrDeployContract<T extends ContractBase>(
|
|
272
|
+
name: string,
|
|
273
|
+
deploy: DeployMethod<T>,
|
|
274
|
+
deployOpts: DeployOptions,
|
|
275
|
+
): Promise<T> {
|
|
276
|
+
const address = (await deploy.getInstance(deployOpts)).address;
|
|
277
|
+
if ((await this.pxe.getContractMetadata(address)).isContractPubliclyDeployed) {
|
|
278
|
+
this.log.info(`Contract ${name} at ${address.toString()} already deployed`);
|
|
279
|
+
return deploy.register();
|
|
280
|
+
} else {
|
|
281
|
+
this.log.info(`Deploying contract ${name} at ${address.toString()}`);
|
|
282
|
+
const sentTx = deploy.send(deployOpts);
|
|
283
|
+
const txHash = await sentTx.getTxHash();
|
|
284
|
+
this.log.info(`Sent tx with hash ${txHash.toString()}`);
|
|
285
|
+
await this.tryFlushTxs();
|
|
286
|
+
this.log.verbose(`Waiting for contract ${name} setup to settle`);
|
|
287
|
+
return sentTx.deployed({ timeout: this.config.txMinedWaitSeconds });
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
169
291
|
/**
|
|
170
292
|
* Mints private and public tokens for the sender if their balance is below the minimum.
|
|
171
293
|
* @param token - Token contract.
|
|
@@ -209,7 +331,7 @@ export class BotFactory {
|
|
|
209
331
|
await sentTx.wait({ timeout: this.config.txMinedWaitSeconds });
|
|
210
332
|
}
|
|
211
333
|
|
|
212
|
-
private async bridgeL1FeeJuice(recipient: AztecAddress
|
|
334
|
+
private async bridgeL1FeeJuice(recipient: AztecAddress) {
|
|
213
335
|
const l1RpcUrls = this.config.l1RpcUrls;
|
|
214
336
|
if (!l1RpcUrls?.length) {
|
|
215
337
|
throw new Error('L1 Rpc url is required to bridge the fee juice to fund the deployment of the account.');
|
|
@@ -226,12 +348,13 @@ export class BotFactory {
|
|
|
226
348
|
const { publicClient, walletClient } = createL1Clients(chain.rpcUrls, mnemonicOrPrivateKey, chain.chainInfo);
|
|
227
349
|
|
|
228
350
|
const portal = await L1FeeJuicePortalManager.new(this.pxe, publicClient, walletClient, this.log);
|
|
229
|
-
const
|
|
351
|
+
const mintAmount = await portal.getTokenManager().getMintAmount();
|
|
352
|
+
const claim = await portal.bridgeTokensPublic(recipient, mintAmount, true /* mint */);
|
|
230
353
|
|
|
231
354
|
const isSynced = async () => await this.pxe.isL1ToL2MessageSynced(Fr.fromHexString(claim.messageHash));
|
|
232
355
|
await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 1);
|
|
233
356
|
|
|
234
|
-
this.log.info(`Created a claim for ${
|
|
357
|
+
this.log.info(`Created a claim for ${mintAmount} L1 fee juice to ${recipient}.`, claim);
|
|
235
358
|
|
|
236
359
|
// Progress by 2 L2 blocks so that the l1ToL2Message added above will be available to use on L2.
|
|
237
360
|
await this.advanceL2Block();
|
|
@@ -250,7 +373,7 @@ export class BotFactory {
|
|
|
250
373
|
if (this.config.flushSetupTransactions) {
|
|
251
374
|
this.log.verbose('Flushing transactions');
|
|
252
375
|
try {
|
|
253
|
-
await this.
|
|
376
|
+
await this.nodeAdmin!.flushTxs();
|
|
254
377
|
} catch (err) {
|
|
255
378
|
this.log.error(`Failed to flush transactions: ${err}`);
|
|
256
379
|
}
|
package/src/index.ts
CHANGED
package/src/runner.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { type AztecNode, type PXE, createAztecNodeClient, createLogger } from '@aztec/aztec.js';
|
|
2
2
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
3
|
+
import { type AztecNodeAdmin, createAztecNodeAdminClient } from '@aztec/stdlib/interfaces/client';
|
|
3
4
|
import { type TelemetryClient, type Traceable, type Tracer, makeTracedFetch, trackSpan } from '@aztec/telemetry-client';
|
|
4
5
|
|
|
6
|
+
import { AmmBot } from './amm_bot.js';
|
|
7
|
+
import type { BaseBot } from './base_bot.js';
|
|
5
8
|
import { Bot } from './bot.js';
|
|
6
9
|
import { type BotConfig, getVersions } from './config.js';
|
|
7
10
|
import type { BotRunnerApi } from './interface.js';
|
|
8
11
|
|
|
9
12
|
export class BotRunner implements BotRunnerApi, Traceable {
|
|
10
13
|
private log = createLogger('bot');
|
|
11
|
-
private bot?: Promise<
|
|
14
|
+
private bot?: Promise<BaseBot>;
|
|
12
15
|
private pxe?: PXE;
|
|
13
16
|
private node: AztecNode;
|
|
17
|
+
private nodeAdmin?: AztecNodeAdmin;
|
|
14
18
|
private runningPromise: RunningPromise;
|
|
15
19
|
private consecutiveErrors = 0;
|
|
16
20
|
private healthy = true;
|
|
@@ -19,15 +23,19 @@ export class BotRunner implements BotRunnerApi, Traceable {
|
|
|
19
23
|
|
|
20
24
|
public constructor(
|
|
21
25
|
private config: BotConfig,
|
|
22
|
-
dependencies: { pxe?: PXE; node?: AztecNode; telemetry: TelemetryClient },
|
|
26
|
+
dependencies: { pxe?: PXE; node?: AztecNode; nodeAdmin?: AztecNodeAdmin; telemetry: TelemetryClient },
|
|
23
27
|
) {
|
|
24
28
|
this.tracer = dependencies.telemetry.getTracer('Bot');
|
|
25
29
|
this.pxe = dependencies.pxe;
|
|
26
30
|
if (!dependencies.node && !config.nodeUrl) {
|
|
27
31
|
throw new Error(`Missing node URL in config or dependencies`);
|
|
28
32
|
}
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
const versions = getVersions();
|
|
34
|
+
const fetch = makeTracedFetch([1, 2, 3], true);
|
|
35
|
+
this.node = dependencies.node ?? createAztecNodeClient(config.nodeUrl!, versions, fetch);
|
|
36
|
+
this.nodeAdmin =
|
|
37
|
+
dependencies.nodeAdmin ??
|
|
38
|
+
(config.nodeAdminUrl ? createAztecNodeAdminClient(config.nodeAdminUrl, versions, fetch) : undefined);
|
|
31
39
|
this.runningPromise = new RunningPromise(() => this.#work(), this.log, config.txIntervalSeconds * 1000);
|
|
32
40
|
}
|
|
33
41
|
|
|
@@ -131,7 +139,9 @@ export class BotRunner implements BotRunnerApi, Traceable {
|
|
|
131
139
|
|
|
132
140
|
async #createBot() {
|
|
133
141
|
try {
|
|
134
|
-
this.bot =
|
|
142
|
+
this.bot = this.config.ammTxs
|
|
143
|
+
? AmmBot.create(this.config, { pxe: this.pxe, node: this.node, nodeAdmin: this.nodeAdmin })
|
|
144
|
+
: Bot.create(this.config, { pxe: this.pxe, node: this.node, nodeAdmin: this.nodeAdmin });
|
|
135
145
|
await this.bot;
|
|
136
146
|
} catch (err) {
|
|
137
147
|
this.log.error(`Error setting up bot: ${err}`);
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ContractBase } from '@aztec/aztec.js';
|
|
2
|
+
import type { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
1
3
|
import type { EasyPrivateTokenContract } from '@aztec/noir-contracts.js/EasyPrivateToken';
|
|
2
4
|
import type { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
3
5
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
@@ -22,6 +24,10 @@ export async function getPrivateBalance(token: EasyPrivateTokenContract, who: Az
|
|
|
22
24
|
return privateBalance;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
export function isStandardTokenContract(token:
|
|
27
|
+
export function isStandardTokenContract(token: ContractBase): token is TokenContract {
|
|
26
28
|
return 'mint_to_public' in token.methods;
|
|
27
29
|
}
|
|
30
|
+
|
|
31
|
+
export function isAMMContract(contract: ContractBase): contract is AMMContract {
|
|
32
|
+
return 'add_liquidity' in contract.methods;
|
|
33
|
+
}
|