plugin-liquidvision 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -2
- package/dist/index.d.ts +27 -0
- package/dist/index.js +234 -0
- package/images/banner.jpg +0 -0
- package/images/logo.jpg +0 -0
- package/package.json +39 -4
package/README.md
CHANGED
|
@@ -1,3 +1,45 @@
|
|
|
1
|
-
#
|
|
1
|
+
# plugin-liquidvision (ElizaOS)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Crypto derivatives context for ElizaOS agents from [LiquidVision.app](https://liquidvision.app):
|
|
4
|
+
exchange-exact open interest, liquidations, cascades, positioning regime, measured Hyperliquid
|
|
5
|
+
liquidation maps, funding dispersion across 13 venues, and tokenized stocks traded as perps on
|
|
6
|
+
DEXs. Read-only: nothing here signs, trades or spends. No key needed.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
elizaos plugins add plugin-liquidvision # or: bun add plugin-liquidvision
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{ "name": "Trader", "plugins": ["plugin-liquidvision"] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## What the agent can now answer
|
|
17
|
+
|
|
18
|
+
| Ask | Action |
|
|
19
|
+
|---|---|
|
|
20
|
+
| "What's the derivatives picture on $BTC?" | `LIQUIDVISION_DERIVATIVES_BRIEF` — price, OI, liquidations by side and window, largest venues |
|
|
21
|
+
| "Is this ETH rally new longs or short covering?" | `LIQUIDVISION_POSITIONING_REGIME` — price x open interest per coin |
|
|
22
|
+
| "Any big liquidation cascades today?" | `LIQUIDVISION_LIQUIDATION_CASCADES` — events with what price did in the hour after |
|
|
23
|
+
| "Where are the BTC liquidation levels?" | `LIQUIDVISION_LIQUIDATION_MAP` — measured Hyperliquid positions, densest levels below and above |
|
|
24
|
+
| "Where is funding cheapest for SOL?" | `LIQUIDVISION_FUNDING_DISPERSION` — cheapest long venue vs richest short venue, own settlement cycles |
|
|
25
|
+
| "How big is the tokenized stocks perp market?" | `LIQUIDVISION_TOKENIZED_STOCKS` — Lighter, Hyperliquid builder markets, Ostium, gTrade |
|
|
26
|
+
|
|
27
|
+
A dynamic provider, `LIQUIDVISION_DERIVATIVES`, adds a one-paragraph derivatives context when a
|
|
28
|
+
message mentions a coin (`$BTC`, `ethereum`, `SOLUSDT`).
|
|
29
|
+
|
|
30
|
+
## Settings
|
|
31
|
+
|
|
32
|
+
| Setting | Default | |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| `LIQUIDVISION_API_KEY` | — | Optional. Free endpoints need no key (60 req/min per IP); a Pro/Bot key raises it. |
|
|
35
|
+
| `LIQUIDVISION_BASE_URL` | `https://liquidvision.app/api/v1` | |
|
|
36
|
+
|
|
37
|
+
## Honest data
|
|
38
|
+
|
|
39
|
+
- Liquidation totals are a floor: Binance and Bitget publish at most one order per contract per second.
|
|
40
|
+
- Open interest is one side on every venue.
|
|
41
|
+
- The liquidation map is **measured** (real Hyperliquid positions with the exchange's liquidation price), large accounts only.
|
|
42
|
+
- Funding spreads are gross: before fees, basis and margin. Market data, not financial advice.
|
|
43
|
+
|
|
44
|
+
Raw rows, history and alerts are on the REST API and MCP server: https://liquidvision.app/llms.txt.
|
|
45
|
+
MCP for agents: `https://liquidvision.app/mcp/lite`.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* plugin-liquidvision — crypto derivatives context for ElizaOS agents.
|
|
3
|
+
*
|
|
4
|
+
* Six actions and one provider over LiquidVision.app's free "conclusions"
|
|
5
|
+
* endpoints: an agent asked "is BTC leverage building?", "where are the
|
|
6
|
+
* liquidations?", "where is funding cheapest?" answers from exchange-exact
|
|
7
|
+
* data on 13 venues instead of guessing. Read-only: nothing here signs,
|
|
8
|
+
* trades or spends. No key needed; LIQUIDVISION_API_KEY (Pro/Bot) is passed
|
|
9
|
+
* through for higher limits.
|
|
10
|
+
*/
|
|
11
|
+
import type { Action, Plugin, Provider } from "@elizaos/core";
|
|
12
|
+
export declare function extractSymbol(text: string): string | null;
|
|
13
|
+
export declare function summarizeBrief(b: any): string;
|
|
14
|
+
export declare function summarizeRegime(r: any, symbol: string | null): string;
|
|
15
|
+
export declare function summarizeCascades(c: any, symbol: string | null): string;
|
|
16
|
+
export declare function summarizeLiqmap(m: any): string;
|
|
17
|
+
export declare function summarizeDispersion(d: any, symbol: string | null): string;
|
|
18
|
+
export declare function summarizeTokenized(t: any): string;
|
|
19
|
+
export declare const briefAction: Action;
|
|
20
|
+
export declare const regimeAction: Action;
|
|
21
|
+
export declare const cascadesAction: Action;
|
|
22
|
+
export declare const liqmapAction: Action;
|
|
23
|
+
export declare const fundingAction: Action;
|
|
24
|
+
export declare const tokenizedAction: Action;
|
|
25
|
+
export declare const derivativesProvider: Provider;
|
|
26
|
+
export declare const liquidvisionPlugin: Plugin;
|
|
27
|
+
export default liquidvisionPlugin;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
const DEFAULT_BASE = "https://liquidvision.app/api/v1";
|
|
2
|
+
const UA = "plugin-liquidvision/0.1.0";
|
|
3
|
+
// ---------------------------------------------------------------- helpers
|
|
4
|
+
function base(runtime) {
|
|
5
|
+
return String(runtime.getSetting("LIQUIDVISION_BASE_URL") || DEFAULT_BASE).replace(/\/+$/, "");
|
|
6
|
+
}
|
|
7
|
+
async function lv(runtime, path, params = {}) {
|
|
8
|
+
const url = new URL(base(runtime) + path);
|
|
9
|
+
for (const [k, v] of Object.entries(params))
|
|
10
|
+
url.searchParams.set(k, String(v));
|
|
11
|
+
const headers = { Accept: "application/json", "User-Agent": UA };
|
|
12
|
+
const key = runtime.getSetting("LIQUIDVISION_API_KEY");
|
|
13
|
+
if (typeof key === "string" && key)
|
|
14
|
+
headers["X-API-Key"] = key;
|
|
15
|
+
const r = await fetch(url, { headers });
|
|
16
|
+
if (!r.ok) {
|
|
17
|
+
const body = await r.text();
|
|
18
|
+
throw new Error(`LiquidVision ${r.status}: ${body.slice(0, 200)}`);
|
|
19
|
+
}
|
|
20
|
+
return r.json();
|
|
21
|
+
}
|
|
22
|
+
/** "$BTC", "eth", "Solana", "BTCUSDT" -> "BTCUSDT"; null when nothing recognisable. */
|
|
23
|
+
const NAMES = {
|
|
24
|
+
BITCOIN: "BTC", ETHEREUM: "ETH", ETHER: "ETH", SOLANA: "SOL", RIPPLE: "XRP", DOGECOIN: "DOGE",
|
|
25
|
+
HYPERLIQUID: "HYPE", BINANCE: "BNB", CARDANO: "ADA", CHAINLINK: "LINK", AVALANCHE: "AVAX", SUI: "SUI",
|
|
26
|
+
};
|
|
27
|
+
const COMMON = new Set(["BTC", "ETH", "SOL", "XRP", "DOGE", "BNB", "ADA", "HYPE", "LINK", "AVAX", "SUI", "TRX",
|
|
28
|
+
"LTC", "DOT", "TON", "PEPE", "WIF", "ENA", "ARB", "OP", "NEAR", "APT", "ZEC", "AAVE", "UNI", "TIA", "SEI"]);
|
|
29
|
+
export function extractSymbol(text) {
|
|
30
|
+
const t = (text || "").toUpperCase();
|
|
31
|
+
const tagged = t.match(/\$([A-Z0-9]{2,10})\b/);
|
|
32
|
+
if (tagged)
|
|
33
|
+
return tagged[1].replace(/USDT$/, "") + "USDT";
|
|
34
|
+
const pair = t.match(/\b([A-Z0-9]{2,10})USDT\b/);
|
|
35
|
+
if (pair)
|
|
36
|
+
return pair[1] + "USDT";
|
|
37
|
+
for (const [name, sym] of Object.entries(NAMES))
|
|
38
|
+
if (new RegExp(`\\b${name}\\b`).test(t))
|
|
39
|
+
return sym + "USDT";
|
|
40
|
+
for (const w of t.split(/[^A-Z0-9]+/))
|
|
41
|
+
if (COMMON.has(w))
|
|
42
|
+
return w + "USDT";
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const usd = (v) => {
|
|
46
|
+
if (v == null || !Number.isFinite(v))
|
|
47
|
+
return "n/a";
|
|
48
|
+
const a = Math.abs(v), s = v < 0 ? "-" : "";
|
|
49
|
+
if (a >= 1e9)
|
|
50
|
+
return `${s}$${(a / 1e9).toFixed(2)}B`;
|
|
51
|
+
if (a >= 1e6)
|
|
52
|
+
return `${s}$${(a / 1e6).toFixed(1)}M`;
|
|
53
|
+
if (a >= 1e3)
|
|
54
|
+
return `${s}$${(a / 1e3).toFixed(0)}K`;
|
|
55
|
+
return `${s}$${a.toFixed(0)}`;
|
|
56
|
+
};
|
|
57
|
+
const pct = (v, d = 1) => v == null || !Number.isFinite(v) ? "n/a" : `${v >= 0 ? "+" : ""}${v.toFixed(d)}%`;
|
|
58
|
+
const textOf = (m) => m?.content?.text || "";
|
|
59
|
+
const mentions = (m, words) => words.test(textOf(m).toLowerCase());
|
|
60
|
+
async function reply(callback, text, action, data) {
|
|
61
|
+
if (callback)
|
|
62
|
+
await callback({ text, actions: [action], source: "liquidvision" });
|
|
63
|
+
return { success: true, text, data };
|
|
64
|
+
}
|
|
65
|
+
async function fail(callback, action, e) {
|
|
66
|
+
const msg = `I could not read LiquidVision.app right now (${e?.message ?? e}).`;
|
|
67
|
+
if (callback)
|
|
68
|
+
await callback({ text: msg, actions: [action], source: "liquidvision" });
|
|
69
|
+
return { success: false, text: msg, error: e };
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------- summaries (exported for tests)
|
|
72
|
+
export function summarizeBrief(b) {
|
|
73
|
+
const sym = String(b.symbol || "").replace(/USDT$/, "");
|
|
74
|
+
const a = b.asset || {};
|
|
75
|
+
// windows_usd is MARKET-WIDE; this_symbol_24h is the coin itself
|
|
76
|
+
const mkt = (b.liquidations?.windows_usd || {})["24h"] || {};
|
|
77
|
+
const own = b.liquidations?.this_symbol_24h || {};
|
|
78
|
+
const lines = [
|
|
79
|
+
`${sym} ${a.price != null ? `$${Number(a.price).toLocaleString("en-US")}` : ""} (${pct(a.change_24h_pct, 2)} 24h), open interest ${usd(a.open_interest_usd)}.`,
|
|
80
|
+
`${sym} liquidated 24h: ${usd(own.total)} (longs ${usd(own.long)}, shorts ${usd(own.short)}); whole market ${usd(mkt.total)}.`,
|
|
81
|
+
];
|
|
82
|
+
const venues = (b.open_interest_by_venue || b.oi_by_venue || []).slice?.(0, 3) || [];
|
|
83
|
+
if (venues.length)
|
|
84
|
+
lines.push(`Largest OI venues: ${venues.map((v) => `${v.exchange} ${usd(v.oi_usd)}`).join(", ")}.`);
|
|
85
|
+
lines.push("Source: LiquidVision.app (exchange-exact, 13 venues; Binance/Bitget liquidation feeds are throttled, so totals are a floor).");
|
|
86
|
+
return lines.join(" ");
|
|
87
|
+
}
|
|
88
|
+
export function summarizeRegime(r, symbol) {
|
|
89
|
+
const s = (r.summary || []).filter((x) => x.coins > 0)
|
|
90
|
+
.map((x) => `${x.label}: ${x.coins} coins (${usd(x.oi_delta_usd)} OI)`).join("; ");
|
|
91
|
+
let line = `Positioning over the last ${r.minutes} min across ${r.symbols} coins — ${s}.`;
|
|
92
|
+
if (symbol) {
|
|
93
|
+
const row = (r.rows || []).find((x) => x.symbol === symbol);
|
|
94
|
+
if (row)
|
|
95
|
+
line += ` ${symbol.replace(/USDT$/, "")}: ${row.regime_label || row.regime} (price ${pct(row.price_change_pct ?? row.price_chg_pct, 2)}, OI ${pct(row.oi_change_pct ?? row.oi_chg_pct, 2)}, ${usd(row.oi_delta_usd)}).`;
|
|
96
|
+
}
|
|
97
|
+
return line + " New longs/new shorts = fresh positions; short covering/long flush = positions closing. Source: LiquidVision.app.";
|
|
98
|
+
}
|
|
99
|
+
export function summarizeCascades(c, symbol) {
|
|
100
|
+
let ev = c.events || c.cascades || [];
|
|
101
|
+
if (symbol)
|
|
102
|
+
ev = ev.filter((e) => e.symbol === symbol);
|
|
103
|
+
const top = ev.slice(0, 3).map((e) => `${String(e.symbol).replace(/USDT$/, "")} ${e.side ?? ""} ${usd(e.usd ?? e.total_usd)} over ${e.minutes ?? "?"} min (${Number(e.x_normal ?? 0).toFixed(0)}x its normal minute, price impact ${pct(e.impact_pct, 2)}, reversion ${pct(e.reversion_pct, 2)})`);
|
|
104
|
+
const mw = (c.market_wide || []).length;
|
|
105
|
+
return `${c.events_total ?? ev.length} liquidation cascades in the last ${c.hours}h${mw ? `, ${mw} market-wide` : ""}. ` +
|
|
106
|
+
(top.length ? `Largest: ${top.join("; ")}. ` : "") +
|
|
107
|
+
"Reversion after the cascade tells a flush that marked the low from one that started the move. Source: LiquidVision.app.";
|
|
108
|
+
}
|
|
109
|
+
export function summarizeLiqmap(m) {
|
|
110
|
+
const p = Number(m.current_price);
|
|
111
|
+
const bins = m.bins || [];
|
|
112
|
+
const longs = m.long || m.long_usd || [];
|
|
113
|
+
const shorts = m.short || m.short_usd || [];
|
|
114
|
+
let below = { px: 0, usd: 0 }, above = { px: 0, usd: 0 };
|
|
115
|
+
bins.forEach((px, i) => {
|
|
116
|
+
const l = longs[i] || 0, s = shorts[i] || 0;
|
|
117
|
+
if (px < p && l > below.usd)
|
|
118
|
+
below = { px, usd: l };
|
|
119
|
+
if (px > p && s > above.usd)
|
|
120
|
+
above = { px, usd: s };
|
|
121
|
+
});
|
|
122
|
+
const sym = String(m.symbol || "").replace(/USDT$/, "");
|
|
123
|
+
return `${sym} measured Hyperliquid positions (real accounts, exchange-reported liquidation prices): ` +
|
|
124
|
+
`densest long liquidations below at ~$${Math.round(below.px).toLocaleString("en-US")} (${usd(below.usd)}), ` +
|
|
125
|
+
`densest short liquidations above at ~$${Math.round(above.px).toLocaleString("en-US")} (${usd(above.usd)}); price $${p.toLocaleString("en-US")}. ` +
|
|
126
|
+
"Measured, not modeled; large accounts only. Source: LiquidVision.app.";
|
|
127
|
+
}
|
|
128
|
+
export function summarizeDispersion(d, symbol) {
|
|
129
|
+
let rows = d.rows || [];
|
|
130
|
+
if (symbol)
|
|
131
|
+
rows = rows.filter((r) => r.symbol === symbol);
|
|
132
|
+
const top = rows.slice(0, 5).map((r) => `${String(r.symbol).replace(/USDT$/, "")}: long on ${r.long_venue} (${pct(r.long_apr)}), short on ${r.short_venue} (${pct(r.short_apr)}), spread ${r.spread_apr?.toFixed(1)}% APR`);
|
|
133
|
+
return (top.length ? `Funding disagreement across venues — ${top.join("; ")}. ` : `No funding dispersion row${symbol ? ` for ${symbol}` : ""}. `) +
|
|
134
|
+
"Each leg annualized with its own settlement cycle; gross of fees and basis. Market data, not financial advice. Source: LiquidVision.app.";
|
|
135
|
+
}
|
|
136
|
+
export function summarizeTokenized(t) {
|
|
137
|
+
const rows = (t.rows || []).slice(0, 5).map((r) => `${r.id} ${usd(r.oi_usd)} OI${r.change_24h_pct != null ? ` (${pct(r.change_24h_pct, 2)})` : ""}`);
|
|
138
|
+
return `Tokenized stocks/indices/commodities/FX as perps on DEXs: ${usd(t.total_oi_usd)} open interest, ${usd(t.total_volume_24h_usd)} traded 24h across ${t.underlyings} underlyings. Largest: ${rows.join(", ")}. Source: LiquidVision.app.`;
|
|
139
|
+
}
|
|
140
|
+
// ---------------------------------------------------------------- actions
|
|
141
|
+
function action(spec) {
|
|
142
|
+
return {
|
|
143
|
+
name: spec.name,
|
|
144
|
+
similes: spec.similes,
|
|
145
|
+
description: spec.description,
|
|
146
|
+
validate: async (_runtime, message) => mentions(message, spec.words),
|
|
147
|
+
handler: async (runtime, message, _state, _options, callback) => {
|
|
148
|
+
try {
|
|
149
|
+
const { text, data } = await spec.run(runtime, extractSymbol(textOf(message)));
|
|
150
|
+
return reply(callback, text, spec.name, data);
|
|
151
|
+
}
|
|
152
|
+
catch (e) {
|
|
153
|
+
return fail(callback, spec.name, e);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
examples: [[
|
|
157
|
+
{ name: "{{user1}}", content: { text: spec.example[0] } },
|
|
158
|
+
{ name: "{{agent}}", content: { text: spec.example[1], actions: [spec.name] } },
|
|
159
|
+
]],
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
export const briefAction = action({
|
|
163
|
+
name: "LIQUIDVISION_DERIVATIVES_BRIEF",
|
|
164
|
+
similes: ["DERIVATIVES_BRIEF", "MARKET_BRIEF", "LEVERAGE_SNAPSHOT"],
|
|
165
|
+
description: "One-coin derivatives snapshot from LiquidVision.app: price, open interest, liquidations by side and window, largest venues.",
|
|
166
|
+
words: /(brief|snapshot|derivatives|open interest|\boi\b|leverage|liquidat|what.*(happening|going on))/,
|
|
167
|
+
run: async (rt, sym) => { const b = await lv(rt, `/brief/${sym ?? "BTCUSDT"}`); return { text: summarizeBrief(b), data: b }; },
|
|
168
|
+
example: ["what's the derivatives picture on $BTC?", "BTC $81,300 (-0.9% 24h), open interest $27.6B. Liquidated 24h: $201.6M (longs $107.4M, shorts $94.2M)…"],
|
|
169
|
+
});
|
|
170
|
+
export const regimeAction = action({
|
|
171
|
+
name: "LIQUIDVISION_POSITIONING_REGIME",
|
|
172
|
+
similes: ["POSITIONING_REGIME", "NEW_LONGS_OR_SHORT_COVERING", "OI_REGIME"],
|
|
173
|
+
description: "Is a move new money or positions closing? Price change crossed with open-interest change per coin (new longs, short covering, new shorts, long flush).",
|
|
174
|
+
words: /(regime|short covering|new longs|new shorts|long flush|positioning|new money|who is driving)/,
|
|
175
|
+
run: async (rt, sym) => { const r = await lv(rt, "/oi/regime", { minutes: 240 }); return { text: summarizeRegime(r, sym), data: r }; },
|
|
176
|
+
example: ["is this ETH rally new longs or short covering?", "Positioning over the last 240 min across 107 coins — New longs: 3 coins…"],
|
|
177
|
+
});
|
|
178
|
+
export const cascadesAction = action({
|
|
179
|
+
name: "LIQUIDVISION_LIQUIDATION_CASCADES",
|
|
180
|
+
similes: ["LIQUIDATION_CASCADES", "LIQUIDATION_EVENTS", "FLUSH"],
|
|
181
|
+
description: "Liquidation cascades over the last 24h as events: size, duration, price move and what price did in the hour after.",
|
|
182
|
+
words: /(cascade|flush|got liquidated|liquidation event|wipe|rekt)/,
|
|
183
|
+
run: async (rt, sym) => { const c = await lv(rt, "/liquidations/cascades", { hours: 24, limit: 50 }); return { text: summarizeCascades(c, sym), data: c }; },
|
|
184
|
+
example: ["were there any big liquidation cascades today?", "436 liquidation cascades in the last 24h, 6 market-wide. Largest: ETH long $14.2M over 3 min…"],
|
|
185
|
+
});
|
|
186
|
+
export const liqmapAction = action({
|
|
187
|
+
name: "LIQUIDVISION_LIQUIDATION_MAP",
|
|
188
|
+
similes: ["LIQUIDATION_MAP", "LIQUIDATION_LEVELS", "WHERE_ARE_LIQUIDATIONS"],
|
|
189
|
+
description: "Where leverage would break: measured Hyperliquid positions binned by exchange-reported liquidation price, densest levels below and above.",
|
|
190
|
+
words: /(liquidation (map|level|cluster|zone)|where.*liquidat|liq map|leverage (sits|levels))/,
|
|
191
|
+
run: async (rt, sym) => { const m = await lv(rt, `/liqmap/hl/${sym ?? "BTCUSDT"}`, { range: "1d" }); return { text: summarizeLiqmap(m), data: m }; },
|
|
192
|
+
example: ["where are the BTC liquidation levels?", "BTC measured Hyperliquid positions: densest long liquidations below at ~$78,500 ($41.2M)…"],
|
|
193
|
+
});
|
|
194
|
+
export const fundingAction = action({
|
|
195
|
+
name: "LIQUIDVISION_FUNDING_DISPERSION",
|
|
196
|
+
similes: ["FUNDING_DISPERSION", "FUNDING_CARRY", "FUNDING_ARBITRAGE", "CHEAPEST_FUNDING"],
|
|
197
|
+
description: "Where the same coin pays very different funding across venues: the cheapest venue to be long and the richest to be short, each leg on its own settlement cycle.",
|
|
198
|
+
words: /(funding|carry|basis trade|funding arb)/,
|
|
199
|
+
run: async (rt, sym) => { const d = await lv(rt, "/funding/dispersion"); return { text: summarizeDispersion(d, sym), data: d }; },
|
|
200
|
+
example: ["where is funding cheapest for SOL?", "Funding disagreement across venues — SOL: long on bybit (+2.1%), short on kraken (+14.0%)…"],
|
|
201
|
+
});
|
|
202
|
+
export const tokenizedAction = action({
|
|
203
|
+
name: "LIQUIDVISION_TOKENIZED_STOCKS",
|
|
204
|
+
similes: ["TOKENIZED_STOCKS", "STOCK_PERPS", "RWA_PERPS"],
|
|
205
|
+
description: "Tokenized stocks, indices, commodities and FX traded as perps on DEXs (Lighter, Hyperliquid builder markets, Ostium, gTrade): open interest, volume, 24h change.",
|
|
206
|
+
words: /(tokeni[sz]ed|stock perp|equity perp|rwa|s&p|nasdaq|nvda|tsla|gold perp)/,
|
|
207
|
+
run: async (rt) => { const t = await lv(rt, "/stocks/tokenized"); return { text: summarizeTokenized(t), data: t }; },
|
|
208
|
+
example: ["how big is the tokenized stocks perp market?", "Tokenized stocks/indices/commodities/FX as perps on DEXs: $3.9B open interest…"],
|
|
209
|
+
});
|
|
210
|
+
// ---------------------------------------------------------------- provider
|
|
211
|
+
export const derivativesProvider = {
|
|
212
|
+
name: "LIQUIDVISION_DERIVATIVES",
|
|
213
|
+
description: "Derivatives context (open interest, liquidations) for a coin mentioned in the message, from LiquidVision.app.",
|
|
214
|
+
dynamic: true,
|
|
215
|
+
get: async (runtime, message, _state) => {
|
|
216
|
+
const sym = extractSymbol(textOf(message));
|
|
217
|
+
if (!sym)
|
|
218
|
+
return { text: "" };
|
|
219
|
+
try {
|
|
220
|
+
const b = await lv(runtime, `/brief/${sym}`);
|
|
221
|
+
return { text: `# Derivatives context\n${summarizeBrief(b)}`, values: { liquidvisionSymbol: sym }, data: { brief: b } };
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
return { text: "" };
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
export const liquidvisionPlugin = {
|
|
229
|
+
name: "liquidvision",
|
|
230
|
+
description: "Exchange-exact crypto derivatives data from LiquidVision.app: open interest, liquidations, cascades, positioning regime, measured liquidation maps, funding dispersion, tokenized stocks on DEXs. Read-only, no key needed.",
|
|
231
|
+
actions: [briefAction, regimeAction, cascadesAction, liqmapAction, fundingAction, tokenizedAction],
|
|
232
|
+
providers: [derivativesProvider],
|
|
233
|
+
};
|
|
234
|
+
export default liquidvisionPlugin;
|
|
Binary file
|
package/images/logo.jpg
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,41 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plugin-liquidvision",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "ElizaOS plugin for LiquidVision.app: exchange-exact crypto derivatives context for agents — open interest, liquidations, cascades, positioning regime (new longs vs short covering), measured Hyperliquid liquidation maps, funding dispersion across 13 venues, tokenized stocks on DEXs. Read-only, no key needed.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": { "types": "./dist/index.d.ts", "import": "./dist/index.js", "default": "./dist/index.js" }
|
|
11
|
+
},
|
|
12
|
+
"files": ["dist", "README.md", "images"],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc -p tsconfig.json",
|
|
15
|
+
"test": "node test/smoke.mjs"
|
|
16
|
+
},
|
|
17
|
+
"keywords": ["elizaos", "elizaos-plugins", "plugin", "crypto", "derivatives", "liquidations", "open-interest", "funding-rate", "hyperliquid", "trading", "market-data", "liquidvision"],
|
|
18
|
+
"author": "LiquidVision.app",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"homepage": "https://liquidvision.app",
|
|
21
|
+
"repository": { "type": "git", "url": "https://github.com/lv-analytics/liquidvision-mcp", "directory": "integrations/elizaos/plugin-liquidvision" },
|
|
22
|
+
"peerDependencies": { "@elizaos/core": "^1.7.2" },
|
|
23
|
+
"devDependencies": { "@elizaos/core": "^1.7.2", "typescript": "^5.6.0" },
|
|
24
|
+
"agentConfig": {
|
|
25
|
+
"pluginType": "elizaos:plugin:1.0.0",
|
|
26
|
+
"pluginParameters": {
|
|
27
|
+
"LIQUIDVISION_API_KEY": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"required": false,
|
|
30
|
+
"sensitive": true,
|
|
31
|
+
"description": "Optional LiquidVision.app key (lv_...). Not needed: every action uses the free endpoints. A Pro/Bot key raises the rate limit from 60 to 600/1,200 requests a minute."
|
|
32
|
+
},
|
|
33
|
+
"LIQUIDVISION_BASE_URL": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"required": false,
|
|
36
|
+
"sensitive": false,
|
|
37
|
+
"description": "API base URL, default https://liquidvision.app/api/v1."
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|