@coinbase/agentkit 0.2.3 → 0.4.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 (46) hide show
  1. package/README.md +30 -0
  2. package/dist/action-providers/allora/alloraActionProvider.d.ts +44 -0
  3. package/dist/action-providers/allora/alloraActionProvider.js +195 -0
  4. package/dist/action-providers/allora/alloraActionProvider.test.d.ts +1 -0
  5. package/dist/action-providers/allora/alloraActionProvider.test.js +109 -0
  6. package/dist/action-providers/allora/index.d.ts +2 -0
  7. package/dist/action-providers/allora/index.js +18 -0
  8. package/dist/action-providers/allora/schemas.d.ts +28 -0
  9. package/dist/action-providers/allora/schemas.js +30 -0
  10. package/dist/action-providers/defillama/constants.d.ts +8 -0
  11. package/dist/action-providers/defillama/constants.js +11 -0
  12. package/dist/action-providers/defillama/defillamaActionProvider.d.ts +54 -0
  13. package/dist/action-providers/defillama/defillamaActionProvider.js +180 -0
  14. package/dist/action-providers/defillama/defillamaActionProvider.test.d.ts +1 -0
  15. package/dist/action-providers/defillama/defillamaActionProvider.test.js +114 -0
  16. package/dist/action-providers/defillama/index.d.ts +1 -0
  17. package/dist/action-providers/defillama/index.js +17 -0
  18. package/dist/action-providers/defillama/schemas.d.ts +34 -0
  19. package/dist/action-providers/defillama/schemas.js +34 -0
  20. package/dist/action-providers/defillama/types.d.ts +73 -0
  21. package/dist/action-providers/defillama/types.js +2 -0
  22. package/dist/action-providers/defillama/utils.d.ts +10 -0
  23. package/dist/action-providers/defillama/utils.js +87 -0
  24. package/dist/action-providers/defillama/utils.test.d.ts +1 -0
  25. package/dist/action-providers/defillama/utils.test.js +124 -0
  26. package/dist/action-providers/erc721/constants.d.ts +0 -4
  27. package/dist/action-providers/erc721/constants.js +1 -4
  28. package/dist/action-providers/erc721/erc721ActionProvider.js +1 -1
  29. package/dist/action-providers/erc721/erc721ActionProvider.test.js +1 -1
  30. package/dist/action-providers/index.d.ts +3 -0
  31. package/dist/action-providers/index.js +3 -0
  32. package/dist/action-providers/morpho/morphoActionProvider.js +11 -4
  33. package/dist/action-providers/morpho/morphoActionProvider.test.js +2 -0
  34. package/dist/action-providers/opensea/index.d.ts +1 -0
  35. package/dist/action-providers/opensea/index.js +17 -0
  36. package/dist/action-providers/opensea/openseaActionProvider.d.ts +59 -0
  37. package/dist/action-providers/opensea/openseaActionProvider.js +146 -0
  38. package/dist/action-providers/opensea/openseaActionProvider.test.d.ts +1 -0
  39. package/dist/action-providers/opensea/openseaActionProvider.test.js +201 -0
  40. package/dist/action-providers/opensea/schemas.d.ts +30 -0
  41. package/dist/action-providers/opensea/schemas.js +33 -0
  42. package/dist/action-providers/opensea/utils.d.ts +12 -0
  43. package/dist/action-providers/opensea/utils.js +47 -0
  44. package/dist/wallet-providers/cdpWalletProvider.d.ts +6 -0
  45. package/dist/wallet-providers/cdpWalletProvider.js +11 -0
  46. package/package.json +13 -2
@@ -0,0 +1,201 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const opensea_js_1 = require("opensea-js");
4
+ const openseaActionProvider_1 = require("./openseaActionProvider");
5
+ jest.mock("opensea-js");
6
+ describe("OpenSea Action Provider", () => {
7
+ const MOCK_API_KEY = "test-api-key";
8
+ const MOCK_PRIVATE_KEY = "1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
9
+ const MOCK_CONTRACT = "0x1234567890123456789012345678901234567890";
10
+ const MOCK_TOKEN_ID = "1";
11
+ const MOCK_PRICE = 0.1;
12
+ const MOCK_EXPIRATION_DAYS = 90;
13
+ const MOCK_OPENSEA_BASE_URL = "https://testnets.opensea.io";
14
+ const MOCK_OPENSEA_CHAIN = "base_sepolia";
15
+ let actionProvider;
16
+ beforeEach(() => {
17
+ jest.clearAllMocks();
18
+ // Mock OpenSeaSDK constructor
19
+ opensea_js_1.OpenSeaSDK.mockImplementation(() => ({
20
+ createListing: jest.fn(),
21
+ api: {
22
+ apiBaseUrl: MOCK_OPENSEA_BASE_URL,
23
+ getNFTsByAccount: jest.fn(),
24
+ },
25
+ chain: MOCK_OPENSEA_CHAIN,
26
+ }));
27
+ actionProvider = (0, openseaActionProvider_1.openseaActionProvider)({
28
+ apiKey: MOCK_API_KEY,
29
+ privateKey: MOCK_PRIVATE_KEY,
30
+ networkId: "base-sepolia",
31
+ });
32
+ });
33
+ describe("listNft", () => {
34
+ it("should successfully list an NFT", async () => {
35
+ const mockListing = {};
36
+ const mockCreateListing = jest.fn().mockResolvedValue(mockListing);
37
+ // Update the mock implementation with the mock function
38
+ opensea_js_1.OpenSeaSDK.mockImplementation(() => ({
39
+ createListing: mockCreateListing,
40
+ api: {
41
+ apiBaseUrl: MOCK_OPENSEA_BASE_URL,
42
+ },
43
+ chain: MOCK_OPENSEA_CHAIN,
44
+ }));
45
+ // Re-create provider with new mock
46
+ actionProvider = (0, openseaActionProvider_1.openseaActionProvider)({
47
+ apiKey: MOCK_API_KEY,
48
+ privateKey: MOCK_PRIVATE_KEY,
49
+ networkId: "base-sepolia",
50
+ });
51
+ const args = {
52
+ contractAddress: MOCK_CONTRACT,
53
+ tokenId: MOCK_TOKEN_ID,
54
+ price: MOCK_PRICE,
55
+ expirationDays: MOCK_EXPIRATION_DAYS,
56
+ };
57
+ const response = await actionProvider.listNft(args);
58
+ expect(mockCreateListing).toHaveBeenCalledWith(expect.objectContaining({
59
+ asset: {
60
+ tokenId: MOCK_TOKEN_ID,
61
+ tokenAddress: MOCK_CONTRACT,
62
+ },
63
+ startAmount: MOCK_PRICE,
64
+ quantity: 1,
65
+ }));
66
+ expect(response).toBe(`Successfully listed NFT ${MOCK_CONTRACT} token ${MOCK_TOKEN_ID} for ${MOCK_PRICE} ETH, expiring in ${MOCK_EXPIRATION_DAYS} days. Listing on OpenSea: ${MOCK_OPENSEA_BASE_URL}/assets/${MOCK_OPENSEA_CHAIN}/${MOCK_CONTRACT}/${MOCK_TOKEN_ID}.`);
67
+ });
68
+ it("should handle listing errors", async () => {
69
+ const error = new Error("Listing failed");
70
+ const mockCreateListing = jest.fn().mockRejectedValue(error);
71
+ // Update the mock implementation with the mock function
72
+ opensea_js_1.OpenSeaSDK.mockImplementation(() => ({
73
+ createListing: mockCreateListing,
74
+ api: {
75
+ apiBaseUrl: MOCK_OPENSEA_BASE_URL,
76
+ },
77
+ chain: MOCK_OPENSEA_CHAIN,
78
+ }));
79
+ // Re-create provider with new mock
80
+ actionProvider = (0, openseaActionProvider_1.openseaActionProvider)({
81
+ apiKey: MOCK_API_KEY,
82
+ privateKey: MOCK_PRIVATE_KEY,
83
+ networkId: "base-sepolia",
84
+ });
85
+ const args = {
86
+ contractAddress: MOCK_CONTRACT,
87
+ tokenId: MOCK_TOKEN_ID,
88
+ price: MOCK_PRICE,
89
+ expirationDays: MOCK_EXPIRATION_DAYS,
90
+ };
91
+ const response = await actionProvider.listNft(args);
92
+ expect(response).toContain(`Error listing NFT ${MOCK_CONTRACT} token ${MOCK_TOKEN_ID}`);
93
+ expect(response).toContain(error.message);
94
+ });
95
+ });
96
+ describe("getNftsByAccount", () => {
97
+ const MOCK_WALLET_ADDRESS = "0xabcdef1234567890abcdef1234567890abcdef12";
98
+ const MOCK_NFTS = [
99
+ {
100
+ identifier: "1",
101
+ contract: MOCK_CONTRACT,
102
+ name: "Test NFT 1",
103
+ },
104
+ {
105
+ identifier: "2",
106
+ contract: MOCK_CONTRACT,
107
+ name: "Test NFT 2",
108
+ },
109
+ ];
110
+ it("should successfully fetch NFTs for the specified account", async () => {
111
+ const mockGetNFTsByAccount = jest.fn().mockResolvedValue({ nfts: MOCK_NFTS });
112
+ // Update the mock implementation with the mock function
113
+ opensea_js_1.OpenSeaSDK.mockImplementation(() => ({
114
+ createListing: jest.fn(),
115
+ api: {
116
+ apiBaseUrl: MOCK_OPENSEA_BASE_URL,
117
+ getNFTsByAccount: mockGetNFTsByAccount,
118
+ },
119
+ chain: MOCK_OPENSEA_CHAIN,
120
+ }));
121
+ // Re-create provider with new mock
122
+ actionProvider = (0, openseaActionProvider_1.openseaActionProvider)({
123
+ apiKey: MOCK_API_KEY,
124
+ privateKey: MOCK_PRIVATE_KEY,
125
+ networkId: "base-sepolia",
126
+ });
127
+ const args = {
128
+ accountAddress: MOCK_WALLET_ADDRESS,
129
+ };
130
+ const response = await actionProvider.getNftsByAccount(args);
131
+ expect(mockGetNFTsByAccount).toHaveBeenCalledWith(MOCK_WALLET_ADDRESS);
132
+ expect(response).toBe(JSON.stringify(MOCK_NFTS));
133
+ });
134
+ it("should use connected wallet address when no account is specified", async () => {
135
+ const mockGetNFTsByAccount = jest.fn().mockResolvedValue({ nfts: MOCK_NFTS });
136
+ // Update the mock implementation with the mock function
137
+ opensea_js_1.OpenSeaSDK.mockImplementation(() => ({
138
+ createListing: jest.fn(),
139
+ api: {
140
+ apiBaseUrl: MOCK_OPENSEA_BASE_URL,
141
+ getNFTsByAccount: mockGetNFTsByAccount,
142
+ },
143
+ chain: MOCK_OPENSEA_CHAIN,
144
+ }));
145
+ // Re-create provider with new mock
146
+ actionProvider = (0, openseaActionProvider_1.openseaActionProvider)({
147
+ apiKey: MOCK_API_KEY,
148
+ privateKey: MOCK_PRIVATE_KEY,
149
+ networkId: "base-sepolia",
150
+ });
151
+ const args = {}; // No accountAddress provided
152
+ const response = await actionProvider.getNftsByAccount(args);
153
+ // Should use the wallet address from the provider
154
+ expect(mockGetNFTsByAccount).toHaveBeenCalled();
155
+ expect(response).toBe(JSON.stringify(MOCK_NFTS));
156
+ });
157
+ it("should handle errors when fetching NFTs", async () => {
158
+ const error = new Error("Failed to fetch NFTs");
159
+ const mockGetNFTsByAccount = jest.fn().mockRejectedValue(error);
160
+ // Update the mock implementation with the mock function
161
+ opensea_js_1.OpenSeaSDK.mockImplementation(() => ({
162
+ createListing: jest.fn(),
163
+ api: {
164
+ apiBaseUrl: MOCK_OPENSEA_BASE_URL,
165
+ getNFTsByAccount: mockGetNFTsByAccount,
166
+ },
167
+ chain: MOCK_OPENSEA_CHAIN,
168
+ }));
169
+ // Re-create provider with new mock
170
+ actionProvider = (0, openseaActionProvider_1.openseaActionProvider)({
171
+ apiKey: MOCK_API_KEY,
172
+ privateKey: MOCK_PRIVATE_KEY,
173
+ networkId: "base-sepolia",
174
+ });
175
+ const args = {
176
+ accountAddress: MOCK_WALLET_ADDRESS,
177
+ };
178
+ const response = await actionProvider.getNftsByAccount(args);
179
+ expect(mockGetNFTsByAccount).toHaveBeenCalledWith(MOCK_WALLET_ADDRESS);
180
+ expect(response).toContain(`Error fetching NFTs for account ${MOCK_WALLET_ADDRESS}`);
181
+ expect(response).toContain(error.message);
182
+ });
183
+ });
184
+ describe("supportsNetwork", () => {
185
+ it("should return true for supported networks", () => {
186
+ const baseSepoliaNetwork = {
187
+ protocolFamily: "evm",
188
+ networkId: "base-sepolia",
189
+ chainId: "84532",
190
+ };
191
+ expect(actionProvider.supportsNetwork(baseSepoliaNetwork)).toBe(true);
192
+ });
193
+ it("should return false for unsupported networks", () => {
194
+ const fantomNetwork = {
195
+ protocolFamily: "bitcoin",
196
+ networkId: "any",
197
+ };
198
+ expect(actionProvider.supportsNetwork(fantomNetwork)).toBe(false);
199
+ });
200
+ });
201
+ });
@@ -0,0 +1,30 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Input schema for listing an NFT on OpenSea.
4
+ */
5
+ export declare const ListNftSchema: z.ZodObject<{
6
+ contractAddress: z.ZodString;
7
+ tokenId: z.ZodString;
8
+ price: z.ZodNumber;
9
+ expirationDays: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ contractAddress: string;
12
+ price: number;
13
+ tokenId: string;
14
+ expirationDays: number;
15
+ }, {
16
+ contractAddress: string;
17
+ price: number;
18
+ tokenId: string;
19
+ expirationDays?: number | undefined;
20
+ }>;
21
+ /**
22
+ * Input schema for getting NFTs from a specific wallet address.
23
+ */
24
+ export declare const GetNftsByAccountSchema: z.ZodObject<{
25
+ accountAddress: z.ZodOptional<z.ZodString>;
26
+ }, "strip", z.ZodTypeAny, {
27
+ accountAddress?: string | undefined;
28
+ }, {
29
+ accountAddress?: string | undefined;
30
+ }>;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetNftsByAccountSchema = exports.ListNftSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ /**
6
+ * Input schema for listing an NFT on OpenSea.
7
+ */
8
+ exports.ListNftSchema = zod_1.z
9
+ .object({
10
+ contractAddress: zod_1.z.string().nonempty().describe("The NFT contract address to list"),
11
+ tokenId: zod_1.z.string().nonempty().describe("The tokenID of the NFT to list"),
12
+ price: zod_1.z.number().positive().describe("The price in ETH to list the NFT for"),
13
+ expirationDays: zod_1.z
14
+ .number()
15
+ .positive()
16
+ .optional()
17
+ .default(90)
18
+ .describe("Number of days the listing should be active for (default: 90)"),
19
+ })
20
+ .strip()
21
+ .describe("Input schema for listing an NFT on OpenSea");
22
+ /**
23
+ * Input schema for getting NFTs from a specific wallet address.
24
+ */
25
+ exports.GetNftsByAccountSchema = zod_1.z
26
+ .object({
27
+ accountAddress: zod_1.z
28
+ .string()
29
+ .optional()
30
+ .describe("The wallet address to fetch NFTs for (defaults to connected wallet if not provided)"),
31
+ })
32
+ .strip()
33
+ .describe("Input schema for fetching NFTs by account");
@@ -0,0 +1,12 @@
1
+ import { Chain } from "opensea-js";
2
+ /**
3
+ * Supported Opensea chains
4
+ */
5
+ export declare const supportedChains: Record<string, Chain>;
6
+ /**
7
+ * Maps EVM chain IDs to Opensea chain
8
+ *
9
+ * @param chainId - The EVM chain ID to map
10
+ * @returns The corresponding OpenSea Chain enum value
11
+ */
12
+ export declare const chainIdToOpenseaChain: (chainId: string) => Chain;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chainIdToOpenseaChain = exports.supportedChains = void 0;
4
+ const opensea_js_1 = require("opensea-js");
5
+ /**
6
+ * Supported Opensea chains
7
+ */
8
+ exports.supportedChains = {
9
+ "1": opensea_js_1.Chain.Mainnet,
10
+ "137": opensea_js_1.Chain.Polygon,
11
+ "80002": opensea_js_1.Chain.Amoy,
12
+ "11155111": opensea_js_1.Chain.Sepolia,
13
+ "8217": opensea_js_1.Chain.Klaytn,
14
+ "1001": opensea_js_1.Chain.Baobab,
15
+ "43114": opensea_js_1.Chain.Avalanche,
16
+ "43113": opensea_js_1.Chain.Fuji,
17
+ "42161": opensea_js_1.Chain.Arbitrum,
18
+ "42170": opensea_js_1.Chain.ArbitrumNova,
19
+ "421614": opensea_js_1.Chain.ArbitrumSepolia,
20
+ "238": opensea_js_1.Chain.Blast,
21
+ "168587773": opensea_js_1.Chain.BlastSepolia,
22
+ "8453": opensea_js_1.Chain.Base,
23
+ "84532": opensea_js_1.Chain.BaseSepolia,
24
+ "10": opensea_js_1.Chain.Optimism,
25
+ "11155420": opensea_js_1.Chain.OptimismSepolia,
26
+ "7777777": opensea_js_1.Chain.Zora,
27
+ "999999999": opensea_js_1.Chain.ZoraSepolia,
28
+ "1329": opensea_js_1.Chain.Sei,
29
+ "1328": opensea_js_1.Chain.SeiTestnet,
30
+ "8333": opensea_js_1.Chain.B3,
31
+ "1993": opensea_js_1.Chain.B3Sepolia,
32
+ "80094": opensea_js_1.Chain.BeraChain,
33
+ };
34
+ /**
35
+ * Maps EVM chain IDs to Opensea chain
36
+ *
37
+ * @param chainId - The EVM chain ID to map
38
+ * @returns The corresponding OpenSea Chain enum value
39
+ */
40
+ const chainIdToOpenseaChain = (chainId) => {
41
+ const chain = exports.supportedChains[chainId];
42
+ if (!chain) {
43
+ throw new Error(`Unsupported chain ID on Opensea: ${chainId}`);
44
+ }
45
+ return chain;
46
+ };
47
+ exports.chainIdToOpenseaChain = chainIdToOpenseaChain;
@@ -227,5 +227,11 @@ export declare class CdpWalletProvider extends EvmWalletProvider {
227
227
  * @returns The wallet's data.
228
228
  */
229
229
  exportWallet(): Promise<WalletData>;
230
+ /**
231
+ * Gets the wallet.
232
+ *
233
+ * @returns The wallet.
234
+ */
235
+ getWallet(): Wallet;
230
236
  }
231
237
  export {};
@@ -381,6 +381,17 @@ class CdpWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
381
381
  }
382
382
  return __classPrivateFieldGet(this, _CdpWalletProvider_cdpWallet, "f").export();
383
383
  }
384
+ /**
385
+ * Gets the wallet.
386
+ *
387
+ * @returns The wallet.
388
+ */
389
+ getWallet() {
390
+ if (!__classPrivateFieldGet(this, _CdpWalletProvider_cdpWallet, "f")) {
391
+ throw new Error("Wallet not initialized");
392
+ }
393
+ return __classPrivateFieldGet(this, _CdpWalletProvider_cdpWallet, "f");
394
+ }
384
395
  }
385
396
  exports.CdpWalletProvider = CdpWalletProvider;
386
397
  _CdpWalletProvider_cdpWallet = new WeakMap(), _CdpWalletProvider_address = new WeakMap(), _CdpWalletProvider_network = new WeakMap(), _CdpWalletProvider_publicClient = new WeakMap(), _CdpWalletProvider_gasLimitMultiplier = new WeakMap(), _CdpWalletProvider_feePerGasMultiplier = new WeakMap();
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@coinbase/agentkit",
3
3
  "description": "Coinbase AgentKit core primitives",
4
4
  "repository": "https://github.com/coinbase/agentkit",
5
- "version": "0.2.3",
5
+ "version": "0.4.0",
6
6
  "author": "Coinbase Inc.",
7
7
  "license": "Apache-2.0",
8
8
  "main": "dist/index.js",
@@ -25,7 +25,8 @@
25
25
  "prepack": "tsc",
26
26
  "docs": "typedoc --entryPoints ./src --entryPointStrategy expand --exclude ./src/tests/**/*.ts",
27
27
  "docs:serve": "http-server ./docs",
28
- "dev": "tsc --watch"
28
+ "dev": "tsc --watch",
29
+ "generate:action-provider": "tsx ./scripts/generate-action-provider/main.ts"
29
30
  },
30
31
  "keywords": [
31
32
  "coinbase",
@@ -39,12 +40,14 @@
39
40
  "typescript"
40
41
  ],
41
42
  "dependencies": {
43
+ "@alloralabs/allora-sdk": "^0.1.0",
42
44
  "@coinbase/coinbase-sdk": "^0.20.0",
43
45
  "@jup-ag/api": "^6.0.39",
44
46
  "@privy-io/server-auth": "^1.18.4",
45
47
  "@solana/spl-token": "^0.4.12",
46
48
  "@solana/web3.js": "^1.98.0",
47
49
  "md5": "^2.3.0",
50
+ "opensea-js": "^7.1.18",
48
51
  "reflect-metadata": "^0.2.2",
49
52
  "twitter-api-v2": "^1.18.2",
50
53
  "viem": "^2.22.16",
@@ -52,12 +55,20 @@
52
55
  },
53
56
  "devDependencies": {
54
57
  "@types/jest": "^29.5.14",
58
+ "@types/nunjucks": "^3.2.6",
59
+ "@types/ora": "^3.2.0",
60
+ "@types/prompts": "^2.4.9",
55
61
  "@types/secp256k1": "^4.0.6",
56
62
  "http-server": "^14.1.1",
57
63
  "jest": "^29.7.0",
58
64
  "mock-fs": "^5.2.0",
65
+ "nunjucks": "^3.2.4",
66
+ "ora": "^7.0.1",
67
+ "picocolors": "^1.0.0",
68
+ "prompts": "^2.4.2",
59
69
  "ts-jest": "^29.2.5",
60
70
  "tsd": "^0.31.2",
71
+ "tsx": "^4.7.1",
61
72
  "typescript": "^5.7.2"
62
73
  },
63
74
  "exports": {