@coinbase/agentkit 0.0.0-nightly-20250820210426 → 0.0.0-nightly-20250822210413
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 +37 -0
- package/dist/action-providers/cdp/cdpApiActionProvider.d.ts +3 -11
- package/dist/action-providers/cdp/cdpApiActionProvider.js +2 -65
- package/dist/action-providers/cdp/cdpApiActionProvider.test.js +0 -125
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.d.ts +17 -1
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.js +219 -0
- package/dist/action-providers/cdp/cdpEvmWalletActionProvider.test.js +270 -0
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.d.ts +17 -1
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.js +220 -0
- package/dist/action-providers/cdp/cdpSmartWalletActionProvider.test.js +254 -0
- 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 +32 -0
- package/dist/action-providers/cdp/swapUtils.js +142 -0
- package/dist/action-providers/index.d.ts +1 -0
- package/dist/action-providers/index.js +1 -0
- package/dist/action-providers/jupiter/schemas.d.ts +1 -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 +108 -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 +18 -0
- package/dist/action-providers/superfluid/utils/parseLogs.js +78 -0
- package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +3 -2
- package/dist/wallet-providers/cdpSmartWalletProvider.js +4 -5
- package/dist/wallet-providers/viemWalletProvider.d.ts +4 -0
- package/dist/wallet-providers/viemWalletProvider.js +2 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -383,6 +383,43 @@ const agent = createReactAgent({
|
|
|
383
383
|
</table>
|
|
384
384
|
</details>
|
|
385
385
|
<details>
|
|
386
|
+
<summary><strong>Superfluid</strong></summary>
|
|
387
|
+
<table width="100%">
|
|
388
|
+
<tr>
|
|
389
|
+
<td width="200"><code>create_pool</code></td>
|
|
390
|
+
<td width="768">Creates a new Superfluid pool for a Supertoken.</td>
|
|
391
|
+
</tr>
|
|
392
|
+
<tr>
|
|
393
|
+
<td width="200"><code>update_pool</code></td>
|
|
394
|
+
<td width="768">Updates an existing Superfluid pool with recipients and flow rates.</td>
|
|
395
|
+
</tr>
|
|
396
|
+
<tr>
|
|
397
|
+
<td width="200"><code>query_streams</code></td>
|
|
398
|
+
<td width="768">Queries existing Superfluid streams using Graphql.</td>
|
|
399
|
+
</tr>
|
|
400
|
+
<tr>
|
|
401
|
+
<td width="200"><code>create_stream</code></td>
|
|
402
|
+
<td width="768">Creates a new Superfluid stream to an address with a given flow rate.</td>
|
|
403
|
+
</tr>
|
|
404
|
+
<tr>
|
|
405
|
+
<td width="200"><code>update_stream</code></td>
|
|
406
|
+
<td width="768">Updates an existing Superfluid stream with a new flow rate.</td>
|
|
407
|
+
</tr>
|
|
408
|
+
<tr>
|
|
409
|
+
<td width="200"><code>delete_stream</code></td>
|
|
410
|
+
<td width="768">Stops an existing Superfluid stream.</td>
|
|
411
|
+
</tr>
|
|
412
|
+
<tr>
|
|
413
|
+
<td width="200"><code>create_super_token</code></td>
|
|
414
|
+
<td width="768">Creates a new Supertoken implementation for an existing ERC20 token.</td>
|
|
415
|
+
</tr>
|
|
416
|
+
<tr>
|
|
417
|
+
<td width="200"><code>wrap_superfluid_token</code></td>
|
|
418
|
+
<td width="768">Wraps an ERC20 token into its Superfluid Super token implementation.</td>
|
|
419
|
+
</tr>
|
|
420
|
+
</table>
|
|
421
|
+
</details>
|
|
422
|
+
<details>
|
|
386
423
|
<summary><strong>Twitter</strong></summary>
|
|
387
424
|
<table width="100%">
|
|
388
425
|
<tr>
|
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { Network } from "../../network";
|
|
3
3
|
import { WalletProvider } from "../../wallet-providers";
|
|
4
4
|
import { ActionProvider } from "../actionProvider";
|
|
5
|
-
import { RequestFaucetFundsV2Schema
|
|
5
|
+
import { RequestFaucetFundsV2Schema } from "./schemas";
|
|
6
6
|
/**
|
|
7
7
|
* CdpApiActionProvider is an action provider for CDP API.
|
|
8
8
|
*
|
|
@@ -23,20 +23,12 @@ export declare class CdpApiActionProvider extends ActionProvider<WalletProvider>
|
|
|
23
23
|
*/
|
|
24
24
|
faucet(walletProvider: WalletProvider, args: z.infer<typeof RequestFaucetFundsV2Schema>): Promise<string>;
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* @param walletProvider - The wallet provider to perform the swap with.
|
|
29
|
-
* @param args - The input arguments for the swap action.
|
|
30
|
-
* @returns A confirmation message with transaction details.
|
|
31
|
-
*/
|
|
32
|
-
swap(walletProvider: WalletProvider, args: z.infer<typeof SwapSchema>): Promise<string>;
|
|
33
|
-
/**
|
|
34
|
-
* Checks if the Cdp action provider supports the given network.
|
|
26
|
+
* Checks if the CDP action provider supports the given network.
|
|
35
27
|
*
|
|
36
28
|
* NOTE: Network scoping is done at the action implementation level
|
|
37
29
|
*
|
|
38
30
|
* @param _ - The network to check.
|
|
39
|
-
* @returns True if the
|
|
31
|
+
* @returns True if the CDP action provider supports the network, false otherwise.
|
|
40
32
|
*/
|
|
41
33
|
supportsNetwork: (_: Network) => boolean;
|
|
42
34
|
}
|
|
@@ -8,11 +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
11
|
var _CdpApiActionProvider_instances, _CdpApiActionProvider_getCdpSdkNetwork;
|
|
17
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
13
|
exports.cdpApiActionProvider = exports.CdpApiActionProvider = void 0;
|
|
@@ -35,12 +30,12 @@ class CdpApiActionProvider extends actionProvider_1.ActionProvider {
|
|
|
35
30
|
super("cdp_api", []);
|
|
36
31
|
_CdpApiActionProvider_instances.add(this);
|
|
37
32
|
/**
|
|
38
|
-
* Checks if the
|
|
33
|
+
* Checks if the CDP action provider supports the given network.
|
|
39
34
|
*
|
|
40
35
|
* NOTE: Network scoping is done at the action implementation level
|
|
41
36
|
*
|
|
42
37
|
* @param _ - The network to check.
|
|
43
|
-
* @returns True if the
|
|
38
|
+
* @returns True if the CDP action provider supports the network, false otherwise.
|
|
44
39
|
*/
|
|
45
40
|
this.supportsNetwork = (_) => true;
|
|
46
41
|
}
|
|
@@ -84,50 +79,6 @@ class CdpApiActionProvider extends actionProvider_1.ActionProvider {
|
|
|
84
79
|
throw new Error("Wallet provider is not a CDP Wallet Provider.");
|
|
85
80
|
}
|
|
86
81
|
}
|
|
87
|
-
/**
|
|
88
|
-
* Swaps tokens using the CDP client.
|
|
89
|
-
*
|
|
90
|
-
* @param walletProvider - The wallet provider to perform the swap with.
|
|
91
|
-
* @param args - The input arguments for the swap action.
|
|
92
|
-
* @returns A confirmation message with transaction details.
|
|
93
|
-
*/
|
|
94
|
-
async swap(walletProvider, args) {
|
|
95
|
-
const network = walletProvider.getNetwork();
|
|
96
|
-
const networkId = network.networkId;
|
|
97
|
-
if ((0, cdpShared_1.isWalletProviderWithClient)(walletProvider)) {
|
|
98
|
-
if (network.protocolFamily === "evm") {
|
|
99
|
-
try {
|
|
100
|
-
const cdpNetwork = __classPrivateFieldGet(this, _CdpApiActionProvider_instances, "m", _CdpApiActionProvider_getCdpSdkNetwork).call(this, networkId);
|
|
101
|
-
// Get the account for the wallet address
|
|
102
|
-
const account = await walletProvider.getClient().evm.getAccount({
|
|
103
|
-
address: walletProvider.getAddress(),
|
|
104
|
-
});
|
|
105
|
-
// Execute swap using the all-in-one pattern
|
|
106
|
-
const swapResult = await account.swap({
|
|
107
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
|
-
network: cdpNetwork,
|
|
109
|
-
from: args.fromAssetId,
|
|
110
|
-
to: args.toAssetId,
|
|
111
|
-
amount: args.amount,
|
|
112
|
-
slippageBps: 100, // 1% slippage tolerance
|
|
113
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
114
|
-
paymasterUrl: walletProvider.getPaymasterUrl?.(),
|
|
115
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
116
|
-
});
|
|
117
|
-
return `Successfully swapped ${args.amount} ${args.fromAssetId.toUpperCase()} to ${args.toAssetId.toUpperCase()}. Transaction hash: ${swapResult.transactionHash}`;
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
throw new Error(`Swap failed: ${error}`);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
throw new Error("Swap is currently only supported on EVM networks.");
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
throw new Error("Wallet provider is not a CDP Wallet Provider.");
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
82
|
}
|
|
132
83
|
exports.CdpApiActionProvider = CdpApiActionProvider;
|
|
133
84
|
_CdpApiActionProvider_instances = new WeakSet(), _CdpApiActionProvider_getCdpSdkNetwork = function _CdpApiActionProvider_getCdpSdkNetwork(networkId) {
|
|
@@ -159,19 +110,5 @@ from another wallet and provide the user with your wallet details.`,
|
|
|
159
110
|
__metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
|
|
160
111
|
__metadata("design:returntype", Promise)
|
|
161
112
|
], CdpApiActionProvider.prototype, "faucet", null);
|
|
162
|
-
__decorate([
|
|
163
|
-
(0, actionDecorator_1.CreateAction)({
|
|
164
|
-
name: "swap",
|
|
165
|
-
description: `This tool swaps tokens using the CDP API. It takes the wallet, from asset ID, to asset ID, and amount as input.
|
|
166
|
-
Swaps are currently supported on EVM networks like Base and Ethereum.
|
|
167
|
-
Example usage:
|
|
168
|
-
- Swap 0.1 ETH to USDC: { fromAssetId: "eth", toAssetId: "usdc", amount: "0.1" }
|
|
169
|
-
- Swap 100 USDC to ETH: { fromAssetId: "usdc", toAssetId: "eth", amount: "100" }`,
|
|
170
|
-
schema: schemas_1.SwapSchema,
|
|
171
|
-
}),
|
|
172
|
-
__metadata("design:type", Function),
|
|
173
|
-
__metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
|
|
174
|
-
__metadata("design:returntype", Promise)
|
|
175
|
-
], CdpApiActionProvider.prototype, "swap", null);
|
|
176
113
|
const cdpApiActionProvider = () => new CdpApiActionProvider();
|
|
177
114
|
exports.cdpApiActionProvider = cdpApiActionProvider;
|
|
@@ -10,20 +10,14 @@ describe("CDP API Action Provider", () => {
|
|
|
10
10
|
let mockCdpClient;
|
|
11
11
|
beforeEach(() => {
|
|
12
12
|
jest.clearAllMocks();
|
|
13
|
-
const mockAccount = {
|
|
14
|
-
swap: jest.fn(),
|
|
15
|
-
};
|
|
16
13
|
mockCdpClient = {
|
|
17
14
|
evm: {
|
|
18
15
|
requestFaucet: jest.fn(),
|
|
19
|
-
getAccount: jest.fn(),
|
|
20
16
|
},
|
|
21
17
|
solana: {
|
|
22
18
|
requestFaucet: jest.fn(),
|
|
23
19
|
},
|
|
24
20
|
};
|
|
25
|
-
// Set up default mock behavior
|
|
26
|
-
mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
|
|
27
21
|
mockWalletProvider = {
|
|
28
22
|
getNetwork: jest.fn(),
|
|
29
23
|
getAddress: jest.fn(),
|
|
@@ -93,94 +87,6 @@ describe("CDP API Action Provider", () => {
|
|
|
93
87
|
await expect(actionProvider.faucet(mockWalletWithoutClient, { assetId: "eth" })).rejects.toThrow("Wallet provider is not a CDP Wallet Provider");
|
|
94
88
|
});
|
|
95
89
|
});
|
|
96
|
-
describe("swap", () => {
|
|
97
|
-
it("should perform swap on base-sepolia", async () => {
|
|
98
|
-
const mockNetwork = { protocolFamily: "evm", networkId: "base-sepolia" };
|
|
99
|
-
mockWalletProvider.getNetwork.mockReturnValue(mockNetwork);
|
|
100
|
-
mockWalletProvider.getAddress.mockReturnValue("0x123456789");
|
|
101
|
-
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
102
|
-
const mockAccount = { swap: jest.fn() };
|
|
103
|
-
mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
|
|
104
|
-
mockAccount.swap.mockResolvedValue({
|
|
105
|
-
transactionHash: "0xswap123456",
|
|
106
|
-
});
|
|
107
|
-
const result = await actionProvider.swap(mockWalletProvider, {
|
|
108
|
-
fromAssetId: "eth",
|
|
109
|
-
toAssetId: "usdc",
|
|
110
|
-
amount: "0.1",
|
|
111
|
-
});
|
|
112
|
-
expect(mockCdpClient.evm.getAccount).toHaveBeenCalledWith({
|
|
113
|
-
address: "0x123456789",
|
|
114
|
-
});
|
|
115
|
-
expect(mockAccount.swap).toHaveBeenCalledWith({
|
|
116
|
-
network: "base-sepolia",
|
|
117
|
-
from: "eth",
|
|
118
|
-
to: "usdc",
|
|
119
|
-
amount: "0.1",
|
|
120
|
-
slippageBps: 100,
|
|
121
|
-
});
|
|
122
|
-
expect(result).toContain("Successfully swapped 0.1 ETH to USDC");
|
|
123
|
-
expect(result).toContain("0xswap123456");
|
|
124
|
-
});
|
|
125
|
-
it("should perform swap on base-mainnet", async () => {
|
|
126
|
-
const mockNetwork = { protocolFamily: "evm", networkId: "base-mainnet" };
|
|
127
|
-
mockWalletProvider.getNetwork.mockReturnValue(mockNetwork);
|
|
128
|
-
mockWalletProvider.getAddress.mockReturnValue("0x123456789");
|
|
129
|
-
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
130
|
-
const mockAccount = { swap: jest.fn() };
|
|
131
|
-
mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
|
|
132
|
-
mockAccount.swap.mockResolvedValue({
|
|
133
|
-
transactionHash: "0xswap789",
|
|
134
|
-
});
|
|
135
|
-
const result = await actionProvider.swap(mockWalletProvider, {
|
|
136
|
-
fromAssetId: "usdc",
|
|
137
|
-
toAssetId: "eth",
|
|
138
|
-
amount: "100",
|
|
139
|
-
});
|
|
140
|
-
expect(mockAccount.swap).toHaveBeenCalledWith({
|
|
141
|
-
network: "base", // Should convert base-mainnet to base
|
|
142
|
-
from: "usdc",
|
|
143
|
-
to: "eth",
|
|
144
|
-
amount: "100",
|
|
145
|
-
slippageBps: 100,
|
|
146
|
-
});
|
|
147
|
-
expect(result).toContain("Successfully swapped 100 USDC to ETH");
|
|
148
|
-
});
|
|
149
|
-
it("should throw error for non-EVM networks", async () => {
|
|
150
|
-
const mockNetwork = { protocolFamily: "svm", networkId: "solana-devnet" };
|
|
151
|
-
mockWalletProvider.getNetwork.mockReturnValue(mockNetwork);
|
|
152
|
-
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
153
|
-
await expect(actionProvider.swap(mockWalletProvider, {
|
|
154
|
-
fromAssetId: "sol",
|
|
155
|
-
toAssetId: "usdc",
|
|
156
|
-
amount: "1",
|
|
157
|
-
})).rejects.toThrow("Swap is currently only supported on EVM networks");
|
|
158
|
-
});
|
|
159
|
-
it("should throw error for wallet provider without client", async () => {
|
|
160
|
-
const mockWalletWithoutClient = {
|
|
161
|
-
getNetwork: jest.fn().mockReturnValue({ protocolFamily: "evm", networkId: "base-sepolia" }),
|
|
162
|
-
};
|
|
163
|
-
await expect(actionProvider.swap(mockWalletWithoutClient, {
|
|
164
|
-
fromAssetId: "eth",
|
|
165
|
-
toAssetId: "usdc",
|
|
166
|
-
amount: "0.1",
|
|
167
|
-
})).rejects.toThrow("Wallet provider is not a CDP Wallet Provider");
|
|
168
|
-
});
|
|
169
|
-
it("should handle swap errors", async () => {
|
|
170
|
-
const mockNetwork = { protocolFamily: "evm", networkId: "base-sepolia" };
|
|
171
|
-
mockWalletProvider.getNetwork.mockReturnValue(mockNetwork);
|
|
172
|
-
mockWalletProvider.getAddress.mockReturnValue("0x123456789");
|
|
173
|
-
mockWalletProvider.getClient.mockReturnValue(mockCdpClient);
|
|
174
|
-
const mockAccount = { swap: jest.fn() };
|
|
175
|
-
mockCdpClient.evm.getAccount.mockResolvedValue(mockAccount);
|
|
176
|
-
mockAccount.swap.mockRejectedValue(new Error("Insufficient liquidity"));
|
|
177
|
-
await expect(actionProvider.swap(mockWalletProvider, {
|
|
178
|
-
fromAssetId: "eth",
|
|
179
|
-
toAssetId: "usdc",
|
|
180
|
-
amount: "1000",
|
|
181
|
-
})).rejects.toThrow("Swap failed: Error: Insufficient liquidity");
|
|
182
|
-
});
|
|
183
|
-
});
|
|
184
90
|
describe("RequestFaucetFundsV2Schema", () => {
|
|
185
91
|
it("should validate correct input", () => {
|
|
186
92
|
const validInput = { assetId: "eth" };
|
|
@@ -193,35 +99,4 @@ describe("CDP API Action Provider", () => {
|
|
|
193
99
|
expect(result.success).toBe(true);
|
|
194
100
|
});
|
|
195
101
|
});
|
|
196
|
-
describe("SwapSchema", () => {
|
|
197
|
-
it("should validate correct swap input", () => {
|
|
198
|
-
const validInput = {
|
|
199
|
-
fromAssetId: "eth",
|
|
200
|
-
toAssetId: "usdc",
|
|
201
|
-
amount: "0.1",
|
|
202
|
-
};
|
|
203
|
-
const result = schemas_1.SwapSchema.safeParse(validInput);
|
|
204
|
-
expect(result.success).toBe(true);
|
|
205
|
-
expect(result.data).toEqual(validInput);
|
|
206
|
-
});
|
|
207
|
-
it("should validate swap input with network", () => {
|
|
208
|
-
const validInput = {
|
|
209
|
-
fromAssetId: "usdc",
|
|
210
|
-
toAssetId: "eth",
|
|
211
|
-
amount: "100",
|
|
212
|
-
network: "base-sepolia",
|
|
213
|
-
};
|
|
214
|
-
const result = schemas_1.SwapSchema.safeParse(validInput);
|
|
215
|
-
expect(result.success).toBe(true);
|
|
216
|
-
expect(result.data).toEqual(validInput);
|
|
217
|
-
});
|
|
218
|
-
it("should fail validation when missing required fields", () => {
|
|
219
|
-
const invalidInput = {
|
|
220
|
-
fromAssetId: "eth",
|
|
221
|
-
// missing toAssetId and amount
|
|
222
|
-
};
|
|
223
|
-
const result = schemas_1.SwapSchema.safeParse(invalidInput);
|
|
224
|
-
expect(result.success).toBe(false);
|
|
225
|
-
});
|
|
226
|
-
});
|
|
227
102
|
});
|
|
@@ -2,7 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { WalletProvider } from "../../wallet-providers";
|
|
3
3
|
import { CdpEvmWalletProvider } from "../../wallet-providers/cdpEvmWalletProvider";
|
|
4
4
|
import { ActionProvider } from "../actionProvider";
|
|
5
|
-
import { UseSpendPermissionSchema, ListSpendPermissionsSchema } from "./schemas";
|
|
5
|
+
import { UseSpendPermissionSchema, ListSpendPermissionsSchema, SwapSchema } from "./schemas";
|
|
6
6
|
import type { Network } from "../../network";
|
|
7
7
|
/**
|
|
8
8
|
* CdpEvmWalletActionProvider is an action provider for CDP EVM Wallet specific actions.
|
|
@@ -32,6 +32,22 @@ export declare class CdpEvmWalletActionProvider extends ActionProvider<CdpEvmWal
|
|
|
32
32
|
* @returns A confirmation message with transaction details.
|
|
33
33
|
*/
|
|
34
34
|
useSpendPermission(walletProvider: WalletProvider, args: z.infer<typeof UseSpendPermissionSchema>): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Gets a price quote for swapping tokens using the CDP Swap API.
|
|
37
|
+
*
|
|
38
|
+
* @param walletProvider - The EVM wallet provider to get the quote for.
|
|
39
|
+
* @param args - The input arguments for the swap price action.
|
|
40
|
+
* @returns A JSON string with detailed swap price quote information.
|
|
41
|
+
*/
|
|
42
|
+
getSwapPrice(walletProvider: CdpEvmWalletProvider, args: z.infer<typeof SwapSchema>): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Swaps tokens using the CDP client.
|
|
45
|
+
*
|
|
46
|
+
* @param walletProvider - The EVM wallet provider to perform the swap with.
|
|
47
|
+
* @param args - The input arguments for the swap action.
|
|
48
|
+
* @returns A JSON string with detailed swap execution information.
|
|
49
|
+
*/
|
|
50
|
+
swap(walletProvider: CdpEvmWalletProvider, args: z.infer<typeof SwapSchema>): Promise<string>;
|
|
35
51
|
/**
|
|
36
52
|
* Checks if the EVM wallet action provider supports the given network.
|
|
37
53
|
*
|
|
@@ -19,10 +19,13 @@ exports.cdpEvmWalletActionProvider = exports.CdpEvmWalletActionProvider = void 0
|
|
|
19
19
|
const zod_1 = require("zod");
|
|
20
20
|
const wallet_providers_1 = require("../../wallet-providers");
|
|
21
21
|
const cdpShared_1 = require("../../wallet-providers/cdpShared");
|
|
22
|
+
const cdpEvmWalletProvider_1 = require("../../wallet-providers/cdpEvmWalletProvider");
|
|
22
23
|
const actionDecorator_1 = require("../actionDecorator");
|
|
23
24
|
const actionProvider_1 = require("../actionProvider");
|
|
24
25
|
const schemas_1 = require("./schemas");
|
|
25
26
|
const spendPermissionUtils_1 = require("./spendPermissionUtils");
|
|
27
|
+
const swapUtils_1 = require("./swapUtils");
|
|
28
|
+
const viem_1 = require("viem");
|
|
26
29
|
/**
|
|
27
30
|
* CdpEvmWalletActionProvider is an action provider for CDP EVM Wallet specific actions.
|
|
28
31
|
*
|
|
@@ -105,6 +108,181 @@ class CdpEvmWalletActionProvider extends actionProvider_1.ActionProvider {
|
|
|
105
108
|
return "Wallet provider is not a CDP Wallet Provider.";
|
|
106
109
|
}
|
|
107
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Gets a price quote for swapping tokens using the CDP Swap API.
|
|
113
|
+
*
|
|
114
|
+
* @param walletProvider - The EVM wallet provider to get the quote for.
|
|
115
|
+
* @param args - The input arguments for the swap price action.
|
|
116
|
+
* @returns A JSON string with detailed swap price quote information.
|
|
117
|
+
*/
|
|
118
|
+
async getSwapPrice(walletProvider, args) {
|
|
119
|
+
// Get CDP SDK network
|
|
120
|
+
const network = walletProvider.getNetwork();
|
|
121
|
+
const networkId = network.networkId;
|
|
122
|
+
const cdpNetwork = __classPrivateFieldGet(this, _CdpEvmWalletActionProvider_instances, "m", _CdpEvmWalletActionProvider_getCdpSdkNetwork).call(this, networkId);
|
|
123
|
+
// Check if the network is supported
|
|
124
|
+
if (networkId !== "base-mainnet" && networkId !== "ethereum-mainnet")
|
|
125
|
+
return JSON.stringify({
|
|
126
|
+
success: false,
|
|
127
|
+
error: "CDP Swap API is currently only supported on 'base-mainnet' or 'ethereum-mainnet'.",
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
// Get token details
|
|
131
|
+
const { fromTokenDecimals, toTokenDecimals, fromTokenName, toTokenName } = await (0, swapUtils_1.getTokenDetails)(walletProvider, args.fromToken, args.toToken);
|
|
132
|
+
// Get swap price quote
|
|
133
|
+
const swapPrice = (await walletProvider.getClient().evm.getSwapPrice({
|
|
134
|
+
fromToken: args.fromToken,
|
|
135
|
+
toToken: args.toToken,
|
|
136
|
+
fromAmount: (0, viem_1.parseUnits)(args.fromAmount, fromTokenDecimals),
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
138
|
+
network: cdpNetwork,
|
|
139
|
+
taker: walletProvider.getAddress(),
|
|
140
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
141
|
+
}));
|
|
142
|
+
const formattedResponse = {
|
|
143
|
+
success: true,
|
|
144
|
+
fromAmount: args.fromAmount,
|
|
145
|
+
fromTokenName: fromTokenName,
|
|
146
|
+
fromToken: args.fromToken,
|
|
147
|
+
toAmount: (0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals),
|
|
148
|
+
minToAmount: (0, viem_1.formatUnits)(swapPrice.minToAmount, toTokenDecimals),
|
|
149
|
+
toTokenName: toTokenName,
|
|
150
|
+
toToken: args.toToken,
|
|
151
|
+
slippageBps: args.slippageBps,
|
|
152
|
+
liquidityAvailable: swapPrice.liquidityAvailable,
|
|
153
|
+
balanceEnough: swapPrice.issues.balance === undefined,
|
|
154
|
+
priceOfBuyTokenInSellToken: (Number(args.fromAmount) / Number((0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals))).toString(),
|
|
155
|
+
priceOfSellTokenInBuyToken: (Number((0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals)) / Number(args.fromAmount)).toString(),
|
|
156
|
+
};
|
|
157
|
+
return JSON.stringify(formattedResponse);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
return JSON.stringify({
|
|
161
|
+
success: false,
|
|
162
|
+
error: `Error fetching swap price: ${error}`,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Swaps tokens using the CDP client.
|
|
168
|
+
*
|
|
169
|
+
* @param walletProvider - The EVM wallet provider to perform the swap with.
|
|
170
|
+
* @param args - The input arguments for the swap action.
|
|
171
|
+
* @returns A JSON string with detailed swap execution information.
|
|
172
|
+
*/
|
|
173
|
+
async swap(walletProvider, args) {
|
|
174
|
+
// Get CDP SDK network
|
|
175
|
+
const network = walletProvider.getNetwork();
|
|
176
|
+
const networkId = network.networkId;
|
|
177
|
+
const cdpNetwork = __classPrivateFieldGet(this, _CdpEvmWalletActionProvider_instances, "m", _CdpEvmWalletActionProvider_getCdpSdkNetwork).call(this, networkId);
|
|
178
|
+
// Check if the network is supported
|
|
179
|
+
if (networkId !== "base-mainnet" && networkId !== "ethereum-mainnet")
|
|
180
|
+
return JSON.stringify({
|
|
181
|
+
success: false,
|
|
182
|
+
error: "CDP Swap API is currently only supported on 'base-mainnet' or 'ethereum-mainnet'.",
|
|
183
|
+
});
|
|
184
|
+
try {
|
|
185
|
+
// Get token details
|
|
186
|
+
const { fromTokenDecimals, fromTokenName, toTokenName, toTokenDecimals } = await (0, swapUtils_1.getTokenDetails)(walletProvider, args.fromToken, args.toToken);
|
|
187
|
+
// Get the account
|
|
188
|
+
const account = await walletProvider.getClient().evm.getAccount({
|
|
189
|
+
address: walletProvider.getAddress(),
|
|
190
|
+
});
|
|
191
|
+
// Estimate swap price first to check liquidity, token balance and permit2 approval status
|
|
192
|
+
const swapPrice = await walletProvider.getClient().evm.getSwapPrice({
|
|
193
|
+
fromToken: args.fromToken,
|
|
194
|
+
toToken: args.toToken,
|
|
195
|
+
fromAmount: (0, viem_1.parseUnits)(args.fromAmount, fromTokenDecimals),
|
|
196
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
197
|
+
network: cdpNetwork,
|
|
198
|
+
taker: account.address,
|
|
199
|
+
});
|
|
200
|
+
// Check if liquidity is available
|
|
201
|
+
if (!swapPrice.liquidityAvailable) {
|
|
202
|
+
return JSON.stringify({
|
|
203
|
+
success: false,
|
|
204
|
+
error: `No liquidity available to swap ${args.fromAmount} ${fromTokenName} (${args.fromToken}) to ${toTokenName} (${args.toToken})`,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
// Check if balance is enough
|
|
208
|
+
if (swapPrice.issues.balance) {
|
|
209
|
+
return JSON.stringify({
|
|
210
|
+
success: false,
|
|
211
|
+
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})`,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
// Check if allowance is enough
|
|
215
|
+
let approvalTxHash = null;
|
|
216
|
+
if (swapPrice.issues.allowance) {
|
|
217
|
+
try {
|
|
218
|
+
approvalTxHash = await walletProvider.sendTransaction({
|
|
219
|
+
to: args.fromToken,
|
|
220
|
+
data: (0, viem_1.encodeFunctionData)({
|
|
221
|
+
abi: viem_1.erc20Abi,
|
|
222
|
+
functionName: "approve",
|
|
223
|
+
args: [swapUtils_1.PERMIT2_ADDRESS, viem_1.maxUint256],
|
|
224
|
+
}),
|
|
225
|
+
});
|
|
226
|
+
const receipt = await walletProvider.waitForTransactionReceipt(approvalTxHash);
|
|
227
|
+
if (receipt.status !== "success") {
|
|
228
|
+
return JSON.stringify({
|
|
229
|
+
success: false,
|
|
230
|
+
error: `Approval transaction failed`,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
return JSON.stringify({
|
|
236
|
+
success: false,
|
|
237
|
+
error: `Error approving token: ${error}`,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// Execute swap using the all-in-one pattern with retry logic
|
|
242
|
+
const swapResult = await (0, swapUtils_1.retryWithExponentialBackoff)(async () => {
|
|
243
|
+
return (await account.swap({
|
|
244
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
245
|
+
network: cdpNetwork,
|
|
246
|
+
fromToken: args.fromToken,
|
|
247
|
+
toToken: args.toToken,
|
|
248
|
+
fromAmount: (0, viem_1.parseUnits)(args.fromAmount, fromTokenDecimals),
|
|
249
|
+
slippageBps: args.slippageBps,
|
|
250
|
+
signerAddress: account.address,
|
|
251
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
252
|
+
}));
|
|
253
|
+
}, 3, 5000); // Max 3 retries with 5s base delay
|
|
254
|
+
// Check if swap was successful
|
|
255
|
+
const swapReceipt = await walletProvider.waitForTransactionReceipt(swapResult.transactionHash);
|
|
256
|
+
if (swapReceipt.status !== "success") {
|
|
257
|
+
return JSON.stringify({
|
|
258
|
+
success: false,
|
|
259
|
+
error: `Swap transaction failed`,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
// Format the successful response
|
|
263
|
+
const formattedResponse = {
|
|
264
|
+
success: true,
|
|
265
|
+
...(approvalTxHash ? { approvalTxHash } : {}),
|
|
266
|
+
transactionHash: swapResult.transactionHash,
|
|
267
|
+
fromAmount: args.fromAmount,
|
|
268
|
+
fromTokenName: fromTokenName,
|
|
269
|
+
fromToken: args.fromToken,
|
|
270
|
+
toAmount: (0, viem_1.formatUnits)(swapPrice.toAmount, toTokenDecimals),
|
|
271
|
+
minToAmount: (0, viem_1.formatUnits)(swapPrice.minToAmount, toTokenDecimals),
|
|
272
|
+
toTokenName: toTokenName,
|
|
273
|
+
toToken: args.toToken,
|
|
274
|
+
slippageBps: args.slippageBps,
|
|
275
|
+
network: networkId,
|
|
276
|
+
};
|
|
277
|
+
return JSON.stringify(formattedResponse);
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
return JSON.stringify({
|
|
281
|
+
success: false,
|
|
282
|
+
error: `Swap failed: ${error}`,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
108
286
|
}
|
|
109
287
|
exports.CdpEvmWalletActionProvider = CdpEvmWalletActionProvider;
|
|
110
288
|
_CdpEvmWalletActionProvider_instances = new WeakSet(), _CdpEvmWalletActionProvider_getCdpSdkNetwork = function _CdpEvmWalletActionProvider_getCdpSdkNetwork(networkId) {
|
|
@@ -147,5 +325,46 @@ This action is specifically designed for EVM wallets and uses the EVM wallet for
|
|
|
147
325
|
__metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
|
|
148
326
|
__metadata("design:returntype", Promise)
|
|
149
327
|
], CdpEvmWalletActionProvider.prototype, "useSpendPermission", null);
|
|
328
|
+
__decorate([
|
|
329
|
+
(0, actionDecorator_1.CreateAction)({
|
|
330
|
+
name: "get_swap_price",
|
|
331
|
+
description: `
|
|
332
|
+
This tool fetches a price quote for swapping (trading) between two tokens using the CDP Swap API but does not execute a swap.
|
|
333
|
+
It takes the following inputs:
|
|
334
|
+
- fromToken: The contract address of the token to sell
|
|
335
|
+
- toToken: The contract address of the token to buy
|
|
336
|
+
- fromAmount: The amount of fromToken to swap in whole units (e.g. 1 ETH or 10.5 USDC)
|
|
337
|
+
- slippageBps: (Optional) Maximum allowed slippage in basis points (100 = 1%)
|
|
338
|
+
Important notes:
|
|
339
|
+
- The contract address for native ETH is "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
|
340
|
+
- Use fromAmount units exactly as provided, do not convert to wei or any other units.
|
|
341
|
+
`,
|
|
342
|
+
schema: schemas_1.SwapSchema,
|
|
343
|
+
}),
|
|
344
|
+
__metadata("design:type", Function),
|
|
345
|
+
__metadata("design:paramtypes", [cdpEvmWalletProvider_1.CdpEvmWalletProvider, void 0]),
|
|
346
|
+
__metadata("design:returntype", Promise)
|
|
347
|
+
], CdpEvmWalletActionProvider.prototype, "getSwapPrice", null);
|
|
348
|
+
__decorate([
|
|
349
|
+
(0, actionDecorator_1.CreateAction)({
|
|
350
|
+
name: "swap",
|
|
351
|
+
description: `
|
|
352
|
+
This tool executes a token swap (trade) using the CDP Swap API.
|
|
353
|
+
It takes the following inputs:
|
|
354
|
+
- fromToken: The contract address of the token to sell
|
|
355
|
+
- toToken: The contract address of the token to buy
|
|
356
|
+
- fromAmount: The amount of fromToken to swap in whole units (e.g. 1 ETH or 10.5 USDC)
|
|
357
|
+
- slippageBps: (Optional) Maximum allowed slippage in basis points (100 = 1%)
|
|
358
|
+
Important notes:
|
|
359
|
+
- The contract address for native ETH is "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
|
|
360
|
+
- If needed, it will automatically approve the permit2 contract to spend the fromToken
|
|
361
|
+
- Use fromAmount units exactly as provided, do not convert to wei or any other units.
|
|
362
|
+
`,
|
|
363
|
+
schema: schemas_1.SwapSchema,
|
|
364
|
+
}),
|
|
365
|
+
__metadata("design:type", Function),
|
|
366
|
+
__metadata("design:paramtypes", [cdpEvmWalletProvider_1.CdpEvmWalletProvider, void 0]),
|
|
367
|
+
__metadata("design:returntype", Promise)
|
|
368
|
+
], CdpEvmWalletActionProvider.prototype, "swap", null);
|
|
150
369
|
const cdpEvmWalletActionProvider = () => new CdpEvmWalletActionProvider();
|
|
151
370
|
exports.cdpEvmWalletActionProvider = cdpEvmWalletActionProvider;
|