shll-skills 5.3.0 → 5.3.2
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/.env.example +2 -8
- package/README.md +5 -4
- package/SKILL.md +3 -1
- package/dist/mcp.js +5 -5
- package/dist/mcp.mjs +5 -5
- package/package.json +2 -2
- package/src/mcp.ts +5 -5
package/.env.example
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
# ── Required ─────────────────────────────────────────────
|
|
2
2
|
# Private key for the operator/renter wallet.
|
|
3
|
-
# ⚠️ This key is used for:
|
|
3
|
+
# ⚠️ This key is used for: swap, wrap, unwrap, transfer, lend, redeem, config.
|
|
4
4
|
# ⚠️ Use a DEDICATED wallet with limited funds. Never use your main wallet.
|
|
5
5
|
RUNNER_PRIVATE_KEY=0x_YOUR_PRIVATE_KEY_HERE
|
|
6
6
|
|
|
7
7
|
# ── Optional Overrides ───────────────────────────────────
|
|
8
8
|
# BSC RPC endpoint (default: public BSC RPC)
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
# AgentNFA contract address (default: mainnet deployment)
|
|
12
|
-
# NFA_ADDRESS=0x...
|
|
13
|
-
|
|
14
|
-
# PolicyGuardV4 contract address (default: mainnet deployment)
|
|
15
|
-
# GUARD_ADDRESS=0x...
|
|
9
|
+
# SHLL_RPC=https://bsc-dataseed.binance.org
|
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ RUNNER_PRIVATE_KEY=0x... shll-mcp
|
|
|
65
65
|
|
|
66
66
|
The server communicates via **stdio** using JSON-RPC 2.0. Send `tools/list` to discover all available tools.
|
|
67
67
|
|
|
68
|
-
### Available MCP Tools (
|
|
68
|
+
### Available MCP Tools (24 total)
|
|
69
69
|
|
|
70
70
|
| Tool | Type | Description |
|
|
71
71
|
|------|------|-------------|
|
|
@@ -91,6 +91,7 @@ The server communicates via **stdio** using JSON-RPC 2.0. Send `tools/list` to d
|
|
|
91
91
|
| `generate_wallet` | Info | Create new operator wallet (address + key) |
|
|
92
92
|
| `execute_calldata` | Write | Execute raw calldata from any source through PolicyGuard |
|
|
93
93
|
| `execute_calldata_batch` | Write | Execute multiple calldata actions atomically through PolicyGuard |
|
|
94
|
+
| `token_restriction` | Read | View token whitelist restriction status + whitelisted tokens |
|
|
94
95
|
|
|
95
96
|
---
|
|
96
97
|
|
|
@@ -172,9 +173,9 @@ AI Agent -> CLI/MCP -> PolicyClient.validate() -> PolicyGuard (on-chain) -> vaul
|
|
|
172
173
|
| Variable | Required | Description |
|
|
173
174
|
|----------|----------|-------------|
|
|
174
175
|
| `RUNNER_PRIVATE_KEY` | Yes | Operator wallet key (~$1 BNB for gas) |
|
|
175
|
-
| `SHLL_RPC` | No | BSC RPC URL override |
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
| `SHLL_RPC` | No | BSC RPC URL override (default: public BSC RPC) |
|
|
177
|
+
|
|
178
|
+
> **Note:** Contract addresses (AgentNFA, PolicyGuard) are hardcoded for security reasons. Override env vars are intentionally not supported to prevent supply-chain attacks.
|
|
178
179
|
|
|
179
180
|
## Links
|
|
180
181
|
|
package/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: shll-run
|
|
3
3
|
description: Execute DeFi transactions on BSC via SHLL AgentNFA. The AI handles all commands — users only need to chat.
|
|
4
|
-
version:
|
|
4
|
+
version: 5.3.2
|
|
5
5
|
author: SHLL Team
|
|
6
6
|
website: https://shll.run
|
|
7
7
|
twitter: https://twitter.com/shllrun
|
|
@@ -196,6 +196,8 @@ Supported lending tokens: **BNB, USDT, USDC, BUSD**
|
|
|
196
196
|
| `shll-run config -k <ID> --tx-limit <BNB> --daily-limit <BNB> --cooldown <SEC>` | Tighten risk limits |
|
|
197
197
|
| `shll-run status -k <ID>` | One-shot security overview (vault, operator, policies, activity) |
|
|
198
198
|
| `shll-run history -k <ID> [--limit N]` | Recent transactions + policy rejections |
|
|
199
|
+
| `shll-run my-agents` | List all agents where current operator key is authorized |
|
|
200
|
+
| `shll-run token-restriction -k <ID>` | View token whitelist restriction status + whitelisted tokens |
|
|
199
201
|
|
|
200
202
|
**Supported tokens:** BNB, USDC, USDT, WBNB, CAKE, ETH, BTCB, DAI, BUSD, or any 0x address.
|
|
201
203
|
|
package/dist/mcp.js
CHANGED
|
@@ -709,7 +709,7 @@ function policyRejectionHelp(reason, tokenId) {
|
|
|
709
709
|
}
|
|
710
710
|
var server = new import_mcp.McpServer({
|
|
711
711
|
name: "shll-defi",
|
|
712
|
-
version: "5.2
|
|
712
|
+
version: "5.3.2"
|
|
713
713
|
});
|
|
714
714
|
server.tool(
|
|
715
715
|
"portfolio",
|
|
@@ -987,7 +987,7 @@ server.tool(
|
|
|
987
987
|
const data = (0, import_viem2.encodeFunctionData)({ abi: VTOKEN_ABI, functionName: "redeemUnderlying", args: [amt] });
|
|
988
988
|
const action = { target: vTokenAddr, value: 0n, data };
|
|
989
989
|
const sim = await policyClient.validate(tokenId, action);
|
|
990
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
990
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
991
991
|
const result = await policyClient.execute(tokenId, action, true);
|
|
992
992
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, protocol: "venus", action: "redeem", token: symbol, amount }) }] };
|
|
993
993
|
}
|
|
@@ -1052,7 +1052,7 @@ server.tool(
|
|
|
1052
1052
|
action = { target: tokenInfo.address, value: 0n, data };
|
|
1053
1053
|
}
|
|
1054
1054
|
const sim = await policyClient.validate(tokenId, action);
|
|
1055
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
1055
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
1056
1056
|
const result = await policyClient.execute(tokenId, action, true);
|
|
1057
1057
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, token, amount, to: recipient }) }] };
|
|
1058
1058
|
}
|
|
@@ -1139,7 +1139,7 @@ server.tool(
|
|
|
1139
1139
|
const data = (0, import_viem2.encodeFunctionData)({ abi: WBNB_ABI, functionName: "deposit" });
|
|
1140
1140
|
const action = { target: WBNB, value: amt, data };
|
|
1141
1141
|
const sim = await policyClient.validate(tokenId, action);
|
|
1142
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
1142
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
1143
1143
|
const result = await policyClient.execute(tokenId, action, true);
|
|
1144
1144
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, message: `Wrapped ${amount} BNB \u2192 WBNB` }) }] };
|
|
1145
1145
|
}
|
|
@@ -1160,7 +1160,7 @@ server.tool(
|
|
|
1160
1160
|
const data = (0, import_viem2.encodeFunctionData)({ abi: WBNB_ABI, functionName: "withdraw", args: [amt] });
|
|
1161
1161
|
const action = { target: WBNB, value: 0n, data };
|
|
1162
1162
|
const sim = await policyClient.validate(tokenId, action);
|
|
1163
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
1163
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
1164
1164
|
const result = await policyClient.execute(tokenId, action, true);
|
|
1165
1165
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, message: `Unwrapped ${amount} WBNB \u2192 BNB` }) }] };
|
|
1166
1166
|
}
|
package/dist/mcp.mjs
CHANGED
|
@@ -220,7 +220,7 @@ function policyRejectionHelp(reason, tokenId) {
|
|
|
220
220
|
}
|
|
221
221
|
var server = new McpServer({
|
|
222
222
|
name: "shll-defi",
|
|
223
|
-
version: "5.2
|
|
223
|
+
version: "5.3.2"
|
|
224
224
|
});
|
|
225
225
|
server.tool(
|
|
226
226
|
"portfolio",
|
|
@@ -498,7 +498,7 @@ server.tool(
|
|
|
498
498
|
const data = encodeFunctionData({ abi: VTOKEN_ABI, functionName: "redeemUnderlying", args: [amt] });
|
|
499
499
|
const action = { target: vTokenAddr, value: 0n, data };
|
|
500
500
|
const sim = await policyClient.validate(tokenId, action);
|
|
501
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
501
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
502
502
|
const result = await policyClient.execute(tokenId, action, true);
|
|
503
503
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, protocol: "venus", action: "redeem", token: symbol, amount }) }] };
|
|
504
504
|
}
|
|
@@ -563,7 +563,7 @@ server.tool(
|
|
|
563
563
|
action = { target: tokenInfo.address, value: 0n, data };
|
|
564
564
|
}
|
|
565
565
|
const sim = await policyClient.validate(tokenId, action);
|
|
566
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
566
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
567
567
|
const result = await policyClient.execute(tokenId, action, true);
|
|
568
568
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, token, amount, to: recipient }) }] };
|
|
569
569
|
}
|
|
@@ -650,7 +650,7 @@ server.tool(
|
|
|
650
650
|
const data = encodeFunctionData({ abi: WBNB_ABI, functionName: "deposit" });
|
|
651
651
|
const action = { target: WBNB, value: amt, data };
|
|
652
652
|
const sim = await policyClient.validate(tokenId, action);
|
|
653
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
653
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
654
654
|
const result = await policyClient.execute(tokenId, action, true);
|
|
655
655
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, message: `Wrapped ${amount} BNB \u2192 WBNB` }) }] };
|
|
656
656
|
}
|
|
@@ -671,7 +671,7 @@ server.tool(
|
|
|
671
671
|
const data = encodeFunctionData({ abi: WBNB_ABI, functionName: "withdraw", args: [amt] });
|
|
672
672
|
const action = { target: WBNB, value: 0n, data };
|
|
673
673
|
const sim = await policyClient.validate(tokenId, action);
|
|
674
|
-
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
674
|
+
if (!sim.ok) return { content: [{ type: "text", text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
675
675
|
const result = await policyClient.execute(tokenId, action, true);
|
|
676
676
|
return { content: [{ type: "text", text: JSON.stringify({ status: "success", hash: result.hash, message: `Unwrapped ${amount} WBNB \u2192 BNB` }) }] };
|
|
677
677
|
}
|
package/package.json
CHANGED
package/src/mcp.ts
CHANGED
|
@@ -266,7 +266,7 @@ function policyRejectionHelp(reason: string | undefined, tokenId: string): Recor
|
|
|
266
266
|
|
|
267
267
|
const server = new McpServer({
|
|
268
268
|
name: "shll-defi",
|
|
269
|
-
version: "5.2
|
|
269
|
+
version: "5.3.2",
|
|
270
270
|
});
|
|
271
271
|
|
|
272
272
|
// ── Tool: portfolio ─────────────────────────────────────
|
|
@@ -575,7 +575,7 @@ server.tool(
|
|
|
575
575
|
const action: Action = { target: vTokenAddr, value: 0n, data };
|
|
576
576
|
|
|
577
577
|
const sim = await policyClient.validate(tokenId, action);
|
|
578
|
-
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
578
|
+
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
579
579
|
|
|
580
580
|
const result = await policyClient.execute(tokenId, action, true);
|
|
581
581
|
return { content: [{ type: "text" as const, text: JSON.stringify({ status: "success", hash: result.hash, protocol: "venus", action: "redeem", token: symbol, amount }) }] };
|
|
@@ -649,7 +649,7 @@ server.tool(
|
|
|
649
649
|
}
|
|
650
650
|
|
|
651
651
|
const sim = await policyClient.validate(tokenId, action);
|
|
652
|
-
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
652
|
+
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
653
653
|
|
|
654
654
|
const result = await policyClient.execute(tokenId, action, true);
|
|
655
655
|
return { content: [{ type: "text" as const, text: JSON.stringify({ status: "success", hash: result.hash, token, amount, to: recipient }) }] };
|
|
@@ -742,7 +742,7 @@ server.tool(
|
|
|
742
742
|
const action: Action = { target: WBNB as Address, value: amt, data };
|
|
743
743
|
|
|
744
744
|
const sim = await policyClient.validate(tokenId, action);
|
|
745
|
-
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
745
|
+
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
746
746
|
|
|
747
747
|
const result = await policyClient.execute(tokenId, action, true);
|
|
748
748
|
return { content: [{ type: "text" as const, text: JSON.stringify({ status: "success", hash: result.hash, message: `Wrapped ${amount} BNB → WBNB` }) }] };
|
|
@@ -766,7 +766,7 @@ server.tool(
|
|
|
766
766
|
const action: Action = { target: WBNB as Address, value: 0n, data };
|
|
767
767
|
|
|
768
768
|
const sim = await policyClient.validate(tokenId, action);
|
|
769
|
-
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason }) }] };
|
|
769
|
+
if (!sim.ok) return { content: [{ type: "text" as const, text: JSON.stringify({ status: "rejected", reason: sim.reason, ...policyRejectionHelp(sim.reason, token_id) }) }] };
|
|
770
770
|
|
|
771
771
|
const result = await policyClient.execute(tokenId, action, true);
|
|
772
772
|
return { content: [{ type: "text" as const, text: JSON.stringify({ status: "success", hash: result.hash, message: `Unwrapped ${amount} WBNB → BNB` }) }] };
|