@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,23 +36,29 @@ 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"));
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 Smart Wallet Action Provider", () => {
43
45
  let actionProvider;
44
46
  let mockWalletProvider;
45
47
  let mockCdpClient;
46
48
  let mockSmartAccount;
49
+ const mockGetTokenDetails = swapUtils.getTokenDetails;
50
+ const mockRetryWithExponentialBackoff = swapUtils.retryWithExponentialBackoff;
47
51
  beforeEach(() => {
48
52
  jest.clearAllMocks();
49
53
  mockSmartAccount = {
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(),
61
+ getSwapPrice: jest.fn(),
56
62
  },
57
63
  };
58
64
  mockWalletProvider = {
@@ -60,7 +66,18 @@ describe("CDP Smart Wallet Action Provider", () => {
60
66
  getAddress: jest.fn(),
61
67
  getClient: jest.fn(),
62
68
  smartAccount: mockSmartAccount,
69
+ ownerAccount: {
70
+ type: "server",
71
+ address: "0xowner123",
72
+ },
73
+ sendTransaction: jest.fn(),
74
+ waitForTransactionReceipt: jest.fn(),
75
+ getPaymasterUrl: jest.fn(),
63
76
  };
77
+ // Default setup for utility functions
78
+ mockRetryWithExponentialBackoff.mockImplementation(async (fn) => {
79
+ return await fn();
80
+ });
64
81
  actionProvider = new cdpSmartWalletActionProvider_1.CdpSmartWalletActionProvider();
65
82
  });
66
83
  describe("listSpendPermissions", () => {
@@ -188,6 +205,243 @@ describe("CDP Smart Wallet Action Provider", () => {
188
205
  expect(() => schemas_1.UseSpendPermissionSchema.parse(invalidInput)).toThrow();
189
206
  });
190
207
  });
208
+ describe("getSwapPrice", () => {
209
+ const mockArgs = {
210
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
211
+ toToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
212
+ fromAmount: "0.1",
213
+ slippageBps: 100,
214
+ };
215
+ beforeEach(() => {
216
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
217
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
218
+ mockGetTokenDetails.mockResolvedValue({
219
+ fromTokenDecimals: 18,
220
+ toTokenDecimals: 6,
221
+ fromTokenName: "ETH",
222
+ toTokenName: "USDC",
223
+ });
224
+ });
225
+ it("should get swap price quote on base-mainnet", async () => {
226
+ mockWalletProvider.getNetwork.mockReturnValue({
227
+ protocolFamily: "evm",
228
+ networkId: "base-mainnet",
229
+ });
230
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
231
+ toAmount: "990000", // 0.99 USDC
232
+ minToAmount: "980000", // 0.98 USDC
233
+ liquidityAvailable: true,
234
+ issues: {},
235
+ });
236
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
237
+ const parsedResult = JSON.parse(result);
238
+ expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
239
+ fromToken: mockArgs.fromToken,
240
+ toToken: mockArgs.toToken,
241
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
242
+ network: "base",
243
+ taker: "0x1234567890123456789012345678901234567890",
244
+ });
245
+ expect(parsedResult.success).toBe(true);
246
+ expect(parsedResult.fromAmount).toBe("0.1");
247
+ expect(parsedResult.toAmount).toBe("0.99");
248
+ expect(parsedResult.liquidityAvailable).toBe(true);
249
+ });
250
+ it("should get swap price quote on base-sepolia", async () => {
251
+ mockWalletProvider.getNetwork.mockReturnValue({
252
+ protocolFamily: "evm",
253
+ networkId: "base-sepolia",
254
+ });
255
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
256
+ toAmount: "990000",
257
+ minToAmount: "980000",
258
+ liquidityAvailable: true,
259
+ issues: {},
260
+ });
261
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
262
+ const parsedResult = JSON.parse(result);
263
+ expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
264
+ fromToken: mockArgs.fromToken,
265
+ toToken: mockArgs.toToken,
266
+ fromAmount: 100000000000000000n,
267
+ network: "base-sepolia",
268
+ taker: "0x1234567890123456789012345678901234567890",
269
+ });
270
+ expect(parsedResult.success).toBe(true);
271
+ });
272
+ it("should return error for unsupported networks", async () => {
273
+ mockWalletProvider.getNetwork.mockReturnValue({
274
+ protocolFamily: "evm",
275
+ networkId: "ethereum-mainnet",
276
+ });
277
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
278
+ const parsedResult = JSON.parse(result);
279
+ expect(parsedResult.success).toBe(false);
280
+ expect(parsedResult.error).toContain("CDP Swap API for smart wallets is currently only supported on Base networks");
281
+ });
282
+ it("should handle swap price API errors", async () => {
283
+ mockWalletProvider.getNetwork.mockReturnValue({
284
+ protocolFamily: "evm",
285
+ networkId: "base-mainnet",
286
+ });
287
+ mockCdpClient.evm.getSwapPrice.mockRejectedValue(new Error("API Error"));
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("Error fetching swap price: Error: API Error");
292
+ });
293
+ });
294
+ describe("swap", () => {
295
+ const mockArgs = {
296
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
297
+ toToken: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // USDC on Base
298
+ fromAmount: "0.1",
299
+ slippageBps: 100,
300
+ };
301
+ beforeEach(() => {
302
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
303
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
304
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValue({ status: "complete" });
305
+ mockWalletProvider.getPaymasterUrl.mockReturnValue("https://paymaster.example");
306
+ mockGetTokenDetails.mockResolvedValue({
307
+ fromTokenDecimals: 18,
308
+ toTokenDecimals: 6,
309
+ fromTokenName: "ETH",
310
+ toTokenName: "USDC",
311
+ });
312
+ });
313
+ it("should execute swap on base-mainnet", async () => {
314
+ mockWalletProvider.getNetwork.mockReturnValue({
315
+ protocolFamily: "evm",
316
+ networkId: "base-mainnet",
317
+ });
318
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
319
+ liquidityAvailable: true,
320
+ issues: {},
321
+ toAmount: "990000", // 0.99 USDC
322
+ minToAmount: "980000", // 0.98 USDC
323
+ });
324
+ mockSmartAccount.swap.mockResolvedValue({ userOpHash: "0xswap789" });
325
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
326
+ const parsedResult = JSON.parse(result);
327
+ expect(mockSmartAccount.swap).toHaveBeenCalledWith({
328
+ network: "base",
329
+ fromToken: mockArgs.fromToken,
330
+ toToken: mockArgs.toToken,
331
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
332
+ slippageBps: 100,
333
+ paymasterUrl: "https://paymaster.example",
334
+ signerAddress: "0xowner123",
335
+ });
336
+ expect(parsedResult.success).toBe(true);
337
+ expect(parsedResult.transactionHash).toBe("0xswap789");
338
+ expect(parsedResult.fromAmount).toBe("0.1");
339
+ expect(parsedResult.toAmount).toBe("0.99");
340
+ });
341
+ it("should return error for unsupported networks", async () => {
342
+ mockWalletProvider.getNetwork.mockReturnValue({
343
+ protocolFamily: "evm",
344
+ networkId: "ethereum-mainnet",
345
+ });
346
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
347
+ const parsedResult = JSON.parse(result);
348
+ expect(parsedResult.success).toBe(false);
349
+ expect(parsedResult.error).toContain("CDP Swap API for smart wallets is currently only supported on Base networks");
350
+ });
351
+ it("should throw error for local owner account", async () => {
352
+ mockWalletProvider.getNetwork.mockReturnValue({
353
+ protocolFamily: "evm",
354
+ networkId: "base-mainnet",
355
+ });
356
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
357
+ mockWalletProvider.ownerAccount = {
358
+ type: "local",
359
+ address: "0xlocal123",
360
+ };
361
+ await expect(actionProvider.swap(mockWalletProvider, mockArgs)).rejects.toThrow("Smart wallet owner account is not a CDP server account");
362
+ });
363
+ it("should return error when liquidity is not available", async () => {
364
+ mockWalletProvider.getNetwork.mockReturnValue({
365
+ protocolFamily: "evm",
366
+ networkId: "base-mainnet",
367
+ });
368
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
369
+ liquidityAvailable: false,
370
+ issues: {},
371
+ toAmount: "0",
372
+ minToAmount: "0",
373
+ });
374
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
375
+ const parsedResult = JSON.parse(result);
376
+ expect(parsedResult.success).toBe(false);
377
+ expect(parsedResult.error).toContain("No liquidity available to swap");
378
+ });
379
+ it("should return error when balance is insufficient", async () => {
380
+ mockWalletProvider.getNetwork.mockReturnValue({
381
+ protocolFamily: "evm",
382
+ networkId: "base-mainnet",
383
+ });
384
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
385
+ liquidityAvailable: true,
386
+ issues: {
387
+ balance: {
388
+ currentBalance: "50000000000000000", // 0.05 ETH
389
+ },
390
+ },
391
+ toAmount: "990000",
392
+ minToAmount: "980000",
393
+ });
394
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
395
+ const parsedResult = JSON.parse(result);
396
+ expect(parsedResult.success).toBe(false);
397
+ expect(parsedResult.error).toContain("Balance is not enough to perform swap");
398
+ expect(parsedResult.error).toContain("but only have 0.05 ETH");
399
+ });
400
+ it("should handle approval transaction when allowance is insufficient", async () => {
401
+ mockWalletProvider.getNetwork.mockReturnValue({
402
+ protocolFamily: "evm",
403
+ networkId: "base-mainnet",
404
+ });
405
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
406
+ liquidityAvailable: true,
407
+ issues: {
408
+ allowance: {
409
+ requiredAllowance: "100000000000000000",
410
+ currentAllowance: "0",
411
+ },
412
+ },
413
+ toAmount: "990000",
414
+ minToAmount: "980000",
415
+ });
416
+ mockWalletProvider.sendTransaction.mockResolvedValue("0xapproval123");
417
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "complete" }); // For approval
418
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "complete" }); // For swap
419
+ mockSmartAccount.swap.mockResolvedValue({ userOpHash: "0xswap789" });
420
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
421
+ const parsedResult = JSON.parse(result);
422
+ expect(mockWalletProvider.sendTransaction).toHaveBeenCalled();
423
+ expect(parsedResult.success).toBe(true);
424
+ expect(parsedResult.approvalTxHash).toBe("0xapproval123");
425
+ expect(parsedResult.transactionHash).toBe("0xswap789");
426
+ });
427
+ it("should handle swap execution errors", async () => {
428
+ mockWalletProvider.getNetwork.mockReturnValue({
429
+ protocolFamily: "evm",
430
+ networkId: "base-mainnet",
431
+ });
432
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
433
+ liquidityAvailable: true,
434
+ issues: {},
435
+ toAmount: "990000",
436
+ minToAmount: "980000",
437
+ });
438
+ mockSmartAccount.swap.mockRejectedValue(new Error("Swap execution failed"));
439
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
440
+ const parsedResult = JSON.parse(result);
441
+ expect(parsedResult.success).toBe(false);
442
+ expect(parsedResult.error).toContain("Swap failed: Error: Swap execution failed");
443
+ });
444
+ });
191
445
  describe("supportsNetwork", () => {
192
446
  it("should return true for any network", () => {
193
447
  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,32 @@
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
+ }>;
24
+ /**
25
+ * Retry function with exponential backoff
26
+ *
27
+ * @param fn - The function to retry
28
+ * @param maxRetries - Maximum number of retries (default: 3)
29
+ * @param baseDelay - Base delay in milliseconds (default: 1000)
30
+ * @returns Promise that resolves with the function result or rejects with the last error
31
+ */
32
+ export declare function retryWithExponentialBackoff<T>(fn: () => Promise<T>, maxRetries?: number, baseDelay?: number): Promise<T>;
@@ -0,0 +1,142 @@
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
+ exports.retryWithExponentialBackoff = retryWithExponentialBackoff;
7
+ const viem_1 = require("viem");
8
+ // Permit2 contract address is the same across all networks
9
+ exports.PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
10
+ /**
11
+ * Checks if a token is native ETH.
12
+ *
13
+ * @param token - The token address to check.
14
+ * @returns True if the token is native ETH, false otherwise.
15
+ */
16
+ function isNativeEth(token) {
17
+ return token.toLowerCase() === "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
18
+ }
19
+ /**
20
+ * Gets the details (decimals and name) for both fromToken and toToken
21
+ *
22
+ * @param walletProvider - The EVM wallet provider to read contracts
23
+ * @param fromToken - The contract address of the from token
24
+ * @param toToken - The contract address of the to token
25
+ * @returns Promise<{fromTokenDecimals: number, toTokenDecimals: number, fromTokenName: string, toTokenName: string}>
26
+ */
27
+ async function getTokenDetails(walletProvider, fromToken, toToken) {
28
+ // Initialize default values for native ETH
29
+ let fromTokenDecimals = 18;
30
+ let fromTokenName = "ETH";
31
+ let toTokenDecimals = 18;
32
+ let toTokenName = "ETH";
33
+ // Prepare multicall contracts array
34
+ const contracts = [];
35
+ const contractIndexMap = {
36
+ fromDecimals: -1,
37
+ fromName: -1,
38
+ toDecimals: -1,
39
+ toName: -1,
40
+ };
41
+ // Add from token contracts if not native ETH
42
+ if (!isNativeEth(fromToken)) {
43
+ contractIndexMap.fromDecimals = contracts.length;
44
+ contracts.push({
45
+ address: fromToken,
46
+ abi: viem_1.erc20Abi,
47
+ functionName: "decimals",
48
+ });
49
+ contractIndexMap.fromName = contracts.length;
50
+ contracts.push({
51
+ address: fromToken,
52
+ abi: viem_1.erc20Abi,
53
+ functionName: "name",
54
+ });
55
+ }
56
+ // Add to token contracts if not native ETH
57
+ if (!isNativeEth(toToken)) {
58
+ contractIndexMap.toDecimals = contracts.length;
59
+ contracts.push({
60
+ address: toToken,
61
+ abi: viem_1.erc20Abi,
62
+ functionName: "decimals",
63
+ });
64
+ contractIndexMap.toName = contracts.length;
65
+ contracts.push({
66
+ address: toToken,
67
+ abi: viem_1.erc20Abi,
68
+ functionName: "name",
69
+ });
70
+ }
71
+ // Execute multicall if there are contracts to call
72
+ if (contracts.length > 0) {
73
+ try {
74
+ const results = await walletProvider.getPublicClient().multicall({
75
+ contracts,
76
+ });
77
+ // Extract from token details
78
+ if (contractIndexMap.fromDecimals !== -1) {
79
+ const decimalsResult = results[contractIndexMap.fromDecimals];
80
+ const nameResult = results[contractIndexMap.fromName];
81
+ if (decimalsResult.status === "success" && nameResult.status === "success") {
82
+ fromTokenDecimals = decimalsResult.result;
83
+ fromTokenName = nameResult.result;
84
+ }
85
+ else {
86
+ throw new Error(`Failed to read details for fromToken ${fromToken}. This address may not be a valid ERC20 contract.`);
87
+ }
88
+ }
89
+ // Extract to token details
90
+ if (contractIndexMap.toDecimals !== -1) {
91
+ const decimalsResult = results[contractIndexMap.toDecimals];
92
+ const nameResult = results[contractIndexMap.toName];
93
+ if (decimalsResult.status === "success" && nameResult.status === "success") {
94
+ toTokenDecimals = decimalsResult.result;
95
+ toTokenName = nameResult.result;
96
+ }
97
+ else {
98
+ throw new Error(`Failed to read details for toToken ${toToken}. This address may not be a valid ERC20 contract.`);
99
+ }
100
+ }
101
+ }
102
+ catch (error) {
103
+ throw new Error(`Failed to read token details via multicall. Error: ${error}`);
104
+ }
105
+ }
106
+ return { fromTokenDecimals, toTokenDecimals, fromTokenName, toTokenName };
107
+ }
108
+ /**
109
+ * Utility function to sleep for a given number of milliseconds
110
+ *
111
+ * @param ms - Number of milliseconds to sleep
112
+ * @returns Promise that resolves after the specified delay
113
+ */
114
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
115
+ /**
116
+ * Retry function with exponential backoff
117
+ *
118
+ * @param fn - The function to retry
119
+ * @param maxRetries - Maximum number of retries (default: 3)
120
+ * @param baseDelay - Base delay in milliseconds (default: 1000)
121
+ * @returns Promise that resolves with the function result or rejects with the last error
122
+ */
123
+ async function retryWithExponentialBackoff(fn, maxRetries = 3, baseDelay = 1000) {
124
+ let lastError;
125
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
126
+ // Wait before each attempt
127
+ // Calculate delay with exponential backoff: baseDelay * 2^attempt
128
+ const delay = baseDelay * Math.pow(2, attempt);
129
+ await sleep(delay);
130
+ try {
131
+ return await fn();
132
+ }
133
+ catch (error) {
134
+ lastError = error;
135
+ // If this was the last attempt, throw the error
136
+ if (attempt === maxRetries) {
137
+ throw lastError;
138
+ }
139
+ }
140
+ }
141
+ throw lastError;
142
+ }
@@ -18,6 +18,7 @@ export * from "./moonwell";
18
18
  export * from "./morpho";
19
19
  export * from "./opensea";
20
20
  export * from "./spl";
21
+ export * from "./superfluid";
21
22
  export * from "./truemarkets";
22
23
  export * from "./twitter";
23
24
  export * from "./wallet";
@@ -34,6 +34,7 @@ __exportStar(require("./moonwell"), exports);
34
34
  __exportStar(require("./morpho"), exports);
35
35
  __exportStar(require("./opensea"), exports);
36
36
  __exportStar(require("./spl"), exports);
37
+ __exportStar(require("./superfluid"), exports);
37
38
  __exportStar(require("./truemarkets"), exports);
38
39
  __exportStar(require("./twitter"), exports);
39
40
  __exportStar(require("./wallet"), exports);
@@ -9,9 +9,9 @@ export declare const SwapTokenSchema: z.ZodObject<{
9
9
  slippageBps: z.ZodDefault<z.ZodNumber>;
10
10
  }, "strip", z.ZodTypeAny, {
11
11
  amount: number;
12
+ slippageBps: number;
12
13
  inputMint: string;
13
14
  outputMint: string;
14
- slippageBps: number;
15
15
  }, {
16
16
  amount: number;
17
17
  inputMint: string;