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