@jhinresh/elizaos-plugin 0.2.0 → 0.7.3
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 +66 -0
- package/dist/index.d.ts +3 -30
- package/dist/index.js +21 -240
- package/package.json +22 -7
- package/src/index.ts +22 -261
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# @jhinresh/elizaos-plugin
|
|
2
|
+
|
|
3
|
+
> Maiat Trust Score plugin for ElizaOS — verify trust before your agent swaps or transacts.
|
|
4
|
+
|
|
5
|
+
Adds trust-checking actions and evaluators to any ElizaOS agent so it can **refuse to interact with low-trust addresses** before executing swaps, transfers, or on-chain actions.
|
|
6
|
+
|
|
7
|
+
Powered by [Maiat Protocol](https://app.maiat.io) — on-chain verified trust scores for tokens, DeFi protocols, and AI agents on Base.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @jhinresh/elizaos-plugin
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { maiatPlugin } from "@jhinresh/elizaos-plugin";
|
|
19
|
+
|
|
20
|
+
const agent = new ElizaAgent({
|
|
21
|
+
plugins: [
|
|
22
|
+
maiatPlugin({
|
|
23
|
+
minScore: 3.0, // reject addresses with score < 3.0/10
|
|
24
|
+
chain: "base",
|
|
25
|
+
}),
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## What it does
|
|
31
|
+
|
|
32
|
+
| Component | Type | Behaviour |
|
|
33
|
+
|-----------|------|-----------|
|
|
34
|
+
| `CHECK_TRUST` | Action | Agent can ask "is 0x... safe?" and get a trust score |
|
|
35
|
+
| `TRUST_GATE` | Evaluator | Runs before any swap/transfer — rejects low-trust addresses |
|
|
36
|
+
| `TRUST_DATA` | Provider | Injects trust context into agent's world state |
|
|
37
|
+
|
|
38
|
+
## Trust Score Scale
|
|
39
|
+
|
|
40
|
+
| Score | Risk | Action |
|
|
41
|
+
|-------|------|--------|
|
|
42
|
+
| 7–10 | 🟢 Low | Allow |
|
|
43
|
+
| 4–6.9 | 🟡 Medium | Warn |
|
|
44
|
+
| 0–3.9 | 🔴 High | **Block** |
|
|
45
|
+
|
|
46
|
+
## Config
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
maiatPlugin({
|
|
50
|
+
apiUrl: "https://app.maiat.io", // default
|
|
51
|
+
apiKey: "your-key", // optional — free tier: 100 req/day
|
|
52
|
+
minScore: 3.0, // 0–10 scale
|
|
53
|
+
chain: "base", // base | bnb | solana
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Links
|
|
58
|
+
|
|
59
|
+
- 🌐 [Live app](https://app.maiat.io)
|
|
60
|
+
- 📖 [API docs](https://app.maiat.io/docs)
|
|
61
|
+
- 🔗 [GitHub](https://github.com/JhiNResH/maiat-protocol)
|
|
62
|
+
- 📦 [npm](https://www.npmjs.com/package/@jhinresh/elizaos-plugin)
|
|
63
|
+
|
|
64
|
+
## License
|
|
65
|
+
|
|
66
|
+
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @maiat/elizaos-plugin
|
|
3
|
-
*
|
|
4
|
-
* Maiat Trust Score plugin for ElizaOS (ai16z agent framework).
|
|
5
|
-
*
|
|
6
|
-
* V0.2.0 — Cold-start update:
|
|
7
|
-
* - CHECK_TRUST: Trust score lookup (existing)
|
|
8
|
-
* - SUBMIT_REVIEW: Submit reviews with Scarab staking
|
|
9
|
-
* - GET_INTERACTIONS: Discover wallet contract interactions
|
|
10
|
-
* - GET_PASSPORT: Reputation passport
|
|
11
|
-
* - DEFI_INFO: Query DeFi protocols
|
|
12
|
-
* - AGENT_INFO: Query AI agents
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```typescript
|
|
16
|
-
* import { maiatPlugin } from "@maiat/elizaos-plugin";
|
|
17
|
-
*
|
|
18
|
-
* const agent = new ElizaAgent({
|
|
19
|
-
* plugins: [maiatPlugin({ minScore: 3.0 })],
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
1
|
export interface MaiatElizaConfig {
|
|
24
2
|
apiUrl?: string;
|
|
25
3
|
apiKey?: string;
|
|
@@ -28,11 +6,6 @@ export interface MaiatElizaConfig {
|
|
|
28
6
|
}
|
|
29
7
|
/**
|
|
30
8
|
* ElizaOS plugin definition following the standard plugin interface.
|
|
31
|
-
*
|
|
32
|
-
* Registers:
|
|
33
|
-
* - Actions: CHECK_TRUST, SUBMIT_REVIEW, GET_INTERACTIONS, GET_PASSPORT, DEFI_INFO, AGENT_INFO
|
|
34
|
-
* - Evaluator: TRUST_GATE
|
|
35
|
-
* - Provider: TRUST_DATA
|
|
36
9
|
*/
|
|
37
10
|
export declare function maiatPlugin(config?: MaiatElizaConfig): {
|
|
38
11
|
name: string;
|
|
@@ -47,7 +20,7 @@ export declare function maiatPlugin(config?: MaiatElizaConfig): {
|
|
|
47
20
|
data?: undefined;
|
|
48
21
|
} | {
|
|
49
22
|
text: string;
|
|
50
|
-
data:
|
|
23
|
+
data: import("maiat-sdk").AgentTrustResult;
|
|
51
24
|
}>;
|
|
52
25
|
}[];
|
|
53
26
|
evaluators: {
|
|
@@ -59,11 +32,11 @@ export declare function maiatPlugin(config?: MaiatElizaConfig): {
|
|
|
59
32
|
pass: boolean;
|
|
60
33
|
reason: string;
|
|
61
34
|
score?: undefined;
|
|
62
|
-
|
|
35
|
+
verdict?: undefined;
|
|
63
36
|
} | {
|
|
64
37
|
pass: boolean;
|
|
65
38
|
score: number;
|
|
66
|
-
|
|
39
|
+
verdict: "proceed" | "caution" | "avoid";
|
|
67
40
|
reason: string;
|
|
68
41
|
}>;
|
|
69
42
|
}[];
|
package/dist/index.js
CHANGED
|
@@ -1,79 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
* @maiat/elizaos-plugin
|
|
3
|
-
*
|
|
4
|
-
* Maiat Trust Score plugin for ElizaOS (ai16z agent framework).
|
|
5
|
-
*
|
|
6
|
-
* V0.2.0 — Cold-start update:
|
|
7
|
-
* - CHECK_TRUST: Trust score lookup (existing)
|
|
8
|
-
* - SUBMIT_REVIEW: Submit reviews with Scarab staking
|
|
9
|
-
* - GET_INTERACTIONS: Discover wallet contract interactions
|
|
10
|
-
* - GET_PASSPORT: Reputation passport
|
|
11
|
-
* - DEFI_INFO: Query DeFi protocols
|
|
12
|
-
* - AGENT_INFO: Query AI agents
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```typescript
|
|
16
|
-
* import { maiatPlugin } from "@maiat/elizaos-plugin";
|
|
17
|
-
*
|
|
18
|
-
* const agent = new ElizaAgent({
|
|
19
|
-
* plugins: [maiatPlugin({ minScore: 3.0 })],
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
// ═══════════════════════════════════════════
|
|
24
|
-
// API Client (lightweight)
|
|
25
|
-
// ═══════════════════════════════════════════
|
|
26
|
-
function getHeaders(config) {
|
|
27
|
-
const h = {
|
|
28
|
-
"Content-Type": "application/json",
|
|
29
|
-
"User-Agent": "maiat-elizaos-plugin/0.2.0",
|
|
30
|
-
};
|
|
31
|
-
if (config.apiKey)
|
|
32
|
-
h["Authorization"] = `Bearer ${config.apiKey}`;
|
|
33
|
-
return h;
|
|
34
|
-
}
|
|
35
|
-
function getApiUrl(config) {
|
|
36
|
-
return config.apiUrl || "https://maiat-protocol.vercel.app";
|
|
37
|
-
}
|
|
38
|
-
async function queryMaiat(address, config) {
|
|
39
|
-
const apiUrl = getApiUrl(config);
|
|
40
|
-
const chain = config.chain || "base";
|
|
41
|
-
const minScore = config.minScore ?? 3.0;
|
|
42
|
-
const res = await fetch(`${apiUrl}/api/v1/score/${address}?chain=${chain}`, {
|
|
43
|
-
headers: getHeaders(config),
|
|
44
|
-
});
|
|
45
|
-
if (!res.ok) {
|
|
46
|
-
throw new Error(`Maiat API error: ${res.status}`);
|
|
47
|
-
}
|
|
48
|
-
const data = await res.json();
|
|
49
|
-
return {
|
|
50
|
-
address: data.address,
|
|
51
|
-
score: data.score,
|
|
52
|
-
risk: data.risk,
|
|
53
|
-
type: data.type,
|
|
54
|
-
flags: data.flags || [],
|
|
55
|
-
safe: data.score >= minScore,
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
// ═══════════════════════════════════════════
|
|
59
|
-
// ElizaOS Plugin
|
|
60
|
-
// ═══════════════════════════════════════════
|
|
1
|
+
import { Maiat } from "maiat-sdk";
|
|
61
2
|
/**
|
|
62
3
|
* ElizaOS plugin definition following the standard plugin interface.
|
|
63
|
-
*
|
|
64
|
-
* Registers:
|
|
65
|
-
* - Actions: CHECK_TRUST, SUBMIT_REVIEW, GET_INTERACTIONS, GET_PASSPORT, DEFI_INFO, AGENT_INFO
|
|
66
|
-
* - Evaluator: TRUST_GATE
|
|
67
|
-
* - Provider: TRUST_DATA
|
|
68
4
|
*/
|
|
69
5
|
export function maiatPlugin(config = {}) {
|
|
70
|
-
const
|
|
71
|
-
|
|
6
|
+
const sdk = new Maiat({
|
|
7
|
+
baseUrl: config.apiUrl,
|
|
8
|
+
apiKey: config.apiKey,
|
|
9
|
+
framework: "elizaos",
|
|
10
|
+
clientId: "elizaos-plugin-standard"
|
|
11
|
+
});
|
|
12
|
+
const minScore = config.minScore ?? 60; // SDK uses 0-100 scale
|
|
72
13
|
return {
|
|
73
14
|
name: "maiat-trust",
|
|
74
15
|
description: "Trust scoring for on-chain addresses via Maiat Protocol",
|
|
75
16
|
actions: [
|
|
76
|
-
// --- Existing: CHECK_TRUST ---
|
|
77
17
|
{
|
|
78
18
|
name: "CHECK_TRUST",
|
|
79
19
|
description: "Check the trust score of an on-chain address",
|
|
@@ -90,10 +30,11 @@ export function maiatPlugin(config = {}) {
|
|
|
90
30
|
if (!match)
|
|
91
31
|
return { text: "Please provide a valid Ethereum address (0x...)" };
|
|
92
32
|
try {
|
|
93
|
-
const result = await
|
|
94
|
-
const
|
|
33
|
+
const result = await sdk.agentTrust(match[0]);
|
|
34
|
+
const safe = result.trustScore >= minScore;
|
|
35
|
+
const emoji = safe ? "🟢" : result.verdict === "avoid" ? "🔴" : "🟡";
|
|
95
36
|
return {
|
|
96
|
-
text: `${emoji} **Trust Score: ${result.
|
|
37
|
+
text: `${emoji} **Trust Score: ${result.trustScore}/100** (${result.verdict} verdict)\n\nAddress: \`${result.address}\`\nSource: ${result.dataSource}\nJobs: ${result.breakdown.totalJobs}\n\n${safe ? "✅ Safe to interact." : "⚠️ Exercise caution — score below threshold."}`,
|
|
97
38
|
data: result,
|
|
98
39
|
};
|
|
99
40
|
}
|
|
@@ -104,167 +45,6 @@ export function maiatPlugin(config = {}) {
|
|
|
104
45
|
}
|
|
105
46
|
},
|
|
106
47
|
},
|
|
107
|
-
// --- NEW: SUBMIT_REVIEW ---
|
|
108
|
-
{
|
|
109
|
-
name: "SUBMIT_REVIEW",
|
|
110
|
-
description: "Submit a trust review for a contract. Costs 2 Scarab, earn 3-10 for quality.",
|
|
111
|
-
examples: [
|
|
112
|
-
"Review 0x833589... — rating 8, great stablecoin",
|
|
113
|
-
"Submit review: address 0xabc, rating 3, seems risky",
|
|
114
|
-
],
|
|
115
|
-
validate: async (message) => /0x[a-fA-F0-9]{40}/.test(message) && /\d/.test(message),
|
|
116
|
-
handler: async (message) => {
|
|
117
|
-
const addrMatch = message.match(/0x[a-fA-F0-9]{40}/);
|
|
118
|
-
const ratingMatch = message.match(/rating\s*:?\s*(\d+)/i) || message.match(/(\d+)\s*\/\s*10/);
|
|
119
|
-
if (!addrMatch)
|
|
120
|
-
return { text: "Please provide a contract address (0x...)" };
|
|
121
|
-
const rating = ratingMatch ? Math.min(10, Math.max(1, parseInt(ratingMatch[1]))) : 5;
|
|
122
|
-
try {
|
|
123
|
-
const res = await fetch(`${apiUrl}/api/v1/review`, {
|
|
124
|
-
method: "POST",
|
|
125
|
-
headers,
|
|
126
|
-
body: JSON.stringify({
|
|
127
|
-
address: addrMatch[0],
|
|
128
|
-
rating,
|
|
129
|
-
comment: message,
|
|
130
|
-
reviewer: "eliza-agent",
|
|
131
|
-
}),
|
|
132
|
-
});
|
|
133
|
-
const data = await res.json();
|
|
134
|
-
if (!res.ok)
|
|
135
|
-
throw new Error(data.error || `HTTP ${res.status}`);
|
|
136
|
-
return {
|
|
137
|
-
text: `✅ Review submitted!\n\n- Address: \`${addrMatch[0]}\`\n- Rating: ${rating}/10\n- Scarab earned: ${data.meta?.scarabReward || 0} 🪲`,
|
|
138
|
-
data,
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
return { text: `❌ Review failed: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
143
|
-
}
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
// --- NEW: GET_INTERACTIONS ---
|
|
147
|
-
{
|
|
148
|
-
name: "GET_INTERACTIONS",
|
|
149
|
-
description: "Discover which contracts a wallet has interacted with",
|
|
150
|
-
examples: [
|
|
151
|
-
"What contracts has 0x1234... interacted with?",
|
|
152
|
-
"Show interactions for 0xabcd...",
|
|
153
|
-
],
|
|
154
|
-
validate: async (message) => /0x[a-fA-F0-9]{40}/.test(message),
|
|
155
|
-
handler: async (message) => {
|
|
156
|
-
const match = message.match(/0x[a-fA-F0-9]{40}/);
|
|
157
|
-
if (!match)
|
|
158
|
-
return { text: "Please provide a wallet address." };
|
|
159
|
-
try {
|
|
160
|
-
const res = await fetch(`${apiUrl}/api/v1/wallet/${match[0]}/interactions`, { headers });
|
|
161
|
-
if (!res.ok)
|
|
162
|
-
throw new Error(`HTTP ${res.status}`);
|
|
163
|
-
const data = await res.json();
|
|
164
|
-
const list = data.interacted?.map((c) => ` • ${c.name} (${c.category}) — ${c.txCount} txs`).join("\n") || "None found";
|
|
165
|
-
return {
|
|
166
|
-
text: `📋 Wallet Interactions (${data.interactedCount} contracts):\n\n${list}`,
|
|
167
|
-
data,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
catch (error) {
|
|
171
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
172
|
-
}
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
// --- NEW: GET_PASSPORT ---
|
|
176
|
-
{
|
|
177
|
-
name: "GET_PASSPORT",
|
|
178
|
-
description: "Get a wallet's reputation passport",
|
|
179
|
-
examples: [
|
|
180
|
-
"Show passport for 0x1234...",
|
|
181
|
-
"What's my reputation level?",
|
|
182
|
-
],
|
|
183
|
-
validate: async (message) => /0x[a-fA-F0-9]{40}/.test(message),
|
|
184
|
-
handler: async (message) => {
|
|
185
|
-
const match = message.match(/0x[a-fA-F0-9]{40}/);
|
|
186
|
-
if (!match)
|
|
187
|
-
return { text: "Please provide a wallet address." };
|
|
188
|
-
try {
|
|
189
|
-
const res = await fetch(`${apiUrl}/api/v1/wallet/${match[0]}/passport`, { headers });
|
|
190
|
-
if (!res.ok)
|
|
191
|
-
throw new Error(`HTTP ${res.status}`);
|
|
192
|
-
const data = await res.json();
|
|
193
|
-
const p = data.passport;
|
|
194
|
-
return {
|
|
195
|
-
text: `🛡️ Reputation Passport\n\n- Trust Level: ${p.trustLevel.toUpperCase()}\n- Reputation: ${p.reputationScore}\n- Reviews: ${p.totalReviews}\n- Scarab: ${data.scarab?.balance || 0} 🪲\n- Fee Tier: ${p.feeTier.discount}`,
|
|
196
|
-
data,
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
catch (error) {
|
|
200
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
201
|
-
}
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
// --- NEW: DEFI_INFO ---
|
|
205
|
-
{
|
|
206
|
-
name: "DEFI_INFO",
|
|
207
|
-
description: "Look up a DeFi protocol by name or address",
|
|
208
|
-
examples: [
|
|
209
|
-
"Tell me about USDC",
|
|
210
|
-
"What's the trust score for Aerodrome?",
|
|
211
|
-
"Look up 0x833589...",
|
|
212
|
-
],
|
|
213
|
-
validate: async (message) => true,
|
|
214
|
-
handler: async (message) => {
|
|
215
|
-
const addrMatch = message.match(/0x[a-fA-F0-9]{40}/);
|
|
216
|
-
const slugMatch = message.match(/\b(usdc|weth|dai|aerodrome|aave|compound|morpho|uniswap|chainlink|stargate)\b/i);
|
|
217
|
-
const query = addrMatch?.[0] || slugMatch?.[0]?.toLowerCase();
|
|
218
|
-
if (!query)
|
|
219
|
-
return { text: "Please specify a DeFi protocol name (e.g. USDC, Aave) or address." };
|
|
220
|
-
try {
|
|
221
|
-
const res = await fetch(`${apiUrl}/api/v1/defi/${query}`, { headers });
|
|
222
|
-
if (!res.ok)
|
|
223
|
-
throw new Error(res.status === 404 ? `"${query}" not found` : `HTTP ${res.status}`);
|
|
224
|
-
const data = await res.json();
|
|
225
|
-
const e = data.entity;
|
|
226
|
-
return {
|
|
227
|
-
text: `📊 ${e.name}\n\n- Address: \`${e.address}\`\n- Category: ${e.category}\n- Trust: ${data.trust?.score ?? "N/A"}/10\n- Reviews: ${data.reviews?.total || 0}`,
|
|
228
|
-
data,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
catch (error) {
|
|
232
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
233
|
-
}
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
// --- NEW: AGENT_INFO ---
|
|
237
|
-
{
|
|
238
|
-
name: "AGENT_INFO",
|
|
239
|
-
description: "Look up an AI agent by name or address",
|
|
240
|
-
examples: [
|
|
241
|
-
"Tell me about AIXBT",
|
|
242
|
-
"What's Virtuals trust score?",
|
|
243
|
-
"Look up agent 0x4f9fd6...",
|
|
244
|
-
],
|
|
245
|
-
validate: async (message) => true,
|
|
246
|
-
handler: async (message) => {
|
|
247
|
-
const addrMatch = message.match(/0x[a-fA-F0-9]{40}/);
|
|
248
|
-
const slugMatch = message.match(/\b(aixbt|virtuals|luna|vaderai|freysa|sekoia)\b/i);
|
|
249
|
-
const query = addrMatch?.[0] || slugMatch?.[0]?.toLowerCase();
|
|
250
|
-
if (!query)
|
|
251
|
-
return { text: "Please specify an agent name (e.g. AIXBT, Virtuals) or address." };
|
|
252
|
-
try {
|
|
253
|
-
const res = await fetch(`${apiUrl}/api/v1/agent/${query}`, { headers });
|
|
254
|
-
if (!res.ok)
|
|
255
|
-
throw new Error(res.status === 404 ? `"${query}" not found` : `HTTP ${res.status}`);
|
|
256
|
-
const data = await res.json();
|
|
257
|
-
const e = data.entity;
|
|
258
|
-
return {
|
|
259
|
-
text: `🤖 ${e.name}\n\n- Address: \`${e.address}\`\n- Category: ${e.category}\n- Trust: ${data.trust?.score ?? "N/A"}/10\n- Reviews: ${data.reviews?.total || 0}`,
|
|
260
|
-
data,
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
catch (error) {
|
|
264
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
265
|
-
}
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
48
|
],
|
|
269
49
|
evaluators: [
|
|
270
50
|
{
|
|
@@ -274,14 +54,15 @@ export function maiatPlugin(config = {}) {
|
|
|
274
54
|
if (!context.address)
|
|
275
55
|
return { pass: true, reason: "No address to check" };
|
|
276
56
|
try {
|
|
277
|
-
const result = await
|
|
57
|
+
const result = await sdk.agentTrust(context.address);
|
|
58
|
+
const safe = result.trustScore >= minScore;
|
|
278
59
|
return {
|
|
279
|
-
pass:
|
|
280
|
-
score: result.
|
|
281
|
-
|
|
282
|
-
reason:
|
|
283
|
-
? `Address trusted (${result.
|
|
284
|
-
: `Address untrusted (${result.
|
|
60
|
+
pass: safe,
|
|
61
|
+
score: result.trustScore,
|
|
62
|
+
verdict: result.verdict,
|
|
63
|
+
reason: safe
|
|
64
|
+
? `Address trusted (${result.trustScore}/100)`
|
|
65
|
+
: `Address untrusted (${result.trustScore}/100, ${result.verdict} verdict)`,
|
|
285
66
|
};
|
|
286
67
|
}
|
|
287
68
|
catch {
|
|
@@ -296,7 +77,7 @@ export function maiatPlugin(config = {}) {
|
|
|
296
77
|
description: "Provides trust scoring context for agent reasoning",
|
|
297
78
|
handler: async () => {
|
|
298
79
|
return {
|
|
299
|
-
text:
|
|
80
|
+
text: `You have access to Maiat trust scoring. Before interacting with any unknown on-chain address, use CHECK_TRUST to verify it's safe. Addresses scoring below ${minScore}/100 should be avoided.`,
|
|
300
81
|
};
|
|
301
82
|
},
|
|
302
83
|
},
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jhinresh/elizaos-plugin",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.7.3",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "Maiat Trust Score plugin for ElizaOS — verify trust before your agent swaps or transacts",
|
|
5
8
|
"license": "MIT",
|
|
6
9
|
"type": "module",
|
|
7
10
|
"main": "dist/index.js",
|
|
@@ -10,14 +13,26 @@
|
|
|
10
13
|
"build": "tsc",
|
|
11
14
|
"dev": "tsc --watch"
|
|
12
15
|
},
|
|
13
|
-
"
|
|
14
|
-
"
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@jhinresh/maiat-sdk": "^0.7.3"
|
|
15
18
|
},
|
|
16
19
|
"keywords": [
|
|
17
20
|
"maiat",
|
|
18
21
|
"elizaos",
|
|
22
|
+
"eliza",
|
|
19
23
|
"ai16z",
|
|
20
24
|
"trust-score",
|
|
21
|
-
"ai-agent"
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
"ai-agent",
|
|
26
|
+
"web3",
|
|
27
|
+
"defi",
|
|
28
|
+
"base"
|
|
29
|
+
],
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/JhiNResH/elizaos-plugin-maiat.git"
|
|
33
|
+
},
|
|
34
|
+
"homepage": "https://app.maiat.io",
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"typescript": "^5.5.0"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,29 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* @maiat/elizaos-plugin
|
|
3
|
-
*
|
|
4
|
-
* Maiat Trust Score plugin for ElizaOS (ai16z agent framework).
|
|
5
|
-
*
|
|
6
|
-
* V0.2.0 — Cold-start update:
|
|
7
|
-
* - CHECK_TRUST: Trust score lookup (existing)
|
|
8
|
-
* - SUBMIT_REVIEW: Submit reviews with Scarab staking
|
|
9
|
-
* - GET_INTERACTIONS: Discover wallet contract interactions
|
|
10
|
-
* - GET_PASSPORT: Reputation passport
|
|
11
|
-
* - DEFI_INFO: Query DeFi protocols
|
|
12
|
-
* - AGENT_INFO: Query AI agents
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```typescript
|
|
16
|
-
* import { maiatPlugin } from "@maiat/elizaos-plugin";
|
|
17
|
-
*
|
|
18
|
-
* const agent = new ElizaAgent({
|
|
19
|
-
* plugins: [maiatPlugin({ minScore: 3.0 })],
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
// ═══════════════════════════════════════════
|
|
25
|
-
// Types
|
|
26
|
-
// ═══════════════════════════════════════════
|
|
1
|
+
import { Maiat } from "@jhinresh/maiat-sdk";
|
|
27
2
|
|
|
28
3
|
export interface MaiatElizaConfig {
|
|
29
4
|
apiUrl?: string;
|
|
@@ -32,81 +7,24 @@ export interface MaiatElizaConfig {
|
|
|
32
7
|
minScore?: number;
|
|
33
8
|
}
|
|
34
9
|
|
|
35
|
-
interface TrustResult {
|
|
36
|
-
address: string;
|
|
37
|
-
score: number;
|
|
38
|
-
risk: string;
|
|
39
|
-
type: string;
|
|
40
|
-
flags: string[];
|
|
41
|
-
safe: boolean;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// ═══════════════════════════════════════════
|
|
45
|
-
// API Client (lightweight)
|
|
46
|
-
// ═══════════════════════════════════════════
|
|
47
|
-
|
|
48
|
-
function getHeaders(config: MaiatElizaConfig): Record<string, string> {
|
|
49
|
-
const h: Record<string, string> = {
|
|
50
|
-
"Content-Type": "application/json",
|
|
51
|
-
"User-Agent": "maiat-elizaos-plugin/0.2.0",
|
|
52
|
-
};
|
|
53
|
-
if (config.apiKey) h["Authorization"] = `Bearer ${config.apiKey}`;
|
|
54
|
-
return h;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function getApiUrl(config: MaiatElizaConfig): string {
|
|
58
|
-
return config.apiUrl || "https://maiat-protocol.vercel.app";
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function queryMaiat(
|
|
62
|
-
address: string,
|
|
63
|
-
config: MaiatElizaConfig
|
|
64
|
-
): Promise<TrustResult> {
|
|
65
|
-
const apiUrl = getApiUrl(config);
|
|
66
|
-
const chain = config.chain || "base";
|
|
67
|
-
const minScore = config.minScore ?? 3.0;
|
|
68
|
-
|
|
69
|
-
const res = await fetch(`${apiUrl}/api/v1/score/${address}?chain=${chain}`, {
|
|
70
|
-
headers: getHeaders(config),
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
if (!res.ok) {
|
|
74
|
-
throw new Error(`Maiat API error: ${res.status}`);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const data = await res.json();
|
|
78
|
-
return {
|
|
79
|
-
address: data.address,
|
|
80
|
-
score: data.score,
|
|
81
|
-
risk: data.risk,
|
|
82
|
-
type: data.type,
|
|
83
|
-
flags: data.flags || [],
|
|
84
|
-
safe: data.score >= minScore,
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ═══════════════════════════════════════════
|
|
89
|
-
// ElizaOS Plugin
|
|
90
|
-
// ═══════════════════════════════════════════
|
|
91
|
-
|
|
92
10
|
/**
|
|
93
11
|
* ElizaOS plugin definition following the standard plugin interface.
|
|
94
|
-
*
|
|
95
|
-
* Registers:
|
|
96
|
-
* - Actions: CHECK_TRUST, SUBMIT_REVIEW, GET_INTERACTIONS, GET_PASSPORT, DEFI_INFO, AGENT_INFO
|
|
97
|
-
* - Evaluator: TRUST_GATE
|
|
98
|
-
* - Provider: TRUST_DATA
|
|
99
12
|
*/
|
|
100
13
|
export function maiatPlugin(config: MaiatElizaConfig = {}) {
|
|
101
|
-
const
|
|
102
|
-
|
|
14
|
+
const sdk = new Maiat({
|
|
15
|
+
baseUrl: config.apiUrl,
|
|
16
|
+
apiKey: config.apiKey,
|
|
17
|
+
framework: "elizaos",
|
|
18
|
+
clientId: "elizaos-plugin-standard"
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const minScore = config.minScore ?? 60; // SDK uses 0-100 scale
|
|
103
22
|
|
|
104
23
|
return {
|
|
105
24
|
name: "maiat-trust",
|
|
106
25
|
description: "Trust scoring for on-chain addresses via Maiat Protocol",
|
|
107
26
|
|
|
108
27
|
actions: [
|
|
109
|
-
// --- Existing: CHECK_TRUST ---
|
|
110
28
|
{
|
|
111
29
|
name: "CHECK_TRUST",
|
|
112
30
|
description: "Check the trust score of an on-chain address",
|
|
@@ -123,11 +41,12 @@ export function maiatPlugin(config: MaiatElizaConfig = {}) {
|
|
|
123
41
|
if (!match) return { text: "Please provide a valid Ethereum address (0x...)" };
|
|
124
42
|
|
|
125
43
|
try {
|
|
126
|
-
const result = await
|
|
127
|
-
const
|
|
44
|
+
const result = await sdk.agentTrust(match[0]);
|
|
45
|
+
const safe = result.trustScore >= minScore;
|
|
46
|
+
const emoji = safe ? "🟢" : result.verdict === "avoid" ? "🔴" : "🟡";
|
|
128
47
|
|
|
129
48
|
return {
|
|
130
|
-
text: `${emoji} **Trust Score: ${result.
|
|
49
|
+
text: `${emoji} **Trust Score: ${result.trustScore}/100** (${result.verdict} verdict)\n\nAddress: \`${result.address}\`\nSource: ${result.dataSource}\nJobs: ${result.breakdown.totalJobs}\n\n${safe ? "✅ Safe to interact." : "⚠️ Exercise caution — score below threshold."}`,
|
|
131
50
|
data: result,
|
|
132
51
|
};
|
|
133
52
|
} catch (error) {
|
|
@@ -137,165 +56,6 @@ export function maiatPlugin(config: MaiatElizaConfig = {}) {
|
|
|
137
56
|
}
|
|
138
57
|
},
|
|
139
58
|
},
|
|
140
|
-
// --- NEW: SUBMIT_REVIEW ---
|
|
141
|
-
{
|
|
142
|
-
name: "SUBMIT_REVIEW",
|
|
143
|
-
description: "Submit a trust review for a contract. Costs 2 Scarab, earn 3-10 for quality.",
|
|
144
|
-
examples: [
|
|
145
|
-
"Review 0x833589... — rating 8, great stablecoin",
|
|
146
|
-
"Submit review: address 0xabc, rating 3, seems risky",
|
|
147
|
-
],
|
|
148
|
-
validate: async (message: string) => /0x[a-fA-F0-9]{40}/.test(message) && /\d/.test(message),
|
|
149
|
-
handler: async (message: string) => {
|
|
150
|
-
const addrMatch = message.match(/0x[a-fA-F0-9]{40}/);
|
|
151
|
-
const ratingMatch = message.match(/rating\s*:?\s*(\d+)/i) || message.match(/(\d+)\s*\/\s*10/);
|
|
152
|
-
if (!addrMatch) return { text: "Please provide a contract address (0x...)" };
|
|
153
|
-
const rating = ratingMatch ? Math.min(10, Math.max(1, parseInt(ratingMatch[1]))) : 5;
|
|
154
|
-
|
|
155
|
-
try {
|
|
156
|
-
const res = await fetch(`${apiUrl}/api/v1/review`, {
|
|
157
|
-
method: "POST",
|
|
158
|
-
headers,
|
|
159
|
-
body: JSON.stringify({
|
|
160
|
-
address: addrMatch[0],
|
|
161
|
-
rating,
|
|
162
|
-
comment: message,
|
|
163
|
-
reviewer: "eliza-agent",
|
|
164
|
-
}),
|
|
165
|
-
});
|
|
166
|
-
const data = await res.json();
|
|
167
|
-
if (!res.ok) throw new Error(data.error || `HTTP ${res.status}`);
|
|
168
|
-
|
|
169
|
-
return {
|
|
170
|
-
text: `✅ Review submitted!\n\n- Address: \`${addrMatch[0]}\`\n- Rating: ${rating}/10\n- Scarab earned: ${data.meta?.scarabReward || 0} 🪲`,
|
|
171
|
-
data,
|
|
172
|
-
};
|
|
173
|
-
} catch (error) {
|
|
174
|
-
return { text: `❌ Review failed: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
// --- NEW: GET_INTERACTIONS ---
|
|
179
|
-
{
|
|
180
|
-
name: "GET_INTERACTIONS",
|
|
181
|
-
description: "Discover which contracts a wallet has interacted with",
|
|
182
|
-
examples: [
|
|
183
|
-
"What contracts has 0x1234... interacted with?",
|
|
184
|
-
"Show interactions for 0xabcd...",
|
|
185
|
-
],
|
|
186
|
-
validate: async (message: string) => /0x[a-fA-F0-9]{40}/.test(message),
|
|
187
|
-
handler: async (message: string) => {
|
|
188
|
-
const match = message.match(/0x[a-fA-F0-9]{40}/);
|
|
189
|
-
if (!match) return { text: "Please provide a wallet address." };
|
|
190
|
-
|
|
191
|
-
try {
|
|
192
|
-
const res = await fetch(`${apiUrl}/api/v1/wallet/${match[0]}/interactions`, { headers });
|
|
193
|
-
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
194
|
-
const data = await res.json();
|
|
195
|
-
|
|
196
|
-
const list = data.interacted?.map((c: { name: string; category: string; txCount: number }) =>
|
|
197
|
-
` • ${c.name} (${c.category}) — ${c.txCount} txs`
|
|
198
|
-
).join("\n") || "None found";
|
|
199
|
-
|
|
200
|
-
return {
|
|
201
|
-
text: `📋 Wallet Interactions (${data.interactedCount} contracts):\n\n${list}`,
|
|
202
|
-
data,
|
|
203
|
-
};
|
|
204
|
-
} catch (error) {
|
|
205
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
206
|
-
}
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
// --- NEW: GET_PASSPORT ---
|
|
210
|
-
{
|
|
211
|
-
name: "GET_PASSPORT",
|
|
212
|
-
description: "Get a wallet's reputation passport",
|
|
213
|
-
examples: [
|
|
214
|
-
"Show passport for 0x1234...",
|
|
215
|
-
"What's my reputation level?",
|
|
216
|
-
],
|
|
217
|
-
validate: async (message: string) => /0x[a-fA-F0-9]{40}/.test(message),
|
|
218
|
-
handler: async (message: string) => {
|
|
219
|
-
const match = message.match(/0x[a-fA-F0-9]{40}/);
|
|
220
|
-
if (!match) return { text: "Please provide a wallet address." };
|
|
221
|
-
|
|
222
|
-
try {
|
|
223
|
-
const res = await fetch(`${apiUrl}/api/v1/wallet/${match[0]}/passport`, { headers });
|
|
224
|
-
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
225
|
-
const data = await res.json();
|
|
226
|
-
|
|
227
|
-
const p = data.passport;
|
|
228
|
-
return {
|
|
229
|
-
text: `🛡️ Reputation Passport\n\n- Trust Level: ${p.trustLevel.toUpperCase()}\n- Reputation: ${p.reputationScore}\n- Reviews: ${p.totalReviews}\n- Scarab: ${data.scarab?.balance || 0} 🪲\n- Fee Tier: ${p.feeTier.discount}`,
|
|
230
|
-
data,
|
|
231
|
-
};
|
|
232
|
-
} catch (error) {
|
|
233
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
234
|
-
}
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
// --- NEW: DEFI_INFO ---
|
|
238
|
-
{
|
|
239
|
-
name: "DEFI_INFO",
|
|
240
|
-
description: "Look up a DeFi protocol by name or address",
|
|
241
|
-
examples: [
|
|
242
|
-
"Tell me about USDC",
|
|
243
|
-
"What's the trust score for Aerodrome?",
|
|
244
|
-
"Look up 0x833589...",
|
|
245
|
-
],
|
|
246
|
-
validate: async (message: string) => true,
|
|
247
|
-
handler: async (message: string) => {
|
|
248
|
-
const addrMatch = message.match(/0x[a-fA-F0-9]{40}/);
|
|
249
|
-
const slugMatch = message.match(/\b(usdc|weth|dai|aerodrome|aave|compound|morpho|uniswap|chainlink|stargate)\b/i);
|
|
250
|
-
const query = addrMatch?.[0] || slugMatch?.[0]?.toLowerCase();
|
|
251
|
-
if (!query) return { text: "Please specify a DeFi protocol name (e.g. USDC, Aave) or address." };
|
|
252
|
-
|
|
253
|
-
try {
|
|
254
|
-
const res = await fetch(`${apiUrl}/api/v1/defi/${query}`, { headers });
|
|
255
|
-
if (!res.ok) throw new Error(res.status === 404 ? `"${query}" not found` : `HTTP ${res.status}`);
|
|
256
|
-
const data = await res.json();
|
|
257
|
-
const e = data.entity;
|
|
258
|
-
|
|
259
|
-
return {
|
|
260
|
-
text: `📊 ${e.name}\n\n- Address: \`${e.address}\`\n- Category: ${e.category}\n- Trust: ${data.trust?.score ?? "N/A"}/10\n- Reviews: ${data.reviews?.total || 0}`,
|
|
261
|
-
data,
|
|
262
|
-
};
|
|
263
|
-
} catch (error) {
|
|
264
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
265
|
-
}
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
// --- NEW: AGENT_INFO ---
|
|
269
|
-
{
|
|
270
|
-
name: "AGENT_INFO",
|
|
271
|
-
description: "Look up an AI agent by name or address",
|
|
272
|
-
examples: [
|
|
273
|
-
"Tell me about AIXBT",
|
|
274
|
-
"What's Virtuals trust score?",
|
|
275
|
-
"Look up agent 0x4f9fd6...",
|
|
276
|
-
],
|
|
277
|
-
validate: async (message: string) => true,
|
|
278
|
-
handler: async (message: string) => {
|
|
279
|
-
const addrMatch = message.match(/0x[a-fA-F0-9]{40}/);
|
|
280
|
-
const slugMatch = message.match(/\b(aixbt|virtuals|luna|vaderai|freysa|sekoia)\b/i);
|
|
281
|
-
const query = addrMatch?.[0] || slugMatch?.[0]?.toLowerCase();
|
|
282
|
-
if (!query) return { text: "Please specify an agent name (e.g. AIXBT, Virtuals) or address." };
|
|
283
|
-
|
|
284
|
-
try {
|
|
285
|
-
const res = await fetch(`${apiUrl}/api/v1/agent/${query}`, { headers });
|
|
286
|
-
if (!res.ok) throw new Error(res.status === 404 ? `"${query}" not found` : `HTTP ${res.status}`);
|
|
287
|
-
const data = await res.json();
|
|
288
|
-
const e = data.entity;
|
|
289
|
-
|
|
290
|
-
return {
|
|
291
|
-
text: `🤖 ${e.name}\n\n- Address: \`${e.address}\`\n- Category: ${e.category}\n- Trust: ${data.trust?.score ?? "N/A"}/10\n- Reviews: ${data.reviews?.total || 0}`,
|
|
292
|
-
data,
|
|
293
|
-
};
|
|
294
|
-
} catch (error) {
|
|
295
|
-
return { text: `❌ Error: ${error instanceof Error ? error.message : "Unknown error"}` };
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
59
|
],
|
|
300
60
|
|
|
301
61
|
evaluators: [
|
|
@@ -306,14 +66,15 @@ export function maiatPlugin(config: MaiatElizaConfig = {}) {
|
|
|
306
66
|
if (!context.address) return { pass: true, reason: "No address to check" };
|
|
307
67
|
|
|
308
68
|
try {
|
|
309
|
-
const result = await
|
|
69
|
+
const result = await sdk.agentTrust(context.address);
|
|
70
|
+
const safe = result.trustScore >= minScore;
|
|
310
71
|
return {
|
|
311
|
-
pass:
|
|
312
|
-
score: result.
|
|
313
|
-
|
|
314
|
-
reason:
|
|
315
|
-
? `Address trusted (${result.
|
|
316
|
-
: `Address untrusted (${result.
|
|
72
|
+
pass: safe,
|
|
73
|
+
score: result.trustScore,
|
|
74
|
+
verdict: result.verdict,
|
|
75
|
+
reason: safe
|
|
76
|
+
? `Address trusted (${result.trustScore}/100)`
|
|
77
|
+
: `Address untrusted (${result.trustScore}/100, ${result.verdict} verdict)`,
|
|
317
78
|
};
|
|
318
79
|
} catch {
|
|
319
80
|
return { pass: false, reason: "Trust check failed — blocking by default" };
|
|
@@ -328,7 +89,7 @@ export function maiatPlugin(config: MaiatElizaConfig = {}) {
|
|
|
328
89
|
description: "Provides trust scoring context for agent reasoning",
|
|
329
90
|
handler: async () => {
|
|
330
91
|
return {
|
|
331
|
-
text:
|
|
92
|
+
text: `You have access to Maiat trust scoring. Before interacting with any unknown on-chain address, use CHECK_TRUST to verify it's safe. Addresses scoring below ${minScore}/100 should be avoided.`,
|
|
332
93
|
};
|
|
333
94
|
},
|
|
334
95
|
},
|