shll-skills 5.0.1 → 5.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 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 (20 total)
68
+ ### Available MCP Tools (22 total)
69
69
 
70
70
  | Tool | Type | Description |
71
71
  |------|------|-------------|
@@ -89,6 +89,8 @@ The server communicates via **stdio** using JSON-RPC 2.0. Send `tools/list` to d
89
89
  | `config` | Write | Configure risk parameters (spending limits, cooldown) |
90
90
  | `setup_guide` | Info | Generate dual-wallet onboarding URL + steps |
91
91
  | `generate_wallet` | Info | Create new operator wallet (address + key) |
92
+ | `execute_calldata` | Write | Execute raw calldata from any source through PolicyGuard |
93
+ | `execute_calldata_batch` | Write | Execute multiple calldata actions atomically through PolicyGuard |
92
94
 
93
95
  ---
94
96
 
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: 5.0.0
4
+ version: 6.0.0
5
5
  author: SHLL Team
6
6
  website: https://shll.run
7
7
  twitter: https://twitter.com/shllrun
@@ -249,6 +249,27 @@ If the user has multiple DeFi skills installed, understand the architectural dif
249
249
 
250
250
  **Routing rule:** When the user's intent involves their SHLL agent vault (identified by token-id), ALWAYS use SHLL tools. It's fine to use other skills for price quotes, market research, or operations outside SHLL.
251
251
 
252
+ ### Cross-Skill Execution Pattern
253
+
254
+ If another skill provides **calldata** (e.g. OKX DEX API returns a swap route), you can execute it through SHLL's safety layer:
255
+
256
+ 1. **Get calldata from other skill** → e.g., OKX returns `{to: "0xDEX...", data: "0xABC...", value: "100000..."}`
257
+ 2. **Execute via SHLL** → use `execute_calldata` tool with the target, data, and value
258
+ 3. **PolicyGuard validates** → spending limits, cooldowns, whitelists enforced
259
+ 4. **Vault executes** → transaction runs from the agent vault
260
+
261
+ Example flow:
262
+ ```
263
+ User: "Use OKX to find the best swap route for 0.5 BNB to USDT, then execute it"
264
+
265
+ Step 1: Call OKX DEX API skill → get calldata
266
+ Step 2: Call SHLL execute_calldata(token_id, target, data, value) → PolicyGuard validated execution
267
+ ```
268
+
269
+ **This pattern gives you the best of both worlds:** superior routing from specialized DEX aggregators + SHLL's on-chain policy enforcement.
270
+
271
+ For multi-step transactions (e.g. approve + swap), use `execute_calldata_batch` to execute atomically.
272
+
252
273
  ---
253
274
 
254
275
  ## LINKS
package/dist/mcp.js CHANGED
@@ -1314,6 +1314,96 @@ server.tool(
1314
1314
  };
1315
1315
  }
1316
1316
  );
1317
+ server.tool(
1318
+ "execute_calldata",
1319
+ "Execute raw calldata through PolicyGuard safety layer. Use this to execute transactions from other DeFi skills (OKX DEX API, Bitget, 1inch, etc.) with SHLL on-chain policy enforcement. All actions are validated against spending limits, cooldowns, and whitelists before execution.",
1320
+ {
1321
+ token_id: import_zod.z.string().describe("Agent NFA Token ID"),
1322
+ target: import_zod.z.string().describe("Target contract address (0x...)"),
1323
+ data: import_zod.z.string().describe("Transaction calldata hex string"),
1324
+ value: import_zod.z.string().default("0").describe("Native BNB value in wei (default: 0)")
1325
+ },
1326
+ async ({ token_id, target, data, value }) => {
1327
+ const { policyClient } = createClients();
1328
+ const tokenId = BigInt(token_id);
1329
+ const action = {
1330
+ target,
1331
+ value: BigInt(value),
1332
+ data
1333
+ };
1334
+ const sim = await policyClient.validate(tokenId, action);
1335
+ if (!sim.ok) {
1336
+ return {
1337
+ content: [{
1338
+ type: "text",
1339
+ text: JSON.stringify({
1340
+ status: "rejected",
1341
+ reason: sim.reason,
1342
+ note: "PolicyGuard rejected this calldata. The target contract or operation may not be whitelisted, or it exceeds spending/cooldown limits."
1343
+ })
1344
+ }]
1345
+ };
1346
+ }
1347
+ const result = await policyClient.execute(tokenId, action, true);
1348
+ return {
1349
+ content: [{
1350
+ type: "text",
1351
+ text: JSON.stringify({
1352
+ status: "success",
1353
+ hash: result.hash,
1354
+ note: "Calldata executed through PolicyGuard. Transaction validated against all on-chain policies."
1355
+ })
1356
+ }]
1357
+ };
1358
+ }
1359
+ );
1360
+ server.tool(
1361
+ "execute_calldata_batch",
1362
+ "Execute multiple raw calldata actions atomically through PolicyGuard. Useful for approve+swap patterns from external DEX aggregators.",
1363
+ {
1364
+ token_id: import_zod.z.string().describe("Agent NFA Token ID"),
1365
+ actions: import_zod.z.array(import_zod.z.object({
1366
+ target: import_zod.z.string().describe("Target contract address"),
1367
+ data: import_zod.z.string().describe("Calldata hex"),
1368
+ value: import_zod.z.string().default("0").describe("BNB value in wei")
1369
+ })).describe("Array of actions to execute atomically")
1370
+ },
1371
+ async ({ token_id, actions: rawActions }) => {
1372
+ const { policyClient } = createClients();
1373
+ const tokenId = BigInt(token_id);
1374
+ const actions = rawActions.map((a) => ({
1375
+ target: a.target,
1376
+ value: BigInt(a.value || "0"),
1377
+ data: a.data
1378
+ }));
1379
+ for (let i = 0; i < actions.length; i++) {
1380
+ const sim = await policyClient.validate(tokenId, actions[i]);
1381
+ if (!sim.ok) {
1382
+ return {
1383
+ content: [{
1384
+ type: "text",
1385
+ text: JSON.stringify({
1386
+ status: "rejected",
1387
+ failedActionIndex: i,
1388
+ reason: sim.reason
1389
+ })
1390
+ }]
1391
+ };
1392
+ }
1393
+ }
1394
+ const result = actions.length === 1 ? await policyClient.execute(tokenId, actions[0], true) : await policyClient.executeBatch(tokenId, actions, true);
1395
+ return {
1396
+ content: [{
1397
+ type: "text",
1398
+ text: JSON.stringify({
1399
+ status: "success",
1400
+ hash: result.hash,
1401
+ actionsExecuted: actions.length
1402
+ })
1403
+ }]
1404
+ };
1405
+ }
1406
+ );
1317
1407
  server.tool(
1318
1408
  "generate_wallet",
1319
1409
  "Generate a new operator wallet (address + private key) for AI to use. This is a HOT wallet for trading only.",
package/dist/mcp.mjs CHANGED
@@ -825,6 +825,96 @@ server.tool(
825
825
  };
826
826
  }
827
827
  );
828
+ server.tool(
829
+ "execute_calldata",
830
+ "Execute raw calldata through PolicyGuard safety layer. Use this to execute transactions from other DeFi skills (OKX DEX API, Bitget, 1inch, etc.) with SHLL on-chain policy enforcement. All actions are validated against spending limits, cooldowns, and whitelists before execution.",
831
+ {
832
+ token_id: z.string().describe("Agent NFA Token ID"),
833
+ target: z.string().describe("Target contract address (0x...)"),
834
+ data: z.string().describe("Transaction calldata hex string"),
835
+ value: z.string().default("0").describe("Native BNB value in wei (default: 0)")
836
+ },
837
+ async ({ token_id, target, data, value }) => {
838
+ const { policyClient } = createClients();
839
+ const tokenId = BigInt(token_id);
840
+ const action = {
841
+ target,
842
+ value: BigInt(value),
843
+ data
844
+ };
845
+ const sim = await policyClient.validate(tokenId, action);
846
+ if (!sim.ok) {
847
+ return {
848
+ content: [{
849
+ type: "text",
850
+ text: JSON.stringify({
851
+ status: "rejected",
852
+ reason: sim.reason,
853
+ note: "PolicyGuard rejected this calldata. The target contract or operation may not be whitelisted, or it exceeds spending/cooldown limits."
854
+ })
855
+ }]
856
+ };
857
+ }
858
+ const result = await policyClient.execute(tokenId, action, true);
859
+ return {
860
+ content: [{
861
+ type: "text",
862
+ text: JSON.stringify({
863
+ status: "success",
864
+ hash: result.hash,
865
+ note: "Calldata executed through PolicyGuard. Transaction validated against all on-chain policies."
866
+ })
867
+ }]
868
+ };
869
+ }
870
+ );
871
+ server.tool(
872
+ "execute_calldata_batch",
873
+ "Execute multiple raw calldata actions atomically through PolicyGuard. Useful for approve+swap patterns from external DEX aggregators.",
874
+ {
875
+ token_id: z.string().describe("Agent NFA Token ID"),
876
+ actions: z.array(z.object({
877
+ target: z.string().describe("Target contract address"),
878
+ data: z.string().describe("Calldata hex"),
879
+ value: z.string().default("0").describe("BNB value in wei")
880
+ })).describe("Array of actions to execute atomically")
881
+ },
882
+ async ({ token_id, actions: rawActions }) => {
883
+ const { policyClient } = createClients();
884
+ const tokenId = BigInt(token_id);
885
+ const actions = rawActions.map((a) => ({
886
+ target: a.target,
887
+ value: BigInt(a.value || "0"),
888
+ data: a.data
889
+ }));
890
+ for (let i = 0; i < actions.length; i++) {
891
+ const sim = await policyClient.validate(tokenId, actions[i]);
892
+ if (!sim.ok) {
893
+ return {
894
+ content: [{
895
+ type: "text",
896
+ text: JSON.stringify({
897
+ status: "rejected",
898
+ failedActionIndex: i,
899
+ reason: sim.reason
900
+ })
901
+ }]
902
+ };
903
+ }
904
+ }
905
+ const result = actions.length === 1 ? await policyClient.execute(tokenId, actions[0], true) : await policyClient.executeBatch(tokenId, actions, true);
906
+ return {
907
+ content: [{
908
+ type: "text",
909
+ text: JSON.stringify({
910
+ status: "success",
911
+ hash: result.hash,
912
+ actionsExecuted: actions.length
913
+ })
914
+ }]
915
+ };
916
+ }
917
+ );
828
918
  server.tool(
829
919
  "generate_wallet",
830
920
  "Generate a new operator wallet (address + private key) for AI to use. This is a HOT wallet for trading only.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shll-skills",
3
- "version": "5.0.1",
3
+ "version": "5.1.0",
4
4
  "description": "SHLL DeFi Agent — CLI + MCP Server for BSC",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/src/mcp.ts CHANGED
@@ -968,6 +968,107 @@ server.tool(
968
968
  }
969
969
  );
970
970
 
971
+ // ── Tool: execute_calldata ──────────────────────────────
972
+ // Universal safety execution layer: accepts calldata from ANY source
973
+ // (OKX DEX API, Bitget, 1inch, etc.) and routes through PolicyGuard
974
+ server.tool(
975
+ "execute_calldata",
976
+ "Execute raw calldata through PolicyGuard safety layer. Use this to execute transactions from other DeFi skills (OKX DEX API, Bitget, 1inch, etc.) with SHLL on-chain policy enforcement. All actions are validated against spending limits, cooldowns, and whitelists before execution.",
977
+ {
978
+ token_id: z.string().describe("Agent NFA Token ID"),
979
+ target: z.string().describe("Target contract address (0x...)"),
980
+ data: z.string().describe("Transaction calldata hex string"),
981
+ value: z.string().default("0").describe("Native BNB value in wei (default: 0)"),
982
+ },
983
+ async ({ token_id, target, data, value }) => {
984
+ const { policyClient } = createClients();
985
+ const tokenId = BigInt(token_id);
986
+ const action: Action = {
987
+ target: target as Address,
988
+ value: BigInt(value),
989
+ data: data as Hex,
990
+ };
991
+
992
+ // Validate through PolicyGuard (spending limits, cooldowns, whitelists)
993
+ const sim = await policyClient.validate(tokenId, action);
994
+ if (!sim.ok) {
995
+ return {
996
+ content: [{
997
+ type: "text" as const, text: JSON.stringify({
998
+ status: "rejected",
999
+ reason: sim.reason,
1000
+ note: "PolicyGuard rejected this calldata. The target contract or operation may not be whitelisted, or it exceeds spending/cooldown limits.",
1001
+ })
1002
+ }]
1003
+ };
1004
+ }
1005
+
1006
+ const result = await policyClient.execute(tokenId, action, true);
1007
+ return {
1008
+ content: [{
1009
+ type: "text" as const, text: JSON.stringify({
1010
+ status: "success",
1011
+ hash: result.hash,
1012
+ note: "Calldata executed through PolicyGuard. Transaction validated against all on-chain policies.",
1013
+ })
1014
+ }]
1015
+ };
1016
+ }
1017
+ );
1018
+
1019
+ // ── Tool: execute_calldata_batch ─────────────────────────
1020
+ server.tool(
1021
+ "execute_calldata_batch",
1022
+ "Execute multiple raw calldata actions atomically through PolicyGuard. Useful for approve+swap patterns from external DEX aggregators.",
1023
+ {
1024
+ token_id: z.string().describe("Agent NFA Token ID"),
1025
+ actions: z.array(z.object({
1026
+ target: z.string().describe("Target contract address"),
1027
+ data: z.string().describe("Calldata hex"),
1028
+ value: z.string().default("0").describe("BNB value in wei"),
1029
+ })).describe("Array of actions to execute atomically"),
1030
+ },
1031
+ async ({ token_id, actions: rawActions }) => {
1032
+ const { policyClient } = createClients();
1033
+ const tokenId = BigInt(token_id);
1034
+ const actions: Action[] = rawActions.map(a => ({
1035
+ target: a.target as Address,
1036
+ value: BigInt(a.value || "0"),
1037
+ data: a.data as Hex,
1038
+ }));
1039
+
1040
+ // Validate all actions
1041
+ for (let i = 0; i < actions.length; i++) {
1042
+ const sim = await policyClient.validate(tokenId, actions[i]);
1043
+ if (!sim.ok) {
1044
+ return {
1045
+ content: [{
1046
+ type: "text" as const, text: JSON.stringify({
1047
+ status: "rejected",
1048
+ failedActionIndex: i,
1049
+ reason: sim.reason,
1050
+ })
1051
+ }]
1052
+ };
1053
+ }
1054
+ }
1055
+
1056
+ const result = actions.length === 1
1057
+ ? await policyClient.execute(tokenId, actions[0], true)
1058
+ : await policyClient.executeBatch(tokenId, actions, true);
1059
+
1060
+ return {
1061
+ content: [{
1062
+ type: "text" as const, text: JSON.stringify({
1063
+ status: "success",
1064
+ hash: result.hash,
1065
+ actionsExecuted: actions.length,
1066
+ })
1067
+ }]
1068
+ };
1069
+ }
1070
+ );
1071
+
971
1072
  // ── Tool: generate_wallet ───────────────────────────────
972
1073
  server.tool(
973
1074
  "generate_wallet",