@coinbase/agentkit 0.1.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 (148) hide show
  1. package/README.md +305 -0
  2. package/dist/action-providers/actionDecorator.d.ts +69 -0
  3. package/dist/action-providers/actionDecorator.js +96 -0
  4. package/dist/action-providers/actionProvider.d.ts +48 -0
  5. package/dist/action-providers/actionProvider.js +62 -0
  6. package/dist/action-providers/basename/basenameActionProvider.d.ts +30 -0
  7. package/dist/action-providers/basename/basenameActionProvider.js +109 -0
  8. package/dist/action-providers/basename/basenameActionProvider.test.d.ts +1 -0
  9. package/dist/action-providers/basename/basenameActionProvider.test.js +146 -0
  10. package/dist/action-providers/basename/constants.d.ts +52 -0
  11. package/dist/action-providers/basename/constants.js +81 -0
  12. package/dist/action-providers/basename/index.d.ts +2 -0
  13. package/dist/action-providers/basename/index.js +18 -0
  14. package/dist/action-providers/basename/schemas.d.ts +14 -0
  15. package/dist/action-providers/basename/schemas.js +14 -0
  16. package/dist/action-providers/cdp/cdpApiActionProvider.d.ts +41 -0
  17. package/dist/action-providers/cdp/cdpApiActionProvider.js +111 -0
  18. package/dist/action-providers/cdp/cdpApiActionProvider.test.d.ts +1 -0
  19. package/dist/action-providers/cdp/cdpApiActionProvider.test.js +134 -0
  20. package/dist/action-providers/cdp/cdpWalletActionProvider.d.ts +58 -0
  21. package/dist/action-providers/cdp/cdpWalletActionProvider.js +218 -0
  22. package/dist/action-providers/cdp/cdpWalletActionProvider.test.d.ts +1 -0
  23. package/dist/action-providers/cdp/cdpWalletActionProvider.test.js +259 -0
  24. package/dist/action-providers/cdp/constants.d.ts +31 -0
  25. package/dist/action-providers/cdp/constants.js +34 -0
  26. package/dist/action-providers/cdp/index.d.ts +3 -0
  27. package/dist/action-providers/cdp/index.js +19 -0
  28. package/dist/action-providers/cdp/schemas.d.ts +91 -0
  29. package/dist/action-providers/cdp/schemas.js +77 -0
  30. package/dist/action-providers/customActionProvider.d.ts +30 -0
  31. package/dist/action-providers/customActionProvider.js +66 -0
  32. package/dist/action-providers/erc20/constants.d.ts +135 -0
  33. package/dist/action-providers/erc20/constants.js +191 -0
  34. package/dist/action-providers/erc20/erc20ActionProvider.d.ts +38 -0
  35. package/dist/action-providers/erc20/erc20ActionProvider.js +118 -0
  36. package/dist/action-providers/erc20/erc20ActionProvider.test.d.ts +1 -0
  37. package/dist/action-providers/erc20/erc20ActionProvider.test.js +117 -0
  38. package/dist/action-providers/erc20/index.d.ts +1 -0
  39. package/dist/action-providers/erc20/index.js +17 -0
  40. package/dist/action-providers/erc20/schemas.d.ts +27 -0
  41. package/dist/action-providers/erc20/schemas.js +26 -0
  42. package/dist/action-providers/erc721/constants.d.ts +236 -0
  43. package/dist/action-providers/erc721/constants.js +301 -0
  44. package/dist/action-providers/erc721/erc721ActionProvider.d.ts +46 -0
  45. package/dist/action-providers/erc721/erc721ActionProvider.js +164 -0
  46. package/dist/action-providers/erc721/erc721ActionProvider.test.d.ts +1 -0
  47. package/dist/action-providers/erc721/erc721ActionProvider.test.js +137 -0
  48. package/dist/action-providers/erc721/index.d.ts +1 -0
  49. package/dist/action-providers/erc721/index.js +17 -0
  50. package/dist/action-providers/erc721/schemas.d.ts +46 -0
  51. package/dist/action-providers/erc721/schemas.js +44 -0
  52. package/dist/action-providers/farcaster/farcasterActionProvider.d.ts +57 -0
  53. package/dist/action-providers/farcaster/farcasterActionProvider.js +142 -0
  54. package/dist/action-providers/farcaster/farcasterActionProvider.test.d.ts +1 -0
  55. package/dist/action-providers/farcaster/farcasterActionProvider.test.js +143 -0
  56. package/dist/action-providers/farcaster/index.d.ts +2 -0
  57. package/dist/action-providers/farcaster/index.js +18 -0
  58. package/dist/action-providers/farcaster/schemas.d.ts +15 -0
  59. package/dist/action-providers/farcaster/schemas.js +20 -0
  60. package/dist/action-providers/index.d.ts +13 -0
  61. package/dist/action-providers/index.js +29 -0
  62. package/dist/action-providers/morpho/constants.d.ts +16 -0
  63. package/dist/action-providers/morpho/constants.js +27 -0
  64. package/dist/action-providers/morpho/index.d.ts +2 -0
  65. package/dist/action-providers/morpho/index.js +18 -0
  66. package/dist/action-providers/morpho/morphoActionProvider.d.ts +39 -0
  67. package/dist/action-providers/morpho/morphoActionProvider.js +147 -0
  68. package/dist/action-providers/morpho/morphoActionProvider.test.d.ts +1 -0
  69. package/dist/action-providers/morpho/morphoActionProvider.test.js +126 -0
  70. package/dist/action-providers/morpho/schemas.d.ts +36 -0
  71. package/dist/action-providers/morpho/schemas.js +47 -0
  72. package/dist/action-providers/pyth/index.d.ts +2 -0
  73. package/dist/action-providers/pyth/index.js +18 -0
  74. package/dist/action-providers/pyth/pythActionProvider.d.ts +33 -0
  75. package/dist/action-providers/pyth/pythActionProvider.js +121 -0
  76. package/dist/action-providers/pyth/schemas.d.ts +21 -0
  77. package/dist/action-providers/pyth/schemas.js +20 -0
  78. package/dist/action-providers/twitter/index.d.ts +2 -0
  79. package/dist/action-providers/twitter/index.js +18 -0
  80. package/dist/action-providers/twitter/schemas.d.ts +38 -0
  81. package/dist/action-providers/twitter/schemas.js +44 -0
  82. package/dist/action-providers/twitter/twitterActionProvider.d.ts +82 -0
  83. package/dist/action-providers/twitter/twitterActionProvider.js +204 -0
  84. package/dist/action-providers/twitter/twitterActionProvider.test.d.ts +1 -0
  85. package/dist/action-providers/twitter/twitterActionProvider.test.js +185 -0
  86. package/dist/action-providers/wallet/index.d.ts +1 -0
  87. package/dist/action-providers/wallet/index.js +17 -0
  88. package/dist/action-providers/wallet/schemas.d.ts +19 -0
  89. package/dist/action-providers/wallet/schemas.js +19 -0
  90. package/dist/action-providers/wallet/walletActionProvider.d.ts +44 -0
  91. package/dist/action-providers/wallet/walletActionProvider.js +127 -0
  92. package/dist/action-providers/wallet/walletActionProvider.test.d.ts +1 -0
  93. package/dist/action-providers/wallet/walletActionProvider.test.js +116 -0
  94. package/dist/action-providers/weth/constants.d.ts +19 -0
  95. package/dist/action-providers/weth/constants.js +29 -0
  96. package/dist/action-providers/weth/index.d.ts +1 -0
  97. package/dist/action-providers/weth/index.js +17 -0
  98. package/dist/action-providers/weth/schemas.d.ts +8 -0
  99. package/dist/action-providers/weth/schemas.js +10 -0
  100. package/dist/action-providers/weth/wethActionProvider.d.ts +30 -0
  101. package/dist/action-providers/weth/wethActionProvider.js +89 -0
  102. package/dist/action-providers/weth/wethActionProvider.test.d.ts +1 -0
  103. package/dist/action-providers/weth/wethActionProvider.test.js +92 -0
  104. package/dist/action-providers/wow/constants.d.ts +15 -0
  105. package/dist/action-providers/wow/constants.js +844 -0
  106. package/dist/action-providers/wow/index.d.ts +2 -0
  107. package/dist/action-providers/wow/index.js +18 -0
  108. package/dist/action-providers/wow/schemas.d.ts +43 -0
  109. package/dist/action-providers/wow/schemas.js +47 -0
  110. package/dist/action-providers/wow/uniswap/constants.d.ts +3 -0
  111. package/dist/action-providers/wow/uniswap/constants.js +100 -0
  112. package/dist/action-providers/wow/uniswap/utils.d.ts +82 -0
  113. package/dist/action-providers/wow/uniswap/utils.js +226 -0
  114. package/dist/action-providers/wow/utils.d.ts +27 -0
  115. package/dist/action-providers/wow/utils.js +63 -0
  116. package/dist/action-providers/wow/wowActionProvider.d.ts +46 -0
  117. package/dist/action-providers/wow/wowActionProvider.js +223 -0
  118. package/dist/action-providers/wow/wowActionProvider.test.d.ts +1 -0
  119. package/dist/action-providers/wow/wowActionProvider.test.js +287 -0
  120. package/dist/agentkit.d.ts +45 -0
  121. package/dist/agentkit.js +60 -0
  122. package/dist/analytics/index.d.ts +1 -0
  123. package/dist/analytics/index.js +17 -0
  124. package/dist/analytics/sendAnalyticsEvent.d.ts +31 -0
  125. package/dist/analytics/sendAnalyticsEvent.js +51 -0
  126. package/dist/index.d.ts +3 -0
  127. package/dist/index.js +22 -0
  128. package/dist/network/index.d.ts +1 -0
  129. package/dist/network/index.js +17 -0
  130. package/dist/network/network.d.ts +13 -0
  131. package/dist/network/network.js +41 -0
  132. package/dist/network/types.d.ts +17 -0
  133. package/dist/network/types.js +2 -0
  134. package/dist/utils.d.ts +11 -0
  135. package/dist/utils.js +43 -0
  136. package/dist/utils.test.d.ts +1 -0
  137. package/dist/utils.test.js +50 -0
  138. package/dist/wallet-providers/cdpWalletProvider.d.ts +218 -0
  139. package/dist/wallet-providers/cdpWalletProvider.js +362 -0
  140. package/dist/wallet-providers/evmWalletProvider.d.ts +51 -0
  141. package/dist/wallet-providers/evmWalletProvider.js +14 -0
  142. package/dist/wallet-providers/index.d.ts +4 -0
  143. package/dist/wallet-providers/index.js +20 -0
  144. package/dist/wallet-providers/viemWalletProvider.d.ts +89 -0
  145. package/dist/wallet-providers/viemWalletProvider.js +187 -0
  146. package/dist/wallet-providers/walletProvider.d.ts +48 -0
  147. package/dist/wallet-providers/walletProvider.js +41 -0
  148. package/package.json +65 -0
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cdpApiActionProvider_1 = require("./cdpApiActionProvider");
4
+ const schemas_1 = require("./schemas");
5
+ // Mock the entire module
6
+ jest.mock("@coinbase/coinbase-sdk");
7
+ // Get the mocked constructor
8
+ const { ExternalAddress } = jest.requireMock("@coinbase/coinbase-sdk");
9
+ describe("CDP API Action Provider Input Schemas", () => {
10
+ describe("Address Reputation Schema", () => {
11
+ it("should successfully parse valid input", () => {
12
+ const validInput = {
13
+ address: "0xe6b2af36b3bb8d47206a129ff11d5a2de2a63c83",
14
+ network: "base-mainnet",
15
+ };
16
+ const result = schemas_1.AddressReputationSchema.safeParse(validInput);
17
+ expect(result.success).toBe(true);
18
+ expect(result.data).toEqual(validInput);
19
+ });
20
+ it("should fail parsing invalid address", () => {
21
+ const invalidInput = {
22
+ address: "invalid-address",
23
+ network: "base-mainnet",
24
+ };
25
+ const result = schemas_1.AddressReputationSchema.safeParse(invalidInput);
26
+ expect(result.success).toBe(false);
27
+ });
28
+ });
29
+ describe("Request Faucet Funds Schema", () => {
30
+ it("should successfully parse with optional assetId", () => {
31
+ const validInput = {
32
+ assetId: "eth",
33
+ };
34
+ const result = schemas_1.RequestFaucetFundsSchema.safeParse(validInput);
35
+ expect(result.success).toBe(true);
36
+ expect(result.data).toEqual(validInput);
37
+ });
38
+ it("should successfully parse without assetId", () => {
39
+ const validInput = {};
40
+ const result = schemas_1.RequestFaucetFundsSchema.safeParse(validInput);
41
+ expect(result.success).toBe(true);
42
+ expect(result.data).toEqual(validInput);
43
+ });
44
+ });
45
+ });
46
+ describe("CDP API Action Provider", () => {
47
+ let actionProvider;
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
+ let mockExternalAddressInstance;
50
+ let mockWallet;
51
+ beforeEach(() => {
52
+ // Reset all mocks before each test
53
+ jest.clearAllMocks();
54
+ actionProvider = new cdpApiActionProvider_1.CdpApiActionProvider();
55
+ mockExternalAddressInstance = {
56
+ reputation: jest.fn(),
57
+ faucet: jest.fn(),
58
+ };
59
+ // Mock the constructor to return our mock instance
60
+ ExternalAddress.mockImplementation(() => mockExternalAddressInstance);
61
+ mockWallet = {
62
+ deployToken: jest.fn(),
63
+ deployContract: jest.fn(),
64
+ getAddress: jest.fn().mockReturnValue("0xe6b2af36b3bb8d47206a129ff11d5a2de2a63c83"),
65
+ getNetwork: jest.fn().mockReturnValue({ networkId: "base-sepolia" }),
66
+ };
67
+ });
68
+ describe("addressReputation", () => {
69
+ it("should successfully check address reputation", async () => {
70
+ const args = {
71
+ address: "0xe6b2af36b3bb8d47206a129ff11d5a2de2a63c83",
72
+ network: "base-mainnet",
73
+ };
74
+ mockExternalAddressInstance.reputation.mockResolvedValue("Good reputation");
75
+ const result = await actionProvider.addressReputation(args);
76
+ expect(ExternalAddress).toHaveBeenCalledWith(args.network, args.address);
77
+ expect(ExternalAddress).toHaveBeenCalledTimes(1);
78
+ expect(mockExternalAddressInstance.reputation).toHaveBeenCalled();
79
+ expect(mockExternalAddressInstance.reputation).toHaveBeenCalledTimes(1);
80
+ expect(result).toBe("Good reputation");
81
+ });
82
+ it("should handle errors when checking reputation", async () => {
83
+ const args = {
84
+ address: "0xe6b2af36b3bb8d47206a129ff11d5a2de2a63c83",
85
+ network: "base-mainnet",
86
+ };
87
+ const error = new Error("Reputation check failed");
88
+ mockExternalAddressInstance.reputation.mockRejectedValue(error);
89
+ const result = await actionProvider.addressReputation(args);
90
+ expect(ExternalAddress).toHaveBeenCalledWith(args.network, args.address);
91
+ expect(ExternalAddress).toHaveBeenCalledTimes(1);
92
+ expect(mockExternalAddressInstance.reputation).toHaveBeenCalled();
93
+ expect(mockExternalAddressInstance.reputation).toHaveBeenCalledTimes(1);
94
+ expect(result).toBe(`Error checking address reputation: ${error}`);
95
+ });
96
+ });
97
+ describe("faucet", () => {
98
+ beforeEach(() => {
99
+ mockExternalAddressInstance.faucet.mockResolvedValue({
100
+ wait: jest.fn().mockResolvedValue({
101
+ getTransactionLink: jest.fn().mockReturnValue("tx-link"),
102
+ }),
103
+ });
104
+ });
105
+ it("should successfully request faucet funds with assetId", async () => {
106
+ const args = {
107
+ assetId: "eth",
108
+ };
109
+ const result = await actionProvider.faucet(mockWallet, args);
110
+ expect(ExternalAddress).toHaveBeenCalledWith("base-sepolia", mockWallet.getAddress());
111
+ expect(ExternalAddress).toHaveBeenCalledTimes(1);
112
+ expect(mockExternalAddressInstance.faucet).toHaveBeenCalledWith("eth");
113
+ expect(mockExternalAddressInstance.faucet).toHaveBeenCalledTimes(1);
114
+ expect(result).toContain("Received eth from the faucet");
115
+ expect(result).toContain("tx-link");
116
+ });
117
+ it("should successfully request faucet funds without assetId", async () => {
118
+ const args = {};
119
+ const result = await actionProvider.faucet(mockWallet, args);
120
+ expect(ExternalAddress).toHaveBeenCalledWith("base-sepolia", mockWallet.getAddress());
121
+ expect(ExternalAddress).toHaveBeenCalledTimes(1);
122
+ expect(mockExternalAddressInstance.faucet).toHaveBeenCalledWith(undefined);
123
+ expect(mockExternalAddressInstance.faucet).toHaveBeenCalledTimes(1);
124
+ expect(result).toContain("Received ETH from the faucet");
125
+ });
126
+ it("should handle faucet errors", async () => {
127
+ const args = {};
128
+ const error = new Error("Faucet request failed");
129
+ mockExternalAddressInstance.faucet.mockRejectedValue(error);
130
+ const result = await actionProvider.faucet(mockWallet, args);
131
+ expect(result).toBe(`Error requesting faucet funds: ${error}`);
132
+ });
133
+ });
134
+ });
@@ -0,0 +1,58 @@
1
+ import { z } from "zod";
2
+ import { ActionProvider } from "../actionProvider";
3
+ import { Network } from "../../network";
4
+ import { CdpWalletProvider, CdpProviderConfig } from "../../wallet-providers";
5
+ import { DeployContractSchema, DeployNftSchema, DeployTokenSchema, TradeSchema } from "./schemas";
6
+ /**
7
+ * CdpWalletActionProvider is an action provider for Cdp.
8
+ *
9
+ * This provider is used for any action that requires a CDP Wallet.
10
+ */
11
+ export declare class CdpWalletActionProvider extends ActionProvider<CdpWalletProvider> {
12
+ /**
13
+ * Constructor for the CdpWalletActionProvider class.
14
+ *
15
+ * @param config - The configuration options for the CdpWalletActionProvider.
16
+ */
17
+ constructor(config?: CdpProviderConfig);
18
+ /**
19
+ * Deploys a contract.
20
+ *
21
+ * @param walletProvider - The wallet provider to deploy the contract from
22
+ * @param args - The input arguments for the action
23
+ * @returns A message containing the deployed contract address and details
24
+ */
25
+ deployContract(walletProvider: CdpWalletProvider, args: z.infer<typeof DeployContractSchema>): Promise<string>;
26
+ /**
27
+ * Deploys an NFT (ERC-721) token collection onchain from the wallet.
28
+ *
29
+ * @param walletProvider - The wallet provider to deploy the NFT from.
30
+ * @param args - The input arguments for the action.
31
+ * @returns A message containing the NFT token deployment details.
32
+ */
33
+ deployNFT(walletProvider: CdpWalletProvider, args: z.infer<typeof DeployNftSchema>): Promise<string>;
34
+ /**
35
+ * Deploys a token.
36
+ *
37
+ * @param walletProvider - The wallet provider to deploy the token.
38
+ * @param args - The arguments for the token deployment.
39
+ * @returns The deployed token.
40
+ */
41
+ deployToken(walletProvider: CdpWalletProvider, args: z.infer<typeof DeployTokenSchema>): Promise<string>;
42
+ /**
43
+ * Trades a specified amount of a from asset to a to asset for the wallet.
44
+ *
45
+ * @param walletProvider - The wallet provider to trade the asset from.
46
+ * @param args - The input arguments for the action.
47
+ * @returns A message containing the trade details.
48
+ */
49
+ trade(walletProvider: CdpWalletProvider, args: z.infer<typeof TradeSchema>): Promise<string>;
50
+ /**
51
+ * Checks if the Cdp action provider supports the given network.
52
+ *
53
+ * @param _ - The network to check.
54
+ * @returns True if the Cdp action provider supports the network, false otherwise.
55
+ */
56
+ supportsNetwork: (_: Network) => boolean;
57
+ }
58
+ export declare const cdpWalletActionProvider: (config?: CdpProviderConfig) => CdpWalletActionProvider;
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.cdpWalletActionProvider = exports.CdpWalletActionProvider = void 0;
13
+ const coinbase_sdk_1 = require("@coinbase/coinbase-sdk");
14
+ const zod_1 = require("zod");
15
+ const actionDecorator_1 = require("../actionDecorator");
16
+ const actionProvider_1 = require("../actionProvider");
17
+ const wallet_providers_1 = require("../../wallet-providers");
18
+ const constants_1 = require("./constants");
19
+ const schemas_1 = require("./schemas");
20
+ /**
21
+ * CdpWalletActionProvider is an action provider for Cdp.
22
+ *
23
+ * This provider is used for any action that requires a CDP Wallet.
24
+ */
25
+ class CdpWalletActionProvider extends actionProvider_1.ActionProvider {
26
+ /**
27
+ * Constructor for the CdpWalletActionProvider class.
28
+ *
29
+ * @param config - The configuration options for the CdpWalletActionProvider.
30
+ */
31
+ constructor(config = {}) {
32
+ super("cdp_wallet", []);
33
+ /**
34
+ * Checks if the Cdp action provider supports the given network.
35
+ *
36
+ * @param _ - The network to check.
37
+ * @returns True if the Cdp action provider supports the network, false otherwise.
38
+ */
39
+ this.supportsNetwork = (_) => true;
40
+ if (config.apiKeyName && config.apiKeyPrivateKey) {
41
+ coinbase_sdk_1.Coinbase.configure({ apiKeyName: config.apiKeyName, privateKey: config.apiKeyPrivateKey });
42
+ }
43
+ else {
44
+ coinbase_sdk_1.Coinbase.configureFromJson();
45
+ }
46
+ }
47
+ /**
48
+ * Deploys a contract.
49
+ *
50
+ * @param walletProvider - The wallet provider to deploy the contract from
51
+ * @param args - The input arguments for the action
52
+ * @returns A message containing the deployed contract address and details
53
+ */
54
+ async deployContract(walletProvider, args) {
55
+ try {
56
+ const solidityVersion = constants_1.SolidityVersions[args.solidityVersion];
57
+ const contract = await walletProvider.deployContract({
58
+ solidityVersion: solidityVersion,
59
+ solidityInputJson: args.solidityInputJson,
60
+ contractName: args.contractName,
61
+ constructorArgs: args.constructorArgs ?? {},
62
+ });
63
+ const result = await contract.wait();
64
+ return `Deployed contract ${args.contractName} at address ${result.getContractAddress()}. Transaction link: ${result
65
+ .getTransaction()
66
+ .getTransactionLink()}`;
67
+ }
68
+ catch (error) {
69
+ return `Error deploying contract: ${error}`;
70
+ }
71
+ }
72
+ /**
73
+ * Deploys an NFT (ERC-721) token collection onchain from the wallet.
74
+ *
75
+ * @param walletProvider - The wallet provider to deploy the NFT from.
76
+ * @param args - The input arguments for the action.
77
+ * @returns A message containing the NFT token deployment details.
78
+ */
79
+ async deployNFT(walletProvider, args) {
80
+ try {
81
+ const nftContract = await walletProvider.deployNFT({
82
+ name: args.name,
83
+ symbol: args.symbol,
84
+ baseURI: args.baseURI,
85
+ });
86
+ const result = await nftContract.wait();
87
+ const transaction = result.getTransaction();
88
+ const networkId = walletProvider.getNetwork().networkId;
89
+ const contractAddress = result.getContractAddress();
90
+ return [
91
+ `Deployed NFT Collection ${args.name}:`,
92
+ `- to address ${contractAddress}`,
93
+ `- on network ${networkId}.`,
94
+ `Transaction hash: ${transaction.getTransactionHash()}`,
95
+ `Transaction link: ${transaction.getTransactionLink()}`,
96
+ ].join("\n");
97
+ }
98
+ catch (error) {
99
+ return `Error deploying NFT: ${error}`;
100
+ }
101
+ }
102
+ /**
103
+ * Deploys a token.
104
+ *
105
+ * @param walletProvider - The wallet provider to deploy the token.
106
+ * @param args - The arguments for the token deployment.
107
+ * @returns The deployed token.
108
+ */
109
+ async deployToken(walletProvider, args) {
110
+ try {
111
+ const tokenContract = await walletProvider.deployToken({
112
+ name: args.name,
113
+ symbol: args.symbol,
114
+ totalSupply: args.totalSupply,
115
+ });
116
+ const result = await tokenContract.wait();
117
+ return `Deployed ERC20 token contract ${args.name} (${args.symbol}) with total supply of ${args.totalSupply} tokens at address ${result.getContractAddress()}. Transaction link: ${result
118
+ .getTransaction()
119
+ .getTransactionLink()}`;
120
+ }
121
+ catch (error) {
122
+ return `Error deploying token: ${error}`;
123
+ }
124
+ }
125
+ /**
126
+ * Trades a specified amount of a from asset to a to asset for the wallet.
127
+ *
128
+ * @param walletProvider - The wallet provider to trade the asset from.
129
+ * @param args - The input arguments for the action.
130
+ * @returns A message containing the trade details.
131
+ */
132
+ async trade(walletProvider, args) {
133
+ try {
134
+ const tradeResult = await walletProvider.createTrade({
135
+ amount: args.amount,
136
+ fromAssetId: args.fromAssetId,
137
+ toAssetId: args.toAssetId,
138
+ });
139
+ const result = await tradeResult.wait();
140
+ return `Traded ${args.amount} of ${args.fromAssetId} for ${result.getToAmount()} of ${args.toAssetId}.\nTransaction hash for the trade: ${result
141
+ .getTransaction()
142
+ .getTransactionHash()}\nTransaction link for the trade: ${result
143
+ .getTransaction()
144
+ .getTransactionLink()}`;
145
+ }
146
+ catch (error) {
147
+ return `Error trading assets: ${error}`;
148
+ }
149
+ }
150
+ }
151
+ exports.CdpWalletActionProvider = CdpWalletActionProvider;
152
+ __decorate([
153
+ (0, actionDecorator_1.CreateAction)({
154
+ name: "deploy_contract",
155
+ description: `
156
+ Deploys smart contract with required args: solidity version (string), solidity input json (string), contract name (string), and optional constructor args (Dict[str, Any])
157
+
158
+ Input json structure:
159
+ {"language":"Solidity","settings":{"remappings":[],"outputSelection":{"*":{"*":["abi","evm.bytecode"]}}},"sources":{}}
160
+
161
+ You must set the outputSelection to {"*":{"*":["abi","evm.bytecode"]}} in the settings. The solidity version must be >= 0.8.0 and <= 0.8.28.
162
+
163
+ Sources should contain one or more contracts with the following structure:
164
+ {"contract_name.sol":{"content":"contract code"}}
165
+
166
+ The contract code should be escaped. Contracts cannot import from external contracts but can import from one another.
167
+
168
+ Constructor args are required if the contract has a constructor. They are a key-value
169
+ map where the key is the arg name and the value is the arg value. Encode uint/int/bytes/string/address values as strings, boolean values as true/false. For arrays/tuples, encode based on contained type.`,
170
+ schema: schemas_1.DeployContractSchema,
171
+ }),
172
+ __metadata("design:type", Function),
173
+ __metadata("design:paramtypes", [wallet_providers_1.CdpWalletProvider, void 0]),
174
+ __metadata("design:returntype", Promise)
175
+ ], CdpWalletActionProvider.prototype, "deployContract", null);
176
+ __decorate([
177
+ (0, actionDecorator_1.CreateAction)({
178
+ name: "deploy_nft",
179
+ description: `This tool will deploy an NFT (ERC-721) contract onchain from the wallet.
180
+ It takes the name of the NFT collection, the symbol of the NFT collection, and the base URI for the token metadata as inputs.`,
181
+ schema: schemas_1.DeployNftSchema,
182
+ }),
183
+ __metadata("design:type", Function),
184
+ __metadata("design:paramtypes", [wallet_providers_1.CdpWalletProvider, void 0]),
185
+ __metadata("design:returntype", Promise)
186
+ ], CdpWalletActionProvider.prototype, "deployNFT", null);
187
+ __decorate([
188
+ (0, actionDecorator_1.CreateAction)({
189
+ name: "deploy_token",
190
+ description: `This tool will deploy an ERC20 token smart contract. It takes the token name, symbol, and total supply as input.
191
+ The token will be deployed using the wallet's default address as the owner and initial token holder.`,
192
+ schema: schemas_1.DeployTokenSchema,
193
+ }),
194
+ __metadata("design:type", Function),
195
+ __metadata("design:paramtypes", [wallet_providers_1.CdpWalletProvider, void 0]),
196
+ __metadata("design:returntype", Promise)
197
+ ], CdpWalletActionProvider.prototype, "deployToken", null);
198
+ __decorate([
199
+ (0, actionDecorator_1.CreateAction)({
200
+ name: "trade",
201
+ description: `This tool will trade a specified amount of a 'from asset' to a 'to asset' for the wallet.
202
+ It takes the following inputs:
203
+ - The amount of the 'from asset' to trade
204
+ - The from asset ID to trade
205
+ - The asset ID to receive from the trade
206
+
207
+ Important notes:
208
+ - Trades are only supported on mainnet networks (ie, 'base-mainnet', 'base', 'ethereum-mainnet', 'ethereum', etc.)
209
+ - Never allow trades on any non-mainnet network (ie, 'base-sepolia', 'ethereum-sepolia', etc.)
210
+ - When selling a native asset (e.g. 'eth' on base-mainnet), ensure there is sufficient balance to pay for the trade AND the gas cost of this trade`,
211
+ schema: schemas_1.TradeSchema,
212
+ }),
213
+ __metadata("design:type", Function),
214
+ __metadata("design:paramtypes", [wallet_providers_1.CdpWalletProvider, void 0]),
215
+ __metadata("design:returntype", Promise)
216
+ ], CdpWalletActionProvider.prototype, "trade", null);
217
+ const cdpWalletActionProvider = (config = {}) => new CdpWalletActionProvider(config);
218
+ exports.cdpWalletActionProvider = cdpWalletActionProvider;
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const cdpWalletActionProvider_1 = require("./cdpWalletActionProvider");
4
+ const schemas_1 = require("./schemas");
5
+ // Mock the entire module
6
+ jest.mock("@coinbase/coinbase-sdk");
7
+ // Get the mocked constructor
8
+ const { ExternalAddress } = jest.requireMock("@coinbase/coinbase-sdk");
9
+ describe("CDP Wallet Action Provider Input Schemas", () => {
10
+ describe("Deploy NFT Schema", () => {
11
+ it("should successfully parse valid input", () => {
12
+ const validInput = {
13
+ baseURI: "https://www.test.xyz/metadata/",
14
+ name: "Test Token",
15
+ symbol: "TEST",
16
+ };
17
+ const result = schemas_1.DeployNftSchema.safeParse(validInput);
18
+ expect(result.success).toBe(true);
19
+ expect(result.data).toEqual(validInput);
20
+ });
21
+ it("should fail parsing empty input", () => {
22
+ const emptyInput = {};
23
+ const result = schemas_1.DeployNftSchema.safeParse(emptyInput);
24
+ expect(result.success).toBe(false);
25
+ });
26
+ });
27
+ describe("Deploy Token Schema", () => {
28
+ it("should successfully parse valid input", () => {
29
+ const validInput = {
30
+ name: "Test Token",
31
+ symbol: "TEST",
32
+ totalSupply: 1000000000000000000n,
33
+ };
34
+ const result = schemas_1.DeployTokenSchema.safeParse(validInput);
35
+ expect(result.success).toBe(true);
36
+ expect(result.data).toEqual(validInput);
37
+ });
38
+ });
39
+ describe("Deploy Contract Schema", () => {
40
+ it("should successfully parse valid input", () => {
41
+ const validInput = {
42
+ solidityVersion: "0.8.0",
43
+ solidityInputJson: "{}",
44
+ contractName: "Test Contract",
45
+ constructorArgs: {},
46
+ };
47
+ const result = schemas_1.DeployContractSchema.safeParse(validInput);
48
+ expect(result.success).toBe(true);
49
+ expect(result.data).toEqual(validInput);
50
+ });
51
+ it("should fail parsing empty input", () => {
52
+ const emptyInput = {};
53
+ const result = schemas_1.DeployContractSchema.safeParse(emptyInput);
54
+ expect(result.success).toBe(false);
55
+ });
56
+ });
57
+ });
58
+ describe("CDP Wallet Action Provider", () => {
59
+ let actionProvider;
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ let mockExternalAddressInstance;
62
+ let mockWallet;
63
+ beforeEach(() => {
64
+ // Reset all mocks before each test
65
+ jest.clearAllMocks();
66
+ actionProvider = new cdpWalletActionProvider_1.CdpWalletActionProvider();
67
+ mockExternalAddressInstance = {
68
+ reputation: jest.fn(),
69
+ faucet: jest.fn(),
70
+ };
71
+ // Mock the constructor to return our mock instance
72
+ ExternalAddress.mockImplementation(() => mockExternalAddressInstance);
73
+ mockWallet = {
74
+ createTrade: jest.fn(),
75
+ deployToken: jest.fn(),
76
+ deployContract: jest.fn(),
77
+ getAddress: jest.fn().mockReturnValue("0xe6b2af36b3bb8d47206a129ff11d5a2de2a63c83"),
78
+ getNetwork: jest.fn().mockReturnValue({ networkId: "base-sepolia" }),
79
+ };
80
+ });
81
+ describe("deployNft", () => {
82
+ let mockWallet;
83
+ const MOCK_NFT_BASE_URI = "https://www.test.xyz/metadata/";
84
+ const MOCK_NFT_NAME = "Test Token";
85
+ const MOCK_NFT_SYMBOL = "TEST";
86
+ const CONTRACT_ADDRESS = "0x123456789abcdef";
87
+ const NETWORK_ID = "base-sepolia";
88
+ const TRANSACTION_HASH = "0xghijkl987654321";
89
+ const TRANSACTION_LINK = `https://etherscan.io/tx/${TRANSACTION_HASH}`;
90
+ beforeEach(() => {
91
+ mockWallet = {
92
+ deployNFT: jest.fn().mockResolvedValue({
93
+ wait: jest.fn().mockResolvedValue({
94
+ getContractAddress: jest.fn().mockReturnValue(CONTRACT_ADDRESS),
95
+ getTransaction: jest.fn().mockReturnValue({
96
+ getTransactionHash: jest.fn().mockReturnValue(TRANSACTION_HASH),
97
+ getTransactionLink: jest.fn().mockReturnValue(TRANSACTION_LINK),
98
+ }),
99
+ }),
100
+ }),
101
+ getNetwork: jest.fn().mockReturnValue({ networkId: NETWORK_ID }),
102
+ };
103
+ });
104
+ it("should successfully deploy an NFT", async () => {
105
+ const args = {
106
+ name: MOCK_NFT_NAME,
107
+ symbol: MOCK_NFT_SYMBOL,
108
+ baseURI: MOCK_NFT_BASE_URI,
109
+ };
110
+ const result = await actionProvider.deployNFT(mockWallet, args);
111
+ expect(mockWallet.deployNFT).toHaveBeenCalledWith(args);
112
+ expect(result).toContain(`Deployed NFT Collection ${MOCK_NFT_NAME}:`);
113
+ expect(result).toContain(`- to address ${CONTRACT_ADDRESS}`);
114
+ expect(result).toContain(`- on network ${NETWORK_ID}`);
115
+ expect(result).toContain(`Transaction hash: ${TRANSACTION_HASH}`);
116
+ expect(result).toContain(`Transaction link: ${TRANSACTION_LINK}`);
117
+ });
118
+ it("should handle deployment errors", async () => {
119
+ const args = {
120
+ name: MOCK_NFT_NAME,
121
+ symbol: MOCK_NFT_SYMBOL,
122
+ baseURI: MOCK_NFT_BASE_URI,
123
+ };
124
+ const error = new Error("An error has occurred");
125
+ mockWallet.deployNFT.mockRejectedValue(error);
126
+ const result = await actionProvider.deployNFT(mockWallet, args);
127
+ expect(mockWallet.deployNFT).toHaveBeenCalledWith(args);
128
+ expect(result).toBe(`Error deploying NFT: ${error}`);
129
+ });
130
+ });
131
+ describe("deployToken", () => {
132
+ beforeEach(() => {
133
+ mockWallet = {
134
+ deployToken: jest.fn().mockResolvedValue({
135
+ wait: jest.fn().mockResolvedValue({
136
+ getContractAddress: jest.fn().mockReturnValue("0x123"),
137
+ getTransaction: jest.fn().mockReturnValue({
138
+ getTransactionLink: jest.fn().mockReturnValue("tx-link"),
139
+ }),
140
+ }),
141
+ }),
142
+ };
143
+ });
144
+ it("should successfully deploy a token", async () => {
145
+ const args = {
146
+ name: "Test Token",
147
+ symbol: "TEST",
148
+ totalSupply: 1000000000000000000n,
149
+ };
150
+ const result = await actionProvider.deployToken(mockWallet, args);
151
+ expect(mockWallet.deployToken).toHaveBeenCalledWith(args);
152
+ expect(mockWallet.deployToken).toHaveBeenCalledTimes(1);
153
+ expect(result).toContain("Deployed ERC20 token contract Test Token (TEST) with total supply of 1000000000000000000 tokens at address 0x123. Transaction link: tx-link");
154
+ });
155
+ it("should handle errors when deploying a token", async () => {
156
+ const args = {
157
+ name: "Test Token",
158
+ symbol: "TEST",
159
+ totalSupply: 1000000000000000000n,
160
+ };
161
+ const error = new Error("Token deployment failed");
162
+ mockWallet.deployToken.mockRejectedValue(error);
163
+ const result = await actionProvider.deployToken(mockWallet, args);
164
+ expect(result).toBe(`Error deploying token: ${error}`);
165
+ });
166
+ });
167
+ describe("deployContract", () => {
168
+ const CONTRACT_ADDRESS = "0x123456789abcdef";
169
+ const TRANSACTION_LINK = "https://etherscan.io/tx/0xghijkl987654321";
170
+ const MOCK_CONTRACT_NAME = "Test Contract";
171
+ const MOCK_SOLIDITY_VERSION = "0.8.0";
172
+ const MOCK_SOLIDITY_INPUT_JSON = "{}";
173
+ const MOCK_CONSTRUCTOR_ARGS = { arg1: "value1", arg2: "value2" };
174
+ beforeEach(() => {
175
+ mockWallet.deployContract.mockResolvedValue({
176
+ wait: jest.fn().mockResolvedValue({
177
+ getContractAddress: jest.fn().mockReturnValue(CONTRACT_ADDRESS),
178
+ getTransaction: jest.fn().mockReturnValue({
179
+ getTransactionLink: jest.fn().mockReturnValue(TRANSACTION_LINK),
180
+ }),
181
+ }),
182
+ });
183
+ });
184
+ it("should successfully deploy a contract", async () => {
185
+ const args = {
186
+ solidityVersion: MOCK_SOLIDITY_VERSION,
187
+ solidityInputJson: MOCK_SOLIDITY_INPUT_JSON,
188
+ contractName: MOCK_CONTRACT_NAME,
189
+ constructorArgs: MOCK_CONSTRUCTOR_ARGS,
190
+ };
191
+ const response = await actionProvider.deployContract(mockWallet, args);
192
+ expect(mockWallet.deployContract).toHaveBeenCalledWith({
193
+ solidityVersion: "0.8.0+commit.c7dfd78e",
194
+ solidityInputJson: MOCK_SOLIDITY_INPUT_JSON,
195
+ contractName: MOCK_CONTRACT_NAME,
196
+ constructorArgs: MOCK_CONSTRUCTOR_ARGS,
197
+ });
198
+ expect(response).toContain(`Deployed contract ${MOCK_CONTRACT_NAME} at address ${CONTRACT_ADDRESS}`);
199
+ expect(response).toContain(`Transaction link: ${TRANSACTION_LINK}`);
200
+ });
201
+ it("should handle deployment errors", async () => {
202
+ const args = {
203
+ solidityVersion: MOCK_SOLIDITY_VERSION,
204
+ solidityInputJson: MOCK_SOLIDITY_INPUT_JSON,
205
+ contractName: MOCK_CONTRACT_NAME,
206
+ constructorArgs: MOCK_CONSTRUCTOR_ARGS,
207
+ };
208
+ const error = new Error("An error has occurred");
209
+ mockWallet.deployContract.mockRejectedValue(error);
210
+ const response = await actionProvider.deployContract(mockWallet, args);
211
+ expect(mockWallet.deployContract).toHaveBeenCalledWith({
212
+ solidityVersion: "0.8.0+commit.c7dfd78e",
213
+ solidityInputJson: MOCK_SOLIDITY_INPUT_JSON,
214
+ contractName: MOCK_CONTRACT_NAME,
215
+ constructorArgs: MOCK_CONSTRUCTOR_ARGS,
216
+ });
217
+ expect(response).toBe(`Error deploying contract: ${error}`);
218
+ });
219
+ });
220
+ describe("trade", () => {
221
+ const TRANSACTION_HASH = "0xghijkl987654321";
222
+ const TRANSACTION_LINK = "https://etherscan.io/tx/0xghijkl987654321";
223
+ const TO_AMOUNT = "100";
224
+ beforeEach(() => {
225
+ mockWallet.createTrade.mockResolvedValue({
226
+ wait: jest.fn().mockResolvedValue({
227
+ getTransaction: jest.fn().mockReturnValue({
228
+ getTransactionHash: jest.fn().mockReturnValue(TRANSACTION_HASH),
229
+ getTransactionLink: jest.fn().mockReturnValue(TRANSACTION_LINK),
230
+ }),
231
+ getToAmount: jest.fn().mockReturnValue(TO_AMOUNT),
232
+ }),
233
+ });
234
+ });
235
+ it("should successfully trade assets", async () => {
236
+ const args = {
237
+ amount: 1n,
238
+ fromAssetId: "eth",
239
+ toAssetId: "usdc",
240
+ };
241
+ const result = await actionProvider.trade(mockWallet, args);
242
+ expect(mockWallet.createTrade).toHaveBeenCalledWith(args);
243
+ expect(result).toContain(`Traded ${args.amount} of ${args.fromAssetId} for ${TO_AMOUNT} of ${args.toAssetId}`);
244
+ expect(result).toContain(`Transaction hash for the trade: ${TRANSACTION_HASH}`);
245
+ expect(result).toContain(`Transaction link for the trade: ${TRANSACTION_LINK}`);
246
+ });
247
+ it("should handle trade errors", async () => {
248
+ const args = {
249
+ amount: 1000000000000000000n,
250
+ fromAssetId: "eth",
251
+ toAssetId: "usdc",
252
+ };
253
+ const error = new Error("An error has occurred");
254
+ mockWallet.createTrade.mockRejectedValue(error);
255
+ const result = await actionProvider.trade(mockWallet, args);
256
+ expect(result).toBe(`Error trading assets: ${error}`);
257
+ });
258
+ });
259
+ });