@coinbase/agentkit 0.9.1 → 0.10.1

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 (151) hide show
  1. package/README.md +181 -54
  2. package/dist/action-providers/across/acrossActionProvider.js +3 -3
  3. package/dist/action-providers/cdp/cdpApiActionProvider.d.ts +3 -12
  4. package/dist/action-providers/cdp/cdpApiActionProvider.js +2 -79
  5. package/dist/action-providers/cdp/cdpApiActionProvider.test.js +0 -125
  6. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.d.ts +58 -0
  7. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.js +351 -0
  8. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.d.ts +1 -0
  9. package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.js +520 -0
  10. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.d.ts +57 -0
  11. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.js +337 -0
  12. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.d.ts +1 -0
  13. package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.js +463 -0
  14. package/dist/action-providers/cdp/index.d.ts +3 -0
  15. package/dist/action-providers/cdp/index.js +3 -0
  16. package/dist/action-providers/cdp/schemas.d.ts +38 -9
  17. package/dist/action-providers/cdp/schemas.js +49 -6
  18. package/dist/action-providers/cdp/spendPermissionUtils.d.ts +24 -0
  19. package/dist/action-providers/cdp/spendPermissionUtils.js +66 -0
  20. package/dist/action-providers/cdp/swapUtils.d.ts +32 -0
  21. package/dist/action-providers/cdp/swapUtils.js +142 -0
  22. package/dist/action-providers/clanker/clankerActionProvider.d.ts +43 -0
  23. package/dist/action-providers/clanker/clankerActionProvider.js +130 -0
  24. package/dist/action-providers/clanker/clankerActionProvider.test.d.ts +4 -0
  25. package/dist/action-providers/clanker/clankerActionProvider.test.js +119 -0
  26. package/dist/action-providers/clanker/index.d.ts +2 -0
  27. package/dist/action-providers/clanker/index.js +18 -0
  28. package/dist/action-providers/clanker/schemas.d.ts +56 -0
  29. package/dist/action-providers/clanker/schemas.js +47 -0
  30. package/dist/action-providers/clanker/utils.d.ts +9 -0
  31. package/dist/action-providers/clanker/utils.js +23 -0
  32. package/dist/action-providers/compound/constants.d.ts +1 -1
  33. package/dist/action-providers/compound/constants.js +2 -2
  34. package/dist/action-providers/erc20/constants.d.ts +35 -135
  35. package/dist/action-providers/erc20/constants.js +37 -189
  36. package/dist/action-providers/erc20/erc20ActionProvider.d.ts +9 -1
  37. package/dist/action-providers/erc20/erc20ActionProvider.js +87 -35
  38. package/dist/action-providers/erc20/erc20ActionProvider.test.js +115 -52
  39. package/dist/action-providers/erc20/schemas.d.ts +25 -12
  40. package/dist/action-providers/erc20/schemas.js +34 -6
  41. package/dist/action-providers/erc20/utils.d.ts +19 -0
  42. package/dist/action-providers/erc20/utils.js +54 -0
  43. package/dist/action-providers/flaunch/constants.d.ts +1 -1
  44. package/dist/action-providers/flaunch/constants.js +2 -2
  45. package/dist/action-providers/flaunch/flaunchActionProvider.js +3 -11
  46. package/dist/action-providers/flaunch/flaunchActionProvider.test.js +5 -0
  47. package/dist/action-providers/index.d.ts +4 -0
  48. package/dist/action-providers/index.js +4 -0
  49. package/dist/action-providers/jupiter/schemas.d.ts +1 -1
  50. package/dist/action-providers/moonwell/schemas.d.ts +2 -2
  51. package/dist/action-providers/morpho/morphoActionProvider.js +5 -5
  52. package/dist/action-providers/morpho/schemas.d.ts +2 -2
  53. package/dist/action-providers/pyth/pythActionProvider.js +5 -0
  54. package/dist/action-providers/pyth/pythActionProvider.test.js +5 -1
  55. package/dist/action-providers/superfluid/constants.d.ts +814 -0
  56. package/dist/action-providers/superfluid/constants.js +2826 -0
  57. package/dist/action-providers/superfluid/graphQueries/endpoints.d.ts +2 -0
  58. package/dist/action-providers/superfluid/graphQueries/endpoints.js +5 -0
  59. package/dist/action-providers/superfluid/graphQueries/queries.d.ts +1 -0
  60. package/dist/action-providers/superfluid/graphQueries/queries.js +35 -0
  61. package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.d.ts +8 -0
  62. package/dist/action-providers/superfluid/graphQueries/superfluidGraphQueries.js +24 -0
  63. package/dist/action-providers/superfluid/graphQueries/types.d.ts +27 -0
  64. package/dist/action-providers/superfluid/graphQueries/types.js +2 -0
  65. package/dist/action-providers/superfluid/index.d.ts +7 -0
  66. package/dist/action-providers/superfluid/index.js +23 -0
  67. package/dist/action-providers/superfluid/schemas.d.ts +86 -0
  68. package/dist/action-providers/superfluid/schemas.js +103 -0
  69. package/dist/action-providers/superfluid/superfluidActionProvider.d.ts +20 -0
  70. package/dist/action-providers/superfluid/superfluidActionProvider.js +36 -0
  71. package/dist/action-providers/superfluid/superfluidPoolActionProvider.d.ts +46 -0
  72. package/dist/action-providers/superfluid/superfluidPoolActionProvider.js +143 -0
  73. package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.d.ts +1 -0
  74. package/dist/action-providers/superfluid/superfluidPoolActionProvider.test.js +92 -0
  75. package/dist/action-providers/superfluid/superfluidQueryActionProvider.d.ts +27 -0
  76. package/dist/action-providers/superfluid/superfluidQueryActionProvider.js +71 -0
  77. package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.d.ts +1 -0
  78. package/dist/action-providers/superfluid/superfluidQueryActionProvider.test.js +57 -0
  79. package/dist/action-providers/superfluid/superfluidStreamActionProvider.d.ts +56 -0
  80. package/dist/action-providers/superfluid/superfluidStreamActionProvider.js +191 -0
  81. package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.d.ts +1 -0
  82. package/dist/action-providers/superfluid/superfluidStreamActionProvider.test.js +80 -0
  83. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.d.ts +30 -0
  84. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.js +108 -0
  85. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.d.ts +1 -0
  86. package/dist/action-providers/superfluid/superfluidSuperTokenCreatorActionProvider.test.js +75 -0
  87. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.d.ts +32 -0
  88. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.js +101 -0
  89. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.d.ts +1 -0
  90. package/dist/action-providers/superfluid/superfluidWrapperActionProvider.test.js +85 -0
  91. package/dist/action-providers/superfluid/utils/parseLogs.d.ts +18 -0
  92. package/dist/action-providers/superfluid/utils/parseLogs.js +78 -0
  93. package/dist/action-providers/truemarkets/truemarketsActionProvider.d.ts +4 -16
  94. package/dist/action-providers/truemarkets/truemarketsActionProvider.js +20 -41
  95. package/dist/action-providers/truemarkets/truemarketsActionProvider.test.js +11 -33
  96. package/dist/action-providers/wallet/walletActionProvider.js +21 -10
  97. package/dist/action-providers/wallet/walletActionProvider.test.js +6 -2
  98. package/dist/action-providers/zerion/constants.d.ts +1 -0
  99. package/dist/action-providers/zerion/constants.js +4 -0
  100. package/dist/action-providers/zerion/index.d.ts +2 -0
  101. package/dist/action-providers/zerion/index.js +18 -0
  102. package/dist/action-providers/zerion/schemas.d.ts +11 -0
  103. package/dist/action-providers/zerion/schemas.js +15 -0
  104. package/dist/action-providers/zerion/types.d.ts +125 -0
  105. package/dist/action-providers/zerion/types.js +16 -0
  106. package/dist/action-providers/zerion/utils.d.ts +3 -0
  107. package/dist/action-providers/zerion/utils.js +45 -0
  108. package/dist/action-providers/zerion/zerionActionProvider.d.ts +57 -0
  109. package/dist/action-providers/zerion/zerionActionProvider.js +159 -0
  110. package/dist/action-providers/zerion/zerionActionProvider.test.d.ts +1 -0
  111. package/dist/action-providers/zerion/zerionActionProvider.test.js +213 -0
  112. package/dist/action-providers/zeroX/index.d.ts +1 -0
  113. package/dist/action-providers/zeroX/index.js +17 -0
  114. package/dist/action-providers/zeroX/schemas.d.ts +51 -0
  115. package/dist/action-providers/zeroX/schemas.js +82 -0
  116. package/dist/action-providers/zeroX/utils.d.ts +23 -0
  117. package/dist/action-providers/zeroX/utils.js +106 -0
  118. package/dist/action-providers/zeroX/zeroXActionProvider.d.ts +57 -0
  119. package/dist/action-providers/zeroX/zeroXActionProvider.js +407 -0
  120. package/dist/action-providers/zeroX/zeroXActionProvider.test.d.ts +1 -0
  121. package/dist/action-providers/zeroX/zeroXActionProvider.test.js +445 -0
  122. package/dist/wallet-providers/cdpEvmWalletProvider.d.ts +20 -2
  123. package/dist/wallet-providers/cdpEvmWalletProvider.js +40 -15
  124. package/dist/wallet-providers/cdpShared.d.ts +9 -0
  125. package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +29 -3
  126. package/dist/wallet-providers/cdpSmartWalletProvider.js +64 -28
  127. package/dist/wallet-providers/cdpSolanaWalletProvider.d.ts +1 -1
  128. package/dist/wallet-providers/cdpSolanaWalletProvider.js +7 -7
  129. package/dist/wallet-providers/cdpSolanaWalletProvider.test.js +15 -12
  130. package/dist/wallet-providers/evmWalletProvider.d.ts +5 -1
  131. package/dist/wallet-providers/legacyCdpSmartWalletProvider.d.ts +9 -2
  132. package/dist/wallet-providers/legacyCdpSmartWalletProvider.js +12 -2
  133. package/dist/wallet-providers/legacyCdpWalletProvider.d.ts +12 -2
  134. package/dist/wallet-providers/legacyCdpWalletProvider.js +11 -2
  135. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.d.ts +10 -2
  136. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.js +12 -3
  137. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.test.js +1 -1
  138. package/dist/wallet-providers/privyEvmWalletProvider.d.ts +2 -0
  139. package/dist/wallet-providers/privyEvmWalletProvider.js +2 -1
  140. package/dist/wallet-providers/privyEvmWalletProvider.test.js +1 -1
  141. package/dist/wallet-providers/solanaKeypairWalletProvider.d.ts +1 -1
  142. package/dist/wallet-providers/solanaKeypairWalletProvider.js +3 -4
  143. package/dist/wallet-providers/solanaKeypairWalletProvider.test.js +4 -2
  144. package/dist/wallet-providers/viemWalletProvider.d.ts +12 -2
  145. package/dist/wallet-providers/viemWalletProvider.js +12 -3
  146. package/dist/wallet-providers/viemWalletProvider.test.js +6 -5
  147. package/dist/wallet-providers/walletProvider.d.ts +1 -1
  148. package/dist/wallet-providers/zeroDevWalletProvider.d.ts +10 -2
  149. package/dist/wallet-providers/zeroDevWalletProvider.js +14 -5
  150. package/dist/wallet-providers/zeroDevWalletProvider.test.js +2 -2
  151. package/package.json +4 -2
@@ -0,0 +1,520 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const cdpEvmWalletActionProvider_1 = require("./cdpEvmWalletActionProvider");
37
+ const schemas_1 = require("./schemas");
38
+ const spendPermissionUtils = __importStar(require("./spendPermissionUtils"));
39
+ const swapUtils = __importStar(require("./swapUtils"));
40
+ // Mock the CDP SDK and utility functions
41
+ jest.mock("@coinbase/cdp-sdk");
42
+ jest.mock("./spendPermissionUtils");
43
+ jest.mock("./swapUtils");
44
+ describe("CDP EVM Wallet Action Provider", () => {
45
+ let actionProvider;
46
+ let mockWalletProvider;
47
+ let mockCdpClient;
48
+ let mockAccount;
49
+ const mockGetTokenDetails = swapUtils.getTokenDetails;
50
+ const mockRetryWithExponentialBackoff = swapUtils.retryWithExponentialBackoff;
51
+ beforeEach(() => {
52
+ jest.clearAllMocks();
53
+ mockAccount = {
54
+ useSpendPermission: jest.fn(),
55
+ swap: jest.fn(),
56
+ address: "0x1234567890123456789012345678901234567890",
57
+ };
58
+ mockCdpClient = {
59
+ evm: {
60
+ listSpendPermissions: jest.fn(),
61
+ getAccount: jest.fn(),
62
+ getSwapPrice: jest.fn(),
63
+ },
64
+ };
65
+ mockWalletProvider = {
66
+ getNetwork: jest.fn(),
67
+ getAddress: jest.fn(),
68
+ getClient: jest.fn(),
69
+ sendTransaction: jest.fn(),
70
+ waitForTransactionReceipt: jest.fn(),
71
+ getCdpSdkNetwork: jest.fn(),
72
+ };
73
+ // Default setup for utility functions
74
+ mockRetryWithExponentialBackoff.mockImplementation(async (fn) => {
75
+ return await fn();
76
+ });
77
+ actionProvider = new cdpEvmWalletActionProvider_1.CdpEvmWalletActionProvider();
78
+ });
79
+ describe("listSpendPermissions", () => {
80
+ const mockArgs = {
81
+ smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
82
+ };
83
+ beforeEach(() => {
84
+ mockWalletProvider.getNetwork.mockReturnValue({
85
+ protocolFamily: "evm",
86
+ networkId: "base-sepolia",
87
+ });
88
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
89
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
90
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
91
+ });
92
+ it("should successfully list spend permissions for EVM wallets", async () => {
93
+ const expectedResult = "Found 2 spend permission(s):\n1. Token: USDC, Allowance: 500, Period: 1800 seconds, Start: 111111, End: 222222\n2. Token: ETH, Allowance: 1000, Period: 3600 seconds, Start: 123456, End: 234567";
94
+ spendPermissionUtils.listSpendPermissionsForSpender.mockResolvedValue(expectedResult);
95
+ const result = await actionProvider.listSpendPermissions(mockWalletProvider, mockArgs);
96
+ expect(spendPermissionUtils.listSpendPermissionsForSpender).toHaveBeenCalledWith(mockCdpClient, mockArgs.smartAccountAddress, "0x1234567890123456789012345678901234567890");
97
+ expect(result).toBe(expectedResult);
98
+ });
99
+ it("should return error message for non-EVM networks", async () => {
100
+ mockWalletProvider.getNetwork.mockReturnValue({
101
+ protocolFamily: "svm",
102
+ networkId: "solana-devnet",
103
+ });
104
+ const result = await actionProvider.listSpendPermissions(mockWalletProvider, mockArgs);
105
+ expect(result).toBe("Spend permissions are currently only supported on EVM networks.");
106
+ expect(spendPermissionUtils.listSpendPermissionsForSpender).not.toHaveBeenCalled();
107
+ });
108
+ it("should handle utility function errors gracefully", async () => {
109
+ spendPermissionUtils.listSpendPermissionsForSpender.mockResolvedValue("Failed to list spend permissions: Network error");
110
+ const result = await actionProvider.listSpendPermissions(mockWalletProvider, mockArgs);
111
+ expect(result).toBe("Failed to list spend permissions: Network error");
112
+ });
113
+ it("should validate input schema", () => {
114
+ const validInput = { smartAccountAddress: "0xabcd1234567890123456789012345678901234567890" };
115
+ const invalidInput = { wrongField: "0xabcd1234567890123456789012345678901234567890" };
116
+ expect(() => schemas_1.ListSpendPermissionsSchema.parse(validInput)).not.toThrow();
117
+ expect(() => schemas_1.ListSpendPermissionsSchema.parse(invalidInput)).toThrow();
118
+ });
119
+ });
120
+ describe("useSpendPermission", () => {
121
+ const mockArgs = {
122
+ smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
123
+ value: "2500",
124
+ };
125
+ beforeEach(() => {
126
+ mockWalletProvider.getNetwork.mockReturnValue({
127
+ protocolFamily: "evm",
128
+ networkId: "base-sepolia",
129
+ });
130
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
131
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
132
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base-sepolia");
133
+ mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
134
+ });
135
+ it("should successfully use spend permission for EVM wallets", async () => {
136
+ const mockPermission = {
137
+ spender: "0x1234567890123456789012345678901234567890",
138
+ token: "USDC",
139
+ allowance: "5000",
140
+ period: 7200,
141
+ start: 111111,
142
+ end: 333333,
143
+ };
144
+ const mockSpendResult = {
145
+ status: "completed",
146
+ transactionHash: "0xdef456789",
147
+ };
148
+ spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
149
+ mockAccount.useSpendPermission.mockResolvedValue(mockSpendResult);
150
+ const result = await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
151
+ expect(spendPermissionUtils.findLatestSpendPermission).toHaveBeenCalledWith(mockCdpClient, mockArgs.smartAccountAddress, "0x1234567890123456789012345678901234567890");
152
+ expect(mockCdpClient.evm.getAccount).toHaveBeenCalledWith({
153
+ address: "0x1234567890123456789012345678901234567890",
154
+ });
155
+ expect(mockAccount.useSpendPermission).toHaveBeenCalledWith({
156
+ spendPermission: mockPermission,
157
+ value: BigInt(2500),
158
+ network: "base-sepolia",
159
+ });
160
+ expect(result).toBe("Successfully spent 2500 tokens using spend permission. Transaction hash: 0xdef456789");
161
+ });
162
+ it("should handle different network conversions", async () => {
163
+ const testCases = [
164
+ { networkId: "base-sepolia", expected: "base-sepolia" },
165
+ { networkId: "base-mainnet", expected: "base" },
166
+ { networkId: "ethereum-sepolia", expected: "ethereum-sepolia" },
167
+ { networkId: "ethereum-mainnet", expected: "ethereum" },
168
+ ];
169
+ const mockPermission = { spender: "0x1234", token: "ETH" };
170
+ const mockSpendResult = { status: "completed" };
171
+ spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
172
+ mockAccount.useSpendPermission.mockResolvedValue(mockSpendResult);
173
+ for (const testCase of testCases) {
174
+ jest.clearAllMocks();
175
+ mockWalletProvider.getNetwork.mockReturnValue({
176
+ protocolFamily: "evm",
177
+ networkId: testCase.networkId,
178
+ });
179
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
180
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue(testCase.expected);
181
+ mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
182
+ await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
183
+ expect(mockAccount.useSpendPermission).toHaveBeenCalledWith({
184
+ spendPermission: mockPermission,
185
+ value: BigInt(2500),
186
+ network: testCase.expected,
187
+ });
188
+ }
189
+ });
190
+ it("should handle unknown networks by passing them as-is", async () => {
191
+ mockWalletProvider.getNetwork.mockReturnValue({
192
+ protocolFamily: "evm",
193
+ networkId: "polygon-mainnet",
194
+ });
195
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("polygon-mainnet");
196
+ const mockPermission = { spender: "0x1234", token: "MATIC" };
197
+ const mockSpendResult = { status: "completed" };
198
+ spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
199
+ mockAccount.useSpendPermission.mockResolvedValue(mockSpendResult);
200
+ await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
201
+ expect(mockAccount.useSpendPermission).toHaveBeenCalledWith({
202
+ spendPermission: mockPermission,
203
+ value: BigInt(2500),
204
+ network: "polygon-mainnet",
205
+ });
206
+ });
207
+ it("should return error message for non-EVM networks", async () => {
208
+ mockWalletProvider.getNetwork.mockReturnValue({
209
+ protocolFamily: "svm",
210
+ networkId: "solana-devnet",
211
+ });
212
+ const result = await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
213
+ expect(result).toBe("Spend permissions are currently only supported on EVM networks.");
214
+ });
215
+ it("should handle spend permission not found error", async () => {
216
+ spendPermissionUtils.findLatestSpendPermission.mockRejectedValue(new Error("No spend permissions found for spender"));
217
+ const result = await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
218
+ expect(result).toBe("Failed to use spend permission: Error: No spend permissions found for spender");
219
+ });
220
+ it("should handle account creation failure", async () => {
221
+ spendPermissionUtils.findLatestSpendPermission.mockResolvedValue({
222
+ spender: "0x1234",
223
+ token: "ETH",
224
+ });
225
+ mockCdpClient.evm.getAccount.mockRejectedValue(new Error("Account not found"));
226
+ const result = await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
227
+ expect(result).toBe("Failed to use spend permission: Error: Account not found");
228
+ });
229
+ it("should handle account use permission failure", async () => {
230
+ const mockPermission = { spender: "0x1234", token: "ETH" };
231
+ spendPermissionUtils.findLatestSpendPermission.mockResolvedValue(mockPermission);
232
+ mockAccount.useSpendPermission.mockRejectedValue(new Error("Insufficient allowance"));
233
+ const result = await actionProvider.useSpendPermission(mockWalletProvider, mockArgs);
234
+ expect(result).toBe("Failed to use spend permission: Error: Insufficient allowance");
235
+ });
236
+ it("should validate input schema", () => {
237
+ const validInput = {
238
+ smartAccountAddress: "0xabcd1234567890123456789012345678901234567890",
239
+ value: "1000",
240
+ };
241
+ const invalidInput = {
242
+ smartAccountAddress: "not-an-address",
243
+ value: -100,
244
+ };
245
+ expect(() => schemas_1.UseSpendPermissionSchema.parse(validInput)).not.toThrow();
246
+ expect(() => schemas_1.UseSpendPermissionSchema.parse(invalidInput)).toThrow();
247
+ });
248
+ });
249
+ describe("getSwapPrice", () => {
250
+ const mockArgs = {
251
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
252
+ toToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48", // USDC
253
+ fromAmount: "0.1",
254
+ slippageBps: 100,
255
+ };
256
+ beforeEach(() => {
257
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
258
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
259
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
260
+ mockGetTokenDetails.mockResolvedValue({
261
+ fromTokenDecimals: 18,
262
+ toTokenDecimals: 6,
263
+ fromTokenName: "ETH",
264
+ toTokenName: "USDC",
265
+ });
266
+ });
267
+ it("should get swap price quote on base-mainnet", async () => {
268
+ mockWalletProvider.getNetwork.mockReturnValue({
269
+ protocolFamily: "evm",
270
+ networkId: "base-mainnet",
271
+ });
272
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
273
+ toAmount: "990000", // 0.99 USDC
274
+ minToAmount: "980000", // 0.98 USDC
275
+ liquidityAvailable: true,
276
+ issues: {},
277
+ });
278
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
279
+ const parsedResult = JSON.parse(result);
280
+ expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
281
+ fromToken: mockArgs.fromToken,
282
+ toToken: mockArgs.toToken,
283
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
284
+ network: "base",
285
+ taker: "0x1234567890123456789012345678901234567890",
286
+ });
287
+ expect(parsedResult.success).toBe(true);
288
+ expect(parsedResult.fromAmount).toBe("0.1");
289
+ expect(parsedResult.toAmount).toBe("0.99");
290
+ expect(parsedResult.liquidityAvailable).toBe(true);
291
+ });
292
+ it("should get swap price quote on ethereum-mainnet", async () => {
293
+ mockWalletProvider.getNetwork.mockReturnValue({
294
+ protocolFamily: "evm",
295
+ networkId: "ethereum-mainnet",
296
+ });
297
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("ethereum");
298
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
299
+ toAmount: "990000",
300
+ minToAmount: "980000",
301
+ liquidityAvailable: true,
302
+ issues: {},
303
+ });
304
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
305
+ const parsedResult = JSON.parse(result);
306
+ expect(mockCdpClient.evm.getSwapPrice).toHaveBeenCalledWith({
307
+ fromToken: mockArgs.fromToken,
308
+ toToken: mockArgs.toToken,
309
+ fromAmount: 100000000000000000n,
310
+ network: "ethereum",
311
+ taker: "0x1234567890123456789012345678901234567890",
312
+ });
313
+ expect(parsedResult.success).toBe(true);
314
+ });
315
+ it("should return error for unsupported networks", async () => {
316
+ mockWalletProvider.getNetwork.mockReturnValue({
317
+ protocolFamily: "evm",
318
+ networkId: "base-sepolia",
319
+ });
320
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
321
+ const parsedResult = JSON.parse(result);
322
+ expect(parsedResult.success).toBe(false);
323
+ expect(parsedResult.error).toContain("CDP Swap API is currently only supported on 'base-mainnet' or 'ethereum-mainnet'");
324
+ });
325
+ it("should handle swap price API errors", async () => {
326
+ mockWalletProvider.getNetwork.mockReturnValue({
327
+ protocolFamily: "evm",
328
+ networkId: "base-mainnet",
329
+ });
330
+ mockCdpClient.evm.getSwapPrice.mockRejectedValue(new Error("API Error"));
331
+ const result = await actionProvider.getSwapPrice(mockWalletProvider, mockArgs);
332
+ const parsedResult = JSON.parse(result);
333
+ expect(parsedResult.success).toBe(false);
334
+ expect(parsedResult.error).toContain("Error fetching swap price: Error: API Error");
335
+ });
336
+ });
337
+ describe("swap", () => {
338
+ const mockArgs = {
339
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee", // ETH
340
+ toToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48", // USDC
341
+ fromAmount: "0.1",
342
+ slippageBps: 100,
343
+ };
344
+ beforeEach(() => {
345
+ mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
346
+ mockWalletProvider.getAddress.mockReturnValue("0x1234567890123456789012345678901234567890");
347
+ mockWalletProvider.getCdpSdkNetwork.mockReturnValue("base");
348
+ mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
349
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValue({ status: "success" });
350
+ mockGetTokenDetails.mockResolvedValue({
351
+ fromTokenDecimals: 18,
352
+ toTokenDecimals: 6,
353
+ fromTokenName: "ETH",
354
+ toTokenName: "USDC",
355
+ });
356
+ });
357
+ it("should execute swap on base-mainnet", async () => {
358
+ mockWalletProvider.getNetwork.mockReturnValue({
359
+ protocolFamily: "evm",
360
+ networkId: "base-mainnet",
361
+ });
362
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
363
+ liquidityAvailable: true,
364
+ issues: {},
365
+ toAmount: "990000", // 0.99 USDC
366
+ minToAmount: "980000", // 0.98 USDC
367
+ });
368
+ mockAccount.swap.mockResolvedValue({ transactionHash: "0xswap789" });
369
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
370
+ const parsedResult = JSON.parse(result);
371
+ expect(mockCdpClient.evm.getAccount).toHaveBeenCalledWith({
372
+ address: "0x1234567890123456789012345678901234567890",
373
+ });
374
+ expect(mockAccount.swap).toHaveBeenCalledWith({
375
+ network: "base",
376
+ fromToken: mockArgs.fromToken,
377
+ toToken: mockArgs.toToken,
378
+ fromAmount: 100000000000000000n, // 0.1 ETH in wei
379
+ slippageBps: 100,
380
+ signerAddress: "0x1234567890123456789012345678901234567890",
381
+ });
382
+ expect(parsedResult.success).toBe(true);
383
+ expect(parsedResult.transactionHash).toBe("0xswap789");
384
+ expect(parsedResult.fromAmount).toBe("0.1");
385
+ expect(parsedResult.toAmount).toBe("0.99");
386
+ });
387
+ it("should return error for unsupported networks", async () => {
388
+ mockWalletProvider.getNetwork.mockReturnValue({
389
+ protocolFamily: "evm",
390
+ networkId: "base-sepolia",
391
+ });
392
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
393
+ const parsedResult = JSON.parse(result);
394
+ expect(parsedResult.success).toBe(false);
395
+ expect(parsedResult.error).toContain("CDP Swap API is currently only supported on 'base-mainnet' or 'ethereum-mainnet'");
396
+ });
397
+ it("should return error when liquidity is not available", async () => {
398
+ mockWalletProvider.getNetwork.mockReturnValue({
399
+ protocolFamily: "evm",
400
+ networkId: "base-mainnet",
401
+ });
402
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
403
+ liquidityAvailable: false,
404
+ issues: {},
405
+ toAmount: "0",
406
+ minToAmount: "0",
407
+ });
408
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
409
+ const parsedResult = JSON.parse(result);
410
+ expect(parsedResult.success).toBe(false);
411
+ expect(parsedResult.error).toContain("No liquidity available to swap");
412
+ });
413
+ it("should return error when balance is insufficient", async () => {
414
+ mockWalletProvider.getNetwork.mockReturnValue({
415
+ protocolFamily: "evm",
416
+ networkId: "base-mainnet",
417
+ });
418
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
419
+ liquidityAvailable: true,
420
+ issues: {
421
+ balance: {
422
+ currentBalance: "50000000000000000", // 0.05 ETH
423
+ },
424
+ },
425
+ toAmount: "990000",
426
+ minToAmount: "980000",
427
+ });
428
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
429
+ const parsedResult = JSON.parse(result);
430
+ expect(parsedResult.success).toBe(false);
431
+ expect(parsedResult.error).toContain("Balance is not enough to perform swap");
432
+ expect(parsedResult.error).toContain("but only have 0.05 ETH");
433
+ });
434
+ it("should handle approval transaction when allowance is insufficient", async () => {
435
+ mockWalletProvider.getNetwork.mockReturnValue({
436
+ protocolFamily: "evm",
437
+ networkId: "base-mainnet",
438
+ });
439
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
440
+ liquidityAvailable: true,
441
+ issues: {
442
+ allowance: {
443
+ requiredAllowance: "100000000000000000",
444
+ currentAllowance: "0",
445
+ },
446
+ },
447
+ toAmount: "990000",
448
+ minToAmount: "980000",
449
+ });
450
+ mockWalletProvider.sendTransaction.mockResolvedValue("0xapproval123");
451
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "success" }); // For approval
452
+ mockWalletProvider.waitForTransactionReceipt.mockResolvedValueOnce({ status: "success" }); // For swap
453
+ mockAccount.swap.mockResolvedValue({ transactionHash: "0xswap789" });
454
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
455
+ const parsedResult = JSON.parse(result);
456
+ expect(mockWalletProvider.sendTransaction).toHaveBeenCalled();
457
+ expect(parsedResult.success).toBe(true);
458
+ expect(parsedResult.approvalTxHash).toBe("0xapproval123");
459
+ expect(parsedResult.transactionHash).toBe("0xswap789");
460
+ });
461
+ it("should handle swap execution errors", async () => {
462
+ mockWalletProvider.getNetwork.mockReturnValue({
463
+ protocolFamily: "evm",
464
+ networkId: "base-mainnet",
465
+ });
466
+ mockCdpClient.evm.getSwapPrice.mockResolvedValue({
467
+ liquidityAvailable: true,
468
+ issues: {},
469
+ toAmount: "990000",
470
+ minToAmount: "980000",
471
+ });
472
+ mockAccount.swap.mockRejectedValue(new Error("Swap execution failed"));
473
+ const result = await actionProvider.swap(mockWalletProvider, mockArgs);
474
+ const parsedResult = JSON.parse(result);
475
+ expect(parsedResult.success).toBe(false);
476
+ expect(parsedResult.error).toContain("Swap failed: Error: Swap execution failed");
477
+ });
478
+ });
479
+ describe("supportsNetwork", () => {
480
+ it("should return true for EVM networks", () => {
481
+ const evmNetwork = { protocolFamily: "evm", networkId: "base-sepolia" };
482
+ expect(actionProvider.supportsNetwork(evmNetwork)).toBe(true);
483
+ });
484
+ it("should return false for non-EVM networks", () => {
485
+ const svmNetwork = { protocolFamily: "svm", networkId: "solana-devnet" };
486
+ expect(actionProvider.supportsNetwork(svmNetwork)).toBe(false);
487
+ });
488
+ });
489
+ describe("SwapSchema", () => {
490
+ it("should validate correct swap input", () => {
491
+ const validInput = {
492
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
493
+ toToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48",
494
+ fromAmount: "0.1",
495
+ };
496
+ const result = schemas_1.SwapSchema.safeParse(validInput);
497
+ expect(result.success).toBe(true);
498
+ expect(result.data).toEqual({ ...validInput, slippageBps: 100 });
499
+ });
500
+ it("should validate swap input with optional slippageBps", () => {
501
+ const validInput = {
502
+ fromToken: "0xA0b86991c6218b36c1d19D4a2e9EB0cE3606eB48",
503
+ toToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
504
+ fromAmount: "100",
505
+ slippageBps: 50,
506
+ };
507
+ const result = schemas_1.SwapSchema.safeParse(validInput);
508
+ expect(result.success).toBe(true);
509
+ expect(result.data).toEqual(validInput);
510
+ });
511
+ it("should fail validation when missing required fields", () => {
512
+ const invalidInput = {
513
+ fromToken: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
514
+ // missing toToken and fromAmount
515
+ };
516
+ const result = schemas_1.SwapSchema.safeParse(invalidInput);
517
+ expect(result.success).toBe(false);
518
+ });
519
+ });
520
+ });
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ import { CdpSmartWalletProvider } from "../../wallet-providers/cdpSmartWalletProvider";
3
+ import { ActionProvider } from "../actionProvider";
4
+ import { UseSpendPermissionSchema, ListSpendPermissionsSchema, SwapSchema } from "./schemas";
5
+ import type { Network } from "../../network";
6
+ /**
7
+ * CdpSmartWalletActionProvider is an action provider for CDP Smart Wallet specific actions.
8
+ *
9
+ * This provider is scoped specifically to CdpSmartWalletProvider and provides actions
10
+ * that are optimized for smart wallet functionality.
11
+ */
12
+ export declare class CdpSmartWalletActionProvider extends ActionProvider<CdpSmartWalletProvider> {
13
+ /**
14
+ * Constructor for the CdpSmartWalletActionProvider class.
15
+ */
16
+ constructor();
17
+ /**
18
+ * Lists spend permissions for a smart account.
19
+ *
20
+ * @param walletProvider - The smart wallet provider to use for listing permissions.
21
+ * @param args - The input arguments for listing spend permissions.
22
+ * @returns A list of spend permissions available to the current wallet.
23
+ */
24
+ listSpendPermissions(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof ListSpendPermissionsSchema>): Promise<string>;
25
+ /**
26
+ * Uses a spend permission to transfer tokens from a smart account to the current smart wallet.
27
+ *
28
+ * @param walletProvider - The smart wallet provider to use for the spend operation.
29
+ * @param args - The input arguments for using the spend permission.
30
+ * @returns A confirmation message with transaction details.
31
+ */
32
+ useSpendPermission(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof UseSpendPermissionSchema>): Promise<string>;
33
+ /**
34
+ * Gets a price quote for swapping tokens using the CDP Swap API.
35
+ *
36
+ * @param walletProvider - The smart wallet provider to get the quote for.
37
+ * @param args - The input arguments for the swap price action.
38
+ * @returns A JSON string with detailed swap price quote information.
39
+ */
40
+ getSwapPrice(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof SwapSchema>): Promise<string>;
41
+ /**
42
+ * Swaps tokens using the CDP client.
43
+ *
44
+ * @param walletProvider - The smart wallet provider to perform the swap with.
45
+ * @param args - The input arguments for the swap action.
46
+ * @returns A JSON string with detailed swap execution information.
47
+ */
48
+ swap(walletProvider: CdpSmartWalletProvider, args: z.infer<typeof SwapSchema>): Promise<string>;
49
+ /**
50
+ * Checks if the smart wallet action provider supports the given network.
51
+ *
52
+ * @param _ - The network to check.
53
+ * @returns True if the smart wallet action provider supports the network, false otherwise.
54
+ */
55
+ supportsNetwork: (_: Network) => boolean;
56
+ }
57
+ export declare const cdpSmartWalletActionProvider: () => CdpSmartWalletActionProvider;