@coinbase/agentkit 0.7.0 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action-providers/cdp-v2/cdpApiV2ActionProvider.d.ts +2 -5
- package/dist/action-providers/cdp-v2/cdpApiV2ActionProvider.js +27 -20
- package/dist/action-providers/flaunch/utils.js +1 -1
- package/dist/action-providers/twitter/twitterActionProvider.d.ts +8 -1
- package/dist/action-providers/twitter/twitterActionProvider.js +36 -18
- package/dist/action-providers/twitter/twitterActionProvider.test.js +45 -0
- package/dist/wallet-providers/cdpV2EvmWalletProvider.js +21 -1
- package/dist/wallet-providers/cdpV2Shared.d.ts +7 -0
- package/dist/wallet-providers/cdpV2Shared.js +13 -0
- package/package.json +1 -1
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { Network } from "../../network";
|
|
3
3
|
import { WalletProvider } from "../../wallet-providers";
|
|
4
|
-
import { WalletProviderWithClient } from "../../wallet-providers/cdpV2Shared";
|
|
5
4
|
import { ActionProvider } from "../actionProvider";
|
|
6
5
|
import { RequestFaucetFundsV2Schema } from "./schemas";
|
|
7
|
-
type CdpV2WalletProviderWithClient = WalletProvider & WalletProviderWithClient;
|
|
8
6
|
/**
|
|
9
7
|
* CdpApiActionProvider is an action provider for CDP API.
|
|
10
8
|
*
|
|
11
9
|
* This provider is used for any action that uses the CDP API, but does not require a CDP Wallet.
|
|
12
10
|
*/
|
|
13
|
-
export declare class CdpApiV2ActionProvider extends ActionProvider<
|
|
11
|
+
export declare class CdpApiV2ActionProvider extends ActionProvider<WalletProvider> {
|
|
14
12
|
/**
|
|
15
13
|
* Constructor for the CdpApiActionProvider class.
|
|
16
14
|
*/
|
|
@@ -22,7 +20,7 @@ export declare class CdpApiV2ActionProvider extends ActionProvider<CdpV2WalletPr
|
|
|
22
20
|
* @param args - The input arguments for the action.
|
|
23
21
|
* @returns A confirmation message with transaction details.
|
|
24
22
|
*/
|
|
25
|
-
faucet(walletProvider:
|
|
23
|
+
faucet(walletProvider: WalletProvider, args: z.infer<typeof RequestFaucetFundsV2Schema>): Promise<string>;
|
|
26
24
|
/**
|
|
27
25
|
* Checks if the Cdp action provider supports the given network.
|
|
28
26
|
*
|
|
@@ -34,4 +32,3 @@ export declare class CdpApiV2ActionProvider extends ActionProvider<CdpV2WalletPr
|
|
|
34
32
|
supportsNetwork: (_: Network) => boolean;
|
|
35
33
|
}
|
|
36
34
|
export declare const cdpApiV2ActionProvider: () => CdpApiV2ActionProvider;
|
|
37
|
-
export {};
|
|
@@ -11,6 +11,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.cdpApiV2ActionProvider = exports.CdpApiV2ActionProvider = void 0;
|
|
13
13
|
const zod_1 = require("zod");
|
|
14
|
+
const wallet_providers_1 = require("../../wallet-providers");
|
|
15
|
+
const cdpV2Shared_1 = require("../../wallet-providers/cdpV2Shared");
|
|
14
16
|
const actionDecorator_1 = require("../actionDecorator");
|
|
15
17
|
const actionProvider_1 = require("../actionProvider");
|
|
16
18
|
const schemas_1 = require("./schemas");
|
|
@@ -45,29 +47,34 @@ class CdpApiV2ActionProvider extends actionProvider_1.ActionProvider {
|
|
|
45
47
|
async faucet(walletProvider, args) {
|
|
46
48
|
const network = walletProvider.getNetwork();
|
|
47
49
|
const networkId = network.networkId;
|
|
48
|
-
if (
|
|
49
|
-
if (
|
|
50
|
-
|
|
50
|
+
if ((0, cdpV2Shared_1.isWalletProviderWithClient)(walletProvider)) {
|
|
51
|
+
if (network.protocolFamily === "evm") {
|
|
52
|
+
if (networkId !== "base-sepolia" && networkId !== "ethereum-sepolia") {
|
|
53
|
+
throw new Error("Faucet is only supported on 'base-sepolia' or 'ethereum-sepolia' evm networks.");
|
|
54
|
+
}
|
|
55
|
+
const faucetTx = await walletProvider.getClient().evm.requestFaucet({
|
|
56
|
+
address: walletProvider.getAddress(),
|
|
57
|
+
token: (args.assetId || "eth"),
|
|
58
|
+
network: networkId,
|
|
59
|
+
});
|
|
60
|
+
return `Received ${args.assetId || "ETH"} from the faucet. Transaction hash: ${faucetTx.transactionHash}`;
|
|
51
61
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
+
else if (network.protocolFamily === "svm") {
|
|
63
|
+
if (networkId !== "solana-devnet") {
|
|
64
|
+
throw new Error("Faucet is only supported on 'solana-devnet' solana networks.");
|
|
65
|
+
}
|
|
66
|
+
const faucetTx = await walletProvider.getClient().solana.requestFaucet({
|
|
67
|
+
address: walletProvider.getAddress(),
|
|
68
|
+
token: (args.assetId || "sol"),
|
|
69
|
+
});
|
|
70
|
+
return `Received ${args.assetId || "SOL"} from the faucet. Transaction signature hash: ${faucetTx.signature}`;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new Error("Faucet is only supported on Ethereum and Solana protocol families.");
|
|
62
74
|
}
|
|
63
|
-
const faucetTx = await walletProvider.getClient().solana.requestFaucet({
|
|
64
|
-
address: walletProvider.getAddress(),
|
|
65
|
-
token: (args.assetId || "sol"),
|
|
66
|
-
});
|
|
67
|
-
return `Received ${args.assetId || "SOL"} from the faucet. Transaction signature hash: ${faucetTx.signature}`;
|
|
68
75
|
}
|
|
69
76
|
else {
|
|
70
|
-
throw new Error("
|
|
77
|
+
throw new Error("Wallet provider is not a CDP Wallet Provider.");
|
|
71
78
|
}
|
|
72
79
|
}
|
|
73
80
|
}
|
|
@@ -84,7 +91,7 @@ from another wallet and provide the user with your wallet details.`,
|
|
|
84
91
|
schema: schemas_1.RequestFaucetFundsV2Schema,
|
|
85
92
|
}),
|
|
86
93
|
__metadata("design:type", Function),
|
|
87
|
-
__metadata("design:paramtypes", [
|
|
94
|
+
__metadata("design:paramtypes", [wallet_providers_1.WalletProvider, void 0]),
|
|
88
95
|
__metadata("design:returntype", Promise)
|
|
89
96
|
], CdpApiV2ActionProvider.prototype, "faucet", null);
|
|
90
97
|
const cdpApiV2ActionProvider = () => new CdpApiV2ActionProvider();
|
|
@@ -313,7 +313,7 @@ const ethToMemecoin = (params) => {
|
|
|
313
313
|
};
|
|
314
314
|
};
|
|
315
315
|
exports.ethToMemecoin = ethToMemecoin;
|
|
316
|
-
// @notice
|
|
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
|
|
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
|
-
|
|
32
|
-
|
|
33
|
-
config
|
|
34
|
-
|
|
35
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
});
|
|
@@ -118,9 +118,29 @@ class CdpV2EvmWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
|
|
|
118
118
|
* @returns The hash of the transaction.
|
|
119
119
|
*/
|
|
120
120
|
async sendTransaction(transaction) {
|
|
121
|
+
const txWithGasParams = {
|
|
122
|
+
...transaction,
|
|
123
|
+
chainId: __classPrivateFieldGet(this, _CdpV2EvmWalletProvider_network, "f").chainId,
|
|
124
|
+
};
|
|
125
|
+
if (!txWithGasParams.maxFeePerGas && !txWithGasParams.gasPrice) {
|
|
126
|
+
const feeData = await __classPrivateFieldGet(this, _CdpV2EvmWalletProvider_publicClient, "f").estimateFeesPerGas();
|
|
127
|
+
txWithGasParams.maxFeePerGas = feeData.maxFeePerGas;
|
|
128
|
+
txWithGasParams.maxPriorityFeePerGas = feeData.maxPriorityFeePerGas;
|
|
129
|
+
}
|
|
130
|
+
if (!txWithGasParams.gas) {
|
|
131
|
+
try {
|
|
132
|
+
txWithGasParams.gas = await __classPrivateFieldGet(this, _CdpV2EvmWalletProvider_publicClient, "f").estimateGas({
|
|
133
|
+
account: __classPrivateFieldGet(this, _CdpV2EvmWalletProvider_serverAccount, "f").address,
|
|
134
|
+
...txWithGasParams,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.warn("Failed to estimate gas, continuing without gas estimation", error);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
121
141
|
const result = await __classPrivateFieldGet(this, _CdpV2EvmWalletProvider_cdp, "f").evm.sendTransaction({
|
|
122
142
|
address: __classPrivateFieldGet(this, _CdpV2EvmWalletProvider_serverAccount, "f").address,
|
|
123
|
-
transaction: (0, viem_1.serializeTransaction)(
|
|
143
|
+
transaction: (0, viem_1.serializeTransaction)(txWithGasParams),
|
|
124
144
|
network: __classPrivateFieldGet(this, _CdpV2EvmWalletProvider_instances, "m", _CdpV2EvmWalletProvider_getCdpSdkNetwork).call(this),
|
|
125
145
|
});
|
|
126
146
|
return result.transactionHash;
|
|
@@ -39,3 +39,10 @@ export interface WalletProviderWithClient {
|
|
|
39
39
|
*/
|
|
40
40
|
getClient(): CdpClient;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Type guard to check if a wallet provider implements WalletProviderWithClient interface.
|
|
44
|
+
*
|
|
45
|
+
* @param provider - The provider to check
|
|
46
|
+
* @returns True if the provider implements WalletProviderWithClient
|
|
47
|
+
*/
|
|
48
|
+
export declare function isWalletProviderWithClient(provider: unknown): provider is WalletProviderWithClient;
|
|
@@ -1,2 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isWalletProviderWithClient = isWalletProviderWithClient;
|
|
4
|
+
/**
|
|
5
|
+
* Type guard to check if a wallet provider implements WalletProviderWithClient interface.
|
|
6
|
+
*
|
|
7
|
+
* @param provider - The provider to check
|
|
8
|
+
* @returns True if the provider implements WalletProviderWithClient
|
|
9
|
+
*/
|
|
10
|
+
function isWalletProviderWithClient(provider) {
|
|
11
|
+
return (provider !== null &&
|
|
12
|
+
typeof provider === "object" &&
|
|
13
|
+
"getClient" in provider &&
|
|
14
|
+
typeof provider.getClient === "function");
|
|
15
|
+
}
|
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.
|
|
5
|
+
"version": "0.7.2",
|
|
6
6
|
"author": "Coinbase Inc.",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"main": "dist/index.js",
|