@coinbase/agentkit 0.7.0 → 0.7.1

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.
@@ -313,7 +313,7 @@ const ethToMemecoin = (params) => {
313
313
  };
314
314
  };
315
315
  exports.ethToMemecoin = ethToMemecoin;
316
- // @notice Beofre calling the UniversalRouter the user must have:
316
+ // @notice Before calling the UniversalRouter the user must have:
317
317
  // 1. Given the Permit2 contract allowance to spend the memecoin
318
318
  const memecoinToEthWithPermit2 = (params) => {
319
319
  const flETH = constants_1.FLETHAddress[params.chainId];
@@ -29,7 +29,8 @@ export interface TwitterActionProviderConfig {
29
29
  * @augments ActionProvider
30
30
  */
31
31
  export declare class TwitterActionProvider extends ActionProvider {
32
- private readonly client;
32
+ private client;
33
+ private config;
33
34
  /**
34
35
  * Constructor for the TwitterActionProvider class.
35
36
  *
@@ -72,6 +73,12 @@ export declare class TwitterActionProvider extends ActionProvider {
72
73
  * @returns Always returns true as Twitter actions are network-independent
73
74
  */
74
75
  supportsNetwork(_: Network): boolean;
76
+ /**
77
+ * Get the Twitter API client, initializing it if needed
78
+ *
79
+ * @returns The Twitter API client
80
+ */
81
+ private getClient;
75
82
  }
76
83
  /**
77
84
  * Factory function to create a new TwitterActionProvider instance.
@@ -27,29 +27,29 @@ class TwitterActionProvider extends actionProvider_1.ActionProvider {
27
27
  * @param config - The configuration options for the TwitterActionProvider
28
28
  */
29
29
  constructor(config = {}) {
30
+ var _a, _b, _c, _d;
30
31
  super("twitter", []);
31
- config.apiKey || (config.apiKey = process.env.TWITTER_API_KEY);
32
- config.apiSecret || (config.apiSecret = process.env.TWITTER_API_SECRET);
33
- config.accessToken || (config.accessToken = process.env.TWITTER_ACCESS_TOKEN);
34
- config.accessTokenSecret || (config.accessTokenSecret = process.env.TWITTER_ACCESS_TOKEN_SECRET);
35
- if (!config.apiKey) {
32
+ this.client = null;
33
+ // Store config for later use but don't initialize the client yet
34
+ this.config = { ...config };
35
+ // Set defaults from environment variables
36
+ (_a = this.config).apiKey || (_a.apiKey = process.env.TWITTER_API_KEY);
37
+ (_b = this.config).apiSecret || (_b.apiSecret = process.env.TWITTER_API_SECRET);
38
+ (_c = this.config).accessToken || (_c.accessToken = process.env.TWITTER_ACCESS_TOKEN);
39
+ (_d = this.config).accessTokenSecret || (_d.accessTokenSecret = process.env.TWITTER_ACCESS_TOKEN_SECRET);
40
+ // Validate config
41
+ if (!this.config.apiKey) {
36
42
  throw new Error("TWITTER_API_KEY is not configured.");
37
43
  }
38
- if (!config.apiSecret) {
44
+ if (!this.config.apiSecret) {
39
45
  throw new Error("TWITTER_API_SECRET is not configured.");
40
46
  }
41
- if (!config.accessToken) {
47
+ if (!this.config.accessToken) {
42
48
  throw new Error("TWITTER_ACCESS_TOKEN is not configured.");
43
49
  }
44
- if (!config.accessTokenSecret) {
50
+ if (!this.config.accessTokenSecret) {
45
51
  throw new Error("TWITTER_ACCESS_TOKEN_SECRET is not configured.");
46
52
  }
47
- this.client = new twitter_api_v2_1.TwitterApi({
48
- appKey: config.apiKey,
49
- appSecret: config.apiSecret,
50
- accessToken: config.accessToken,
51
- accessSecret: config.accessTokenSecret,
52
- });
53
53
  }
54
54
  /**
55
55
  * Get account details for the currently authenticated Twitter (X) user.
@@ -59,7 +59,7 @@ class TwitterActionProvider extends actionProvider_1.ActionProvider {
59
59
  */
60
60
  async accountDetails(_) {
61
61
  try {
62
- const response = await this.client.v2.me();
62
+ const response = await this.getClient().v2.me();
63
63
  response.data.url = `https://x.com/${response.data.username}`;
64
64
  return `Successfully retrieved authenticated user account details:\n${JSON.stringify(response)}`;
65
65
  }
@@ -75,7 +75,7 @@ class TwitterActionProvider extends actionProvider_1.ActionProvider {
75
75
  */
76
76
  async accountMentions(args) {
77
77
  try {
78
- const response = await this.client.v2.userMentionTimeline(args.userId);
78
+ const response = await this.getClient().v2.userMentionTimeline(args.userId);
79
79
  return `Successfully retrieved account mentions:\n${JSON.stringify(response)}`;
80
80
  }
81
81
  catch (error) {
@@ -90,7 +90,7 @@ class TwitterActionProvider extends actionProvider_1.ActionProvider {
90
90
  */
91
91
  async postTweet(args) {
92
92
  try {
93
- const response = await this.client.v2.tweet(args.tweet);
93
+ const response = await this.getClient().v2.tweet(args.tweet);
94
94
  return `Successfully posted to Twitter:\n${JSON.stringify(response)}`;
95
95
  }
96
96
  catch (error) {
@@ -105,7 +105,7 @@ class TwitterActionProvider extends actionProvider_1.ActionProvider {
105
105
  */
106
106
  async postTweetReply(args) {
107
107
  try {
108
- const response = await this.client.v2.tweet(args.tweetReply, {
108
+ const response = await this.getClient().v2.tweet(args.tweetReply, {
109
109
  reply: { in_reply_to_tweet_id: args.tweetId },
110
110
  });
111
111
  return `Successfully posted reply to Twitter:\n${JSON.stringify(response)}`;
@@ -124,6 +124,24 @@ class TwitterActionProvider extends actionProvider_1.ActionProvider {
124
124
  supportsNetwork(_) {
125
125
  return true;
126
126
  }
127
+ /**
128
+ * Get the Twitter API client, initializing it if needed
129
+ *
130
+ * @returns The Twitter API client
131
+ */
132
+ getClient() {
133
+ if (!this.client) {
134
+ // Initialize client only when needed
135
+ const tokens = {
136
+ appKey: this.config.apiKey,
137
+ appSecret: this.config.apiSecret,
138
+ accessToken: this.config.accessToken,
139
+ accessSecret: this.config.accessTokenSecret,
140
+ };
141
+ this.client = new twitter_api_v2_1.TwitterApi(tokens);
142
+ }
143
+ return this.client;
144
+ }
127
145
  }
128
146
  exports.TwitterActionProvider = TwitterActionProvider;
129
147
  __decorate([
@@ -44,6 +44,24 @@ describe("TwitterActionProvider", () => {
44
44
  delete process.env.TWITTER_ACCESS_TOKEN_SECRET;
45
45
  expect(() => new twitterActionProvider_1.TwitterActionProvider()).toThrow("TWITTER_API_KEY is not configured.");
46
46
  });
47
+ it("should implement lazy initialization", async () => {
48
+ // We'll check lazy initialization by observing that we can create an instance
49
+ // without error, and then use it to call methods successfully
50
+ const provider = new twitterActionProvider_1.TwitterActionProvider(MOCK_CONFIG);
51
+ // Mock a response for accountDetails
52
+ mockClient.me.mockResolvedValue({
53
+ data: {
54
+ id: MOCK_ID,
55
+ name: MOCK_NAME,
56
+ username: MOCK_USERNAME,
57
+ },
58
+ });
59
+ // Call a method that should trigger initialization
60
+ const response = await provider.accountDetails({});
61
+ // Verify the method worked, which means initialization succeeded
62
+ expect(response).toContain("Successfully retrieved authenticated user account details");
63
+ expect(mockClient.me).toHaveBeenCalled();
64
+ });
47
65
  });
48
66
  describe("Account Details Action", () => {
49
67
  const mockResponse = {
@@ -182,4 +200,31 @@ describe("TwitterActionProvider", () => {
182
200
  expect(provider.supportsNetwork({ protocolFamily: "solana", networkId: "2" })).toBe(true);
183
201
  });
184
202
  });
203
+ describe("Next.js Integration", () => {
204
+ it("should work in a simulated Next.js environment", async () => {
205
+ // Create a clean instance of the provider
206
+ const provider = new twitterActionProvider_1.TwitterActionProvider(MOCK_CONFIG);
207
+ // Mock v2.me to test functionality
208
+ const mockResponse = {
209
+ data: {
210
+ id: MOCK_ID,
211
+ name: MOCK_NAME,
212
+ username: MOCK_USERNAME,
213
+ },
214
+ };
215
+ const mockTwitterApi = {
216
+ v2: {
217
+ me: jest.fn().mockResolvedValue(mockResponse),
218
+ },
219
+ };
220
+ // Override the getClient method to return our mocked API
221
+ jest
222
+ .spyOn(provider, "getClient")
223
+ .mockReturnValue(mockTwitterApi);
224
+ // Simulate a Next.js API route calling the provider
225
+ const result = await provider.accountDetails({});
226
+ expect(result).toContain("Successfully retrieved authenticated user account details");
227
+ expect(mockTwitterApi.v2.me).toHaveBeenCalled();
228
+ });
229
+ });
185
230
  });
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.7.0",
5
+ "version": "0.7.1",
6
6
  "author": "Coinbase Inc.",
7
7
  "license": "Apache-2.0",
8
8
  "main": "dist/index.js",