@coinbase/agentkit 0.10.0 → 0.10.2

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 (169) hide show
  1. package/README.md +195 -23
  2. package/dist/action-providers/across/acrossActionProvider.js +3 -3
  3. package/dist/action-providers/across/schemas.d.ts +1 -1
  4. package/dist/action-providers/baseAccount/baseAccountActionProvider.d.ts +46 -0
  5. package/dist/action-providers/baseAccount/baseAccountActionProvider.js +404 -0
  6. package/dist/action-providers/baseAccount/baseAccountActionProvider.test.d.ts +1 -0
  7. package/dist/action-providers/baseAccount/baseAccountActionProvider.test.js +325 -0
  8. package/dist/action-providers/baseAccount/index.d.ts +2 -0
  9. package/dist/action-providers/baseAccount/index.js +18 -0
  10. package/dist/action-providers/baseAccount/schemas.d.ts +43 -0
  11. package/dist/action-providers/baseAccount/schemas.js +62 -0
  12. package/dist/action-providers/baseAccount/types.d.ts +17 -0
  13. package/dist/action-providers/baseAccount/types.js +2 -0
  14. package/dist/action-providers/baseAccount/utils.d.ts +14 -0
  15. package/dist/action-providers/baseAccount/utils.js +57 -0
  16. package/dist/action-providers/cdp/cdpApiActionProvider.d.ts +3 -12
  17. package/dist/action-providers/cdp/cdpApiActionProvider.js +2 -81
  18. package/dist/action-providers/cdp/cdpApiActionProvider.test.js +0 -125
  19. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.d.ts +18 -3
  20. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.js +224 -23
  21. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.js +280 -0
  22. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.d.ts +17 -2
  23. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.js +224 -18
  24. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.js +267 -1
  25. package/dist/action-providers/cdp/schemas.d.ts +12 -12
  26. package/dist/action-providers/cdp/schemas.js +17 -5
  27. package/dist/action-providers/cdp/swapUtils.d.ts +23 -0
  28. package/dist/action-providers/cdp/swapUtils.js +106 -0
  29. package/dist/action-providers/clanker/clankerActionProvider.d.ts +43 -0
  30. package/dist/action-providers/clanker/clankerActionProvider.js +130 -0
  31. package/dist/action-providers/clanker/clankerActionProvider.test.d.ts +4 -0
  32. package/dist/action-providers/clanker/clankerActionProvider.test.js +119 -0
  33. package/dist/action-providers/clanker/index.d.ts +2 -0
  34. package/dist/action-providers/clanker/index.js +18 -0
  35. package/dist/action-providers/clanker/schemas.d.ts +56 -0
  36. package/dist/action-providers/clanker/schemas.js +47 -0
  37. package/dist/action-providers/clanker/utils.d.ts +9 -0
  38. package/dist/action-providers/clanker/utils.js +23 -0
  39. package/dist/action-providers/compound/constants.d.ts +1 -1
  40. package/dist/action-providers/compound/constants.js +2 -2
  41. package/dist/action-providers/erc20/constants.d.ts +35 -135
  42. package/dist/action-providers/erc20/constants.js +37 -189
  43. package/dist/action-providers/erc20/erc20ActionProvider.d.ts +9 -1
  44. package/dist/action-providers/erc20/erc20ActionProvider.js +87 -35
  45. package/dist/action-providers/erc20/erc20ActionProvider.test.js +115 -52
  46. package/dist/action-providers/erc20/schemas.d.ts +25 -12
  47. package/dist/action-providers/erc20/schemas.js +34 -6
  48. package/dist/action-providers/erc20/utils.d.ts +19 -0
  49. package/dist/action-providers/erc20/utils.js +54 -0
  50. package/dist/action-providers/flaunch/client_utils.d.ts +25 -0
  51. package/dist/action-providers/flaunch/client_utils.js +62 -0
  52. package/dist/action-providers/flaunch/constants.d.ts +42 -21
  53. package/dist/action-providers/flaunch/constants.js +113 -38
  54. package/dist/action-providers/flaunch/flaunchActionProvider.d.ts +4 -43
  55. package/dist/action-providers/flaunch/flaunchActionProvider.js +133 -209
  56. package/dist/action-providers/flaunch/flaunchActionProvider.test.js +113 -13
  57. package/dist/action-providers/flaunch/metadata_utils.d.ts +12 -0
  58. package/dist/action-providers/flaunch/metadata_utils.js +216 -0
  59. package/dist/action-providers/flaunch/schemas.d.ts +39 -3
  60. package/dist/action-providers/flaunch/schemas.js +62 -10
  61. package/dist/action-providers/flaunch/{utils.d.ts → swap_utils.d.ts} +17 -19
  62. package/dist/action-providers/flaunch/{utils.js → swap_utils.js} +137 -172
  63. package/dist/action-providers/index.d.ts +4 -0
  64. package/dist/action-providers/index.js +4 -0
  65. package/dist/action-providers/jupiter/schemas.d.ts +1 -1
  66. package/dist/action-providers/moonwell/schemas.d.ts +2 -2
  67. package/dist/action-providers/morpho/morphoActionProvider.js +5 -5
  68. package/dist/action-providers/morpho/schemas.d.ts +2 -2
  69. package/dist/action-providers/pyth/pythActionProvider.d.ts +2 -2
  70. package/dist/action-providers/pyth/pythActionProvider.js +83 -26
  71. package/dist/action-providers/pyth/pythActionProvider.test.js +179 -23
  72. package/dist/action-providers/pyth/schemas.d.ts +6 -0
  73. package/dist/action-providers/pyth/schemas.js +9 -1
  74. package/dist/action-providers/superfluid/constants.d.ts +814 -0
  75. package/dist/action-providers/superfluid/constants.js +2826 -0
  76. package/dist/action-providers/superfluid/graphQueries/endpoints.d.ts +2 -0
  77. package/dist/action-providers/superfluid/graphQueries/endpoints.js +5 -0
  78. package/dist/action-providers/superfluid/graphQueries/queries.d.ts +1 -0
  79. package/dist/action-providers/superfluid/graphQueries/queries.js +35 -0
  80. package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.d.ts +8 -0
  81. package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.js +24 -0
  82. package/dist/action-providers/superfluid/graphQueries/types.d.ts +27 -0
  83. package/dist/action-providers/superfluid/graphQueries/types.js +2 -0
  84. package/dist/action-providers/superfluid/index.d.ts +7 -0
  85. package/dist/action-providers/superfluid/index.js +23 -0
  86. package/dist/action-providers/superfluid/schemas.d.ts +86 -0
  87. package/dist/action-providers/superfluid/schemas.js +103 -0
  88. package/dist/action-providers/superfluid/superfluidActionProvider.d.ts +20 -0
  89. package/dist/action-providers/superfluid/superfluidActionProvider.js +36 -0
  90. package/dist/action-providers/superfluid/superfluidPoolActionProvider.d.ts +46 -0
  91. package/dist/action-providers/superfluid/superfluidPoolActionProvider.js +143 -0
  92. package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.d.ts +1 -0
  93. package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.js +92 -0
  94. package/dist/action-providers/superfluid/superfluidQueryActionProvider.d.ts +27 -0
  95. package/dist/action-providers/superfluid/superfluidQueryActionProvider.js +71 -0
  96. package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.d.ts +1 -0
  97. package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.js +57 -0
  98. package/dist/action-providers/superfluid/superfluidStreamActionProvider.d.ts +56 -0
  99. package/dist/action-providers/superfluid/superfluidStreamActionProvider.js +191 -0
  100. package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.d.ts +1 -0
  101. package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.js +80 -0
  102. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.d.ts +30 -0
  103. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.js +109 -0
  104. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.d.ts +1 -0
  105. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.js +75 -0
  106. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.d.ts +32 -0
  107. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.js +101 -0
  108. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.d.ts +1 -0
  109. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.js +85 -0
  110. package/dist/action-providers/superfluid/utils/parseLogs.d.ts +19 -0
  111. package/dist/action-providers/superfluid/utils/parseLogs.js +81 -0
  112. package/dist/action-providers/truemarkets/truemarketsActionProvider.d.ts +4 -16
  113. package/dist/action-providers/truemarkets/truemarketsActionProvider.js +20 -41
  114. package/dist/action-providers/truemarkets/truemarketsActionProvider.test.js +11 -33
  115. package/dist/action-providers/wallet/walletActionProvider.js +24 -10
  116. package/dist/action-providers/wallet/walletActionProvider.test.js +6 -2
  117. package/dist/action-providers/x402/schemas.d.ts +7 -0
  118. package/dist/action-providers/x402/schemas.js +11 -1
  119. package/dist/action-providers/x402/utils.d.ts +55 -0
  120. package/dist/action-providers/x402/utils.js +160 -0
  121. package/dist/action-providers/x402/x402ActionProvider.d.ts +9 -9
  122. package/dist/action-providers/x402/x402ActionProvider.js +158 -39
  123. package/dist/action-providers/x402/x402ActionProvider.test.js +116 -10
  124. package/dist/action-providers/zeroX/index.d.ts +1 -0
  125. package/dist/action-providers/zeroX/index.js +17 -0
  126. package/dist/action-providers/zeroX/schemas.d.ts +51 -0
  127. package/dist/action-providers/zeroX/schemas.js +82 -0
  128. package/dist/action-providers/zeroX/utils.d.ts +23 -0
  129. package/dist/action-providers/zeroX/utils.js +106 -0
  130. package/dist/action-providers/zeroX/zeroXActionProvider.d.ts +57 -0
  131. package/dist/action-providers/zeroX/zeroXActionProvider.js +407 -0
  132. package/dist/action-providers/zeroX/zeroXActionProvider.test.d.ts +1 -0
  133. package/dist/action-providers/zeroX/zeroXActionProvider.test.js +445 -0
  134. package/dist/utils.d.ts +10 -0
  135. package/dist/utils.js +43 -13
  136. package/dist/wallet-providers/cdpEvmWalletProvider.d.ts +27 -2
  137. package/dist/wallet-providers/cdpEvmWalletProvider.js +54 -36
  138. package/dist/wallet-providers/cdpEvmWalletProvider.test.js +7 -0
  139. package/dist/wallet-providers/cdpShared.d.ts +5 -0
  140. package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +29 -3
  141. package/dist/wallet-providers/cdpSmartWalletProvider.js +66 -25
  142. package/dist/wallet-providers/cdpSmartWalletProvider.test.js +6 -10
  143. package/dist/wallet-providers/cdpSolanaWalletProvider.d.ts +1 -1
  144. package/dist/wallet-providers/cdpSolanaWalletProvider.js +7 -7
  145. package/dist/wallet-providers/cdpSolanaWalletProvider.test.js +15 -12
  146. package/dist/wallet-providers/evmWalletProvider.d.ts +13 -2
  147. package/dist/wallet-providers/evmWalletProvider.js +4 -0
  148. package/dist/wallet-providers/legacyCdpSmartWalletProvider.d.ts +18 -2
  149. package/dist/wallet-providers/legacyCdpSmartWalletProvider.js +23 -2
  150. package/dist/wallet-providers/legacyCdpWalletProvider.d.ts +19 -2
  151. package/dist/wallet-providers/legacyCdpWalletProvider.js +27 -2
  152. package/dist/wallet-providers/legacyCdpWalletProvider.test.js +6 -0
  153. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.d.ts +17 -2
  154. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.js +39 -3
  155. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.test.js +1 -1
  156. package/dist/wallet-providers/privyEvmWalletProvider.d.ts +2 -0
  157. package/dist/wallet-providers/privyEvmWalletProvider.js +2 -1
  158. package/dist/wallet-providers/privyEvmWalletProvider.test.js +12 -1
  159. package/dist/wallet-providers/solanaKeypairWalletProvider.d.ts +1 -1
  160. package/dist/wallet-providers/solanaKeypairWalletProvider.js +3 -4
  161. package/dist/wallet-providers/solanaKeypairWalletProvider.test.js +4 -2
  162. package/dist/wallet-providers/viemWalletProvider.d.ts +20 -3
  163. package/dist/wallet-providers/viemWalletProvider.js +33 -4
  164. package/dist/wallet-providers/viemWalletProvider.test.js +27 -6
  165. package/dist/wallet-providers/walletProvider.d.ts +1 -1
  166. package/dist/wallet-providers/zeroDevWalletProvider.d.ts +17 -2
  167. package/dist/wallet-providers/zeroDevWalletProvider.js +26 -5
  168. package/dist/wallet-providers/zeroDevWalletProvider.test.js +12 -2
  169. package/package.json +8 -4
@@ -36,23 +36,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  const cdpSmartWalletActionProvider_1 = require("./cdpSmartWalletActionProvider");
37
37
  const schemas_1 = require("./schemas");
38
38
  const spendPermissionUtils = __importStar(require("./spendPermissionUtils"));
39
+ const swapUtils = __importStar(require("./swapUtils"));
40
+ const utils = __importStar(require("../../utils"));
39
41
  // Mock the CDP SDK and utility functions
40
42
  jest.mock("@coinbase/cdp-sdk");
41
43
  jest.mock("./spendPermissionUtils");
44
+ jest.mock("./swapUtils");
45
+ jest.mock("../../utils");
42
46
  describe("CDP Smart Wallet Action Provider", () => {
43
47
  let actionProvider;
44
48
  let mockWalletProvider;
45
49
  let mockCdpClient;
46
50
  let mockSmartAccount;
51
+ const mockGetTokenDetails = swapUtils.getTokenDetails;
52
+ const mockRetryWithExponentialBackoff = utils.retryWithExponentialBackoff;
47
53
  beforeEach(() => {
48
54
  jest.clearAllMocks();
49
55
  mockSmartAccount = {
50
56
  useSpendPermission: jest.fn(),
57
+ swap: jest.fn(),
51
58
  address: "0x1234567890123456789012345678901234567890",
52
59
  };
53
60
  mockCdpClient = {
54
61
  evm: {
55
62
  listSpendPermissions: jest.fn(),
63
+ getSwapPrice: jest.fn(),
56
64
  },
57
65
  };
58
66
  mockWalletProvider = {
@@ -60,7 +68,19 @@ describe("CDP Smart Wallet Action Provider", () => {
60
68
  getAddress: jest.fn(),
61
69
  getClient: jest.fn(),
62
70
  smartAccount: mockSmartAccount,
71
+ ownerAccount: {
72
+ type: "server",
73
+ address: "0xowner123",
74
+ },
75
+ sendTransaction: jest.fn(),
76
+ waitForTransactionReceipt: jest.fn(),
77
+ getPaymasterUrl: jest.fn(),
78
+ getCdpSdkNetwork: jest.fn(),
63
79
  };
80
+ // Default setup for utility functions
81
+ mockRetryWithExponentialBackoff.mockImplementation(async (fn) => {
82
+ return await fn();
83
+ });
64
84
  actionProvider = new cdpSmartWalletActionProvider_1.CdpSmartWalletActionProvider();
65
85
  });
66
86
  describe("listSpendPermissions", () => {
@@ -74,6 +94,7 @@ describe("CDP Smart Wallet Action Provider", () => {
74
94
  });
75
95
  mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
76
96
  mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
97
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
77
98
  });
78
99
  it("should successfully list spend permissions for EVM networks", async () => {
79
100
  const expectedResult = "Found 1 spend permission(s):\n1. Token: ETH, Allowance: 1000, Period: 3600 seconds, Start: 123456, End: 234567";
@@ -110,6 +131,7 @@ describe("CDP Smart Wallet Action Provider", () => {
110
131
  });
111
132
  mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
112
133
  mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
134
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
113
135
  });
114
136
  it("should successfully use spend permission for EVM networks", async () => {
115
137
  const mockPermission = {
@@ -140,6 +162,7 @@ describe("CDP Smart Wallet Action Provider", () => {
140
162
  protocolFamily: "evm",
141
163
  networkId: "base-mainnet",
142
164
  });
165
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
143
166
  const mockPermission = { spender: "0x1234", token: "ETH" };
144
167
  const mockSpendResult = { status: "completed" };
145
168
  spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
@@ -156,6 +179,9 @@ describe("CDP Smart Wallet Action Provider", () => {
156
179
  protocolFamily: "evm",
157
180
  networkId: "ethereum-mainnet",
158
181
  });
182
+ mockWalletProvider.getCdpSdkNetwork.mockImplementation(() => {
183
+ throw new Error("Unsupported network for smart wallets: ethereum-mainnet");
184
+ });
159
185
  await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Unsupported network for smart wallets: ethereum-mainnet");
160
186
  });
161
187
  it("should return error message for non-EVM networks", async () => {
@@ -163,7 +189,7 @@ describe("CDP Smart Wallet Action Provider", () => {
163
189
  protocolFamily: "svm",
164
190
  networkId: "solana-devnet",
165
191
  });
166
- await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Unsupported network for smart wallets: solana-devnet");
192
+ await expect(actionProvider.useSpendPermission(mockWalletProvider, mockArgs)).rejects.toThrow("Spend permissions are currently only supported on EVM networks.");
167
193
  });
168
194
  it("should handle spend permission not found error", async () => {
169
195
  spendPermissionUtils.findLatestSpendPermission.mockRejectedValue(new Error("No spend permissions found"));
@@ -188,6 +214,246 @@ describe("CDP Smart Wallet Action Provider", () => {
188
214
  expect(() => schemas_1.UseSpendPermissionSchema.parse(invalidInput)).toThrow();
189
215
  });
190
216
  });
217
+ describe("getSwapPrice", () => {
218
+ const mockArgs = {
219
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
220
+ toToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
221
+ fromAmount: "0.1",
222
+ slippageBps: 100,
223
+ };
224
+ beforeEach(() => {
225
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
226
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
227
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
228
+ mockGetTokenDetails.mockResolvedValue({
229
+ fromTokenDecimals: 18,
230
+ toTokenDecimals: 6,
231
+ fromTokenName: "ETH",
232
+ toTokenName: "USDC",
233
+ });
234
+ });
235
+ it("should get swap price quote on base-mainnet", async () => {
236
+ mockWalletProvider.getNetwork.mockReturnValue({
237
+ protocolFamily: "evm",
238
+ networkId: "base-mainnet",
239
+ });
240
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
241
+ toAmount: "990000", // 0.99 USDC
242
+ minToAmount: "980000", // 0.98 USDC
243
+ liquidityAvailable: true,
244
+ issues: {},
245
+ });
246
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
247
+ const parsedResult = JSON.parse(result);
248
+ expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
249
+ fromToken: mockArgs.fromToken,
250
+ toToken: mockArgs.toToken,
251
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
252
+ network: "base",
253
+ taker: "0x1234567890123456789012345678901234567890",
254
+ });
255
+ expect(parsedResult.success).toBe(true);
256
+ expect(parsedResult.fromAmount).toBe("0.1");
257
+ expect(parsedResult.toAmount).toBe("0.99");
258
+ expect(parsedResult.liquidityAvailable).toBe(true);
259
+ });
260
+ it("should get swap price quote on base-sepolia", async () => {
261
+ mockWalletProvider.getNetwork.mockReturnValue({
262
+ protocolFamily: "evm",
263
+ networkId: "base-sepolia",
264
+ });
265
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
266
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
267
+ toAmount: "990000",
268
+ minToAmount: "980000",
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,
278
+ network: "base-sepolia",
279
+ taker: "0x1234567890123456789012345678901234567890",
280
+ });
281
+ expect(parsedResult.success).toBe(true);
282
+ });
283
+ it("should return error for unsupported networks", async () => {
284
+ mockWalletProvider.getNetwork.mockReturnValue({
285
+ protocolFamily: "evm",
286
+ networkId: "ethereum-mainnet",
287
+ });
288
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
289
+ const parsedResult = JSON.parse(result);
290
+ expect(parsedResult.success).toBe(false);
291
+ expect(parsedResult.error).toContain("CDP Swap API for smart wallets is currently only supported on Base networks");
292
+ });
293
+ it("should handle swap price API errors", async () => {
294
+ mockWalletProvider.getNetwork.mockReturnValue({
295
+ protocolFamily: "evm",
296
+ networkId: "base-mainnet",
297
+ });
298
+ mockCdpClient.evm.getSwapPrice.mockRejectedValue(new Error("API Error"));
299
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
300
+ const parsedResult = JSON.parse(result);
301
+ expect(parsedResult.success).toBe(false);
302
+ expect(parsedResult.error).toContain("Error fetching swap price: Error: API Error");
303
+ });
304
+ });
305
+ describe("swap", () => {
306
+ const mockArgs = {
307
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
308
+ toToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
309
+ fromAmount: "0.1",
310
+ slippageBps: 100,
311
+ };
312
+ beforeEach(() => {
313
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
314
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
315
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
316
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValue({ status: "complete" });
317
+ mockWalletProvider.getPaymasterUrl.mockReturnValue("https://paymaster.example");
318
+ mockGetTokenDetails.mockResolvedValue({
319
+ fromTokenDecimals: 18,
320
+ toTokenDecimals: 6,
321
+ fromTokenName: "ETH",
322
+ toTokenName: "USDC",
323
+ });
324
+ });
325
+ it("should execute swap on base-mainnet", async () => {
326
+ mockWalletProvider.getNetwork.mockReturnValue({
327
+ protocolFamily: "evm",
328
+ networkId: "base-mainnet",
329
+ });
330
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
331
+ liquidityAvailable: true,
332
+ issues: {},
333
+ toAmount: "990000", // 0.99 USDC
334
+ minToAmount: "980000", // 0.98 USDC
335
+ });
336
+ mockSmartAccount.swap.mockResolvedValue({ userOpHash: "0xswap789" });
337
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
338
+ const parsedResult = JSON.parse(result);
339
+ expect(mockSmartAccount.swap).toHaveBeenCalledWith({
340
+ network: "base",
341
+ fromToken: mockArgs.fromToken,
342
+ toToken: mockArgs.toToken,
343
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
344
+ slippageBps: 100,
345
+ paymasterUrl: "https://paymaster.example",
346
+ signerAddress: "0xowner123",
347
+ });
348
+ expect(parsedResult.success).toBe(true);
349
+ expect(parsedResult.transactionHash).toBe("0xswap789");
350
+ expect(parsedResult.fromAmount).toBe("0.1");
351
+ expect(parsedResult.toAmount).toBe("0.99");
352
+ });
353
+ it("should return error for unsupported networks", async () => {
354
+ mockWalletProvider.getNetwork.mockReturnValue({
355
+ protocolFamily: "evm",
356
+ networkId: "ethereum-mainnet",
357
+ });
358
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
359
+ const parsedResult = JSON.parse(result);
360
+ expect(parsedResult.success).toBe(false);
361
+ expect(parsedResult.error).toContain("CDP Swap API for smart wallets is currently only supported on Base networks");
362
+ });
363
+ it("should throw error for local owner account", async () => {
364
+ mockWalletProvider.getNetwork.mockReturnValue({
365
+ protocolFamily: "evm",
366
+ networkId: "base-mainnet",
367
+ });
368
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
369
+ mockWalletProvider.ownerAccount = {
370
+ type: "local",
371
+ address: "0xlocal123",
372
+ };
373
+ await expect(actionProvider.swap(mockWalletProvider, mockArgs)).rejects.toThrow("Smart wallet owner account is not a CDP server account");
374
+ });
375
+ it("should return error when liquidity is not available", async () => {
376
+ mockWalletProvider.getNetwork.mockReturnValue({
377
+ protocolFamily: "evm",
378
+ networkId: "base-mainnet",
379
+ });
380
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
381
+ liquidityAvailable: false,
382
+ issues: {},
383
+ toAmount: "0",
384
+ minToAmount: "0",
385
+ });
386
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
387
+ const parsedResult = JSON.parse(result);
388
+ expect(parsedResult.success).toBe(false);
389
+ expect(parsedResult.error).toContain("No liquidity available to swap");
390
+ });
391
+ it("should return error when balance is insufficient", async () => {
392
+ mockWalletProvider.getNetwork.mockReturnValue({
393
+ protocolFamily: "evm",
394
+ networkId: "base-mainnet",
395
+ });
396
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
397
+ liquidityAvailable: true,
398
+ issues: {
399
+ balance: {
400
+ currentBalance: "50000000000000000", // 0.05 ETH
401
+ },
402
+ },
403
+ toAmount: "990000",
404
+ minToAmount: "980000",
405
+ });
406
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
407
+ const parsedResult = JSON.parse(result);
408
+ expect(parsedResult.success).toBe(false);
409
+ expect(parsedResult.error).toContain("Balance is not enough to perform swap");
410
+ expect(parsedResult.error).toContain("but only have 0.05 ETH");
411
+ });
412
+ it("should handle approval transaction when allowance is insufficient", async () => {
413
+ mockWalletProvider.getNetwork.mockReturnValue({
414
+ protocolFamily: "evm",
415
+ networkId: "base-mainnet",
416
+ });
417
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
418
+ liquidityAvailable: true,
419
+ issues: {
420
+ allowance: {
421
+ requiredAllowance: "100000000000000000",
422
+ currentAllowance: "0",
423
+ },
424
+ },
425
+ toAmount: "990000",
426
+ minToAmount: "980000",
427
+ });
428
+ mockWalletProvider.sendTransaction.mockResolvedValue("0xapproval123");
429
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "complete" }); // For approval
430
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "complete" }); // For swap
431
+ mockSmartAccount.swap.mockResolvedValue({ userOpHash: "0xswap789" });
432
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
433
+ const parsedResult = JSON.parse(result);
434
+ expect(mockWalletProvider.sendTransaction).toHaveBeenCalled();
435
+ expect(parsedResult.success).toBe(true);
436
+ expect(parsedResult.approvalTxHash).toBe("0xapproval123");
437
+ expect(parsedResult.transactionHash).toBe("0xswap789");
438
+ });
439
+ it("should handle swap execution errors", async () => {
440
+ mockWalletProvider.getNetwork.mockReturnValue({
441
+ protocolFamily: "evm",
442
+ networkId: "base-mainnet",
443
+ });
444
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
445
+ liquidityAvailable: true,
446
+ issues: {},
447
+ toAmount: "990000",
448
+ minToAmount: "980000",
449
+ });
450
+ mockSmartAccount.swap.mockRejectedValue(new Error("Swap execution failed"));
451
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
452
+ const parsedResult = JSON.parse(result);
453
+ expect(parsedResult.success).toBe(false);
454
+ expect(parsedResult.error).toContain("Swap failed: Error: Swap execution failed");
455
+ });
456
+ });
191
457
  describe("supportsNetwork", () => {
192
458
  it("should return true for any network", () => {
193
459
  const evmNetwork = { protocolFamily: "evm", networkId: "base-sepolia" };
@@ -13,20 +13,20 @@ export declare const RequestFaucetFundsV2Schema: z.ZodObject<{
13
13
  * Input schema for swap tokens action.
14
14
  */
15
15
  export declare const SwapSchema: z.ZodObject<{
16
- fromAssetId: z.ZodString;
17
- toAssetId: z.ZodString;
18
- amount: z.ZodString;
19
- network: z.ZodOptional<z.ZodString>;
16
+ fromToken: z.ZodString;
17
+ toToken: z.ZodString;
18
+ fromAmount: z.ZodString;
19
+ slippageBps: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
20
20
  }, "strip", z.ZodTypeAny, {
21
- amount: string;
22
- fromAssetId: string;
23
- toAssetId: string;
24
- network?: string | undefined;
21
+ fromToken: string;
22
+ toToken: string;
23
+ fromAmount: string;
24
+ slippageBps: number;
25
25
  }, {
26
- amount: string;
27
- fromAssetId: string;
28
- toAssetId: string;
29
- network?: string | undefined;
26
+ fromToken: string;
27
+ toToken: string;
28
+ fromAmount: string;
29
+ slippageBps?: number | undefined;
30
30
  }>;
31
31
  /**
32
32
  * Input schema for listing spend permissions action.
@@ -16,13 +16,25 @@ exports.RequestFaucetFundsV2Schema = zod_1.z
16
16
  */
17
17
  exports.SwapSchema = zod_1.z
18
18
  .object({
19
- fromAssetId: zod_1.z.string().describe("The asset ID to swap from (e.g., 'eth', 'usdc')"),
20
- toAssetId: zod_1.z.string().describe("The asset ID to swap to (e.g., 'eth', 'usdc')"),
21
- amount: zod_1.z.string().describe("The amount to swap (in the from asset's units)"),
22
- network: zod_1.z
19
+ fromToken: zod_1.z
20
+ .string()
21
+ .regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address format")
22
+ .describe("The token contract address to swap from"),
23
+ toToken: zod_1.z
24
+ .string()
25
+ .regex(/^0x[a-fA-F0-9]{40}$/, "Invalid Ethereum address format")
26
+ .describe("The token contract address to swap to"),
27
+ fromAmount: zod_1.z
23
28
  .string()
29
+ .describe("The amount of fromToken to sell in whole units (e.g., 1.5 WETH, 10.5 USDC)"),
30
+ slippageBps: zod_1.z
31
+ .number()
32
+ .int()
33
+ .min(0)
34
+ .max(10000)
24
35
  .optional()
25
- .describe("The network to perform the swap on (defaults to wallet's network)"),
36
+ .default(100)
37
+ .describe("The maximum acceptable slippage in basis points (0-10000, default: 100 = 1%)"),
26
38
  })
27
39
  .strip()
28
40
  .describe("Instructions for swapping tokens");
@@ -0,0 +1,23 @@
1
+ import { EvmWalletProvider } from "../../wallet-providers";
2
+ export declare const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
3
+ /**
4
+ * Checks if a token is native ETH.
5
+ *
6
+ * @param token - The token address to check.
7
+ * @returns True if the token is native ETH, false otherwise.
8
+ */
9
+ export declare function isNativeEth(token: string): boolean;
10
+ /**
11
+ * Gets the details (decimals and name) for both fromToken and toToken
12
+ *
13
+ * @param walletProvider - The EVM wallet provider to read contracts
14
+ * @param fromToken - The contract address of the from token
15
+ * @param toToken - The contract address of the to token
16
+ * @returns Promise<{fromTokenDecimals: number, toTokenDecimals: number, fromTokenName: string, toTokenName: string}>
17
+ */
18
+ export declare function getTokenDetails(walletProvider: EvmWalletProvider, fromToken: string, toToken: string): Promise<{
19
+ fromTokenDecimals: number;
20
+ toTokenDecimals: number;
21
+ fromTokenName: string;
22
+ toTokenName: string;
23
+ }>;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PERMIT2_ADDRESS = void 0;
4
+ exports.isNativeEth = isNativeEth;
5
+ exports.getTokenDetails = getTokenDetails;
6
+ const viem_1 = require("viem");
7
+ // Permit2 contract address is the same across all networks
8
+ exports.PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
9
+ /**
10
+ * Checks if a token is native ETH.
11
+ *
12
+ * @param token - The token address to check.
13
+ * @returns True if the token is native ETH, false otherwise.
14
+ */
15
+ function isNativeEth(token) {
16
+ return token.toLowerCase() === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
17
+ }
18
+ /**
19
+ * Gets the details (decimals and name) for both fromToken and toToken
20
+ *
21
+ * @param walletProvider - The EVM wallet provider to read contracts
22
+ * @param fromToken - The contract address of the from token
23
+ * @param toToken - The contract address of the to token
24
+ * @returns Promise<{fromTokenDecimals: number, toTokenDecimals: number, fromTokenName: string, toTokenName: string}>
25
+ */
26
+ async function getTokenDetails(walletProvider, fromToken, toToken) {
27
+ // Initialize default values for native ETH
28
+ let fromTokenDecimals = 18;
29
+ let fromTokenName = "ETH";
30
+ let toTokenDecimals = 18;
31
+ let toTokenName = "ETH";
32
+ // Prepare multicall contracts array
33
+ const contracts = [];
34
+ const contractIndexMap = {
35
+ fromDecimals: -1,
36
+ fromName: -1,
37
+ toDecimals: -1,
38
+ toName: -1,
39
+ };
40
+ // Add from token contracts if not native ETH
41
+ if (!isNativeEth(fromToken)) {
42
+ contractIndexMap.fromDecimals = contracts.length;
43
+ contracts.push({
44
+ address: fromToken,
45
+ abi: viem_1.erc20Abi,
46
+ functionName: "decimals",
47
+ });
48
+ contractIndexMap.fromName = contracts.length;
49
+ contracts.push({
50
+ address: fromToken,
51
+ abi: viem_1.erc20Abi,
52
+ functionName: "name",
53
+ });
54
+ }
55
+ // Add to token contracts if not native ETH
56
+ if (!isNativeEth(toToken)) {
57
+ contractIndexMap.toDecimals = contracts.length;
58
+ contracts.push({
59
+ address: toToken,
60
+ abi: viem_1.erc20Abi,
61
+ functionName: "decimals",
62
+ });
63
+ contractIndexMap.toName = contracts.length;
64
+ contracts.push({
65
+ address: toToken,
66
+ abi: viem_1.erc20Abi,
67
+ functionName: "name",
68
+ });
69
+ }
70
+ // Execute multicall if there are contracts to call
71
+ if (contracts.length > 0) {
72
+ try {
73
+ const results = await walletProvider.getPublicClient().multicall({
74
+ contracts,
75
+ });
76
+ // Extract from token details
77
+ if (contractIndexMap.fromDecimals !== -1) {
78
+ const decimalsResult = results[contractIndexMap.fromDecimals];
79
+ const nameResult = results[contractIndexMap.fromName];
80
+ if (decimalsResult.status === "success" && nameResult.status === "success") {
81
+ fromTokenDecimals = decimalsResult.result;
82
+ fromTokenName = nameResult.result;
83
+ }
84
+ else {
85
+ throw new Error(`Failed to read details for fromToken ${fromToken}. This address may not be a valid ERC20 contract.`);
86
+ }
87
+ }
88
+ // Extract to token details
89
+ if (contractIndexMap.toDecimals !== -1) {
90
+ const decimalsResult = results[contractIndexMap.toDecimals];
91
+ const nameResult = results[contractIndexMap.toName];
92
+ if (decimalsResult.status === "success" && nameResult.status === "success") {
93
+ toTokenDecimals = decimalsResult.result;
94
+ toTokenName = nameResult.result;
95
+ }
96
+ else {
97
+ throw new Error(`Failed to read details for toToken ${toToken}. This address may not be a valid ERC20 contract.`);
98
+ }
99
+ }
100
+ }
101
+ catch (error) {
102
+ throw new Error(`Failed to read token details via multicall. Error: ${error}`);
103
+ }
104
+ }
105
+ return { fromTokenDecimals, toTokenDecimals, fromTokenName, toTokenName };
106
+ }
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ import { ActionProvider } from "../actionProvider";
3
+ import { Network } from "../../network";
4
+ import { EvmWalletProvider } from "../../wallet-providers";
5
+ import { ClankTokenSchema } from "./schemas";
6
+ /**
7
+ * ClankerActionProvider provides actions for clanker operations.
8
+ *
9
+ * @description
10
+ * This provider is designed to work with EvmWalletProvider for blockchain interactions.
11
+ * It supports all evm networks.
12
+ */
13
+ export declare class ClankerActionProvider extends ActionProvider<EvmWalletProvider> {
14
+ /**
15
+ * Constructor for the ClankerActionProvider.
16
+ */
17
+ constructor();
18
+ /**
19
+ * Clanker action provider
20
+ *
21
+ * @description
22
+ * This action deploys a clanker token using the Clanker sdk
23
+ * It automatically includes the coin in the Clanker ecosystem
24
+ *
25
+ * @param walletProvider - The wallet provider instance for blockchain interactions
26
+ * @param args - Clanker arguments (modify these to fine tune token deployment, like initial quote token and rewards config)
27
+ * @returns A promise that resolves to a string describing the clanker result
28
+ */
29
+ clankToken(walletProvider: EvmWalletProvider, args: z.infer<typeof ClankTokenSchema>): Promise<string>;
30
+ /**
31
+ * Checks if this provider supports the given network.
32
+ *
33
+ * @param network - The network to check support for
34
+ * @returns True if the network is supported
35
+ */
36
+ supportsNetwork(network: Network): boolean;
37
+ }
38
+ /**
39
+ * Factory function to create a new ClankerActionProvider instance.
40
+ *
41
+ * @returns A new ClankerActionProvider instance
42
+ */
43
+ export declare const clankerActionProvider: () => ClankerActionProvider;