-
Notifications
You must be signed in to change notification settings - Fork 594
Expand file tree
/
Copy pathbot.ts
More file actions
97 lines (80 loc) · 3.28 KB
/
bot.ts
File metadata and controls
97 lines (80 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import {
type AztecAddress,
BatchCall,
FeeJuicePaymentMethod,
NoFeePaymentMethod,
type SendMethodOptions,
type Wallet,
createDebugLogger,
} from '@aztec/aztec.js';
import { type FunctionCall, type PXE } from '@aztec/circuit-types';
import { GasSettings } from '@aztec/circuits.js';
import { times } from '@aztec/foundation/collection';
import { type TokenContract } from '@aztec/noir-contracts.js';
import { type BotConfig } from './config.js';
import { BotFactory } from './factory.js';
import { getBalances } from './utils.js';
const TRANSFER_AMOUNT = 1;
export class Bot {
private log = createDebugLogger('aztec:bot');
protected constructor(
public readonly wallet: Wallet,
public readonly token: TokenContract,
public readonly recipient: AztecAddress,
public readonly config: BotConfig,
) {}
static async create(config: BotConfig, dependencies: { pxe?: PXE } = {}): Promise<Bot> {
const { wallet, token, recipient } = await new BotFactory(config, dependencies).setup();
return new Bot(wallet, token, recipient, config);
}
public async run() {
const logCtx = { runId: Date.now() * 1000 + Math.floor(Math.random() * 1000) };
const { privateTransfersPerTx, publicTransfersPerTx, feePaymentMethod } = this.config;
const { token, recipient, wallet } = this;
const sender = wallet.getAddress();
this.log.verbose(
`Sending tx with ${feePaymentMethod} fee with ${privateTransfersPerTx} private and ${publicTransfersPerTx} public transfers`,
logCtx,
);
const calls: FunctionCall[] = [
...times(privateTransfersPerTx, () => token.methods.transfer(recipient, TRANSFER_AMOUNT).request()),
...times(publicTransfersPerTx, () =>
token.methods.transfer_public(sender, recipient, TRANSFER_AMOUNT, 0).request(),
),
];
const paymentMethod =
feePaymentMethod === 'fee_juice' ? new FeeJuicePaymentMethod(sender) : new NoFeePaymentMethod();
const gasSettings = GasSettings.default();
const opts: SendMethodOptions = { estimateGas: true, fee: { paymentMethod, gasSettings } };
const batch = new BatchCall(wallet, calls);
this.log.verbose(`Creating batch execution request with ${calls.length} calls`, logCtx);
await batch.create(opts);
this.log.verbose(`Simulating transaction`, logCtx);
await batch.simulate();
this.log.verbose(`Proving transaction`, logCtx);
await batch.prove(opts);
this.log.verbose(`Sending tx`, logCtx);
const tx = batch.send(opts);
const txHash = await tx.getTxHash();
if (this.config.followChain === 'NONE') {
this.log.info(`Transaction ${txHash} sent, not waiting for it to be mined`);
return;
}
this.log.verbose(
`Awaiting tx ${txHash} to be on the ${this.config.followChain} (timeout ${this.config.txMinedWaitSeconds}s)`,
logCtx,
);
const receipt = await tx.wait({
timeout: this.config.txMinedWaitSeconds,
provenTimeout: this.config.txMinedWaitSeconds,
proven: this.config.followChain === 'PROVEN',
});
this.log.info(`Tx ${receipt.txHash} mined in block ${receipt.blockNumber}`, logCtx);
}
public async getBalances() {
return {
sender: await getBalances(this.token, this.wallet.getAddress()),
recipient: await getBalances(this.token, this.recipient),
};
}
}