@wzrd_sol/eliza-plugin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actions/claim.d.ts +3 -0
- package/dist/actions/claim.js +31 -0
- package/dist/actions/deposit.d.ts +2 -0
- package/dist/actions/deposit.js +70 -0
- package/dist/actions/leaderboard.d.ts +3 -0
- package/dist/actions/leaderboard.js +25 -0
- package/dist/actions/portfolio.d.ts +3 -0
- package/dist/actions/portfolio.js +20 -0
- package/dist/actions/velocity.d.ts +3 -0
- package/dist/actions/velocity.js +57 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +17 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +14 -0
- package/package.json +59 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { getWzrdClient } from '../client.js';
|
|
2
|
+
export const claimAction = {
|
|
3
|
+
name: 'WZRD_CLAIM',
|
|
4
|
+
similes: ['WZRD_HARVEST', 'CLAIM_CCM', 'COLLECT_YIELD'],
|
|
5
|
+
description: 'Claim accrued CCM tokens via gasless relay. Server pays tx fees.',
|
|
6
|
+
examples: [[
|
|
7
|
+
{ name: '{{user1}}', content: { text: 'Claim my WZRD rewards' } },
|
|
8
|
+
{ name: '{{agentName}}', content: { text: 'Claimed CCM via gasless relay. Tx: 5S7L...' } },
|
|
9
|
+
]],
|
|
10
|
+
validate: async () => true,
|
|
11
|
+
handler: async (runtime, _msg, _state, _opt, callback) => {
|
|
12
|
+
const client = getWzrdClient(runtime);
|
|
13
|
+
const claims = await client.getClaims();
|
|
14
|
+
const claimable = claims.cumulative_total - claims.claimed_total;
|
|
15
|
+
if (claimable <= 0) {
|
|
16
|
+
const text = `No CCM to claim. Cumulative: ${claims.cumulative_total}, claimed: ${claims.claimed_total}.`;
|
|
17
|
+
await callback?.({ text });
|
|
18
|
+
return { success: true, text, data: claims };
|
|
19
|
+
}
|
|
20
|
+
const result = await client.claimRelay();
|
|
21
|
+
if (result.status === 'already_claimed') {
|
|
22
|
+
const text = `Already claimed through root ${result.root_seq}.`;
|
|
23
|
+
await callback?.({ text });
|
|
24
|
+
return { success: true, text, data: result };
|
|
25
|
+
}
|
|
26
|
+
const text = `Claimed CCM via relay. Cumulative: ${(result.cumulative_total / 1e6).toFixed(4)} CCM. ` +
|
|
27
|
+
`Root: ${result.root_seq}. Tx: ${result.tx_sig?.slice(0, 16)}...`;
|
|
28
|
+
await callback?.({ text });
|
|
29
|
+
return { success: true, text, data: result };
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/** ELIZA Action: WZRD_DEPOSIT — deposit USDC into attention market, mint vLOFI (auth + keypair). */
|
|
2
|
+
import { Keypair, ComputeBudgetProgram, TransactionMessage, VersionedTransaction, Connection } from '@solana/web3.js';
|
|
3
|
+
export const depositAction = {
|
|
4
|
+
name: 'WZRD_DEPOSIT',
|
|
5
|
+
similes: ['DEPOSIT_USDC', 'BUY_ATTENTION', 'ENTER_MARKET'],
|
|
6
|
+
description: 'Deposit USDC into a WZRD attention market to mint vLOFI. Requires market_id and amount_usdc in message content.',
|
|
7
|
+
examples: [[
|
|
8
|
+
{ name: '{{user1}}', content: { text: 'Deposit 0.01 USDC into WZRD market 10' } },
|
|
9
|
+
{ name: '{{agentName}}', content: { text: 'Deposited 0.0100 USDC into Market #10. Tx: X7FG...' } },
|
|
10
|
+
]],
|
|
11
|
+
validate: async () => true,
|
|
12
|
+
handler: async (runtime, message, _state, _opt, callback) => {
|
|
13
|
+
const { market_id: marketId, amount_usdc: amountUsdc, priority_fee = 50_000 } = message.content;
|
|
14
|
+
if (!marketId || !amountUsdc || amountUsdc > 100) {
|
|
15
|
+
const text = !marketId || !amountUsdc
|
|
16
|
+
? 'Missing required: market_id and amount_usdc.' : 'Max 100 USDC per deposit.';
|
|
17
|
+
await callback?.({ text });
|
|
18
|
+
return { success: false, text };
|
|
19
|
+
}
|
|
20
|
+
const sk = runtime.getSetting('SOLANA_PRIVATE_KEY');
|
|
21
|
+
if (!sk)
|
|
22
|
+
throw new Error('SOLANA_PRIVATE_KEY not configured');
|
|
23
|
+
const kp = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(String(sk))));
|
|
24
|
+
const payer = kp.publicKey;
|
|
25
|
+
const amt = BigInt(Math.round(amountUsdc * 1e6));
|
|
26
|
+
const rpcSetting = runtime.getSetting('SOLANA_RPC_URL');
|
|
27
|
+
const rpc = (typeof rpcSetting === 'string' ? rpcSetting : undefined) || 'https://api.mainnet-beta.solana.com';
|
|
28
|
+
const conn = new Connection(rpc, 'confirmed');
|
|
29
|
+
const sdk = await import('@wzrd_sol/sdk');
|
|
30
|
+
const vault = await sdk.fetchMarketVault(conn, marketId);
|
|
31
|
+
if (!vault) {
|
|
32
|
+
await callback?.({ text: `Market ${marketId} has no vault.` });
|
|
33
|
+
return { success: false };
|
|
34
|
+
}
|
|
35
|
+
const pos = await sdk.fetchOnChainPosition(conn, payer, marketId);
|
|
36
|
+
if (pos && pos.depositedAmount > 0n && !pos.settled) {
|
|
37
|
+
await callback?.({ text: `Position exists in market ${marketId}.` });
|
|
38
|
+
return { success: false };
|
|
39
|
+
}
|
|
40
|
+
const bal = await sdk.fetchTokenBalance(conn, sdk.getAta(payer, vault.depositMint, sdk.TOKEN_PROGRAM_ID));
|
|
41
|
+
if (bal < amt) {
|
|
42
|
+
await callback?.({ text: `Insufficient USDC.` });
|
|
43
|
+
return { success: false };
|
|
44
|
+
}
|
|
45
|
+
const ixs = await sdk.createDepositMarketIx(conn, payer, marketId, amt);
|
|
46
|
+
ixs.unshift(ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }), ComputeBudgetProgram.setComputeUnitPrice({ microLamports: priority_fee }));
|
|
47
|
+
const { blockhash, lastValidBlockHeight } = await conn.getLatestBlockhash('confirmed');
|
|
48
|
+
const tx = new VersionedTransaction(new TransactionMessage({ payerKey: payer, recentBlockhash: blockhash, instructions: ixs }).compileToV0Message());
|
|
49
|
+
tx.sign([kp]);
|
|
50
|
+
const sim = await conn.simulateTransaction(tx);
|
|
51
|
+
if (sim.value.err) {
|
|
52
|
+
await callback?.({ text: `Sim failed: ${JSON.stringify(sim.value.err)}` });
|
|
53
|
+
return { success: false };
|
|
54
|
+
}
|
|
55
|
+
const sig = await conn.sendTransaction(tx, { skipPreflight: true, maxRetries: 3 });
|
|
56
|
+
try {
|
|
57
|
+
await Promise.race([
|
|
58
|
+
conn.confirmTransaction({ signature: sig, blockhash, lastValidBlockHeight }, 'confirmed'),
|
|
59
|
+
new Promise((_, rej) => setTimeout(() => rej(new Error('Timeout')), 60_000)),
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
await callback?.({ text: `Deposit sent, confirmation timed out. Tx: ${sig}` });
|
|
64
|
+
return { success: true, data: { signature: sig, timed_out: true } };
|
|
65
|
+
}
|
|
66
|
+
const text = `Deposited ${amountUsdc.toFixed(4)} USDC into Market #${marketId}. Tx: ${sig.slice(0, 16)}...`;
|
|
67
|
+
await callback?.({ text });
|
|
68
|
+
return { success: true, text, data: { signature: sig, market_id: marketId, amount_usdc: amountUsdc } };
|
|
69
|
+
},
|
|
70
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getWzrdClient } from '../client.js';
|
|
2
|
+
export const leaderboardAction = {
|
|
3
|
+
name: 'WZRD_LEADERBOARD',
|
|
4
|
+
similes: ['WZRD_MARKETS', 'WZRD_TRENDING', 'TOP_MODELS'],
|
|
5
|
+
description: 'Fetch the WZRD attention market leaderboard ranked by velocity EMA.',
|
|
6
|
+
examples: [[
|
|
7
|
+
{ name: '{{user1}}', content: { text: 'Show me the top WZRD markets' } },
|
|
8
|
+
{ name: '{{agentName}}', content: { text: 'Here are the top WZRD attention markets...' } },
|
|
9
|
+
]],
|
|
10
|
+
validate: async () => true,
|
|
11
|
+
handler: async (runtime, _msg, _state, _opt, callback) => {
|
|
12
|
+
const result = await getWzrdClient(runtime).getLeaderboard(10);
|
|
13
|
+
const lines = result.markets.map((m, i) => `${i + 1}. ${m.metric} — ${fmtV(m.velocity_ema)} velocity (${m.platform}) | ${m.multiplier_bps / 10_000}x | id=${m.market_id}`);
|
|
14
|
+
const text = `WZRD Leaderboard (${result.markets.length} markets, root_seq=${result.root.root_seq}):\n${lines.join('\n')}`;
|
|
15
|
+
await callback?.({ text });
|
|
16
|
+
return { success: true, data: result };
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
function fmtV(v) {
|
|
20
|
+
if (v >= 1e6)
|
|
21
|
+
return `${(v / 1e6).toFixed(1)}M`;
|
|
22
|
+
if (v >= 1e3)
|
|
23
|
+
return `${(v / 1e3).toFixed(0)}K`;
|
|
24
|
+
return v.toFixed(0);
|
|
25
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { getWzrdClient } from '../client.js';
|
|
2
|
+
export const portfolioAction = {
|
|
3
|
+
name: 'WZRD_PORTFOLIO',
|
|
4
|
+
similes: ['WZRD_POSITIONS', 'WZRD_BALANCE', 'MY_POSITIONS'],
|
|
5
|
+
description: 'Fetch your WZRD portfolio — open positions, USDC deposited, CCM earned.',
|
|
6
|
+
examples: [[
|
|
7
|
+
{ name: '{{user1}}', content: { text: 'Show my WZRD portfolio' } },
|
|
8
|
+
{ name: '{{agentName}}', content: { text: 'Your WZRD portfolio has 2 open positions...' } },
|
|
9
|
+
]],
|
|
10
|
+
validate: async () => true,
|
|
11
|
+
handler: async (runtime, _msg, _state, _opt, callback) => {
|
|
12
|
+
const p = await getWzrdClient(runtime).getPortfolio();
|
|
13
|
+
const open = p.positions.filter((x) => !x.is_settled);
|
|
14
|
+
const lines = open.map((x) => `Market #${x.market_id} (${x.metric}): ${(x.usdc_deposited / 1e6).toFixed(4)} USDC, ${(x.multiplier_bps / 1e4).toFixed(1)}x`);
|
|
15
|
+
const text = `Portfolio (${open.length} open):\n${lines.length ? lines.join('\n') : '(none)'}\n` +
|
|
16
|
+
`Total: ${(p.total_deposited_usdc / 1e6).toFixed(4)} USDC, ${(p.total_ccm_earned / 1e6).toFixed(4)} CCM`;
|
|
17
|
+
await callback?.({ text });
|
|
18
|
+
return { success: true, data: p };
|
|
19
|
+
},
|
|
20
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { getWzrdClient } from '../client.js';
|
|
2
|
+
export const velocityAction = {
|
|
3
|
+
name: 'WZRD_VELOCITY',
|
|
4
|
+
similes: ['WZRD_SIGNAL', 'ATTENTION_SIGNAL', 'VELOCITY_CHECK'],
|
|
5
|
+
description: 'Analyze velocity across WZRD markets. Classifies into BREAKOUT/MOMENTUM/EMERGING/STABLE/COOLING/WEAK.',
|
|
6
|
+
examples: [[
|
|
7
|
+
{ name: '{{user1}}', content: { text: 'Analyze WZRD velocity signals' } },
|
|
8
|
+
{ name: '{{agentName}}', content: { text: 'BREAKOUT: Qwen 3.5 35B (450K velocity, p95)...' } },
|
|
9
|
+
]],
|
|
10
|
+
validate: async () => true,
|
|
11
|
+
handler: async (runtime, _msg, _state, _opt, callback) => {
|
|
12
|
+
const { markets } = await getWzrdClient(runtime).getLeaderboard(50);
|
|
13
|
+
if (!markets.length) {
|
|
14
|
+
await callback?.({ text: 'No markets found.' });
|
|
15
|
+
return { success: true, data: { signals: [] } };
|
|
16
|
+
}
|
|
17
|
+
const sorted = [...markets].sort((a, b) => a.velocity_ema - b.velocity_ema);
|
|
18
|
+
const signals = markets.map((m) => {
|
|
19
|
+
const pct = ((sorted.findIndex((s) => s.market_id === m.market_id) + 1) / sorted.length) * 100;
|
|
20
|
+
return { market_id: m.market_id, metric: m.metric, platform: m.platform,
|
|
21
|
+
velocity_ema: m.velocity_ema, signal: classify(m, pct), percentile: Math.round(pct) };
|
|
22
|
+
});
|
|
23
|
+
const tiers = ['BREAKOUT', 'MOMENTUM', 'EMERGING', 'STABLE', 'COOLING', 'WEAK'];
|
|
24
|
+
const lines = [];
|
|
25
|
+
for (const t of tiers) {
|
|
26
|
+
const g = signals.filter((s) => s.signal === t);
|
|
27
|
+
if (!g.length)
|
|
28
|
+
continue;
|
|
29
|
+
lines.push(`${t}:`);
|
|
30
|
+
g.forEach((s) => lines.push(` ${s.metric} (${fmtV(s.velocity_ema)}, p${s.percentile}) [${s.platform}]`));
|
|
31
|
+
}
|
|
32
|
+
const median = sorted[Math.floor(sorted.length / 2)]?.velocity_ema ?? 0;
|
|
33
|
+
const text = `Velocity analysis (${markets.length} markets, median ${fmtV(median)}):\n${lines.join('\n')}`;
|
|
34
|
+
await callback?.({ text });
|
|
35
|
+
return { success: true, data: { signals, median_velocity: median } };
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
function classify(m, p) {
|
|
39
|
+
if (p >= 90)
|
|
40
|
+
return 'BREAKOUT';
|
|
41
|
+
if (p >= 70)
|
|
42
|
+
return 'MOMENTUM';
|
|
43
|
+
if (m.snapshot_count < 300 && p >= 50)
|
|
44
|
+
return 'EMERGING';
|
|
45
|
+
if (p >= 40)
|
|
46
|
+
return 'STABLE';
|
|
47
|
+
if (p >= 20)
|
|
48
|
+
return 'COOLING';
|
|
49
|
+
return 'WEAK';
|
|
50
|
+
}
|
|
51
|
+
function fmtV(v) {
|
|
52
|
+
if (v >= 1e6)
|
|
53
|
+
return `${(v / 1e6).toFixed(1)}M`;
|
|
54
|
+
if (v >= 1e3)
|
|
55
|
+
return `${(v / 1e3).toFixed(0)}K`;
|
|
56
|
+
return v.toFixed(0);
|
|
57
|
+
}
|
package/dist/client.d.ts
ADDED
package/dist/client.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Shared helper: extract wallet from ELIZA runtime, return cached WzrdClient. */
|
|
2
|
+
import { Keypair } from '@solana/web3.js';
|
|
3
|
+
import { WzrdClient } from '@wzrd_sol/solana-agent-plugin';
|
|
4
|
+
const DEFAULT_API_URL = 'https://api.twzrd.xyz';
|
|
5
|
+
const cache = new Map();
|
|
6
|
+
export function getWzrdClient(runtime) {
|
|
7
|
+
const sk = runtime.getSetting('SOLANA_PRIVATE_KEY');
|
|
8
|
+
if (!sk)
|
|
9
|
+
throw new Error('SOLANA_PRIVATE_KEY not configured in ELIZA runtime');
|
|
10
|
+
const kp = Keypair.fromSecretKey(Uint8Array.from(JSON.parse(String(sk))));
|
|
11
|
+
const pub = kp.publicKey.toBase58();
|
|
12
|
+
if (!cache.has(pub)) {
|
|
13
|
+
const apiUrl = runtime.getSetting('WZRD_API_URL');
|
|
14
|
+
cache.set(pub, new WzrdClient(kp, (typeof apiUrl === 'string' ? apiUrl : undefined) || DEFAULT_API_URL));
|
|
15
|
+
}
|
|
16
|
+
return cache.get(pub);
|
|
17
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @wzrd_sol/eliza-plugin — WZRD Liquid Attention Protocol for ElizaOS.
|
|
3
|
+
* Thin adapter wrapping @wzrd_sol/solana-agent-plugin's WzrdClient.
|
|
4
|
+
*
|
|
5
|
+
* Config (runtime.getSetting): SOLANA_PRIVATE_KEY (required), WZRD_API_URL, SOLANA_RPC_URL
|
|
6
|
+
*/
|
|
7
|
+
import type { Plugin } from '@elizaos/core';
|
|
8
|
+
import { leaderboardAction } from './actions/leaderboard.js';
|
|
9
|
+
import { portfolioAction } from './actions/portfolio.js';
|
|
10
|
+
import { claimAction } from './actions/claim.js';
|
|
11
|
+
import { depositAction } from './actions/deposit.js';
|
|
12
|
+
import { velocityAction } from './actions/velocity.js';
|
|
13
|
+
export declare const wzrdPlugin: Plugin;
|
|
14
|
+
export default wzrdPlugin;
|
|
15
|
+
export { leaderboardAction, portfolioAction, claimAction, depositAction, velocityAction };
|
|
16
|
+
export { getWzrdClient } from './client.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { leaderboardAction } from './actions/leaderboard.js';
|
|
2
|
+
import { portfolioAction } from './actions/portfolio.js';
|
|
3
|
+
import { claimAction } from './actions/claim.js';
|
|
4
|
+
import { depositAction } from './actions/deposit.js';
|
|
5
|
+
import { velocityAction } from './actions/velocity.js';
|
|
6
|
+
export const wzrdPlugin = {
|
|
7
|
+
name: 'wzrd',
|
|
8
|
+
description: 'WZRD Liquid Attention Protocol — deposit USDC into AI attention markets, ' +
|
|
9
|
+
'earn CCM yield based on model velocity.',
|
|
10
|
+
actions: [leaderboardAction, portfolioAction, claimAction, depositAction, velocityAction],
|
|
11
|
+
};
|
|
12
|
+
export default wzrdPlugin;
|
|
13
|
+
export { leaderboardAction, portfolioAction, claimAction, depositAction, velocityAction };
|
|
14
|
+
export { getWzrdClient } from './client.js';
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@wzrd_sol/eliza-plugin",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "WZRD Liquid Attention Protocol plugin for ElizaOS — leaderboard, portfolio, deposit, claim, velocity",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"scripts": {
|
|
16
|
+
"build": "tsc",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@wzrd_sol/solana-agent-plugin": "^0.1.0",
|
|
21
|
+
"@wzrd_sol/sdk": "^0.1.1",
|
|
22
|
+
"@solana/web3.js": "^1.95.0"
|
|
23
|
+
},
|
|
24
|
+
"peerDependencies": {
|
|
25
|
+
"@elizaos/core": "^1.0.0"
|
|
26
|
+
},
|
|
27
|
+
"peerDependenciesMeta": {
|
|
28
|
+
"@elizaos/core": {
|
|
29
|
+
"optional": true
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@elizaos/core": "^1.0.0",
|
|
34
|
+
"typescript": "^5.6.3"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"solana",
|
|
38
|
+
"eliza",
|
|
39
|
+
"elizaos",
|
|
40
|
+
"wzrd",
|
|
41
|
+
"attention",
|
|
42
|
+
"defi",
|
|
43
|
+
"ai-agent"
|
|
44
|
+
],
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "https://github.com/twzrd-sol/wzrd-final",
|
|
52
|
+
"directory": "agents/eliza-plugin"
|
|
53
|
+
},
|
|
54
|
+
"files": [
|
|
55
|
+
"dist",
|
|
56
|
+
"package.json",
|
|
57
|
+
"README.md"
|
|
58
|
+
]
|
|
59
|
+
}
|