@aztec/bot 0.0.0-test.1 → 0.0.1-commit.001888fc

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.
Files changed (57) hide show
  1. package/dest/amm_bot.d.ts +32 -0
  2. package/dest/amm_bot.d.ts.map +1 -0
  3. package/dest/amm_bot.js +108 -0
  4. package/dest/base_bot.d.ts +21 -0
  5. package/dest/base_bot.d.ts.map +1 -0
  6. package/dest/base_bot.js +79 -0
  7. package/dest/bot.d.ts +13 -18
  8. package/dest/bot.d.ts.map +1 -1
  9. package/dest/bot.js +26 -84
  10. package/dest/config.d.ts +106 -66
  11. package/dest/config.d.ts.map +1 -1
  12. package/dest/config.js +89 -39
  13. package/dest/cross_chain_bot.d.ts +54 -0
  14. package/dest/cross_chain_bot.d.ts.map +1 -0
  15. package/dest/cross_chain_bot.js +134 -0
  16. package/dest/factory.d.ts +43 -29
  17. package/dest/factory.d.ts.map +1 -1
  18. package/dest/factory.js +380 -139
  19. package/dest/index.d.ts +5 -2
  20. package/dest/index.d.ts.map +1 -1
  21. package/dest/index.js +4 -1
  22. package/dest/interface.d.ts +12 -1
  23. package/dest/interface.d.ts.map +1 -1
  24. package/dest/interface.js +5 -0
  25. package/dest/l1_to_l2_seeding.d.ts +8 -0
  26. package/dest/l1_to_l2_seeding.d.ts.map +1 -0
  27. package/dest/l1_to_l2_seeding.js +63 -0
  28. package/dest/rpc.d.ts +1 -7
  29. package/dest/rpc.d.ts.map +1 -1
  30. package/dest/rpc.js +0 -11
  31. package/dest/runner.d.ts +15 -11
  32. package/dest/runner.d.ts.map +1 -1
  33. package/dest/runner.js +457 -51
  34. package/dest/store/bot_store.d.ts +69 -0
  35. package/dest/store/bot_store.d.ts.map +1 -0
  36. package/dest/store/bot_store.js +138 -0
  37. package/dest/store/index.d.ts +2 -0
  38. package/dest/store/index.d.ts.map +1 -0
  39. package/dest/store/index.js +1 -0
  40. package/dest/utils.d.ts +8 -5
  41. package/dest/utils.d.ts.map +1 -1
  42. package/dest/utils.js +14 -5
  43. package/package.json +30 -23
  44. package/src/amm_bot.ts +129 -0
  45. package/src/base_bot.ts +82 -0
  46. package/src/bot.ts +52 -101
  47. package/src/config.ts +129 -71
  48. package/src/cross_chain_bot.ts +203 -0
  49. package/src/factory.ts +476 -152
  50. package/src/index.ts +4 -1
  51. package/src/interface.ts +9 -0
  52. package/src/l1_to_l2_seeding.ts +79 -0
  53. package/src/rpc.ts +0 -13
  54. package/src/runner.ts +51 -21
  55. package/src/store/bot_store.ts +196 -0
  56. package/src/store/index.ts +1 -0
  57. package/src/utils.ts +17 -6
package/src/index.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  export { Bot } from './bot.js';
2
+ export { AmmBot } from './amm_bot.js';
3
+ export { CrossChainBot } from './cross_chain_bot.js';
2
4
  export { BotRunner } from './runner.js';
5
+ export { BotStore } from './store/bot_store.js';
3
6
  export {
4
7
  type BotConfig,
5
8
  getBotConfigFromEnv,
@@ -7,5 +10,5 @@ export {
7
10
  botConfigMappings,
8
11
  SupportedTokenContracts,
9
12
  } from './config.js';
10
- export { createBotRunnerRpcServer, getBotRunnerApiHandler } from './rpc.js';
13
+ export { getBotRunnerApiHandler } from './rpc.js';
11
14
  export * from './interface.js';
package/src/interface.ts CHANGED
@@ -1,15 +1,23 @@
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
1
2
  import type { ApiSchemaFor } from '@aztec/stdlib/schemas';
2
3
 
3
4
  import { z } from 'zod';
4
5
 
5
6
  import { type BotConfig, BotConfigSchema } from './config.js';
6
7
 
8
+ export const BotInfoSchema = z.object({
9
+ botAddress: AztecAddress.schema,
10
+ });
11
+
12
+ export type BotInfo = z.infer<typeof BotInfoSchema>;
13
+
7
14
  export interface BotRunnerApi {
8
15
  start(): Promise<void>;
9
16
  stop(): Promise<void>;
10
17
  run(): Promise<void>;
11
18
  setup(): Promise<void>;
12
19
  getConfig(): Promise<BotConfig>;
20
+ getInfo(): Promise<BotInfo>;
13
21
  update(config: BotConfig): Promise<void>;
14
22
  }
15
23
 
@@ -18,6 +26,7 @@ export const BotRunnerApiSchema: ApiSchemaFor<BotRunnerApi> = {
18
26
  stop: z.function().args().returns(z.void()),
19
27
  run: z.function().args().returns(z.void()),
20
28
  setup: z.function().args().returns(z.void()),
29
+ getInfo: z.function().args().returns(BotInfoSchema),
21
30
  getConfig: z.function().args().returns(BotConfigSchema),
22
31
  update: z.function().args(BotConfigSchema).returns(z.void()),
23
32
  };
@@ -0,0 +1,79 @@
1
+ import { generateClaimSecret } from '@aztec/aztec.js/ethereum';
2
+ import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
3
+ import { compactArray } from '@aztec/foundation/collection';
4
+ import { Fr } from '@aztec/foundation/curves/bn254';
5
+ import { EthAddress } from '@aztec/foundation/eth-address';
6
+ import type { Logger } from '@aztec/foundation/log';
7
+ import { InboxAbi } from '@aztec/l1-artifacts';
8
+ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
9
+
10
+ import { decodeEventLog, getContract } from 'viem';
11
+
12
+ import type { BotStore, PendingL1ToL2Message } from './store/index.js';
13
+
14
+ /** Sends an L1→L2 message via the Inbox contract and stores it. */
15
+ export async function seedL1ToL2Message(
16
+ l1Client: ExtendedViemWalletClient,
17
+ inboxAddress: EthAddress,
18
+ l2Recipient: AztecAddress,
19
+ rollupVersion: bigint,
20
+ store: BotStore,
21
+ log: Logger,
22
+ ): Promise<PendingL1ToL2Message> {
23
+ log.info('Seeding L1→L2 message');
24
+ const [secret, secretHash] = await generateClaimSecret(log);
25
+ const content = Fr.random();
26
+
27
+ const inbox = getContract({
28
+ address: inboxAddress.toString(),
29
+ abi: InboxAbi,
30
+ client: l1Client,
31
+ });
32
+
33
+ const txHash = await inbox.write.sendL2Message(
34
+ [{ actor: l2Recipient.toString(), version: rollupVersion }, content.toString(), secretHash.toString()],
35
+ { gas: 1_000_000n },
36
+ );
37
+ log.info(`L1→L2 message sent in tx ${txHash}`);
38
+
39
+ const txReceipt = await l1Client.waitForTransactionReceipt({ hash: txHash });
40
+ if (txReceipt.status !== 'success') {
41
+ throw new Error(`L1→L2 message tx failed: ${txHash}`);
42
+ }
43
+
44
+ // Extract MessageSent event
45
+ const messageSentLogs = compactArray(
46
+ txReceipt.logs
47
+ .filter(l => l.address.toLowerCase() === inboxAddress.toString().toLowerCase())
48
+ .map(l => {
49
+ try {
50
+ return decodeEventLog({ abi: InboxAbi, eventName: 'MessageSent', data: l.data, topics: l.topics });
51
+ } catch {
52
+ return undefined;
53
+ }
54
+ }),
55
+ );
56
+
57
+ if (messageSentLogs.length !== 1) {
58
+ throw new Error(`Expected 1 MessageSent event, got ${messageSentLogs.length}`);
59
+ }
60
+
61
+ const event = messageSentLogs[0];
62
+
63
+ const msgHash = event.args.hash;
64
+ const globalLeafIndex = event.args.index;
65
+
66
+ const msg: PendingL1ToL2Message = {
67
+ content: content.toString(),
68
+ secret: secret.toString(),
69
+ secretHash: secretHash.toString(),
70
+ msgHash,
71
+ sender: l1Client.account!.address,
72
+ globalLeafIndex: globalLeafIndex.toString(),
73
+ timestamp: Date.now(),
74
+ };
75
+
76
+ await store.savePendingL1ToL2Message(msg);
77
+ log.info(`Seeded L1→L2 message msgHash=${msg.msgHash}`);
78
+ return msg;
79
+ }
package/src/rpc.ts CHANGED
@@ -1,21 +1,8 @@
1
1
  import type { ApiHandler } from '@aztec/foundation/json-rpc/server';
2
- import { createTracedJsonRpcServer } from '@aztec/telemetry-client';
3
2
 
4
3
  import { BotRunnerApiSchema } from './interface.js';
5
4
  import type { BotRunner } from './runner.js';
6
5
 
7
- /**
8
- * Wraps a bot runner with a JSON RPC HTTP server.
9
- * @param botRunner - The BotRunner.
10
- * @returns An JSON-RPC HTTP server
11
- */
12
- export function createBotRunnerRpcServer(botRunner: BotRunner) {
13
- createTracedJsonRpcServer(botRunner, BotRunnerApiSchema, {
14
- http200OnError: false,
15
- healthCheck: botRunner.isHealthy.bind(botRunner),
16
- });
17
- }
18
-
19
6
  export function getBotRunnerApiHandler(botRunner: BotRunner): ApiHandler {
20
7
  return [botRunner, BotRunnerApiSchema, botRunner.isHealthy.bind(botRunner)];
21
8
  }
package/src/runner.ts CHANGED
@@ -1,16 +1,22 @@
1
- import { type AztecNode, type PXE, createAztecNodeClient, createLogger } from '@aztec/aztec.js';
1
+ import { createLogger } from '@aztec/aztec.js/log';
2
+ import type { AztecNode } from '@aztec/aztec.js/node';
3
+ import { omit } from '@aztec/foundation/collection';
2
4
  import { RunningPromise } from '@aztec/foundation/running-promise';
3
- import { type TelemetryClient, type Traceable, type Tracer, makeTracedFetch, trackSpan } from '@aztec/telemetry-client';
5
+ import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
6
+ import { type TelemetryClient, type Traceable, type Tracer, trackSpan } from '@aztec/telemetry-client';
7
+ import type { EmbeddedWallet } from '@aztec/wallets/embedded';
4
8
 
9
+ import { AmmBot } from './amm_bot.js';
10
+ import type { BaseBot } from './base_bot.js';
5
11
  import { Bot } from './bot.js';
6
- import { type BotConfig, getVersions } from './config.js';
7
- import type { BotRunnerApi } from './interface.js';
12
+ import type { BotConfig } from './config.js';
13
+ import { CrossChainBot } from './cross_chain_bot.js';
14
+ import type { BotInfo, BotRunnerApi } from './interface.js';
15
+ import { BotStore } from './store/index.js';
8
16
 
9
17
  export class BotRunner implements BotRunnerApi, Traceable {
10
18
  private log = createLogger('bot');
11
- private bot?: Promise<Bot>;
12
- private pxe?: PXE;
13
- private node: AztecNode;
19
+ private bot?: Promise<BaseBot>;
14
20
  private runningPromise: RunningPromise;
15
21
  private consecutiveErrors = 0;
16
22
  private healthy = true;
@@ -19,15 +25,14 @@ export class BotRunner implements BotRunnerApi, Traceable {
19
25
 
20
26
  public constructor(
21
27
  private config: BotConfig,
22
- dependencies: { pxe?: PXE; node?: AztecNode; telemetry: TelemetryClient },
28
+ private readonly wallet: EmbeddedWallet,
29
+ private readonly aztecNode: AztecNode,
30
+ private readonly telemetry: TelemetryClient,
31
+ private readonly aztecNodeAdmin: AztecNodeAdmin | undefined,
32
+ private readonly store: BotStore,
23
33
  ) {
24
- this.tracer = dependencies.telemetry.getTracer('Bot');
25
- this.pxe = dependencies.pxe;
26
- if (!dependencies.node && !config.nodeUrl) {
27
- throw new Error(`Missing node URL in config or dependencies`);
28
- }
29
- this.node =
30
- dependencies.node ?? createAztecNodeClient(config.nodeUrl!, getVersions(), makeTracedFetch([1, 2, 3], true));
34
+ this.tracer = telemetry.getTracer('Bot');
35
+
31
36
  this.runningPromise = new RunningPromise(() => this.#work(), this.log, config.txIntervalSeconds * 1000);
32
37
  }
33
38
 
@@ -65,6 +70,7 @@ export class BotRunner implements BotRunnerApi, Traceable {
65
70
  this.log.verbose(`Stopping bot`);
66
71
  await this.runningPromise.stop();
67
72
  }
73
+ await this.store.close();
68
74
  this.log.info(`Stopped bot`);
69
75
  }
70
76
 
@@ -126,12 +132,36 @@ export class BotRunner implements BotRunnerApi, Traceable {
126
132
 
127
133
  /** Returns the current configuration for the bot. */
128
134
  public getConfig() {
129
- return Promise.resolve(this.config);
135
+ const redacted = omit(this.config, 'l1Mnemonic', 'l1PrivateKey', 'senderPrivateKey');
136
+ return Promise.resolve(redacted as BotConfig);
137
+ }
138
+
139
+ /** Returns the bot sender address. */
140
+ public async getInfo(): Promise<BotInfo> {
141
+ if (!this.bot) {
142
+ throw new Error(`Bot is not initialized`);
143
+ }
144
+ const botAddress = await this.bot.then(b => b.defaultAccountAddress);
145
+ return { botAddress };
130
146
  }
131
147
 
132
148
  async #createBot() {
133
149
  try {
134
- this.bot = Bot.create(this.config, { pxe: this.pxe, node: this.node });
150
+ switch (this.config.botMode) {
151
+ case 'crosschain':
152
+ this.bot = CrossChainBot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store);
153
+ break;
154
+ case 'amm':
155
+ this.bot = AmmBot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store);
156
+ break;
157
+ case 'transfer':
158
+ this.bot = Bot.create(this.config, this.wallet, this.aztecNode, this.aztecNodeAdmin, this.store);
159
+ break;
160
+ default: {
161
+ const _exhaustive: never = this.config.botMode;
162
+ throw new Error(`Unsupported bot mode: [${_exhaustive}]`);
163
+ }
164
+ }
135
165
  await this.bot;
136
166
  } catch (err) {
137
167
  this.log.error(`Error setting up bot: ${err}`);
@@ -142,16 +172,16 @@ export class BotRunner implements BotRunnerApi, Traceable {
142
172
  @trackSpan('Bot.work')
143
173
  async #work() {
144
174
  if (this.config.maxPendingTxs > 0) {
145
- const pendingTxs = await this.node.getPendingTxs();
146
- if (pendingTxs.length >= this.config.maxPendingTxs) {
147
- this.log.verbose(`Not sending bot tx since node has ${pendingTxs.length} pending txs`);
175
+ const pendingTxCount = await this.aztecNode.getPendingTxCount();
176
+ if (pendingTxCount >= this.config.maxPendingTxs) {
177
+ this.log.verbose(`Not sending bot tx since node has ${pendingTxCount} pending txs`);
148
178
  return;
149
179
  }
150
180
  }
151
181
 
152
182
  try {
153
183
  await this.run();
154
- } catch (err) {
184
+ } catch {
155
185
  // Already logged in run()
156
186
  if (this.config.maxConsecutiveErrors > 0 && this.consecutiveErrors >= this.config.maxConsecutiveErrors) {
157
187
  this.log.error(`Too many errors bot is unhealthy`);
@@ -0,0 +1,196 @@
1
+ import { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import type { L2AmountClaim } from '@aztec/aztec.js/ethereum';
3
+ import { Fr } from '@aztec/foundation/curves/bn254';
4
+ import { type Logger, createLogger } from '@aztec/foundation/log';
5
+ import { DateProvider } from '@aztec/foundation/timer';
6
+ import type { AztecAsyncKVStore, AztecAsyncMap } from '@aztec/kv-store';
7
+
8
+ export interface BridgeClaimData {
9
+ claim: L2AmountClaim;
10
+ timestamp: number;
11
+ recipient: string;
12
+ }
13
+
14
+ export interface PendingL1ToL2Message {
15
+ /** Random content field sent in the message. */
16
+ content: string;
17
+ /** Secret for consuming the message. */
18
+ secret: string;
19
+ /** Hash of the secret. */
20
+ secretHash: string;
21
+ /** Hash of the L1→L2 message. */
22
+ msgHash: string;
23
+ /** L1 sender address (hex). */
24
+ sender: string;
25
+ /** Global leaf index in the L1→L2 message tree. */
26
+ globalLeafIndex: string;
27
+ /** Timestamp when the message was seeded. */
28
+ timestamp: number;
29
+ }
30
+
31
+ /**
32
+ * Simple data store for the bot to persist L1 bridge claims.
33
+ */
34
+ export class BotStore {
35
+ public static readonly SCHEMA_VERSION = 1;
36
+ private readonly bridgeClaims: AztecAsyncMap<string, string>;
37
+ private readonly pendingL1ToL2: AztecAsyncMap<string, string>;
38
+
39
+ constructor(
40
+ private readonly store: AztecAsyncKVStore,
41
+ private readonly log: Logger = createLogger('bot:store'),
42
+ private readonly dateProvider: DateProvider = new DateProvider(),
43
+ ) {
44
+ this.bridgeClaims = store.openMap<string, string>('bridge_claims');
45
+ this.pendingL1ToL2 = store.openMap<string, string>('pending_l1_to_l2');
46
+ }
47
+
48
+ /**
49
+ * Saves a bridge claim for a recipient.
50
+ */
51
+ public async saveBridgeClaim(recipient: AztecAddress, claim: L2AmountClaim): Promise<void> {
52
+ // Convert Fr fields and BigInts to strings for JSON serialization
53
+ const serializableClaim = {
54
+ claimAmount: claim.claimAmount.toString(),
55
+ claimSecret: claim.claimSecret.toString(),
56
+ claimSecretHash: claim.claimSecretHash.toString(),
57
+ messageHash: claim.messageHash,
58
+ messageLeafIndex: claim.messageLeafIndex.toString(),
59
+ };
60
+
61
+ const data = {
62
+ claim: serializableClaim,
63
+ timestamp: this.dateProvider.now(),
64
+ recipient: recipient.toString(),
65
+ };
66
+
67
+ await this.bridgeClaims.set(recipient.toString(), JSON.stringify(data));
68
+ this.log.info(`Saved bridge claim for ${recipient.toString()}`);
69
+ }
70
+
71
+ /**
72
+ * Gets a bridge claim for a recipient if it exists.
73
+ */
74
+ public async getBridgeClaim(recipient: AztecAddress): Promise<BridgeClaimData | undefined> {
75
+ const data = await this.bridgeClaims.getAsync(recipient.toString());
76
+ if (!data) {
77
+ return undefined;
78
+ }
79
+
80
+ const parsed = JSON.parse(data);
81
+
82
+ // Reconstruct L2AmountClaim from serialized data
83
+ const claim: L2AmountClaim = {
84
+ claimAmount: BigInt(parsed.claim.claimAmount),
85
+ claimSecret: Fr.fromString(parsed.claim.claimSecret),
86
+ claimSecretHash: Fr.fromString(parsed.claim.claimSecretHash),
87
+ messageHash: parsed.claim.messageHash,
88
+ messageLeafIndex: BigInt(parsed.claim.messageLeafIndex),
89
+ };
90
+
91
+ return {
92
+ claim,
93
+ timestamp: parsed.timestamp,
94
+ recipient: parsed.recipient,
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Deletes a bridge claim for a recipient.
100
+ */
101
+ public async deleteBridgeClaim(recipient: AztecAddress): Promise<void> {
102
+ await this.bridgeClaims.delete(recipient.toString());
103
+ this.log.info(`Deleted bridge claim for ${recipient.toString()}`);
104
+ }
105
+
106
+ /**
107
+ * Gets all stored bridge claims.
108
+ */
109
+ public async getAllBridgeClaims(): Promise<BridgeClaimData[]> {
110
+ const claims: BridgeClaimData[] = [];
111
+ const entries = this.bridgeClaims.entriesAsync();
112
+
113
+ for await (const [_, data] of entries) {
114
+ const parsed = JSON.parse(data);
115
+
116
+ // Reconstruct L2AmountClaim from serialized data
117
+ const claim: L2AmountClaim = {
118
+ claimAmount: BigInt(parsed.claim.claimAmount),
119
+ claimSecret: Fr.fromString(parsed.claim.claimSecret),
120
+ claimSecretHash: Fr.fromString(parsed.claim.claimSecretHash),
121
+ messageHash: parsed.claim.messageHash,
122
+ messageLeafIndex: BigInt(parsed.claim.messageLeafIndex),
123
+ };
124
+
125
+ claims.push({
126
+ claim,
127
+ timestamp: parsed.timestamp,
128
+ recipient: parsed.recipient,
129
+ });
130
+ }
131
+
132
+ return claims;
133
+ }
134
+
135
+ /**
136
+ * Cleans up old bridge claims (older than 24 hours).
137
+ */
138
+ public async cleanupOldClaims(maxAgeMs: number = 24 * 60 * 60 * 1000): Promise<number> {
139
+ const now = this.dateProvider.now();
140
+ let cleanedCount = 0;
141
+ const entries = this.bridgeClaims.entriesAsync();
142
+
143
+ for await (const [key, data] of entries) {
144
+ const parsed = JSON.parse(data);
145
+ if (now - parsed.timestamp > maxAgeMs) {
146
+ await this.bridgeClaims.delete(key);
147
+ cleanedCount++;
148
+ this.log.info(`Cleaned up old bridge claim for ${parsed.recipient}`);
149
+ }
150
+ }
151
+
152
+ return cleanedCount;
153
+ }
154
+
155
+ /** Saves a pending L1→L2 message keyed by msgHash. */
156
+ public async savePendingL1ToL2Message(msg: PendingL1ToL2Message): Promise<void> {
157
+ await this.pendingL1ToL2.set(msg.msgHash, JSON.stringify(msg));
158
+ this.log.info(`Saved pending L1→L2 message ${msg.msgHash}`);
159
+ }
160
+
161
+ /** Returns all unconsumed pending L1→L2 messages. */
162
+ public async getUnconsumedL1ToL2Messages(): Promise<PendingL1ToL2Message[]> {
163
+ const messages: PendingL1ToL2Message[] = [];
164
+ for await (const [_, data] of this.pendingL1ToL2.entriesAsync()) {
165
+ messages.push(JSON.parse(data));
166
+ }
167
+ return messages;
168
+ }
169
+
170
+ /** Deletes a consumed L1→L2 message from the store. */
171
+ public async deleteL1ToL2Message(msgHash: string): Promise<void> {
172
+ await this.pendingL1ToL2.delete(msgHash);
173
+ this.log.info(`Deleted consumed L1→L2 message ${msgHash}`);
174
+ }
175
+
176
+ /** Cleans up pending L1→L2 messages older than maxAgeMs. */
177
+ public async cleanupOldPendingMessages(maxAgeMs: number = 24 * 60 * 60 * 1000): Promise<number> {
178
+ const now = this.dateProvider.now();
179
+ let cleanedCount = 0;
180
+ for await (const [key, data] of this.pendingL1ToL2.entriesAsync()) {
181
+ const parsed = JSON.parse(data);
182
+ if (now - parsed.timestamp > maxAgeMs) {
183
+ await this.pendingL1ToL2.delete(key);
184
+ cleanedCount++;
185
+ this.log.info(`Cleaned up old pending L1→L2 message ${key}`);
186
+ }
187
+ }
188
+ return cleanedCount;
189
+ }
190
+
191
+ /** Closes the store. */
192
+ public async close(): Promise<void> {
193
+ await this.store.close();
194
+ this.log.info('Closed bot data store');
195
+ }
196
+ }
@@ -0,0 +1 @@
1
+ export { BotStore, type BridgeClaimData, type PendingL1ToL2Message } from './bot_store.js';
package/src/utils.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { EasyPrivateTokenContract } from '@aztec/noir-contracts.js/EasyPrivateToken';
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
 
@@ -11,17 +13,26 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address';
11
13
  export async function getBalances(
12
14
  token: TokenContract,
13
15
  who: AztecAddress,
16
+ from?: AztecAddress,
14
17
  ): Promise<{ privateBalance: bigint; publicBalance: bigint }> {
15
- const privateBalance = await token.methods.balance_of_private(who).simulate();
16
- const publicBalance = await token.methods.balance_of_public(who).simulate();
18
+ const { result: privateBalance } = await token.methods.balance_of_private(who).simulate({ from: from ?? who });
19
+ const { result: publicBalance } = await token.methods.balance_of_public(who).simulate({ from: from ?? who });
17
20
  return { privateBalance, publicBalance };
18
21
  }
19
22
 
20
- export async function getPrivateBalance(token: EasyPrivateTokenContract, who: AztecAddress): Promise<bigint> {
21
- const privateBalance = await token.methods.get_balance(who).simulate();
23
+ export async function getPrivateBalance(
24
+ token: PrivateTokenContract,
25
+ who: AztecAddress,
26
+ from?: AztecAddress,
27
+ ): Promise<bigint> {
28
+ const { result: privateBalance } = await token.methods.get_balance(who).simulate({ from: from ?? who });
22
29
  return privateBalance;
23
30
  }
24
31
 
25
- export function isStandardTokenContract(token: TokenContract | EasyPrivateTokenContract): token is TokenContract {
32
+ export function isStandardTokenContract(token: ContractBase): token is TokenContract {
26
33
  return 'mint_to_public' in token.methods;
27
34
  }
35
+
36
+ export function isAMMContract(contract: ContractBase): contract is AMMContract {
37
+ return 'add_liquidity' in contract.methods;
38
+ }