@coinbase/agentkit 0.4.0 → 0.5.0

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 (65) hide show
  1. package/README.md +73 -7
  2. package/dist/action-providers/across/acrossActionProvider.d.ts +50 -0
  3. package/dist/action-providers/across/acrossActionProvider.js +333 -0
  4. package/dist/action-providers/across/acrossActionProvider.test.d.ts +1 -0
  5. package/dist/action-providers/across/acrossActionProvider.test.js +391 -0
  6. package/dist/action-providers/across/constants.d.ts +1 -0
  7. package/dist/action-providers/across/constants.js +2 -0
  8. package/dist/action-providers/across/index.d.ts +1 -0
  9. package/dist/action-providers/across/index.js +17 -0
  10. package/dist/action-providers/across/schemas.d.ts +36 -0
  11. package/dist/action-providers/across/schemas.js +46 -0
  12. package/dist/action-providers/across/utils.d.ts +7 -0
  13. package/dist/action-providers/across/utils.js +25 -0
  14. package/dist/action-providers/erc20/constants.d.ts +2 -0
  15. package/dist/action-providers/erc20/constants.js +12 -1
  16. package/dist/action-providers/erc20/erc20ActionProvider.js +18 -0
  17. package/dist/action-providers/erc20/erc20ActionProvider.test.js +4 -0
  18. package/dist/action-providers/index.d.ts +2 -0
  19. package/dist/action-providers/index.js +2 -0
  20. package/dist/action-providers/messari/constants.d.ts +17 -0
  21. package/dist/action-providers/messari/constants.js +20 -0
  22. package/dist/action-providers/messari/index.d.ts +5 -0
  23. package/dist/action-providers/messari/index.js +21 -0
  24. package/dist/action-providers/messari/messariActionProvider.d.ts +42 -0
  25. package/dist/action-providers/messari/messariActionProvider.js +128 -0
  26. package/dist/action-providers/messari/messariActionProvider.test.d.ts +1 -0
  27. package/dist/action-providers/messari/messariActionProvider.test.js +152 -0
  28. package/dist/action-providers/messari/schemas.d.ts +11 -0
  29. package/dist/action-providers/messari/schemas.js +16 -0
  30. package/dist/action-providers/messari/types.d.ts +40 -0
  31. package/dist/action-providers/messari/types.js +2 -0
  32. package/dist/action-providers/messari/utils.d.ts +22 -0
  33. package/dist/action-providers/messari/utils.js +65 -0
  34. package/dist/wallet-providers/cdpWalletProvider.d.ts +11 -2
  35. package/dist/wallet-providers/cdpWalletProvider.js +24 -0
  36. package/dist/wallet-providers/cdpWalletProvider.test.d.ts +1 -0
  37. package/dist/wallet-providers/cdpWalletProvider.test.js +701 -0
  38. package/dist/wallet-providers/evmWalletProvider.test.d.ts +1 -0
  39. package/dist/wallet-providers/evmWalletProvider.test.js +56 -0
  40. package/dist/wallet-providers/index.d.ts +1 -0
  41. package/dist/wallet-providers/index.js +1 -0
  42. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.d.ts +167 -0
  43. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.js +438 -0
  44. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.test.d.ts +1 -0
  45. package/dist/wallet-providers/privyEvmDelegatedEmbeddedWalletProvider.test.js +280 -0
  46. package/dist/wallet-providers/privyEvmWalletProvider.test.d.ts +1 -0
  47. package/dist/wallet-providers/privyEvmWalletProvider.test.js +331 -0
  48. package/dist/wallet-providers/privyShared.d.ts +9 -0
  49. package/dist/wallet-providers/privyShared.js +16 -5
  50. package/dist/wallet-providers/privySvmWalletProvider.test.d.ts +1 -0
  51. package/dist/wallet-providers/privySvmWalletProvider.test.js +310 -0
  52. package/dist/wallet-providers/privyWalletProvider.d.ts +21 -8
  53. package/dist/wallet-providers/privyWalletProvider.js +39 -7
  54. package/dist/wallet-providers/privyWalletProvider.test.d.ts +1 -0
  55. package/dist/wallet-providers/privyWalletProvider.test.js +124 -0
  56. package/dist/wallet-providers/smartWalletProvider.test.d.ts +1 -0
  57. package/dist/wallet-providers/smartWalletProvider.test.js +388 -0
  58. package/dist/wallet-providers/solanaKeypairWalletProvider.test.js +210 -16
  59. package/dist/wallet-providers/svmWalletProvider.test.d.ts +1 -0
  60. package/dist/wallet-providers/svmWalletProvider.test.js +55 -0
  61. package/dist/wallet-providers/viemWalletProvider.test.d.ts +1 -0
  62. package/dist/wallet-providers/viemWalletProvider.test.js +338 -0
  63. package/dist/wallet-providers/walletProvider.test.d.ts +1 -0
  64. package/dist/wallet-providers/walletProvider.test.js +103 -0
  65. package/package.json +24 -20
@@ -0,0 +1,391 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const acrossActionProvider_1 = require("./acrossActionProvider");
4
+ const viem_1 = require("viem");
5
+ // Mock the necessary imports and modules
6
+ jest.mock("viem", () => {
7
+ return {
8
+ ...jest.requireActual("viem"),
9
+ createPublicClient: jest.fn(),
10
+ createWalletClient: jest.fn(() => ({
11
+ writeContract: jest.fn().mockResolvedValue("0xdepositTxHash"),
12
+ })),
13
+ http: jest.fn(),
14
+ formatUnits: jest.fn().mockImplementation((value, decimals) => {
15
+ // Simple mock implementation just for testing
16
+ if (typeof value === "bigint") {
17
+ if (decimals === 18) {
18
+ return (Number(value) / 10 ** 18).toString();
19
+ }
20
+ return value.toString();
21
+ }
22
+ return value.toString();
23
+ }),
24
+ parseUnits: jest.fn().mockImplementation((value, decimals) => {
25
+ if (decimals === 18) {
26
+ return BigInt(Number(value) * 10 ** 18);
27
+ }
28
+ return BigInt(value);
29
+ }),
30
+ };
31
+ });
32
+ jest.mock("viem/accounts", () => ({
33
+ privateKeyToAccount: jest.fn().mockReturnValue({
34
+ address: "0x9876543210987654321098765432109876543210",
35
+ }),
36
+ }));
37
+ // Mock the network module
38
+ jest.mock("../../network", () => {
39
+ return {
40
+ ...jest.requireActual("../../network"),
41
+ NETWORK_ID_TO_VIEM_CHAIN: {
42
+ "ethereum-mainnet": {
43
+ id: 1,
44
+ name: "Ethereum",
45
+ network: "mainnet",
46
+ },
47
+ optimism: {
48
+ id: 10,
49
+ name: "Optimism",
50
+ network: "optimism",
51
+ },
52
+ "base-sepolia": {
53
+ id: 84532,
54
+ name: "Base Sepolia",
55
+ network: "base-sepolia",
56
+ },
57
+ },
58
+ CHAIN_ID_TO_NETWORK_ID: {
59
+ "1": "ethereum-mainnet",
60
+ "10": "optimism",
61
+ "84532": "base-sepolia",
62
+ },
63
+ };
64
+ });
65
+ // Mock the Across SDK
66
+ const mockCreateAcrossClient = jest.fn();
67
+ jest.mock("@across-protocol/app-sdk", () => ({
68
+ createAcrossClient: mockCreateAcrossClient,
69
+ }));
70
+ // Default implementation for the createAcrossClient mock
71
+ const defaultClientImplementation = () => ({
72
+ getSupportedChains: jest.fn().mockResolvedValue([
73
+ {
74
+ chainId: 1, // Ethereum
75
+ name: "Ethereum",
76
+ network: "mainnet",
77
+ inputTokens: [
78
+ {
79
+ symbol: "ETH",
80
+ address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
81
+ decimals: 18,
82
+ },
83
+ {
84
+ symbol: "USDC",
85
+ address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
86
+ decimals: 6,
87
+ },
88
+ ],
89
+ },
90
+ {
91
+ chainId: 10, // Optimism
92
+ name: "Optimism",
93
+ network: "optimism",
94
+ inputTokens: [
95
+ {
96
+ symbol: "ETH",
97
+ address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
98
+ decimals: 18,
99
+ },
100
+ ],
101
+ },
102
+ ]),
103
+ getAvailableRoutes: jest.fn().mockResolvedValue([
104
+ {
105
+ isNative: true,
106
+ originToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
107
+ },
108
+ {
109
+ isNative: false,
110
+ originToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
111
+ },
112
+ ]),
113
+ getQuote: jest.fn().mockResolvedValue({
114
+ deposit: {
115
+ inputAmount: BigInt("1000000000000000000"), // 1 ETH
116
+ outputAmount: BigInt("990000000000000000"), // 0.99 ETH (1% difference)
117
+ spokePoolAddress: "0x1234567890123456789012345678901234567890",
118
+ },
119
+ limits: {
120
+ minDeposit: BigInt("100000000000000000"), // 0.1 ETH
121
+ maxDeposit: BigInt("10000000000000000000"), // 10 ETH
122
+ },
123
+ }),
124
+ simulateDepositTx: jest.fn().mockResolvedValue({
125
+ request: {
126
+ address: "0x1234567890123456789012345678901234567890",
127
+ abi: [],
128
+ functionName: "deposit",
129
+ args: [],
130
+ },
131
+ }),
132
+ waitForDepositTx: jest.fn().mockResolvedValue({
133
+ depositId: "123456",
134
+ }),
135
+ });
136
+ // Set the default implementation
137
+ mockCreateAcrossClient.mockImplementation(() => {
138
+ const client = defaultClientImplementation();
139
+ // Add the chains property to match what the code expects
140
+ return {
141
+ ...client,
142
+ chains: [
143
+ {
144
+ id: 1,
145
+ name: "Ethereum",
146
+ network: "mainnet",
147
+ },
148
+ {
149
+ id: 10,
150
+ name: "Optimism",
151
+ network: "optimism",
152
+ },
153
+ ],
154
+ };
155
+ });
156
+ // Mock the isTestnet function
157
+ jest.mock("./utils", () => ({
158
+ isAcrossSupportedTestnet: jest.fn().mockReturnValue(false),
159
+ }));
160
+ describe("Across Action Provider", () => {
161
+ const MOCK_PRIVATE_KEY = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
162
+ const MOCK_INPUT_TOKEN_SYMBOL = "ETH";
163
+ const MOCK_AMOUNT = "1.0";
164
+ const MOCK_DESTINATION_CHAIN_ID = "10"; // Optimism
165
+ const MOCK_RECIPIENT = "0x9876543210987654321098765432109876543210";
166
+ const MOCK_MAX_SLIPPAGE = 2.0;
167
+ let mockWallet;
168
+ let actionProvider;
169
+ let mockPublicClient;
170
+ beforeEach(() => {
171
+ jest.clearAllMocks();
172
+ // Reset to default implementation
173
+ mockCreateAcrossClient.mockImplementation(() => {
174
+ const client = defaultClientImplementation();
175
+ // Add the chains property to match what the code expects
176
+ return {
177
+ ...client,
178
+ chains: [
179
+ {
180
+ id: 1,
181
+ name: "Ethereum",
182
+ network: "mainnet",
183
+ },
184
+ {
185
+ id: 10,
186
+ name: "Optimism",
187
+ network: "optimism",
188
+ },
189
+ ],
190
+ };
191
+ });
192
+ mockPublicClient = {
193
+ getBalance: jest.fn().mockResolvedValue(BigInt("2000000000000000000")), // 2 ETH
194
+ readContract: jest.fn().mockResolvedValue(BigInt("2000000000000000000")), // 2 ETH or 2 USDC
195
+ waitForTransactionReceipt: jest.fn().mockResolvedValue({}),
196
+ };
197
+ viem_1.createPublicClient.mockReturnValue(mockPublicClient);
198
+ mockWallet = {
199
+ getAddress: jest.fn().mockReturnValue(MOCK_RECIPIENT),
200
+ sendTransaction: jest.fn().mockResolvedValue("0xmocktxhash"),
201
+ waitForTransactionReceipt: jest.fn(),
202
+ getNetwork: jest.fn().mockReturnValue({
203
+ chainId: "1", // Ethereum mainnet
204
+ networkId: "ethereum-mainnet",
205
+ protocolFamily: "evm",
206
+ }),
207
+ getBalance: jest.fn().mockResolvedValue(BigInt("2000000000000000000")), // 2 ETH
208
+ readContract: jest.fn().mockResolvedValue(BigInt("2000000000000000000")), // 2 ETH/USDC
209
+ };
210
+ actionProvider = (0, acrossActionProvider_1.acrossActionProvider)({
211
+ privateKey: MOCK_PRIVATE_KEY,
212
+ });
213
+ });
214
+ describe("bridgeToken", () => {
215
+ it("should successfully bridge native ETH", async () => {
216
+ const args = {
217
+ inputTokenSymbol: MOCK_INPUT_TOKEN_SYMBOL,
218
+ amount: MOCK_AMOUNT,
219
+ destinationChainId: MOCK_DESTINATION_CHAIN_ID,
220
+ recipient: MOCK_RECIPIENT,
221
+ maxSplippage: MOCK_MAX_SLIPPAGE,
222
+ };
223
+ const response = await actionProvider.bridgeToken(mockWallet, args);
224
+ // Verify the SDK interactions and response
225
+ expect(response).toContain("Successfully deposited tokens");
226
+ expect(response).toContain(`Token: ${MOCK_INPUT_TOKEN_SYMBOL}`);
227
+ expect(response).toContain("Transaction Hash for deposit: 0xdepositTxHash");
228
+ });
229
+ it("should successfully bridge ERC20 tokens", async () => {
230
+ const args = {
231
+ inputTokenSymbol: "USDC",
232
+ amount: "100",
233
+ destinationChainId: MOCK_DESTINATION_CHAIN_ID,
234
+ recipient: MOCK_RECIPIENT,
235
+ maxSplippage: MOCK_MAX_SLIPPAGE,
236
+ };
237
+ // Set up mock for approval and deposit transactions
238
+ mockWallet.sendTransaction
239
+ .mockResolvedValueOnce("0xapprovalTxHash")
240
+ .mockResolvedValueOnce("0xdepositTxHash");
241
+ const response = await actionProvider.bridgeToken(mockWallet, args);
242
+ // Verify the SDK interactions and response
243
+ expect(response).toContain("Successfully deposited tokens");
244
+ expect(response).toContain(`Token: ${args.inputTokenSymbol}`);
245
+ expect(response).toContain("Transaction Hash for approval: 0xapprovalTxHash");
246
+ expect(response).toContain("Transaction Hash for deposit: 0xdepositTxHash");
247
+ });
248
+ it("should fail when slippage is too high", async () => {
249
+ // Override the default mock with high slippage for this test only
250
+ mockCreateAcrossClient.mockImplementationOnce(() => ({
251
+ getSupportedChains: jest.fn().mockResolvedValue([
252
+ {
253
+ chainId: 1,
254
+ inputTokens: [
255
+ {
256
+ symbol: "ETH",
257
+ address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
258
+ decimals: 18,
259
+ },
260
+ ],
261
+ },
262
+ ]),
263
+ getAvailableRoutes: jest.fn().mockResolvedValue([
264
+ {
265
+ isNative: true,
266
+ originToken: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
267
+ },
268
+ ]),
269
+ getQuote: jest.fn().mockResolvedValue({
270
+ deposit: {
271
+ inputAmount: BigInt("1000000000000000000"), // 1 ETH
272
+ outputAmount: BigInt("800000000000000000"), // 0.8 ETH (20% difference)
273
+ spokePoolAddress: "0x1234567890123456789012345678901234567890",
274
+ },
275
+ limits: {
276
+ minDeposit: BigInt("100000000000000000"),
277
+ maxDeposit: BigInt("10000000000000000000"),
278
+ },
279
+ }),
280
+ simulateDepositTx: jest.fn().mockResolvedValue({
281
+ request: {
282
+ address: "0x1234567890123456789012345678901234567890",
283
+ abi: [],
284
+ functionName: "deposit",
285
+ args: [],
286
+ },
287
+ }),
288
+ waitForDepositTx: jest.fn().mockResolvedValue({
289
+ depositId: "123456",
290
+ }),
291
+ }));
292
+ // Set a low max slippage
293
+ const args = {
294
+ inputTokenSymbol: MOCK_INPUT_TOKEN_SYMBOL,
295
+ amount: MOCK_AMOUNT,
296
+ destinationChainId: MOCK_DESTINATION_CHAIN_ID,
297
+ recipient: MOCK_RECIPIENT,
298
+ maxSplippage: 0.5, // Only allow 0.5% slippage
299
+ };
300
+ const response = await actionProvider.bridgeToken(mockWallet, args);
301
+ // Verify the error response
302
+ expect(response).toContain("Error with Across SDK");
303
+ expect(response).toContain("exceeds the maximum allowed slippage of 0.5%");
304
+ });
305
+ it("should handle errors in bridging", async () => {
306
+ const error = new Error("Insufficient balance");
307
+ mockWallet.getBalance.mockRejectedValueOnce(error);
308
+ mockWallet.sendTransaction.mockRejectedValueOnce(error);
309
+ const args = {
310
+ inputTokenSymbol: MOCK_INPUT_TOKEN_SYMBOL,
311
+ amount: MOCK_AMOUNT,
312
+ destinationChainId: MOCK_DESTINATION_CHAIN_ID,
313
+ recipient: MOCK_RECIPIENT,
314
+ maxSplippage: MOCK_MAX_SLIPPAGE,
315
+ };
316
+ const response = await actionProvider.bridgeToken(mockWallet, args);
317
+ expect(response).toContain("Error with Across SDK");
318
+ expect(response).toContain(error.message);
319
+ });
320
+ });
321
+ describe("checkDepositStatus", () => {
322
+ beforeEach(() => {
323
+ global.fetch = jest.fn();
324
+ });
325
+ it("should successfully check deposit status", async () => {
326
+ // Mock successful API response
327
+ const mockApiResponse = {
328
+ status: "filled",
329
+ originChainId: 1,
330
+ destinationChainId: 10,
331
+ depositTxHash: "0xdepositTxHash",
332
+ fillTx: "0xfillTxHash",
333
+ };
334
+ global.fetch.mockResolvedValueOnce({
335
+ ok: true,
336
+ json: async () => mockApiResponse,
337
+ });
338
+ const args = {
339
+ originChainId: "1",
340
+ depositId: "123456",
341
+ };
342
+ const response = await actionProvider.checkDepositStatus(mockWallet, args);
343
+ const parsedResponse = JSON.parse(response);
344
+ expect(parsedResponse.status).toEqual("filled");
345
+ expect(parsedResponse.depositTxInfo.txHash).toEqual("0xdepositTxHash");
346
+ expect(parsedResponse.fillTxInfo.txHash).toEqual("0xfillTxHash");
347
+ });
348
+ it("should handle API errors", async () => {
349
+ // Mock API error
350
+ global.fetch.mockResolvedValueOnce({
351
+ ok: false,
352
+ status: 404,
353
+ });
354
+ const args = {
355
+ originChainId: "1",
356
+ depositId: "123456",
357
+ };
358
+ const response = await actionProvider.checkDepositStatus(mockWallet, args);
359
+ expect(response).toContain("Error checking deposit status");
360
+ expect(response).toContain("404");
361
+ });
362
+ it("should handle network errors", async () => {
363
+ // Mock network error
364
+ global.fetch.mockRejectedValueOnce(new Error("Network error"));
365
+ const args = {
366
+ originChainId: "1",
367
+ depositId: "123456",
368
+ };
369
+ const response = await actionProvider.checkDepositStatus(mockWallet, args);
370
+ expect(response).toContain("Error checking deposit status");
371
+ expect(response).toContain("Network error");
372
+ });
373
+ });
374
+ describe("supportsNetwork", () => {
375
+ it("should return true for supported networks", () => {
376
+ const evmNetwork = {
377
+ protocolFamily: "evm",
378
+ networkId: "ethereum",
379
+ chainId: "1",
380
+ };
381
+ expect(actionProvider.supportsNetwork(evmNetwork)).toBe(true);
382
+ });
383
+ it("should return false for unsupported networks", () => {
384
+ const nonEvmNetwork = {
385
+ protocolFamily: "solana",
386
+ networkId: "mainnet",
387
+ };
388
+ expect(actionProvider.supportsNetwork(nonEvmNetwork)).toBe(false);
389
+ });
390
+ });
391
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export * from "./acrossActionProvider";
@@ -0,0 +1,17 @@
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./acrossActionProvider"), exports);
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Input schema for bridge token action.
4
+ */
5
+ export declare const BridgeTokenSchema: z.ZodObject<{
6
+ destinationChainId: z.ZodString;
7
+ inputTokenSymbol: z.ZodDefault<z.ZodString>;
8
+ amount: z.ZodString;
9
+ recipient: z.ZodOptional<z.ZodString>;
10
+ maxSplippage: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ amount: string;
13
+ destinationChainId: string;
14
+ inputTokenSymbol: string;
15
+ maxSplippage: number;
16
+ recipient?: string | undefined;
17
+ }, {
18
+ amount: string;
19
+ destinationChainId: string;
20
+ inputTokenSymbol?: string | undefined;
21
+ recipient?: string | undefined;
22
+ maxSplippage?: number | undefined;
23
+ }>;
24
+ /**
25
+ * Input schema for check deposit status action.
26
+ */
27
+ export declare const CheckDepositStatusSchema: z.ZodObject<{
28
+ originChainId: z.ZodOptional<z.ZodString>;
29
+ depositId: z.ZodString;
30
+ }, "strip", z.ZodTypeAny, {
31
+ depositId: string;
32
+ originChainId?: string | undefined;
33
+ }, {
34
+ depositId: string;
35
+ originChainId?: string | undefined;
36
+ }>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CheckDepositStatusSchema = exports.BridgeTokenSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ /**
6
+ * Input schema for bridge token action.
7
+ */
8
+ exports.BridgeTokenSchema = zod_1.z
9
+ .object({
10
+ destinationChainId: zod_1.z
11
+ .string()
12
+ .describe("The chain ID of the destination chain (e.g. 11155111 for ethereum-sepolia)"),
13
+ inputTokenSymbol: zod_1.z
14
+ .string()
15
+ .describe("The symbol of the token to bridge (e.g., 'ETH', 'WETH', 'USDC')")
16
+ .default("ETH"),
17
+ amount: zod_1.z
18
+ .string()
19
+ .describe("The amount of tokens to bridge in whole units (e.g. 1.5 WETH, 10 USDC)"),
20
+ recipient: zod_1.z
21
+ .string()
22
+ .optional()
23
+ .describe("The recipient address on the destination chain (defaults to sender)"),
24
+ maxSplippage: zod_1.z
25
+ .number()
26
+ .optional()
27
+ .describe("The maximum slippage percentage (e.g. 10 for 10%)")
28
+ .default(1.5),
29
+ })
30
+ .strip()
31
+ .describe("Instructions for bridging tokens across chains using Across Protocol");
32
+ /**
33
+ * Input schema for check deposit status action.
34
+ */
35
+ exports.CheckDepositStatusSchema = zod_1.z
36
+ .object({
37
+ originChainId: zod_1.z
38
+ .string()
39
+ .optional()
40
+ .describe("The chain ID of the origin chain (defaults to the current chain)"),
41
+ depositId: zod_1.z
42
+ .string()
43
+ .describe("The ID of the deposit to check (returned by the bridge deposit transaction)"),
44
+ })
45
+ .strip()
46
+ .describe("Instructions for checking the status of a deposit on Across Protocol");
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Checks if a chain ID corresponds to a testnet network supported by Across
3
+ *
4
+ * @param chainId - The blockchain network chain ID
5
+ * @returns true if the chain ID corresponds to a testnet network supported by Across, false otherwise
6
+ */
7
+ export declare function isAcrossSupportedTestnet(chainId: number): boolean;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isAcrossSupportedTestnet = isAcrossSupportedTestnet;
4
+ /**
5
+ * Checks if a chain ID corresponds to a testnet network supported by Across
6
+ *
7
+ * @param chainId - The blockchain network chain ID
8
+ * @returns true if the chain ID corresponds to a testnet network supported by Across, false otherwise
9
+ */
10
+ function isAcrossSupportedTestnet(chainId) {
11
+ // List of testnet chain IDs
12
+ const testnetChainIds = [
13
+ 11155111, // Sepolia
14
+ 84532, // Base Sepolia
15
+ 421614, // Arbitrum Sepolia
16
+ 11155420, // Optimism Sepolia
17
+ 919, // Mode Sepolia
18
+ 80002, // Polygon Amoy
19
+ 168587773, // Blast Sepolia
20
+ 4202, // Lisk Sepolia
21
+ 37111, // Lens Sepolia
22
+ 1301, // Unichain Sepolia
23
+ ];
24
+ return testnetChainIds.includes(chainId);
25
+ }
@@ -133,3 +133,5 @@ export declare const abi: readonly [{
133
133
  readonly type: "bool";
134
134
  }];
135
135
  }];
136
+ export declare const BaseTokenToAssetId: Map<string, string>;
137
+ export declare const BaseSepoliaTokenToAssetId: Map<string, string>;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.abi = void 0;
3
+ exports.BaseSepoliaTokenToAssetId = exports.BaseTokenToAssetId = exports.abi = void 0;
4
+ const coinbase_sdk_1 = require("@coinbase/coinbase-sdk");
4
5
  exports.abi = [
5
6
  {
6
7
  type: "event",
@@ -189,3 +190,13 @@ exports.abi = [
189
190
  ],
190
191
  },
191
192
  ];
193
+ exports.BaseTokenToAssetId = new Map([
194
+ ["0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf", coinbase_sdk_1.Coinbase.assets.Cbbtc],
195
+ ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", coinbase_sdk_1.Coinbase.assets.Usdc],
196
+ ["0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42", coinbase_sdk_1.Coinbase.assets.Eurc],
197
+ ]);
198
+ exports.BaseSepoliaTokenToAssetId = new Map([
199
+ ["0xcbB7C0006F23900c38EB856149F799620fcb8A4a", coinbase_sdk_1.Coinbase.assets.Cbbtc],
200
+ ["0x036CbD53842c5426634e7929541eC2318f3dCF7e", coinbase_sdk_1.Coinbase.assets.Usdc],
201
+ ["0x808456652fdb597867f38412077A9182bf77359F", coinbase_sdk_1.Coinbase.assets.Eurc],
202
+ ]);
@@ -70,6 +70,24 @@ class ERC20ActionProvider extends actionProvider_1.ActionProvider {
70
70
  */
71
71
  async transfer(walletProvider, args) {
72
72
  try {
73
+ // Check if we can do gasless transfer
74
+ const isCdpWallet = walletProvider.getName() === "cdp_wallet_provider";
75
+ const network = walletProvider.getNetwork();
76
+ const tokenAddress = (0, viem_1.getAddress)(args.contractAddress);
77
+ const canDoGasless = isCdpWallet &&
78
+ ((network.networkId === "base-mainnet" && constants_1.BaseTokenToAssetId.has(tokenAddress)) ||
79
+ (network.networkId === "base-sepolia" && constants_1.BaseSepoliaTokenToAssetId.has(tokenAddress)));
80
+ if (canDoGasless) {
81
+ // Cast to CdpWalletProvider to access erc20Transfer
82
+ const cdpWallet = walletProvider;
83
+ const assetId = network.networkId === "base-mainnet"
84
+ ? constants_1.BaseTokenToAssetId.get(tokenAddress)
85
+ : constants_1.BaseSepoliaTokenToAssetId.get(tokenAddress);
86
+ const hash = await cdpWallet.gaslessERC20Transfer(assetId, args.destination, args.amount);
87
+ await walletProvider.waitForTransactionReceipt(hash);
88
+ return `Transferred ${args.amount} of ${args.contractAddress} to ${args.destination} using gasless transfer.\nTransaction hash: ${hash}`;
89
+ }
90
+ // Fallback to regular transfer
73
91
  const hash = await walletProvider.sendTransaction({
74
92
  to: args.contractAddress,
75
93
  data: (0, viem_1.encodeFunctionData)({
@@ -74,6 +74,10 @@ describe("Transfer Action", () => {
74
74
  mockWallet = {
75
75
  sendTransaction: jest.fn(),
76
76
  waitForTransactionReceipt: jest.fn(),
77
+ getName: jest.fn().mockReturnValue("evm_wallet_provider"),
78
+ getNetwork: jest.fn().mockReturnValue({
79
+ networkId: "base-mainnet",
80
+ }),
77
81
  };
78
82
  mockWallet.sendTransaction.mockResolvedValue(TRANSACTION_HASH);
79
83
  mockWallet.waitForTransactionReceipt.mockResolvedValue({});
@@ -1,6 +1,7 @@
1
1
  export * from "./actionDecorator";
2
2
  export * from "./actionProvider";
3
3
  export * from "./customActionProvider";
4
+ export * from "./across";
4
5
  export * from "./alchemy";
5
6
  export * from "./basename";
6
7
  export * from "./cdp";
@@ -10,6 +11,7 @@ export * from "./erc20";
10
11
  export * from "./erc721";
11
12
  export * from "./farcaster";
12
13
  export * from "./jupiter";
14
+ export * from "./messari";
13
15
  export * from "./pyth";
14
16
  export * from "./moonwell";
15
17
  export * from "./morpho";
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./actionDecorator"), exports);
18
18
  __exportStar(require("./actionProvider"), exports);
19
19
  __exportStar(require("./customActionProvider"), exports);
20
+ __exportStar(require("./across"), exports);
20
21
  __exportStar(require("./alchemy"), exports);
21
22
  __exportStar(require("./basename"), exports);
22
23
  __exportStar(require("./cdp"), exports);
@@ -26,6 +27,7 @@ __exportStar(require("./erc20"), exports);
26
27
  __exportStar(require("./erc721"), exports);
27
28
  __exportStar(require("./farcaster"), exports);
28
29
  __exportStar(require("./jupiter"), exports);
30
+ __exportStar(require("./messari"), exports);
29
31
  __exportStar(require("./pyth"), exports);
30
32
  __exportStar(require("./moonwell"), exports);
31
33
  __exportStar(require("./morpho"), exports);
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Base URL for the Messari API
3
+ */
4
+ export declare const MESSARI_BASE_URL = "https://api.messari.io/ai/v1";
5
+ /**
6
+ * Default error message when API key is missing
7
+ */
8
+ export declare const API_KEY_MISSING_ERROR = "MESSARI_API_KEY is not configured.";
9
+ /**
10
+ * Rate limits by subscription tier
11
+ */
12
+ export declare const RATE_LIMITS: {
13
+ FREE: string;
14
+ LITE: string;
15
+ PRO: string;
16
+ ENTERPRISE: string;
17
+ };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RATE_LIMITS = exports.API_KEY_MISSING_ERROR = exports.MESSARI_BASE_URL = void 0;
4
+ /**
5
+ * Base URL for the Messari API
6
+ */
7
+ exports.MESSARI_BASE_URL = "https://api.messari.io/ai/v1";
8
+ /**
9
+ * Default error message when API key is missing
10
+ */
11
+ exports.API_KEY_MISSING_ERROR = "MESSARI_API_KEY is not configured.";
12
+ /**
13
+ * Rate limits by subscription tier
14
+ */
15
+ exports.RATE_LIMITS = {
16
+ FREE: "2 requests per day",
17
+ LITE: "10 requests per day",
18
+ PRO: "20 requests per day",
19
+ ENTERPRISE: "50 requests per day",
20
+ };