@madeonsol/plugin-madeonsol 1.3.0 → 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 +5 -42
- package/package.json +1 -1
- package/dist/actions/deployer-alerts.d.ts +0 -2
- package/dist/actions/deployer-alerts.js +0 -55
- package/dist/actions/kol-alerts-recent.d.ts +0 -2
- package/dist/actions/kol-alerts-recent.js +0 -48
- package/dist/actions/kol-compare.d.ts +0 -2
- package/dist/actions/kol-compare.js +0 -57
- package/dist/actions/kol-coordination.d.ts +0 -2
- package/dist/actions/kol-coordination.js +0 -50
- package/dist/actions/kol-feed.d.ts +0 -2
- package/dist/actions/kol-feed.js +0 -46
- package/dist/actions/kol-leaderboard.d.ts +0 -2
- package/dist/actions/kol-leaderboard.js +0 -45
- package/dist/actions/kol-token-entry-order.d.ts +0 -2
- package/dist/actions/kol-token-entry-order.js +0 -53
- package/dist/actions/wallet-tracker.d.ts +0 -3
- package/dist/actions/wallet-tracker.js +0 -84
- package/dist/client.d.ts +0 -404
- package/dist/client.js +0 -282
- package/dist/index.d.ts +0 -17
- package/dist/index.js +0 -72
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
|
|
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,30 +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
54
|
Your agent can then respond to queries like:
|
|
91
55
|
- "What are KOLs buying right now?"
|
|
92
56
|
- "Show me the KOL leaderboard this week"
|
|
@@ -99,18 +63,17 @@ Your agent can then respond to queries like:
|
|
|
99
63
|
|
|
100
64
|
| Tier | Price | Wallets tracked | Requests/day |
|
|
101
65
|
|------|-------|-----------------|--------------|
|
|
102
|
-
|
|
|
103
|
-
|
|
|
104
|
-
|
|
|
66
|
+
| BASIC | Free | 10 | 200 |
|
|
67
|
+
| PRO | $49/mo | 50 | 10,000 |
|
|
68
|
+
| ULTRA | $149/mo | 100 + WS events | 100,000 |
|
|
105
69
|
|
|
106
|
-
|
|
70
|
+
Get a key at [madeonsol.com/developer](https://madeonsol.com/developer).
|
|
107
71
|
|
|
108
72
|
## Also Available
|
|
109
73
|
|
|
110
74
|
| Platform | Package |
|
|
111
75
|
|---|---|
|
|
112
76
|
| TypeScript SDK | [`madeonsol`](https://www.npmjs.com/package/madeonsol) on npm |
|
|
113
|
-
| Rust SDK | [`madeonsol`](https://crates.io/crates/madeonsol) on crates.io |
|
|
114
77
|
| Python (LangChain, CrewAI) | [`madeonsol-x402`](https://pypi.org/project/madeonsol-x402/) on PyPI |
|
|
115
78
|
| MCP Server (Claude, Cursor) | [`mcp-server-madeonsol`](https://www.npmjs.com/package/mcp-server-madeonsol) |
|
|
116
79
|
| Solana Agent Kit | [`solana-agent-kit-plugin-madeonsol`](https://www.npmjs.com/package/solana-agent-kit-plugin-madeonsol) |
|
package/package.json
CHANGED
|
@@ -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,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,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,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
|
-
};
|
package/dist/actions/kol-feed.js
DELETED
|
@@ -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,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,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,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
|
-
};
|