@openpump/eliza-plugin 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.
package/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # @openpump/eliza-plugin
2
+
3
+ ElizaOS plugin for [OpenPump](https://openpump.io) -- buy, sell, and launch PumpFun tokens via conversational AI agents.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @openpump/eliza-plugin
9
+ # or
10
+ pnpm add @openpump/eliza-plugin
11
+ ```
12
+
13
+ > **Peer dependency:** Requires `@elizaos/core` >= 1.0.0
14
+
15
+ ## Quick Start
16
+
17
+ Add the plugin to your ElizaOS character configuration:
18
+
19
+ ```json
20
+ {
21
+ "name": "TradingAgent",
22
+ "plugins": ["@openpump/eliza-plugin"],
23
+ "settings": {
24
+ "secrets": {
25
+ "OPENPUMP_API_KEY": "op_sk_live_..."
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ That's it. Your agent now has access to 8 trading actions and a portfolio context provider.
32
+
33
+ ## Configuration
34
+
35
+ | Setting | Required | Default | Description |
36
+ |---------|----------|---------|-------------|
37
+ | `OPENPUMP_API_KEY` | Yes | -- | Your OpenPump API key (starts with `op_sk_`) |
38
+ | `OPENPUMP_API_URL` | No | `https://api.openpump.io` | Custom API base URL |
39
+
40
+ Settings are read from `runtime.getSetting()`, which resolves from your character JSON's `settings.secrets` object.
41
+
42
+ ## Actions
43
+
44
+ The plugin registers 8 actions that the agent can invoke based on natural language:
45
+
46
+ ### OPENPUMP_BUY_TOKEN
47
+
48
+ Buy a token from a specific wallet.
49
+
50
+ ```
51
+ "Buy 0.5 SOL worth of token ABC from my sniper wallet"
52
+ ```
53
+
54
+ **Parameters:** `walletId`, `mint`, `amountLamports` (optional: `slippageBps`, `priorityLevel`)
55
+
56
+ ### OPENPUMP_SELL_TOKEN
57
+
58
+ Sell a token from a specific wallet.
59
+
60
+ ```
61
+ "Sell all my tokens XYZ from wallet w1"
62
+ ```
63
+
64
+ **Parameters:** `walletId`, `mint`, `tokenAmount` (optional: `slippageBps`, `priorityLevel`)
65
+
66
+ ### OPENPUMP_CREATE_TOKEN
67
+
68
+ Create a new PumpFun token.
69
+
70
+ ```
71
+ "Create a token called DOGE3 with symbol D3 and this image URL"
72
+ ```
73
+
74
+ **Parameters:** `walletId`, `name`, `symbol`, `description`, `imageUrl` (optional: `twitter`, `telegram`, `website`)
75
+
76
+ ### OPENPUMP_GET_TOKEN_INFO
77
+
78
+ Get current price, market cap, and bonding curve state for a token.
79
+
80
+ ```
81
+ "What's the current price of token ABC?"
82
+ ```
83
+
84
+ **Parameters:** `mint`
85
+
86
+ ### OPENPUMP_LIST_WALLETS
87
+
88
+ List all managed wallets with their public keys and labels.
89
+
90
+ ```
91
+ "Show me my wallets"
92
+ ```
93
+
94
+ **Parameters:** None required.
95
+
96
+ ### OPENPUMP_GET_BALANCE
97
+
98
+ Get SOL balance and token positions for a specific wallet.
99
+
100
+ ```
101
+ "What's the balance of wallet w1?"
102
+ ```
103
+
104
+ **Parameters:** `walletId`
105
+
106
+ ### OPENPUMP_BUNDLE_BUY
107
+
108
+ Atomically create a token and execute coordinated multi-wallet buys using Jito MEV bundles.
109
+
110
+ ```
111
+ "Bundle launch token MOON with 3 sniper wallets buying 0.5 SOL each"
112
+ ```
113
+
114
+ **Parameters:** `devWalletId`, `buyWalletIds[]`, `name`, `symbol`, `description`, `imageUrl`, `devBuyAmountLamports`, `walletBuyAmounts[]`
115
+
116
+ ### OPENPUMP_SELL_ALL
117
+
118
+ Sell a token from ALL wallets that hold it.
119
+
120
+ ```
121
+ "Sell all positions in token XYZ across all wallets"
122
+ ```
123
+
124
+ **Parameters:** `mint`
125
+
126
+ ## Provider
127
+
128
+ ### WalletProvider
129
+
130
+ The `openpumpWalletProvider` automatically injects current portfolio state into the agent's context before each response. This gives the agent awareness of:
131
+
132
+ - All managed wallets with labels
133
+ - SOL balances per wallet
134
+ - Token positions with amounts
135
+ - Total portfolio summary
136
+
137
+ The provider runs automatically -- no configuration needed beyond the API key.
138
+
139
+ ## Advanced Usage
140
+
141
+ You can import individual components for custom integrations:
142
+
143
+ ```typescript
144
+ import {
145
+ openpumpPlugin,
146
+ buyTokenAction,
147
+ sellTokenAction,
148
+ walletProvider,
149
+ createApiClient,
150
+ getClient,
151
+ } from '@openpump/eliza-plugin';
152
+ ```
153
+
154
+ ### Custom API Client
155
+
156
+ ```typescript
157
+ import { createApiClient } from '@openpump/eliza-plugin';
158
+
159
+ const client = createApiClient('op_sk_live_...', 'https://api.openpump.io');
160
+ const res = await client.get('/api/wallets');
161
+ ```
162
+
163
+ ## Development
164
+
165
+ ```bash
166
+ # Install dependencies
167
+ pnpm install
168
+
169
+ # Run tests
170
+ pnpm test
171
+
172
+ # Type check
173
+ pnpm typecheck
174
+
175
+ # Build
176
+ pnpm build
177
+ ```
178
+
179
+ ## Architecture
180
+
181
+ The plugin follows a thin adapter pattern:
182
+
183
+ ```
184
+ ElizaOS Runtime
185
+ -> Plugin.init() validates API key
186
+ -> Action.validate() checks key exists
187
+ -> Action.handler() extracts params from message.content
188
+ -> ApiClient calls OpenPump REST API
189
+ -> Handler formats response as conversational text
190
+ -> Provider injects portfolio context into agent state
191
+ ```
192
+
193
+ Each action is stateless and uses a module-level API client cache keyed by agent ID. The plugin has zero runtime dependencies beyond `fetch` (available in Node 18+).
194
+
195
+ ## License
196
+
197
+ MIT
@@ -0,0 +1,125 @@
1
+ import { Plugin, IAgentRuntime, Provider, Action } from '@elizaos/core';
2
+
3
+ /**
4
+ * Thin typed wrapper for calling the OpenPump REST API from the ElizaOS plugin.
5
+ *
6
+ * Mirrors the pattern from `apps/mcp/src/lib/api-client.ts`.
7
+ * Authentication uses the raw API key (op_sk_live_...) as a Bearer token.
8
+ */
9
+ interface ApiClient {
10
+ get(path: string): Promise<Response>;
11
+ post(path: string, body: unknown): Promise<Response>;
12
+ }
13
+ /**
14
+ * Create an authenticated API client for the OpenPump REST API.
15
+ *
16
+ * @param apiKey - Raw API key string (op_sk_live_...) from character settings
17
+ * @param baseUrl - Base URL of the REST API (e.g. https://api.openpump.io)
18
+ */
19
+ declare function createApiClient(apiKey: string, baseUrl: string): ApiClient;
20
+
21
+ /**
22
+ * OpenPump ElizaOS plugin — main plugin definition.
23
+ *
24
+ * Exports a valid ElizaOS Plugin object with:
25
+ * - init() that validates the API key and pre-creates the client
26
+ * - 8 actions for trading, token management, and wallet queries
27
+ * - 1 provider for portfolio context injection
28
+ */
29
+
30
+ /**
31
+ * Retrieve or create an ApiClient for the given runtime.
32
+ * Called by action handlers and providers to get the authenticated client.
33
+ */
34
+ declare function getClient(runtime: IAgentRuntime): ApiClient;
35
+ /**
36
+ * Clear a cached client (useful for testing).
37
+ */
38
+ declare function clearClientCache(agentId?: string): void;
39
+ declare const openpumpPlugin: Plugin;
40
+
41
+ /**
42
+ * WalletProvider — Injects current wallet balances and token positions into agent state.
43
+ *
44
+ * This provider runs before each agent response turn, giving the agent awareness of
45
+ * the user's current portfolio. The text output is included in the agent's context
46
+ * so it can make informed trading decisions.
47
+ */
48
+
49
+ declare const walletProvider: Provider;
50
+
51
+ /**
52
+ * OPENPUMP_BUY_TOKEN action — Buy a PumpFun token with SOL.
53
+ *
54
+ * Calls POST /api/tokens/:mint/buy on the OpenPump REST API.
55
+ * Server-side signing — no local keypair needed.
56
+ */
57
+
58
+ declare const buyTokenAction: Action;
59
+
60
+ /**
61
+ * OPENPUMP_SELL_TOKEN action — Sell a PumpFun token back to SOL.
62
+ *
63
+ * Calls POST /api/tokens/:mint/sell on the OpenPump REST API.
64
+ * Use tokenAmount: "all" to sell the entire balance.
65
+ */
66
+
67
+ declare const sellTokenAction: Action;
68
+
69
+ /**
70
+ * OPENPUMP_CREATE_TOKEN action — Create a new PumpFun token with bonding curve.
71
+ *
72
+ * Calls POST /api/tokens/create on the OpenPump REST API.
73
+ * Uploads metadata and image to IPFS, then submits the creation transaction.
74
+ */
75
+
76
+ declare const createTokenAction: Action;
77
+
78
+ /**
79
+ * OPENPUMP_GET_TOKEN_INFO action — Get bonding curve state for a PumpFun token.
80
+ *
81
+ * Calls GET /api/tokens/:mint/curve-state on the OpenPump REST API.
82
+ * Read-only operation — no blockchain writes.
83
+ */
84
+
85
+ declare const getTokenInfoAction: Action;
86
+
87
+ /**
88
+ * OPENPUMP_LIST_WALLETS action — List all managed wallets.
89
+ *
90
+ * Calls GET /api/wallets on the OpenPump REST API.
91
+ * Read-only operation — returns wallet IDs, public keys, and labels.
92
+ */
93
+
94
+ declare const listWalletsAction: Action;
95
+
96
+ /**
97
+ * OPENPUMP_GET_BALANCE action — Get SOL and token balances for a wallet.
98
+ *
99
+ * Calls GET /api/wallets/:id/balance on the OpenPump REST API.
100
+ * Read-only operation — returns real-time on-chain data.
101
+ */
102
+
103
+ declare const getBalanceAction: Action;
104
+
105
+ /**
106
+ * OPENPUMP_BUNDLE_BUY action — Create a token + coordinated multi-wallet buy.
107
+ *
108
+ * Calls POST /api/tokens/bundle-launch on the OpenPump REST API.
109
+ * Async operation — returns a jobId for progress tracking.
110
+ * Uses Jito MEV bundles for same-block execution.
111
+ */
112
+
113
+ declare const bundleBuyAction: Action;
114
+
115
+ /**
116
+ * OPENPUMP_SELL_ALL action — Sell a token from all wallets that hold it.
117
+ *
118
+ * Iterates through all managed wallets, checks holdings, then calls
119
+ * POST /api/tokens/:mint/sell for each wallet holding the token.
120
+ * Useful for exiting all positions in a single conversational command.
121
+ */
122
+
123
+ declare const sellAllAction: Action;
124
+
125
+ export { type ApiClient, bundleBuyAction, buyTokenAction, clearClientCache, createApiClient, createTokenAction, openpumpPlugin as default, getBalanceAction, getClient, getTokenInfoAction, listWalletsAction, openpumpPlugin, sellAllAction, sellTokenAction, walletProvider };
package/dist/index.js ADDED
@@ -0,0 +1,781 @@
1
+ // src/actions/buy-token.ts
2
+ var buyTokenAction = {
3
+ name: "OPENPUMP_BUY_TOKEN",
4
+ similes: ["BUY_TOKEN", "PURCHASE_TOKEN", "SWAP_SOL_FOR_TOKEN", "BUY_PUMPFUN"],
5
+ description: "Buy a PumpFun token with SOL from an OpenPump managed wallet. Requires wallet ID, token mint address, and SOL amount in lamports. Uses server-side signing (no local keypair needed).",
6
+ examples: [
7
+ [
8
+ { name: "user", content: { text: "Buy 0.5 SOL of token ABC123mint from wallet-1" } },
9
+ { name: "agent", content: { text: "Executing buy order for 0.5 SOL of token ABC123mint from wallet-1..." } }
10
+ ],
11
+ [
12
+ { name: "user", content: { text: "Use my sniper wallet to buy 0.1 SOL of that new token" } },
13
+ { name: "agent", content: { text: "Buying 0.1 SOL worth of tokens using your sniper wallet..." } }
14
+ ]
15
+ ],
16
+ validate: (runtime, _message, _state) => {
17
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
18
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
19
+ },
20
+ handler: async (runtime, message, _state, _options, callback) => {
21
+ try {
22
+ const client = getClient(runtime);
23
+ const content = message.content;
24
+ const walletId = content["walletId"];
25
+ const mint = content["mint"];
26
+ const amountLamports = content["amountLamports"];
27
+ const slippageBps = content["slippageBps"];
28
+ const priorityLevel = content["priorityLevel"] ?? "normal";
29
+ if (!walletId || !mint || !amountLamports) {
30
+ if (callback) {
31
+ await callback({
32
+ text: "I need the wallet ID, token mint address, and SOL amount in lamports to execute a buy. Could you provide those details?",
33
+ actions: ["OPENPUMP_BUY_TOKEN"]
34
+ });
35
+ }
36
+ return { success: false, error: "Missing required parameters: walletId, mint, amountLamports" };
37
+ }
38
+ const body = {
39
+ walletId,
40
+ amountLamports,
41
+ priorityLevel
42
+ };
43
+ if (slippageBps !== void 0) body["slippageBps"] = slippageBps;
44
+ const res = await client.post(`/api/tokens/${mint}/buy`, body);
45
+ if (!res.ok) {
46
+ const errText = await res.text();
47
+ const errorMsg = `Buy failed (HTTP ${String(res.status)}): ${errText}`;
48
+ if (callback) {
49
+ await callback({ text: errorMsg, actions: ["OPENPUMP_BUY_TOKEN"] });
50
+ }
51
+ return { success: false, error: errorMsg };
52
+ }
53
+ const data = await res.json();
54
+ const solAmount = (Number(amountLamports) / 1e9).toFixed(4);
55
+ const sig = typeof data["signature"] === "string" ? data["signature"] : "pending";
56
+ const successMsg = `Buy order executed successfully.
57
+ Spent: ${solAmount} SOL
58
+ Token: ${mint}
59
+ Signature: ${sig}`;
60
+ if (callback) {
61
+ await callback({ text: successMsg, actions: ["OPENPUMP_BUY_TOKEN"] });
62
+ }
63
+ return { success: true, text: successMsg, data };
64
+ } catch (error) {
65
+ const errMsg = `Buy request failed: ${error instanceof Error ? error.message : String(error)}`;
66
+ if (callback) {
67
+ await callback({ text: errMsg, actions: ["OPENPUMP_BUY_TOKEN"] });
68
+ }
69
+ return { success: false, error: errMsg };
70
+ }
71
+ }
72
+ };
73
+
74
+ // src/actions/sell-token.ts
75
+ var sellTokenAction = {
76
+ name: "OPENPUMP_SELL_TOKEN",
77
+ similes: ["SELL_TOKEN", "DUMP_TOKEN", "SWAP_TOKEN_FOR_SOL", "SELL_PUMPFUN"],
78
+ description: 'Sell a PumpFun token back to SOL from an OpenPump managed wallet. Use tokenAmount: "all" to sell the entire balance.',
79
+ examples: [
80
+ [
81
+ { name: "user", content: { text: "Sell all of token XYZ from wallet-2" } },
82
+ { name: "agent", content: { text: "Selling entire balance of token XYZ from wallet-2..." } }
83
+ ],
84
+ [
85
+ { name: "user", content: { text: "Dump 50% of that token we just bought" } },
86
+ { name: "agent", content: { text: "Selling half of your token position..." } }
87
+ ]
88
+ ],
89
+ validate: (runtime, _message, _state) => {
90
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
91
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
92
+ },
93
+ handler: async (runtime, message, _state, _options, callback) => {
94
+ try {
95
+ const client = getClient(runtime);
96
+ const content = message.content;
97
+ const walletId = content["walletId"];
98
+ const mint = content["mint"];
99
+ const tokenAmount = content["tokenAmount"] ?? "all";
100
+ const slippageBps = content["slippageBps"];
101
+ const priorityLevel = content["priorityLevel"] ?? "normal";
102
+ if (!walletId || !mint) {
103
+ if (callback) {
104
+ await callback({
105
+ text: "I need the wallet ID and token mint address to execute a sell. Could you provide those?",
106
+ actions: ["OPENPUMP_SELL_TOKEN"]
107
+ });
108
+ }
109
+ return { success: false, error: "Missing required parameters: walletId, mint" };
110
+ }
111
+ const body = { walletId, tokenAmount, priorityLevel };
112
+ if (slippageBps !== void 0) body["slippageBps"] = slippageBps;
113
+ const res = await client.post(`/api/tokens/${mint}/sell`, body);
114
+ if (!res.ok) {
115
+ const errText = await res.text();
116
+ const errorMsg = `Sell failed (HTTP ${String(res.status)}): ${errText}`;
117
+ if (callback) await callback({ text: errorMsg, actions: ["OPENPUMP_SELL_TOKEN"] });
118
+ return { success: false, error: errorMsg };
119
+ }
120
+ const data = await res.json();
121
+ const sig = typeof data["signature"] === "string" ? data["signature"] : "pending";
122
+ const successMsg = `Sell order executed successfully.
123
+ Token: ${mint}
124
+ Amount: ${tokenAmount === "all" ? "entire balance" : tokenAmount}
125
+ Signature: ${sig}`;
126
+ if (callback) await callback({ text: successMsg, actions: ["OPENPUMP_SELL_TOKEN"] });
127
+ return { success: true, text: successMsg, data };
128
+ } catch (error) {
129
+ const errMsg = `Sell request failed: ${error instanceof Error ? error.message : String(error)}`;
130
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_SELL_TOKEN"] });
131
+ return { success: false, error: errMsg };
132
+ }
133
+ }
134
+ };
135
+
136
+ // src/actions/create-token.ts
137
+ function resolveImageType(contentType) {
138
+ if (contentType.includes("jpeg")) return "image/jpeg";
139
+ if (contentType.includes("gif")) return "image/gif";
140
+ return "image/png";
141
+ }
142
+ var createTokenAction = {
143
+ name: "OPENPUMP_CREATE_TOKEN",
144
+ similes: ["CREATE_TOKEN", "LAUNCH_TOKEN", "DEPLOY_TOKEN", "MINT_TOKEN"],
145
+ description: "Create a new PumpFun token with a bonding curve. Uploads metadata and image to IPFS, then submits the creation transaction. Returns mint address and signature.",
146
+ examples: [
147
+ [
148
+ { name: "user", content: { text: 'Launch a token called DOGE2 with symbol D2, description "The next doge", use wallet-1' } },
149
+ { name: "agent", content: { text: "Creating token DOGE2 (D2) on PumpFun..." } }
150
+ ],
151
+ [
152
+ { name: "user", content: { text: "Create a meme token named PEPE3 with my dev wallet" } },
153
+ { name: "agent", content: { text: "Deploying new PumpFun token PEPE3..." } }
154
+ ]
155
+ ],
156
+ validate: (runtime, _message, _state) => {
157
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
158
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
159
+ },
160
+ handler: async (runtime, message, _state, _options, callback) => {
161
+ try {
162
+ const client = getClient(runtime);
163
+ const content = message.content;
164
+ const walletId = content["walletId"];
165
+ const name = content["name"];
166
+ const symbol = content["symbol"];
167
+ const description = content["description"];
168
+ const imageUrl = content["imageUrl"];
169
+ if (!walletId || !name || !symbol || !description || !imageUrl) {
170
+ if (callback) {
171
+ await callback({
172
+ text: "To create a token I need: wallet ID, token name, symbol, description, and an image URL.",
173
+ actions: ["OPENPUMP_CREATE_TOKEN"]
174
+ });
175
+ }
176
+ return { success: false, error: "Missing required parameters: walletId, name, symbol, description, imageUrl" };
177
+ }
178
+ const imageRes = await fetch(imageUrl);
179
+ if (!imageRes.ok) {
180
+ const errMsg = `Failed to fetch token image from ${imageUrl}: HTTP ${String(imageRes.status)}`;
181
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_CREATE_TOKEN"] });
182
+ return { success: false, error: errMsg };
183
+ }
184
+ const imageBuffer = await imageRes.arrayBuffer();
185
+ const imageBase64 = Buffer.from(imageBuffer).toString("base64");
186
+ const contentType = imageRes.headers.get("content-type") ?? "image/png";
187
+ const body = {
188
+ walletId,
189
+ name,
190
+ symbol,
191
+ description,
192
+ imageBase64,
193
+ imageType: resolveImageType(contentType)
194
+ };
195
+ if (content["twitter"]) body["twitter"] = content["twitter"];
196
+ if (content["telegram"]) body["telegram"] = content["telegram"];
197
+ if (content["website"]) body["website"] = content["website"];
198
+ if (content["initialBuyAmountSol"]) body["initialBuyAmountSol"] = content["initialBuyAmountSol"];
199
+ const res = await client.post("/api/tokens/create", body);
200
+ if (!res.ok) {
201
+ const errText = await res.text();
202
+ const errorMsg = `Token creation failed (HTTP ${String(res.status)}): ${errText}`;
203
+ if (callback) await callback({ text: errorMsg, actions: ["OPENPUMP_CREATE_TOKEN"] });
204
+ return { success: false, error: errorMsg };
205
+ }
206
+ const data = await res.json();
207
+ const mintAddr = typeof data["mint"] === "string" ? data["mint"] : "pending";
208
+ const sig = typeof data["signature"] === "string" ? data["signature"] : "pending";
209
+ const successMsg = `Token created successfully!
210
+ Name: ${name} (${symbol})
211
+ Mint: ${mintAddr}
212
+ Signature: ${sig}`;
213
+ if (callback) await callback({ text: successMsg, actions: ["OPENPUMP_CREATE_TOKEN"] });
214
+ return { success: true, text: successMsg, data };
215
+ } catch (error) {
216
+ const errMsg = `Token creation failed: ${error instanceof Error ? error.message : String(error)}`;
217
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_CREATE_TOKEN"] });
218
+ return { success: false, error: errMsg };
219
+ }
220
+ }
221
+ };
222
+
223
+ // src/actions/get-token-info.ts
224
+ var getTokenInfoAction = {
225
+ name: "OPENPUMP_GET_TOKEN_INFO",
226
+ similes: ["GET_TOKEN_INFO", "TOKEN_INFO", "CHECK_TOKEN", "TOKEN_PRICE", "TOKEN_STATUS"],
227
+ description: "Get current info about a PumpFun token: name, symbol, price, market cap, bonding curve progress, and graduation status. Read-only \u2014 no transaction submitted.",
228
+ examples: [
229
+ [
230
+ { name: "user", content: { text: "What is the price of token ABC123mint?" } },
231
+ { name: "agent", content: { text: "Looking up token ABC123mint on PumpFun..." } }
232
+ ],
233
+ [
234
+ { name: "user", content: { text: "Check the bonding curve progress for that new token" } },
235
+ { name: "agent", content: { text: "Fetching bonding curve state..." } }
236
+ ]
237
+ ],
238
+ validate: (runtime, _message, _state) => {
239
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
240
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
241
+ },
242
+ handler: async (runtime, message, _state, _options, callback) => {
243
+ try {
244
+ const client = getClient(runtime);
245
+ const content = message.content;
246
+ const mint = content["mint"];
247
+ if (!mint) {
248
+ if (callback) {
249
+ await callback({
250
+ text: "I need the token mint address to look up its info. Could you provide the mint address?",
251
+ actions: ["OPENPUMP_GET_TOKEN_INFO"]
252
+ });
253
+ }
254
+ return { success: false, error: "Missing required parameter: mint" };
255
+ }
256
+ const res = await client.get(`/api/tokens/${mint}/curve-state`);
257
+ if (!res.ok) {
258
+ const errText = await res.text();
259
+ const errorMsg = res.status === 404 ? `Token with mint "${mint}" was not found on PumpFun. Please verify the mint address.` : `Failed to fetch token info (HTTP ${String(res.status)}): ${errText}`;
260
+ if (callback) await callback({ text: errorMsg, actions: ["OPENPUMP_GET_TOKEN_INFO"] });
261
+ return { success: false, error: errorMsg };
262
+ }
263
+ const data = await res.json();
264
+ const s = (val) => typeof val === "string" || typeof val === "number" || typeof val === "boolean" ? String(val) : JSON.stringify(val);
265
+ const lines = [`Token Info for ${mint}:`];
266
+ if (data["name"]) lines.push(` Name: ${s(data["name"])}`);
267
+ if (data["symbol"]) lines.push(` Symbol: ${s(data["symbol"])}`);
268
+ if (data["priceSOL"] !== void 0) lines.push(` Price: ${s(data["priceSOL"])} SOL`);
269
+ if (data["marketCapSOL"] !== void 0) lines.push(` Market Cap: ${s(data["marketCapSOL"])} SOL`);
270
+ if (data["bondingCurveProgress"] !== void 0) lines.push(` Bonding Curve: ${s(data["bondingCurveProgress"])}%`);
271
+ if (data["graduated"] !== void 0) lines.push(` Graduated: ${s(data["graduated"])}`);
272
+ const successMsg = lines.join("\n");
273
+ if (callback) await callback({ text: successMsg, actions: ["OPENPUMP_GET_TOKEN_INFO"] });
274
+ return { success: true, text: successMsg, data };
275
+ } catch (error) {
276
+ const errMsg = `Token info fetch failed: ${error instanceof Error ? error.message : String(error)}`;
277
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_GET_TOKEN_INFO"] });
278
+ return { success: false, error: errMsg };
279
+ }
280
+ }
281
+ };
282
+
283
+ // src/actions/list-wallets.ts
284
+ var listWalletsAction = {
285
+ name: "OPENPUMP_LIST_WALLETS",
286
+ similes: ["LIST_WALLETS", "SHOW_WALLETS", "MY_WALLETS", "GET_WALLETS"],
287
+ description: "List all OpenPump managed wallets for the authenticated user. Returns wallet IDs, public keys, and labels. Use GET_BALANCE for live SOL balances.",
288
+ examples: [
289
+ [
290
+ { name: "user", content: { text: "Show me my wallets" } },
291
+ { name: "agent", content: { text: "Fetching your OpenPump wallets..." } }
292
+ ],
293
+ [
294
+ { name: "user", content: { text: "Which wallets do I have?" } },
295
+ { name: "agent", content: { text: "Looking up your managed wallets..." } }
296
+ ]
297
+ ],
298
+ validate: (runtime, _message, _state) => {
299
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
300
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
301
+ },
302
+ handler: async (runtime, _message, _state, _options, callback) => {
303
+ try {
304
+ const client = getClient(runtime);
305
+ const res = await client.get("/api/wallets");
306
+ if (!res.ok) {
307
+ const errText = await res.text();
308
+ const errorMsg = `Failed to fetch wallets (HTTP ${String(res.status)}): ${errText}`;
309
+ if (callback) await callback({ text: errorMsg, actions: ["OPENPUMP_LIST_WALLETS"] });
310
+ return { success: false, error: errorMsg };
311
+ }
312
+ const body = await res.json();
313
+ const wallets = body.data ?? [];
314
+ if (wallets.length === 0) {
315
+ const msg = "No wallets found for your account.";
316
+ if (callback) await callback({ text: msg, actions: ["OPENPUMP_LIST_WALLETS"] });
317
+ return { success: true, text: msg, data: { wallets: [] } };
318
+ }
319
+ const lines = [`You have ${String(wallets.length)} wallet(s):`];
320
+ for (const w of wallets) {
321
+ const label = w.label ? ` "${w.label}"` : "";
322
+ lines.push(` - ${w.id}${label}: ${w.publicKey}`);
323
+ }
324
+ const successMsg = lines.join("\n");
325
+ if (callback) await callback({ text: successMsg, actions: ["OPENPUMP_LIST_WALLETS"] });
326
+ return { success: true, text: successMsg, data: { wallets } };
327
+ } catch (error) {
328
+ const errMsg = `Wallet list failed: ${error instanceof Error ? error.message : String(error)}`;
329
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_LIST_WALLETS"] });
330
+ return { success: false, error: errMsg };
331
+ }
332
+ }
333
+ };
334
+
335
+ // src/actions/get-balance.ts
336
+ var getBalanceAction = {
337
+ name: "OPENPUMP_GET_BALANCE",
338
+ similes: ["GET_BALANCE", "CHECK_BALANCE", "WALLET_BALANCE", "SOL_BALANCE"],
339
+ description: "Get the SOL balance and all token balances held by the specified OpenPump wallet. Returns real-time on-chain data.",
340
+ examples: [
341
+ [
342
+ { name: "user", content: { text: "Check the balance of wallet-1" } },
343
+ { name: "agent", content: { text: "Fetching balance for wallet-1..." } }
344
+ ],
345
+ [
346
+ { name: "user", content: { text: "How much SOL is in my sniper wallet?" } },
347
+ { name: "agent", content: { text: "Looking up your sniper wallet balance..." } }
348
+ ]
349
+ ],
350
+ validate: (runtime, _message, _state) => {
351
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
352
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
353
+ },
354
+ handler: async (runtime, message, _state, _options, callback) => {
355
+ try {
356
+ const client = getClient(runtime);
357
+ const content = message.content;
358
+ const walletId = content["walletId"];
359
+ if (!walletId) {
360
+ if (callback) {
361
+ await callback({
362
+ text: "I need the wallet ID to check its balance. Use LIST_WALLETS to see available wallets.",
363
+ actions: ["OPENPUMP_GET_BALANCE"]
364
+ });
365
+ }
366
+ return { success: false, error: "Missing required parameter: walletId" };
367
+ }
368
+ const res = await client.get(`/api/wallets/${walletId}/balance`);
369
+ if (!res.ok) {
370
+ const errText = await res.text();
371
+ const errorMsg = res.status === 404 ? `Wallet "${walletId}" not found. Use LIST_WALLETS to see available wallet IDs.` : `Failed to fetch balance (HTTP ${String(res.status)}): ${errText}`;
372
+ if (callback) await callback({ text: errorMsg, actions: ["OPENPUMP_GET_BALANCE"] });
373
+ return { success: false, error: errorMsg };
374
+ }
375
+ const body = await res.json();
376
+ const data = body.data;
377
+ const lines = [`Wallet ${walletId} Balance:`];
378
+ lines.push(` SOL: ${data.solBalance}`);
379
+ const tokenPositions = data.tokenBalances.filter(
380
+ (tb) => tb.uiAmount === null ? tb.amount !== "0" : tb.uiAmount > 0
381
+ );
382
+ if (tokenPositions.length > 0) {
383
+ lines.push(` Token Positions (${String(tokenPositions.length)}):`);
384
+ for (const tb of tokenPositions) {
385
+ lines.push(` - ${tb.mint}: ${String(tb.uiAmount ?? tb.amount)}`);
386
+ }
387
+ } else {
388
+ lines.push(" No token positions");
389
+ }
390
+ const successMsg = lines.join("\n");
391
+ if (callback) await callback({ text: successMsg, actions: ["OPENPUMP_GET_BALANCE"] });
392
+ return { success: true, text: successMsg, data };
393
+ } catch (error) {
394
+ const errMsg = `Balance fetch failed: ${error instanceof Error ? error.message : String(error)}`;
395
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_GET_BALANCE"] });
396
+ return { success: false, error: errMsg };
397
+ }
398
+ }
399
+ };
400
+
401
+ // src/actions/bundle-buy.ts
402
+ function resolveImageType2(contentType) {
403
+ if (contentType.includes("jpeg")) return "image/jpeg";
404
+ if (contentType.includes("gif")) return "image/gif";
405
+ return "image/png";
406
+ }
407
+ var bundleBuyAction = {
408
+ name: "OPENPUMP_BUNDLE_BUY",
409
+ similes: ["BUNDLE_BUY", "BUNDLE_LAUNCH", "COORDINATED_BUY", "MULTI_WALLET_BUY"],
410
+ description: "Atomically create a new PumpFun token and execute coordinated buys from multiple wallets using Jito MEV bundles. Returns a jobId for async tracking. LEGAL WARNING: Coordinated bundle buying may be subject to legal restrictions in your jurisdiction.",
411
+ examples: [
412
+ [
413
+ { name: "user", content: { text: "Bundle launch a token DOGE3 with 3 sniper wallets buying 0.5 SOL each" } },
414
+ { name: "agent", content: { text: "Preparing bundle launch for DOGE3 with 3 coordinated buy wallets..." } }
415
+ ],
416
+ [
417
+ { name: "user", content: { text: "Do a coordinated buy with my dev wallet and 2 buy wallets" } },
418
+ { name: "agent", content: { text: "Setting up Jito MEV bundle for coordinated token launch..." } }
419
+ ]
420
+ ],
421
+ validate: (runtime, _message, _state) => {
422
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
423
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
424
+ },
425
+ handler: async (runtime, message, _state, _options, callback) => {
426
+ try {
427
+ const client = getClient(runtime);
428
+ const content = message.content;
429
+ const devWalletId = content["devWalletId"];
430
+ const buyWalletIds = content["buyWalletIds"];
431
+ const name = content["name"];
432
+ const symbol = content["symbol"];
433
+ const description = content["description"];
434
+ const imageUrl = content["imageUrl"];
435
+ const devBuyAmountLamports = content["devBuyAmountLamports"];
436
+ const walletBuyAmounts = content["walletBuyAmounts"];
437
+ if (!devWalletId || !buyWalletIds || !name || !symbol || !description || !imageUrl || !devBuyAmountLamports || !walletBuyAmounts) {
438
+ if (callback) {
439
+ await callback({
440
+ text: "Bundle launch requires: devWalletId, buyWalletIds[], token name, symbol, description, imageUrl, devBuyAmountLamports, and walletBuyAmounts[]. Please provide all parameters.",
441
+ actions: ["OPENPUMP_BUNDLE_BUY"]
442
+ });
443
+ }
444
+ return { success: false, error: "Missing required parameters for bundle launch" };
445
+ }
446
+ const imageRes = await fetch(imageUrl);
447
+ if (!imageRes.ok) {
448
+ const errMsg = `Failed to fetch token image from ${imageUrl}: HTTP ${String(imageRes.status)}`;
449
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_BUNDLE_BUY"] });
450
+ return { success: false, error: errMsg };
451
+ }
452
+ const imageBuffer = await imageRes.arrayBuffer();
453
+ const imageBase64 = Buffer.from(imageBuffer).toString("base64");
454
+ const imgContentType = imageRes.headers.get("content-type") ?? "image/png";
455
+ const body = {
456
+ devWalletId,
457
+ buyWalletIds,
458
+ name,
459
+ symbol,
460
+ description,
461
+ imageBase64,
462
+ imageType: resolveImageType2(imgContentType),
463
+ devBuyAmountLamports,
464
+ walletBuyAmounts,
465
+ tipLamports: 5e4
466
+ // Default normal priority
467
+ };
468
+ const res = await client.post("/api/tokens/bundle-launch", body);
469
+ if (!res.ok) {
470
+ const errText = await res.text();
471
+ const errorMsg = `Bundle launch failed (HTTP ${String(res.status)}): ${errText}`;
472
+ if (callback) await callback({ text: errorMsg, actions: ["OPENPUMP_BUNDLE_BUY"] });
473
+ return { success: false, error: errorMsg };
474
+ }
475
+ const data = await res.json();
476
+ const successMsg = `Bundle launch submitted successfully!
477
+ Job ID: ${String(data.jobId ?? "unknown")}
478
+ Token: ${name} (${symbol})
479
+ Dev wallet: ${devWalletId}
480
+ Buy wallets: ${String(buyWalletIds.length)}
481
+ Track progress with the job ID.`;
482
+ if (callback) await callback({ text: successMsg, actions: ["OPENPUMP_BUNDLE_BUY"] });
483
+ return { success: true, text: successMsg, data };
484
+ } catch (error) {
485
+ const errMsg = `Bundle launch failed: ${error instanceof Error ? error.message : String(error)}`;
486
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_BUNDLE_BUY"] });
487
+ return { success: false, error: errMsg };
488
+ }
489
+ }
490
+ };
491
+
492
+ // src/actions/sell-all.ts
493
+ var sellAllAction = {
494
+ name: "OPENPUMP_SELL_ALL",
495
+ similes: ["SELL_ALL", "EXIT_ALL_POSITIONS", "DUMP_ALL", "SELL_EVERYTHING"],
496
+ description: "Sell a token from ALL wallets that hold it. Iterates through your managed wallets, finds those holding the specified token, and sells the entire balance from each. Returns results per wallet.",
497
+ examples: [
498
+ [
499
+ { name: "user", content: { text: "Sell all positions in token XYZ across all wallets" } },
500
+ { name: "agent", content: { text: "Selling token XYZ from all wallets that hold it..." } }
501
+ ],
502
+ [
503
+ { name: "user", content: { text: "Exit all my positions in that token" } },
504
+ { name: "agent", content: { text: "Finding all wallets holding the token and selling..." } }
505
+ ]
506
+ ],
507
+ validate: (runtime, _message, _state) => {
508
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
509
+ return Promise.resolve(typeof apiKey === "string" && apiKey.length > 0);
510
+ },
511
+ handler: async (runtime, message, _state, _options, callback) => {
512
+ try {
513
+ const client = getClient(runtime);
514
+ const content = message.content;
515
+ const mint = content["mint"];
516
+ if (!mint) {
517
+ if (callback) {
518
+ await callback({
519
+ text: "I need the token mint address to sell all positions. Could you provide it?",
520
+ actions: ["OPENPUMP_SELL_ALL"]
521
+ });
522
+ }
523
+ return { success: false, error: "Missing required parameter: mint" };
524
+ }
525
+ const walletsRes = await client.get("/api/wallets");
526
+ if (!walletsRes.ok) {
527
+ const errMsg = `Failed to fetch wallets: HTTP ${String(walletsRes.status)}`;
528
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_SELL_ALL"] });
529
+ return { success: false, error: errMsg };
530
+ }
531
+ const walletsBody = await walletsRes.json();
532
+ const wallets = walletsBody.data ?? [];
533
+ if (wallets.length === 0) {
534
+ const msg = "No wallets found. Nothing to sell.";
535
+ if (callback) await callback({ text: msg, actions: ["OPENPUMP_SELL_ALL"] });
536
+ return { success: true, text: msg, data: { results: [] } };
537
+ }
538
+ const balanceResults = await Promise.allSettled(
539
+ wallets.map(async (w) => {
540
+ const res = await client.get(`/api/wallets/${w.id}/balance`);
541
+ if (!res.ok) return null;
542
+ const body = await res.json();
543
+ const holding = body.data.tokenBalances.find((tb) => tb.mint === mint);
544
+ if (!holding) return null;
545
+ const hasBalance = holding.uiAmount === null ? holding.amount !== "0" : holding.uiAmount > 0;
546
+ if (!hasBalance) return null;
547
+ return { walletId: w.id, label: w.label, amount: holding.amount };
548
+ })
549
+ );
550
+ const holders = balanceResults.filter(
551
+ (r) => r.status === "fulfilled"
552
+ ).map((r) => r.value).filter((v) => v !== null);
553
+ if (holders.length === 0) {
554
+ const msg = `No wallets hold token ${mint}. Nothing to sell.`;
555
+ if (callback) await callback({ text: msg, actions: ["OPENPUMP_SELL_ALL"] });
556
+ return { success: true, text: msg, data: { results: [] } };
557
+ }
558
+ const sellResults = [];
559
+ for (const holder of holders) {
560
+ try {
561
+ const sellRes = await client.post(`/api/tokens/${mint}/sell`, {
562
+ walletId: holder.walletId,
563
+ tokenAmount: "all",
564
+ priorityLevel: "normal"
565
+ });
566
+ if (sellRes.ok) {
567
+ const sellData = await sellRes.json();
568
+ const sig = typeof sellData["signature"] === "string" ? sellData["signature"] : "pending";
569
+ sellResults.push({
570
+ walletId: holder.walletId,
571
+ success: true,
572
+ signature: sig
573
+ });
574
+ } else {
575
+ const errText = await sellRes.text();
576
+ sellResults.push({
577
+ walletId: holder.walletId,
578
+ success: false,
579
+ error: `HTTP ${String(sellRes.status)}: ${errText}`
580
+ });
581
+ }
582
+ } catch (error) {
583
+ sellResults.push({
584
+ walletId: holder.walletId,
585
+ success: false,
586
+ error: error instanceof Error ? error.message : String(error)
587
+ });
588
+ }
589
+ }
590
+ const successCount = sellResults.filter((r) => r.success).length;
591
+ const failCount = sellResults.length - successCount;
592
+ const lines = [`Sell-all results for token ${mint}:`];
593
+ for (const r of sellResults) {
594
+ if (r.success) {
595
+ lines.push(` ${r.walletId}: SOLD (sig: ${r.signature ?? "pending"})`);
596
+ } else {
597
+ lines.push(` ${r.walletId}: FAILED (${r.error ?? "unknown error"})`);
598
+ }
599
+ }
600
+ lines.push(`Summary: ${String(successCount)} succeeded, ${String(failCount)} failed`);
601
+ const successMsg = lines.join("\n");
602
+ if (callback) await callback({ text: successMsg, actions: ["OPENPUMP_SELL_ALL"] });
603
+ return { success: failCount === 0, text: successMsg, data: { results: sellResults } };
604
+ } catch (error) {
605
+ const errMsg = `Sell-all failed: ${error instanceof Error ? error.message : String(error)}`;
606
+ if (callback) await callback({ text: errMsg, actions: ["OPENPUMP_SELL_ALL"] });
607
+ return { success: false, error: errMsg };
608
+ }
609
+ }
610
+ };
611
+
612
+ // src/providers/wallet-provider.ts
613
+ var walletProvider = {
614
+ name: "openpumpWalletProvider",
615
+ description: "Provides current OpenPump managed wallet balances and token positions for portfolio awareness",
616
+ dynamic: true,
617
+ position: 10,
618
+ get: async (runtime, _message, _state) => {
619
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
620
+ if (!apiKey) {
621
+ return { text: "", data: {}, values: {} };
622
+ }
623
+ try {
624
+ const client = getClient(runtime);
625
+ const walletsRes = await client.get("/api/wallets");
626
+ if (!walletsRes.ok) {
627
+ return { text: "OpenPump: Unable to fetch wallets", data: {}, values: {} };
628
+ }
629
+ const walletsData = await walletsRes.json();
630
+ const wallets = walletsData.data ?? [];
631
+ if (wallets.length === 0) {
632
+ return {
633
+ text: "OpenPump Portfolio: No wallets configured.",
634
+ data: { wallets: [] },
635
+ values: { walletCount: 0 }
636
+ };
637
+ }
638
+ const balanceResults = await Promise.allSettled(
639
+ wallets.map(async (w) => {
640
+ const res = await client.get(`/api/wallets/${w.id}/balance`);
641
+ if (!res.ok) throw new Error(`HTTP ${String(res.status)}`);
642
+ const body = await res.json();
643
+ return {
644
+ walletId: w.id,
645
+ publicKey: w.publicKey,
646
+ label: w.label,
647
+ solBalance: body.data.solBalance,
648
+ lamports: body.data.lamports,
649
+ tokenBalances: body.data.tokenBalances
650
+ };
651
+ })
652
+ );
653
+ const balances = balanceResults.filter((r) => r.status === "fulfilled").map((r) => r.value);
654
+ const lines = ["OpenPump Portfolio:"];
655
+ let totalSol = 0;
656
+ let totalTokenPositions = 0;
657
+ for (const b of balances) {
658
+ const sol = Number.parseFloat(b.solBalance);
659
+ totalSol += sol;
660
+ const label = b.label ? ` "${b.label}"` : "";
661
+ lines.push(` Wallet${label} (${b.walletId}): ${b.solBalance} SOL`);
662
+ for (const tb of b.tokenBalances) {
663
+ if (tb.uiAmount !== null && tb.uiAmount > 0) {
664
+ totalTokenPositions++;
665
+ lines.push(` - Token ${tb.mint}: ${String(tb.uiAmount)} (raw: ${tb.amount})`);
666
+ }
667
+ }
668
+ }
669
+ lines.push(
670
+ `Total: ${totalSol.toFixed(4)} SOL across ${String(wallets.length)} wallets, ${String(totalTokenPositions)} token positions`
671
+ );
672
+ return {
673
+ text: lines.join("\n"),
674
+ data: { wallets: balances },
675
+ values: {
676
+ walletCount: wallets.length,
677
+ totalSol: totalSol.toFixed(4),
678
+ totalTokenPositions
679
+ }
680
+ };
681
+ } catch (error) {
682
+ return {
683
+ text: `OpenPump: Portfolio fetch failed (${error instanceof Error ? error.message : String(error)})`,
684
+ data: {},
685
+ values: {}
686
+ };
687
+ }
688
+ }
689
+ };
690
+
691
+ // src/lib/api-client.ts
692
+ function createApiClient(apiKey, baseUrl) {
693
+ const authHeader = "Bearer " + apiKey;
694
+ return {
695
+ async get(path) {
696
+ return fetch(baseUrl + path, {
697
+ headers: { Authorization: authHeader }
698
+ });
699
+ },
700
+ async post(path, body) {
701
+ return fetch(baseUrl + path, {
702
+ method: "POST",
703
+ headers: {
704
+ Authorization: authHeader,
705
+ "Content-Type": "application/json"
706
+ },
707
+ body: JSON.stringify(body)
708
+ });
709
+ }
710
+ };
711
+ }
712
+
713
+ // src/plugin.ts
714
+ var clientCache = /* @__PURE__ */ new Map();
715
+ function getClient(runtime) {
716
+ const agentId = runtime.agentId;
717
+ const cached = clientCache.get(agentId);
718
+ if (cached) {
719
+ return cached;
720
+ }
721
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
722
+ const baseUrl = runtime.getSetting("OPENPUMP_API_URL");
723
+ if (!apiKey || typeof apiKey !== "string") {
724
+ throw new Error("OPENPUMP_API_KEY not configured in character settings");
725
+ }
726
+ const client = createApiClient(apiKey, typeof baseUrl === "string" ? baseUrl : "https://api.openpump.io");
727
+ clientCache.set(agentId, client);
728
+ return client;
729
+ }
730
+ function clearClientCache(agentId) {
731
+ if (agentId) {
732
+ clientCache.delete(agentId);
733
+ } else {
734
+ clientCache.clear();
735
+ }
736
+ }
737
+ var openpumpPlugin = {
738
+ name: "openpump",
739
+ description: "Buy, sell, and launch PumpFun tokens via the OpenPump managed wallet API. Provides trading actions and portfolio context for conversational AI agents.",
740
+ init: (_config, runtime) => {
741
+ const apiKey = runtime.getSetting("OPENPUMP_API_KEY");
742
+ if (!apiKey || typeof apiKey !== "string") {
743
+ throw new Error(
744
+ "OpenPump plugin requires OPENPUMP_API_KEY in character settings. Add it to settings.secrets.OPENPUMP_API_KEY in your character JSON."
745
+ );
746
+ }
747
+ const rawBaseUrl = runtime.getSetting("OPENPUMP_API_URL");
748
+ const baseUrl = typeof rawBaseUrl === "string" ? rawBaseUrl : "https://api.openpump.io";
749
+ const client = createApiClient(apiKey, baseUrl);
750
+ clientCache.set(runtime.agentId, client);
751
+ return Promise.resolve();
752
+ },
753
+ actions: [
754
+ buyTokenAction,
755
+ sellTokenAction,
756
+ createTokenAction,
757
+ getTokenInfoAction,
758
+ listWalletsAction,
759
+ getBalanceAction,
760
+ bundleBuyAction,
761
+ sellAllAction
762
+ ],
763
+ providers: [walletProvider]
764
+ };
765
+ export {
766
+ bundleBuyAction,
767
+ buyTokenAction,
768
+ clearClientCache,
769
+ createApiClient,
770
+ createTokenAction,
771
+ openpumpPlugin as default,
772
+ getBalanceAction,
773
+ getClient,
774
+ getTokenInfoAction,
775
+ listWalletsAction,
776
+ openpumpPlugin,
777
+ sellAllAction,
778
+ sellTokenAction,
779
+ walletProvider
780
+ };
781
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/actions/buy-token.ts","../src/actions/sell-token.ts","../src/actions/create-token.ts","../src/actions/get-token-info.ts","../src/actions/list-wallets.ts","../src/actions/get-balance.ts","../src/actions/bundle-buy.ts","../src/actions/sell-all.ts","../src/providers/wallet-provider.ts","../src/lib/api-client.ts","../src/plugin.ts"],"sourcesContent":["/**\n * OPENPUMP_BUY_TOKEN action — Buy a PumpFun token with SOL.\n *\n * Calls POST /api/tokens/:mint/buy on the OpenPump REST API.\n * Server-side signing — no local keypair needed.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nexport const buyTokenAction: Action = {\n name: 'OPENPUMP_BUY_TOKEN',\n similes: ['BUY_TOKEN', 'PURCHASE_TOKEN', 'SWAP_SOL_FOR_TOKEN', 'BUY_PUMPFUN'],\n description:\n 'Buy a PumpFun token with SOL from an OpenPump managed wallet. ' +\n 'Requires wallet ID, token mint address, and SOL amount in lamports. ' +\n 'Uses server-side signing (no local keypair needed).',\n\n examples: [\n [\n { name: 'user', content: { text: 'Buy 0.5 SOL of token ABC123mint from wallet-1' } },\n { name: 'agent', content: { text: 'Executing buy order for 0.5 SOL of token ABC123mint from wallet-1...' } },\n ],\n [\n { name: 'user', content: { text: 'Use my sniper wallet to buy 0.1 SOL of that new token' } },\n { name: 'agent', content: { text: 'Buying 0.1 SOL worth of tokens using your sniper wallet...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n\n // Extract parameters from message content (populated by LLM runtime)\n const content = message.content as Record<string, unknown>;\n const walletId = content['walletId'] as string | undefined;\n const mint = content['mint'] as string | undefined;\n const amountLamports = content['amountLamports'] as string | undefined;\n const slippageBps = content['slippageBps'] as number | undefined;\n const priorityLevel = (content['priorityLevel'] as string | undefined) ?? 'normal';\n\n if (!walletId || !mint || !amountLamports) {\n if (callback) {\n await callback({\n text: 'I need the wallet ID, token mint address, and SOL amount in lamports to execute a buy. Could you provide those details?',\n actions: ['OPENPUMP_BUY_TOKEN'],\n });\n }\n return { success: false, error: 'Missing required parameters: walletId, mint, amountLamports' };\n }\n\n const body: Record<string, unknown> = {\n walletId,\n amountLamports,\n priorityLevel,\n };\n if (slippageBps !== undefined) body['slippageBps'] = slippageBps;\n\n const res = await client.post(`/api/tokens/${mint}/buy`, body);\n\n if (!res.ok) {\n const errText = await res.text();\n const errorMsg = `Buy failed (HTTP ${String(res.status)}): ${errText}`;\n if (callback) {\n await callback({ text: errorMsg, actions: ['OPENPUMP_BUY_TOKEN'] });\n }\n return { success: false, error: errorMsg };\n }\n\n const data = (await res.json()) as Record<string, unknown>;\n const solAmount = (Number(amountLamports) / 1_000_000_000).toFixed(4);\n const sig = typeof data['signature'] === 'string' ? data['signature'] : 'pending';\n const successMsg =\n `Buy order executed successfully.\\n` +\n `Spent: ${solAmount} SOL\\n` +\n `Token: ${mint}\\n` +\n `Signature: ${sig}`;\n\n if (callback) {\n await callback({ text: successMsg, actions: ['OPENPUMP_BUY_TOKEN'] });\n }\n\n return { success: true, text: successMsg, data };\n } catch (error) {\n const errMsg = `Buy request failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) {\n await callback({ text: errMsg, actions: ['OPENPUMP_BUY_TOKEN'] });\n }\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * OPENPUMP_SELL_TOKEN action — Sell a PumpFun token back to SOL.\n *\n * Calls POST /api/tokens/:mint/sell on the OpenPump REST API.\n * Use tokenAmount: \"all\" to sell the entire balance.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nexport const sellTokenAction: Action = {\n name: 'OPENPUMP_SELL_TOKEN',\n similes: ['SELL_TOKEN', 'DUMP_TOKEN', 'SWAP_TOKEN_FOR_SOL', 'SELL_PUMPFUN'],\n description:\n 'Sell a PumpFun token back to SOL from an OpenPump managed wallet. ' +\n 'Use tokenAmount: \"all\" to sell the entire balance.',\n\n examples: [\n [\n { name: 'user', content: { text: 'Sell all of token XYZ from wallet-2' } },\n { name: 'agent', content: { text: 'Selling entire balance of token XYZ from wallet-2...' } },\n ],\n [\n { name: 'user', content: { text: 'Dump 50% of that token we just bought' } },\n { name: 'agent', content: { text: 'Selling half of your token position...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n const content = message.content as Record<string, unknown>;\n const walletId = content['walletId'] as string | undefined;\n const mint = content['mint'] as string | undefined;\n const tokenAmount = (content['tokenAmount'] as string | undefined) ?? 'all';\n const slippageBps = content['slippageBps'] as number | undefined;\n const priorityLevel = (content['priorityLevel'] as string | undefined) ?? 'normal';\n\n if (!walletId || !mint) {\n if (callback) {\n await callback({\n text: 'I need the wallet ID and token mint address to execute a sell. Could you provide those?',\n actions: ['OPENPUMP_SELL_TOKEN'],\n });\n }\n return { success: false, error: 'Missing required parameters: walletId, mint' };\n }\n\n const body: Record<string, unknown> = { walletId, tokenAmount, priorityLevel };\n if (slippageBps !== undefined) body['slippageBps'] = slippageBps;\n\n const res = await client.post(`/api/tokens/${mint}/sell`, body);\n\n if (!res.ok) {\n const errText = await res.text();\n const errorMsg = `Sell failed (HTTP ${String(res.status)}): ${errText}`;\n if (callback) await callback({ text: errorMsg, actions: ['OPENPUMP_SELL_TOKEN'] });\n return { success: false, error: errorMsg };\n }\n\n const data = (await res.json()) as Record<string, unknown>;\n const sig = typeof data['signature'] === 'string' ? data['signature'] : 'pending';\n const successMsg =\n `Sell order executed successfully.\\n` +\n `Token: ${mint}\\n` +\n `Amount: ${tokenAmount === 'all' ? 'entire balance' : tokenAmount}\\n` +\n `Signature: ${sig}`;\n\n if (callback) await callback({ text: successMsg, actions: ['OPENPUMP_SELL_TOKEN'] });\n return { success: true, text: successMsg, data };\n } catch (error) {\n const errMsg = `Sell request failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_SELL_TOKEN'] });\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * OPENPUMP_CREATE_TOKEN action — Create a new PumpFun token with bonding curve.\n *\n * Calls POST /api/tokens/create on the OpenPump REST API.\n * Uploads metadata and image to IPFS, then submits the creation transaction.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nfunction resolveImageType(contentType: string): string {\n if (contentType.includes('jpeg')) return 'image/jpeg';\n if (contentType.includes('gif')) return 'image/gif';\n return 'image/png';\n}\n\nexport const createTokenAction: Action = {\n name: 'OPENPUMP_CREATE_TOKEN',\n similes: ['CREATE_TOKEN', 'LAUNCH_TOKEN', 'DEPLOY_TOKEN', 'MINT_TOKEN'],\n description:\n 'Create a new PumpFun token with a bonding curve. Uploads metadata and image to IPFS, ' +\n 'then submits the creation transaction. Returns mint address and signature.',\n\n examples: [\n [\n { name: 'user', content: { text: 'Launch a token called DOGE2 with symbol D2, description \"The next doge\", use wallet-1' } },\n { name: 'agent', content: { text: 'Creating token DOGE2 (D2) on PumpFun...' } },\n ],\n [\n { name: 'user', content: { text: 'Create a meme token named PEPE3 with my dev wallet' } },\n { name: 'agent', content: { text: 'Deploying new PumpFun token PEPE3...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n const content = message.content as Record<string, unknown>;\n const walletId = content['walletId'] as string | undefined;\n const name = content['name'] as string | undefined;\n const symbol = content['symbol'] as string | undefined;\n const description = content['description'] as string | undefined;\n const imageUrl = content['imageUrl'] as string | undefined;\n\n if (!walletId || !name || !symbol || !description || !imageUrl) {\n if (callback) {\n await callback({\n text: 'To create a token I need: wallet ID, token name, symbol, description, and an image URL.',\n actions: ['OPENPUMP_CREATE_TOKEN'],\n });\n }\n return { success: false, error: 'Missing required parameters: walletId, name, symbol, description, imageUrl' };\n }\n\n // Fetch image and convert to base64 (same pattern as MCP token-tools.ts)\n const imageRes = await fetch(imageUrl);\n if (!imageRes.ok) {\n const errMsg = `Failed to fetch token image from ${imageUrl}: HTTP ${String(imageRes.status)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_CREATE_TOKEN'] });\n return { success: false, error: errMsg };\n }\n const imageBuffer = await imageRes.arrayBuffer();\n const imageBase64 = Buffer.from(imageBuffer).toString('base64');\n const contentType = imageRes.headers.get('content-type') ?? 'image/png';\n\n const body: Record<string, unknown> = {\n walletId,\n name,\n symbol,\n description,\n imageBase64,\n imageType: resolveImageType(contentType),\n };\n\n // Optional fields\n if (content['twitter']) body['twitter'] = content['twitter'];\n if (content['telegram']) body['telegram'] = content['telegram'];\n if (content['website']) body['website'] = content['website'];\n if (content['initialBuyAmountSol']) body['initialBuyAmountSol'] = content['initialBuyAmountSol'];\n\n const res = await client.post('/api/tokens/create', body);\n\n if (!res.ok) {\n const errText = await res.text();\n const errorMsg = `Token creation failed (HTTP ${String(res.status)}): ${errText}`;\n if (callback) await callback({ text: errorMsg, actions: ['OPENPUMP_CREATE_TOKEN'] });\n return { success: false, error: errorMsg };\n }\n\n const data = (await res.json()) as Record<string, unknown>;\n const mintAddr = typeof data['mint'] === 'string' ? data['mint'] : 'pending';\n const sig = typeof data['signature'] === 'string' ? data['signature'] : 'pending';\n const successMsg =\n `Token created successfully!\\n` +\n `Name: ${name} (${symbol})\\n` +\n `Mint: ${mintAddr}\\n` +\n `Signature: ${sig}`;\n\n if (callback) await callback({ text: successMsg, actions: ['OPENPUMP_CREATE_TOKEN'] });\n return { success: true, text: successMsg, data };\n } catch (error) {\n const errMsg = `Token creation failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_CREATE_TOKEN'] });\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * OPENPUMP_GET_TOKEN_INFO action — Get bonding curve state for a PumpFun token.\n *\n * Calls GET /api/tokens/:mint/curve-state on the OpenPump REST API.\n * Read-only operation — no blockchain writes.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nexport const getTokenInfoAction: Action = {\n name: 'OPENPUMP_GET_TOKEN_INFO',\n similes: ['GET_TOKEN_INFO', 'TOKEN_INFO', 'CHECK_TOKEN', 'TOKEN_PRICE', 'TOKEN_STATUS'],\n description:\n 'Get current info about a PumpFun token: name, symbol, price, market cap, bonding curve progress, ' +\n 'and graduation status. Read-only — no transaction submitted.',\n\n examples: [\n [\n { name: 'user', content: { text: 'What is the price of token ABC123mint?' } },\n { name: 'agent', content: { text: 'Looking up token ABC123mint on PumpFun...' } },\n ],\n [\n { name: 'user', content: { text: 'Check the bonding curve progress for that new token' } },\n { name: 'agent', content: { text: 'Fetching bonding curve state...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n const content = message.content as Record<string, unknown>;\n const mint = content['mint'] as string | undefined;\n\n if (!mint) {\n if (callback) {\n await callback({\n text: 'I need the token mint address to look up its info. Could you provide the mint address?',\n actions: ['OPENPUMP_GET_TOKEN_INFO'],\n });\n }\n return { success: false, error: 'Missing required parameter: mint' };\n }\n\n const res = await client.get(`/api/tokens/${mint}/curve-state`);\n\n if (!res.ok) {\n const errText = await res.text();\n const errorMsg = res.status === 404\n ? `Token with mint \"${mint}\" was not found on PumpFun. Please verify the mint address.`\n : `Failed to fetch token info (HTTP ${String(res.status)}): ${errText}`;\n if (callback) await callback({ text: errorMsg, actions: ['OPENPUMP_GET_TOKEN_INFO'] });\n return { success: false, error: errorMsg };\n }\n\n const data = (await res.json()) as Record<string, unknown>;\n\n // Format as readable text -- use JSON.stringify for safety on unknown values\n const s = (val: unknown): string => (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') ? String(val) : JSON.stringify(val);\n const lines: string[] = [`Token Info for ${mint}:`];\n if (data['name']) lines.push(` Name: ${s(data['name'])}`);\n if (data['symbol']) lines.push(` Symbol: ${s(data['symbol'])}`);\n if (data['priceSOL'] !== undefined) lines.push(` Price: ${s(data['priceSOL'])} SOL`);\n if (data['marketCapSOL'] !== undefined) lines.push(` Market Cap: ${s(data['marketCapSOL'])} SOL`);\n if (data['bondingCurveProgress'] !== undefined) lines.push(` Bonding Curve: ${s(data['bondingCurveProgress'])}%`);\n if (data['graduated'] !== undefined) lines.push(` Graduated: ${s(data['graduated'])}`);\n\n const successMsg = lines.join('\\n');\n if (callback) await callback({ text: successMsg, actions: ['OPENPUMP_GET_TOKEN_INFO'] });\n return { success: true, text: successMsg, data };\n } catch (error) {\n const errMsg = `Token info fetch failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_GET_TOKEN_INFO'] });\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * OPENPUMP_LIST_WALLETS action — List all managed wallets.\n *\n * Calls GET /api/wallets on the OpenPump REST API.\n * Read-only operation — returns wallet IDs, public keys, and labels.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nexport const listWalletsAction: Action = {\n name: 'OPENPUMP_LIST_WALLETS',\n similes: ['LIST_WALLETS', 'SHOW_WALLETS', 'MY_WALLETS', 'GET_WALLETS'],\n description:\n 'List all OpenPump managed wallets for the authenticated user. ' +\n 'Returns wallet IDs, public keys, and labels. Use GET_BALANCE for live SOL balances.',\n\n examples: [\n [\n { name: 'user', content: { text: 'Show me my wallets' } },\n { name: 'agent', content: { text: 'Fetching your OpenPump wallets...' } },\n ],\n [\n { name: 'user', content: { text: 'Which wallets do I have?' } },\n { name: 'agent', content: { text: 'Looking up your managed wallets...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n _message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n const res = await client.get('/api/wallets');\n\n if (!res.ok) {\n const errText = await res.text();\n const errorMsg = `Failed to fetch wallets (HTTP ${String(res.status)}): ${errText}`;\n if (callback) await callback({ text: errorMsg, actions: ['OPENPUMP_LIST_WALLETS'] });\n return { success: false, error: errorMsg };\n }\n\n const body = (await res.json()) as {\n data: Array<{ id: string; publicKey: string; label: string | null; walletIndex: number }>;\n };\n const wallets = body.data ?? [];\n\n if (wallets.length === 0) {\n const msg = 'No wallets found for your account.';\n if (callback) await callback({ text: msg, actions: ['OPENPUMP_LIST_WALLETS'] });\n return { success: true, text: msg, data: { wallets: [] } };\n }\n\n const lines: string[] = [`You have ${String(wallets.length)} wallet(s):`];\n for (const w of wallets) {\n const label = w.label ? ` \"${w.label}\"` : '';\n lines.push(` - ${w.id}${label}: ${w.publicKey}`);\n }\n\n const successMsg = lines.join('\\n');\n if (callback) await callback({ text: successMsg, actions: ['OPENPUMP_LIST_WALLETS'] });\n return { success: true, text: successMsg, data: { wallets } };\n } catch (error) {\n const errMsg = `Wallet list failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_LIST_WALLETS'] });\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * OPENPUMP_GET_BALANCE action — Get SOL and token balances for a wallet.\n *\n * Calls GET /api/wallets/:id/balance on the OpenPump REST API.\n * Read-only operation — returns real-time on-chain data.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nexport const getBalanceAction: Action = {\n name: 'OPENPUMP_GET_BALANCE',\n similes: ['GET_BALANCE', 'CHECK_BALANCE', 'WALLET_BALANCE', 'SOL_BALANCE'],\n description:\n 'Get the SOL balance and all token balances held by the specified OpenPump wallet. ' +\n 'Returns real-time on-chain data.',\n\n examples: [\n [\n { name: 'user', content: { text: 'Check the balance of wallet-1' } },\n { name: 'agent', content: { text: 'Fetching balance for wallet-1...' } },\n ],\n [\n { name: 'user', content: { text: 'How much SOL is in my sniper wallet?' } },\n { name: 'agent', content: { text: 'Looking up your sniper wallet balance...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n const content = message.content as Record<string, unknown>;\n const walletId = content['walletId'] as string | undefined;\n\n if (!walletId) {\n if (callback) {\n await callback({\n text: 'I need the wallet ID to check its balance. Use LIST_WALLETS to see available wallets.',\n actions: ['OPENPUMP_GET_BALANCE'],\n });\n }\n return { success: false, error: 'Missing required parameter: walletId' };\n }\n\n const res = await client.get(`/api/wallets/${walletId}/balance`);\n\n if (!res.ok) {\n const errText = await res.text();\n const errorMsg = res.status === 404\n ? `Wallet \"${walletId}\" not found. Use LIST_WALLETS to see available wallet IDs.`\n : `Failed to fetch balance (HTTP ${String(res.status)}): ${errText}`;\n if (callback) await callback({ text: errorMsg, actions: ['OPENPUMP_GET_BALANCE'] });\n return { success: false, error: errorMsg };\n }\n\n const body = (await res.json()) as {\n data: {\n solBalance: string;\n lamports: string;\n tokenBalances: Array<{ mint: string; amount: string; uiAmount: number | null; decimals: number }>;\n };\n };\n const data = body.data;\n\n const lines: string[] = [`Wallet ${walletId} Balance:`];\n lines.push(` SOL: ${data.solBalance}`);\n\n const tokenPositions = data.tokenBalances.filter(\n (tb) => tb.uiAmount === null ? tb.amount !== '0' : tb.uiAmount > 0,\n );\n\n if (tokenPositions.length > 0) {\n lines.push(` Token Positions (${String(tokenPositions.length)}):`);\n for (const tb of tokenPositions) {\n lines.push(` - ${tb.mint}: ${String(tb.uiAmount ?? tb.amount)}`);\n }\n } else {\n lines.push(' No token positions');\n }\n\n const successMsg = lines.join('\\n');\n if (callback) await callback({ text: successMsg, actions: ['OPENPUMP_GET_BALANCE'] });\n return { success: true, text: successMsg, data };\n } catch (error) {\n const errMsg = `Balance fetch failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_GET_BALANCE'] });\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * OPENPUMP_BUNDLE_BUY action — Create a token + coordinated multi-wallet buy.\n *\n * Calls POST /api/tokens/bundle-launch on the OpenPump REST API.\n * Async operation — returns a jobId for progress tracking.\n * Uses Jito MEV bundles for same-block execution.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nfunction resolveImageType(contentType: string): string {\n if (contentType.includes('jpeg')) return 'image/jpeg';\n if (contentType.includes('gif')) return 'image/gif';\n return 'image/png';\n}\n\nexport const bundleBuyAction: Action = {\n name: 'OPENPUMP_BUNDLE_BUY',\n similes: ['BUNDLE_BUY', 'BUNDLE_LAUNCH', 'COORDINATED_BUY', 'MULTI_WALLET_BUY'],\n description:\n 'Atomically create a new PumpFun token and execute coordinated buys from multiple wallets ' +\n 'using Jito MEV bundles. Returns a jobId for async tracking. ' +\n 'LEGAL WARNING: Coordinated bundle buying may be subject to legal restrictions in your jurisdiction.',\n\n examples: [\n [\n { name: 'user', content: { text: 'Bundle launch a token DOGE3 with 3 sniper wallets buying 0.5 SOL each' } },\n { name: 'agent', content: { text: 'Preparing bundle launch for DOGE3 with 3 coordinated buy wallets...' } },\n ],\n [\n { name: 'user', content: { text: 'Do a coordinated buy with my dev wallet and 2 buy wallets' } },\n { name: 'agent', content: { text: 'Setting up Jito MEV bundle for coordinated token launch...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n const content = message.content as Record<string, unknown>;\n const devWalletId = content['devWalletId'] as string | undefined;\n const buyWalletIds = content['buyWalletIds'] as string[] | undefined;\n const name = content['name'] as string | undefined;\n const symbol = content['symbol'] as string | undefined;\n const description = content['description'] as string | undefined;\n const imageUrl = content['imageUrl'] as string | undefined;\n const devBuyAmountLamports = content['devBuyAmountLamports'] as string | undefined;\n const walletBuyAmounts = content['walletBuyAmounts'] as string[] | undefined;\n\n if (!devWalletId || !buyWalletIds || !name || !symbol || !description || !imageUrl || !devBuyAmountLamports || !walletBuyAmounts) {\n if (callback) {\n await callback({\n text:\n 'Bundle launch requires: devWalletId, buyWalletIds[], token name, symbol, description, imageUrl, ' +\n 'devBuyAmountLamports, and walletBuyAmounts[]. Please provide all parameters.',\n actions: ['OPENPUMP_BUNDLE_BUY'],\n });\n }\n return { success: false, error: 'Missing required parameters for bundle launch' };\n }\n\n // Fetch image and convert to base64\n const imageRes = await fetch(imageUrl);\n if (!imageRes.ok) {\n const errMsg = `Failed to fetch token image from ${imageUrl}: HTTP ${String(imageRes.status)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_BUNDLE_BUY'] });\n return { success: false, error: errMsg };\n }\n const imageBuffer = await imageRes.arrayBuffer();\n const imageBase64 = Buffer.from(imageBuffer).toString('base64');\n const imgContentType = imageRes.headers.get('content-type') ?? 'image/png';\n\n const body: Record<string, unknown> = {\n devWalletId,\n buyWalletIds,\n name,\n symbol,\n description,\n imageBase64,\n imageType: resolveImageType(imgContentType),\n devBuyAmountLamports,\n walletBuyAmounts,\n tipLamports: 50_000, // Default normal priority\n };\n\n const res = await client.post('/api/tokens/bundle-launch', body);\n\n if (!res.ok) {\n const errText = await res.text();\n const errorMsg = `Bundle launch failed (HTTP ${String(res.status)}): ${errText}`;\n if (callback) await callback({ text: errorMsg, actions: ['OPENPUMP_BUNDLE_BUY'] });\n return { success: false, error: errorMsg };\n }\n\n const data = (await res.json()) as { jobId?: string };\n const successMsg =\n `Bundle launch submitted successfully!\\n` +\n `Job ID: ${String(data.jobId ?? 'unknown')}\\n` +\n `Token: ${name} (${symbol})\\n` +\n `Dev wallet: ${devWalletId}\\n` +\n `Buy wallets: ${String(buyWalletIds.length)}\\n` +\n `Track progress with the job ID.`;\n\n if (callback) await callback({ text: successMsg, actions: ['OPENPUMP_BUNDLE_BUY'] });\n return { success: true, text: successMsg, data };\n } catch (error) {\n const errMsg = `Bundle launch failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_BUNDLE_BUY'] });\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * OPENPUMP_SELL_ALL action — Sell a token from all wallets that hold it.\n *\n * Iterates through all managed wallets, checks holdings, then calls\n * POST /api/tokens/:mint/sell for each wallet holding the token.\n * Useful for exiting all positions in a single conversational command.\n */\nimport type { Action, ActionResult, IAgentRuntime, Memory, State, HandlerOptions, HandlerCallback } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\nexport const sellAllAction: Action = {\n name: 'OPENPUMP_SELL_ALL',\n similes: ['SELL_ALL', 'EXIT_ALL_POSITIONS', 'DUMP_ALL', 'SELL_EVERYTHING'],\n description:\n 'Sell a token from ALL wallets that hold it. Iterates through your managed wallets, ' +\n 'finds those holding the specified token, and sells the entire balance from each. ' +\n 'Returns results per wallet.',\n\n examples: [\n [\n { name: 'user', content: { text: 'Sell all positions in token XYZ across all wallets' } },\n { name: 'agent', content: { text: 'Selling token XYZ from all wallets that hold it...' } },\n ],\n [\n { name: 'user', content: { text: 'Exit all my positions in that token' } },\n { name: 'agent', content: { text: 'Finding all wallets holding the token and selling...' } },\n ],\n ],\n\n validate: (runtime: IAgentRuntime, _message: Memory, _state?: State): Promise<boolean> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n return Promise.resolve(typeof apiKey === 'string' && apiKey.length > 0);\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n try {\n const client = getClient(runtime);\n const content = message.content as Record<string, unknown>;\n const mint = content['mint'] as string | undefined;\n\n if (!mint) {\n if (callback) {\n await callback({\n text: 'I need the token mint address to sell all positions. Could you provide it?',\n actions: ['OPENPUMP_SELL_ALL'],\n });\n }\n return { success: false, error: 'Missing required parameter: mint' };\n }\n\n // Step 1: Get all wallets\n const walletsRes = await client.get('/api/wallets');\n if (!walletsRes.ok) {\n const errMsg = `Failed to fetch wallets: HTTP ${String(walletsRes.status)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_SELL_ALL'] });\n return { success: false, error: errMsg };\n }\n const walletsBody = (await walletsRes.json()) as {\n data: Array<{ id: string; publicKey: string; label: string | null }>;\n };\n const wallets = walletsBody.data ?? [];\n\n if (wallets.length === 0) {\n const msg = 'No wallets found. Nothing to sell.';\n if (callback) await callback({ text: msg, actions: ['OPENPUMP_SELL_ALL'] });\n return { success: true, text: msg, data: { results: [] } };\n }\n\n // Step 2: Check balances for each wallet to find holders\n const balanceResults = await Promise.allSettled(\n wallets.map(async (w) => {\n const res = await client.get(`/api/wallets/${w.id}/balance`);\n if (!res.ok) return null;\n const body = (await res.json()) as {\n data: {\n tokenBalances: Array<{ mint: string; amount: string; uiAmount: number | null }>;\n };\n };\n const holding = body.data.tokenBalances.find((tb) => tb.mint === mint);\n if (!holding) return null;\n const hasBalance = holding.uiAmount === null ? holding.amount !== '0' : holding.uiAmount > 0;\n if (!hasBalance) return null;\n return { walletId: w.id, label: w.label, amount: holding.amount };\n }),\n );\n\n const holders = balanceResults\n .filter((r): r is PromiseFulfilledResult<{ walletId: string; label: string | null; amount: string } | null> =>\n r.status === 'fulfilled',\n )\n .map((r) => r.value)\n .filter((v): v is { walletId: string; label: string | null; amount: string } => v !== null);\n\n if (holders.length === 0) {\n const msg = `No wallets hold token ${mint}. Nothing to sell.`;\n if (callback) await callback({ text: msg, actions: ['OPENPUMP_SELL_ALL'] });\n return { success: true, text: msg, data: { results: [] } };\n }\n\n // Step 3: Execute sell for each holder\n const sellResults: Array<{ walletId: string; success: boolean; signature?: string; error?: string }> = [];\n\n for (const holder of holders) {\n try {\n const sellRes = await client.post(`/api/tokens/${mint}/sell`, {\n walletId: holder.walletId,\n tokenAmount: 'all',\n priorityLevel: 'normal',\n });\n\n if (sellRes.ok) {\n const sellData = (await sellRes.json()) as Record<string, unknown>;\n const sig = typeof sellData['signature'] === 'string' ? sellData['signature'] : 'pending';\n sellResults.push({\n walletId: holder.walletId,\n success: true,\n signature: sig,\n });\n } else {\n const errText = await sellRes.text();\n sellResults.push({\n walletId: holder.walletId,\n success: false,\n error: `HTTP ${String(sellRes.status)}: ${errText}`,\n });\n }\n } catch (error) {\n sellResults.push({\n walletId: holder.walletId,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n const successCount = sellResults.filter((r) => r.success).length;\n const failCount = sellResults.length - successCount;\n\n const lines: string[] = [`Sell-all results for token ${mint}:`];\n for (const r of sellResults) {\n if (r.success) {\n lines.push(` ${r.walletId}: SOLD (sig: ${r.signature ?? 'pending'})`);\n } else {\n lines.push(` ${r.walletId}: FAILED (${r.error ?? 'unknown error'})`);\n }\n }\n lines.push(`Summary: ${String(successCount)} succeeded, ${String(failCount)} failed`);\n\n const successMsg = lines.join('\\n');\n if (callback) await callback({ text: successMsg, actions: ['OPENPUMP_SELL_ALL'] });\n return { success: failCount === 0, text: successMsg, data: { results: sellResults } };\n } catch (error) {\n const errMsg = `Sell-all failed: ${error instanceof Error ? error.message : String(error)}`;\n if (callback) await callback({ text: errMsg, actions: ['OPENPUMP_SELL_ALL'] });\n return { success: false, error: errMsg };\n }\n },\n};\n","/**\n * WalletProvider — Injects current wallet balances and token positions into agent state.\n *\n * This provider runs before each agent response turn, giving the agent awareness of\n * the user's current portfolio. The text output is included in the agent's context\n * so it can make informed trading decisions.\n */\nimport type { Provider, IAgentRuntime, Memory, State } from '@elizaos/core';\nimport { getClient } from '../plugin.js';\n\ninterface WalletBalance {\n walletId: string;\n publicKey: string;\n label: string | null;\n solBalance: string;\n lamports: string;\n tokenBalances: Array<{\n mint: string;\n amount: string;\n uiAmount: number | null;\n decimals: number;\n }>;\n}\n\nexport const walletProvider: Provider = {\n name: 'openpumpWalletProvider',\n description: 'Provides current OpenPump managed wallet balances and token positions for portfolio awareness',\n dynamic: true,\n position: 10,\n\n get: async (runtime: IAgentRuntime, _message: Memory, _state: State) => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n if (!apiKey) {\n return { text: '', data: {}, values: {} };\n }\n\n try {\n const client = getClient(runtime);\n\n // Fetch wallet list\n const walletsRes = await client.get('/api/wallets');\n if (!walletsRes.ok) {\n return { text: 'OpenPump: Unable to fetch wallets', data: {}, values: {} };\n }\n const walletsData = (await walletsRes.json()) as {\n data: Array<{ id: string; publicKey: string; label: string | null; walletIndex: number }>;\n };\n const wallets = walletsData.data ?? [];\n\n if (wallets.length === 0) {\n return {\n text: 'OpenPump Portfolio: No wallets configured.',\n data: { wallets: [] },\n values: { walletCount: 0 },\n };\n }\n\n // Fetch balances for all wallets in parallel\n const balanceResults = await Promise.allSettled(\n wallets.map(async (w): Promise<WalletBalance> => {\n const res = await client.get(`/api/wallets/${w.id}/balance`);\n if (!res.ok) throw new Error(`HTTP ${String(res.status)}`);\n const body = (await res.json()) as {\n data: {\n solBalance: string;\n lamports: string;\n tokenBalances: Array<{ mint: string; amount: string; uiAmount: number | null; decimals: number }>;\n };\n };\n return {\n walletId: w.id,\n publicKey: w.publicKey,\n label: w.label,\n solBalance: body.data.solBalance,\n lamports: body.data.lamports,\n tokenBalances: body.data.tokenBalances,\n };\n }),\n );\n\n const balances: WalletBalance[] = balanceResults\n .filter((r): r is PromiseFulfilledResult<WalletBalance> => r.status === 'fulfilled')\n .map((r) => r.value);\n\n // Format as readable text for agent context\n const lines: string[] = ['OpenPump Portfolio:'];\n let totalSol = 0;\n let totalTokenPositions = 0;\n\n for (const b of balances) {\n const sol = Number.parseFloat(b.solBalance);\n totalSol += sol;\n const label = b.label ? ` \"${b.label}\"` : '';\n lines.push(` Wallet${label} (${b.walletId}): ${b.solBalance} SOL`);\n\n for (const tb of b.tokenBalances) {\n if (tb.uiAmount !== null && tb.uiAmount > 0) {\n totalTokenPositions++;\n lines.push(` - Token ${tb.mint}: ${String(tb.uiAmount)} (raw: ${tb.amount})`);\n }\n }\n }\n\n lines.push(\n `Total: ${totalSol.toFixed(4)} SOL across ${String(wallets.length)} wallets, ` +\n `${String(totalTokenPositions)} token positions`,\n );\n\n return {\n text: lines.join('\\n'),\n data: { wallets: balances },\n values: {\n walletCount: wallets.length,\n totalSol: totalSol.toFixed(4),\n totalTokenPositions,\n },\n };\n } catch (error) {\n return {\n text: `OpenPump: Portfolio fetch failed (${error instanceof Error ? error.message : String(error)})`,\n data: {},\n values: {},\n };\n }\n },\n};\n","/**\n * Thin typed wrapper for calling the OpenPump REST API from the ElizaOS plugin.\n *\n * Mirrors the pattern from `apps/mcp/src/lib/api-client.ts`.\n * Authentication uses the raw API key (op_sk_live_...) as a Bearer token.\n */\n\nexport interface ApiClient {\n get(path: string): Promise<Response>;\n post(path: string, body: unknown): Promise<Response>;\n}\n\n/**\n * Create an authenticated API client for the OpenPump REST API.\n *\n * @param apiKey - Raw API key string (op_sk_live_...) from character settings\n * @param baseUrl - Base URL of the REST API (e.g. https://api.openpump.io)\n */\nexport function createApiClient(apiKey: string, baseUrl: string): ApiClient {\n const authHeader = 'Bearer ' + apiKey;\n\n return {\n async get(path: string): Promise<Response> {\n return fetch(baseUrl + path, {\n headers: { Authorization: authHeader },\n });\n },\n\n async post(path: string, body: unknown): Promise<Response> {\n return fetch(baseUrl + path, {\n method: 'POST',\n headers: {\n Authorization: authHeader,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n },\n };\n}\n","/**\n * OpenPump ElizaOS plugin — main plugin definition.\n *\n * Exports a valid ElizaOS Plugin object with:\n * - init() that validates the API key and pre-creates the client\n * - 8 actions for trading, token management, and wallet queries\n * - 1 provider for portfolio context injection\n */\nimport type { Plugin, IAgentRuntime } from '@elizaos/core';\nimport { buyTokenAction } from './actions/buy-token.js';\nimport { sellTokenAction } from './actions/sell-token.js';\nimport { createTokenAction } from './actions/create-token.js';\nimport { getTokenInfoAction } from './actions/get-token-info.js';\nimport { listWalletsAction } from './actions/list-wallets.js';\nimport { getBalanceAction } from './actions/get-balance.js';\nimport { bundleBuyAction } from './actions/bundle-buy.js';\nimport { sellAllAction } from './actions/sell-all.js';\nimport { walletProvider } from './providers/wallet-provider.js';\nimport { createApiClient, type ApiClient } from './lib/api-client.js';\n\n/** Module-level client cache keyed by agent ID to avoid re-creating per call. */\nconst clientCache = new Map<string, ApiClient>();\n\n/**\n * Retrieve or create an ApiClient for the given runtime.\n * Called by action handlers and providers to get the authenticated client.\n */\nexport function getClient(runtime: IAgentRuntime): ApiClient {\n const agentId = runtime.agentId;\n const cached = clientCache.get(agentId);\n if (cached) {\n return cached;\n }\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n const baseUrl = runtime.getSetting('OPENPUMP_API_URL');\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error('OPENPUMP_API_KEY not configured in character settings');\n }\n const client = createApiClient(apiKey, typeof baseUrl === 'string' ? baseUrl : 'https://api.openpump.io');\n clientCache.set(agentId, client);\n return client;\n}\n\n/**\n * Clear a cached client (useful for testing).\n */\nexport function clearClientCache(agentId?: string): void {\n if (agentId) {\n clientCache.delete(agentId);\n } else {\n clientCache.clear();\n }\n}\n\nexport const openpumpPlugin: Plugin = {\n name: 'openpump',\n description:\n 'Buy, sell, and launch PumpFun tokens via the OpenPump managed wallet API. ' +\n 'Provides trading actions and portfolio context for conversational AI agents.',\n\n init: (_config: Record<string, string>, runtime: IAgentRuntime): Promise<void> => {\n const apiKey = runtime.getSetting('OPENPUMP_API_KEY');\n if (!apiKey || typeof apiKey !== 'string') {\n throw new Error(\n 'OpenPump plugin requires OPENPUMP_API_KEY in character settings. ' +\n 'Add it to settings.secrets.OPENPUMP_API_KEY in your character JSON.',\n );\n }\n // Pre-create client to validate configuration at startup\n const rawBaseUrl = runtime.getSetting('OPENPUMP_API_URL');\n const baseUrl = typeof rawBaseUrl === 'string' ? rawBaseUrl : 'https://api.openpump.io';\n const client = createApiClient(apiKey, baseUrl);\n clientCache.set(runtime.agentId, client);\n return Promise.resolve();\n },\n\n actions: [\n buyTokenAction,\n sellTokenAction,\n createTokenAction,\n getTokenInfoAction,\n listWalletsAction,\n getBalanceAction,\n bundleBuyAction,\n sellAllAction,\n ],\n\n providers: [walletProvider],\n};\n"],"mappings":"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","names":["resolveImageType"]}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@openpump/eliza-plugin",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "ElizaOS plugin for OpenPump — buy, sell, and launch PumpFun tokens via conversational AI agents",
6
+ "type": "module",
7
+ "license": "MIT",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/openpump/openpump.git",
14
+ "directory": "packages/eliza-plugin"
15
+ },
16
+ "main": "dist/index.js",
17
+ "types": "dist/index.d.ts",
18
+ "exports": {
19
+ ".": {
20
+ "import": "./dist/index.js",
21
+ "types": "./dist/index.d.ts"
22
+ }
23
+ },
24
+ "files": ["dist", "README.md"],
25
+ "scripts": {
26
+ "build": "tsup",
27
+ "dev": "tsup --watch",
28
+ "test": "vitest run",
29
+ "typecheck": "tsc --noEmit",
30
+ "lint": "eslint src/"
31
+ },
32
+ "peerDependencies": {
33
+ "@elizaos/core": ">=1.0.0"
34
+ },
35
+ "devDependencies": {
36
+ "@elizaos/core": "^1.0.0",
37
+ "@openpump/typescript-config": "workspace:*",
38
+ "@types/node": "^22.0.0",
39
+ "tsup": "^8.0.0",
40
+ "typescript": "^5.3.0",
41
+ "vitest": "^1.2.0"
42
+ }
43
+ }