@aztec/bot 0.0.1-fake-ceab37513c → 0.0.2-commit.217f559981
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 +9 -10
- package/dest/amm_bot.d.ts.map +1 -1
- package/dest/amm_bot.js +27 -20
- package/dest/base_bot.d.ts +12 -9
- package/dest/base_bot.d.ts.map +1 -1
- package/dest/base_bot.js +28 -29
- package/dest/bot.d.ts +9 -10
- package/dest/bot.d.ts.map +1 -1
- package/dest/bot.js +12 -10
- package/dest/config.d.ts +82 -63
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +61 -31
- package/dest/cross_chain_bot.d.ts +54 -0
- package/dest/cross_chain_bot.d.ts.map +1 -0
- package/dest/cross_chain_bot.js +140 -0
- package/dest/factory.d.ts +27 -34
- package/dest/factory.d.ts.map +1 -1
- package/dest/factory.js +271 -151
- package/dest/index.d.ts +3 -1
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +2 -0
- package/dest/interface.d.ts +2 -2
- package/dest/interface.d.ts.map +1 -1
- package/dest/interface.js +1 -1
- package/dest/l1_to_l2_seeding.d.ts +8 -0
- package/dest/l1_to_l2_seeding.d.ts.map +1 -0
- package/dest/l1_to_l2_seeding.js +63 -0
- package/dest/rpc.d.ts +1 -1
- package/dest/runner.d.ts +12 -13
- package/dest/runner.d.ts.map +1 -1
- package/dest/runner.js +445 -61
- package/dest/store/bot_store.d.ts +69 -0
- package/dest/store/bot_store.d.ts.map +1 -0
- package/dest/store/bot_store.js +138 -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 +4 -4
- package/dest/utils.d.ts.map +1 -1
- package/dest/utils.js +5 -5
- package/package.json +19 -13
- package/src/amm_bot.ts +40 -32
- package/src/base_bot.ts +27 -39
- package/src/bot.ts +25 -13
- package/src/config.ts +101 -72
- package/src/cross_chain_bot.ts +209 -0
- package/src/factory.ts +313 -177
- package/src/index.ts +2 -0
- package/src/interface.ts +1 -1
- package/src/l1_to_l2_seeding.ts +79 -0
- package/src/runner.ts +33 -24
- package/src/store/bot_store.ts +196 -0
- package/src/store/index.ts +1 -0
- package/src/utils.ts +10 -5
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
2
|
+
import { createLogger } from '@aztec/foundation/log';
|
|
3
|
+
import { DateProvider } from '@aztec/foundation/timer';
|
|
4
|
+
/**
|
|
5
|
+
* Simple data store for the bot to persist L1 bridge claims.
|
|
6
|
+
*/ export class BotStore {
|
|
7
|
+
store;
|
|
8
|
+
log;
|
|
9
|
+
dateProvider;
|
|
10
|
+
static SCHEMA_VERSION = 1;
|
|
11
|
+
bridgeClaims;
|
|
12
|
+
pendingL1ToL2;
|
|
13
|
+
constructor(store, log = createLogger('bot:store'), dateProvider = new DateProvider()){
|
|
14
|
+
this.store = store;
|
|
15
|
+
this.log = log;
|
|
16
|
+
this.dateProvider = dateProvider;
|
|
17
|
+
this.bridgeClaims = store.openMap('bridge_claims');
|
|
18
|
+
this.pendingL1ToL2 = store.openMap('pending_l1_to_l2');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Saves a bridge claim for a recipient.
|
|
22
|
+
*/ async saveBridgeClaim(recipient, claim) {
|
|
23
|
+
// Convert Fr fields and BigInts to strings for JSON serialization
|
|
24
|
+
const serializableClaim = {
|
|
25
|
+
claimAmount: claim.claimAmount.toString(),
|
|
26
|
+
claimSecret: claim.claimSecret.toString(),
|
|
27
|
+
claimSecretHash: claim.claimSecretHash.toString(),
|
|
28
|
+
messageHash: claim.messageHash,
|
|
29
|
+
messageLeafIndex: claim.messageLeafIndex.toString()
|
|
30
|
+
};
|
|
31
|
+
const data = {
|
|
32
|
+
claim: serializableClaim,
|
|
33
|
+
timestamp: this.dateProvider.now(),
|
|
34
|
+
recipient: recipient.toString()
|
|
35
|
+
};
|
|
36
|
+
await this.bridgeClaims.set(recipient.toString(), JSON.stringify(data));
|
|
37
|
+
this.log.info(`Saved bridge claim for ${recipient.toString()}`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Gets a bridge claim for a recipient if it exists.
|
|
41
|
+
*/ async getBridgeClaim(recipient) {
|
|
42
|
+
const data = await this.bridgeClaims.getAsync(recipient.toString());
|
|
43
|
+
if (!data) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
const parsed = JSON.parse(data);
|
|
47
|
+
// Reconstruct L2AmountClaim from serialized data
|
|
48
|
+
const claim = {
|
|
49
|
+
claimAmount: BigInt(parsed.claim.claimAmount),
|
|
50
|
+
claimSecret: Fr.fromString(parsed.claim.claimSecret),
|
|
51
|
+
claimSecretHash: Fr.fromString(parsed.claim.claimSecretHash),
|
|
52
|
+
messageHash: parsed.claim.messageHash,
|
|
53
|
+
messageLeafIndex: BigInt(parsed.claim.messageLeafIndex)
|
|
54
|
+
};
|
|
55
|
+
return {
|
|
56
|
+
claim,
|
|
57
|
+
timestamp: parsed.timestamp,
|
|
58
|
+
recipient: parsed.recipient
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Deletes a bridge claim for a recipient.
|
|
63
|
+
*/ async deleteBridgeClaim(recipient) {
|
|
64
|
+
await this.bridgeClaims.delete(recipient.toString());
|
|
65
|
+
this.log.info(`Deleted bridge claim for ${recipient.toString()}`);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Gets all stored bridge claims.
|
|
69
|
+
*/ async getAllBridgeClaims() {
|
|
70
|
+
const claims = [];
|
|
71
|
+
const entries = this.bridgeClaims.entriesAsync();
|
|
72
|
+
for await (const [_, data] of entries){
|
|
73
|
+
const parsed = JSON.parse(data);
|
|
74
|
+
// Reconstruct L2AmountClaim from serialized data
|
|
75
|
+
const claim = {
|
|
76
|
+
claimAmount: BigInt(parsed.claim.claimAmount),
|
|
77
|
+
claimSecret: Fr.fromString(parsed.claim.claimSecret),
|
|
78
|
+
claimSecretHash: Fr.fromString(parsed.claim.claimSecretHash),
|
|
79
|
+
messageHash: parsed.claim.messageHash,
|
|
80
|
+
messageLeafIndex: BigInt(parsed.claim.messageLeafIndex)
|
|
81
|
+
};
|
|
82
|
+
claims.push({
|
|
83
|
+
claim,
|
|
84
|
+
timestamp: parsed.timestamp,
|
|
85
|
+
recipient: parsed.recipient
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return claims;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Cleans up old bridge claims (older than 24 hours).
|
|
92
|
+
*/ async cleanupOldClaims(maxAgeMs = 24 * 60 * 60 * 1000) {
|
|
93
|
+
const now = this.dateProvider.now();
|
|
94
|
+
let cleanedCount = 0;
|
|
95
|
+
const entries = this.bridgeClaims.entriesAsync();
|
|
96
|
+
for await (const [key, data] of entries){
|
|
97
|
+
const parsed = JSON.parse(data);
|
|
98
|
+
if (now - parsed.timestamp > maxAgeMs) {
|
|
99
|
+
await this.bridgeClaims.delete(key);
|
|
100
|
+
cleanedCount++;
|
|
101
|
+
this.log.info(`Cleaned up old bridge claim for ${parsed.recipient}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return cleanedCount;
|
|
105
|
+
}
|
|
106
|
+
/** Saves a pending L1→L2 message keyed by msgHash. */ async savePendingL1ToL2Message(msg) {
|
|
107
|
+
await this.pendingL1ToL2.set(msg.msgHash, JSON.stringify(msg));
|
|
108
|
+
this.log.info(`Saved pending L1→L2 message ${msg.msgHash}`);
|
|
109
|
+
}
|
|
110
|
+
/** Returns all unconsumed pending L1→L2 messages. */ async getUnconsumedL1ToL2Messages() {
|
|
111
|
+
const messages = [];
|
|
112
|
+
for await (const [_, data] of this.pendingL1ToL2.entriesAsync()){
|
|
113
|
+
messages.push(JSON.parse(data));
|
|
114
|
+
}
|
|
115
|
+
return messages;
|
|
116
|
+
}
|
|
117
|
+
/** Deletes a consumed L1→L2 message from the store. */ async deleteL1ToL2Message(msgHash) {
|
|
118
|
+
await this.pendingL1ToL2.delete(msgHash);
|
|
119
|
+
this.log.info(`Deleted consumed L1→L2 message ${msgHash}`);
|
|
120
|
+
}
|
|
121
|
+
/** Cleans up pending L1→L2 messages older than maxAgeMs. */ async cleanupOldPendingMessages(maxAgeMs = 24 * 60 * 60 * 1000) {
|
|
122
|
+
const now = this.dateProvider.now();
|
|
123
|
+
let cleanedCount = 0;
|
|
124
|
+
for await (const [key, data] of this.pendingL1ToL2.entriesAsync()){
|
|
125
|
+
const parsed = JSON.parse(data);
|
|
126
|
+
if (now - parsed.timestamp > maxAgeMs) {
|
|
127
|
+
await this.pendingL1ToL2.delete(key);
|
|
128
|
+
cleanedCount++;
|
|
129
|
+
this.log.info(`Cleaned up old pending L1→L2 message ${key}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return cleanedCount;
|
|
133
|
+
}
|
|
134
|
+
/** Closes the store. */ async close() {
|
|
135
|
+
await this.store.close();
|
|
136
|
+
this.log.info('Closed bot data store');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { BotStore, type BridgeClaimData, type PendingL1ToL2Message } from './bot_store.js';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssZUFBZSxFQUFFLEtBQUssb0JBQW9CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQyJ9
|
|
@@ -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,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BotStore } from './bot_store.js';
|
package/dest/utils.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ContractBase } from '@aztec/aztec.js/contracts';
|
|
2
2
|
import type { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
3
3
|
import type { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
|
|
4
4
|
import type { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
@@ -9,11 +9,11 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
|
9
9
|
* @param who - Address to get the balance for.
|
|
10
10
|
* @returns - Private and public token balances as bigints.
|
|
11
11
|
*/
|
|
12
|
-
export declare function getBalances(token: TokenContract, who: AztecAddress): Promise<{
|
|
12
|
+
export declare function getBalances(token: TokenContract, who: AztecAddress, from?: AztecAddress): Promise<{
|
|
13
13
|
privateBalance: bigint;
|
|
14
14
|
publicBalance: bigint;
|
|
15
15
|
}>;
|
|
16
|
-
export declare function getPrivateBalance(token: PrivateTokenContract, who: AztecAddress): Promise<bigint>;
|
|
16
|
+
export declare function getPrivateBalance(token: PrivateTokenContract, who: AztecAddress, from?: AztecAddress): Promise<bigint>;
|
|
17
17
|
export declare function isStandardTokenContract(token: ContractBase): token is TokenContract;
|
|
18
18
|
export declare function isAMMContract(contract: ContractBase): contract is AMMContract;
|
|
19
|
-
//# sourceMappingURL=
|
|
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,
|
|
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,21 +3,21 @@
|
|
|
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) {
|
|
6
|
+
*/ export async function getBalances(token, who, from) {
|
|
7
7
|
const privateBalance = await token.methods.balance_of_private(who).simulate({
|
|
8
|
-
from: who
|
|
8
|
+
from: from ?? who
|
|
9
9
|
});
|
|
10
10
|
const publicBalance = await token.methods.balance_of_public(who).simulate({
|
|
11
|
-
from: who
|
|
11
|
+
from: from ?? who
|
|
12
12
|
});
|
|
13
13
|
return {
|
|
14
14
|
privateBalance,
|
|
15
15
|
publicBalance
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
|
-
export async function getPrivateBalance(token, who) {
|
|
18
|
+
export async function getPrivateBalance(token, who, from) {
|
|
19
19
|
const privateBalance = await token.methods.get_balance(who).simulate({
|
|
20
|
-
from: who
|
|
20
|
+
from: from ?? who
|
|
21
21
|
});
|
|
22
22
|
return privateBalance;
|
|
23
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/bot",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2-commit.217f559981",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"../package.common.json"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"build": "yarn clean && tsc
|
|
14
|
-
"build:dev": "tsc
|
|
13
|
+
"build": "yarn clean && ../scripts/tsc.sh",
|
|
14
|
+
"build:dev": "../scripts/tsc.sh --watch",
|
|
15
15
|
"clean": "rm -rf ./dest .tsbuildinfo",
|
|
16
16
|
"bb": "node --no-warnings ./dest/bb/index.js",
|
|
17
17
|
"test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules ../node_modules/.bin/jest --passWithNoTests --maxWorkers=${JEST_MAX_WORKERS:-8}"
|
|
@@ -54,18 +54,23 @@
|
|
|
54
54
|
]
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@aztec/accounts": "0.0.
|
|
58
|
-
"@aztec/aztec.js": "0.0.
|
|
59
|
-
"@aztec/entrypoints": "0.0.
|
|
60
|
-
"@aztec/ethereum": "0.0.
|
|
61
|
-
"@aztec/foundation": "0.0.
|
|
62
|
-
"@aztec/
|
|
63
|
-
"@aztec/
|
|
64
|
-
"@aztec/
|
|
65
|
-
"@aztec/
|
|
66
|
-
"@aztec/
|
|
57
|
+
"@aztec/accounts": "0.0.2-commit.217f559981",
|
|
58
|
+
"@aztec/aztec.js": "0.0.2-commit.217f559981",
|
|
59
|
+
"@aztec/entrypoints": "0.0.2-commit.217f559981",
|
|
60
|
+
"@aztec/ethereum": "0.0.2-commit.217f559981",
|
|
61
|
+
"@aztec/foundation": "0.0.2-commit.217f559981",
|
|
62
|
+
"@aztec/kv-store": "0.0.2-commit.217f559981",
|
|
63
|
+
"@aztec/l1-artifacts": "0.0.2-commit.217f559981",
|
|
64
|
+
"@aztec/noir-contracts.js": "0.0.2-commit.217f559981",
|
|
65
|
+
"@aztec/noir-protocol-circuits-types": "0.0.2-commit.217f559981",
|
|
66
|
+
"@aztec/noir-test-contracts.js": "0.0.2-commit.217f559981",
|
|
67
|
+
"@aztec/protocol-contracts": "0.0.2-commit.217f559981",
|
|
68
|
+
"@aztec/stdlib": "0.0.2-commit.217f559981",
|
|
69
|
+
"@aztec/telemetry-client": "0.0.2-commit.217f559981",
|
|
70
|
+
"@aztec/wallets": "0.0.2-commit.217f559981",
|
|
67
71
|
"source-map-support": "^0.5.21",
|
|
68
72
|
"tslib": "^2.4.0",
|
|
73
|
+
"viem": "npm:@aztec/viem@2.38.2",
|
|
69
74
|
"zod": "^3.23.8"
|
|
70
75
|
},
|
|
71
76
|
"devDependencies": {
|
|
@@ -73,6 +78,7 @@
|
|
|
73
78
|
"@types/jest": "^30.0.0",
|
|
74
79
|
"@types/node": "^22.15.17",
|
|
75
80
|
"@types/source-map-support": "^0.5.10",
|
|
81
|
+
"@typescript/native-preview": "7.0.0-dev.20260113.1",
|
|
76
82
|
"jest": "^30.0.0",
|
|
77
83
|
"jest-mock-extended": "^4.0.0",
|
|
78
84
|
"ts-node": "^10.9.1",
|
package/src/amm_bot.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import { AztecAddress
|
|
1
|
+
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import { NO_WAIT } from '@aztec/aztec.js/contracts';
|
|
3
|
+
import { Fr } from '@aztec/aztec.js/fields';
|
|
4
|
+
import { TxHash, TxReceipt } from '@aztec/aztec.js/tx';
|
|
2
5
|
import { jsonStringify } from '@aztec/foundation/json-rpc';
|
|
3
6
|
import type { AMMContract } from '@aztec/noir-contracts.js/AMM';
|
|
4
7
|
import type { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
5
|
-
import type { AztecNode, AztecNodeAdmin
|
|
8
|
+
import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
9
|
+
import type { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
6
10
|
|
|
7
11
|
import { BaseBot } from './base_bot.js';
|
|
8
12
|
import type { BotConfig } from './config.js';
|
|
9
13
|
import { BotFactory } from './factory.js';
|
|
14
|
+
import type { BotStore } from './store/index.js';
|
|
10
15
|
|
|
11
16
|
const TRANSFER_BASE_AMOUNT = 1_000;
|
|
12
17
|
const TRANSFER_VARIANCE = 200;
|
|
@@ -15,29 +20,35 @@ type Balances = { token0: bigint; token1: bigint };
|
|
|
15
20
|
|
|
16
21
|
export class AmmBot extends BaseBot {
|
|
17
22
|
protected constructor(
|
|
18
|
-
|
|
19
|
-
wallet:
|
|
23
|
+
node: AztecNode,
|
|
24
|
+
wallet: EmbeddedWallet,
|
|
20
25
|
defaultAccountAddress: AztecAddress,
|
|
21
26
|
public readonly amm: AMMContract,
|
|
22
27
|
public readonly token0: TokenContract,
|
|
23
28
|
public readonly token1: TokenContract,
|
|
24
29
|
config: BotConfig,
|
|
25
30
|
) {
|
|
26
|
-
super(
|
|
31
|
+
super(node, wallet, defaultAccountAddress, config);
|
|
27
32
|
}
|
|
28
33
|
|
|
29
34
|
static async create(
|
|
30
35
|
config: BotConfig,
|
|
31
|
-
|
|
36
|
+
wallet: EmbeddedWallet,
|
|
37
|
+
aztecNode: AztecNode,
|
|
38
|
+
aztecNodeAdmin: AztecNodeAdmin | undefined,
|
|
39
|
+
store: BotStore,
|
|
32
40
|
): Promise<AmmBot> {
|
|
33
|
-
const {
|
|
41
|
+
const { defaultAccountAddress, token0, token1, amm } = await new BotFactory(
|
|
34
42
|
config,
|
|
35
|
-
|
|
43
|
+
wallet,
|
|
44
|
+
store,
|
|
45
|
+
aztecNode,
|
|
46
|
+
aztecNodeAdmin,
|
|
36
47
|
).setupAmm();
|
|
37
|
-
return new AmmBot(
|
|
48
|
+
return new AmmBot(aztecNode, wallet, defaultAccountAddress, amm, token0, token1, config);
|
|
38
49
|
}
|
|
39
50
|
|
|
40
|
-
protected async createAndSendTx(logCtx: object): Promise<
|
|
51
|
+
protected async createAndSendTx(logCtx: object): Promise<TxHash> {
|
|
41
52
|
const { feePaymentMethod } = this.config;
|
|
42
53
|
const { wallet, amm, token0, token1 } = this;
|
|
43
54
|
|
|
@@ -53,9 +64,11 @@ export class AmmBot extends BaseBot {
|
|
|
53
64
|
|
|
54
65
|
const [tokenIn, tokenOut] = Math.random() < 0.5 ? [token0, token1] : [token1, token0];
|
|
55
66
|
|
|
56
|
-
const swapAuthwit = await wallet.createAuthWit({
|
|
67
|
+
const swapAuthwit = await wallet.createAuthWit(this.defaultAccountAddress, {
|
|
57
68
|
caller: amm.address,
|
|
58
|
-
|
|
69
|
+
call: await tokenIn.methods
|
|
70
|
+
.transfer_to_public(this.defaultAccountAddress, amm.address, amountIn, authwitNonce)
|
|
71
|
+
.getFunctionCall(),
|
|
59
72
|
});
|
|
60
73
|
|
|
61
74
|
const amountOutMin = await amm.methods
|
|
@@ -66,22 +79,17 @@ export class AmmBot extends BaseBot {
|
|
|
66
79
|
)
|
|
67
80
|
.simulate({ from: this.defaultAccountAddress });
|
|
68
81
|
|
|
69
|
-
const swapExactTokensInteraction = amm.methods
|
|
70
|
-
tokenIn.address,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
authwitNonce,
|
|
75
|
-
);
|
|
82
|
+
const swapExactTokensInteraction = amm.methods
|
|
83
|
+
.swap_exact_tokens_for_tokens(tokenIn.address, tokenOut.address, amountIn, amountOutMin, authwitNonce)
|
|
84
|
+
.with({
|
|
85
|
+
authWitnesses: [swapAuthwit],
|
|
86
|
+
});
|
|
76
87
|
|
|
77
|
-
const opts = this.getSendMethodOpts(
|
|
78
|
-
|
|
79
|
-
this.log.verbose(`Proving transaction`, logCtx);
|
|
80
|
-
const tx = await swapExactTokensInteraction.prove(opts);
|
|
88
|
+
const opts = await this.getSendMethodOpts(swapExactTokensInteraction);
|
|
81
89
|
|
|
90
|
+
this.log.verbose(`Sending transaction`, logCtx);
|
|
82
91
|
this.log.info(`Tx. Balances: ${jsonStringify(balances)}`, { ...logCtx, balances });
|
|
83
|
-
|
|
84
|
-
return tx.send();
|
|
92
|
+
return swapExactTokensInteraction.send({ ...opts, wait: NO_WAIT });
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
protected override async onTxMined(receipt: TxReceipt, logCtx: object): Promise<void> {
|
|
@@ -97,20 +105,20 @@ export class AmmBot extends BaseBot {
|
|
|
97
105
|
return {
|
|
98
106
|
senderPublic: await this.getPublicBalanceFor(this.defaultAccountAddress),
|
|
99
107
|
senderPrivate: await this.getPrivateBalanceFor(this.defaultAccountAddress),
|
|
100
|
-
amm: await this.getPublicBalanceFor(this.amm.address),
|
|
108
|
+
amm: await this.getPublicBalanceFor(this.amm.address, this.defaultAccountAddress),
|
|
101
109
|
};
|
|
102
110
|
}
|
|
103
111
|
|
|
104
|
-
private async getPublicBalanceFor(address: AztecAddress): Promise<Balances> {
|
|
112
|
+
private async getPublicBalanceFor(address: AztecAddress, from?: AztecAddress): Promise<Balances> {
|
|
105
113
|
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 }),
|
|
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 }),
|
|
108
116
|
};
|
|
109
117
|
}
|
|
110
|
-
private async getPrivateBalanceFor(address: AztecAddress): Promise<Balances> {
|
|
118
|
+
private async getPrivateBalanceFor(address: AztecAddress, from?: AztecAddress): Promise<Balances> {
|
|
111
119
|
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 }),
|
|
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 }),
|
|
114
122
|
};
|
|
115
123
|
}
|
|
116
124
|
}
|
package/src/base_bot.ts
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
SentTx,
|
|
7
|
-
TxHash,
|
|
8
|
-
TxReceipt,
|
|
9
|
-
type Wallet,
|
|
10
|
-
createLogger,
|
|
11
|
-
waitForProven,
|
|
12
|
-
} from '@aztec/aztec.js';
|
|
1
|
+
import { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import { BatchCall, ContractFunctionInteraction, type SendInteractionOptions } from '@aztec/aztec.js/contracts';
|
|
3
|
+
import { createLogger } from '@aztec/aztec.js/log';
|
|
4
|
+
import { waitForTx } from '@aztec/aztec.js/node';
|
|
5
|
+
import { TxHash, TxReceipt, TxStatus } from '@aztec/aztec.js/tx';
|
|
13
6
|
import { Gas } from '@aztec/stdlib/gas';
|
|
14
|
-
import type {
|
|
7
|
+
import type { AztecNode } from '@aztec/stdlib/interfaces/client';
|
|
8
|
+
import type { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
15
9
|
|
|
16
10
|
import type { BotConfig } from './config.js';
|
|
17
11
|
|
|
@@ -22,37 +16,28 @@ export abstract class BaseBot {
|
|
|
22
16
|
protected successes: number = 0;
|
|
23
17
|
|
|
24
18
|
protected constructor(
|
|
25
|
-
public readonly
|
|
26
|
-
public readonly wallet:
|
|
19
|
+
public readonly node: AztecNode,
|
|
20
|
+
public readonly wallet: EmbeddedWallet,
|
|
27
21
|
public readonly defaultAccountAddress: AztecAddress,
|
|
28
22
|
public config: BotConfig,
|
|
29
23
|
) {}
|
|
30
24
|
|
|
31
25
|
public async run(): Promise<TxReceipt | TxHash> {
|
|
32
26
|
this.attempts++;
|
|
33
|
-
const logCtx = { runId: Date.now() * 1000 + Math.floor(Math.random() * 1000) };
|
|
34
27
|
const { followChain, txMinedWaitSeconds } = this.config;
|
|
28
|
+
const logCtx = { runId: Date.now() * 1000 + Math.floor(Math.random() * 1000), followChain, txMinedWaitSeconds };
|
|
35
29
|
|
|
36
30
|
this.log.verbose(`Creating tx`, logCtx);
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
const txHash = await tx.getTxHash();
|
|
31
|
+
const txHash = await this.createAndSendTx(logCtx);
|
|
40
32
|
|
|
41
33
|
if (followChain === 'NONE') {
|
|
42
34
|
this.log.info(`Transaction ${txHash.toString()} sent, not waiting for it to be mined`);
|
|
43
35
|
return txHash;
|
|
44
36
|
}
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
);
|
|
50
|
-
const receipt = await tx.wait({
|
|
51
|
-
timeout: txMinedWaitSeconds,
|
|
52
|
-
});
|
|
53
|
-
if (followChain === 'PROVEN') {
|
|
54
|
-
await waitForProven(this.pxe, receipt, { provenTimeout: txMinedWaitSeconds });
|
|
55
|
-
}
|
|
38
|
+
const waitForStatus = TxStatus[followChain];
|
|
39
|
+
this.log.verbose(`Awaiting tx ${txHash.toString()} to be on the ${followChain} chain`, logCtx);
|
|
40
|
+
const receipt = await waitForTx(this.node, txHash, { timeout: txMinedWaitSeconds, waitForStatus });
|
|
56
41
|
this.successes++;
|
|
57
42
|
this.log.info(
|
|
58
43
|
`Tx #${this.attempts} ${receipt.txHash} successfully mined in block ${receipt.blockNumber} (stats: ${this.successes}/${this.attempts} success)`,
|
|
@@ -64,31 +49,34 @@ export abstract class BaseBot {
|
|
|
64
49
|
return receipt;
|
|
65
50
|
}
|
|
66
51
|
|
|
67
|
-
protected abstract createAndSendTx(logCtx: object): Promise<
|
|
52
|
+
protected abstract createAndSendTx(logCtx: object): Promise<TxHash>;
|
|
68
53
|
|
|
69
54
|
protected onTxMined(_receipt: TxReceipt, _logCtx: object): Promise<void> {
|
|
70
55
|
// no-op
|
|
71
56
|
return Promise.resolve();
|
|
72
57
|
}
|
|
73
58
|
|
|
74
|
-
protected getSendMethodOpts(
|
|
75
|
-
|
|
76
|
-
|
|
59
|
+
protected async getSendMethodOpts(
|
|
60
|
+
interaction: ContractFunctionInteraction | BatchCall,
|
|
61
|
+
): Promise<SendInteractionOptions> {
|
|
62
|
+
const { l2GasLimit, daGasLimit, minFeePadding } = this.config;
|
|
63
|
+
|
|
64
|
+
this.wallet.setMinFeePadding(minFeePadding);
|
|
77
65
|
|
|
78
|
-
let gasSettings
|
|
66
|
+
let gasSettings;
|
|
79
67
|
if (l2GasLimit !== undefined && l2GasLimit > 0 && daGasLimit !== undefined && daGasLimit > 0) {
|
|
80
68
|
gasSettings = { gasLimits: Gas.from({ l2Gas: l2GasLimit, daGas: daGasLimit }) };
|
|
81
|
-
estimateGas = false;
|
|
82
69
|
this.log.verbose(`Using gas limits ${l2GasLimit} L2 gas ${daGasLimit} DA gas`);
|
|
83
70
|
} else {
|
|
84
|
-
estimateGas = true;
|
|
85
71
|
this.log.verbose(`Estimating gas for transaction`);
|
|
72
|
+
({ estimatedGas: gasSettings } = await interaction.simulate({
|
|
73
|
+
fee: { estimateGas: true },
|
|
74
|
+
from: this.defaultAccountAddress,
|
|
75
|
+
}));
|
|
86
76
|
}
|
|
87
|
-
const baseFeePadding = 2; // Send 3x the current base fee
|
|
88
77
|
return {
|
|
89
78
|
from: this.defaultAccountAddress,
|
|
90
|
-
fee: {
|
|
91
|
-
authWitnesses,
|
|
79
|
+
fee: { gasSettings },
|
|
92
80
|
};
|
|
93
81
|
}
|
|
94
82
|
}
|
package/src/bot.ts
CHANGED
|
@@ -1,34 +1,47 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AztecAddress } from '@aztec/aztec.js/addresses';
|
|
2
|
+
import { BatchCall, NO_WAIT } from '@aztec/aztec.js/contracts';
|
|
3
|
+
import { TxHash } from '@aztec/aztec.js/tx';
|
|
2
4
|
import { times } from '@aztec/foundation/collection';
|
|
3
5
|
import type { PrivateTokenContract } from '@aztec/noir-contracts.js/PrivateToken';
|
|
4
6
|
import type { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
5
|
-
import type { AztecNode, AztecNodeAdmin
|
|
7
|
+
import type { AztecNode, AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
8
|
+
import type { EmbeddedWallet } from '@aztec/wallets/embedded';
|
|
6
9
|
|
|
7
10
|
import { BaseBot } from './base_bot.js';
|
|
8
11
|
import type { BotConfig } from './config.js';
|
|
9
12
|
import { BotFactory } from './factory.js';
|
|
13
|
+
import type { BotStore } from './store/index.js';
|
|
10
14
|
import { getBalances, getPrivateBalance, isStandardTokenContract } from './utils.js';
|
|
11
15
|
|
|
12
16
|
const TRANSFER_AMOUNT = 1;
|
|
13
17
|
|
|
14
18
|
export class Bot extends BaseBot {
|
|
15
19
|
protected constructor(
|
|
16
|
-
|
|
17
|
-
wallet:
|
|
20
|
+
node: AztecNode,
|
|
21
|
+
wallet: EmbeddedWallet,
|
|
18
22
|
defaultAccountAddress: AztecAddress,
|
|
19
23
|
public readonly token: TokenContract | PrivateTokenContract,
|
|
20
24
|
public readonly recipient: AztecAddress,
|
|
21
25
|
config: BotConfig,
|
|
22
26
|
) {
|
|
23
|
-
super(
|
|
27
|
+
super(node, wallet, defaultAccountAddress, config);
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
static async create(
|
|
27
31
|
config: BotConfig,
|
|
28
|
-
|
|
32
|
+
wallet: EmbeddedWallet,
|
|
33
|
+
aztecNode: AztecNode,
|
|
34
|
+
aztecNodeAdmin: AztecNodeAdmin | undefined,
|
|
35
|
+
store: BotStore,
|
|
29
36
|
): Promise<Bot> {
|
|
30
|
-
const {
|
|
31
|
-
|
|
37
|
+
const { defaultAccountAddress, token, recipient } = await new BotFactory(
|
|
38
|
+
config,
|
|
39
|
+
wallet,
|
|
40
|
+
store,
|
|
41
|
+
aztecNode,
|
|
42
|
+
aztecNodeAdmin,
|
|
43
|
+
).setup();
|
|
44
|
+
return new Bot(aztecNode, wallet, defaultAccountAddress, token, recipient, config);
|
|
32
45
|
}
|
|
33
46
|
|
|
34
47
|
public updateConfig(config: Partial<BotConfig>) {
|
|
@@ -36,7 +49,7 @@ export class Bot extends BaseBot {
|
|
|
36
49
|
this.config = { ...this.config, ...config };
|
|
37
50
|
}
|
|
38
51
|
|
|
39
|
-
protected async createAndSendTx(logCtx: object): Promise<
|
|
52
|
+
protected async createAndSendTx(logCtx: object): Promise<TxHash> {
|
|
40
53
|
const { privateTransfersPerTx, publicTransfersPerTx, feePaymentMethod } = this.config;
|
|
41
54
|
const { token, recipient, wallet } = this;
|
|
42
55
|
|
|
@@ -56,15 +69,14 @@ export class Bot extends BaseBot {
|
|
|
56
69
|
token.methods.transfer(TRANSFER_AMOUNT, this.defaultAccountAddress, recipient),
|
|
57
70
|
);
|
|
58
71
|
|
|
59
|
-
const opts = this.getSendMethodOpts();
|
|
60
72
|
const batch = new BatchCall(wallet, calls);
|
|
73
|
+
const opts = await this.getSendMethodOpts(batch);
|
|
61
74
|
|
|
62
75
|
this.log.verbose(`Simulating transaction with ${calls.length}`, logCtx);
|
|
63
76
|
await batch.simulate({ from: this.defaultAccountAddress });
|
|
64
77
|
|
|
65
|
-
this.log.verbose(`
|
|
66
|
-
|
|
67
|
-
return provenTx.send();
|
|
78
|
+
this.log.verbose(`Sending transaction`, logCtx);
|
|
79
|
+
return batch.send({ ...opts, wait: NO_WAIT });
|
|
68
80
|
}
|
|
69
81
|
|
|
70
82
|
public async getBalances() {
|