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