@coinbase/agentkit 0.0.0-nightly-20250820210426 → 0.0.0-nightly-20250821210420

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 (60) hide show
  1. package/README.md +37 -0
  2. package/dist/action-providers/cdp/cdpApiActionProvider.d.ts +3 -11
  3. package/dist/action-providers/cdp/cdpApiActionProvider.js +2 -65
  4. package/dist/action-providers/cdp/cdpApiActionProvider.test.js +0 -125
  5. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.d.ts +17 -1
  6. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.js +219 -0
  7. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.js +270 -0
  8. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.d.ts +17 -1
  9. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.js +220 -0
  10. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.js +254 -0
  11. package/dist/action-providers/cdp/schemas.d.ts +12 -12
  12. package/dist/action-providers/cdp/schemas.js +17 -5
  13. package/dist/action-providers/cdp/swapUtils.d.ts +32 -0
  14. package/dist/action-providers/cdp/swapUtils.js +142 -0
  15. package/dist/action-providers/index.d.ts +1 -0
  16. package/dist/action-providers/index.js +1 -0
  17. package/dist/action-providers/jupiter/schemas.d.ts +1 -1
  18. package/dist/action-providers/superfluid/constants.d.ts +814 -0
  19. package/dist/action-providers/superfluid/constants.js +2826 -0
  20. package/dist/action-providers/superfluid/graphQueries/endpoints.d.ts +2 -0
  21. package/dist/action-providers/superfluid/graphQueries/endpoints.js +5 -0
  22. package/dist/action-providers/superfluid/graphQueries/queries.d.ts +1 -0
  23. package/dist/action-providers/superfluid/graphQueries/queries.js +35 -0
  24. package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.d.ts +8 -0
  25. package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.js +24 -0
  26. package/dist/action-providers/superfluid/graphQueries/types.d.ts +27 -0
  27. package/dist/action-providers/superfluid/graphQueries/types.js +2 -0
  28. package/dist/action-providers/superfluid/index.d.ts +7 -0
  29. package/dist/action-providers/superfluid/index.js +23 -0
  30. package/dist/action-providers/superfluid/schemas.d.ts +86 -0
  31. package/dist/action-providers/superfluid/schemas.js +103 -0
  32. package/dist/action-providers/superfluid/superfluidActionProvider.d.ts +20 -0
  33. package/dist/action-providers/superfluid/superfluidActionProvider.js +36 -0
  34. package/dist/action-providers/superfluid/superfluidPoolActionProvider.d.ts +46 -0
  35. package/dist/action-providers/superfluid/superfluidPoolActionProvider.js +143 -0
  36. package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.d.ts +1 -0
  37. package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.js +92 -0
  38. package/dist/action-providers/superfluid/superfluidQueryActionProvider.d.ts +27 -0
  39. package/dist/action-providers/superfluid/superfluidQueryActionProvider.js +71 -0
  40. package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.d.ts +1 -0
  41. package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.js +57 -0
  42. package/dist/action-providers/superfluid/superfluidStreamActionProvider.d.ts +56 -0
  43. package/dist/action-providers/superfluid/superfluidStreamActionProvider.js +191 -0
  44. package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.d.ts +1 -0
  45. package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.js +80 -0
  46. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.d.ts +30 -0
  47. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.js +108 -0
  48. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.d.ts +1 -0
  49. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.js +75 -0
  50. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.d.ts +32 -0
  51. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.js +101 -0
  52. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.d.ts +1 -0
  53. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.js +85 -0
  54. package/dist/action-providers/superfluid/utils/parseLogs.d.ts +18 -0
  55. package/dist/action-providers/superfluid/utils/parseLogs.js +78 -0
  56. package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +3 -2
  57. package/dist/wallet-providers/cdpSmartWalletProvider.js +4 -5
  58. package/dist/wallet-providers/viemWalletProvider.d.ts +4 -0
  59. package/dist/wallet-providers/viemWalletProvider.js +2 -1
  60. package/package.json +3 -2
@@ -36,31 +36,43 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const cdpEvmWalletActionProvider_1 = require("./cdpEvmWalletActionProvider");
37
37
  const schemas_1 = require("./schemas");
38
38
  const spendPermissionUtils = __importStar(require("./spendPermissionUtils"));
39
+ const swapUtils = __importStar(require("./swapUtils"));
39
40
  // Mock the CDP SDK and utility functions
40
41
  jest.mock("@coinbase/cdp-sdk");
41
42
  jest.mock("./spendPermissionUtils");
43
+ jest.mock("./swapUtils");
42
44
  describe("CDP EVM Wallet Action Provider", () => {
43
45
  let actionProvider;
44
46
  let mockWalletProvider;
45
47
  let mockCdpClient;
46
48
  let mockAccount;
49
+ const mockGetTokenDetails = swapUtils.getTokenDetails;
50
+ const mockRetryWithExponentialBackoff = swapUtils.retryWithExponentialBackoff;
47
51
  beforeEach(() => {
48
52
  jest.clearAllMocks();
49
53
  mockAccount = {
50
54
  useSpendPermission: jest.fn(),
55
+ swap: jest.fn(),
51
56
  address: "0x1234567890123456789012345678901234567890",
52
57
  };
53
58
  mockCdpClient = {
54
59
  evm: {
55
60
  listSpendPermissions: jest.fn(),
56
61
  getAccount: jest.fn(),
62
+ getSwapPrice: jest.fn(),
57
63
  },
58
64
  };
59
65
  mockWalletProvider = {
60
66
  getNetwork: jest.fn(),
61
67
  getAddress: jest.fn(),
62
68
  getClient: jest.fn(),
69
+ sendTransaction: jest.fn(),
70
+ waitForTransactionReceipt: jest.fn(),
63
71
  };
72
+ // Default setup for utility functions
73
+ mockRetryWithExponentialBackoff.mockImplementation(async (fn) => {
74
+ return await fn();
75
+ });
64
76
  actionProvider = new cdpEvmWalletActionProvider_1.CdpEvmWalletActionProvider();
65
77
  });
66
78
  describe("listSpendPermissions", () => {
@@ -229,6 +241,233 @@ describe("CDP EVM Wallet Action Provider", () => {
229
241
  expect(() => schemas_1.UseSpendPermissionSchema.parse(invalidInput)).toThrow();
230
242
  });
231
243
  });
244
+ describe("getSwapPrice", () => {
245
+ const mockArgs = {
246
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
247
+ toToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48", // USDC
248
+ fromAmount: "0.1",
249
+ slippageBps: 100,
250
+ };
251
+ beforeEach(() => {
252
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
253
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
254
+ mockGetTokenDetails.mockResolvedValue({
255
+ fromTokenDecimals: 18,
256
+ toTokenDecimals: 6,
257
+ fromTokenName: "ETH",
258
+ toTokenName: "USDC",
259
+ });
260
+ });
261
+ it("should get swap price quote on base-mainnet", async () => {
262
+ mockWalletProvider.getNetwork.mockReturnValue({
263
+ protocolFamily: "evm",
264
+ networkId: "base-mainnet",
265
+ });
266
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
267
+ toAmount: "990000", // 0.99 USDC
268
+ minToAmount: "980000", // 0.98 USDC
269
+ liquidityAvailable: true,
270
+ issues: {},
271
+ });
272
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
273
+ const parsedResult = JSON.parse(result);
274
+ expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
275
+ fromToken: mockArgs.fromToken,
276
+ toToken: mockArgs.toToken,
277
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
278
+ network: "base",
279
+ taker: "0x1234567890123456789012345678901234567890",
280
+ });
281
+ expect(parsedResult.success).toBe(true);
282
+ expect(parsedResult.fromAmount).toBe("0.1");
283
+ expect(parsedResult.toAmount).toBe("0.99");
284
+ expect(parsedResult.liquidityAvailable).toBe(true);
285
+ });
286
+ it("should get swap price quote on ethereum-mainnet", async () => {
287
+ mockWalletProvider.getNetwork.mockReturnValue({
288
+ protocolFamily: "evm",
289
+ networkId: "ethereum-mainnet",
290
+ });
291
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
292
+ toAmount: "990000",
293
+ minToAmount: "980000",
294
+ liquidityAvailable: true,
295
+ issues: {},
296
+ });
297
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
298
+ const parsedResult = JSON.parse(result);
299
+ expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
300
+ fromToken: mockArgs.fromToken,
301
+ toToken: mockArgs.toToken,
302
+ fromAmount: 100000000000000000n,
303
+ network: "ethereum",
304
+ taker: "0x1234567890123456789012345678901234567890",
305
+ });
306
+ expect(parsedResult.success).toBe(true);
307
+ });
308
+ it("should return error for unsupported networks", async () => {
309
+ mockWalletProvider.getNetwork.mockReturnValue({
310
+ protocolFamily: "evm",
311
+ networkId: "base-sepolia",
312
+ });
313
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
314
+ const parsedResult = JSON.parse(result);
315
+ expect(parsedResult.success).toBe(false);
316
+ expect(parsedResult.error).toContain("CDP Swap API is currently only supported on 'base-mainnet' or 'ethereum-mainnet'");
317
+ });
318
+ it("should handle swap price API errors", async () => {
319
+ mockWalletProvider.getNetwork.mockReturnValue({
320
+ protocolFamily: "evm",
321
+ networkId: "base-mainnet",
322
+ });
323
+ mockCdpClient.evm.getSwapPrice.mockRejectedValue(new Error("API Error"));
324
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
325
+ const parsedResult = JSON.parse(result);
326
+ expect(parsedResult.success).toBe(false);
327
+ expect(parsedResult.error).toContain("Error fetching swap price: Error: API Error");
328
+ });
329
+ });
330
+ describe("swap", () => {
331
+ const mockArgs = {
332
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
333
+ toToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48", // USDC
334
+ fromAmount: "0.1",
335
+ slippageBps: 100,
336
+ };
337
+ beforeEach(() => {
338
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
339
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
340
+ mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
341
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValue({ status: "success" });
342
+ mockGetTokenDetails.mockResolvedValue({
343
+ fromTokenDecimals: 18,
344
+ toTokenDecimals: 6,
345
+ fromTokenName: "ETH",
346
+ toTokenName: "USDC",
347
+ });
348
+ });
349
+ it("should execute swap on base-mainnet", async () => {
350
+ mockWalletProvider.getNetwork.mockReturnValue({
351
+ protocolFamily: "evm",
352
+ networkId: "base-mainnet",
353
+ });
354
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
355
+ liquidityAvailable: true,
356
+ issues: {},
357
+ toAmount: "990000", // 0.99 USDC
358
+ minToAmount: "980000", // 0.98 USDC
359
+ });
360
+ mockAccount.swap.mockResolvedValue({ transactionHash: "0xswap789" });
361
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
362
+ const parsedResult = JSON.parse(result);
363
+ expect(mockCdpClient.evm.getAccount).toHaveBeenCalledWith({
364
+ address: "0x1234567890123456789012345678901234567890",
365
+ });
366
+ expect(mockAccount.swap).toHaveBeenCalledWith({
367
+ network: "base",
368
+ fromToken: mockArgs.fromToken,
369
+ toToken: mockArgs.toToken,
370
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
371
+ slippageBps: 100,
372
+ signerAddress: "0x1234567890123456789012345678901234567890",
373
+ });
374
+ expect(parsedResult.success).toBe(true);
375
+ expect(parsedResult.transactionHash).toBe("0xswap789");
376
+ expect(parsedResult.fromAmount).toBe("0.1");
377
+ expect(parsedResult.toAmount).toBe("0.99");
378
+ });
379
+ it("should return error for unsupported networks", async () => {
380
+ mockWalletProvider.getNetwork.mockReturnValue({
381
+ protocolFamily: "evm",
382
+ networkId: "base-sepolia",
383
+ });
384
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
385
+ const parsedResult = JSON.parse(result);
386
+ expect(parsedResult.success).toBe(false);
387
+ expect(parsedResult.error).toContain("CDP Swap API is currently only supported on 'base-mainnet' or 'ethereum-mainnet'");
388
+ });
389
+ it("should return error when liquidity is not available", async () => {
390
+ mockWalletProvider.getNetwork.mockReturnValue({
391
+ protocolFamily: "evm",
392
+ networkId: "base-mainnet",
393
+ });
394
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
395
+ liquidityAvailable: false,
396
+ issues: {},
397
+ toAmount: "0",
398
+ minToAmount: "0",
399
+ });
400
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
401
+ const parsedResult = JSON.parse(result);
402
+ expect(parsedResult.success).toBe(false);
403
+ expect(parsedResult.error).toContain("No liquidity available to swap");
404
+ });
405
+ it("should return error when balance is insufficient", async () => {
406
+ mockWalletProvider.getNetwork.mockReturnValue({
407
+ protocolFamily: "evm",
408
+ networkId: "base-mainnet",
409
+ });
410
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
411
+ liquidityAvailable: true,
412
+ issues: {
413
+ balance: {
414
+ currentBalance: "50000000000000000", // 0.05 ETH
415
+ },
416
+ },
417
+ toAmount: "990000",
418
+ minToAmount: "980000",
419
+ });
420
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
421
+ const parsedResult = JSON.parse(result);
422
+ expect(parsedResult.success).toBe(false);
423
+ expect(parsedResult.error).toContain("Balance is not enough to perform swap");
424
+ expect(parsedResult.error).toContain("but only have 0.05 ETH");
425
+ });
426
+ it("should handle approval transaction when allowance is insufficient", async () => {
427
+ mockWalletProvider.getNetwork.mockReturnValue({
428
+ protocolFamily: "evm",
429
+ networkId: "base-mainnet",
430
+ });
431
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
432
+ liquidityAvailable: true,
433
+ issues: {
434
+ allowance: {
435
+ requiredAllowance: "100000000000000000",
436
+ currentAllowance: "0",
437
+ },
438
+ },
439
+ toAmount: "990000",
440
+ minToAmount: "980000",
441
+ });
442
+ mockWalletProvider.sendTransaction.mockResolvedValue("0xapproval123");
443
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "success" }); // For approval
444
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "success" }); // For swap
445
+ mockAccount.swap.mockResolvedValue({ transactionHash: "0xswap789" });
446
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
447
+ const parsedResult = JSON.parse(result);
448
+ expect(mockWalletProvider.sendTransaction).toHaveBeenCalled();
449
+ expect(parsedResult.success).toBe(true);
450
+ expect(parsedResult.approvalTxHash).toBe("0xapproval123");
451
+ expect(parsedResult.transactionHash).toBe("0xswap789");
452
+ });
453
+ it("should handle swap execution errors", async () => {
454
+ mockWalletProvider.getNetwork.mockReturnValue({
455
+ protocolFamily: "evm",
456
+ networkId: "base-mainnet",
457
+ });
458
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
459
+ liquidityAvailable: true,
460
+ issues: {},
461
+ toAmount: "990000",
462
+ minToAmount: "980000",
463
+ });
464
+ mockAccount.swap.mockRejectedValue(new Error("Swap execution failed"));
465
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
466
+ const parsedResult = JSON.parse(result);
467
+ expect(parsedResult.success).toBe(false);
468
+ expect(parsedResult.error).toContain("Swap failed: Error: Swap execution failed");
469
+ });
470
+ });
232
471
  describe("supportsNetwork", () => {
233
472
  it("should return true for EVM networks", () => {
234
473
  const evmNetwork = { protocolFamily: "evm", networkId: "base-sepolia" };
@@ -239,4 +478,35 @@ describe("CDP EVM Wallet Action Provider", () => {
239
478
  expect(actionProvider.supportsNetwork(svmNetwork)).toBe(false);
240
479
  });
241
480
  });
481
+ describe("SwapSchema", () => {
482
+ it("should validate correct swap input", () => {
483
+ const validInput = {
484
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
485
+ toToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48",
486
+ fromAmount: "0.1",
487
+ };
488
+ const result = schemas_1.SwapSchema.safeParse(validInput);
489
+ expect(result.success).toBe(true);
490
+ expect(result.data).toEqual({ ...validInput, slippageBps: 100 });
491
+ });
492
+ it("should validate swap input with optional slippageBps", () => {
493
+ const validInput = {
494
+ fromToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48",
495
+ toToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
496
+ fromAmount: "100",
497
+ slippageBps: 50,
498
+ };
499
+ const result = schemas_1.SwapSchema.safeParse(validInput);
500
+ expect(result.success).toBe(true);
501
+ expect(result.data).toEqual(validInput);
502
+ });
503
+ it("should fail validation when missing required fields", () => {
504
+ const invalidInput = {
505
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
506
+ // missing toToken and fromAmount
507
+ };
508
+ const result = schemas_1.SwapSchema.safeParse(invalidInput);
509
+ expect(result.success).toBe(false);
510
+ });
511
+ });
242
512
  });
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { CdpSmartWalletProvider } from "../../wallet-providers/cdpSmartWalletProvider";
3
3
  import { ActionProvider } from "../actionProvider";
4
- import { UseSpendPermissionSchema, ListSpendPermissionsSchema } from "./schemas";
4
+ import { UseSpendPermissionSchema, ListSpendPermissionsSchema, SwapSchema } from "./schemas";
5
5
  import type { Network } from "../../network";
6
6
  /**
7
7
  * CdpSmartWalletActionProvider is an action provider for CDP Smart Wallet specific actions.
@@ -31,6 +31,22 @@ export declare class CdpSmartWalletActionProvider extends ActionProvider<CdpSmar
31
31
  * @returns A confirmation message with transaction details.
32
32
  */
33
33
  useSpendPermission(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof UseSpendPermissionSchema>): Promise<string>;
34
+ /**
35
+ * Gets a price quote for swapping tokens using the CDP Swap API.
36
+ *
37
+ * @param walletProvider - The smart wallet provider to get the quote for.
38
+ * @param args - The input arguments for the swap price action.
39
+ * @returns A JSON string with detailed swap price quote information.
40
+ */
41
+ getSwapPrice(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof SwapSchema>): Promise<string>;
42
+ /**
43
+ * Swaps tokens using the CDP client.
44
+ *
45
+ * @param walletProvider - The smart wallet provider to perform the swap with.
46
+ * @param args - The input arguments for the swap action.
47
+ * @returns A JSON string with detailed swap execution information.
48
+ */
49
+ swap(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof SwapSchema>): Promise<string>;
34
50
  /**
35
51
  * Checks if the smart wallet action provider supports the given network.
36
52
  *
@@ -22,6 +22,8 @@ const actionDecorator_1 = require("../actionDecorator");
22
22
  const actionProvider_1 = require("../actionProvider");
23
23
  const schemas_1 = require("./schemas");
24
24
  const spendPermissionUtils_1 = require("./spendPermissionUtils");
25
+ const swapUtils_1 = require("./swapUtils");
26
+ const viem_1 = require("viem");
25
27
  /**
26
28
  * CdpSmartWalletActionProvider is an action provider for CDP Smart Wallet specific actions.
27
29
  *
@@ -90,6 +92,183 @@ class CdpSmartWalletActionProvider extends actionProvider_1.ActionProvider {
90
92
  throw new Error("Spend permissions are currently only supported on EVM networks.");
91
93
  }
92
94
  }
95
+ /**
96
+ * Gets a price quote for swapping tokens using the CDP Swap API.
97
+ *
98
+ * @param walletProvider - The smart wallet provider to get the quote for.
99
+ * @param args - The input arguments for the swap price action.
100
+ * @returns A JSON string with detailed swap price quote information.
101
+ */
102
+ async getSwapPrice(walletProvider, args) {
103
+ const network = walletProvider.getNetwork();
104
+ const networkId = network.networkId;
105
+ // Check if the network is supported
106
+ if (networkId !== "base-mainnet" && networkId !== "base-sepolia") {
107
+ return JSON.stringify({
108
+ success: false,
109
+ error: "CDP Swap API for smart wallets is currently only supported on Base networks.",
110
+ });
111
+ }
112
+ const cdpNetwork = __classPrivateFieldGet(this, _CdpSmartWalletActionProvider_instances, "m", _CdpSmartWalletActionProvider_getCdpSdkNetwork).call(this, networkId);
113
+ try {
114
+ // Get token details
115
+ const { fromTokenDecimals, toTokenDecimals, fromTokenName, toTokenName } = await (0, swapUtils_1.getTokenDetails)(walletProvider, args.fromToken, args.toToken);
116
+ // Get swap price quote
117
+ const swapPrice = (await walletProvider.getClient().evm.getSwapPrice({
118
+ fromToken: args.fromToken,
119
+ toToken: args.toToken,
120
+ fromAmount: (0, viem_1.parseUnits)(args.fromAmount, fromTokenDecimals),
121
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
122
+ network: cdpNetwork,
123
+ taker: walletProvider.getAddress(),
124
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
125
+ }));
126
+ const formattedResponse = {
127
+ success: true,
128
+ fromAmount: args.fromAmount,
129
+ fromTokenName: fromTokenName,
130
+ fromToken: args.fromToken,
131
+ toAmount: (0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals),
132
+ minToAmount: (0, viem_1.formatUnits)(swapPrice.minToAmount, toTokenDecimals),
133
+ toTokenName: toTokenName,
134
+ toToken: args.toToken,
135
+ slippageBps: args.slippageBps,
136
+ liquidityAvailable: swapPrice.liquidityAvailable,
137
+ balanceEnough: swapPrice.issues.balance === undefined,
138
+ priceOfBuyTokenInSellToken: (Number(args.fromAmount) / Number((0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals))).toString(),
139
+ priceOfSellTokenInBuyToken: (Number((0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals)) / Number(args.fromAmount)).toString(),
140
+ };
141
+ return JSON.stringify(formattedResponse);
142
+ }
143
+ catch (error) {
144
+ return JSON.stringify({
145
+ success: false,
146
+ error: `Error fetching swap price: ${error}`,
147
+ });
148
+ }
149
+ }
150
+ /**
151
+ * Swaps tokens using the CDP client.
152
+ *
153
+ * @param walletProvider - The smart wallet provider to perform the swap with.
154
+ * @param args - The input arguments for the swap action.
155
+ * @returns A JSON string with detailed swap execution information.
156
+ */
157
+ async swap(walletProvider, args) {
158
+ const network = walletProvider.getNetwork();
159
+ const networkId = network.networkId;
160
+ // Check if the network is supported
161
+ if (networkId !== "base-mainnet" && networkId !== "base-sepolia") {
162
+ return JSON.stringify({
163
+ success: false,
164
+ error: "CDP Swap API for smart wallets is currently only supported on Base networks.",
165
+ });
166
+ }
167
+ const cdpNetwork = __classPrivateFieldGet(this, _CdpSmartWalletActionProvider_instances, "m", _CdpSmartWalletActionProvider_getCdpSdkNetwork).call(this, networkId);
168
+ // Check if the owner account is a CDP server account
169
+ if (walletProvider.ownerAccount.type === "local") {
170
+ throw new Error("Smart wallet owner account is not a CDP server account.");
171
+ }
172
+ try {
173
+ // Get token details
174
+ const { fromTokenDecimals, fromTokenName, toTokenName, toTokenDecimals } = await (0, swapUtils_1.getTokenDetails)(walletProvider, args.fromToken, args.toToken);
175
+ // Estimate swap price first to check liquidity, token balance and permit2 approval status
176
+ const swapPrice = await walletProvider.getClient().evm.getSwapPrice({
177
+ fromToken: args.fromToken,
178
+ toToken: args.toToken,
179
+ fromAmount: (0, viem_1.parseUnits)(args.fromAmount, fromTokenDecimals),
180
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
181
+ network: cdpNetwork,
182
+ taker: walletProvider.smartAccount.address,
183
+ });
184
+ // Check if liquidity is available
185
+ if (!swapPrice.liquidityAvailable) {
186
+ return JSON.stringify({
187
+ success: false,
188
+ error: `No liquidity available to swap ${args.fromAmount} ${fromTokenName} (${args.fromToken}) to ${toTokenName} (${args.toToken})`,
189
+ });
190
+ }
191
+ // Check if balance is enough
192
+ if (swapPrice.issues.balance) {
193
+ return JSON.stringify({
194
+ success: false,
195
+ error: `Balance is not enough to perform swap. Required: ${args.fromAmount} ${fromTokenName}, but only have ${(0, viem_1.formatUnits)(swapPrice.issues.balance.currentBalance, fromTokenDecimals)} ${fromTokenName} (${args.fromToken})`,
196
+ });
197
+ }
198
+ // Check if allowance is enough
199
+ let approvalTxHash = null;
200
+ if (swapPrice.issues.allowance) {
201
+ try {
202
+ approvalTxHash = await walletProvider.sendTransaction({
203
+ to: args.fromToken,
204
+ data: (0, viem_1.encodeFunctionData)({
205
+ abi: viem_1.erc20Abi,
206
+ functionName: "approve",
207
+ args: [swapUtils_1.PERMIT2_ADDRESS, viem_1.maxUint256],
208
+ }),
209
+ });
210
+ const receipt = await walletProvider.waitForTransactionReceipt(approvalTxHash);
211
+ if (receipt.status !== "complete") {
212
+ return JSON.stringify({
213
+ success: false,
214
+ error: `Approval transaction failed`,
215
+ });
216
+ }
217
+ }
218
+ catch (error) {
219
+ return JSON.stringify({
220
+ success: false,
221
+ error: `Error approving token: ${error}`,
222
+ });
223
+ }
224
+ }
225
+ // Execute swap using the all-in-one pattern with retry logic
226
+ const swapResult = await (0, swapUtils_1.retryWithExponentialBackoff)(async () => {
227
+ return (await walletProvider.smartAccount.swap({
228
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
229
+ network: cdpNetwork,
230
+ fromToken: args.fromToken,
231
+ toToken: args.toToken,
232
+ fromAmount: (0, viem_1.parseUnits)(args.fromAmount, fromTokenDecimals),
233
+ slippageBps: args.slippageBps,
234
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
235
+ paymasterUrl: walletProvider.getPaymasterUrl(),
236
+ signerAddress: walletProvider.ownerAccount.address,
237
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
238
+ }));
239
+ }, 3, 5000); // Max 3 retries with 5s base delay
240
+ // Check if swap was successful
241
+ const swapReceipt = await walletProvider.waitForTransactionReceipt(swapResult.userOpHash);
242
+ if (swapReceipt.status !== "complete") {
243
+ return JSON.stringify({
244
+ success: false,
245
+ error: `Swap transaction failed`,
246
+ });
247
+ }
248
+ // Format the successful response
249
+ const formattedResponse = {
250
+ success: true,
251
+ ...(approvalTxHash ? { approvalTxHash } : {}),
252
+ transactionHash: swapResult.userOpHash,
253
+ fromAmount: args.fromAmount,
254
+ fromTokenName: fromTokenName,
255
+ fromToken: args.fromToken,
256
+ toAmount: (0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals),
257
+ minToAmount: (0, viem_1.formatUnits)(swapPrice.minToAmount, toTokenDecimals),
258
+ toTokenName: toTokenName,
259
+ toToken: args.toToken,
260
+ slippageBps: args.slippageBps,
261
+ network: networkId,
262
+ };
263
+ return JSON.stringify(formattedResponse);
264
+ }
265
+ catch (error) {
266
+ return JSON.stringify({
267
+ success: false,
268
+ error: `Swap failed: ${error}`,
269
+ });
270
+ }
271
+ }
93
272
  }
94
273
  exports.CdpSmartWalletActionProvider = CdpSmartWalletActionProvider;
95
274
  _CdpSmartWalletActionProvider_instances = new WeakSet(), _CdpSmartWalletActionProvider_getCdpSdkNetwork = function _CdpSmartWalletActionProvider_getCdpSdkNetwork(networkId) {
@@ -128,5 +307,46 @@ This action is specifically designed for smart wallets and uses the smart accoun
128
307
  __metadata("design:paramtypes", [cdpSmartWalletProvider_1.CdpSmartWalletProvider, void 0]),
129
308
  __metadata("design:returntype", Promise)
130
309
  ], CdpSmartWalletActionProvider.prototype, "useSpendPermission", null);
310
+ __decorate([
311
+ (0, actionDecorator_1.CreateAction)({
312
+ name: "get_swap_price",
313
+ description: `
314
+ This tool fetches a price quote for swapping (trading) between two tokens using the CDP Swap API but does not execute a swap.
315
+ It takes the following inputs:
316
+ - fromToken: The contract address of the token to sell
317
+ - toToken: The contract address of the token to buy
318
+ - fromAmount: The amount of fromToken to swap in whole units (e.g. 1 ETH or 10.5 USDC)
319
+ - slippageBps: (Optional) Maximum allowed slippage in basis points (100 = 1%)
320
+ Important notes:
321
+ - The contract address for native ETH is "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
322
+ - Use fromAmount units exactly as provided, do not convert to wei or any other units.
323
+ `,
324
+ schema: schemas_1.SwapSchema,
325
+ }),
326
+ __metadata("design:type", Function),
327
+ __metadata("design:paramtypes", [cdpSmartWalletProvider_1.CdpSmartWalletProvider, void 0]),
328
+ __metadata("design:returntype", Promise)
329
+ ], CdpSmartWalletActionProvider.prototype, "getSwapPrice", null);
330
+ __decorate([
331
+ (0, actionDecorator_1.CreateAction)({
332
+ name: "swap",
333
+ description: `
334
+ This tool executes a token swap (trade) using the CDP Swap API.
335
+ It takes the following inputs:
336
+ - fromToken: The contract address of the token to sell
337
+ - toToken: The contract address of the token to buy
338
+ - fromAmount: The amount of fromToken to swap in whole units (e.g. 1 ETH or 10.5 USDC)
339
+ - slippageBps: (Optional) Maximum allowed slippage in basis points (100 = 1%)
340
+ Important notes:
341
+ - The contract address for native ETH is "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
342
+ - If needed, it will automatically approve the permit2 contract to spend the fromToken
343
+ - Use fromAmount units exactly as provided, do not convert to wei or any other units.
344
+ `,
345
+ schema: schemas_1.SwapSchema,
346
+ }),
347
+ __metadata("design:type", Function),
348
+ __metadata("design:paramtypes", [cdpSmartWalletProvider_1.CdpSmartWalletProvider, void 0]),
349
+ __metadata("design:returntype", Promise)
350
+ ], CdpSmartWalletActionProvider.prototype, "swap", null);
131
351
  const cdpSmartWalletActionProvider = () => new CdpSmartWalletActionProvider();
132
352
  exports.cdpSmartWalletActionProvider = cdpSmartWalletActionProvider;