@madeonsol/plugin-madeonsol 1.3.1 → 1.4.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
@@ -4,18 +4,6 @@ ElizaOS plugin for [MadeOnSol](https://madeonsol.com) — Solana KOL trading int
4
4
 
5
5
  > Real-time Solana trading intelligence: track 1,000+ KOL wallets with <3s latency, score 6,700+ Pump.fun deployers by reputation, detect multi-KOL coordination signals, monitor any Solana wallet for swaps and transfers, and stream every DEX trade. Free tier: 200 requests/day at [madeonsol.com/developer](https://madeonsol.com/developer) — no credit card required.
6
6
 
7
- ## Quick start (10 seconds)
8
-
9
- ```bash
10
- npm install @madeonsol/plugin-madeonsol
11
- ```
12
-
13
- ```ts
14
- import { madeOnSolPlugin } from "@madeonsol/plugin-madeonsol";
15
- const agent = { plugins: [madeOnSolPlugin], settings: { MADEONSOL_API_KEY: "msk_..." } }; // free key: https://madeonsol.com/developer
16
- // Then ask the agent: "What are KOLs buying right now?"
17
- ```
18
-
19
7
  ## Authentication
20
8
 
21
9
  Three options (in priority order):
@@ -32,7 +20,7 @@ Gives your ElizaOS agent access to MadeOnSol's Solana intelligence API.
32
20
  | Action | Description |
33
21
  |--------|-------------|
34
22
  | `GET_KOL_FEED` | Real-time KOL trade feed (1,000+ wallets) |
35
- | `GET_KOL_COORDINATION` | Multi-KOL convergence (v1.1 — peak-density, exits, 0-100 score) |
23
+ | `GET_KOL_COORDINATION` | Multi-KOL convergence signals |
36
24
  | `GET_KOL_LEADERBOARD` | KOL PnL/win-rate rankings (180 days of history) |
37
25
  | `GET_DEPLOYER_ALERTS` | Pump.fun deployer alerts with KOL enrichment |
38
26
  | `WALLET_TRACKER_WATCHLIST` | List your tracked wallets and remaining capacity |
@@ -63,57 +51,6 @@ const agent = {
63
51
  };
64
52
  ```
65
53
 
66
- ### v1.1 Coordination alerts (programmatic)
67
-
68
- The `GET_KOL_COORDINATION` action surfaces the v1.1 `coordination_score`, `peak_kols`, and `exited_count` fields. For **push alerts** (fires within ~1s of a qualifying trade via WS `kol:coordination` channel + HMAC-signed webhook), use the client directly from a custom action:
69
-
70
- ```ts
71
- import { MadeOnSolClient } from "@madeonsol/plugin-madeonsol";
72
-
73
- const client = new MadeOnSolClient({ apiKey: process.env.MADEONSOL_API_KEY });
74
- const res = await client.coordinationAlertsCreate({
75
- name: "fresh pump cluster",
76
- min_kols: 4,
77
- window_minutes: 15,
78
- min_score: 70,
79
- include_majors: false,
80
- cooldown_min: 60,
81
- score_jump_break: 10,
82
- delivery_mode: "both",
83
- webhook_url: "https://you.com/hooks/coord",
84
- });
85
- // store res.data.webhook_secret — shown ONCE
86
- ```
87
-
88
- PRO=5 rules, ULTRA=20. Also available: `coordinationAlertsList()`, `coordinationAlertsGet(id)`, `coordinationAlertsUpdate(id, updates)`, `coordinationAlertsDelete(id)`.
89
-
90
- ### First-touch signal *(new in 1.3)*
91
-
92
- Every "first KOL buy on a token mint" event — when a tracked KOL is the first of the cohort to touch a token. Filterable by **scout tier** (S/A/B/C from `mv_kol_scout_score`), KOL winrate, token age, mint suffix.
93
-
94
- **Backtest:** S-tier scouts attract ≥3 follow-on KOLs within 4h ~50% of the time vs ~14% baseline (38d / 491k buys).
95
-
96
- ```ts
97
- import { MadeOnSolClient } from "@madeonsol/plugin-madeonsol";
98
- const client = new MadeOnSolClient({ apiKey: process.env.MADEONSOL_API_KEY });
99
-
100
- // REST query
101
- const { events } = await client.firstTouches({ preset: "scout", min_scout_tier: "S", limit: 20 });
102
-
103
- // Webhook subscription (Ultra) — push delivery, HMAC-signed
104
- const { subscription, webhook_secret } = await client.firstTouchSubscriptionsCreate({
105
- name: "S-tier scouts on pump tokens",
106
- filters: { min_scout_tier: "S", mint_suffix: "pump" },
107
- delivery_mode: "webhook",
108
- webhook_url: "https://you.com/hooks/scout",
109
- });
110
- // store webhook_secret — shown ONCE
111
- ```
112
-
113
- ULTRA only for subscriptions — up to 10 active. CRUD: `firstTouchSubscriptionsList()`, `firstTouchSubscriptionsGet(id)`, `firstTouchSubscriptionsUpdate(id, updates)`, `firstTouchSubscriptionsDelete(id)`.
114
-
115
- > **Don't poll — push.** Median lead time before the second KOL is 12 seconds. WebSocket channel: `kol:first_touches`.
116
-
117
54
  Your agent can then respond to queries like:
118
55
  - "What are KOLs buying right now?"
119
56
  - "Show me the KOL leaderboard this week"
@@ -126,18 +63,17 @@ Your agent can then respond to queries like:
126
63
 
127
64
  | Tier | Price | Wallets tracked | Requests/day |
128
65
  |------|-------|-----------------|--------------|
129
- | Free | $0 | 10 | 200 |
130
- | Pro | $49/mo | 50 | 10,000 |
131
- | Ultra | $149/mo | 100 + WS events | 100,000 |
66
+ | BASIC | Free | 10 | 200 |
67
+ | PRO | $49/mo | 50 | 10,000 |
68
+ | ULTRA | $149/mo | 100 + WS events | 100,000 |
132
69
 
133
- Free tier returns the full REST response shape on every endpoint — real wallets, TX signatures, full precision. Paid tiers unlock webhooks, WebSockets, rule engines, and ULTRA-only data depth. Get a key at [madeonsol.com/developer](https://madeonsol.com/developer).
70
+ Get a key at [madeonsol.com/developer](https://madeonsol.com/developer).
134
71
 
135
72
  ## Also Available
136
73
 
137
74
  | Platform | Package |
138
75
  |---|---|
139
76
  | TypeScript SDK | [`madeonsol`](https://www.npmjs.com/package/madeonsol) on npm |
140
- | Rust SDK | [`madeonsol`](https://crates.io/crates/madeonsol) on crates.io |
141
77
  | Python (LangChain, CrewAI) | [`madeonsol-x402`](https://pypi.org/project/madeonsol-x402/) on PyPI |
142
78
  | MCP Server (Claude, Cursor) | [`mcp-server-madeonsol`](https://www.npmjs.com/package/mcp-server-madeonsol) |
143
79
  | Solana Agent Kit | [`solana-agent-kit-plugin-madeonsol`](https://www.npmjs.com/package/solana-agent-kit-plugin-madeonsol) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@madeonsol/plugin-madeonsol",
3
- "version": "1.3.1",
3
+ "version": "1.4.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",
@@ -1,2 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const deployerAlertsAction: Action;
@@ -1,55 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- export const deployerAlertsAction = {
7
- name: "GET_DEPLOYER_ALERTS",
8
- description: "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.",
9
- similes: [
10
- "deployer alerts",
11
- "pump fun launches",
12
- "new token alerts",
13
- "deployer tracker",
14
- "elite deployer tokens",
15
- ],
16
- validate: async (_runtime, message) => {
17
- const text = (message.content?.text || "").toLowerCase();
18
- return /\b(deployer|pump\.?fun|launch|new token)/i.test(text) && /\b(alert|track|monitor|latest|recent)/i.test(text);
19
- },
20
- handler: async (runtime, message, _state, _options, callback) => {
21
- const client = getClient(runtime);
22
- const text = (message.content?.text || "").toLowerCase();
23
- const limit = text.match(/\b(\d+)\s*(alert|token|launch)/)?.[1] || "10";
24
- // Best-effort tier inference from the user's prompt — only sent to the API
25
- // when the user explicitly mentioned a tier. The tier filter requires
26
- // PRO/ULTRA on the caller's API key.
27
- const tierMatch = text.match(/\b(elite|good|moderate|rising|cold)\b/);
28
- const tier = tierMatch?.[1];
29
- const result = await client.getDeployerAlerts(tier ? { limit, tier } : { limit });
30
- if (result.error) {
31
- callback?.({ text: result.status === 402
32
- ? "Authentication required. Set MADEONSOL_API_KEY — free at https://madeonsol.com/developer — or SVM_PRIVATE_KEY."
33
- : `Error: ${result.error}` });
34
- return undefined;
35
- }
36
- const data = result.data;
37
- const lines = (data.alerts || []).slice(0, 10).map((a) => {
38
- const deployer = a.deployers;
39
- const mc = a.market_cap_at_alert ? `$${(a.market_cap_at_alert / 1000).toFixed(1)}k` : "?";
40
- const kols = a.kol_buys ? `${a.kol_buys.count} KOLs buying` : "";
41
- return `[${deployer?.tier}] ${a.token_symbol || "?"} — MC: ${mc}${kols ? ` | ${kols}` : ""}`;
42
- });
43
- callback?.({
44
- text: `Deployer Alerts:\n${lines.join("\n") || "No recent alerts."}`,
45
- content: data,
46
- });
47
- return undefined;
48
- },
49
- examples: [
50
- [
51
- { name: "user1", content: { text: "Show me the latest deployer alerts from Pump.fun" } },
52
- { name: "assistant", content: { text: "Here are the latest deployer alerts..." } },
53
- ],
54
- ],
55
- };
@@ -1,2 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const kolAlertsRecentAction: Action;
@@ -1,48 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- export const kolAlertsRecentAction = {
7
- name: "GET_KOL_ALERTS_RECENT",
8
- description: "Get live KOL alerts from MadeOnSol — consensus clusters, fresh-token KOL buys, and heating-up wallets in one unified stream.",
9
- similes: [
10
- "kol alerts",
11
- "recent alerts",
12
- "kol signals",
13
- "whats happening now",
14
- "live kol feed",
15
- ],
16
- validate: async (_runtime, message) => {
17
- const text = (message.content?.text || "").toLowerCase();
18
- return /\b(kol|smart money)\b/.test(text) && /\b(alert|signal|recent|live|now)\b/.test(text);
19
- },
20
- handler: async (runtime, message, _state, _options, callback) => {
21
- const client = getClient(runtime);
22
- const text = (message.content?.text || "").toLowerCase();
23
- const window = text.includes("1h") ? "1h" : text.includes("6h") ? "6h" : text.includes("24h") ? "24h" : text.includes("5m") ? "5m" : "15m";
24
- const result = await client.getKolAlertsRecent({ window, limit: "20" });
25
- if (result.error) {
26
- callback?.({ text: result.status === 402
27
- ? "Authentication required. Set MADEONSOL_API_KEY — free at https://madeonsol.com/developer — or SVM_PRIVATE_KEY."
28
- : `Error: ${result.error}` });
29
- return undefined;
30
- }
31
- const data = result.data;
32
- const lines = (data.alerts || []).slice(0, 10).map((a) => {
33
- const subject = a.token_symbol || a.kol_name || "—";
34
- return `[${a.severity}] ${a.type}: ${subject}`;
35
- });
36
- callback?.({
37
- text: `KOL alerts (${window}):\n${lines.join("\n") || "No alerts in window."}`,
38
- content: data,
39
- });
40
- return undefined;
41
- },
42
- examples: [
43
- [
44
- { name: "user1", content: { text: "What are the recent KOL alerts?" } },
45
- { name: "assistant", content: { text: "Here are the live KOL alerts..." } },
46
- ],
47
- ],
48
- };
@@ -1,2 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const kolCompareAction: Action;
@@ -1,57 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- const ADDR_RE = /\b[1-9A-HJ-NP-Za-km-z]{32,44}\b/g;
7
- export const kolCompareAction = {
8
- name: "GET_KOL_COMPARE",
9
- description: "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).",
10
- similes: [
11
- "compare kols",
12
- "compare wallets",
13
- "kol comparison",
14
- "side by side kols",
15
- "who is better kol",
16
- ],
17
- validate: async (_runtime, message) => {
18
- const text = message.content?.text || "";
19
- const matches = text.match(ADDR_RE) ?? [];
20
- return /\bcompare\b/i.test(text) && matches.length >= 2;
21
- },
22
- handler: async (runtime, message, _state, _options, callback) => {
23
- const client = getClient(runtime);
24
- const wallets = ((message.content?.text || "").match(ADDR_RE) ?? []).slice(0, 5);
25
- if (wallets.length < 2) {
26
- callback?.({ text: "Please include at least 2 wallet addresses to compare." });
27
- return undefined;
28
- }
29
- const result = await client.getKolCompare(wallets);
30
- if (result.error) {
31
- callback?.({ text: result.status === 402
32
- ? "Authentication required. Set MADEONSOL_API_KEY — free at https://madeonsol.com/developer — or SVM_PRIVATE_KEY."
33
- : `Error: ${result.error}` });
34
- return undefined;
35
- }
36
- const data = result.data;
37
- const lines = (data.profiles || []).map((p) => {
38
- const who = p.name || `${p.wallet_address.slice(0, 4)}…${p.wallet_address.slice(-4)}`;
39
- const wr = p.winrate_7d != null ? `${p.winrate_7d.toFixed(1)}%` : "—";
40
- const pnl = p.pnl_30d != null ? `${p.pnl_30d > 0 ? "+" : ""}${p.pnl_30d.toFixed(1)} SOL` : "—";
41
- return `${who} [${p.strategy_tag || "mixed"}] winrate 7d: ${wr}, PnL 30d: ${pnl}`;
42
- });
43
- const overlap = (data.overlap || []).slice(0, 5).map((o) => `${o.token_symbol || "?"} (${o.wallets.length} wallets)`);
44
- callback?.({
45
- text: `KOL comparison:\n${lines.join("\n")}` +
46
- (overlap.length ? `\n\nOverlap (30d): ${overlap.join(", ")}` : ""),
47
- content: data,
48
- });
49
- return undefined;
50
- },
51
- examples: [
52
- [
53
- { name: "user1", content: { text: "Compare these two KOLs: ABC...123 and DEF...456" } },
54
- { name: "assistant", content: { text: "Here's the side-by-side comparison..." } },
55
- ],
56
- ],
57
- };
@@ -1,2 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const kolCoordinationAction: Action;
@@ -1,50 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- export const kolCoordinationAction = {
7
- name: "GET_KOL_COORDINATION",
8
- description: "Get KOL convergence signals from MadeOnSol — tokens being accumulated by multiple KOLs simultaneously. Shows which tokens smart money is converging on.",
9
- similes: [
10
- "kol convergence",
11
- "what tokens are kols accumulating",
12
- "kol coordination",
13
- "smart money convergence",
14
- "multiple kols buying",
15
- ],
16
- validate: async (_runtime, message) => {
17
- const text = (message.content?.text || "").toLowerCase();
18
- return /\b(kol|smart money)\b/.test(text) && /\b(converg|coordinat|accumul|same token|multiple)/i.test(text);
19
- },
20
- handler: async (runtime, message, _state, _options, callback) => {
21
- const client = getClient(runtime);
22
- const text = (message.content?.text || "").toLowerCase();
23
- const period = text.includes("1h") ? "1h" : text.includes("7d") ? "7d" : text.includes("6h") ? "6h" : "24h";
24
- const result = await client.getKolCoordination({ period, limit: "10" });
25
- if (result.error) {
26
- callback?.({ text: result.status === 402
27
- ? "Authentication required. Set MADEONSOL_API_KEY — free at https://madeonsol.com/developer — or SVM_PRIVATE_KEY."
28
- : `Error: ${result.error}` });
29
- return undefined;
30
- }
31
- const data = result.data;
32
- const lines = (data.coordination || []).map((t) => {
33
- const score = t.coordination_score != null ? ` · score ${t.coordination_score}/100` : "";
34
- const peak = t.peak_kols != null ? ` · peak ${t.peak_kols}` : "";
35
- const exited = t.exited_count ? ` · ${t.exited_count} exited` : "";
36
- return `${t.token_symbol}: ${t.kol_count} KOLs ${t.signal} (${t.net_sol_flow > 0 ? "+" : ""}${t.net_sol_flow.toFixed(2)} SOL net)${score}${peak}${exited}`;
37
- });
38
- callback?.({
39
- text: `KOL convergence signals (${period}):\n${lines.join("\n") || "No coordination signals found."}`,
40
- content: data,
41
- });
42
- return undefined;
43
- },
44
- examples: [
45
- [
46
- { name: "user1", content: { text: "What tokens are multiple KOLs accumulating?" } },
47
- { name: "assistant", content: { text: "Here are the KOL convergence signals..." } },
48
- ],
49
- ],
50
- };
@@ -1,2 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const kolFeedAction: Action;
@@ -1,46 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- export const kolFeedAction = {
7
- name: "GET_KOL_FEED",
8
- description: "Get the real-time Solana KOL trade feed from MadeOnSol. Shows latest buys and sells from 1,000+ tracked KOL wallets with deployer enrichment.",
9
- similes: [
10
- "kol trades",
11
- "what are kols buying",
12
- "solana kol feed",
13
- "kol activity",
14
- "smart money trades",
15
- "what did kols trade",
16
- ],
17
- validate: async (_runtime, message) => {
18
- const text = (message.content?.text || "").toLowerCase();
19
- return /\b(kol|smart money)\b/.test(text) && /\b(feed|trade|buy|sell|activit)/i.test(text);
20
- },
21
- handler: async (runtime, message, _state, _options, callback) => {
22
- const client = getClient(runtime);
23
- const text = (message.content?.text || "").toLowerCase();
24
- const action = text.includes("buy") ? "buy" : text.includes("sell") ? "sell" : undefined;
25
- const result = await client.getKolFeed({ limit: "10", ...(action ? { action } : {}) });
26
- if (result.error) {
27
- callback?.({ text: result.status === 402
28
- ? "Authentication required. Set MADEONSOL_API_KEY — free at https://madeonsol.com/developer — or SVM_PRIVATE_KEY."
29
- : `Error: ${result.error}` });
30
- return undefined;
31
- }
32
- const data = result.data;
33
- const lines = (data.trades || []).slice(0, 10).map((t) => `${t.kol_name || "Unknown"} ${t.action === "buy" ? "bought" : "sold"} ${t.token_symbol || "?"} for ${Number(t.sol_amount).toFixed(2)} SOL`);
34
- callback?.({
35
- text: `Latest KOL trades:\n${lines.join("\n")}`,
36
- content: data,
37
- });
38
- return undefined;
39
- },
40
- examples: [
41
- [
42
- { name: "user1", content: { text: "What are the latest KOL trades on Solana?" } },
43
- { name: "assistant", content: { text: "Here are the latest KOL trades from MadeOnSol..." } },
44
- ],
45
- ],
46
- };
@@ -1,2 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const kolLeaderboardAction: Action;
@@ -1,45 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- export const kolLeaderboardAction = {
7
- name: "GET_KOL_LEADERBOARD",
8
- description: "Get KOL performance rankings from MadeOnSol — top Solana KOLs ranked by PnL, volume, and win rate.",
9
- similes: [
10
- "kol leaderboard",
11
- "best performing kols",
12
- "top kol traders",
13
- "kol rankings",
14
- "who is the best kol",
15
- ],
16
- validate: async (_runtime, message) => {
17
- const text = (message.content?.text || "").toLowerCase();
18
- return /\b(kol|smart money)\b/.test(text) && /\b(leaderboard|ranking|top|best|perform|pnl|win rate)/i.test(text);
19
- },
20
- handler: async (runtime, message, _state, _options, callback) => {
21
- const client = getClient(runtime);
22
- const text = (message.content?.text || "").toLowerCase();
23
- const period = text.includes("today") ? "today" : text.includes("30d") || text.includes("month") ? "30d" : "7d";
24
- const result = await client.getKolLeaderboard({ period, limit: "10" });
25
- if (result.error) {
26
- callback?.({ text: result.status === 402
27
- ? "Authentication required. Set MADEONSOL_API_KEY — free at https://madeonsol.com/developer — or SVM_PRIVATE_KEY."
28
- : `Error: ${result.error}` });
29
- return undefined;
30
- }
31
- const data = result.data;
32
- const lines = (data.leaderboard || []).map((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` : ""})`);
33
- callback?.({
34
- text: `KOL Leaderboard (${period}):\n${lines.join("\n") || "No data for this period."}`,
35
- content: data,
36
- });
37
- return undefined;
38
- },
39
- examples: [
40
- [
41
- { name: "user1", content: { text: "Show me the top performing KOLs this week" } },
42
- { name: "assistant", content: { text: "Here are the top KOLs by PnL..." } },
43
- ],
44
- ],
45
- };
@@ -1,2 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const kolTokenEntryOrderAction: Action;
@@ -1,53 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- const MINT_RE = /\b([1-9A-HJ-NP-Za-km-z]{32,44})\b/;
7
- export const kolTokenEntryOrderAction = {
8
- name: "GET_KOL_TOKEN_ENTRY_ORDER",
9
- description: "Get the ranked order of KOL first-buyers for a specific Solana token from MadeOnSol. Shows who entered first and how quickly others followed.",
10
- similes: [
11
- "who bought first",
12
- "first kol buyers",
13
- "kol entry order",
14
- "token entry ranking",
15
- "who entered first",
16
- ],
17
- validate: async (_runtime, message) => {
18
- const text = message.content?.text || "";
19
- return /\b(first|entry|entered|order)\b/i.test(text) && MINT_RE.test(text);
20
- },
21
- handler: async (runtime, message, _state, _options, callback) => {
22
- const client = getClient(runtime);
23
- const mint = (message.content?.text || "").match(MINT_RE)?.[1];
24
- if (!mint) {
25
- callback?.({ text: "Please include a token mint address." });
26
- return undefined;
27
- }
28
- const result = await client.getKolTokenEntryOrder(mint, { limit: "20" });
29
- if (result.error) {
30
- callback?.({ text: result.status === 402
31
- ? "Authentication required. Set MADEONSOL_API_KEY — free at https://madeonsol.com/developer — or SVM_PRIVATE_KEY."
32
- : `Error: ${result.error}` });
33
- return undefined;
34
- }
35
- const data = result.data;
36
- const lines = (data.entries || []).slice(0, 10).map((e) => {
37
- const who = e.kol_name || `${e.wallet_address.slice(0, 4)}…${e.wallet_address.slice(-4)}`;
38
- const when = e.seconds_after_first === 0 ? "first" : `+${e.seconds_after_first}s`;
39
- return `#${e.rank} ${who} — ${e.sol_amount.toFixed(2)} SOL (${when})`;
40
- });
41
- callback?.({
42
- text: `KOL entry order for ${mint.slice(0, 8)}…:\n${lines.join("\n") || "No KOL buys recorded."}`,
43
- content: data,
44
- });
45
- return undefined;
46
- },
47
- examples: [
48
- [
49
- { name: "user1", content: { text: "Who were the first KOLs to buy 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU?" } },
50
- { name: "assistant", content: { text: "Here's the KOL entry order for that token..." } },
51
- ],
52
- ],
53
- };
@@ -1,3 +0,0 @@
1
- import type { Action } from "@elizaos/core";
2
- export declare const walletTrackerWatchlistAction: Action;
3
- export declare const walletTrackerTradesAction: Action;
@@ -1,84 +0,0 @@
1
- import { MadeOnSolClient } from "../client.js";
2
- import { MADEONSOL_CLIENT_KEY } from "../index.js";
3
- function getClient(runtime) {
4
- return runtime[MADEONSOL_CLIENT_KEY] ?? new MadeOnSolClient();
5
- }
6
- export const walletTrackerWatchlistAction = {
7
- name: "WALLET_TRACKER_WATCHLIST",
8
- description: "List wallets in your MadeOnSol wallet watchlist with labels and remaining capacity.",
9
- similes: [
10
- "wallet watchlist",
11
- "tracked wallets",
12
- "my wallets",
13
- "wallet tracker list",
14
- "show tracked wallets",
15
- ],
16
- validate: async (_runtime, message) => {
17
- const text = (message.content?.text || "").toLowerCase();
18
- return /\b(wallet.tracker|watchlist|tracked wallet)/i.test(text) && /\b(list|show|get|my)\b/i.test(text);
19
- },
20
- handler: async (runtime, _message, _state, _options, callback) => {
21
- const client = getClient(runtime);
22
- const result = await client.getWalletTrackerWatchlist();
23
- if (result.error) {
24
- callback?.({ text: `Error: ${result.error}` });
25
- return undefined;
26
- }
27
- const data = result.data;
28
- const lines = (data.wallets || []).map((w) => `${w.label ? `[${w.label}] ` : ""}${w.wallet_address}`);
29
- callback?.({
30
- text: lines.length
31
- ? `Tracked wallets (${data.count}/${data.limit}):\n${lines.join("\n")}\n${data.remaining} slot(s) remaining.`
32
- : `No wallets tracked yet. Limit: ${data.limit}.`,
33
- content: data,
34
- });
35
- return undefined;
36
- },
37
- examples: [
38
- [
39
- { name: "user1", content: { text: "Show my wallet tracker watchlist" } },
40
- { name: "assistant", content: { text: "Here are your tracked wallets..." } },
41
- ],
42
- ],
43
- };
44
- export const walletTrackerTradesAction = {
45
- name: "WALLET_TRACKER_TRADES",
46
- description: "Get recent swap and transfer events from wallets in your MadeOnSol watchlist.",
47
- similes: [
48
- "wallet tracker trades",
49
- "tracked wallet activity",
50
- "watchlist trades",
51
- "wallet swaps",
52
- "wallet transfers",
53
- "what did my tracked wallets do",
54
- ],
55
- validate: async (_runtime, message) => {
56
- const text = (message.content?.text || "").toLowerCase();
57
- return /\b(wallet.tracker|watchlist|tracked wallet)/i.test(text) && /\b(trade|swap|transfer|activity|buy|sell)\b/i.test(text);
58
- },
59
- handler: async (runtime, message, _state, _options, callback) => {
60
- const client = getClient(runtime);
61
- const text = (message.content?.text || "").toLowerCase();
62
- const action = text.includes("buy") ? "buy" : text.includes("sell") ? "sell" : undefined;
63
- const result = await client.getWalletTrackerTrades({ limit: "20", ...(action ? { action } : {}) });
64
- if (result.error) {
65
- callback?.({ text: `Error: ${result.error}` });
66
- return undefined;
67
- }
68
- const data = result.data;
69
- const lines = (data.events || []).slice(0, 15).map((e) => `${e.label || e.wallet_address.slice(0, 8)} ${e.action} ${e.token_symbol || "?"} for ${Number(e.sol_amount).toFixed(2)} SOL`);
70
- callback?.({
71
- text: lines.length
72
- ? `Recent wallet tracker events:\n${lines.join("\n")}`
73
- : "No recent events for your tracked wallets.",
74
- content: data,
75
- });
76
- return undefined;
77
- },
78
- examples: [
79
- [
80
- { name: "user1", content: { text: "What did my tracked wallets trade recently?" } },
81
- { name: "assistant", content: { text: "Here are the latest trades from your watchlist..." } },
82
- ],
83
- ],
84
- };