@aztec/bot 0.0.0-test.1 → 0.0.1-commit.5476d83
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 +97 -0
- package/dest/base_bot.d.ts +21 -0
- package/dest/base_bot.d.ts.map +1 -0
- package/dest/base_bot.js +80 -0
- package/dest/bot.d.ts +13 -18
- package/dest/bot.d.ts.map +1 -1
- package/dest/bot.js +24 -86
- package/dest/config.d.ts +82 -57
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +55 -32
- package/dest/factory.d.ts +31 -27
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +277 -132
- package/dest/index.d.ts +4 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +3 -1
- package/dest/interface.d.ts +12 -1
- package/dest/interface.d.ts.map +1 -1
- package/dest/interface.js +5 -0
- package/dest/rpc.d.ts +1 -7
- package/dest/rpc.d.ts.map +1 -1
- package/dest/rpc.js +0 -11
- package/dest/runner.d.ts +15 -11
- package/dest/runner.d.ts.map +1 -1
- package/dest/runner.js +33 -25
- package/dest/store/bot_store.d.ts +44 -0
- package/dest/store/bot_store.d.ts.map +1 -0
- package/dest/store/bot_store.js +107 -0
- package/dest/store/index.d.ts +2 -0
- package/dest/store/index.d.ts.map +1 -0
- package/dest/store/index.js +1 -0
- package/dest/utils.d.ts +8 -5
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +14 -5
- package/package.json +27 -23
- package/src/amm_bot.ts +124 -0
- package/src/base_bot.ts +96 -0
- package/src/bot.ts +52 -103
- package/src/config.ts +66 -38
- package/src/factory.ts +335 -146
- package/src/index.ts +3 -1
- package/src/interface.ts +9 -0
- package/src/rpc.ts +0 -13
- package/src/runner.ts +38 -21
- package/src/store/bot_store.ts +141 -0
- package/src/store/index.ts +1 -0
- package/src/utils.ts +17 -6
package/dest/runner.d.ts
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AztecNode } from '@aztec/aztec.js/node';
|
|
2
|
+
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
2
3
|
import { type TelemetryClient, type Traceable, type Tracer } from '@aztec/telemetry-client';
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
4
|
+
import type { TestWallet } from '@aztec/test-wallet/server';
|
|
5
|
+
import type { BotConfig } from './config.js';
|
|
6
|
+
import type { BotInfo, BotRunnerApi } from './interface.js';
|
|
7
|
+
import { BotStore } from './store/index.js';
|
|
5
8
|
export declare class BotRunner implements BotRunnerApi, Traceable {
|
|
6
9
|
#private;
|
|
7
10
|
private config;
|
|
11
|
+
private readonly wallet;
|
|
12
|
+
private readonly aztecNode;
|
|
13
|
+
private readonly telemetry;
|
|
14
|
+
private readonly aztecNodeAdmin;
|
|
15
|
+
private readonly store;
|
|
8
16
|
private log;
|
|
9
17
|
private bot?;
|
|
10
|
-
private pxe?;
|
|
11
|
-
private node;
|
|
12
18
|
private runningPromise;
|
|
13
19
|
private consecutiveErrors;
|
|
14
20
|
private healthy;
|
|
15
21
|
readonly tracer: Tracer;
|
|
16
|
-
constructor(config: BotConfig,
|
|
17
|
-
pxe?: PXE;
|
|
18
|
-
node?: AztecNode;
|
|
19
|
-
telemetry: TelemetryClient;
|
|
20
|
-
});
|
|
22
|
+
constructor(config: BotConfig, wallet: TestWallet, aztecNode: AztecNode, telemetry: TelemetryClient, aztecNodeAdmin: AztecNodeAdmin | undefined, store: BotStore);
|
|
21
23
|
/** Initializes the bot if needed. Blocks until the bot setup is finished. */
|
|
22
24
|
setup(): Promise<void>;
|
|
23
25
|
private doSetup;
|
|
@@ -45,5 +47,7 @@ export declare class BotRunner implements BotRunnerApi, Traceable {
|
|
|
45
47
|
run(): Promise<void>;
|
|
46
48
|
/** Returns the current configuration for the bot. */
|
|
47
49
|
getConfig(): Promise<BotConfig>;
|
|
50
|
+
/** Returns the bot sender address. */
|
|
51
|
+
getInfo(): Promise<BotInfo>;
|
|
48
52
|
}
|
|
49
|
-
//# sourceMappingURL=
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVubmVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcnVubmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBR3RELE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBRSxLQUFLLFNBQVMsRUFBRSxLQUFLLE1BQU0sRUFBYSxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZHLE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBSzVELE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3QyxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRTVDLHFCQUFhLFNBQVUsWUFBVyxZQUFZLEVBQUUsU0FBUzs7SUFVckQsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU07SUFDdkIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTO0lBQzFCLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUztJQUMxQixPQUFPLENBQUMsUUFBUSxDQUFDLGNBQWM7SUFDL0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLO0lBZHhCLE9BQU8sQ0FBQyxHQUFHLENBQXVCO0lBQ2xDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBbUI7SUFDL0IsT0FBTyxDQUFDLGNBQWMsQ0FBaUI7SUFDdkMsT0FBTyxDQUFDLGlCQUFpQixDQUFLO0lBQzlCLE9BQU8sQ0FBQyxPQUFPLENBQVE7SUFFdkIsU0FBZ0IsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUUvQixZQUNVLE1BQU0sRUFBRSxTQUFTLEVBQ1IsTUFBTSxFQUFFLFVBQVUsRUFDbEIsU0FBUyxFQUFFLFNBQVMsRUFDcEIsU0FBUyxFQUFFLGVBQWUsRUFDMUIsY0FBYyxFQUFFLGNBQWMsR0FBRyxTQUFTLEVBQzFDLEtBQUssRUFBRSxRQUFRLEVBS2pDO0lBRUQsNkVBQTZFO0lBQ2hFLEtBQUssa0JBSWpCO1lBR2EsT0FBTztJQU1yQjs7O09BR0c7SUFDVSxLQUFLLGtCQU1qQjtJQUVEOztPQUVHO0lBQ1UsSUFBSSxrQkFPaEI7SUFFTSxTQUFTLFlBRWY7SUFFRCwwQ0FBMEM7SUFDbkMsU0FBUyxZQUVmO0lBRUQ7OztPQUdHO0lBQ1UsTUFBTSxDQUFDLE1BQU0sRUFBRSxTQUFTLGlCQWFwQztJQUVEOzs7T0FHRztJQUNVLEdBQUcsa0JBc0JmO0lBRUQscURBQXFEO0lBQzlDLFNBQVMsdUJBR2Y7SUFFRCxzQ0FBc0M7SUFDekIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FNdkM7Q0F1Q0YifQ==
|
package/dest/runner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,MAAM,EAAa,MAAM,yBAAyB,CAAC;AACvG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAK5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,qBAAa,SAAU,YAAW,YAAY,EAAE,SAAS;;IAUrD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAdxB,OAAO,CAAC,GAAG,CAAuB;IAClC,OAAO,CAAC,GAAG,CAAC,CAAmB;IAC/B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,OAAO,CAAQ;IAEvB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAE/B,YACU,MAAM,EAAE,SAAS,EACR,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,eAAe,EAC1B,cAAc,EAAE,cAAc,GAAG,SAAS,EAC1C,KAAK,EAAE,QAAQ,EAKjC;IAED,6EAA6E;IAChE,KAAK,kBAIjB;YAGa,OAAO;IAMrB;;;OAGG;IACU,KAAK,kBAMjB;IAED;;OAEG;IACU,IAAI,kBAOhB;IAEM,SAAS,YAEf;IAED,0CAA0C;IACnC,SAAS,YAEf;IAED;;;OAGG;IACU,MAAM,CAAC,MAAM,EAAE,SAAS,iBAapC;IAED;;;OAGG;IACU,GAAG,kBAsBf;IAED,qDAAqD;IAC9C,SAAS,uBAGf;IAED,sCAAsC;IACzB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAMvC;CAuCF"}
|
package/dest/runner.js
CHANGED
|
@@ -4,36 +4,36 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
4
4
|
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
}
|
|
7
|
-
import {
|
|
7
|
+
import { createLogger } from '@aztec/aztec.js/log';
|
|
8
|
+
import { omit } from '@aztec/foundation/collection';
|
|
8
9
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
9
|
-
import {
|
|
10
|
+
import { trackSpan } from '@aztec/telemetry-client';
|
|
11
|
+
import { AmmBot } from './amm_bot.js';
|
|
10
12
|
import { Bot } from './bot.js';
|
|
11
|
-
import { getVersions } from './config.js';
|
|
12
13
|
export class BotRunner {
|
|
13
14
|
config;
|
|
15
|
+
wallet;
|
|
16
|
+
aztecNode;
|
|
17
|
+
telemetry;
|
|
18
|
+
aztecNodeAdmin;
|
|
19
|
+
store;
|
|
14
20
|
log;
|
|
15
21
|
bot;
|
|
16
|
-
pxe;
|
|
17
|
-
node;
|
|
18
22
|
runningPromise;
|
|
19
23
|
consecutiveErrors;
|
|
20
24
|
healthy;
|
|
21
25
|
tracer;
|
|
22
|
-
constructor(config,
|
|
26
|
+
constructor(config, wallet, aztecNode, telemetry, aztecNodeAdmin, store){
|
|
23
27
|
this.config = config;
|
|
28
|
+
this.wallet = wallet;
|
|
29
|
+
this.aztecNode = aztecNode;
|
|
30
|
+
this.telemetry = telemetry;
|
|
31
|
+
this.aztecNodeAdmin = aztecNodeAdmin;
|
|
32
|
+
this.store = store;
|
|
24
33
|
this.log = createLogger('bot');
|
|
25
34
|
this.consecutiveErrors = 0;
|
|
26
35
|
this.healthy = true;
|
|
27
|
-
this.tracer =
|
|
28
|
-
this.pxe = dependencies.pxe;
|
|
29
|
-
if (!dependencies.node && !config.nodeUrl) {
|
|
30
|
-
throw new Error(`Missing node URL in config or dependencies`);
|
|
31
|
-
}
|
|
32
|
-
this.node = dependencies.node ?? createAztecNodeClient(config.nodeUrl, getVersions(), makeTracedFetch([
|
|
33
|
-
1,
|
|
34
|
-
2,
|
|
35
|
-
3
|
|
36
|
-
], true));
|
|
36
|
+
this.tracer = telemetry.getTracer('Bot');
|
|
37
37
|
this.runningPromise = new RunningPromise(()=>this.#work(), this.log, config.txIntervalSeconds * 1000);
|
|
38
38
|
}
|
|
39
39
|
/** Initializes the bot if needed. Blocks until the bot setup is finished. */ async setup() {
|
|
@@ -63,6 +63,7 @@ export class BotRunner {
|
|
|
63
63
|
this.log.verbose(`Stopping bot`);
|
|
64
64
|
await this.runningPromise.stop();
|
|
65
65
|
}
|
|
66
|
+
await this.store.close();
|
|
66
67
|
this.log.info(`Stopped bot`);
|
|
67
68
|
}
|
|
68
69
|
isHealthy() {
|
|
@@ -116,14 +117,21 @@ export class BotRunner {
|
|
|
116
117
|
}
|
|
117
118
|
}
|
|
118
119
|
/** Returns the current configuration for the bot. */ getConfig() {
|
|
119
|
-
|
|
120
|
+
const redacted = omit(this.config, 'l1Mnemonic', 'l1PrivateKey', 'senderPrivateKey');
|
|
121
|
+
return Promise.resolve(redacted);
|
|
122
|
+
}
|
|
123
|
+
/** Returns the bot sender address. */ async getInfo() {
|
|
124
|
+
if (!this.bot) {
|
|
125
|
+
throw new Error(`Bot is not initialized`);
|
|
126
|
+
}
|
|
127
|
+
const botAddress = await this.bot.then((b)=>b.defaultAccountAddress);
|
|
128
|
+
return {
|
|
129
|
+
botAddress
|
|
130
|
+
};
|
|
120
131
|
}
|
|
121
132
|
async #createBot() {
|
|
122
133
|
try {
|
|
123
|
-
this.bot = Bot.create(this.config,
|
|
124
|
-
pxe: this.pxe,
|
|
125
|
-
node: this.node
|
|
126
|
-
});
|
|
134
|
+
this.bot = this.config.ammTxs ? AmmBot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store) : Bot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store);
|
|
127
135
|
await this.bot;
|
|
128
136
|
} catch (err) {
|
|
129
137
|
this.log.error(`Error setting up bot: ${err}`);
|
|
@@ -132,15 +140,15 @@ export class BotRunner {
|
|
|
132
140
|
}
|
|
133
141
|
async #work() {
|
|
134
142
|
if (this.config.maxPendingTxs > 0) {
|
|
135
|
-
const
|
|
136
|
-
if (
|
|
137
|
-
this.log.verbose(`Not sending bot tx since node has ${
|
|
143
|
+
const pendingTxCount = await this.aztecNode.getPendingTxCount();
|
|
144
|
+
if (pendingTxCount >= this.config.maxPendingTxs) {
|
|
145
|
+
this.log.verbose(`Not sending bot tx since node has ${pendingTxCount} pending txs`);
|
|
138
146
|
return;
|
|
139
147
|
}
|
|
140
148
|
}
|
|
141
149
|
try {
|
|
142
150
|
await this.run();
|
|
143
|
-
} catch
|
|
151
|
+
} catch {
|
|
144
152
|
// Already logged in run()
|
|
145
153
|
if (this.config.maxConsecutiveErrors > 0 && this.consecutiveErrors >= this.config.maxConsecutiveErrors) {
|
|
146
154
|
this.log.error(`Too many errors bot is unhealthy`);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import type { L2AmountClaim } from '@aztec/aztec.js/ethereum';
|
|
3
|
+
import { type Logger } from '@aztec/foundation/log';
|
|
4
|
+
import type { AztecAsyncKVStore } from '@aztec/kv-store';
|
|
5
|
+
export interface BridgeClaimData {
|
|
6
|
+
claim: L2AmountClaim;
|
|
7
|
+
timestamp: number;
|
|
8
|
+
recipient: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Simple data store for the bot to persist L1 bridge claims.
|
|
12
|
+
*/
|
|
13
|
+
export declare class BotStore {
|
|
14
|
+
private readonly store;
|
|
15
|
+
private readonly log;
|
|
16
|
+
static readonly SCHEMA_VERSION: number;
|
|
17
|
+
private readonly bridgeClaims;
|
|
18
|
+
constructor(store: AztecAsyncKVStore, log?: Logger);
|
|
19
|
+
/**
|
|
20
|
+
* Saves a bridge claim for a recipient.
|
|
21
|
+
*/
|
|
22
|
+
saveBridgeClaim(recipient: AztecAddress, claim: L2AmountClaim): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Gets a bridge claim for a recipient if it exists.
|
|
25
|
+
*/
|
|
26
|
+
getBridgeClaim(recipient: AztecAddress): Promise<BridgeClaimData | undefined>;
|
|
27
|
+
/**
|
|
28
|
+
* Deletes a bridge claim for a recipient.
|
|
29
|
+
*/
|
|
30
|
+
deleteBridgeClaim(recipient: AztecAddress): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Gets all stored bridge claims.
|
|
33
|
+
*/
|
|
34
|
+
getAllBridgeClaims(): Promise<BridgeClaimData[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Cleans up old bridge claims (older than 24 hours).
|
|
37
|
+
*/
|
|
38
|
+
cleanupOldClaims(maxAgeMs?: number): Promise<number>;
|
|
39
|
+
/**
|
|
40
|
+
* Closes the store.
|
|
41
|
+
*/
|
|
42
|
+
close(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm90X3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmUvYm90X3N0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN6RCxPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU5RCxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFDbEUsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQWlCLE1BQU0saUJBQWlCLENBQUM7QUFFeEUsTUFBTSxXQUFXLGVBQWU7SUFDOUIsS0FBSyxFQUFFLGFBQWEsQ0FBQztJQUNyQixTQUFTLEVBQUUsTUFBTSxDQUFDO0lBQ2xCLFNBQVMsRUFBRSxNQUFNLENBQUM7Q0FDbkI7QUFFRDs7R0FFRztBQUNILHFCQUFhLFFBQVE7SUFLakIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxLQUFLO0lBQ3RCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRztJQUx0QixnQkFBdUIsY0FBYyxTQUFLO0lBQzFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFnQztJQUU3RCxZQUNtQixLQUFLLEVBQUUsaUJBQWlCLEVBQ3hCLEdBQUcsR0FBRSxNQUFrQyxFQUd6RDtJQUVEOztPQUVHO0lBQ1UsZUFBZSxDQUFDLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLGFBQWEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBa0J6RjtJQUVEOztPQUVHO0lBQ1UsY0FBYyxDQUFDLFNBQVMsRUFBRSxZQUFZLEdBQUcsT0FBTyxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUMsQ0FzQnpGO0lBRUQ7O09BRUc7SUFDVSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsWUFBWSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FHckU7SUFFRDs7T0FFRztJQUNVLGtCQUFrQixJQUFJLE9BQU8sQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQXdCNUQ7SUFFRDs7T0FFRztJQUNVLGdCQUFnQixDQUFDLFFBQVEsR0FBRSxNQUE0QixHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FlckY7SUFFRDs7T0FFRztJQUNVLEtBQUssSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBR2xDO0NBQ0YifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bot_store.d.ts","sourceRoot":"","sources":["../../src/store/bot_store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,iBAAiB,CAAC;AAExE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,QAAQ;IAKjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IALtB,gBAAuB,cAAc,SAAK;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAgC;IAE7D,YACmB,KAAK,EAAE,iBAAiB,EACxB,GAAG,GAAE,MAAkC,EAGzD;IAED;;OAEG;IACU,eAAe,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBzF;IAED;;OAEG;IACU,cAAc,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAsBzF;IAED;;OAEG;IACU,iBAAiB,CAAC,SAAS,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrE;IAED;;OAEG;IACU,kBAAkB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAwB5D;IAED;;OAEG;IACU,gBAAgB,CAAC,QAAQ,GAAE,MAA4B,GAAG,OAAO,CAAC,MAAM,CAAC,CAerF;IAED;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAGlC;CACF"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/fields';
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
/**
|
|
4
|
+
* Simple data store for the bot to persist L1 bridge claims.
|
|
5
|
+
*/ export class BotStore {
|
|
6
|
+
store;
|
|
7
|
+
log;
|
|
8
|
+
static SCHEMA_VERSION = 1;
|
|
9
|
+
bridgeClaims;
|
|
10
|
+
constructor(store, log = createLogger('bot:store')){
|
|
11
|
+
this.store = store;
|
|
12
|
+
this.log = log;
|
|
13
|
+
this.bridgeClaims = store.openMap('bridge_claims');
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Saves a bridge claim for a recipient.
|
|
17
|
+
*/ async saveBridgeClaim(recipient, claim) {
|
|
18
|
+
// Convert Fr fields and BigInts to strings for JSON serialization
|
|
19
|
+
const serializableClaim = {
|
|
20
|
+
claimAmount: claim.claimAmount.toString(),
|
|
21
|
+
claimSecret: claim.claimSecret.toString(),
|
|
22
|
+
claimSecretHash: claim.claimSecretHash.toString(),
|
|
23
|
+
messageHash: claim.messageHash,
|
|
24
|
+
messageLeafIndex: claim.messageLeafIndex.toString()
|
|
25
|
+
};
|
|
26
|
+
const data = {
|
|
27
|
+
claim: serializableClaim,
|
|
28
|
+
timestamp: Date.now(),
|
|
29
|
+
recipient: recipient.toString()
|
|
30
|
+
};
|
|
31
|
+
await this.bridgeClaims.set(recipient.toString(), JSON.stringify(data));
|
|
32
|
+
this.log.info(`Saved bridge claim for ${recipient.toString()}`);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Gets a bridge claim for a recipient if it exists.
|
|
36
|
+
*/ async getBridgeClaim(recipient) {
|
|
37
|
+
const data = await this.bridgeClaims.getAsync(recipient.toString());
|
|
38
|
+
if (!data) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const parsed = JSON.parse(data);
|
|
42
|
+
// Reconstruct L2AmountClaim from serialized data
|
|
43
|
+
const claim = {
|
|
44
|
+
claimAmount: BigInt(parsed.claim.claimAmount),
|
|
45
|
+
claimSecret: Fr.fromString(parsed.claim.claimSecret),
|
|
46
|
+
claimSecretHash: Fr.fromString(parsed.claim.claimSecretHash),
|
|
47
|
+
messageHash: parsed.claim.messageHash,
|
|
48
|
+
messageLeafIndex: BigInt(parsed.claim.messageLeafIndex)
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
claim,
|
|
52
|
+
timestamp: parsed.timestamp,
|
|
53
|
+
recipient: parsed.recipient
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Deletes a bridge claim for a recipient.
|
|
58
|
+
*/ async deleteBridgeClaim(recipient) {
|
|
59
|
+
await this.bridgeClaims.delete(recipient.toString());
|
|
60
|
+
this.log.info(`Deleted bridge claim for ${recipient.toString()}`);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Gets all stored bridge claims.
|
|
64
|
+
*/ async getAllBridgeClaims() {
|
|
65
|
+
const claims = [];
|
|
66
|
+
const entries = this.bridgeClaims.entriesAsync();
|
|
67
|
+
for await (const [_, data] of entries){
|
|
68
|
+
const parsed = JSON.parse(data);
|
|
69
|
+
// Reconstruct L2AmountClaim from serialized data
|
|
70
|
+
const claim = {
|
|
71
|
+
claimAmount: BigInt(parsed.claim.claimAmount),
|
|
72
|
+
claimSecret: Fr.fromString(parsed.claim.claimSecret),
|
|
73
|
+
claimSecretHash: Fr.fromString(parsed.claim.claimSecretHash),
|
|
74
|
+
messageHash: parsed.claim.messageHash,
|
|
75
|
+
messageLeafIndex: BigInt(parsed.claim.messageLeafIndex)
|
|
76
|
+
};
|
|
77
|
+
claims.push({
|
|
78
|
+
claim,
|
|
79
|
+
timestamp: parsed.timestamp,
|
|
80
|
+
recipient: parsed.recipient
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return claims;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Cleans up old bridge claims (older than 24 hours).
|
|
87
|
+
*/ async cleanupOldClaims(maxAgeMs = 24 * 60 * 60 * 1000) {
|
|
88
|
+
const now = Date.now();
|
|
89
|
+
let cleanedCount = 0;
|
|
90
|
+
const entries = this.bridgeClaims.entriesAsync();
|
|
91
|
+
for await (const [key, data] of entries){
|
|
92
|
+
const parsed = JSON.parse(data);
|
|
93
|
+
if (now - parsed.timestamp > maxAgeMs) {
|
|
94
|
+
await this.bridgeClaims.delete(key);
|
|
95
|
+
cleanedCount++;
|
|
96
|
+
this.log.info(`Cleaned up old bridge claim for ${parsed.recipient}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return cleanedCount;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Closes the store.
|
|
103
|
+
*/ async close() {
|
|
104
|
+
await this.store.close();
|
|
105
|
+
this.log.info('Closed bot data store');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { BotStore, type BridgeClaimData } from './bot_store.js';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUMifQ==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BotStore } from './bot_store.js';
|
package/dest/utils.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ContractBase } from '@aztec/aztec.js/contracts';
|
|
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
|
/**
|
|
@@ -7,10 +9,11 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
7
9
|
* @param who - Address to get the balance for.
|
|
8
10
|
* @returns - Private and public token balances as bigints.
|
|
9
11
|
*/
|
|
10
|
-
export declare function getBalances(token: TokenContract, who: AztecAddress): Promise<{
|
|
12
|
+
export declare function getBalances(token: TokenContract, who: AztecAddress, from?: AztecAddress): Promise<{
|
|
11
13
|
privateBalance: bigint;
|
|
12
14
|
publicBalance: bigint;
|
|
13
15
|
}>;
|
|
14
|
-
export declare function getPrivateBalance(token:
|
|
15
|
-
export declare function isStandardTokenContract(token:
|
|
16
|
-
|
|
16
|
+
export declare function getPrivateBalance(token: PrivateTokenContract, who: AztecAddress, from?: AztecAddress): Promise<bigint>;
|
|
17
|
+
export declare function isStandardTokenContract(token: ContractBase): token is TokenContract;
|
|
18
|
+
export declare function isAMMContract(contract: ContractBase): contract is AMMContract;
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDekQsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNsRixPQUFPLEtBQUssRUFBRSxhQUFhLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUVoRTs7Ozs7R0FLRztBQUNILHdCQUFzQixXQUFXLENBQy9CLEtBQUssRUFBRSxhQUFhLEVBQ3BCLEdBQUcsRUFBRSxZQUFZLEVBQ2pCLElBQUksQ0FBQyxFQUFFLFlBQVksR0FDbEIsT0FBTyxDQUFDO0lBQUUsY0FBYyxFQUFFLE1BQU0sQ0FBQztJQUFDLGFBQWEsRUFBRSxNQUFNLENBQUE7Q0FBRSxDQUFDLENBSTVEO0FBRUQsd0JBQXNCLGlCQUFpQixDQUNyQyxLQUFLLEVBQUUsb0JBQW9CLEVBQzNCLEdBQUcsRUFBRSxZQUFZLEVBQ2pCLElBQUksQ0FBQyxFQUFFLFlBQVksR0FDbEIsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUdqQjtBQUVELHdCQUFnQix1QkFBdUIsQ0FBQyxLQUFLLEVBQUUsWUFBWSxHQUFHLEtBQUssSUFBSSxhQUFhLENBRW5GO0FBRUQsd0JBQWdCLGFBQWEsQ0FBQyxRQUFRLEVBQUUsWUFBWSxHQUFHLFFBQVEsSUFBSSxXQUFXLENBRTdFIn0=
|
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,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,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,EACjB,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,CAI5D;AAED,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,oBAAoB,EAC3B,GAAG,EAAE,YAAY,EACjB,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC,MAAM,CAAC,CAGjB;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
|
@@ -3,18 +3,27 @@
|
|
|
3
3
|
* @param token - Token contract.
|
|
4
4
|
* @param who - Address to get the balance for.
|
|
5
5
|
* @returns - Private and public token balances as bigints.
|
|
6
|
-
*/ export async function getBalances(token, who) {
|
|
7
|
-
const privateBalance = await token.methods.balance_of_private(who).simulate(
|
|
8
|
-
|
|
6
|
+
*/ export async function getBalances(token, who, from) {
|
|
7
|
+
const privateBalance = await token.methods.balance_of_private(who).simulate({
|
|
8
|
+
from: from ?? who
|
|
9
|
+
});
|
|
10
|
+
const publicBalance = await token.methods.balance_of_public(who).simulate({
|
|
11
|
+
from: from ?? who
|
|
12
|
+
});
|
|
9
13
|
return {
|
|
10
14
|
privateBalance,
|
|
11
15
|
publicBalance
|
|
12
16
|
};
|
|
13
17
|
}
|
|
14
|
-
export async function getPrivateBalance(token, who) {
|
|
15
|
-
const privateBalance = await token.methods.get_balance(who).simulate(
|
|
18
|
+
export async function getPrivateBalance(token, who, from) {
|
|
19
|
+
const privateBalance = await token.methods.get_balance(who).simulate({
|
|
20
|
+
from: 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-commit.5476d83",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -10,11 +10,9 @@
|
|
|
10
10
|
"../package.common.json"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "yarn clean &&
|
|
14
|
-
"build:dev": "
|
|
13
|
+
"build": "yarn clean && tsgo -b",
|
|
14
|
+
"build:dev": "tsgo -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,39 @@
|
|
|
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/
|
|
61
|
-
"@aztec/noir-
|
|
62
|
-
"@aztec/protocol-
|
|
63
|
-
"@aztec/
|
|
64
|
-
"@aztec/
|
|
57
|
+
"@aztec/accounts": "0.0.1-commit.5476d83",
|
|
58
|
+
"@aztec/aztec.js": "0.0.1-commit.5476d83",
|
|
59
|
+
"@aztec/entrypoints": "0.0.1-commit.5476d83",
|
|
60
|
+
"@aztec/ethereum": "0.0.1-commit.5476d83",
|
|
61
|
+
"@aztec/foundation": "0.0.1-commit.5476d83",
|
|
62
|
+
"@aztec/kv-store": "0.0.1-commit.5476d83",
|
|
63
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.5476d83",
|
|
64
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.5476d83",
|
|
65
|
+
"@aztec/protocol-contracts": "0.0.1-commit.5476d83",
|
|
66
|
+
"@aztec/stdlib": "0.0.1-commit.5476d83",
|
|
67
|
+
"@aztec/telemetry-client": "0.0.1-commit.5476d83",
|
|
68
|
+
"@aztec/test-wallet": "0.0.1-commit.5476d83",
|
|
65
69
|
"source-map-support": "^0.5.21",
|
|
66
70
|
"tslib": "^2.4.0",
|
|
67
71
|
"zod": "^3.23.8"
|
|
68
72
|
},
|
|
69
73
|
"devDependencies": {
|
|
70
|
-
"@jest/globals": "^
|
|
71
|
-
"@types/jest": "^
|
|
72
|
-
"@types/
|
|
73
|
-
"@types/node": "^18.7.23",
|
|
74
|
+
"@jest/globals": "^30.0.0",
|
|
75
|
+
"@types/jest": "^30.0.0",
|
|
76
|
+
"@types/node": "^22.15.17",
|
|
74
77
|
"@types/source-map-support": "^0.5.10",
|
|
75
|
-
"
|
|
76
|
-
"jest
|
|
78
|
+
"@typescript/native-preview": "7.0.0-dev.20251126.1",
|
|
79
|
+
"jest": "^30.0.0",
|
|
80
|
+
"jest-mock-extended": "^4.0.0",
|
|
77
81
|
"ts-node": "^10.9.1",
|
|
78
|
-
"typescript": "^5.
|
|
82
|
+
"typescript": "^5.3.3"
|
|
79
83
|
},
|
|
80
84
|
"files": [
|
|
81
85
|
"dest",
|
|
@@ -84,6 +88,6 @@
|
|
|
84
88
|
],
|
|
85
89
|
"types": "./dest/index.d.ts",
|
|
86
90
|
"engines": {
|
|
87
|
-
"node": ">=
|
|
91
|
+
"node": ">=20.10"
|
|
88
92
|
}
|
|
89
93
|
}
|
package/src/amm_bot.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import { SentTx } from '@aztec/aztec.js/contracts';
|
|
3
|
+
import { Fr } from '@aztec/aztec.js/fields';
|
|
4
|
+
import { TxReceipt } from '@aztec/aztec.js/tx';
|
|
5
|
+
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
6
|
+
import type { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
7
|
+
import type { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
8
|
+
import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
9
|
+
import type { TestWallet } from '@aztec/test-wallet/server';
|
|
10
|
+
|
|
11
|
+
import { BaseBot } from './base_bot.js';
|
|
12
|
+
import type { BotConfig } from './config.js';
|
|
13
|
+
import { BotFactory } from './factory.js';
|
|
14
|
+
import type { BotStore } from './store/index.js';
|
|
15
|
+
|
|
16
|
+
const TRANSFER_BASE_AMOUNT = 1_000;
|
|
17
|
+
const TRANSFER_VARIANCE = 200;
|
|
18
|
+
|
|
19
|
+
type Balances = { token0: bigint; token1: bigint };
|
|
20
|
+
|
|
21
|
+
export class AmmBot extends BaseBot {
|
|
22
|
+
protected constructor(
|
|
23
|
+
node: AztecNode,
|
|
24
|
+
wallet: TestWallet,
|
|
25
|
+
defaultAccountAddress: AztecAddress,
|
|
26
|
+
public readonly amm: AMMContract,
|
|
27
|
+
public readonly token0: TokenContract,
|
|
28
|
+
public readonly token1: TokenContract,
|
|
29
|
+
config: BotConfig,
|
|
30
|
+
) {
|
|
31
|
+
super(node, wallet, defaultAccountAddress, config);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static async create(
|
|
35
|
+
config: BotConfig,
|
|
36
|
+
wallet: TestWallet,
|
|
37
|
+
aztecNode: AztecNode,
|
|
38
|
+
aztecNodeAdmin: AztecNodeAdmin | undefined,
|
|
39
|
+
store: BotStore,
|
|
40
|
+
): Promise<AmmBot> {
|
|
41
|
+
const { defaultAccountAddress, token0, token1, amm } = await new BotFactory(
|
|
42
|
+
config,
|
|
43
|
+
wallet,
|
|
44
|
+
store,
|
|
45
|
+
aztecNode,
|
|
46
|
+
aztecNodeAdmin,
|
|
47
|
+
).setupAmm();
|
|
48
|
+
return new AmmBot(aztecNode, wallet, defaultAccountAddress, amm, token0, token1, config);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected async createAndSendTx(logCtx: object): Promise<SentTx> {
|
|
52
|
+
const { feePaymentMethod } = this.config;
|
|
53
|
+
const { wallet, amm, token0, token1 } = this;
|
|
54
|
+
|
|
55
|
+
const balances = this.getBalances();
|
|
56
|
+
this.log.info(`Preparing tx with ${feePaymentMethod} fee to swap tokens. Balances: ${jsonStringify(balances)}`, {
|
|
57
|
+
...logCtx,
|
|
58
|
+
balances,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// 1000 ± 200
|
|
62
|
+
const amountIn = Math.floor(TRANSFER_BASE_AMOUNT + (Math.random() - 0.5) * TRANSFER_VARIANCE);
|
|
63
|
+
const authwitNonce = Fr.random();
|
|
64
|
+
|
|
65
|
+
const [tokenIn, tokenOut] = Math.random() < 0.5 ? [token0, token1] : [token1, token0];
|
|
66
|
+
|
|
67
|
+
const swapAuthwit = await wallet.createAuthWit(this.defaultAccountAddress, {
|
|
68
|
+
caller: amm.address,
|
|
69
|
+
call: await tokenIn.methods
|
|
70
|
+
.transfer_to_public(this.defaultAccountAddress, amm.address, amountIn, authwitNonce)
|
|
71
|
+
.getFunctionCall(),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
const amountOutMin = await amm.methods
|
|
75
|
+
.get_amount_out_for_exact_in(
|
|
76
|
+
await tokenIn.methods.balance_of_public(amm.address).simulate({ from: this.defaultAccountAddress }),
|
|
77
|
+
await tokenOut.methods.balance_of_public(amm.address).simulate({ from: this.defaultAccountAddress }),
|
|
78
|
+
amountIn,
|
|
79
|
+
)
|
|
80
|
+
.simulate({ from: this.defaultAccountAddress });
|
|
81
|
+
|
|
82
|
+
const swapExactTokensInteraction = amm.methods
|
|
83
|
+
.swap_exact_tokens_for_tokens(tokenIn.address, tokenOut.address, amountIn, amountOutMin, authwitNonce)
|
|
84
|
+
.with({
|
|
85
|
+
authWitnesses: [swapAuthwit],
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const opts = await this.getSendMethodOpts(swapExactTokensInteraction);
|
|
89
|
+
|
|
90
|
+
this.log.verbose(`Sending transaction`, logCtx);
|
|
91
|
+
this.log.info(`Tx. Balances: ${jsonStringify(balances)}`, { ...logCtx, balances });
|
|
92
|
+
return swapExactTokensInteraction.send(opts);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
protected override async onTxMined(receipt: TxReceipt, logCtx: object): Promise<void> {
|
|
96
|
+
const balances = await this.getBalances();
|
|
97
|
+
this.log.info(`Balances after swap in tx ${receipt.txHash}: ${jsonStringify(balances)}`, { ...logCtx, balances });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public getAmmBalances(): Promise<Balances> {
|
|
101
|
+
return this.getPublicBalanceFor(this.amm.address);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public async getBalances(): Promise<{ senderPublic: Balances; senderPrivate: Balances; amm: Balances }> {
|
|
105
|
+
return {
|
|
106
|
+
senderPublic: await this.getPublicBalanceFor(this.defaultAccountAddress),
|
|
107
|
+
senderPrivate: await this.getPrivateBalanceFor(this.defaultAccountAddress),
|
|
108
|
+
amm: await this.getPublicBalanceFor(this.amm.address, this.defaultAccountAddress),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private async getPublicBalanceFor(address: AztecAddress, from?: AztecAddress): Promise<Balances> {
|
|
113
|
+
return {
|
|
114
|
+
token0: await this.token0.methods.balance_of_public(address).simulate({ from: from ?? address }),
|
|
115
|
+
token1: await this.token1.methods.balance_of_public(address).simulate({ from: from ?? address }),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
private async getPrivateBalanceFor(address: AztecAddress, from?: AztecAddress): Promise<Balances> {
|
|
119
|
+
return {
|
|
120
|
+
token0: await this.token0.methods.balance_of_private(address).simulate({ from: from ?? address }),
|
|
121
|
+
token1: await this.token1.methods.balance_of_private(address).simulate({ from: from ?? address }),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|