web3agent 0.1.0 → 0.2.0

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.
@@ -0,0 +1,1760 @@
1
+ import {
2
+ createWalletClientForChain,
3
+ getActiveAccount,
4
+ getTransportForChain,
5
+ getWalletState,
6
+ walletEvents
7
+ } from "./chunk-KPRIUALX.js";
8
+ import {
9
+ getChainById,
10
+ getConfig,
11
+ isSupported,
12
+ parseEnv,
13
+ tryGetConfig
14
+ } from "./chunk-7QEKU2RP.js";
15
+
16
+ // src/api/errors.ts
17
+ var Web3AgentError = class _Web3AgentError extends Error {
18
+ code;
19
+ details;
20
+ cause;
21
+ constructor(options) {
22
+ super(options.message);
23
+ this.name = "Web3AgentError";
24
+ this.code = options.code;
25
+ this.details = options.details;
26
+ this.cause = options.cause;
27
+ }
28
+ static fromUnknown(code, error, fallbackMessage = "Unknown error", details) {
29
+ if (error instanceof _Web3AgentError) {
30
+ return error;
31
+ }
32
+ if (error instanceof Error) {
33
+ return new _Web3AgentError({
34
+ code,
35
+ message: error.message,
36
+ details,
37
+ cause: error
38
+ });
39
+ }
40
+ return new _Web3AgentError({
41
+ code,
42
+ message: typeof error === "string" ? error : fallbackMessage,
43
+ details,
44
+ cause: error
45
+ });
46
+ }
47
+ };
48
+
49
+ // src/goat/plugins.ts
50
+ import { zeroEx } from "@goat-sdk/plugin-0x";
51
+ import { balancer } from "@goat-sdk/plugin-balancer";
52
+ import { coingecko } from "@goat-sdk/plugin-coingecko";
53
+ import { dexscreener } from "@goat-sdk/plugin-dexscreener";
54
+ import { ens } from "@goat-sdk/plugin-ens";
55
+ import { USDC, WETH, erc20 } from "@goat-sdk/plugin-erc20";
56
+
57
+ // node_modules/.pnpm/@goat-sdk+plugin-erc721@0.1.22_@goat-sdk+core@0.5.0_zod@3.25.76__bufferutil@4.1.0_typescript@_kuv3rgxdfmzbc55zxk3icop5ti/node_modules/@goat-sdk/plugin-erc721/dist/chunk-YSXGDEY5.mjs
58
+ var c = Object.defineProperty;
59
+ var d = (a2, b) => c(a2, "name", { value: b, configurable: true });
60
+
61
+ // node_modules/.pnpm/@goat-sdk+plugin-erc721@0.1.22_@goat-sdk+core@0.5.0_zod@3.25.76__bufferutil@4.1.0_typescript@_kuv3rgxdfmzbc55zxk3icop5ti/node_modules/@goat-sdk/plugin-erc721/dist/chunk-YVTV6MH2.mjs
62
+ var d2 = { symbol: "BAYC", name: "Bored Ape Yacht Club", chains: { 1: { contractAddress: "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D" } } };
63
+ var A = { symbol: "PUNK", name: "CryptoPunks", chains: { 1: { contractAddress: "0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB" } } };
64
+ function m(t2, c4) {
65
+ let s3 = [];
66
+ for (let o2 of c4) {
67
+ let e3 = o2.chains[t2];
68
+ e3 && s3.push({ chainId: t2, symbol: o2.symbol, name: o2.name, contractAddress: e3.contractAddress });
69
+ }
70
+ return s3;
71
+ }
72
+ d(m, "getTokensForNetwork");
73
+
74
+ // node_modules/.pnpm/@goat-sdk+plugin-erc721@0.1.22_@goat-sdk+core@0.5.0_zod@3.25.76__bufferutil@4.1.0_typescript@_kuv3rgxdfmzbc55zxk3icop5ti/node_modules/@goat-sdk/plugin-erc721/dist/chunk-Y4M3I524.mjs
75
+ import { parseAbi as e } from "viem";
76
+ var o = e(["function transferFrom(address from, address to, uint256 tokenId) external", "function safeTransferFrom(address from, address to, uint256 tokenId) external", "function safeTransferFrom(address from, address to, uint256 tokenId, bytes data) external", "function approve(address to, uint256 tokenId) external", "function setApprovalForAll(address operator, bool approved) external", "function getApproved(uint256 tokenId) external view returns (address)", "function isApprovedForAll(address owner, address operator) external view returns (bool)", "function balanceOf(address owner) external view returns (uint256)", "function ownerOf(uint256 tokenId) external view returns (address)"]);
77
+
78
+ // node_modules/.pnpm/@goat-sdk+plugin-erc721@0.1.22_@goat-sdk+core@0.5.0_zod@3.25.76__bufferutil@4.1.0_typescript@_kuv3rgxdfmzbc55zxk3icop5ti/node_modules/@goat-sdk/plugin-erc721/dist/chunk-7FXBTDRO.mjs
79
+ async function f(a2, o2, r) {
80
+ try {
81
+ return (await a2.read({ address: o2.contractAddress, abi: o, functionName: "balanceOf", args: [r.wallet] })).value.toString();
82
+ } catch (t2) {
83
+ throw Error(`Failed to fetch balance: ${t2}`);
84
+ }
85
+ }
86
+ d(f, "balanceOf");
87
+ async function u(a2, o2, r) {
88
+ try {
89
+ let t2 = r.to;
90
+ return (await a2.sendTransaction({ to: o2.contractAddress, abi: o, functionName: "safeTransferFrom", args: [a2.getAddress(), t2, r.tokenId] })).hash;
91
+ } catch (t2) {
92
+ throw Error(`Failed to transfer: ${t2}`);
93
+ }
94
+ }
95
+ d(u, "transfer");
96
+ async function l(a2, o2) {
97
+ try {
98
+ return (await a2.read({ address: o2.contractAddress, abi: o, functionName: "totalSupply" })).value.toString();
99
+ } catch (r) {
100
+ throw Error(`Failed to fetch total supply: ${r}`);
101
+ }
102
+ }
103
+ d(l, "totalSupply");
104
+ async function p(a2, o2, r) {
105
+ try {
106
+ let t2 = r.spender;
107
+ return (await a2.sendTransaction({ to: o2.contractAddress, abi: o, functionName: "approve", args: [t2, r.tokenId] })).hash;
108
+ } catch (t2) {
109
+ throw Error(`Failed to approve: ${t2}`);
110
+ }
111
+ }
112
+ d(p, "approve");
113
+ async function y(a2, o2, r) {
114
+ try {
115
+ let t2 = r.from, s3 = r.to;
116
+ return (await a2.sendTransaction({ to: o2.contractAddress, abi: o, functionName: "safeTransferFrom", args: [t2, s3, r.tokenId] })).hash;
117
+ } catch (t2) {
118
+ throw Error(`Failed to transfer from: ${t2}`);
119
+ }
120
+ }
121
+ d(y, "transferFrom");
122
+
123
+ // node_modules/.pnpm/@goat-sdk+plugin-erc721@0.1.22_@goat-sdk+core@0.5.0_zod@3.25.76__bufferutil@4.1.0_typescript@_kuv3rgxdfmzbc55zxk3icop5ti/node_modules/@goat-sdk/plugin-erc721/dist/chunk-QJ4AOIPR.mjs
124
+ import { z as e2 } from "zod";
125
+ var s = e2.object({ wallet: e2.string().describe("The address to get the NFT balance of") });
126
+ var a = e2.object({ to: e2.string().describe("The address to transfer the NFT to"), tokenId: e2.string().describe("The ID of the NFT to transfer") });
127
+ var c2 = e2.object({});
128
+ var n = e2.object({ spender: e2.string().describe("The address to approve for the NFT"), tokenId: e2.string().describe("The ID of the NFT to approve") });
129
+ var h = e2.object({ from: e2.string().describe("The address to transfer the NFT from"), to: e2.string().describe("The address to transfer the NFT to"), tokenId: e2.string().describe("The ID of the NFT to transfer") });
130
+ var d3 = e2.object({ tokenId: e2.string().describe("The ID of the NFT to check ownership of") });
131
+
132
+ // node_modules/.pnpm/@goat-sdk+plugin-erc721@0.1.22_@goat-sdk+core@0.5.0_zod@3.25.76__bufferutil@4.1.0_typescript@_kuv3rgxdfmzbc55zxk3icop5ti/node_modules/@goat-sdk/plugin-erc721/dist/chunk-CBG3ZAQD.mjs
133
+ import { createTool as s2 } from "@goat-sdk/core";
134
+ function k(e3, b) {
135
+ let a2 = [];
136
+ for (let o2 of b) {
137
+ let d4 = s2({ name: `get_${o2.symbol}_balance`, description: `This {{tool}} gets the number of NFTs owned for ${o2.symbol}`, parameters: s }, (r) => f(e3, o2, r)), $ = s2({ name: `transfer_${o2.symbol}`, description: `This {{tool}} transfers a ${o2.symbol} NFT to the specified address`, parameters: a }, (r) => u(e3, o2, r)), u2 = s2({ name: `get_${o2.symbol}_total_supply`, description: `This {{tool}} gets the total supply of ${o2.symbol} NFTs`, parameters: c2 }, (r) => l(e3, o2)), _ = s2({ name: `approve_${o2.symbol}`, description: `This {{tool}} approves an address to transfer a specific ${o2.symbol} NFT`, parameters: n }, (r) => p(e3, o2, r)), F = s2({ name: `transfer_${o2.symbol}_from`, description: `This {{tool}} transfers a ${o2.symbol} NFT from one address to another`, parameters: h }, (r) => y(e3, o2, r));
138
+ a2.push(d4, $, u2, _, F);
139
+ }
140
+ return a2;
141
+ }
142
+ d(k, "getTools");
143
+
144
+ // node_modules/.pnpm/@goat-sdk+plugin-erc721@0.1.22_@goat-sdk+core@0.5.0_zod@3.25.76__bufferutil@4.1.0_typescript@_kuv3rgxdfmzbc55zxk3icop5ti/node_modules/@goat-sdk/plugin-erc721/dist/chunk-DH72JTG4.mjs
145
+ import { PluginBase as c3 } from "@goat-sdk/core";
146
+ var t = class extends c3 {
147
+ static {
148
+ d(this, "ERC721Plugin");
149
+ }
150
+ tokens;
151
+ constructor({ tokens: o2 }) {
152
+ super("erc721", []), this.tokens = o2;
153
+ }
154
+ supportsChain = d((o2) => o2.type === "evm", "supportsChain");
155
+ getTools(o2) {
156
+ let s3 = o2.getChain();
157
+ if (!s3.id) throw new Error("Network ID is required");
158
+ let p2 = m(s3.id, this.tokens);
159
+ return k(o2, p2);
160
+ }
161
+ };
162
+ function w({ tokens: e3 }) {
163
+ return new t({ tokens: e3 });
164
+ }
165
+ d(w, "erc721");
166
+
167
+ // src/goat/plugins.ts
168
+ import { uniswap } from "@goat-sdk/plugin-uniswap";
169
+ function loadPlugins(options) {
170
+ const result = {
171
+ plugins: [],
172
+ loadedTier0: [],
173
+ loadedTier1: [],
174
+ loadedTier2: [],
175
+ failedPlugins: []
176
+ };
177
+ const tier0 = [
178
+ {
179
+ name: "erc20",
180
+ factory: () => erc20({ tokens: [USDC, WETH] })
181
+ },
182
+ {
183
+ name: "erc721",
184
+ factory: () => w({ tokens: [d2, A] })
185
+ },
186
+ {
187
+ name: "ens",
188
+ factory: () => ens({})
189
+ },
190
+ {
191
+ name: "dexscreener",
192
+ factory: () => dexscreener()
193
+ }
194
+ ];
195
+ for (const { name, factory } of tier0) {
196
+ try {
197
+ result.plugins.push(factory());
198
+ result.loadedTier0.push(name);
199
+ } catch (e3) {
200
+ process.stderr.write(`[web3agent] GOAT plugin ${name} failed to load: ${e3}
201
+ `);
202
+ result.failedPlugins.push({ name, error: String(e3) });
203
+ }
204
+ }
205
+ if (options.hasWallet) {
206
+ const tier1 = [
207
+ {
208
+ name: "uniswap",
209
+ factory: () => uniswap({
210
+ apiKey: "default",
211
+ baseUrl: "https://api.uniswap.org"
212
+ }),
213
+ condition: true
214
+ },
215
+ {
216
+ name: "balancer",
217
+ factory: () => balancer({ rpcUrl: options.rpcUrl ?? "https://eth.llamarpc.com" }),
218
+ condition: true
219
+ }
220
+ ];
221
+ for (const { name, factory, condition } of tier1) {
222
+ if (!condition) continue;
223
+ try {
224
+ result.plugins.push(factory());
225
+ result.loadedTier1.push(name);
226
+ } catch (e3) {
227
+ process.stderr.write(`[web3agent] GOAT plugin ${name} failed to load: ${e3}
228
+ `);
229
+ result.failedPlugins.push({ name, error: String(e3) });
230
+ }
231
+ }
232
+ }
233
+ if (options.coingeckoApiKey) {
234
+ try {
235
+ result.plugins.push(coingecko({ apiKey: options.coingeckoApiKey }));
236
+ result.loadedTier2.push("coingecko");
237
+ } catch (e3) {
238
+ process.stderr.write(`[web3agent] GOAT plugin coingecko failed to load: ${e3}
239
+ `);
240
+ result.failedPlugins.push({ name: "coingecko", error: String(e3) });
241
+ }
242
+ }
243
+ if (options.zeroxApiKey) {
244
+ try {
245
+ result.plugins.push(zeroEx({ apiKey: options.zeroxApiKey }));
246
+ result.loadedTier2.push("0x");
247
+ } catch (e3) {
248
+ process.stderr.write(`[web3agent] GOAT plugin 0x failed to load: ${e3}
249
+ `);
250
+ result.failedPlugins.push({ name: "0x", error: String(e3) });
251
+ }
252
+ }
253
+ return result;
254
+ }
255
+
256
+ // src/goat/toolset.ts
257
+ import { getTools } from "@goat-sdk/core";
258
+ import { zodToJsonSchema } from "zod-to-json-schema";
259
+ async function buildGoatTools(params) {
260
+ const plugins = params.pluginResult.plugins;
261
+ return getTools({
262
+ wallet: params.wallet,
263
+ plugins
264
+ });
265
+ }
266
+ function createGoatToolSnapshot(chainId, tools) {
267
+ return {
268
+ listOfTools: tools.map((tool) => ({
269
+ name: tool.name,
270
+ description: tool.description,
271
+ inputSchema: zodToJsonSchema(tool.parameters)
272
+ })),
273
+ toolHandler: async (toolName, params) => {
274
+ const tool = tools.find((candidate) => candidate.name === toolName);
275
+ if (!tool) {
276
+ throw new Error(`Tool ${toolName} not found`);
277
+ }
278
+ const parsed = tool.parameters.parse(params ?? {});
279
+ const result = await tool.execute(parsed);
280
+ return {
281
+ content: [
282
+ {
283
+ type: "text",
284
+ text: JSON.stringify(result)
285
+ }
286
+ ]
287
+ };
288
+ },
289
+ chainId
290
+ };
291
+ }
292
+
293
+ // src/utils/errors.ts
294
+ function toErrorBody(code, message, details) {
295
+ return {
296
+ error: code,
297
+ message,
298
+ ...details === void 0 ? {} : { details }
299
+ };
300
+ }
301
+ function formatToolError(code, message, details) {
302
+ const body = toErrorBody(code, message, details);
303
+ const structuredContent = {
304
+ ok: false,
305
+ error: {
306
+ code,
307
+ message,
308
+ ...details === void 0 ? {} : { details }
309
+ }
310
+ };
311
+ return {
312
+ content: [
313
+ {
314
+ type: "text",
315
+ text: JSON.stringify(body)
316
+ }
317
+ ],
318
+ structuredContent,
319
+ isError: true
320
+ };
321
+ }
322
+ function formatToolResponse(data) {
323
+ const structuredContent = {
324
+ ok: true,
325
+ data
326
+ };
327
+ return {
328
+ content: [
329
+ {
330
+ type: "text",
331
+ text: typeof data === "string" ? data : JSON.stringify(data, null, 2)
332
+ }
333
+ ],
334
+ structuredContent,
335
+ isError: false
336
+ };
337
+ }
338
+ function formatToolErrorFromUnknown(fallbackCode, error, fallbackMessage = "Unknown error") {
339
+ if (error instanceof Web3AgentError) {
340
+ return formatToolError(error.code, error.message, error.details);
341
+ }
342
+ if (error instanceof Error) {
343
+ return formatToolError(fallbackCode, error.message);
344
+ }
345
+ return formatToolError(fallbackCode, typeof error === "string" ? error : fallbackMessage);
346
+ }
347
+
348
+ // src/goat/provider.ts
349
+ import { viem } from "@goat-sdk/wallet-viem";
350
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
351
+ var GoatProvider = class {
352
+ snapshots = /* @__PURE__ */ new Map();
353
+ pluginResult;
354
+ referenceSnapshot;
355
+ generation = 0;
356
+ runtimeConfig;
357
+ walletChangeHandler;
358
+ rebuildPromise = Promise.resolve();
359
+ async initialize(config) {
360
+ this.runtimeConfig = config;
361
+ const walletState = getWalletState();
362
+ const hasWallet = walletState.mode !== "read-only";
363
+ this.pluginResult = loadPlugins({
364
+ hasWallet,
365
+ zeroxApiKey: config.zeroxApiKey,
366
+ coingeckoApiKey: config.coingeckoApiKey,
367
+ rpcUrl: config.rpcUrl
368
+ });
369
+ const defaultChainId = walletState.chainId;
370
+ await this.buildSnapshot(defaultChainId);
371
+ this.referenceSnapshot = this.snapshots.get(defaultChainId);
372
+ this.walletChangeHandler = (state) => {
373
+ this.generation++;
374
+ const gen = this.generation;
375
+ const hasWallet2 = state.mode !== "read-only";
376
+ this.pluginResult = loadPlugins({
377
+ hasWallet: hasWallet2,
378
+ zeroxApiKey: this.runtimeConfig?.zeroxApiKey,
379
+ coingeckoApiKey: this.runtimeConfig?.coingeckoApiKey,
380
+ rpcUrl: this.runtimeConfig?.rpcUrl
381
+ });
382
+ this.rebuildPromise = this.rebuildPromise.catch(() => {
383
+ }).then(() => this.buildSnapshot(state.chainId)).then(() => {
384
+ if (this.generation !== gen) return;
385
+ this.referenceSnapshot = this.snapshots.get(state.chainId);
386
+ process.stderr.write(
387
+ `[goat] Rebuilt snapshot for chain ${state.chainId} after wallet change
388
+ `
389
+ );
390
+ }).catch((e3) => {
391
+ process.stderr.write(`[goat] Failed to rebuild snapshot after wallet change: ${e3}
392
+ `);
393
+ });
394
+ };
395
+ walletEvents.on("wallet-changed", this.walletChangeHandler);
396
+ }
397
+ /** Wait for any in-flight rebuild triggered by a wallet change. */
398
+ async waitForRebuild() {
399
+ await this.rebuildPromise;
400
+ }
401
+ shutdown() {
402
+ if (this.walletChangeHandler) {
403
+ walletEvents.off("wallet-changed", this.walletChangeHandler);
404
+ this.walletChangeHandler = void 0;
405
+ }
406
+ }
407
+ async buildSnapshot(chainId) {
408
+ if (!this.pluginResult) {
409
+ throw new Error("GoatProvider not initialized \u2014 call initialize() first");
410
+ }
411
+ let account;
412
+ const walletState = getWalletState();
413
+ if (walletState.mode !== "read-only") {
414
+ account = getActiveAccount();
415
+ } else {
416
+ const ephemeralKey = generatePrivateKey();
417
+ account = privateKeyToAccount(ephemeralKey);
418
+ }
419
+ const walletClient = createWalletClientForChain(account, chainId, this.runtimeConfig);
420
+ const tools = await buildGoatTools({
421
+ wallet: viem(walletClient),
422
+ pluginResult: this.pluginResult
423
+ });
424
+ this.snapshots.set(chainId, createGoatToolSnapshot(chainId, tools));
425
+ }
426
+ async getOrBuildSnapshot(chainId) {
427
+ const existing = this.snapshots.get(chainId);
428
+ if (existing) return existing;
429
+ try {
430
+ await this.buildSnapshot(chainId);
431
+ return this.snapshots.get(chainId);
432
+ } catch (e3) {
433
+ process.stderr.write(`[web3agent] GOAT snapshot failed for chain ${chainId}: ${e3}
434
+ `);
435
+ return void 0;
436
+ }
437
+ }
438
+ getReferenceSnapshot() {
439
+ return this.referenceSnapshot;
440
+ }
441
+ getAllToolNames() {
442
+ if (this.referenceSnapshot) {
443
+ return this.referenceSnapshot.listOfTools.map((t2) => t2.name);
444
+ }
445
+ return [];
446
+ }
447
+ getLoadedPlugins() {
448
+ if (!this.pluginResult) return [];
449
+ return [
450
+ ...this.pluginResult.loadedTier0,
451
+ ...this.pluginResult.loadedTier1,
452
+ ...this.pluginResult.loadedTier2
453
+ ];
454
+ }
455
+ };
456
+ var goatProvider = new GoatProvider();
457
+
458
+ // src/goat/dispatch.ts
459
+ var RESTRICTED_PLUGIN_CHAINS = {
460
+ uniswap: [1, 137, 43114, 8453, 10, 42161, 42220],
461
+ balancer: [34443, 8453, 137, 100, 42161, 43114, 10]
462
+ };
463
+ function findRestrictedPlugin(toolName) {
464
+ const lowerName = toolName.toLowerCase();
465
+ const sortedKeys = Object.keys(RESTRICTED_PLUGIN_CHAINS).sort((a2, b) => b.length - a2.length);
466
+ for (const pluginKey of sortedKeys) {
467
+ if (lowerName.startsWith(pluginKey.toLowerCase())) {
468
+ return pluginKey;
469
+ }
470
+ }
471
+ return void 0;
472
+ }
473
+ async function dispatchGoatTool(toolName, params, options) {
474
+ const config = options?.config ?? getConfig();
475
+ const activeGoatProvider = options?.goatProvider ?? goatProvider;
476
+ const chainId = typeof params.chainId === "number" ? params.chainId : config.chainId;
477
+ if (!isSupported(chainId)) {
478
+ return formatToolError("UNSUPPORTED_CHAIN", `Chain ${chainId} is not a known EVM chain`);
479
+ }
480
+ const pluginKey = findRestrictedPlugin(toolName);
481
+ if (pluginKey) {
482
+ const availableChains = RESTRICTED_PLUGIN_CHAINS[pluginKey];
483
+ if (!availableChains.includes(chainId)) {
484
+ return formatToolError(
485
+ "TOOL_UNAVAILABLE_ON_CHAIN",
486
+ `${toolName} is not available on chain ${chainId}. Available on chains: ${availableChains.join(", ")}`,
487
+ { availableChainIds: availableChains }
488
+ );
489
+ }
490
+ }
491
+ const snapshot = await activeGoatProvider.getOrBuildSnapshot(chainId);
492
+ if (!snapshot) {
493
+ return formatToolError(
494
+ "CHAIN_INIT_FAILED",
495
+ `Failed to initialize GOAT tools for chain ${chainId}`
496
+ );
497
+ }
498
+ const { chainId: _ignored, ...goatParams } = params;
499
+ try {
500
+ const result = await snapshot.toolHandler(toolName, goatParams);
501
+ return result;
502
+ } catch (e3) {
503
+ return formatToolError("GOAT_TOOL_ERROR", String(e3));
504
+ }
505
+ }
506
+
507
+ // src/operations/validation.ts
508
+ import { isAddress, isHex } from "viem";
509
+ function assertChainSupported(chainId) {
510
+ const chain = getChainById(chainId);
511
+ if (!chain) {
512
+ throw new Web3AgentError({
513
+ code: "CHAIN_NOT_SUPPORTED",
514
+ message: `Unsupported chain ID: ${chainId}`
515
+ });
516
+ }
517
+ return chain;
518
+ }
519
+ function assertHex(value, field) {
520
+ if (!isHex(value)) {
521
+ throw new Web3AgentError({
522
+ code: "INVALID_PARAMS",
523
+ message: `${field} must be a valid 0x-prefixed hex string`
524
+ });
525
+ }
526
+ return value;
527
+ }
528
+ function assertAddress(value, field) {
529
+ if (!isAddress(value)) {
530
+ throw new Web3AgentError({
531
+ code: "INVALID_PARAMS",
532
+ message: `${field} must be a valid EVM address`
533
+ });
534
+ }
535
+ return value;
536
+ }
537
+ function assertRecord(value, field, code = "INVALID_PARAMS") {
538
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
539
+ throw new Web3AgentError({
540
+ code,
541
+ message: `${field} must be an object`
542
+ });
543
+ }
544
+ return value;
545
+ }
546
+ function parseBigIntString(value, field) {
547
+ try {
548
+ return BigInt(value);
549
+ } catch (error) {
550
+ throw new Web3AgentError({
551
+ code: "INVALID_PARAMS",
552
+ message: `${field} must be a valid integer string`,
553
+ cause: error
554
+ });
555
+ }
556
+ }
557
+
558
+ // src/operations/chain-access.ts
559
+ import { createPublicClient } from "viem";
560
+ function getFallbackProcessConfig(chainId) {
561
+ return parseEnv({
562
+ ...process.env,
563
+ CHAIN_ID: String(chainId)
564
+ });
565
+ }
566
+ function resolveRuntimeConfig(chainId, config) {
567
+ if (config) {
568
+ return config;
569
+ }
570
+ return tryGetConfig() ?? getFallbackProcessConfig(chainId);
571
+ }
572
+ function getChainForRuntime(chainId) {
573
+ return assertChainSupported(chainId);
574
+ }
575
+ function getRuntimeConfigForChain(chainId, config) {
576
+ return resolveRuntimeConfig(chainId, config);
577
+ }
578
+ function getTransportForRuntimeChain(chainId, config) {
579
+ return getTransportForChain(chainId, getRuntimeConfigForChain(chainId, config));
580
+ }
581
+ function getRpcUrlForRuntimeChain(chainId, config) {
582
+ const resolvedConfig = getRuntimeConfigForChain(chainId, config);
583
+ return resolvedConfig.chainRpcUrls[chainId] ?? (resolvedConfig.chainId === chainId ? resolvedConfig.rpcUrl : void 0);
584
+ }
585
+ function createPublicClientForRuntimeChain(chainId, config) {
586
+ return createPublicClient({
587
+ chain: getChainForRuntime(chainId),
588
+ transport: getTransportForRuntimeChain(chainId, config)
589
+ });
590
+ }
591
+
592
+ // src/api/schemas/common.ts
593
+ import { isAddress as isAddress2, isHex as isHex2 } from "viem";
594
+ import { z } from "zod";
595
+ var addressSchema = z.string().refine((value) => isAddress2(value), {
596
+ message: "must be a valid EVM address"
597
+ });
598
+ var hexSchema = z.string().refine((value) => isHex2(value), {
599
+ message: "must be a valid 0x-prefixed hex string"
600
+ });
601
+ var typedDataPayloadSchema = z.object({
602
+ domain: z.record(z.unknown()),
603
+ types: z.record(
604
+ z.array(
605
+ z.object({
606
+ name: z.string(),
607
+ type: z.string()
608
+ })
609
+ )
610
+ ),
611
+ primaryType: z.string(),
612
+ message: z.record(z.unknown())
613
+ });
614
+ var preparedTransactionRequestSchema = z.object({
615
+ to: addressSchema,
616
+ chainId: z.number().int(),
617
+ data: hexSchema.optional(),
618
+ value: z.string().optional(),
619
+ gasLimit: z.string().optional()
620
+ });
621
+ var preparedTransactionActionSchema = z.object({
622
+ id: z.string(),
623
+ type: z.literal("transaction"),
624
+ label: z.string(),
625
+ tx: preparedTransactionRequestSchema
626
+ });
627
+ var preparedSignTypedDataActionSchema = z.object({
628
+ id: z.string(),
629
+ type: z.literal("signTypedData"),
630
+ label: z.string(),
631
+ chainId: z.number().int(),
632
+ eip712: typedDataPayloadSchema
633
+ });
634
+ var preparedSignMessageActionSchema = z.object({
635
+ id: z.string(),
636
+ type: z.literal("signMessage"),
637
+ label: z.string(),
638
+ chainId: z.number().int(),
639
+ message: z.string()
640
+ });
641
+ var preparedActionSchema = z.union([
642
+ preparedTransactionActionSchema,
643
+ preparedSignTypedDataActionSchema,
644
+ preparedSignMessageActionSchema
645
+ ]);
646
+ var operationActionResultSchema = z.union([
647
+ z.object({
648
+ type: z.literal("transaction"),
649
+ txHash: z.string({ required_error: "txHash is required" }),
650
+ status: z.literal("confirmed")
651
+ }),
652
+ z.object({
653
+ type: z.literal("signature"),
654
+ signature: z.string({ required_error: "signature is required" })
655
+ }),
656
+ z.object({
657
+ type: z.literal("messageSignature"),
658
+ signature: z.string({ required_error: "signature is required" })
659
+ })
660
+ ]);
661
+ var operationActionResultsMapSchema = z.record(operationActionResultSchema);
662
+ var resumeStateBaseSchema = z.object({
663
+ summary: z.string().optional(),
664
+ intent: z.record(z.unknown()).optional(),
665
+ meta: z.record(z.unknown()).optional(),
666
+ actionResults: operationActionResultsMapSchema.optional()
667
+ });
668
+
669
+ // src/api/schemas/lifi.ts
670
+ import { z as z2 } from "zod";
671
+ var lifiGetQuoteSchema = z2.object({
672
+ fromChainId: z2.number({ required_error: "fromChainId is required" }).describe("Source chain ID"),
673
+ toChainId: z2.number({ required_error: "toChainId is required" }).describe("Destination chain ID"),
674
+ fromTokenAddress: z2.string({ required_error: "fromTokenAddress is required" }).describe("Source token address"),
675
+ toTokenAddress: z2.string({ required_error: "toTokenAddress is required" }).describe("Destination token address"),
676
+ fromAmount: z2.string({ required_error: "fromAmount is required" }).describe("Amount in smallest token units")
677
+ });
678
+ var lifiExecuteBridgeSchema = lifiGetQuoteSchema;
679
+ var lifiPrepareBridgeIntentSchema = lifiGetQuoteSchema.extend({
680
+ account: addressSchema.describe("Sender wallet address"),
681
+ approvalAmount: z2.string().optional().describe("Optional override for the token approval amount")
682
+ });
683
+
684
+ // src/api/schemas/orbs.ts
685
+ import { z as z3 } from "zod";
686
+ var orbsGetQuoteSchema = z3.object({
687
+ chainId: z3.number().optional().describe("Chain ID (defaults to runtime config)"),
688
+ fromToken: z3.string({ required_error: "fromToken is required" }).describe("Source token address"),
689
+ toToken: z3.string({ required_error: "toToken is required" }).describe("Destination token address"),
690
+ inAmount: z3.string({ required_error: "inAmount is required" }).describe("Amount in smallest token units"),
691
+ slippage: z3.number().optional().describe("Slippage percentage (0.5 = 0.5%, default 0.5)")
692
+ });
693
+ var orbsSwapSchema = orbsGetQuoteSchema;
694
+ var orbsPrepareSwapIntentSchema = orbsGetQuoteSchema.extend({
695
+ account: addressSchema.describe("User wallet address")
696
+ });
697
+ var orbsGetRequiredApprovalsSchema = z3.object({
698
+ chainId: z3.number().optional().describe("Chain ID (defaults to runtime config)"),
699
+ fromToken: z3.string({ required_error: "fromToken is required" }).describe("Source token address"),
700
+ inAmount: z3.string({ required_error: "inAmount is required" }).describe("Amount in smallest token units"),
701
+ account: addressSchema.describe("User wallet address")
702
+ });
703
+ var orbsPlaceTwapSchema = z3.object({
704
+ chainId: z3.number().optional().describe("Chain ID (defaults to runtime config)"),
705
+ srcToken: z3.string({ required_error: "srcToken is required" }).describe("Source token address"),
706
+ dstToken: z3.string({ required_error: "dstToken is required" }).describe("Destination token address"),
707
+ srcAmount: z3.string({ required_error: "srcAmount is required" }).describe("Total amount in smallest token units"),
708
+ chunks: z3.number({ required_error: "chunks is required" }).describe("Number of TWAP intervals"),
709
+ fillDelay: z3.number({ required_error: "fillDelay is required" }).describe("Delay between fills in seconds")
710
+ });
711
+ var orbsPrepareTwapIntentSchema = orbsPlaceTwapSchema.extend({
712
+ account: addressSchema.describe("User wallet address")
713
+ });
714
+ var orbsPlaceLimitSchema = z3.object({
715
+ chainId: z3.number().optional().describe("Chain ID (defaults to runtime config)"),
716
+ srcToken: z3.string({ required_error: "srcToken is required" }).describe("Source token address"),
717
+ dstToken: z3.string({ required_error: "dstToken is required" }).describe("Destination token address"),
718
+ srcAmount: z3.string({ required_error: "srcAmount is required" }).describe("Amount in smallest token units"),
719
+ dstMinAmount: z3.string({ required_error: "dstMinAmount is required" }).describe("Minimum output amount in smallest token units"),
720
+ expiry: z3.number().optional().describe("Order expiry as Unix timestamp")
721
+ });
722
+ var orbsPrepareLimitIntentSchema = orbsPlaceLimitSchema.extend({
723
+ account: addressSchema.describe("User wallet address")
724
+ });
725
+ var orbsSubmitSignedSwapSchema = z3.object({
726
+ chainId: z3.number().optional().describe("Chain ID (defaults to runtime config)"),
727
+ quote: z3.record(z3.unknown()).describe("Quote object from orbs_get_quote"),
728
+ signature: hexSchema.refine((v) => v.length >= 132, {
729
+ message: "signature must be at least 65 bytes (132 hex characters + 0x prefix)"
730
+ }).describe("Hex-encoded signature of the permit2 typed data")
731
+ });
732
+ var orbsSubmitSignedTwapOrderSchema = z3.object({
733
+ order: z3.record(z3.unknown()).describe("Order object from orbs_place_twap"),
734
+ signature: z3.object({
735
+ v: z3.number({ required_error: "signature.v is required" }).describe("Recovery parameter"),
736
+ r: z3.string({ required_error: "signature.r is required" }).describe("ECDSA r value"),
737
+ s: z3.string({ required_error: "signature.s is required" }).describe("ECDSA s value")
738
+ }).describe("EIP-712 signature components")
739
+ });
740
+ var orbsSwapStatusSchema = z3.object({
741
+ chainId: z3.number().optional().describe("Chain ID (defaults to runtime config)"),
742
+ sessionId: z3.string({ required_error: "sessionId is required" }).describe("Session ID from swap submission"),
743
+ user: z3.string({ required_error: "user is required" }).describe("User wallet address"),
744
+ maxAttempts: z3.number().optional().describe("Max polling attempts (default 20)")
745
+ });
746
+ var orbsListOrdersSchema = z3.object({
747
+ chainId: z3.number().optional().describe("Chain ID (defaults to runtime config)")
748
+ });
749
+
750
+ // src/api/schemas/operations.ts
751
+ import { z as z4 } from "zod";
752
+ var integerChainIdSchema = z4.custom(
753
+ (value) => typeof value === "number" && Number.isInteger(value),
754
+ {
755
+ message: "resumeState.state.chainId must be an integer"
756
+ }
757
+ );
758
+ var lifiBridgeFinalizationSchema = z4.discriminatedUnion("kind", [
759
+ z4.object({
760
+ kind: z4.literal("none")
761
+ }),
762
+ z4.object({
763
+ kind: z4.literal("permit2"),
764
+ signatureActionId: z4.string(),
765
+ tokenAddress: addressSchema,
766
+ amount: z4.string(),
767
+ nonce: z4.string(),
768
+ deadline: z4.string(),
769
+ permit2Proxy: addressSchema,
770
+ account: addressSchema,
771
+ witness: z4.literal(true),
772
+ diamondAddress: addressSchema,
773
+ diamondCalldataHash: hexSchema
774
+ })
775
+ ]);
776
+ var orbsSwapResumeStateStateSchema = resumeStateBaseSchema.extend({
777
+ chainId: integerChainIdSchema,
778
+ quote: z4.record(z4.unknown()),
779
+ approvalActions: z4.array(preparedTransactionActionSchema),
780
+ signAction: preparedSignTypedDataActionSchema
781
+ });
782
+ var orbsOrderResumeStateStateSchema = resumeStateBaseSchema.extend({
783
+ order: z4.record(z4.unknown()),
784
+ signAction: preparedSignTypedDataActionSchema
785
+ });
786
+ var goatResumeStateStateSchema = resumeStateBaseSchema.extend({
787
+ toolName: z4.string(),
788
+ params: z4.record(z4.unknown()).optional(),
789
+ chainId: integerChainIdSchema,
790
+ account: addressSchema
791
+ });
792
+ var lifiBridgeResumeStateStateSchema = resumeStateBaseSchema.extend({
793
+ stages: z4.array(z4.array(preparedActionSchema)),
794
+ finalAction: preparedTransactionActionSchema,
795
+ finalization: lifiBridgeFinalizationSchema.optional()
796
+ });
797
+ var operationResumeStateSchema = z4.object({
798
+ version: z4.literal(1),
799
+ integration: z4.enum(["orbs", "lifi", "goat"]).describe("Integration name (e.g. 'orbs', 'lifi')"),
800
+ kind: z4.string({ required_error: "kind is required" }).describe("Action type"),
801
+ state: z4.record(z4.unknown()).describe("Opaque resume state from previous call")
802
+ });
803
+ var prepareOperationSchema = z4.union([
804
+ orbsPrepareSwapIntentSchema.extend({
805
+ integration: z4.literal("orbs").describe("Integration name (e.g. 'orbs', 'lifi')"),
806
+ kind: z4.literal("swap").describe("Action type")
807
+ }),
808
+ orbsPrepareTwapIntentSchema.extend({
809
+ integration: z4.literal("orbs").describe("Integration name (e.g. 'orbs', 'lifi')"),
810
+ kind: z4.literal("twap").describe("Action type")
811
+ }),
812
+ orbsPrepareLimitIntentSchema.extend({
813
+ integration: z4.literal("orbs").describe("Integration name (e.g. 'orbs', 'lifi')"),
814
+ kind: z4.literal("limit").describe("Action type")
815
+ }),
816
+ lifiPrepareBridgeIntentSchema.extend({
817
+ integration: z4.literal("lifi").describe("Integration name (e.g. 'orbs', 'lifi')"),
818
+ kind: z4.literal("bridge").describe("Action type")
819
+ }),
820
+ z4.object({
821
+ integration: z4.literal("goat").describe("Integration name (e.g. 'orbs', 'lifi')"),
822
+ kind: z4.literal("tool").describe("Action type"),
823
+ toolName: z4.string({ required_error: "toolName is required" }),
824
+ params: z4.record(z4.unknown()).optional().describe("Action parameters"),
825
+ chainId: z4.number({ required_error: "chainId is required" }),
826
+ account: addressSchema
827
+ })
828
+ ]);
829
+ var resumeOperationSchema = z4.object({
830
+ resumeState: operationResumeStateSchema.describe("Opaque resume state from previous call"),
831
+ actionResults: operationActionResultsMapSchema.optional().describe("Array of completed action results")
832
+ });
833
+
834
+ // src/api/schemas/tokens.ts
835
+ import { z as z5 } from "zod";
836
+ var resolveTokenSchema = z5.object({
837
+ symbol: z5.string({ required_error: "symbol is required" }).describe("Token symbol (e.g. 'USDT', 'USDC', 'WETH', 'WBNB', 'DAI')"),
838
+ chainId: z5.number({ required_error: "chainId is required" }).describe(
839
+ "EVM chain ID (e.g. 1=Ethereum, 56=BSC, 137=Polygon, 8453=Base, 59144=Linea, 42161=Arbitrum, 10=Optimism)"
840
+ )
841
+ });
842
+ var listChainTokensSchema = z5.object({
843
+ chainId: z5.number({ required_error: "chainId is required" }).describe("EVM chain ID")
844
+ });
845
+
846
+ // src/api/schemas/wallet.ts
847
+ import { z as z6 } from "zod";
848
+ var walletFromMnemonicSchema = z6.object({
849
+ mnemonic: z6.string({ required_error: "mnemonic is required" }).min(1, "mnemonic must not be empty").describe("BIP-39 mnemonic phrase"),
850
+ accountIndex: z6.number().optional().describe("BIP-44 account index (default 0)"),
851
+ addressIndex: z6.number().optional().describe("BIP-44 address index (default 0)")
852
+ });
853
+ var walletDeriveAddressesSchema = z6.object({
854
+ mnemonic: z6.string({ required_error: "mnemonic is required" }).min(1, "mnemonic must not be empty").describe("BIP-39 mnemonic phrase"),
855
+ count: z6.number().min(1).max(20).optional().describe("Number of addresses to derive (1-20, default 5)")
856
+ });
857
+ var walletActivateSchema = z6.object({
858
+ privateKey: z6.string().optional().describe("Hex-encoded private key (0x-prefixed)"),
859
+ mnemonic: z6.string().optional().describe("BIP-39 mnemonic phrase"),
860
+ accountIndex: z6.number().optional().describe("BIP-44 account index (default 0, mnemonic only)"),
861
+ addressIndex: z6.number().optional().describe("BIP-44 address index (default 0, mnemonic only)")
862
+ }).refine((data) => data.privateKey || data.mnemonic, {
863
+ message: "Either privateKey or mnemonic must be provided"
864
+ });
865
+ var walletSetConfirmationSchema = z6.object({
866
+ enabled: z6.boolean({ required_error: "enabled is required" }).describe("true to require confirmation for writes, false to execute immediately")
867
+ });
868
+ var transactionConfirmSchema = z6.object({
869
+ id: z6.string({ required_error: "id is required" }).min(1, "id must not be empty").describe("UUID of the pending operation to confirm")
870
+ });
871
+ var transactionDenySchema = transactionConfirmSchema;
872
+ var transactionSimulateSchema = z6.object({
873
+ chainId: z6.number({ required_error: "chainId is required" }).describe("Target chain ID"),
874
+ to: addressSchema.describe("Destination contract or recipient address"),
875
+ data: hexSchema.describe("Hex-encoded calldata"),
876
+ value: z6.string().optional().describe("Optional native value in wei"),
877
+ from: addressSchema.describe("Sender address used for simulation")
878
+ });
879
+
880
+ // src/api/validation.ts
881
+ import { z as z7 } from "zod";
882
+ function parseInput(schema, input) {
883
+ try {
884
+ return schema.parse(input);
885
+ } catch (error) {
886
+ if (error instanceof z7.ZodError) {
887
+ throw new Web3AgentError({
888
+ code: "INVALID_PARAMS",
889
+ message: error.errors.map((issue) => issue.message).join("; "),
890
+ details: error.errors,
891
+ cause: error
892
+ });
893
+ }
894
+ throw Web3AgentError.fromUnknown("INVALID_PARAMS", error);
895
+ }
896
+ }
897
+
898
+ // src/api/operations/shared.ts
899
+ function isMissingReceiptError(error) {
900
+ if (!(error instanceof Error)) {
901
+ return false;
902
+ }
903
+ const message = error.message.toLowerCase();
904
+ return message.includes("receipt") && message.includes("not found");
905
+ }
906
+ function createPreparedApprovalActions(chainId, approvals) {
907
+ return approvals.map((step, index) => ({
908
+ id: `approval:${index}`,
909
+ type: "transaction",
910
+ label: step.label,
911
+ tx: {
912
+ to: step.tx.to,
913
+ chainId,
914
+ ...step.tx.data ? { data: step.tx.data } : {},
915
+ ...step.tx.value ? { value: step.tx.value } : {}
916
+ }
917
+ }));
918
+ }
919
+ function createTypedDataAction(chainId, label, eip712) {
920
+ return {
921
+ id: "sign-typed-data:0",
922
+ type: "signTypedData",
923
+ label,
924
+ chainId,
925
+ eip712
926
+ };
927
+ }
928
+ function buildPreparedOperation(integration, kind, summary, actions, state, meta) {
929
+ return {
930
+ integration,
931
+ kind,
932
+ summary,
933
+ actions,
934
+ resumeState: {
935
+ version: 1,
936
+ integration,
937
+ kind,
938
+ state: {
939
+ ...state,
940
+ actionResults: state.actionResults && typeof state.actionResults === "object" ? state.actionResults : {},
941
+ ...meta ? { meta } : {}
942
+ }
943
+ },
944
+ ...meta ? { meta } : {}
945
+ };
946
+ }
947
+ function getStoredActionResults(state) {
948
+ if (state.actionResults === void 0) {
949
+ return {};
950
+ }
951
+ return parseInput(operationActionResultsMapSchema, state.actionResults);
952
+ }
953
+ function mergeActionResults(state, actionResults) {
954
+ return {
955
+ ...getStoredActionResults(state),
956
+ ...actionResults ?? {}
957
+ };
958
+ }
959
+ function assertActionResultType(actionResults, actionId, expectedType) {
960
+ const result = actionResults[actionId];
961
+ if (!result) return void 0;
962
+ if (result.type !== expectedType) {
963
+ throw new Web3AgentError({
964
+ code: "INVALID_PARAMS",
965
+ message: `Action result ${actionId} must be of type ${expectedType}`
966
+ });
967
+ }
968
+ return result;
969
+ }
970
+ async function getConfirmedReceipt(action, result) {
971
+ const publicClient = createPublicClientForRuntimeChain(action.tx.chainId);
972
+ try {
973
+ const receipt = await publicClient.getTransactionReceipt({
974
+ hash: result.txHash
975
+ });
976
+ if (receipt.status !== "success") {
977
+ throw new Web3AgentError({
978
+ code: "INVALID_PARAMS",
979
+ message: `Action result ${action.id} must reference a successful confirmed transaction`
980
+ });
981
+ }
982
+ if (receipt.to && receipt.to.toLowerCase() !== action.tx.to.toLowerCase()) {
983
+ throw new Web3AgentError({
984
+ code: "INVALID_PARAMS",
985
+ message: `Action result ${action.id} transaction target does not match the prepared action`
986
+ });
987
+ }
988
+ return receipt;
989
+ } catch (error) {
990
+ if (error instanceof Web3AgentError) {
991
+ throw error;
992
+ }
993
+ if (isMissingReceiptError(error)) {
994
+ throw new Web3AgentError({
995
+ code: "INVALID_PARAMS",
996
+ message: `Action result ${action.id} must reference a confirmed transaction receipt`,
997
+ cause: error
998
+ });
999
+ }
1000
+ throw new Web3AgentError({
1001
+ code: "INVALID_PARAMS",
1002
+ message: `Failed to verify transaction result for action ${action.id}`,
1003
+ cause: error
1004
+ });
1005
+ }
1006
+ }
1007
+ async function isPreparedActionSatisfied(actionResults, action) {
1008
+ if (action.type === "transaction") {
1009
+ const result2 = assertActionResultType(actionResults, action.id, "transaction");
1010
+ if (!result2) {
1011
+ return false;
1012
+ }
1013
+ await getConfirmedReceipt(action, result2);
1014
+ return true;
1015
+ }
1016
+ if (action.type === "signTypedData") {
1017
+ return assertActionResultType(actionResults, action.id, "signature") !== void 0;
1018
+ }
1019
+ const result = actionResults[action.id];
1020
+ if (!result) return false;
1021
+ if (result.type !== "messageSignature" && result.type !== "signature") {
1022
+ throw new Web3AgentError({
1023
+ code: "INVALID_PARAMS",
1024
+ message: `Action result ${action.id} must be a message signature`
1025
+ });
1026
+ }
1027
+ return true;
1028
+ }
1029
+ async function getPendingPreparedActions(actions, actionResults) {
1030
+ const pending = [];
1031
+ for (const action of actions) {
1032
+ if (!await isPreparedActionSatisfied(actionResults, action)) {
1033
+ pending.push(action);
1034
+ }
1035
+ }
1036
+ return pending;
1037
+ }
1038
+ async function assertConfirmedTransactionResult(actionResults, action) {
1039
+ const result = assertActionResultType(actionResults, action.id, "transaction");
1040
+ if (!result) {
1041
+ return void 0;
1042
+ }
1043
+ await getConfirmedReceipt(action, result);
1044
+ return result;
1045
+ }
1046
+ function toPendingOperation(resumeState, actions, fallbackSummary, actionResults) {
1047
+ const state = assertRecord(resumeState.state, "resumeState.state");
1048
+ const summary = typeof state.summary === "string" && state.summary.length > 0 ? state.summary : fallbackSummary;
1049
+ const meta = state.meta && typeof state.meta === "object" ? { ...state.meta } : {};
1050
+ const nextResumeState = {
1051
+ ...resumeState,
1052
+ state: {
1053
+ ...state,
1054
+ actionResults
1055
+ }
1056
+ };
1057
+ return {
1058
+ integration: resumeState.integration,
1059
+ kind: resumeState.kind,
1060
+ summary,
1061
+ actions,
1062
+ resumeState: nextResumeState,
1063
+ ...Object.keys(meta).length > 0 ? { meta } : {}
1064
+ };
1065
+ }
1066
+ function assertSubmitSwapQuote(quote) {
1067
+ const record = assertRecord(quote, "quote");
1068
+ const requiredFields = [
1069
+ "sessionId",
1070
+ "inToken",
1071
+ "outToken",
1072
+ "inAmount",
1073
+ "outAmount",
1074
+ "minAmountOut",
1075
+ "user"
1076
+ ];
1077
+ for (const field of requiredFields) {
1078
+ if (typeof record[field] !== "string") {
1079
+ throw new Web3AgentError({
1080
+ code: "INVALID_PARAMS",
1081
+ message: `quote.${field} must be a string`
1082
+ });
1083
+ }
1084
+ }
1085
+ return record;
1086
+ }
1087
+ function assertSignedOrder(order) {
1088
+ return assertRecord(order, "order");
1089
+ }
1090
+ function asQuote(value) {
1091
+ if (typeof value.sessionId !== "string") {
1092
+ throw new Web3AgentError({
1093
+ code: "INVALID_PARAMS",
1094
+ message: "quote.sessionId must be a string"
1095
+ });
1096
+ }
1097
+ return value;
1098
+ }
1099
+
1100
+ // src/tokens/registry.ts
1101
+ var TOKENS_BY_ADDRESS = /* @__PURE__ */ new Map();
1102
+ var WELL_KNOWN_TOKENS = {
1103
+ // ── Ethereum Mainnet (1) ──────────────────────────────────────────
1104
+ 1: {
1105
+ USDT: {
1106
+ address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
1107
+ decimals: 6,
1108
+ name: "Tether USD",
1109
+ symbol: "USDT"
1110
+ },
1111
+ USDC: {
1112
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
1113
+ decimals: 6,
1114
+ name: "USD Coin",
1115
+ symbol: "USDC"
1116
+ },
1117
+ WETH: {
1118
+ address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
1119
+ decimals: 18,
1120
+ name: "Wrapped Ether",
1121
+ symbol: "WETH"
1122
+ },
1123
+ DAI: {
1124
+ address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
1125
+ decimals: 18,
1126
+ name: "Dai Stablecoin",
1127
+ symbol: "DAI"
1128
+ },
1129
+ WBTC: {
1130
+ address: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
1131
+ decimals: 8,
1132
+ name: "Wrapped BTC",
1133
+ symbol: "WBTC"
1134
+ },
1135
+ LINK: {
1136
+ address: "0x514910771AF9Ca656af840dff83E8264EcF986CA",
1137
+ decimals: 18,
1138
+ name: "Chainlink",
1139
+ symbol: "LINK"
1140
+ },
1141
+ UNI: {
1142
+ address: "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
1143
+ decimals: 18,
1144
+ name: "Uniswap",
1145
+ symbol: "UNI"
1146
+ },
1147
+ AAVE: {
1148
+ address: "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9",
1149
+ decimals: 18,
1150
+ name: "Aave",
1151
+ symbol: "AAVE"
1152
+ }
1153
+ },
1154
+ // ── BNB Smart Chain (56) ──────────────────────────────────────────
1155
+ 56: {
1156
+ USDT: {
1157
+ address: "0x55d398326f99059fF775485246999027B3197955",
1158
+ decimals: 18,
1159
+ name: "Binance-Peg BSC-USD",
1160
+ symbol: "USDT"
1161
+ },
1162
+ USDC: {
1163
+ address: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",
1164
+ decimals: 18,
1165
+ name: "Binance-Peg USD Coin",
1166
+ symbol: "USDC"
1167
+ },
1168
+ WBNB: {
1169
+ address: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
1170
+ decimals: 18,
1171
+ name: "Wrapped BNB",
1172
+ symbol: "WBNB"
1173
+ },
1174
+ WETH: {
1175
+ address: "0x2170Ed0880ac9A755fd29B2688956BD959F933F8",
1176
+ decimals: 18,
1177
+ name: "Binance-Peg Ethereum",
1178
+ symbol: "WETH"
1179
+ },
1180
+ DAI: {
1181
+ address: "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3",
1182
+ decimals: 18,
1183
+ name: "Binance-Peg Dai",
1184
+ symbol: "DAI"
1185
+ },
1186
+ BTCB: {
1187
+ address: "0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c",
1188
+ decimals: 18,
1189
+ name: "Binance-Peg BTCB",
1190
+ symbol: "BTCB"
1191
+ },
1192
+ CAKE: {
1193
+ address: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82",
1194
+ decimals: 18,
1195
+ name: "PancakeSwap",
1196
+ symbol: "CAKE"
1197
+ }
1198
+ },
1199
+ // ── Polygon (137) ─────────────────────────────────────────────────
1200
+ 137: {
1201
+ USDT: {
1202
+ address: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
1203
+ decimals: 6,
1204
+ name: "Tether USD",
1205
+ symbol: "USDT"
1206
+ },
1207
+ USDC: {
1208
+ address: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
1209
+ decimals: 6,
1210
+ name: "USD Coin",
1211
+ symbol: "USDC"
1212
+ },
1213
+ "USDC.E": {
1214
+ address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
1215
+ decimals: 6,
1216
+ name: "Bridged USDC",
1217
+ symbol: "USDC.e"
1218
+ },
1219
+ WETH: {
1220
+ address: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
1221
+ decimals: 18,
1222
+ name: "Wrapped Ether",
1223
+ symbol: "WETH"
1224
+ },
1225
+ WMATIC: {
1226
+ address: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
1227
+ decimals: 18,
1228
+ name: "Wrapped Matic",
1229
+ symbol: "WMATIC"
1230
+ },
1231
+ WPOL: {
1232
+ address: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
1233
+ decimals: 18,
1234
+ name: "Wrapped POL",
1235
+ symbol: "WPOL"
1236
+ },
1237
+ DAI: {
1238
+ address: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
1239
+ decimals: 18,
1240
+ name: "Dai Stablecoin",
1241
+ symbol: "DAI"
1242
+ },
1243
+ WBTC: {
1244
+ address: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
1245
+ decimals: 8,
1246
+ name: "Wrapped BTC",
1247
+ symbol: "WBTC"
1248
+ },
1249
+ LINK: {
1250
+ address: "0x53E0bca35eC356BD5ddDFebbD1Fc0fD03FaBad39",
1251
+ decimals: 18,
1252
+ name: "Chainlink",
1253
+ symbol: "LINK"
1254
+ },
1255
+ AAVE: {
1256
+ address: "0xD6DF932A45C0f255f85145f286eA0b292B21C90B",
1257
+ decimals: 18,
1258
+ name: "Aave",
1259
+ symbol: "AAVE"
1260
+ }
1261
+ },
1262
+ // ── Arbitrum One (42161) ──────────────────────────────────────────
1263
+ 42161: {
1264
+ USDT: {
1265
+ address: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
1266
+ decimals: 6,
1267
+ name: "Tether USD",
1268
+ symbol: "USDT"
1269
+ },
1270
+ USDC: {
1271
+ address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
1272
+ decimals: 6,
1273
+ name: "USD Coin",
1274
+ symbol: "USDC"
1275
+ },
1276
+ "USDC.E": {
1277
+ address: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
1278
+ decimals: 6,
1279
+ name: "Bridged USDC",
1280
+ symbol: "USDC.e"
1281
+ },
1282
+ WETH: {
1283
+ address: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
1284
+ decimals: 18,
1285
+ name: "Wrapped Ether",
1286
+ symbol: "WETH"
1287
+ },
1288
+ DAI: {
1289
+ address: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
1290
+ decimals: 18,
1291
+ name: "Dai Stablecoin",
1292
+ symbol: "DAI"
1293
+ },
1294
+ WBTC: {
1295
+ address: "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f",
1296
+ decimals: 8,
1297
+ name: "Wrapped BTC",
1298
+ symbol: "WBTC"
1299
+ },
1300
+ ARB: {
1301
+ address: "0x912CE59144191C1204E64559FE8253a0e49E6548",
1302
+ decimals: 18,
1303
+ name: "Arbitrum",
1304
+ symbol: "ARB"
1305
+ },
1306
+ LINK: {
1307
+ address: "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4",
1308
+ decimals: 18,
1309
+ name: "Chainlink",
1310
+ symbol: "LINK"
1311
+ }
1312
+ },
1313
+ // ── Optimism (10) ─────────────────────────────────────────────────
1314
+ 10: {
1315
+ USDT: {
1316
+ address: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58",
1317
+ decimals: 6,
1318
+ name: "Tether USD",
1319
+ symbol: "USDT"
1320
+ },
1321
+ USDC: {
1322
+ address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
1323
+ decimals: 6,
1324
+ name: "USD Coin",
1325
+ symbol: "USDC"
1326
+ },
1327
+ "USDC.E": {
1328
+ address: "0x7F5c764cBc14f9669B88837ca1490cCa17c31607",
1329
+ decimals: 6,
1330
+ name: "Bridged USDC",
1331
+ symbol: "USDC.e"
1332
+ },
1333
+ WETH: {
1334
+ address: "0x4200000000000000000000000000000000000006",
1335
+ decimals: 18,
1336
+ name: "Wrapped Ether",
1337
+ symbol: "WETH"
1338
+ },
1339
+ DAI: {
1340
+ address: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
1341
+ decimals: 18,
1342
+ name: "Dai Stablecoin",
1343
+ symbol: "DAI"
1344
+ },
1345
+ WBTC: {
1346
+ address: "0x68f180fcCe6836688e9084f035309E29Bf0A2095",
1347
+ decimals: 8,
1348
+ name: "Wrapped BTC",
1349
+ symbol: "WBTC"
1350
+ },
1351
+ OP: {
1352
+ address: "0x4200000000000000000000000000000000000042",
1353
+ decimals: 18,
1354
+ name: "Optimism",
1355
+ symbol: "OP"
1356
+ },
1357
+ LINK: {
1358
+ address: "0x350a791Bfc2C21F9Ed5d10980Dad2e2638ffa7f6",
1359
+ decimals: 18,
1360
+ name: "Chainlink",
1361
+ symbol: "LINK"
1362
+ }
1363
+ },
1364
+ // ── Base (8453) ───────────────────────────────────────────────────
1365
+ 8453: {
1366
+ USDC: {
1367
+ address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
1368
+ decimals: 6,
1369
+ name: "USD Coin",
1370
+ symbol: "USDC"
1371
+ },
1372
+ USDT: {
1373
+ address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2",
1374
+ decimals: 6,
1375
+ name: "Tether USD",
1376
+ symbol: "USDT"
1377
+ },
1378
+ WETH: {
1379
+ address: "0x4200000000000000000000000000000000000006",
1380
+ decimals: 18,
1381
+ name: "Wrapped Ether",
1382
+ symbol: "WETH"
1383
+ },
1384
+ DAI: {
1385
+ address: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
1386
+ decimals: 18,
1387
+ name: "Dai Stablecoin",
1388
+ symbol: "DAI"
1389
+ },
1390
+ CBBTC: {
1391
+ address: "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
1392
+ decimals: 8,
1393
+ name: "Coinbase Wrapped BTC",
1394
+ symbol: "cbBTC"
1395
+ },
1396
+ AERO: {
1397
+ address: "0x940181a94A35A4569E4529A3CDfB74e38FD98631",
1398
+ decimals: 18,
1399
+ name: "Aerodrome",
1400
+ symbol: "AERO"
1401
+ }
1402
+ },
1403
+ // ── Linea (59144) ─────────────────────────────────────────────────
1404
+ 59144: {
1405
+ WETH: {
1406
+ address: "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f",
1407
+ decimals: 18,
1408
+ name: "Wrapped Ether",
1409
+ symbol: "WETH"
1410
+ },
1411
+ USDC: {
1412
+ address: "0x176211869cA2b568f2A7D4EE941E073a821EE1ff",
1413
+ decimals: 6,
1414
+ name: "USDC",
1415
+ symbol: "USDC"
1416
+ },
1417
+ USDT: {
1418
+ address: "0xA219439258ca9da29E9Cc4cE5596924745e12B93",
1419
+ decimals: 6,
1420
+ name: "Tether USD",
1421
+ symbol: "USDT"
1422
+ },
1423
+ DAI: {
1424
+ address: "0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5",
1425
+ decimals: 18,
1426
+ name: "Dai Stablecoin",
1427
+ symbol: "DAI"
1428
+ },
1429
+ WBTC: {
1430
+ address: "0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4",
1431
+ decimals: 8,
1432
+ name: "Wrapped BTC",
1433
+ symbol: "WBTC"
1434
+ }
1435
+ },
1436
+ // ── Avalanche C-Chain (43114) ─────────────────────────────────────
1437
+ 43114: {
1438
+ USDT: {
1439
+ address: "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7",
1440
+ decimals: 6,
1441
+ name: "Tether USD",
1442
+ symbol: "USDT"
1443
+ },
1444
+ USDC: {
1445
+ address: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
1446
+ decimals: 6,
1447
+ name: "USD Coin",
1448
+ symbol: "USDC"
1449
+ },
1450
+ WAVAX: {
1451
+ address: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",
1452
+ decimals: 18,
1453
+ name: "Wrapped AVAX",
1454
+ symbol: "WAVAX"
1455
+ },
1456
+ "WETH.E": {
1457
+ address: "0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB",
1458
+ decimals: 18,
1459
+ name: "Wrapped Ether",
1460
+ symbol: "WETH.e"
1461
+ },
1462
+ WETH: {
1463
+ address: "0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB",
1464
+ decimals: 18,
1465
+ name: "Wrapped Ether",
1466
+ symbol: "WETH"
1467
+ },
1468
+ DAI: {
1469
+ address: "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70",
1470
+ decimals: 18,
1471
+ name: "Dai Stablecoin",
1472
+ symbol: "DAI"
1473
+ },
1474
+ "WBTC.E": {
1475
+ address: "0x50b7545627a5162F82A992c33b87aDc75187B218",
1476
+ decimals: 8,
1477
+ name: "Wrapped BTC",
1478
+ symbol: "WBTC.e"
1479
+ },
1480
+ WBTC: {
1481
+ address: "0x50b7545627a5162F82A992c33b87aDc75187B218",
1482
+ decimals: 8,
1483
+ name: "Wrapped BTC",
1484
+ symbol: "WBTC"
1485
+ }
1486
+ },
1487
+ // ── Blast (81457) ─────────────────────────────────────────────────
1488
+ 81457: {
1489
+ WETH: {
1490
+ address: "0x4300000000000000000000000000000000000004",
1491
+ decimals: 18,
1492
+ name: "Wrapped Ether",
1493
+ symbol: "WETH"
1494
+ },
1495
+ USDB: {
1496
+ address: "0x4300000000000000000000000000000000000003",
1497
+ decimals: 18,
1498
+ name: "USDB",
1499
+ symbol: "USDB"
1500
+ },
1501
+ BLAST: {
1502
+ address: "0xb1a5700fA2358173Fe465e6eA4Ff52E36e88E2ad",
1503
+ decimals: 18,
1504
+ name: "Blast",
1505
+ symbol: "BLAST"
1506
+ }
1507
+ },
1508
+ // ── zkSync Era (324) ──────────────────────────────────────────────
1509
+ 324: {
1510
+ USDT: {
1511
+ address: "0x493257fD37EDB34451f62EDf8D2a0C418852bA4C",
1512
+ decimals: 6,
1513
+ name: "Tether USD",
1514
+ symbol: "USDT"
1515
+ },
1516
+ USDC: {
1517
+ address: "0x1d17CBcF0D6D143135aE902365D2E5e2A16538D4",
1518
+ decimals: 6,
1519
+ name: "USD Coin",
1520
+ symbol: "USDC"
1521
+ },
1522
+ WETH: {
1523
+ address: "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91",
1524
+ decimals: 18,
1525
+ name: "Wrapped Ether",
1526
+ symbol: "WETH"
1527
+ },
1528
+ WBTC: {
1529
+ address: "0xBBeB516fb02a01611cBBE0453Fe3c580D7281011",
1530
+ decimals: 8,
1531
+ name: "Wrapped BTC",
1532
+ symbol: "WBTC"
1533
+ }
1534
+ },
1535
+ // ── Scroll (534352) ───────────────────────────────────────────────
1536
+ 534352: {
1537
+ USDT: {
1538
+ address: "0xf55BEC9cafDbE8730f096Aa55dad6D22d44099Df",
1539
+ decimals: 6,
1540
+ name: "Tether USD",
1541
+ symbol: "USDT"
1542
+ },
1543
+ USDC: {
1544
+ address: "0x06eFdBFf2a14a7c8E15944D1F4A48F9F95F663A4",
1545
+ decimals: 6,
1546
+ name: "USD Coin",
1547
+ symbol: "USDC"
1548
+ },
1549
+ WETH: {
1550
+ address: "0x5300000000000000000000000000000000000004",
1551
+ decimals: 18,
1552
+ name: "Wrapped Ether",
1553
+ symbol: "WETH"
1554
+ },
1555
+ DAI: {
1556
+ address: "0xcA77eB3fEFe3725Dc33bccB54eDEFc3D9f764f97",
1557
+ decimals: 18,
1558
+ name: "Dai Stablecoin",
1559
+ symbol: "DAI"
1560
+ },
1561
+ WBTC: {
1562
+ address: "0x3C1BCa5a656e69edCD0D4E36BEbb3FcDAcA60Cf1",
1563
+ decimals: 8,
1564
+ name: "Wrapped BTC",
1565
+ symbol: "WBTC"
1566
+ }
1567
+ },
1568
+ // ── Gnosis (100) ──────────────────────────────────────────────────
1569
+ 100: {
1570
+ USDT: {
1571
+ address: "0x4ECaBa5870353805a9F068101A40E0f32ed605C6",
1572
+ decimals: 6,
1573
+ name: "Tether USD",
1574
+ symbol: "USDT"
1575
+ },
1576
+ USDC: {
1577
+ address: "0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83",
1578
+ decimals: 6,
1579
+ name: "USD Coin",
1580
+ symbol: "USDC"
1581
+ },
1582
+ WETH: {
1583
+ address: "0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1",
1584
+ decimals: 18,
1585
+ name: "Wrapped Ether",
1586
+ symbol: "WETH"
1587
+ },
1588
+ WXDAI: {
1589
+ address: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d",
1590
+ decimals: 18,
1591
+ name: "Wrapped xDAI",
1592
+ symbol: "WXDAI"
1593
+ },
1594
+ GNO: {
1595
+ address: "0x9C58BAcC331c9aa871AFD802DB6379a98e80CEdb",
1596
+ decimals: 18,
1597
+ name: "Gnosis",
1598
+ symbol: "GNO"
1599
+ }
1600
+ },
1601
+ // ── Celo (42220) ──────────────────────────────────────────────────
1602
+ 42220: {
1603
+ USDT: {
1604
+ address: "0x48065fbBE25f71C9282ddf5e1cD6D6A887483D5e",
1605
+ decimals: 6,
1606
+ name: "Tether USD",
1607
+ symbol: "USDT"
1608
+ },
1609
+ USDC: {
1610
+ address: "0xcebA9300f2b948710d2653dD7B07f33A8B32118C",
1611
+ decimals: 6,
1612
+ name: "USD Coin",
1613
+ symbol: "USDC"
1614
+ },
1615
+ CELO: {
1616
+ address: "0x471EcE3750Da237f93B8E339c536989b8978a438",
1617
+ decimals: 18,
1618
+ name: "Celo",
1619
+ symbol: "CELO"
1620
+ }
1621
+ },
1622
+ // ── Mantle (5000) ─────────────────────────────────────────────────
1623
+ 5e3: {
1624
+ USDT: {
1625
+ address: "0x201EBa5CC46D216Ce6DC03F6a759e8E766e956aE",
1626
+ decimals: 6,
1627
+ name: "Tether USD",
1628
+ symbol: "USDT"
1629
+ },
1630
+ USDC: {
1631
+ address: "0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9",
1632
+ decimals: 6,
1633
+ name: "USD Coin",
1634
+ symbol: "USDC"
1635
+ },
1636
+ WMNT: {
1637
+ address: "0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8",
1638
+ decimals: 18,
1639
+ name: "Wrapped Mantle",
1640
+ symbol: "WMNT"
1641
+ },
1642
+ WETH: {
1643
+ address: "0xdEAddEaDdeadDEadDEADDEAddEADDEAddead1111",
1644
+ decimals: 18,
1645
+ name: "Wrapped Ether",
1646
+ symbol: "WETH"
1647
+ }
1648
+ },
1649
+ // ── Mode (34443) ──────────────────────────────────────────────────
1650
+ 34443: {
1651
+ USDT: {
1652
+ address: "0xf0F161fDA2712DB8b566946122a5af183995e2eD",
1653
+ decimals: 6,
1654
+ name: "Tether USD",
1655
+ symbol: "USDT"
1656
+ },
1657
+ USDC: {
1658
+ address: "0xd988097fb8612cc24eeC14542bC03424c656005f",
1659
+ decimals: 6,
1660
+ name: "USD Coin",
1661
+ symbol: "USDC"
1662
+ },
1663
+ WETH: {
1664
+ address: "0x4200000000000000000000000000000000000006",
1665
+ decimals: 18,
1666
+ name: "Wrapped Ether",
1667
+ symbol: "WETH"
1668
+ }
1669
+ }
1670
+ };
1671
+ for (const [chainId, tokens] of Object.entries(WELL_KNOWN_TOKENS)) {
1672
+ TOKENS_BY_ADDRESS.set(
1673
+ Number(chainId),
1674
+ new Map(
1675
+ Object.values(tokens).map(
1676
+ (token) => [token.address.toLowerCase(), token]
1677
+ )
1678
+ )
1679
+ );
1680
+ }
1681
+ function lookupToken(symbol, chainId) {
1682
+ return WELL_KNOWN_TOKENS[chainId]?.[symbol.toUpperCase()];
1683
+ }
1684
+ function lookupTokenByAddress(address, chainId) {
1685
+ return TOKENS_BY_ADDRESS.get(chainId)?.get(address.toLowerCase());
1686
+ }
1687
+ function getChainTokens(chainId) {
1688
+ return WELL_KNOWN_TOKENS[chainId];
1689
+ }
1690
+
1691
+ export {
1692
+ Web3AgentError,
1693
+ formatToolError,
1694
+ formatToolResponse,
1695
+ formatToolErrorFromUnknown,
1696
+ loadPlugins,
1697
+ buildGoatTools,
1698
+ GoatProvider,
1699
+ RESTRICTED_PLUGIN_CHAINS,
1700
+ findRestrictedPlugin,
1701
+ dispatchGoatTool,
1702
+ assertChainSupported,
1703
+ assertHex,
1704
+ assertAddress,
1705
+ assertRecord,
1706
+ parseBigIntString,
1707
+ getChainForRuntime,
1708
+ getRuntimeConfigForChain,
1709
+ getTransportForRuntimeChain,
1710
+ getRpcUrlForRuntimeChain,
1711
+ createPublicClientForRuntimeChain,
1712
+ operationActionResultSchema,
1713
+ lifiGetQuoteSchema,
1714
+ lifiExecuteBridgeSchema,
1715
+ lifiPrepareBridgeIntentSchema,
1716
+ orbsGetQuoteSchema,
1717
+ orbsSwapSchema,
1718
+ orbsPrepareSwapIntentSchema,
1719
+ orbsGetRequiredApprovalsSchema,
1720
+ orbsPlaceTwapSchema,
1721
+ orbsPrepareTwapIntentSchema,
1722
+ orbsPlaceLimitSchema,
1723
+ orbsPrepareLimitIntentSchema,
1724
+ orbsSubmitSignedSwapSchema,
1725
+ orbsSubmitSignedTwapOrderSchema,
1726
+ orbsSwapStatusSchema,
1727
+ orbsListOrdersSchema,
1728
+ orbsSwapResumeStateStateSchema,
1729
+ orbsOrderResumeStateStateSchema,
1730
+ goatResumeStateStateSchema,
1731
+ lifiBridgeResumeStateStateSchema,
1732
+ operationResumeStateSchema,
1733
+ prepareOperationSchema,
1734
+ resumeOperationSchema,
1735
+ resolveTokenSchema,
1736
+ listChainTokensSchema,
1737
+ walletFromMnemonicSchema,
1738
+ walletDeriveAddressesSchema,
1739
+ walletActivateSchema,
1740
+ walletSetConfirmationSchema,
1741
+ transactionConfirmSchema,
1742
+ transactionDenySchema,
1743
+ transactionSimulateSchema,
1744
+ parseInput,
1745
+ createPreparedApprovalActions,
1746
+ createTypedDataAction,
1747
+ buildPreparedOperation,
1748
+ mergeActionResults,
1749
+ assertActionResultType,
1750
+ getConfirmedReceipt,
1751
+ getPendingPreparedActions,
1752
+ assertConfirmedTransactionResult,
1753
+ toPendingOperation,
1754
+ assertSubmitSwapQuote,
1755
+ assertSignedOrder,
1756
+ asQuote,
1757
+ lookupToken,
1758
+ lookupTokenByAddress,
1759
+ getChainTokens
1760
+ };