@madeonsol/plugin-madeonsol 0.7.0 → 1.0.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 CHANGED
@@ -42,7 +42,7 @@ import { madeOnSolPlugin } from "@madeonsol/plugin-madeonsol";
42
42
  const agent = {
43
43
  plugins: [madeOnSolPlugin],
44
44
  settings: {
45
- // Option 1: API key (simplest — get one free at madeonsol.com/developer)
45
+ // Option 1: API key — get one free at madeonsol.com/developer
46
46
  MADEONSOL_API_KEY: "msk_your_api_key_here",
47
47
 
48
48
  // Option 2: x402 micropayments (AI agents)
@@ -29,7 +29,7 @@ export const deployerAlertsAction = {
29
29
  const result = await client.getDeployerAlerts(tier ? { limit, tier } : { limit });
30
30
  if (result.error) {
31
31
  callback?.({ text: result.status === 402
32
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
32
+ ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY."
33
33
  : `Error: ${result.error}` });
34
34
  return undefined;
35
35
  }
@@ -24,7 +24,7 @@ export const kolAlertsRecentAction = {
24
24
  const result = await client.getKolAlertsRecent({ window, limit: "20" });
25
25
  if (result.error) {
26
26
  callback?.({ text: result.status === 402
27
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
27
+ ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY."
28
28
  : `Error: ${result.error}` });
29
29
  return undefined;
30
30
  }
@@ -29,7 +29,7 @@ export const kolCompareAction = {
29
29
  const result = await client.getKolCompare(wallets);
30
30
  if (result.error) {
31
31
  callback?.({ text: result.status === 402
32
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
32
+ ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY."
33
33
  : `Error: ${result.error}` });
34
34
  return undefined;
35
35
  }
@@ -24,7 +24,7 @@ export const kolCoordinationAction = {
24
24
  const result = await client.getKolCoordination({ period, limit: "10" });
25
25
  if (result.error) {
26
26
  callback?.({ text: result.status === 402
27
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
27
+ ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY."
28
28
  : `Error: ${result.error}` });
29
29
  return undefined;
30
30
  }
@@ -25,7 +25,7 @@ export const kolFeedAction = {
25
25
  const result = await client.getKolFeed({ limit: "10", ...(action ? { action } : {}) });
26
26
  if (result.error) {
27
27
  callback?.({ text: result.status === 402
28
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
28
+ ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY."
29
29
  : `Error: ${result.error}` });
30
30
  return undefined;
31
31
  }
@@ -24,7 +24,7 @@ export const kolLeaderboardAction = {
24
24
  const result = await client.getKolLeaderboard({ period, limit: "10" });
25
25
  if (result.error) {
26
26
  callback?.({ text: result.status === 402
27
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
27
+ ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY."
28
28
  : `Error: ${result.error}` });
29
29
  return undefined;
30
30
  }
@@ -28,7 +28,7 @@ export const kolTokenEntryOrderAction = {
28
28
  const result = await client.getKolTokenEntryOrder(mint, { limit: "20" });
29
29
  if (result.error) {
30
30
  callback?.({ text: result.status === 402
31
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
31
+ ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY."
32
32
  : `Error: ${result.error}` });
33
33
  return undefined;
34
34
  }
package/dist/client.d.ts CHANGED
@@ -1,22 +1,32 @@
1
1
  /**
2
2
  * MadeOnSol API client.
3
- * Supports 3 auth modes: API key (simplest), RapidAPI key, or x402 micropayments.
3
+ * Two auth modes: MadeOnSol API key (`msk_`, recommended) or x402 micropayments.
4
+ *
5
+ * v1.0 breaking change: RapidAPI auth has been removed (marketplace retired 2026-04-19).
6
+ * Get a free `msk_` key at https://madeonsol.com/developer.
4
7
  */
5
8
  export interface MadeOnSolClientOptions {
6
9
  baseUrl?: string;
7
10
  /** MadeOnSol API key (get one free at madeonsol.com/developer). Preferred. */
8
11
  apiKey?: string;
9
- /** RapidAPI subscription key. */
10
- rapidApiKey?: string;
11
12
  /** x402 payment-enabled fetch (for AI agents with SVM_PRIVATE_KEY). */
12
13
  fetchFn?: typeof fetch;
13
14
  }
15
+ export interface RateLimitInfo {
16
+ limit?: string;
17
+ remaining?: string;
18
+ reset?: string;
19
+ requestId?: string;
20
+ }
14
21
  export declare class MadeOnSolClient {
15
22
  private baseUrl;
16
23
  private fetchFn;
17
24
  private authMode;
18
25
  private authHeaders;
26
+ /** Most recent rate-limit headers, populated by every request. */
27
+ lastRateLimit: RateLimitInfo;
19
28
  constructor(options?: MadeOnSolClientOptions);
29
+ private captureRateLimit;
20
30
  query<T = unknown>(path: string, params?: Record<string, string | undefined>): Promise<{
21
31
  data?: T;
22
32
  error?: string;
@@ -194,4 +204,74 @@ export declare class MadeOnSolClient {
194
204
  error?: string;
195
205
  status: number;
196
206
  }>;
207
+ getAlphaLeaderboard(params?: {
208
+ limit?: string;
209
+ min_tokens?: string;
210
+ min_pnl?: string;
211
+ }): Promise<{
212
+ data?: unknown;
213
+ error?: string;
214
+ status: number;
215
+ }>;
216
+ getAlphaWallet(wallet: string): Promise<{
217
+ data?: unknown;
218
+ error?: string;
219
+ status: number;
220
+ }>;
221
+ getAlphaLinked(wallet: string): Promise<{
222
+ data?: unknown;
223
+ error?: string;
224
+ status: number;
225
+ }>;
226
+ getTokenCapTable(mint: string): Promise<{
227
+ data?: unknown;
228
+ error?: string;
229
+ status: number;
230
+ }>;
231
+ getTokenBuyerQuality(mint: string): Promise<{
232
+ data?: unknown;
233
+ error?: string;
234
+ status: number;
235
+ }>;
236
+ copyTradeList(): Promise<{
237
+ data?: unknown;
238
+ error?: string;
239
+ status: number;
240
+ }>;
241
+ copyTradeCreate(params: {
242
+ name: string;
243
+ source_wallet: string;
244
+ is_active?: boolean;
245
+ webhook_url?: string;
246
+ delivery?: "webhook" | "websocket" | "both";
247
+ filters?: Record<string, unknown>;
248
+ }): Promise<{
249
+ data?: unknown;
250
+ error?: string;
251
+ status: number;
252
+ }>;
253
+ copyTradeGet(ruleId: string): Promise<{
254
+ data?: unknown;
255
+ error?: string;
256
+ status: number;
257
+ }>;
258
+ copyTradeUpdate(ruleId: string, updates: Record<string, unknown>): Promise<{
259
+ data?: unknown;
260
+ error?: string;
261
+ status: number;
262
+ }>;
263
+ copyTradeDelete(ruleId: string): Promise<{
264
+ data?: unknown;
265
+ error?: string;
266
+ status: number;
267
+ }>;
268
+ copyTradeSignals(params?: {
269
+ rule_id?: string;
270
+ limit?: string;
271
+ since?: string;
272
+ }): Promise<{
273
+ data?: unknown;
274
+ error?: string;
275
+ status: number;
276
+ }>;
197
277
  }
package/dist/client.js CHANGED
@@ -1,14 +1,18 @@
1
1
  /**
2
2
  * MadeOnSol API client.
3
- * Supports 3 auth modes: API key (simplest), RapidAPI key, or x402 micropayments.
3
+ * Two auth modes: MadeOnSol API key (`msk_`, recommended) or x402 micropayments.
4
+ *
5
+ * v1.0 breaking change: RapidAPI auth has been removed (marketplace retired 2026-04-19).
6
+ * Get a free `msk_` key at https://madeonsol.com/developer.
4
7
  */
5
8
  const DEFAULT_BASE = "https://madeonsol.com";
6
- const RAPIDAPI_HOST = "madeonsol-solana-kol-tracker-tools-api.p.rapidapi.com";
7
9
  export class MadeOnSolClient {
8
10
  baseUrl;
9
11
  fetchFn;
10
12
  authMode;
11
13
  authHeaders;
14
+ /** Most recent rate-limit headers, populated by every request. */
15
+ lastRateLimit = {};
12
16
  constructor(options = {}) {
13
17
  this.baseUrl = options.baseUrl || DEFAULT_BASE;
14
18
  this.fetchFn = options.fetchFn || globalThis.fetch;
@@ -17,10 +21,6 @@ export class MadeOnSolClient {
17
21
  this.authMode = "madeonsol";
18
22
  this.authHeaders = { Authorization: `Bearer ${options.apiKey}` };
19
23
  }
20
- else if (options.rapidApiKey) {
21
- this.authMode = "rapidapi";
22
- this.authHeaders = { "x-rapidapi-key": options.rapidApiKey, "x-rapidapi-host": RAPIDAPI_HOST };
23
- }
24
24
  else if (options.fetchFn) {
25
25
  this.authMode = "x402";
26
26
  }
@@ -28,6 +28,14 @@ export class MadeOnSolClient {
28
28
  this.authMode = "none";
29
29
  }
30
30
  }
31
+ captureRateLimit(res) {
32
+ this.lastRateLimit = {
33
+ limit: res.headers.get("X-RateLimit-Limit") ?? undefined,
34
+ remaining: res.headers.get("X-RateLimit-Remaining") ?? undefined,
35
+ reset: res.headers.get("X-RateLimit-Reset") ?? undefined,
36
+ requestId: res.headers.get("X-Request-Id") ?? undefined,
37
+ };
38
+ }
31
39
  async query(path, params) {
32
40
  const apiPath = this.authMode === "x402" || this.authMode === "none"
33
41
  ? path
@@ -42,6 +50,7 @@ export class MadeOnSolClient {
42
50
  const res = this.authMode === "x402"
43
51
  ? await this.fetchFn(url.toString(), { method: "GET" })
44
52
  : await this.fetchFn(url.toString(), { method: "GET", headers: this.authHeaders });
53
+ this.captureRateLimit(res);
45
54
  if (res.status === 402) {
46
55
  const body = await res.json();
47
56
  return { error: `Payment required: ${JSON.stringify(body.accepts?.[0] || body)}`, status: 402 };
@@ -98,10 +107,10 @@ export class MadeOnSolClient {
98
107
  getDeployerTrajectory(wallet) {
99
108
  return this.restRequest("GET", `/deployer-hunter/${wallet}/trajectory`);
100
109
  }
101
- // ── Webhook management (requires API key or RapidAPI key with Pro/Ultra) ──
110
+ // ── REST helper (used by webhooks, streaming, alpha, copy-trade, wallet-tracker) ──
102
111
  async restRequest(method, path, body) {
103
- if (this.authMode !== "madeonsol" && this.authMode !== "rapidapi") {
104
- return { error: "API key or RapidAPI key required for webhook/streaming features. Get a free key at madeonsol.com/developer", status: 401 };
112
+ if (this.authMode !== "madeonsol") {
113
+ return { error: "MadeOnSol API key required for this endpoint. Get a free `msk_` key at madeonsol.com/developer", status: 401 };
105
114
  }
106
115
  const res = await this.fetchFn(`${this.baseUrl}/api/v1${path}`, {
107
116
  method,
@@ -111,12 +120,14 @@ export class MadeOnSolClient {
111
120
  },
112
121
  ...(body ? { body: JSON.stringify(body) } : {}),
113
122
  });
123
+ this.captureRateLimit(res);
114
124
  if (!res.ok) {
115
125
  const text = await res.text().catch(() => "Unknown error");
116
126
  return { error: text, status: res.status };
117
127
  }
118
128
  return { data: await res.json(), status: res.status };
119
129
  }
130
+ // ── Webhook management (PRO/ULTRA) ──
120
131
  createWebhook(params) {
121
132
  return this.restRequest("POST", "/webhooks", params);
122
133
  }
@@ -143,14 +154,15 @@ export class MadeOnSolClient {
143
154
  return this.restRequest("DELETE", `/wallet-tracker/watchlist/${encodeURIComponent(walletAddress)}`);
144
155
  }
145
156
  getWalletTrackerTrades(params) {
146
- const url = new URL(`${this.baseUrl}/api/v1/wallet-tracker/trades`);
157
+ const qs = new URLSearchParams();
147
158
  if (params) {
148
159
  for (const [k, v] of Object.entries(params)) {
149
160
  if (v !== undefined)
150
- url.searchParams.set(k, v);
161
+ qs.set(k, v);
151
162
  }
152
163
  }
153
- return this.restRequest("GET", `/wallet-tracker/trades${url.search}`);
164
+ const query = qs.toString() ? `?${qs.toString()}` : "";
165
+ return this.restRequest("GET", `/wallet-tracker/trades${query}`);
154
166
  }
155
167
  getWalletTrackerSummary(params) {
156
168
  const qs = new URLSearchParams();
@@ -161,4 +173,52 @@ export class MadeOnSolClient {
161
173
  const query = qs.toString() ? `?${qs.toString()}` : "";
162
174
  return this.restRequest("GET", `/wallet-tracker/summary${query}`);
163
175
  }
176
+ // ── Alpha Wallet Intelligence ──
177
+ getAlphaLeaderboard(params) {
178
+ const qs = new URLSearchParams();
179
+ if (params)
180
+ for (const [k, v] of Object.entries(params))
181
+ if (v !== undefined)
182
+ qs.set(k, v);
183
+ const query = qs.toString() ? `?${qs.toString()}` : "";
184
+ return this.restRequest("GET", `/alpha/leaderboard${query}`);
185
+ }
186
+ getAlphaWallet(wallet) {
187
+ return this.restRequest("GET", `/alpha/wallet/${encodeURIComponent(wallet)}`);
188
+ }
189
+ getAlphaLinked(wallet) {
190
+ return this.restRequest("GET", `/alpha/wallet/${encodeURIComponent(wallet)}/linked`);
191
+ }
192
+ // ── Token Quality ──
193
+ getTokenCapTable(mint) {
194
+ return this.restRequest("GET", `/token/${encodeURIComponent(mint)}/cap-table`);
195
+ }
196
+ getTokenBuyerQuality(mint) {
197
+ return this.restRequest("GET", `/token/${encodeURIComponent(mint)}/buyer-quality`);
198
+ }
199
+ // ── Copy-Trade Rules (PRO/ULTRA) ──
200
+ copyTradeList() {
201
+ return this.restRequest("GET", "/copy-trade/rules");
202
+ }
203
+ copyTradeCreate(params) {
204
+ return this.restRequest("POST", "/copy-trade/rules", params);
205
+ }
206
+ copyTradeGet(ruleId) {
207
+ return this.restRequest("GET", `/copy-trade/rules/${encodeURIComponent(ruleId)}`);
208
+ }
209
+ copyTradeUpdate(ruleId, updates) {
210
+ return this.restRequest("PATCH", `/copy-trade/rules/${encodeURIComponent(ruleId)}`, updates);
211
+ }
212
+ copyTradeDelete(ruleId) {
213
+ return this.restRequest("DELETE", `/copy-trade/rules/${encodeURIComponent(ruleId)}`);
214
+ }
215
+ copyTradeSignals(params) {
216
+ const qs = new URLSearchParams();
217
+ if (params)
218
+ for (const [k, v] of Object.entries(params))
219
+ if (v !== undefined)
220
+ qs.set(k, v);
221
+ const query = qs.toString() ? `?${qs.toString()}` : "";
222
+ return this.restRequest("GET", `/copy-trade/signals${query}`);
223
+ }
164
224
  }
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ import { MadeOnSolClient } from "./client.js";
11
11
  export const MADEONSOL_CLIENT_KEY = "madeonsol:client";
12
12
  export const madeOnSolPlugin = {
13
13
  name: "madeonsol",
14
- description: "Query Solana KOL trading intelligence and deployer analytics from MadeOnSol. Tracks 1,000+ KOL wallets and 4000+ Pump.fun deployers.",
14
+ description: "Query Solana KOL trading intelligence and deployer analytics from MadeOnSol. Tracks 1,000+ KOL wallets and 6,700+ Pump.fun deployers.",
15
15
  actions: [
16
16
  kolFeedAction,
17
17
  kolCoordinationAction,
@@ -25,21 +25,20 @@ export const madeOnSolPlugin = {
25
25
  ],
26
26
  /**
27
27
  * Initialize the MadeOnSol client.
28
- * Auth priority: MADEONSOL_API_KEY > RAPIDAPI_KEY > SVM_PRIVATE_KEY (x402).
29
- * Get a free API key at madeonsol.com/developer — no wallet needed.
28
+ * Auth priority: MADEONSOL_API_KEY > SVM_PRIVATE_KEY (x402).
29
+ * Get a free `msk_` API key at madeonsol.com/developer — no wallet needed.
30
+ *
31
+ * v1.0 breaking change: RAPIDAPI_KEY support has been removed
32
+ * (MadeOnSol RapidAPI marketplace was retired 2026-04-19).
30
33
  */
31
34
  init: async (_config, runtime) => {
32
35
  const baseUrl = String(runtime.getSetting?.("MADEONSOL_API_URL") || "https://madeonsol.com");
33
36
  const apiKey = runtime.getSetting?.("MADEONSOL_API_KEY");
34
- const rapidApiKey = runtime.getSetting?.("RAPIDAPI_KEY");
35
37
  const privateKey = runtime.getSetting?.("SVM_PRIVATE_KEY");
36
38
  let fetchFn;
37
39
  if (apiKey) {
38
40
  console.log("[madeonsol] Using MadeOnSol API key (Bearer auth)");
39
41
  }
40
- else if (rapidApiKey) {
41
- console.log("[madeonsol] Using RapidAPI key");
42
- }
43
42
  else if (privateKey) {
44
43
  try {
45
44
  const { wrapFetchWithPayment } = await import("@x402/fetch");
@@ -58,9 +57,9 @@ export const madeOnSolPlugin = {
58
57
  }
59
58
  }
60
59
  else {
61
- console.log("[madeonsol] No auth configured. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY.");
60
+ console.log("[madeonsol] No auth configured. Set MADEONSOL_API_KEY (free at madeonsol.com/developer) or SVM_PRIVATE_KEY.");
62
61
  }
63
- const madeOnSolClient = new MadeOnSolClient({ baseUrl, apiKey, rapidApiKey, fetchFn });
62
+ const madeOnSolClient = new MadeOnSolClient({ baseUrl, apiKey, fetchFn });
64
63
  runtime[MADEONSOL_CLIENT_KEY] = madeOnSolClient;
65
64
  },
66
65
  };
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@madeonsol/plugin-madeonsol",
3
- "version": "0.7.0",
3
+ "version": "1.0.0",
4
4
  "description": "ElizaOS plugin for MadeOnSol — Solana KOL intelligence and deployer analytics via x402 micropayments",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE"
12
+ ],
8
13
  "scripts": {
9
14
  "build": "tsc",
10
15
  "dev": "tsc --watch"
@@ -1,72 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- export const deployerAlertsAction: Action = {
10
- name: "GET_DEPLOYER_ALERTS",
11
- description:
12
- "Get real-time Pump.fun deployer alerts from MadeOnSol. Shows new token launches from tracked elite/good deployers with stats, market cap, and KOL buy enrichment.",
13
- similes: [
14
- "deployer alerts",
15
- "pump fun launches",
16
- "new token alerts",
17
- "deployer tracker",
18
- "elite deployer tokens",
19
- ],
20
-
21
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
22
- const text = (message.content?.text || "").toLowerCase();
23
- return /\b(deployer|pump\.?fun|launch|new token)/i.test(text) && /\b(alert|track|monitor|latest|recent)/i.test(text);
24
- },
25
-
26
- handler: async (
27
- runtime: IAgentRuntime,
28
- message: Memory,
29
- _state?: State,
30
- _options?: unknown,
31
- callback?: HandlerCallback,
32
- ) => {
33
- const client = getClient(runtime);
34
- const text = (message.content?.text || "").toLowerCase();
35
- const limit = text.match(/\b(\d+)\s*(alert|token|launch)/)?.[1] || "10";
36
- // Best-effort tier inference from the user's prompt — only sent to the API
37
- // when the user explicitly mentioned a tier. The tier filter requires
38
- // PRO/ULTRA on the caller's API key.
39
- const tierMatch = text.match(/\b(elite|good|moderate|rising|cold)\b/);
40
- const tier = tierMatch?.[1];
41
-
42
- const result = await client.getDeployerAlerts(tier ? { limit, tier } : { limit });
43
-
44
- if (result.error) {
45
- callback?.({ text: result.status === 402
46
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
47
- : `Error: ${result.error}` });
48
- return undefined;
49
- }
50
-
51
- const data = result.data as { alerts: Array<{ title: string; token_symbol: string; priority: string; market_cap_at_alert: number | null; deployers: { tier: string; bonding_rate: number | null }; kol_buys: { count: number; kols: string[] } | null }> };
52
- const lines = (data.alerts || []).slice(0, 10).map((a) => {
53
- const deployer = a.deployers as unknown as { tier: string; bonding_rate: number | null };
54
- const mc = a.market_cap_at_alert ? `$${(a.market_cap_at_alert / 1000).toFixed(1)}k` : "?";
55
- const kols = a.kol_buys ? `${a.kol_buys.count} KOLs buying` : "";
56
- return `[${deployer?.tier}] ${a.token_symbol || "?"} — MC: ${mc}${kols ? ` | ${kols}` : ""}`;
57
- });
58
-
59
- callback?.({
60
- text: `Deployer Alerts:\n${lines.join("\n") || "No recent alerts."}`,
61
- content: data,
62
- });
63
- return undefined;
64
- },
65
-
66
- examples: [
67
- [
68
- { name: "user1", content: { text: "Show me the latest deployer alerts from Pump.fun" } },
69
- { name: "assistant", content: { text: "Here are the latest deployer alerts..." } },
70
- ],
71
- ] as Action["examples"],
72
- };
@@ -1,67 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- export const kolAlertsRecentAction: Action = {
10
- name: "GET_KOL_ALERTS_RECENT",
11
- description:
12
- "Get live KOL alerts from MadeOnSol — consensus clusters, fresh-token KOL buys, and heating-up wallets in one unified stream.",
13
- similes: [
14
- "kol alerts",
15
- "recent alerts",
16
- "kol signals",
17
- "whats happening now",
18
- "live kol feed",
19
- ],
20
-
21
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
22
- const text = (message.content?.text || "").toLowerCase();
23
- return /\b(kol|smart money)\b/.test(text) && /\b(alert|signal|recent|live|now)\b/.test(text);
24
- },
25
-
26
- handler: async (
27
- runtime: IAgentRuntime,
28
- message: Memory,
29
- _state?: State,
30
- _options?: unknown,
31
- callback?: HandlerCallback,
32
- ) => {
33
- const client = getClient(runtime);
34
- const text = (message.content?.text || "").toLowerCase();
35
- const window = text.includes("1h") ? "1h" : text.includes("6h") ? "6h" : text.includes("24h") ? "24h" : text.includes("5m") ? "5m" : "15m";
36
-
37
- const result = await client.getKolAlertsRecent({ window, limit: "20" });
38
-
39
- if (result.error) {
40
- callback?.({ text: result.status === 402
41
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
42
- : `Error: ${result.error}` });
43
- return undefined;
44
- }
45
-
46
- const data = result.data as {
47
- alerts: Array<{ type: string; severity: string; token_symbol: string | null; kol_name: string | null; detected_at: string }>;
48
- };
49
- const lines = (data.alerts || []).slice(0, 10).map((a) => {
50
- const subject = a.token_symbol || a.kol_name || "—";
51
- return `[${a.severity}] ${a.type}: ${subject}`;
52
- });
53
-
54
- callback?.({
55
- text: `KOL alerts (${window}):\n${lines.join("\n") || "No alerts in window."}`,
56
- content: data,
57
- });
58
- return undefined;
59
- },
60
-
61
- examples: [
62
- [
63
- { name: "user1", content: { text: "What are the recent KOL alerts?" } },
64
- { name: "assistant", content: { text: "Here are the live KOL alerts..." } },
65
- ],
66
- ] as Action["examples"],
67
- };
@@ -1,79 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- const ADDR_RE = /\b[1-9A-HJ-NP-Za-km-z]{32,44}\b/g;
10
-
11
- export const kolCompareAction: Action = {
12
- name: "GET_KOL_COMPARE",
13
- description:
14
- "Compare 2-5 Solana KOL wallets side-by-side on MadeOnSol — strategy, winrates, ROI, percentile. PRO+ adds overlap tokens (bought by 2+ in last 30d).",
15
- similes: [
16
- "compare kols",
17
- "compare wallets",
18
- "kol comparison",
19
- "side by side kols",
20
- "who is better kol",
21
- ],
22
-
23
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
24
- const text = message.content?.text || "";
25
- const matches = text.match(ADDR_RE) ?? [];
26
- return /\bcompare\b/i.test(text) && matches.length >= 2;
27
- },
28
-
29
- handler: async (
30
- runtime: IAgentRuntime,
31
- message: Memory,
32
- _state?: State,
33
- _options?: unknown,
34
- callback?: HandlerCallback,
35
- ) => {
36
- const client = getClient(runtime);
37
- const wallets = ((message.content?.text || "").match(ADDR_RE) ?? []).slice(0, 5);
38
- if (wallets.length < 2) {
39
- callback?.({ text: "Please include at least 2 wallet addresses to compare." });
40
- return undefined;
41
- }
42
-
43
- const result = await client.getKolCompare(wallets);
44
-
45
- if (result.error) {
46
- callback?.({ text: result.status === 402
47
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
48
- : `Error: ${result.error}` });
49
- return undefined;
50
- }
51
-
52
- const data = result.data as {
53
- profiles: Array<{ wallet_address: string; name: string | null; strategy_tag: string | null; winrate_7d: number | null; pnl_30d: number | null }>;
54
- overlap?: Array<{ token_symbol: string | null; wallets: string[] }>;
55
- };
56
- const lines = (data.profiles || []).map((p) => {
57
- const who = p.name || `${p.wallet_address.slice(0, 4)}…${p.wallet_address.slice(-4)}`;
58
- const wr = p.winrate_7d != null ? `${p.winrate_7d.toFixed(1)}%` : "—";
59
- const pnl = p.pnl_30d != null ? `${p.pnl_30d > 0 ? "+" : ""}${p.pnl_30d.toFixed(1)} SOL` : "—";
60
- return `${who} [${p.strategy_tag || "mixed"}] winrate 7d: ${wr}, PnL 30d: ${pnl}`;
61
- });
62
- const overlap = (data.overlap || []).slice(0, 5).map((o) => `${o.token_symbol || "?"} (${o.wallets.length} wallets)`);
63
-
64
- callback?.({
65
- text:
66
- `KOL comparison:\n${lines.join("\n")}` +
67
- (overlap.length ? `\n\nOverlap (30d): ${overlap.join(", ")}` : ""),
68
- content: data,
69
- });
70
- return undefined;
71
- },
72
-
73
- examples: [
74
- [
75
- { name: "user1", content: { text: "Compare these two KOLs: ABC...123 and DEF...456" } },
76
- { name: "assistant", content: { text: "Here's the side-by-side comparison..." } },
77
- ],
78
- ] as Action["examples"],
79
- };
@@ -1,64 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- export const kolCoordinationAction: Action = {
10
- name: "GET_KOL_COORDINATION",
11
- description:
12
- "Get KOL convergence signals from MadeOnSol — tokens being accumulated by multiple KOLs simultaneously. Shows which tokens smart money is converging on.",
13
- similes: [
14
- "kol convergence",
15
- "what tokens are kols accumulating",
16
- "kol coordination",
17
- "smart money convergence",
18
- "multiple kols buying",
19
- ],
20
-
21
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
22
- const text = (message.content?.text || "").toLowerCase();
23
- return /\b(kol|smart money)\b/.test(text) && /\b(converg|coordinat|accumul|same token|multiple)/i.test(text);
24
- },
25
-
26
- handler: async (
27
- runtime: IAgentRuntime,
28
- message: Memory,
29
- _state?: State,
30
- _options?: unknown,
31
- callback?: HandlerCallback,
32
- ) => {
33
- const client = getClient(runtime);
34
- const text = (message.content?.text || "").toLowerCase();
35
- const period = text.includes("1h") ? "1h" : text.includes("7d") ? "7d" : text.includes("6h") ? "6h" : "24h";
36
-
37
- const result = await client.getKolCoordination({ period, limit: "10" });
38
-
39
- if (result.error) {
40
- callback?.({ text: result.status === 402
41
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
42
- : `Error: ${result.error}` });
43
- return undefined;
44
- }
45
-
46
- const data = result.data as { coordination: Array<{ token_symbol: string; kol_count: number; signal: string; net_sol_flow: number }> };
47
- const lines = (data.coordination || []).map(
48
- (t) => `${t.token_symbol}: ${t.kol_count} KOLs ${t.signal} (${t.net_sol_flow > 0 ? "+" : ""}${t.net_sol_flow.toFixed(2)} SOL net)`
49
- );
50
-
51
- callback?.({
52
- text: `KOL convergence signals (${period}):\n${lines.join("\n") || "No coordination signals found."}`,
53
- content: data,
54
- });
55
- return undefined;
56
- },
57
-
58
- examples: [
59
- [
60
- { name: "user1", content: { text: "What tokens are multiple KOLs accumulating?" } },
61
- { name: "assistant", content: { text: "Here are the KOL convergence signals..." } },
62
- ],
63
- ] as Action["examples"],
64
- };
@@ -1,65 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- export const kolFeedAction: Action = {
10
- name: "GET_KOL_FEED",
11
- description:
12
- "Get the real-time Solana KOL trade feed from MadeOnSol. Shows latest buys and sells from 1,000+ tracked KOL wallets with deployer enrichment.",
13
- similes: [
14
- "kol trades",
15
- "what are kols buying",
16
- "solana kol feed",
17
- "kol activity",
18
- "smart money trades",
19
- "what did kols trade",
20
- ],
21
-
22
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
23
- const text = (message.content?.text || "").toLowerCase();
24
- return /\b(kol|smart money)\b/.test(text) && /\b(feed|trade|buy|sell|activit)/i.test(text);
25
- },
26
-
27
- handler: async (
28
- runtime: IAgentRuntime,
29
- message: Memory,
30
- _state?: State,
31
- _options?: unknown,
32
- callback?: HandlerCallback,
33
- ) => {
34
- const client = getClient(runtime);
35
- const text = (message.content?.text || "").toLowerCase();
36
- const action = text.includes("buy") ? "buy" : text.includes("sell") ? "sell" : undefined;
37
-
38
- const result = await client.getKolFeed({ limit: "10", ...(action ? { action } : {}) });
39
-
40
- if (result.error) {
41
- callback?.({ text: result.status === 402
42
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
43
- : `Error: ${result.error}` });
44
- return undefined;
45
- }
46
-
47
- const data = result.data as { trades: Array<{ kol_name: string; token_symbol: string; action: string; sol_amount: number; traded_at: string }> };
48
- const lines = (data.trades || []).slice(0, 10).map(
49
- (t) => `${t.kol_name || "Unknown"} ${t.action === "buy" ? "bought" : "sold"} ${t.token_symbol || "?"} for ${Number(t.sol_amount).toFixed(2)} SOL`
50
- );
51
-
52
- callback?.({
53
- text: `Latest KOL trades:\n${lines.join("\n")}`,
54
- content: data,
55
- });
56
- return undefined;
57
- },
58
-
59
- examples: [
60
- [
61
- { name: "user1", content: { text: "What are the latest KOL trades on Solana?" } },
62
- { name: "assistant", content: { text: "Here are the latest KOL trades from MadeOnSol..." } },
63
- ],
64
- ] as Action["examples"],
65
- };
@@ -1,64 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- export const kolLeaderboardAction: Action = {
10
- name: "GET_KOL_LEADERBOARD",
11
- description:
12
- "Get KOL performance rankings from MadeOnSol — top Solana KOLs ranked by PnL, volume, and win rate.",
13
- similes: [
14
- "kol leaderboard",
15
- "best performing kols",
16
- "top kol traders",
17
- "kol rankings",
18
- "who is the best kol",
19
- ],
20
-
21
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
22
- const text = (message.content?.text || "").toLowerCase();
23
- return /\b(kol|smart money)\b/.test(text) && /\b(leaderboard|ranking|top|best|perform|pnl|win rate)/i.test(text);
24
- },
25
-
26
- handler: async (
27
- runtime: IAgentRuntime,
28
- message: Memory,
29
- _state?: State,
30
- _options?: unknown,
31
- callback?: HandlerCallback,
32
- ) => {
33
- const client = getClient(runtime);
34
- const text = (message.content?.text || "").toLowerCase();
35
- const period = text.includes("today") ? "today" : text.includes("30d") || text.includes("month") ? "30d" : "7d";
36
-
37
- const result = await client.getKolLeaderboard({ period, limit: "10" });
38
-
39
- if (result.error) {
40
- callback?.({ text: result.status === 402
41
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
42
- : `Error: ${result.error}` });
43
- return undefined;
44
- }
45
-
46
- const data = result.data as { leaderboard: Array<{ name: string; pnl_sol: number; buy_count: number; sell_count: number; win_rate: number | null }> };
47
- const lines = (data.leaderboard || []).map(
48
- (k, i) => `${i + 1}. ${k.name}: ${k.pnl_sol > 0 ? "+" : ""}${k.pnl_sol.toFixed(2)} SOL PnL (${k.buy_count}B/${k.sell_count}S${k.win_rate != null ? `, ${(k.win_rate * 100).toFixed(0)}% WR` : ""})`
49
- );
50
-
51
- callback?.({
52
- text: `KOL Leaderboard (${period}):\n${lines.join("\n") || "No data for this period."}`,
53
- content: data,
54
- });
55
- return undefined;
56
- },
57
-
58
- examples: [
59
- [
60
- { name: "user1", content: { text: "Show me the top performing KOLs this week" } },
61
- { name: "assistant", content: { text: "Here are the top KOLs by PnL..." } },
62
- ],
63
- ] as Action["examples"],
64
- };
@@ -1,71 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- const MINT_RE = /\b([1-9A-HJ-NP-Za-km-z]{32,44})\b/;
10
-
11
- export const kolTokenEntryOrderAction: Action = {
12
- name: "GET_KOL_TOKEN_ENTRY_ORDER",
13
- description:
14
- "Get the ranked order of KOL first-buyers for a specific Solana token from MadeOnSol. Shows who entered first and how quickly others followed.",
15
- similes: [
16
- "who bought first",
17
- "first kol buyers",
18
- "kol entry order",
19
- "token entry ranking",
20
- "who entered first",
21
- ],
22
-
23
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
24
- const text = message.content?.text || "";
25
- return /\b(first|entry|entered|order)\b/i.test(text) && MINT_RE.test(text);
26
- },
27
-
28
- handler: async (
29
- runtime: IAgentRuntime,
30
- message: Memory,
31
- _state?: State,
32
- _options?: unknown,
33
- callback?: HandlerCallback,
34
- ) => {
35
- const client = getClient(runtime);
36
- const mint = (message.content?.text || "").match(MINT_RE)?.[1];
37
- if (!mint) {
38
- callback?.({ text: "Please include a token mint address." });
39
- return undefined;
40
- }
41
-
42
- const result = await client.getKolTokenEntryOrder(mint, { limit: "20" });
43
-
44
- if (result.error) {
45
- callback?.({ text: result.status === 402
46
- ? "Authentication required. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY."
47
- : `Error: ${result.error}` });
48
- return undefined;
49
- }
50
-
51
- const data = result.data as { entries: Array<{ rank: number; kol_name: string | null; wallet_address: string; sol_amount: number; seconds_after_first: number }> };
52
- const lines = (data.entries || []).slice(0, 10).map((e) => {
53
- const who = e.kol_name || `${e.wallet_address.slice(0, 4)}…${e.wallet_address.slice(-4)}`;
54
- const when = e.seconds_after_first === 0 ? "first" : `+${e.seconds_after_first}s`;
55
- return `#${e.rank} ${who} — ${e.sol_amount.toFixed(2)} SOL (${when})`;
56
- });
57
-
58
- callback?.({
59
- text: `KOL entry order for ${mint.slice(0, 8)}…:\n${lines.join("\n") || "No KOL buys recorded."}`,
60
- content: data,
61
- });
62
- return undefined;
63
- },
64
-
65
- examples: [
66
- [
67
- { name: "user1", content: { text: "Who were the first KOLs to buy 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU?" } },
68
- { name: "assistant", content: { text: "Here's the KOL entry order for that token..." } },
69
- ],
70
- ] as Action["examples"],
71
- };
@@ -1,119 +0,0 @@
1
- import type { Action, IAgentRuntime, Memory, State, HandlerCallback } from "@elizaos/core";
2
- import { MadeOnSolClient } from "../client.js";
3
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
4
-
5
- function getClient(runtime: IAgentRuntime): MadeOnSolClient {
6
- return ((runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] as MadeOnSolClient) ?? new MadeOnSolClient();
7
- }
8
-
9
- export const walletTrackerWatchlistAction: Action = {
10
- name: "WALLET_TRACKER_WATCHLIST",
11
- description:
12
- "List wallets in your MadeOnSol wallet watchlist with labels and remaining capacity.",
13
- similes: [
14
- "wallet watchlist",
15
- "tracked wallets",
16
- "my wallets",
17
- "wallet tracker list",
18
- "show tracked wallets",
19
- ],
20
-
21
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
22
- const text = (message.content?.text || "").toLowerCase();
23
- return /\b(wallet.tracker|watchlist|tracked wallet)/i.test(text) && /\b(list|show|get|my)\b/i.test(text);
24
- },
25
-
26
- handler: async (
27
- runtime: IAgentRuntime,
28
- _message: Memory,
29
- _state?: State,
30
- _options?: unknown,
31
- callback?: HandlerCallback,
32
- ) => {
33
- const client = getClient(runtime);
34
- const result = await client.getWalletTrackerWatchlist();
35
-
36
- if (result.error) {
37
- callback?.({ text: `Error: ${result.error}` });
38
- return undefined;
39
- }
40
-
41
- const data = result.data as { wallets: Array<{ wallet_address: string; label: string | null; added_at: string }>; count: number; limit: number; remaining: number };
42
- const lines = (data.wallets || []).map(
43
- (w) => `${w.label ? `[${w.label}] ` : ""}${w.wallet_address}`
44
- );
45
-
46
- callback?.({
47
- text: lines.length
48
- ? `Tracked wallets (${data.count}/${data.limit}):\n${lines.join("\n")}\n${data.remaining} slot(s) remaining.`
49
- : `No wallets tracked yet. Limit: ${data.limit}.`,
50
- content: data,
51
- });
52
- return undefined;
53
- },
54
-
55
- examples: [
56
- [
57
- { name: "user1", content: { text: "Show my wallet tracker watchlist" } },
58
- { name: "assistant", content: { text: "Here are your tracked wallets..." } },
59
- ],
60
- ] as Action["examples"],
61
- };
62
-
63
- export const walletTrackerTradesAction: Action = {
64
- name: "WALLET_TRACKER_TRADES",
65
- description:
66
- "Get recent swap and transfer events from wallets in your MadeOnSol watchlist.",
67
- similes: [
68
- "wallet tracker trades",
69
- "tracked wallet activity",
70
- "watchlist trades",
71
- "wallet swaps",
72
- "wallet transfers",
73
- "what did my tracked wallets do",
74
- ],
75
-
76
- validate: async (_runtime: IAgentRuntime, message: Memory): Promise<boolean> => {
77
- const text = (message.content?.text || "").toLowerCase();
78
- return /\b(wallet.tracker|watchlist|tracked wallet)/i.test(text) && /\b(trade|swap|transfer|activity|buy|sell)\b/i.test(text);
79
- },
80
-
81
- handler: async (
82
- runtime: IAgentRuntime,
83
- message: Memory,
84
- _state?: State,
85
- _options?: unknown,
86
- callback?: HandlerCallback,
87
- ) => {
88
- const client = getClient(runtime);
89
- const text = (message.content?.text || "").toLowerCase();
90
- const action = text.includes("buy") ? "buy" : text.includes("sell") ? "sell" : undefined;
91
-
92
- const result = await client.getWalletTrackerTrades({ limit: "20", ...(action ? { action } : {}) });
93
-
94
- if (result.error) {
95
- callback?.({ text: `Error: ${result.error}` });
96
- return undefined;
97
- }
98
-
99
- const data = result.data as { events: Array<{ wallet_address: string; label: string | null; action: string; token_symbol: string | null; sol_amount: number; block_time_iso: string }>; count: number };
100
- const lines = (data.events || []).slice(0, 15).map(
101
- (e) => `${e.label || e.wallet_address.slice(0, 8)} ${e.action} ${e.token_symbol || "?"} for ${Number(e.sol_amount).toFixed(2)} SOL`
102
- );
103
-
104
- callback?.({
105
- text: lines.length
106
- ? `Recent wallet tracker events:\n${lines.join("\n")}`
107
- : "No recent events for your tracked wallets.",
108
- content: data,
109
- });
110
- return undefined;
111
- },
112
-
113
- examples: [
114
- [
115
- { name: "user1", content: { text: "What did my tracked wallets trade recently?" } },
116
- { name: "assistant", content: { text: "Here are the latest trades from your watchlist..." } },
117
- ],
118
- ] as Action["examples"],
119
- };
package/src/client.ts DELETED
@@ -1,204 +0,0 @@
1
- /**
2
- * MadeOnSol API client.
3
- * Supports 3 auth modes: API key (simplest), RapidAPI key, or x402 micropayments.
4
- */
5
-
6
- const DEFAULT_BASE = "https://madeonsol.com";
7
- const RAPIDAPI_HOST = "madeonsol-solana-kol-tracker-tools-api.p.rapidapi.com";
8
-
9
- type AuthMode = "madeonsol" | "rapidapi" | "x402" | "none";
10
-
11
- export interface MadeOnSolClientOptions {
12
- baseUrl?: string;
13
- /** MadeOnSol API key (get one free at madeonsol.com/developer). Preferred. */
14
- apiKey?: string;
15
- /** RapidAPI subscription key. */
16
- rapidApiKey?: string;
17
- /** x402 payment-enabled fetch (for AI agents with SVM_PRIVATE_KEY). */
18
- fetchFn?: typeof fetch;
19
- }
20
-
21
- export class MadeOnSolClient {
22
- private baseUrl: string;
23
- private fetchFn: typeof fetch;
24
- private authMode: AuthMode;
25
- private authHeaders: Record<string, string>;
26
-
27
- constructor(options: MadeOnSolClientOptions = {}) {
28
- this.baseUrl = options.baseUrl || DEFAULT_BASE;
29
- this.fetchFn = options.fetchFn || globalThis.fetch;
30
- this.authHeaders = {};
31
-
32
- if (options.apiKey) {
33
- this.authMode = "madeonsol";
34
- this.authHeaders = { Authorization: `Bearer ${options.apiKey}` };
35
- } else if (options.rapidApiKey) {
36
- this.authMode = "rapidapi";
37
- this.authHeaders = { "x-rapidapi-key": options.rapidApiKey, "x-rapidapi-host": RAPIDAPI_HOST };
38
- } else if (options.fetchFn) {
39
- this.authMode = "x402";
40
- } else {
41
- this.authMode = "none";
42
- }
43
- }
44
-
45
- async query<T = unknown>(path: string, params?: Record<string, string | undefined>): Promise<{ data?: T; error?: string; status: number }> {
46
- const apiPath = this.authMode === "x402" || this.authMode === "none"
47
- ? path
48
- : path.replace("/api/x402/", "/api/v1/");
49
- const url = new URL(apiPath, this.baseUrl);
50
- if (params) {
51
- for (const [k, v] of Object.entries(params)) {
52
- if (v !== undefined) url.searchParams.set(k, v);
53
- }
54
- }
55
-
56
- const res = this.authMode === "x402"
57
- ? await this.fetchFn(url.toString(), { method: "GET" })
58
- : await this.fetchFn(url.toString(), { method: "GET", headers: this.authHeaders });
59
-
60
- if (res.status === 402) {
61
- const body = await res.json();
62
- return { error: `Payment required: ${JSON.stringify(body.accepts?.[0] || body)}`, status: 402 };
63
- }
64
-
65
- if (!res.ok) {
66
- const text = await res.text().catch(() => "Unknown error");
67
- return { error: text, status: res.status };
68
- }
69
-
70
- const data = await res.json() as T;
71
- return { data, status: res.status };
72
- }
73
-
74
- getKolFeed(params?: { limit?: string; action?: string; kol?: string }) {
75
- return this.query("/api/x402/kol/feed", params);
76
- }
77
-
78
- getKolCoordination(params?: { period?: string; min_kols?: string; limit?: string }) {
79
- return this.query("/api/x402/kol/coordination", params);
80
- }
81
-
82
- getKolLeaderboard(params?: { period?: string; limit?: string }) {
83
- return this.query("/api/x402/kol/leaderboard", params);
84
- }
85
-
86
- /**
87
- * Get deployer alerts. The `tier` filter (elite/good/moderate/rising/cold)
88
- * is PRO/ULTRA only — BASIC callers passing it receive HTTP 403.
89
- */
90
- getDeployerAlerts(params?: { since?: string; limit?: string; offset?: string; tier?: string }) {
91
- return this.query("/api/x402/deployer-hunter/alerts", params);
92
- }
93
-
94
- getKolPairs(params?: { period?: string; min_shared?: string; limit?: string }) {
95
- return this.query("/api/x402/kol/pairs", params);
96
- }
97
-
98
- getKolHotTokens(params?: { period?: string; min_kols?: string; limit?: string }) {
99
- return this.query("/api/x402/kol/tokens/hot", params);
100
- }
101
-
102
- getKolTrendingTokens(params?: { period?: string; min_kols?: string; limit?: string }) {
103
- return this.query("/api/x402/kol/tokens/trending", params);
104
- }
105
-
106
- getKolTokenEntryOrder(mint: string, params?: { limit?: string }) {
107
- return this.query(`/api/x402/kol/tokens/${encodeURIComponent(mint)}/entry-order`, params);
108
- }
109
-
110
- getKolCompare(wallets: string[]) {
111
- return this.query("/api/x402/kol/compare", { wallets: wallets.join(",") });
112
- }
113
-
114
- getKolAlertsRecent(params?: { window?: string; types?: string; min_severity?: string; limit?: string }) {
115
- return this.query("/api/x402/kol/alerts/recent", params);
116
- }
117
-
118
- getKolPnl(wallet: string, params?: { period?: string }) {
119
- const qs = params?.period ? `?period=${params.period}` : "";
120
- return this.restRequest("GET", `/kol/${wallet}/pnl${qs}`);
121
- }
122
-
123
- getKolTiming(wallet: string, params?: { period?: string }) {
124
- const qs = params?.period ? `?period=${params.period}` : "";
125
- return this.restRequest("GET", `/kol/${wallet}/timing${qs}`);
126
- }
127
-
128
- getDeployerTrajectory(wallet: string) {
129
- return this.restRequest("GET", `/deployer-hunter/${wallet}/trajectory`);
130
- }
131
-
132
- // ── Webhook management (requires API key or RapidAPI key with Pro/Ultra) ──
133
-
134
- private async restRequest<T = unknown>(method: string, path: string, body?: unknown): Promise<{ data?: T; error?: string; status: number }> {
135
- if (this.authMode !== "madeonsol" && this.authMode !== "rapidapi") {
136
- return { error: "API key or RapidAPI key required for webhook/streaming features. Get a free key at madeonsol.com/developer", status: 401 };
137
- }
138
- const res = await this.fetchFn(`${this.baseUrl}/api/v1${path}`, {
139
- method,
140
- headers: {
141
- "Content-Type": "application/json",
142
- ...this.authHeaders,
143
- },
144
- ...(body ? { body: JSON.stringify(body) } : {}),
145
- });
146
- if (!res.ok) {
147
- const text = await res.text().catch(() => "Unknown error");
148
- return { error: text, status: res.status };
149
- }
150
- return { data: await res.json() as T, status: res.status };
151
- }
152
-
153
- createWebhook(params: { url: string; events: string[]; filters?: Record<string, unknown> }) {
154
- return this.restRequest("POST", "/webhooks", params);
155
- }
156
-
157
- listWebhooks() {
158
- return this.restRequest("GET", "/webhooks");
159
- }
160
-
161
- deleteWebhook(id: number) {
162
- return this.restRequest("DELETE", `/webhooks/${id}`);
163
- }
164
-
165
- testWebhook(webhookId: number) {
166
- return this.restRequest("POST", "/webhooks/test", { webhook_id: webhookId });
167
- }
168
-
169
- getStreamToken() {
170
- return this.restRequest("POST", "/stream/token");
171
- }
172
-
173
- // ── Wallet Tracker ──
174
-
175
- getWalletTrackerWatchlist() {
176
- return this.restRequest("GET", "/wallet-tracker/watchlist");
177
- }
178
-
179
- addToWatchlist(walletAddress: string, label?: string) {
180
- return this.restRequest("POST", "/wallet-tracker/watchlist", { wallet_address: walletAddress, ...(label ? { label } : {}) });
181
- }
182
-
183
- removeFromWatchlist(walletAddress: string) {
184
- return this.restRequest("DELETE", `/wallet-tracker/watchlist/${encodeURIComponent(walletAddress)}`);
185
- }
186
-
187
- getWalletTrackerTrades(params?: { wallet?: string; action?: string; event_type?: string; limit?: string; before?: string }) {
188
- const url = new URL(`${this.baseUrl}/api/v1/wallet-tracker/trades`);
189
- if (params) {
190
- for (const [k, v] of Object.entries(params)) {
191
- if (v !== undefined) url.searchParams.set(k, v);
192
- }
193
- }
194
- return this.restRequest("GET", `/wallet-tracker/trades${url.search}`);
195
- }
196
-
197
- getWalletTrackerSummary(params?: { period?: string; wallet?: string }) {
198
- const qs = new URLSearchParams();
199
- if (params?.period) qs.set("period", params.period);
200
- if (params?.wallet) qs.set("wallet", params.wallet);
201
- const query = qs.toString() ? `?${qs.toString()}` : "";
202
- return this.restRequest("GET", `/wallet-tracker/summary${query}`);
203
- }
204
- }
package/src/index.ts DELETED
@@ -1,78 +0,0 @@
1
- import type { Plugin, IAgentRuntime } from "@elizaos/core";
2
- import { kolFeedAction } from "./actions/kol-feed.js";
3
- import { kolCoordinationAction } from "./actions/kol-coordination.js";
4
- import { kolLeaderboardAction } from "./actions/kol-leaderboard.js";
5
- import { deployerAlertsAction } from "./actions/deployer-alerts.js";
6
- import { walletTrackerWatchlistAction, walletTrackerTradesAction } from "./actions/wallet-tracker.js";
7
- import { kolTokenEntryOrderAction } from "./actions/kol-token-entry-order.js";
8
- import { kolCompareAction } from "./actions/kol-compare.js";
9
- import { kolAlertsRecentAction } from "./actions/kol-alerts-recent.js";
10
- import { MadeOnSolClient } from "./client.js";
11
-
12
- /** Key used to store the initialized client on the runtime */
13
- export const MADEONSOL_CLIENT_KEY = "madeonsol:client";
14
-
15
- export const madeOnSolPlugin: Plugin = {
16
- name: "madeonsol",
17
- description:
18
- "Query Solana KOL trading intelligence and deployer analytics from MadeOnSol. Tracks 1,000+ KOL wallets and 4000+ Pump.fun deployers.",
19
- actions: [
20
- kolFeedAction,
21
- kolCoordinationAction,
22
- kolLeaderboardAction,
23
- deployerAlertsAction,
24
- walletTrackerWatchlistAction,
25
- walletTrackerTradesAction,
26
- kolTokenEntryOrderAction,
27
- kolCompareAction,
28
- kolAlertsRecentAction,
29
- ],
30
-
31
- /**
32
- * Initialize the MadeOnSol client.
33
- * Auth priority: MADEONSOL_API_KEY > RAPIDAPI_KEY > SVM_PRIVATE_KEY (x402).
34
- * Get a free API key at madeonsol.com/developer — no wallet needed.
35
- */
36
- init: async (_config: Record<string, string>, runtime: IAgentRuntime) => {
37
- const baseUrl = String(runtime.getSetting?.("MADEONSOL_API_URL") || "https://madeonsol.com");
38
- const apiKey = runtime.getSetting?.("MADEONSOL_API_KEY") as string | undefined;
39
- const rapidApiKey = runtime.getSetting?.("RAPIDAPI_KEY") as string | undefined;
40
- const privateKey = runtime.getSetting?.("SVM_PRIVATE_KEY") as string | undefined;
41
-
42
- let fetchFn: typeof fetch | undefined;
43
-
44
- if (apiKey) {
45
- console.log("[madeonsol] Using MadeOnSol API key (Bearer auth)");
46
- } else if (rapidApiKey) {
47
- console.log("[madeonsol] Using RapidAPI key");
48
- } else if (privateKey) {
49
- try {
50
- const { wrapFetchWithPayment } = await import("@x402/fetch");
51
- const { x402Client } = await import("@x402/core/client");
52
- const { ExactSvmScheme } = await import("@x402/svm/exact/client");
53
- const { createKeyPairSignerFromBytes } = await import("@solana/kit");
54
- const { base58 } = await import("@scure/base");
55
-
56
- const signer = await createKeyPairSignerFromBytes(base58.decode(privateKey));
57
- const client = new x402Client();
58
- client.register("solana:*", new ExactSvmScheme(signer));
59
- fetchFn = wrapFetchWithPayment(fetch, client);
60
-
61
- console.log(`[madeonsol] x402 payments enabled, wallet: ${signer.address}`);
62
- } catch (err) {
63
- console.warn("[madeonsol] x402 payment setup failed:", err);
64
- }
65
- } else {
66
- console.log("[madeonsol] No auth configured. Set MADEONSOL_API_KEY (free at madeonsol.com/developer), RAPIDAPI_KEY, or SVM_PRIVATE_KEY.");
67
- }
68
-
69
- const madeOnSolClient = new MadeOnSolClient({ baseUrl, apiKey, rapidApiKey, fetchFn });
70
- (runtime as unknown as Record<string, unknown>)[MADEONSOL_CLIENT_KEY] = madeOnSolClient;
71
- },
72
- };
73
-
74
- export default madeOnSolPlugin;
75
- export { MadeOnSolClient } from "./client.js";
76
- export { kolFeedAction, kolCoordinationAction, kolLeaderboardAction, deployerAlertsAction };
77
- export { walletTrackerWatchlistAction, walletTrackerTradesAction };
78
- export { kolTokenEntryOrderAction, kolCompareAction, kolAlertsRecentAction };
package/tsconfig.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "bundler",
6
- "declaration": true,
7
- "outDir": "dist",
8
- "rootDir": "src",
9
- "strict": true,
10
- "esModuleInterop": true,
11
- "skipLibCheck": true
12
- },
13
- "include": ["src"]
14
- }